work in progress
This commit is contained in:
commit
ac5a09bd88
|
@ -0,0 +1,52 @@
|
|||
# MAPLE+G1MP ML/Irc3 Hybrid VARIANTED INTO NETSPANNING
|
||||
```
|
||||
[ Netspanning ]
|
||||
- irc
|
||||
- matrix
|
||||
[ The hybridization ]
|
||||
- m4plmp - [sourcecode](https://git.tcp.direct/decoded/m4pl1mp)
|
||||
[ Hybrid of machine learning and irc3 framework ]
|
||||
- Maple - [sourcecode](https://git.tcp.direct/decoded/Maple)
|
||||
- g1mp - [sourcecode](https://git.tcp.direct/decoded/g1mp)
|
||||
```
|
||||
## Prerequisites
|
||||
|
||||
1. `apt install python3`
|
||||
2. `apt install python3-pip`
|
||||
3. `python3 -m pip install virtualenv`
|
||||
|
||||
## Instructions
|
||||
|
||||
1. `git clone --recursive https://git.tcp.direct/decoded/maple_netspan.git`
|
||||
2. `cd maple_netspan`
|
||||
3. `virtualenv env -p python3`
|
||||
4. `source env/bin/activate`
|
||||
### Append your developer api keys to env/bin/activate. Example below:
|
||||
```
|
||||
cat env/bin/activate
|
||||
..
|
||||
export BOT_SASL_USERNAME=your_nickserv_username
|
||||
export BOT_SASL_PASSWORD=your_nickserv_password
|
||||
export NICKSERV_USERNAME=your_nickserv_username
|
||||
export NICKSERV_PASSWORD=your_nickserv_password
|
||||
export MATRIX_HOMESERVER=https://matrix.org
|
||||
export MATRIX___USERNAME=your_matrix_username
|
||||
export MATRIX___PASSWORD=your_matrix_password
|
||||
export DEVELOPER_KEY="1394823190182390182382383215382158321" # <- YOUTUBE API KEY
|
||||
export CONSUMER_KEY="2151235132512351235123512351325231" # <- TWITTER API KEY
|
||||
export CONSUMER_SECRET="514512521345234523452345234523452345234523452" # <- TWITTER API KEY
|
||||
export ACCESS_TOKEN_KEY="24513429875209348502934850294898348034850293485203948592" # <- TWITTER API KEY
|
||||
export ACCESS_TOKEN_SECRET="523490582034985203948520394804884820934850923485" # <- TWITTER API KEY
|
||||
```
|
||||
5. `pip install -r requirements.txt`
|
||||
6. `edit maple.py - add your matrix username here so that it self-ignores`
|
||||
```
|
||||
guds.add_credentials("@maple.or.g1mp:matrix.org")
|
||||
guds.add_credentials("@maple:pcriot.org")
|
||||
```
|
||||
7. `edit plugins/net_matrix_plugin.py - change this username to your to access commands`
|
||||
```
|
||||
if m_sender=="@d:tcp.direct":
|
||||
```
|
||||
8. `python3 maple.py`
|
||||
|
|
@ -0,0 +1,426 @@
|
|||
¢‿¢
|
||||
©¿© o
|
||||
ª{•̃̾_•̃̾}ª
|
||||
¬_¬
|
||||
¯\(º_o)/¯
|
||||
¯\(º o)/¯
|
||||
¯\_(⊙︿⊙)_/¯
|
||||
¯\_(ツ)_/¯
|
||||
°ω°
|
||||
°Д°
|
||||
°‿‿°
|
||||
°ﺑ°
|
||||
´ ▽ ` )ノ
|
||||
¿ⓧ_ⓧﮌ
|
||||
Ò,ó
|
||||
ó‿ó
|
||||
ô⌐ô
|
||||
ôヮô
|
||||
ŎםŎ
|
||||
ŏﺡó
|
||||
ʕ•̫͡•ʔ
|
||||
ʕ•ᴥ•ʔ
|
||||
ʘ‿ʘ
|
||||
˚•_•˚
|
||||
˚⌇˚
|
||||
˚▱˚
|
||||
̿ ̿̿'̿'\̵͇̿̿\=(•̪●)=/̵͇̿̿/'̿̿ ̿ ̿ ̿
|
||||
͡° ͜ʖ ͡°
|
||||
Σ ◕ ◡ ◕
|
||||
Σ (゚Д゚;)
|
||||
Σ(゚Д゚;≡;゚д゚)
|
||||
Σ(゚Д゚ )
|
||||
Σ(||゚Д゚)
|
||||
Φ,Φ
|
||||
δﺡό
|
||||
σ_σ
|
||||
д_д
|
||||
ф_ф
|
||||
щ(゚Д゚щ)
|
||||
щ(ಠ益ಠщ)
|
||||
щ(ಥДಥщ)
|
||||
Ծ_Ծ
|
||||
أ‿أ
|
||||
ب_ب
|
||||
ح˚௰˚づ
|
||||
ح˚ᆺ˚ว
|
||||
حᇂﮌᇂ)
|
||||
٩๏̯͡๏۶
|
||||
٩๏̯͡๏)۶
|
||||
٩◔̯◔۶
|
||||
٩(×̯×)۶
|
||||
٩(̾●̮̮̃̾•̃̾)۶
|
||||
٩(͡๏̯͡๏)۶
|
||||
٩(͡๏̯ ͡๏)۶
|
||||
٩(ಥ_ಥ)۶
|
||||
٩(•̮̮̃•̃)۶
|
||||
٩(●̮̮̃•̃)۶
|
||||
٩(●̮̮̃●̃)۶
|
||||
٩(。͡•‿•。)۶
|
||||
٩(-̮̮̃•̃)۶
|
||||
٩(-̮̮̃-̃)۶
|
||||
۞_۞
|
||||
۞_۟۞
|
||||
۹ↁﮌↁ
|
||||
۹⌤_⌤۹
|
||||
॓_॔
|
||||
१✌◡✌५
|
||||
१|˚–˚|५
|
||||
ਉ_ਉ
|
||||
ଘ_ଘ
|
||||
இ_இ
|
||||
ఠ_ఠ
|
||||
రృర
|
||||
ಠ¿ಠi
|
||||
ಠ‿ಠ
|
||||
ಠ⌣ಠ
|
||||
ಠ╭╮ಠ
|
||||
ಠ▃ಠ
|
||||
ಠ◡ಠ
|
||||
ಠ益ಠ
|
||||
ಠ益ಠ
|
||||
ಠ︵ಠ凸
|
||||
ಠ , ಥ
|
||||
ಠ.ಠ
|
||||
ಠoಠ
|
||||
ಠ_ృ
|
||||
ಠ_ಠ
|
||||
ಠ_๏
|
||||
ಠ~ಠ
|
||||
ಡ_ಡ
|
||||
ತಎತ
|
||||
ತ_ತ
|
||||
ಥдಥ
|
||||
ಥ‿ಥ
|
||||
ಥ⌣ಥ
|
||||
ಥ◡ಥ
|
||||
ಥ﹏ಥ
|
||||
ಥ_ಥ
|
||||
ಭ_ಭ
|
||||
ರ_ರ
|
||||
ಸ , ໖
|
||||
ಸ_ಸ
|
||||
ക_ക
|
||||
อ้_อ้
|
||||
อ_อ
|
||||
โ๏௰๏ใ ื
|
||||
๏̯͡๏﴿
|
||||
๏̯͡๏
|
||||
๏̯͡๏﴿
|
||||
๏[-ิิ_•ิ]๏
|
||||
๏_๏
|
||||
໖_໖
|
||||
ლ(´ڡ`ლ)
|
||||
ლ(́◉◞౪◟◉‵ლ)
|
||||
ლ(ಠ益ಠლ)
|
||||
ლ(╹◡╹ლ)
|
||||
ლ(◉◞౪◟◉‵ლ)
|
||||
ლ,ᔑ•ﺪ͟͠•ᔐ.ლ
|
||||
ᄽὁȍ ̪ őὀᄿ
|
||||
ᕕ( ᐛ )ᕗ
|
||||
ᕙ(⇀‸↼‶)ᕗ
|
||||
ᕦ(ò_óˇ)ᕤ
|
||||
ᶘ ᵒᴥᵒᶅ
|
||||
‘︿’
|
||||
•▱•
|
||||
•✞_✞•
|
||||
•ﺑ•
|
||||
•(⌚_⌚)•
|
||||
•_•)
|
||||
‷̗ↂ凸ↂ‴̖
|
||||
‹•.•›
|
||||
‹› ‹(•¿•)› ‹›
|
||||
‹(ᵒᴥᵒ)›
|
||||
‹(•¿•)›
|
||||
ↁ_ↁ
|
||||
⇎_⇎
|
||||
∩(︶▽︶)∩
|
||||
∩( ・ω・)∩
|
||||
≖‿≖
|
||||
≧ヮ≦
|
||||
⊂•⊃_⊂•⊃
|
||||
⊂⌒~⊃。Д。)⊃
|
||||
⊂(◉‿◉)つ
|
||||
⊂(゚Д゚,,⊂⌒`つ
|
||||
⊙ω⊙
|
||||
⊙▂⊙
|
||||
⊙▃⊙
|
||||
⊙△⊙
|
||||
⊙︿⊙
|
||||
⊙﹏⊙
|
||||
⊙0⊙
|
||||
⊛ठ̯⊛
|
||||
⋋ō_ō`
|
||||
━━━ヽ(ヽ(゚ヽ(゚ヽ(゚゚ヽ(゚゚)ノ゚゚)ノ゚)ノ゚)ノ)ノ━━━
|
||||
┌∩┐(◕_◕)┌∩┐
|
||||
┌( ಠ_ಠ)┘
|
||||
┌( ಥ_ಥ)┘
|
||||
╚(•⌂•)╝
|
||||
╭╮╭╮☜{•̃̾_•̃̾}☞╭╮╭╮
|
||||
╭✬⌢✬╮
|
||||
╮(▽)╭
|
||||
╯‵Д′)╯彡┻━┻
|
||||
╰☆╮
|
||||
□_□
|
||||
►_◄
|
||||
◃┆◉◡◉┆▷
|
||||
◉△◉
|
||||
◉︵◉
|
||||
◉_◉
|
||||
○_○
|
||||
●¿●\ ~
|
||||
●_●
|
||||
◔̯◔
|
||||
◔ᴗ◔
|
||||
◔ ⌣ ◔
|
||||
◔_◔
|
||||
◕ω◕
|
||||
◕‿◕
|
||||
◕◡◕
|
||||
◕ ◡ ◕
|
||||
◖♪_♪|◗
|
||||
◖|◔◡◉|◗
|
||||
◘_◘
|
||||
◙‿◙
|
||||
◜㍕◝
|
||||
◪_◪
|
||||
◮_◮
|
||||
☁ ☝ˆ~ˆ☂
|
||||
☆¸☆
|
||||
☉‿⊙
|
||||
☉_☉
|
||||
☐_☐
|
||||
☜ق❂Ⴢ❂ق☞
|
||||
☜(⌒▽⌒)☞
|
||||
☜(゚ヮ゚☜)
|
||||
☜-(ΘLΘ)-☞
|
||||
☝☞✌
|
||||
☮▁▂▃▄☾ ♛ ◡ ♛ ☽▄▃▂▁☮
|
||||
☹_☹
|
||||
☻_☻
|
||||
☼.☼
|
||||
☾˙❀‿❀˙☽
|
||||
♀ح♀ヾ
|
||||
♥‿♥
|
||||
♥╣[-_-]╠♥
|
||||
♥╭╮♥
|
||||
♥◡♥
|
||||
✌♫♪˙❤‿❤˙♫♪✌
|
||||
✌.ʕʘ‿ʘʔ.✌
|
||||
✌.|•͡˘‿•͡˘|.✌
|
||||
✖‿✖
|
||||
✖_✖
|
||||
❐‿❑
|
||||
_
|
||||
_Ꙩ
|
||||
⨂_⨂
|
||||
〆(・・@)
|
||||
《〠_〠》
|
||||
【•】_【•】
|
||||
〠_〠
|
||||
〴⋋_⋌〵
|
||||
の<EFBFBD> <20>の
|
||||
ニガー? ━━━━━━(゚゚)━━━━━━ ニガー?
|
||||
ペ㍕˚\
|
||||
ヽ(´ー` )ノ
|
||||
ヽ(๏๏ )ノ
|
||||
ヽ(`Д´)ノ
|
||||
ヽ(o`皿′o)ノ
|
||||
ヽ(`Д´)ノ
|
||||
ㅎ_ㅎ
|
||||
乂◜◬◝乂
|
||||
凸ಠ益ಠ)凸
|
||||
句_句
|
||||
Ꙩ⌵Ꙩ
|
||||
Ꙩ_Ꙩ
|
||||
ꙩ_ꙩ
|
||||
Ꙫ_Ꙫ
|
||||
ꙫ_ꙫ
|
||||
ꙮ_ꙮ
|
||||
흫_흫
|
||||
句_句
|
||||
﴾͡๏̯͡๏﴿ O'RLY?
|
||||
¯\(ºдಠ)/¯
|
||||
(·×·)
|
||||
(⌒Д⌒)
|
||||
(╹ェ╹)
|
||||
(♯・・)⊃
|
||||
( ´`)☆
|
||||
( ´`)
|
||||
(゜Д゜)
|
||||
(・・)
|
||||
(・A・)
|
||||
(゚゚)
|
||||
( ̄へ ̄)
|
||||
( ´☣///_ゝ///☣`)
|
||||
( つ Д `)
|
||||
_☆( ´_⊃`)☆_
|
||||
。◕‿‿◕。
|
||||
。◕ ‿ ◕。
|
||||
!⑈ˆ~ˆ!⑈
|
||||
!(`・ω・。)
|
||||
(¬‿¬)
|
||||
(¬▂¬)
|
||||
(¬_¬)
|
||||
(°ℇ °)
|
||||
(°°)
|
||||
(´ω`)
|
||||
(´◉◞౪◟◉)
|
||||
(´ヘ`;)
|
||||
(´・ω・`)
|
||||
(´ー`)
|
||||
(ʘ‿ʘ)
|
||||
(ʘ_ʘ)
|
||||
(˚இ˚)
|
||||
(͡๏̯͡๏)
|
||||
(ΘεΘ;)
|
||||
(ι´Д`)ノ
|
||||
(Ծ‸ Ծ)
|
||||
(॓_॔)
|
||||
(० ्०)
|
||||
(ு८ு_ .:)
|
||||
(ಠ‾ಠ)
|
||||
(ಠ‿ʘ)
|
||||
(ಠ‿ಠ)
|
||||
(ಠ⌣ಠ)
|
||||
(ಠ益ಠ ╬)
|
||||
(ಠ益ಠ)
|
||||
(ಠ_ృ)
|
||||
(ಠ_ಠ)
|
||||
(ಥ﹏ಥ)
|
||||
(ಥ_ಥ)
|
||||
(๏̯͡๏ )
|
||||
(ღ˘⌣˘ღ) ♫・*:.。. .。.:*・
|
||||
(ღ˘⌣˘ღ)
|
||||
(ᵔᴥᵔ)
|
||||
(•ω•)
|
||||
(•‿•)
|
||||
(•⊙ω⊙•)
|
||||
(• ε •)
|
||||
(∩▂∩)
|
||||
(∩︵∩)
|
||||
(∪ ◡ ∪)
|
||||
(≧ω≦)
|
||||
(≧◡≦)
|
||||
(≧ロ≦)
|
||||
(⊙ヮ⊙)
|
||||
(⊙_◎)
|
||||
(⋋▂⋌)
|
||||
(⌐■_■)
|
||||
(‿‿)
|
||||
(┛◉Д◉)┛┻━┻
|
||||
(╥_╥)
|
||||
(╬ಠ益ಠ)
|
||||
(╬◣д◢)
|
||||
(╬ ಠ益ಠ)
|
||||
(╯°□°)╯︵ ┻━┻
|
||||
(╯ಊ╰)
|
||||
(╯◕_◕)╯
|
||||
(╯︵╰,)
|
||||
(╯3╰)
|
||||
(╯_╰)
|
||||
(╹◡╹)凸
|
||||
(▰˘◡˘▰)
|
||||
(●´ω`●)
|
||||
(●´`●)
|
||||
(◑‿◐)
|
||||
(◑◡◑)
|
||||
(◕‿◕✿)
|
||||
(◕‿◕)
|
||||
(◕‿-)
|
||||
(◕︵◕)
|
||||
(◕ ^ ◕)
|
||||
(◕_◕)
|
||||
(◜௰◝)
|
||||
(◡‿◡✿)
|
||||
(◣_◢)
|
||||
(☞゚゚)☞
|
||||
(☞゚ヮ゚)☞
|
||||
(☞゚ ゚ )☞
|
||||
(☼◡☼)
|
||||
(☼_☼)
|
||||
(✌゚゚)☞
|
||||
(✖╭╮✖)
|
||||
(✪㉨✪)
|
||||
(✿◠‿◠)
|
||||
(✿ ♥‿♥)
|
||||
( ・・)
|
||||
( ・ัω・ั)?
|
||||
( ゚゚)o彡゜えーりんえーりん!!
|
||||
(。・_・。)
|
||||
(つд`)
|
||||
(づ。◕‿‿◕。)づ
|
||||
(ノಠ益ಠ)ノ彡┻━┻
|
||||
(ノ ◑‿◑)ノ
|
||||
(ノ_・。)
|
||||
(・・ )
|
||||
(屮゚Д゚)屮
|
||||
(︶ω︶)
|
||||
(︶︹︺)
|
||||
(ﺧ益ﺨ)
|
||||
(;一_一)
|
||||
(`・ω・´)”
|
||||
(。◕‿‿◕。)
|
||||
(。◕‿◕。)
|
||||
(。◕ ‿ ◕。)
|
||||
(。♥‿♥。)
|
||||
(。・ω..・)っ
|
||||
(・ェ-)
|
||||
(ノ◕ヮ◕)ノ*:・゚✧
|
||||
(゚Д゚)
|
||||
(゚Д゚)y┛~~
|
||||
(゚゚)
|
||||
(゚ヮ゚)
|
||||
( ̄□ ̄)
|
||||
( ̄。 ̄)
|
||||
( ̄ー ̄)
|
||||
( ̄(エ) ̄)
|
||||
( °٢° )
|
||||
( ´_ゝ`)
|
||||
( ͡° ͜ʖ ͡°)
|
||||
( ͡~ ͜ʖ ͡°)
|
||||
( ಠ◡ಠ )
|
||||
( •_•)>⌐■-■
|
||||
( ゚,_ゝ゚)
|
||||
( ・ิз・ิ)
|
||||
( ゚д゚)、
|
||||
( ^▽^)σ)~O~)
|
||||
((((゜д゜;))))
|
||||
(*´д`*)
|
||||
(*..Д`)
|
||||
(*..д`*)
|
||||
(*~▽~)
|
||||
(-’๏_๏’-)
|
||||
(-_- )ノ
|
||||
(/◔ ◡ ◔)/
|
||||
(///_ಥ)
|
||||
(;´Д`)
|
||||
(=ω=;)
|
||||
(=゜ω゜)
|
||||
(>'o')> ♥ <('o'<)
|
||||
(n˘v˘•)¬
|
||||
(o´ω`o)
|
||||
(V)(°,,°)(V)
|
||||
(\/) (°,,°) (\/)
|
||||
(^▽^)
|
||||
(`・ω・´)
|
||||
(~ ̄▽ ̄)~
|
||||
/╲/\╭ºoꍘoº╮/\╱\
|
||||
<【☯】‿【☯】>
|
||||
= (゚д゚)ウ
|
||||
@_@
|
||||
d(*⌒▽⌒*)b
|
||||
o(≧≦)o
|
||||
o(≧o≦)o
|
||||
q(❂‿❂)p
|
||||
y=ー( ゚д゚)・∵.
|
||||
\˚ㄥ˚\
|
||||
\ᇂ_ᇂ\
|
||||
\(ಠ ὡ ಠ )/
|
||||
\(◕ ◡ ◕\)
|
||||
^̮^
|
||||
^ㅂ^
|
||||
_(͡๏̯͡๏)_
|
||||
{´◕ ◡ ◕`}
|
||||
{ಠ_ಠ}__,,|,
|
||||
{◕ ◡ ◕}
|
|
@ -0,0 +1,63 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import irc3,os,threading,asyncio,ipdb
|
||||
from time import sleep
|
||||
from plugins.tool_dims_plugin import dims
|
||||
from plugins.tool_guds_plugin import guds
|
||||
from plugins.net_irc_plugin import config_ircbot
|
||||
from plugins.net_irc_plugin import start_ircbot
|
||||
from plugins.net_matrix_plugin import start_matrixbot
|
||||
from plugins.tool_bus_plugin import BUS
|
||||
##################################################channel##################################
|
||||
class BOTIO:
|
||||
#######################################################################################
|
||||
verbosity=True
|
||||
log_exit_level=[]
|
||||
#######################################################################################
|
||||
def __init__(self):
|
||||
print(f'<<< ________botio_class >>> [ instantiated ]')
|
||||
self.ircbot=config_ircbot()
|
||||
self.net_irc=[]
|
||||
self.net_matrix=[]
|
||||
print(f'<<< ________botio_class >>> [ ircbot configured ]')
|
||||
#######################################################################################
|
||||
def __boot__irc(self):
|
||||
print('<<< system_status__info >>> [ booting connection: irc ]')
|
||||
self=start_ircbot(self)
|
||||
#######################################################################################
|
||||
def __boot__matrix(self):
|
||||
print('<<< system_status__info >>> [ booting connection: matrix ]')
|
||||
self=start_matrixbot(self)
|
||||
#######################################################################################
|
||||
def __boot__empty(self):
|
||||
print('<<< system_status__info >>> [ booting connection: empty ]')
|
||||
#######################################################################################
|
||||
def __main__(self,index):
|
||||
if index==0:
|
||||
t=threading.Thread(target=self.__boot__irc)
|
||||
print(f'<<< system_status__info >>> [ irc thread setup ]')
|
||||
t.start()
|
||||
print(f'<<< system_status__info >>> [ irc thread started ]')
|
||||
elif index==1:
|
||||
t=threading.Thread(target=self.__boot__matrix)
|
||||
print(f'<<< system_status__info >>> [ matrix thread setup ]')
|
||||
t.start()
|
||||
t.join()
|
||||
print(f'<<< system_status__info >>> [ matrix thread started ]')
|
||||
# elif index==2:
|
||||
# print(f'<<< system_status__info >>> [ empty thread setup ]')
|
||||
# t=threading.Thread(target=self.__boot__empty)
|
||||
# t.start()
|
||||
# print(f'<<< system_status__info >>> [ empty thread started ]')
|
||||
###########################################################################################
|
||||
if __name__ == '__main__':
|
||||
print('<<< system_status__info >>> [ main startup ]')
|
||||
guds.add_credentials("@maple.or.g1mp:matrix.org")
|
||||
guds.add_credentials("@maple:pcriot.org")
|
||||
bio=BOTIO()
|
||||
globals()['guds'].memories.append([bio,'maple:__main__.bio'])
|
||||
for i in range(3):
|
||||
bio.log_exit_level.append(bio.__main__(i))
|
||||
while True:
|
||||
if bio.verbosity: print('<<< system_status__info >>> [ eventloop idler thread ]')
|
||||
sleep(1)
|
||||
####################################################################################### EOF
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.cron import cron
|
||||
import irc3, os
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
NICKSERV_USERNAME=os.environ['NICKSERV_USERNAME']
|
||||
NICKSERV_PASSWORD=os.environ['NICKSERV_PASSWORD']
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
def __init__(self,bot):
|
||||
self.bot=bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.CONNECTED)
|
||||
def connected(self, **kw):
|
||||
MSG=f"identify {NICKSERV_USERNAME} {NICKSERV_PASSWORD}"
|
||||
self.bot.privmsg('NICKSERV',MSG)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@cron('*/1 * * * *')
|
||||
def cron_auth(bot):
|
||||
if not bot.nick==bot.original_nick:
|
||||
MSG=f"identify {NICKSERV_USERNAME} {NICKSERV_PASSWORD}"
|
||||
bot.privmsg('NICKSERV',MSG)
|
||||
###########################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,267 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
from irc3.utils import IrcString
|
||||
import irc3
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import re
|
||||
import functools
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
USER_STRING_MATCH = re.compile('(.+)!(.+)@(.+)')
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
def __init__(self,bot):
|
||||
self.bot=bot
|
||||
staff_set=set()
|
||||
self.bot.auto_kick_list = set(self.bot.db.getlist("auto_kick_list", []))
|
||||
self.bot.ignore_list = set(self.bot.db.getlist("ignore_nicks_list", []))
|
||||
self.bot.staff_list = set(self.bot.db.getlist("staff_list", []))
|
||||
current_masks = self.bot.config.get('irc3.plugins.command.masks')
|
||||
for k, v in current_masks.items():
|
||||
if v in ["staff", "all_permissions"]:
|
||||
staff_set.add(k)
|
||||
if not self.bot.ignore_list:
|
||||
self.bot.ignore_list = set(self.bot.config.get('irc3.plugins.command.masks', {}).get("ignore_list", []))
|
||||
if not self.bot.staff_list:
|
||||
self.bot.staff_list = set(staff_set)
|
||||
self.bot.db.setlist("staff_list", self.bot.staff_list)
|
||||
for hostname in self.bot.staff_list:
|
||||
if not current_masks.get(hostname):
|
||||
self.bot.config['irc3.plugins.command.masks'][hostname] = "staff"
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.extend
|
||||
def check_if_ignored(self, hostmask):
|
||||
global_hostmask = hostmask.replace(hostmask.nick, ".+")
|
||||
nick_mask = hostmask.replace(hostmask.host,".+@.+")
|
||||
host_pattern = re.compile(global_hostmask)
|
||||
nick_pattern = re.compile(nick_mask)
|
||||
for mask in self.bot.ignore_list:
|
||||
if host_pattern.match(mask):
|
||||
return True
|
||||
if nick_pattern.match(mask):
|
||||
return True
|
||||
return False
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.CONNECTED)
|
||||
def _add_hostmask(self, *args, **kwargs):
|
||||
def handle_who(self, response):
|
||||
result = response.result()
|
||||
self.bot.hostmask = result.get('mask')
|
||||
task = self.bot.who(self.bot.get_nick())
|
||||
task.add_done_callback(functools.partial(handle_who, self))
|
||||
opper_password = self.bot.config.get("opper_password")
|
||||
opper_username = self.bot.config.get("opper_username")
|
||||
self.bot.send_line(f"GOD {opper_username} {opper_password}")
|
||||
self.bot.privmsg("nickserv", f"IDENTIFY {self.bot.nick} {opper_password}")
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.JOIN)
|
||||
def auto_kick_handler(self, mask, channel, **kw):
|
||||
msg = "g1mp'n ain't easy unless you're maple"
|
||||
if mask.nick in self.bot.auto_kick_list:
|
||||
cmd = f"MODE {channel} +b {mask.nick}!*@*"
|
||||
self.bot.send(cmd)
|
||||
self.bot.kick(channel, mask.nick, msg)
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@command(permission='view', public=True, show_in_help_list=True)
|
||||
def v(self, mask, target, args):
|
||||
"""Voices all present users in channel
|
||||
%%v
|
||||
"""
|
||||
channel = self.bot.channels[target]
|
||||
try:
|
||||
OP_FLAG=False
|
||||
channel = self.bot.channels[target]
|
||||
for _, nick in channel.modes.items():
|
||||
for __ in _:
|
||||
modes=["%","@","&","~"]
|
||||
if __ in modes:
|
||||
if mask.nick in nick:
|
||||
OP_FLAG=True
|
||||
if OP_FLAG:
|
||||
has_voice_list = []
|
||||
for _, nick in channel.modes.items():
|
||||
has_voice_list.append(nick)
|
||||
for nick in channel:
|
||||
if nick not in has_voice_list:
|
||||
cmd = f"MODE {target} +v {mask.nick}"
|
||||
self.bot.send(cmd)
|
||||
except Exception as e:
|
||||
msg=f'error: base_plugin > v: {e}'
|
||||
print(msg)
|
||||
self.bot.privmsg(target,self.bot.emo(msg))
|
||||
pass
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@command(permission='admin', public=True, show_in_help_list=False)
|
||||
def op(self, mask, target, args):
|
||||
"""Ops user
|
||||
%%op <nick>
|
||||
"""
|
||||
if args['<nick>']:
|
||||
nick = args['<nick>']
|
||||
cmd = f"MODE {target} +o {mask.nick}"
|
||||
self.bot.send(cmd)
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@command(permission='admin', public=True, show_in_help_list=False)
|
||||
def deop(self, mask, target, args):
|
||||
"""Deops user
|
||||
%%op <nick>
|
||||
"""
|
||||
if args['<nick>']:
|
||||
nick = args['<nick>']
|
||||
cmd = f"MODE {target} -o {mask.nick}"
|
||||
self.bot.send(cmd)
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@command(permission="admin", show_in_help_list=False)
|
||||
def stats(self, mask, target, args):
|
||||
"""Stats
|
||||
%%stats
|
||||
"""
|
||||
channel = target
|
||||
if channel in self.bot.channels:
|
||||
channel = self.bot.channels[channel]
|
||||
message = f'{len(channel)} users'
|
||||
for mode, nicknames in sorted(channel.modes.items()):
|
||||
message += f' - {mode}({len(nicknames)})'
|
||||
self.bot.privmsg(target, message)
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@command(permission='admin', public=False, show_in_help_list=False)
|
||||
def restart(self, mask, target, args):
|
||||
"""restart
|
||||
%%restart
|
||||
"""
|
||||
self.bot.privmsg(target, 'BOT RESTARTING')
|
||||
time.sleep(1)
|
||||
os.execl(sys.executable, sys.executable, *sys.argv)
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@command(permission='admin', public=False, show_in_help_list=False)
|
||||
def uptime(self, mask, target, args):
|
||||
pass
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@command(permission='admin', public=False, show_in_help_list=False)
|
||||
def ping(self, mask, target, args):
|
||||
pass
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@command(permission='staff', public=True, show_in_help_list=True)
|
||||
def staff(self, mask, target, args):
|
||||
"""staff
|
||||
%%staff <noise>...
|
||||
"""
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
def __staff_list(self, mask, target, args):
|
||||
current_masks = self.bot.config.get("irc3.plugins.command.masks", "")
|
||||
current_staff_list = [k for k,v in current_masks.items() if v in ["all_permissions", "staff"]]
|
||||
self.bot.privmsg(target, "\x02༺Staff List༻\x0F\x02\x0303 > \x0F\x0302{}".format(", ".join(current_staff_list)))
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
def __staff_del(self, mask, target, args):
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
def del_hostmask(self, host_string):
|
||||
current_masks = self.bot.config.get("irc3.plugins.command.masks", "")
|
||||
if host_string in current_masks.keys():
|
||||
mask_list = current_masks.get(host_string, "").split(",")
|
||||
if "all_permissions" in mask_list:
|
||||
self.bot.privmsg(target, "Don't fuck with the admin")
|
||||
return
|
||||
elif "staff" in mask_list:
|
||||
del(self.bot.config["irc3.plugins.command.masks"][host_string])
|
||||
self.bot.staff_list.remove(host_string)
|
||||
self.bot.db.setlist("staff_list", self.bot.staff_list)
|
||||
self.bot.privmsg(target, f'{host_string} removed from staff')
|
||||
return
|
||||
else:
|
||||
pass # pass for brevarity
|
||||
else:
|
||||
self.bot.privmsg(target, f'{host_string} is not a staff member')
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
def handle_who(self, response):
|
||||
result = response.result()
|
||||
nick = result.get("nick")
|
||||
mask = result.get('mask')
|
||||
host_string = mask.replace(nick,"*")
|
||||
del_hostmask(self, host_string)
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
nick = args.get("<nick>")
|
||||
match_list = USER_STRING_MATCH.findall(nick)
|
||||
if match_list and len(match_list[0]) == 3:
|
||||
del_hostmask(self, nick)
|
||||
return
|
||||
else:
|
||||
task = self.bot.who(nick)
|
||||
task.add_done_callback(functools.partial(handle_who, self))
|
||||
return
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
def __staff_add(self, mask, target, args):
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
def add_hostmask(self, host_string):
|
||||
current_masks = self.bot.config.get("irc3.plugins.command.masks", "")
|
||||
if host_string in current_masks.keys():
|
||||
mask_list = current_masks.get(host_string, "").split(",")
|
||||
if "staff" or "all_permissions" in mask_list:
|
||||
self.bot.privmsg(target, f"{host_string} is already a staff member")
|
||||
return
|
||||
else:
|
||||
self.bot.config["irc3.plugins.command.masks"][host_string] = "staff"
|
||||
self.bot.staff_list.add(host_string)
|
||||
self.bot.db.setlist("staff_list", self.bot.staff_list)
|
||||
self.bot.privmsg(target, f'{host_string} added to staff')
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
def handle_who(self, response):
|
||||
result = response.result()
|
||||
nick = result.get("nick")
|
||||
mask = result.get('mask')
|
||||
host_string = mask.replace(nick,"*")
|
||||
add_hostmask(self, host_string)
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
nick = args.get("<nick>")
|
||||
match_list = USER_STRING_MATCH.findall(nick)
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
if match_list and len(match_list[0]) == 3:
|
||||
add_hostmask(self, nick)
|
||||
return
|
||||
else:
|
||||
task = self.bot.who(nick)
|
||||
task.add_done_callback(functools.partial(handle_who, self))
|
||||
return
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
cmd = ' '.join(args['<noise>'])[0]
|
||||
args = ' '.join(args['<noise>'])[1:]
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
if not cmd:
|
||||
self.bot.privmsg(target, "please specify add/del/list")
|
||||
elif cmd in ["d","del","delete","remove"]:
|
||||
__staff_del(self, mask, target, args)
|
||||
elif cmd in ["l", "list"]:
|
||||
__staff_list(self, mask, target, args)
|
||||
elif cmd in ["w", "write","a", "add"]:
|
||||
__staff_add(self, mask, target, args)
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,772 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
###########################################################################################
|
||||
import irc3
|
||||
from irc3.plugins.command import command
|
||||
from urllib.parse import urlparse
|
||||
from datetime import datetime
|
||||
from glob import glob
|
||||
from typing import Type
|
||||
import random
|
||||
import string
|
||||
import os
|
||||
########################################################################## THE ASCII LOGO TO BE USED
|
||||
MOTD="""
|
||||
_________ _________ _________ ___ ___ _________ _________ ____ ____
|
||||
| o ) / O \ / O \ | \ / | | o ) / O \ \ \_/ /
|
||||
|_____O___) \_________/ \_________/ |____|____| |_____O___) \_________/ /___/%\___\\
|
||||
'BBBBBBB' 'BBBBBBB' 'BBBBBBB' 'BBBBBBB' 'BBBBBBB' 'BBBBBBB' 'BB' 'BB'
|
||||
"""
|
||||
######################################################################## BOOMBOX MAIN ENTRY
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
##################################################################### BOOMBOX MAIN INIT
|
||||
def __init__(self, bot):
|
||||
###################################################################################
|
||||
self.bot=bot
|
||||
self.bot.diagnostic_flag=False
|
||||
self.bot.bbs=BOOMBOX_CONFIG(self.bot)
|
||||
#################################################################### SOF COLOR INIT
|
||||
self.bot.bbs.c=[]
|
||||
self.bot.bbs.b1,self.bot.bbs.b2,self.bot.bbs.b3,self.bot.bbs.b4=self.bot.bbs.palette()[0:4]
|
||||
self.bot.bbs.b5,self.bot.bbs.b6,self.bot.bbs.b7,self.bot.bbs.b8=self.bot.bbs.palette()[0:4]
|
||||
######################################################################## COLOR INIT
|
||||
self.bot.bbs.sites=['soundcloud','youtube','spotify','bandcamp']
|
||||
self.bot.bbs.floor__top_songs=15
|
||||
self.bot.bbs.floor__last_songs=15
|
||||
self.bot.bbs.floor__top_users=5
|
||||
self.bot.bbs.floor__top_sites=len(self.bot.bbs.sites)
|
||||
self.bot.bbs.ceiling__top_songs=50
|
||||
self.bot.bbs.ceiling__last_songs=50
|
||||
self.bot.bbs.ceiling__top_users=25
|
||||
self.bot.bbs.ceiling__top_sites=len(self.bot.bbs.sites)
|
||||
#################################################################### EOF COLOR INIT
|
||||
self.bot.bbs.bot=self.bot
|
||||
################################################################## CHECK OR PREP DB
|
||||
######################################################################## BOOMBOX MAIN 1
|
||||
@command(permission='view',public=True, show_in_help_list=False)
|
||||
def dbdo(self, mask, target, args):
|
||||
"""dbdo sync
|
||||
%%dbdo <noise>...
|
||||
"""
|
||||
noise=' '.join(args['<noise>'])
|
||||
commands=noise.split()
|
||||
db=noise.split()[0]
|
||||
op=noise.split()[1]
|
||||
data=' '.join(noise.split()[2:])
|
||||
result=self.bot.bbs.dbdo(db,op,data)
|
||||
######################################################################## BOOMBOX MAIN 1
|
||||
@command(permission='view',public=True, show_in_help_list=False)
|
||||
def bb(self, mask, target, args):
|
||||
"""Convert boombox token to a url
|
||||
%%bb <token>...
|
||||
"""
|
||||
c=self.bot.bbs.palette()
|
||||
self.bot.bbs.c=c
|
||||
token=''.join(args['<token>'])
|
||||
tokens=self.bot.db.getlist("bbs_token")
|
||||
url=''
|
||||
for t in tokens:
|
||||
if token in t:
|
||||
url=t[token]
|
||||
msg=f"{c[0]}{mask.nick} {c[1]}> {c[2]}boombox"
|
||||
if url:
|
||||
title_prefetch_data=self.bot.prefetch_title(url,target,mask)
|
||||
if url.find('soundcloud'):
|
||||
try:
|
||||
if title_prefetch_data:
|
||||
title=title_prefetch_data.split('|')[0].strip().replace('Stream','').strip()
|
||||
msg+=f"{c[1]} > {c[4]}{title} {c[1]}> {c[3]}{url}{c[1]}"
|
||||
else:
|
||||
msg+=f"{c[2]}url{c[1]} > {c[3]}{url}"
|
||||
except:
|
||||
msg+=f"{c[2]}url{c[1]} > {c[3]}{url}"
|
||||
else:
|
||||
msg+=f"{c[2]}error{c[1]}: {c[3]}{token} is an invalid token"
|
||||
self.bot.privmsg(target,self.bot.emo(msg))
|
||||
######################################################################## BOOMBOX MAIN 2
|
||||
@command(permission='view',error_format="{cmd} error - usage: ?{cmd} all,top,old,user,site - example: ?{cmd} all".format)
|
||||
def boombox(self, mask, target, args):
|
||||
"""boombox
|
||||
%%boombox
|
||||
"""
|
||||
command='all'
|
||||
###################################################################################
|
||||
commands=['top','old','user','site','all']
|
||||
###################################################################################
|
||||
if not command in commands:
|
||||
msg="boombox - usage: ?boombox top, ?boombox old, ?boombox user, ?boombox site, ?boombox all"
|
||||
self.bot.privmsg(target,self.bot.emo(msg))
|
||||
return
|
||||
###################################################################################
|
||||
bbs_last=self.bot.db.getlist("bbs_last")
|
||||
bbs_data=self.bot.db.getlist('bbs_data')
|
||||
###################################################################################
|
||||
if bbs_data:
|
||||
###############################################################################
|
||||
c1,c2,c3,c4,c5,c6,c7,c8=self.bot.bbs.c
|
||||
###############################################################################
|
||||
if command=='all':
|
||||
for _ in MOTD.splitlines():
|
||||
if _:
|
||||
self.bot.privmsg(target,f'{self.bot.bbs.palette()[0]}{_}')
|
||||
###################################################################################
|
||||
|
||||
if command=='top' or command=='all':
|
||||
# TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP
|
||||
# TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP
|
||||
# TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP SONGS TOP
|
||||
msg=f'TOP SONGS ◸{c2}◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸'
|
||||
###########################################################################
|
||||
self.bot.privmsg(target,msg)
|
||||
bbs_data=self.bot.db.getlist('bbs_data')
|
||||
hits=[]
|
||||
for i,data in enumerate(bbs_data):
|
||||
hits.append(data['hits'])
|
||||
lot=[(k,v) for k, v in zip(range(len(hits)),hits)]
|
||||
nl=[]
|
||||
while len(lot)> 0:
|
||||
nl.append(max(lot,key=lambda x: x[1]))
|
||||
lot.remove(nl[-1])
|
||||
nl[0:len(bbs_data)]
|
||||
###########################################################################
|
||||
mode_length=0
|
||||
if command=='top':
|
||||
mode_length=self.bot.bbs.ceiling__top_songs
|
||||
elif command=='all':
|
||||
mode_length=self.bot.bbs.floor__top_songs
|
||||
###########################################################################
|
||||
top_songs=[]
|
||||
for i in range(mode_length):
|
||||
try:
|
||||
base=bbs_data[nl[i][0]]
|
||||
except:
|
||||
pass
|
||||
title=base['title'].lower()
|
||||
token=base['token']
|
||||
url=base['url']
|
||||
site=base['site']
|
||||
hits=base['hits']
|
||||
lot_nicks=[(k,v) for k, v in zip(range(len(base['nicks'].values())),base['nicks'].values())]
|
||||
buf_nicks=[]
|
||||
while len(lot_nicks)>0:
|
||||
buf_nicks.append(max(lot_nicks,key=lambda x: x[1]))
|
||||
lot_nicks.remove(buf_nicks[-1])
|
||||
nick_hits=buf_nicks[0][1]
|
||||
nick=list(base['nicks'])[buf_nicks[0][0]]
|
||||
msg=f'{c4}{self.bot.bbs.tailor(title.lower(),50)} {c1}╏ {c3}{self.bot.bbs.tailor(site.lower(),10)} {c1}╏ {c8}{self.bot.bbs.tailor(nick.lower(),10)} {c1}╏ {c7}{str(nick_hits).zfill(2)}{c1}/{c7}{str(hits).zfill(2)} {c6}plays {c1}╏ {c5}?bb {token}'
|
||||
top_songs.append(msg)
|
||||
last_song=""
|
||||
for song in top_songs:
|
||||
if song==last_song:
|
||||
break
|
||||
last_song=song
|
||||
self.bot.privmsg(target,song)
|
||||
###############################################################################
|
||||
if command=='old' or command=='all':
|
||||
# OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD
|
||||
# OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD
|
||||
# OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD SONGS OLD
|
||||
msg=f'OLD SONGS ◸{c2}◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸'
|
||||
self.bot.privmsg(target,msg)
|
||||
bbs_data=self.bot.db.getlist('bbs_data')
|
||||
last_songs=[]
|
||||
try:
|
||||
for i,lastdb in enumerate(bbs_last):
|
||||
nick=lastdb[0]
|
||||
site=lastdb[1]
|
||||
title=lastdb[2]
|
||||
token=lastdb[3]
|
||||
url=lastdb[4]
|
||||
try:
|
||||
reverse_index=self.bot.bbs.dbgaze('bbs_data','token',token)
|
||||
hits=bbs_data[reverse_index]['hits']
|
||||
db_key_nicks=list(zip(list(bbs_data[reverse_index]['nicks'].values()),list(bbs_data[reverse_index]['nicks'].keys())))
|
||||
db_key_nicks.sort()
|
||||
user=db_key_nicks[-1][1]
|
||||
plays=user=db_key_nicks[-1][0]
|
||||
if len(lastdb)>0:
|
||||
msg=f'{c4}{self.bot.bbs.tailor(title.lower(),50)} {c1}╏ {c3}{self.bot.bbs.tailor(site.lower(),10)} {c1}╏ {c8}{self.bot.bbs.tailor(nick.lower(),10)} {c1}╏ {c7}{str(plays).zfill(2)}{c1}/{c7}{str(hits).zfill(2)} {c6}plays {c1}╏ {c5}?bb {token}'
|
||||
last_songs.append(msg)
|
||||
except Exception as e:
|
||||
print(f'<<< _____boombox_plugin >>> boombox:last - error: {e}')
|
||||
except Exception as e:
|
||||
pass
|
||||
###########################################################################
|
||||
mode_length=0
|
||||
if command=='old':
|
||||
mode_length=self.bot.bbs.ceiling__last_songs
|
||||
elif command=='all':
|
||||
mode_length=self.bot.bbs.floor__last_songs
|
||||
###########################################################################
|
||||
try:
|
||||
for i in range(mode_length):
|
||||
self.bot.privmsg(target,last_songs[i])
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
if command=='user' or command=='all':
|
||||
# TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP
|
||||
# TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP
|
||||
# TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP USERS TOP
|
||||
msg=f'TOP USERS ◸{c2}◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸'
|
||||
self.bot.privmsg(target,msg)
|
||||
top_data=self.bot.db.getlist('bbs_data')
|
||||
bbs_nicks=self.bot.db.getlist("bbs_nicks")
|
||||
top_nicks=list(bbs_nicks[0].keys())
|
||||
top_users_tally=[]; top_users=[]
|
||||
for _ in [ x for x in bbs_nicks[0] ]:
|
||||
top_users_tally.append(bbs_nicks[0][_]['tally'])
|
||||
for _ in [ x for x in bbs_nicks[0] ]:
|
||||
top_users.append(_)
|
||||
userlist=list(zip(top_users_tally,top_users))
|
||||
userlist.sort()
|
||||
userlist.reverse()
|
||||
for i,userdata in enumerate(userlist):
|
||||
tally,user=userdata
|
||||
top_users=[]
|
||||
for _user in userlist:
|
||||
top_user=_user[1]
|
||||
user_hits=[]
|
||||
for i,_ in enumerate(bbs_data):
|
||||
try:
|
||||
user_hits.append(f"{_['nicks'][_user[1]]},{i}")
|
||||
except:
|
||||
pass
|
||||
user_hits.sort()
|
||||
user_hits.reverse()
|
||||
top_hits=int(user_hits[0].split(',')[0])
|
||||
top_index=int(user_hits[0].split(',')[1])
|
||||
top_hits_site=int(bbs_data[top_index]['hits'])
|
||||
top_site=bbs_data[top_index]['site']
|
||||
top_title=bbs_data[top_index]['title']
|
||||
top_token=bbs_data[top_index]['token']
|
||||
msg=f'{c4}{self.bot.bbs.tailor(top_title.lower(),50)} {c1}╏ {c3}{self.bot.bbs.tailor(top_site.lower(),10)} {c1}╏ {c8}{self.bot.bbs.tailor(top_user.lower(),10)} {c1}╏ {c7}{str(top_hits).zfill(2)}{c1}/{c7}{str(top_hits_site).zfill(2)} {c6}plays {c1}╏ {c5}?bb {top_token}'
|
||||
top_users.append(msg)
|
||||
###########################################################################
|
||||
mode_length=0
|
||||
if command=='user':
|
||||
mode_length=self.bot.bbs.ceiling__top_users
|
||||
elif command=='all':
|
||||
mode_length=self.bot.bbs.floor__top_users
|
||||
###########################################################################
|
||||
try:
|
||||
for i in range(mode_length):
|
||||
self.bot.privmsg(target,top_users[i])
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
if command=='site' or command=='all':
|
||||
# TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP
|
||||
# TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP
|
||||
# TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP SITES TOP
|
||||
bbs_sites=self.bot.db.getlist("bbs_sites")
|
||||
msg=f'TOP SITES ◸{c2}◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸◹◸'
|
||||
self.bot.privmsg(target,msg)
|
||||
bbs_nicks=self.bot.db.getlist('bbs_nicks')
|
||||
site_nicks=list(bbs_nicks[0].keys())
|
||||
site_users_bandcamp=[]; site_users_soundcloud=[];
|
||||
site_users_youtube=[]; site_users_spotify=[];
|
||||
for _ in [ x for x in site_nicks ]:
|
||||
site_users_bandcamp.append([bbs_nicks[0][_]['bandcamp'],_])
|
||||
site_users_soundcloud.append([bbs_nicks[0][_]['soundcloud'],_])
|
||||
site_users_youtube.append([bbs_nicks[0][_]['youtube'],_])
|
||||
site_users_spotify.append([bbs_nicks[0][_]['spotify'],_])
|
||||
site_users_bandcamp.sort(); site_users_bandcamp.reverse()
|
||||
site_users_soundcloud.sort(); site_users_soundcloud.reverse()
|
||||
site_users_youtube.sort(); site_users_youtube.reverse()
|
||||
site_users_spotify.sort(); site_users_spotify.reverse()
|
||||
###########################################################################
|
||||
bandcamp_top_user_hits=[]
|
||||
for i,_ in enumerate(bbs_data):
|
||||
if _['site']=='bandcamp':
|
||||
bandcamp_top_user_hits.append(f'{_["hits"]},{i}')
|
||||
bandcamp_top_user_hits.sort()
|
||||
bandcamp_top_user_hits.reverse()
|
||||
bandcamp_index=int(bandcamp_top_user_hits[0].split(',')[1])
|
||||
bandcamp_title=bbs_data[bandcamp_index]['title']
|
||||
bandcamp_site=bbs_data[bandcamp_index]['site']
|
||||
bandcamp_user=site_users_bandcamp[0][1]
|
||||
bandcamp_userhits=bandcamp_top_user_hits[0].split(',')[0]
|
||||
bbs_sites=self.bot.db.getlist('bbs_sites')
|
||||
bandcamp_sitehits=bbs_sites[0]['bandcamp']
|
||||
bandcamp_token=bbs_data[bandcamp_index]['token']
|
||||
site_bandcamp=[bandcamp_title,bandcamp_site,bandcamp_user,bandcamp_userhits,bandcamp_sitehits,bandcamp_token,bandcamp_index]
|
||||
###########################################################################
|
||||
soundcloud_top_user_hits=[]
|
||||
for i,_ in enumerate(bbs_data):
|
||||
if _['site']=='soundcloud':
|
||||
soundcloud_top_user_hits.append(f'{_["hits"]},{i}')
|
||||
soundcloud_top_user_hits.sort()
|
||||
soundcloud_top_user_hits.reverse()
|
||||
soundcloud_index=int(soundcloud_top_user_hits[0].split(',')[1])
|
||||
soundcloud_title=bbs_data[soundcloud_index]['title']
|
||||
soundcloud_site=bbs_data[soundcloud_index]['site']
|
||||
soundcloud_user=site_users_soundcloud[0][1]
|
||||
soundcloud_userhits=soundcloud_top_user_hits[0].split(',')[0]
|
||||
bbs_sites=self.bot.db.getlist('bbs_sites')
|
||||
soundcloud_sitehits=bbs_sites[0]['soundcloud']
|
||||
soundcloud_token=bbs_data[soundcloud_index]['token']
|
||||
site_soundcloud=[soundcloud_title,soundcloud_site,soundcloud_user,soundcloud_userhits,soundcloud_sitehits,soundcloud_token,soundcloud_index]
|
||||
###########################################################################
|
||||
youtube_top_user_hits=[]
|
||||
for i,_ in enumerate(bbs_data):
|
||||
if _['site']=='youtube':
|
||||
youtube_top_user_hits.append(f'{_["hits"]},{i}')
|
||||
youtube_top_user_hits.sort()
|
||||
youtube_top_user_hits.reverse()
|
||||
youtube_index=int(youtube_top_user_hits[0].split(',')[1])
|
||||
youtube_title=bbs_data[youtube_index]['title']
|
||||
youtube_site=bbs_data[youtube_index]['site']
|
||||
youtube_user=site_users_youtube[0][1]
|
||||
youtube_userhits=youtube_top_user_hits[0].split(',')[0]
|
||||
bbs_sites=self.bot.db.getlist('bbs_sites')
|
||||
youtube_sitehits=bbs_sites[0]['youtube']
|
||||
youtube_token=bbs_data[youtube_index]['token']
|
||||
site_youtube=[youtube_title,youtube_site,youtube_user,youtube_userhits,youtube_sitehits,youtube_token,youtube_index]
|
||||
###########################################################################
|
||||
spotify_top_user_hits=[]
|
||||
for i,_ in enumerate(bbs_data):
|
||||
if _['site']=='spotify':
|
||||
spotify_top_user_hits.append(f'{_["hits"]},{i}')
|
||||
spotify_top_user_hits.sort()
|
||||
spotify_top_user_hits.reverse()
|
||||
spotify_index=int(spotify_top_user_hits[0].split(',')[1])
|
||||
spotify_title=bbs_data[spotify_index]['title']
|
||||
spotify_site=bbs_data[spotify_index]['site']
|
||||
spotify_user=site_users_spotify[0][1]
|
||||
spotify_userhits=spotify_top_user_hits[0].split(',')[0]
|
||||
bbs_sites=self.bot.db.getlist('bbs_sites')
|
||||
spotify_sitehits=bbs_sites[0]['spotify']
|
||||
spotify_token=bbs_data[spotify_index]['token']
|
||||
site_spotify=[spotify_title,spotify_site,spotify_user,spotify_userhits,spotify_sitehits,spotify_token,spotify_index]
|
||||
###########################################################################
|
||||
bbs_sites=self.bot.db.getlist("bbs_sites")
|
||||
hits=[]
|
||||
for i,data in enumerate(bbs_sites[0].keys()):
|
||||
hits.append(bbs_sites[0][data])
|
||||
lot=[(k,v) for k, v in zip(range(len(hits)),hits)]
|
||||
nl=[]
|
||||
while len(lot)> 0:
|
||||
nl.append(max(lot,key=lambda x: x[1]))
|
||||
lot.remove(nl[-1])
|
||||
siteorder=[]
|
||||
for i in range(len(nl)): siteorder.append(list(bbs_sites[0].keys())[nl[i][0]])
|
||||
top_sites=[]
|
||||
for site in siteorder:
|
||||
if site=='soundcloud':
|
||||
msg=f'{c4}{self.bot.bbs.tailor(site_soundcloud[0].lower(),50)} {c1}╏ {c3}{self.bot.bbs.tailor(site_soundcloud[1].lower(),10)} {c1}╏ {c8}{self.bot.bbs.tailor(site_soundcloud[2].lower(),10)} {c1}╏ {c7}{str(site_soundcloud[3]).zfill(2)}{c1}/{c7}{str(site_soundcloud[4]).zfill(2)} {c6}plays {c1}╏ {c5}?bb {site_soundcloud[5]}'
|
||||
top_sites.append(msg)
|
||||
elif site=='bandcamp':
|
||||
msg=f'{c4}{self.bot.bbs.tailor(site_bandcamp[0].lower(),50)} {c1}╏ {c3}{self.bot.bbs.tailor(site_bandcamp[1].lower(),10)} {c1}╏ {c8}{self.bot.bbs.tailor(site_bandcamp[2].lower(),10)} {c1}╏ {c7}{str(site_bandcamp[3]).zfill(2)}{c1}/{c7}{str(site_bandcamp[4]).zfill(2)} {c6}plays {c1}╏ {c5}?bb {site_bandcamp[5]}'
|
||||
top_sites.append(msg)
|
||||
elif site=='youtube':
|
||||
msg=f'{c4}{self.bot.bbs.tailor(site_youtube[0].lower(),50)} {c1}╏ {c3}{self.bot.bbs.tailor(site_youtube[1].lower(),10)} {c1}╏ {c8}{self.bot.bbs.tailor(site_youtube[2].lower(),10)} {c1}╏ {c7}{str(site_youtube[3]).zfill(2)}{c1}/{c7}{str(site_youtube[4]).zfill(2)} {c6}plays {c1}╏ {c5}?bb {site_youtube[5]}'
|
||||
top_sites.append(msg)
|
||||
elif site=='spotify':
|
||||
msg=f'{c4}{self.bot.bbs.tailor(site_spotify[0].lower(),50)} {c1}╏ {c3}{self.bot.bbs.tailor(site_spotify[1].lower(),10)} {c1}╏ {c8}{self.bot.bbs.tailor(site_spotify[2].lower(),10)} {c1}╏ {c7}{str(site_spotify[3]).zfill(2)}{c1}/{c7}{str(site_spotify[4]).zfill(2)} {c6}plays {c1}╏ {c5}?bb {site_spotify[5]}'
|
||||
top_sites.append(msg)
|
||||
###########################################################################
|
||||
mode_length=0
|
||||
if command=='site':
|
||||
mode_length=self.bot.bbs.ceiling__top_sites
|
||||
elif command=='all':
|
||||
mode_length=self.bot.bbs.floor__top_sites
|
||||
###########################################################################
|
||||
try:
|
||||
for i in range(mode_length):
|
||||
self.bot.privmsg(target,top_sites[i])
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
###################################################################################
|
||||
###################################################################### BOOMBOX CONFIG ENTRY
|
||||
class BOOMBOX_CONFIG:
|
||||
################################################################### BOOMBOX CONFIG INIT
|
||||
def __init__(self,bot):
|
||||
self.bot=bot
|
||||
self.db=[]
|
||||
self.bot.bbdb=[]
|
||||
self.database_names=['bbs_data','bbs_last','bbs_nicks','bbs_sites','bbs_token','bbs_tokenmirror']
|
||||
print(f'<<< _____boombox_plugin >>> [ database diagnostics ]')
|
||||
for index,database in enumerate(self.database_names):
|
||||
db=self.bot.db.getlist(database)
|
||||
if not db:
|
||||
print(f'<<< _____boombox_plugin >>> [ {" "*19}{index+1}/{len(self.database_names)} ] - [ missing database: {self.database_names[index]} ]')
|
||||
self.db_diagnostics(database)
|
||||
else:
|
||||
print(f'<<< _____boombox_plugin >>> [ {index+1}/{len(self.database_names)} ] - [ located database: {self.database_names[index]} ]')
|
||||
#print(f'{"#"*80} SOF')
|
||||
#print(f' pre - a database name: {database}')
|
||||
#print(f' pre - database memory: \n{self.db}')
|
||||
#print(f' pre - a datbase entry: \n{db}')
|
||||
#print(f'post - database merged: \n{db}')
|
||||
#print(f'{"#"*80} EOF')
|
||||
for _ in self.database_names:
|
||||
self.bot.bbdb.append(self.bot.db.getlist(_))
|
||||
############################################################ BOOMBOX CONFIG COLOR CODES
|
||||
def color(self,c):
|
||||
try:
|
||||
c=str(c.lower())
|
||||
if c=='0': return '\x0300'
|
||||
if c=='1': return '\x0301'
|
||||
if c=='2': return '\x0302'
|
||||
if c=='3': return '\x0303'
|
||||
if c=='4': return '\x0304'
|
||||
if c=='5': return '\x0305'
|
||||
if c=='6': return '\x0306'
|
||||
if c=='7': return '\x0307'
|
||||
if c=='8': return '\x0308'
|
||||
if c=='9': return '\x0309'
|
||||
if c=='a': return '\x0310'
|
||||
if c=='b': return '\x0311'
|
||||
if c=='c': return '\x0312'
|
||||
if c=='d': return '\x0313'
|
||||
if c=='e': return '\x0314'
|
||||
if c=='f': return '\x0315'
|
||||
if c=='n': return ''
|
||||
if c=='t': return '\x0f'
|
||||
print('color: empty')
|
||||
return '\x0f'
|
||||
except:
|
||||
print('color: error')
|
||||
return '\x0f'
|
||||
############################################################# BOOMBOX CONFIG COLOR SETS
|
||||
def palette(self):
|
||||
self.c=[]; self.n=[]
|
||||
for i in range(0,8):
|
||||
n=random.randint(0,15)
|
||||
c=self.color(hex(n)[2:])
|
||||
self.c.append(c); self.n.append(n)
|
||||
return self.c
|
||||
######################################################## BOOMBOX CONFIG TEXT ALIGNMENTS
|
||||
def tailor(self,s,n):
|
||||
if len(s)<=n:
|
||||
result=s+"."*(n-len(s))
|
||||
return result
|
||||
else:
|
||||
return s[0:n]
|
||||
######################################################## BOOMBOX CONFIG TEXT ALIGNMENTS
|
||||
def dbsync(self,db):
|
||||
for i,database in enumerate(['bbs_data','bbs_last','bbs_nicks','bbs_sites','bbs_token','bbs_tokenmirror']):
|
||||
if db == database:
|
||||
try:
|
||||
db_stored=self.bot.db.getlist(database)
|
||||
db_memory=self.bot.bbdb[i]
|
||||
if not db_memory==db_stored:
|
||||
self.bot.db.setlist(database,db_memory)
|
||||
print('<<< _____boombox_plugin >>> success: storage database updated from memory')
|
||||
else:
|
||||
print('<<< _____boombox_plugin >>> aborted: storage database same as memory content')
|
||||
except Exception as e:
|
||||
print('<<< _____boombox_plugin >>> dbsync:error - failed in writing to storage database from memory: {e}')
|
||||
######################################################## BOOMBOX CONFIG TEXT ALIGNMENTS
|
||||
def dbdo(self,database,operation,data=""):
|
||||
database_names=(['bbs_data','bbs_last','bbs_nicks','bbs_sites','bbs_token','bbs_tokenmirror'])
|
||||
operations=['get','set','update','append']
|
||||
if database in database_names:
|
||||
index=database_names.index(database)
|
||||
if operation in operations:
|
||||
if operation=="get":
|
||||
return self.bot.bbdb[index]
|
||||
elif operation=='set':
|
||||
db_stored=self.bot.db.getlist(database)
|
||||
print(f'<<< _____boombox_plugin >>> pre:{database} db_stored: {db_stored}')
|
||||
print(f'<<< _____boombox_plugin >>> pre:{database} db_memory: {self.bot.bbdb[index]}')
|
||||
print(f'<<< _____boombox_plugin >>> pre:{database} db_sent: {data}')
|
||||
self.bot.bbdb[index]=data
|
||||
print(f'<<< _____boombox_plugin >>> post:{database} db_memory: {self.bot.bbdb[index]}')
|
||||
print(f'<<< _____boombox_plugin >>> writing from memory to storage')
|
||||
self.dbsync(database)
|
||||
elif operation=='append':
|
||||
db_stored=self.bot.db.getlist(database)
|
||||
print(f'<<< _____boombox_plugin >>> pre:{database} db_stored: {db_stored}')
|
||||
print(f'<<< _____boombox_plugin >>> pre:{database} db_memory: {self.bot.bbdb[index]}')
|
||||
self.bot.bbdb[index].append(data)
|
||||
print(f'<<< _____boombox_plugin >>> post:{database} db_memory: {self.bot.bbdb[index]}')
|
||||
print(f'<<< _____boombox_plugin >>> writing from memory to storage')
|
||||
self.dbsync(database)
|
||||
#################################################### BOOMBOX CONFIG DATABASE OPERATIONS
|
||||
def push(self,nick,site,title,token,url):
|
||||
nick=self.no_unicode(nick)
|
||||
title=self.no_unicode(title)
|
||||
bbs_data=self.dbdo('bbs_data','get')
|
||||
bbs_last=self.dbdo('bbs_last','get')
|
||||
bbs_last=bbs_last[-1:]+bbs_last[:-1]
|
||||
bbs_last[0]=[nick,site,title,token,url]
|
||||
self.dbdo('bbs_last','set',bbs_last)
|
||||
#################################################### BOOMBOX CONFIG DATABASE OPERATIONS
|
||||
def check(self,nick,site,data):
|
||||
###################################################################################
|
||||
bbs_nicks=self.dbdo('bbs_nicks','get')
|
||||
bbs_sites=self.dbdo('bbs_sites','get')
|
||||
bbs_data=self.dbdo('bbs_data','get')
|
||||
bbs_token=self.dbdo('bbs_token','get')
|
||||
bbs_tokenmirror=self.dbdo('bbs_tokenmirror','get')
|
||||
###################################################################################
|
||||
try:
|
||||
if bbs_data:
|
||||
for i,_data in enumerate(bbs_data):
|
||||
if data['url']==_data['url']:
|
||||
_data['hits']+=1
|
||||
try:
|
||||
_data['nicks'][nick]+=1
|
||||
except:
|
||||
_data['nicks'].update({nick:1})
|
||||
try:
|
||||
bbs_nicks[0][nick]['tally']+=1
|
||||
bbs_nicks[0][nick][site]+=1
|
||||
except:
|
||||
bbs_nicks[0].update({nick:{'tally':1,'bandcamp':0,'soundcloud':0,'spotify':0,'youtube':0}})
|
||||
bbs_nicks[0][nick][site]+=1
|
||||
bbs_sites[0][site]+=1
|
||||
bbs_data[i]=_data
|
||||
self.dbdo("bbs_nicks",'set',bbs_nicks)
|
||||
self.dbdo("bbs_sites",'set',bbs_sites)
|
||||
self.dbdo("bbs_data",'set',bbs_data)
|
||||
return
|
||||
###########################################################################
|
||||
try:
|
||||
bbs_nicks[0][nick]['tally']+=1
|
||||
bbs_nicks[0][nick][site]+=1
|
||||
except:
|
||||
bbs_nicks[0].update({nick:{'tally':1,'bandcamp':0,'soundcloud':0,'spotify':0,'youtube':0}})
|
||||
bbs_nicks[0][nick][site]+=1
|
||||
###########################################################################
|
||||
self.dbdo("bbs_nicks",'set',bbs_nicks)
|
||||
bbs_sites[0][site]+=1
|
||||
self.dbdo("bbs_sites",'set',bbs_sites)
|
||||
bbs_data.append(data)
|
||||
self.dbdo("bbs_data",'set',bbs_data)
|
||||
URL=data['url']; TOKEN=data['token']
|
||||
self.dbdo('bbs_token','append',{TOKEN:URL})
|
||||
self.dbdo("bbs_token",'set',bbs_token)
|
||||
self.dbdo('bbs_tokenmirror','append',{TOKEN:URL})
|
||||
self.dbdo('bbs_tokenmirror','set',bbs_tokenmirror)
|
||||
except:
|
||||
bbs_nicks=[]
|
||||
self.dbdo('bbs_nicks','append',{nick:{'tally':1,'bandcamp':0,'soundcloud':0,'spotify':0,'youtube':0}})
|
||||
bbs_nicks[0][nick][site]+=1 ############################################ NOTICE
|
||||
self.dbdo('bbs_nicks','set',bbs_nicks)
|
||||
self.dbdo('bbs_sites','set',[{'soundcloud':0,'youtube':0,'spotify':0,'bandcamp':0}])
|
||||
bbs_sites=self.dbdo('bbs_sites','get')
|
||||
bbs_sites[0][site]+=1 ################################################## NOTICE
|
||||
self.dbdo('bbs_sites','set',bbs_sites)
|
||||
self.dbdo('bbs_data','set',[data])
|
||||
URL=data['url']; TOKEN=data['token']
|
||||
self.dbdo('bbs_token',{TOKEN:URL})
|
||||
self.dbdo('bbs_token','set', bbs_token)
|
||||
self.dbdo('bbs_token',{TOKEN:URL})
|
||||
self.dbdo('bbs_tokenmirror','append',{URL:TOKEN})
|
||||
self.dbdo('bbs_tokenmirror','set',bbs_tokenmirror)
|
||||
################################### BOOMBOX CONFIG HOOKED EXTERNALS DATABASE OPERATIONS
|
||||
def getsite(self,url):
|
||||
###################################################################################
|
||||
sites=['soundcloud','youtube','spotify','bandcamp']
|
||||
if not url.find('soundcloud.com')==-1:
|
||||
return sites[0]
|
||||
if not url.find('youtube.com')==-1 or not url.find('youtu.be')==-1:
|
||||
return sites[1]
|
||||
if not url.find('spotify.com')==-1:
|
||||
return sites[2]
|
||||
if not url.find('bandcamp.com')==-1:
|
||||
return sites[3]
|
||||
################################### BOOMBOX CONFIG HOOKED EXTERNALS DATABASE OPERATIONS
|
||||
def enter(self,nick,url,title):
|
||||
###################################################################################
|
||||
timestamp=datetime.now().timestamp()
|
||||
token=self.token(url)
|
||||
bbs_token=self.dbdo('bbs_token','get')
|
||||
nick=self.no_unicode(nick)
|
||||
title=self.no_unicode(title).lower()
|
||||
site=self.getsite(url)
|
||||
###################################################################################
|
||||
data={'nicks':{nick:1},'title':title.lower(),'url':url,'token':token,'timestamp':timestamp,'site':site,'hits':1}
|
||||
###################################################################################
|
||||
if site=='soundcloud':
|
||||
title=title[:title.rfind('by')].replace('Stream','').strip().lower()
|
||||
if not title=='SoundCloud - Hear the world’s sound':
|
||||
data['title']=title.split('music |')[0].rstrip().lower()
|
||||
data=self.check(nick,site,data)
|
||||
self.push(nick.lower(),site,title.lower(),token,url)
|
||||
###################################################################################
|
||||
if site=='youtube':
|
||||
id=url[-11:]
|
||||
result=self.bot.videos_list_by_id(id=id)
|
||||
if result:
|
||||
data=self.check(nick,site,data)
|
||||
self.push(nick.lower(),site,title.lower(),token,url)
|
||||
###################################################################################
|
||||
if site=='spotify':
|
||||
offset=url.rfind('/')+1
|
||||
try:
|
||||
track=title.split('|')[0].split('- song by')[0].strip()
|
||||
try:
|
||||
artist=title.split('|')[0].split('- song by')[1].strip()
|
||||
except:
|
||||
artist=title.split('|')[0].split('- Album by')[0].strip()
|
||||
try:
|
||||
artist=title.split('|')[0].split('- Album by')[1].strip()
|
||||
except:
|
||||
artist=title.split('by ')[1].split(' | ')[0]
|
||||
try:
|
||||
track=title.split(' - ')[0]
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
title=title.lower()
|
||||
|
||||
if track and artist:
|
||||
title=f'{artist} - {track}'.lower()
|
||||
data['title']=title
|
||||
data=self.check(nick,site,data)
|
||||
self.push(nick.lower(),site,title.lower(),token,url)
|
||||
###################################################################################
|
||||
if site=='bandcamp':
|
||||
offset=url.rfind('/')+1
|
||||
try:
|
||||
track=title.split('|')[0].lower().strip()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
artist=title.split('|')[1].lower().strip()
|
||||
title=f'{artist} - {track}'.lower()
|
||||
except:
|
||||
artist=""
|
||||
title=f'{artist}{track}'.lower()
|
||||
data['title']=title.lower()
|
||||
data=self.check(nick,site,data)
|
||||
self.push(nick.lower(),site,title.lower(),token,url)
|
||||
########################################### BOOMBOX CONFIG DATABASE OPERATIONS FOR URLS
|
||||
def token(self,url):
|
||||
bbs_token=self.dbdo('bbs_token','get')
|
||||
bbs_tokenmirror=self.dbdo('bbs_tokenmirror','get')
|
||||
S=list(string.ascii_letters+string.digits)
|
||||
random.shuffle(S)
|
||||
S=''.join(S)[:5]
|
||||
while S in [list(x.keys())[0] for x in bbs_token]:
|
||||
S=list(string.ascii_letters+string.digits)
|
||||
random.shuffle(S); S=''.join(S)[:5]
|
||||
return f'{S}'
|
||||
#################################### BOOMBOX CONFIG TEXT FILTERING BY STRIPPING UNICODE
|
||||
def no_unicode(self,s):
|
||||
if len(s) < 1: return s
|
||||
s=s.encode('ascii','ignore').decode()
|
||||
s=s.strip().replace(' ',' ')
|
||||
return s
|
||||
##### BOOMBOX CONFIG DB OPERATIONS - SUB-SCANNING RECORDS RETURNING CONDITIONAL BOOLEAN
|
||||
def dbskim(self,db,s):
|
||||
buffer=self.dbdo(db,'get')
|
||||
for _ in buffer:
|
||||
try:
|
||||
result=_[s]
|
||||
if result:
|
||||
return result
|
||||
except:
|
||||
pass
|
||||
##### BOOMBOX CONFIG DB OPERATIONS - SUB-SCANNING RECORDS RETURNING CONDITIONAL BOOLEAN
|
||||
def dbgaze(self,db,key,s):
|
||||
buffer=self.dbdo(db,'get')
|
||||
for i,_ in enumerate(buffer):
|
||||
try:
|
||||
result=(_[key]==s)
|
||||
if result:
|
||||
return i
|
||||
except:
|
||||
pass
|
||||
##### BOOMBOX CONFIG DB OPERATIONS - AUTOMATICALLY CREATES/REPAIRS/STAGES THE DATABASES
|
||||
@irc3.extend
|
||||
def db_diagnostics(self,database_name,*args):
|
||||
#######################################################################################
|
||||
# database_names = ['bbs_data','bbs_last','bbs_nicks','bbs_sites','bbs_token','bbs_tokenmirror']
|
||||
###################################################################################
|
||||
index=-1
|
||||
###################################################################################
|
||||
for i, database in enumerate(self.database_names):
|
||||
if database_name==database:
|
||||
index=i
|
||||
break
|
||||
print(f"<<< _____boombox_plugin >>> [ db_diagnostics - index: {index} - database: {database_name} ]")
|
||||
###################################################################################
|
||||
print(f'<<< _____boombox_plugin >>> [{index+1}/{len(self.database_names)}] - [ creating database: {self.database_names[index]} ]')
|
||||
automation_flag=False
|
||||
########################################################## database: 0/5 - bbs_data
|
||||
if database_name==self.database_names[0]:
|
||||
###############################################################################
|
||||
try:
|
||||
db=[]
|
||||
db.append({'nicks':{"dr1p":1},'title':'fenix flexin - 10 toes ( dr1ph0p m1x )','url':'https://soundcloud.com/vanta_sec/fenix-flexin-10-toes-dr1ph0p-m1x','token':'06660','timestamp':1658706829.869036,'site':'soundcloud','hits':1})
|
||||
self.bot.db.setlist(database_name,db)
|
||||
if db: automation_flag=not automation_flag
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
########################################################## database: 1/5 - bbs_last
|
||||
elif database_name==self.database_names[1]:
|
||||
###############################################################################
|
||||
try:
|
||||
db=[]
|
||||
for _ in range(0,self.bot.bbs.ceiling__last_songs):
|
||||
db.append('')
|
||||
db.pop()
|
||||
db.append(["dr1p","soundcloud","fenix flexin - 10 toes ( dr1ph0p m1x )","06660","https://soundcloud.com/vanta_sec/fenix-flexin-10-toes-dr1ph0p-m1x"])
|
||||
db.reverse()
|
||||
self.bot.db.setlist(database_name,db)
|
||||
if db: automation_flag=not automation_flag
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
######################################################### database: 2/5 - bbs_nicks
|
||||
elif database_name==self.database_names[2]:
|
||||
###############################################################################
|
||||
try:
|
||||
db=[]
|
||||
db.append({'dr1p':{'tally':1,'bandcamp':0,'soundcloud':1,'spotify':0,'youtube':0}})
|
||||
self.bot.db.setlist(database_name,db)
|
||||
if db: automation_flag=not automation_flag
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
##########################################################database: 3/5 - bbs_sites
|
||||
elif database_name==self.database_names[3]:
|
||||
###############################################################################
|
||||
try:
|
||||
db=[]
|
||||
db.append({'soundcloud':1,'youtube':0,'spotify':0,'bandcamp':0})
|
||||
self.bot.db.setlist(database_name,db)
|
||||
if db: automation_flag=not automation_flag
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
######################################################### database: 4/5 - bbs_token
|
||||
elif database_name==self.database_names[4]:
|
||||
###############################################################################
|
||||
try:
|
||||
db=[]
|
||||
db.append({'06660':'https://soundcloud.com/vanta_sec/fenix-flexin-10-toes-dr1ph0p-m1x'})
|
||||
self.bot.db.setlist(database_name,db)
|
||||
if db: automation_flag=not automation_flag
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
################################################### database: 5/5 - bbs_tokenmirror
|
||||
elif database_name==self.database_names[5]:
|
||||
###############################################################################
|
||||
try:
|
||||
db=[]
|
||||
db.append({'https://soundcloud.com/vanta_sec/fenix-flexin-10-toes-dr1ph0p-m1x':'06660'})
|
||||
self.bot.db.setlist(database_name,db)
|
||||
if db: automation_flag=not automation_flag
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
###################################################################################
|
||||
msg=f'<<< _____boombox_plugin >>> [{index+1}/{len(self.database_names)}] - [ {self.database_names[index]} created ]'
|
||||
if automation_flag:
|
||||
status='+++ success +++'
|
||||
else:
|
||||
status='--- failure ---'
|
||||
print(f'{msg} {status}')
|
||||
###################################################################################
|
||||
################################################################################### EOF
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,46 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3,ipdb
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def dr1pjack(self, mask, target, args):
|
||||
"""dr1pjack
|
||||
%%dr1pjack <message>...
|
||||
"""
|
||||
message=' '.join(args['<message>'])
|
||||
ipdb.set_trace()
|
||||
try:
|
||||
bio=globals()['dug'].memories[2][0]
|
||||
bio.motapi
|
||||
bio.roomid
|
||||
msg=f'bio.motapi:{bio.motapi}->{bio.roomid}->rebouncing<-message'
|
||||
bio.motapi(bio.roomid,msg)
|
||||
except Exception as e:
|
||||
print(f'dr1p_plugin:error - {e}')
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def dr1p(self, mask, target, args):
|
||||
"""dr1p
|
||||
%%dr1p
|
||||
"""
|
||||
ipdb.set_trace()
|
||||
msg=''
|
||||
self.bot.privmsg(target, msg)
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def list_rooms(self, mask, target, args):
|
||||
"""list_rooms
|
||||
%%list_rooms
|
||||
"""
|
||||
msg=f'{mask.nick}: [ list_rooms_plugin ] - api calling'
|
||||
self.bot.privmsg(target, self.bot.emo(msg))
|
||||
from plugins.net_matrix_plugin import joined_rooms as matrix_list_rooms
|
||||
result=matrix_list_rooms()
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,112 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import async_timeout
|
||||
headers = { 'authorization': 'Apikey 94e50805f19646893ee16424918998caad5ec6accff539a23ffee8e546eda4e3' }
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def cc(self, mask, target, args):
|
||||
"""Show Crypto Value
|
||||
%%cc <coin>
|
||||
"""
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
coin = args['<coin>'].upper()
|
||||
async def fetch(session, url):
|
||||
async with async_timeout.timeout(10):
|
||||
async with session.get(url) as response:
|
||||
return await response.json()
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
async def grab_url(url):
|
||||
async with aiohttp.ClientSession(headers=headers) as session:
|
||||
json_response = await fetch(session, url)
|
||||
return json_response
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
def parse_coin(response):
|
||||
try:
|
||||
task_result, _ = response.result()
|
||||
task1, task2, task3 = task_result
|
||||
rlist = sorted([task1.result(), task2.result(), task3.result()], key=lambda item: len(item.keys()))
|
||||
if rlist[1].get("USD"):
|
||||
price = rlist[1].get("USD")
|
||||
price_multi = rlist[2].get("DISPLAY")[coin].get("USD", {})
|
||||
daily_avg = rlist[0].get("USD")
|
||||
|
||||
elif rlist[2].get("USD"):
|
||||
price_multi = rlist[1].get("DISPLAY")[coin].get("USD", {})
|
||||
price = rlist[2].get("USD")
|
||||
daily_avg = rlist[0].get("USD")
|
||||
data_dict = {}
|
||||
for k, v in price_multi.items():
|
||||
if isinstance(v, str):
|
||||
v = v.replace("$","").replace(" ","").replace(",","")
|
||||
data_dict[k] = v
|
||||
price_multi = data_dict
|
||||
|
||||
X = float(daily_avg) # AVERAGE OF THE DAY
|
||||
P = float(price_multi.get('PRICE')) # PRICE CURRENTLY
|
||||
H = float(price_multi.get('HIGHDAY')) # HIGH OF THE DAY
|
||||
L = float(price_multi.get('LOWDAY')) # LOW OF THE DAY
|
||||
A = float(price) # AGGREGATED EXCHANGE
|
||||
Y = float(price_multi.get('CHANGE24HOUR')) # PRICE PERCENT DIFFERENTIAL 24 HOURS AGO
|
||||
C = float(price_multi.get('CHANGEPCT24HOUR'))
|
||||
|
||||
if C <= 0:
|
||||
C = "\x0304{}\x0F".format(C)
|
||||
else:
|
||||
C = "\x0303{}\x0F".format(C)
|
||||
if Y <= 0:
|
||||
Y = "\x0304{}\x0F".format(Y)
|
||||
else:
|
||||
Y = "\x0303{}\x0F".format(Y)
|
||||
|
||||
symbol = price_multi.get('FROMSYMBOL')
|
||||
msg = "\x02\x0302[ {coin:}/{symbol:} ]\x0F @\x0303${p:,}\x0F ::: H\x0303${h:,}\x0F L\x0303${l:,}\x0F ::: Y${y:} @ %{c:} ::: X\x0303${x:,}\x0F A\x0303${a:,}\x0F".format(coin=coin, symbol=symbol, p=P, h=H, l=L, y=Y,c=C, x=X, a=A)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
except Exception as e:
|
||||
msg = self.bot.emo('their api is glitching: check back later')
|
||||
self.bot.privmsg(target, msg)
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
def process_lookups(response):
|
||||
try:
|
||||
html = response.result()
|
||||
except Exception as e:
|
||||
msg = self.bot.emo('site error: {}'.format(e.message))
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
coin_result = html.get("Data",{}).get(coin, None)
|
||||
if not coin_result:
|
||||
msg = self.bot.emo('Invalid coin - see https://min-api.cryptocompare.com/data/all/coinlist data keys')
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
day_avg_url = "https://min-api.cryptocompare.com/data/dayAvg?fsym={}&tsym=USD&api_key=94e50805f19646893ee16424918998caad5ec6accff539a23ffee8e546eda4e3".format(coin)
|
||||
price_multi_url = "https://min-api.cryptocompare.com/data/pricemultifull?fsyms={}&tsyms=USD&api_key=94e50805f19646893ee16424918998caad5ec6accff539a23ffee8e546eda4e3".format(coin)
|
||||
price_url = "https://min-api.cryptocompare.com/data/price?fsym={}&tsyms=USD&api_key=94e50805f19646893ee16424918998caad5ec6accff539a23ffee8e546eda4e3".format(coin)
|
||||
tasks = [asyncio.ensure_future(grab_url(day_avg_url)),
|
||||
asyncio.ensure_future(grab_url(price_multi_url)),
|
||||
asyncio.ensure_future(grab_url(price_url))]
|
||||
task = self.bot.create_task(asyncio.wait(tasks))
|
||||
task.add_done_callback(parse_coin)
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
url = "https://min-api.cryptocompare.com/data/all/coinlist"
|
||||
asyncio.ensure_future(grab_url(url), loop=self.bot.loop).add_done_callback(process_lookups)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
###########################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,41 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import random
|
||||
import os
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.extend
|
||||
def emo(self,s):
|
||||
emote_db = '%s/../databases/emote.db' % dir_path
|
||||
emoj = random.choice(list(open(emote_db)))
|
||||
random.randint(0,1)
|
||||
if random.randint(0,1) == 0:
|
||||
emoj = "\x0304{}\x0F".format(emoj)
|
||||
else:
|
||||
emoj = "\x0303{}\x0F".format(emoj)
|
||||
s = s + '\x0303 > ' + emoj
|
||||
return s
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def emote(self, mask, target, args):
|
||||
"""Show Emotion
|
||||
%%emote
|
||||
"""
|
||||
def __random_line():
|
||||
emote_db = '%s/../databases/emote.db' % dir_path
|
||||
return random.choice(list(open(emote_db)))
|
||||
emoj = __random_line()
|
||||
self.bot.privmsg(target, "%s" % emoj)
|
||||
###########################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,101 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import os
|
||||
import irc3
|
||||
from stat import S_ISFIFO
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Fifo:
|
||||
#######################################################################################
|
||||
BLOCK_SIZE = 1024
|
||||
MAX_BUFFER_SIZE = 800
|
||||
#######################################################################################
|
||||
def __init__(self, context):
|
||||
self.context = context
|
||||
self.config = self.context.config
|
||||
self.send_blank_line = self.config.get('send_blank_line', True)
|
||||
self.runpath = self.config.get('runpath', f'{os.getcwd()}/fifo')
|
||||
if not os.path.exists(self.runpath):
|
||||
os.makedirs(self.runpath)
|
||||
self.loop = self.context.loop
|
||||
self.fifos = {}
|
||||
self.buffers = {}
|
||||
self.create_fifo(None)
|
||||
#######################################################################################
|
||||
@classmethod
|
||||
def read_fd(cls, fd):
|
||||
while True:
|
||||
try:
|
||||
return os.read(fd, cls.BLOCK_SIZE)
|
||||
except InterruptedError:
|
||||
continue
|
||||
except BlockingIOError:
|
||||
return b""
|
||||
#######################################################################################
|
||||
def handle_line(self, line, channel):
|
||||
if not line:
|
||||
return
|
||||
line = line.decode("utf8")
|
||||
if not self.send_blank_line and not line.strip():
|
||||
return
|
||||
if channel is None:
|
||||
self.context.send_line(line)
|
||||
else:
|
||||
self.context.privmsg(channel, line)
|
||||
#######################################################################################
|
||||
def data_received(self, data, channel):
|
||||
if not data:
|
||||
return
|
||||
prev = self.buffers.get(channel, b"")
|
||||
lines = (prev + data).splitlines(True)
|
||||
last = lines[-1]
|
||||
for line in lines[:-1]:
|
||||
line = line.rstrip(b'\r\n')
|
||||
self.handle_line(line, channel)
|
||||
if last.endswith(b'\n'):
|
||||
line = last.rstrip(b'\r\n')
|
||||
self.handle_line(line, channel)
|
||||
self.buffers[channel] = b""
|
||||
return
|
||||
if len(last) > self.MAX_BUFFER_SIZE:
|
||||
self.handle_line(last, channel)
|
||||
self.buffers[channel] = b""
|
||||
else:
|
||||
self.buffers[channel] = last
|
||||
#######################################################################################
|
||||
def watch_fd(self, fd, channel):
|
||||
reading = True
|
||||
|
||||
while reading:
|
||||
data = self.read_fd(fd)
|
||||
reading = len(data) == self.BLOCK_SIZE
|
||||
self.data_received(data, channel)
|
||||
#######################################################################################
|
||||
def create_fifo(self, channel):
|
||||
if channel is None:
|
||||
path = os.path.join(self.runpath, ':raw')
|
||||
else:
|
||||
path = os.path.join(self.runpath, channel.strip('#&+'))
|
||||
try:
|
||||
mode = os.stat(path).st_mode
|
||||
except OSError:
|
||||
pass
|
||||
else:
|
||||
if not S_ISFIFO(mode):
|
||||
self.context.log.warn(
|
||||
'file %s created without mkfifo. remove it',
|
||||
path)
|
||||
os.remove(path)
|
||||
if not os.path.exists(path):
|
||||
os.mkfifo(path)
|
||||
fd = os.open(path, os.O_RDWR | os.O_NONBLOCK)
|
||||
self.loop.add_reader(fd, self.watch_fd, fd, channel)
|
||||
self.context.log.debug("%s's fifo is %s %r",
|
||||
channel or ':raw', path, fd)
|
||||
return fd
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.JOIN)
|
||||
def join(self, mask=None, channel=None, **kwargs):
|
||||
if mask.nick == self.context.nick:
|
||||
if channel not in self.fifos:
|
||||
self.fifos[channel] = self.create_fifo(channel)
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,58 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import pyfiglet
|
||||
import random
|
||||
###########################################################################################
|
||||
fig = pyfiglet.Figlet(width=100)
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.fig_fonts = set(self.bot.db.getlist("fig_font_list", []))
|
||||
if not self.fig_fonts:
|
||||
self.fig_fonts = fig.getFonts()
|
||||
self.bot.db.setlist("fig_font_list", self.fig_fonts)
|
||||
#######################################################################################
|
||||
@irc3.extend
|
||||
def fig(self, text, font=None):
|
||||
if font in self.fig_fonts:
|
||||
fig.setFont(font=font)
|
||||
else:
|
||||
font = random.choice(list(self.fig_fonts))
|
||||
return fig.renderText(text)
|
||||
#######################################################################################
|
||||
@command(permission='view', name="fig", public=True, show_in_help_list=True)
|
||||
def figcmd(self, mask, target, args):
|
||||
"""Print figlet Text
|
||||
%%fig <cmdmsg>...
|
||||
"""
|
||||
cmdmsg = ' '.join(args['<cmdmsg>'])
|
||||
cmd = ' '.join(cmdmsg.split()[:1])
|
||||
msg = ' '.join(cmdmsg.split()[1:])
|
||||
font = cmd
|
||||
text = msg
|
||||
if font == "list":
|
||||
font_list = self.bot.db.getlist("fig_font_list")
|
||||
self.bot.privmsg(target, "Current Fig Fonts {}".format(",".join(font_list)))
|
||||
return
|
||||
if font == "ignore":
|
||||
ignored_font = args.get("<text>")
|
||||
self.fig_fonts.remove(ignored_font)
|
||||
self.bot.db.setlist("fig_font_list", self.fig_fonts)
|
||||
self.bot.privmsg(target, "Ignoring {}".format(ignored_font))
|
||||
return
|
||||
if text is not None and font in self.fig_fonts:
|
||||
msg = self.bot.emo(font)
|
||||
self.bot.privmsg(target, msg)
|
||||
fig_text = self.fig(text=text, font=font)
|
||||
else:
|
||||
newfont = random.choice(list(self.fig_fonts))
|
||||
msg = self.bot.emo(newfont)
|
||||
self.bot.privmsg(target, msg)
|
||||
fig_text = self.fig(text=font, font=newfont) # Cause weird command format
|
||||
for line in fig_text.split("\n"):
|
||||
self.bot.privmsg(target, line)
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,55 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
from lxml.html import fromstring
|
||||
from googlesearch import search
|
||||
import irc3,os,sys,requests
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
def __get_tiny_url(self, url):
|
||||
tiny_url = 'http://tinyurl.com/api-create.php?url=%s' % url
|
||||
r = requests.get(tiny_url)
|
||||
return r.text
|
||||
#######################################################################################
|
||||
@command(permission='view', public=True, show_in_help_list=True)
|
||||
def g(self, mask, target, args):
|
||||
"""Google Query
|
||||
%%g <query>...
|
||||
"""
|
||||
query = ' '.join(args['<query>'])
|
||||
for j in search(query):
|
||||
result = "{}".format(j)
|
||||
url = result
|
||||
read_size = 0
|
||||
try:
|
||||
r = requests.get(url, timeout=3, stream=True)
|
||||
content_type = r.headers.get("Content-Type")
|
||||
content_length = r.headers.get('Content-Length')
|
||||
if not content_length:
|
||||
content_length = 0
|
||||
if not content_type.startswith("text/html"):
|
||||
return
|
||||
if int(content_length) > 200000:
|
||||
self.bot.privmsg(target, "pre-fetch aborted -> fuck your large ass content")
|
||||
while read_size <= (2000 * 10):
|
||||
for content in r.iter_content(chunk_size=2000):
|
||||
tree = fromstring(content)
|
||||
title = tree.find(".//title")
|
||||
if title is not None:
|
||||
title = title.text.strip()[:100]
|
||||
#Tiny URL
|
||||
#if len(url) >= 60:
|
||||
# url = self.__get_tiny_url(url)
|
||||
#url = archiveis.capture(url)
|
||||
msg = "\x02{nick:}\x0F\x02\x0303 > \x0F\x02\x0312{url:}\x0F\x0303 > \x0F\x1D\x0314{title:}\x0F".format(nick=mask.nick,url=url,title=title)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target,self.bot.emo(msg))
|
||||
read_size = read_size + 2000
|
||||
except Exception as e:
|
||||
print("%s" % e)
|
||||
pass
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,128 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import random
|
||||
import os
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot=bot
|
||||
#######################################################################################
|
||||
def __color(self,c):
|
||||
try:
|
||||
c=str(c.lower())
|
||||
if c=='0': return '\x0300'
|
||||
if c=='1': return '\x0301'
|
||||
if c=='2': return '\x0302'
|
||||
if c=='3': return '\x0303'
|
||||
if c=='4': return '\x0304'
|
||||
if c=='5': return '\x0305'
|
||||
if c=='6': return '\x0306'
|
||||
if c=='7': return '\x0307'
|
||||
if c=='8': return '\x0308'
|
||||
if c=='9': return '\x0309'
|
||||
if c=='a': return '\x0310'
|
||||
if c=='b': return '\x0311'
|
||||
if c=='c': return '\x0312'
|
||||
if c=='d': return '\x0313'
|
||||
if c=='e': return '\x0314'
|
||||
if c=='f': return '\x0315'
|
||||
if c=='n': return ''
|
||||
if c=='t': return '\x0f'
|
||||
print('_color: empty')
|
||||
return '\x0f'
|
||||
except:
|
||||
print('_color: error')
|
||||
return '\x0f'
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view',public=True,show_in_help_list=True)
|
||||
def hl(self, mask, target, args):
|
||||
"""hl - use a chosen or random color palette that will iterate a message to whichever ircnick you pick.
|
||||
c1,c2,c3,c4,s1,s2,s3,s4,s5,s6 accept a color range of 0-15 and symbol range of 0-30. usage: ?hl c1,c2,c3,c4,s1,s2,s3,s4,s5,s6 ircnick n message.
|
||||
uses specified colors & symbols, tags ircnick dr1p with hello message 10 times. example 1: ?hl 8,12,9,13,3,4 dr1p 10 hello.
|
||||
uses a random color palette, tags ircnick dr1p with hello message 10 times. example 2: ?hl dr1p 10 hello.
|
||||
uses a random color palette, tags ircnick dr1p with hello message 1 time. example 3: ?hl dr1p hello.
|
||||
%%hl <message>...
|
||||
"""
|
||||
###################################################################################
|
||||
try:
|
||||
message=' '.join(args['<message>']).strip()
|
||||
channel=self.bot.channels[target]
|
||||
c1=random.randint(0,15)
|
||||
c2=random.randint(0,15)
|
||||
c3=random.randint(0,15)
|
||||
c4=random.randint(0,15)
|
||||
symbols=['╲╱','══','╀╀','▓▓','◨◧','◎◎','╳╳','░░','◅▻','▖▗','▤▤','╼╾','▒▒','┹┺','╮╭','╷╷','┒┎','┿┿','▛▜','◸◹','▚▞','┓┏','╏╏','┥┝','╽╽','┛┗','◊◊','╌','║║','◫◫','▭▭']
|
||||
n1=random.randint(0,len(symbols)-1),random.randint(0,len(symbols)-1),random.randint(0,len(symbols)-1)
|
||||
s1=[f'{symbols[n1[0]][0]}{symbols[n1[1]][0]}{symbols[n1[2]][0]}',f'{symbols[n1[2]][1]}{symbols[n1[1]][1]}{symbols[n1[0]][1]}']
|
||||
n2=random.randint(0,len(symbols)-1),random.randint(0,len(symbols)-1),random.randint(0,len(symbols)-1)
|
||||
s2=[f'{symbols[n2[0]][0]}{symbols[n2[1]][0]}{symbols[n2[2]][0]}',f'{symbols[n2[2]][1]}{symbols[n2[1]][1]}{symbols[n2[0]][1]}']
|
||||
GOT_PALETTE=''; palette=''
|
||||
GOT_IRCNICK=''; ircnick=mask.nick
|
||||
GOT_ITERATIONS=''; iterations=1
|
||||
###############################################################################
|
||||
for palette in message.split():
|
||||
try:
|
||||
if len(palette.split(','))==10:
|
||||
GOT_PALETTE=palette
|
||||
break
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
for ircnick in message.split():
|
||||
try:
|
||||
if ircnick in channel:
|
||||
GOT_IRCNICK=ircnick
|
||||
break
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
for iterations in message.split():
|
||||
try:
|
||||
if int(iterations)>0:
|
||||
GOT_ITERATIONS=int(iterations)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
###############################################################################
|
||||
if GOT_IRCNICK:
|
||||
message=message.replace(GOT_IRCNICK,'')
|
||||
ircnick=GOT_IRCNICK
|
||||
else:
|
||||
ircnick=mask.nick
|
||||
if GOT_PALETTE:
|
||||
message=message.replace(GOT_PALETTE,'')
|
||||
palette=GOT_PALETTE
|
||||
c1=int(palette.split(',')[0])
|
||||
c2=int(palette.split(',')[1])
|
||||
c3=int(palette.split(',')[2])
|
||||
c4=int(palette.split(',')[3])
|
||||
n1=int(palette.split(',')[4]),int(palette.split(',')[5]),int(palette.split(',')[6])
|
||||
n2=int(palette.split(',')[7]),int(palette.split(',')[8]),int(palette.split(',')[9])
|
||||
s1=[f'{symbols[n1[0]][0]}{symbols[n1[1]][0]}{symbols[n1[2]][0]}',f'{symbols[n1[2]][1]}{symbols[n1[1]][1]}{symbols[n1[0]][1]}']
|
||||
s2=[f'{symbols[n2[0]][0]}{symbols[n2[1]][0]}{symbols[n2[2]][0]}',f'{symbols[n2[2]][1]}{symbols[n2[1]][1]}{symbols[n2[0]][1]}']
|
||||
if GOT_ITERATIONS:
|
||||
message=message.replace(str(GOT_ITERATIONS),'')
|
||||
iterations=GOT_ITERATIONS
|
||||
else:
|
||||
iterations=1
|
||||
###############################################################################
|
||||
message=message.strip()
|
||||
for i in range(int(iterations)):
|
||||
h1=self.__color(hex(c1)[2:])
|
||||
h2=self.__color(hex(c2)[2:])
|
||||
h3=self.__color(hex(c3)[2:])
|
||||
h4=self.__color(hex(c4)[2:])
|
||||
msg=f'{h1}{s1[0]} {h2}{ircnick} {h1}{s1[1]} {h3}{s2[0]} {h4}{message} {h3}{s2[1]} {h1}{s1[0]} {h2}{ircnick} {h1}{s1[1]}\x20'
|
||||
if not GOT_PALETTE: msg+=f"{h1}{str(c1).zfill(2)},{h2}{str(c2).zfill(2)},{h3}{str(c3).zfill(2)},{h4}{str(c4).zfill(2)},{h1}{str(n1[0]).zfill(2)},{str(n1[1]).zfill(2)},{str(n1[2]).zfill(2)},{h3}{str(n2[0]).zfill(2)},{str(n2[1]).zfill(2)},{str(n2[2]).zfill(2)}"
|
||||
self.bot.privmsg(target,self.bot.emo(msg))
|
||||
###############################################################################
|
||||
###################################################################################
|
||||
except Exception as e:
|
||||
msg=f"{mask.nick}: highlight_plugin:hl - error: {e}"
|
||||
self.bot.privmsg(target,self.bot.emo(msg))
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,84 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import URLError, HTTPError
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def isup_check(self, domain_or_ip):
|
||||
msg=''
|
||||
try:
|
||||
url=f'http://{domain_or_ip}'
|
||||
try:
|
||||
req = Request(
|
||||
url,
|
||||
data=None,
|
||||
headers={
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
|
||||
}
|
||||
)
|
||||
response=urlopen(req,timeout=10).read().decode('utf-8')
|
||||
except HTTPError as e:
|
||||
msg='maybe -> could not complete the request. error code: {}'.format(e.code)
|
||||
except URLError as e:
|
||||
msg='down -> failed to reach the server. reason: {}'.format(e.reason)
|
||||
else:
|
||||
msg=f'up -> http://{domain_or_ip} is communicating'
|
||||
except:
|
||||
url=f'https://{domain_or_ip}'
|
||||
try:
|
||||
req = Request(
|
||||
url,
|
||||
data=None,
|
||||
headers={
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
|
||||
}
|
||||
)
|
||||
response=urlopen(req,timeout=10).read().decode('utf-8')
|
||||
except HTTPError as e:
|
||||
msg='maybe -> could not complete the request. error code: {}'.format(e.code)
|
||||
except URLError as e:
|
||||
msg='down -> failed to reach the server. reason: {}'.format(e.reason)
|
||||
else:
|
||||
msg=f'up -> https://{domain_or_ip} is communicating'
|
||||
finally:
|
||||
return msg
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def isup(self, mask, target, args):
|
||||
"""isup domain
|
||||
%%isup <domain>
|
||||
"""
|
||||
domain=args.get('<domain>')
|
||||
domain_noise=domain
|
||||
try:
|
||||
domain_noise=domain.split('://')[1]
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
if not domain_noise:
|
||||
domain_noise=domain[:domain.find('.')+domain[domain.find('.')+1:].find('/')+1].split('://')[1]
|
||||
except:
|
||||
if not domain_noise.find('/')==-1:
|
||||
domain_noise=domain[:domain.find('.')+domain[domain.find('.')+1:].find('/')+1].split('://')[0]
|
||||
if domain_noise[-1]=="/": domain_noise=domain_noise[:-1]
|
||||
if domain_noise[:domain_noise.find(':')].replace('.','').isnumeric() and (len(domain_noise[:domain_noise.find(':')])-3)==len(domain_noise[:domain_noise.find(':')].replace('.','')):
|
||||
domain=domain_noise
|
||||
elif domain_noise.replace('.','').isnumeric() and (len(domain_noise)-3) == len(domain_noise.replace('.','')):
|
||||
domain=domain_noise
|
||||
elif domain_noise.find('/') == -1 and not domain_noise.find('.') == -1 and domain_noise.replace('.','').isalnum():
|
||||
domain=domain_noise
|
||||
else:
|
||||
self.bot.privmsg(target,self.bot.emo("{}: doesn't sanitize towards a valid domain/ip".format(domain)))
|
||||
return
|
||||
self.bot.privmsg(target,self.bot.emo("{}".format(self.isup_check(domain))))
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import URLError, HTTPError
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot=bot
|
||||
self.site_url="https://icanhazdadjoke.com"
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def urlget(self,url):
|
||||
USER_AGENT_CURL="curl/7.78.0"
|
||||
ACCEPT_MODES="text/plain"
|
||||
STATUS_BAD_CODE=":( - error code: {}"
|
||||
STATUS_BAD_REASON=":( - failed reason: {}"
|
||||
STATUS_OK=":)"
|
||||
r = Request(url,data=None,headers={ 'user-agent': USER_AGENT_CURL, 'accept': ACCEPT_MODES })
|
||||
try: response = urlopen(r,timeout=15).read().decode('utf-8')
|
||||
except HTTPError as e: return STATUS_BAD_CODE.format(e.code)
|
||||
except URLError as e: return STATUS_BAD_REASON.format(e.reason)
|
||||
else: return STATUS_OK + response
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.extend
|
||||
@command(permission='view')
|
||||
def joke(self, mask, target, args):
|
||||
"""joke
|
||||
%%joke
|
||||
"""
|
||||
response=self.urlget(self.site_url)[2:]
|
||||
for msg in response.splitlines():
|
||||
if len(msg) > 1:
|
||||
self.bot.privmsg(target, self.bot.emo(msg))
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,522 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import os
|
||||
import io
|
||||
import irc3
|
||||
from difflib import SequenceMatcher
|
||||
import requests
|
||||
from tqdm import tqdm
|
||||
from glob import glob
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
import numpy as np
|
||||
import signal
|
||||
import configparser
|
||||
import logging
|
||||
import random
|
||||
from transformers import GPT2Config,GPT2LMHeadModel,GPT2Tokenizer
|
||||
from datetime import datetime
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from time import time
|
||||
###########################################################################################
|
||||
class MESSAGE_HISTORY():
|
||||
#######################################################################################
|
||||
maple_messages = []
|
||||
maple_emotions = []
|
||||
user_messages = []
|
||||
user_users = []
|
||||
last_message = ''
|
||||
last_emotion = ''
|
||||
maple_message = ''
|
||||
#######################################################################################
|
||||
def __init__(self):
|
||||
self.processing=0
|
||||
self.bounce=False
|
||||
self.loopcount=0
|
||||
#######################################################################################
|
||||
def push_maple_messages(self,data):
|
||||
self.maple_messages = self.maple_messages[-1:] + self.maple_messages[:-1]
|
||||
self.maple_messages[0] = data
|
||||
#######################################################################################
|
||||
def push_user_messages(self,user,data):
|
||||
self.user_users.append(user)
|
||||
self.user_messages.append(data)
|
||||
#######################################################################################
|
||||
def push_maple_emotions(self,data):
|
||||
self.maple_emotions.append(data)
|
||||
#######################################################################################
|
||||
def similar(self,a,b):
|
||||
return SequenceMatcher(None,a,b).ratio()
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
PoolExecutor=ThreadPoolExecutor
|
||||
#######################################################################################
|
||||
terminate=False
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
|
||||
logger=logging.getLogger(__name__)
|
||||
#######################################################################################
|
||||
CONFIG_FILE={
|
||||
'small':'https://convaisharables.blob.core.windows.net/lsp/117M/config.json',
|
||||
'medium':'https://convaisharables.blob.core.windows.net/lsp/345M/config.json'
|
||||
}
|
||||
#######################################################################################
|
||||
VOCAB_FILE={
|
||||
'small':'https://convaisharables.blob.core.windows.net/lsp/117M/vocab.json',
|
||||
'medium':'https://convaisharables.blob.core.windows.net/lsp/345M/vocab.json'
|
||||
}
|
||||
#######################################################################################
|
||||
MERGE_FILE={
|
||||
'small':'https://convaisharables.blob.core.windows.net/lsp/117M/merges.txt',
|
||||
'medium':'https://convaisharables.blob.core.windows.net/lsp/345M/merges.txt'
|
||||
}
|
||||
#######################################################################################
|
||||
LSP_MODEL_URL={
|
||||
'multiref':{
|
||||
'medium_fs':'https://convaisharables.blob.core.windows.net/lsp/multiref/medium_fs.pkl',
|
||||
'medium_ft':'https://convaisharables.blob.core.windows.net/lsp/multiref/medium_ft.pkl',
|
||||
'small_fs':'https://convaisharables.blob.core.windows.net/lsp/multiref/small_fs.pkl',
|
||||
'small_ft':'https://convaisharables.blob.core.windows.net/lsp/multiref/small_ft.pkl'
|
||||
},
|
||||
'dstc':{
|
||||
'small_ft':'https://convaisharables.blob.core.windows.net/lsp/DSTC/medium_ft.pkl'
|
||||
}
|
||||
}
|
||||
#######################################################################################
|
||||
REVERSE_MODEL_URL='https://convaisharables.blob.core.windows.net/lsp/multiref/small_reverse.pkl'
|
||||
OPINION="""
|
||||
"""
|
||||
#######################################################################################
|
||||
WISDOM="""
|
||||
"""
|
||||
#######################################################################################
|
||||
PERSONALITY="""
|
||||
[model]
|
||||
data_folder=models
|
||||
model_size=medium
|
||||
dataset=multiref
|
||||
from_scratch=True
|
||||
no_cuda=False
|
||||
use_mmi=False
|
||||
[decoder]
|
||||
seed=0
|
||||
temperature=0.6474
|
||||
top_k=40
|
||||
top_p=0
|
||||
max_length=1024
|
||||
num_samples=1
|
||||
max_turns_history=-1
|
||||
"""
|
||||
#######################################################################################
|
||||
def __init__(self,bot):
|
||||
self.bot=bot
|
||||
self.bot.history=MESSAGE_HISTORY()
|
||||
#############################################
|
||||
for _ in range(5):
|
||||
self.bot.history.maple_messages.append("")
|
||||
#############################################
|
||||
self.mode=0
|
||||
self.span=0
|
||||
self.epoch_time_last=0
|
||||
self.epoch_time_now=0
|
||||
self.epoch_time_boolean=False
|
||||
self.maple_io=[]
|
||||
self.PERSONALITY=self.PERSONALITY.format(RND=datetime.now().microsecond)
|
||||
self.delay=0.05
|
||||
CONFIG=io.StringIO(self.PERSONALITY)
|
||||
self.config=configparser.ConfigParser()
|
||||
self.config.read_file(CONFIG)
|
||||
self.target_folder_name=self.download_model_folder(self.config)
|
||||
self.model,self.tokenizer=self.load_model(self.target_folder_name,self.config)
|
||||
self.use_mmi=self.config.getboolean('model','use_mmi')
|
||||
if self.use_mmi:
|
||||
self.mmi_target_folder_name=self.download_reverse_model_folder(self.config)
|
||||
self.mmi_model,mmi_tokenizer=self.load_model(self.mmi_target_folder_name,self.config)
|
||||
else:
|
||||
self.mmi_model=None
|
||||
self.mmi_tokenizer=None
|
||||
self.main()
|
||||
loop=self.bot.loop
|
||||
loop.call_later(self.delay,self.main)
|
||||
#######################################################################################
|
||||
def signal_handling(self,signum,frame):
|
||||
self.terminate=True
|
||||
#######################################################################################
|
||||
def http_get(self,url,temp_file):
|
||||
req=requests.get(url,stream=True)
|
||||
content_length=req.headers.get('Content-Length')
|
||||
total=int(content_length) if content_length is not None else None
|
||||
progress=tqdm(unit="B",total=total)
|
||||
for chunk in req.iter_content(chunk_size=1024):
|
||||
if chunk:
|
||||
progress.update(len(chunk))
|
||||
temp_file.write(chunk)
|
||||
progress.close()
|
||||
#######################################################################################
|
||||
def download_file(self,url,folder):
|
||||
if not os.path.exists(folder):
|
||||
os.makedirs(folder,exist_ok=True)
|
||||
file_name=os.path.basename(url)
|
||||
if 'pytorch_model.bin' in file_name:
|
||||
file_name='pytorch_model.bin'
|
||||
if os.path.isfile(os.path.join(folder,file_name)):
|
||||
return
|
||||
with open(os.path.join(folder,file_name),'wb') as f:
|
||||
self.http_get(url,f)
|
||||
#######################################################################################
|
||||
def download_model_folder(self,config):
|
||||
data_folder=config.get('model','data_folder')
|
||||
model_size=config.get('model','model_size')
|
||||
dataset=config.get('model','dataset')
|
||||
from_scratch=config.getboolean('model','from_scratch')
|
||||
if not os.path.exists(data_folder):
|
||||
os.makedirs(data_folder, exist_ok=True)
|
||||
target_folder_name=model_size+"_"+dataset+("_fs" if from_scratch else "_ft")
|
||||
target_folder=os.path.join(data_folder,target_folder_name)
|
||||
self.logger.info(f"Downloading model files to {target_folder_name}...")
|
||||
self.download_file(self.CONFIG_FILE[model_size],target_folder)
|
||||
self.download_file(self.VOCAB_FILE[model_size],target_folder)
|
||||
self.download_file(self.MERGE_FILE[model_size],target_folder)
|
||||
model_train_type=model_size+('_fs' if from_scratch else '_ft')
|
||||
if model_train_type not in self.LSP_MODEL_URL[dataset]:
|
||||
k=','.join(list(self.LSP_MODEL_URL[dataset].keys()))
|
||||
raise ValueError(f"'{model_train_type}' not exist for dataset '{dataset}', please choose from [{k}]")
|
||||
self.download_file(self.LSP_MODEL_URL[dataset][model_train_type],target_folder)
|
||||
return target_folder_name
|
||||
#######################################################################################
|
||||
def download_reverse_model_folder(self,config):
|
||||
data_folder=config.get('model','data_folder')
|
||||
model_size='medium'
|
||||
if not os.path.exists(data_folder):
|
||||
os.makedirs(data_folder,exist_ok=True)
|
||||
target_folder_name=model_size+'_reverse'
|
||||
target_folder=os.path.join(data_folder,target_folder_name)
|
||||
self.logger.info(f"Downloading model files to {target_folder_name}...")
|
||||
self.download_file(self.CONFIG_FILE[model_size],target_folder)
|
||||
self.download_file(self.VOCAB_FILE[model_size],target_folder)
|
||||
self.download_file(self.MERGE_FILE[model_size],target_folder)
|
||||
self.download_file(self.REVERSE_MODEL_URL,target_folder)
|
||||
return target_folder_name
|
||||
#######################################################################################
|
||||
def load_model(self,target_folder_name,config):
|
||||
data_folder=config.get('model','data_folder')
|
||||
model_size=config.get('model','model_size')
|
||||
no_cuda=config.getboolean('model', 'no_cuda')
|
||||
self.logger.info(f"Loading model from {target_folder_name}...")
|
||||
device=torch.device("cuda" if torch.cuda.is_available() and not no_cuda else "cpu")
|
||||
target_folder=os.path.join(data_folder,target_folder_name)
|
||||
tokenizer=GPT2Tokenizer(os.path.join(target_folder, 'vocab.json'), os.path.join(target_folder,'merges.txt'))
|
||||
config=GPT2Config.from_json_file(os.path.join(target_folder,'config.json'))
|
||||
state_dict_path=glob(os.path.join(target_folder,f'*.pkl'))[0]
|
||||
state_dict=torch.load(state_dict_path,map_location=device)
|
||||
if model_size=='small':
|
||||
for key in list(state_dict.keys()):
|
||||
state_dict[key.replace('module.','')]=state_dict.pop(key)
|
||||
state_dict['lm_head.weight']=state_dict['lm_head.decoder.weight']
|
||||
state_dict.pop("lm_head.decoder.weight",None)
|
||||
model=GPT2LMHeadModel(config)
|
||||
model.load_state_dict(state_dict)
|
||||
model.to(device)
|
||||
model.eval()
|
||||
return model,tokenizer
|
||||
#######################################################################################
|
||||
def set_seed(self,seed):
|
||||
random.seed(seed)
|
||||
np.random.seed(seed)
|
||||
torch.manual_seed(seed)
|
||||
#######################################################################################
|
||||
def top_k_top_p_filtering(self,logits,top_k=0,top_p=0.0,filter_value=-float('Inf')):
|
||||
top_k=min(top_k,logits.size(-1))
|
||||
if top_k>0:
|
||||
indices_to_remove=logits<torch.topk(logits,top_k)[0][...,-1,None]
|
||||
logits[indices_to_remove]=filter_value
|
||||
if top_p>0.0:
|
||||
sorted_logits,sorted_indices=torch.sort(logits,descending=True)
|
||||
cumulative_probs=torch.cumsum(F.softmax(sorted_logits,dim=-1),dim=-1)
|
||||
sorted_indices_to_remove=cumulative_probs>top_p
|
||||
sorted_indices_to_remove[...,1:]=sorted_indices_to_remove[...,:-1].clone()
|
||||
sorted_indices_to_remove[...,0]=0
|
||||
indices_to_remove=sorted_indices_to_remove.scatter(dim=1,index=sorted_indices,src=sorted_indices_to_remove)
|
||||
logits[indices_to_remove]=filter_value
|
||||
return logits
|
||||
#######################################################################################
|
||||
def sample_sequence(self,model,tokenizer,context_ids,config):
|
||||
no_cuda=config.getboolean('model','no_cuda')
|
||||
num_samples=config.getint('decoder','num_samples')
|
||||
max_length=config.getint('decoder','max_length')
|
||||
temperature=config.getfloat('decoder','temperature')
|
||||
top_k=config.getint('decoder','top_k')
|
||||
top_p=config.getfloat('decoder','top_p')
|
||||
device=torch.device("cuda" if torch.cuda.is_available() and not no_cuda else "cpu")
|
||||
context_tensor=torch.tensor(context_ids,dtype=torch.long,device=device)
|
||||
context_tensor=context_tensor.unsqueeze(0).repeat(num_samples,1)
|
||||
generated=context_tensor
|
||||
with torch.no_grad():
|
||||
while True:
|
||||
inputs={'input_ids':generated}
|
||||
outputs=model(**inputs)
|
||||
next_token_logits=outputs[0][:,-1,:]/(temperature if temperature>0 else 1.)
|
||||
filtered_logits=self.top_k_top_p_filtering(next_token_logits,top_k=top_k,top_p=top_p)
|
||||
if temperature==0.0:
|
||||
next_token=torch.argmax(filtered_logits,dim=-1).unsqueeze(-1)
|
||||
else:
|
||||
next_token=torch.multinomial(F.softmax(filtered_logits,dim=-1),num_samples=1)
|
||||
generated=torch.cat((generated,next_token),dim=1)
|
||||
if (generated[:,len(context_ids):]==tokenizer.eos_token_id).any(dim=1).all():
|
||||
break
|
||||
if generated.shape[1]-len(context_ids)>=max_length:
|
||||
break
|
||||
return generated
|
||||
#######################################################################################
|
||||
def select_using_mmi(self,mmi_model,mmi_tokenizer,candidates,config):
|
||||
no_cuda=config.getboolean('model','no_cuda')
|
||||
device=torch.device("cuda" if torch.cuda.is_available() and not no_cuda else "cpu")
|
||||
scores=[]
|
||||
for i,candidate in enumerate(candidates):
|
||||
context=[]
|
||||
for response in reversed(candidate):
|
||||
context.extend(response)
|
||||
context.append(mmi_tokenizer.eos_token_id)
|
||||
context_ids=mmi_tokenizer.encode(context)
|
||||
context_tensor=torch.tensor(context_ids,dtype=torch.long,device=device)
|
||||
loss,_,_=mmi_model(input_ids=context_tensor,labels=context_tensor)
|
||||
scores.append(-loss.float())
|
||||
scores=torch.stack(scores, dim=0)
|
||||
winner=torch.multinomial(F.softmax(scores,dim=0),num_samples=1).item()
|
||||
return winner
|
||||
#######################################################################################
|
||||
def generate_response(self,model,tokenizer,context,config,mmi_model=None,mmi_tokenizer=None):
|
||||
use_mmi=config.getboolean('model','use_mmi')
|
||||
num_samples=config.getint('decoder','num_samples')
|
||||
max_length=config.getint('decoder','max_length')
|
||||
seed=config.get('decoder','seed')
|
||||
seed=int(seed) if seed is not None else None
|
||||
if seed is not None:
|
||||
self.set_seed(seed)
|
||||
context_ids=tokenizer.encode(context)
|
||||
samples=self.sample_sequence(model, tokenizer, context_ids, config)
|
||||
samples=samples[:, len(context_ids):].tolist()
|
||||
texts=[]
|
||||
for sample in samples:
|
||||
text=tokenizer.decode(sample,clean_up_tokenization_spaces=True)
|
||||
text=text[: text.find(tokenizer.eos_token)]
|
||||
texts.append(text)
|
||||
if use_mmi:
|
||||
assert(num_samples > 1)
|
||||
candidates=[context+text for text in texts]
|
||||
best_i=self.select_using_mmi(mmi_model,mmi_tokenizer,candidates,config)
|
||||
return [texts[best_i]]
|
||||
return texts
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg_search_for_maple(self, mask=None, target=None, data=None, **kw):
|
||||
##############################################
|
||||
if mask.nick == self.bot.config["nick"] or mask.nick == 'nickserv':
|
||||
print('returning, message data from bot not user')
|
||||
return
|
||||
##############################################
|
||||
if self.epoch_time_boolean==True:
|
||||
print('[ checking flood protection status ]')
|
||||
epoch_time_now=int(str(time()).split('.')[0])
|
||||
if epoch_time_now-self.epoch_time_last>=30:
|
||||
self.epoch_time_boolean=False
|
||||
print('[ turned off flood protection ]')
|
||||
else:
|
||||
print('[ flood protection still on ]')
|
||||
return
|
||||
##############################################
|
||||
data=data.strip().lower()
|
||||
self.bot.history.last_message=data
|
||||
##############################################
|
||||
self.span=0
|
||||
for _ in data.split():
|
||||
for __ in self.OPINION.split():
|
||||
if _ == __:
|
||||
self.span=1
|
||||
break
|
||||
##############################################
|
||||
if mask.nick == "d":
|
||||
if data.find(self.bot.config["nick"])>-1:
|
||||
if data.find('hang with us')>-1:
|
||||
msg="ok, i'll hang out for a bit"
|
||||
self.bot.privmsg(target,self.bot.emo(msg))
|
||||
self.mode=1
|
||||
if data.find('leave us alone')>-1:
|
||||
msg="ok, gotta go"
|
||||
self.bot.privmsg(target,self.bot.emo(msg))
|
||||
self.mode=0
|
||||
##############################################
|
||||
if self.mode==0:
|
||||
if not data.find(self.bot.config["nick"])>-1:
|
||||
if self.span==0:
|
||||
return
|
||||
##############################################
|
||||
self.span=0
|
||||
##############################################
|
||||
emotion=random.choices(['neutral','anger','joy','fear','sadness'])[0]
|
||||
print(f'emote > {emotion}')
|
||||
self.bot.history.push_maple_emotions(emotion)
|
||||
#self.bot.history.last_emotion = emotion
|
||||
body = {'context': [f'{self.bot.history.last_message}'], 'emotion': emotion}
|
||||
url = 'http://127.0.0.1:8080/cakechat_api/v1/actions/get_response'
|
||||
response = requests.post(url, json=body)
|
||||
caple_message=response.json()['response'].lower()
|
||||
self.maple_io.append({'user':mask.nick,'message':f'{data} {caple_message}','target':target})
|
||||
if len(self.maple_io) > 5:
|
||||
self.maple_io=[]
|
||||
self.epoch_time_now=int(str(time()).split('.')[0])
|
||||
self.epoch_time_last=self.epoch_time_now
|
||||
self.epoch_time_boolean=True
|
||||
msg=f"kind of busy at the moment {mask.nick}, i'll be right back"
|
||||
print('[ turned on flood protection ]')
|
||||
self.bot.privmsg(target,msg)
|
||||
#######################################################################################
|
||||
def run_chat(self,model,tokenizer,config,mmi_model=None,mmi_tokenizer=None):
|
||||
num_samples=config.getint('decoder','num_samples')
|
||||
max_turns_history=config.getint('decoder','max_turns_history')
|
||||
turns=[]
|
||||
signal.signal(signal.SIGINT,self.signal_handling)
|
||||
config.set('decoder','seed',f'{datetime.now().microsecond}')
|
||||
try:
|
||||
if not type(self.bot.history.bounce)==bool:
|
||||
print('<received bounce message>')
|
||||
USER=self.bot.history.bounce['user']
|
||||
MESSAGE=self.bot.history.bounce['message']
|
||||
TARGET=self.bot.history.bounce['target']
|
||||
self.maple_io.append({'user':USER,'message':MESSAGE,'target':TARGET})
|
||||
self.bot.history.bounce=False
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.maple_io.reverse()
|
||||
maple_io=self.maple_io.pop()
|
||||
self.maple_io.reverse()
|
||||
USER=maple_io['user']
|
||||
MESSAGE=maple_io['message'].strip()
|
||||
TARGET=maple_io['target']
|
||||
except:
|
||||
return self.exit_strategy
|
||||
print(f'human > {MESSAGE}')
|
||||
|
||||
self.bot.history.maple_message=MESSAGE
|
||||
if max_turns_history==0:
|
||||
turns=[]
|
||||
turn={
|
||||
'human_messages':[],
|
||||
'maple_messages':[]
|
||||
}
|
||||
turns.append(turn)
|
||||
turn['human_messages'].append(f'{USER} {MESSAGE}')
|
||||
history=""
|
||||
from_index=max(len(turns)-max_turns_history-1,0) if max_turns_history>=0 else 0
|
||||
WISDOM=self.WISDOM.splitlines()
|
||||
try:
|
||||
WISDOM.remove('')
|
||||
except:
|
||||
pass
|
||||
for i,_ in enumerate(WISDOM):
|
||||
WISDOM[i]=_.strip()
|
||||
static_history=WISDOM
|
||||
for message in static_history:
|
||||
history += message + tokenizer.eos_token
|
||||
for turn in turns[from_index:]:
|
||||
for message in turn['human_messages']:
|
||||
history+=message+tokenizer.eos_token
|
||||
for message in turn['maple_messages']:
|
||||
history+=message+tokenizer.eos_token
|
||||
maple_messages=self.generate_response(
|
||||
model,
|
||||
tokenizer,
|
||||
history,
|
||||
config,
|
||||
mmi_model=mmi_model,
|
||||
mmi_tokenizer=mmi_tokenizer
|
||||
)
|
||||
if num_samples==1:
|
||||
maple_message=maple_messages[0]
|
||||
else:
|
||||
maple_message=random.choice(maple_messages)
|
||||
turn['maple_messages'].append(maple_message)
|
||||
################################################################################### REPROCESSOR SOF
|
||||
# SIMILARITY
|
||||
for i in range(len(self.bot.history.maple_messages)):
|
||||
if self.bot.history.similar(maple_message,str(self.bot.history.maple_messages[i]))>0.9:
|
||||
self.maple_io.append({'user':USER,'message':f'{MESSAGE}','target':TARGET})
|
||||
print(f'maple - logic ! rejected // maple similarity - repeat of previous response')
|
||||
self.bot.history.loopcount+=1
|
||||
return self.exit_strategy
|
||||
###################################################################################
|
||||
# MOCK / DUPE
|
||||
if self.bot.history.similar(maple_message,MESSAGE)>0.9:
|
||||
self.maple_io.append({'user':USER,'message':f'{MESSAGE}','target':TARGET})
|
||||
print(f'maple - logic ! rejected // human mock - maple response same as human')
|
||||
self.bot.history.loopcount+=1
|
||||
return self.exit_strategy
|
||||
###################################################################################
|
||||
# GPT LOOP GLITCH
|
||||
n=len(maple_message.split())
|
||||
i=len(set(maple_message.split()))
|
||||
if i<int(n/2):
|
||||
self.maple_io.append({'user':USER,'message':f'{MESSAGE}','target':TARGET})
|
||||
print(f'maple - logic ! rejected // gpt loop glitch - reiterating same thing in multiples')
|
||||
self.bot.history.loopcount+=1
|
||||
return self.exit_strategy
|
||||
###################################################################################
|
||||
# LIMITED RESPONSE
|
||||
n=len(maple_message.split())
|
||||
if i<3:
|
||||
self.maple_io.append({'user':USER,'message':f'{MESSAGE}','target':TARGET})
|
||||
print(f'maple - logic ! rejected // limited response - skip an unfinished token chain')
|
||||
self.bot.history.loopcount+=1
|
||||
return self.exit_strategy
|
||||
###################################################################################
|
||||
self.bot.history.push_maple_messages(maple_message)
|
||||
################################################################################### REPROCESSOR EOF
|
||||
#emotion=random.choices(['neutral','anger','joy','fear','sadness'])[0]
|
||||
#body = {'context': [f'{self.bot.history.last_message}'], 'emotion': emotion}
|
||||
#body = {'context': [f'{self.bot.history.last_message} {maple_message}'], 'emotion': emotion}
|
||||
#url = 'http://127.0.0.1:8080/cakechat_api/v1/actions/get_response'
|
||||
#response = requests.post(url, json=body)
|
||||
#caple_message=response.json()['response']
|
||||
emojis=["😐","😡","😂","👻","😭"]
|
||||
emotions=['neutral','anger','joy','fear','sadness']
|
||||
emotion=self.bot.history.maple_emotions[0]
|
||||
emoji=emojis[emotions.index(emotion)]
|
||||
neutral=["ª{•̃̾_•̃̾}ª","¬_¬","¯\(º_o)/¯","ʕ•̫͡•ʔv","˚•_•˚","σ_σ","д_д","ф_ф","Ծ_Ծ"]
|
||||
anger=["(⋋▂⋌)","(┛◉Д◉)┛┻━┻","(╯°□°)╯︵ ┻━┻","(╯◕.◕)╯","(╹◡╹)凸","(ノಠ益ಠ)ノ彡┻━┻","(屮゚Д゚)屮","〴⋋_⋌〵"]
|
||||
joy=["(•‿•)","(◑‿◐)","(◑◡◑)","(◕‿◕✿)","(◕‿◕)","(◕‿-)"]
|
||||
fear=["˚▱˚","٩(×̯×)۶","⊂(◉.◉)つ"]
|
||||
sadness=["¯\_(⊙︿⊙)_/¯","ಠ╭╮ಠ","ಠ︵ಠ凸","ᕙ(⇀‸↼‶)ᕗ","◉︵◉"]
|
||||
emote=random.choices(locals()[emotion])[0]
|
||||
print(f'maple ! {maple_message}')
|
||||
MAPLE_MESSAGE=maple_io['message'].replace(self.bot.history.last_message,'').strip().lower()
|
||||
MAPLE_MESSAGE=MAPLE_MESSAGE.replace('lt 3','<3')
|
||||
caple_message=maple_message.lower().replace('lt 3','<3')
|
||||
print(f'maple > {USER}: {MAPLE_MESSAGE} {caple_message} {emoji} {emotion} {emote}')
|
||||
colors=['\x0300','\x0304','\x0308','\x0306','\x0312']
|
||||
color=colors[emotions.index(emotion)]
|
||||
# msg=f'{USER}: {MAPLE_MESSAGE} {caple_message} {emoji} {color}{emotion} > {emote}'
|
||||
msg=f'{USER}: {MAPLE_MESSAGE} {caple_message} {color}{emote}\x0f'
|
||||
# msg=self.bot.emo(msg)
|
||||
self.bot.privmsg(TARGET,msg)
|
||||
self.bot.history.maple_emotions.reverse()
|
||||
self.bot.history.maple_emotions.pop()
|
||||
self.bot.history.maple_emotions.reverse()
|
||||
self.bot.history.loopcount=0
|
||||
return self.exit_strategy
|
||||
#######################################################################################
|
||||
def main(self):
|
||||
loop=self.bot.loop
|
||||
loop.call_later(self.delay,self.main)
|
||||
tasks=[]
|
||||
task=loop.run_in_executor(None,\
|
||||
self.run_chat(self.model,self.tokenizer,self.config,mmi_model=self.mmi_model,mmi_tokenizer=self.mmi_tokenizer))
|
||||
tasks.append(task)
|
||||
#######################################################################################
|
||||
def exit_strategy(self):
|
||||
if self.bot.history.loopcount>25:
|
||||
self.bot.history.loopcount=0
|
||||
self.maple_io=[]
|
||||
pass
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,224 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import irc3,os,ipdb
|
||||
import simplematrixbotlib as botlib
|
||||
from plugins.tool_dims_plugin import dims
|
||||
from plugins.tool_guds_plugin import guds
|
||||
from irc3.testing import ini2config
|
||||
from irc3.plugins.command import command
|
||||
from plugins.tool_bus_plugin import BUS
|
||||
################################### NET IRC - SERVER CREDENTIALS FOR SASL OR NICKSERV [1/4]
|
||||
BOT_SASL_USERNAME=os.environ['BOT_SASL_USERNAME']
|
||||
BOT_SASL_PASSWORD=os.environ['BOT_SASL_PASSWORD']
|
||||
NICKSERV_USERNAME=os.environ['NICKSERV_USERNAME']
|
||||
NICKSERV_PASSWORD=os.environ['NICKSERV_PASSWORD']
|
||||
################################################################ NET IRC - BOT CONFIG [2/4]
|
||||
def config_ircbot():
|
||||
config=ini2config("""
|
||||
[bot]
|
||||
nick = n0tmaple
|
||||
username = n0tg1mp
|
||||
realname = "[ g1mp'n ain't easy unless you're maple ]"
|
||||
host = ircd.chat
|
||||
port = 6697
|
||||
version = 1
|
||||
url = ircd.chat
|
||||
ssl = true
|
||||
ssl_verify = CERT_NONE
|
||||
|
||||
includes =
|
||||
irc3.plugins.command
|
||||
irc3.plugins.asynchronious
|
||||
irc3.plugins.uptime
|
||||
irc3.plugins.ctcp
|
||||
irc3.plugins.cron
|
||||
irc3.plugins.log
|
||||
irc3.plugins.logger
|
||||
irc3.plugins.userlist
|
||||
plugins.tool_dims_plugin
|
||||
plugins.tool_guds_plugin
|
||||
plugins.tool_bus_plugin
|
||||
plugins.sasl_custom_plugin
|
||||
plugins.net_irc_plugin
|
||||
plugins.net_matrix_plugin
|
||||
plugins.cmd_irc_plugin
|
||||
plugins.storage_plugin
|
||||
plugins.base_plugin
|
||||
plugins.emote_plugin
|
||||
plugins.fifo_plugin
|
||||
plugins.youtube_plugin
|
||||
plugins.crypto_plugin
|
||||
plugins.url_grabber_plugin
|
||||
plugins.notes_plugin
|
||||
plugins.quote_plugin
|
||||
plugins.ratesex_plugin
|
||||
plugins.remind_plugin
|
||||
plugins.sed_plugin
|
||||
plugins.seen_plugin
|
||||
plugins.strain_plugin
|
||||
plugins.tell_plugin
|
||||
plugins.twitter_plugin
|
||||
plugins.ud_plugin
|
||||
plugins.figlet_plugin
|
||||
plugins.soundcloud_plugin
|
||||
plugins.isup_plugin
|
||||
plugins.tcpac_plugin
|
||||
plugins.google_plugin
|
||||
plugins.highlight_plugin
|
||||
plugins.boombox_plugin
|
||||
plugins.whoami_plugin
|
||||
|
||||
autojoins =
|
||||
'#b0tsh0p'
|
||||
'#tcpdirect'
|
||||
|
||||
flood_burst = 0
|
||||
flood_rate = 1
|
||||
flood_rate_delay = 1
|
||||
storage = json://databases/maple_db.json
|
||||
|
||||
[irc3.plugins.command]
|
||||
cmd = ?
|
||||
guard = irc3.plugins.command.mask_based_policy
|
||||
|
||||
[irc3.plugins.command.masks]
|
||||
d!*@1.3.3.7 = all_permissions
|
||||
d*!~dtcpdirect@* = all_permissions
|
||||
d*!~dvaccine@* = all_permissions
|
||||
GregJ!*@* = all_permissions
|
||||
kayos!*@* = all_permissions
|
||||
moony!*@* = all_permissions
|
||||
Dillinger!*@* = all_permissions
|
||||
Civil!*@* = all_permissions
|
||||
chunk!*@* = all_permissions
|
||||
sniff!*@* = all_permissions
|
||||
* = view
|
||||
|
||||
ignore_list =
|
||||
GitServ!*@*
|
||||
GitServ_!*@*
|
||||
g1mp!*@*
|
||||
g1mp_!*@*
|
||||
maple!*@*
|
||||
maple_!*@*
|
||||
[0]!*@*
|
||||
[0]_!*@*
|
||||
nav!*@*
|
||||
nav_!*@*
|
||||
van!*@*
|
||||
van_!*@*
|
||||
professorOak!*@*
|
||||
professorOak_!*@*
|
||||
*!van@*
|
||||
|
||||
[plugins.fifo_plugin]
|
||||
runpath = {PATH}/fifo""".format(PATH=os.getcwd()))
|
||||
ircbot=irc3.IrcBot.from_config(config)
|
||||
for i,_ in enumerate(config['autojoins']):
|
||||
config['autojoins'][i]=_.replace("'","")
|
||||
return ircbot
|
||||
############################################################### NET IRC - BOT STARTUP [3/4]
|
||||
def start_ircbot(self):
|
||||
globals()['guds'].memories.append([self,'net_irc_plugin:start_ircbot.self'])
|
||||
ircbot=guds.memories[2][0]._BOTIO__boot__ircbot=self.ircbot
|
||||
print(f'<<< _____net_irc_plugin >>> [ ircbot started ]')
|
||||
self.ircbot.run(forever=True)
|
||||
return self
|
||||
###################################################################### NET IRC - MAIN [4/4]
|
||||
@irc3.plugin
|
||||
###########################################################################################
|
||||
def __init__(self,bot):
|
||||
self.ircbot=bot
|
||||
print(f'<<< _____net_irc_plugin >>> [ plugin loaded ]')
|
||||
guds.memories.append([self,'net_irc_plugin:__init__.self'])
|
||||
###########################################################################################
|
||||
def connection_made(self):
|
||||
print(f'<<< _____net_irc_plugin:event >>> [ connection made ]')
|
||||
###########################################################################################
|
||||
def server_ready(self):
|
||||
print(f'<<< _____net_irc_plugin:event >>> [ server ready ]')
|
||||
###########################################################################################
|
||||
def connection_lost(self):
|
||||
print(f'<<< _____net_irc_plugin:event >>> [ connection lost ]')
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
async def on_privmsg(self, mask=None, target=None, data=None, **kw):
|
||||
msg=f"{mask.nick}: target: {target} - event: privmsg - data: {data}"
|
||||
if not mask.nick==self.config['nick']: # user
|
||||
netschanlist=dims.list_channels()
|
||||
matrixbot=guds.memories[2][0]._BOTIO__boot__matrix
|
||||
oldbot=guds.memories[2][0]._BOTIO__boot__irc
|
||||
ircbot=self
|
||||
if oldbot==ircbot: # no variance, no problem
|
||||
bridgedbus=(BUS(netschanlist,matrixbot,ircbot))
|
||||
await bridgedbus.input(target,f'{mask.nick}: {data}')
|
||||
else: # variance
|
||||
pass # exposing variance, <research>
|
||||
else: # bot
|
||||
pass
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.JOIN_PART_QUIT)
|
||||
def on_join_part_quit(self,mask=None,target=None,data=None,**kw):
|
||||
target=kw['channel']
|
||||
###################################################################################
|
||||
if not mask.nick==self.config['nick']: # this section is the user
|
||||
msg=f"{mask.nick}: target: {target} - event: join_part_quit:{kw['event']} - data: {data}"
|
||||
self.privmsg(target,msg); print(msg)
|
||||
###################################################################################
|
||||
else: # this section is the bot
|
||||
###############################################################################
|
||||
if kw['event']=='JOIN':
|
||||
result,i,ii=dims.ischannel(target)
|
||||
if not result:
|
||||
dims.__create__('irc',target)
|
||||
print(f"<<< ___tool_dims_plugin:event:join >>> [ dims.__create__(irc,{target}) ] - active channel record created")
|
||||
###############################################################################
|
||||
elif kw['event']=='PART':
|
||||
###########################################################################
|
||||
result,i,ii=dims.ischannel(target)
|
||||
###########################################################################
|
||||
dims.__delete__('irc',i)
|
||||
print(f"<<< ___tool_dims_plugin:event:part >>> [ dims.__delete__(irc,{target}) ] - active channel record deleted")
|
||||
###############################################################################
|
||||
elif kw['event']=='QUIT':
|
||||
###########################################################################
|
||||
result,i,ii=dims.ischannel(target)
|
||||
###########################################################################
|
||||
dims.__delete__('irc',i)
|
||||
print(f"<<< ___tool_dims_plugin:event:quit >>> [ dims.__delete__(irc,{target}) ] - active channel record deleted")
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.TOPIC)
|
||||
def on_topic(self,mask=None,target=None,data=None,**kw):
|
||||
if not mask.nick==self.config['nick']:
|
||||
msg=f"{mask.nick}: target: {target} - event: topic - data: {data}"
|
||||
self.privmsg(target,msg); print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.INVITE)
|
||||
def on_invite(self,mask=None,target=None,data=None,**kw):
|
||||
if not mask.nick==self.config['nick']:
|
||||
msg=f"{mask.nick}: target: {target} - event: invite - data: {data}"
|
||||
self.privmsg(target,msg); print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.KICK)
|
||||
def on_kick(self,mask=None,target=None,data=None,**kw):
|
||||
if not mask.nick==self.config['nick']:
|
||||
msg=f"{mask.nick}: target: {target} - event: kick - data: {data}"
|
||||
self.privmsg(target,msg); print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.MODE)
|
||||
def on_mode(self,mask=None,target=None,data=None,**kw):
|
||||
if not mask.nick==self.config['nick']:
|
||||
msg=f"{mask.nick}: target: {target} - event: mode - data: {data}"
|
||||
self.privmsg(target,msg); print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.NEW_NICK)
|
||||
def on_new_kick(self,mask=None,target=None,data=None,**kw):
|
||||
if not mask.nick==self.config['nick']:
|
||||
msg=f"{mask.nick}: target: {target} - event: new_nick - data: {data}"
|
||||
self.privmsg(target,msg); print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
|
||||
###########################################################################################
|
||||
@irc3.event(irc3.rfc.CTCP)
|
||||
def on_ctcp(self,mask=None,target=None,data=None,**kw):
|
||||
if not mask.nick==self.config['nick']:
|
||||
msg=f"{mask.nick}: target: {target} - event: ctcp - data: {data}"
|
||||
self.privmsg(target,msg); print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import irc3,os,re,ipdb
|
||||
import simplematrixbotlib as botlib
|
||||
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 as bus
|
||||
###########################################################################################
|
||||
MATRIX_HOMESERVER=os.environ['MATRIX_HOMESERVER']
|
||||
MATRIX___USERNAME=os.environ['MATRIX___USERNAME']
|
||||
MATRIX___PASSWORD=os.environ['MATRIX___PASSWORD']
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
creds=botlib.Creds(MATRIX_HOMESERVER,MATRIX___USERNAME,MATRIX___PASSWORD)
|
||||
matrixbot=botlib.Bot(creds)
|
||||
###########################################################################################
|
||||
def start_matrixbot(self):
|
||||
globals()['guds'].memories.append([self,'net_matrix_plugin:start_matrixbot.self'])
|
||||
ircbot=guds.memories[2][0]._BOTIO__boot__ircbot=self.ircbot
|
||||
guds.memories[2][0]._BOTIO__boot__irc=ircbot
|
||||
guds.memories[2][0]._BOTIO__boot__matrix=matrixbot
|
||||
matrixbot.run()
|
||||
return self
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
def __init__(self,bot):
|
||||
self.bot=bot
|
||||
print(f'<<< __net_matrix_plugin >>> [ plugin loaded ]')
|
||||
globals()['guds'].memories.append([self,'net_matrix_plugin:__init__.self'])
|
||||
@matrixbot.listener.on_message_event
|
||||
async def scan(room,message):
|
||||
bridgedbus=''
|
||||
print('<<< __net_matrix_plugin >>> [ event: listener ]')
|
||||
bio=guds.memories[2][0]
|
||||
dims.__create__('matrix',room)
|
||||
m_message=message.source['content']['body']
|
||||
m_sender=message.sender
|
||||
print(f"{m_sender}: {m_message}")
|
||||
############################################################# MESSAGE SENDER FILTER
|
||||
trigger_command="??"
|
||||
if not guds.check_credentials(message.sender):
|
||||
####################################################################### TRIGGER
|
||||
if m_message.lower().startswith(trigger_command):
|
||||
commands=['d_breakpoint','d_listrooms']
|
||||
################################################################## COMMANDS
|
||||
if m_message.lower().split()[0][len(trigger_command):] in commands:
|
||||
command=m_message.lower().split()[0][len(trigger_command):]
|
||||
#######################################################################
|
||||
if command==commands[0]: # ??d_breakpoint - triggered message
|
||||
if m_sender=="@d:tcp.direct":
|
||||
ipdb.set_trace()
|
||||
#######################################################################
|
||||
if command==commands[1]: # ??d_listrooms - triggered message
|
||||
if m_sender=="@d:tcp.direct":
|
||||
await joined_rooms(room.room_id)
|
||||
#######################################################################
|
||||
else:
|
||||
pass
|
||||
msg=f'{m_sender}: {m_message} - triggered message but with a non-listed command'
|
||||
print(msg)
|
||||
###########################################################################
|
||||
else:
|
||||
msg=f'{m_sender}: {m_message} - message not prefixed with a {trigger_command} trigger'
|
||||
print(msg)
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,164 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
from datetime import datetime
|
||||
import dateutil.parser
|
||||
import timeago
|
||||
import uuid
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='admin', public=True, show_in_help_list=True)
|
||||
def notes(self, *args, **kwargs):
|
||||
"""list/write/del notes
|
||||
%%notes [<cmd>] [<operation>]
|
||||
"""
|
||||
return self.note(*args)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='admin', public=True, show_in_help_list=True)
|
||||
def note(self, mask, target, args):
|
||||
"""list/write/del notes
|
||||
%%note [<cmd>] [<operation>]
|
||||
"""
|
||||
cmd = args.get("<cmd>")
|
||||
if not cmd:
|
||||
msg = "Please specify read/write/delete/list"
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
elif cmd in ["d","del","delete","remove"]:
|
||||
self.note_del(mask, target, args)
|
||||
elif cmd in ["w", "write","a", "add"]:
|
||||
self.note_write(mask, target, args)
|
||||
elif cmd in ["l", "list"]:
|
||||
self.note_list(mask, target, args)
|
||||
elif cmd in ["r", "read"]:
|
||||
self.note_read(mask, target, args)
|
||||
return
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='admin', public=True, show_in_help_list=True)
|
||||
def note_del(self, mask, target, args):
|
||||
"""Delete Note or * for all notes
|
||||
%%note <cmd> <operation>
|
||||
"""
|
||||
note_uuid_hash = args.get("<operation>")
|
||||
if not note_uuid_hash:
|
||||
msg = "Please specify note"
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
if note_uuid_hash == "*":
|
||||
self.bot.db.setlist("notes", [])
|
||||
msg = "All notes cleared!"
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
else:
|
||||
note_list = self.bot.db.getlist("notes", [])
|
||||
if not note_list:
|
||||
msg = "{} Not Found".format(note_uuid_hash)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
else:
|
||||
if note_uuid_hash in [item.get("uuid") for item in note_list]:
|
||||
new_note_list = [item for item in note_list if item.get("uuid") != note_uuid_hash]
|
||||
self.bot.db.setlist("notes", new_note_list)
|
||||
msg = "{} Removed".format(note_uuid_hash)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='admin', public=True, show_in_help_list=True)
|
||||
def note_list(self, mask, target, args):
|
||||
"""List All Note Names
|
||||
%%note list
|
||||
"""
|
||||
note_list = self.bot.db.getlist("notes")
|
||||
if not note_list:
|
||||
msg = "No notes!"
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
for note in note_list:
|
||||
note_uuid = note.get("uuid")
|
||||
note_from = note.get("from")
|
||||
note_time = dateutil.parser.parse(note.get("time"))
|
||||
note_time = timeago.format(note_time, datetime.now())
|
||||
note_msg = note.get("note_msg")
|
||||
msg = "<{}> {} | {} | {}".format(note_from, note_time, note_msg, note_uuid)
|
||||
self.bot.privmsg(target, msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='admin', public=True, show_in_help_list=True)
|
||||
def note_read(self, mask, target, args):
|
||||
"""Display Note
|
||||
%%note read <operation>
|
||||
"""
|
||||
note_name = args.get("<operation>")
|
||||
if not note_name:
|
||||
msg = "Please specify name or note id"
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
note_list = self.bot.db.getlist("notes")
|
||||
if not note_list:
|
||||
msg = "No Notes in DB"
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
if not any(note_name in d["uuid"] for d in note_list):
|
||||
msg = "No notes with {} found".format(note_name)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
else:
|
||||
note = [d for d in note_list if d.get("uuid") == note_name]
|
||||
if note:
|
||||
note = note.pop()
|
||||
else:
|
||||
try:
|
||||
note = note_list[int(note_name)]
|
||||
except:
|
||||
msg = "No notes with {} found".format(note_name)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
note_uuid = note.get("uuid")
|
||||
note_from = note.get("from")
|
||||
note_time = dateutil.parser.parse(note.get("time"))
|
||||
note_time = timeago.format(note_time, datetime.now())
|
||||
note_msg = note.get("note_msg")
|
||||
msg = "<{}> {} | {} | {}".format(note_from, note_time, note_msg, note_uuid)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='admin', public=True, show_in_help_list=True)
|
||||
def note_write(self, mask, target, args):
|
||||
"""Add Note
|
||||
%%note write <note>
|
||||
"""
|
||||
note_msg = args.get("<operation>")
|
||||
note_list = self.bot.db.getlist("notes")
|
||||
if not note_list:
|
||||
note_list = []
|
||||
self.bot.db.setlist("notes", note_list)
|
||||
note_uuid = uuid.uuid4().hex
|
||||
note = {"time": datetime.now().isoformat(),
|
||||
"from": mask.nick, "uuid": note_uuid,
|
||||
"note_msg": note_msg}
|
||||
note_list.append(note)
|
||||
self.bot.db.setlist("notes", note_list)
|
||||
msg = "Note Added! {}".format(note_uuid)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,84 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import random
|
||||
import uuid
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self,bot):
|
||||
self.bot=bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.JOIN)
|
||||
def quote_user_join(self, mask, channel, **kw):
|
||||
"""quote a user when they join"""
|
||||
quote_list=self.bot.db.getlist("quotes")
|
||||
if not quote_list:
|
||||
quote_list=[]
|
||||
self.bot.db.setlist('quotes',[])
|
||||
quote_user=[]
|
||||
for i in range(len(quote_list)):
|
||||
user=mask.nick.lower()
|
||||
if mask.nick==self.bot.nick: user=self.bot.original_nick.lower()
|
||||
if(quote_list[i]['user']==user):
|
||||
quote_user.append(quote_list[i]['message'])
|
||||
if quote_user:
|
||||
msg=random.choice(quote_user)+' \x02\x0303>\x0F '+user
|
||||
msg=self.bot.emo(msg)
|
||||
print(f'\n{msg}\n')
|
||||
self.bot.privmsg(channel,msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def quote(self,mask,target, args):
|
||||
"""quote user message
|
||||
%%quote <noise>...
|
||||
"""
|
||||
noise=' '.join(args['<noise>'])
|
||||
user=noise.split(' ')[0]
|
||||
noise=noise.split(' ')[1:]
|
||||
message=' '.join(noise)
|
||||
status=''
|
||||
try:
|
||||
quote_list=self.bot.db.getlist("quotes")
|
||||
if not quote_list:
|
||||
quote_list=[]
|
||||
self.bot.db.setlist("quotes",quote_list)
|
||||
quote_uuid=uuid.uuid4().hex
|
||||
quote={"user":user.lower(),"message":message,"uuid":quote_uuid}
|
||||
quote_list.append(quote)
|
||||
self.bot.db.setlist("quotes",quote_list)
|
||||
status=f"TCPDIRECT/QUOTED: {user} "
|
||||
status+=f"\x02\x0303>\x0F {message} "
|
||||
status+=f"\x02\x0303>\x0F {quote_uuid}"
|
||||
except Exception as e:
|
||||
status=f"\x02\x0304error \x02\x0303>\x0F {e.message[0]['message']}'"
|
||||
msg=self.bot.emo(status)
|
||||
self.bot.privmsg(target,msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def quotes(self, mask, target, args):
|
||||
"""quotes user
|
||||
%%quotes <nick>
|
||||
"""
|
||||
user=args.get("<nick>")
|
||||
quote_list=self.bot.db.getlist("quotes")
|
||||
if not quote_list:
|
||||
quote_list=[]
|
||||
self.bot.db.setlist('quotes',[])
|
||||
quote_user=[]
|
||||
for i in range(len(quote_list)):
|
||||
if(quote_list[i]['user']==user):
|
||||
quote_user.append(quote_list[i]['message'])
|
||||
for i in range(len(quote_user)):
|
||||
msg=user+' \x02\x0303>\x0F '+quote_user[i]
|
||||
msg=self.bot.emo(msg)
|
||||
self.bot.privmsg(target,msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,349 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
from irc3.plugins.cron import cron
|
||||
import irc3
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import URLError, HTTPError
|
||||
from random import randint
|
||||
__doc__ = '''#######################################################################################
|
||||
####################################################################################################
|
||||
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh+MMMMMMMMMMMMMMhsMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMm/ oMMMMMMMMMMMMMMm +NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMy` yMMMMMMMMMMMMMMM- -mMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMs+dMMMMMMMMMM+ sMMMMMMMMMMMMMMM- `dMMMMMMMMMMms/NMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMM+ .omMMMMMM: -MMMMMMMMMMMMMMo `yMMMMMMMy: `dMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMM- /dMMM+ sMMMMMMMMMMMMh `hMMMNo` sMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMd :dm `mMMMMMMMMMMN. .NNo` .MMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMM: - :MMMMMMMMMMs :` sMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMs ymNMMMMMNm. NMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMy `-/-` .MMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMo .NMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMNh+. :sdMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMhso+:. `-/+syMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMM- dMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMM` `.:+/. `/s+:. sMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMNo -oms. .//-` `:/:` `+md+` .hMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMNs` .odNdo. .ohmd+` :dMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMNo` .. .- :hMMMMMMMMMMM
|
||||
MMMMMMMMMd+` -sNMMMMMMMM
|
||||
MMMMMMNs- `.. `/-. `+dMMMMMM
|
||||
MMMNy: ./sdNMMMh: `sNMMMNds/. .odMMM
|
||||
MM+ :ymMMMMMMMMMMh. +NMMMMMMMMMMmo- /NM
|
||||
MMMh: .sNMMMMMMMMMMMMMMN- `hMMMMMMMMMMMMMMMm+` :hMMM
|
||||
MMMMMd:` ``-:+shmMMMMMMMMMMMMMMMMMMN. hMMMMMMMMMMMMMMMMMMMmhs+/-..``````./dMMMMM
|
||||
MMMMMMMMMNNNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMo .MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMy .MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN. /MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN+` `+NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNs. -hMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMdyymMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
|
||||
|
||||
####################################################################################################
|
||||
#################################################################################################'''
|
||||
|
||||
|
||||
rgb2irc = { 52: '16', 94: '17', 100: '18', 58: '19', 22: '20', 29: '21', 23: '22', 24: '23', 17: '24', 54: '25', 53: '26', 89: '27',
|
||||
88: '28', 130: '29', 142: '30', 64: '31', 28: '32', 35: '33', 30: '34', 25: '35', 18: '36', 91: '37', 90: '38', 125: '39',
|
||||
124: '40', 166: '41', 184: '42', 106: '43', 34: '44', 49: '45', 37: '46', 33: '47', 19: '48', 129: '49', 127: '50', 161: '51',
|
||||
196: '52', 208: '53', 226: '54', 154: '55', 46: '56', 86: '57', 51: '58', 75: '59', 21: '60', 171: '61', 201: '62', 198: '63',
|
||||
203: '64', 215: '65', 227: '66', 191: '67', 83: '68', 122: '69', 87: '70', 111: '71', 63: '72', 177: '73', 207: '74', 205: '75',
|
||||
217: '76', 223: '77', 229: '78', 193: '79', 157: '80', 158: '81', 159: '82', 153: '83', 147: '84', 183: '85', 219: '86', 212: '87',
|
||||
16: '88', 233: '89', 235: '90', 237: '91', 239: '92', 241: '93', 244: '94', 247: '95', 250: '96', 254: '97', 231: '98', }
|
||||
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
|
||||
rgb2set = { "ef0": "#000000", "ef1": "#CD0000", "ef2": "#00CD00", "ef3": "#CDCD00", "ef4": "#0000EE", "ef5": "#CD00CD", "ef6": "#00CDCD", "ef7": "#E5E5E5",
|
||||
"ef8": "#7F7F7F", "ef9": "#FF0000", "ef10": "#00FF00", "ef11": "#FFFF00", "ef12": "#5C5CFF", "ef13": "#FF00FF", "ef14": "#00FFFF", "ef15": "#FFFFFF",
|
||||
"eb8": "#7F7F7F", "eb9": "#FF0000", "eb10": "#00FF00", "eb11": "#FFFF00", "eb12": "#5C5CFF", "eb13": "#FF00FF", "eb14": "#00FFFF", "eb15": "#FFFFFF", "ef16": "#000000",
|
||||
"ef17": "#00005f", "ef18": "#000087", "ef19": "#0000af", "ef20": "#0000d7", "ef21": "#0000ff", "ef22": "#005f00", "ef23": "#005f5f", "ef24": "#005f87", "ef25": "#005faf",
|
||||
"ef26": "#005fd7", "ef27": "#005fff", "ef28": "#008700", "ef29": "#00875f", "ef30": "#008787", "ef31": "#0087af", "ef32": "#0087d7", "ef33": "#0087ff", "ef34": "#00af00",
|
||||
"ef35": "#00af5f", "ef36": "#00af87", "ef37": "#00afaf", "ef38": "#00afd7", "ef39": "#00afff", "ef40": "#00d700", "ef41": "#00d75f", "ef42": "#00d787", "ef43": "#00d7af",
|
||||
"ef44": "#00d7d7", "ef45": "#00d7ff", "ef46": "#00ff00", "ef47": "#00ff5f", "ef48": "#00ff87", "ef49": "#00ffaf", "ef50": "#00ffd7", "ef51": "#00ffff", "ef52": "#5f0000",
|
||||
"ef53": "#5f005f", "ef54": "#5f0087", "ef55": "#5f00af", "ef56": "#5f00d7", "ef57": "#5f00ff", "ef58": "#5f5f00", "ef59": "#5f5f5f", "ef60": "#5f5f87", "ef61": "#5f5faf",
|
||||
"ef62": "#5f5fd7", "ef63": "#5f5fff", "ef64": "#5f8700", "ef65": "#5f875f", "ef66": "#5f8787", "ef67": "#5f87af", "ef68": "#5f87d7", "ef69": "#5f87ff", "ef70": "#5faf00",
|
||||
"ef71": "#5faf5f", "ef72": "#5faf87", "ef73": "#5fafaf", "ef74": "#5fafd7", "ef75": "#5fafff", "ef76": "#5fd700", "ef77": "#5fd75f", "ef78": "#5fd787", "ef79": "#5fd7af",
|
||||
"ef80": "#5fd7d7", "ef81": "#5fd7ff", "ef82": "#5fff00", "ef83": "#5fff5f", "ef84": "#5fff87", "ef85": "#5fffaf", "ef86": "#5fffd7", "ef87": "#5fffff", "ef88": "#870000",
|
||||
"ef89": "#87005f", "ef90": "#870087", "ef91": "#8700af", "ef92": "#8700d7", "ef93": "#8700ff", "ef94": "#875f00", "ef95": "#875f5f", "ef96": "#875f87", "ef97": "#875faf",
|
||||
"ef98": "#875fd7", "ef99": "#875fff", "ef100": "#878700", "ef101": "#87875f", "ef102": "#878787", "ef103": "#8787af", "ef104": "#8787d7", "ef105": "#8787ff", "ef106": "#87af00",
|
||||
"ef107": "#87af5f", "ef108": "#87af87", "ef109": "#87afaf", "ef110": "#87afd7", "ef111": "#87afff", "ef112": "#87d700", "ef113": "#87d75f", "ef114": "#87d787", "ef115": "#87d7af",
|
||||
"ef116": "#87d7d7", "ef117": "#87d7ff", "ef118": "#87ff00", "ef119": "#87ff5f", "ef120": "#87ff87", "ef121": "#87ffaf", "ef122": "#87ffd7", "ef123": "#87ffff", "ef124": "#af0000",
|
||||
"ef125": "#af005f", "ef126": "#af0087", "ef127": "#af00af", "ef128": "#af00d7", "ef129": "#af00ff", "ef130": "#af5f00", "ef131": "#af5f5f", "ef132": "#af5f87", "ef133": "#af5faf",
|
||||
"ef134": "#af5fd7", "ef135": "#af5fff", "ef136": "#af8700", "ef137": "#af875f", "ef138": "#af8787", "ef139": "#af87af", "ef140": "#af87d7", "ef141": "#af87ff", "ef142": "#afaf00",
|
||||
"ef143": "#afaf5f", "ef144": "#afaf87", "ef145": "#afafaf", "ef146": "#afafd7", "ef147": "#afafff", "ef148": "#afd700", "ef149": "#afd75f", "ef150": "#afd787", "ef151": "#afd7af",
|
||||
"ef152": "#afd7d7", "ef153": "#afd7ff", "ef154": "#afff00", "ef155": "#afff5f", "ef156": "#afff87", "ef157": "#afffaf", "ef158": "#afffd7", "ef159": "#afffff", "ef160": "#d70000",
|
||||
"ef161": "#d7005f", "ef162": "#d70087", "ef163": "#d700af", "ef164": "#d700d7", "ef165": "#d700ff", "ef166": "#d75f00", "ef167": "#d75f5f", "ef168": "#d75f87", "ef169": "#d75faf",
|
||||
"ef170": "#d75fd7", "ef171": "#d75fff", "ef172": "#d78700", "ef173": "#d7875f", "ef174": "#d78787", "ef175": "#d787af", "ef176": "#d787d7", "ef177": "#d787ff", "ef178": "#d7af00",
|
||||
"ef179": "#d7af5f", "ef180": "#d7af87", "ef181": "#d7afaf", "ef182": "#d7afd7", "ef183": "#d7afff", "ef184": "#d7d700", "ef185": "#d7d75f", "ef186": "#d7d787", "ef187": "#d7d7af",
|
||||
"ef188": "#d7d7d7", "ef189": "#d7d7ff", "ef190": "#d7ff00", "ef191": "#d7ff5f", "ef192": "#d7ff87", "ef193": "#d7ffaf", "ef194": "#d7ffd7", "ef195": "#d7ffff", "ef196": "#ff0000",
|
||||
"ef197": "#ff005f", "ef198": "#ff0087", "ef199": "#ff00af", "ef200": "#ff00d7", "ef201": "#ff00ff", "ef202": "#ff5f00", "ef203": "#ff5f5f", "ef204": "#ff5f87", "ef205": "#ff5faf",
|
||||
"ef206": "#ff5fd7", "ef207": "#ff5fff", "ef208": "#ff8700", "ef209": "#ff875f", "ef210": "#ff8787", "ef211": "#ff87af", "ef212": "#ff87d7", "ef213": "#ff87ff", "ef214": "#ffaf00",
|
||||
"ef215": "#ffaf5f", "ef216": "#ffaf87", "ef217": "#ffafaf", "ef218": "#ffafd7", "ef219": "#ffafff", "ef220": "#ffd700", "ef221": "#ffd75f", "ef222": "#ffd787", "ef223": "#ffd7af",
|
||||
"ef224": "#ffd7d7", "ef225": "#ffd7ff", "ef226": "#ffff00", "ef227": "#ffff5f", "ef228": "#ffff87", "ef229": "#ffffaf", "ef230": "#ffffd7", "ef231": "#ffffff", "ef232": "#080808",
|
||||
"ef233": "#121212", "ef234": "#1c1c1c", "ef235": "#262626", "ef236": "#303030", "ef237": "#3a3a3a", "ef238": "#444444", "ef239": "#4e4e4e", "ef240": "#585858", "ef241": "#626262",
|
||||
"ef242": "#6c6c6c", "ef243": "#767676", "ef244": "#808080", "ef245": "#8a8a8a", "ef246": "#949494", "ef247": "#9e9e9e", "ef248": "#a8a8a8", "ef249": "#b2b2b2", "ef250": "#bcbcbc",
|
||||
"ef251": "#c6c6c6", "ef252": "#d0d0d0", "ef253": "#dadada", "ef254": "#e4e4e4", "ef255": "#eeeeee", }
|
||||
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
|
||||
set2rgb = { 52: '#470000', 94: '#472100', 100: '#474700', 58: '#324700', 22: '#004700', 29: '#00472C', 23: '#004747', 24: '#002747', 17: '#000047', 54: '#2E0047', 53: '#470047', 89: '#47002A',
|
||||
88: '#740000', 130: '#743A00', 142: '#747400', 64: '#517400', 28: '#007400', 35: '#007449', 30: '#007474', 25: '#004074', 18: '#000074', 91: '#4B0074', 90: '#740074', 125: '#740045',
|
||||
124: '#B50000', 166: '#B56300', 184: '#B5B500', 106: '#7DB500', 34: '#00B500', 49: '#00B571', 37: '#00B5B5', 33: '#0063B5', 19: '#0000B5', 129: '#7500B5', 127: '#B500B5', 161: '#B5006B',
|
||||
196: '#FF0000', 208: '#FF8C00', 226: '#FFFF00', 154: '#B2FF00', 46: '#00FF00', 86: '#00FFA0', 51: '#00FFFF', 75: '#008CFF', 21: '#0000FF', 171: '#A500FF', 201: '#FF00FF', 198: '#FF0098',
|
||||
203: '#FF5959', 215: '#FFB459', 227: '#FFFF71', 191: '#CFFF60', 83: '#6FFF6F', 122: '#65FFC9', 87: '#6DFFFF', 111: '#59B4FF', 63: '#5959FF', 177: '#C459FF', 207: '#FF66FF', 205: '#FF59BC',
|
||||
217: '#FF9C9C', 223: '#FFD39C', 229: '#FFFF9C', 193: '#E2FF9C', 157: '#9CFF9C', 158: '#9CFFDB', 159: '#9CFFFF', 153: '#9CD3FF', 147: '#9CD3FF', 183: '#DC9CFF', 219: '#FF9CFF', 212: '#FF94D3',
|
||||
16: '#000000', 233: '#131313', 235: '#282828', 237: '#363636', 239: '#4D4D4D', 241: '#656565', 244: '#818181', 247: '#9F9F9F', 250: '#BCBCBC', 254: '#E2E2E2', 231: '#FFFFFF', }
|
||||
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
def ratesex_request(self,site,commands):
|
||||
USER_AGENT_BROWSER="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
|
||||
USER_AGENT_CURL="curl/7.29.0"
|
||||
STATUS_BAD_CODE=":( - error code: {}"
|
||||
STATUS_BAD_REASON=":( - failed reason: {}"
|
||||
STATUS_OK=":)"
|
||||
|
||||
if site != 'rate':
|
||||
url = f"https://{site}.rate.sx/{commands}"
|
||||
else:
|
||||
url = f"https://rate.sx/{commands}"
|
||||
r = Request(url,data=None,headers={ 'User-Agent': USER_AGENT_CURL })
|
||||
try:
|
||||
response = urlopen(r,timeout=10).read().decode('utf-8')
|
||||
except HTTPError as e:
|
||||
return STATUS_BAD_CODE.format(e.code)
|
||||
except URLError as e:
|
||||
return STATUS_BAD_REASON.format(e.reason)
|
||||
else:
|
||||
return STATUS_OK + response
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def escape_ansi(self,line):
|
||||
ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
|
||||
return ansi_escape.sub('', str(line))
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def invert_dict(self,d):
|
||||
return {v: k for k, v in d.items()}
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def enumerate_dict(self,d):
|
||||
return list(zip(list(d),list(invert_dict(d)),range(len(d))))
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def organize_dict(self,d):
|
||||
_d=list(d.values())
|
||||
return _d.sort()
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def escape_ansi(self,line):
|
||||
ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
|
||||
return ansi_escape.sub('', str(line))
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def hex2gravity(self,h):
|
||||
r,g,b=int(h[1:3],16),int(h[3:5],16),int(h[5:7],16)
|
||||
o=list(set2rgb.values()); o.sort()
|
||||
_R=[]; _G=[]; _B=[];
|
||||
|
||||
for _ in o:
|
||||
R,G,B=(''.join([x for x in _[1:][:2]]).zfill(2)),(''.join([x for x in _[1:][2:4]]).zfill(2)),(''.join([x for x in _[1:][4:6]]).zfill(2))
|
||||
_R.append(int(R,16)); _G.append(int(G,16)); _B.append(int(B,16));
|
||||
|
||||
_r = []
|
||||
for _ in _R:
|
||||
if r < _:
|
||||
rsub = _ - r
|
||||
else:
|
||||
rsub = r - _
|
||||
_r.append(rsub)
|
||||
|
||||
_g = []
|
||||
for _ in _G:
|
||||
if g < _:
|
||||
gsub = _ - g
|
||||
else:
|
||||
gsub = g - _
|
||||
_g.append(gsub)
|
||||
|
||||
_b = []
|
||||
for _ in _B:
|
||||
if b < _:
|
||||
bsub = _ - b
|
||||
else:
|
||||
bsub = b - _
|
||||
_b.append(bsub)
|
||||
rgb = []
|
||||
for _ in range(len(_r)):
|
||||
rgb.append(_r[_]+_g[_]+_b[_])
|
||||
nearest_color_minus = min(rgb)
|
||||
nearest_color_index = [i for i, x in enumerate(rgb) if x == nearest_color_minus]
|
||||
nearest_color = o[nearest_color_index[0]]
|
||||
return str(f"\x03{rgb2irc[self.invert_dict(set2rgb)[nearest_color]]}")
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def parse_control(self,s):
|
||||
px=[]
|
||||
py=[]
|
||||
_s=s
|
||||
px=self.findall(_s,'\x1b')
|
||||
for i,_ in enumerate(px):
|
||||
py.append( _s.find('m',_)+1 )
|
||||
return px,py
|
||||
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def findall(self,s,w):
|
||||
return [i for i in range(len(s)) if s.startswith(w, i)]
|
||||
|
||||
#######################################################################################
|
||||
|
||||
def color_line(self,s,t):
|
||||
codes=["\x1b[0m","\x1b[30m","\x1b[31m","\x1b[32m","\x1b[33m","\x1b[34m","\x1b[35m","\x1b[36m","\x1b[37m","\x1b[40m","\x1b[41m","\x1b[42m","\x1b[43m","\x1b[44m","\x1b[45m","\x1b[46m","\x1b[47m","\x1b(B","\x1b[m","\x1b[2m"]
|
||||
colors=["\x0f","\x0301","\x0304","\x0303","\x0308","\x03002","\x0313","\x0311","\x0300","\x03,01","\x03,04","\x03,03","\x03,08","\x03,02","\x03,13","\x03,11","\x03,00","","\x0f",""] #f.write('\x0301,00decoded\n')
|
||||
_s=s
|
||||
p=[]
|
||||
for _ in range(len(t[0])):
|
||||
r=self.findall(s[t[0][_]:t[1][_]],'\x1b')
|
||||
|
||||
for __ in range(len(r)):
|
||||
if not __ == len(r)-1:
|
||||
p.append(s[t[0][_]:t[1][_]][r[__]:r[__+1]])
|
||||
else:
|
||||
check = s[t[0][_]:t[1][_]][r[__]:]
|
||||
if check.find('mm') == -1:
|
||||
p.append(check)
|
||||
else:
|
||||
p.append(check[:-1])
|
||||
for __ in p:
|
||||
_s = _s.replace(__,"{}")
|
||||
c=[]
|
||||
for _ in p:
|
||||
for i,__ in enumerate(codes):
|
||||
if _ == __:
|
||||
c.append(colors[i])
|
||||
if _.find('\x1b[38;5;') != -1:
|
||||
gravity = _.replace('\x1b[38;5;','')[:-1]
|
||||
farthest_color_hex = rgb2set['ef{}'.format(gravity)]
|
||||
result = self.hex2gravity(farthest_color_hex)
|
||||
c.append(result)
|
||||
|
||||
r=self.findall(_s,'{}')
|
||||
|
||||
for _ in range(len(r)):
|
||||
_s=_s.replace('{}',c[_],1)
|
||||
return _s
|
||||
|
||||
#######################################################################################
|
||||
|
||||
@command(permission='view')
|
||||
def ratesex(self, mask, target, args):
|
||||
"""ratesex - help/commands: visit 'https://rate.sx/:help' or try '?ratesex rate :help', to check exchange rates for top 10 ^cripdoeocurrencies try '?ratesex rate top10.. sites added. rate,eur,btc,rub.. e.g. ?ratesex rate command, ?ratesex eur, ?ratesex btc, ?ratesex rub'
|
||||
%%ratesex [<site>] [<command>]
|
||||
"""
|
||||
|
||||
site = args.get("<site>")
|
||||
command = args.get("<command>")
|
||||
|
||||
if command == "":
|
||||
msg="error: no command issued.. ?ratesex rate, ?ratesex rate eth, ?ratesex rate :help, ?ratesex btc top10"
|
||||
self.bot.privmsg(target, msg)
|
||||
|
||||
sites=['rate','rub','eur','btc']
|
||||
FLAG=0
|
||||
for _ in sites:
|
||||
if site == _:
|
||||
FLAG=1
|
||||
if not FLAG==1:
|
||||
msg="error: no site issued. sites: rate,rub,eur,btc. e.g. ?ratesex rate :help, ?ratesex btc top10, ?ratesex rub top10"
|
||||
self.bot.privmsg(target, msg)
|
||||
if command.lower() == 'top10': command = ''
|
||||
response=self.ratesex_request(site,command)
|
||||
s = ''
|
||||
for _ in response:
|
||||
s = s + ''.join(_)
|
||||
r1=s[2:].splitlines()
|
||||
for i in range(len(r1)-1):
|
||||
d=self.parse_control(r1[i])
|
||||
r=self.color_line(r1[i],d)
|
||||
if not r == '':
|
||||
msg = r+'\n'
|
||||
self.bot.privmsg(target, msg)
|
||||
|
||||
#######################################################################################
|
||||
|
||||
|
||||
__doc__ = ''':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::.
|
||||
/mMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNd-
|
||||
-MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN`
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmNMMMMMMMMMMMmMMMMMMMMMMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh:NMMMMMMMMMMoyMMMMMMMMMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMm -NMMMMMMMMMs.NMMMMMMMMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMy -hmmmmmNNm- sMMMMMMMMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmdyo+:` ```````.` .NMMMymMMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmy+-.` -hNm-+MMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMms:` `.. /MMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh/. /MMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMmMMMMMMMMMMMmhN:` /MMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMM+sNMMMMMMMMMN-h: `-+syyys/- -NMMMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMs +NMMMMMMMhm--d` :. -sdNMMMMMNNmy. :ydMMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMM+ :yhyyyhhso` os yhshNMMMMMMMh+:-:. :s- .NMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMmho` ` `yo.h:sMMMMMMMMMMNd+. -NNs- yMMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMMMNh/. :++`-MMMMMMMMMMMMMm+` :ymds. -NMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMMMmo- .MMMMMMMMMMMMMMMdo. `.-` yMMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMMMmo. `NMMMMMMMMMMMMMMMMNy/.` `mMMMMMMMMMMMMMMM-
|
||||
/MMMMMMMNs. hMMMMMMMMMMMMMMMMMMMNho-` :NMMMMMMMMMMMMMM-
|
||||
/MMMMMMm: ./syyyo- -hmNMMMMMMMMMMMMMMMMMMMMmho:.` /NMMMMMMMMMMMMM-
|
||||
/MMMMMd. .smMMMNNNms` ` `+MMMMMMMMMMMMMMMMMMMMMMMMNdy/ `.yMMMMMMMMMMMMM-
|
||||
/MMMMd. /mMMMMMy/:--` so. `mMMMMMMMMMMMMMMMMMMMMMMMNdo--:+sdNMMMMMMMMMMMMMM-
|
||||
/MMMN- /NMMMMMMMMdo. oMm+. /MMMMMMMMMMMMMMMMdNMMMMMMNNNMMmMMMMMMMMMMMMMMMMM-
|
||||
/MMMo -NMMMMMMMMMMdso-` /hmm+ sMMMMMMMMMMMMMMMs-mMMMMMMMMMM:dMMMMMMMMMMMMMMMM-
|
||||
/MMN. sMMMMMMMMMMMo .os/.``.. `dMMMMMMMMMMMMMMs -NMMMMMMMMM-:MMMMMMMMMMMMMMMM-
|
||||
/MMd mMMMMMMMMMMM/ `:os+-` .dMMMMMMMMMMMNm. -soosyhdms `mMMMMMMMMMMMMMMM-
|
||||
/MMs mMMMMMMMMMMM: .hNhs/.` .dMMMMNmhs+:-` +MMMNoMMMMMMMMMM-
|
||||
/MMy hMMMMMMMMMMM: oMMMMMNdyo/. .mNh+-` +mNy`mMMMMMMMMM-
|
||||
/MMd +MMMMMMMMMMM/ :MMMMMMMMNs.`.:ohh/` ` mMMMMMMMMM-
|
||||
/MMN. `mMMMMMMMMMMo `NMMMMMMNhhdNMMh: mMMMMMMMMM-
|
||||
/MMM+ /MMMMMMMMMMh yMMMMMMMMMMMN+ `NMMMMMMMMM-
|
||||
/MMMm` +MMMMMMMMMN` .NMMMMMMMMMN- :sdmNNNdy+` dMMMMMMMMM-
|
||||
/MMMMo +MMMMMMMMM+ +MMMMMMMMM/ -dMMMMMMNmmNN/ .sdMMMMMMM-
|
||||
/MMMMN: :mMMMMMMMm` oMMMMMMMh .mMMMMMMMms- `` /o` `mMMMMMM-
|
||||
/MMMMMm. .yMMMMMMMo oMMMMMM/ sMMMMMMMMMMMh: :NNo. sMMMMMM-
|
||||
/MMMMMMm. -hMMMMMN: /NMMMM. dMMMMMMMMMMMMMh- :hmNy` .NMMMMM-
|
||||
/MMMMMMMm- -yNMMMm. .yMMM. dMMMMMMMMMMMMMMNh:` `..` yMMMMM-
|
||||
/MMMMMMMMN+ .+hNMd. :hM: dMMMMMMMMMMMMMMMMNmo- .NMMMM-
|
||||
/MMMMMMMMMMh- ./ss. `:: sMMMMMMMMMMMMMMMMMMMNms/. /MMMM-
|
||||
/MMMMMMMMMMMNo. ` :MMMMMMMMMMMMMMMMMMMMMMMNdo:.` oMMM-
|
||||
/MMMMMMMMMMMMMmo. `mMMMMMMMMMMMMMMMMMMMMMMMMMMNmh: .dMM-
|
||||
/MMMMMMMMMMMMMMMNy:` +MMMMMMMMMMMMMMMMMMMMMMMMMMNh+::/+sdNMMM-
|
||||
/MMMMMMMMMMMMMMMMMNdo- `dMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNMMMMMMMM-
|
||||
/MMMMMMMMMMMMMMMMMMMMNd+-` -NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM-
|
||||
-NMMMMMMMMMMMMMMMMMMMMMMNdo:` /NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMd`
|
||||
-ymNNNNNNNNNNNNNNNNNNNNNNNNdo-` +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNmy.
|
||||
............................ .-...............................`
|
||||
`````` ````````` `````````````` `````````` ```'''
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,107 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
from irc3.plugins.cron import cron
|
||||
import irc3
|
||||
from datetime import datetime
|
||||
from time import time
|
||||
import re
|
||||
REMIND_RE = re.compile('maple.remind\s(.+?)\s(.+)')
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __triggered(i):
|
||||
time_now = int(str(time()).split('.')[0])
|
||||
if i <= time_now:
|
||||
print('triggered')
|
||||
else:
|
||||
print('not triggered')
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg_search_for_remind(self, mask=None, target=None, data=None, **kw):
|
||||
match_list = REMIND_RE.findall(data)
|
||||
if len(match_list) > 0:
|
||||
stime = ""
|
||||
trigger = ""
|
||||
bhours = False
|
||||
bminutes = False
|
||||
tell_nick, message = match_list[0]
|
||||
if tell_nick == 'me': tell_nick = mask.nick
|
||||
if not message.split()[0].lower() == 'in':
|
||||
irc_message = "TCPDIRECT/REMIND: reminding {} the format is maple remind ircnick in 2h15m to pet cat, or maple remind me in 1h to pet cat.".format(mask.nick)
|
||||
self.bot.privmsg(target, self.bot.emo(irc_message))
|
||||
return
|
||||
else:
|
||||
message = message[3:]
|
||||
trigger = message.split()[0]
|
||||
message = message[len(trigger)+1:]
|
||||
message_list = self.bot.db.getlist("remind_%s" % tell_nick.lower())
|
||||
ihours = 0
|
||||
iminutes = 0
|
||||
xpos = 0
|
||||
ypos = 0
|
||||
itrigger = 0
|
||||
epoch_time = int(str(time()).split('.')[0])
|
||||
stime = trigger
|
||||
try:
|
||||
if not stime.lower().find('h') == -1:
|
||||
xpos = stime.lower().find('h')+1
|
||||
hours = int(stime[:stime.lower().find('h')])
|
||||
ihours = hours * (60*60)
|
||||
if not stime.lower().find('m') == -1:
|
||||
ypos = stime.lower().find('m')
|
||||
minutes = int(stime[xpos:ypos])
|
||||
if minutes < 1:
|
||||
irc_message = "TCPDIRECT/REMIND: reminding {} to quit wasting my time. format is maple remind ircnick in 2h15m to pet cat, or maple remind me in 1h to pet cat.".format(mask.nick)
|
||||
self.bot.privmsg(target, self.bot.emo(irc_message))
|
||||
return
|
||||
iminutes = minutes * 60
|
||||
except:
|
||||
irc_message = "TCPDIRECT/REMIND: reminding {} to go and fuck themself err i mean, format is maple remind ircnick in 2h15m to pet cat, or maple remind me in 1h to pet cat.".format(mask.nick)
|
||||
self.bot.privmsg(target, self.bot.emo(irc_message))
|
||||
return
|
||||
epoch_trigger = epoch_time + ihours + iminutes
|
||||
if epoch_trigger <= epoch_time:
|
||||
irc_message = "TCPDIRECT/REMIND: reminding {} to quit wasting my time. format is maple remind ircnick in 2h15m to pet cat, or maple remind me in 1h to pet cat.".format(mask.nick)
|
||||
self.bot.privmsg(target, self.bot.emo(irc_message))
|
||||
return
|
||||
new_message = {"from": mask.nick.lower(), "target": target, "message": message, "time": datetime.now().isoformat(), "etime": epoch_time, "etrigger": epoch_trigger }
|
||||
if not message_list:
|
||||
message_list = self.bot.db.setlist("remind_%s" % tell_nick.lower(), [new_message])
|
||||
else:
|
||||
message_list.append(new_message)
|
||||
self.bot.db.setlist("remind_%s" % tell_nick.lower(), message_list)
|
||||
irc_message = "TCPDIRECT/REMIND: {} < {} > reminding < {} > {}".format(new_message.get("time"),new_message.get("from"),tell_nick,new_message.get("message"))
|
||||
self.bot.privmsg(target, self.bot.emo(irc_message))
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@cron('* * * * *')
|
||||
def _reminding(bot):
|
||||
nicks = ','.join(bot.db.context.nicks.keys()).split(',')
|
||||
for _ in nicks:
|
||||
if bot.db.getlist('remind_{}'.format(_)):
|
||||
_keys = []
|
||||
for __ in bot.db.getlist('remind_{}'.format(_)):
|
||||
etime = __['etime']
|
||||
etrigger = __['etrigger']
|
||||
_from = __['from']
|
||||
_target = __['target']
|
||||
_message = __['message']
|
||||
etime_now = int(str(time()).split('.')[0])
|
||||
if etime_now >= etrigger:
|
||||
msg = "TCPDIRECT/REMIND: < {} > reminded < {} > - {}".format(_from,_,_message)
|
||||
bot.privmsg(_target,msg)
|
||||
else:
|
||||
_keys.append(__)
|
||||
bot.db.setlist("remind_{}".format(_),_keys)
|
||||
###########################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,48 @@
|
|||
# -*- coding: utf-8 -*- ########################################################## SOF
|
||||
import irc3,os,base64
|
||||
######################################################################################
|
||||
BOT_SASL_USERNAME=os.environ['BOT_SASL_USERNAME']
|
||||
BOT_SASL_PASSWORD=os.environ['BOT_SASL_PASSWORD']
|
||||
######################################################################################
|
||||
@irc3.plugin
|
||||
class DR1PSASL:
|
||||
##################################################################################
|
||||
def __init__(self, bot):
|
||||
print('<<< _sasl_custom_plugin >>> [ custom sasl initiated ]')
|
||||
self.bot=bot
|
||||
self.auth=(f'{BOT_SASL_USERNAME}\0{BOT_SASL_USERNAME}\0{BOT_SASL_PASSWORD}')
|
||||
self.auth=base64.encodebytes(self.auth.encode('utf8'))
|
||||
self.auth=self.auth.decode('utf8').rstrip('\n')
|
||||
self.events = [
|
||||
irc3.event(r'^:\S+ CAP \S+ LS :(?P<data>.*)', self.cap_ls),
|
||||
irc3.event(r'^:\S+ CAP \S+ ACK sasl', self.cap_ack),
|
||||
irc3.event(r'AUTHENTICATE +', self.authenticate),
|
||||
irc3.event(r'^:\S+ 903 \S+ :Authentication successful',self.cap_end),
|
||||
]
|
||||
##################################################################################
|
||||
def connection_ready(self, *args, **kwargs):
|
||||
print('<<< _sasl_custom_plugin >>> [ CAP LS ]')
|
||||
self.bot.send('CAP LS\r\n')
|
||||
self.bot.attach_events(*self.events)
|
||||
##################################################################################
|
||||
def cap_ls(self, data=None, **kwargs):
|
||||
print('<<< _sasl_custom_plugin >>> [ CAP REQ :sasl ]')
|
||||
if 'sasl' in data.lower():
|
||||
self.bot.send_line('CAP REQ :sasl')
|
||||
else:
|
||||
self.cap_end()
|
||||
##################################################################################
|
||||
def cap_ack(self, **kwargs):
|
||||
print('<<< _sasl_custom_plugin >>> [ AUTHENTICATE PLAIN ]')
|
||||
self.bot.send_line('AUTHENTICATE PLAIN')
|
||||
##################################################################################
|
||||
def authenticate(self, **kwargs):
|
||||
print(f'<<< _sasl_custom_plugin >>> [ AUTHENTICATE {self.auth} ]')
|
||||
self.bot.send_line(f'AUTHENTICATE {self.auth}\n')
|
||||
##################################################################################
|
||||
def cap_end(self, **kwargs):
|
||||
print('<<< _sasl_custom_plugin >>> [ CAP END ]')
|
||||
self.bot.send_line('CAP END\r\n')
|
||||
self.bot.detach_events(*self.events)
|
||||
##################################################################################
|
||||
################################################################################## EOF
|
|
@ -0,0 +1,96 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import irc3
|
||||
import os
|
||||
import random
|
||||
from string import ascii_lowercase as alpha
|
||||
SED1_RE = "s/"
|
||||
SED2_RE = "j/"
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
class TCPSED():
|
||||
buffer_text=[]
|
||||
buffer_nick=[]
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self):
|
||||
return
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def push(self,data,nick):
|
||||
self.buffer_text=self.buffer_text[-1:]+self.buffer_text[:-1]
|
||||
self.buffer_text[0]=data
|
||||
self.buffer_nick=self.buffer_nick[-1:]+self.buffer_nick[:-1]
|
||||
self.buffer_nick[0]=nick
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.d=TCPSED()
|
||||
for _ in range(2000):
|
||||
self.d.buffer_text.append('')
|
||||
self.d.buffer_nick.append('')
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg_search_for_sed(self, mask=None, target=None, data=None, **kw):
|
||||
if self.bot.config.nick == mask.nick:
|
||||
return
|
||||
if mask.nick.lower() == 'nickserv':
|
||||
return
|
||||
flag=0
|
||||
offset = -1
|
||||
offset = data.find(SED1_RE)
|
||||
if not offset == 0:
|
||||
offset = data.find(SED2_RE)
|
||||
if offset == 0:
|
||||
flag=1
|
||||
else:
|
||||
flag=1
|
||||
if flag==0:
|
||||
self.d.push(data,mask.nick)
|
||||
return
|
||||
_data=data.split('/')
|
||||
_from=''
|
||||
_to=''
|
||||
_mode=''
|
||||
try:
|
||||
_from=_data[1]
|
||||
_to=_data[2]
|
||||
except Exception as e:
|
||||
irc_message = f'TCPDIRECT/SED - Error: {e}'
|
||||
self.bot.privmsg(target, self.bot.emo(irc_message))
|
||||
return
|
||||
itwist=-1
|
||||
count=0
|
||||
for i,_ in enumerate(self.d.buffer_text):
|
||||
if not _ == '':
|
||||
itwist=i
|
||||
count = len([_i for _i in range(len(_)) if _.startswith(_from, _i)])
|
||||
if count == 1:
|
||||
self.d.buffer_text[i] = self.d.buffer_text[i].replace(_from,_to)
|
||||
break
|
||||
elif count > 1:
|
||||
self.d.buffer_text[i] = self.d.buffer_text[i].replace(_from,_to,1)
|
||||
break
|
||||
if count != 0:
|
||||
irc_message = "{}: {}".format(self.d.buffer_nick[itwist],self.d.buffer_text[itwist])
|
||||
else:
|
||||
irc_message = f"TCPDIRECT/SED - Error: no result for: {data}"
|
||||
try:
|
||||
if irc_message.find('\x01ACTION'):
|
||||
nick,msg=irc_message.split(': ')
|
||||
msg="\x01ACTION "+nick+": "+msg.split('\x01ACTION ')[1]
|
||||
self.bot.privmsg(target,msg)
|
||||
else:
|
||||
self.bot.privmsg(target,self.bot.emo(irc_message))
|
||||
except:
|
||||
self.bot.privmsg(target,self.bot.emo(irc_message))
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,128 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
from datetime import datetime
|
||||
import operator
|
||||
import irc3
|
||||
import timeago
|
||||
import dateutil.parser
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
return
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.NEW_NICK)
|
||||
def on_nick_change_for_seen(self, nick, new_nick):
|
||||
# record of nickchanges, these are kept
|
||||
# "5": {
|
||||
# "msg": "_d changed nick to d",
|
||||
# "time": "2021-10-03T00:24:03.040916",
|
||||
# "type": "newnick"
|
||||
# },
|
||||
new_key = "last_msg_for_{}".format(new_nick).lower()
|
||||
msg_list = self.bot.db.getlist(new_key)
|
||||
if not msg_list:
|
||||
msg_list = []
|
||||
seen_msg = { "type": "newnick",
|
||||
"time": datetime.now().isoformat(),
|
||||
"msg": "{} changed nick to {}".format(nick.nick, new_nick)}
|
||||
msg_list.append(seen_msg)
|
||||
self.bot.db.setlist(new_key, msg_list)
|
||||
return
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg_for_seen(self, mask=None, target=None, data=None, **kw):
|
||||
if data.startswith("?"): return # no ?
|
||||
if mask.lnick == self.bot.get_nick().lower(): return # Ignore ourseves
|
||||
key = "last_msg_for_{}".format(mask.nick).lower()
|
||||
messages = self.bot.db.getlist(key)
|
||||
# record of did a user speak this day and if so how many words spoken
|
||||
# if there is a record that day, they spoke. if there is no record for that
|
||||
# day then they didn't speak. this data is used as historicals to discern
|
||||
# true lurkers from idlers which are two very different things entirely.
|
||||
# <<< this record specifically will be used in plugins/dsa_plugin.py >>>
|
||||
# record created:
|
||||
# "41": {
|
||||
# "msg": 5,
|
||||
# "time": "2022-07-27",
|
||||
# "type": "activity"
|
||||
# },
|
||||
words_count=0
|
||||
if not messages:
|
||||
messages = []
|
||||
else:
|
||||
for count, msg in enumerate(messages):
|
||||
if msg.get("type") == "activity":
|
||||
if msg.get("time") == datetime.now().isoformat().split('T')[0]:
|
||||
words_count+=int(msg.get('msg'))
|
||||
del(messages[count])
|
||||
activity_msg = { "type": "activity",
|
||||
"time": datetime.now().isoformat().split('T')[0],
|
||||
"msg": len(data.split())+words_count }
|
||||
messages.append(activity_msg)
|
||||
self.bot.db.setlist(key, messages)
|
||||
# all historical privmsg destroyed, and only one retained for seen
|
||||
# "42": {
|
||||
# "msg": "a b c d e",
|
||||
# "time": "2022-07-27T07:26:41.937448",
|
||||
# "type": "privmsg"
|
||||
# },
|
||||
key = "last_msg_for_{}".format(mask.nick).lower()
|
||||
priv_msg = { "type": "privmsg",
|
||||
"time": datetime.now().isoformat(),
|
||||
"msg": data }
|
||||
messages = self.bot.db.getlist(key)
|
||||
if not messages:
|
||||
messages = []
|
||||
else:
|
||||
for count, msg in enumerate(messages):
|
||||
if msg.get("type") == "privmsg":
|
||||
del(messages[count])
|
||||
messages.append(priv_msg)
|
||||
self.bot.db.setlist(key, messages)
|
||||
return
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def seen(self, mask, target, args):
|
||||
"""Display last time user was seen
|
||||
%%seen <nick>
|
||||
"""
|
||||
nick = args.get("<nick>")
|
||||
if nick.lower() == self.bot.get_nick().lower():
|
||||
msg = "please don't spy on me..."
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
key = "last_msg_for_{}".format(nick).lower()
|
||||
message_list = self.bot.db.getlist(key)
|
||||
if message_list:
|
||||
message_list.sort(key=operator.itemgetter('time'), reverse=True)
|
||||
nick_seen_set = set()
|
||||
for msg in message_list:
|
||||
if msg.get("type") == "newnick":
|
||||
notice_msg = msg.get("msg").lower()
|
||||
nick_to_remember = [ item.strip() for item in notice_msg.split("changed nick to")].pop()
|
||||
if nick_to_remember in nick_seen_set:
|
||||
continue
|
||||
else:
|
||||
nick_seen_set.add(nick_to_remember)
|
||||
msg_time = dateutil.parser.parse(msg.get("time"))
|
||||
time_since = timeago.format(msg_time, datetime.now())
|
||||
msg = "\x02{}\x0F \x0303>\x0F \x02\x0302{}\x0F \x0306፨ \x0F\x1F\x1D{}\x0F".format(nick, msg.get("msg"), time_since.capitalize())
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
else:
|
||||
msg = "{} Has Not Been Seen".format(nick)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,88 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import URLError, HTTPError
|
||||
from urllib.parse import quote_plus
|
||||
import html
|
||||
import requests
|
||||
from lxml.html import fromstring
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __soundcloud__request(self,command,query):
|
||||
USER_AGENT_CURL="curl/7.29.0"
|
||||
STATUS_BAD_CODE=":( - error code: {}"
|
||||
STATUS_BAD_REASON=":( - failed reason: {}"
|
||||
STATUS_OK=":)"
|
||||
COMMANDS=['search']
|
||||
for _ in COMMANDS:
|
||||
if _==command.lower():
|
||||
url=f'https://soundcloud.com/{_}?q={quote_plus(query)}'
|
||||
r=Request(url,data=None,headers={'User-Agent':USER_AGENT_CURL})
|
||||
try:
|
||||
response=urlopen(r,timeout=10).read().decode('utf-8')
|
||||
except HTTPError as e:
|
||||
return STATUS_BAD_CODE.format(e.code)
|
||||
except URLError as e:
|
||||
return STATUS_BAD_REASON.format(e.reason)
|
||||
else:
|
||||
return STATUS_OK+response
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def sc(self, mask, target, args):
|
||||
"""Soundcloud artist/song search.. example: ?sc yung innanet nano tapes cronjob
|
||||
%%sc <query>...
|
||||
"""
|
||||
NICK=mask.nick
|
||||
query=' '.join(args['<query>'])
|
||||
result=self.__soundcloud__request('search',query)
|
||||
pop=[];_path=[];_name=[];title='';
|
||||
for _ in result.splitlines():
|
||||
if _.find('<li><h2>') != -1:
|
||||
pop.append(_.strip())
|
||||
for _ in pop:
|
||||
_path.append(_.split('="/').pop().split('">')[0])
|
||||
_name.append(_.split('="/').pop().split('">')[1].split('<')[0])
|
||||
try:
|
||||
url=f'https://soundcloud.com/{_path[0]}'
|
||||
try:
|
||||
read_size = 0
|
||||
r=requests.get(url,timeout=3,stream=True)
|
||||
content_length=r.headers.get('Content-Length')
|
||||
if not content_length:
|
||||
content_length=0
|
||||
while read_size<=(2000*10):
|
||||
for content in r.iter_content(chunk_size=2000):
|
||||
tree=fromstring(content)
|
||||
title=tree.find(".//title")
|
||||
if title is not None:
|
||||
title=title.text.strip()[:100]
|
||||
break
|
||||
except:
|
||||
pass
|
||||
URL=f'https://soundcloud.com/{_path[0]}'
|
||||
TITLE=title.split('|')[0].split('by')[-1].strip()
|
||||
NAME=html.unescape(_name[0]);
|
||||
######## SOUNDCLOUD <-> BOOMBOX_PLUGIN HOOK ######## SOUNDCLOUD <-> BOOMBOX_PLUGIN HOOK ########
|
||||
self.bot.bbs.enter(NICK,URL,TITLE)
|
||||
######## SOUNDCLOUD <-> BOOMBOX_PLUGIN HOOK ######## SOUNDCLOUD <-> BOOMBOX_PLUGIN HOOK ########
|
||||
msg=f"\x02\x0302{NICK}\x0F\x02\x0304 > "
|
||||
msg+=f"\x0F\x02\x0313{NAME}\x0F\x02\x0304 > "
|
||||
msg+=f"\x0F\x02\x0312{URL}\x0F\x02\x0313\x0F\x02\x0304 > "
|
||||
msg+=f"\x0F\x1D\x0314{TITLE}\x0F\x02\x0304 "
|
||||
except:
|
||||
MSG='no result'
|
||||
msg=f"\x02\x0302{NICK}\x0F\x02\x0304 > "
|
||||
msg+=f"\x0F\x02\x0313{MSG}\x0F\x02\x0304 "
|
||||
self.bot.privmsg(target,self.bot.emo(f"{msg}"))
|
||||
###########################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,293 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import os
|
||||
try:
|
||||
import ujson as json
|
||||
except ImportError:
|
||||
import json
|
||||
import irc3
|
||||
import shelve
|
||||
###########################################################################################
|
||||
class Shelve:
|
||||
#######################################################################################
|
||||
def __init__(self, uri=None, **kwargs):
|
||||
self.filename = uri[9:]
|
||||
self.db = shelve.open(self.filename)
|
||||
#######################################################################################
|
||||
def set(self, key, value):
|
||||
self.db[key] = value
|
||||
self.db.sync()
|
||||
#######################################################################################
|
||||
def get(self, key):
|
||||
return self.db[key]
|
||||
#######################################################################################
|
||||
def delete(self, key):
|
||||
del self.db[key]
|
||||
self.sync()
|
||||
#######################################################################################
|
||||
def contains(self, key):
|
||||
return key in self.db
|
||||
#######################################################################################
|
||||
def sync(self):
|
||||
self.db.sync()
|
||||
#######################################################################################
|
||||
def close(self):
|
||||
self.db.close()
|
||||
###########################################################################################
|
||||
class JSON:
|
||||
def __init__(self, uri=None, **kwargs):
|
||||
self.filename = uri[7:]
|
||||
if os.path.isfile(self.filename): # pragma: no cover
|
||||
with open(self.filename) as fd:
|
||||
self.db = json.load(fd)
|
||||
else:
|
||||
self.db = {}
|
||||
#######################################################################################
|
||||
def set(self, key, value):
|
||||
self.db[key] = value
|
||||
self.sync()
|
||||
#######################################################################################
|
||||
def get(self, key):
|
||||
return self.db[key]
|
||||
#######################################################################################
|
||||
def delete(self, key):
|
||||
del self.db[key]
|
||||
self.sync()
|
||||
#######################################################################################
|
||||
def contains(self, key):
|
||||
return key in self.db
|
||||
#######################################################################################
|
||||
def sync(self):
|
||||
with open(self.filename, 'w') as fd:
|
||||
json.dump(self.db, fd, indent=2, sort_keys=True)
|
||||
#######################################################################################
|
||||
def close(self):
|
||||
self.sync()
|
||||
###########################################################################################
|
||||
class Redis:
|
||||
def __init__(self, uri=None, **kwargs):
|
||||
ConnectionPool = irc3.utils.maybedotted(
|
||||
'redis.connection.ConnectionPool')
|
||||
pool = ConnectionPool.from_url(uri)
|
||||
StrictRedis = irc3.utils.maybedotted('redis.client.StrictRedis')
|
||||
self.db = StrictRedis(connection_pool=pool)
|
||||
#######################################################################################
|
||||
def set(self, key, value):
|
||||
self.db.hmset(key, value)
|
||||
#######################################################################################
|
||||
def get(self, key):
|
||||
keys = self.db.hkeys(key)
|
||||
if not keys:
|
||||
raise KeyError()
|
||||
values = self.db.hmget(key, keys)
|
||||
keys = [k.decode('utf8') for k in keys]
|
||||
values = [v.decode('utf8') for v in values]
|
||||
values = dict(zip(keys, values))
|
||||
return values
|
||||
#######################################################################################
|
||||
def delete(self, key):
|
||||
self.db.delete(key)
|
||||
#######################################################################################
|
||||
def contains(self, key):
|
||||
return self.db.exists(key)
|
||||
#######################################################################################
|
||||
def flushdb(self):
|
||||
self.db.flushdb()
|
||||
#######################################################################################
|
||||
def sync(self):
|
||||
self.db.save()
|
||||
#######################################################################################
|
||||
def close(self):
|
||||
self.sync()
|
||||
###########################################################################################
|
||||
class SQLite:
|
||||
CREATE_TABLE = """
|
||||
CREATE TABLE IF NOT EXISTS
|
||||
irc3_storage (
|
||||
key text not null,
|
||||
value text default '',
|
||||
PRIMARY KEY (key)
|
||||
);
|
||||
"""
|
||||
UPSERT = """
|
||||
INSERT OR REPLACE INTO irc3_storage(key,value) VALUES(?, ?);
|
||||
"""
|
||||
#######################################################################################
|
||||
def __init__(self, uri=None, **kwargs):
|
||||
self.sqlite = irc3.utils.maybedotted('sqlite3')
|
||||
self.uri = uri.split('://')[-1]
|
||||
conn = self.sqlite.connect(self.uri)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(self.CREATE_TABLE)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
#######################################################################################
|
||||
def set(self, key, value):
|
||||
conn = self.sqlite.connect(self.uri)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(self.UPSERT, (key, json.dumps(value)))
|
||||
cursor.fetchall()
|
||||
conn.commit()
|
||||
conn.close()
|
||||
#######################################################################################
|
||||
def get(self, key):
|
||||
value = None
|
||||
conn = self.sqlite.connect(self.uri)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT value FROM irc3_storage where key=?;", (key,))
|
||||
for row in cursor.fetchall():
|
||||
value = json.loads(row[0])
|
||||
break
|
||||
cursor.close()
|
||||
conn.close()
|
||||
if value is None:
|
||||
raise KeyError(key)
|
||||
return value
|
||||
#######################################################################################
|
||||
def delete(self, key):
|
||||
conn = self.sqlite.connect(self.uri)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM irc3_storage where key=?;", (key,))
|
||||
cursor.close()
|
||||
conn.commit()
|
||||
conn.close()
|
||||
#######################################################################################
|
||||
def contains(self, key):
|
||||
conn = self.sqlite.connect(self.uri)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT value FROM irc3_storage where key=?;", (key,))
|
||||
res = False
|
||||
if len(list(cursor.fetchall())) == 1:
|
||||
res = True
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return res
|
||||
#######################################################################################
|
||||
def flushdb(self):
|
||||
conn = self.sqlite.connect(self.uri)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DROP TABLE IF EXISTS irc3_storage;")
|
||||
cursor.execute(self.CREATE_TABLE)
|
||||
cursor.close()
|
||||
conn.commit()
|
||||
conn.close()
|
||||
#######################################################################################
|
||||
def sync(self):
|
||||
pass
|
||||
#######################################################################################
|
||||
def close(self):
|
||||
pass
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Storage:
|
||||
backends = {
|
||||
'shelve': Shelve,
|
||||
'json': JSON,
|
||||
'unix': Redis,
|
||||
'redis': Redis,
|
||||
'rediss': Redis,
|
||||
'sqlite': SQLite,
|
||||
}
|
||||
#######################################################################################
|
||||
def __init__(self, context):
|
||||
uri = context.config.storage
|
||||
name = uri.split('://', 1)[0]
|
||||
try:
|
||||
factory = self.backends[name]
|
||||
except KeyError: # pragma: no cover
|
||||
raise LookupError('No such backend %s' % name)
|
||||
self.backend = factory(uri)
|
||||
self.context = context
|
||||
self.context.db = self
|
||||
#######################################################################################
|
||||
def setdefault(self, key_, **kwargs):
|
||||
"""Update storage value for key with kwargs iif the keys doesn't
|
||||
exist. Return stored values"""
|
||||
stored = self[key_]
|
||||
changed = False
|
||||
for k, v in kwargs.items():
|
||||
if k not in stored:
|
||||
stored[k] = v
|
||||
changed = True
|
||||
else:
|
||||
kwargs[k] = stored[k]
|
||||
if changed:
|
||||
self[key_] = stored
|
||||
return kwargs
|
||||
#######################################################################################
|
||||
def get(self, key_, default=None):
|
||||
"""Get storage value for key or return default"""
|
||||
if key_ not in self:
|
||||
return default
|
||||
else:
|
||||
return self[key_]
|
||||
#######################################################################################
|
||||
def getlist(self, key_, default=None):
|
||||
"""Get storage value (as list) for key or return default"""
|
||||
if key_ not in self:
|
||||
return default
|
||||
else:
|
||||
value = self[key_]
|
||||
value = [(int(i), v) for i, v in value.items()]
|
||||
return [v for k, v in sorted(value)]
|
||||
#######################################################################################
|
||||
def set(self, key_, **kwargs):
|
||||
"""Update storage value for key with kwargs"""
|
||||
stored = self.get(key_, dict())
|
||||
changed = False
|
||||
for k, v in kwargs.items():
|
||||
if k not in stored or stored[k] != v:
|
||||
stored[k] = v
|
||||
changed = True
|
||||
if changed:
|
||||
self[key_] = stored
|
||||
#######################################################################################
|
||||
def setlist(self, key_, value):
|
||||
"""Update storage value (as list)"""
|
||||
value = dict([(str(i), v) for i, v in enumerate(value)])
|
||||
if key_ in self:
|
||||
del self[key_]
|
||||
self.set(key_, **value)
|
||||
#######################################################################################
|
||||
def __setitem__(self, key, value):
|
||||
"""Set storage value for key"""
|
||||
key = getattr(key, '__module__', key)
|
||||
if not isinstance(value, dict): # pragma: no cover
|
||||
raise TypeError('value must be a dict')
|
||||
try:
|
||||
return self.backend.set(key, value)
|
||||
except Exception as e: # pragma: no cover
|
||||
self.context.log.exception(e)
|
||||
raise
|
||||
#######################################################################################
|
||||
def __getitem__(self, key):
|
||||
"""Get storage value for key"""
|
||||
key = getattr(key, '__module__', key)
|
||||
try:
|
||||
return self.backend.get(key)
|
||||
except KeyError:
|
||||
raise KeyError(key)
|
||||
except Exception as e: # pragma: no cover
|
||||
self.context.log.exception(e)
|
||||
raise
|
||||
#######################################################################################
|
||||
def __delitem__(self, key):
|
||||
"""Delete key in storage"""
|
||||
key = getattr(key, '__module__', key)
|
||||
try:
|
||||
self.backend.delete(key)
|
||||
except Exception as e: # pragma: no cover
|
||||
self.context.log.exception(e)
|
||||
raise
|
||||
#######################################################################################
|
||||
def __contains__(self, key):
|
||||
"""Return True if storage contains key"""
|
||||
key = getattr(key, '__module__', key)
|
||||
try:
|
||||
return self.backend.contains(key)
|
||||
except Exception as e: # pragma: no cover
|
||||
self.context.log.exception(e)
|
||||
raise
|
||||
#######################################################################################
|
||||
def SIGINT(self):
|
||||
self.backend.close()
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,90 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import requests
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def _get_weed(self,t,s):
|
||||
try:
|
||||
url=""
|
||||
if t == "search":
|
||||
s = s.lower().replace(' ','-')
|
||||
url = 'https://api.wikileaf.com/api/v7/search/all/?type=S&num=24&offset=0&sort=popular&query={}'.format(s)
|
||||
if t == "review":
|
||||
url = 'https://api.wikileaf.com/api/v6/reviews/?content_type__model=strain&object_id={}'.format(s)
|
||||
r = requests.get(url)
|
||||
try:
|
||||
if r.json()['detail'] == 'Not found.':
|
||||
return 'Not Found.'
|
||||
except:
|
||||
return r.json()
|
||||
except:
|
||||
return -1
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def strain(self, mask, target, args):
|
||||
"""strain
|
||||
%%strain <message>...
|
||||
"""
|
||||
try:
|
||||
msg = ' '.join(args['<message>'])
|
||||
r_strain_id = -1
|
||||
r = self._get_weed('search',msg)
|
||||
b = r['results'][0]
|
||||
try:
|
||||
r_name = b['name']
|
||||
r_score = b['score']
|
||||
r_review_avg = b['review_avg']
|
||||
r_review_count = b['review_count']
|
||||
r_type = b['type']
|
||||
r_compound_thc_min = b['compound']['THC']['min']
|
||||
r_compound_thc_max = b['compound']['THC']['max']
|
||||
r_compound_cbd_min = b['compound']['CBD']['min']
|
||||
r_compound_cbd_max = b['compound']['CBD']['max']
|
||||
r_consumption_time = b['consumption_time']
|
||||
r_uses = b['uses']
|
||||
r_effects = b['effects']
|
||||
r_logo_url = "https://assets.wikileaf.com/{}".format(b['logo_url'])
|
||||
r_strain_id = b['strain_id']
|
||||
msg = "> name: {}".format(r_name)
|
||||
msg = msg + " > " + "score: {}".format(r_score)
|
||||
msg = msg + " > " + "review avg: {}".format(r_review_avg)
|
||||
msg = msg + " > " + "review count: {}".format(r_review_count)
|
||||
msg = msg + " > " + "type: {}".format(r_type)
|
||||
msg = msg + " > " + "compound thc min: {} / max: {}".format(r_compound_thc_min,r_compound_thc_max)
|
||||
msg = msg + " > " + "compound cbd min: {} / max: {}".format(r_compound_cbd_min,r_compound_cbd_max)
|
||||
msg = msg + " > " + "consumption time: {}".format(r_consumption_time)
|
||||
msg = msg + " > " + "uses: {}".format(r_uses)
|
||||
msg = msg + " > " + "effects: {}".format(r_effects)
|
||||
msg = msg + " > " + "logo: {}".format(r_logo_url)
|
||||
self.bot.privmsg(target, msg)
|
||||
except:
|
||||
msg = "strain: not found"
|
||||
self.bot.privmsg(target, msg)
|
||||
try:
|
||||
r = self._get_weed('review',r_strain_id)
|
||||
b = r['results']
|
||||
for i,_ in enumerate(b):
|
||||
msg = ">> " + "review {} - rating: {} / comment: {}".format(i+1,_['rating'],_['comment'])
|
||||
self.bot.privmsg(target, msg)
|
||||
if i >= 2: break
|
||||
url = b[0]['url']
|
||||
msg = ">>> " + "url: {}".format(url)
|
||||
self.bot.privmsg(target, msg)
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
msg = "strain: not found"
|
||||
self.bot.privmsg(target, msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,32 @@
|
|||
# -*- coding: utf-8 -*- ############################################################################# SOF
|
||||
from irc3.plugins.command import command
|
||||
from irc3.plugins.cron import cron
|
||||
import irc3
|
||||
import socket
|
||||
#########################################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#########################################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#####################################################################################################
|
||||
@command(permission='view')
|
||||
def tcpac(self, mask, target, args):
|
||||
"""tcpac - the irc version of `cat file - | nc tcp.ac 9999`, usage: ?tcpac message
|
||||
%%tcpac <message>...
|
||||
"""
|
||||
msg=' '.join(args['<message>'])
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
s.connect(("tcp.ac", 9999))
|
||||
s.sendall(bytes(msg.encode()))
|
||||
data = s.recv(1024)
|
||||
response=f'{data!r}'
|
||||
response=response.replace('\\n',' - ').replace("b'","")[:-1]
|
||||
delmsg=response.split(',')[0].split('":"')[1][:-1]
|
||||
txtmsg=response.split(',')[1].split('":"')[1][:-2]
|
||||
msg=f"{mask.nick}: irc version of `cat file - | nc tcp.ac 9999` -> txt: {txtmsg}"
|
||||
self.bot.privmsg(target,msg)
|
||||
msg=f"{mask.nick}: irc version of `cat file - | nc tcp.ac 9999` -> del: {delmsg}"
|
||||
self.bot.privmsg(mask.nick,msg)
|
||||
#####################################################################################################
|
||||
##################################################################################################### EOF
|
|
@ -0,0 +1,45 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from datetime import datetime
|
||||
import irc3
|
||||
import re
|
||||
TELL_RE = re.compile('maple.tell\s(.+?)\s(.+)')
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg_search_to_tell(self, mask=None, target=None, data=None, **kw):
|
||||
if mask.nick.lower() == "maple":
|
||||
return
|
||||
messages_to_send = self.bot.db.getlist("tell_%s" % mask.nick.lower())
|
||||
if messages_to_send:
|
||||
msg = messages_to_send[0]
|
||||
irc_message = "TCPDIRECT/TOLD: {} <{}> told <{}> {}".format(msg.get("time"),msg.get("from"),mask.nick,msg.get("message"))
|
||||
self.bot.privmsg(target, self.bot.emo(irc_message))
|
||||
self.bot.db.setlist("tell_%s" % mask.nick.lower(), messages_to_send[1:])
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg_search_for_tell(self, mask=None, target=None, data=None, **kw):
|
||||
match_list = TELL_RE.findall(data)
|
||||
if len(match_list) > 0:
|
||||
tell_nick, message = match_list[0]
|
||||
if tell_nick == 'me' or tell_nick == 'us' or tell_nick == 'a' or tell_nick == 'some': return
|
||||
message_list = self.bot.db.getlist("tell_%s" % tell_nick.lower())
|
||||
new_message = {"from": mask.nick.lower(), "message": message, "time": datetime.now().isoformat() }
|
||||
if not message_list:
|
||||
message_list = self.bot.db.setlist("tell_%s" % tell_nick.lower(), [new_message])
|
||||
else:
|
||||
message_list.append(new_message)
|
||||
self.bot.db.setlist("tell_%s" % tell_nick.lower(), message_list)
|
||||
irc_message = "TCPDIRECT/TELL: {} <{}> telling <{}> {}".format(new_message.get("time"),new_message.get("from"),tell_nick,new_message.get("message"))
|
||||
self.bot.privmsg(target, self.bot.emo(irc_message))
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
global bus, dims, matrixbot, ircbot
|
||||
from async_timeout import timeout
|
||||
from plugins.tool_dims_plugin import dims
|
||||
from plugins.tool_guds_plugin import guds
|
||||
import asyncio, ipdb
|
||||
###########################################################################################
|
||||
class BUS:
|
||||
#######################################################################################
|
||||
results=[]
|
||||
#######################################################################################
|
||||
def __init__(self,bridged_network_roomchans,matrixbot=None,ircbot=None):
|
||||
self.bridged_network_roomchans=bridged_network_roomchans
|
||||
print(f'<<< ____tool_bus_plugin:BUS.__init__ >>> [ BUS.bridged_network_roomchans={self.bridged_network_roomchans} ]')
|
||||
self.list_of_tasks=[]
|
||||
self.matrixbot=matrixbot
|
||||
print(f'<<< ____tool_bus_plugin:BUS.__init__ >>> [ BUS.matrixbot={self.matrixbot} ]')
|
||||
self.ircbot=ircbot
|
||||
print(f'<<< ____tool_bus_plugin:BUS.__init__ >>> [ BUS.ircbot={self.ircbot} ]')
|
||||
#######################################################################################
|
||||
async def input(self,network_chanroom_src,data):
|
||||
for network_chanroom_dest in self.bridged_network_roomchans:
|
||||
if not str(network_chanroom_src)==network_chanroom_dest:
|
||||
#################################################################### MATRIX
|
||||
if network_chanroom_dest.startswith('!'):
|
||||
#######################################################################
|
||||
msg=(f"m{str(network_chanroom_src)}> ")
|
||||
print('here is the error. press n to step the next line')
|
||||
ipdb.set_trace()
|
||||
task=(await self.matrixbot.api.send_text_message(
|
||||
network_chanroom_dest,str(f'{msg}{data}')))
|
||||
loop=self.ircbot.loop
|
||||
asyncio.ensure_future(task,loop=loop)
|
||||
####################################################################### IRC
|
||||
elif network_chanroom_dest.startswith('#'):
|
||||
msg=(f"i{str(network_chanroom_src)}> ")
|
||||
await self.ircbot.privmsg(
|
||||
network_chanroom_dest,str(f'{msg}{data}'))
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,171 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
# usage: d=DIMS('irc','#r3kt')
|
||||
# usage: d=DIMS('irc','#testing')
|
||||
# usage: d=DIMS('matrix','#tcpdirect:tcp.direct')
|
||||
# usage: d=DIMS('matrix','#b0tsh0p:pcriot.org')
|
||||
# flows: d.irc[n].channels[n] [lots of attributes pertaining to channels on the index ]
|
||||
# flows: d.irc[n].channels[n].bridge.[irc,matrix]_[channels,rooms]_[inbound,outbound]
|
||||
# flows: d.matrix[n].rooms[n] [lots of attributes pertaining to rooms on the index ]
|
||||
# flows: d.matrix[n].rooms[n].bridge.[irc,matrix]_[channels,rooms]_[inbound,outbound]
|
||||
global dims
|
||||
global guds
|
||||
import ipdb
|
||||
###########################################################################################
|
||||
class DIMS:
|
||||
#######################################################################################
|
||||
class __INIT_MATRIX__:
|
||||
###################################################################################
|
||||
class __INIT_ROOM__:
|
||||
###############################################################################
|
||||
class __INIT_BRIDGE_MATRIX__:
|
||||
###########################################################################
|
||||
def __init__(self,room):
|
||||
self.matrix_rooms_outbound=[]
|
||||
self.matrix_rooms_inbound=[]
|
||||
self.irc_channels_outbound=[]
|
||||
self.irc_channels_inbound=[]
|
||||
###############################################################################
|
||||
def __init__(self,room):
|
||||
room_flag=False
|
||||
if len(dir(room))>1:
|
||||
room_flag=True
|
||||
for _ in ['canonical_alias','creator','display_name','encrypted',
|
||||
'federate','fully_read_marker','gen_avatar_url','history_visibility',
|
||||
'invited_count','invited_users','is_group','is_named','join_rule',
|
||||
'joined_count','machine_name','member_count','members_synced',
|
||||
'name','names','own_user_id','power_levels','read_receipts',
|
||||
'room_avatar_url','room_id','room_version','summary','tags','topic',
|
||||
'typing_users','unread_highlights','unread_notifications','users']:
|
||||
if room_flag:
|
||||
exec(f'self.{_}=room.{_}')
|
||||
print(f"room.{_}->{eval(f'self.{_}')}")
|
||||
self.bridge=self.__INIT_BRIDGE_MATRIX__(room.room_id)
|
||||
else:
|
||||
exec(f'self.{_}=""')
|
||||
self.room_id=room
|
||||
self.bridge=self.__INIT_BRIDGE_MATRIX__(room)
|
||||
###################################################################################
|
||||
def __init__(self,room):
|
||||
self.rooms=[]
|
||||
self.rooms.append(self.__INIT_ROOM__(room))
|
||||
#######################################################################################
|
||||
def __update_matrix__(self,index,room,bridge=""):
|
||||
for _ in ['canonical_alias','creator','display_name','encrypted',
|
||||
'federate','fully_read_marker','gen_avatar_url','history_visibility',
|
||||
'invited_count','invited_users','is_group','is_named','join_rule',
|
||||
'joined_count','machine_name','member_count','members_synced',
|
||||
'name','names','own_user_id','power_levels','read_receipts',
|
||||
'room_avatar_url','room_id','room_version','summary','tags','topic',
|
||||
'typing_users','unread_highlights','unread_notifications','users']:
|
||||
cmdp=(f"self.matrix[{index}].rooms[0].{_}")
|
||||
cmdn=(f"room.{_}")
|
||||
if not eval(cmdp)==eval(cmdn):
|
||||
exec(f"self.matrix[{index}].rooms[0].{_}=room.{_}")
|
||||
cmdf=f"room.{_}"
|
||||
cmdt=f"self.matrix[{index}].rooms[0].{_}"
|
||||
print(f"literal: room.{_}->self.matrix[{index}].rooms[0].{_} - explicit: {eval(cmdf)}->{eval(cmdt)}")
|
||||
#######################################################################################
|
||||
def isroom(self,room):
|
||||
###################################################################################
|
||||
try:
|
||||
for index_server,_matrix in enumerate(self.matrix):
|
||||
for index_room,_room in enumerate(_matrix.rooms):
|
||||
if _room==room:
|
||||
return True,index_server,index_room
|
||||
###################################################################################
|
||||
except: pass
|
||||
###################################################################################
|
||||
return False,0,0
|
||||
#######################################################################################
|
||||
class __INIT_IRC__:
|
||||
###################################################################################
|
||||
class __INIT_CHANNEL__:
|
||||
###############################################################################
|
||||
class __INIT_BRIDGE_IRC__:
|
||||
###########################################################################
|
||||
def __init__(self,channel):
|
||||
self.irc_channels_outbound=[]
|
||||
self.irc_channels_inbound=[]
|
||||
self.matrix_rooms_outbound=[]
|
||||
self.matrix_rooms_inbound=[]
|
||||
###############################################################################
|
||||
def __init__(self,channel):
|
||||
self.channel=channel
|
||||
self.bridge=self.__INIT_BRIDGE_IRC__(channel)
|
||||
###################################################################################
|
||||
def __init__(self,channel):
|
||||
self.channels=[]
|
||||
self.channels.append(self.__INIT_CHANNEL__(channel))
|
||||
#######################################################################################
|
||||
def __update_irc__(self,index,channel,bridge=""):
|
||||
self.irc[index].channels[0].channel=channel
|
||||
#######################################################################################
|
||||
def ischannel(self,channel):
|
||||
###################################################################################
|
||||
try:
|
||||
for index_server,_irc in enumerate(self.irc):
|
||||
for index_channel,_channel in enumerate(_irc.channels):
|
||||
if _channel==channel:
|
||||
return True,index_server,index_channel
|
||||
###################################################################################
|
||||
except: pass
|
||||
###################################################################################
|
||||
return False,0,0
|
||||
#######################################################################################
|
||||
matrix=[]; irc=[]; netschanroom=[]
|
||||
#######################################################################################
|
||||
def __init__(self,net="",chanroom=""):
|
||||
###################################################################################
|
||||
if not net or not chanroom: return
|
||||
###################################################################################
|
||||
net=net.lower()
|
||||
dupe_flag=False
|
||||
###################################################################################
|
||||
if net=='matrix':
|
||||
for i in range(len(self.matrix)):
|
||||
if self.matrix[i].rooms[0].room_id==chanroom.room_id:
|
||||
print(f'<<< ________dims_plugin >>> [ updating pre-existing matrix room data ]')
|
||||
dupe_flag=True; index=i; self.__update_matrix__(index,chanroom)
|
||||
if not dupe_flag:
|
||||
print(f'<<< ________dims_plugin >>> [ new matrix room data entry ]')
|
||||
self.matrix.append(self.__INIT_MATRIX__(chanroom))
|
||||
###################################################################################
|
||||
elif net=='irc':
|
||||
for i in range(len(self.irc)):
|
||||
if self.irc[i].channels[0].channel==chanroom:
|
||||
print(f'<<< ________dims_plugin >>> [ updating pre-existing irc channel data ]')
|
||||
dupe_flag=True; index=i; self.__update_irc__(index,chanroom)
|
||||
if not dupe_flag:
|
||||
print(f'<<< ________dims_plugin >>> [ new irc channel data entry ]')
|
||||
self.irc.append(self.__INIT_IRC__(chanroom))
|
||||
#######################################################################################
|
||||
def __create__(self,net="",chanroom=""):
|
||||
###################################################################################
|
||||
if net=='matrix': self.matrix.append(self.__INIT_MATRIX__(chanroom))
|
||||
###################################################################################
|
||||
elif net=='irc': self.irc.append(self.__INIT_IRC__(chanroom))
|
||||
#######################################################################################
|
||||
def __delete__(self,net="",chanroom_index=-1):
|
||||
###################################################################################
|
||||
if net=='matrix': self.matrix.remove(self.matrix[chanroom_index])
|
||||
###################################################################################
|
||||
elif net=='irc': self.irc.remove(self.irc[chanroom_index])
|
||||
#######################################################################################
|
||||
def list_channels(self):
|
||||
###################################################################################
|
||||
from plugins.tool_guds_plugin import guds
|
||||
matrixbot=guds.memories[2][0]._BOTIO__boot__matrix
|
||||
localchannels=[]
|
||||
for _irc in self.irc:
|
||||
for _channels in _irc.channels:
|
||||
localchannels.append(_channels.channel)
|
||||
[ self.netschanroom.append(x) for x in matrixbot.async_client.rooms ]
|
||||
for _irc in self.irc:
|
||||
for _channels in _irc.channels:
|
||||
self.netschanroom.append(_channels.channel)
|
||||
###################################################################################
|
||||
return self.netschanroom
|
||||
###################################################################################
|
||||
###########################################################################################
|
||||
dims=DIMS()
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,34 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import ipdb
|
||||
global dims
|
||||
global guds # global unified data system 2 move instantiated data between processes/threads
|
||||
###########################################################################################
|
||||
class GUDS:
|
||||
#######################################################################################
|
||||
push_index=0; credentials=[]; memories=[];
|
||||
#######################################################################################
|
||||
def __init__(self):
|
||||
pass
|
||||
#######################################################################################
|
||||
def add_credentials(self,credential):
|
||||
self.credentials.append(credential)
|
||||
print(f'<<< ________guds_plugin >>> [ added {credential} credentials to guds.credentials ]')
|
||||
#######################################################################################
|
||||
def check_credentials(self,against_credential):
|
||||
flag_match=False
|
||||
for credential in self.credentials:
|
||||
if not credential.find(against_credential):
|
||||
flag_match=True
|
||||
print(f'<<< ________guds_plugin >>> [ found {credential} against {against_credential} ]')
|
||||
###################################################################################
|
||||
if not flag_match:
|
||||
print(f'<<< ________guds_plugin >>> [ no credentials found matching {against_credential} ]')
|
||||
return False
|
||||
#######################################################################################
|
||||
def push(self,data):
|
||||
self.push_index+=1
|
||||
self.memories.append(data)
|
||||
print(f'<<< ________guds_plugin >>> [ data pushed into guds.memories[{str(self.push_index)}]={guds.memories[-1]} ]')
|
||||
###########################################################################################
|
||||
guds=GUDS()
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,192 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
import irc3
|
||||
from datetime import datetime
|
||||
import twitter
|
||||
import re
|
||||
import os
|
||||
import time
|
||||
import timeago
|
||||
import os
|
||||
import requests
|
||||
from lxml.html import fromstring
|
||||
from difflib import SequenceMatcher
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
CONSUMER_KEY = os.environ['CONSUMER_KEY']
|
||||
CONSUMER_SECRET = os.environ['CONSUMER_SECRET']
|
||||
ACCESS_TOKEN_KEY = os.environ['ACCESS_TOKEN_KEY']
|
||||
ACCESS_TOKEN_SECRET = os.environ['ACCESS_TOKEN_SECRET']
|
||||
TOO_LONG = 2000
|
||||
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=CONSUMER_KEY, consumer_secret=CONSUMER_SECRET,
|
||||
access_token_key=ACCESS_TOKEN_KEY, access_token_secret=ACCESS_TOKEN_SECRET)
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.extend
|
||||
def _similar(self, a, b):
|
||||
return SequenceMatcher(None, a, b).ratio()
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.extend
|
||||
def _check_for_url(self, og_tweet, d_nick, d_url, d_unrolled, d_text, d_target):
|
||||
match_list = URL_REGEX.findall(d_unrolled)
|
||||
read_size = 0
|
||||
if match_list:
|
||||
url = match_list.pop()
|
||||
try:
|
||||
if not d_unrolled.find('https://twitter.com/') == -1:
|
||||
if not d_unrolled.find('status') == -1:
|
||||
try:
|
||||
e_status = d_unrolled.split('/')[-1]
|
||||
e_tweet = twitter.GetStatus(e_status)
|
||||
e_text = e_tweet.text
|
||||
if self._similar(og_tweet.text,e_text) > 0.7: return
|
||||
msg = "\x02\x0302{nick1:}:{nick2:}\x0F\x02\x0303 >> {e_text:} \x0F".format(nick1=d_nick,nick2='UNROLLED',e_text=e_text)
|
||||
if e_tweet.media:
|
||||
for y in range(len(e_tweet.media)):
|
||||
m_turl = e_tweet.media[y].url
|
||||
m_murl = e_tweet.media[y].media_url
|
||||
m_eurl = e_tweet.media[y].expanded_url
|
||||
msg = msg + " >> [media] \x0F\x02\x0312{media_url:}".format(media_url=m_murl)
|
||||
if e_tweet.urls:
|
||||
for y in range(len(e_tweet.urls)):
|
||||
e_turl = e_tweet.urls[y].url
|
||||
e_eurl = e_tweet.urls[y].expanded_url
|
||||
msg = msg + " >> [url] \x0F\x02\x0312{e_url:}".format(e_url=e_eurl)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(d_target, msg)
|
||||
return
|
||||
except Exception as e:
|
||||
msg = "wu/tang >>>>>>>>>>> sub-unrolling: {}".format(e)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(d_target, msg)
|
||||
return
|
||||
r = requests.get(d_unrolled, timeout=3, stream=True)
|
||||
content_type = r.headers.get("Content-Type")
|
||||
content_length = r.headers.get('Content-Length')
|
||||
if not content_length:
|
||||
content_length = 0
|
||||
if content_type.startswith('image'):
|
||||
msg = "\x02\x0302{nick1:}:{nick2:}\x0F\x02\x0303 >> [media] {media:} \x0F".format(nick1=d_nick,nick2='UNROLLED',media=d_unrolled)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(d_target, msg)
|
||||
return
|
||||
if not content_type.startswith("text/html"):
|
||||
return
|
||||
if int(content_length) > 200000:
|
||||
self.bot.privmsg(d_target, "pre-fetch aborted -> fuck your large ass content -> {} -> {}".format(d_url,d_unrolled))
|
||||
while read_size <= (2000 * 10):
|
||||
for content in r.iter_content(chunk_size=2000):
|
||||
tree = fromstring(content)
|
||||
title = tree.find(".//title")
|
||||
if title is not None:
|
||||
title = title.text.strip()[:100]
|
||||
print('title: {}'.format(title))
|
||||
similarity = self.bot._similar(title,d_text)
|
||||
if similarity > 0.4:
|
||||
print('wu/tang: similarity')
|
||||
return
|
||||
msg = "\x02\x0302{nick1:}:{nick2:}\x0F\x02\x0304 >> \x0F\x1D\x0314{url:}\x0F\x0304 >> \x0F\x0303{unrolled:} \x0F\x0304>> \x0F\x1D\x0314{title:}\x0F".format(nick1=d_nick,nick2='UNROLLED',url=d_url,unrolled=d_unrolled,title=title)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(d_target, msg)
|
||||
return
|
||||
read_size = read_size + 2000
|
||||
except Exception as e:
|
||||
self.bot.privmsg("_debug_check_for_url_error: {}".format(e))
|
||||
print("original: {} nick: {} url: {} unrolled: {} text: {} error: {}".format(og_tweet,d_nick,d_url,d_unrolled,d_text,e))
|
||||
pass
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def _check_for_twitter(self, mask=None, data=None, target=None, **kw):
|
||||
match_list = TWITTER_REGEX.findall(data)
|
||||
if match_list:
|
||||
status_id = match_list[0][2]
|
||||
try:
|
||||
tweet = twitter.GetStatus(status_id=status_id)
|
||||
tweet_text = tweet.text
|
||||
user = tweet.user.screen_name
|
||||
fav_count = tweet.favorite_count
|
||||
retweet_count = tweet.retweet_count
|
||||
if tweet.coordinates:
|
||||
location = tweet.coordinates
|
||||
else:
|
||||
location = ""
|
||||
tweet_time = time.strptime(tweet.created_at, '%a %b %d %H:%M:%S +0000 %Y')
|
||||
time_since = timeago.format(time.strftime('%Y-%m-%d %H:%M:%S', tweet_time), datetime.now())
|
||||
msg = "\x02\x0302{} \x0F\x0303>\x0F \x02\x0301{}\x0F\x0314 | Retweets:\x0F \x1D\x0306{}\x0F\x0314 Favorites:\x0F\x1D\x0306 {} \x0F⑆\x1D\x0314\x1D {} {}".format(user, tweet_text, retweet_count, fav_count, time_since, location)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
match_list = URL_REGEX.findall(msg)
|
||||
try:
|
||||
if(match_list):
|
||||
try:
|
||||
if len(tweet.urls) == 0:
|
||||
if tweet.media:
|
||||
for y in range(len(tweet.media)):
|
||||
m_turl = tweet.media[y].url
|
||||
m_murl = tweet.media[y].media_url
|
||||
m_eurl = tweet.media[y].expanded_url
|
||||
msg = "\x02\x0302{nick1:}:{nick2:}\x0F\x02\x0304 >> [media] \x0F\x02\x0312{m_turl:}\x0F\x0304 >> \x0F\x0303{m_murl:} \x0F\x0304>> \x0F\x1D\x0314{m_eurl:}\x0F".format(nick1=user,nick2='UNROLLED',m_turl=m_turl,m_murl=m_murl,m_eurl=m_eurl)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
else:
|
||||
for y in range(len(tweet.urls)):
|
||||
t_turl = tweet.urls[y].url
|
||||
try:
|
||||
match_list.remove(t_turl)
|
||||
except:
|
||||
print('cant remove from matchlist, does not exist')
|
||||
t_eurl = tweet.urls[y].expanded_url
|
||||
yt_match_list = YOUTUBE_REGEX.findall(t_eurl)
|
||||
if yt_match_list:
|
||||
d_video_id = t_eurl.split('=')[1]
|
||||
self.bot.madjust = "{}:UNROLLED".format(user)
|
||||
self.bot.yt(mask,target,{'<keyword>': [d_video_id],'yt': True})
|
||||
self.bot.madjust = ""
|
||||
else:
|
||||
if not str(tweet.id) == t_eurl.split('/')[-1]:
|
||||
self.bot._check_for_url(tweet,user,t_turl,t_eurl,tweet_text,target)
|
||||
else:
|
||||
print('bypassing original tweet')
|
||||
try:
|
||||
if len(match_list) > 0:
|
||||
print('items in matchlist remain')
|
||||
print(match_list)
|
||||
except:
|
||||
print('errrororororororo: cant remove from matchlist, does not exist')
|
||||
except Exception as e:
|
||||
self.bot.privmsg(target,'twitter_plugin <> _debug_unrolling -> wu/tang: {}'.format(e))
|
||||
except Exception as e:
|
||||
self.bot.privmsg(target,'twitter_plugin <> wu/tang: {}'.format(e))
|
||||
except Exception as e:
|
||||
_msg = e.message[0]['message']
|
||||
_code = e.message[0]['code']
|
||||
_erid = ''
|
||||
if _code == 179:
|
||||
_erid = "PROTECTED TW33T"
|
||||
else:
|
||||
_erid = "DON'T CARE EXCEPTION"
|
||||
msg = "\x02\x0302{} \x0F\x0304> \x0F\x02\x0312{} aka {}\x0F\x0303".format(_code,_msg,_erid)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
pass
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg_search_for_twitter(self, mask=None, target=None, data=None, **kw):
|
||||
if data.startswith("?"): return
|
||||
if mask.nick.lower() not in self.bot.ignore_list:
|
||||
self._check_for_twitter(mask, data, target)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,33 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import requests
|
||||
import urllib.parse
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def ud(self, mask, target, args):
|
||||
"""Urban Dictonary A Term
|
||||
%%ud <term>...
|
||||
"""
|
||||
term = ' '.join(args['<term>'])
|
||||
term = urllib.parse.quote(term)
|
||||
r = requests.get('https://api.urbandictionary.com/v0/define?term={}'.format(term))
|
||||
d = r.json()
|
||||
term = urllib.parse.unquote(term)
|
||||
try:
|
||||
msg = "{} - {} - example: {}".format(term, d.get("list")[0].get("definition"), d.get("list")[0].get("example"))
|
||||
except:
|
||||
msg = "{} Term Not Found".format(term)
|
||||
self.bot.privmsg(target,msg)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,117 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import re
|
||||
import requests
|
||||
from lxml.html import fromstring
|
||||
TOO_LONG = 2000
|
||||
URL_REGEX = re.compile('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', re.IGNORECASE)
|
||||
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)
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.event(irc3.rfc.PRIVMSG)
|
||||
def on_privmsg(self, mask=None, target=None, data=None, **kw):
|
||||
if not data.find('reacted with :') == -1: return
|
||||
if data.startswith("?"): return
|
||||
if self.bot.check_if_ignored(mask): return
|
||||
if mask.nick == '[0]' or mask.nick == '[0]_': return
|
||||
self.__check_for_url(data,target,mask)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __check_for_url(self,msg,target,mask):
|
||||
match_list = URL_REGEX.findall(msg)
|
||||
read_size = 0
|
||||
if match_list:
|
||||
url = match_list.pop()
|
||||
if not url.lower().find('wp-login') == -1:
|
||||
msg = 'pre-fetch aborted -> hell nah nigga'
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
y_match = YOUTUBE_REGEX.findall(url)
|
||||
if y_match:
|
||||
y_match = y_match.pop()
|
||||
if len(y_match) == 3:
|
||||
return
|
||||
t_match = TWITTER_REGEX.findall(url)
|
||||
if t_match:
|
||||
t_match = t_match.pop()
|
||||
if len(t_match) == 3:
|
||||
return
|
||||
try:
|
||||
if not url.find("giphy.com") == -1:
|
||||
msg = "\x02\x0302{nick:}\x0F\x02\x0304 > \x0F\x02\x0303{url:}\x0F\x0303".format(nick=mask.nick,url="fuk giphy!!!")
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
if not url.find("facebook.com") == -1:
|
||||
msg = "\x02\x0302{nick:}\x0F\x02\x0304 > \x0F\x02\x0312{url:}\x0F\x0303".format(nick=mask.nick,url="fuk facebook!!!")
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
return
|
||||
r = requests.get(url, timeout=3, stream=True)
|
||||
content_type = r.headers.get("Content-Type")
|
||||
content_length = r.headers.get('Content-Length')
|
||||
if not content_length:
|
||||
content_length = 0
|
||||
if int(content_length) > 200000:
|
||||
return
|
||||
while read_size <= (2000 * 10):
|
||||
for content in r.iter_content(chunk_size=2000):
|
||||
tree = fromstring(content)
|
||||
title = tree.find(".//title")
|
||||
if title is not None:
|
||||
title = title.text.strip()[:100]
|
||||
msg = "\x02\x0302{nick:}\x0F\x02\x0304 > \x0F\x1D\x0314{title:}\x0F".format(nick=mask.nick,title=title)
|
||||
msg = self.bot.emo(msg)
|
||||
self.bot.privmsg(target, msg)
|
||||
######## URL_GRABBER <-> BOOMBOX_PLUGIN HOOK ######## URL_GRABBER <-> BOOMBOX_PLUGIN HOOK ########
|
||||
self.bot.bbs.enter(mask.nick,url,title)
|
||||
######## URL_GRABBER <-> BOOMBOX_PLUGIN HOOK ######## URL_GRABBER <-> BOOMBOX_PLUGIN HOOK ########
|
||||
return
|
||||
read_size = read_size + 2000
|
||||
except Exception as e:
|
||||
print("%s" % e)
|
||||
pass
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@irc3.extend
|
||||
def prefetch_title(self,msg,target,mask):
|
||||
match_list = URL_REGEX.findall(msg)
|
||||
read_size = 0
|
||||
if match_list:
|
||||
url = match_list.pop()
|
||||
if not url.lower().find('wp-login') == -1:
|
||||
print('error: url_grabber_plugin:prefetch_title - aborted')
|
||||
return
|
||||
try:
|
||||
r = requests.get(url, timeout=3, stream=True)
|
||||
content_type = r.headers.get("Content-Type")
|
||||
content_length = r.headers.get('Content-Length')
|
||||
if not content_length:
|
||||
content_length = 0
|
||||
if int(content_length) > 200000:
|
||||
return
|
||||
while read_size <= (2000 * 10):
|
||||
for content in r.iter_content(chunk_size=2000):
|
||||
tree = fromstring(content)
|
||||
title = tree.find(".//title")
|
||||
if title is not None:
|
||||
title = title.text.strip()[:100]
|
||||
return title
|
||||
read_size = read_size + 2000
|
||||
except Exception as e:
|
||||
print("%s" % e)
|
||||
pass
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
#######################################################################################
|
||||
@command(permission='view')
|
||||
def whoami(self, mask, target, args):
|
||||
"""whoami - plugin to give some identity information. usage: ?whoami
|
||||
%%whoami
|
||||
"""
|
||||
msg = f'{mask.nick}: mask: {mask} channel: {target}'
|
||||
self.bot.privmsg(target, self.bot.emo(msg))
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,171 @@
|
|||
# -*- coding: utf-8 -*- ############################################################### SOF
|
||||
from irc3.plugins.command import command
|
||||
import irc3
|
||||
import os
|
||||
import re
|
||||
import datetime
|
||||
import dateutil.parser
|
||||
import timeago
|
||||
import isodate
|
||||
from apiclient.discovery import build
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
DEVELOPER_KEY = os.environ['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=DEVELOPER_KEY)
|
||||
###########################################################################################
|
||||
###########################################################################################
|
||||
@irc3.plugin
|
||||
class Plugin:
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.bot.channel_live = []
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@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)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
@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)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
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]
|
||||
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):
|
||||
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=True)
|
||||
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)
|
||||
#######################################################################################
|
||||
#######################################################################################
|
||||
####################################################################################### EOF
|
|
@ -0,0 +1,16 @@
|
|||
irc3
|
||||
aiocron
|
||||
timeago
|
||||
isodate
|
||||
google-api-python-client
|
||||
oauth2client
|
||||
aiohttp
|
||||
asyncio
|
||||
async_timeout
|
||||
lxml
|
||||
python-twitter
|
||||
googlesearch-python
|
||||
pyfiglet
|
||||
openai
|
||||
simplematrixbotlib
|
||||
ipdb
|
Loading…
Reference in New Issue