This commit is contained in:
.[d]. 2022-09-05 15:30:29 -05:00
parent a580519626
commit 06080338ba
64 changed files with 9716 additions and 0 deletions

22
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,22 @@
{
"version": "6.6.6",
"configurations": [
{
"name": "maple",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/bot_maple.py",
"args" : [""],
"console": "integratedTerminal",
"python":"${workspaceFolder}/env/bin/python3.9",
"justMyCode": false
},
{
"name": "maple",
"type": "bashdb",
"request": "launch",
"program": "/home/dr1p/maple/maple.sh",
"args": ["setup"],
}
],
}

235
README.md Normal file
View File

@ -0,0 +1,235 @@
## [MAPLE|G1MP]+[ML^N]+[NETSPANNING[i]]
---
```
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
```
---
## Summary
```
this project is a hybrid of hybrids - ( m4pl1mp - https://git.tcp.direct/decoded/m4pl1mp )
-
this version spans across different networks and not limited to irc, it connects matrix,
telegram, discord and offers up a newer way of unifying those services in one core process.
```
---
## TODO
- convert escaped irc color codes back to terminal codes for ansi_plugin.py
## Changelog - v2.666-3
- changed the directory structure for ease of use with the hydra system during development
- ive got the hydra system split down at minimal 3.. 1 that stays up no matter what, another that runs
- all of services developed up to this point, and the last one is kind of like the core, it's stripped
- of services because there is already a bot running services but this one can develop new services and
- stop,start,restart,crash etc.. as much as the developer would like with out sacraficing being online
- or known services going offline..
## Changelog - v2.666-2
- plugins/ansi_plugin.py is an ansi recapture utility.. basically if someone is pumping ansi art into a
- channel this will copy it 1:1 but for the intent of using 'ansipants', converting the graphic to an image
- and then re-uploading the image rather than the ansi/utf8 to discord/matrix/telegram due to the fact they
- easily or properly display ansi graphics but they show images.
## Changelog - v2.666-1
- plugins/net_hydra_plugin.py is a multiband wrapper that i use as a headless hydra code/debug logic.
- meaning a core, that stripped of services will always be online, so no matter what a presensce is online.
- anything non core is a dupe, aka hydra.. one may run the ai one machine, and another may just be that im
- coding something and dont want service to go offline and yet i myself require them to code. so that is
- why and how this hydra logic is used, and it because of features of sasl authentication that it's done.
## Changelog - v2.666
- fixed bridge responses double echoing
- simplified the calling of some plugins
- incorporated a multihead wrapper to keep services running
## Changelog - v2.5
- telegram/discord/matrix/irc now netspanned ( always more to do )
- the routerio logic mostly finished in plugins/tool_bus_plugin.py
- the way inter-process threads are handled are now speakable/observable
- maple ai is now online, it's very fast now, almost immediate response
---
## Changelog - v2.4
- telegram netspanned
- experimenting with color coding
---
## Changelog - v2.3
- discord netspanned
---
## Changelog - v2.2
- matrix netspanned
---
## Changelog - v2.1
- tried pyenv+pipenv, ended up up reverting back to pure virtualenv for consistency.
---
## Screenshots
![screenshots](screenshots/ss1.png)
---
## References
###### [ Netspanning network protocols ]
- [online] - irc - https://www.rfc-editor.org/rfc/rfc2812.html
- [online] - matrix - https://spec.matrix.org/latest
- [online] - discord - https://discord.com/developers/docs/reference
- [online] - telegram - https://core.telegram.org/bots/api
###### [ The actual base hybrid - Machine Learning Irc3 ]
- m4plmp - https://git.tcp.direct/decoded/m4pl1mp
###### [ g1mp was the first service bot, maple named herself ]
- Maple - https://git.tcp.direct/decoded/Maple
- g1mp - https://git.tcp.direct/decoded/g1mp
---
## Prerequisites
###### [ substitute apt for the package manager of your choice ]
- `apt install python3` - `*note: python3.9 is ideal`
- `apt install python3-pip`
- `python3 -m pip install virtualenv`
---
## Instructions
###### - [ virtualenv could be substituted for pyenv/pipenv or no virtualenv et al ]
###### - [ environmental credentials of env/bin/activate could alternatively be hardcoded ]
- `git clone --recursive https://git.tcp.direct/decoded/maple_netspan.git`
- `cd maple_netspan`
- `virtualenv -p python3.9 env`
- `source env/bin/activate`
- `pip install -r requirements.txt`
---
###### [ Relevant urls pertaining to the developer api keys and server credentials ]
---
- **openai** - https://beta.openai.com/signup
- **nickserv** - https://wiki.anope.org/index.php/2.0/Modules#NickServ - `/msg nickserv help register`
- **matrix** - https://app.element.io/
- **discord** - https://discord.com/developers/applications
- **telegram** - https://tinyurl.com/bdececee - https://docs.python-telegram-bot.org/en/v20.0a2/examples.html
- **twitter** - https://developer.twitter.com/en/portal/petition/essential/basic-info
- **youtube** - https://console.cloud.google.com/apis/credentials
---
###### [ Append your *developer* / *service* api keys credentials to `env/bin/activate` ]
---
```
cat env/bin/activate
..
export NICKSERV_USERNAME=your_nickserv_username # <- IRCD NICKSERV USER
export NICKSERV_PASSWORD=your_nickserv_password # <- IRCD NICKSERV PASS
export BOT_SASL_USERNAME=$NICKSERV_USERNAME # <- IRCD NICKSERV USER
export BOT_SASL_PASSWORD=$NICKSERV_PASSWORD # <- IRCD NICKSERV PASS
export MATRIX_HOMESERVER=https://matrix.org # <- MATRIX HOMESERVER
export MATRIX___USERNAME=your_matrix_username # <- MATRIX USERNAME
export MATRIX___PASSWORD=your_matrix_password # <- 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
export OPENAPI_KEY=AeJWbyak16wjHZ8L4TAbGIlVk31YwwAyz-GsezWCJ7Wkh7BIFTO # <- OPENAI API KEY
export DISCORD__MAPLE=295326962352954038 # <- DISCORD API KEY
export DISCORD__SCHAN=295326962352954038 # <- DISCORD API KEY
export DISCORD__TOKEN=AT2Sh4g.G1M9vNTOXmIaQzdvn5b6QzQMTyTBX6COJONUIRjLWi5UX0j294 # <- DISCORD API KEY
export TELEGRAM_TOKEN=AHh4DA9FgE3vs1SfAnx8975t85J30mU925GhJWcoUBBo7 # <- TELEGRAM API KEY
export HYDRA_DESIGNATION=dupe # <- DEBUG CORE OR DUPE
export HYDRA_HOME=#b0tsh0p # <- DEBUG HOME CHANNEL
```
---
# Usage
## 1 - `cd maple_netspan`
## 2 - `source env/bin/activate`
## 3 - `python3.9 bot_maple.py`
---
**plugins/net_irc_plugin.py** - main bot config
- `here plugins can be diabled/enabled. e.g. disabling plugins without api keys`
**plugins.net_matrix_plugin.py** - the file to edit for this change
- `@maple:pcriot.org` change this credential to your matrix username:homeserver
- `add_credentials("@maple:pcriot.org")` - what the code looks like to change
---
#### 1 `env/bin/activate` - the actual credentials to be exported into the local environment
#### 2 `relevant plugin` - reads these particular environmental variable exports
#### 3 `the source code` - where the credentials are read back to as runtime only variables
###### [ this method can be hardened with a cipher, but at some point a key is required ]
---
1 export NICKSERV_USERNAME=your_nickserv_username
1 export NICKSERV_PASSWORD=your_nickserv_password
2 plugins.auth_custom_plugin
3 NICKSERV_USERNAME=os.environ['NICKSERV_USERNAME']
3 NICKSERV_PASSWORD=os.environ['NICKSERV_PASSWORD']
---
1 export BOT_SASL_USERNAME=also_your_nickserv_username
1 export BOT_SASL_PASSWORD=also_your_nickserv_password
2 plugins.sasl_custom_plugin
3 BOT_SASL_USERNAME=os.environ['BOT_SASL_USERNAME']
3 BOT_SASL_PASSWORD=os.environ['BOT_SASL_PASSWORD']
---
1 export MATRIX_HOMESERVER=https://matrix.org
1 export MATRIX___USERNAME=your_matrix_username
1 export MATRIX___PASSWORD=your_matrix_password
2 plugins.net_matrix_plugin
3 MATRIX_HOMESERVER=os.environ['MATRIX_HOMESERVER']
3 MATRIX___USERNAME=os.environ['MATRIX___USERNAME']
3 MATRIX___PASSWORD=os.environ['MATRIX___PASSWORD']
---
1 export OPENAPI_KEY=AeJWbyak16wjHZ8L4TAbGIlVk31YwwAyz-GsezWCJ7Wkh7BIFTO
2 plugins.openai_plugin
3 OPENAPI_KEY = os.environ['OPENAPI_KEY']
---
1 export DISCORD__MAPLE=295326962352954038
1 export DISCORD__SCHAN=295326962352954038
1 export DISCORD__TOKEN=AT2Sh4g.G1M9vNTOXmIaQzdvn5b6QzQMTyTBX6COJONUIRjLWi5UX0j294
2 plugins.net_discord_plugin
3 DISCORD__SCHAN=int(os.environ['DISCORD__SCHAN'])
3 DISCORD__MAPLE=int(os.environ['DISCORD__MAPLE'])
3 DISCORD__TOKEN=str(os.environ['DISCORD__TOKEN'])
---
1 export TELEGRAM_TOKEN=AHh4DA9FgE3vs1SfAnx8975t85J30mU925GhJWcoUBBo7
2 plugins.net_telegram_plugin
3 TELEGRAM_TOKEN=os.environ['TELEGRAM_TOKEN']
---
1 export DEVELOPER_KEY=1394823190182390182382383215382158321
2 plugins.youtube_plugin
3 DEVELOPER_KEY = os.environ['DEVELOPER_KEY']
---
1 export CONSUMER_KEY=2151235132512351235123512351325231
1 export CONSUMER_SECRET=514512521345234523452345234523452345234523452
1 export ACCESS_TOKEN_KEY=24513429875209348502934850294898348034850293485203948592
1 export ACCESS_TOKEN_SECRET=523490582034985203948520394804884820934850923485
2 plugins.twitter_plugin
3 CONSUMER_KEY = os.environ['CONSUMER_KEY']
3 CONSUMER_SECRET = os.environ['CONSUMER_SECRET']
3 ACCESS_TOKEN_KEY = os.environ['ACCESS_TOKEN_KEY']
3 ACCESS_TOKEN_SECRET = os.environ['ACCESS_TOKEN_SECRET']
---
## 1 `edit` - plugins/net_irc_plugin.py to configure your bot settings
---

940
maple.sh Executable file
View File

@ -0,0 +1,940 @@
#!/usr/bin/env bash
################################################################################################################# SOF
echo -e '\033[0;34m'" .:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::. "
echo -e '\033[0;34m'" /mMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNd- "
echo -e '\033[0;34m'"-MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN."
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmNMMMMMMMMMMMmMMMMMMMMMMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh:NMMMMMMMMMMoyMMMMMMMMMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMm -NMMMMMMMMMs.NMMMMMMMMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMy -hmmmmmNNm- sMMMMMMMMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmdyo+:. ......... .NMMMymMMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmy+-.. -hNm-+MMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMms:. ... /MMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMh/. /MMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMmMMMMMMMMMMMmhN:. /MMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMM+sNMMMMMMMMMN-h: .-+syyys/- -NMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMs +NMMMMMMMhm--d. :. -sdNMMMMMNNmy. :ydMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMM+ :yhyyyhhso. os yhshNMMMMMMMh+:-:. :s- .NMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMmho. . .yo.h:sMMMMMMMMMMNd+. -NNs- yMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMNh/. :++.-MMMMMMMMMMMMMm+. :ymds. -NMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMmo- .MMMMMMMMMMMMMMMdo. ..-. yMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMmo. .NMMMMMMMMMMMMMMMMNy/.. .mMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMNs. hMMMMMMMMMMMMMMMMMMMNho-. :NMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMm: ./syyyo- -hmNMMMMMMMMMMMMMMMMMMMMmho:.. /NMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMd. .smMMMNNNms. . .+MMMMMMMMMMMMMMMMMMMMMMMMNdy/ ..yMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMd. /mMMMMMy/:--. so. .mMMMMMMMMMMMMMMMMMMMMMMMNdo--:+sdNMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMN- /NMMMMMMMMdo. oMm+. /MMMMMMMMMMMMMMMMdNMMMMMMNNNMMmMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMo -NMMMMMMMMMMdso-. /hmm+ sMMMMMMMMMMMMMMMs-mMMMMMMMMMM:dMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMN. sMMMMMMMMMMMo .os/..... .dMMMMMMMMMMMMMMs -NMMMMMMMMM-:MMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMd mMMMMMMMMMMM/ .:os+-. .dMMMMMMMMMMMNm. -soosyhdms .mMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMs mMMMMMMMMMMM: .hNhs/.. .dMMMMNmhs+:-. +MMMNoMMMMMMMMMM-"
echo -e '\033[0;34m'"/MMy hMMMMMMMMMMM: oMMMMMNdyo/. .mNh+-. +mNy.mMMMMMMMMM-"
echo -e '\033[0;34m'"/MMd +MMMMMMMMMMM/ :MMMMMMMMNs...:ohh/. . mMMMMMMMMM-"
echo -e '\033[0;34m'"/MMN. .mMMMMMMMMMMo .NMMMMMMNhhdNMMh: mMMMMMMMMM-"
echo -e '\033[0;34m'"/MMM+ /MMMMMMMMMMh yMMMMMMMMMMMN+ .NMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMm. +MMMMMMMMMN. .NMMMMMMMMMN- :sdmNNNdy+. dMMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMo +MMMMMMMMM+ +MMMMMMMMM/ -dMMMMMMNmmNN/ .sdMMMMMMM-"
echo -e '\033[0;34m'"/MMMMN: :mMMMMMMMm. oMMMMMMMh .mMMMMMMMms- .. /o. .mMMMMMM-"
echo -e '\033[0;34m'"/MMMMMm. .yMMMMMMMo oMMMMMM/ sMMMMMMMMMMMh: :NNo. sMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMm. -hMMMMMN: /NMMMM. dMMMMMMMMMMMMMh- :hmNy. .NMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMm- -yNMMMm. .yMMM. dMMMMMMMMMMMMMMNh:. .... yMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMN+ .+hNMd. :hM: dMMMMMMMMMMMMMMMMNmo- .NMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMh- ./ss. .:: sMMMMMMMMMMMMMMMMMMMNms/. /MMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMNo. . :MMMMMMMMMMMMMMMMMMMMMMMNdo:.. oMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMmo. .mMMMMMMMMMMMMMMMMMMMMMMMMMMNmh: .dMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMNy:. +MMMMMMMMMMMMMMMMMMMMMMMMMMNh+::/+sdNMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMNdo- .dMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNMMMMMMMM-"
echo -e '\033[0;34m'"/MMMMMMMMMMMMMMMMMMMMNd+-. -NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM-"
echo -e '\033[0;34m'"-NMMMMMMMMMMMMMMMMMMMMMMNdo:. /NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMd."
echo -e '\033[0;34m'" -ymNNNNNNNNNNNNNNNNNNNNNNNNdo-. +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNmy."
echo -e '\033[0;34m'" ............................ .-................................"
echo -e '\033[0;34m'" ...... ......... .............. .......... saiset ......\n"
#####################################################################################################################
R="\x1b[5;31m";G="\x1b[5;32m";Y="\x1b[5;33m";B="\x1b[5;34m";M="\x1b[5;35m";C="\x1b[5;36m";W="\x1b[5;37m";
CMD=$1;
COMMANDS=(setup start stop cleanup );
INIT=0;
[ -e storage/bot/status ] || (mkdir storage/bot/status)
STATUS_ID="storage/bot/status/status_id";
[ -f $STATUS_ID ] && INIT=1;
MEMORY="";
if [ -e preset ]; then
if [ -e preset/credentials ]; then
[ -e storage/user/credentials ] || (mkdir storage/user/credentials)
cp preset/credentials/* storage/user/credentials/
fi
fi
#####################################################################################################################
function rgb () {
R=$((RANDOM%256))
G=$((RANDOM%256))
B=$((RANDOM%256))
echo -e "\e[38;2;"$R";"$G";"$B"m"
}
#####################################################################################################################
function analyze () {
R="$(rgb)"
G="$(rgb)"
B="$(rgb)"
W="$(rgb)"
CYCLE=$((CYCLE+1))
echo -e "######################################################### SOF"
echo -e $W" stage: $CYCLE - ( CONTENT BELOW )"
echo -e $B"filename: $1"
echo -e $B"filesize: `cat $1|wc -c`"
echo -e $G" md5sum: `md5sum $1|cut -c-32`"
echo -e $G"fileinfo: `file $1`"
echo -e $R"`cat $1|hexdump -C`"|head -n 4
echo -e $R"`cat $1|hexdump -C`"|tail -n 4
echo -e $B"filename: $1"
echo -e $W"stage $CYCLE: ( CONTENT ABOVE )"
echo -e "EOF #########################################################"
}
#####################################################################################################################
function pin_ops () {
####################
# encrypts the pin #
####################
function encrypt_pin () {
echo "encrypting pin"
[ -e storage/user/config/maple.pin ] || (echo "storage/user/config/maple.pin not even here")
[ -e storage/user/config/maple.pin ] && (gpg -a --symmetric --cipher-algo AES256 storage/user/config/maple.pin);
}
#############################################################################################################
##############################
# generates a new sshkey ide #
##############################
function generate_pin () {
echo "generating pin"
PASSPHRASE=$(gpg --gen-random 2 48 | base64);
echo -e "$PASSPHRASE" > storage/user/config/maple.pin;
}
#############################################################################################################
########################################################################
# reverts sshkey identify passphrase from a php encrypted file storage #
########################################################################
function decrypt_pin () {
echo "decrypting pin"
PASSPHRASE=$(gpg -d -q storage/user/config/maple.pin.asc);
}
#############################################################################################################
# ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY #
# ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY #
# ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY #
#############################################################################################################
export GPG_TTY=$(tty)
[ -e storage/user/config ] || (mkdir -p storage/user/config)
[ -e storage/user/status ] || (mkdir storage/user/status)
echo "offline" > storage/user/status/status_id
#############################################################################################################
##############################################################################
# check if an encrypted file exists that stores our ssh identity passphrase, #
# if not- create a new identity passphrase and then encrypt it into a file. #
##############################################################################
if [ -e storage/user/config/maple.pin.asc ]; then
echo "storage/user/config/maple.pin.asc found"
if [ -e storage/user/config/maple.pin ]; then
echo "storage/user/config/maple.pin found"
else
echo "storage/user/config/maple.pin not found"
fi; #[ -e storage/user/config/maple.pin ]
else
echo "storage/user/config/maple.pin.asc not found"
(generate_pin);
fi; #[ -e storage/user/config/maple.pin.asc ];
#############################################################################################################
###################################################
# check if ssh agent is running, if not, start it #
###################################################
ssh-add > /dev/null 2>&1; [ $? -eq 2 ] && eval $(ssh-agent -s);
#############################################################################################################
############################################################
# ssh running, create and/or add our identity to the agent #
############################################################
ssh-add > /dev/null 2>&1;
#########################
if [ $? -eq 1 ]; then
####################
IDENTITY="maplenet";
####################
#################################
# check if identify files exist #
#################################
if [ -e "storage/user/config/"$IDENTITY".pub" ]; then
echo "storage/user/config/"$IDENTITY".pub found"
if [ -e "storage/user/config/"$IDENTITY ]; then
export FLAG_IDENTITY=1;
echo "storage/user/config/"$IDENTITY" found"
echo "storage/user/config/"$IDENTITY" not found"
fi; #[ -e storage/user/config/maplenet ]
else
export FLAG_IDENTITY=0;
echo "storage/user/config/"$IDENTITY" not found"
fi; #[ -e storage/user/config/maplenet.pub ]
##############################
# generate new identify file #
##############################
if [ $FLAG_IDENTITY -eq 0 ]; then
(generate_pin);
(echo -e "PASSPHRASE: $PASSPHRASE");
ssh-keygen -t rsa -m pem -b 4096 -f storage/user/config/"$IDENTITY" -N "$PASSPHRASE"
else
(decrypt_pin);
fi; #[ $FLAG_IDENTIFY -eq 0 ]
########################################################################
# add identify file to the ssh-agent including the identity passphrase #
########################################################################
echo "$PASSPHRASE" | openssl rsa -in storage/user/config/"$IDENTITY" -passin stdin | ssh-add -
[ -e storage/user/config/maple.pin.asc ] || (encrypt_pin);
[ -e storage/user/config/maple.pin.asc ] && echo "pin encrypted"
[ -e storage/user/config/maple.pin ] && (rm storage/user/config/maple.pin)
fi; #[ $? -eq 1 ]
}
#####################################################################################################################
kset() {
if [[ -z $1 ]] || [[ -z $2 ]]; then echo "error: no variable or value to kset()"; exit; fi
echo "$1 = $2" >> $CONFIG
}
#####################################################################################################################
kwrite() {
if [[ -z $1 ]]; then echo "error: no value to kwrite()"; exit; fi
echo "$1" >> $CONFIG
}
#####################################################################################################################
kblank() {
echo "" >> $CONFIG
}
#####################################################################################################################
kmodesetup() {
HYDRA=$1; MODE=$2; FAILED=0; echo -e "[ running $HYDRA ]";
if [ ! -e env ]; then
echo -e "[ setting up $HYDRA ]";
which python3 > /dev/null 2>&1
if [ $? -eq 1 ]; then echo "python3 not installed, install like pacman -Sy python3, apt install python3, brew install python3"; FAILED=1; fi
python3 -m pip > /dev/null 2>&1
if [ $? -eq 1 ]; then echo "python3 pip module not installed, attempting to auto-install"; wget https://bootstrap.pypa.io/get-pip.py; python3 get-pip.py; fi
python3 -m pip > /dev/null 2>&1
if [ $? -eq 1 ]; then echo "python3 pip module still not installed, manually install python3 pip module before proceeding"; FAILED=1; fi
which virtualenv > /dev/null 2>&1
if [ $? -eq 1 ]; then echo "python3 virtualenv module not installed, attempting to auto-install"; python3 -m pip install virtualenv; fi
which virtualenv > /dev/null 2>&1
if [ $? -eq 1 ]; then echo "python3 virtualenv module still not installed, manually instlal python3 virtualenv module before proceeding"; FAILED=1; fi
if [ $FAILED -eq 1 ]; then echo "pre-requisites not met, aborting installation"; exit 1; fi
which python3.9 > /dev/null 2>&1
if [ $? -eq 0 ]; then virtualenv -p python3.9 env; else virtualenv python3 env; fi
source env/bin/activate
pip install --upgrade pip
[ "$MODE" = "0" ] && ( cp storage/bot/variants/dupe/bot_maple__services.py ./bot_maple.py; pip install -r storage/bot/requirements/requirements_services.txt )
if [ "$MODE" = "0" ]
then
cmd_services
cat activation >> env/bin/activate
fi
[ "$MODE" = "1" ] && (cp storage/bot/variants/core/maple.ini bot_maple.ini;pip install -r storage/bot/requirements/requirements_core.txt)
[ "$MODE" = "2" ] && (cp storage/bot/variants/dupe/bot_maple__services.py bot_maple.py;pip install -r storage/bot/requirements/requirements_services.txt)
[ "$MODE" = "3" ] && (cp storage/bot/variants/dupe/bot_maple__devops.py bot_maple.py;pip install -r storage/bot/requirements/requirements_devops.txt)
echo -e "\n[ $HYDRA setup complete ]"
deactivate
echo "[ setting up $HYDRA activation ]"
if [ "$MODE" = "1" ] || [ "$MODE" = "2" ] || [ "$MODE" = "3" ]; then
echo "[ fetching $HYDRA credentials ]"
cmd_hydra_undak
cp data_dack/hydra.key storage/user/config/
cp data_dack/maplenet.pub storage/user/config/
cp data_dack/maple.pin.asc storage/user/config/
[ "$MODE" = "1" ] && ( cat data_dack/activate__hydra_core__standalone >> env/bin/activate )
[ "$MODE" = "2" ] && ( cat data_dack/activate__hydra_dupe__services >> env/bin/activate )
[ "$MODE" = "3" ] && ( cat data_dack/activate__hydra_dupe__devops >> env/bin/activate )
rm -Rf {data_dack,data_aes}
fi
echo -e "[ leaving setup and running $HYDRA ]"
fi; #[ ! -e env ]
#############################################################################################################
}
#####################################################################################################################
kmode () {
MODE=$1
echo "entered kmode"
if [ "$MODE" = "0" ]; then
HYDRA="default"
elif [ "$MODE" = "1" ]; then
HYDRA="hydra_core__standalone"
elif [ "$MODE" = "2" ]; then
HYDRA="hydra_dupe__services"
elif [ "$MODE" = "3" ]; then
HYDRA="hydra_dupe__devops"
fi; #[ "$MODE" = "0" ]
[ -e storage/bot/status ] || (mkdir storage/bot/status)
echo "$HYDRA" > storage/bot/status/status_id
kmodesetup "$HYDRA" "$MODE"
}
#####################################################################################################################
kprompt() {
if [[ -z $1 ]] || [[ -z $2 ]] || [[ -z $3 ]] || [[ -z $4 ]] || [[ -z $5 ]] || [[ -z $6 ]]; then echo "error: no variable, prompt, help, enforcement, type or memory passed to kprompt()"; exit; fi
local INIVAR=$1; local PROMPT=$2; local DIALOG=$3; local ENFORCE=$4; local TYPE=$5; local MEMORIZE=$6; unset REPLY;
while [[ -z "${REPLY}" ]] || [[ $ENFORCE -eq 1 ]]; do
if [ $TYPE -eq 1 ]; then
echo -e "$DIALOG"; echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n "[1/2]: "
elif [ $TYPE -eq 2 ]; then
echo -e "$DIALOG"; echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n "[1/2/3]: "
elif [ $TYPE -eq 3 ]; then
echo -e "$DIALOG"; echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n ": "
else
echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n "[y/n]: "
fi;
read;
if [[ $ENFORCE -eq 1 ]] && [[ $TYPE -eq 0 ]]; then
while ! [[ -z $ENFORCE ]]; do
if ([ ${REPLY} == "y" ] || [ ${REPLY} == "Y" ]); then
return 0
elif ([ ${REPLY} == "n" ] || [ ${REPLY} == "N" ]); then
return 9
else
echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n "[y/n]: "
read;
fi;
done;
elif [[ $ENFORCE -eq 1 ]] && [[ $TYPE -eq 1 ]]; then
while ! [[ -z $ENFORCE ]]; do
if ([ "${REPLY}" = "1" ]); then
return 1
elif ([ "${REPLY}" = "2" ]); then
return 2
else
echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n "[1/2]: "
read;
fi;
done;
elif [[ $ENFORCE -eq 1 ]] && [[ $TYPE -eq 2 ]]; then
while ! [[ -z $ENFORCE ]]; do
if ([ "${REPLY}" = "1" ]); then
return 1
elif ([ "${REPLY}" = "2" ]); then
return 2
elif ([ "${REPLY}" = "3" ]); then
return 3
else
echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n "[1/2/3]: "
read;
fi;
done;
elif [[ $ENFORCE -eq 1 ]] && [[ $TYPE -eq 3 ]]; then
while ! [[ -z $ENFORCE ]]; do
if ([ ! "${REPLY}" = "" ]); then
REPLY="$REPLY"
return 0
else
echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n ": "
read;
fi
done;
elif [[ $TYPE -eq 1 ]]; then
while true; do
[[ ${REPLY} =~ ^-?[0-9]+$ ]]
if ! [ $? -eq 0 ]; then
echo -en "$PROMPT"; [ $ENFORCE -eq 0 ] && echo -n ": " || echo -n "[y/n]: "
read;
else
return ${REPLY}
fi
done;
fi;
done;
if [ $MEMORIZE -eq 1 ]; then
echo "MEMORIZE"
MEMORY=${REPLY}
fi;
[ $TYPE -eq 1 ] && return ${REPLY} || kset "$INIVAR" "${REPLY}"
return 0;
}
#####################################################################################################################
cmd_hydra_dak () {
##########################################################################
[ -e data_dack ] && ( rm -Rf data_dack )
##########################################################################
mkdir data_dack
cp storage/user/config/hydra.key data_dack
cp storage/user/config/maplenet.pub data_dack
cp storage/user/config/maple.pin.asc data_dack
[ -e storage/user/credentials ] || (mkdir storage/user/credentials)
cp storage/user/credentials/activate__hydra_core__standalone data_dack
cp storage/user/credentials/activate__hydra_dupe__services data_dack
cp storage/user/credentials/activate__hydra_dupe__devops data_dack
##########################################################################
DAK=data_dack
###################################################################################################################################################
# STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 STAGE 1 #
###################################################################################################################################################
FDIR=$(basename "$DAK"); FNAME="data_dak"; CYCLE=0;
##########################################################################
echo -e $C"[ dacking archive ]"$B
##########################################################################
tar cvfz $FNAME.tgz $FDIR
analyze $FNAME.tgz
###################################################################################################################################################
# STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 STAGE 2 #
###################################################################################################################################################
cat $FNAME.tgz|base64 > $FNAME.tgz.b64
analyze $FNAME.tgz.b64
###################################################################################################################################################
# STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 STAGE 3 #
###################################################################################################################################################
dd bs=128 count=3 if=/dev/random of=random > /dev/null 2>&1
cat random|base64 > b64
dd bs=77 count=2 if=b64 of=trash > /dev/null 2>&1
cat $FNAME.tgz.b64 >> trash
mv trash $FNAME.tgz.b64.d
analyze $FNAME.tgz.b64.d
rm random && rm *b64 && rm $FNAME.tgz
###################################################################################################################################################
# STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 STAGE 4 #
###################################################################################################################################################
FPASS=$(sha256sum $FNAME.tgz.b64.d|cut -c1-64)
zip $FNAME.zip $FNAME.tgz.b64.d -r9 -P $FPASS
analyze $FNAME.zip
rm -Rf $FDIR && rm $FNAME.tgz.b64.d
###################################################################################################################################################
# STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 STAGE 5 #
###################################################################################################################################################
PASSWORD=$(gpg --gen-random 2 1024|base64)
echo $PASSWORD|tr -d ' ' > dr1p_aes1
openssl enc -aes-256-cbc -pbkdf2 -iter 20000 -in "$FNAME.zip" -out "$FNAME.aes" -pass file:"dr1p_aes1"
analyze $FNAME.aes
###################################################################################################################################################
# STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 STAGE 6 #
###################################################################################################################################################
base64 < "$FNAME.aes" > "$FNAME.dak" && rm "$FNAME.aes" && rm "$FNAME.zip"
analyze $FNAME.dak
##########################################################################
echo -e "[ crypto password ]\n$PASSWORD\n[ archive password ]\n$FPASS\n[ archive filename ]\n$FNAME.zip\n[ archive contents ]" > $FNAME.passwords
echo -e $C"[ crypto password ]\n$B$PASSWORD\n"$C"[ archive password ]\n$B$FPASS\n"$C"[ archive filename ]\n$B$FNAME.zip\n"$C"[ archive contents ]"
echo $PASSWORD|tr -d ' ' > dr1p_aes2
echo $FPASS > dr1p_zip
cat $FNAME.passwords > data_dack_dak
cat $FNAME.dak >> data_dack_dak
################################################################################################################################################### data_dack_dat is a staged encryption
# STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 STAGE 7 # while some of it is already ciphered
################################################################################################################################################### & packed, some top layers are not yet
export GPG_TTY=$(tty)
PASSPHRASE=$(gpg -d -q storage/user/config/maple.pin.asc);
gpg -a --symmetric --cipher-algo AES256 data_dack_dak
################################################################################################################################################### dak_tcp is the fully ciphered up form
# STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 STAGE 8 # that is ready to bounce around the
################################################################################################################################################### internet
openssl enc -aes-256-cbc -pbkdf2 -iter 20000 -in "data_dack_dak.asc" -out "data_dack_aes" -k $PASSPHRASE
base64 < "data_dack_aes" > "dak_tcp" && rm {dr1p_,data_}*
analyze dak_tcp
echo -e $B".[d]. xmit dakd .[d]."
cat storage/user/config/maple.pin.asc > dak_tcp.tmp
cat dak_tcp >> dak_tcp.tmp
analyze dak_tcp.tmp
mv dak_tcp.tmp dak_tcp
[ -e storage/user/logs ] || (mkdir storage/user/logs)
TCPAC=$(cat dak_tcp|nc tcp.ac 9999|jq -r '.txt,.del'|xargs); echo $TCPAC>storage/user/logs/tcpac.log
TXT=$(echo $TCPAC|cut -f 1 -d ' '); DEL=$(echo $TCPAC|cut -f 2 -d ' ');
echo -e "\n*** WRITE DOWN THIS TOKEN ***"
[ -e storage/user/logs ] || (mkdir storage/user/logs)
basename "$TXT">storage/user/logs/token.log
TOKEN=$(cat storage/user/logs/token.log)
echo -e "TOKEN: $TOKEN"
echo -e "*** WRITE DOWN THIS TOKEN ***"
}
#####################################################################################################################
cmd_hydra_undak () {
if [ -z "$TOKEN" ]; then
echo -ne "\nwhat is the token?: "
read token
else
token=$TOKEN
fi
curl -L "https://tcp.ac/t/$token" --output dak_tcp
mkdir -p storage/user/config
cp storage/user/scripts/unkey.py .
python3 unkey.py
###################################################################################################################################################
# STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 STAGE 9 #
###################################################################################################################################################
echo -e '\x1b[5;36m[ reached cmd_hydra_undak ]'
export GPG_TTY=$(tty)
PASSPHRASE=$(gpg -d -q storage/user/config/maple.pin.asc);
base64 -d < dak_tcp > data_dack_aes
analyze data_dack_aes
openssl enc -d -aes-256-cbc -pbkdf2 -iter 20000 -in "data_dack_aes" -out "data_dack_dak.asc" -k $PASSPHRASE
analyze data_dack_dak.asc
###################################################################################################################################################
# STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A STAGE A #
###################################################################################################################################################
export GPG_TTY=$(tty)
PASSPHRASE=$(gpg -o data_tcp -d -q data_dack_dak.asc)
analyze data_dack_dak.asc
cp storage/user/scripts/undak.py . && python3 undak.py
###################################################################################################################################################
# STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B STAGE B #
###################################################################################################################################################
base64 -d < data_tcp_deconcatenated > data_aes
openssl enc -d -aes-256-cbc -pbkdf2 -iter 20000 -in "data_aes" -out "data_dak" -pass file:"dr1p_aes2"
FNAME="data_dak"
FPASS=$(cat dr1p_zip)
unzip -P $FPASS $FNAME && FNAMELESS=$(echo "$FNAME" | cut -f 1 -d '.')
###################################################################################################################################################
# STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C STAGE C #
###################################################################################################################################################
if [ $? -ne 0 ]; then echo "not ok: $?"; echo "error: problem undacking"; exit 666; fi
dd skip=77 bs=2 if=$FNAMELESS.tgz.b64.d of=$FNAMELESS.tgz.b64 #> /dev/null 2>&1
if [ $? -ne 0 ]; then echo "not ok: $?"; echo "error: problem undacking"; exit 666; fi
cat $FNAMELESS.tgz.b64|base64 -d > $FNAMELESS.tgz
if [ $? -ne 0 ]; then echo "not ok: $?"; echo "error: problem undacking"; exit 666; fi
tar zxvf $FNAMELESS.tgz
if [ $? -ne 0 ]; then echo "not ok: $?"; echo "error: problem undacking"; exit 666; fi
echo ".[d]. undacked .[d]."
rm *.tgz.b64.d && rm *.tgz.b64 && rm $FNAMELESS.tgz; rm data_dack_aes; rm data_dack_dak.asc; rm data_dak; rm data_tcp; rm data_tcp_deconcatenated;
rm dr1p_*; rm dak_*; rm undak.py; rm unkey.py;
}
#####################################################################################################################
cmd_hydra () {
L="\x1b[0;94m"; D="\x1b[0;34m"; G="\x1b[0;90m"
export GPG_TTY=$(tty)
if [ ! -e storage/user/config/hydra.key ]; then
echo -e "\ngenerating hydra keyset"
HYDRAKEY=$(gpg --gen-random 2 4096 | base64);
[ -e storage/user/config ] || (mkdir storage/user/config)
echo -e "$HYDRAKEY" > storage/user/config/hydra.key
fi;
if [ ! -e storage/user/config/maplenet.pub ]; then
pin_ops;
fi;
kprompt "MODE" "$L""\nneed an online credential pak? " "credential pak" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
cmd_hydra_dak;
fi;
}
#####################################################################################################################
cmd_default () {
(kmode 0);
}
#####################################################################################################################
cmd_services_hydra () {
L="\x1b[0;94m"; D="\x1b[0;34m"; G="\x1b[0;90m"
echo -e "\n"$G"[ "$L"setting up services "$G"]\n"
[ -e storage/user/credentials ] || (mkdir -p storage/user/credentials)
if [ -e storage/user/credentials/activate__hydra_core__standalone ]; then
echo -e "storage/user/credentials/activate__hydra_core__standalone exists"
if [ -e storage/user/credentials/activate__hydra_dupe__services ]; then
echo -e "storage/user/credentials/activate__hydra_dupe__services exists"
if [ -e storage/user/credentials/activate__hydra_dupe__devops ]; then
echo -e "storage/user/credentials/activate__hydra_dupe__devops exists"
return
fi
fi
fi
kprompt "MODE" "hydra irc homechannel" "[ hyrdra irc homechannel ] example: #b0ts3x" 1 3 0; RESULT=$?
echo -e "export HYDRA_DESIGNATION=core" >> storage/user/credentials/activate__hydra_core__standalone
echo -e "export HYDRA_DESIGNATION=dupe" >> storage/user/credentials/activate__hydra_dupe__services
echo -e "export HYDRA_DESIGNATION=dupe" >> storage/user/credentials/activate__hydra_dupe__devops
echo -e "export HYDRA_HOME=$REPLY" >> storage/user/credentials/activate__hydra_core__standalone
echo -e "export HYDRA_HOME=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
echo -e "export HYDRA_HOME=$REPLY" >> storage/user/credentials/activate__hydra_dupe__devops
echo -e 'export HYDRA_PURPOSE="core - keep uptime and designate tasks"' >> storage/user/credentials/activate__hydra_core__standalone
echo -e 'export HYDRA_PURPOSE="services - runs the ai"' >> storage/user/credentials/activate__hydra_dupe__services
echo -e 'export HYDRA_PURPOSE="devops - doing development"' >> storage/user/credentials/activate__hydra_dupe__devops
kprompt "MODE" "nickserv username" "[ nickserv username ] example: username" 1 3 0; RESULT=$?
echo -e "export BOT_SASL_USERNAME=$REPLY" >> storage/user/credentials/activate__hydra_core__standalone
echo -e "export BOT_SASL_USERNAME=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
echo -e "export BOT_SASL_USERNAME=$REPLY" >> storage/user/credentials/activate__hydra_dupe__devops
echo -e "export NICKSERV_USERNAME=$REPLY" >> storage/user/credentials/activate__hydra_core__standalone
echo -e "export NICKSERV_USERNAME=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
echo -e "export NICKSERV_USERNAME=$REPLY" >> storage/user/credentials/activate__hydra_dupe__devops
kprompt "MODE" "nickserv password" "[ nickserv password ] example: password" 1 3 0; RESULT=$?
echo -e "export BOT_SASL_PASSWORD=$REPLY" >> storage/user/credentials/activate__hydra_core__standalone
echo -e "export BOT_SASL_PASSWORD=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
echo -e "export BOT_SASL_PASSWORD=$REPLY" >> storage/user/credentials/activate__hydra_dupe__devops
echo -e "export NICKSERV_PASSWORD=$REPLY" >> storage/user/credentials/activate__hydra_core__standalone
echo -e "export NICKSERV_PASSWORD=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
echo -e "export NICKSERV_PASSWORD=$REPLY" >> storage/user/credentials/activate__hydra_dupe__devops
kprompt "MODE" "will this bot use youtube services? " "youtube" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "developer_key" "[ youtube api key ] example: AIzaSyDmlgOry16XSTIVmm9au06YJDOmNrAZeRz" 1 3 0; RESULT=$?
echo -e "export YOUTUBE_DEVELOPER_KEY=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
fi
kprompt "MODE" "will this bot use twitter services? " "twitter" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "consumer_key" "[ twitter api key ] example: RMIn8DlEGhhJJBCRovD7RezZR" 1 3 0; RESULT=$?
echo -e "export TWITTER_CONSUMER_KEY=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
kprompt "MODE" "consumer_secret" "[ twitter api key ] example: Uc5X87M7kIah0mPucdQVFJZrPWvtIvmZPR9x2L4QPLpZdd3ZzD" 1 3 0; RESULT=$?
echo -e "export TWITTER_CONSUMER_SECRET=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
kprompt "MODE" "access_token_key" "[ twitter api key ] example: 1032240340353188844-yqnMN7ulbgsc4yWUYM0yxAbDdDeeeZ" 1 3 0; RESULT=$?
echo -e "export TWITTER_ACCESS_TOKEN_KEY=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
kprompt "MODE" "access_token_secret" "[ twitter api key ] example: UhlWXud7RTHRdSxdVQWgEBfC9GHmG5tcYos5lq3Zee77E" 1 3 0; RESULT=$?
echo -e "export TWITTER_ACCESS_TOKEN_SECRET=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
fi
kprompt "MODE" "will this bot use openai services? " "openai" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "openai_key" "[ openai api key ] example: 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" 1 3 0; RESULT=$?
echo -e "export OPENAI_KEY=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
fi
kprompt "MODE" "will this bot use matrix services? " "matrix" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "matrix homeserver" "[ matrix homeserver ] example: https://matrix.org" 1 3 0; RESULT=$?
echo -e "export MATRIX_HOMESERVER=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
kprompt "MODE" "matrix username" "[ matrix username ] example: whatever username you setup" 1 3 0; RESULT=$?
echo -e "export MATRIX___USERNAME=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
kprompt "MODE" "matrix password" "[ matrix password ] example: whatever password you setup for this username" 1 3 0; RESULT=$?
echo -e "export MATRIX___PASSWORD=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
fi
kprompt "MODE" "will this bot use discord services? " "discord" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "discord_token" "[ discord token ] example: OTAzOTU4NjQyNTIzNTI5MjM2.GXqwzj.Rnv8RudPRnv5jAeVu4dPnIl6TpSER7Eez5RZze" 1 3 0; RESULT=$?
echo -e "export DISCORD__TOKEN=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
kprompt "MODE" "channel_id" "[ channel_id ] example: 1009465637633929222" 1 3 0; RESULT=$?
echo -e "export DISCORD__SCHAN=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
fi
kprompt "MODE" "will this bot use telegram services? " "discord" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "telegram_token" "[ telegram token ] example: 5405833579:AAHvEUc1hms29JBoJDhoGBUE8Ept8dBrZr5" 1 3 0; RESULT=$?
echo -e "export TELEGRAM_TOKEN=$REPLY" >> storage/user/credentials/activate__hydra_dupe__services
fi
}
#####################################################################################################################
cmd_services () {
[ -e activation ] && rm activation
kprompt "MODE" "will this bot use nickserv/sasl services? " "nickserv/sasl" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "nickserv username" "[ nickserv username ] example: username" 1 3 0; RESULT=$?
echo -e "export BOT_SASL_USERNAME=$REPLY" >> activation
echo -e "export NICKSERV_USERNAME=$REPLY" >> activation
kprompt "MODE" "nickserv password" "[ nickserv password ] example: password" 1 3 0; RESULT=$?
echo -e "export BOT_SASL_PASSWORD=$REPLY" >> activation
echo -e "export NICKSERV_PASSWORD=$REPLY" >> activation
fi
kprompt "MODE" "will this bot use youtube services? " "youtube" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "developer_key" "[ youtube api key ] example: AIzaSyDmlgOry16XSTIVmm9au06YJDOmNrAZeRz" 1 3 0; RESULT=$?
echo -e "export YOUTUBE_DEVELOPER_KEY=$REPLY" >> activation
fi
kprompt "MODE" "will this bot use twitter services? " "twitter" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "consumer_key" "[ twitter api key ] example: RMIn8DlEGhhJJBCRovD7RezZR" 1 3 0; RESULT=$?
echo -e "export TWITTER_CONSUMER_KEY=$REPLY" >> activation
kprompt "MODE" "consumer_secret" "[ twitter api key ] example: Uc5X87M7kIah0mPucdQVFJZrPWvtIvmZPR9x2L4QPLpZdd3ZzD" 1 3 0; RESULT=$?
echo -e "export TWITTER_CONSUMER_SECRET=$REPLY" >> activation
kprompt "MODE" "access_token_key" "[ twitter api key ] example: 1032240340353188844-yqnMN7ulbgsc4yWUYM0yxAbDdDeeeZ" 1 3 0; RESULT=$?
echo -e "export TWITTER_ACCESS_TOKEN_KEY=$REPLY" >> activation
kprompt "MODE" "access_token_secret" "[ twitter api key ] example: UhlWXud7RTHRdSxdVQWgEBfC9GHmG5tcYos5lq3Zee77E" 1 3 0; RESULT=$?
echo -e "export TWITTER_ACCESS_TOKEN_SECRET=$REPLY" >> activation
fi
kprompt "MODE" "will this bot use openai services? " "openai" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "openai_key" "[ openai api key ] example: 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" 1 3 0; RESULT=$?
echo -e "export OPENAI_KEY=$REPLY" >> activation
fi
kprompt "MODE" "will this bot use matrix services? " "matrix" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "matrix homeserver" "[ matrix homeserver ] example: https://matrix.org" 1 3 0; RESULT=$?
echo -e "export MATRIX_HOMESERVER=$REPLY" >> activation
kprompt "MODE" "matrix username" "[ matrix username ] example: whatever username you setup" 1 3 0; RESULT=$?
echo -e "export MATRIX___USERNAME=$REPLY" >> activation
kprompt "MODE" "matrix password" "[ matrix password ] example: whatever password you setup for this username" 1 3 0; RESULT=$?
echo -e "export MATRIX___PASSWORD=$REPLY" >> activation
fi
kprompt "MODE" "will this bot use discord services? " "discord" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "discord_token" "[ discord token ] example: OTAzOTU4NjQyNTIzNTI5MjM2.GXqwzj.Rnv8RudPRnv5jAeVu4dPnIl6TpSER7Eez5RZze" 1 3 0; RESULT=$?
echo -e "export DISCORD__TOKEN=$REPLY" >> activation
kprompt "MODE" "channel_id" "[ channel_id ] example: 1009465637633929222" 1 3 0; RESULT=$?
echo -e "export DISCORD__SCHAN=$REPLY" >> activation
fi
kprompt "MODE" "will this bot use telegram services? " "discord" 1 0 0; RESULT=$?
if [ $RESULT = "0" ]; then
kprompt "MODE" "telegram_token" "[ telegram token ] example: 5405833579:AAHvEUc1hms29JBoJDhoGBUE8Ept8dBrZr5" 1 3 0; RESULT=$?
echo -e "export TELEGRAM_TOKEN=$REPLY" >> activation
fi
}
#####################################################################################################################
cmd_setup () {
#######################################################################
L="\x1b[0;94m"; D="\x1b[0;34m"; G="\x1b[0;90m"
if [ $INIT = 0 ]; then
kprompt "MODE" "which type? " "1"$G") "$L"NON-HYDRA\n"$B"2"$G") "$L"HYDRA\n" 1 1 0
RESULT=$?
if [ $RESULT -eq 1 ]; then
(kmode 0);
if [ ! -e plugins ]; then
mkdir plugins
cat storage/bot/variants/default/bot_maple__default__initial_plugins.txt|grep -v "#"|grep -v irc3|sed s/plugins.//|xargs -I{} cp storage/bot/plugins/{}.py plugins/
sed -i '/includes/r storage/bot/variants/default/bot_maple__default__initial_plugins.txt' plugins/net_irc_plugin.py
sed -i s/"GETTINGTAGGEDUP"/"SERVICES=True"/g plugins/net_irc_plugin.py
sed -i s/"GETTINGTAGGEDUP"/"SERVICES=True"/g plugins/net_discord_plugin.py
fi;
fi;
if [ $RESULT -eq 2 ]; then
cmd_services_hydra
[ -e storage/user/config/hydra.key ] || cmd_hydra;
cmd_setup_bot
fi;
fi;
}
#####################################################################################################################
cmd_setup_bot () {
#######################################################################
L="\x1b[0;94m"; D="\x1b[0;34m"; G="\x1b[0;90m"
if [ $INIT = 0 ]; then
kprompt "MODE" "which mode? " $B"\n1"$G") "$L"CORE "$G"- "$L"STRIPPED\n"$B"2"$G") "$L"DUPE "$G"- "$L"SERVICES\n"$B"3"$G") "$L"DUPE "$G"- "$L"DEVOPS\n" 1 2 0
RESULT=$?
if [ $RESULT -eq 1 ]; then
(kmode 1);
if [ ! -e plugins ]; then
mkdir plugins
cat storage/bot/variants/core/bot_maple__core__initial_plugins.txt|grep -v "#"|grep -v irc3|sed s/plugins.//|xargs -I{} cp storage/bot/plugins/{}.py plugins/
fi;
elif [ $RESULT -eq 2 ]; then
(kmode 2);
if [ ! -e plugins ]; then
mkdir plugins
cat storage/bot/variants/dupe/bot_maple__services__initial_plugins.txt|grep -v "#"|grep -v irc3|sed s/plugins.//|xargs -I{} cp storage/bot/plugins/{}.py plugins/
sed -i '/includes/r storage/bot/variants/dupe/bot_maple__services__initial_plugins.txt' plugins/net_irc_plugin.py
sed -i s/"GETTINGTAGGEDUP"/"SERVICES=True"/g plugins/net_irc_plugin.py
sed -i s/"GETTINGTAGGEDUP"/"SERVICES=True"/g plugins/net_discord_plugin.py
fi;
elif [ $RESULT -eq 3 ]; then
(kmode 3);
if [ ! -e plugins ]; then
mkdir plugins
cat storage/bot/variants/dupe/bot_maple__devops__initial_plugins.txt|grep -v "#"|grep -v irc3|sed s/plugins.//|xargs -I{} cp storage/bot/plugins/{}.py plugins/
sed -i '/includes/r storage/bot/variants/dupe/bot_maple__devops__initial_plugins.txt' plugins/net_irc_plugin.py
sed -i s/"GETTINGTAGGEDUP"/"SERVICES=False"/g plugins/net_irc_plugin.py
#sed -i s/"GETTINGTAGGEDUP"/"SERVICES=False"/g plugins/net_discord_plugin.py
fi;
fi;
fi;
#######################################################################
#######################################################################
if [ ! -e databases ]; then
cp -Rf storage/bot/databases databases
fi;
}
#####################################################################################################################
cmd_start () {
#######################################################################
echo -e "[ running $HYDRA ]"
#######################################################################
source env/bin/activate
[ -e storage/bot/status ] || (mkdir storage/bot/status)
MODE=$(cat storage/bot/status/status_id)
if [ "$MODE" = "hydra_core__standalone" ]; then
sh -c 'echo $$>r3kt.pid; exec irc3 bot_maple.ini & disown'
dip=`cat r3kt.pid`
dip=$((dip+1))
echo $dip>r3kt.pid
else
sh -c 'echo $$>r3kt.pid; exec python3 bot_maple.py & disown'
dip=`cat r3kt.pid`
dip=$((dip+1))
echo $dip>r3kt.pid
fi;
#######################################################################
echo -e "[ $HYDRA bot added to background as a job. pid: `cat *.pid` ]"
#######################################################################
}; # eof cmd_start
################
cmd_stop () {
echo -e "[ stopping `cat r3kt.pid` ]"
pid=`cat r3kt.pid` && kill -9 $pid;rm r3kt.pid
}
################
cmd_cleanup () {
L="\x1b[0;94m"; D="\x1b[0;34m"; G="\x1b[0;90m"
echo -e "$G""[""$L""executed command"$G" - "$D"cleanup""$G""]"
[ -e bot_maple.py ] && (rm bot_maple.py)
[ -e env ] && (rm -Rf env)
[ -e plugins ] && (rm -Rf plugins)
[ -e databases ] && (rm -Rf databases)
rm -Rf storage/user/config/*
rm -Rf {data_,dr1p_}*
[ -e fifo ] && (rm -Rf fifo)
[ -e dak_tcp ] && (rm dak_tcp)
[ -e bot_maple.ini ] && (rm bot_maple.ini)
[ -e storage/bot/status/status_id ] && (rm storage/bot/status/status_id)
[ -e storage/user/credentials/activate__hydra_core__standalone ] && (rm storage/user/credentials/activate__hydra_core__standalone)
[ -e storage/user/credentials/activate__hydra_dupe__services ] && (rm storage/user/credentials/activate__hydra_dupe__services)
[ -e storage/user/credentials/activate__hydra_dupe__devops ] && (rm storage/user/credentials/activate__hydra_dupe__devops)
[ -e storage/bot/status ] && (rm -Rf storage/bot/status)
[ -e storage/user/status ] && (rm -Rf storage/user/status)
[ -e storage/user/config ] && (rm -Rf storage/user/config)
[ -e storage/user/credentials ] && (rm -Rf storage/user/credentials)
[ -e storage/user/logs/tcpac.log ] && (curl `cat storage/user/logs/tcpac.log|cut -f 2 -d ' '`)
[ -e storage/user/logs ] && (rm -Rf storage/user/logs)
}
#####################################################################################################################
error () {
echo -en $R"\terror - $1. "
}
#####################################################################################################################
help () {
[ $1 -eq 1 ] && echo -e $W"commands: ${COMMANDS[*]}"
}
#####################################################################################################################
#####################################################################################################################
# ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY #
# ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY #
# ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY POINT ENTRY #
#####################################################################################################################
#####################################################################################################################
#[ -z $1 ] && error "no command issued" && help 1 && exit
if [ -z $1 ]; then
# detect bot setup, if none start setup
if [ ! -e bot_maple.ini ] || [ ! -e bot_maple.py ]; then
cmd_setup;
fi
# detect bot pid, if no pid then start bot, if pid then stop bot
if [ ! -e r3kt.pid ]; then
cmd_start;
elif [ -e r3kt.pid ]; then
cmd_stop;
fi
fi;
#####################################################################################################################
# if grep -q "$CMD" <<< "${commands[@]}"; then
# echo -e "$CMD command found"
if [ "$CMD" = "default" ]; then
cmd_default;
elif [ "$CMD" = "setup" ]; then
cmd_setup;
elif [ "$CMD" = "hydra" ]; then
cmd_hydra;
elif [ "$CMD" = "ardyh" ]; then
cmd_hydra_undak;
elif [ "$CMD" = "start" ]; then
cmd_start;
elif [ "$CMD" = "stop" ]; then
cmd_stop;
elif [ "$CMD" = "cleanup" ]; then
cmd_cleanup;
fi;
# else
# error "$1 isn't an available command" && help 1 && exit 1
# fi
#####################################################################################################################
#####################################################################################################################
# EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT#
#EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT #
# EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT POINT EXIT#
#####################################################################################################################
#####################################################################################################################
################################################################################################################# EOF

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

BIN
screenshots/ss1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

View File

@ -0,0 +1,426 @@
¢‿¢
©¿© o
ª{•̃̾_•̃̾}ª
¬_¬
¯\(º_o)/¯
¯\(º o)/¯
¯\_(⊙︿⊙)_/¯
¯\_(ツ)_/¯
°ω°
°Д°
°‿‿°
°ﺑ°
´ ▽ ` )ノ
¿ⓧ_ⓧﮌ
Ò,ó
ó‿ó
ô⌐ô
ôヮô
ŎםŎ
ŏﺡó
ʕ•̫͡•ʔ
ʕ•ᴥ•ʔ
ʘ‿ʘ
˚•_•˚
˚⌇˚
˚▱˚
̿ ̿̿'̿'\̵͇̿̿\=(•̪●)=/̵͇̿̿/'̿̿ ̿ ̿ ̿
͡° ͜ʖ ͡°
Σ ◕ ◡ ◕
Σ (゚Д゚;
Σ(゚Д゚;≡;゚д゚)
Σ(゚Д゚ )
Σ(||゚Д゚)
Φ,Φ
δﺡό
σ_σ
д_д
ф_ф
щ(゚Д゚щ)
щ(ಠ益ಠщ)
щ(ಥДಥщ)
Ծ_Ծ
أ‿أ
ب_ب
ح˚௰˚づ
ح˚ᆺ˚ว
حᇂﮌᇂ)
٩๏̯͡๏۶
٩๏̯͡๏)۶
٩◔̯◔۶
٩(×̯×)۶
٩(̾●̮̮̃̾•̃̾)۶
٩(͡๏̯͡๏)۶
٩(͡๏̯ ͡๏)۶
٩(ಥ_ಥ)۶
٩(•̮̮̃•̃)۶
٩(●̮̮̃•̃)۶
٩(●̮̮̃●̃)۶
٩(。͡•‿•。)۶
٩(-̮̮̃•̃)۶
٩(-̮̮̃-̃)۶
۞_۞
۞_۟۞
۹ↁﮌↁ
۹⌤_⌤۹
॓_॔
१✌◡✌५
१|˚–˚|५
ਉ_ਉ
ଘ_ଘ
இ_இ
ఠ_ఠ
రృర
ಠ¿ಠi
ಠ‿ಠ
ಠ⌣ಠ
ಠ╭╮ಠ
ಠ▃ಠ
ಠ◡ಠ
ಠ益ಠ
ಠ益ಠ
ಠ︵ಠ凸
ಠ , ಥ
ಠ.ಠ
ಠoಠ
ಠ_ృ
ಠ_ಠ
ಠ_๏
ಠ~ಠ
ಡ_ಡ
ತಎತ
ತ_ತ
ಥдಥ
ಥ‿ಥ
ಥ⌣ಥ
ಥ◡ಥ
ಥ﹏ಥ
ಥ_ಥ
ಭ_ಭ
ರ_ರ
ಸ , ໖
ಸ_ಸ
ക_ക
อ้_อ้
อ_อ
โ๏௰๏ใ ื
๏̯͡๏﴿
๏̯͡๏
๏̯͡๏﴿
๏[-ิิ_•ิ]๏
๏_๏
໖_໖
ლ(´ڡ`ლ)
ლ(́◉◞౪◟◉‵ლ)
ლ(ಠ益ಠლ)
ლ(╹◡╹ლ)
ლ(◉◞౪◟◉‵ლ)
ლ,ᔑ•ﺪ͟͠•ᔐ.ლ
ᄽὁȍ ̪ őὀᄿ
ᕕ( ᐛ )ᕗ
ᕙ(⇀‸↼‶)ᕗ
ᕦ(ò_óˇ)ᕤ
ᶘ ᵒᴥᵒᶅ
‘︿’
•▱•
•✞_✞•
•ﺑ•
•(⌚_⌚)•
•_•)
‷̗ↂ凸ↂ‴̖
‹•.•›
(•¿•)
(ᵒᴥᵒ­­­­­)
(•¿•)
ↁ_ↁ
⇎_⇎
∩(︶▽︶)∩
∩( ・ω・)∩
≖‿≖
≧ヮ≦
⊂•⊃_⊂•⊃
⊂⌒~⊃。Д。)⊃
⊂(◉‿◉)つ
⊂(゚Д゚,,⊂⌒`つ
⊙ω⊙
⊙▂⊙
⊙▃⊙
⊙△⊙
⊙︿⊙
⊙﹏⊙
⊙0⊙
⊛ठ̯⊛
⋋ō_ō`
━━━ヽ(ヽ(゚ヽ(゚ヽ(゚゚ヽ(゚゚)ノ゚゚)ノ゚)ノ゚)ノ)ノ━━━
┌∩┐(◕_◕)┌∩┐
┌( ಠ_ಠ)┘
┌( ಥ_ಥ)┘
╚(•⌂•)╝
╭╮╭╮☜{•̃̾_•̃̾}☞╭╮╭╮
╭✬⌢✬╮
╮(▽)╭
╯‵Д′)╯彡┻━┻
╰☆╮
□_□
►_◄
◃┆◉◡◉┆▷
◉△◉
◉︵◉
◉_◉
○_○
●¿●\ ~
●_●
◔̯◔
◔ᴗ◔
◔ ⌣ ◔
◔_◔
◕ω◕
◕‿◕
◕◡◕
◕ ◡ ◕
◖♪_♪|◗
◖|◔◡◉|◗
◘_◘
◙‿◙
◜㍕◝
◪_◪
◮_◮
☁ ☝ˆ~ˆ☂
☆¸☆
☉‿⊙
☉_☉
☐_☐
☜ق❂Ⴢ❂ق☞
☜(⌒▽⌒)☞
☜(゚ヮ゚☜)
☜-(ΘLΘ)-☞
☝☞✌
☮▁▂▃▄☾ ♛ ◡ ♛ ☽▄▃▂▁☮
☹_☹
☻_☻
☼.☼
☾˙❀‿❀˙☽
♀ح♀ヾ
♥‿♥
♥╣[-_-]╠♥
♥╭╮♥
♥◡♥
✌♫♪˙❤‿❤˙♫♪✌
✌.ʕʘ‿ʘʔ.✌
✌.|•͡˘‿•͡˘|.✌
✖‿✖
✖_✖
❐‿❑
_
_Ꙩ
⨂_⨂
〆(・・@)
《〠_〠》
【•】_【•】
〠_〠
〴⋋_⋌〵
<EFBFBD> <20>
ニガー? ━━━━━━(゚゚)━━━━━━ ニガー?
ペ㍕˚\
ヽ(´ー` )ノ
ヽ(๏๏ )ノ
ヽ(`Д´)ノ
ヽ(`皿′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=ー( ゚д゚)・∵.
\˚ㄥ˚\
\ᇂ_ᇂ\
\(ಠ ὡ ಠ )/
\(◕ ◡ ◕\)
^̮^
^ㅂ^
_(͡๏̯͡๏)_
{´◕ ◡ ◕`}
{ಠ_ಠ}__,,|,
{◕ ◡ ◕}

View File

@ -0,0 +1,114 @@
{
"bbs_data": {
"0": {
"hits": 1,
"nicks": {
"dr1p": 1
},
"site": "soundcloud",
"timestamp": 1658706829.869036,
"title": "fenix flexin - 10 toes ( dr1ph0p m1x )",
"token": "06660",
"url": "https://soundcloud.com/vanta_sec/fenix-flexin-10-toes-dr1ph0p-m1x"
}
},
"bbs_last": {
"0": [
"dr1p",
"soundcloud",
"fenix flexin - 10 toes ( dr1ph0p m1x )",
"06660",
"https://soundcloud.com/vanta_sec/fenix-flexin-10-toes-dr1ph0p-m1x"
],
"1": "",
"10": "",
"11": "",
"12": "",
"13": "",
"14": "",
"15": "",
"16": "",
"17": "",
"18": "",
"19": "",
"2": "",
"20": "",
"21": "",
"22": "",
"23": "",
"24": "",
"25": "",
"26": "",
"27": "",
"28": "",
"29": "",
"3": "",
"30": "",
"31": "",
"32": "",
"33": "",
"34": "",
"35": "",
"36": "",
"37": "",
"38": "",
"39": "",
"4": "",
"40": "",
"41": "",
"42": "",
"43": "",
"44": "",
"45": "",
"46": "",
"47": "",
"48": "",
"49": "",
"5": "",
"6": "",
"7": "",
"8": "",
"9": ""
},
"bbs_nicks": {
"0": {
"dr1p": {
"bandcamp": 0,
"soundcloud": 1,
"spotify": 0,
"tally": 1,
"youtube": 0
}
}
},
"bbs_sites": {
"0": {
"bandcamp": 0,
"soundcloud": 1,
"spotify": 0,
"youtube": 0
}
},
"bbs_token": {
"0": {
"06660": "https://soundcloud.com/vanta_sec/fenix-flexin-10-toes-dr1ph0p-m1x"
}
},
"bbs_tokenmirror": {
"0": {
"https://soundcloud.com/vanta_sec/fenix-flexin-10-toes-dr1ph0p-m1x": "06660"
}
},
"staff_list": {
"0": "moony!*@*",
"1": "GregJ!*@*",
"2": "Dillinger!*@*",
"3": "d*!~dtcpdirect@*",
"4": "chunk!*@*",
"5": "d*!~dvaccine@*",
"6": "Civil!*@*",
"7": "sniff!*@*",
"8": "d!*@1.3.3.7",
"9": "kayos!*@*"
}
}

View File

View File

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*- ############################################################### SOF
from irc3.plugins.command import command
from irc3.plugins.cron import cron
from datetime import datetime
import irc3,re,os,asyncio
###########################################################################################
dr1p_home=os.environ['ANSI_HOME']
###########################################################################################
class EIO():
#######################################################################################
def __init__(self):
self.regex=re.compile("\x03(?:\d{1,2}(?:,\d{1,2})?)?",re.UNICODE)
self.buffering=False
self.count=0
self.lastcount=-1
self.cycle=0
self.sorted=[]
self.sorting=[]
#######################################################################################
def push(self,nick,channel,dataline,hexdataline):
###################################################################################
if self.buffering==False:
self.sorting.append([nick,True,channel,[datetime.now().timestamp()],[dataline],[hexdataline]])
self.buffering=True
###################################################################################
try:
for x in self.sorting:
if x[0]==nick:
if x[1]:
x[3].append(datetime.now().timestamp())
x[4].append(dataline)
x[5].append(hexdataline)
###################################################################################
except Exception as e:
pass
###########################################################################################
@irc3.plugin
class Plugin:
#######################################################################################
def __init__(self, bot):
self.bot=bot
self.bot.eio=EIO()
#######################################################################################
@irc3.event(irc3.rfc.PRIVMSG)
def on_privmsg(self,mask=None,event=None,target=None,data=None,**kw):
if mask.nick==self.bot.nick: return
hexdataline=''
inverse=self.bot.eio.regex.sub("",data)
if inverse!=data:
for c in data:
hexdataline+=hex(ord(c))[2:].upper()
self.bot.eio.push(mask.nick,target,data,hexdataline)
####################################################################################### EOF
@cron('* * * * * */1')
def eio_cron(bot):
eio=bot.eio
if bot.eio.buffering==True:
eio.cycle+=1
for z,entry in enumerate(eio.sorting):
if entry[1]:
timestamps=entry[3]
bot.eio.lastcount=bot.eio.count
bot.eio.count=len(timestamps)
if bot.eio.count!=bot.eio.lastcount:
return
timestamps.reverse()
distances=[]
for i in range(0,len(timestamps)-1):
distance=timestamps[i]-timestamps[i+1]
distances.append(distance)
longest_distance=max(distances)
timestamp=datetime.now().timestamp()
active_distance=timestamp-timestamps[0]
if active_distance>longest_distance*1.5:
eio.sorting[z][1]=False
nick=eio.sorting[z][0]
channel=eio.sorting[z][2]
eio.sorted.append([nick,channel,entry[4],entry[5]])
eio.sorting.remove(eio.sorting[z])
eio_sorted=eio.sorted[-1]
for dataline in eio_sorted[2]:
bot.privmsg(dr1p_home,dataline)
###################################################################################
SELF_DISABLE_FLAG=True
try:
for eio_sorting in eio.sorting:
for isnotdisabled in eio_sorting[1]:
if isnotdisabled: SELF_DISABLE_FLAG=False
###################################################################################
except:
pass
###################################################################################
if SELF_DISABLE_FLAG:
msg=f'<<< ________ansi_plugin >>> [ event: control code buffer ]'
msg+=' - '
msg+='finished, disabling cleanup cronjob'
print(msg)
bot.eio.buffering=False
####################################################################################### EOF

View File

@ -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

View File

@ -0,0 +1,240 @@
# -*- 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=False)
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=False)
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

View File

@ -0,0 +1,779 @@
# -*- 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
#from plugins.tool_colors_plugin import colorform as print
from plugins.tool_dims_plugin import dims
########################################################################## 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):
try:
bool(dims.checked)
except:
dims.checked=True
if dims.checked:
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(_))
dims.checked=False
############################################################ 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 worlds 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

View File

@ -0,0 +1,159 @@
# -*- coding: utf-8 -*- ############################################################### SOF
import asyncio
import irc3
from irc3.plugins.command import command
from plugins.tool_bus_plugin import BUS
from plugins.tool_colors_plugin import colorform as print
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
###########################################################################################
@irc3.plugin
class Plugin:
#######################################################################################
def __init__(self, bot):
self.bot = bot
#######################################################################################
@irc3.extend
@command(permission='admin',show_in_help_list=True)
async def listrooms(self,sender_netroomchan,sender_user,target,):
"""listrooms - lists rooms/channels/groups this bot is currently in
%%listrooms
"""
results=[]
result=dims.list_channels()
for _ in result:
if _.startswith('!'):
room=f'__matrix: {_}'
elif _.startswith('#'):
room=f'_____irc: {_}'
elif _.startswith('$'):
room=f'telegram: {_}'
elif _.startswith('^'):
room=f'_discord: {_}'
msg=f'<<< _____cmd_irc_plugin >>> [ ({sender_netroomchan})({sender_user})(listrooms)->({target}) ] - {room}'
print(msg)
results.append(room)
return results
#######################################################################################
@irc3.extend
@command(permission='admin',show_in_help_list=True)
async def listbridges(self,sender_netroomchan,sender_user,target,):
"""listbridges - lists rooms/channels/groups this bot is currently in
%%listbridges
"""
results=[]
result=dims.list_channels_bridged()
for _ in result:
msg=f'<<< _____cmd_irc_plugin >>> [ ({sender_netroomchan})({sender_user})(listbridges) ] - {_}'
print(msg)
if _[0]:
channel=_[0]
else:
channel=None
if _[1]:
inbound=_[1]
else:
inbound=None
if _[2]:
outbound=_[2]
else:
outbound=None
if inbound and outbound:
results.append(f"{channel} - inbound: {inbound} - outbound: {outbound}")
elif inbound:
results.append(f"{channel} - inbound: {inbound}")
elif outbound:
results.append(f"{channel} - outbound: {outbound}")
else:
results.append(f"{channel}")
return results
#######################################################################################
@irc3.extend
@command(permission='admin',show_in_help_list=True)
async def addbridge(self,mask,target,args):
"""addbridge - add a bridge rule for a netspan channel/room/group. use ?listrooms, ?listbridges for information. usage: ?addbridge #b0tsh0p ^χιϛ
%%addbridge <noise>...
"""
noise=' '.join(args['<noise>']).strip()
src_outbound=noise.split()[0]
dest_inbound=noise.split()[1]
results=[]
result=dims.bridge_routes(src_outbound,dest_inbound,"add")
if result[0]:
status="status: completed"
else:
status=f"status: failed - {result[1]}"
results.append(f"[ {src_outbound} -> {dest_inbound} ] - adding bridge - {status}")
msg=f'<<< ________dims_plugin >>> [ addbridge ] - {src_outbound} -> {dest_inbound} - {status}'
print(msg)
return results
#######################################################################################
@irc3.extend
@command(permission='admin',show_in_help_list=True)
async def delbridge(self,mask,target,args):
"""delbridge - delete a bridge rule for a netspan channel/room/group. use ?listrooms, ?listbridges for information. usage: ?delbridge #b0tsh0p ^χιϛ
%%delbridge <noise>...
"""
noise=' '.join(args['<noise>']).strip()
src_outbound=noise.split()[0]
dest_inbound=noise.split()[1]
results=[]
result=dims.bridge_routes(src_outbound,dest_inbound,"del")
if result[0]:
status="status: completed"
else:
status=f"status: failed - {result[1]}"
results.append(f"[ {src_outbound} -> {dest_inbound} ] - deleting bridge - {status}")
msg=f'<<< ________dims_plugin >>> [ addbridge ] - {src_outbound} -> {dest_inbound} - {status}'
print(msg)
return results
#######################################################################################
@irc3.extend
@command(permission='admin',show_in_help_list=True)
async def blackhole(self,mask,target,args):
"""blackhole - prevents maple from reverberating on bridges. usage: ?blackhole !asdfasdfasdfsad:pcriot.org add or ?blackhole !asdfasdfasd del
%%blackhole <noise>...
"""
noise=' '.join(args['<noise>']).strip()
if noise=="list":
self.blackhole=[]
ircbot=guds.memory('ircbot')
dbname="blackhole"
db=ircbot.db.getlist(dbname)
if db:
for entry in db:
self.blackhole.append(entry)
return self.blackhole
src_blackhole=noise.split()[0]
command=noise.split()[1]
results=[]
result=dims.blackholes(src_blackhole,command)
results.append(f"[ {src_blackhole} ] - adding blackhole")
msg=f'<<< ________dims_plugin >>> [ addblackhole ] - {src_blackhole}'
print(msg)
return results
#######################################################################################
@irc3.extend
@command(permission='admin',show_in_help_list=True)
async def purgebridges(self, mask=None, target=None, data=None, sender_user=None, sender_netroomchan=None, **kw):
"""purgebridges - erases channel/room message history across nets
%%purgebridges
"""
msg=f'<<< _____cmd_irc_plugin >>> [ ({mask.nick}{target}).purgebridges()->({target}) ] - purging'
print(msg)
from plugins.net_discord_plugin import d_discord_cmd
d_discord_cmd(target,"purgebridges")
###################################################################### NET IRC - MAIN [4/4]
async def _d_cmd_irc(sender_netroomchan,sender_user,target,cmd,) -> None:
#######################################################################################
result=(await eval(f"guds.memory('ircbot').{cmd}")(sender_netroomchan=sender_netroomchan,sender_user=sender_user,target=target,cmd=cmd,))
#######################################################################################
bridgedbus=(BUS(['#b0tsh0p','!OftXgmqAFOPEatmvLU:pcriot.org']))
await bridgedbus.output([sender_netroomchan,sender_user],result)
###########################################################################################
def d_cmd_irc(sender_netroomchan,sender_user,target,cmd,):
self=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(_d_cmd_irc(sender_netroomchan,sender_user,target,cmd,),self.loop)
####################################################################################### EOF

View File

@ -0,0 +1,528 @@
# -*- coding: utf-8 -*-
from irc3.compat import asyncio
from irc3 import utils
from collections import defaultdict
import functools
import venusian
import fnmatch
import logging
import docopt
import shlex
import irc3
import sys
import re
__doc__ = '''
==========================================
:mod:`irc3.plugins.command` Command plugin
==========================================
Introduce a ``@command`` decorator
The decorator use `docopts <http://docopt.org/>`_ to parse command arguments.
Usage
=====
Create a python module with some commands:
.. literalinclude:: ../../examples/mycommands.py
..
>>> import sys
>>> sys.path.append('examples')
>>> from irc3.testing import IrcBot
>>> from irc3.testing import ini2config
And register it::
>>> bot = IrcBot()
>>> bot.include('irc3.plugins.command') # register the plugin
>>> bot.include('mycommands') # register your commands
Check the result::
>>> bot.test(':gawel!user@host PRIVMSG #chan :!echo foo')
PRIVMSG #chan :foo
In the docstring, ``%%`` is replaced by the command character. ``!`` by
default. You can override it by passing a ``cmd`` parameter to bot's config.
When a command is not public, you can't use it on a channel::
>>> bot.test(':gawel!user@host PRIVMSG #chan :!adduser foo pass')
PRIVMSG gawel :You can only use the 'adduser' command in private.
If a command is tagged with ``show_in_help_list=False``, it won't be shown
on the result of ``!help``.
>>> bot.test(':gawel!user@host PRIVMSG #chan :!help')
PRIVMSG #chan :Available commands: !adduser, !echo, !help
View extra info about a command by specifying it to ``!help``.
>>> bot.test(':gawel!user@host PRIVMSG #chan :!help echo')
PRIVMSG #chan :Echo command
PRIVMSG #chan :!echo <words>...
>>> bot.test(':gawel!user@host PRIVMSG #chan :!help nonexistant')
PRIVMSG #chan :No such command. Try !help for an overview of all commands.
Guard
=====
You can use a guard to prevent untrusted users to run some commands. The
:class:`free_policy` is used by default.
There is two builtin policy:
.. autoclass:: free_policy
.. autoclass:: mask_based_policy
Mask based guard using permissions::
>>> config = ini2config("""
... [bot]
... nick = nono
... includes =
... irc3.plugins.command
... mycommands
... [irc3.plugins.command]
... guard = irc3.plugins.command.mask_based_policy
... [irc3.plugins.command.masks]
... gawel!*@* = all_permissions
... foo!*@* = help
... """)
>>> bot = IrcBot(**config)
foo is allowed to use command without permissions::
>>> bot.test(':foo!u@h PRIVMSG nono :!echo got the power')
PRIVMSG foo :got the power
foo is not allowed to use command except those with the help permission::
>>> bot.test(':foo!u@h PRIVMSG nono :!ping')
PRIVMSG foo :You are not allowed to use the 'ping' command
gawel is allowed::
>>> bot.test(':gawel!u@h PRIVMSG nono :!ping')
NOTICE gawel :PONG gawel!
Async commands
==============
Commands can be coroutines:
.. literalinclude:: ../../examples/async_command.py
:language: py
Available options
=================
The plugin accept the folowing options:
.. code-block:: ini
[irc3.plugins.command]
cmd = !
use_shlex = true
antiflood = true
casesensitive = true
guard = irc3.plugins.command.mask_based_policy
Command arguments
=================
The :func:`command` decorator accept the folowing arguments:
**name**: if set, use this name as the command name instead of the function
name.
**permission**: if set, this permission will be required to run the command.
See Guard section
**use_shlex**: if `False`, do not use `shlex` to parse command line.
**options_first**: if `True` use docopt's options_first options. Allow to have
args that starts with `-` as arguments.
**error_format**: allow to customize error messages. must be a callable that
accept keyword arguments `cmd`, `args` and `exc`.
For example, `error_format="Error for {cmd}".format` will work.
**quiet**: if `True` don't show errors
**aliases**: this argument, when present, should be a list of strings. All
those strings will become alternative command names (i.e. aliases).
For example, command 'mycmd' with aliases=['theircmd', 'noonescmd'] could
be called via all three names.
'''
class free_policy:
"""Default policy"""
def __init__(self, bot):
self.context = bot
def __call__(self, predicates, meth, client, target, args, **kwargs):
return meth(client, target, args)
class mask_based_policy:
"""Allow only valid masks. Able to take care or permissions"""
key = __name__ + '.masks'
def __init__(self, bot):
self.context = bot
self.log = logging.getLogger(__name__)
self.log.debug('Masks: %r', self.masks)
@property
def masks(self):
masks = self.context.config[self.key]
if hasattr(self.context, 'db'):
# update config with storage values
try:
value = self.context.db[self]
except KeyError:
pass
else:
if isinstance(value, dict):
masks.update(value)
return masks
def has_permission(self, mask, permission):
if permission is None:
return True
for pattern in self.masks:
if fnmatch.fnmatch(mask, pattern):
if not isinstance(self.masks, dict):
return True
perms = self.masks[pattern]
if permission in perms or 'all_permissions' in perms:
return True
return False
def __call__(self, predicates, meth, client, target, args, **kwargs):
if self.has_permission(client, predicates.get('permission')):
return meth(client, target, args)
cmd_name = predicates.get('name', meth.__name__)
self.context.privmsg(
client.nick,
'You are not allowed to use the %r command' % cmd_name)
def attach_command(func, depth=2, **predicates):
commands = predicates.pop('commands',
'irc3.plugins.command.Commands')
category = predicates.pop('venusian_category',
'irc3.plugins.command')
def callback(context, name, ob):
obj = context.context
if info.scope == 'class':
callback = func.__get__(obj.get_plugin(ob), ob)
else:
callback = utils.wraps_with_context(func, obj)
plugin = obj.get_plugin(utils.maybedotted(commands))
predicates.update(module=func.__module__)
cmd_name = predicates.get('name', func.__name__)
if not plugin.case_sensitive:
cmd_name = cmd_name.lower()
plugin[cmd_name] = (predicates, callback)
aliases = predicates.get('aliases', None)
if aliases is not None:
for alias in aliases:
plugin.aliases[alias] = cmd_name
obj.log.debug('Register command %r %r', cmd_name, aliases)
else:
obj.log.debug('Register command %r', cmd_name)
info = venusian.attach(func, callback,
category=category, depth=depth)
def command(*func, **predicates):
if func:
func = func[0]
attach_command(func, **predicates)
return func
else:
def wrapper(func):
attach_command(func, **predicates)
return func
return wrapper
@irc3.plugin
class Commands(dict):
__reloadable__ = False
requires = [
__name__.replace('command', 'core'),
]
default_policy = free_policy
case_sensitive = False
def __init__(self, context):
self.context = context
module = self.__class__.__module__
self.config = config = context.config.get(module, {})
self.log = logging.getLogger(module)
self.log.debug('Config: %r', config)
if 'cmd' in context.config: # in case of
config['cmd'] = context.config['cmd']
context.config['cmd'] = self.cmd = config.get('cmd', '!')
context.config['re_cmd'] = re.escape(self.cmd)
self.use_shlex = self.config.get('use_shlex', True)
self.antiflood = self.config.get('antiflood', False)
self.case_sensitive = self.config.get('casesensitive',
self.case_sensitive)
guard = utils.maybedotted(config.get('guard', self.default_policy))
self.log.debug('Guard: %s', guard.__name__)
self.guard = guard(context)
self.error_format = utils.maybedotted(config.get('error_format',
"Invalid arguments.".format))
self.handles = defaultdict(Done)
self.tasks = defaultdict(Done)
self.aliases = {}
def split_command(self, data, use_shlex=None):
if not data:
return []
return shlex.split(data) if use_shlex else data.split(' ')
@irc3.event((r'(@(?P<tags>\S+) )?:(?P<mask>\S+) PRIVMSG (?P<target>\S+) '
r':{re_cmd}(?P<cmd>[\w-]+)(\s+(?P<data>\S.*)|(\s*$))'))
def on_command(self, cmd, mask=None, target=None, client=None, **kw):
if not self.case_sensitive:
cmd = cmd.lower()
cmd = self.aliases.get(cmd, cmd)
predicates, meth = self.get(cmd, (None, None))
if meth is not None:
if predicates.get('public', True) is False and target.is_channel:
self.context.privmsg(
mask.nick,
'You can only use the %r command in private.' % str(cmd))
else:
return self.do_command(predicates, meth, mask, target, **kw)
def do_command(self, predicates, meth, client, target, data=None, **kw):
nick = self.context.nick or '-'
to = client.nick if target == nick else target
doc = meth.__doc__ or ''
doc = [line.strip() for line in doc.strip().split('\n')]
doc = [nick + ' ' + line.strip('%%')
for line in doc if line.startswith('%%')]
doc = 'Usage:' + '\n ' + '\n '.join(doc)
if data:
if not isinstance(data, str): # pragma: no cover
encoding = self.context.encoding
data = data.encode(encoding)
try:
data = self.split_command(
data, use_shlex=predicates.get('use_shlex', self.use_shlex))
except ValueError as e:
if not predicates.get('quiet', False):
self.context.privmsg(to, 'Invalid arguments: {}.'.format(e))
return
docopt_args = dict(help=False)
if "options_first" in predicates:
docopt_args.update(options_first=predicates["options_first"])
cmd_name = predicates.get('name', meth.__name__)
try:
args = docopt.docopt(doc, [cmd_name] + data, **docopt_args)
except docopt.DocoptExit as exc:
if not predicates.get('quiet', False):
args = {'cmd': cmd_name, 'args': data,
'args_str': " ".join(data), 'exc': exc}
error_format = predicates.get('error_format',
self.error_format)
self.context.privmsg(to, error_format(**args))
else:
uid = (cmd_name, to)
use_client = isinstance(client, asyncio.Protocol)
if not self.tasks[uid].done():
self.context.notice(
client if use_client else client.nick,
"Another task is already running. "
"Please be patient and don't flood me", nowait=True)
elif not self.handles[uid].done() and self.antiflood:
self.context.notice(
client if use_client else client.nick,
"Please be patient and don't flood me", nowait=True)
else:
# get command result
res = self.guard(predicates, meth, client, target, args=args)
callback = functools.partial(self.command_callback, uid, to)
if res is not None:
coros = (
asyncio.iscoroutinefunction(meth),
asyncio.iscoroutinefunction(self.guard.__call__)
)
if any(coros):
task = asyncio.ensure_future(
res, loop=self.context.loop)
# use a callback if command is a coroutine
task.add_done_callback(callback)
self.tasks[uid] = task
return task
else:
# no callback needed
callback(res)
def command_callback(self, uid, to, msgs):
if isinstance(msgs, asyncio.Future): # pragma: no cover
msgs = msgs.result()
if msgs is not None:
def iterator(msgs):
for msg in msgs:
yield to, msg
if isinstance(msgs, str):
msgs = [msgs]
handle = self.context.call_many('privmsg', iterator(msgs))
if handle is not None:
self.handles[uid] = handle
@command
def help(self, mask, target, args):
"""Show help
%%help [<cmd>]
"""
return "not today stan"
if args['<cmd>']:
args = args['<cmd>']
# Strip out self.context.config.cmd from args so we can use
# both !help !foo and !help foo
if args.startswith(self.context.config.cmd):
args = args[len(self.context.config.cmd):]
args = self.aliases.get(args, args)
predicates, meth = self.get(args, (None, None))
if meth is not None:
doc = meth.__doc__ or ''
doc = [
line.strip() for line in doc.split('\n')
if line.strip()
]
buf = ''
for line in doc:
if '%%' not in line and buf is not None:
buf += line + ' '
else:
if buf is not None:
for b in utils.split_message(buf, 160):
yield b
buf = None
line = line.replace('%%', self.context.config.cmd)
yield line
aliases = predicates.get('aliases', None)
if aliases is not None:
yield 'Aliases: {0}'.format(','.join(sorted(aliases)))
else:
yield ('No such command. Try %shelp for an '
'overview of all commands.'
% self.context.config.cmd)
else:
cmds = sorted((k for (k, (p, m)) in self.items()
if p.get('show_in_help_list', True)))
cmds_str = ', '.join([self.cmd + k for k in cmds])
lines = utils.split_message(
'Available commands: %s ' % cmds_str, 160)
for line in lines:
yield line
url = self.config.get('url')
if url:
yield 'Full help is available at ' + url
def __repr__(self):
return '<Commands %s>' % sorted([self.cmd + k for k in self.keys()])
class Done:
def done(self):
return True
@command(permission='admin', show_in_help_list=False, public=False)
def ping(bot, mask, target, args):
"""ping/pong
%%ping
"""
bot.send('NOTICE %(nick)s :PONG %(nick)s!' % dict(nick=mask.nick))
@command(venusian_category='irc3.debug', show_in_help_list=False)
def quote(bot, mask, target, args):
"""send quote to the server
%%quote <args>...
"""
msg = ' '.join(args['<args>'])
bot.log.info('quote> %r', msg)
bot.send(msg)
@command(venusian_category='irc3.debug', show_in_help_list=False)
def reconnect(bot, mask, target, args):
"""force reconnect
%%reconnect
"""
plugin = bot.get_plugin(utils.maybedotted('irc3.plugins.core.Core'))
bot.loop.call_soon(plugin.reconnect)
@irc3.extend
def print_help_page(bot, file=sys.stdout):
"""print help page"""
def p(text):
print(text, file=file)
plugin = bot.get_plugin(Commands)
title = "Available Commands for {nick} at {host}".format(**bot.config)
p("=" * len(title))
p(title)
p("=" * len(title))
p('')
p('.. contents::')
p('')
modules = {}
for name, (predicates, callback) in plugin.items():
commands = modules.setdefault(callback.__module__, [])
commands.append((name, callback, predicates))
for module in sorted(modules):
p(module)
p('=' * len(module))
p('')
for name, callback, predicates in sorted(modules[module]):
p(name)
p('-' * len(name))
p('')
doc = callback.__doc__
doc = doc.replace('%%', bot.config.cmd)
for line in doc.split('\n'):
line = line.strip()
if line.startswith(bot.config.cmd):
line = ' ``{}``'.format(line)
p(line)
if 'permission' in predicates:
p('*Require {0[permission]} permission.*'.format(predicates))
if predicates.get('public', True) is False:
p('*Only available in private.*')
p('')

View File

@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
from irc3 import event
from irc3 import rfc
__doc__ = '''
==============================================
:mod:`irc3.plugins.core` Core plugin
==============================================
Core events
.. autoclass:: Core
:members:
..
>>> from irc3.testing import IrcBot
Usage::
>>> bot = IrcBot()
>>> bot.include('irc3.plugins.core')
'''
class Core:
def __init__(self, bot):
self.bot = bot
self.timeout = int(self.bot.config.get('timeout'))
self.max_lag = int(self.bot.config.get('max_lag'))
self.reconn_handle = None
self.ping_handle = None
self.nick_handle = None
self.before_connect_events = [
event(rfc.CONNECTED, self.connected),
event(r"^:\S+ 005 \S+ (?P<data>.+) :\S+.*",
self.set_config),
]
def connection_made(self, client=None):
# handle server config
config = self.bot.defaults['server_config'].copy()
self.bot.config['server_config'] = config
self.bot.detach_events(*self.before_connect_events)
self.bot.attach_events(insert=True, *self.before_connect_events)
# ping/ping
self.connection_made_at = self.bot.loop.time()
self.pong(event='CONNECT', data='')
def connected(self, **kwargs):
"""triger the server_ready event"""
self.bot.log.info('Server config: %r', self.bot.server_config)
# recompile when I'm sure of my nickname
self.bot.config['nick'] = kwargs['me']
self.bot.recompile()
# Let all plugins know that server can handle commands
self.bot.notify('server_ready')
# detach useless events
self.bot.detach_events(*self.before_connect_events)
def reconnect(self): # pragma: no cover
self.bot.log.info(
"We're waiting a ping for too long. Trying to reconnect...")
self.bot.loop.call_soon(
self.bot.protocol.connection_lost,
'No pong reply'
)
self.pong(event='RECONNECT', data='')
@event(rfc.PONG)
def pong(self, event='PONG', data='', **kw): # pragma: no cover
"""P0NG/PING"""
self.bot.log.debug('%s ping-pong (%s)', event, data)
if self.reconn_handle is not None:
self.reconn_handle.cancel()
self.reconn_handle = self.bot.loop.call_later(self.timeout,
self.reconnect)
if self.ping_handle is not None:
self.ping_handle.cancel()
self.ping_handle = self.bot.loop.call_later(
self.timeout - self.max_lag, self.bot.send,
'PING :%s' % int(self.bot.loop.time()))
@event(rfc.PING)
def ping(self, data):
"""PING reply"""
self.bot.send('PONG :' + data)
self.pong(event='PING', data=data)
@event(rfc.NEW_NICK)
def recompile(self, nick=None, new_nick=None, **kw):
"""recompile regexp on new nick"""
if self.bot.nick == nick.nick:
self.bot.config['nick'] = new_nick
self.bot.recompile()
@event(rfc.ERR_NICK)
def badnick(self, me=None, nick=None, **kw):
"""Use alt nick on nick error"""
if me == '*':
self.bot.set_nick(self.bot.nick + '_')
self.bot.log.debug('Trying to regain nickname in 30s...')
self.nick_handle = self.bot.loop.call_later(
30, self.bot.set_nick, self.bot.original_nick)
def set_config(self, data=None, **kwargs):
"""Store server config"""
config = self.bot.config['server_config']
for opt in data.split(' '):
if '=' in opt:
opt, value = opt.split('=', 1)
else:
value = True
if opt.isupper():
config[opt] = value

View File

@ -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

View File

@ -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',show_in_help_list=False)
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,524 @@
# -*- coding: utf-8 -*-
import asyncio
import configparser
import io
import logging
import os
import random
from datetime import datetime
from difflib import SequenceMatcher
from glob import glob
from time import time
import irc3
import numpy as np
import requests
import torch
import torch.nn.functional as F
from tqdm import tqdm
from transformers import GPT2Config, GPT2LMHeadModel, GPT2Tokenizer
###########################################################################################
global message_history
class MESSAGE_HISTORY():
#######################################################################################
maple_messages = []
user_messages = []
user_users = []
last_message = ''
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 similar(self,a,b):
return SequenceMatcher(None,a,b).ratio()
###########################################################################################
@irc3.plugin
class Plugin:
#######################################################################################
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()
message_history=self.bot.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
#######################################################################################
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.lower()=='nickserv': return
if target!=self.bot.config['nick'] and mask.nick==self.bot.nick: return
if mask.nick == self.bot.config["nick"]:
if data.startswith("["):
if not data.find("]")==-1:
if not data.find("^")==-1:
mask.nick=data.split('[')[1].split(']')[0]
else:
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 not data.lower().find('joke')==-1:
self.bot.joke(mask,target,'')
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
##############################################
self.maple_io.append({'user':mask.nick,'message':f'{data}','target':target})
self.main()
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)
#######################################################################################
@irc3.extend
async def indirect_maple(self, net=None, data=None, **kw):
##############################################
net_user=net[0]
net_src=net[1]
net_dest=net[2]
##############################################
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.maple_io.append({'user':net_user,'message':f'{data}','target':net_src})
self.main()
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 {net_user}, i'll be right back"
print('[ turned on flood protection ]')
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
netschanlist=dims.list_channels_bridged(netsrc=net_src)
bridgedbus=(BUS(netschanlist))
await bridgedbus.input(net_src,net_user,msg,True)
#######################################################################################
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 True
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 False
###################################################################################
# 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 False
###################################################################################
# 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 False
###################################################################################
# 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 False
###################################################################################
self.bot.history.push_maple_messages(maple_message)
print(f'maple > {maple_message}')
MAPLE_MESSAGE=maple_message.replace('lt 3','<3')
msg=f'{MAPLE_MESSAGE}'
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
netschanlist=dims.list_channels_bridged(netsrc=TARGET)
netschanlist.append(TARGET)
bridgedbus=(BUS(netschanlist))
async def truss(self,TARGET,USER,msg):
await bridgedbus.input(TARGET,USER,msg,True)
asyncio.run_coroutine_threadsafe( bridgedbus.input("👻"+TARGET,USER,msg,True), asyncio.get_event_loop() )
# asyncio.run_coroutine_threadsafe(self.truss(TARGET,USER,msg),self.bot.loop)
# self.bot.privmsg(TARGET,msg)
self.bot.history.loopcount=0
return True
#######################################################################################
def main(self):
FLAG_OK=False
while not FLAG_OK:
FLAG_OK=self.run_chat(self.model,self.tokenizer,self.config,mmi_model=self.mmi_model,mmi_tokenizer=self.mmi_tokenizer)
if self.bot.history.loopcount>25:
self.bot.history.loopcount=0
self.maple_io=[]
FLAG_OK=True
###########################################################################################

View File

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

View File

@ -0,0 +1,158 @@
# -*- coding: utf-8 -*- ############################################################### SOF
from irc3.plugins.command import command
from irc3.plugins.cron import cron
from irc3.plugins import core
import irc3
import os
from random import randint as rint
from random import shuffle
from datetime import datetime
###########################################################################################
class dr1p:
def __init__():
dr1p.designation=""
dr1p.enforcing=False
dr1p.purpose=""
dr1p.color=""
dr1p.token=""
dr1p.home=""
###########################################################################################
@irc3.plugin
class Plugin:
#######################################################################################
def __init__(self,bot):
self.bot=bot
token=""
dr1p.color=""
try:
dr1p.purpose=os.environ['HYDRA_PURPOSE']
dr1p.designation=os.environ['HYDRA_DESIGNATION']
dr1p.home=os.environ['HYDRA_HOME']
dr1p.enforcing=False
except:
dr1p.designation="dupe"
dr1p.enforcing=False
return
if dr1p.designation=="core": dr1p.color="\x0304"
for i in range(7): token+=hex(rint(0,255))[2:].zfill(2).upper()
token+=hex(int(datetime.now().timestamp()))[-4:].upper()
token=list(token)
shuffle(token)
dr1p.token=''.join(token)
#######################################################################################
def server_ready(self):
if not dr1p.designation=='core':
self.bot.privmsg("maple",f"[hydra:{dr1p.token}] - dupe - connected")
else:
self.bot.privmsg("maple",f"core - connected")
#######################################################################################
@irc3.event(irc3.rfc.ERR_NICK)
def on_errnick(self,srv=None,retcode=None,me=None,nick=None,data=None):
###################################################################################
if not dr1p.designation=='core': return
msg=f'err_nick - srv:{srv} - retcode:{retcode} - me:{me} - nick:{nick} - data:{data}'
self.bot.privmsg("maple",msg.lower())
#######################################################################################
@irc3.event(irc3.rfc.NEW_NICK)
def on_newnick(self,nick=None,new_nick=None):
###################################################################################
if not dr1p.designation=='core': return
if nick==self.bot.config['nick'] or new_nick==self.bot.config['nick']:
msg=f'new_nick - nick:{nick} - new_nick:{new_nick}'
self.bot.privmsg("maple",msg.lower())
#######################################################################################
@irc3.event(irc3.rfc.CTCP)
def on_ctcp(self,mask=None,event=None,target=None,ctcp=None):
###################################################################################
if not dr1p.designation=='core': return
msg=f'ctcpd - mask:{mask} - event:{event} - target:{target} - ctcp:{ctcp}'
self.bot.privmsg("maple",msg.lower())
#######################################################################################
@irc3.event(irc3.rfc.INVITE)
def on_invite(self,mask=None,channel=None):
###################################################################################
if not dr1p.designation=='core': return
msg=f'invited - mask:{mask} - channel:{channel}'
self.bot.privmsg("maple",msg.lower())
#######################################################################################
@irc3.event(irc3.rfc.KICK)
def on_kick(self,mask=None,event=None,channel=None,target=None,data=None):
###################################################################################
if not dr1p.designation=='core': return
msg=f'kicked - mask:{mask} - event:{event} - target:{target} - data:{data}'
self.bot.privmsg("maple",msg)
#######################################################################################
@irc3.event(irc3.rfc.PRIVMSG)
def on_privmsg(self,mask=None,event=None,target=None,data=None,**kw):
###################################################################################
# if dr1p.enforcing==False: return
if target!=self.bot.config['nick'] and mask.nick==self.bot.nick: return
if mask.nick==self.bot.nick and target==self.bot.config['nick'] and dr1p.designation=='core':
if data.endswith('dupe - connected'):
_token=data.split("[hydra:")[1].split("]")[0]
_nekot=_token[::-1]
msg=f'[TOKEN:{_token}] - [NEKOT:{_nekot}] - COLOR:{rint(16,87)}'
self.bot.privmsg(self.bot.config['nick'],msg)
if mask.nick==self.bot.nick and target==self.bot.config['nick'] and dr1p.designation=='dupe':
if not data.find('NEKOT')==-1:
_token=data.split(":")[1].split("]")[0]
if _token.lower()==dr1p.token.lower():
if not data.find("] - [NEKOT:")==-1:
_nekot=data.split("] - [NEKOT:")[1].split("]")[0]
if _token.lower()==_nekot[::-1].lower():
_color=int(data.split(" - COLOR:")[1].strip())
if not dr1p.color:
dr1p.color=f"\x03{str(_color)}"
if dr1p.designation=='core':
msg=f"{dr1p.color}[maple:{dr1p.token}] - "
else:
try:
msg=f"{dr1p.color}[hydra:{dr1p.token}] - "
except:
dr1p.color="\x0303"
msg=f"{dr1p.color}[hydra:{dr1p.token}] - "
if mask.nick!=self.bot.config['nick']:
if target!=dr1p.home: return
if target==dr1p.home: return
msg+=f'event:{event} - mask:{mask} - target:{target} - data:'
msg+=f'{data}'
if kw: msg+=f" - kw:{kw}"
self.bot.privmsg(dr1p.home,msg.lower())
#######################################################################################
@irc3.event(irc3.rfc.MY_PRIVMSG)
def on_my_privmsg(self,mask=None,event=None,target=None,data=None,**kw):
###################################################################################
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 mask.nick==self.bot.config['nick']:
###############################################################################
if kw['event']=='JOIN':
self.bot.privmsg("maple",f"joined {target}".lower())
if target!=dr1p.home:
if dr1p.enforcing:
reason=".[d]."
self.bot.part(target,reason)
self.bot.privmsg("maple",f"parted {target} - {reason}".lower())
if dr1p.designation=="core":
msg=f"[maple:{dr1p.token}] - core - maple online - purpose: {dr1p.purpose}"
self.bot.privmsg(dr1p.home,msg)
else:
msg=f"[hydra:{dr1p.token}] - dupe - hydra online - purpose: {dr1p.purpose}"
self.bot.privmsg(dr1p.home,msg)
if kw['event']=='PART':
if dr1p.designation=="core":
msg=f"[maple:{dr1p.token}] -"
else:
msg=f"[hydra:{dr1p.token}] -"
self.bot.privmsg("maple",msg+f"parted {target} - {data}")
if kw['event']=='QUIT':
if dr1p.designation=="core":
msg=f"[maple:{dr1p.token}] -"
else:
msg=f"[hydra:{dr1p.token}] -"
self.bot.privmsg("maple",msg+f"quit {target} - {data}")
####################################################################################### EOF

View File

@ -0,0 +1,227 @@
# -*- coding: utf-8 -*- ############################################################### SOF
GETTINGTAGGEDUP
import irc3,os,asyncio,re
from irc3.testing import ini2config
from irc3.plugins.command import command
if SERVICES:
from nio import AsyncClient, MatrixRoom, RoomMessageText
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
from plugins.tool_bus_plugin import BUS
from plugins.tool_colors_plugin import colorform as print
regex=re.compile("\x03(?:\d{1,2}(?:,\d{1,2})?)?",re.UNICODE)
################################################################ NET IRC - BOT CONFIG [2/4]
def config_ircbot():
config=ini2config("""
[bot]
nick = maple
username = g1mp
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 =
autojoins =
'#b0tsh0p'
'#tcpdirect'
'#PalletTown'
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):
print(f'<<< _____net_irc_plugin >>> [ ircbot started ]')
self.ircbot.loop=self.loop
self.ircbot.run(forever=True)
return self
###################################################################### NET IRC - MAIN [4/4]
async def _d_irc_msg(target,msg,) -> None:
ircbot=guds.memory('ircbot')
await ircbot.privmsg(target,msg,)
###########################################################################################
def d_irc_msg(target,msg,):
self=guds.memory('ircbot')
asyncio.run_coroutine_threadsafe(_d_irc_msg(target,msg),self.loop)
###########################################################################################
@irc3.plugin
class Plugin:
###########################################################################################
def __init__(self,bot):
self.bot=bot
print(f'<<< _____net_irc_plugin >>> [ plugin loaded ]')
globals()['guds'].memories.append([self.bot,'net_irc_plugin:start_ircbot.self'])
self.dbname="ircchat"
#######################################################################################
def connection_made(self):
print(f'<<< _____net_irc_plugin >>> [ event: ircbot connection made ]')
#######################################################################################
def server_ready(self):
print(f'<<< _____net_irc_plugin >>> [ event: ircbot server ready ]')
#######################################################################################
def connection_lost(self):
print(f'<<< _____net_irc_plugin >>> [ event: ircbot connection lost ]')
#######################################################################################
@irc3.event(irc3.rfc.PRIVMSG)
async def on_privmsg(self, mask=None, target=None, data=None, **kw):
msg=f"<<< _____net_irc_plugin >>> [ (i)({self.bot.config['host']})({target}) ] > {mask.nick}: {regex.sub('',data)}"
print(msg)
if not mask.nick==self.bot.config['nick']: # user
if mask.nick.startswith('maple[m]'): return
netschanlist=dims.list_channels_bridged(netsrc=target)
bridgedbus=(BUS(netschanlist))
await bridgedbus.input(target,mask.nick,data,True)
else: # bot
pass
#######################################################################################
def push(self,channel):
self.db=self.bot.db.getlist(self.dbname)
if not self.db: self.db=[]
class ircchat:
def __init__(self,channel):
self.channel=channel
ircc=ircchat(channel)
FLAG_FOUND=False
for entry in self.db:
if entry[0]==ircc.channel:
FLAG_FOUND=True
break
if not FLAG_FOUND:
self.db.append([ircc.channel])
self.bot.db.setlist(self.dbname,self.db)
print(f'<<< _____net_irc_plugin >>> [ new database entry ] > [{ircc.channel}]')
#######################################################################################
@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.bot.config['nick']: # this section is the user
msg=f'<<< _____net_irc_plugin >>> [ event: join_part_quit ] - nick: {mask.nick} - target: {target} - event: {kw["event"]} - data: {data}'
print(msg)
###################################################################################
else: # this section is the bot
###############################################################################
if kw['event']=='JOIN':
result=dims.isircchannel(channel=target,return_index=True)
guds.mask=mask
if not result:
msg=f'<<< _____net_irc_plugin >>> [ event: join_part_quit ] - nick: {mask.nick} - target: {target} - event: {kw["event"]} - data: {data}'
print(msg)
dims.__create__('irc',target)
print(f"<<< ___tool_dims_plugin >>> [ event: join ] - dims.__create__(irc,{target}) - active channel record created")
self.push(target)
###############################################################################
elif kw['event']=='PART':
###########################################################################
result=dims.isircchannel(channel=target,return_index=True)
###########################################################################
msg=f'<<< _____net_irc_plugin >>> [ event: join_part_quit ] - nick: {mask.nick} - target: {target} - event: {kw["event"]} - data: {data}'
print(msg)
dims.__delete__('irc',i)
print(f"<<< ___tool_dims_plugin >>> [ event: part ] - dims.__delete__(irc,{target}) - active channel record deleted")
###############################################################################
elif kw['event']=='QUIT':
###########################################################################
result=dims.isircchannel(target)
###########################################################################
msg=f'<<< _____net_irc_plugin >>> [ event: join_part_quit ] - nick: {mask.nick} - target: {target} - event: {kw["event"]} - data: {data}'
print(msg)
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.bot.config['nick']:
msg=f"{mask.nick}: target: {target} - event: topic - data: {data}"
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.bot.config['nick']:
msg=f"{mask.nick}: target: {target} - event: invite - data: {data}"
print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
#######################################################################################
@irc3.event(irc3.rfc.KICK)
def on_kick(self,mask=None,target=None,data=None,**kw):
try:
if not mask.nick==self.bot.config['nick']:
msg=f"{mask.nick}: target: {target} - event: kick - data: {data}"
print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
except:
pass
#######################################################################################
@irc3.event(irc3.rfc.MODE)
def on_mode(self,mask=None,target=None,data=None,**kw):
try:
if not mask.nick==self.bot.config['nick']:
msg=f"{mask.nick}: target: {target} - event: mode - data: {data}"
print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
except:
pass
#######################################################################################
@irc3.event(irc3.rfc.NEW_NICK)
def on_new_kick(self,mask=None,target=None,data=None,**kw):
try:
if not mask.nick==self.bot.config['nick']:
msg=f"{mask.nick}: target: {target} - event: new_nick - data: {data}"
print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
except:
pass
#######################################################################################
@irc3.event(irc3.rfc.CTCP)
def on_ctcp(self,mask=None,target=None,data=None,**kw):
try:
if not mask.nick==self.bot.config['nick']:
msg=f"{mask.nick}: target: {target} - event: ctcp - data: {data}"
print("<<< _____net_irc_plugin >>> [ "+msg+" ]")
except:
pass
####################################################################################### EOF

View File

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

View File

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

View File

@ -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=False)
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=False)
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=False)
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=False)
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=False)
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

View File

@ -0,0 +1,474 @@
# -*- coding: utf-8 -*-
import os
import re
from difflib import SequenceMatcher
import urllib.parse
import irc3
import openai
import requests
from irc3.plugins.command import command
from random import randint as rint
from random import choices
dir_path = os.path.dirname(os.path.realpath(__file__))
from glob import glob
###########################################################################################
OPENAI_KEY = os.environ['OPENAI_KEY']
###########################################################################################
DREY="\x02\x0315"
GREY="\x02\x0314"
DRED="\x02\x0302"
LRED="\x02\x0312"
###########################################################################################
class OPENAI_MESSAGE_HISTORY():
#######################################################################################
openai_messages = []
user_messages = []
user_users = []
#######################################################################################
def __init__(self):
self.processing=0
#######################################################################################
def push_openai_messages(self,data):
self.openai_messages = self.openai_messages[-1:] + self.openai_messages[:-1]
self.openai_messages[0] = data
#######################################################################################
def push_user_messages(self,user,data):
self.user_users.append(user)
self.user_messages.append(data)
#######################################################################################
def similar(self,a,b):
return SequenceMatcher(None,a,b).ratio()
###########################################################################################
###########################################################################################
@irc3.plugin
class Plugin:
#######################################################################################
#######################################################################################
def __init__(self, bot):
self.bot = bot
self.bot.openai_history=OPENAI_MESSAGE_HISTORY()
#############################################
for _ in range(5):
self.bot.openai_history.openai_messages.append("")
#############################################
self.openai_io=[]
self.start_chat_log=""
self.lastterm=""
self.lastresponse=""
self.default_model="text-davinci-002"
self.temperature=1.1
self.max_tokens=2000
self.top_p=1.0
self.frequency_penalty=0.0
self.presence_penalty=0.0
self.flipcolor=False
self.default_load()
#######################################################################################
#######################################################################################
@command(permission='view')
def ai(self, mask, target, args):
"""OpenAi Question A Term
%%ai <term>...
"""
term=' '.join(args['<term>'])
if not term[-1] == ".": term+="."
openai.api_key = OPENAPI_KEY
######################################################################################
print(f"<<< openai: processing {target} {mask.nick.lower()} message: {term.lower()}")
######################################################################################
MESSAGE_OK=True
TRAP_OK=True
LOOP_COUNT_LIMIT=5
LOOP_COUNT=0
while MESSAGE_OK:
LOOP_COUNT+=1
print(f'<<< loop: {LOOP_COUNT} >>>')
prompt_text=f'{term}'
self.lastterm=f'{term}'
response=openai.Completion.create(
model=self.default_model,
prompt=prompt_text,
temperature=self.temperature,
max_tokens=self.max_tokens,
top_p=self.top_p,
frequency_penalty=self.frequency_penalty,
presence_penalty=self.presence_penalty
)
self.lastresponse=response
##################################################################################
openai_message=response.choices[0].text
USER=mask.nick
MESSAGE=term
# ################################################################################### REPROCESSOR SOF
# # SIMILARITY - QUERY SENT VS QUERY ANSWER
# if MESSAGE_OK:
# if self.bot.openai_history.similar(openai_message.lower(),term.lower())>0.4:
# self.openai_io.append({'user':USER,'message':MESSAGE,'target':target})
# print(f'openai - logic ! rejected // openai similarity - response too similar to query')
# TRAP_OK=False
# ################################################################################### REPROCESSOR SOF
# # SIMILARITY - QUERY ANSWER VS PERSONALITY PROFILE DATABASE
# if MESSAGE_OK:
# if self.bot.openai_history.similar(openai_message.lower().strip(),' '.join(self.start_chat_log.strip().splitlines())[:len(openai_message.strip())])>0.4:
# self.openai_io.append({'user':USER,'message':MESSAGE,'target':target})
# print(f'openai - logic ! rejected // openai similarity - response too similar to persoanlity profile database')
# TRAP_OK=False
# ###################################################################################
# # SIMILARITY - HISTORY
# if MESSAGE_OK:
# for i in range(len(self.bot.openai_history.openai_messages)):
# if self.bot.openai_history.similar(openai_message,str(self.bot.openai_history.openai_messages[i]))>0.8:
# self.openai_io.append({'user':USER,'message':MESSAGE,'target':target})
# print(f'openai - logic ! rejected // openai similarity - repeat of previous response')
# TRAP_OK=False
# ###################################################################################
# # MOCK / DUPE
# if MESSAGE_OK:
# if self.bot.openai_history.similar(openai_message,MESSAGE)>0.8:
# self.openai_io.append({'user':USER,'message':MESSAGE,'target':target})
# print(f'openai - logic ! rejected // human mock - openai response same as human')
# TRAP_OK=False
# ###################################################################################
# # GPT LOOP GLITCH
# if MESSAGE_OK:
# n=len(openai_message.split())
# i=len(set(openai_message.split()))
# if i<int(n/2):
# self.openai_io.append({'user':USER,'message':MESSAGE,'target':target})
# print(f'openai - logic ! rejected // gpt loop glitch - reiterating same thing in multiples')
# TRAP_OK=False
# ###################################################################################
# # LIMITED RESPONSE
# if MESSAGE_OK:
# n=len(openai_message.split())
# if i<3:
# self.openai_io.append({'user':USER,'message':MESSAGE,'target':target})
# print(f'openai - logic ! rejected // limited response - skip an unfinished token chain')
# TRAP_OK=False
###################################################################################
if MESSAGE_OK and TRAP_OK:
self.bot.openai_history.push_openai_messages(openai_message)
_msg = re.findall(r'.{1,400}(?:\s+|$)', openai_message)
#if len(_msg) > 1:
# if len(_msg[0]) < len(_msg[1])//2:
# print(f'openai - discovered and removed a preface glitch: {_msg[0].strip()}')
# _msg.reverse()
# _msg.pop()
# _msg.reverse()
COLOR=""
self.flipcolor = not self.flipcolor
if self.flipcolor:
COLOR=DREY
else:
COLOR=GREY
for i,_ in enumerate(_msg):
if i==0:
self.bot.privmsg(target, f"\x02\x0302{USER:}\x0F\x02\x0309 ▶ {COLOR}{_.strip()}\x0F")
else:
self.bot.privmsg(target, f"{COLOR}{_.strip()}\x0F")
MESSAGE_OK=False
print('<<< openai finished >>>')
###################################################################################
if LOOP_COUNT > LOOP_COUNT_LIMIT:
print(f"<<< openai failed: bouncing to mapleai >>>")
self.bot.history.bounce={'user':USER,'message':term,'target':target}
#MESSAGE=f"{GREY}<<< {DRED}i got nothing to say {GREY}>>>"
#self.bot.privmsg(target, f"{USER}: {MESSAGE}")
break
################################################################################### REPROCESSOR EOF
#######################################################################################
def random_float(self,n):
i=float(rint(0,n))
i/=10
return i
#######################################################################################
def print_response_properties(self,target):
self.bot.privmsg(target, f"{DRED} model{GREY}: {LRED}{self.default_model}")
self.bot.privmsg(target, f"{DRED} temperature{GREY}: {LRED}{self.temperature}")
self.bot.privmsg(target, f"{DRED} max_tokens{GREY}: {LRED}{self.max_tokens}")
self.bot.privmsg(target, f"{DRED} top_p{GREY}: {LRED}{self.top_p}")
self.bot.privmsg(target, f"{DRED}frequency_penalty{GREY}: {LRED}{self.frequency_penalty}")
self.bot.privmsg(target, f"{DRED} presence_penalty{GREY}: {LRED}{self.presence_penalty}")
#######################################################################################
@command(permission='admin')
def airand(self, mask, target, args):
"""OpenAi Randomize Response Properties
%%airand
"""
MODELS=["text-davinci-002","text-curie-001","text-babbage-001","text-ada-001"]
MODEL=choices(MODELS)[0]
TOKEN_CEILING=1000
if MODEL==MODELS[0]:
TOKEN_CEILING=2000
self.default_model=MODEL
self.temperature=self.random_float(20)
self.max_tokens=rint(1,TOKEN_CEILING)
self.top_p=self.random_float(10)
self.frequency_penalty=self.random_float(10000)
self.presence_penalty=self.random_float(20)
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}randomizing personality properties {GREY}>>>"))
self.print_response_properties(target)
#######################################################################################
def default_load(self):
FILE='%s/../personalities/default.db' % dir_path
f=open(FILE,'r')
self.start_chat_log=f.read()
if self.start_chat_log.find('\n')==0:
self.start_chat_log=self.start_chat_log[1:]
f.close()
#######################################################################################
@command(permission='admin')
def airead(self, mask, target, args):
"""OpenAi Read Current Personality
%%airead
"""
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}reading current personality profile {GREY}>>>"))
if self.start_chat_log==None:
self.bot.privmsg(target,"<NULL>")
else:
for _ in self.start_chat_log.splitlines():
msg = re.findall(r'.{1,400}(?:\s+|$)', _)
for __ in msg:
self.bot.privmsg(target, f'{__.strip()}')
#######################################################################################
@command(permission='admin')
def aishow(self, mask, target, args):
"""OpenAi Show Current Personality Properties and Values.
%%aishow
"""
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}showing current personality properties {GREY}>>>"))
self.print_response_properties(target)
#######################################################################################
@command(permission='admin')
def aiterm(self, mask, target, args):
"""OpenAi Show Last Term.
%%aiterm
"""
self.bot.privmsg(target, self.bot.emo(f'{GREY}<<< {DRED}showing last term query {GREY}>>>'))
for _ in self.lastterm.splitlines():
msg = re.findall(r'.{1,400}(?:\s+|$)', _)
for __ in msg:
self.bot.privmsg(target, f'{__.strip()}')
#######################################################################################
@command(permission='admin')
def airesponse(self, mask, target, args):
"""OpenAi Show Last Server Response.
%%airesponse
"""
self.bot.privmsg(target, self.bot.emo(f'{GREY}<<< {DRED}showing last openai server response {GREY}>>>'))
msg=[]
FINISH_REASON=self.lastresponse['choices'][0]['finish_reason']
INDEX=self.lastresponse['choices'][0]['index']
LOGPROBS=self.lastresponse['choices'][0]['logprobs']
TEXT=self.lastresponse['choices'][0]['text'].strip()
MODEL=self.lastresponse['model']
OBJECT=MODEL=self.lastresponse['object']
COMPLETION_TOKENS=MODEL=self.lastresponse['usage']['completion_tokens']
PROMPT_TOKENS=MODEL=self.lastresponse['usage']['prompt_tokens']
TOTAL_TOKENS=MODEL=self.lastresponse['usage']['total_tokens']
_TEXT=re.findall(r'.{1,400}(?:\s+|$)', TEXT)
#msg.append(f'{GREY}[{DRED}usage{GREY}]')
msg.append(f'{DRED}completion_tokens{GREY}: {LRED}{COMPLETION_TOKENS}')
msg.append(f' {DRED}prompt_tokens{GREY}: {LRED}{PROMPT_TOKENS}')
msg.append(f' {DRED}total_tokens{GREY}: {LRED}{TOTAL_TOKENS}')
#msg.append(f'{GREY}[{DRED}choices{GREY}]')
msg.append(f' {DRED}index{GREY}: {LRED}{INDEX}')
msg.append(f' {DRED}logprobs{GREY}: {LRED}{LOGPROBS}')
if len(_TEXT) > 1:
if len(_TEXT[0]) < len(_TEXT[1])//2:
print(f'discovered and removed a preface glitch: {_TEXT[0].strip()}')
_TEXT.reverse()
_TEXT.pop()
_TEXT.reverse()
for i,_ in enumerate(_TEXT):
if i == 0:
msg.append(f' {DRED}text{GREY}: {LRED}{_.strip()}')
else:
msg.append(f'{LRED}{_.strip()}')
for _ in msg:
self.bot.privmsg(target, _)
#######################################################################################
@command(permission='admin')
def ailist(self, mask, target, args):
"""OpenAi List Personalities
%%ailist
"""
PATH='%s/../personalities' % dir_path
FILES=glob(f'{PATH}/*.db')
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}listing personality databases {GREY}>>>"))
for i,_ in enumerate(FILES):
FILE=_.split('/')[-1].replace('.db','')
self.bot.privmsg(target, f'{DRED}{i}{GREY}: {LRED}{FILE}')
#######################################################################################
@command(permission='admin')
def aiload(self, mask, target, args):
"""OpenAi Load Personalities
%%aiload <msg>...
"""
msg = ''.join(args['<msg>'])
try:
i=int(msg)
except:
self.bot.privmsg(target, self.bot.emo(f'{GREY}<<< {DRED}error{GREY}: {LRED}not an integer, use only numbers of the personality databases {GREY}>>>'))
return
PATH='%s/../personalities' % dir_path
FILES=glob(f'{PATH}/*.db')
try:
f=open(FILES[i],'r')
buffer=f.read().splitlines()
f.close()
self.start_chat_log='\n'.join(buffer)
if self.start_chat_log.find('\n')==0:
self.start_chat_log=self.start_chat_log[1:]
FILE=FILES[i].split('/')[-1].replace('.db', '')
self.bot.privmsg(target, self.bot.emo(f'{GREY}<<< {DRED}loaded {FILE} personality database {GREY}>>>'))
except:
self.bot.privmsg(target, self.bot.emo(f'{GREY}<<< {DRED}error{GREY}: {LRED}could not load this personality database, maybe invalid index number {GREY}>>>'))
return
#######################################################################################
@command(permission='admin')
def aiwrite(self, mask, target, args):
"""OpenAi List Personalities
%%aiwrite <msg>...
"""
msg = ''.join(args['<msg>'])
if self.start_chat_log.find('None\n')==0:
self.start_chat_log=self.start_chat_log.replace('None\n','')
msg=msg.replace('.','').replace('/','')
PATH='%s/../personalities' % dir_path
FILE=f'{PATH}/{msg}.db'
if os.path.exists(FILE):
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}personality database already exists, choose a different filename {GREY}>>>"))
return
f=open(FILE, "a")
f.write(f'{self.start_chat_log}\n')
f.close()
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}created {msg} personality database {GREY}>>>"))
#######################################################################################
@command(permission='admin')
def aitrain(self, mask, target, args):
"""OpenAi Question A Term
%%aitrain <term>...
"""
term = ' '.join(args['<term>'])
if term[-1]==',': term=term[::-1].replace(',','')[::-1]
if not term[-1] == ".": term+="."
FILE='%s/../personalities/trained.db' % dir_path
f=open(FILE, "a")
f.write(f'{term}\n')
f.close()
self.start_chat_log=f'{self.start_chat_log}\n{term}'
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}trained {GREY}>>>"))
#######################################################################################
@command(permission='admin')
def aidefault(self, mask, target, args):
"""OpenAi Return to Defaults
%%aidefault
"""
self.default_model="text-davinci-002"
self.temperature=1.1
self.max_tokens=2000
self.top_p=1.0
self.frequency_penalty=0.0
self.presence_penalty=0.0
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}setting personality and properties to defaults {GREY}>>>"))
self.print_response_properties(target)
#######################################################################################
@command(permission='admin')
def aiset(self, mask, target, args):
"""OpenAi Set Response Properties. Properties are default_model, temperature, max_tokens, top_p, frequency_penalty, presence_penalty. Example Usage: ?aiset top_p 1.0
%%aiset <msg>...
"""
msg= ' '.join(args['<msg>'])
PROPERTIES=['model','temperature','max_tokens','top_p','frequency_penalty','presence_penalty']
MODELS=["text-davinci-002","text-curie-001","text-babbage-001","text-ada-001"]
prop=""
val=""
try:
prop=msg.split()[0].lower()
val=msg.split()[1].lower()
except:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}not enough parameters {GREY}- {DRED}property choices{GREY}: {LRED}{PROPERTIES} {GREY}- {DRED}model choices{GREY}: {LRED}{MODELS} {GREY}- {DRED}usage examples{GREY}: {LRED}?aiset model text-davinci-002, ?aiset max_tokens 2000, ?aiset model text-davinci-002, ?aiset temperature 0.7, ?aiset top_p 1.0, ?aiset frequency_penalty 0.0, ?aiset presence_penalty 0.0 {GREY}>>>"))
return
if prop in PROPERTIES:
if prop == "model":
try:
if val in MODELS:
self.default_model=val
if str(val)==MODELS[0]:
self.max_tokens = 2000
else:
self.max_tokens = 1000
else:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}property model value should be a string {GREY}- {DRED}choice of models{GREY}: {LRED}{MODELS} {GREY}- {DRED}example{GREY}: {LRED}?aiset model text-davinci-002 {GREY}>>>"))
except:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}property model value should be a string {GREY}- {DRED}choice of models{GREY}: {LRED}{MODELS} {GREY}- {DRED}example{GREY}: {LRED}?aiset model text-davinci-002 {GREY}>>>"))
return
elif prop == "temperature":
try:
if float(val) <= 2 and float(val) >= 0:
self.temperature=float(val)
except:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}property temperature value should be a float {GREY}- {DRED}example{GREY}: {LRED}?aiset temperature 0.7 {GREY}>>>"))
return
elif prop == "max_tokens":
try:
if int(val) <= 2000 and int(val) >= 100:
self.max_tokens=int(val)
except:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}property max_tokens value should be an integer not greater than 2000 {GREY}- {DRED}example{GREY}: {LRED}?aiset max_tokens 2000 {GREY}>>>"))
return
elif prop == "top_p":
try:
if float(val) <= 1.0 and float(val) >= 0.0:
self.top_p=float(val)
else:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: property model should be a float no greater than 1.0 {GREY}- {DRED}example{GREY}: {LRED}?aiset top_p 0.7 {GREY}>>>"))
return
except:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: property model should be a float no greater than 1.0 {GREY}- {DRED}example{GREY}: {LRED}?aiset top_p 0.7 {GREY}>>>"))
return
elif prop == "frequency_penalty":
try:
if float(val):
self.frequency_penalty=float(val)
except:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}property frequency_penalty should be a float {GREY}- {DRED}example{GREY}: {LRED}?aiset frequency_penalty 0.0 {GREY}>>>"))
return
elif prop == "presence_penalty":
try:
if float(val) <= 2.0 and float(val) >= 0.0:
self.presence_penalty=float(val)
else:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}property presence_penalty should be a float no greater than 2.0 {GREY}- {DRED}example{GREY}: {LRED}?aiset presence_penalty 0.0 {GREY}>>>"))
return
except:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}property presence_penalty should be a float no greater than 2.0 {GREY}- {DRED}example{GREY}: {LRED}?aiset presence_penalty 0.0 {GREY}>>>"))
return
else:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}no properties were set, they remain the same {GREY}>>>"))
self.print_response_properties(target)
return
else:
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}used an invalid property identifier {GREY}- {DRED}property identifiers are {LRED}{PROPERTIES} {GREY}>>>"))
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}error{GREY}: {LRED}no properties were set, they remain the same {GREY}>>>"))
self.print_response_properties(target)
return
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}{prop} property set to the value {val} {GREY}>>>"))
self.print_response_properties(target)
#######################################################################################
@command(permission='admin')
def aiclear(self, mask, target, args):
"""OpenAi Clear Term
%%aiclear
"""
FILE='%s/../personalities/trained.db' % dir_path
f=open(FILE, "w")
f.write("")
f.close()
self.start_chat_log = ""
self.bot.privmsg(target, self.bot.emo(f"{GREY}<<< {DRED}cleared {GREY}>>>"))
#######################################################################################
###########################################################################################
###########################################################################################

View File

@ -0,0 +1,87 @@
# -*- 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)
if not message:
self.quotes(mask,target,{'<nick>': user})
return
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',show_in_help_list=False)
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

View File

@ -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

View File

@ -0,0 +1,108 @@
# -*- 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)
@irc3.extend
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

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*- ########################################################## SOF
import irc3,os,base64
from plugins.tool_colors_plugin import colorform as print
######################################################################################
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
from irc3.plugins.command import command
import irc3
from datetime import datetime
import timeago
from pytz import common_timezones
from pytz import timezone
import re
@irc3.plugin
class Plugin:
def __init__(self, bot):
self.bot = bot
@command(permission='view')
def timezonediff(self, mask, target, args):
"""timezonediff - '?timezonediff yourzone theirzone calendar_date theirzone_event_time message' or '?timezonediff yourzone theirzone theirzone_event_time message'
%%timezonediff <noise>...
"""
noise=' '.join(args['<noise>'])
if noise.split()[0].lower()=="list":
msg=', '.join(common_timezones)
msg=re.findall(r'.{1,400}(?:\s+|$)',msg)
for _ in msg: self.bot.privmsg(target,f'{_.strip()}')
return
try:
zone1=timezone(noise.split()[0])
except:
zone1=noise.split()[0]
msg=f"error: unknown timezone {zone1} in your request of {noise}, to get a list of the available timezones use this command: ?timezonediff list"
self.bot.privmsg(target,self.bot.emo(msg))
return
try:
zone2=timezone(noise.split()[1])
except:
try:
zone2=noise.split()[1]
except:
zone2=None
msg=f"error: unknown timezone {zone2} in your request of {noise}, to get a list of the available timezones use this command: ?timezonediff list"
self.bot.privmsg(target,self.bot.emo(msg))
return
FLAG_DATE=False
try:
date=noise.split()[2].replace("/","")
assert int(date)
if len(date)==6 or len(date)==8:
month=date[0:2]
day=date[2:4]
year=date[4:]
try:
assert int(month) >= 1 and int(month) <= 12
except:
msg=f"error: {month} month is not between 1 and 12. there are 12 months in a year"
self.bot.privmsg(target,self.bot.emo(msg))
return
try:
assert int(day) >= 1 and int(day) <= 31
except:
msg=f"error: {day} day is not between 1 and 31. there are at max 31 days in a month"
self.bot.privmsg(target,self.bot.emo(msg))
return
try:
assert int(year) #future assert str(int(year))[-2:] >= str(datetime.now().year)[-2:]
if len(year)==2: year=f"20{year}"
except:
msg=f"error: {year} year is not a year between 0 and {datetime.now().year}+"
self.bot.privmsg(target,self.bot.emo(msg))
return
FLAG_DATE=True
except:
pass #with no date set we presume it is implied as an event today from now into the time of then
if not FLAG_DATE:
try:
stime=noise.split()[2]
dtn=datetime.now()
dt=datetime.now(zone2)
year=dt.year
month=dt.month
day=dt.day
except:
msg=f"error: no date of or time of event issued in your request {noise}"
self.bot.privmsg(target,self.bot.emo(msg))
return
else:
try:
stime=noise.split()[3]
except:
msg=f"error: time of event issued in your request {noise}"
self.bot.privmsg(target,self.bot.emo(msg))
return
if not FLAG_DATE:
try:
smessage=' '.join(noise.split()[3:])
if not smessage: assert int('cat/0')
except:
msg=f"error: no message with your event {noise}. usage: ?timezonediff yourzone theirzone theirzone_event_time message"
self.bot.privmsg(target,self.bot.emo(msg))
return
else:
try:
smessage=' '.join(noise.split()[4:])
if not smessage: assert int('cat/0')
except:
msg=f"error: no message with your event {noise}. usage: ?timezonediff yourzone theirzone calendar_date theirzone_event_time message"
self.bot.privmsg(target,self.bot.emo(msg))
return
try:
assert int(stime.replace(":","")[0:4]) >= 0 and int(stime.replace(":","")[0:4]) <= 2400
stime=stime.replace(":","")[0:4]
hour=str(stime)[0:2]
minute=str(stime)[2:]
except:
msg="error: time of event is not military time. example 1800 or 18:00 being 6pm"
self.bot.privmsg(target,self.bot.emo(msg))
return
dtf=datetime(int(year),int(month),int(day),int(hour),int(minute))
dtn=datetime.now()
# zone1=timezone('us/central')
# zone2=timezone('cet')
z1=zone1.localize(dtn)
z2=zone2.localize(dtn)
delta=z1-z2
z3=zone2.localize(dtf)
tsz2a=z2.timestamp()
tsz2b=z3.timestamp()
timedistance=timeago.format(tsz2b-delta.seconds,tsz2a)
if str(timedistance).startswith('in'):
msg = f'i will remind in you {timedistance} in your local timezone of {zone1} about {smessage}'
self.bot.privmsg(target, msg)
message_list = self.bot.db.getlist("remind_%s" % mask.nick.lower())
new_message = {"from": self.bot.nick.lower(), "target": mask.nick.lower(), "message": msg, "time": datetime.now().isoformat(), "etime": datetime.now().timestamp(), "etrigger": tsz2b-delta.seconds }
if not message_list:
message_list = self.bot.db.setlist("remind_%s" % mask.nick.lower(), [new_message])
else:
message_list.append(new_message)
self.bot.db.setlist("remind_%s" % mask.nick.lower(), message_list)
irc_message = "TCPDIRECT/REMIND: {} < {} > reminding < {} > {}".format(new_message.get("time"),new_message.get("from"),mask.nick,new_message.get("message"))
self.bot.privmsg(target, self.bot.emo(irc_message))
else:
msg = f'sorry, this time of event is in the past now {timedistance}'
self.bot.privmsg(target, self.bot.emo(msg))

View File

@ -0,0 +1,199 @@
# -*- coding: utf-8 -*- ############################################################### SOF
global bus, dims, matrixbot, ircbot
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
from plugins.tool_colors_plugin import colorform as print
from random import randint as rint
import re
regex=re.compile("\x03(?:\d{1,2}(?:,\d{1,2})?)?",re.UNICODE)
###########################################################################################
class BUS:
#######################################################################################
results=[]
#######################################################################################
def __init__(self,bridged_network_roomchans=[]):
self.bridged_network_roomchans=bridged_network_roomchans
self.matrixbot=guds.memory('matrixbot')
self.ircbot=guds.memory('ircbot')
#######################################################################################
def sortnet(self,s):
if s.startswith('!'):
return '(m)'
elif s.startswith('#'):
return '(i)'
#######################################################################################
async def output(self,netschanroom_src,data):
from plugins.net_irc_plugin import d_irc_msg
from plugins.net_matrix_plugin import d_matrix_msg
###################################################################################
chanroom=netschanroom_src[0]; usernick=netschanroom_src[1]
if type(self.bridged_network_roomchans)==list:
targets=self.bridged_network_roomchans
for target in targets:
if type(data)==list:
if target.startswith('!'):
for _data in data:
d_matrix_msg(target,regex.sub("",_data))
msg=f"<<< ____tool_bus_plugin >>> [ BUS.output ] - {self.sortnet(chanroom)}({chanroom})({usernick})->{self.sortnet(target)}({target}) > {regex.sub('',_data)}"
elif target.startswith('#'):
for _data in data:
d_irc_msg(target,_data)
msg=f'<<< ____tool_bus_plugin >>> [ BUS.output ] - {self.sortnet(chanroom)}({chanroom})({usernick})->{self.sortnet(target)}({target}) > {_data}'
###########################################################################
else:
if target.startswith('!'):
d_matrix_msg(target,regex.sub('',data))
msg=f"<<< ____tool_bus_plugin >>> [ BUS.output ] - {self.sortnet(chanroom)}({chanroom})({usernick})->{self.sortnet(target)}({target}) > {regex.sub('',data)}"
elif target.startswith('#'):
d_irc_msg(target,data)
msg=f'<<< ____tool_bus_plugin >>> [ BUS.output ] - {self.sortnet(chanroom)}({chanroom})({usernick})->{self.sortnet(target)}({target}) > {data}'
print(msg)
else:
target=self.bridged_network_roomchans
if type(data)==list:
if target.startswith('!'):
for _data in data:
d_matrix_msg(target,regex.sub('',_data))
msg=f"<<< ____tool_bus_plugin >>> [ BUS.output ] - {self.sortnet(chanroom)}({chanroom})({usernick})->{self.sortnet(target)}({target}) > {regex.sub('',_data)}"
elif target.startswith('#'):
for msg in data:
d_irc_msg(target,_data)
msg=f'<<< ____tool_bus_plugin >>> [ BUS.output ] - {self.sortnet(chanroom)}({chanroom})({usernick})->{self.sortnet(target)}({target}) > {_data}'
###############################################################################
else:
if target.startswith('!'):
d_matrix_msg(target,regex.sub('',data))
msg=f"<<< ____tool_bus_plugin >>> [ BUS.output ] - {self.sortnet(chanroom)}({chanroom})({usernick})->{self.sortnet(target)}({target}) > {regex.sub('',data)}"
elif target.startswith('#'):
d_irc_msg(target,data)
msg=f'<<< ____tool_bus_plugin >>> [ BUS.output ] - {self.sortnet(chanroom)}({chanroom})({usernick})->{self.sortnet(target)}({target}) > {data}'
print(msg)
#######################################################################################
async def input(self,network_chanroom_user_src,user_src,data,verbose_bridge):
prefix_src=""; maple_dispatch=False
if network_chanroom_user_src.startswith('👻'):
network_chanroom_user_src=network_chanroom_user_src[1:]
maple_dispatch=True
if network_chanroom_user_src.startswith('!'): prefix_src="!m"
elif network_chanroom_user_src.startswith('#'): prefix_src="#i"
elif network_chanroom_user_src.startswith('$'): prefix_src="$t"
elif network_chanroom_user_src.startswith('^'): prefix_src="^d"
netsrc=network_chanroom_user_src
if prefix_src=="": return
sabotage=""
isabotage=rint(0,75)
if isabotage==9:sabotage=".smokin "
if isabotage==19:sabotage="!ai "
if isabotage==21:sabotage=".drinkin "
if isabotage==45:sabotage=".sober "
if isabotage==69:sabotage="^c "
if isabotage==73:sabotage="🖕 "
for network_chanroom_dest in self.bridged_network_roomchans:
from plugins.net_irc_plugin import d_irc_msg
from plugins.net_matrix_plugin import d_matrix_msg
from plugins.net_discord_plugin import d_discord_msg
from plugins.net_telegram_plugin import d_telegram_msg
#################################################################### ROUTER
if type(data)==list:
for _data in data:
########################################################### TELEGRAM
if network_chanroom_dest.startswith('$'):
if verbose_bridge:
_data=regex.sub("",_data)
if maple_dispatch:
mapled="👻 "
else:
mapled=""
msg=f'{sabotage}{mapled}{user_src}{prefix_src}: {data.strip()}'
else:
msg=regex.sub("",data)
d_telegram_msg(network_chanroom_dest,msg)
########################################################### DISCORD
if network_chanroom_dest.startswith('^'):
if verbose_bridge:
_data=regex.sub("",_data)
if maple_dispatch:
mapled="👻 "
else:
mapled=""
msg=f'{sabotage}{mapled}{user_src}{prefix_src}: {data.strip()}'
else:
msg=regex.sub("",data)
d_discord_msg(network_chanroom_dest,msg)
############################################################ MATRIX
if network_chanroom_dest.startswith('!'):
if verbose_bridge:
_data=regex.sub("",_data)
if maple_dispatch:
mapled="👻 "
else:
mapled=""
msg=f'{sabotage}{mapled}{user_src}{prefix_src}: {data.strip()}'
else:
msg=regex.sub("",data)
d_matrix_msg(network_chanroom_dest,msg)
############################################################### IRC
elif network_chanroom_dest.startswith('#'):
if verbose_bridge:
_data=regex.sub("",_data)
if maple_dispatch:
mapled="👻 "
else:
mapled=""
msg=f'{sabotage}{mapled}{user_src}{prefix_src}: {data.strip()}'
else:
msg=f'{_data.strip()}'
d_irc_msg(network_chanroom_dest,msg)
############################################################# LOCAL
else:
############################################################### TELEGRAM
if network_chanroom_dest.startswith('$'):
if verbose_bridge:
data=regex.sub("",data)
if maple_dispatch:
mapled="👻 "
else:
mapled=""
msg=f'{sabotage}{mapled}{user_src}{prefix_src}: {data.strip()}'
else:
msg=regex.sub("",data)
d_telegram_msg(network_chanroom_dest,msg)
############################################################### DISCORD
if network_chanroom_dest.startswith('^'):
if verbose_bridge:
data=regex.sub("",data)
if maple_dispatch:
mapled="👻 "
else:
mapled=""
msg=f'{sabotage}{mapled}{user_src}{prefix_src}: {data.strip()}'
else:
msg=regex.sub("",data)
d_discord_msg(network_chanroom_dest,msg)
################################################################ MATRIX
if network_chanroom_dest.startswith('!'):
if verbose_bridge:
data=regex.sub("",data)
if maple_dispatch:
mapled="👻 "
else:
mapled=""
msg=f'{sabotage}{mapled}{user_src}{prefix_src}: {data.strip()}'
else:
msg=regex.sub("",data)
d_matrix_msg(network_chanroom_dest,msg)
################################################################### IRC
elif network_chanroom_dest.startswith('#'):
if verbose_bridge:
data=regex.sub("",data)
if maple_dispatch:
mapled="👻 "
else:
mapled=""
msg=f'{sabotage}{mapled}{user_src}{prefix_src}: {data.strip()}'
else:
msg=f'{data.strip()}'
d_irc_msg(network_chanroom_dest,msg)
####################################################################################### EOF

View File

@ -0,0 +1,59 @@
# -*- coding: utf-8 -*- ############################################################### SOF
###########################################################################################
def rgb(r=0,g=0,b=0):return f"\033[38;2;{r};{g};{b}m"
###########################################################################################
def rgbe():return f"\033[38;2;255;255;255m"
###########################################################################################
def rgbt(t='',r=0,g=0,b=0):return f"\033[38;2;{r};{g};{b}m{t}\033[38;2;255;255;255m"
###########################################################################################
###########################################################################################
def colorform(s):
#######################################################################################
try:
between_gtlts=s.split(' >>> ')[0].split('<<< ')[1]
except:
pass
try:
between_brackets=s.split(' >>> [ ')[1].split(' ]')[0]
if s[:-2].endswith(between_brackets):
FLAG_A=False
else:
FLAG_A=True
except:
FLAG_A=True
try:
if FLAG_A:
everything_past_brackets=s.split(' >>> [ ')[1].split(' ] ')[1]
except:
pass
#######################################################################################
s=f"{rgb(b=255)}<<<{rgb(g=255,b=255)} {between_gtlts} {rgb(b=255)}>>> {rgb(r=255)}"
if between_brackets.startswith('('):
s+=f"[{rgb(b=255)} {between_brackets} {rgb(r=255)}]"
else:
s+=f"[{rgb(r=255,g=255)} {between_brackets} {rgb(r=255)}]"
#######################################################################################
maybe_delimited=""
try:
if maybe_delimited=="":
if FLAG_A:
if everything_past_brackets.startswith('-'):
maybe_delimited=f" {rgb(b=255)}- "
everything_past_brackets=everything_past_brackets[2:].replace(' - ',f' {rgb(b=255)}- {rgb(r=255,b=255)}')
elif everything_past_brackets.startswith('>'):
maybe_delimited=f" {rgb(b=255)}> "
everything_past_brackets=everything_past_brackets[2:].replace(":",f"{rgb(b=255)}:{rgb(g=255)}",1)
except:
pass
try:
if len(everything_past_brackets)>0:
s+=f"{maybe_delimited}{rgb(r=255,b=255)}{everything_past_brackets}"
print(s)
return
else:
print(s)
return
except:
print(s)
return
####################################################################################### EOFs

View File

@ -0,0 +1,599 @@
# -*- 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]
#from plugins.tool_colors_plugin import colorform as print
from plugins.tool_guds_plugin import guds
import asyncio
global dims
###########################################################################################
class DIMS:
#######################################################################################
class __INIT_MATRIX__:
###################################################################################
class __INIT_ROOM__:
###############################################################################
class __INIT_BRIDGE_MATRIX__:
###########################################################################
def __init__(self,room):
self.inbound=[]
#self.matrix_rooms_inbound=[]
self.outbound=[]
#self.irc_channels_inbound=[]
###############################################################################
def __init__(self,room):
room_flag=False
if len(dir(room))>1:
try:
if room.startswith('!'):
pass
except:
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 ismatrixroom(self,room):
###################################################################################
try:
for index_server,_matrix in enumerate(self.matrix):
for index_room,_room in enumerate(_matrix.rooms):
if _room.room_id==room:
return True
###################################################################################
except: pass
###################################################################################
return False
#######################################################################################
class __INIT_DISCORD__:
###################################################################################
class __INIT_CHANNEL__:
###############################################################################
class __INIT_BRIDGE_DISCORD__:
###########################################################################
def __init__(self,channel):
self.inbound=[]
self.outbound=[]
###############################################################################
def __init__(self,channel):
self.channel=channel
self.bridge=self.__INIT_BRIDGE_DISCORD__(channel)
###################################################################################
def __init__(self,channel):
self.channels=[]
self.channels.append(self.__INIT_CHANNEL__(channel))
#######################################################################################
def isdiscordchannel(self,channel):
###################################################################################
try:
for index_server,_discord in enumerate(self.discord):
for index_channel,_channel in enumerate(_discord.channels):
if _channel.channel==channel:
return True
###################################################################################
except: pass
###################################################################################
return False
#######################################################################################
class __INIT_TELEGRAM__:
###################################################################################
class __INIT_GROUP__:
###############################################################################
class __INIT_BRIDGE_TELEGRAM__:
###########################################################################
def __init__(self,group):
self.inbound=[]
self.outbound=[]
###############################################################################
def __init__(self,group):
self.group=group
self.bridge=self.__INIT_BRIDGE_TELEGRAM__(group)
###################################################################################
def __init__(self,group):
self.groups=[]
self.groups.append(self.__INIT_GROUP__(group))
#######################################################################################
def istelegramgroup(self,group):
###################################################################################
try:
for index_server,_telegram in enumerate(self.telegram):
for index_group,_group in enumerate(_telegram.groups):
if _group.group==group:
return True
###################################################################################
except: pass
###################################################################################
return False
#######################################################################################
class __INIT_IRC__:
###################################################################################
class __INIT_CHANNEL__:
###############################################################################
class __INIT_BRIDGE_IRC__:
###########################################################################
def __init__(self,channel):
self.inbound=[]
#self.irc_channels_inbound=[]
self.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 isircchannel(self,channel=None,return_index=False):
###################################################################################
try:
for index_server,_irc in enumerate(self.irc):
for index_channel,_channel in enumerate(_irc.channels):
if _channel.channel==channel:
if return_index:
return True,index_server
else:
return True
###################################################################################
except: pass
###################################################################################
return False
#######################################################################################
matrix=[]; irc=[]; telegram=[]; discord=[]; netschanroom=[]; netschanroom_bridged=[];
#######################################################################################
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 __boot__(self):
ircbot=guds.memory('ircbot')
dbnames=["matrixchat","telegramchat","discordchat","ircchat"]
for dbname in dbnames:
dbdata=ircbot.db.getlist(dbname)
if dbdata:
for entry in dbdata:
if dbname==dbnames[0]:
if not dims.ismatrixroom(entry[0]):
self.matrix.append(self.__INIT_MATRIX__(entry[0]))
elif dbname==dbnames[1]:
if not dims.istelegramgroup(entry[1]):
self.telegram.append(self.__INIT_TELEGRAM__(entry[1]))
elif dbname==dbnames[2]:
if not dims.isdiscordchannel(entry[1]):
self.discord.append(self.__INIT_DISCORD__(entry[1]))
discordbot=guds.memory('discordbot')
asyncio.run_coroutine_threadsafe(discordbot.listchannels(),discordbot.client.loop)
elif dbname==dbnames[3]:
if not dims.isircchannel(entry[0]):
self.irc.append(self.__INIT_IRC__(entry[0]))
dbname="chatbridges"
dbdata=ircbot.db.getlist(dbname)
if dbdata:
for entry in dbdata:
chanroom=entry[0]
src_outbound=entry[1]
dest_inbound=entry[2]
if chanroom.startswith('!'):
for _matrix in self.matrix:
for _rooms in _matrix.rooms:
if _rooms.room_id==chanroom:
_rooms.bridge.inbound=src_outbound
_rooms.bridge.outbound=dest_inbound
elif chanroom.startswith('#'):
for _irc in self.irc:
for _channels in _irc.channels:
if _channels.channel==chanroom:
_channels.bridge.inbound=src_outbound
_channels.bridge.outbound=dest_inbound
elif chanroom.startswith('$'):
for _telegram in self.telegram:
for _groups in _telegram.groups:
if _groups.group==chanroom:
_groups.bridge.inbound=src_outbound
_groups.bridge.outbound=dest_inbound
elif chanroom.startswith('^'):
for _discord in self.discord:
for _channels in _discord.channels:
if _channels.channel==chanroom:
_channels.bridge.inbound=src_outbound
_channels.bridge.outbound=dest_inbound
#######################################################################################
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))
elif net=='discord':
self.discord.append(self.__INIT_DISCORD__(chanroom))
elif net=='telegram':
self.telegram.append(self.__INIT_TELEGRAM__(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])
###################################################################################
elif net=='discord': self.discord.remove(self.discord[chanroom_index])
###################################################################################
elif net=='telegram': self.telegram.remove(self.telegram[chanroom_index])
#######################################################################################
# def del_channel_bridge(self,src_outbound,dest_inbound):
# commands=[]
# err_chan="bot is not in this channel/room/group: {}"
# try:
# if src_outbound.startswith('!'):
# if not dims.ismatrixroom(src_outbound): return False,err_chan.format(src_outbound)
# for _matrix in self.matrix:
# for _rooms in _matrix.rooms:
# if _rooms.room_id==src_outbound:
# commands.append("_rooms.bridge.outbound.remove(dest_inbound)")
# elif src_outbound.startswith('#'):
# if not dims.isircchannel(src_outbound): return False,err_chan.format(src_outbound)
# for _irc in self.irc:
# for _channels in _irc.channels:
# if _channels.channel==src_outbound:
# commands.append("_channels.bridge.outbound.remove(dest_inbound)")
# elif src_outbound.startswith('$'):
# if not dims.istelegramgroup(src_outbound): return False,err_chan.format(src_outbound)
# for _telegram in self.telegram:
# for _groups in _telegram.groups:
# if _groups.group==src_outbound:
# commands.append("_groups.bridge.outbound.remove(dest_inbound)")
# elif src_outbound.startswith('^'):
# if not dims.isdiscordchannel(src_outbound): return False,err_chan.format(src_outbound)
# for _discord in self.discord:
# for _channels in _discord.channels:
# if _channels.channel==src_outbound:
# commands.append("_channels.bridge.outbound.remove(dest_inbound)")
# if dest_inbound.startswith('!'):
# if not dims.ismatrixroom(dest_inbound): return False,err_chan.format(dest_inbound)
# for _matrix in self.matrix:
# for _rooms in _matrix.rooms:
# if _rooms.room_id==dest_inbound:
# commands.append("_rooms.bridge.inbound.remove(src_outbound)")
# elif dest_inbound.startswith('#'):
# if not dims.isircchannel(dest_inbound): return False,err_chan.format(dest_inbound)
# for _irc in self.irc:
# for _channels in _irc.channels:
# if _channels.channel==dest_inbound:
# commands.append("_channels.bridge.inbound.remove(src_outbound)")
# elif dest_inbound.startswith('$'):
# if not dims.istelegramgroup(dest_inbound): return False,err_chan.format(dest_inbound)
# for _telegram in self.telegram:
# for _groups in _telegram.groups:
# if _groups.group==dest_inbound:
# commands.append("_groups.bridge.inbound.remove(src_outbound)")
# elif dest_inbound.startswith('^'):
# if not dims.isdiscordchannel(dest_inbound): return False,err_chan.format(dest_inbound)
# for _discord in self.discord:
# for _channels in _discord.channels:
# if _channels.channel==dest_inbound:
# commands.append("_channels.bridge.inbound.remove(src_outbound)")
# for command in commands: exec(command)
# return True,None
# except Exception as e:
# return False,e
#######################################################################################
def blackholes(self,src_blackhole,cmd=None):
self.blackhole=[]
ircbot=guds.memory('ircbot')
dbname="blackhole"
db=ircbot.db.getlist(dbname)
if not db:
db=[]
for entry in db:
self.blackhole.append(entry)
if cmd=="add":
try:
self.blackhole.append(src_blackhole)
ircbot.db.setlist(dbname,self.blackhole)
except:
pass
elif cmd=="del":
try:
self.blackhole.remove(src_blackhole)
ircbot.db.setlist(dbname,self.blackhole)
except:
pass
return self.blackhole
def bridge_routes(self,src_outbound,dest_inbound,cmd=None):
err_chan="bot is not in this channel/room/group: {}"
err_dupe="this channel/room/group is a duplicate: {}"
err_cmds="wrong command given to bridge_routes: {}"
err_flow="wrong flow direction given: {}"
err_same="src_outbound: {} and dest_inbound: {} are the same route"
###################################################################################
if src_outbound==dest_inbound: return False,err_same.format(src_outbound,dest_inbound)
try:
for flow in ["out","in"]:
if flow=="out":
flow_direction=src_outbound
elif flow=="in":
flow_direction=dest_inbound
###############################################################################
if flow_direction.startswith('!'):
if not dims.ismatrixroom(flow_direction): return False,err_chan.format(flow_direction)
for _matrix in self.matrix:
for _rooms in _matrix.rooms:
if _rooms.room_id==flow_direction:
if cmd=="add":
if flow=="out":
for bridge_outbound in _rooms.bridge.outbound:
if bridge_outbound==dest_inbound: return False,err_dupe
_rooms.bridge.outbound.append(dest_inbound)
elif flow=="in":
for bridge_inbound in _rooms.bridge.inbound:
if bridge_inbound==src_outbound: return False,err_dupe
_rooms.bridge.inbound.append(src_outbound)
else:
return False,err_flow
elif cmd=="del":
if flow=="out":
_rooms.bridge.outbound.remove(dest_inbound)
elif flow=="in":
_rooms.bridge.inbound.remove(src_outbound)
else:
return False,err_flow
else:
return False,err_cmds
###################################################################################
elif flow_direction.startswith('#'):
if not dims.isircchannel(flow_direction): return False,err_chan.format(flow_direction)
for _irc in self.irc:
for _channels in _irc.channels:
if _channels.channel==flow_direction:
if cmd=="add":
if flow=="out":
for bridge_outbound in _channels.bridge.outbound:
if bridge_outbound==dest_inbound: return False,err_dupe
_channels.bridge.outbound.append(dest_inbound)
elif flow=="in":
for bridge_inbound in _channels.bridge.inbound:
if bridge_inbound==src_outbound: return False,err_dupe
_channels.bridge.inbound.append(src_outbound)
else:
return False,err_flow
elif cmd=="del":
if flow=="out":
_channels.bridge.outbound.remove(dest_inbound)
elif flow=="in":
_channels.bridge.inbound.remove(src_outbound)
else:
return False,err_flow
else:
return False,err_cmds
###################################################################################
elif flow_direction.startswith('$'):
if not dims.istelegramgroup(flow_direction): return False,err_chan.format(flow_direction)
for _telegram in self.telegram:
for _groups in _telegram.groups:
if _groups.group==flow_direction:
if cmd=="add":
if flow=="out":
for bridge_outbound in _groups.bridge.outbound:
if bridge_outbound==dest_inbound: return False,err_dupe
_groups.bridge.outbound.append(dest_inbound)
elif flow=="in":
for bridge_inbound in _groups.bridge.inbound:
if bridge_inbound==src_outbound: return False,err_dupe
_groups.bridge.inbound.append(src_outbound)
else:
return False,err_flow
elif cmd=="del":
if flow=="out":
_groups.bridge.outbound.remove(dest_inbound)
elif flow=="in":
_groups.bridge.inbound.remove(src_outbound)
else:
return False,err_flow
else:
return False,err_cmds
###################################################################################
elif flow_direction.startswith('^'):
if not dims.isdiscordchannel(flow_direction): return False,err_chan.format(flow_direction)
for _discord in self.discord:
for _channels in _discord.channels:
if _channels.channel==flow_direction:
if cmd.lower()=="add":
if flow=="out":
for bridge_outbound in _channels.bridge.outbound:
if bridge_outbound==dest_inbound: return False,err_dupe
_channels.bridge.outbound.append(dest_inbound)
elif flow=="in":
for bridge_inbound in _channels.bridge.inbound:
if bridge_inbound==src_outbound: return False,err_dupe
_channels.bridge.inbound.append(src_outbound)
else:
return False,err_flow
elif cmd.lower()=="del":
if flow=="out":
_channels.bridge.outbound.remove(dest_inbound)
elif flow=="in":
_channels.bridge.inbound.remove(src_outbound)
else:
return False,err_flow
else:
return False,err_cmds
###################################################################################
self.ircbot=guds.memory('ircbot')
self.dbname="chatbridges"
self.db=self.ircbot.db.getlist(self.dbname)
if not self.db: self.db=[]
FLAG_SRC=False
FLAG_DEST=False
for entry in self.db:
if entry[0]==src_outbound:
for i,entry in enumerate(self.db):
try:
result=entry.index(src_outbound)
if not type(result)=="NoneType":
FLAG_DEST=True
result=i
inbound=entry[2]
inbound.append(dest_inbound)
inbound=list(set(inbound))
inbound.sort()
outbound=entry[1]
self.db[i]=[src_outbound,outbound,inbound]
except:
pass
try:
result=entry.index(dest_inbound)
if not type(result)=="NoneType":
FLAG_SRC=True
result=i
outbound=entry[1]
outbound.append(src_outbound)
outbound=list(set(outbound))
outbound.sort()
inbound=entry[1]
self.db[i]=[dest_inbound,outbound,inbound]
except:
pass
if not FLAG_DEST:
self.db.append([src_outbound,[],[dest_inbound]])
if not FLAG_SRC:
self.db.append([dest_inbound,[src_outbound],[]])
self.ircbot.db.setlist(self.dbname,self.db)
return True,None
except Exception as e:
return False,e
#######################################################################################
def list_channels_bridged(self,netsrc=False):
self.netschanroom_bridged=[]
for _irc in self.irc:
for _channels in _irc.channels:
if netsrc:
if netsrc==_channels.channel:
[self.netschanroom_bridged.append(x) for x in _channels.bridge.outbound]
else:
self.netschanroom_bridged.append([_channels.channel,_channels.bridge.inbound,_channels.bridge.outbound])
for _matrix in self.matrix:
for _rooms in _matrix.rooms:
if netsrc:
if netsrc==_rooms.room_id:
[self.netschanroom_bridged.append(x) for x in _rooms.bridge.outbound]
else:
self.netschanroom_bridged.append([_rooms.room_id,_rooms.bridge.inbound,_rooms.bridge.outbound])
for _telegram in self.telegram:
for _groups in _telegram.groups:
if netsrc:
if netsrc==_groups.group:
[self.netschanroom_bridged.append(x) for x in _groups.bridge.outbound]
else:
self.netschanroom_bridged.append([_groups.group,_groups.bridge.inbound,_groups.bridge.outbound])
for _discord in self.discord:
for _channels in _discord.channels:
if netsrc:
if netsrc==_channels.channel:
[self.netschanroom_bridged.append(x) for x in _channels.bridge.outbound]
else:
self.netschanroom_bridged.append([_channels.channel,_channels.bridge.inbound,_channels.bridge.outbound])
return self.netschanroom_bridged
#######################################################################################
def list_channels(self):
###################################################################################
self.netschanroom=[]
ircbot=guds.memory('ircbot')
dbname="matrixchat"
db=ircbot.db.getlist(dbname)
if db:
for entry in db:
self.netschanroom.append(entry[0])
dbname="telegramchat"
db=ircbot.db.getlist(dbname)
if db:
for entry in db:
self.netschanroom.append(entry[1])
dbname="discordchat"
db=ircbot.db.getlist(dbname)
if db:
for entry in db:
self.netschanroom.append(entry[1])
dbname="ircchat"
db=ircbot.db.getlist(dbname)
if db:
for entry in db:
self.netschanroom.append(entry[0])
# for _irc in self.irc:
# for _channels in _irc.channels:
# self.netschanroom.append(_channels.channel)
# ircbot=guds.memory('ircbot')
# discordbot=guds.memory('discordbot')
# discordchannels=list(discordbot.client.get_all_channels())
# if discordchannels[0].__class__.__name__=="CategoryChannel" and discordchannels[0].name=='bridged':
# for channel in discordchannels[0].channels:
# self.netschanroom.append(f"^{channel.name}")
# print('break')
###################################################################################
return self.netschanroom
###########################################################################################
dims=DIMS()
####################################################################################### EOF

View File

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*- ############################################################### SOF
from datetime import datetime
from datetime import timedelta
import timeago
from plugins.tool_colors_plugin import colorform as print
global guds # global unified data system 2 move instantiated data between processes/threads
###########################################################################################
class GUDS:
#######################################################################################
push_index=0; memories=[]; timestamped_alarm=[];
#######################################################################################
def __init__(self):
pass
#######################################################################################
def timestamp_alarm(self,reason,seconds):
try:
iseconds=int(seconds)
timestamp=datetime.now().timestamp()
timestamp+=iseconds
self.timestamped_alarm.append([reason,False,timestamp])
print(f'<<< ________guds_plugin >>> [ timestamp_alarm ] - active: {reason} - alarm: {timestamp} - now: {datetime.now().timestamp()}')
except:
print('<<< ________guds_plugin >>> [ timestamp_alarm ] - error')
#######################################################################################
def timestamp_check(self,reason):
try:
REASON_FLAG=True
for i,_ in enumerate(self.timestamped_alarm):
if _[0]==reason:
if _[1]==True:
return True
else:
REASON_FLAG=False
if datetime.now().timestamp()>=_[2]:
# print('times up')
self.timestamped_alarm[i]=[_[0],True,_[2]]
return True
else:
now=datetime.now().timestamp(); then=_[2];
if int(then-now) <= 0:
# print('times up noticed in failure before success')
pass
# print(f'timeleft on alarm: {timeago.format(then,now)} - {int(then-now)}')
return False
if REASON_FLAG:
print('<<< ________guds_plugin >>> [ timestamp_check ] timestamped reason not found')
return -1
except:
print('<<< ________guds_plugin >>> [ timestamp_check ] timestamp_check error')
return -1
#######################################################################################
def memory(self,data):
for _ in self.memories:
if not _[1].find(data)==-1:
return _[0]
#######################################################################################
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

View File

@ -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
###########################################################################################
###########################################################################################
TWITTER_CONSUMER_KEY = os.environ['TWITTER_CONSUMER_KEY']
TWITTER_CONSUMER_SECRET = os.environ['TWITTER_CONSUMER_SECRET']
TWITTER_ACCESS_TOKEN_KEY = os.environ['TWITTER_ACCESS_TOKEN_KEY']
TWITTER_ACCESS_TOKEN_SECRET = os.environ['TWITTER_ACCESS_TOKEN_SECRET']
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=TWITTER_CONSUMER_KEY, consumer_secret=TWITTER_CONSUMER_SECRET,
access_token_key=TWITTER_ACCESS_TOKEN_KEY, access_token_secret=TWITTER_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

View File

@ -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

View File

@ -0,0 +1,121 @@
# -*- 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")
title = title.text.strip()[:100]
if title is not None:
if not url.lower().find('soundcloud.com')==-1:
if title.startswith('Stream'):
title=title[7:]
title=title.split(" | Listen")[0].lower()
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

View File

@ -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

View File

@ -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__))
YOUTUBE_DEVELOPER_KEY = os.environ['YOUTUBE_DEVELOPER_KEY']
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
YOUTUBE_REGEX = re.compile('http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?[\w\?=]*)?', re.IGNORECASE)
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=YOUTUBE_DEVELOPER_KEY)
###########################################################################################
###########################################################################################
@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=False)
def y(self, *args, **kwargs):
"""Search for youtube video
%%y <keyword>...
"""
return self.yt(*args)
#######################################################################################
#######################################################################################
@irc3.extend
@command(permission='view')
def yt(self, mask, target, args):
"""Search for youtube video
%%yt <keyword>...
"""
keyword = ' '.join(args['<keyword>'])
video = self.youtube_search(q=keyword)
if video:
video_id = video.get("id",{}).get("videoId")
video = video.get("snippet")
video_info = self.videos_list_by_id(id=video_id)
title = video_info.get("snippet",{}).get("title")
published_at = video_info.get("snippet",{}).get("publishedAt")
like_count=0
try:
view_count = int(video_info.get("statistics").get("viewCount"))
except:
like_count = int(video_info.get("statistics").get("likeCount"))
if published_at:
published_at = dateutil.parser.parse(published_at)
published_at = timeago.format(published_at.replace(tzinfo=None), datetime.datetime.now())
try:
topics = video_info.get("topicDetails",{}).get("topicCategories")
topics[:] = [i.replace("https://en.wikipedia.org/wiki/", "").replace("_"," ").title() for i in topics]
except:
topics = []
duration = isodate.parse_duration(video_info.get("contentDetails").get("duration"))
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ########
MUSIC_FOUND=False
for topic in topics:
if topic.lower().find('music'):
MUSIC_FOUND=True
if MUSIC_FOUND:
url = "https://youtu.be/{}".format(video_id)
self.bot.bbs.enter(mask.nick,url,title)
######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ######## YOUTUBE <-> BOOMBOX_PLUGIN HOOK: 2 of 2 ########
_nick = ""
try:
if len(self.bot.madjust) > 0:
_nick = self.bot.madjust
else:
_nick = mask.nick
except:
_nick = mask.nick
msg = "\x02\x0302{nick:}\x0F\x02\x0304 >> \x02\x0303\x1D\x1F{title:}\x0F".format(nick=_nick, title=title)
msg = msg + "\x02\x1D\x0304 > \x0F\x1D\x0314Duration: \x0F\x1D{duration:} \x0F".format(duration=duration)
if like_count == 0:
msg = msg + "\x0F\x1D\x0314Published: \x0F\x1D{published:} \x0F\x1D\x0314Views: \x0F\x1D{views:,} \x0F\x1D\x0314Type: \x0F\x1DVideo\x0F".format(published=published_at, views=view_count)
else:
msg = msg + "\x0F\x1D\x0314Published: \x0F\x1D{published:} \x0F\x1D\x0314Likes: \x0F\x1D{views:,} \x0F\x1D\x0314Type: \x0F\x1DMovie\x0F".format(published=published_at, views=like_count)
msg = msg + "\x0F\x02\x0312 ♫ \x0F\x02\x0313\x1D{topics:}\x0F\x02\x0312 ".format(topics=", ".join(topics))
msg = msg + url
msg = self.bot.emo(msg)
self.bot.privmsg(target, msg)
#######################################################################################
#######################################################################################
####################################################################################### EOF

View File

@ -0,0 +1,2 @@
irc3
ipdb

View File

@ -0,0 +1,10 @@
irc3
timeago
isodate
oauth2client
asyncio
async-timeout
lxml
aiocron
ipdb
pytz

View File

@ -0,0 +1,25 @@
irc3
timeago
isodate
google-api-python-client
oauth2client
asyncio
async-timeout
lxml
python-twitter
googlesearch-python
pyfiglet
ipdb
matrix-nio
discord
python-telegram-bot
openai
aiocron
pytz
imgaug==0.2.7
folium==0.2.1
torch==1.9.1
transformers==2.3.0
googletrans==2.4.0
textblob==0.15.3
matplotlib==3.1.1

View File

@ -0,0 +1,39 @@
irc3.plugins.log
irc3.plugins.logger
plugins.command_plugin
plugins.core_plugin
plugins.storage_plugin
plugins.fifo_plugin
plugins.sasl_custom_plugin
plugins.net_hydra_plugin
plugins.tool_colors_plugin
# plugins.timezonediff_plugin
# plugins.remind_plugin
# plugins.net_hydra_plugin
# plugins.ansi_plugin
# plugins.net_matrix_plugin
# plugins.net_discord_plugin
# plugins.net_telegram_plugin
# plugins.youtube_plugin
# plugins.crypto_plugin
# plugins.url_grabber_plugin
# plugins.notes_plugin
# plugins.quote_plugin
# plugins.ratesex_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
# plugins.joke_plugin
# plugins.maple_plugin
# plugins.openai_plugin

View File

@ -0,0 +1,31 @@
[bot]
nick = maple
username = g1mp
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.log
irc3.plugins.logger
plugins.command_plugin
plugins.storage_plugin
plugins.fifo_plugin
plugins.sasl_custom_plugin
plugins.net_hydra_plugin
plugins.tool_colors_plugin
autojoins =
${#}PalletTown
flood_burst = 0
flood_rate = 1
flood_rate_delay = 1
storage = json://databases/maple_db.json
[plugins.fifo_plugin]
runpath = .fifo

View File

@ -0,0 +1,48 @@
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.net_discord_plugin
plugins.net_telegram_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.timezonediff_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
plugins.joke_plugin
plugins.maple_plugin
#plugins.net_hydra_plugin
#plugins.ansi_plugin
#plugins.openai_plugin

View File

@ -0,0 +1,102 @@
# -*- coding: utf-8 -*- ############################################################### SOF
global SERVICES
SERVICES=False
import asyncio
import os
import threading
from time import sleep
##################################################channel##################################
import irc3
# from nio import AsyncClient, MatrixRoom, RoomMessageText
##################################################channel##################################
# from plugins.net_discord_plugin import start_discordbot
from plugins.net_irc_plugin import config_ircbot, start_ircbot
# from plugins.net_matrix_plugin import start_matrixbot
# from plugins.net_telegram_plugin import start_telegrambot
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
#from plugins.tool_colors_plugin import colorform as print
##################################################channel##################################
class BOTIO:
#######################################################################################
verbosity=True
log_exit_level=[]
loop=asyncio.get_event_loop()
#######################################################################################
def __init__(self):
print(f'<<< ________botio_class >>> [ instantiated ]')
self.ircbot=config_ircbot()
self._bio=guds.memory('__main__.bio')
self.net_irc=[]
self.net_matrix=[]
self.net_discord=[]
self.net_discord_initialized=False
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__discord(self):
# print('<<< system_status__info >>> [ booting connection ] - discord')
# self=start_discordbot(self)
# #######################################################################################
# def __boot__telegram(self):
# print('<<< system_status__info >>> [ booting connection ] - telegram')
# self=start_telegrambot(self)
#######################################################################################
def __boot__empty(self):
print('<<< system_status__info >>> [ booting connection ] - empty')
#######################################################################################
def __main__(self,index):
counter=0
if index==0:
t=threading.Thread(target=self.__boot__irc)
print(f'<<< system_status__info >>> [ thread setup ] - irc')
t.start()
print(f'<<< system_status__info >>> [ thread started ] - irc')
# elif index==1:
# t=threading.Thread(target=self.__boot__matrix)
# print(f'<<< system_status__info >>> [ thread setup ] - matrix')
# t.start()
# t.join()
# print(f'<<< system_status__info >>> [ thread started ] - matrix')
# elif index==2:
# t=threading.Thread(target=self.__boot__discord)
# print(f'<<< system_status__info >>> [ thread setup ] - discord')
# t.start()
# t.join()
# print(f'<<< system_status__info >>> [ thread started ] - discord')
# elif index==3:
# t=threading.Thread(target=self.__boot__telegram)
# print(f'<<< system_status__info >>> [ thread setup ] - telegram')
# t.start()
# t.join()
# print(f'<<< system_status__info >>> [ thread started ] - telegram')
elif index==4:
t=threading.Thread(target=self.__boot__empty)
print(f'<<< system_status__info >>> [ thread setup ] - empty')
t.start()
print(f'<<< system_status__info >>> [ thread started ] - empty')
###########################################################################################
if __name__ == '__main__':
print('<<< system_status__info >>> [ main loop ] - startup')
bio=BOTIO()
globals()['guds'].memories.append([bio,'maple:__main__.bio'])
for i in range(4):
bio.log_exit_level.append(bio.__main__(i))
counter=0
while True:
counter+=1
if counter<=3:
print(f'<<< system_status__info >>> [ eventloop idler thread ] - not ready - system locked for {str(counter).zfill(2)}/3 seconds')
if counter==4:
dims.__boot__()
print(f'<<< system_status__info >>> [ eventloop idler thread ] - system ready')
sleep(1)
####################################################################################### EOF

View File

@ -0,0 +1,50 @@
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_hydra_plugin
plugins.net_irc_plugin
plugins.cmd_irc_plugin
plugins.storage_plugin
plugins.base_plugin
plugins.emote_plugin
plugins.fifo_plugin
plugins.tool_colors_plugin
plugins.net_hydra_plugin
# plugins.timezonediff_plugin
# plugins.remind_plugin
# plugins.ansi_plugin
# plugins.net_matrix_plugin
# plugins.net_discord_plugin
# plugins.net_telegram_plugin
# plugins.youtube_plugin
# plugins.crypto_plugin
# plugins.url_grabber_plugin
# plugins.notes_plugin
# plugins.quote_plugin
# plugins.ratesex_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
# plugins.joke_plugin
# plugins.maple_plugin
# plugins.openai_plugin

View File

@ -0,0 +1,100 @@
# -*- coding: utf-8 -*- ############################################################### SOF
import asyncio
import os
import threading
from time import sleep
##################################################channel##################################
import irc3
from nio import AsyncClient, MatrixRoom, RoomMessageText
##################################################channel##################################
from plugins.net_discord_plugin import start_discordbot
from plugins.net_irc_plugin import config_ircbot, start_ircbot
from plugins.net_matrix_plugin import start_matrixbot
from plugins.net_telegram_plugin import start_telegrambot
from plugins.tool_bus_plugin import BUS
from plugins.tool_dims_plugin import dims
from plugins.tool_guds_plugin import guds
#from plugins.tool_colors_plugin import colorform as print
##################################################channel##################################
class BOTIO:
#######################################################################################
verbosity=True
log_exit_level=[]
loop=asyncio.get_event_loop()
#######################################################################################
def __init__(self):
print(f'<<< ________botio_class >>> [ instantiated ]')
self.ircbot=config_ircbot()
self._bio=guds.memory('__main__.bio')
self.net_irc=[]
self.net_matrix=[]
self.net_discord=[]
self.net_discord_initialized=False
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__discord(self):
print('<<< system_status__info >>> [ booting connection ] - discord')
self=start_discordbot(self)
#######################################################################################
def __boot__telegram(self):
print('<<< system_status__info >>> [ booting connection ] - telegram')
self=start_telegrambot(self)
#######################################################################################
def __boot__empty(self):
print('<<< system_status__info >>> [ booting connection ] - empty')
#######################################################################################
def __main__(self,index):
counter=0
if index==0:
t=threading.Thread(target=self.__boot__irc)
print(f'<<< system_status__info >>> [ thread setup ] - irc')
t.start()
print(f'<<< system_status__info >>> [ thread started ] - irc')
elif index==1:
t=threading.Thread(target=self.__boot__matrix)
print(f'<<< system_status__info >>> [ thread setup ] - matrix')
t.start()
t.join()
print(f'<<< system_status__info >>> [ thread started ] - matrix')
elif index==2:
t=threading.Thread(target=self.__boot__discord)
print(f'<<< system_status__info >>> [ thread setup ] - discord')
t.start()
t.join()
print(f'<<< system_status__info >>> [ thread started ] - discord')
elif index==3:
t=threading.Thread(target=self.__boot__telegram)
print(f'<<< system_status__info >>> [ thread setup ] - telegram')
t.start()
t.join()
print(f'<<< system_status__info >>> [ thread started ] - telegram')
elif index==4:
t=threading.Thread(target=self.__boot__empty)
print(f'<<< system_status__info >>> [ thread setup ] - empty')
t.start()
print(f'<<< system_status__info >>> [ thread started ] - empty')
###########################################################################################
if __name__ == '__main__':
print('<<< system_status__info >>> [ main loop ] - startup')
bio=BOTIO()
globals()['guds'].memories.append([bio,'maple:__main__.bio'])
for i in range(4):
bio.log_exit_level.append(bio.__main__(i))
counter=0
while True:
counter+=1
if counter<=3:
print(f'<<< system_status__info >>> [ eventloop idler thread ] - not ready - system locked for {str(counter).zfill(2)}/3 seconds')
if counter==4:
dims.__boot__()
print(f'<<< system_status__info >>> [ eventloop idler thread ] - system ready')
sleep(1)
####################################################################################### EOF

View File

@ -0,0 +1,49 @@
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_hydra_plugin
plugins.net_irc_plugin
plugins.net_matrix_plugin
plugins.net_discord_plugin
plugins.net_telegram_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.timezonediff_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
plugins.joke_plugin
plugins.maple_plugin
plugins.tool_colors_plugin
#plugins.ansi_plugin
#plugins.openai_plugin

View File

@ -0,0 +1,29 @@
############################################################################################### SOF
f=open('data_tcp','r')
l=f.read().splitlines()
f.close()
tags=['[ crypto password ]','[ archive password ]','[ archive filename ]','[ archive contents ]']
nfo=[]
for i,_ in enumerate(l):
for ii,__ in enumerate(tags):
if _ in __:
nfo.append([_,i])
###################################################################################################
crypto_password=''.join(l[nfo[0][1]+1:nfo[1][1]])
f=open('dr1p_aes2','w')
f.write(crypto_password)
f.close()
archive_password=l[nfo[1][1]+1]
f=open('dr1p_zip','w')
f.write(archive_password)
f.close()
archive_filename=l[nfo[2][1]+1]
f=open('dak_archive_hint','w')
f.write(archive_filename)
f.close()
archive_contents=''.join(l[nfo[3][1]+1:])
f=open('data_tcp_deconcatenated','w')
f.write(archive_contents)
f.close()
print(".[d]. undakd .[d].")
############################################################################################### EOF

View File

@ -0,0 +1,16 @@
f=open('dak_tcp','r')
l=f.read().splitlines()
f.close()
for i,_ in enumerate(l):
if not _.find("-----END PGP MESSAGE-----")==-1:
f=open('storage/user/config/maple.pin.asc','w')
for ii in range(0,i+1):
f.write(f"{l[ii]}\n")
f.close()
f=open('dak_tcp','w')
for ii in range(i+1,len(l)):
f.write(f"{l[ii]}\n")
f.close()
break