This commit is contained in:
.[d]. 2022-10-04 18:01:11 -05:00
parent 5b9e993cee
commit 06e348af0e
6 changed files with 522 additions and 501 deletions

@ -2,8 +2,11 @@
from irc3.plugins.command import command
import irc3,os,aiohttp, asyncio, async_timeout
dir_path = os.path.dirname(os.path.realpath(__file__))
CRYPTOCOMPARE_KEY = os.environ['CRYPTOCOMPARE_KEY']
headers = { 'authorization': f'Apikey {CRYPTOCOMPARE_KEY}' }
try:
CRYPTOCOMPARE_KEY = os.environ['CRYPTOCOMPARE_KEY']
headers = { 'authorization': f'Apikey {CRYPTOCOMPARE_KEY}' }
except:
pass
###########################################################################################
###########################################################################################
@irc3.plugin

@ -2,150 +2,150 @@
###########################################################################################
???DISCORD???
###########################################################################################
import asyncio
import os
import re
###########################################################################################
if SERVICES_DISCORD:
import asyncio
import os
import re
###########################################################################################
import discord
###########################################################################################
from plugins.tool_colors_plugin import colorform as print
import irc3
###########################################################################################
if SERVICES_DISCORD:
from discord import Client
from discord.ext import commands, tasks
###########################################################################################
from irc3.plugins.command import command
###########################################################################################
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
###########################################################################################
if SERVICES_DISCORD:
DISCORD__SCHAN=int(os.environ['DISCORD__SCHAN'])
DISCORD__TOKEN=str(os.environ['DISCORD__TOKEN'])
###########################################################################################
global client
###########################################################################################
async def _d_bnc_msg(netsrc,usernick,netdest,data):
netsrc="^{}".format(netsrc)
bridgedbus=(BUS(netdest))
await bridgedbus.input(netsrc,usernick,data,True)
###########################################################################################
def d_bnc_msg(netsrc,usernick,netdest,data,):
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(_d_bnc_msg(netsrc,usernick,netdest,data),ircbot.loop)
###########################################################################################
def start_discordbot(self):
print(f'<<< _net_discord_plugin >>> [ discordbot started ]')
self.discordbot=DISCORDBOT()
globals()['guds'].memories.append([self.discordbot,'net_discord_plugin:start_discordbot.self'])
asyncio.set_event_loop(self.loop)
asyncio.run_coroutine_threadsafe(self.discordbot.client.start(DISCORD__TOKEN),self.loop)
return self
class DISCORDBOT:
###########################################################################################
from plugins.tool_colors_plugin import colorform as print
import irc3
###########################################################################################
if SERVICES_DISCORD:
#######################################################################################
intents=discord.Intents.default()
intents.members = True
intents.messages = True
intents = discord.Intents.default()
intents.message_content = True
client=discord.Client(intents=intents)
def __init__(self):
self.ircbot=guds.memory('ircbot')
self.dbname="discordchat"
self.db=self.ircbot.db.getlist(self.dbname)
if not self.db: self.db=[]
#######################################################################################
@client.event
async def on_ready():
print(f'<<< _net_discord_plugin >>> [ discordbot connection made as {globals()["DISCORDBOT"].client.user.name} ]')
#######################################################################################
async def listchannels(self):
print(f"<<< _net_discord_plugin >>> [ event: scanning channels ] - started")
discordchannels=list(globals()['DISCORDBOT'].client.get_all_channels())
if discordchannels[0].__class__.__name__=="CategoryChannel" and discordchannels[0].name=='bridged':
for channel in discordchannels[0].channels:
channel_name=f"^{channel.name}"
result=dims.isdiscordchannel(channel_name)
if not result:
dims.__create__('discord',channel_name)
print(f"<<< _net_discord_plugin >>> [ event: new channel ] - dims.__create__(discord,{channel_name}) - active channel record created")
globals()['DISCORDBOT'].push(channel.id,channel.name)
#######################################################################################
async def clear():
discordbot=guds.memory('discordbot')
client=discordbot.client
TRAP_FLAG=True
purge_cycle=0
while TRAP_FLAG:
purge_cycle+=1
channel=client.get_channel(DISCORD__SCHAN)
await asyncio.sleep(0.1)
if not channel.last_message==None:
msg=f'<<< _net_discord_plugin >>> [ purging bridge ] - cycle: {purge_cycle}'
print(msg)
await channel.purge()
else:
msg=f'<<< _net_discord_plugin >>> [ purging bridge ] - completed'
print(msg)
TRAP_FLAG=False
#######################################################################################
def push(id,name):
class discordchat:
def __init__(self,id,name):
self.id=id
self.name=name
dc=discordchat(id,name)
FLAG_FOUND=False
self=guds.memory('discordbot')
for entry in self.db:
if entry[0]==dc.id:
FLAG_FOUND=True
break
if not FLAG_FOUND:
self.db.append([dc.id,f"^{dc.name}"])
self.ircbot.db.setlist(self.dbname,self.db)
print(f'<<< _net_discord_plugin >>> [ new database entry ] > [{dc.id},^{dc.name}]')
########################################################################################
@client.event
async def on_message(message):
###################################################################################
discordbot=guds.memory('discordbot')
client=discordbot.client
if message.author.name == client.user.name:
return
discordbot=guds.memory('discordbot')
asyncio.run_coroutine_threadsafe(discordbot.listchannels(),discordbot.client.loop)
channel_name=f"^{message.channel.name}"
TARGET="^χιϛ"
USER=message.author.name
if not message.content.lower().find('maple')==-1:
from discord import Client
from discord.ext import commands, tasks
###########################################################################################
from irc3.plugins.command import command
###########################################################################################
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
###########################################################################################
if SERVICES_DISCORD:
DISCORD__SCHAN=int(os.environ['DISCORD__SCHAN'])
DISCORD__TOKEN=str(os.environ['DISCORD__TOKEN'])
###########################################################################################
global client
###########################################################################################
async def _d_bnc_msg(netsrc,usernick,netdest,data):
netsrc="^{}".format(netsrc)
bridgedbus=(BUS(netdest))
await bridgedbus.input(netsrc,usernick,data,True)
###########################################################################################
def d_bnc_msg(netsrc,usernick,netdest,data,):
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(_d_bnc_msg(netsrc,usernick,netdest,data),ircbot.loop)
###########################################################################################
def start_discordbot(self):
print(f'<<< _net_discord_plugin >>> [ discordbot started ]')
self.discordbot=DISCORDBOT()
globals()['guds'].memories.append([self.discordbot,'net_discord_plugin:start_discordbot.self'])
asyncio.set_event_loop(self.loop)
asyncio.run_coroutine_threadsafe(self.discordbot.client.start(DISCORD__TOKEN),self.loop)
return self
class DISCORDBOT:
if SERVICES_DISCORD:
#######################################################################################
intents=discord.Intents.default()
intents.members = True
intents.messages = True
intents = discord.Intents.default()
intents.message_content = True
client=discord.Client(intents=intents)
def __init__(self):
self.ircbot=guds.memory('ircbot')
self.dbname="discordchat"
self.db=self.ircbot.db.getlist(self.dbname)
if not self.db: self.db=[]
#######################################################################################
@client.event
async def on_ready():
print(f'<<< _net_discord_plugin >>> [ discordbot connection made as {globals()["DISCORDBOT"].client.user.name} ]')
#######################################################################################
async def listchannels(self):
print(f"<<< _net_discord_plugin >>> [ event: scanning channels ] - started")
discordchannels=list(globals()['DISCORDBOT'].client.get_all_channels())
if discordchannels[0].__class__.__name__=="CategoryChannel" and discordchannels[0].name=='bridged':
for channel in discordchannels[0].channels:
channel_name=f"^{channel.name}"
result=dims.isdiscordchannel(channel_name)
if not result:
dims.__create__('discord',channel_name)
print(f"<<< _net_discord_plugin >>> [ event: new channel ] - dims.__create__(discord,{channel_name}) - active channel record created")
globals()['DISCORDBOT'].push(channel.id,channel.name)
#######################################################################################
async def clear():
discordbot=guds.memory('discordbot')
client=discordbot.client
TRAP_FLAG=True
purge_cycle=0
while TRAP_FLAG:
purge_cycle+=1
channel=client.get_channel(DISCORD__SCHAN)
await asyncio.sleep(0.1)
if not channel.last_message==None:
msg=f'<<< _net_discord_plugin >>> [ purging bridge ] - cycle: {purge_cycle}'
print(msg)
await channel.purge()
else:
msg=f'<<< _net_discord_plugin >>> [ purging bridge ] - completed'
print(msg)
TRAP_FLAG=False
#######################################################################################
def push(id,name):
class discordchat:
def __init__(self,id,name):
self.id=id
self.name=name
dc=discordchat(id,name)
FLAG_FOUND=False
self=guds.memory('discordbot')
for entry in self.db:
if entry[0]==dc.id:
FLAG_FOUND=True
break
if not FLAG_FOUND:
self.db.append([dc.id,f"^{dc.name}"])
self.ircbot.db.setlist(self.dbname,self.db)
print(f'<<< _net_discord_plugin >>> [ new database entry ] > [{dc.id},^{dc.name}]')
########################################################################################
@client.event
async def on_message(message):
###################################################################################
discordbot=guds.memory('discordbot')
client=discordbot.client
if message.author.name == client.user.name:
return
discordbot=guds.memory('discordbot')
asyncio.run_coroutine_threadsafe(discordbot.listchannels(),discordbot.client.loop)
channel_name=f"^{message.channel.name}"
TARGET="^χιϛ"
USER=message.author.name
if not message.content.lower().find('maple')==-1:
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(ircbot.indirect_maple([USER,TARGET,"#tcpdirect"],message.content),ircbot.loop)
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(ircbot.indirect_maple([USER,TARGET,"#tcpdirect"],message.content),ircbot.loop)
ircbot=guds.memory('ircbot')
netschanlist=dims.list_channels_bridged(netsrc=TARGET)
netschanlist.append(TARGET)
bridgedbus=(BUS(netschanlist))
asyncio.run_coroutine_threadsafe(bridgedbus.input(TARGET,USER,message.content,True),ircbot.loop)
msg=f'<<< _net_discord_plugin >>> [ (d)({message.channel.id})({channel_name}) ] > {str(message.author)}: {message.content}'
print(msg)
###################################################################################
async def _d_discord_msg(self,target,msg):
discordbot=guds.memory('discordbot')
client=discordbot.client
if [x.id for x in list(client.get_all_channels()) if x.name==target[1:]][0]:
channel=client.get_channel([x.id for x in list(client.get_all_channels()) if x.name==target[1:]][0])
await channel.send(msg)
###########################################################################################
def d_discord_cmd(target,cmd,):
discordbot=guds.memory('discordbot')
if cmd=="purgebridges":
asyncio.run_coroutine_threadsafe(discordbot.clear(),discordbot.client.loop)
###########################################################################################
def d_discord_msg(target,msg,):
discordbot=guds.memory('discordbot')
asyncio.run_coroutine_threadsafe(discordbot._d_discord_msg(target,msg),discordbot.client.loop)
####################################################################################### EOF#.[d].
netschanlist=dims.list_channels_bridged(netsrc=TARGET)
netschanlist.append(TARGET)
bridgedbus=(BUS(netschanlist))
asyncio.run_coroutine_threadsafe(bridgedbus.input(TARGET,USER,message.content,True),ircbot.loop)
msg=f'<<< _net_discord_plugin >>> [ (d)({message.channel.id})({channel_name}) ] > {str(message.author)}: {message.content}'
print(msg)
###################################################################################
async def _d_discord_msg(self,target,msg):
discordbot=guds.memory('discordbot')
client=discordbot.client
if [x.id for x in list(client.get_all_channels()) if x.name==target[1:]][0]:
channel=client.get_channel([x.id for x in list(client.get_all_channels()) if x.name==target[1:]][0])
await channel.send(msg)
###########################################################################################
def d_discord_cmd(target,cmd,):
discordbot=guds.memory('discordbot')
if cmd=="purgebridges":
asyncio.run_coroutine_threadsafe(discordbot.clear(),discordbot.client.loop)
###########################################################################################
def d_discord_msg(target,msg,):
discordbot=guds.memory('discordbot')
asyncio.run_coroutine_threadsafe(discordbot._d_discord_msg(target,msg),discordbot.client.loop)
####################################################################################### EOF#.[d].

@ -1,128 +1,130 @@
# -*- coding: utf-8 -*- ############################################################### SOF
import irc3,asyncio,os,re
from nio import AsyncClient, MatrixRoom, RoomMessageText
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
from irc3.plugins.command import command
from plugins.tool_bus_plugin import BUS
from datetime import datetime
from plugins.tool_colors_plugin import colorform as print
###########################################################################################
try:
MATRIX_HOMESERVER=os.environ['MATRIX_HOMESERVER']
MATRIX___USERNAME=os.environ['MATRIX___USERNAME']
MATRIX___PASSWORD=os.environ['MATRIX___PASSWORD']
except:
pass
###########################################################################################
matrix_bot_credentials=[]
###########################################################################################
def add_credentials(credential):
matrix_bot_credentials.append(credential)
print(f'<<< __net_matrix_plugin >>> [ add_credentials ] - added {credential} credentials to net_matrix_plugin.matrix_bot_credentials')
###########################################################################################
def check_credentials(self,against_credential):
flag_match=False
for credential in matrix_bot_credentials:
if not credential.find(against_credential):
flag_match=True
print(f'<<< __net_matrix_plugin >>> [ check_credentials ] - found {credential} against {against_credential}')
#######################################################################################
if not flag_match:
print(f'<<< __net_matrix_plugin >>> [ check_credentials ] - no credentials found matching {against_credential}')
#######################################################################################
return flag_match
###########################################################################################
def start_matrixbot(self):
print(f'<<< __net_matrix_plugin >>> [ matrixbot started ]')
add_credentials("@maple.or.g1mp:matrix.org")
add_credentials("@maple:pcriot.org")
self.matrixbot=MATRIXBOT()
self.matrixbot.loop=self.loop
asyncio.set_event_loop(self.loop)
asyncio.run_coroutine_threadsafe(self.matrixbot.main(),self.loop)
self.matrixbot.client=AsyncClient(MATRIX_HOMESERVER, MATRIX___USERNAME)
return self
###########################################################################################
async def _d_matrix_msg(target,msg,) -> None:
matrixbot=guds.memory('matrixbot')
await matrixbot.client.room_send(
room_id=target,
message_type="m.room.message",
content={"msgtype":"m.text","body":msg},
)
###########################################################################################
def d_matrix_msg(target,msg,):
matrixbot=guds.memory('matrixbot')
asyncio.run_coroutine_threadsafe(_d_matrix_msg(target,msg),matrixbot.loop)
###########################################################################################
class MATRIXBOT:
def __init__(self):
self.ircbot=guds.memory('ircbot')
self.dbname="matrixchat"
self.db=self.ircbot.db.getlist(self.dbname)
if not self.db: self.db=[]
print(f'<<< __net_matrix_plugin >>> [ plugin loaded ]')
globals()['guds'].memories.append([self,'net_matrix_plugin:start_matrixbot.self'])
#######################################################################################
async def message_callback(self,room: MatrixRoom, event: RoomMessageText) -> None:
if guds.timestamp_check('matrix_boot')==False:
return
print(f"<<< __net_matrix_plugin >>> [ (m)({room.room_id})({room.display_name}) ] > {room.user_name(event.sender)}: {event.body}")
if event.sender==self.client.user_id or event.sender=="@ircd_maple:tcp.direct":
return # ignore messages from self, e.g. @maple:pcriot.org
user_src=str(event.sender)[1:].split(":")[0]
netschanlist=dims.list_channels_bridged(netsrc=room.room_id)
bridgedbus=(BUS(netschanlist))
await bridgedbus.input(room.room_id,user_src,event.body,True)
if not event.body.lower().find("maple")==-1:
#######################################################################################
self.blackhole=[]
ircbot=guds.memory('ircbot')
dbname="blackhole"
db=ircbot.db.getlist(dbname)
if db:
for entry in db:
self.blackhole.append(entry)
if not room.room_id in self.blackhole:
???MATRIX???
if SERVICES_MATRIX:
import irc3,asyncio,os,re
from nio import AsyncClient, MatrixRoom, RoomMessageText
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
from irc3.plugins.command import command
from plugins.tool_bus_plugin import BUS
from datetime import datetime
from plugins.tool_colors_plugin import colorform as print
###########################################################################################
try:
MATRIX_HOMESERVER=os.environ['MATRIX_HOMESERVER']
MATRIX___USERNAME=os.environ['MATRIX___USERNAME']
MATRIX___PASSWORD=os.environ['MATRIX___PASSWORD']
except:
pass
###########################################################################################
matrix_bot_credentials=[]
###########################################################################################
def add_credentials(credential):
matrix_bot_credentials.append(credential)
print(f'<<< __net_matrix_plugin >>> [ add_credentials ] - added {credential} credentials to net_matrix_plugin.matrix_bot_credentials')
###########################################################################################
def check_credentials(self,against_credential):
flag_match=False
for credential in matrix_bot_credentials:
if not credential.find(against_credential):
flag_match=True
print(f'<<< __net_matrix_plugin >>> [ check_credentials ] - found {credential} against {against_credential}')
#######################################################################################
if not flag_match:
print(f'<<< __net_matrix_plugin >>> [ check_credentials ] - no credentials found matching {against_credential}')
#######################################################################################
return flag_match
###########################################################################################
def start_matrixbot(self):
print(f'<<< __net_matrix_plugin >>> [ matrixbot started ]')
add_credentials("@maple.or.g1mp:matrix.org")
add_credentials("@maple:pcriot.org")
self.matrixbot=MATRIXBOT()
self.matrixbot.loop=self.loop
asyncio.set_event_loop(self.loop)
asyncio.run_coroutine_threadsafe(self.matrixbot.main(),self.loop)
self.matrixbot.client=AsyncClient(MATRIX_HOMESERVER, MATRIX___USERNAME)
return self
###########################################################################################
async def _d_matrix_msg(target,msg,) -> None:
matrixbot=guds.memory('matrixbot')
await matrixbot.client.room_send(
room_id=target,
message_type="m.room.message",
content={"msgtype":"m.text","body":msg},
)
###########################################################################################
def d_matrix_msg(target,msg,):
matrixbot=guds.memory('matrixbot')
asyncio.run_coroutine_threadsafe(_d_matrix_msg(target,msg),matrixbot.loop)
###########################################################################################
class MATRIXBOT:
def __init__(self):
self.ircbot=guds.memory('ircbot')
self.dbname="matrixchat"
self.db=self.ircbot.db.getlist(self.dbname)
if not self.db: self.db=[]
print(f'<<< __net_matrix_plugin >>> [ plugin loaded ]')
globals()['guds'].memories.append([self,'net_matrix_plugin:start_matrixbot.self'])
#######################################################################################
async def message_callback(self,room: MatrixRoom, event: RoomMessageText) -> None:
if guds.timestamp_check('matrix_boot')==False:
return
print(f"<<< __net_matrix_plugin >>> [ (m)({room.room_id})({room.display_name}) ] > {room.user_name(event.sender)}: {event.body}")
if event.sender==self.client.user_id or event.sender=="@ircd_maple:tcp.direct":
return # ignore messages from self, e.g. @maple:pcriot.org
user_src=str(event.sender)[1:].split(":")[0]
netschanlist=dims.list_channels_bridged(netsrc=room.room_id)
bridgedbus=(BUS(netschanlist))
await bridgedbus.input(room.room_id,user_src,event.body,True)
if not event.body.lower().find("maple")==-1:
#######################################################################################
self.blackhole=[]
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(ircbot.indirect_maple([user_src,room.room_id,"#tcpdirect"],event.body),ircbot.loop)
if event.body.startswith("?"):
from plugins.cmd_irc_plugin import d_cmd_irc
if not event.body.find('listrooms')==-1:
d_cmd_irc(room.room_id,event.sender,'!OftXgmqAFOPEatmvLU:pcriot.org','listrooms','')
elif not event.body.find('purgebridges')==-1:
d_cmd_irc(room.room_id,event.sender,'!OftXgmqAFOPEatmvLU:pcriot.org','purgebridges','')
#######################################################################################
def push(self,room_id):
class matrixchat:
def __init__(self,room_id):
self.room_id=room_id
mc=matrixchat(room_id)
FLAG_FOUND=False
for entry in self.db:
if entry[0]==mc.room_id:
FLAG_FOUND=True
break
if not FLAG_FOUND:
self.db.append([mc.room_id])
self.ircbot.db.setlist(self.dbname,self.db)
print(f'<<< __net_matrix_plugin >>> [ new database entry ] > [{mc.room_id}]')
dbname="blackhole"
db=ircbot.db.getlist(dbname)
if db:
for entry in db:
self.blackhole.append(entry)
if not room.room_id in self.blackhole:
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(ircbot.indirect_maple([user_src,room.room_id,"#tcpdirect"],event.body),ircbot.loop)
if event.body.startswith("?"):
from plugins.cmd_irc_plugin import d_cmd_irc
if not event.body.find('listrooms')==-1:
d_cmd_irc(room.room_id,event.sender,'!OftXgmqAFOPEatmvLU:pcriot.org','listrooms','')
elif not event.body.find('purgebridges')==-1:
d_cmd_irc(room.room_id,event.sender,'!OftXgmqAFOPEatmvLU:pcriot.org','purgebridges','')
#######################################################################################
async def main(self,) -> None:
self.client.add_event_callback(self.message_callback,RoomMessageText)
await self.client.login(MATRIX___PASSWORD)
guds.timestamp_alarm('matrix_boot',3)
joined_rooms=(await self.client.joined_rooms())
for _room in joined_rooms.rooms:
result=dims.ismatrixroom(_room)
if not result:
msg=f'<<< __net_matrix_plugin >>> [ event: join ] - user_id: {self.client.user_id} - target: {_room}'
print(msg)
dims.__create__('matrix',_room)
print(f"<<< ___tool_dims_plugin >>> [ event: join ] - dims.__create__(matrix,{_room}) - active room record created")
self.push(_room)
###################################################################################
print(f'<<< __net_matrix_plugin >>> [ await client.sync_forever(timeout=5000) ]')
await self.client.sync_forever(timeout=5000) # milliseconds
####################################################################################### EOF#.[d].
def push(self,room_id):
class matrixchat:
def __init__(self,room_id):
self.room_id=room_id
mc=matrixchat(room_id)
FLAG_FOUND=False
for entry in self.db:
if entry[0]==mc.room_id:
FLAG_FOUND=True
break
if not FLAG_FOUND:
self.db.append([mc.room_id])
self.ircbot.db.setlist(self.dbname,self.db)
print(f'<<< __net_matrix_plugin >>> [ new database entry ] > [{mc.room_id}]')
#######################################################################################
async def main(self,) -> None:
self.client.add_event_callback(self.message_callback,RoomMessageText)
await self.client.login(MATRIX___PASSWORD)
guds.timestamp_alarm('matrix_boot',3)
joined_rooms=(await self.client.joined_rooms())
for _room in joined_rooms.rooms:
result=dims.ismatrixroom(_room)
if not result:
msg=f'<<< __net_matrix_plugin >>> [ event: join ] - user_id: {self.client.user_id} - target: {_room}'
print(msg)
dims.__create__('matrix',_room)
print(f"<<< ___tool_dims_plugin >>> [ event: join ] - dims.__create__(matrix,{_room}) - active room record created")
self.push(_room)
###################################################################################
print(f'<<< __net_matrix_plugin >>> [ await client.sync_forever(timeout=5000) ]')
await self.client.sync_forever(timeout=5000) # milliseconds
####################################################################################### EOF#.[d].

@ -1,119 +1,121 @@
# -*- coding: utf-8 -*- ############################################################### SOF
###########################################################################################
import asyncio
import configparser
import logging
import os
import random
import re
from functools import wraps
###########################################################################################
import irc3
import telegram
from irc3.plugins.command import command
from telegram import ChatAction, ParseMode
from telegram.ext import (ChatJoinRequestHandler, CommandHandler, Filters,
MessageHandler, Updater)
###########################################################################################
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
###########################################################################################
from plugins.tool_colors_plugin import colorform as print
###########################################################################################
try:
TELEGRAM_TOKEN=os.environ['TELEGRAM_TOKEN']
except:
pass
###########################################################################################
def start_telegrambot(self):
print(f'<<< net_telegram_plugin >>> [ telegrambot started ]')
self.telegrambot=TELEGRAMBOT()
globals()['guds'].memories.append([self.telegrambot,'net_telegram_plugin:start_telegrambot.self'])
self.telegrambot.main()
return self
###########################################################################################
class TELEGRAMBOT:
#######################################################################################
def __init__(self):
self.ircbot=guds.memory('ircbot')
self.dbname="telegramchat"
self.db=self.ircbot.db.getlist(self.dbname)
if not self.db: self.db=[]
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger=logging.getLogger(__name__)
#######################################################################################
def start(self,update,context):
update.message.reply_text('Hi!')
#######################################################################################
def help(self,update,context):
update.message.reply_text('Help!')
#######################################################################################
async def _t_bnc_msg(self,netsrc,usernick,netdest,data,):
bridgedbus=(BUS(netdest))
await bridgedbus.input(f"${netsrc}",usernick,data,True)
???TELEGRAM???
if SERVICES_TELEGRAM:
import asyncio
import configparser
import logging
import os
import random
import re
from functools import wraps
###########################################################################################
def t_bnc_msg(self,netsrc,usernick,netdest,data,):
import irc3
import telegram
from irc3.plugins.command import command
from telegram import ChatAction, ParseMode
from telegram.ext import (ChatJoinRequestHandler, CommandHandler, Filters,
MessageHandler, Updater)
###########################################################################################
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
###########################################################################################
from plugins.tool_colors_plugin import colorform as print
###########################################################################################
try:
TELEGRAM_TOKEN=os.environ['TELEGRAM_TOKEN']
except:
pass
###########################################################################################
def start_telegrambot(self):
print(f'<<< net_telegram_plugin >>> [ telegrambot started ]')
self.telegrambot=TELEGRAMBOT()
globals()['guds'].memories.append([self.telegrambot,'net_telegram_plugin:start_telegrambot.self'])
self.telegrambot.main()
return self
###########################################################################################
class TELEGRAMBOT:
#######################################################################################
def __init__(self):
self.ircbot=guds.memory('ircbot')
self.dbname="telegramchat"
self.db=self.ircbot.db.getlist(self.dbname)
if not self.db: self.db=[]
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger=logging.getLogger(__name__)
#######################################################################################
def start(self,update,context):
update.message.reply_text('Hi!')
#######################################################################################
def help(self,update,context):
update.message.reply_text('Help!')
#######################################################################################
async def _t_bnc_msg(self,netsrc,usernick,netdest,data,):
bridgedbus=(BUS(netdest))
await bridgedbus.input(f"${netsrc}",usernick,data,True)
###########################################################################################
def t_bnc_msg(self,netsrc,usernick,netdest,data,):
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(self._t_bnc_msg(netsrc,usernick,netdest,data),ircbot.loop)
#######################################################################################
def push(self,chat_id):
class telegramchat:
def __init__(self,id,type,title):
self.id=id
self.title=title
self.type=type
context=self.api.getChat(chat_id)
tgc=telegramchat(context.id,context.type,context.title)
FLAG_FOUND=False
for entry in self.db:
if entry[0]==tgc.id:
FLAG_FOUND=True
break
if not FLAG_FOUND:
self.db.append([tgc.id,f"${tgc.title}",tgc.type])
self.ircbot.db.setlist(self.dbname,self.db)
print(f'<<< net_telegram_plugin >>> [ new database entry ] > [{tgc.id},${tgc.title},{tgc.type}]')
#######################################################################################
def echo(self,update,context):
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
group_title=f"${self.api.get_chat(context._chat_id_and_data[0]).title}"
result=dims.istelegramgroup(group_title)
TARGET="$b0tsh0p"
USER=update.message.from_user.username
if not result:
dims.__create__('telegram',group_title)
print(f"<<< net_telegram_plugin >>> [ event: new group ] - dims.__create__(telegram,{group_title}) - active group record created")
self.push(context._chat_id_and_data[0])
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(self.ircbot.indirect_maple([USER,"$b0tsh0p","#tcpdirect"],update.message.text),self.ircbot.loop)
msg=update.message.text
netschanlist=dims.list_channels_bridged(netsrc=TARGET)
netschanlist.append(TARGET)
bridgedbus=(BUS(netschanlist))
asyncio.run_coroutine_threadsafe(bridgedbus.input(TARGET,USER,msg,True),self.ircbot.loop)
#######################################################################################
def error(self,update,context):
self.logger.warning('Update "%s" caused error "%s"',update,context.error)
#######################################################################################
def main(self):
self.updater=Updater(TELEGRAM_TOKEN,use_context=True)
self.api=self.updater.bot
self.dp=self.updater.dispatcher
self.dp.add_handler(CommandHandler("start",self.start))
self.dp.add_handler(CommandHandler("help",help))
self.dp.add_handler(MessageHandler(Filters.text,self.echo))
self.dp.add_error_handler(self.error)
self.updater.start_polling()
###########################################################################################
def d_telegram_msg(target,msg):
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(self._t_bnc_msg(netsrc,usernick,netdest,data),ircbot.loop)
#######################################################################################
def push(self,chat_id):
class telegramchat:
def __init__(self,id,type,title):
self.id=id
self.title=title
self.type=type
context=self.api.getChat(chat_id)
tgc=telegramchat(context.id,context.type,context.title)
FLAG_FOUND=False
for entry in self.db:
if entry[0]==tgc.id:
FLAG_FOUND=True
break
if not FLAG_FOUND:
self.db.append([tgc.id,f"${tgc.title}",tgc.type])
self.ircbot.db.setlist(self.dbname,self.db)
print(f'<<< net_telegram_plugin >>> [ new database entry ] > [{tgc.id},${tgc.title},{tgc.type}]')
#######################################################################################
def echo(self,update,context):
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
group_title=f"${self.api.get_chat(context._chat_id_and_data[0]).title}"
result=dims.istelegramgroup(group_title)
TARGET="$b0tsh0p"
USER=update.message.from_user.username
if not result:
dims.__create__('telegram',group_title)
print(f"<<< net_telegram_plugin >>> [ event: new group ] - dims.__create__(telegram,{group_title}) - active group record created")
self.push(context._chat_id_and_data[0])
ircbot=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(self.ircbot.indirect_maple([USER,"$b0tsh0p","#tcpdirect"],update.message.text),self.ircbot.loop)
msg=update.message.text
netschanlist=dims.list_channels_bridged(netsrc=TARGET)
netschanlist.append(TARGET)
bridgedbus=(BUS(netschanlist))
asyncio.run_coroutine_threadsafe(bridgedbus.input(TARGET,USER,msg,True),self.ircbot.loop)
#######################################################################################
def error(self,update,context):
self.logger.warning('Update "%s" caused error "%s"',update,context.error)
#######################################################################################
def main(self):
self.updater=Updater(TELEGRAM_TOKEN,use_context=True)
self.api=self.updater.bot
self.dp=self.updater.dispatcher
self.dp.add_handler(CommandHandler("start",self.start))
self.dp.add_handler(CommandHandler("help",help))
self.dp.add_handler(MessageHandler(Filters.text,self.echo))
self.dp.add_error_handler(self.error)
self.updater.start_polling()
###########################################################################################
def d_telegram_msg(target,msg):
ircbot=guds.memory('ircbot')
telegram_groups=ircbot.db.getlist('telegramchat')
for _group in telegram_groups:
if target==_group[1]:
group=_group[0]
telegrambot=guds.memory('telegrambot')
telegrambot.api.send_message(group,msg)
####################################################################################### EOF#.[d].
telegram_groups=ircbot.db.getlist('telegramchat')
for _group in telegram_groups:
if target==_group[1]:
group=_group[0]
telegrambot=guds.memory('telegrambot')
telegrambot.api.send_message(group,msg)
####################################################################################### EOF#.[d].

@ -15,10 +15,13 @@ from lxml.html import fromstring
from difflib import SequenceMatcher
###########################################################################################
###########################################################################################
TWITTER_CONSUMER_KEY = os.environ['TWITTER_CONSUMER_KEY']
TWITTER_CONSUMER_SECRET = os.environ['TWITTER_CONSUMER_SECRET']
TWITTER_ACCESS_TOKEN_KEY = os.environ['TWITTER_ACCESS_TOKEN_KEY']
TWITTER_ACCESS_TOKEN_SECRET = os.environ['TWITTER_ACCESS_TOKEN_SECRET']
try:
TWITTER_CONSUMER_KEY = os.environ['TWITTER_CONSUMER_KEY']
TWITTER_CONSUMER_SECRET = os.environ['TWITTER_CONSUMER_SECRET']
TWITTER_ACCESS_TOKEN_KEY = os.environ['TWITTER_ACCESS_TOKEN_KEY']
TWITTER_ACCESS_TOKEN_SECRET = os.environ['TWITTER_ACCESS_TOKEN_SECRET']
except:
pass
TOO_LONG = 2000
###########################################################################################
###########################################################################################
@ -26,10 +29,13 @@ if SERVICES_YOUTUBE:
YOUTUBE_REGEX = re.compile('http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?[\w\?=]*)?', re.IGNORECASE)
###########################################################################################
###########################################################################################
TWITTER_REGEX = re.compile('https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(es)?\/(\d+)$', re.IGNORECASE)
URL_REGEX = re.compile('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', re.IGNORECASE)
twitter = twitter.Api(consumer_key=TWITTER_CONSUMER_KEY, consumer_secret=TWITTER_CONSUMER_SECRET,
access_token_key=TWITTER_ACCESS_TOKEN_KEY, access_token_secret=TWITTER_ACCESS_TOKEN_SECRET)
try:
TWITTER_REGEX = re.compile('https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(es)?\/(\d+)$', re.IGNORECASE)
URL_REGEX = re.compile('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', re.IGNORECASE)
twitter = twitter.Api(consumer_key=TWITTER_CONSUMER_KEY, consumer_secret=TWITTER_CONSUMER_SECRET,
access_token_key=TWITTER_ACCESS_TOKEN_KEY, access_token_secret=TWITTER_ACCESS_TOKEN_SECRET)
except:
pass
###########################################################################################
###########################################################################################
@irc3.plugin

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- ############################################################### SOF
???YOUTUBE???
from irc3.plugins.command import command
import irc3
import os
@ -10,13 +11,14 @@ import isodate
from apiclient.discovery import build
dir_path = os.path.dirname(os.path.realpath(__file__))
try:
YOUTUBE_DEVELOPER_KEY = os.environ['YOUTUBE_DEVELOPER_KEY']
if SERVICES_YOUTUBE:
YOUTUBE_DEVELOPER_KEY = os.environ['YOUTUBE_DEVELOPER_KEY']
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
YOUTUBE_REGEX = re.compile('http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?[\w\?=]*)?', re.IGNORECASE)
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=YOUTUBE_DEVELOPER_KEY)
except:
pass
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
YOUTUBE_REGEX = re.compile('http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?[\w\?=]*)?', re.IGNORECASE)
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=YOUTUBE_DEVELOPER_KEY)
###########################################################################################
###########################################################################################
@irc3.plugin
@ -30,36 +32,107 @@ class Plugin:
#######################################################################################
@irc3.extend
def youtube_search(self, q=None, eventType=None, max_results=1, order="relevance", channelId=None, token=None, location=None, location_radius=None):
search_response = youtube.search().list(
q=q,
channelId=channelId,
type="video",
pageToken=token,
order=order,
eventType=eventType,
part="id,snippet",
maxResults=max_results,
location=location,
locationRadius=location_radius
).execute()
for search_result in search_response.get("items", []):
if search_result["id"]["kind"] == "youtube#video":
return(search_result)
if SERVICES_YOUTUBE:
search_response = youtube.search().list(
q=q,
channelId=channelId,
type="video",
pageToken=token,
order=order,
eventType=eventType,
part="id,snippet",
maxResults=max_results,
location=location,
locationRadius=location_radius
).execute()
for search_result in search_response.get("items", []):
if search_result["id"]["kind"] == "youtube#video":
return(search_result)
#######################################################################################
#######################################################################################
@irc3.event(irc3.rfc.PRIVMSG)
def on_privmsg_search_for_youtube(self, mask=None, target=None, data=None, **kw):
if data.startswith("?"): return
if self.bot.check_if_ignored(mask): return
self.__check_for_youtube(mask, data, target)
if SERVICES_YOUTUBE:
if data.startswith("?"): return
if self.bot.check_if_ignored(mask): return
self.__check_for_youtube(mask, data, target)
#######################################################################################
#######################################################################################
def __check_for_youtube(self, mask, msg, target):
match_list = YOUTUBE_REGEX.findall(msg)
if match_list:
video_id = match_list.pop()
if int(len(video_id)) == 3:
video_id = video_id[0]
if SERVICES_YOUTUBE:
match_list = YOUTUBE_REGEX.findall(msg)
if match_list:
video_id = match_list.pop()
if int(len(video_id)) == 3:
video_id = video_id[0]
video_info = self.videos_list_by_id(id=video_id)
title = video_info.get("snippet",{}).get("title")
published_at = video_info.get("snippet",{}).get("publishedAt")
like_count=0
try:
view_count = int(video_info.get("statistics").get("viewCount"))
except:
like_count = int(video_info.get("statistics").get("likeCount"))
if published_at:
published_at = dateutil.parser.parse(published_at)
published_at = timeago.format(published_at.replace(tzinfo=None), datetime.datetime.now())
try:
topics = video_info.get("topicDetails",{}).get("topicCategories")
topics[:] = [i.replace("https://en.wikipedia.org/wiki/", "").replace("_"," ").title() for i in topics]
except:
topics = []
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 1 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 1 of 2 ########
MUSIC_FOUND=False
for topic in topics:
if topic.lower().find('music'):
MUSIC_FOUND=True
if MUSIC_FOUND:
url = "https://youtu.be/{}".format(video_id)
self.bot.bbs.enter(mask.nick,url,title)
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 1 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 1 of 2 ########
duration = isodate.parse_duration(video_info.get("contentDetails").get("duration"))
msg = "\x02\x0302{nick:}\x0F\x02\x0304 >> \x02\x0303\x1D\x1F{title:}\x0F".format(nick=mask.nick, title=title)
msg = msg + "\x02\x1D\x0304 > \x0F\x1D\x0314Duration: \x0F\x1D{duration:} \x0F".format(duration=duration)
if like_count == 0:
msg = msg + "\x0F\x1D\x0314Published: \x0F\x1D{published:} \x0F\x1D\x0314Views: \x0F\x1D{views:,} \x0F\x1D\x0314Type: \x0F\x1DVideo\x0F".format(published=published_at, views=view_count)
else:
msg = msg + "\x0F\x1D\x0314Published: \x0F\x1D{published:} \x0F\x1D\x0314Likes: \x0F\x1D{views:,} \x0F\x1D\x0314Type: \x0F\x1DMovie\x0F".format(published=published_at, views=like_count)
msg = msg + "\x0F\x02\x0312 ♫ \x0F\x02\x0313\x1D{topics:}\x0F\x02\x0312".format(topics=", ".join(topics))
msg = msg +" \x0304> \x0F\x02\x0312"+ url
msg = self.bot.emo(msg)
self.bot.privmsg(target,msg)
#######################################################################################
#######################################################################################
@irc3.extend
def videos_list_by_id(self, id):
if SERVICES_YOUTUBE:
search_response = youtube.videos().list(part="id,snippet,statistics,topicDetails,contentDetails", id=id).execute()
for search_result in search_response.get("items", []):
if search_result["kind"] == "youtube#video":
return(search_result)
#######################################################################################
#######################################################################################
@command(permission='view', public=True, show_in_help_list=False)
def y(self, *args, **kwargs):
"""Search for youtube video
%%y <keyword>...
"""
if SERVICES_YOUTUBE:
return self.yt(*args)
#######################################################################################
#######################################################################################
@irc3.extend
@command(permission='view')
def yt(self, mask, target, args):
"""Search for youtube video
%%yt <keyword>...
"""
if SERVICES_YOUTUBE:
keyword = ' '.join(args['<keyword>'])
video = self.youtube_search(q=keyword)
if video:
video_id = video.get("id",{}).get("videoId")
video = video.get("snippet")
video_info = self.videos_list_by_id(id=video_id)
title = video_info.get("snippet",{}).get("title")
published_at = video_info.get("snippet",{}).get("publishedAt")
@ -76,7 +149,8 @@ class Plugin:
topics[:] = [i.replace("https://en.wikipedia.org/wiki/", "").replace("_"," ").title() for i in topics]
except:
topics = []
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 1 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 1 of 2 ########
duration = isodate.parse_duration(video_info.get("contentDetails").get("duration"))
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ########
MUSIC_FOUND=False
for topic in topics:
if topic.lower().find('music'):
@ -84,91 +158,25 @@ class Plugin:
if MUSIC_FOUND:
url = "https://youtu.be/{}".format(video_id)
self.bot.bbs.enter(mask.nick,url,title)
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 1 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 1 of 2 ########
duration = isodate.parse_duration(video_info.get("contentDetails").get("duration"))
msg = "\x02\x0302{nick:}\x0F\x02\x0304 >> \x02\x0303\x1D\x1F{title:}\x0F".format(nick=mask.nick, title=title)
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ########
_nick = ""
try:
if len(self.bot.madjust) > 0:
_nick = self.bot.madjust
else:
_nick = mask.nick
except:
_nick = mask.nick
msg = "\x02\x0302{nick:}\x0F\x02\x0304 >> \x02\x0303\x1D\x1F{title:}\x0F".format(nick=_nick, title=title)
msg = msg + "\x02\x1D\x0304 > \x0F\x1D\x0314Duration: \x0F\x1D{duration:} \x0F".format(duration=duration)
if like_count == 0:
msg = msg + "\x0F\x1D\x0314Published: \x0F\x1D{published:} \x0F\x1D\x0314Views: \x0F\x1D{views:,} \x0F\x1D\x0314Type: \x0F\x1DVideo\x0F".format(published=published_at, views=view_count)
else:
msg = msg + "\x0F\x1D\x0314Published: \x0F\x1D{published:} \x0F\x1D\x0314Likes: \x0F\x1D{views:,} \x0F\x1D\x0314Type: \x0F\x1DMovie\x0F".format(published=published_at, views=like_count)
msg = msg + "\x0F\x02\x0312 ♫ \x0F\x02\x0313\x1D{topics:}\x0F\x02\x0312".format(topics=", ".join(topics))
msg = msg +" \x0304> \x0F\x02\x0312"+ url
msg = msg + "\x0F\x02\x0312 ♫ \x0F\x02\x0313\x1D{topics:}\x0F\x02\x0312 ".format(topics=", ".join(topics))
msg = msg + url
msg = self.bot.emo(msg)
self.bot.privmsg(target,msg)
#######################################################################################
#######################################################################################
@irc3.extend
def videos_list_by_id(self, id):
search_response = youtube.videos().list(part="id,snippet,statistics,topicDetails,contentDetails", id=id).execute()
for search_result in search_response.get("items", []):
if search_result["kind"] == "youtube#video":
return(search_result)
#######################################################################################
#######################################################################################
@command(permission='view', public=True, show_in_help_list=False)
def y(self, *args, **kwargs):
"""Search for youtube video
%%y <keyword>...
"""
return self.yt(*args)
#######################################################################################
#######################################################################################
@irc3.extend
@command(permission='view')
def yt(self, mask, target, args):
"""Search for youtube video
%%yt <keyword>...
"""
keyword = ' '.join(args['<keyword>'])
video = self.youtube_search(q=keyword)
if video:
video_id = video.get("id",{}).get("videoId")
video = video.get("snippet")
video_info = self.videos_list_by_id(id=video_id)
title = video_info.get("snippet",{}).get("title")
published_at = video_info.get("snippet",{}).get("publishedAt")
like_count=0
try:
view_count = int(video_info.get("statistics").get("viewCount"))
except:
like_count = int(video_info.get("statistics").get("likeCount"))
if published_at:
published_at = dateutil.parser.parse(published_at)
published_at = timeago.format(published_at.replace(tzinfo=None), datetime.datetime.now())
try:
topics = video_info.get("topicDetails",{}).get("topicCategories")
topics[:] = [i.replace("https://en.wikipedia.org/wiki/", "").replace("_"," ").title() for i in topics]
except:
topics = []
duration = isodate.parse_duration(video_info.get("contentDetails").get("duration"))
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ########
MUSIC_FOUND=False
for topic in topics:
if topic.lower().find('music'):
MUSIC_FOUND=True
if MUSIC_FOUND:
url = "https://youtu.be/{}".format(video_id)
self.bot.bbs.enter(mask.nick,url,title)
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ########
_nick = ""
try:
if len(self.bot.madjust) > 0:
_nick = self.bot.madjust
else:
_nick = mask.nick
except:
_nick = mask.nick
msg = "\x02\x0302{nick:}\x0F\x02\x0304 >> \x02\x0303\x1D\x1F{title:}\x0F".format(nick=_nick, title=title)
msg = msg + "\x02\x1D\x0304 > \x0F\x1D\x0314Duration: \x0F\x1D{duration:} \x0F".format(duration=duration)
if like_count == 0:
msg = msg + "\x0F\x1D\x0314Published: \x0F\x1D{published:} \x0F\x1D\x0314Views: \x0F\x1D{views:,} \x0F\x1D\x0314Type: \x0F\x1DVideo\x0F".format(published=published_at, views=view_count)
else:
msg = msg + "\x0F\x1D\x0314Published: \x0F\x1D{published:} \x0F\x1D\x0314Likes: \x0F\x1D{views:,} \x0F\x1D\x0314Type: \x0F\x1DMovie\x0F".format(published=published_at, views=like_count)
msg = msg + "\x0F\x02\x0312 ♫ \x0F\x02\x0313\x1D{topics:}\x0F\x02\x0312 ".format(topics=", ".join(topics))
msg = msg + url
msg = self.bot.emo(msg)
self.bot.privmsg(target, msg)
self.bot.privmsg(target, msg)
#######################################################################################
#######################################################################################
####################################################################################### EOF