Compare commits

...
This repository has been archived on 2023-04-13. You can view files and clone it, but cannot push or open issues or pull requests.

714 Commits

Author SHA1 Message Date
ChChBot admin 358b415566 added corridor light 2017-11-30 22:24:15 +01:00
ChChBot admin 3e1ea6ac4e fixed command names 2017-03-13 23:46:44 +01:00
ChChBot admin 48b627ad4b Merge branch 'ChaosChemnitz' of https://git.chch.it/ChCh/CloudBot_github into ChaosChemnitz 2017-03-13 23:32:29 +01:00
ChChBot admin 1f1ff649c9 deactivated unused functions 2017-03-13 23:31:52 +01:00
Florian Schlegel 8344fe7693 implemented light commands for e-lab 2017-03-13 23:22:15 +01:00
Florian Schlegel a6992d5d1a Merge branch 'ChaosChemnitz' of vcup.florz.net:/home/cloudbot/CloudBot into ChaosChemnitz 2017-02-24 22:21:33 +01:00
ChChBot admin 21db4efd98 implemented lounge_light command 2017-02-24 22:20:30 +01:00
ChChBot admin 8941d59dc2 removed buggy part for killing old processes 2017-02-24 17:08:01 +01:00
Florian Schlegel 09ce708709 Merge branch 'ChaosChemnitz' of vcup.florz.net:/home/cloudbot/CloudBot into ChaosChemnitz 2017-02-23 00:46:13 +01:00
ChChBot admin 29cc95f0ad Merge branch 'ChaosChemnitz' of https://git.chch.it/ChCh/CloudBot_github into ChaosChemnitz
Conflicts:
	plugins/chch_worker.py
2017-02-23 00:41:05 +01:00
Florian Schlegel 4a02f545ea Merge branch 'ChaosChemnitz' of github.com:ChaosChemnitz/CloudBot into ChaosChemnitz 2017-02-23 00:35:13 +01:00
ChChBot admin 28176ad2ad added new feature to toggle lounge light 2017-02-23 00:18:23 +01:00
ChChBot admin 651d4a953e fork and disown start script 2017-02-22 23:45:52 +01:00
ChChBot admin 80711e1278 changed IP to localhost 2017-02-22 23:45:32 +01:00
Florian Schlegel a88d5ef0bd Merge pull request #4 from marenz2569/ChaosChemnitz
command lamp_lounge: UDP -> TCP
2017-01-12 10:17:45 +01:00
Markus Schmidl 827c5c73e8 command lamp_lounge: UDP -> TCP 2017-01-11 21:29:01 +01:00
ChChBot admin 580415ed76 Merge branch 'ChaosChemnitz' of https://git.chch.it/ChCh/CloudBot_github into ChaosChemnitz 2016-11-17 21:40:48 +01:00
Florian Schlegel c562a2c7ae Merge branch 'ChaosChemnitz' of github.com:ChaosChemnitz/CloudBot into ChaosChemnitz 2016-11-17 21:32:54 +01:00
ChChBot admin 4b5e86c237 ignore config.ssl 2016-11-17 21:24:07 +01:00
txt.file 11687a9ad0 Merge pull request #3 from marenz2569/ChaosChemnitz
Fensterbogenbeleuchtungssteuerung
2016-11-17 19:18:48 +00:00
Markus Schmidl 296de07e14 uncommented event 332 2016-11-17 19:53:00 +01:00
Markus Schmidl dfbead6946 added command for controlling the fensterbogenbeleuchtung in the lounge (lamp_lounge) 2016-11-17 19:50:06 +01:00
root e30eca5ebd old changes + fixed utf8 problems 2016-02-04 16:55:03 +01:00
root 2a3c9f52dc added logging to syslog 2016-02-04 16:53:15 +01:00
ChChBot admin f88c3267d4 created reverse SSH tunnel for light control 2015-02-21 20:11:56 +01:00
ChChBot admin 2b18eaac5a Revert "disable chch_worker"
This reverts commit 05bfb9099a.
2015-02-20 13:13:45 +01:00
Florian Schlegel 0650046d18 Merge branch 'ChaosChemnitz' of https://github.com/Stummi/CloudBot into ChaosChemnitz 2015-02-19 22:14:13 +01:00
Michael Stummvoll 4e386c9008 update default config 2015-02-19 17:22:27 +01:00
Michael Stummvoll 05bfb9099a disable chch_worker 2015-02-19 17:20:59 +01:00
Michael Stummvoll bfa3fb6e74 move version check into own plugin 2015-02-19 17:20:35 +01:00
Florian Schlegel d415d0fc69 Merge pull request #2 from ChaosChemnitz/revert-1-ChaosChemnitz
Revert "add ctcp version check and kick the logbot clients"
2015-02-19 16:22:32 +01:00
Florian Schlegel 433d97d276 Revert "add ctcp version check and kick the logbot clients" 2015-02-19 16:21:14 +01:00
Florian Schlegel 121715115a Merge pull request #1 from Stummi/ChaosChemnitz
add ctcp version check and kick the logbot clients
2015-02-19 14:06:57 +01:00
Michael Stummvoll 620de651ce add ctcp version check and kick the logbot clients 2015-02-19 13:59:27 +01:00
ChChBot admin 3f205eaafa simple restart script to keep the bot alive 2015-02-18 23:01:52 +01:00
ChChBot admin 59cd8380d2 some changes... 2015-02-18 22:55:28 +01:00
ChChBot admin 7cce9bf27e disabled many plugins 2015-02-18 22:53:13 +01:00
ChChBot admin 0ba2001b62 some new plugins (thx to _20h_) 2015-02-18 22:49:44 +01:00
Morris Jobke 63fc042027 add plugin for topic update with status 2014-04-05 12:27:28 +02:00
Luke Rogers 9421d8160d Merge pull request #224 from daboross/patch-3
Create config.default that was removed
2014-04-04 14:11:33 +13:00
Dabo Ross 4b4ac2d918 Create config.default that was removed
1062e69e56 ?
2014-04-03 09:29:09 -07:00
Luke Rogers 05a68faf1d tidied 2014-04-03 19:44:38 +13:00
Luke Rogers 40328cf24f Merge remote-tracking branch 'origin/develop' into develop 2014-04-03 18:27:42 +13:00
Luke Rogers fb471bee17 Added random output, switched API URL 2014-04-03 18:27:17 +13:00
Luke Rogers 48ab7417b8 Update recipe.py 2014-04-03 15:01:19 +13:00
Luke Rogers 97a3283eff Switched suggest API 2014-04-02 23:22:39 +13:00
Luke Rogers 6d147e1677 Stuff 2014-04-02 20:12:21 +13:00
Luke Rogers c99c44616c Adapted code to get multiple results! 2014-04-02 20:08:56 +13:00
Luke Rogers 1062e69e56 Strip spaces 2014-04-02 20:03:14 +13:00
Luke Rogers 5ca45fea4b Added recipe searching! 2014-04-02 15:03:10 +13:00
Luke Rogers 04af154c5b Added more features! 2014-04-01 19:43:03 +13:00
Luke Rogers f82041fc87 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2014-04-01 17:58:00 +13:00
Luke Rogers a027bd780f Added fancy new recipe plugin! 2014-04-01 17:57:39 +13:00
Luke Rogers a611e0df45 Merge pull request #221 from daboross/fix-dictionary-unicode-support
Fix unicode support for dictionary.py
2014-03-31 20:58:10 +13:00
Luke Rogers e49ec9a9c9 Merge pull request #218 from daboross/fix-wiki-unicode-support
Fix unicode support for wikipedia
2014-03-31 20:58:09 +13:00
Luke Rogers 5ee62107f9 unbold 2014-03-31 20:23:45 +13:00
Dabo Ross 4652ed90a3 Fix unicode support for wikipedia 2014-03-28 18:15:39 -07:00
Dabo Ross ff3ef576b7 Fix unicode support for dictionary.py 2014-03-27 10:30:30 -07:00
Luke Rogers ec9f5e9777 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2014-03-27 10:09:46 +13:00
Luke Rogers 7f3b433209 Fix lastfm 2014-03-27 10:08:54 +13:00
Luke Rogers 2cb772674a Merge pull request #214 from prplz/fix-geoip-unicode
Use unicode string for returned message in geoip
2014-03-25 20:00:40 +13:00
Luke Rogers e46cb5c826 Update twitter.py 2014-03-19 17:40:21 +13:00
prplz b917b495f7 Use unicode string for returned message in geoip 2014-03-18 16:20:12 +11:00
Luke Rogers 4b7c8ffa75 Merge pull request #210 from xxyy/feature/tell-multiconn
Update tell.py to support multiple connections
2014-03-03 10:58:48 +13:00
xxyy 7cf3d88c96 Update tell.py to support multiple connections 2014-03-02 19:38:26 +01:00
Luke Rogers 21d06ae4f0 Removed old duplicate suggest plugin 2014-03-02 14:01:15 +13:00
Luke Rogers 50e2f72be4 Merge pull request #209 from xxyy/feature/seen-multiconn
Make history support multiple connections and merge seen.py into history.py
2014-03-02 13:53:41 +13:00
xxyy 1aacd8c511 Update seen and history to support multiple connections at once, Move seen command to history.py to reduce spaghetti code 2014-03-02 01:10:31 +01:00
Luke Rogers 6518fe7136 I am not a smart person sometimes 2014-03-01 18:40:36 +13:00
Luke Rogers fd7253ded7 handle socket.error 2014-03-01 13:12:48 +13:00
Luke Rogers f05a35dd96 Improved correction some more 2014-02-28 20:08:50 +13:00
Luke Rogers 8340f55adf herp 2014-02-28 19:49:46 +13:00
Luke Rogers 10907bf214 tweaked new correction code 2014-02-28 19:48:46 +13:00
Luke Rogers d834ae9070 Finished new mcuser - added legacy status and pretty colors 2014-02-28 17:28:54 +13:00
Luke Rogers 31d9031dcc test 2014-02-28 17:16:01 +13:00
Luke Rogers 17b75a2ba9 Improved http module, improved mcuser 2014-02-28 16:56:32 +13:00
Luke Rogers 0acb22e0a7 fixes 2014-02-28 15:52:05 +13:00
Luke Rogers 1be204236a tiny tweak 2014-02-28 15:32:24 +13:00
Luke Rogers a7a6f8c01e Rewrote mcpaid! 2014-02-28 15:29:40 +13:00
Luke Rogers 1bcf687ea2 just keep 100 messages per channel for now 2014-02-28 14:01:22 +13:00
Luke Rogers b9bf09e6b6 rewrite correction to use new history tracker 2014-02-28 13:59:31 +13:00
Luke Rogers 914bc255ab Added chat history tracker 2014-02-28 13:19:39 +13:00
Luke Rogers 2028075d2f Few small tweaks and fixes 2014-02-26 22:22:10 +13:00
Luke Rogers 8b1de13c8e Added really shoddy, probably broken git plugin 2014-02-25 19:30:55 +13:00
Luke Rogers d32619063a test 2014-02-25 18:50:03 +13:00
Luke Rogers 9cfdc0b706 Ugly code for force-reload 2014-02-25 13:36:52 +13:00
Luke Rogers 5d3280b9d5 strip excess whitespace 2014-02-24 02:15:58 +13:00
Luke Rogers 807cbf3f07 Rewrote OSRC to use HTML scraping because the API has been changed 2014-02-23 23:50:32 +13:00
Luke Rogers c7d2535098 testpush suggest 2014-02-23 20:33:08 +13:00
Luke Rogers 44cb335bc0 But, push this for now 2014-02-23 19:35:51 +13:00
Luke Rogers 90a91c1ef8 Fixed issues @daboross - closes #208 2014-02-23 13:30:24 +13:00
Luke Rogers 13df70da1b semi-rewrote mcping 2014-02-22 22:04:39 +13:00
Luke Rogers 5008da1331 MtGox is no longer an accurate indication of the value of a Bitcoin. 2014-02-21 14:57:54 +13:00
Luke Rogers 281a77c67c e 2014-02-16 17:50:50 +13:00
Luke Rogers 92796a218f Changed something because people can't take a joke 2014-02-16 17:45:55 +13:00
Luke Rogers 45a1f65748 fixed up mcping 2014-02-16 17:26:53 +13:00
Luke Rogers 160785e92c pep 2014-02-15 14:19:12 +13:00
Luke Rogers 763d73ea7a Merge pull request #207 from xxyy/patch-1
Fix xkcd comics made in January throwing an error
2014-02-15 12:21:59 +13:00
xxyy 694cbbe81f Fix xkcd comics made in January throwing an error
Previously, any commit written in January would throw an error because the array key for January was falsely '1' instead of the integer 1. This would lead to the moth name not being found and the error occuring.
This PR fixes that problem by changing the key of January to the integer 1.

**How to reproduce:**
Ask your CloudBot to `xkcd Regular Expressions`, an error will be shown in console.
2014-02-15 00:16:03 +01:00
Luke Rogers e8876c2c48 Merge pull request #202 from blha303/patch-16
Created plugin to parse Google urls to normal urls
2014-02-15 11:19:30 +13:00
Luke Rogers b0c6815085 fixed horoscope 2014-02-15 00:49:48 +13:00
Luke Rogers f7af1b0726 quote_plus() 2014-02-14 23:44:05 +13:00
Luke Rogers 2c6e01a41d Fixed up old religion.py plugin, added to disabled_stuff 2014-02-14 19:56:11 +13:00
Luke Rogers b6558ccdd5 I've been doing this all wrong for a long time 2014-02-14 19:43:36 +13:00
Luke Rogers 27b62feb5f tweakages 2014-02-14 19:13:30 +13:00
Luke Rogers 29258fdcac Merge pull request #205 from blha303/patch-17
xkcd.py - xkcd search and autoresponse
2014-02-14 18:46:27 +13:00
Steven Smith 86a0333afd xkcd.py - xkcd search and autoresponse 2014-02-14 13:44:12 +08:00
Luke Rogers 526d1de989 asdf 2014-02-14 17:03:49 +13:00
Luke Rogers d6683b32f4 PEP-8 2014-02-14 17:03:08 +13:00
Luke Rogers 004ceb79fc Spelling, docstrings 2014-02-14 16:49:41 +13:00
Luke Rogers a76ff29d4b Tidy Imports 2014-02-14 16:36:57 +13:00
Luke Rogers 4447e6cd1f more little things 2014-02-14 16:30:38 +13:00
Luke Rogers b4d7e200a3 Tweaks, improved reddit 2014-02-14 16:21:00 +13:00
Luke Rogers 7265413a21 Merge pull request #204 from daboross/patch-2
Add per-channel regex filtering
2014-02-14 13:08:18 +13:00
Dabo Ross 6086a7c6da Add per-channel regex filtering. 2014-02-13 10:24:29 -08:00
Luke Rogers 6169be6da1 no message 2014-02-14 01:04:50 +13:00
Luke Rogers ee0ad67a16 tidying! 2014-02-14 00:47:01 +13:00
Luke Rogers ada153c8bc Delete disabled_plugins 2014-02-13 23:21:07 +13:00
Luke Rogers 3a13621ae4 Delete puush.py 2014-02-13 22:18:00 +13:00
Dabo Ross 289561e76a Resolve 'time' name conflicts 2014-02-13 20:55:06 +13:00
Luke Rogers c21b358f9b messing with dice 2014-02-13 20:51:11 +13:00
Luke Rogers 136acd126d Reduce line length 2014-02-13 20:47:47 +13:00
Luke Rogers a7e931541f Fixed mcping on windows :) 2014-02-13 20:07:01 +13:00
Luke Rogers 223bef30a5 pepepepep8 2014-02-13 15:09:22 +13:00
Luke Rogers cd5ae1d32b further pepping, spelling and other such things 2014-02-13 15:02:44 +13:00
Luke Rogers 6cc7554cd8 A dash of PEP-8 2014-02-13 14:34:50 +13:00
Luke Rogers 398b34fad5 Disabled mark.py @md-5 2014-02-13 12:34:03 +13:00
Luke Rogers 10ef353782 Get game description from meta tags - no pesky HTML to strip 2014-02-13 12:00:33 +13:00
Luke Rogers 1c9216ac1d commented! 2014-02-13 11:57:10 +13:00
Luke Rogers a9d0d006ab magic, or something 2014-02-13 11:48:33 +13:00
Luke Rogers c2884242b3 Catch much errors 2014-02-13 10:54:20 +13:00
Luke Rogers 294a97b629 fixed minecraftwiki, thanks josephrooks! 2014-02-13 10:41:01 +13:00
Luke Rogers 2fde060dc4 Update URL 2014-02-13 10:10:34 +13:00
Luke Rogers df1023da55 fix mcwiki 2014-02-13 09:36:28 +13:00
Dabo Ross 954ff2ad00 Add command not found message when using .help one a non-command 2014-02-12 14:22:27 +13:00
Luke Rogers afdf5ccfe9 Revamped and re-added scene search command from Skybot 2014-02-11 17:04:21 +13:00
Luke Rogers fa66cf3c87 simplified code 2014-02-11 17:02:52 +13:00
Steven Smith 6c6c108549 Created plugin to parse Google urls to normal urls
Example Google url: http://www.google.nl/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&docid=kzd-kV9_31JsiM&tbnid=7Sl4EuqcSGY2wM:&ved=0CAIQjBw&url=http%3A%2F%2F4sysops.com%2Fwp-content%2Fuploads%2F2011%2F02%2FFTP.client.for_.the_.Windows.command.line_.FTPUse.gif&ei=2ujvUta0BKrV0QWdj4DoDg&bvm=bv.60444564,d.d2k&psig=AFQjCNEI_OCuyO1vWor1SoK_i5QGQYaY-Q&ust=1391540811442407
Example output url: http://4sysops.com/wp-content/uploads/2011/02/FTP.client.for_.the_.Windows.command.line_.FTPUse.gif
2014-02-04 03:37:27 +08:00
Luke Rogers 90bb260f5f Merge pull request #199 from Mu5tank05/patch-2
Mark now works with out an input
2014-01-25 02:00:23 -08:00
Nathan Blaney af8b07d20b Mark now works with out an input 2014-01-25 16:28:16 +11:00
Luke Rogers 728ab6f60b Update slaps.json 2014-01-23 14:00:19 +13:00
Luke Rogers d3aa2d3edd Merge pull request #192 from nathanblaney/patch-3
Added pycrypto requirement
2014-01-15 12:42:15 -08:00
Luke Rogers 4f5a8e3ed5 Merge pull request #193 from CHCMATT/patch-1
Update itemids.txt to Snapshot 14w02c
2014-01-15 12:41:38 -08:00
Luke Rogers d7195dce0e Merge pull request #197 from daboross/patch-3
Fix the correction plugin
2014-01-15 12:41:30 -08:00
Luke Rogers efef951501 Merge pull request #195 from daboross/patch-2
Add support for multiple channels to .join and .leave
2014-01-15 12:41:19 -08:00
Luke Rogers ae1c9d0788 Merge pull request #198 from daboross/patch-4
Fix twitch plugin - Don't assume that data has any elements
2014-01-15 12:41:09 -08:00
Dabo Ross 8b6647f521 Don't assume that data has any elements 2014-01-14 00:19:50 -08:00
Dabo Ross aecf61746f Fix correction to actually work, and change format 2014-01-14 00:15:27 -08:00
Dabo Ross c5765cc5f6 Add support for multiple channels to .join and .leave 2014-01-13 23:58:46 -08:00
Luke Rogers 75908c6ab6 Merge pull request #194 from nathanblaney/patch-4
Updated Mark :)
2014-01-13 04:20:38 -08:00
Nathan Blaney 0ae8d3d5f9 Much better 2014-01-13 20:11:01 +11:00
Luke Rogers 6f6779dcc5 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2014-01-13 20:58:02 +13:00
thenoodle68 62a92b104b whoops 2014-01-13 20:57:33 +13:00
thenoodle68 a8bf157ced Mark Harmon
GLORY TO MARK HARMON
2014-01-13 20:57:26 +13:00
Matt Anthony d17234828c Update itemids.txt to Snapshot 14w02c
Remove ALL items and re-add EVERYTHING up to Snapshot 14w02c.
2014-01-12 17:36:59 -05:00
Luke Rogers d10dcbac68 Merge pull request #191 from CHCMATT/patch-3
Update recipes.txt
2014-01-05 12:38:31 -08:00
Nathan Blaney 1febd1362d Added pycrypto requirement 2014-01-04 15:19:49 +11:00
Matt Anthony 1f403bcd7a Update recipes.txt
Add all 1.6 and 1.7 blocks.
2014-01-01 17:53:37 -05:00
Luke Rogers 6035f1b1fc test 2013-12-12 19:00:14 +13:00
Luke Rogers e29ea1c613 moved to new util structure from refresh 2013-12-12 15:13:32 +13:00
Luke Rogers b25b8d6cec I'm an idiot 2013-12-12 15:06:29 +13:00
Luke Rogers cda99f1852 tweaks 2013-12-11 17:31:57 +13:00
Luke Rogers e94c607b3e documentation! 2013-12-11 17:27:42 +13:00
Luke Rogers 6decd65a19 split format_time out to a util module! 2013-12-11 17:17:56 +13:00
Luke Rogers b65e6e5a75 Don't show URL if it just parsed a URL 2013-12-11 17:11:34 +13:00
Luke Rogers fdbcb967bb totally removed karma 2013-12-04 14:12:50 +13:00
Luke Rogers 8b8623eb9e I fix, you tube? 2013-12-03 22:54:38 +13:00
Luke Rogers 57e53e8eb7 *dance* 2013-12-02 23:16:34 +13:00
Luke Rogers be3df6718f ianalmore 2013-12-02 23:10:08 +13:00
Luke Rogers 1e22ca4995 ianal 2013-12-02 23:06:26 +13:00
Luke Rogers 4236b7bc29 and this 2013-12-02 23:04:36 +13:00
Luke Rogers 97e7741434 modular! 2013-12-02 23:03:29 +13:00
Luke Rogers 3df53f95a8 re-added .randomplugin @blha303 2013-12-02 22:55:58 +13:00
Luke Rogers 91c827a03b unfinished 2013-12-01 22:53:40 +13:00
Luke Rogers fb84e17e34 Merge pull request #188 from daboross/patch-5
Simplify permissions checking and only print value if user is in group
2013-11-30 23:50:47 -08:00
Luke Rogers 3e073c8278 a bunch of things 2013-12-01 20:44:04 +13:00
Luke Rogers 8317ba0920 only ping once 2013-12-01 20:10:53 +13:00
Luke Rogers bb73e70112 split commands properly 2013-12-01 19:37:12 +13:00
Luke Rogers 017fd4fc2e simple :D 2013-12-01 19:28:24 +13:00
Luke Rogers b3a8703d15 redesigned bukkit plugin search (still needs work and readding random plugin) 2013-12-01 19:11:39 +13:00
Luke Rogers a37fc245d0 added variable accuracy to the time_format function (really should move this, huh) 2013-12-01 18:38:08 +13:00
Dabo Ross 2eb6112f2f Improve permissions checking 2013-11-30 10:44:52 -08:00
Luke Rogers a59becca73 . 2013-12-01 00:56:07 +13:00
Luke Rogers 77459a0879 plurals! 2013-12-01 00:49:09 +13:00
Luke Rogers b489b9d3c7 Merge remote-tracking branch 'noodle/patch-5' into develop
Conflicts:
	plugins/youtube.py - fixed
2013-12-01 00:42:56 +13:00
Luke Rogers 8b18c33ce5 stuff 2013-12-01 00:39:40 +13:00
thenoodle68 cdf8922f4d Added decades and centuries
Will need slightly different logic for different naming conventions.
2013-11-30 19:33:12 +08:00
Luke Rogers f55c8f8d4e improved the time format function some more 2013-11-30 23:18:45 +13:00
Luke Rogers 78912b908f this mostly works (should we make those time functions another module?) 2013-11-30 21:16:44 +13:00
Luke Rogers fb08870f4a bunch'o'stuff 2013-11-30 19:19:04 +13:00
Luke Rogers 2fa3a5a015 er 2013-11-30 17:40:09 +13:00
Luke Rogers 6b4f3ac546 Merge pull request #186 from daboross/patch-4
Remove executable permissions
2013-11-29 19:48:45 -08:00
Dabo Ross 323d045868 Remove executable permissions 2013-11-29 19:47:40 -08:00
Luke Rogers 4ccfd1e3ca Newegg URL parser? :D 2013-11-30 16:37:01 +13:00
Luke Rogers 834cbaabd8 *puffs* 2013-11-30 00:21:26 +13:00
Luke Rogers d3fbf1bc80 bitbitbit 2013-11-30 00:05:55 +13:00
Luke Rogers 3825c94c9d im feeling bold 2013-11-29 22:08:38 +13:00
Luke Rogers 9c7e2074f5 comments! 2013-11-29 21:59:48 +13:00
Luke Rogers 8d7f853426 Furthere tweaks to newegg 2013-11-29 20:40:18 +13:00
Luke Rogers 49bb446c27 Added newegg item search command! 2013-11-29 20:00:41 +13:00
Luke Rogers 44c7bceaf4 workaround 2013-11-29 18:16:17 +13:00
Luke Rogers 0bb1574ebd plurals and fanciness 2013-11-29 16:35:41 +13:00
Luke Rogers 85d8c4e5cb switched youtube to like/dislike 2013-11-29 16:30:06 +13:00
Luke Rogers 2d5208cbde commacommacommacommacommacommacomma 2013-11-29 16:18:18 +13:00
Luke Rogers d78f96b3ec . 2013-11-29 11:55:07 +13:00
Luke Rogers 9bc72bc57f more mcping stuff 2013-11-29 11:45:18 +13:00
Luke Rogers 8d42933554 Merge pull request #181 from daboross/patch-3
Update minecraft_ping.py to 1.7
2013-11-28 14:26:05 -08:00
Luke Rogers e75fe73563 wop 2013-11-29 11:18:25 +13:00
Luke Rogers 29b25e0b1f Tweaks to twitter 2013-11-29 11:13:11 +13:00
Luke Rogers 2b5f5e925d v 2013-11-29 01:14:58 +13:00
Luke Rogers f95b607914 cbf 2013-11-29 01:06:12 +13:00
Luke Rogers 181b43df71 gold k 2013-11-29 01:03:34 +13:00
Luke Rogers 1ecdd3a246 magic? 2013-11-29 00:36:54 +13:00
Luke Rogers 13c7e5915b rouunndddinng 2013-11-29 00:04:28 +13:00
Luke Rogers 9c94cb01f9 Merge pull request #185 from thenoodle68/patch-4
Add litecoin command reading from BTC-E
2013-11-28 02:53:01 -08:00
thenoodle68 2e66e03c7d Add litecoin command reading from BTC-E 2013-11-28 18:48:11 +08:00
Dabo Ross a5a5fd2dfb Update minecraft_ping to 1.7, add commands mcping6 and mcping7 for version-specific pings, having mcping try 7 and revert back to 6 is failed. 2013-11-27 03:49:06 -08:00
Andy Eff cbe4e3177e uhh 2013-11-27 17:54:09 +13:00
Luke Rogers f51bcf4ecf Merge pull request #183 from bbeng89/develop
Bug fixes in reddit and github plugins
2013-11-26 19:51:05 -08:00
Luke Rogers 439ef0ba1c Merge pull request #180 from daboross/patch-2
Format all plugins to pep8 guidelines
2013-11-26 19:50:51 -08:00
Blake Bengtson b2c9f46d78 Fixed bug with ghissues truncate function. (newlines were causing problems) 2013-11-26 16:32:54 -06:00
Blake Bengtson 186f272062 Fixed bug with github plugin (string formatting was throwing exceptions) 2013-11-26 16:23:59 -06:00
Blake Bengtson df6ee28462 Fixed bug with reddit plugin. 2013-11-26 16:07:53 -06:00
Dabo Ross 99fe34a0b1 Format everything to pep8 guidelines 2013-11-12 18:49:29 +01:00
Luke Rogers cd4b65de3d Moved calculation to the wolframalpha plugin (the old google calculator plugin no longer works correctly, sorry!(=) 2013-11-11 10:01:45 +13:00
Luke Rogers b6d1620cec Merge pull request #172 from blha303/patch-15
soundc.py - Wow, how did that happen?
2013-11-10 12:53:55 -08:00
Luke Rogers 0a19fd9347 Merge pull request #177 from RobertClarke/patch-1
More flirts
2013-11-10 12:53:32 -08:00
Luke Rogers 3d739483de switch to integrated YQL code 2013-11-11 09:47:46 +13:00
Luke Rogers 12e2a445d7 fixed stock from skybot! 2013-11-11 09:13:15 +13:00
RobertClarke d58a8b5c65 More flirts 2013-11-09 19:29:00 -08:00
Luke Rogers 5e7d1e9c92 Merge pull request #175 from thenoodle68/patch-2
Remove steam api key
2013-11-08 23:48:27 -08:00
thenoodle68 21eb5760fd Remove steam api key 2013-11-09 15:44:02 +08:00
Steven Smith b6ce9b7e50 Wow, how did that happen? 2013-11-03 05:08:09 +08:00
Luke Rogers 5258e13de2 Fixes! 2013-10-09 10:49:16 +13:00
Luke Rogers 12203d2580 -.- 2013-10-08 11:33:00 +13:00
Luke Rogers b5a2497b00 fix correction 2013-10-08 11:32:17 +13:00
Luke Rogers 05782766e9 fixed unicode 2013-10-07 21:11:01 +13:00
Luke Rogers 853b4b7db8 helptext 2013-10-07 01:20:36 +13:00
Luke Rogers b05056ff28 Update utility.py 2013-10-07 01:12:12 +13:00
Luke Rogers ce0063f4aa Merge pull request #168 from blha303/patch-13
Fix github.py
2013-10-05 19:20:00 -07:00
Luke Rogers 2e20487676 Merge pull request #167 from nathanblaney/patch-1
Added reverse to utility.py
2013-10-05 19:19:49 -07:00
Steven Smith 436dfc356c Dammit noodle 2013-10-05 21:11:52 +08:00
Nathan Blaney a42b8513c6 Better English in reverse 2013-10-05 22:59:07 +10:00
Nathan Blaney d83d82978e Added reverse to utility.py 2013-10-05 22:49:52 +10:00
Luke Rogers 8a6803a22a Merge pull request #165 from thenoodle68/rainfix
Rainbow shouldn't colour spaces
2013-10-04 03:44:54 -07:00
Fletcher Boyd c308b7dcb5 Rainbow fix 2013-10-04 17:49:02 +08:00
Luke Rogers c9c3fbf671 properly fixed notices 2013-10-04 11:40:28 +13:00
Luke Rogers a2c5964438 Hell hath no fury like an IRC user scorned. (fixed notices) 2013-10-03 21:47:35 +13:00
Luke Rogers b6c3a233eb fixed CTCP 2013-10-02 00:09:57 +13:00
Luke Rogers cfe9ebd054 Merge branch 'feature/encrypt' into develop 2013-10-01 20:49:35 +13:00
Luke Rogers a6130ab780 Merge commit '47eae6255989055440b45cfe667c9a6f8a92ce27' into develop 2013-10-01 20:49:16 +13:00
Luke Rogers dd40b71252 moved bot.py to cloudbot.py 2013-10-01 17:33:48 +13:00
Luke Rogers cd30b053f6 moar 2013-10-01 16:57:20 +13:00
Luke Rogers 42a72f068e More refactoring! Break everything! 2013-10-01 16:55:18 +13:00
Luke Rogers b5ae12f50b Merge branch 'develop' into feature/encrypt 2013-10-01 15:49:38 +13:00
Luke Rogers 51c866de6d commented core more 2013-10-01 15:48:22 +13:00
Luke Rogers 72babfceb2 refactored me() to action() 2013-10-01 15:41:54 +13:00
Luke Rogers 47eae62559 Tidied code some more 2013-10-01 14:57:02 +13:00
Luke Rogers 46f571382c Comments 2013-10-01 13:38:00 +13:00
Luke Rogers 72dce244b4 anti-asshat 2013-10-01 13:18:41 +13:00
Luke Rogers 2ae2a8575a OTT encryption for silly secret messages 2013-10-01 12:17:08 +13:00
Luke Rogers b38c540bf3 Added prototype plugin 2013-10-01 11:54:09 +13:00
Luke Rogers 52f6260e1c fixed 2013-10-01 11:53:15 +13:00
Luke Rogers 651db7168f dfsdf 2013-10-01 11:42:36 +13:00
Luke Rogers dd50cb4a36 fixes 2013-10-01 11:40:04 +13:00
Luke Rogers 839871f636 Added RAINBOWS 2013-10-01 10:03:46 +13:00
Luke Rogers af9f024d63 no message 2013-10-01 04:08:13 +13:00
Luke Rogers d673f8d15c Added escape and unescape 2013-10-01 03:42:55 +13:00
Luke Rogers f8ad033f8e Added more text tools 2013-10-01 03:32:06 +13:00
Luke Rogers 52b14b367a Made new utility plugin with hash, length and other text formatting commands 2013-10-01 03:26:40 +13:00
Luke Rogers a16b1776f8 Added simple ROT13 command 2013-10-01 03:19:00 +13:00
Luke Rogers a45d470363 Added NSFW alert to reddit.py
\
2013-10-01 03:10:19 +13:00
Luke Rogers 9b92d73f3a reddit and imgur fixes 2013-10-01 03:06:53 +13:00
Luke Rogers 0abac29523 Added NSFW filter, and made command grab random images if no subreddit defined 2013-10-01 03:03:03 +13:00
Luke Rogers 3a142e4810 final tweaks 2013-10-01 02:37:00 +13:00
Luke Rogers 4f2c690b2d Added support for reading albums, other fixes 2013-10-01 02:33:20 +13:00
Luke Rogers a49bcc881c Add imgur prototype 2013-10-01 01:53:57 +13:00
Luke Rogers bfd600cf49 Revamped reddit plugin with search command, inspired by @blha303 :) 2013-10-01 00:38:12 +13:00
Luke Rogers f9f15f3597 Merge pull request #164 from blha303/patch-12
aww plugin, retrieves random imgur link from /r/aww front page
2013-09-30 03:44:47 -07:00
Steven Smith aea91cc33f aww plugin, retrieves random imgur link from /r/aww front page 2013-09-30 18:42:51 +08:00
Luke Rogers 7474904e97 I said how to fix them 2013-09-27 20:48:01 +12:00
Luke Rogers a5d5845faf Merge pull request #163 from thenoodle68/develop
Quote fix
2013-09-27 01:47:20 -07:00
Fletcher Boyd 92e61a5348 Remove broken double tuple 2013-09-27 11:57:52 +08:00
Fletcher Boyd 57d9ec985a Merge remote-tracking branch 'upstream/develop' into develop 2013-09-27 11:57:01 +08:00
Luke Rogers afa81ae7c4 unicode everything 2013-09-23 11:47:03 +12:00
Luke Rogers 80d976ba23 Merge pull request #160 from blha303/patch-10
Fix youtube.py Uploader name to use display name instead of username
2013-09-21 06:36:22 -07:00
Steven Smith 764a74a3ea Fixed uploader name display for Youtube's new display names 2013-09-21 20:27:20 +08:00
Steven Smith 5867cb05c7 Update youtube.py 2013-09-21 20:24:39 +08:00
Steven Smith f5e4b67777 Fix youtube.py Uploader name to use display name instead of username 2013-09-21 20:18:08 +08:00
Luke Rogers d3e5099dab silly attempt to make calc plugin last longer before google totally breaks it
cookies are an attempt to make it less likely to realise cloudbot is a bot, and the IE user agent is to force it to use the legacy HTML we can actually parse
2013-09-19 10:58:22 +12:00
Luke Rogers dabf61a520 disabled broken plugin 2013-09-19 10:44:46 +12:00
Luke Rogers c0b3285c4a Fixed namegen
I need to redesign TextGenerator a bit, I kinda hacked it to do two things and it's not the most elegant.
2013-09-19 10:42:44 +12:00
Luke Rogers f98774032f Simplify code and change output string to unicode
I wish I had Python3, the whole unicode/normal string thing sucks.
2013-09-19 10:38:42 +12:00
Luke Rogers 45330ddfb4 MORE 2013-09-19 10:29:39 +12:00
Luke Rogers 348de62f17 I'm a fucking idiot 2013-09-18 15:44:04 +12:00
Luke Rogers 5b1258f544 Fix pls? 2013-09-16 13:37:47 +12:00
Luke Rogers 483226d2ad TextGenerator now supports a single string as a part 2013-09-16 13:26:51 +12:00
Fletcher Boyd 0030669682 Merge remote-tracking branch 'upstream/develop' into develop
Conflicts:
	plugins/karma.py
2013-09-15 19:22:33 +08:00
Luke Rogers d5163a846a Updated .kill to use TextGenerator! :) 2013-09-15 23:00:53 +12:00
Luke Rogers 00f7e35a24 Thanks cracks 2013-09-14 01:15:36 +12:00
Luke Rogers e5038156ea Merge pull request #159 from blha303/patch-10
Fixed!
2013-09-13 03:28:45 -07:00
Steven Smith a69c4eceb3 Update valvesounds.py 2013-09-13 17:45:13 +08:00
Steven Smith b460fb2fd2 Update valvesounds.py 2013-09-13 17:30:01 +08:00
Steven Smith e8947a603b Update valvesounds.py 2013-09-13 17:28:51 +08:00
Steven Smith ae258e6c37 Update valvesounds.py 2013-09-13 17:27:18 +08:00
Luke Rogers 59d615aa88 rename! 2013-09-13 21:18:45 +12:00
Luke Rogers 8b629ee886 Merge pull request #158 from blha303/patch-9
Updated site search function, fixing associated plugin
2013-09-13 02:17:36 -07:00
Steven Smith 1bba6262bc Updated site search function, fixing associated plugin 2013-09-13 17:17:15 +08:00
Luke Rogers d9f613f6f4 Update slaps.json 2013-09-13 10:32:09 +12:00
Luke Rogers cb7f9b736f fix? 2013-09-13 00:33:45 +12:00
CafogenMod ecab6076ea update restart command 2013-09-12 23:51:33 +12:00
Luke Rogers cbcf1dc4b5 more stuff @cybojenix 2013-09-12 23:05:15 +12:00
Luke Rogers 2be0c46b89 made slap use the new TextGenerator class 2013-09-12 22:46:43 +12:00
Luke Rogers 15e7825125 Moved generation logic out of namegen.py 2013-09-12 20:47:39 +12:00
Luke Rogers 8e545b3a31 Fixed namegen 2013-09-12 11:58:00 +12:00
Luke Rogers ea39a6fbb9 no 2013-09-12 00:12:50 +12:00
Luke Rogers 9a296d4076 karma update 2013-09-12 00:10:42 +12:00
Luke Rogers 2d06a1fc4a patched! 2013-09-11 22:59:13 +12:00
Fletcher Boyd 1b3d3b51e7 Added better karma check. 2013-09-11 17:41:59 +08:00
Luke Rogers 5c09ff6967 Ignore votes with spaces 2013-09-11 16:20:20 +12:00
Luke Rogers dde9b97223 tweaaks 2013-09-11 13:44:02 +12:00
Luke Rogers 931eb1f51a oops 2013-09-11 12:25:08 +12:00
Luke Rogers 10d235623c Removed debug line that was printing the time module
?_?
2013-09-11 11:02:06 +12:00
Luke Rogers 45ac28b6a6 added message when you try to vote on yourself @blha303 2013-09-11 10:58:33 +12:00
Luke Rogers a714354d69 Re-added old karma plugin, now with more features 2013-09-11 10:54:38 +12:00
Luke Rogers 4160015e61 xrange is correct in this case 2013-09-11 02:28:43 +12:00
Luke Rogers bf49b374eb Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-09-10 19:32:36 +12:00
Luke Rogers 273ca05858 Strip HTML from online status. @Red_M 2013-09-10 19:30:40 +12:00
Luke Rogers 0655f6d0bb this never existed 2013-09-10 17:15:04 +12:00
Luke Rogers 178ff6f4e1 untest 2013-09-10 15:40:16 +12:00
Luke Rogers 92eca3844e reverted changes to seen.py for now, need to work out privacy stuff 2013-09-10 15:35:26 +12:00
Luke Rogers 27bd43b5ec Merge branch 'patch-1' of https://github.com/nathanblaney/CloudBot into nathanblaney-patch-1 2013-09-10 15:32:14 +12:00
Luke Rogers 79f06b034e Merge branch 'patch-6' of https://github.com/blha303/CloudBot into blha303-patch-6 2013-09-10 15:26:51 +12:00
Luke Rogers 83cb28283b More pythonic function name 2013-09-10 14:59:45 +12:00
Luke Rogers a8255723ba renamed p2sounds 2013-09-10 14:58:00 +12:00
Luke Rogers 52f8fc97d0 test 2013-09-10 14:55:00 +12:00
Luke Rogers 06e78b7871 PEP-8 2013-09-10 14:53:25 +12:00
Luke Rogers b42aac00d5 if the user has no location/description, don't show it 2013-09-10 14:49:33 +12:00
Luke Rogers 285c61fe11 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-09-10 13:36:02 +12:00
Luke Rogers a9c084a14d added adminonly to the default permissions set 2013-09-10 13:35:43 +12:00
Luke Rogers 2ef0579fe6 Merge pull request #155 from blha303/patch-8
p2sounds - Lyrics formatting
2013-09-09 18:30:27 -07:00
Luke Rogers a157a250be Yes Fletcher, there was a good reason 2013-09-10 13:29:38 +12:00
Luke Rogers 415740a399 resolve merge conflict 2013-09-10 12:02:24 +12:00
Luke Rogers 1f699c8f00 If data already exists for a user, return that and wait until after the command has finished to trigger an update 2013-09-10 12:00:29 +12:00
Steven Smith 4cd74ae3fd p2sounds - Lyrics formatting 2013-09-09 13:50:06 +08:00
Luke Rogers fe220ffc93 Merge pull request #154 from blha303/patch-7
Re-add portal2sounds plugin
2013-09-08 22:35:54 -07:00
Steven Smith 803ca5da9a Re-add portal2sounds plugin
Now with 100% less portal2sounds.com interaction!
2013-09-09 13:27:18 +08:00
Steven Smith 00368f59b0 Admin-only command to upload plugins to hastebin 2013-09-08 13:03:11 +08:00
Luke Rogers d3d36891e7 Merge pull request #150 from thenoodle68/develop
Small corrections.
2013-09-07 08:53:34 -07:00
Luke Rogers e644a0a0ca fml 2013-09-08 03:50:53 +12:00
Fletcher Boyd efee5072ad ily 2013-09-07 23:44:27 +08:00
Fletcher Boyd 83faace7f7 Merge remote-tracking branch 'upstream/develop' into develop 2013-09-07 23:31:29 +08:00
Luke Rogers 143cd8dc96 bot restart needed. added support for timeouts to http.py, adjusted steam_calc timeout 2013-09-08 03:26:34 +12:00
Luke Rogers 909306cfbe add temporary workaround for missing user issue 2013-09-08 03:11:27 +12:00
Luke Rogers 8ebf1e24ee Those uppercase dict keys were annoying the hell out of me 2013-09-08 02:43:11 +12:00
Luke Rogers 63cf1f0514 few more comments 2013-09-08 02:37:47 +12:00
Luke Rogers b40b4640d8 Added brand new steam_calc.py plugin 2013-09-08 02:34:55 +12:00
Fletcher Boyd 5efca90faa Good catch there luke. 2013-09-07 19:07:22 +08:00
Fletcher Boyd 1363e27475 Added bot modes to the default config. 2013-09-07 17:10:16 +08:00
Luke Rogers fac18416a8 Merge pull request #149 from thenoodle68/util
Colour formatting.
2013-09-06 02:14:43 -07:00
Fletcher Boyd f8e6ec1e9c Merge remote-tracking branch 'upstream/develop' into util 2013-09-06 17:08:23 +08:00
Fletcher Boyd c2d021a07a better name. 2013-09-06 17:06:52 +08:00
Luke Rogers 54d6453aa4 denoodleification 2013-09-06 21:05:05 +12:00
Fletcher Boyd 893f621dd0 Added clear, updated err. 2013-09-06 16:10:48 +08:00
Fletcher Boyd d29b3c313f Fixing dict.update() 2013-09-06 15:40:08 +08:00
Fletcher Boyd 75d4af1393 ircformat.raw makes more sense with the addition of ircformat.err. 2013-09-06 15:10:39 +08:00
Fletcher Boyd 5f87bf0e76 Added base context styling. 2013-09-06 15:06:00 +08:00
Fletcher Boyd 2fb0f811b8 Docstring and typo fix. 2013-09-06 14:59:07 +08:00
Fletcher Boyd 07b5abff7b bb moved to more descriptive rep. 2013-09-06 14:57:26 +08:00
Fletcher Boyd 14530f07f1 Added text set. 2013-09-06 14:54:50 +08:00
Fletcher Boyd 2103c64dd5 Added multiple code sets. Future proofed code set adding. 2013-09-06 14:23:33 +08:00
Fletcher Boyd d9324eaf95 bbcode style formatting. 2013-09-06 14:12:21 +08:00
Luke Rogers 382b76ca26 Merge pull request #148 from thenoodle68/develop
Better help, fixed bitcoin, bones of better steam.
2013-09-05 20:59:00 -07:00
Fletcher Boyd d39e101f45 Help can return over two lines. 2013-09-06 11:51:01 +08:00
Fletcher Boyd 363d0ba6d9 I should check data more often. 2013-09-06 11:20:34 +08:00
Fletcher Boyd c08d3c2daf Merge remote-tracking branch 'upstream/develop' into develop 2013-09-06 11:12:21 +08:00
Luke Rogers 847f1e468d Merge pull request #147 from blha303/patch-5
portal2sounds.com has banned Cloudbot's user agent.
2013-09-05 20:10:14 -07:00
Steven Smith 3d4bd6a694 portal2sounds.com has banned Cloudbot's user agent. 2013-09-06 10:32:33 +08:00
Luke Rogers 8a83eb9b5b Removed references to a function in spotify.py that doesn't exist 2013-09-06 10:01:16 +12:00
Fletcher Boyd 20e96e1e07 Added (currently unused) method for retrieving steam data through steam. 2013-09-05 18:17:05 +08:00
Luke Rogers 1610c14c6f NOOOOODDDDLLLLLEEEEEE 2013-09-05 21:15:59 +12:00
Luke Rogers bc2612e9ae updating this monster 2013-09-05 20:50:41 +12:00
Luke Rogers 29ac513c2b I
'm OCD about formatting. 'nuff said
2013-09-05 20:24:13 +12:00
Luke Rogers 74fc62139c this might actually work 2013-09-05 20:19:35 +12:00
Luke Rogers f96a975b70 Merge pull request #146 from thenoodle68/develop
pullderp
2013-09-05 01:14:20 -07:00
Fletcher Boyd 8f789222b1 I'm a muppet. 2013-09-05 16:12:41 +08:00
Fletcher Boyd f12066df0a rdio api added to config. 2013-09-05 16:09:27 +08:00
Luke Rogers 49e306568d Thou shalt not bolden links 2013-09-05 20:08:25 +12:00
Luke Rogers b6e9b175db did some math to calcuate offset, now spellcheck only needs to update once :) 2013-09-05 18:31:33 +12:00
Luke Rogers 033dd8af12 please? 2013-09-05 18:21:27 +12:00
Nathan Blaney 114975d058 Added hypen support to tell
For example "~tell Mu5tank05-mc hello?"
2013-09-05 16:04:03 +10:00
Nathan Blaney 6b3b4fc562 Added support for checking in a set channel
For example "~seen WizardCM #minecraft"
2013-09-05 16:00:49 +10:00
Luke Rogers af2382aea5 test 2013-09-05 17:51:24 +12:00
Luke Rogers 1dbf309971 changed spellcheck.py to use SpellChecker() for sentences 2013-09-05 17:38:25 +12:00
Luke Rogers 9efedde734 denoodled seen, this should fix it all 2013-09-05 16:28:37 +12:00
Luke Rogers 8e121f5b5f wtf 2013-09-05 16:22:14 +12:00
Luke Rogers 8881f694fa denoodle the core 2013-09-05 16:17:39 +12:00
Luke Rogers f788af8d55 Merge pull request #143 from thenoodle68/develop
Formatting and other things.
2013-09-04 21:10:38 -07:00
Fletcher Boyd 00e3fb2dc1 Merge remote-tracking branch 'upstream/develop' into develop 2013-09-05 12:04:47 +08:00
Luke Rogers d7ea20cd3b Fixed up user URL 2013-09-05 16:01:01 +12:00
Luke Rogers 5844d914de Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-09-05 15:54:54 +12:00
Luke Rogers 80dd3ad573 added open source report card plugin 2013-09-05 15:54:35 +12:00
Fletcher Boyd 5a586bb373 Merge remote-tracking branch 'upstream/develop' into develop 2013-09-05 10:42:03 +08:00
Fletcher Boyd 1ce777a5e4 Core format string changes. 2013-09-05 10:41:44 +08:00
Fletcher Boyd 015dd93df3 last round of .format conversion for string formatting. 2013-09-05 10:36:25 +08:00
Fletcher Boyd 0aa2185ede more .format. 2013-09-05 10:11:18 +08:00
Fletcher Boyd 7ab4f756fe .format 2013-09-05 09:46:49 +08:00
Luke Rogers 6c4d7db976 Removed debug code 2013-09-05 13:16:08 +12:00
Luke Rogers 06546ffdd9 Merge pull request #142 from thenoodle68/develop
Fix cypher
2013-09-04 18:03:15 -07:00
Fletcher Boyd 2812569593 .format 2013-09-05 09:03:01 +08:00
Fletcher Boyd a211115b7e I'm sure there was a reason this was complicated. 2013-09-05 08:53:07 +08:00
Fletcher Boyd 8c60a923ba Rewrite 2013-09-05 08:42:40 +08:00
Luke Rogers 304a2bed00 Merge pull request #141 from thenoodle68/develop
Fixing typos.
2013-09-04 16:58:27 -07:00
Fletcher Boyd bc1062e8d6 Fixing typos. 2013-09-05 07:51:42 +08:00
Luke Rogers a92209119d Merge pull request #140 from thenoodle68/develop
Added option to authenticate as another nickserv user.  op.py changes.
2013-09-04 16:48:51 -07:00
Fletcher Boyd 5a8b2c2825 Corrected typo in unmute, added lock/unlock. 2013-09-05 07:45:34 +08:00
Fletcher Boyd b3c08a33da Added mode function for channel modes. Added mute/unmute. 2013-09-05 07:44:29 +08:00
Fletcher Boyd 73aef2e9ae Added option to authenticate as another nickserv user. 2013-09-05 07:28:47 +08:00
Luke Rogers 6247409906 moved strip_html from http to text 2013-09-05 11:00:04 +12:00
Luke Rogers 8b23ba9c12 Merge pull request #139 from thenoodle68/develop
Fix kicking with a reason in op.py
2013-09-04 15:33:39 -07:00
Luke Rogers 4460254f28 moved WA to try_isgd() 2013-09-05 10:33:03 +12:00
Fletcher Boyd 9eeebe1a9d Fix kicking with a reason in op.py 2013-09-05 06:30:58 +08:00
Luke Rogers e061427207 a few small tweaks to puush 2013-09-05 10:08:36 +12:00
Luke Rogers 0f488665aa wrapped a long line 2013-09-05 09:59:50 +12:00
Luke Rogers 059024cb61 removed test server from minecraft_status 2013-09-05 09:54:43 +12:00
Luke Rogers a44e0bb7bf Merge pull request #138 from thenoodle68/develop
Pull some more noodlecode
2013-09-04 14:44:03 -07:00
Fletcher Boyd 4b4541dd99 things look better in threes. 2013-09-05 00:25:46 +08:00
Fletcher Boyd d5a5237fb8 Formatting and updating docstring. 2013-09-04 23:50:57 +08:00
Fletcher Boyd 253ffaafda Added multiword support. 2013-09-04 23:48:56 +08:00
Fletcher Boyd 9d6aef731e Update docstring 2013-09-04 22:53:18 +08:00
Fletcher Boyd d58646628c Add random puu.sh fetcher. 2013-09-04 22:49:55 +08:00
Luke Rogers fabda30543 Merge pull request #137 from thenoodle68/develop
Fixing mistakes and mcstatus update.
2013-09-04 07:11:35 -07:00
Fletcher Boyd df9fe0e8ac Geocities data doesn't need to be committed. 2013-09-04 21:55:06 +08:00
Fletcher Boyd bc2362e6a6 Merge commit '1a3094242b9f1411963ee1e8003e833e9a27646a' into develop 2013-09-04 21:54:06 +08:00
Fletcher Boyd 33c6ee6f19 spaaace 2013-09-04 21:36:35 +08:00
Fletcher Boyd f54f0edff8 Comment was commenting the wrong code. 2013-09-04 21:31:36 +08:00
Fletcher Boyd 706ddbfbe9 Shortened mcstatus output. 2013-09-04 21:31:07 +08:00
Luke Rogers 270785a31a Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-09-05 00:47:16 +12:00
Luke Rogers 1a3094242b denoodled another plugin 2013-09-05 00:46:52 +12:00
Fletcher Boyd d6bdf3ab38 Possible fix for non alphanumeric characters, needs testing. 2013-09-04 20:13:45 +08:00
Fletcher Boyd 397842f518 More formatting. 2013-09-04 20:13:03 +08:00
thenoodle68 caf45fbae2 Merge pull request #1 from ClouDev/develop
this works? :/
2013-09-04 04:18:43 -07:00
Luke Rogers cc0231e849 Merge pull request #136 from thenoodle68/develop
This is what happens when you don't test things
2013-09-04 04:15:52 -07:00
Luke Rogers 99b14bac59 Updated CONTRIBUTORS. You are all great! 2013-09-04 23:06:44 +12:00
Fletcher Boyd 7c6453be1e Fixed flawed logic in word construction. 2013-09-04 19:05:39 +08:00
Luke Rogers f85bc3e935 unborked 2013-09-04 22:59:58 +12:00
Fletcher Boyd 2457f6da00 So apparently you do need inp. 2013-09-04 18:56:58 +08:00
Luke Rogers 242ba0d18d Merge pull request #135 from thenoodle68/develop
Lots of formatting fixes!
2013-09-04 03:51:52 -07:00
Fletcher Boyd b8d9610e56 Add ignore for PyCharm. 2013-09-04 18:33:16 +08:00
Fletcher Boyd fa97d4659c Fixed formatting and removed unused imports. 2013-09-04 18:32:17 +08:00
Fletcher Boyd fb62640ccc Possibly broke, fixed formatting. 2013-09-04 18:31:46 +08:00
Fletcher Boyd b08bc570d1 Fixed formatting and changed string construction. 2013-09-04 18:30:48 +08:00
Fletcher Boyd 4069dd21a3 Fixed formatting. 2013-09-04 18:30:04 +08:00
Fletcher Boyd 146ae3c279 Formatting, updated copyright. 2013-09-04 18:16:57 +08:00
Luke Rogers 3c0ba0bdd2 added isup 2013-09-04 21:28:10 +12:00
Luke Rogers 5e161486ff unstandardised that one bit 2013-09-04 20:30:26 +12:00
Luke Rogers 13d284a861 standarised format of drama.py to match other plugins 2013-09-04 20:27:46 +12:00
Luke Rogers 8769b97dc0 made qr.py use the google API directly, also did a neat thing with a dictionary 2013-09-04 20:14:14 +12:00
Luke Rogers 488d00e758 slight tweak to URL fetching in stock.py 2013-09-04 20:00:52 +12:00
Luke Rogers 543a1cd4d7 added alternate truncate method 2013-09-04 19:52:38 +12:00
Luke Rogers 6de14f33e3 Google translate is back, but you need a paid API key 2013-09-04 19:42:08 +12:00
Luke Rogers 94b6026b3f Merge pull request #131 from blha303/patch-1
Fix stock.py, add company searching
2013-09-03 04:44:21 -07:00
Luke Rogers 6a325b5333 Merge pull request #133 from blha303/patch-6
thanks :)
2013-09-03 04:42:48 -07:00
Steven Smith bc0eb32d9b Hulu command help 2013-09-03 19:41:53 +08:00
Luke Rogers 9fadc40d97 Merge pull request #132 from blha303/patch-5
Create hulu.py
2013-09-03 04:39:44 -07:00
Steven Smith 4fb4e3c1fb Create hulu.py 2013-09-03 19:39:02 +08:00
Steven Smith 4129d2d889 Fix stock.py, add company searching 2013-09-03 17:37:03 +08:00
Luke Rogers 4e0a0b9d6d Merge pull request #129 from nasonfish/patch-2
Make <url> a Factoid post-processor. Now we can make our own web server api things and use them without having to make a plugin
2013-09-02 20:53:43 -07:00
Daniel Barnes 0e6e744605 Make <url> a Factoid post-processor. This allows us to use text-web-api-things that are sightly more dynamic 2013-09-02 21:19:47 -06:00
Luke Rogers 2089a53c50 Merge pull request #121 from blha303/patch-8
Add catch for git.io assigning the same ID twice, provide alternative custom url
2013-09-02 16:19:24 -07:00
Luke Rogers b499c3848e Merge pull request #125 from TheFiZi/patch-3
Added handling of exponents
2013-09-02 16:18:59 -07:00
Luke Rogers 201589e7ec Merge pull request #126 from nasonfish/patch-1
Added a plugin to use domai.nr's API
2013-09-02 16:18:48 -07:00
Luke Rogers 2793fe4895 Merge pull request #128 from blha303/patch-10
Lyrics and portal2sounds.com/tf2sounds.com searching
2013-09-02 16:18:28 -07:00
Luke Rogers aee1974264 Merge pull request #127 from blha303/patch-9
Far less page scraping, far more API. (twitch.py)
2013-09-02 16:18:15 -07:00
Steven Smith 28c449bde5 Create valvesounds.py 2013-09-03 07:13:35 +08:00
Steven Smith 81d7ce08c3 Create lyrics.py 2013-09-03 07:12:38 +08:00
Steven Smith 5d89f4d598 My logic is really terrible
views = views + "s" if *not* views == 1, you idiot.
2013-09-03 03:22:34 +08:00
Steven Smith 3573bac4a9 Far less page scraping, far more API.
There's API for highlights and channels, so I need to find an information API for broadcasts next.
2013-09-03 03:00:55 +08:00
Daniel Barnes 81b37c09ed Added a plugin to use domai.nr's API 2013-09-01 23:00:40 -06:00
Eric 4647e767da Added handling of exponents
Slightly better than my last suggestion. Why doesn't git let you edit existing pull requests??
2013-08-31 11:18:38 -07:00
Steven Smith 4bf05b36c9 Add catch for git.io assigning the same ID twice, provide alternative custom url
![What the hell, git.io](http://i.imgur.com/oED3qPD.png)
2013-08-29 20:48:22 +08:00
Luke Rogers 3a6f18f67b Merge pull request #120 from cybojenix/patch-6
allow custom targets for the common output commands
2013-08-26 05:15:43 -07:00
Cybo Jenix 27ac526438 allow custom targets for the common output commands 2013-08-26 11:43:24 +01:00
Luke Rogers 7e8b53d17a Merge pull request #119 from blha303/patch-7
Fix duration, add new function for timestamp formatting
2013-08-24 02:24:43 -07:00
Steven Smith b2b5270686 Return vimeo.py to where it was before, but with better duration and comma-grouped likes and plays 2013-08-24 17:23:15 +08:00
Steven Smith 86be633213 Update timeformat.py 2013-08-24 17:15:54 +08:00
Steven Smith 53d49a78f1 Update timeformat.py 2013-08-24 17:11:21 +08:00
Steven Smith 15b2b259df Create timeformat.py 2013-08-24 16:45:05 +08:00
Steven Smith 9356e4e9ca Fix duration, add new function for timestamp formatting 2013-08-24 16:44:22 +08:00
Luke Rogers 32593e3be8 Merge pull request #118 from CafogenMod/cloudev
fetch the latest kernel info
2013-08-22 06:52:29 -07:00
CafogenMod 9c9ce943a9 fetch the latest kernel info 2013-08-22 17:41:28 +04:00
Luke Rogers aded5c0aff Merge pull request #117 from blha303/patch-6
Oops. (github.py)
2013-08-19 21:02:50 -07:00
Luke Rogers cb664117d5 Merge pull request #116 from blha303/patch-5
Create util/color.py
2013-08-19 21:02:43 -07:00
Luke Rogers c05b6b25c2 please, work? 2013-08-20 10:55:58 +12:00
Steven Smith ee8e2cb5e7 Oops. 2013-08-19 18:21:46 +08:00
Steven Smith 88beb69f1a Create util/color.py 2013-08-19 17:51:57 +08:00
Luke Rogers 08b1e82f41 Merge pull request #113 from blha303/patch-1
steam.py - Fix page scraping, use markdown instead, PLUGIN IS NO LONGER BROKEN!
2013-08-14 01:22:23 -07:00
Steven Smith 23e75115d2 steam.py - Fix page scraping, use markdown instead, PLUGIN IS NO LONGER BROKEN! 2013-08-14 16:20:24 +08:00
Luke Rogers 48b52ac872 played with steam a bit 2013-08-14 20:00:17 +12:00
Luke Rogers 0f77d94da7 Merge pull request #112 from blha303/patch-6
Add support for ACTION in correction.py
2013-08-12 20:34:44 -07:00
Steven Smith 7818049e23 Add support for ACTION
Before and after: http://with-you.pw/6I4Z
2013-08-13 11:31:51 +08:00
Luke Rogers ea2f1ba633 Merge pull request #111 from blha303/patch-5
okay
2013-08-11 18:52:04 -07:00
Steven Smith a049b13927 Update correction.py 2013-08-12 09:50:20 +08:00
Luke Rogers 8c01183cfc imported web 2013-08-11 19:57:16 +12:00
Luke Rogers 807a2b43fd Update correction.py 2013-08-11 11:47:54 +12:00
Luke Rogers af4bcdb621 Merge pull request #110 from cybojenix/patch-5
add in option to correct other people's mistakes
2013-08-10 16:42:12 -07:00
Cybo Jenix 05b90ea82c add in option to correct other people's mistakes 2013-08-10 19:52:43 +01:00
Luke Rogers 88e6e642df Merge pull request #109 from CafogenMod/cloudev
add in remove command
2013-08-09 18:28:03 -07:00
cybojenix 17c29feb60 add in cleverbot 2013-08-09 23:53:54 +01:00
cybojenix a8349814a0 add in remove command 2013-08-09 23:23:16 +01:00
Luke Rogers 1018481499 Merge pull request #108 from CafogenMod/cloudev
implement a sed style correction method
2013-08-07 07:58:51 -07:00
cybojenix 3204d15bde correction: update to use the seen_user db 2013-08-07 15:53:21 +01:00
cybojenix d3429f3297 implement a sed style correction method 2013-08-07 14:29:51 +01:00
Luke Rogers ce4a786680 Added op to default permissions 2013-08-07 01:06:34 +12:00
Luke Rogers 8b304637eb Merge pull request #106 from Mu5tank05/patch-4
Language Fix in op.py
2013-08-06 03:58:12 -07:00
Nathan Blaney 52e170020e Language Fix in op.py
Instead of "Attempting to Cyprezz quiet in #cloudbot..." it will be
"Attempting to quiet Cyprezz in #cloudbot..."
2013-08-06 20:31:06 +10:00
Luke Rogers 5d94ed4387 Changed yahooanswers.py to use try_isgd 2013-08-06 11:13:50 +12:00
Luke Rogers 350991ec1f Merge pull request #103 from cybojenix/patch-4
admins: permissions: fix messy output
2013-08-05 15:59:42 -07:00
Luke Rogers 38a9eda09a Updated the op.py plugin 2013-08-06 10:56:44 +12:00
Cybo Jenix 9e8bbbdcbf admins: permissions: fix messy output 2013-08-05 23:40:59 +01:00
Luke Rogers c88d8ff1b6 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-08-06 10:17:36 +12:00
Luke Rogers 1d74e455a2 Added memory to horoscope, removed debug text (closes #101) 2013-08-06 10:17:00 +12:00
Luke Rogers 5d0754f21c Merge pull request #102 from CafogenMod/cloudev
implement tools for editing users with permissions via irc for the new p...
2013-08-05 15:15:29 -07:00
Luke Rogers eb845d1062 Fix default config syntax 2013-08-06 10:13:18 +12:00
cybojenix a3844480a1 implement tools for editing users with permissions via irc for the new permissions system 2013-08-05 23:06:05 +01:00
Luke Rogers 132ad104ed Tweaked lart to remove some more confusing stuff 2013-08-06 09:54:34 +12:00
Luke Rogers 66fd6ca1d5 Merge pull request #100 from Mu5tank05/patch-2
Create QR code plugin
2013-08-05 03:59:35 -07:00
Nathan Blaney 41fe6723fc Updated to use proper shorten 2013-08-05 20:56:46 +10:00
Nathan Blaney a02761bbd4 OK then 2013-08-05 20:49:50 +10:00
Luke Rogers e5fb97f128 Merge pull request #99 from blha303/patch-1
Add snd.sc url catcher, change return contents for invalid urls, move soundcloud lookup into another function
2013-08-05 03:46:34 -07:00
Nathan Blaney aa80de0bb4 Updated to new web.py 2013-08-05 20:30:58 +10:00
Steven Smith fd9689e5ce Add snd.sc url catcher, change return contents for invalid urls, move soundcloud lookup into another function 2013-08-05 18:02:15 +08:00
Nathan Blaney 0160d86a64 Create QR code plugin 2013-08-05 19:32:53 +10:00
Luke Rogers 4d74493610 Fixed adminonly 2013-08-05 11:16:06 +12:00
Luke Rogers e74a92e252 Merge pull request #97 from Sepero/patch-1
Fixed bug- Not recognizing nick hyphens
2013-08-04 15:13:52 -07:00
Sepero 6bd692f34a Fixed bug- Not recognizing hyphens 2013-08-04 16:27:00 -04:00
Luke Rogers ba6c2ae2c8 I forgot this! 2013-08-04 20:16:14 +12:00
Luke Rogers adaab18192 Added more items. 2013-08-04 20:15:37 +12:00
Luke Rogers 644813c0d8 Merge pull request #96 from nathanblaney/patch-1
Update op.py to new perms system
2013-08-04 01:12:03 -07:00
Nathan Blaney 383fe71b4d Update op.py to new perms system 2013-08-04 14:22:38 +10:00
Luke Rogers 8a9638fcf3 Merge pull request #95 from blha303/patch-8
Change sptfy() to use is.gd unless sptfy=True is added to calls
2013-08-03 03:07:18 -07:00
Steven Smith 9c95dd6590 Update spotify.py 2013-08-03 17:27:02 +08:00
Luke Rogers 4a04feff11 Merge pull request #94 from blha303/patch-7
Add catch for Free to Play games
2013-08-03 01:42:46 -07:00
Steven Smith 50c2825ea7 Update steam.py 2013-08-03 11:18:35 +08:00
Luke Rogers 58a857380d Made fact.py use web.try_isgd() 2013-08-02 12:30:16 +12:00
Luke Rogers fb2b5fc26e Some minor tweaks 2013-08-02 12:05:44 +12:00
Luke Rogers e574a0d41e Removed debug code 2013-08-02 11:53:05 +12:00
Luke Rogers e281bbd62b Changed the permissions config format again! (this might happen a few times, sorry) 2013-08-02 11:52:01 +12:00
Luke Rogers e6af470a16 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-08-02 10:59:23 +12:00
Luke Rogers 1feb6d1a1b Added sneaky dictionary to bot and conn 2013-08-02 10:58:59 +12:00
Luke Rogers 8460d8d3a0 Merge pull request #92 from blha303/patch-6
Merge what we have so far!
2013-08-01 06:08:43 -07:00
Steven Smith cf1732d917 Adjust terms, change references to 'master' to 'develop', fix links 2013-08-01 21:03:24 +08:00
Steven Smith 65a1827004 Add note to check files with pep8, add tl;dr for first-time submitters 2013-08-01 20:53:30 +08:00
Luke Rogers 205294dea7 Actually, totally remove the admin checks from help.py until I can figure out how to make this work well with the new permissions system 2013-08-02 00:26:31 +12:00
Luke Rogers 77499cbb3e Merge pull request #91 from mikeleigh/patch-1
Update help.py
2013-08-01 05:24:22 -07:00
Mike Leigh 2a3c0e1723 Update help.py
The new permissions have broken the help.  This patch corrects the help behaviour.

To replicate send .help and you should get the following error:
Unhandled exception in thread started by <function run at 0x7fe5e63018c0>
Traceback (most recent call last):                                       
  File "core/main.py", line 63, in run                                   
    out = func(input.inp, **kw)                                          
  File "plugins/help.py", line 16, in help                               
    input.nick in bot.config["admins"] or\                               
KeyError: 'admins'

With this patch the help responds as expected.
2013-08-01 13:21:11 +01:00
Luke Rogers 4c273705b9 Updated contributor information 2013-08-02 00:17:20 +12:00
Luke Rogers 272ba283e9 Added the neat Horoscope plugin by @infinitylabs from infinitylabs/UguuBot 2013-08-02 00:16:16 +12:00
Luke Rogers 52a1e58db1 If censor list is empty, don't censor 2013-08-02 00:12:48 +12:00
Luke Rogers e764890636 Removed old code, fixes #90 (I hope) 2013-08-02 00:04:41 +12:00
Luke Rogers 2c0879f972 Strip steam username to remove extra spaces 2013-08-01 23:00:04 +12:00
Luke Rogers 150e6acda7 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-08-01 22:35:21 +12:00
Luke Rogers 5e99e1a82f Added something I forgot to push 2013-08-01 22:34:42 +12:00
Luke Rogers ec09da2d93 Merge pull request #89 from blha303/patch-5
Rename .steamsearch to .steam
2013-08-01 03:19:21 -07:00
Steven Smith e025103d39 Update steam.py 2013-08-01 18:17:41 +08:00
Luke Rogers 810802ec65 Merge pull request #88 from blha303/patch-4
Add .steamsearch, split steam info lookup into separate function
2013-08-01 03:15:18 -07:00
Steven Smith 4868ecf976 Update steam.py 2013-08-01 18:07:20 +08:00
Luke Rogers 63cc79371d Swapped order to avoid extra fnmatch() 2013-08-01 21:17:13 +12:00
Luke Rogers 94244c7c86 Updated ignore to work with the new permissions system and work with *add plugins/ignore.py@* masks 2013-08-01 21:15:13 +12:00
Luke Rogers 1a6efcdb4b Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-08-01 21:09:03 +12:00
Luke Rogers 98395457e5 fix new permissions system 2013-08-01 21:08:41 +12:00
Luke Rogers afff36b190 Update config.default 2013-08-01 19:22:05 +12:00
Luke Rogers 20c33f02d5 Update config.default 2013-08-01 19:20:53 +12:00
Luke Rogers 7f57f3c8ca Update for new config 2013-08-01 19:19:42 +12:00
Luke Rogers 0bdbade75f Added default config file, removed config autogeneration 2013-08-01 19:17:44 +12:00
Luke Rogers e6d669be2b ._. 2013-08-01 19:07:16 +12:00
Luke Rogers 28dd4cf5f7 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-08-01 19:05:45 +12:00
Luke Rogers 9becfa9897 New permissions system :D 2013-08-01 19:03:40 +12:00
Luke Rogers baa98ee5cc From skybot 2013-08-01 17:48:18 +12:00
Luke Rogers d5ddc72a53 Merged github and gitio, pending rewrite 2013-08-01 10:39:15 +12:00
Luke Rogers d69feb68d8 merged feelings.py and violence.py 2013-08-01 10:36:47 +12:00
Luke Rogers 78173b7f63 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-08-01 10:30:55 +12:00
Luke Rogers 412c03f2ed Added HTML stripper/decoder to HTTP.py 2013-08-01 10:20:07 +12:00
Luke Rogers f0842cb887 Adjust the .gitignore file a bit. 2013-08-01 04:03:08 +12:00
Luke Rogers c0e8c4efdc Added the MLIA plugin by @infinitylabs from infinitylabs/UguuBot 2013-08-01 03:55:31 +12:00
Luke Rogers c6ecd1db81 split some lines and added pointless comments 2013-08-01 02:53:53 +12:00
Luke Rogers d26de98ebe Merge pull request #86 from blha303/patch-4
Better formatting, 4-space indents, use http.get_soup instead of BeautifulSoup directly (Fixes #84)
2013-07-31 07:44:25 -07:00
Steven Smith e042aa1bbe Better formatting, 4-space indents, use http.get_soup instead of BeautifulSoup directly 2013-07-31 22:42:59 +08:00
Luke Rogers 0100f1d071 keep capitals for now to reduce issues 2013-08-01 02:34:25 +12:00
Luke Rogers ba21f11f6b Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-08-01 02:33:50 +12:00
Luke Rogers 0ee036df56 strip the connection name 2013-08-01 02:33:27 +12:00
Luke Rogers 4a38289022 Merge pull request #85 from blha303/patch-1
Added generic CONTRIBUTING.md, .editorconfig for automatic style preference setting in supported editors
2013-07-31 07:16:50 -07:00
Steven Smith 7963e05e93 Create .editorconfig 2013-07-31 22:10:21 +08:00
Steven Smith b208635d1b Create CONTRIBUTING.md 2013-07-31 22:07:24 +08:00
Luke Rogers 7ad1ad20b2 Why the shit is that still there. It does nothing at all 2013-08-01 01:48:50 +12:00
Luke Rogers 9467014bf9 renamerename 2013-08-01 01:37:21 +12:00
Luke Rogers 585f4f2c4a more plugin renaming 2013-08-01 01:33:43 +12:00
Luke Rogers 715358298d renamed minecraft-related plugins 2013-08-01 01:31:48 +12:00
Luke Rogers 0f217fa3dd Added Steam URL parser by @blha303 and tweaked steam.py 2013-08-01 01:10:48 +12:00
Luke Rogers 67f111b6a6 Merge pull request #83 from blha303/patch-4
Create bukkitplugin.py
2013-07-30 02:31:02 -07:00
Steven Smith 29f1ace599 Create bukkitplugin.py 2013-07-30 16:48:42 +08:00
Luke Rogers 19821b35c8 noodle 2013-07-28 23:02:19 +12:00
Luke Rogers cac785f957 :D 2013-07-27 17:56:14 +12:00
Luke Rogers 510f70decb Merge pull request #80 from cybojenix/patch-1
fix the topic command, now it will actually do something
2013-07-26 22:47:13 -07:00
Luke Rogers 67a6554d2f Merge pull request #81 from blha303/patch-3
Add optional type support to web.haste()
2013-07-26 22:02:28 -07:00
Steven Smith 4d298dc898 Add optional type support to web.haste() 2013-07-27 11:02:51 +08:00
Luke Rogers 6fdcd83491 Merge pull request #79 from blha303/patch-2
Fix issue with incomplete Steam profiles, fix to pep8 standards
2013-07-22 12:08:10 -07:00
Steven Smith 0d35422d87 Update steam.py 2013-07-23 03:07:25 +08:00
Steven Smith 963f512d1e Fix issue with incomplete Steam profiles, fix to pep8 standards (except line length) 2013-07-23 02:53:17 +08:00
Luke Rogers 21d608763b Merge pull request #78 from blha303/patch-1
Update .steamcalc to use steamdb.info
2013-07-22 11:37:31 -07:00
Luke Rogers 07db016e42 rewrote a bunch of soundcloud because I can 2013-07-23 04:32:17 +12:00
Luke Rogers fd4a8ac6fa Merge pull request #77 from blha303/patch-7
soundc.py: Remove dependency on soundcloud plugin, add description truncating
2013-07-22 08:06:22 -07:00
Steven Smith 6750b076d8 Update .steamcalc to use steamdb.info 2013-07-22 22:01:47 +08:00
Cybo Jenix 85f4cd724f fix the topic command, now it will actually do something 2013-07-22 12:20:47 +01:00
Steven Smith c59aa4470a Update requirements.txt 2013-07-20 14:23:49 +08:00
Steven Smith 5a8aa32e24 Remove dependency on soundcloud plugin, add description truncating 2013-07-20 14:23:12 +08:00
Luke Rogers a8b830af4f Merge pull request #76 from blha303/patch-6
Add soundcloud autoresponse plugin.
2013-07-19 03:49:27 -07:00
Steven Smith ea3462558e Update config.py 2013-07-19 17:22:06 +08:00
Steven Smith ff5769d773 Update requirements.txt 2013-07-19 17:18:09 +08:00
Steven Smith 3d78028b43 Add soundcloud autoresponse plugin.
Currently supports tracks/playlists and users. The /resolve endpoint doesn't send any kind of information about what the item is, except missing items in the response (like .title, which is only in track and playlist responses). So I catch the AttributeError there and switch to returning username instead.
2013-07-19 17:17:08 +08:00
Luke Rogers bf69674661 fine 2013-07-16 04:23:48 +12:00
Luke Rogers 04cf2fcdf0 Added stuff 2013-07-16 03:32:47 +12:00
Luke Rogers 8873d61c0a Merge pull request #75 from blha303/patch-6
Add sptfy URL shortener to spotify.py
2013-07-15 08:07:30 -07:00
Luke Rogers a3669e6b50 Run data through BS4 to fix the text formatting and all that crap (will optimise later) 2013-07-16 03:04:07 +12:00
Steven Smith 6ea9187a3a Add in things that changed from the original. First commit was to see the diff. 2013-07-15 22:57:24 +08:00
Luke Rogers 85ec22a005 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-07-16 02:53:15 +12:00
Luke Rogers dea3b1b896 Added very early version of SCP plugin 2013-07-16 02:52:55 +12:00
Steven Smith f0c8669dff Add URL shortener 2013-07-15 22:46:41 +08:00
Luke Rogers 3fe26a91b1 Delete DOCUMENTATION 2013-07-15 23:29:10 +12:00
Luke Rogers 4324d538af More work on the ReadMe. 2013-07-15 23:22:17 +12:00
Luke Rogers 24c1e946c3 Added Tweepy contributor and license information 2013-07-15 23:15:23 +12:00
Luke Rogers f230439c56 Split mcping and mctools, fixed geoip loading, removed CTCP finer (do we really need to reveal the bots username?) 2013-07-15 23:01:01 +12:00
Luke Rogers b0e43c0aea Updated bundled version of PyGeoIP 2013-07-14 22:12:31 +12:00
Luke Rogers 487ee03e6c Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-07-14 22:07:01 +12:00
Luke Rogers 2182d5a0fd Updated bunded version of BS4 2013-07-14 22:06:37 +12:00
Luke Rogers 263e791138 Changed parsers.py back to reddit.py! 2013-07-14 21:58:13 +12:00
Luke Rogers 5d30398bc1 Removed outdated mclogin command, removed unused fields from default config 2013-07-09 08:09:58 +12:00
Luke Rogers 6564338b94 Actually learned how the API works, cut out a bunch of stuff 2013-07-09 01:35:53 +12:00
Luke Rogers 98f9e814b7 Rewrite weather.py to use the Wunderground API 2013-07-09 01:19:36 +12:00
Luke Rogers bc6d604897 A 2013-07-08 22:22:06 +12:00
Luke Rogers 90df679324 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-07-08 22:15:23 +12:00
Luke Rogers 5033332985 Fixed display of /me 2013-07-08 22:15:00 +12:00
Luke Rogers 08fae5e286 Merge pull request #74 from frdmn/develop
Typo fix in "web.py"
2013-07-05 05:23:42 -07:00
Jonas Friedmann 6595f7d54a Fix: Typo in web.py plugin 2013-07-03 14:55:06 +02:00
Luke Rogers 48cbc834de strip spaces and newlines from tweet text 2013-07-02 21:50:58 +12:00
Luke Rogers 27e05421fa Updated twitter plugin with support for hashtags and tweet ids. #yolo 2013-07-02 15:26:25 +12:00
Luke Rogers 986567a97f Added + icon for verified users, fixed times 2013-07-02 06:27:01 +12:00
Luke Rogers ffa63ead4a Added follower count and fancy number formatting to .twuser 2013-07-02 06:08:26 +12:00
Luke Rogers 75b5e2bc6d CloudBot will now automatically download the geolocation database when you run the bot; 2013-07-02 05:56:01 +12:00
Luke Rogers 9779943b91 Tweaked IMDB.py a bit 2013-07-02 05:14:54 +12:00
Luke Rogers eba21e1584 Quick hack so mctools.py still works without PyDNS installed 2013-07-02 04:12:41 +12:00
Luke Rogers 1be43d9e51 Uploaded the old launcher to the disabled_stuff folder, because some people still want it 2013-07-02 03:52:11 +12:00
Luke Rogers fa630eb285 Added twitter options to default config. 2013-07-02 03:49:27 +12:00
Luke Rogers 18deba34f3 Revamped Readme 2013-07-02 03:47:33 +12:00
Luke Rogers 6b76ba3e2a Add tweepy module 2013-07-02 03:29:12 +12:00
Luke Rogers 696f2b7c1a Early version of new Twitter plugin 2013-07-02 03:28:46 +12:00
Luke Rogers e091a48744 catch more errors, pep8 2013-06-28 21:25:06 +12:00
Luke Rogers b98b6ad933 I'm back. Cleaning out some old stuff 2013-06-28 20:52:26 +12:00
Luke Rogers 536cfcb87c Merge pull request #73 from blha303/patch-5
Add autoresponse to some plugins, add rdio and newgrounds search/autoresponse
2013-06-27 04:43:59 -07:00
Steven Smith a9bd3c4c68 Update rdio.py
Update, remove key/secret, add key check
2013-06-27 18:49:00 +08:00
Steven Smith 190953f866 Update youtube.py
Add playlist parsing
2013-06-27 18:42:18 +08:00
Steven Smith af6c37ee2e Create newgrounds.py
Add autoresponse
2013-06-27 18:38:57 +08:00
Steven Smith 7dbd59e1f2 Create rdio.py
Rdio search and autoresponse plugin
2013-06-27 18:37:09 +08:00
Steven Smith 10f1f06e55 Update imdb.py
Add autoresponse
2013-06-27 18:34:06 +08:00
Luke Rogers ef1bf8338c Merge pull request #72 from blha303/patch-4
Update github.py
2013-06-25 09:22:12 -07:00
Steven Smith 4df5510281 Check if summary is null 2013-06-26 00:21:28 +08:00
Steven Smith 569d84a75f Update github.py 2013-06-26 00:16:30 +08:00
Luke Rogers 15d19dd1d8 Merge pull request #70 from blha303/patch-3
Create github.py
2013-06-25 09:13:50 -07:00
Luke Rogers 7159ad8a0e Merge pull request #69 from blha303/patch-2
Update twitch.py
2013-06-25 09:13:34 -07:00
Steven Smith ba9d015ac2 Create github.py
Add command for retrieving github issues by number, or all open.
2013-06-21 18:52:39 +08:00
Steven Smith cc5c81544d Update twitch.py
Fix online/offline check (L21)
2013-06-21 18:49:27 +08:00
Luke Rogers 79a25f2600 Update README.md 2013-06-21 21:55:02 +12:00
Luke Rogers 1817609c9c Merge pull request #68 from blha303/patch-1
Update twitch.py
2013-06-21 01:49:04 -07:00
Steven Smith 4ef52d3762 Update twitch.py
Added colours to the message (L36), added error catch for if user has no stream or videos (L16), added currently-streaming check (L21)
2013-06-21 16:08:15 +08:00
Luke Rogers 9f5fc95d5b Merge pull request #66 from KsaRedFx/patch-1
Fixed bug in weather.py
2013-06-18 03:19:38 -07:00
Luke Rogers ebc3720f1e Merge pull request #67 from blha303/develop
Twitch.tv url parser
2013-06-18 03:19:13 -07:00
blha303 7603bb7b6a Twitch.tv url parser 2013-06-18 08:26:17 +00:00
Luke Rogers 88c179f568 whut
whut
2013-06-14 15:56:39 +12:00
Robert "Red" English 617eb42f17 Fixed bug in weather.py
Weather.py doesn't always receive the correct data for visibility and fails silently - this prevents that.
2013-06-10 17:39:54 -03:00
Luke Rogers 8c363e5f76 Merge pull request #65 from nasonfish/patch-1
Added new Minecraft items to items.txt
2013-06-07 20:54:12 -07:00
nasonfish b6d2139e6e Added new Minecraft items to items.txt 2013-06-07 22:42:35 -05:00
Luke Rogers 5b30095b3d Merge pull request #64 from blha303/spotify
Added two new commands, removed spotimeta
2013-05-22 06:20:59 -07:00
blha303 81ccdd2849 Added two new commands, removed spotimeta 2013-05-18 21:27:12 +08:00
Luke Rogers c4e5e91c14 Update mctools.py 2013-05-14 01:30:43 +12:00
Luke Rogers 3d74b7781d Update web.py 2013-05-14 01:01:19 +12:00
Luke Rogers 16ad0cfbf6 Merge pull request #62 from blha303/patch-1
spotify.py - Removed spotimeta dependency, using json api natively
2013-05-13 05:58:19 -07:00
Luke Rogers c6edec3000 Merge pull request #63 from KsaRedFx/develop
Redid SRV lookups in mytools.py due to slow speeds.
2013-05-13 05:58:05 -07:00
KsaRedFx 2885273f6d Updated Readme 2013-05-12 19:15:30 -04:00
KsaRedFx 0f689f4583 Forgot to remove debug lines 2013-05-12 19:13:42 -04:00
KsaRedFx cf7658d28e Updated missing dependancy in requirements.txt and fixed speed issues in SRV lookups for mcping 2013-05-12 19:11:52 -04:00
Robert "Red" English 50195ba8cd Merge pull request #1 from ClouDev/develop
Update fork to ClouDev's version.
2013-05-12 14:48:09 -07:00
Steven Smith f980e6ed9f spotify.py - Removed spotimeta dependency, using json api natively 2013-05-10 02:22:16 +08:00
Luke Rogers fc2e8e56a4 Fixed Help String 2013-04-17 21:32:52 -07:00
Luke Rogers f46f752878 Pulled fixed version of .bitcoin from rmmh/skybot@bcc253fcd8 by @crisisking 2013-04-17 21:32:24 -07:00
Neer Sighted d517130082 Merge pull request #61 from KsaRedFx/develop
Updated mctools.py to read SRV Records
2013-04-16 21:34:30 -07:00
Robert "Red" English 29ec904777 Updated requirements.txt to contain 'pydns' 2013-04-15 13:41:41 -03:00
Robert "Red" English 57dc9bbaf6 Updated README.md to have a reference to 'pydns' 2013-04-15 13:40:27 -03:00
Robert "Red" English 6bc35605e5 Fixed Host Error in mctools.py 2013-04-12 23:16:49 -03:00
Robert "Red" English 2a33c97f4d Updated mctools.py to read SRV Records
Updated MC Tools to read SRV Records that were implemented in Minecraft 1.3.1 
Requires module 'pydns' so please run 'sudo pip install pydns'
2013-04-12 22:45:20 -03:00
Neer Sighted 501f3c8af8 Merge pull request #59 from blha303/develop
Updating .mcstatus to fix colors
2013-04-04 13:33:58 -07:00
blha303 8ac4450ff7 Removed colors on the non-status text 2013-04-05 03:59:49 +08:00
Steven Smith dce3c35424 Fixed colors on .mcstatus 2013-04-04 22:50:35 +08:00
blha303 5a64ce4983 Updating .mcstatus to show correct colors. 2013-04-04 22:35:34 +08:00
Luke Rogers 6516caccdc Merge pull request #55 from blha303/develop
Add Minecraft colours to .mcping
2013-03-21 03:30:30 -07:00
blha303 7737c1a373 .mcping - finished adding colours 2013-03-14 02:21:13 +08:00
blha303 8f4bc45c56 .mcping - finished adding colours 2013-03-14 01:55:33 +08:00
Steven Smith 18340b3f3c .mcping color 2013-03-14 00:46:30 +08:00
Neer Sighted 8278e659ef Merge pull request #50 from urbels/patch-1
Update Readme with required linux packages
2013-02-28 08:17:59 -08:00
Edža 8c83bd3c50 Update Readme with required linux packages 2013-02-28 16:03:59 +02:00
Luke Rogers 072e73f3a1 Merge branch 'develop' of https://github.com/ClouDev/CloudBot into develop 2013-02-13 17:40:20 +13:00
Luke Rogers 08e3cd3c13 Changed 2013-02-13 17:37:57 +13:00
Luke Rogers 3885dd0ac9 Update plugins/weather.py 2013-02-07 23:26:10 +13:00
Luke Rogers 93fe9610f4 Fixed another issue. 2013-02-07 19:55:53 +13:00
Luke Rogers ceb09f4334 Fixed bug. 2013-02-07 11:54:11 +13:00
241 changed files with 13040 additions and 5021 deletions

18
.editorconfig Normal file
View File

@ -0,0 +1,18 @@
# CloudBot editor configuration normalization
# Copied from Drupal (GPL)
# @see http://editorconfig.org/
# This is the top-most .editorconfig file; do not search in parent directories.
root = true
# All files.
[*]
end_of_line = LF
indent_style = space
indent_size = 4
# Not in the spec yet:
# @see https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

6
.gitignore vendored Executable file → Normal file
View File

@ -1,5 +1,6 @@
persist
config
config.ssl
gitflow
*.db
*.log
@ -7,7 +8,8 @@ gitflow
*.pyc
*.orig
.project
.pydevproject
.geany
*.sublime-project
*.sublime-workspace
*.sublime-workspace
.idea/
plugins/data/GeoLiteCity.dat

55
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,55 @@
# How to contribute
I like to encourage you to contribute to the repository.
This should be as easy as possible for you but there are a few things to consider when contributing.
The following guidelines for contribution should be followed if you want to submit a pull request.
## TL;DR
* Read [Github documentation](http://help.github.com/) and [Pull Request documentation](http://help.github.com/send-pull-requests/)
* Fork the repository
* Edit the files, add new files
* Check the files with [`pep8`](https://pypi.python.org/pypi/pep8), fix any reported errors
* Check that the files work as expected in CloudBot
* Create a new branch with a descriptive name for your feature (optional)
* Commit changes, push to your fork on GitHub
* Create a new pull request, provide a short summary of changes in the title line, with more information in the description field.
* After submitting the pull request, join the IRC channel (irc.esper.net #cloudbot) and paste a link to the pull request so people are aware of it
* After discussion, your pull request will be accepted or rejected.
## How to prepare
* You need a [GitHub account](https://github.com/signup/free)
* Submit an [issue ticket](https://github.com/ClouDev/CloudBot/issues) for your issue if the is no one yet.
* Describe the issue and include steps to reproduce if it's a bug.
* Ensure to mention the earliest version that you know is affected.
* If you are able and want to fix this, fork the repository on GitHub
## Make Changes
* In your forked repository, create a topic branch for your upcoming patch. (e.g. `feature--autoplay` or `bugfix--ios-crash`)
* Usually this is based on the develop branch.
* Create a branch based on master; `git branch
fix/develop/my_contribution develop` then checkout the new branch with `git
checkout fix/develop/my_contribution`. Please avoid working directly on the `develop` branch.
* Make sure you stick to the coding style that is used already.
* Make use of the [`.editorconfig`](http://editorconfig.org/) file.
* Make commits of logical units and describe them properly.
* Check for unnecessary whitespace with `git diff --check` before committing.
* Check your changes with [`pep8`](https://pypi.python.org/pypi/pep8). Ignore messages about line length.
## Submit Changes
* Push your changes to a topic branch in your fork of the repository.
* Open a pull request to the original repository and choose the right original branch you want to patch.
_Advanced users may use [`hub`](https://github.com/defunkt/hub#git-pull-request) gem for that._
* If not done in commit messages (which you really should do) please reference and update your issue with the code changes. But _please do not close the issue yourself_.
_Notice: You can [turn your previously filed issues into a pull-request here](http://issue2pr.herokuapp.com/)._
* Even if you have write access to the repository, do not directly push or merge pull-requests. Let another team member review your pull request and approve.
# Additional Resources
* [General GitHub documentation](http://help.github.com/)
* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
* [Read the Issue Guidelines by @necolas](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md) for more details
* [This CONTRIBUTING.md from here](https://github.com/anselmh/CONTRIBUTING.md)

34
CONTRIBUTORS Normal file
View File

@ -0,0 +1,34 @@
Thanks to everyone who has contributed to CloudBot! Come in IRC and ping me if I forgot anyone.
Luke Rogers (lukeroge)
Neersighted
blha303
cybojenix
KsaRedFx
nathanblaney
thenoodle68
nasonfish
urbels
puffrfish
Sepero
TheFiZi
mikeleigh
Spudstabber
frozenMC
frdmn
We are using code from the following projects:
./plugins/mlia.py - https://github.com/infinitylabs/UguuBot
./plugins/horoscope.py - https://github.com/infinitylabs/UguuBot
color section in ./plugins/utility.py - https://github.com/hitzler/homero
Special Thanks:
Rmmh (created skybot!)
lahwran (for his advice and stuff I stole from his skybot fork!)
TheNoodle (for helping with some plugins when I was first starting out)
If any of your code is in here and you don't have credit, I'm sorry. I didn't keep track of a lot of code I added in the early days of the project.
You are all awesome :)

View File

@ -1 +0,0 @@
Please see the wiki @ http://git.io/cloudbotircwiki

0
LICENSE Executable file → Normal file
View File

89
README.md Executable file → Normal file
View File

@ -1,25 +1,12 @@
# CloudBot/DEV
# CloudBot
## About
CloudBot is a Python IRC bot very heavily based on [Skybot](http://git.io/skybot) by [rmmh](http://git.io/rmmh).
### Goals
* Easy to use wrapper
* Intuitive configuration
* Fully controlled from IRC
* Fully compatable with existing skybot plugins
* Easily extendable
* Thorough documentation
* Cross-platform
* Muti-threaded, efficient
* Automatic reloading
* Little boilerplate
CloudBot is a Python IRC bot based on [Skybot](http://git.io/skybot) by [rmmh](http://git.io/rmmh).
## Getting and using CloudBot
### Download
### Download
Get CloudBot at [https://github.com/ClouDev/CloudBot/zipball/develop](https://github.com/ClouDev/CloudBot/zipball/develop "Get CloudBot from Github!").
@ -27,51 +14,33 @@ Unzip the resulting file, and continue to read this document.
### Install
Before you can run the bot, you need to install a few Python dependencies. These can be installed with `pip` (The Python package manager):
Before you can run the bot, you need to install a few Python dependencies. LXML is required while Enchant and PyDNS are needed for several plugins.
These can be installed with `pip` (The Python package manager):
[sudo] pip install -r requirements.txt
If you use `pip`, you will also need the following packages on linux or `pip` will fail to install the requirements.
```python, python-dev, libenchant-dev, libenchant1c2a, libxslt-dev, libxml2-dev.```
#### How to install `pip`
curl -O http://python-distribute.org/distribute_setup.py # or download with your browser on windows
python distribute_setup.py
easy_install pip
If you are unable to use pip, there are Windows installers for LXML available for [64 bit](https://pypi.python.org/packages/2.7/l/lxml/lxml-2.3.win-amd64-py2.7.exe) and [32 bit](https://pypi.python.org/packages/2.7/l/lxml/lxml-2.3.win32-py2.7.exe) versions of Python.
### Run
Once you have installed the required dependencies, there are two ways you can run the bot:
Before you run the bot, rename `config.default` to `config` and edit it with your preferred settings.
#### Launcher
**Note:** Due to some issues with the launcher we recommend you run the bot manually as detailed below.
The launcher will start the bot as a background process, and allow the bot to close and restart itself. This is only supported on unix-like machines (not Windows).
For the launcher to work properly, install `screen`, or `daemon` (daemon is recommended):
`apt-get install screen`
`apt-get install daemon`
Once you have installed either `screen` or `daemon`, run the start command:
`./cloudbot start`
It will generate a default config for you. Once you have edited the config, run it again with the same command:
`./cloudbot start`
This will start up your bot as a background process. To stop it, use `./cloudbot stop`. (Config docs at the [wiki](http://git.io/cloudbotircconfig))
#### Manually
To manually run the bot and get console output, run it with:
Once you have installed the required dependencies and renamed the config file, you can run the bot! Make sure you are in the correct folder and run the following command:
`python bot.py`
On Windows you can usually just double-click the `bot.py` file to start the bot, as long as you have Python installed correctly.
(note: running the bot without the launcher breaks the start and restart commands)
On Windows you can usually just double-click `bot.py` to start the bot, as long as you have Python installed correctly.
## Getting help with CloudBot
@ -83,6 +52,8 @@ To write your own plugins, visit the [Plugin Wiki Page](http://git.io/cloudbotir
More at the [Wiki Main Page](http://git.io/cloudbotircwiki).
(some of the information on the wiki is outdated and needs to be rewritten)
### Support
The developers reside in [#CloudBot](irc://irc.esper.net/cloudbot) on [EsperNet](http://esper.net) and would be glad to help you.
@ -91,31 +62,25 @@ If you think you have found a bug/have a idea/suggestion, please **open a issue*
### Requirements
CloudBot runs on **Python** *2.7.x*. It is developed on **Ubuntu** *12.04* with **Python** *2.7.3*.
CloudBot runs on **Python** *2.7.x*. It is currently developed on **Windows** *8* with **Python** *2.7.5*.
It **requires the Python module** `lXML`, and `Enchant` is needed for the spellcheck plugin.
It **requires the Python module** lXML.
The module `Enchant` is needed for the spellcheck plugin.
The module `PyDNS` is needed for SRV record lookup in the mcping plugin.
The programs `daemon` or `screen` are recomended for the launcher to run optimaly.
**Windows** users: Windows compatibility with the launcher and some plugins is **broken** (such as ping), but we do intend to add it.³
**Windows** users: Windows compatibility some plugins is **broken** (such as ping), but we do intend to add it. Eventually.
## Example CloudBots
The developers of CloudBot run two CloudBots on [Espernet](http://esper.net).
They can both be found in [#CloudBot](irc://irc.esper.net/cloudbot "Connect via IRC to #CloudBot on irc.esper.net").
**mau5bot** is the semi-stable bot, and runs on the latest stable development version of CloudBot. (mau5bot is running on **Ubuntu Server** *12.04* with **Python** *2.7.3*)
**neerbot** is unstable bot, and runs on the `HEAD` of the `develop` branch. (neerbot is running on **Debian** *Wheezy/Testing* with **Python** *2.7.2*)
You can find a number of example bots in [#CloudBot](irc://irc.esper.net/cloudbot "Connect via IRC to #CloudBot on irc.esper.net").
## License
CloudBot is **licensed** under the **GPL v3** license. The terms are as follows.
CloudBot/DEV
CloudBot
Copyright © 2011-2012 Luke Rogers / ClouDev - <[cloudev.github.com](http://cloudev.github.com)>
Copyright © 2011-2013 Luke Rogers
CloudBot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -129,7 +94,3 @@ CloudBot is **licensed** under the **GPL v3** license. The terms are as follows.
You should have received a copy of the GNU General Public License
along with CloudBot. If not, see <http://www.gnu.org/licenses/>.
## Notes
³ eventually

View File

@ -1,49 +1,32 @@
#!/usr/bin/env python
__author__ = "ClouDev"
__authors__ = ["Lukeroge", "neersighted"]
__copyright__ = "Copyright 2012, ClouDev"
__credits__ = ["thenoodle", "_frozen", "rmmh"]
__license__ = "GPL v3"
__version__ = "DEV"
__maintainer__ = "ClouDev"
__email__ = "cloudev@neersighted.com"
__status__ = "Development"
import os
import Queue
import sys
import time
import platform
import re
sys.path += ['plugins'] # so 'import hook' works without duplication
sys.path += ['lib']
sys.path += ['plugins', 'lib'] # add stuff to the sys.path for easy imports
os.chdir(sys.path[0] or '.') # do stuff relative to the install directory
class Bot(object):
pass
print 'CloudBot %s (%s) <http://git.io/cloudbotirc>' % (__version__, __status__)
# print debug info
opsys = platform.platform()
python_imp = platform.python_implementation()
python_ver = platform.python_version()
architecture = ' '.join(platform.architecture())
print "Operating System: %s, Python " \
"Version: %s %s, Architecture: %s" \
"" % (opsys, python_imp, python_ver, architecture)
print 'CloudBot DEV <http://git.io/cloudbotirc>'
# create new bot object
bot = Bot()
bot.vars = {}
# record start time for the uptime command
bot.start_time = time.time()
print 'Loading plugins...'
print 'Begin Plugin Loading.'
# bootstrap the reloader
eval(compile(open(os.path.join('core', 'reload.py'), 'U').read(),
os.path.join('core', 'reload.py'), 'exec'))
os.path.join('core', 'reload.py'), 'exec'))
reload(init=True)
config()
@ -56,14 +39,17 @@ bot.conns = {}
try:
for name, conf in bot.config['connections'].iteritems():
# strip all spaces and capitalization from the connection name
name = name.replace(" ", "_")
name = re.sub('[^A-Za-z0-9_]+', '', name)
print 'Connecting to server: %s' % conf['server']
if conf.get('ssl'):
bot.conns[name] = SSLIRC(name, conf['server'], conf['nick'], conf=conf,
port=conf.get('port', 6667), channels=conf['channels'],
ignore_certificate_errors=conf.get('ignore_cert', True))
port=conf.get('port', 6667), channels=conf['channels'],
ignore_certificate_errors=conf.get('ignore_cert', True))
else:
bot.conns[name] = IRC(name, conf['server'], conf['nick'], conf=conf,
port=conf.get('port', 6667), channels=conf['channels'])
port=conf.get('port', 6667), channels=conf['channels'])
except Exception as e:
print 'ERROR: malformed config file', e
sys.exit()

77
config.default Normal file
View File

@ -0,0 +1,77 @@
{
"connections": {
"hackint": {
"server": "irc.hackint.eu",
"nick": "antibot",
"user": "antibot",
"realname": "CloudBot - http://git.io/cloudbotirc",
"mode": "",
"_nickserv_password": "",
"-nickserv_user": "",
"channels": [
"#ChaosChemnitz",
"#logbot"
],
"invite_join": true,
"auto_rejoin": false,
"command_prefix": "."
}
},
"disabled_plugins": [],
"disabled_commands": [],
"acls": {},
"api_keys": {
"tvdb": "",
"wolframalpha": "",
"lastfm": "",
"rottentomatoes": "",
"soundcloud": "",
"twitter_consumer_key": "",
"twitter_consumer_secret": "",
"twitter_access_token": "",
"twitter_access_secret": "",
"wunderground": "",
"googletranslate": "",
"rdio_key": "",
"rdio_secret": ""
},
"permissions": {
"admins": {
"perms": [
"adminonly",
"addfactoid",
"delfactoid",
"ignore",
"botcontrol",
"permissions_users",
"op"
],
"users": [
"examplea!user@example.com",
"exampleb!user@example.com"
]
},
"moderators": {
"perms": [
"addfactoid",
"delfactoid",
"ignore"
],
"users": [
"stummi!~Stummi@stummi.org"
]
}
},
"plugins": {
"factoids": {
"prefix": false
},
"ignore": {
"ignored": []
}
},
"censored_strings": [
"mypass",
"mysecret"
]
}

57
core/config.py Executable file → Normal file
View File

@ -7,60 +7,8 @@ def save(conf):
json.dump(conf, open('config', 'w'), sort_keys=True, indent=2)
if not os.path.exists('config'):
open('config', 'w').write(inspect.cleandoc(
r'''
{
"connections":
{
"EsperNet":
{
"server": "irc.esper.net",
"nick": "MyNewCloudBot",
"user": "cloudbot",
"realname": "CloudBot - http://git.io/cloudbotirc",
"nickserv_password": "",
"channels": ["#cloudbot"],
"invite_join": true,
"auto_rejoin": false,
"command_prefix": "."
}
},
"disabled_plugins": [],
"disabled_commands": [],
"acls": {},
"api_keys":
{
"geoip": "INSERT API KEY FROM ipinfodb.com HERE",
"tvdb": "INSERT API KEY FROM thetvdb.com HERE",
"bitly_user": "INSERT USERNAME FROM bitly.com HERE",
"bitly_api": "INSERT API KEY FROM bitly.com HERE",
"wolframalpha": "INSERT API KEY FROM wolframalpha.com HERE",
"lastfm": "INSERT API KEY FROM lastfm HERE",
"rottentomatoes": "INSERT API KEY FROM rottentomatoes HERE",
"mc_user": "INSERT minecraft USERNAME HERE",
"mc_pass": "INSERT minecraft PASSWORD HERE"
},
"plugins":
{
"factoids":
{
"prefix": false
},
"ignore":
{
"ignored": []
}
},
"censored_strings":
[
"mypass",
"mysecret"
],
"admins": ["myname@myhost"]
}''') + '\n')
print "Config generated!"
print "Please edit the config now!"
print "For help, see http://git.io/cloudbotircwiki"
print "Please rename 'config.default' to 'config' to set up your bot!"
print "For help, see http://git.io/cloudbotirc"
print "Thank you for using CloudBot!"
sys.exit()
@ -77,4 +25,3 @@ def config():
bot._config_mtime = 0

2
core/db.py Executable file → Normal file
View File

@ -6,7 +6,7 @@ threaddbs = {}
def get_db_connection(conn, name=''):
"returns an sqlite3 connection to a persistent database"
"""returns an sqlite3 connection to a persistent database"""
if not name:
name = '{}.db'.format(conn.name)

92
core/irc.py Executable file → Normal file
View File

@ -17,16 +17,18 @@ def decode(txt):
def censor(text):
text = text.replace('\n', '').replace('\r', '')
replacement = '[censored]'
if 'censored_strings' in bot.config:
words = map(re.escape, bot.config['censored_strings'])
regex = re.compile('(%s)' % "|".join(words))
text = regex.sub(replacement, text)
if bot.config['censored_strings']:
words = map(re.escape, bot.config['censored_strings'])
regex = re.compile('({})'.format("|".join(words)))
text = regex.sub(replacement, text)
return text
class crlf_tcp(object):
"Handles tcp connections that consist of utf-8 lines ending with crlf"
"""Handles tcp connections that consist of utf-8 lines ending with crlf"""
def __init__(self, host, port, timeout=300):
self.ibuffer = ""
@ -42,7 +44,16 @@ class crlf_tcp(object):
return socket.socket(socket.AF_INET, socket.TCP_NODELAY)
def run(self):
self.socket.connect((self.host, self.port))
noerror = 0
while 1:
try:
self.socket.connect((self.host, self.port))
break
except socket.gaierror as e:
time.sleep(5)
except socket.timeout as e:
time.sleep(5)
thread.start_new_thread(self.recv_loop, ())
thread.start_new_thread(self.send_loop, ())
@ -53,17 +64,25 @@ class crlf_tcp(object):
return socket.timeout
def handle_receive_exception(self, error, last_timestamp):
print("Receive exception: %s" % (error))
if time.time() - last_timestamp > self.timeout:
print("Receive timeout. Restart connection.")
self.iqueue.put(StopIteration)
self.socket.close()
return True
return False
def handle_send_exception(self, error):
print("Send exception: %s" % (error))
self.iqueue.put(StopIteration)
self.socket.close()
return True
def recv_loop(self):
last_timestamp = time.time()
while True:
try:
data = self.recv_from_socket(4096)
data = self.recv_from_socket(4096)
self.ibuffer += data
if data:
last_timestamp = time.time()
@ -77,6 +96,8 @@ class crlf_tcp(object):
if self.handle_receive_exception(e, last_timestamp):
return
continue
except AttributeError:
return
while '\r\n' in self.ibuffer:
line, self.ibuffer = self.ibuffer.split('\r\n', 1)
@ -84,24 +105,31 @@ class crlf_tcp(object):
def send_loop(self):
while True:
line = self.oqueue.get().splitlines()[0][:500]
print ">>> %r" % line
self.obuffer += line.encode('utf-8', 'replace') + '\r\n'
while self.obuffer:
sent = self.socket.send(self.obuffer)
self.obuffer = self.obuffer[sent:]
try:
line = self.oqueue.get().splitlines()[0][:500]
if line == StopIteration:
return
print ">>> %r" % line
self.obuffer += line.encode('utf-8', 'replace') + '\r\n'
while self.obuffer:
sent = self.socket.send(self.obuffer)
self.obuffer = self.obuffer[sent:]
except socket.error as e:
self.handle_send_exception(e)
return
class crlf_ssl_tcp(crlf_tcp):
"Handles ssl tcp connetions that consist of utf-8 lines ending with crlf"
"""Handles ssl tcp connetions that consist of utf-8 lines ending with crlf"""
def __init__(self, host, port, ignore_cert_errors, timeout=300):
self.ignore_cert_errors = ignore_cert_errors
crlf_tcp.__init__(self, host, port, timeout)
def create_socket(self):
return wrap_socket(crlf_tcp.create_socket(self), server_side=False,
cert_reqs=CERT_NONE if self.ignore_cert_errors else
CERT_REQUIRED)
cert_reqs=CERT_NONE if self.ignore_cert_errors else
CERT_REQUIRED)
def recv_from_socket(self, nbytes):
return self.socket.read(nbytes)
@ -111,10 +139,14 @@ class crlf_ssl_tcp(crlf_tcp):
def handle_receive_exception(self, error, last_timestamp):
# this is terrible
if not "timed out" in error.args[0]:
raise
#if not "timed out" in error.args[0]:
# raise
return crlf_tcp.handle_receive_exception(self, error, last_timestamp)
def handle_send_exception(self, error):
return crlf_tcp.handle_send_exception(self, error)
irc_prefix_rem = re.compile(r'(.*?) (.*?) (.*)').match
irc_noprefix_rem = re.compile(r'()(.*?) (.*)').match
irc_netmask_rem = re.compile(r':?([^!@]*)!?([^@]*)@?(.*)').match
@ -122,7 +154,8 @@ irc_param_ref = re.compile(r'(?:^|(?<= ))(:.*|[^ ]+)').findall
class IRC(object):
"handles the IRC protocol"
"""handles the IRC protocol"""
def __init__(self, name, server, nick, port=6667, channels=[], conf={}):
self.name = name
self.channels = channels
@ -130,6 +163,8 @@ class IRC(object):
self.server = server
self.port = port
self.nick = nick
self.history = {}
self.vars = {}
self.out = Queue.Queue() # responses from the server are placed here
# format: [rawline, prefix, command, params,
@ -147,8 +182,8 @@ class IRC(object):
self.set_pass(self.conf.get('server_password'))
self.set_nick(self.nick)
self.cmd("USER",
[conf.get('user', 'cloudbot'), "3", "*", conf.get('realname',
'CloudBot - http://git.io/cloudbot')])
[conf.get('user', 'cloudbot'), "3", "*", conf.get('realname',
'CloudBot - http://git.io/cloudbot')])
def parse_loop(self):
while True:
@ -165,7 +200,7 @@ class IRC(object):
else:
prefix, command, params = irc_noprefix_rem(msg).groups()
nick, user, host = irc_netmask_rem(prefix).groups()
mask = user + "@" + host
mask = nick + "!" + user + "@" + host
paramlist = irc_param_ref(params)
lastparam = ""
if paramlist:
@ -174,7 +209,7 @@ class IRC(object):
lastparam = paramlist[-1]
# put the parsed message in the response queue
self.out.put([msg, prefix, command, params, nick, user, host,
mask, paramlist, lastparam])
mask, paramlist, lastparam])
# if the server pings us, pong them back
if command == "PING":
self.cmd("PONG", paramlist)
@ -188,7 +223,7 @@ class IRC(object):
def join(self, channel):
""" makes the bot join a channel """
self.send("JOIN %s" % channel)
self.send("JOIN {}".format(channel))
if channel not in self.channels:
self.channels.append(channel)
@ -199,13 +234,18 @@ class IRC(object):
self.channels.remove(channel)
def msg(self, target, text):
""" makes the bot send a message to a user """
""" makes the bot send a PRIVMSG to a target """
self.cmd("PRIVMSG", [target, text])
def ctcp(self, target, ctcp_type, text):
""" makes the bot send a PRIVMSG CTCP to a target """
out = u"\x01{} {}\x01".format(ctcp_type, text)
self.cmd("PRIVMSG", [target, out])
def cmd(self, command, params=None):
if params:
params[-1] = ':' + params[-1]
self.send(command + ' ' + ' '.join(map(censor, params)))
params[-1] = u':' + params[-1]
self.send(u"{} {}".format(command, ' '.join(params)))
else:
self.send(command)

58
core/main.py Executable file → Normal file
View File

@ -7,35 +7,40 @@ thread.stack_size(1024 * 512) # reduce vm size
class Input(dict):
def __init__(self, conn, raw, prefix, command, params,
nick, user, host, mask, paraml, msg):
nick, user, host, mask, paraml, msg):
chan = paraml[0].lower()
if chan == conn.nick.lower(): # is a PM
chan = nick
def say(msg):
conn.msg(chan, msg)
def message(message, target=chan):
"""sends a message to a specific or current channel/user"""
conn.msg(target, message)
def pm(msg):
conn.msg(nick, msg)
def reply(msg):
if chan == nick: # PMs don't need prefixes
conn.msg(chan, msg)
def reply(message, target=chan):
"""sends a message to the current channel/user with a prefix"""
if target == nick:
conn.msg(target, message)
else:
conn.msg(chan, '(' + nick + ') ' + msg)
conn.msg(target, u"({}) {}".format(nick, message))
def me(msg):
conn.msg(chan, "\x01%s %s\x01" % ("ACTION", msg))
def action(message, target=chan):
"""sends an action to the current channel/user or a specific channel/user"""
conn.ctcp(target, "ACTION", message)
def notice(msg):
conn.cmd('NOTICE', [nick, msg])
def ctcp(message, ctcp_type, target=chan):
"""sends an ctcp to the current channel/user or a specific channel/user"""
conn.ctcp(target, ctcp_type, message)
def notice(message, target=nick):
"""sends a notice to the current channel/user or a specific channel/user"""
conn.cmd('NOTICE', [target, message])
dict.__init__(self, conn=conn, raw=raw, prefix=prefix, command=command,
params=params, nick=nick, user=user, host=host, mask=mask,
paraml=paraml, msg=msg, server=conn.server, chan=chan,
notice=notice, say=say, reply=reply, pm=pm, bot=bot,
me=me, lastparam=paraml[-1])
params=params, nick=nick, user=user, host=host, mask=mask,
paraml=paraml, msg=msg, server=conn.server, chan=chan,
notice=notice, message=message, reply=reply, bot=bot,
action=action, ctcp=ctcp, lastparam=paraml[-1])
# make dict keys accessible as attributes
def __getattr__(self, key):
@ -77,7 +82,8 @@ def do_sieve(sieve, bot, input, func, type, args):
class Handler(object):
'''Runs plugins in their own threads (ensures order)'''
"""Runs plugins in their own threads (ensures order)"""
def __init__(self, func):
self.func = func
self.input_queue = Queue.Queue()
@ -103,6 +109,7 @@ class Handler(object):
run(self.func, input)
except:
import traceback
traceback.print_exc()
def stop(self):
@ -115,11 +122,10 @@ class Handler(object):
def dispatch(input, kind, func, args, autohelp=False):
for sieve, in bot.plugs['sieve']:
input = do_sieve(sieve, bot, input, func, kind, args)
if input == None:
if input is None:
return
if autohelp and args.get('autohelp', True) and not input.inp \
and func.__doc__ is not None:
if not (not autohelp or not args.get('autohelp', True) or input.inp or not (func.__doc__ is not None)):
input.notice(input.conn.conf["command_prefix"] + func.__doc__)
return
@ -153,9 +159,9 @@ def main(conn, out):
if inp.command == 'PRIVMSG':
# COMMANDS
if inp.chan == inp.nick: # private message, no command prefix
prefix = '^(?:[%s]?|' % command_prefix
prefix = '^(?:[{}]?|'.format(command_prefix)
else:
prefix = '^(?:[%s]|' % command_prefix
prefix = '^(?:[{}]|'.format(command_prefix)
command_re = prefix + inp.conn.nick
command_re += r'[,;:]+\s+)(\w+)(?:$|\s+)(.*)'
@ -168,8 +174,8 @@ def main(conn, out):
if isinstance(command, list): # multiple potential matches
input = Input(conn, *out)
input.notice("Did you mean %s or %s?" %
(', '.join(command[:-1]), command[-1]))
input.notice("Did you mean {} or {}?".format
(', '.join(command[:-1]), command[-1]))
elif command in bot.commands:
input = Input(conn, *out)
input.trigger = trigger

19
core/reload.py Executable file → Normal file
View File

@ -17,8 +17,8 @@ def make_signature(f):
return f.func_code.co_filename, f.func_name, f.func_code.co_firstlineno
def format_plug(plug, kind='', lpad=0, width=40):
out = ' ' * lpad + '%s:%s:%s' % make_signature(plug[0])
def format_plug(plug, kind='', lpad=0):
out = ' ' * lpad + '{}:{}:{}'.format(*make_signature(plug[0]))
if kind == 'command':
out += ' ' * (50 - len(out)) + plug[1]['name']
@ -49,7 +49,7 @@ def reload(init=False):
try:
eval(compile(open(filename, 'U').read(), filename, 'exec'),
globals())
globals())
except Exception:
traceback.print_exc()
if init: # stop if there's an error (syntax?) in a core
@ -111,20 +111,19 @@ def reload(init=False):
if not init:
print '### new plugin (type: %s) loaded:' % \
type, format_plug(data)
type, format_plug(data)
if changed:
bot.commands = {}
for plug in bot.plugs['command']:
name = plug[1]['name'].lower()
if not re.match(r'^\w+$', name):
print '### ERROR: invalid command name "%s" (%s)' % (name,
format_plug(plug))
print '### ERROR: invalid command name "{}" ({})'.format(name, format_plug(plug))
continue
if name in bot.commands:
print "### ERROR: command '%s' already registered (%s, %s)" % \
(name, format_plug(bot.commands[name]),
format_plug(plug))
print "### ERROR: command '{}' already registered ({}, {})".format(name,
format_plug(bot.commands[name]),
format_plug(plug))
continue
bot.commands[name] = plug
@ -155,7 +154,7 @@ def reload(init=False):
for kind, plugs in sorted(bot.plugs.iteritems()):
if kind == 'command':
continue
print ' %s:' % kind
print ' {}:'.format(kind)
for plug in plugs:
print format_plug(plug, kind=kind, lpad=6)
print

View File

@ -1,33 +0,0 @@
def yaml_load(filename):
import yaml
fileHandle = open(filename, 'r')
stuff = yaml.load(fileHandle.read())
fileHandle.close()
return stuff
def yaml_save(stuff, filename):
import yaml
fileHandle = open (filename, 'w' )
fileHandle.write (yaml.dump(stuff))
fileHandle.close()
from util import hook
@hook.event('*')
def tellinput(paraml, input=None, say=None):
# import time
# now = time.time()
# spam = yaml_load('spam')
# if spam[input.nick]:
# spam[input.nick].append(time.time())
# else:
# spam[input.nick] = [time.time()]
# for x in spam[input.nick]:
# if now - x > 5:
# spam[input.nick].pop(x)
# if len(spam[input.nick]) > 8:
# say(":O")
# say("HOW COULD YOU "+input.nick)
# say("lol!")
# yaml_save(spam,'spam')
return

View File

@ -1,33 +0,0 @@
import json
import random
import re
from util import hook, http
@hook.command
def suggest(inp, inp_unstripped=''):
".suggest [#n] <phrase> -- gets a random/the nth suggested google search"
inp = inp_unstripped
m = re.match('^#(\d+) (.+)$', inp)
if m:
num, inp = m.groups()
num = int(num)
if num > 10:
return 'I can only get the first ten suggestions.'
else:
num = 0
page = http.get('http://google.com/complete/search', output='json', client='hp', q=inp)
page_json = page.split('(', 1)[1][:-1]
suggestions = json.loads(page_json)[1]
if not suggestions:
return 'No suggestions found.'
if num:
if len(suggestions) + 1 <= num:
return 'I only got %d suggestions.' % len(suggestions)
out = suggestions[num - 1]
else:
out = random.choice(suggestions)
return '#%d: %s' % (int(out[2][0]) + 1, out[0].replace('<b>', '').replace('</b>', ''))

72
disabled_stuff/attacks.py Normal file
View File

@ -0,0 +1,72 @@
import random
from util import hook
with open("plugins/data/larts.txt") as f:
larts = [line.strip() for line in f.readlines()
if not line.startswith("//")]
with open("plugins/data/insults.txt") as f:
insults = [line.strip() for line in f.readlines()
if not line.startswith("//")]
with open("plugins/data/flirts.txt") as f:
flirts = [line.strip() for line in f.readlines()
if not line.startswith("//")]
@hook.command
def lart(inp, action=None, nick=None, conn=None, notice=None):
"""lart <user> -- LARTs <user>."""
target = inp.strip()
if " " in target:
notice("Invalid username!")
return
# if the user is trying to make the bot slap itself, slap them
if target.lower() == conn.nick.lower() or target.lower() == "itself":
target = nick
values = {"user": target}
phrase = random.choice(larts)
# act out the message
action(phrase.format(**values))
@hook.command
def insult(inp, nick=None, action=None, conn=None, notice=None):
"""insult <user> -- Makes the bot insult <user>."""
target = inp.strip()
if " " in target:
notice("Invalid username!")
return
if target == conn.nick.lower() or target == "itself":
target = nick
else:
target = inp
out = 'insults {}... "{}"'.format(target, random.choice(insults))
action(out)
@hook.command
def flirt(inp, action=None, conn=None, notice=None):
"""flirt <user> -- Make the bot flirt with <user>."""
target = inp.strip()
if " " in target:
notice("Invalid username!")
return
if target == conn.nick.lower() or target == "itself":
target = 'itself'
else:
target = inp
out = 'flirts with {}... "{}"'.format(target, random.choice(flirts))
action(out)

16
plugins/bf.py → disabled_stuff/brainfuck.py Executable file → Normal file
View File

@ -1,5 +1,5 @@
'''brainfuck interpreter adapted from (public domain) code at
http://brainfuck.sourceforge.net/brain.py'''
"""brainfuck interpreter adapted from (public domain) code at
http://brainfuck.sourceforge.net/brain.py"""
import re
import random
@ -14,7 +14,7 @@ MAX_STEPS = 1000000
@hook.command('brainfuck')
@hook.command
def bf(inp):
"bf <prog> -- Executes <prog> as Brainfuck code."
"""bf <prog> -- Executes <prog> as Brainfuck code."""
program = re.sub('[^][<>+-.,]', '', inp)
@ -45,10 +45,10 @@ def bf(inp):
# the main program loop:
while ip < len(program):
c = program[ip]
if c == '+':
memory[mp] = memory[mp] + 1 % 256
if c == '+':
memory[mp] += 1 % 256
elif c == '-':
memory[mp] = memory[mp] - 1 % 256
memory[mp] -= 1 % 256
elif c == '>':
mp += 1
if mp > rightmost:
@ -57,7 +57,7 @@ def bf(inp):
# no restriction on memory growth!
memory.extend([0] * BUFFER_SIZE)
elif c == '<':
mp = mp - 1 % len(memory)
mp -= 1 % len(memory)
elif c == '.':
output += chr(memory[mp])
if len(output) > 500:
@ -76,7 +76,7 @@ def bf(inp):
if steps > MAX_STEPS:
if output == '':
output = '(no output)'
output += '[exceeded %d iterations]' % MAX_STEPS
output += '[exceeded {} iterations]'.format(MAX_STEPS)
break
stripped_output = re.sub(r'[\x00-\x1F]', '', output)

4
plugins/choose.py → disabled_stuff/choose.py Executable file → Normal file
View File

@ -6,8 +6,8 @@ from util import hook
@hook.command
def choose(inp):
"choose <choice1>, [choice2], [choice3], [choice4], ... -- " \
"Randomly picks one of the given choices."
"""choose <choice1>, [choice2], [choice3], [choice4], ... --
Randomly picks one of the given choices."""
c = re.findall(r'([^,]+)', inp)
if len(c) == 1:

121
disabled_stuff/cleverbot.py Normal file
View File

@ -0,0 +1,121 @@
# from jessi bot
import urllib2
import hashlib
import re
import unicodedata
from util import hook
# these are just parts required
# TODO: Merge them.
arglist = ['', 'y', '', '', '', '', '', '', '', '', 'wsf', '',
'', '', '', '', '', '', '', '0', 'Say', '1', 'false']
always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'abcdefghijklmnopqrstuvwxyz'
'0123456789' '_.-')
headers = {'X-Moz': 'prefetch', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1)Gecko/20100101 Firefox/7.0',
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Referer': 'http://www.cleverbot.com',
'Pragma': 'no-cache', 'Cache-Control': 'no-cache, no-cache', 'Accept-Language': 'en-us;q=0.8,en;q=0.5'}
keylist = ['stimulus', 'start', 'sessionid', 'vText8', 'vText7', 'vText6',
'vText5', 'vText4', 'vText3', 'vText2', 'icognoid',
'icognocheck', 'prevref', 'emotionaloutput', 'emotionalhistory',
'asbotname', 'ttsvoice', 'typing', 'lineref', 'fno', 'sub',
'islearning', 'cleanslate']
MsgList = list()
def quote(s, safe='/'): # quote('abc def') -> 'abc%20def'
s = s.encode('utf-8')
s = s.decode('utf-8')
print "s= " + s
print "safe= " + safe
safe += always_safe
safe_map = dict()
for i in range(256):
c = chr(i)
safe_map[c] = (c in safe) and c or ('%%%02X' % i)
try:
res = map(safe_map.__getitem__, s)
except:
print "blank"
return ''
print "res= " + ''.join(res)
return ''.join(res)
def encode(keylist, arglist):
text = str()
for i in range(len(keylist)):
k = keylist[i]
v = quote(arglist[i])
text += '&' + k + '=' + v
text = text[1:]
return text
def Send():
data = encode(keylist, arglist)
digest_txt = data[9:29]
new_hash = hashlib.md5(digest_txt).hexdigest()
arglist[keylist.index('icognocheck')] = new_hash
data = encode(keylist, arglist)
req = urllib2.Request('http://www.cleverbot.com/webservicemin',
data, headers)
f = urllib2.urlopen(req)
reply = f.read()
return reply
def parseAnswers(text):
d = dict()
keys = ['text', 'sessionid', 'logurl', 'vText8', 'vText7', 'vText6',
'vText5', 'vText4', 'vText3', 'vText2', 'prevref', 'foo',
'emotionalhistory', 'ttsLocMP3', 'ttsLocTXT', 'ttsLocTXT3',
'ttsText', 'lineRef', 'lineURL', 'linePOST', 'lineChoices',
'lineChoicesAbbrev', 'typingData', 'divert']
values = text.split('\r')
i = 0
for key in keys:
d[key] = values[i]
i += 1
return d
def ask(inp):
arglist[keylist.index('stimulus')] = inp
if MsgList:
arglist[keylist.index('lineref')] = '!0' + str(len(
MsgList) / 2)
asw = Send()
MsgList.append(inp)
answer = parseAnswers(asw)
for k, v in answer.iteritems():
try:
arglist[keylist.index(k)] = v
except ValueError:
pass
arglist[keylist.index('emotionaloutput')] = str()
text = answer['ttsText']
MsgList.append(text)
return text
@hook.command("cb")
def cleverbot(inp, reply=None):
reply(ask(inp))
''' # TODO: add in command to control extra verbose per channel
@hook.event('PRIVMSG')
def cbevent(inp, reply=None):
reply(ask(inp))
@hook.command("cbver", permissions=['cleverbot'])
def cleverbotverbose(inp, notice=None):
if on in input
'''

0
cloudbot → disabled_stuff/cloudbot.sh Executable file → Normal file
View File

14
plugins/coin.py → disabled_stuff/coin.py Executable file → Normal file
View File

@ -1,10 +1,11 @@
from util import hook
import random
from util import hook
@hook.command(autohelp=False)
def coin(inp, me=None):
"coin [amount] -- Flips [amount] of coins."
def coin(inp, action=None):
"""coin [amount] -- Flips [amount] of coins."""
if inp:
try:
@ -15,11 +16,10 @@ def coin(inp, me=None):
amount = 1
if amount == 1:
me("flips a coin and gets %s." % random.choice(["heads", "tails"]))
action("flips a coin and gets {}.".format(random.choice(["heads", "tails"])))
elif amount == 0:
me("makes a coin flipping motion with its hands.")
action("makes a coin flipping motion with its hands.")
else:
heads = int(random.normalvariate(.5 * amount, (.75 * amount) ** .5))
tails = amount - heads
me("flips %i coins and gets " \
"%i heads and %i tails." % (amount, heads, tails))
action("flips {} coins and gets {} heads and {} tails.".format(amount, heads, tails))

View File

@ -0,0 +1,37 @@
from util import hook
import re
CORRECTION_RE = r'^(s|S)/.*/.*/?\S*$'
@hook.regex(CORRECTION_RE)
def correction(match, input=None, conn=None, message=None):
split = input.msg.split("/")
if len(split) == 4:
nick = split[3].lower()
else:
nick = None
find = split[1]
replace = split[2]
for item in conn.history[input.chan].__reversed__():
name, timestamp, msg = item
if msg.startswith("s/"):
# don't correct corrections, it gets really confusing
continue
if nick:
if nick != name.lower():
continue
if find in msg:
if "\x01ACTION" in msg:
msg = msg.replace("\x01ACTION ", "/me ").replace("\x01", "")
message(u"Correction, <{}> {}".format(name, msg.replace(find, "\x02" + replace + "\x02")))
return
else:
continue
return u"Did not find {} in any recent messages.".format(find)

View File

@ -0,0 +1,60 @@
from util import http, hook
## CONSTANTS
exchanges = {
"blockchain": {
"api_url": "https://blockchain.info/ticker",
"func": lambda data: u"Blockchain // Buy: \x0307${:,.2f}\x0f -"
u" Sell: \x0307${:,.2f}\x0f".format(data["USD"]["buy"], data["USD"]["sell"])
},
"coinbase": {
"api_url": "https://coinbase.com/api/v1/prices/spot_rate",
"func": lambda data: u"Coinbase // Current: \x0307${:,.2f}\x0f".format(float(data['amount']))
},
"bitpay": {
"api_url": "https://bitpay.com/api/rates",
"func": lambda data: u"Bitpay // Current: \x0307${:,.2f}\x0f".format(data[0]['rate'])
},
"bitstamp": {
"api_url": "https://www.bitstamp.net/api/ticker/",
"func": lambda data: u"BitStamp // Current: \x0307${:,.2f}\x0f - High: \x0307${:,.2f}\x0f -"
u" Low: \x0307${:,.2f}\x0f - Volume: {:,.2f} BTC".format(float(data['last']),
float(data['high']),
float(data['low']),
float(data['volume']))
}
}
## HOOK FUNCTIONS
@hook.command("btc", autohelp=False)
@hook.command(autohelp=False)
def bitcoin(inp):
"""bitcoin <exchange> -- Gets current exchange rate for bitcoins from several exchanges, default is Blockchain.
Supports MtGox, Bitpay, Coinbase and BitStamp."""
inp = inp.lower()
if inp:
if inp in exchanges:
exchange = exchanges[inp]
else:
return "Invalid Exchange"
else:
exchange = exchanges["blockchain"]
data = http.get_json(exchange["api_url"])
func = exchange["func"]
return func(data)
@hook.command("ltc", autohelp=False)
@hook.command(autohelp=False)
def litecoin(inp, message=None):
"""litecoin -- gets current exchange rate for litecoins from BTC-E"""
data = http.get_json("https://btc-e.com/api/2/ltc_usd/ticker")
ticker = data['ticker']
message("Current: \x0307${:,.2f}\x0f - High: \x0307${:,.2f}\x0f"
" - Low: \x0307${:,.2f}\x0f - Volume: {:,.2f} LTC".format(ticker['buy'], ticker['high'], ticker['low'],
ticker['vol_cur']))

39
disabled_stuff/cypher.py Normal file
View File

@ -0,0 +1,39 @@
import base64
from util import hook
def encode(key, clear):
enc = []
for i in range(len(clear)):
key_c = key[i % len(key)]
enc_c = chr((ord(clear[i]) + ord(key_c)) % 256)
enc.append(enc_c)
return base64.urlsafe_b64encode("".join(enc))
def decode(key, enc):
dec = []
enc = base64.urlsafe_b64decode(enc.encode('ascii', 'ignore'))
for i in range(len(enc)):
key_c = key[i % len(key)]
dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
@hook.command
def cypher(inp):
"""cypher <pass> <string> -- Cyphers <string> with <password>."""
passwd = inp.split(" ")[0]
inp = " ".join(inp.split(" ")[1:])
return encode(passwd, inp)
@hook.command
def decypher(inp):
"""decypher <pass> <string> -- Decyphers <string> with <password>."""
passwd = inp.split(" ")[0]
inp = " ".join(inp.split(" ")[1:])
return decode(passwd, inp)

View File

@ -44,4 +44,11 @@ Do you live on a chicken farm? Because you sure know how to raise cocks.
Are you wearing space pants? Because your ass is out of this world.
Nice legs. What time do they open?
Are you lost? Because its so strange to see an angel so far from heaven.
Your daddy must have been a baker, because you've got a nice set of buns.
Your daddy must have been a baker, because you've got a nice set of buns.
You're so beautiful that last night you made me forget my pickup line.
I've never seen such dark eyes with so much light in them.
I think we should just be friends with sexual tension.
Whenever I see you I feel like a dog dying to get out of the car.
If I'd have held you any closer I'd be in back of you.
I wish I were on Facebook so I could poke you.
I want you like JFK wanted a car with a roof.

View File

View File

View File

@ -0,0 +1,620 @@
1 Stone
1:1 Granite
1:2 Polished Granite
1:3 Diorite
1:4 Polished Diorite
1:5 Andesite
1:6 Polished Andesite
2 Grass
3 Dirt
3:1 Dirt (No Grass)
3:2 Podzol
4 Cobblestone
5 Wooden Plank (Oak)
5:1 Wooden Plank (Spruce)
5:2 Wooden Plank (Birch)
5:3 Wooden Plank (Jungle)
5:4 Wooden Plank (Acacia)
5:5 Wooden Plank (Dark Oak)
6 Sapling (Oak)
6:1 Sapling (Spruce)
6:2 Sapling (Birch)
6:3 Sapling (Jungle)
6:4 Sapling (Acacia)
6:5 Sapling (Dark Oak)
7 Bedrock
8 Water
9 Water (No Spread)
10 Lava
11 Lava (No Spread)
12 Sand
12:1 Red Sand
13 Gravel
14 Gold Ore
15 Iron Ore
16 Coal Ore
17 Wood (Oak)
17:1 Wood (Spruce)
17:2 Wood (Birch)
17:3 Wood (Jungle)
17:4 Wood (Oak 4)
17:5 Wood (Oak 5)
18 Leaves (Oak)
18:1 Leaves (Spruce)
18:2 Leaves (Birch)
18:3 Leaves (Jungle)
19 Sponge
20 Glass
21 Lapis Lazuli Ore
22 Lapis Lazuli Block
23 Dispenser
24 Sandstone
24:1 Sandstone (Chiseled)
24:2 Sandstone (Smooth)
25 Note Block
26 Bed (Block)
27 Rail (Powered)
28 Rail (Detector)
29 Sticky Piston
30 Cobweb
31 Tall Grass (Dead Shrub)
31:1 Tall Grass
31:2 Tall Grass (Fern)
32 Dead Shrub
33 Piston
34 Piston (Head)
35 Wool
35:1 Orange Wool
35:2 Magenta Wool
35:3 Light Blue Wool
35:4 Yellow Wool
35:5 Lime Wool
35:6 Pink Wool
35:7 Gray Wool
35:8 Light Gray Wool
35:9 Cyan Wool
35:10 Purple Wool
35:11 Blue Wool
35:12 Brown Wool
35:13 Green Wool
35:14 Red Wool
35:15 Black Wool
36 Piston (Moving)
37 Dandelion
38 Poppy
38:1 Blue Orchid
38:2 Allium
38:4 Red Tulip
38:5 Orange Tulip
38:6 White Tulip
38:7 Pink Tulip
38:8 Oxeye Daisy
39 Brown Mushroom
40 Red Mushroom
41 Block of Gold
42 Block of Iron
43 Stone Slab (Double)
43:1 Sandstone Slab (Double)
43:2 Wooden Slab (Double)
43:3 Cobblestone Slab (Double)
43:4 Brick Slab (Double)
43:5 Stone Brick Slab (Double)
43:6 Nether Brick Slab (Double)
43:7 Quartz Slab (Double)
43:8 Smooth Stone Slab (Double)
43:9 Smooth Sandstone Slab (Double)
44 Stone Slab
44:1 Sandstone Slab
44:2 Wooden Slab
44:3 Cobblestone Slab
44:4 Brick Slab
44:5 Stone Brick Slab
44:6 Nether Brick Slab
44:7 Quartz Slab
45 Brick
46 TNT
47 Bookshelf
48 Moss Stone
49 Obsidian
50 Torch
51 Fire
52 Mob Spawner
53 Wooden Stairs (Oak)
54 Chest
55 Redstone Wire
56 Diamond Ore
57 Block of Diamond
58 Workbench
59 Wheat (Crop)
60 Farmland
61 Furnace
62 Furnace (Smelting)
63 Sign (Block)
64 Wood Door (Block)
65 Ladder
66 Rail
67 Cobblestone Stairs
68 Sign (Wall Block)
69 Lever
70 Stone Pressure Plate
71 Iron Door (Block)
72 Wooden Pressure Plate
73 Redstone Ore
74 Redstone Ore (Glowing)
75 Redstone Torch (Off)
76 Redstone Torch
77 Button (Stone)
78 Snow
79 Ice
80 Snow Block
81 Cactus
82 Clay Block
83 Sugar Cane (Block)
84 Jukebox
85 Fence
86 Pumpkin
87 Netherrack
88 Soul Sand
89 Glowstone
90 Portal
91 Jack-O-Lantern
92 Cake (Block)
93 Redstone Repeater (Block Off)
94 Redstone Repeater (Block On)
95 Stained Glass (White)
95:1 Stained Glass (Orange)
95:2 Stained Glass (Magenta)
95:3 Stained Glass (Light Blue)
95:4 Stained Glass (Yellow)
95:5 Stained Glass (Lime)
95:6 Stained Glass (Pink)
95:7 Stained Glass (Gray)
95:8 Stained Glass (Light Grey)
95:9 Stained Glass (Cyan)
95:10 Stained Glass (Purple)
95:11 Stained Glass (Blue)
95:12 Stained Glass (Brown)
95:13 Stained Glass (Green)
95:14 Stained Glass (Red)
95:15 Stained Glass (Black)
96 Trapdoor
97 Monster Egg (Stone)
97:1 Monster Egg (Cobblestone)
97:2 Monster Egg (Stone Brick)
97:3 Monster Egg (Mossy Stone Brick)
97:4 Monster Egg (Cracked Stone)
97:5 Monster Egg (Chiseled Stone)
98 Stone Bricks
98:1 Mossy Stone Bricks
98:2 Cracked Stone Bricks
98:3 Chiseled Stone Brick
99 Brown Mushroom (Block)
100 Red Mushroom (Block)
101 Iron Bars
102 Glass Pane
103 Melon (Block)
104 Pumpkin Vine
105 Melon Vine
106 Vines
107 Fence Gate
108 Brick Stairs
109 Stone Brick Stairs
110 Mycelium
111 Lily Pad
112 Nether Brick
113 Nether Brick Fence
114 Nether Brick Stairs
115 Nether Wart
116 Enchantment Table
117 Brewing Stand (Block)
118 Cauldron (Block)
119 End Portal
120 End Portal Frame
121 End Stone
122 Dragon Egg
123 Redstone Lamp
124 Redstone Lamp (On)
125 Oak-Wood Slab (Double)
125:1 Spruce-Wood Slab (Double)
125:2 Birch-Wood Slab (Double)
125:3 Jungle-Wood Slab (Double)
125:4 Acacia Wood Slab (Double)
125:5 Dark Oak Wood Slab (Double)
126 Oak-Wood Slab
126:1 Spruce-Wood Slab
126:2 Birch-Wood Slab
126:3 Jungle-Wood Slab
126:4 Acacia Wood Slab
126:5 Dark Oak Wood Slab
127 Cocoa Plant
128 Sandstone Stairs
129 Emerald Ore
130 Ender Chest
131 Tripwire Hook
132 Tripwire
133 Block of Emerald
134 Wooden Stairs (Spruce)
135 Wooden Stairs (Birch)
136 Wooden Stairs (Jungle)
137 Command Block
138 Beacon
139 Cobblestone Wall
139:1 Mossy Cobblestone Wall
140 Flower Pot (Block)
141 Carrot (Crop)
142 Potatoes (Crop)
143 Button (Wood)
144 Head Block (Skeleton)
144:1 Head Block (Wither)
144:2 Head Block (Zombie)
144:3 Head Block (Steve)
144:4 Head Block (Creeper)
145 Anvil
145:1 Anvil (Slightly Damaged)
145:2 Anvil (Very Damaged)
146 Trapped Chest
147 Weighted Pressure Plate (Light)
148 Weighted Pressure Plate (Heavy)
149 Redstone Comparator (Off)
150 Redstone Comparator (On)
151 Daylight Sensor
152 Block of Redstone
153 Nether Quartz Ore
154 Hopper
155 Quartz Block
155:1 Chiseled Quartz Block
155:2 Pillar Quartz Block
156 Quartz Stairs
157 Rail (Activator)
158 Dropper
159 Stained Clay (White)
159:1 Stained Clay (Orange)
159:2 Stained Clay (Magenta)
159:3 Stained Clay (Light Blue)
159:4 Stained Clay (Yellow)
159:5 Stained Clay (Lime)
159:6 Stained Clay (Pink)
159:7 Stained Clay (Gray)
159:8 Stained Clay (Light Gray)
159:9 Stained Clay (Cyan)
159:10 Stained Clay (Purple)
159:11 Stained Clay (Blue)
159:12 Stained Clay (Brown)
159:13 Stained Clay (Green)
159:14 Stained Clay (Red)
159:15 Stained Clay (Black)
160 Stained Glass Pane (White)
160:1 Stained Glass Pane (Orange)
160:2 Stained Glass Pane (Magenta)
160:3 Stained Glass Pane (Light Blue)
160:4 Stained Glass Pane (Yellow)
160:5 Stained Glass Pane (Lime)
160:6 Stained Glass Pane (Pink)
160:7 Stained Glass Pane (Gray)
160:8 Stained Glass Pane (Light Gray)
160:9 Stained Glass Pane (Cyan)
160:10 Stained Glass Pane (Purple)
160:11 Stained Glass Pane (Blue)
160:12 Stained Glass Pane (Brown)
160:13 Stained Glass Pane (Green)
160:14 Stained Glass Pane (Red)
160:15 Stained Glass Pane (Black)
162 Wood (Acacia Oak)
162:1 Wood (Dark Oak)
163 Wooden Stairs (Acacia)
164 Wooden Stairs (Dark Oak)
165 Slime Block
170 Hay Bale
171 Carpet (White)
171:1 Carpet (Orange)
171:2 Carpet (Magenta)
171:3 Carpet (Light Blue)
171:4 Carpet (Yellow)
171:5 Carpet (Lime)
171:6 Carpet (Pink)
171:7 Carpet (Grey)
171:8 Carpet (Light Gray)
171:9 Carpet (Cyan)
171:10 Carpet (Purple)
171:11 Carpet (Blue)
171:12 Carpet (Brown)
171:13 Carpet (Green)
171:14 Carpet (Red)
171:15 Carpet (Black)
172 Hardened Clay
173 Block of Coal
174 Packed Ice
175 Sunflower
175:1 Lilac
175:2 Double Tallgrass
175:3 Large Fern
175:4 Rose Bush
175:5 Peony
256 Iron Shovel
257 Iron Pickaxe
258 Iron Axe
259 Flint and Steel
260 Apple
261 Bow
262 Arrow
263 Coal
263:1 Charcoal
264 Diamond Gem
265 Iron Ingot
266 Gold Ingot
267 Iron Sword
268 Wooden Sword
269 Wooden Shovel
270 Wooden Pickaxe
271 Wooden Axe
272 Stone Sword
273 Stone Shovel
274 Stone Pickaxe
275 Stone Axe
276 Diamond Sword
277 Diamond Shovel
278 Diamond Pickaxe
279 Diamond Axe
280 Stick
281 Bowl
282 Mushroom Stew
283 Gold Sword
284 Gold Shovel
285 Gold Pickaxe
286 Gold Axe
287 String
288 Feather
289 Gunpowder
290 Wooden Hoe
291 Stone Hoe
292 Iron Hoe
293 Diamond Hoe
294 Gold Hoe
295 Wheat Seeds
296 Wheat
297 Bread
298 Leather Helmet
299 Leather Chestplate
300 Leather Leggings
301 Leather Boots
302 Chainmail Helmet
303 Chainmail Chestplate
304 Chainmail Leggings
305 Chainmail Boots
306 Iron Helmet
307 Iron Chestplate
308 Iron Leggings
309 Iron Boots
310 Diamond Helmet
311 Diamond Chestplate
312 Diamond Leggings
313 Diamond Boots
314 Gold Helmet
315 Gold Chestplate
316 Gold Leggings
317 Gold Boots
318 Flint
319 Raw Porkchop
320 Cooked Porkchop
321 Painting
322 Golden Apple
322:1 Enchanted Golden Apple
323 Sign
324 Wooden Door
325 Bucket
326 Bucket (Water)
327 Bucket (Lava)
328 Minecart
329 Saddle
330 Iron Door
331 Redstone Dust
332 Snowball
333 Boat
334 Leather
335 Bucket (Milk)
336 Clay Brick
337 Clay
338 Sugar Cane
339 Paper
340 Book
341 Slime Ball
342 Minecart (Storage)
343 Minecart (Powered)
344 Egg
345 Compass
346 Fishing Rod
347 Watch
348 Glowstone Dust
349 Raw Fish
349:1 Raw Salmon
349:2 Clownfish
349:3 Pufferfish
350 Cooked Fish
350:1 Cooked Salmon
350:2 Clownfish
350:3 Pufferfish
351 Ink Sack
351:1 Rose Red Dye
351:2 Cactus Green Dye
351:3 Cocoa Bean
351:4 Lapis Lazuli
351:5 Purple Dye
351:6 Cyan Dye
351:7 Light Gray Dye
351:8 Gray Dye
351:9 Pink Dye
351:10 Lime Dye
351:11 Dandelion Yellow Dye
351:12 Light Blue Dye
351:13 Magenta Dye
351:14 Orange Dye
351:15 Bone Meal
352 Bone
353 Sugar
354 Cake
355 Bed
356 Redstone Repeater
357 Cookie
358 Map
359 Shears
360 Melon (Slice)
361 Pumpkin Seeds
362 Melon Seeds
363 Raw Beef
364 Steak
365 Raw Chicken
366 Cooked Chicken
367 Rotten Flesh
368 Ender Pearl
369 Blaze Rod
370 Ghast Tear
371 Gold Nugget
372 Nether Wart Seeds
373 Water Bottle
373:16 Awkward Potion
373:32 Thick Potion
373:64 Mundane Potion
373:8193 Regeneration Potion (0:45)
373:8194 Swiftness Potion (3:00)
373:8195 Fire Resistance Potion (3:00)
373:8196 Poison Potion (0:45)
373:8197 Healing Potion
373:8198 Night Vision Potion (3:00)
373:8200 Weakness Potion (1:30)
373:8201 Strength Potion (3:00)
373:8202 Slowness Potion (1:30)
373:8204 Harming Potion
373:8205 Water Breathing Potion (3:00)
373:8206 Invisibility Potion (3:00)
373:8225 Regeneration Potion II (0:22)
373:8226 Swiftness Potion II (1:30)
373:8228 Poison Potion II (0:22)
373:8229 Healing Potion II
373:8233 Strength Potion II (1:30)
373:8236 Harming Potion II
373:8257 Regeneration Potion (2:00)
373:8258 Swiftness Potion (8:00)
373:8259 Fire Resistance Potion (8:00)
373:8260 Poison Potion (2:00)
373:8262 Night Vision Potion (8:00)
373:8264 Weakness Potion (4:00)
373:8265 Strength Potion (8:00)
373:8266 Slowness Potion (4:00)
373:8269 Water Breathing Potion (8:00)
373:8270 Invisibility Potion (8:00)
373:8289 Regeneration Potion II (1:00)
373:8290 Swiftness Potion II (4:00)
373:8292 Poison Potion II (1:00)
373:8297 Strength Potion II (4:00)
373:16385 Regeneration Splash (0:33)
373:16386 Swiftness Splash (2:15)
373:16387 Fire Resistance Splash (2:15)
373:16388 Poison Splash (0:33)
373:16389 Healing Splash
373:16390 Night Vision Splash (2:15)
373:16392 Weakness Splash (1:07)
373:16393 Strength Splash (2:15)
373:16394 Slowness Splash (1:07)
373:16396 Harming Splash
373:16397 Breathing Splash (2:15)
373:16398 Invisibility Splash (2:15)
373:16417 Regeneration Splash II (0:16)
373:16418 Swiftness Splash II (1:07)
373:16420 Poison Splash II (0:16)
373:16421 Healing Splash II
373:16425 Strength Splash II (1:07)
373:16428 Harming Splash II
373:16449 Regeneration Splash (1:30)
373:16450 Swiftness Splash (6:00)
373:16451 Fire Resistance Splash (6:00)
373:16452 Poison Splash (1:30)
373:16454 Night Vision Splash (6:00)
373:16456 Weakness Splash (3:00)
373:16457 Strength Splash (6:00)
373:16458 Slowness Splash (3:00)
373:16461 Breathing Splash (6:00)
373:16462 Invisibility Splash (6:00)
373:16481 Regeneration Splash II (0:45)
373:16482 Swiftness Splash II (3:00)
373:16484 Poison Splash II (0:45)
373:16489 Strength Splash II (3:00)
374 Glass Bottle
375 Spider Eye
376 Fermented Spider Eye
377 Blaze Powder
378 Magma Cream
379 Brewing Stand
380 Cauldron
381 Eye of Ender
382 Glistering Melon (Slice)
383:50 Spawn Egg (Creeper)
383:51 Spawn Egg (Skeleton)
383:52 Spawn Egg (Spider)
383:54 Spawn Egg (Zombie)
383:55 Spawn Egg (Slime)
383:56 Spawn Egg (Ghast)
383:57 Spawn Egg (Zombie Pigmen)
383:58 Spawn Egg (Endermen)
383:59 Spawn Egg (Cave Spider)
383:60 Spawn Egg (Silverfish)
383:61 Spawn Egg (Blaze)
383:62 Spawn Egg (Magma Cube)
383:65 Spawn Egg (Bat)
383:66 Spawn Egg (Witch)
383:90 Spawn Egg (Pig)
383:91 Spawn Egg (Sheep)
383:92 Spawn Egg (Cow)
383:93 Spawn Egg (Chicken)
383:94 Spawn Egg (Squid)
383:95 Spawn Egg (Wolf)
383:96 Spawn Egg (Mooshroom)
383:98 Spawn Egg (Ocelot)
383:100 Spawn Egg (Horse)
383:120 Spawn Egg (Villager)
384 Bottle of Enchanting
385 Fire Charge
386 Book and Quill
387 Written Book
388 Emerald
389 Item Frame
390 Flower Pot
391 Carrot
392 Potato
393 Baked Potato
394 Poisonous Potato
395 Empty Map
396 Golden Carrot
397 Head (Skeleton)
397:1 Head (Wither)
397:2 Head (Zombie)
397:3 Head (Steve)
397:4 Head (Creeper)
398 Carrot on a Stick
399 Nether Star
400 Pumpkin Pie
401 Firework Rocket
402 Firework Star
403 Enchanted Book
404 Redstone Comparator
405 Nether Brick (Item)
406 Nether Quartz
407 Minecart (TNT)
408 Minecart (Hopper)
417 Iron Horse Armor
418 Gold Horse Armor
419 Diamond Horse Armor
420 Lead
421 Name Tag
422 Minecart (Command Block)
2256 Music Disk (13)
2257 Music Disk (Cat)
2258 Music Disk (Blocks)
2259 Music Disk (Chirp)
2260 Music Disk (Far)
2261 Music Disk (Mall)
2262 Music Disk (Mellohi)
2263 Music Disk (Stal)
2264 Music Disk (Strad)
2265 Music Disk (Ward)
2266 Music Disk (11)
2267 Music Disk (Wait)

View File

@ -0,0 +1,79 @@
{
"templates": [
"rips off {user}'s {limbs} and leaves them to die.",
"grabs {user}'s head and rips it clean off their body.",
"grabs a {gun} and riddles {user}'s body with bullets.",
"gags and ties {user} then throws them off a {tall_thing}.",
"crushes {user} with a huge spiked {spiked_thing}.",
"glares at {user} until they die of boredom.",
"stabs {user} in the heart a few times with a {weapon_stab}.",
"rams a {weapon_explosive} up {user}'s ass and lets off a few rounds.",
"crushes {user}'s skull in with a {weapon_crush}.",
"unleashes the armies of Isengard on {user}.",
"gags and ties {user} then throws them off a {tall_thing} to their death.",
"reaches out and punches right through {user}'s chest.",
"slices {user}'s limbs off with a {weapon_slice}.",
"throws {user} to Cthulu and watches them get ripped to shreds.",
"feeds {user} to an owlbear who then proceeds to maul them violently.",
"turns {user} into a snail and covers then in salt.",
"snacks on {user}'s dismembered body.",
"stuffs {bomb} up {user}'s ass and waits for it to go off.",
"puts {user} into a sack, throws the sack in the river, and hurls the river into space.",
"goes bowling with {user}'s bloody disembodied head.",
"sends {user} to /dev/null!",
"feeds {user} coke and mentos till they violently explode."
],
"parts": {
"gun": [
"AK47",
"machine gun",
"automatic pistol",
"Uzi"
],
"limbs": [
"legs",
"arms",
"limbs"
],
"weapon_stab": [
"knife",
"shard of glass",
"sword blade",
"butchers knife",
"corkscrew"
],
"weapon_slice": [
"sharpened katana",
"chainsaw",
"polished axe"
],
"weapon_crush": [
"spiked mace",
"baseball bat",
"wooden club",
"massive steel ball",
"heavy iron rod"
],
"weapon_explosive": [
"rocket launcher",
"grenade launcher",
"napalm launcher"
],
"tall_thing": [
"bridge",
"tall building",
"cliff",
"mountain"
],
"spiked_thing": [
"boulder",
"rock",
"barrel of rocks"
],
"bomb": [
"a bomb",
"some TNT",
"a bunch of C4"
]
}
}

View File

View File

@ -1,6 +1,6 @@
smacks {user} in the face with a burlap sack full of broken glass.
swaps {user}'s shampoo with glue.
installs Windows on {user}'s computer.
installs Windows Vista on {user}'s computer.
forces {user} to use perl for 3 weeks.
registers {user}'s name with 50 known spammers.
resizes {user}'s console to 40x24.
@ -37,10 +37,8 @@ takes away {user}'s internet connection.
pushes {user} past the Shoe Event Horizon.
counts '1, 2, 5... er... 3!' and hurls the Holy Handgrenade Of Antioch at {user}.
puts {user} in a nest of camel spiders.
makes {user} read slashdot at -1.
puts 'alias vim=emacs' in {user}'s /etc/profile.
uninstalls every web browser from {user}'s system.
locks {user} in the Chateau d'If.
signs {user} up for getting hit on the head lessons.
makes {user} try to set up a Lexmark printer.
fills {user}'s eyedrop bottle with lime juice.
@ -53,13 +51,10 @@ puts sugar between {user}'s bedsheets.
pours sand into {user}'s breakfast.
mixes epoxy into {user}'s toothpaste.
puts Icy-Hot in {user}'s lube container.
straps {user} to a chair, and plays a endless low bitrate MP3 loop of "the world's most annoying sound" from "Dumb and Dumber".
tells Dr. Dre that {user} was talking smack.
forces {user} to use a Commodore 64 for all their word processing.
puts {user} in a room with several heavily armed manic depressives.
makes {user} watch reruns of "Blue's Clues".
puts lye in {user}'s coffee.
introduces {user} to the clue-by-four.
tattoos the Windows symbol on {user}'s ass.
lets Borg have his way with {user}.
signs {user} up for line dancing classes at the local senior center.
@ -94,12 +89,11 @@ signs {user} up for the Iowa State Ferret Legging Championship.
attempts to hotswap {user}'s RAM.
dragon punches {user}.
puts railroad spikes into {user}'s side.
replaces {user}'s Astroglide with JB Weld.
replaces {user}'s lubricant with liquid weld.
replaces {user}'s stress pills with rat poison pellets.
replaces {user}'s crotch itch cream with Nair.
replaces {user}'s itch cream with hair removal cream.
does the Australian Death Grip on {user}.
dances upon the grave of {user}'s ancestors.
farts in {user}'s general direction.
farts loudly in {user}'s general direction.
flogs {user} with stinging nettle.
intoduces {user} to the Knights who say Ni.
hands {user} a poison ivy joint.

View File

@ -1,7 +1,7 @@
//Minecraft Recipes List
//Created by _303
//Obtained from https://github.com/ClouDev/CloudBot/blob/develop/plugins/data/recipes.txt
//Edited by _frozen
//Edited by CHCMATT for Minecraft version: 1.7.4
//
//Summary of Use: Each column is seperated by a comma (,) and rows by a vertical bar (|). Order of Recipes & Categories taken from
//www.minecraftwiki.net/wiki/Crafting for easier updating in the future (The Future!)
@ -21,7 +21,10 @@
1x Block of Gold: Gold Ingot, Gold Ingot, Gold Ingot | Gold Ingot, Gold Ingot, Gold Ingot | Gold Ingot, Gold Ingot, Gold Ingot
1x Block of Iron: Iron Ingot, Iron Ingot, Iron Ingot | Iron Ingot, Iron Ingot, Iron Ingot | Iron Ingot, Iron Ingot, Iron Ingot
1x Block of Diamond: Diamond, Diamond, Diamond | Diamond, Diamond, Diamond | Diamond, Diamond, Diamond
1x Block of Coal: Coal, Coal, Coal | Coal, Coal, Coal | Coal, Coal, Coal
1x Block of Redstone: Redstone Dust, Redstone Dust, Redstone Dust | Redstone Dust, Redstone Dust, Redstone Dust | Redstone Dust, Redstone Dust, Redstone Dust
1x Lapis Lazuli Block: Lapis Lazuli, Lapis Lazuli, Lapis Lazuli | Lapis Lazuli, Lapis Lazuli, Lapis Lazuli | Lapis Lazuli, Lapis Lazuli, Lapis Lazuli
1x Emerald Block: Emerald, Emerald, Emerald | Emerald, Emerald, Emerald | Emerald, Emerald, Emerald
1x Glowstone: Glowstone Dust, Glowstone Dust | Glowstone Dust, Glowstone Dust
1x Wool: String, String | String, String
1x TNT: Gunpowder, Sand, Gunpowder | Sand, Gunpowder, Sand | Gunpowder, Sand, Gunpowder
@ -117,6 +120,7 @@
6x Powered Rail: Gold Ingot, None, Gold Ingot | Gold Ingot, Stick, Gold Ingot | Gold Ingot, Redstone, Gold Ingot
6x Detector Rail: Iron Ingot, None, Iron Ingot | Iron Ingot, Pressure Plate, Iron Ingot | Iron Ingot, Redstone, Iron Ingot
1x Boat: Wooden Planks, None, Wooden Planks | Wooden Planks, Wooden Planks, Wooden Planks
1x Carrot On A Stick: Fishing Rod | None, Carrot
//
//Mechanism Recipes
//
@ -125,7 +129,8 @@
2x Trapdoor: Wooden Planks, Wooden Planks, Wooden Planks | Wooden Planks, Wooden Planks, Wooden Planks
1x Stone Pressure Plate: Stone, Stone
1x Wooden Pressure Plate: Wooden Planks, Wooden Planks
1x Button: Stone | Stone
1x Stone Button: Stone
1x Wooden Button: Wooden Planks
1x Redstone Torch: Redstone | Stick
1x Lever: Stick | Cobblestone
1x Note Block: Wooden Planks, Wooden Planks, Wooden Planks | Wooden Planks, Redstone, Wooden Planks | Wooden Planks, Wooden Planks, Wooden Planks
@ -133,8 +138,13 @@
1x Dispenser: Cobblestone, Cobblestone, Cobblestone | Cobblestone, Bow, Cobblestone | Cobblestone, Redstone, Cobblestone
1x Redstone Repeater: Redstone Torch, Redstone, Redstone Torch | Stone, Stone, Stone
1x Piston: Wooden Planks, Wooden Planks, Wooden Planks | Cobblestone, Iron Ingot, Cobblestone | Cobblestone, Redstone, Cobblestone
1x Sticky Piston: none, slime ball, none | none, piston, none
1x Redstone Lamp: none, redstone dust, none | redstone dust, glowstone block, redstone | none, redstone dust, none
1x Sticky Piston: Slime Ball | Piston
1x Redstone Lamp: None, Redstone Dust, None | Redstone Dust, Glowstone Block, Redstone Dust | None, Redstone Dust, None
1x Trapped Chest: Chest, Tripwire Hook
1x Dropper: Cobblestone, Cobblestone, Cobblestone | Cobblestone, None, Cobblestone | Cobblestone, Redstone Dust, Cobblestone
1x Weighted Pressure Plate (Heavy): Iron Ingot, Iron Ingot
1x Weighted Pressure Plate (Light): Gold Ingot, Gold Ingot
2x Tripwire Hook: Iron Ingot | Stick | Wooden Planks
//
//Food Recipes
//
@ -169,6 +179,11 @@
9x Gold Nugget: Gold Ingot
1x Gold Ingot: Gold Nugget, Gold Nugget, Gold Nugget | Gold Nugget, Gold Nugget, Gold Nugget | Gold Nugget, Gold Nugget, Gold Nugget
1x Eye of Ender: Ender Pearl | Blaze Powder
1x Item Frame: Stick, Stick, Stick | Stick, Leather, Stick | Stick, Stick, Stick
1x Anvil: Block of Iron, Block of Iron, Block of Iron | None, Iron Ingot, None | Iron Ingot, Iron Ingot, Iron Ingot
1x Ender Chest: Obsidian, Obsidian, Obsidian | Osbidian, Eye of Ender, Obsidian | Obsidian, Obsidian, Obsidian
1x Flower Pot: Brick, None, Brick | None, Brick, None
2x Lead: None, String, String | None, Slime Ball, String | String, None, None
//
//Dye Recipes
//
@ -214,4 +229,41 @@
1x Fermented Spider Eye: Spider Eye | Brown Mushroom, Sugar
1x Glistering Melon: Melon Slice, Gold Nugget
9x Gold Nugget: Gold Ingot
1x Enchantment Table: None, Book, None | Diamond, Obsidian, Diamond | Obsidian, Obsidian, Obsidian
1x Enchantment Table: None, Book, None | Diamond, Obsidian, Diamond | Obsidian, Obsidian, Obsidian
//
//Stained Glass Recipes
//
8x White Stained Glass: Glass, Glass, Glass | Glass, Bone Meal, Glass | Glass, Glass, Glass
8x Orange Stained Glass: Glass, Glass, Glass | Glass, Orange Dye, Glass | Glass, Glass, Glass
8x Magenta Stained Glass: Glass, Glass, Glass | Glass, Magenta Dye, Glass | Glass, Glass, Glass
8x Light Blue Stained Glass: Glass, Glass, Glass | Glass, Light Blue Dye, Glass | Glass, Glass, Glass
8x Yellow Stained Glass: Glass, Glass, Glass | Glass, Dandelion Yellow, Glass | Glass, Glass, Glass
8x Lime Stained Glass: Glass, Glass, Glass | Glass, Lime Dye, Glass | Glass, Glass, Glass
8x Pink Stained Glass: Glass, Glass, Glass | Glass, Pink Dye, Glass | Glass, Glass, Glass
8x Gray Stained Glass: Glass, Glass, Glass | Glass, Gray Dye, Glass | Glass, Glass, Glass
8x Light Gray Stained Glass: Glass, Glass, Glass | Glass, Light Gray Dye, Glass | Glass, Glass, Glass
8x Cyan Stained Glass: Glass, Glass, Glass | Glass, Cyan Dye, Glass | Glass, Glass, Glass
8x Purple Stained Glass: Glass, Glass, Glass | Glass, Purple Dye, Glass | Glass, Glass, Glass
8x Blue Stained Glass: Glass, Glass, Glass | Glass, Lapis Lazuli, Glass | Glass, Glass, Glass
8x Brown Stained Glass: Glass, Glass, Glass | Glass, Cocoa Beans, Glass | Glass, Glass, Glass
8x Green Stained Glass: Glass, Glass, Glass | Glass, Cactus Green, Glass | Glass, Glass, Glass
8x Red Stained Glass: Glass, Glass, Glass | Glass, Rose Red, Glass | Glass, Glass, Glass
8x Black Stained Glass: Glass, Glass, Glass | Glass, Inc Sac, Glass | Glass, Glass, Glass
//
//Stained Glass Panes
//
16x White Stained Glass Panes: White Stained Glass, White Stained Glass, White Stained Glass | White Stained Glass, White Stained Glass, White Stained Glass
16x Orange Stained Glass Panes: Orange Stained Glass, Orange Stained Glass, Orange Stained Glass | Orange Stained Glass, Orange Stained Glass, Orange Stained Glass
16x Magenta Stained Glass Panes: Magenta Stained Glass, Magenta Stained Glass, Magenta Stained Glass | Magenta Stained Glass, Magenta Stained Glass, Magenta Stained Glass
16x Light Blue Stained Glass Panes: Light Blue Stained Glass, Light Blue Stained Glass, Light Blue Stained Glass | Light Blue Stained Glass, Light Blue Stained Glass, Light Blue Stained Glass
16x Yellow Stained Glass Panes: Yellow Stained Glass, Yellow Stained Glass, Yellow Stained Glass | Yellow Stained Glass, Yellow Stained Glass, Yellow Stained Glass
16x Lime Stained Glass Panes: Lime Stained Glass, Lime Stained Glass, Lime Stained Glass | Lime Stained Glass, Lime Stained Glass, Lime Stained Glass
16x Pink Stained Glass Panes: Pink Stained Glass, Pink Stained Glass, Pink Stained Glass | Pink Stained Glass, Pink Stained Glass, Pink Stained Glass
16x Gray Stained Glass Panes: Gray Stained Glass, Gray Stained Glass, Gray Stained Glass | Gray Stained Glass, Gray Stained Glass, Gray Stained Glass
16x Light Gray Stained Glass Panes: Light Gray Stained Glass, Light Gray Stained Glass, Light Gray Stained Glass | Light Gray Stained Glass, Light Gray Stained Glass, Light Gray Stained Glass
16x Cyan Stained Glass Panes: Cyan Stained Glass, Cyan Stained Glass, Cyan Stained Glass | Cyan Stained Glass, Cyan Stained Glass, Cyan Stained Glass
16x Purple Stained Glass Panes: Purple Stained Glass, Purple Stained Glass, Purple Stained Glass | Purple Stained Glass, Purple Stained Glass, Purple Stained Glass
16x Blue Stained Glass Panes: Blue Stained Glass, Blue Stained Glass, Blue Stained Glass | Blue Stained Glass, Blue Stained Glass, Blue Stained Glass
16x Brown Stained Glass Panes: Brown Stained Glass, Brown Stained Glass, Brown Stained Glass | Brown Stained Glass, Brown Stained Glass, Brown Stained Glass
16x Green Stained Glass Panes: Green Stained Glass, Green Stained Glass, Green Stained Glass | Green Stained Glass, Green Stained Glass, Green Stained Glass
16x Black Stained Glass Panes: Black Stained Glass, Black Stained Glass, Black Stained Glass | Black Stained Glass, Black Stained Glass, Black Stained Glass

View File

@ -0,0 +1,69 @@
{
"templates":[
"{hits} {user} with a {item}.",
"{hits} {user} around a bit with a {item}.",
"{throws} a {item} at {user}.",
"{throws} a few {item}s at {user}.",
"grabs a {item} and {throws} it in {user}'s face.",
"launches a {item} in {user}'s general direction.",
"sits on {user}'s face while slamming a {item} into their crotch.",
"starts slapping {user} silly with a {item}.",
"holds {user} down and repeatedly {hits} them with a {item}.",
"prods {user} with a {item}.",
"picks up a {item} and {hits} {user} with it.",
"ties {user} to a chair and {throws} a {item} at them.",
"{hits} {user} {where} with a {item}.",
"ties {user} to a pole and whips them with a {item}."
],
"parts": {
"item":[
"cast iron skillet",
"large trout",
"baseball bat",
"wooden cane",
"nail",
"printer",
"shovel",
"pair of trousers",
"CRT monitor",
"diamond sword",
"baguette",
"physics textbook",
"toaster",
"portrait of Richard Stallman",
"television",
"mau5head",
"five ton truck",
"roll of duct tape",
"book",
"laptop",
"old television",
"sack of rocks",
"rainbow trout",
"cobblestone block",
"lava bucket",
"rubber chicken",
"spiked bat",
"gold block",
"fire extinguisher",
"heavy rock",
"chunk of dirt"
],
"throws": [
"throws",
"flings",
"chucks"
],
"hits": [
"hits",
"whacks",
"slaps",
"smacks"
],
"where": [
"in the chest",
"on the head",
"on the bum"
]
}
}

View File

33
plugins/dice.py → disabled_stuff/dice.py Executable file → Normal file
View File

@ -14,8 +14,8 @@ sign_re = re.compile(r'[+-]?(?:\d*d)?(?:\d+|F)', re.I)
split_re = re.compile(r'([\d+-]*)d?(F|\d*)', re.I)
def nrolls(count, n):
"roll an n-sided die count times"
def n_rolls(count, n):
"""roll an n-sided die count times"""
if n == "F":
return [random.randint(-1, 1) for x in xrange(min(count, 100))]
if n < 2: # it's a coin
@ -28,16 +28,16 @@ def nrolls(count, n):
return [random.randint(1, n) for x in xrange(count)]
else: # fake it
return [int(random.normalvariate(.5 * (1 + n) * count,
(((n + 1) * (2 * n + 1) / 6. -
(.5 * (1 + n)) ** 2) * count) ** .5))]
(((n + 1) * (2 * n + 1) / 6. -
(.5 * (1 + n)) ** 2) * count) ** .5))]
@hook.command('roll')
#@hook.regex(valid_diceroll, re.I)
@hook.command
def dice(inp):
"dice <diceroll> -- Simulates dicerolls. Example of <diceroll>:" \
" 'dice 2d20-d5+4 roll 2'. D20s, subtract 1D5, add 4"
"""dice <dice roll> -- Simulates dice rolls. Example of <dice roll>:
'dice 2d20-d5+4 roll 2'. D20s, subtract 1D5, add 4"""
try: # if inp is a re.match object...
(inp, desc) = inp.groups()
@ -49,7 +49,7 @@ def dice(inp):
spec = whitespace_re.sub('', inp)
if not valid_diceroll_re.match(spec):
return "Invalid diceroll"
return "Invalid dice roll"
groups = sign_re.findall(spec)
total = 0
@ -59,7 +59,7 @@ def dice(inp):
count, side = split_re.match(roll).groups()
count = int(count) if count not in " +-" else 1
if side.upper() == "F": # fudge dice are basically 1d3-2
for fudge in nrolls(count, "F"):
for fudge in n_rolls(count, "F"):
if fudge == 1:
rolls.append("\x033+\x0F")
elif fudge == -1:
@ -73,17 +73,18 @@ def dice(inp):
side = int(side)
try:
if count > 0:
dice = nrolls(count, side)
rolls += map(str, dice)
total += sum(dice)
d = n_rolls(count, side)
rolls += map(str, d)
total += sum(d)
else:
dice = nrolls(-count, side)
rolls += [str(-x) for x in dice]
total -= sum(dice)
d = n_rolls(-count, side)
rolls += [str(-x) for x in d]
total -= sum(d)
except OverflowError:
# I have never seen this happen. If you make this happen, you win a cookie
return "Thanks for overflowing a float, jerk >:["
if desc:
return "%s: %d (%s)" % (desc.strip(), total, ", ".join(rolls))
return "{}: {} ({})".format(desc.strip(), total, ", ".join(rolls))
else:
return "%d (%s)" % (total, ", ".join(rolls))
return "{} ({})".format(total, ", ".join(rolls))

15
plugins/dictionary.py → disabled_stuff/dictionary.py Executable file → Normal file
View File

@ -1,5 +1,6 @@
# Plugin by GhettoWizard and Scaevolus
import re
from util import hook
from util import http
@ -7,7 +8,7 @@ from util import http
@hook.command('dictionary')
@hook.command
def define(inp):
"define <word> -- Fetches definition of <word>."
"""define <word> -- Fetches definition of <word>."""
url = 'http://ninjawords.com/'
@ -18,14 +19,14 @@ def define(inp):
'//div[@class="example"]')
if not definition:
return 'No results for ' + inp + ' :('
return u'No results for {} :('.format(inp)
def format_output(show_examples):
result = '%s: ' % h.xpath('//dt[@class="title-word"]/a/text()')[0]
result = u'{}: '.format(h.xpath('//dt[@class="title-word"]/a/text()')[0])
correction = h.xpath('//span[@class="correct-word"]/text()')
if correction:
result = 'Definition for "%s": ' % correction[0]
result = 'Definition for "{}": '.format(correction[0])
sections = []
for section in definition:
@ -40,7 +41,7 @@ def define(inp):
for article in sections:
result += article[0]
if len(article) > 2:
result += ' '.join('%d. %s' % (n + 1, section)
result += u' '.join(u'{}. {}'.format(n + 1, section)
for n, section in enumerate(article[1:]))
else:
result += article[1] + ' '
@ -67,7 +68,7 @@ def define(inp):
@hook.command('e')
@hook.command
def etymology(inp):
"etymology <word> -- Retrieves the etymology of <word>."
"""etymology <word> -- Retrieves the etymology of <word>."""
url = 'http://www.etymonline.com/index.php'
@ -76,7 +77,7 @@ def etymology(inp):
etym = h.xpath('//dl')
if not etym:
return 'No etymology found for ' + inp + ' :('
return u'No etymology found for {} :('.format(inp)
etym = etym[0].text_content()

18
disabled_stuff/domainr.py Normal file
View File

@ -0,0 +1,18 @@
from util import hook, http
@hook.command
def domainr(inp):
"""domainr <domain> - Use domain.nr's API to search for a domain, and similar domains."""
try:
data = http.get_json('http://domai.nr/api/json/search?q=' + inp)
except (http.URLError, http.HTTPError) as e:
return "Unable to get data for some reason. Try again later."
if data['query'] == "":
return "An error occurred: {status} - {message}".format(**data['error'])
domains = ""
for domain in data['results']:
domains += ("\x034" if domain['availability'] == "taken" else (
"\x033" if domain['availability'] == "available" else "\x031")) + domain['domain'] + "\x0f" + domain[
'path'] + ", "
return "Domains: " + domains

6
plugins/down.py → disabled_stuff/down.py Executable file → Normal file
View File

@ -5,7 +5,7 @@ from util import hook, http
@hook.command
def down(inp):
"down <url> -- Checks if the site at <url> is up or down."
"""down <url> -- Checks if the site at <url> is up or down."""
if 'http://' not in inp:
inp = 'http://' + inp
@ -15,6 +15,6 @@ def down(inp):
# http://mail.python.org/pipermail/python-list/2006-December/589854.html
try:
http.get(inp, get_method='HEAD')
return inp + ' seems to be up'
return '{} seems to be up'.format(inp)
except http.URLError:
return inp + ' seems to be down'
return '{} seems to be down'.format(inp)

16
plugins/drama.py → disabled_stuff/drama.py Executable file → Normal file
View File

@ -1,4 +1,7 @@
from util import hook, http
import re
from util import hook, http, text
api_url = "http://encyclopediadramatica.se/api.php?action=opensearch"
ed_url = "http://encyclopediadramatica.se/"
@ -6,10 +9,11 @@ ed_url = "http://encyclopediadramatica.se/"
@hook.command
def drama(inp):
"drama <phrase> -- Gets the first paragraph of" \
" the Encyclopedia Dramatica article on <phrase>."
"""drama <phrase> -- Gets the first paragraph of
the Encyclopedia Dramatica article on <phrase>."""
j = http.get_json(api_url, search=inp)
if not j[1]:
return "No results found."
article_name = j[1][0].replace(' ', '_').encode('utf8')
@ -20,8 +24,8 @@ def drama(inp):
for p in page.xpath('//div[@id="bodyContent"]/p'):
if p.text_content():
summary = " ".join(p.text_content().splitlines())
if len(summary) > 300:
summary = summary[:summary.rfind(' ', 0, 300)] + "..."
return "%s :: \x02%s\x02" % (summary, url)
summary = re.sub("\[\d+\]", "", summary)
summary = text.truncate_str(summary, 220)
return "{} :: {}".format(summary, url)
return "Unknown Error."

View File

@ -0,0 +1,23 @@
import random
from util import hook, text
color_codes = {
"<r>": "\x02\x0305",
"<g>": "\x02\x0303",
"<y>": "\x02"
}
with open("plugins/data/8ball_responses.txt") as f:
responses = [line.strip() for line in
f.readlines() if not line.startswith("//")]
@hook.command('8ball')
def eightball(inp, action=None):
"""8ball <question> -- The all knowing magic eight ball,
in electronic form. Ask and it shall be answered!"""
magic = text.multiword_replace(random.choice(responses), color_codes)
action("shakes the magic 8 ball... {}".format(magic))

105
disabled_stuff/encrypt.py Normal file
View File

@ -0,0 +1,105 @@
import os
import base64
import json
import hashlib
from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from util import hook
# helper functions to pad and unpad a string to a specified block size
# <http://stackoverflow.com/questions/12524994/encrypt-decrypt-using-pycrypto-aes-256>
BS = AES.block_size
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s: s[0:-ord(s[-1])]
# helper functions to encrypt and encode a string with AES and base64
encode_aes = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
decode_aes = lambda c, s: unpad(c.decrypt(base64.b64decode(s)))
db_ready = False
def db_init(db):
"""check to see that our db has the the encryption table."""
global db_ready
if not db_ready:
db.execute("create table if not exists encryption(encrypted, iv, "
"primary key(encrypted))")
db.commit()
db_ready = True
def get_salt(bot):
"""generate an encryption salt if none exists, then returns the salt"""
if not bot.config.get("random_salt", False):
bot.config["random_salt"] = hashlib.md5(os.urandom(16)).hexdigest()
json.dump(bot.config, open('config', 'w'), sort_keys=True, indent=2)
return bot.config["random_salt"]
@hook.command
def encrypt(inp, bot=None, db=None, notice=None):
"""encrypt <pass> <string> -- Encrypts <string> with <pass>. (<string> can only be decrypted using this bot)"""
db_init(db)
split = inp.split(" ")
# if there is only one argument, return the help message
if len(split) == 1:
notice(encrypt.__doc__)
return
# generate the key from the password and salt
password = split[0]
salt = get_salt(bot)
key = PBKDF2(password, salt)
# generate the IV and encode it to store in the database
iv = Random.new().read(AES.block_size)
iv_encoded = base64.b64encode(iv)
# create the AES cipher and encrypt/encode the text with it
text = " ".join(split[1:])
cipher = AES.new(key, AES.MODE_CBC, iv)
encoded = encode_aes(cipher, text)
# store the encoded text and IV in the DB for decoding later
db.execute("insert or replace into encryption(encrypted, iv)"
"values(?,?)", (encoded, iv_encoded))
db.commit()
return encoded
@hook.command
def decrypt(inp, bot=None, db=None, notice=None):
"""decrypt <pass> <string> -- Decrypts <string> with <pass>. (can only decrypt strings encrypted on this bot)"""
if not db_ready:
db_init(db)
split = inp.split(" ")
# if there is only one argument, return the help message
if len(split) == 1:
notice(decrypt.__doc__)
return
# generate the key from the password and salt
password = split[0]
salt = get_salt(bot)
key = PBKDF2(password, salt)
text = " ".join(split[1:])
# get the encoded IV from the database and decode it
iv_encoded = db.execute("select iv from encryption where"
" encrypted=?", (text,)).fetchone()[0]
iv = base64.b64decode(iv_encoded)
# create AES cipher, decode text, decrypt text, and unpad it
cipher = AES.new(key, AES.MODE_CBC, iv)
return decode_aes(cipher, text)

17
plugins/fact.py → disabled_stuff/fact.py Executable file → Normal file
View File

@ -2,8 +2,8 @@ from util import hook, http, web
@hook.command(autohelp=False)
def fact(inp, say=False, nick=False):
"fact -- Gets a random fact from OMGFACTS."
def fact(inp):
"""fact -- Gets a random fact from OMGFACTS."""
attempts = 0
@ -20,10 +20,10 @@ def fact(inp, say=False, nick=False):
response = soup.find('a', {'class': 'surprise'})
link = response['href']
fact = ''.join(response.find(text=True))
fact_data = ''.join(response.find(text=True))
if fact:
fact = fact.strip()
if fact_data:
fact_data = fact_data.strip()
break
else:
if attempts > 2:
@ -32,9 +32,6 @@ def fact(inp, say=False, nick=False):
attempts += 1
continue
try:
url = web.isgd(link)
except (web.ShortenError, http.HTTPError):
url = link
url = web.try_isgd(link)
return "%s - %s" % (fact, url)
return "{} - {}".format(fact_data, url)

88
plugins/factoids.py → disabled_stuff/factoids.py Executable file → Normal file
View File

@ -1,29 +1,34 @@
# Written by Scaevolus 2010
from util import hook, http, text, execute
import string
import sqlite3
import re
from util import hook, http, text, pyexec
re_lineends = re.compile(r'[\r\n]*')
db_ready = False
# some simple "shortcodes" for formatting purposes
shortcodes = {
'[b]': '\x02',
'[/b]': '\x02',
'[u]': '\x1F',
'[/u]': '\x1F',
'[i]': '\x16',
'[/i]': '\x16'}
'[b]': '\x02',
'[/b]': '\x02',
'[u]': '\x1F',
'[/u]': '\x1F',
'[i]': '\x16',
'[/i]': '\x16'}
def db_init(db):
db.execute("create table if not exists mem(word, data, nick,"
" primary key(word))")
db.commit()
global db_ready
if not db_ready:
db.execute("create table if not exists mem(word, data, nick,"
" primary key(word))")
db.commit()
db_ready = True
def get_memory(db, word):
row = db.execute("select data from mem where word=lower(?)",
[word]).fetchone()
if row:
@ -32,11 +37,11 @@ def get_memory(db, word):
return None
@hook.command("r", adminonly=True)
@hook.command(adminonly=True)
def remember(inp, nick='', db=None, say=None, input=None, notice=None):
"remember <word> [+]<data> -- Remembers <data> with <word>. Add +"
" to <data> to append."
@hook.command("r", permissions=["addfactoid"])
@hook.command(permissions=["addfactoid"])
def remember(inp, nick='', db=None, notice=None):
"""remember <word> [+]<data> -- Remembers <data> with <word>. Add +
to <data> to append."""
db_init(db)
append = False
@ -64,20 +69,18 @@ def remember(inp, nick='', db=None, say=None, input=None, notice=None):
if old_data:
if append:
notice("Appending \x02%s\x02 to \x02%s\x02" % (new_data, old_data))
notice("Appending \x02{}\x02 to \x02{}\x02".format(new_data, old_data))
else:
notice('Remembering \x02%s\x02 for \x02%s\x02. Type ?%s to see it.'
% (data, word, word))
notice('Previous data was \x02%s\x02' % old_data)
notice('Remembering \x02{}\x02 for \x02{}\x02. Type ?{} to see it.'.format(data, word, word))
notice('Previous data was \x02{}\x02'.format(old_data))
else:
notice('Remembering \x02%s\x02 for \x02%s\x02. Type ?%s to see it.'
% (data, word, word))
notice('Remembering \x02{}\x02 for \x02{}\x02. Type ?{} to see it.'.format(data, word, word))
@hook.command("f", adminonly=True)
@hook.command(adminonly=True)
def forget(inp, db=None, input=None, notice=None):
"forget <word> -- Forgets a remembered <word>."
@hook.command("f", permissions=["delfactoid"])
@hook.command(permissions=["delfactoid"])
def forget(inp, db=None, notice=None):
"""forget <word> -- Forgets a remembered <word>."""
db_init(db)
data = get_memory(db, inp)
@ -95,7 +98,7 @@ def forget(inp, db=None, input=None, notice=None):
@hook.command
def info(inp, notice=None, db=None):
"info <factoid> -- Shows the source of a factoid."
"""info <factoid> -- Shows the source of a factoid."""
db_init(db)
@ -109,8 +112,8 @@ def info(inp, notice=None, db=None):
@hook.regex(r'^\? ?(.+)')
def factoid(inp, say=None, db=None, bot=None, me=None, conn=None, input=None):
"?<word> -- Shows what data is associated with <word>."
def factoid(inp, message=None, db=None, bot=None, action=None, conn=None, input=None):
"""?<word> -- Shows what data is associated with <word>."""
try:
prefix_on = bot.config["plugins"]["factoids"].get("prefix", False)
except KeyError:
@ -133,15 +136,10 @@ def factoid(inp, say=None, db=None, bot=None, me=None, conn=None, input=None):
# factoid preprocessors
if data.startswith("<py>"):
code = data[4:].strip()
variables = 'input="""%s"""; nick="%s"; chan="%s"; bot_nick="%s";' % (arguments.replace('"', '\\"'),
input.nick, input.chan, input.conn.nick)
result = execute.eval_py(variables + code)
elif data.startswith("<url>"):
url = data[5:].strip()
try:
result = http.get(url)
except http.HttpError:
result = "Could not fetch URL."
variables = 'input="""{}"""; nick="{}"; chan="{}"; bot_nick="{}";'.format(arguments.replace('"', '\\"'),
input.nick, input.chan,
input.conn.nick)
result = pyexec.eval_py(variables + code)
else:
result = data
@ -150,9 +148,15 @@ def factoid(inp, say=None, db=None, bot=None, me=None, conn=None, input=None):
if result.startswith("<act>"):
result = result[5:].strip()
me(result)
action(result)
elif result.startswith("<url>"):
url = result[5:].strip()
try:
message(http.get(url))
except http.HttpError:
message("Could not fetch URL.")
else:
if prefix_on:
say("\x02[%s]:\x02 %s" % (factoid_id, result))
message("\x02[{}]:\x02 {}".format(factoid_id, result))
else:
say(result)
message(result)

View File

@ -0,0 +1,57 @@
from urllib import quote_plus
from util import hook, http
api_url = "http://api.fishbans.com/stats/{}/"
@hook.command("bans")
@hook.command
def fishbans(inp):
"""fishbans <user> -- Gets information on <user>s minecraft bans from fishbans"""
user = inp.strip()
try:
request = http.get_json(api_url.format(quote_plus(user)))
except (http.HTTPError, http.URLError) as e:
return "Could not fetch ban data from the Fishbans API: {}".format(e)
if not request["success"]:
return "Could not fetch ban data for {}.".format(user)
user_url = "http://fishbans.com/u/{}/".format(user)
ban_count = request["stats"]["totalbans"]
return "The user \x02{}\x02 has \x02{}\x02 ban(s). See detailed info " \
"at {}".format(user, ban_count, user_url)
@hook.command
def bancount(inp):
"""bancount <user> -- Gets a count of <user>s minecraft bans from fishbans"""
user = inp.strip()
try:
request = http.get_json(api_url.format(quote_plus(user)))
except (http.HTTPError, http.URLError) as e:
return "Could not fetch ban data from the Fishbans API: {}".format(e)
if not request["success"]:
return "Could not fetch ban data for {}.".format(user)
user_url = "http://fishbans.com/u/{}/".format(user)
services = request["stats"]["service"]
out = []
for service, ban_count in services.items():
if ban_count != 0:
out.append("{}: \x02{}\x02".format(service, ban_count))
else:
pass
if not out:
return "The user \x02{}\x02 has no bans.".format(user)
else:
return "Bans for \x02{}\x02: ".format(user) + ", ".join(out) + ". More info " \
"at {}".format(user_url)

10
plugins/fmylife.py → disabled_stuff/fmylife.py Executable file → Normal file
View File

@ -8,9 +8,9 @@ def refresh_cache():
soup = http.get_soup('http://www.fmylife.com/random/')
for e in soup.find_all('div', {'class': 'post article'}):
id = int(e['id'])
fml_id = int(e['id'])
text = ''.join(e.find('p').find_all(text=True))
fml_cache.append((id, text))
fml_cache.append((fml_id, text))
# do an initial refresh of the cache
refresh_cache()
@ -18,12 +18,12 @@ refresh_cache()
@hook.command(autohelp=False)
def fml(inp, reply=None):
"fml -- Gets a random quote from fmyfife.com."
"""fml -- Gets a random quote from fmyfife.com."""
# grab the last item in the fml cache and remove it
id, text = fml_cache.pop()
fml_id, text = fml_cache.pop()
# reply with the fml we grabbed
reply('(#%d) %s' % (id, text))
reply('(#{}) {}'.format(fml_id, text))
# refresh fml cache if its getting empty
if len(fml_cache) < 3:
refresh_cache()

6
plugins/fortune.py → disabled_stuff/fortune.py Executable file → Normal file
View File

@ -1,6 +1,8 @@
from util import hook
import random
from util import hook
with open("plugins/data/fortunes.txt") as f:
fortunes = [line.strip() for line in f.readlines()
if not line.startswith("//")]
@ -8,5 +10,5 @@ with open("plugins/data/fortunes.txt") as f:
@hook.command(autohelp=False)
def fortune(inp):
"fortune -- Fortune cookies on demand."
"""fortune -- Fortune cookies on demand."""
return random.choice(fortunes)

13
disabled_stuff/freddy.py Normal file
View File

@ -0,0 +1,13 @@
from util import hook, http, web
from subprocess import check_output, CalledProcessError
@hook.command
def freddycode(inp):
"""freddycode <code> - Check if the Freddy Fresh code is correct."""
try:
return "Freddy: '%s' ist %s" % (inp, \
check_output(["/bin/freddycheck", inp]))
except CalledProcessError as err:
return "Freddy: Skript returned %s" % (str(err))

28
plugins/geoip.py → disabled_stuff/geoip.py Executable file → Normal file
View File

@ -1,20 +1,36 @@
from util import hook
import os.path
import pygeoip
import json
import gzip
from StringIO import StringIO
# initalise geolocation database
geo = pygeoip.GeoIP(os.path.abspath("./plugins/data/geoip.dat"))
import pygeoip
from util import hook, http
# load region database
with open("./plugins/data/geoip_regions.json", "rb") as f:
regions = json.loads(f.read())
if os.path.isfile(os.path.abspath("./plugins/data/GeoLiteCity.dat")):
# initialise geolocation database
geo = pygeoip.GeoIP(os.path.abspath("./plugins/data/GeoLiteCity.dat"))
else:
download = http.get("http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz")
string_io = StringIO(download)
geoip_file = gzip.GzipFile(fileobj=string_io, mode='rb')
output = open(os.path.abspath("./plugins/data/GeoLiteCity.dat"), 'wb')
output.write(geoip_file.read())
output.close()
geo = pygeoip.GeoIP(os.path.abspath("./plugins/data/GeoLiteCity.dat"))
@hook.command
def geoip(inp):
"geoip <host/ip> -- Gets the location of <host/ip>"
"""geoip <host/ip> -- Gets the location of <host/ip>"""
try:
record = geo.record_by_name(inp)
except:
@ -35,4 +51,4 @@ def geoip(inp):
data["cc"] = record["country_code"] or "N/A"
data["country"] = record["country_name"] or "Unknown"
data["city"] = record["city"] or "Unknown"
return "\x02Country:\x02 {country} ({cc}), \x02City:\x02 {city}{region}".format(**data)
return u"\x02Country:\x02 {country} ({cc}), \x02City:\x02 {city}{region}".format(**data)

120
disabled_stuff/github.py Normal file
View File

@ -0,0 +1,120 @@
import json
import urllib2
from util import hook, http
shortcuts = {"cloudbot": "ClouDev/CloudBot"}
def truncate(msg):
nmsg = msg.split()
out = None
x = 0
for i in nmsg:
if x <= 7:
if out:
out = out + " " + nmsg[x]
else:
out = nmsg[x]
x += 1
if x <= 7:
return out
else:
return out + "..."
@hook.command
def ghissues(inp):
"""ghissues username/repo [number] - Get specified issue summary, or open issue count """
args = inp.split(" ")
try:
if args[0] in shortcuts:
repo = shortcuts[args[0]]
else:
repo = args[0]
url = "https://api.github.com/repos/{}/issues".format(repo)
except IndexError:
return "Invalid syntax. .github issues username/repo [number]"
try:
url += "/%s" % args[1]
number = True
except IndexError:
number = False
try:
data = json.loads(http.open(url).read())
print url
if not number:
try:
data = data[0]
except IndexError:
print data
return "Repo has no open issues"
except ValueError:
return "Invalid data returned. Check arguments (.github issues username/repo [number]"
fmt = "Issue: #%s (%s) by %s: %s | %s %s" # (number, state, user.login, title, truncate(body), gitio.gitio(data.url))
fmt1 = "Issue: #%s (%s) by %s: %s %s" # (number, state, user.login, title, gitio.gitio(data.url))
number = data["number"]
if data["state"] == "open":
state = u"\x033\x02OPEN\x02\x0f"
else:
state = u"\x034\x02CLOSED\x02\x0f by {}".format(data["closed_by"]["login"])
user = data["user"]["login"]
title = data["title"]
summary = truncate(data["body"])
gitiourl = gitio(data["html_url"])
if "Failed to get URL" in gitiourl:
gitiourl = gitio(data["html_url"] + " " + repo.split("/")[1] + number)
if summary == "":
return fmt1 % (number, state, user, title, gitiourl)
else:
return fmt % (number, state, user, title, summary, gitiourl)
@hook.command
def gitio(inp):
"""gitio <url> [code] -- Shorten Github URLs with git.io. [code] is
a optional custom short code."""
split = inp.split(" ")
url = split[0]
try:
code = split[1]
except:
code = None
# if the first 8 chars of "url" are not "https://" then append
# "https://" to the url, also convert "http://" to "https://"
if url[:8] != "https://":
if url[:7] != "http://":
url = "https://" + url
else:
url = "https://" + url[7:]
url = 'url=' + str(url)
if code:
url = url + '&code=' + str(code)
req = urllib2.Request(url='http://git.io', data=url)
# try getting url, catch http error
try:
f = urllib2.urlopen(req)
except urllib2.HTTPError:
return "Failed to get URL!"
urlinfo = str(f.info())
# loop over the rows in urlinfo and pick out location and
# status (this is pretty odd code, but urllib2.Request is weird)
for row in urlinfo.split("\n"):
if row.find("Status") != -1:
status = row
if row.find("Location") != -1:
location = row
print status
if not "201" in status:
return "Failed to get URL!"
# this wont work for some reason, so lets ignore it ^
# return location, minus the first 10 chars
return location[10:]

18
plugins/google.py → disabled_stuff/google.py Executable file → Normal file
View File

@ -1,4 +1,5 @@
import random
from util import hook, http, text
@ -13,28 +14,25 @@ def api_get(kind, query):
@hook.command('gis')
@hook.command
def googleimage(inp):
"gis <query> -- Returns first Google Image result for <query>."
"""gis <query> -- Returns first Google Image result for <query>."""
parsed = api_get('images', inp)
if not 200 <= parsed['responseStatus'] < 300:
raise IOError('error searching for images: %d: %s' % ( \
parsed['responseStatus'], ''))
raise IOError('error searching for images: {}: {}'.format(parsed['responseStatus'], ''))
if not parsed['responseData']['results']:
return 'no images found'
return random.choice(parsed['responseData']['results'][:10]) \
['unescapedUrl']
return random.choice(parsed['responseData']['results'][:10])['unescapedUrl']
@hook.command('search')
@hook.command('g')
@hook.command
def google(inp):
"google <query> -- Returns first google search result for <query>."
"""google <query> -- Returns first google search result for <query>."""
parsed = api_get('web', inp)
if not 200 <= parsed['responseStatus'] < 300:
raise IOError('error searching for pages: %d: %s' % (
parsed['responseStatus'], ''))
raise IOError('error searching for pages: {}: {}'.format(parsed['responseStatus'], ''))
if not parsed['responseData']['results']:
return 'No results found.'
@ -50,6 +48,4 @@ def google(inp):
content = http.html.fromstring(content).text_content()
content = text.truncate_str(content, 150)
out = '%s -- \x02%s\x02: "%s"' % (result['unescapedUrl'], title, content)
return out
return u'{} -- \x02{}\x02: "{}"'.format(result['unescapedUrl'], title, content)

View File

@ -0,0 +1,168 @@
"""
A Google API key is required and retrieved from the bot config file.
Since December 1, 2011, the Google Translate API is a paid service only.
"""
import htmlentitydefs
import re
from util import hook, http
max_length = 100
########### from http://effbot.org/zone/re-sub.htm#unescape-html #############
def unescape(text):
def fixup(m):
text = m.group(0)
if text[:2] == "&#":
# character reference
try:
if text[:3] == "&#x":
return unichr(int(text[3:-1], 16))
else:
return unichr(int(text[2:-1]))
except ValueError:
pass
else:
# named entity
try:
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
except KeyError:
pass
return text # leave as is
return re.sub("&#?\w+;", fixup, text)
##############################################################################
def goog_trans(api_key, text, slang, tlang):
url = 'https://www.googleapis.com/language/translate/v2'
if len(text) > max_length:
return "This command only supports input of less then 100 characters."
if slang:
parsed = http.get_json(url, key=api_key, q=text, source=slang, target=tlang, format="text")
else:
parsed = http.get_json(url, key=api_key, q=text, target=tlang, format="text")
#if not 200 <= parsed['responseStatus'] < 300:
# raise IOError('error with the translation server: %d: %s' % (
# parsed['responseStatus'], parsed['responseDetails']))
if not slang:
return unescape('(%(detectedSourceLanguage)s) %(translatedText)s' %
(parsed['data']['translations'][0]))
return unescape('%(translatedText)s' % parsed['data']['translations'][0])
def match_language(fragment):
fragment = fragment.lower()
for short, _ in lang_pairs:
if fragment in short.lower().split():
return short.split()[0]
for short, full in lang_pairs:
if fragment in full.lower():
return short.split()[0]
return None
@hook.command
def translate(inp, bot=None):
"""translate [source language [target language]] <sentence> -- translates
<sentence> from source language (default autodetect) to target
language (default English) using Google Translate"""
api_key = bot.config.get("api_keys", {}).get("googletranslate", None)
if not api_key:
return "This command requires a paid API key."
args = inp.split(u' ', 2)
try:
if len(args) >= 2:
sl = match_language(args[0])
if not sl:
return goog_trans(api_key, inp, '', 'en')
if len(args) == 2:
return goog_trans(api_key, args[1], sl, 'en')
if len(args) >= 3:
tl = match_language(args[1])
if not tl:
if sl == 'en':
return 'unable to determine desired target language'
return goog_trans(api_key, args[1] + ' ' + args[2], sl, 'en')
return goog_trans(api_key, args[2], sl, tl)
return goog_trans(api_key, inp, '', 'en')
except IOError, e:
return e
lang_pairs = [
("no", "Norwegian"),
("it", "Italian"),
("ht", "Haitian Creole"),
("af", "Afrikaans"),
("sq", "Albanian"),
("ar", "Arabic"),
("hy", "Armenian"),
("az", "Azerbaijani"),
("eu", "Basque"),
("be", "Belarusian"),
("bg", "Bulgarian"),
("ca", "Catalan"),
("zh-CN zh", "Chinese"),
("hr", "Croatian"),
("cs", "Czech"),
("da", "Danish"),
("nl", "Dutch"),
("en", "English"),
("et", "Estonian"),
("tl", "Filipino"),
("fi", "Finnish"),
("fr", "French"),
("gl", "Galician"),
("ka", "Georgian"),
("de", "German"),
("el", "Greek"),
("ht", "Haitian Creole"),
("iw", "Hebrew"),
("hi", "Hindi"),
("hu", "Hungarian"),
("is", "Icelandic"),
("id", "Indonesian"),
("ga", "Irish"),
("it", "Italian"),
("ja jp jpn", "Japanese"),
("ko", "Korean"),
("lv", "Latvian"),
("lt", "Lithuanian"),
("mk", "Macedonian"),
("ms", "Malay"),
("mt", "Maltese"),
("no", "Norwegian"),
("fa", "Persian"),
("pl", "Polish"),
("pt", "Portuguese"),
("ro", "Romanian"),
("ru", "Russian"),
("sr", "Serbian"),
("sk", "Slovak"),
("sl", "Slovenian"),
("es", "Spanish"),
("sw", "Swahili"),
("sv", "Swedish"),
("th", "Thai"),
("tr", "Turkish"),
("uk", "Ukrainian"),
("ur", "Urdu"),
("vi", "Vietnamese"),
("cy", "Welsh"),
("yi", "Yiddish")
]

View File

@ -0,0 +1,22 @@
from util import hook
from urllib import unquote
@hook.command(autohelp=False)
def googleurl(inp, db=None, nick=None):
"""googleurl [nickname] - Converts Google urls (google.com/url) to normal urls
where possible, in the specified nickname's last message. If nickname isn't provided,
action will be performed on user's last message"""
if not inp:
inp = nick
last_message = db.execute("select name, quote from seen_user where name"
" like ? and chan = ?", (inp.lower(), input.chan.lower())).fetchone()
if last_message:
msg = last_message[1]
out = ", ".join([(unquote(a[4:]) if a[:4] == "url=" else "") for a in msg.split("&")])\
.replace(", ,", "").strip()
return out if out else "No matches in your last message."
else:
if inp == nick:
return "You haven't said anything in this channel yet!"
else:
return "That user hasn't said anything in this channel yet!"

89
disabled_stuff/history.py Normal file
View File

@ -0,0 +1,89 @@
from collections import deque
from util import hook, timesince
import time
import re
db_ready = []
def db_init(db, conn_name):
"""check to see that our db has the the seen table (connection name is for caching the result per connection)"""
global db_ready
if db_ready.count(conn_name) < 1:
db.execute("create table if not exists seen_user(name, time, quote, chan, host, "
"primary key(name, chan))")
db.commit()
db_ready.append(conn_name)
def track_seen(input, message_time, db, conn):
""" Tracks messages for the .seen command """
db_init(db, conn)
# keep private messages private
if input.chan[:1] == "#" and not re.findall('^s/.*/.*/$', input.msg.lower()):
db.execute("insert or replace into seen_user(name, time, quote, chan, host)"
"values(?,?,?,?,?)", (input.nick.lower(), message_time, input.msg,
input.chan, input.mask))
db.commit()
def track_history(input, message_time, conn):
try:
history = conn.history[input.chan]
except KeyError:
conn.history[input.chan] = deque(maxlen=100)
history = conn.history[input.chan]
data = (input.nick, message_time, input.msg)
history.append(data)
@hook.singlethread
@hook.event('PRIVMSG', ignorebots=False)
def chat_tracker(paraml, input=None, db=None, conn=None):
message_time = time.time()
track_seen(input, message_time, db, conn)
track_history(input, message_time, conn)
@hook.command(autohelp=False)
def resethistory(inp, input=None, conn=None):
"""resethistory - Resets chat history for the current channel"""
try:
conn.history[input.chan].clear()
return "Reset chat history for current channel."
except KeyError:
# wat
return "There is no history for this channel."
"""seen.py: written by sklnd in about two beers July 2009"""
@hook.command
def seen(inp, nick='', chan='', db=None, input=None, conn=None):
"""seen <nick> <channel> -- Tell when a nickname was last in active in one of this bot's channels."""
if input.conn.nick.lower() == inp.lower():
return "You need to get your eyes checked."
if inp.lower() == nick.lower():
return "Have you looked in a mirror lately?"
if not re.match("^[A-Za-z0-9_|.\-\]\[]*$", inp.lower()):
return "I can't look up that name, its impossible to use!"
db_init(db, conn.name)
last_seen = db.execute("select name, time, quote from seen_user where name"
" like ? and chan = ?", (inp, chan)).fetchone()
if last_seen:
reltime = timesince.timesince(last_seen[1])
if last_seen[0] != inp.lower(): # for glob matching
inp = last_seen[0]
if last_seen[2][0:1] == "\x01":
return '{} was last seen {} ago: * {} {}'.format(inp, reltime, inp,
last_seen[2][8:-1])
else:
return '{} was last seen {} ago saying: {}'.format(inp, reltime, last_seen[2])
else:
return "I've never seen {} talking in this channel.".format(inp)

View File

@ -0,0 +1,56 @@
# Plugin by Infinity - <https://github.com/infinitylabs/UguuBot>
from util import hook, http, text
db_ready = False
def db_init(db):
"""check to see that our db has the horoscope table and return a connection."""
global db_ready
if not db_ready:
db.execute("create table if not exists horoscope(nick primary key, sign)")
db.commit()
db_ready = True
@hook.command(autohelp=False)
def horoscope(inp, db=None, notice=None, nick=None):
"""horoscope <sign> -- Get your horoscope."""
db_init(db)
# check if the user asked us not to save his details
dontsave = inp.endswith(" dontsave")
if dontsave:
sign = inp[:-9].strip().lower()
else:
sign = inp
db.execute("create table if not exists horoscope(nick primary key, sign)")
if not sign:
sign = db.execute("select sign from horoscope where nick=lower(?)",
(nick,)).fetchone()
if not sign:
notice("horoscope <sign> -- Get your horoscope")
return
sign = sign[0]
url = "http://my.horoscope.com/astrology/free-daily-horoscope-{}.html".format(sign)
soup = http.get_soup(url)
title = soup.find_all('h1', {'class': 'h1b'})[1]
horoscope_text = soup.find('div', {'class': 'fontdef1'})
result = u"\x02%s\x02 %s" % (title, horoscope_text)
result = text.strip_html(result)
#result = unicode(result, "utf8").replace('flight ','')
if not title:
return "Could not get the horoscope for {}.".format(inp)
if inp and not dontsave:
db.execute("insert or replace into horoscope(nick, sign) values (?,?)",
(nick.lower(), sign))
db.commit()
return result

30
disabled_stuff/hulu.py Normal file
View File

@ -0,0 +1,30 @@
from urllib import urlencode
import re
from util import hook, http, timeformat
hulu_re = (r'(.*://)(www.hulu.com|hulu.com)(.*)', re.I)
@hook.regex(*hulu_re)
def hulu_url(match):
data = http.get_json("http://www.hulu.com/api/oembed.json?url=http://www.hulu.com" + match.group(3))
showname = data['title'].split("(")[-1].split(")")[0]
title = data['title'].split(" (")[0]
return "{}: {} - {}".format(showname, title, timeformat.format_time(int(data['duration'])))
@hook.command('hulu')
def hulu_search(inp):
"""hulu <search> - Search Hulu"""
result = http.get_soup(
"http://m.hulu.com/search?dp_identifier=hulu&{}&items_per_page=1&page=1".format(urlencode({'query': inp})))
data = result.find('results').find('videos').find('video')
showname = data.find('show').find('name').text
title = data.find('title').text
duration = timeformat.format_time(int(float(data.find('duration').text)))
description = data.find('description').text
rating = data.find('content-rating').text
return "{}: {} - {} - {} ({}) {}".format(showname, title, description, duration, rating,
"http://www.hulu.com/watch/" + str(data.find('id').text))

59
disabled_stuff/imdb.py Normal file
View File

@ -0,0 +1,59 @@
# IMDb lookup plugin by Ghetto Wizard (2011) and blha303 (2013)
import re
from util import hook, http, text
id_re = re.compile("tt\d+")
imdb_re = (r'(.*:)//(imdb.com|www.imdb.com)(:[0-9]+)?(.*)', re.I)
@hook.command
def imdb(inp):
"""imdb <movie> -- Gets information about <movie> from IMDb."""
strip = inp.strip()
if id_re.match(strip):
content = http.get_json("http://www.omdbapi.com/", i=strip)
else:
content = http.get_json("http://www.omdbapi.com/", t=strip)
if content.get('Error', None) == 'Movie not found!':
return 'Movie not found!'
elif content['Response'] == 'True':
content['URL'] = 'http://www.imdb.com/title/{}'.format(content['imdbID'])
out = '\x02%(Title)s\x02 (%(Year)s) (%(Genre)s): %(Plot)s'
if content['Runtime'] != 'N/A':
out += ' \x02%(Runtime)s\x02.'
if content['imdbRating'] != 'N/A' and content['imdbVotes'] != 'N/A':
out += ' \x02%(imdbRating)s/10\x02 with \x02%(imdbVotes)s\x02' \
' votes.'
out += ' %(URL)s'
return out % content
else:
return 'Unknown error.'
@hook.regex(*imdb_re)
def imdb_url(match):
imdb_id = match.group(4).split('/')[-1]
if imdb_id == "":
imdb_id = match.group(4).split('/')[-2]
content = http.get_json("http://www.omdbapi.com/", i=imdb_id)
if content.get('Error', None) == 'Movie not found!':
return 'Movie not found!'
elif content['Response'] == 'True':
content['URL'] = 'http://www.imdb.com/title/%(imdbID)s' % content
content['Plot'] = text.truncate_str(content['Plot'], 50)
out = '\x02%(Title)s\x02 (%(Year)s) (%(Genre)s): %(Plot)s'
if content['Runtime'] != 'N/A':
out += ' \x02%(Runtime)s\x02.'
if content['imdbRating'] != 'N/A' and content['imdbVotes'] != 'N/A':
out += ' \x02%(imdbRating)s/10\x02 with \x02%(imdbVotes)s\x02' \
' votes.'
return out % content
else:
return 'Unknown error.'

82
disabled_stuff/imgur.py Normal file
View File

@ -0,0 +1,82 @@
import re
import random
from util import hook, http, web
base_url = "http://reddit.com/r/{}/.json"
imgur_re = re.compile(r'http://(?:i\.)?imgur\.com/(a/)?(\w+\b(?!/))\.?\w?')
album_api = "https://api.imgur.com/3/album/{}/images.json"
def is_valid(data):
if data["domain"] in ["i.imgur.com", "imgur.com"]:
return True
else:
return False
@hook.command(autohelp=False)
def imgur(inp):
"""imgur [subreddit] -- Gets the first page of imgur images from [subreddit] and returns a link to them.
If [subreddit] is undefined, return any imgur images"""
if inp:
# see if the input ends with "nsfw"
show_nsfw = inp.endswith(" nsfw")
# remove "nsfw" from the input string after checking for it
if show_nsfw:
inp = inp[:-5].strip().lower()
url = base_url.format(inp.strip())
else:
url = "http://www.reddit.com/domain/imgur.com/.json"
show_nsfw = False
try:
data = http.get_json(url, user_agent=http.ua_chrome)
except Exception as e:
return "Error: " + str(e)
data = data["data"]["children"]
random.shuffle(data)
# filter list to only have imgur links
filtered_posts = [i["data"] for i in data if is_valid(i["data"])]
if not filtered_posts:
return "No images found."
items = []
headers = {
"Authorization": "Client-ID b5d127e6941b07a"
}
# loop over the list of posts
for post in filtered_posts:
if post["over_18"] and not show_nsfw:
continue
match = imgur_re.search(post["url"])
if match.group(1) == 'a/':
# post is an album
url = album_api.format(match.group(2))
images = http.get_json(url, headers=headers)["data"]
# loop over the images in the album and add to the list
for image in images:
items.append(image["id"])
elif match.group(2) is not None:
# post is an image
items.append(match.group(2))
if not items:
return "No images found (use .imgur <subreddit> nsfw to show explicit content)"
if show_nsfw:
return "{} \x02NSFW\x02".format(web.isgd("http://imgur.com/" + ','.join(items)))
else:
return web.isgd("http://imgur.com/" + ','.join(items))

28
disabled_stuff/isup.py Normal file
View File

@ -0,0 +1,28 @@
import urlparse
from util import hook, http, urlnorm
@hook.command
def isup(inp):
"""isup -- uses isup.me to see if a site is up or not"""
# slightly overcomplicated, esoteric URL parsing
scheme, auth, path, query, fragment = urlparse.urlsplit(inp.strip())
domain = auth.encode('utf-8') or path.encode('utf-8')
url = urlnorm.normalize(domain, assume_scheme="http")
try:
soup = http.get_soup('http://isup.me/' + domain)
except http.HTTPError, http.URLError:
return "Could not get status."
content = soup.find('div').text.strip()
if "not just you" in content:
return "It's not just you. {} looks \x02\x034down\x02\x0f from here!".format(url)
elif "is up" in content:
return "It's just you. {} is \x02\x033up\x02\x0f.".format(url)
else:
return "Huh? That doesn't look like a site on the interweb."

15
disabled_stuff/kernel.py Normal file
View File

@ -0,0 +1,15 @@
import re
from util import hook, http
@hook.command(autohelp=False)
def kernel(inp, reply=None):
contents = http.get("https://www.kernel.org/finger_banner")
contents = re.sub(r'The latest(\s*)', '', contents)
contents = re.sub(r'version of the Linux kernel is:(\s*)', '- ', contents)
lines = contents.split("\n")
message = "Linux kernel versions: "
message += ", ".join(line for line in lines[:-1])
reply(message)

33
disabled_stuff/kill.py Normal file
View File

@ -0,0 +1,33 @@
import json
from util import hook, textgen
def get_generator(_json, variables):
data = json.loads(_json)
return textgen.TextGenerator(data["templates"],
data["parts"], variables=variables)
@hook.command
def kill(inp, action=None, nick=None, conn=None, notice=None):
"""kill <user> -- Makes the bot kill <user>."""
target = inp.strip()
if " " in target:
notice("Invalid username!")
return
# if the user is trying to make the bot kill itself, kill them
if target.lower() == conn.nick.lower() or target.lower() == "itself":
target = nick
variables = {
"user": target
}
with open("plugins/data/kills.json") as f:
generator = get_generator(f.read(), variables)
# act out the message
action(generator.generate_string())

24
plugins/lastfm.py → disabled_stuff/lastfm.py Executable file → Normal file
View File

@ -1,14 +1,16 @@
from util import hook, http, timesince
from datetime import datetime
from util import hook, http, timesince
api_url = "http://ws.audioscrobbler.com/2.0/?format=json"
@hook.command('l', autohelp=False)
@hook.command(autohelp=False)
def lastfm(inp, nick='', say=None, db=None, bot=None, notice=None):
"lastfm [user] [dontsave] -- Displays the now playing (or last played)" \
" track of LastFM user [user]."
def lastfm(inp, nick='', db=None, bot=None, notice=None):
"""lastfm [user] [dontsave] -- Displays the now playing (or last played)
track of LastFM user [user]."""
api_key = bot.config.get("api_keys", {}).get("lastfm")
if not api_key:
return "error: no api key set"
@ -34,10 +36,10 @@ def lastfm(inp, nick='', say=None, db=None, bot=None, notice=None):
api_key=api_key, user=user, limit=1)
if 'error' in response:
return "Error: %s." % response["message"]
return u"Error: {}.".format(response["message"])
if not "track" in response["recenttracks"] or len(response["recenttracks"]["track"]) == 0:
return 'No recent tracks for user "%s" found.' % user
return u'No recent tracks for user "{}" found.'.format(user)
tracks = response["recenttracks"]["track"]
@ -55,7 +57,7 @@ def lastfm(inp, nick='', say=None, db=None, bot=None, notice=None):
# lets see how long ago they listened to it
time_listened = datetime.fromtimestamp(int(track["date"]["uts"]))
time_since = timesince.timesince(time_listened)
ending = ' (%s ago)' % time_since
ending = ' ({} ago)'.format(time_since)
else:
return "error: could not parse track listing"
@ -64,18 +66,18 @@ def lastfm(inp, nick='', say=None, db=None, bot=None, notice=None):
album = track["album"]["#text"]
artist = track["artist"]["#text"]
out = '%s %s "%s"' % (user, status, title)
out = u'{} {} "{}"'.format(user, status, title)
if artist:
out += " by \x02%s\x0f" % artist
out += u" by \x02{}\x0f".format(artist)
if album:
out += " from the album \x02%s\x0f" % album
out += u" from the album \x02{}\x0f".format(album)
# append ending based on what type it was
out += ending
if inp and not dontsave:
db.execute("insert or replace into lastfm(nick, acc) values (?,?)",
(nick.lower(), user))
(nick.lower(), user))
db.commit()
return out

View File

@ -3,10 +3,10 @@ from util import hook, web, http
@hook.command('gfy')
@hook.command
def lmgtfy(inp, bot=None):
"lmgtfy [phrase] - Posts a google link for the specified phrase"
def lmgtfy(inp):
"""lmgtfy [phrase] - Posts a google link for the specified phrase"""
link = "http://lmgtfy.com/?q=%s" % http.quote_plus(inp)
link = u"http://lmgtfy.com/?q={}".format(http.quote_plus(inp))
try:
return web.isgd(link)

16
plugins/log.py → disabled_stuff/log.py Executable file → Normal file
View File

@ -27,11 +27,11 @@ formats = {
}
ctcp_formats = {
'ACTION': '* %(nick)s %(ctcpmsg)s',
'VERSION': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'PING': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'TIME': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'FINGER': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s'
'ACTION': '* %(nick)s %(ctcpmsg)s',
'VERSION': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'PING': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'TIME': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s',
'FINGER': '%(nick)s has requested CTCP %(ctcpcmd)s from %(chan)s: %(ctcpmsg)s'
}
irc_color_re = re.compile(r'(\x03(\d+,\d+|\d)|[\x0f\x02\x16\x1f])')
@ -39,7 +39,7 @@ irc_color_re = re.compile(r'(\x03(\d+,\d+|\d)|[\x0f\x02\x16\x1f])')
def get_log_filename(dir, server, chan):
return os.path.join(dir, 'log', gmtime('%Y'), server, chan,
(gmtime('%%s.%m-%d.log') % chan).lower())
(gmtime('%%s.%m-%d.log') % chan).lower())
def gmtime(format):
@ -64,8 +64,8 @@ def beautify(input):
ctcp += ['']
args['ctcpcmd'], args['ctcpmsg'] = ctcp
format = ctcp_formats.get(args['ctcpcmd'],
'%(nick)s [%(user)s@%(host)s] requested unknown CTCP '
'%(ctcpcmd)s from %(chan)s: %(ctcpmsg)s')
'%(nick)s [%(user)s@%(host)s] requested unknown CTCP '
'%(ctcpcmd)s from %(chan)s: %(ctcpmsg)s')
return format % args

43
disabled_stuff/lyrics.py Normal file
View File

@ -0,0 +1,43 @@
from util import hook, http, web
url = "http://search.azlyrics.com/search.php?q="
@hook.command
def lyrics(inp):
"""lyrics <search> - Search AZLyrics.com for song lyrics"""
if "pastelyrics" in inp:
dopaste = True
inp = inp.replace("pastelyrics", "").strip()
else:
dopaste = False
soup = http.get_soup(url + inp.replace(" ", "+"))
if "Try to compose less restrictive search query" in soup.find('div', {'id': 'inn'}).text:
return "No results. Check spelling."
div = None
for i in soup.findAll('div', {'class': 'sen'}):
if "/lyrics/" in i.find('a')['href']:
div = i
break
if div:
title = div.find('a').text
link = div.find('a')['href']
if dopaste:
newsoup = http.get_soup(link)
try:
lyrics = newsoup.find('div', {'style': 'margin-left:10px;margin-right:10px;'}).text.strip()
pasteurl = " " + web.haste(lyrics)
except Exception as e:
pasteurl = " (\x02Unable to paste lyrics\x02 [{}])".format(str(e))
else:
pasteurl = ""
artist = div.find('b').text.title()
lyricsum = div.find('div').text
if "\r\n" in lyricsum.strip():
lyricsum = " / ".join(lyricsum.strip().split("\r\n")[0:4]) # truncate, format
else:
lyricsum = " / ".join(lyricsum.strip().split("\n")[0:4]) # truncate, format
return "\x02{}\x02 by \x02{}\x02 {}{} - {}".format(title, artist, web.try_isgd(link), pasteurl,
lyricsum[:-3])
else:
return "No song results. " + url + inp.replace(" ", "+")

53
plugins/metacritic.py → disabled_stuff/metacritic.py Executable file → Normal file
View File

@ -9,14 +9,13 @@ from util import hook, http
@hook.command('mc')
@hook.command
def metacritic(inp):
"mc [all|movie|tv|album|x360|ps3|wii|pc|ds|3ds|vita] <title> -- Gets rating for <title> from metacritic on the specified medium."
# if the results suck, it's metacritic's fault
"""mc [all|movie|tv|album|x360|ps3|pc|gba|ds|3ds|wii|vita|wiiu|xone|ps4] <title>
Gets rating for <title> from metacritic on the specified medium."""
args = inp.strip()
game_platforms = ('x360', 'ps3', 'pc', 'ds', 'wii', '3ds', 'gba',
'psp', 'vita')
game_platforms = ('x360', 'ps3', 'pc', 'gba', 'ds', '3ds', 'wii',
'vita', 'wiiu', 'xone', 'ps4')
all_platforms = game_platforms + ('all', 'movie', 'tv', 'album')
@ -35,45 +34,14 @@ def metacritic(inp):
title_safe = http.quote_plus(title)
url = 'http://www.metacritic.com/search/%s/%s/results' % (cat, title_safe)
url = 'http://www.metacritic.com/search/{}/{}/results'.format(cat, title_safe)
try:
doc = http.get_html(url)
except HTTPError:
return 'error fetching results'
''' result format:
-- game result, with score
-- subsequent results are the same structure, without first_result class
<li class="result first_result">
<div class="result_type">
<strong>Game</strong>
<span class="platform">WII</span>
</div>
<div class="result_wrap">
<div class="basic_stats has_score">
<div class="main_stats">
<h3 class="product_title basic_stat">...</h3>
<div class="std_score">
<div class="score_wrap">
<span class="label">Metascore: </span>
<span class="data metascore score_favorable">87</span>
</div>
</div>
</div>
<div class="more_stats extended_stats">...</div>
</div>
</div>
</li>
-- other platforms are the same basic layout
-- if it doesn't have a score, there is no div.basic_score
-- the <div class="result_type"> changes content for non-games:
<div class="result_type"><strong>Movie</strong></div>
'''
# get the proper result element we want to pull data from
result = None
if not doc.find_class('query_results'):
@ -118,7 +86,7 @@ def metacritic(inp):
link = 'http://metacritic.com' + product_title.find('a').attrib['href']
try:
release = result.find_class('release_date')[0].\
release = result.find_class('release_date')[0]. \
find_class('data')[0].text_content()
# strip extra spaces out of the release date
@ -127,11 +95,10 @@ def metacritic(inp):
release = None
try:
score = result.find_class('metascore')[0].text_content()
score = result.find_class('metascore_w')[0].text_content()
except IndexError:
score = None
return '[%s] %s - \x02%s/100\x02, %s - %s' % (plat.upper(), name,
score or 'no score',
'release: \x02%s\x02' % release if release else 'unreleased',
link)
return '[{}] {} - \x02{}/100\x02, {} - {}'.format(plat.upper(), name, score or 'no score',
'release: \x02%s\x02' % release if release else 'unreleased',
link)

View File

@ -0,0 +1,154 @@
import time
import random
from util import hook, http, web, text
## CONSTANTS
base_url = "http://api.bukget.org/3/"
search_url = base_url + "search/plugin_name/like/{}"
random_url = base_url + "plugins/bukkit/?start={}&size=1"
details_url = base_url + "plugins/bukkit/{}"
categories = http.get_json("http://api.bukget.org/3/categories")
count_total = sum([cat["count"] for cat in categories])
count_categories = {cat["name"].lower(): int(cat["count"]) for cat in categories} # dict comps!
class BukgetError(Exception):
def __init__(self, code, text):
self.code = code
self.text = text
def __str__(self):
return self.text
## DATA FUNCTIONS
def plugin_search(term):
""" searches for a plugin with the bukget API and returns the slug """
term = term.lower().strip()
search_term = http.quote_plus(term)
try:
results = http.get_json(search_url.format(search_term))
except (http.HTTPError, http.URLError) as e:
raise BukgetError(500, "Error Fetching Search Page: {}".format(e))
if not results:
raise BukgetError(404, "No Results Found")
for result in results:
if result["slug"] == term:
return result["slug"]
return results[0]["slug"]
def plugin_random():
""" gets a random plugin from the bukget API and returns the slug """
results = None
while not results:
plugin_number = random.randint(1, count_total)
print "trying {}".format(plugin_number)
try:
results = http.get_json(random_url.format(plugin_number))
except (http.HTTPError, http.URLError) as e:
raise BukgetError(500, "Error Fetching Search Page: {}".format(e))
return results[0]["slug"]
def plugin_details(slug):
""" takes a plugin slug and returns details from the bukget API """
slug = slug.lower().strip()
try:
details = http.get_json(details_url.format(slug))
except (http.HTTPError, http.URLError) as e:
raise BukgetError(500, "Error Fetching Details: {}".format(e))
return details
## OTHER FUNCTIONS
def format_output(data):
""" takes plugin data and returns two strings representing information about that plugin """
name = data["plugin_name"]
description = text.truncate_str(data['description'], 30)
url = data['website']
authors = data['authors'][0]
authors = authors[0] + u"\u200b" + authors[1:]
stage = data['stage']
current_version = data['versions'][0]
last_update = time.strftime('%d %B %Y %H:%M',
time.gmtime(current_version['date']))
version_number = data['versions'][0]['version']
bukkit_versions = ", ".join(current_version['game_versions'])
link = web.try_isgd(current_version['link'])
if description:
line_a = u"\x02{}\x02, by \x02{}\x02 - {} - ({}) \x02{}".format(name, authors, description, stage, url)
else:
line_a = u"\x02{}\x02, by \x02{}\x02 ({}) \x02{}".format(name, authors, stage, url)
line_b = u"Last release: \x02v{}\x02 for \x02{}\x02 at {} \x02{}\x02".format(version_number, bukkit_versions,
last_update, link)
return line_a, line_b
## HOOK FUNCTIONS
@hook.command('plugin')
@hook.command
def bukget(inp, reply=None, message=None):
"""bukget <slug/name> - Look up a plugin on dev.bukkit.org"""
# get the plugin slug using search
try:
slug = plugin_search(inp)
except BukgetError as e:
return e
# get the plugin info using the slug
try:
data = plugin_details(slug)
except BukgetError as e:
return e
# format the final message and send it to IRC
line_a, line_b = format_output(data)
reply(line_a)
message(line_b)
@hook.command(autohelp=None)
def randomplugin(inp, reply=None, message=None):
"""randomplugin - Gets a random plugin from dev.bukkit.org"""
# get a random plugin slug
try:
slug = plugin_random()
except BukgetError as e:
return e
# get the plugin info using the slug
try:
data = plugin_details(slug)
except BukgetError as e:
return e
# format the final message and send it to IRC
line_a, line_b = format_output(data)
reply(line_a)
message(line_b)

View File

@ -1,9 +1,10 @@
""" plugin by _303 (?)
"""
from util import hook
import re
import itertools
from util import hook
pattern = re.compile(r'^(?P<count>\d+)x (?P<name>.+?): (?P<ingredients>.*)$')
@ -32,9 +33,9 @@ with open("plugins/data/recipes.txt") as f:
if not match:
continue
recipelist.append(Recipe(line=line,
output=match.group("name").lower(),
ingredients=match.group("ingredients"),
count=match.group("count")))
output=match.group("name").lower(),
ingredients=match.group("ingredients"),
count=match.group("count")))
ids = []
@ -43,36 +44,35 @@ with open("plugins/data/itemids.txt") as f:
if line.startswith("//"):
continue
parts = line.strip().split()
id = parts[0]
itemid = parts[0]
name = " ".join(parts[1:])
ids.append((id, name))
ids.append((itemid, name))
@hook.command("mcid")
@hook.command
def mcitem(input, reply=None):
"mcitem <item/id> -- gets the id from an item or vice versa"
input = input.lower().strip()
def mcitem(inp, reply=None):
"""mcitem <item/id> -- gets the id from an item or vice versa"""
inp = inp.lower().strip()
if input == "":
if inp == "":
reply("error: no input.")
return
results = []
for id, name in ids:
if input == id:
results = ["\x02[%s]\x02 %s" % (id, name)]
for item_id, item_name in ids:
if inp == item_id:
results = ["\x02[{}]\x02 {}".format(item_id, item_name)]
break
elif input in name.lower():
results.append("\x02[%s]\x02 %s" % (id, name))
elif inp in item_name.lower():
results.append("\x02[{}]\x02 {}".format(item_id, item_name))
if not results:
return "No matches found."
if len(results) > 12:
reply("There are too many options, please narrow your search. " \
"(%s)" % len(results))
reply("There are too many options, please narrow your search. ({})".format(str(len(results))))
return
out = ", ".join(results)
@ -82,19 +82,18 @@ def mcitem(input, reply=None):
@hook.command("mccraft")
@hook.command
def mcrecipe(input, reply=None):
"mcrecipe <item> -- gets the crafting recipe for an item"
input = input.lower().strip()
def mcrecipe(inp, reply=None):
"""mcrecipe <item> -- gets the crafting recipe for an item"""
inp = inp.lower().strip()
results = [recipe.line for recipe in recipelist
if input in recipe.output]
if inp in recipe.output]
if not results:
return "No matches found."
if len(results) > 3:
reply("There are too many options, please narrow your search. " \
"(%s)" % len(results))
reply("There are too many options, please narrow your search. ({})".format(len(results)))
return
for result in results:

View File

@ -0,0 +1,232 @@
import socket
import struct
import json
import traceback
from util import hook
try:
import DNS
has_dns = True
except ImportError:
has_dns = False
mc_colors = [(u'\xa7f', u'\x0300'), (u'\xa70', u'\x0301'), (u'\xa71', u'\x0302'), (u'\xa72', u'\x0303'),
(u'\xa7c', u'\x0304'), (u'\xa74', u'\x0305'), (u'\xa75', u'\x0306'), (u'\xa76', u'\x0307'),
(u'\xa7e', u'\x0308'), (u'\xa7a', u'\x0309'), (u'\xa73', u'\x0310'), (u'\xa7b', u'\x0311'),
(u'\xa71', u'\x0312'), (u'\xa7d', u'\x0313'), (u'\xa78', u'\x0314'), (u'\xa77', u'\x0315'),
(u'\xa7l', u'\x02'), (u'\xa79', u'\x0310'), (u'\xa7o', u'\t'), (u'\xa7m', u'\x13'),
(u'\xa7r', u'\x0f'), (u'\xa7n', u'\x15')]
## EXCEPTIONS
class PingError(Exception):
def __init__(self, text):
self.text = text
def __str__(self):
return self.text
class ParseError(Exception):
def __init__(self, text):
self.text = text
def __str__(self):
return self.text
## MISC
def unpack_varint(s):
d = 0
i = 0
while True:
b = ord(s.recv(1))
d |= (b & 0x7F) << 7 * i
i += 1
if not b & 0x80:
return d
pack_data = lambda d: struct.pack('>b', len(d)) + d
pack_port = lambda i: struct.pack('>H', i)
## DATA FUNCTIONS
def mcping_modern(host, port):
""" pings a server using the modern (1.7+) protocol and returns data """
try:
# connect to the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((host, port))
except socket.gaierror:
raise PingError("Invalid hostname")
except socket.timeout:
raise PingError("Request timed out")
# send handshake + status request
s.send(pack_data("\x00\x00" + pack_data(host.encode('utf8')) + pack_port(port) + "\x01"))
s.send(pack_data("\x00"))
# read response
unpack_varint(s) # Packet length
unpack_varint(s) # Packet ID
l = unpack_varint(s) # String length
if not l > 1:
raise PingError("Invalid response")
d = ""
while len(d) < l:
d += s.recv(1024)
# Close our socket
s.close()
except socket.error:
raise PingError("Socket Error")
# Load json and return
data = json.loads(d.decode('utf8'))
try:
version = data["version"]["name"]
try:
desc = u" ".join(data["description"]["text"].split())
except TypeError:
desc = u" ".join(data["description"].split())
max_players = data["players"]["max"]
online = data["players"]["online"]
except Exception as e:
# TODO: except Exception is bad
traceback.print_exc(e)
raise PingError("Unknown Error: {}".format(e))
output = {
"motd": format_colors(desc),
"motd_raw": desc,
"version": version,
"players": online,
"players_max": max_players
}
return output
def mcping_legacy(host, port):
""" pings a server using the legacy (1.6 and older) protocol and returns data """
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((host, port))
sock.send('\xfe\x01')
response = sock.recv(1)
except socket.gaierror:
raise PingError("Invalid hostname")
except socket.timeout:
raise PingError("Request timed out")
if response[0] != '\xff':
raise PingError("Invalid response")
length = struct.unpack('!h', sock.recv(2))[0]
values = sock.recv(length * 2).decode('utf-16be')
data = values.split(u'\x00') # try to decode data using new format
if len(data) == 1:
# failed to decode data, server is using old format
data = values.split(u'\xa7')
output = {
"motd": format_colors(" ".join(data[0].split())),
"motd_raw": data[0],
"version": None,
"players": data[1],
"players_max": data[2]
}
else:
# decoded data, server is using new format
output = {
"motd": format_colors(" ".join(data[3].split())),
"motd_raw": data[3],
"version": data[2],
"players": data[4],
"players_max": data[5]
}
sock.close()
return output
## FORMATTING/PARSING FUNCTIONS
def check_srv(domain):
""" takes a domain and finds minecraft SRV records """
DNS.DiscoverNameServers()
srv_req = DNS.Request(qtype='srv')
srv_result = srv_req.req('_minecraft._tcp.{}'.format(domain))
for getsrv in srv_result.answers:
if getsrv['typename'] == 'SRV':
data = [getsrv['data'][2], getsrv['data'][3]]
return data
def parse_input(inp):
""" takes the input from the mcping command and returns the host and port """
inp = inp.strip().split(" ")[0]
if ":" in inp:
# the port is defined in the input string
host, port = inp.split(":", 1)
try:
port = int(port)
if port > 65535 or port < 0:
raise ParseError("The port '{}' is invalid.".format(port))
except ValueError:
raise ParseError("The port '{}' is invalid.".format(port))
return host, port
if has_dns:
# the port is not in the input string, but we have PyDNS so look for a SRV record
srv_data = check_srv(inp)
if srv_data:
return str(srv_data[1]), int(srv_data[0])
# return default port
return inp, 25565
def format_colors(motd):
for original, replacement in mc_colors:
motd = motd.replace(original, replacement)
motd = motd.replace(u"\xa7k", "")
return motd
def format_output(data):
if data["version"]:
return u"{motd}\x0f - {version}\x0f - {players}/{players_max}" \
u" players.".format(**data).replace("\n", u"\x0f - ")
else:
return u"{motd}\x0f - {players}/{players_max}" \
u" players.".format(**data).replace("\n", u"\x0f - ")
@hook.command
@hook.command("mcp")
def mcping(inp):
"""mcping <server>[:port] - Ping a Minecraft server to check status."""
try:
host, port = parse_input(inp)
except ParseError as e:
return "Could not parse input ({})".format(e)
try:
data = mcping_modern(host, port)
except PingError:
try:
data = mcping_legacy(host, port)
except PingError as e:
return "Could not ping server, is it offline? ({})".format(e)
return format_output(data)

View File

@ -0,0 +1,44 @@
import json
from util import hook, http
@hook.command(autohelp=False)
def mcstatus(inp):
"""mcstatus -- Checks the status of various Mojang (the creators of Minecraft) servers."""
try:
request = http.get("http://status.mojang.com/check")
except (http.URLError, http.HTTPError) as e:
return "Unable to get Minecraft server status: {}".format(e)
# lets just reformat this data to get in a nice format
data = json.loads(request.replace("}", "").replace("{", "").replace("]", "}").replace("[", "{"))
out = []
# use a loop so we don't have to update it if they add more servers
green = []
yellow = []
red = []
for server, status in data.items():
if status == "green":
green.append(server)
elif status == "yellow":
yellow.append(server)
else:
red.append(server)
if green:
out = "\x033\x02Online\x02\x0f: " + ", ".join(green)
if yellow:
out += " "
if yellow:
out += "\x02Issues\x02: " + ", ".join(yellow)
if red:
out += " "
if red:
out += "\x034\x02Offline\x02\x0f: " + ", ".join(red)
return "\x0f" + out.replace(".mojang.com", ".mj") \
.replace(".minecraft.net", ".mc")

View File

@ -0,0 +1,101 @@
import json
from util import hook, http
NAME_URL = "https://account.minecraft.net/buy/frame/checkName/{}"
PAID_URL = "http://www.minecraft.net/haspaid.jsp"
class McuError(Exception):
pass
def get_status(name):
""" takes a name and returns status """
try:
name_encoded = http.quote_plus(name)
response = http.get(NAME_URL.format(name_encoded))
except (http.URLError, http.HTTPError) as e:
raise McuError("Could not get name status: {}".format(e))
if "OK" in response:
return "free"
elif "TAKEN" in response:
return "taken"
elif "invalid characters" in response:
return "invalid"
def get_profile(name):
profile = {}
# form the profile request
request = {
"name": name,
"agent": "minecraft"
}
# submit the profile request
try:
headers = {"Content-Type": "application/json"}
r = http.get_json(
'https://api.mojang.com/profiles/page/1',
post_data=json.dumps(request),
headers=headers
)
except (http.URLError, http.HTTPError) as e:
raise McuError("Could not get profile status: {}".format(e))
user = r["profiles"][0]
profile["name"] = user["name"]
profile["id"] = user["id"]
profile["legacy"] = user.get("legacy", False)
try:
response = http.get(PAID_URL, user=name)
except (http.URLError, http.HTTPError) as e:
raise McuError("Could not get payment status: {}".format(e))
if "true" in response:
profile["paid"] = True
else:
profile["paid"] = False
return profile
@hook.command("haspaid")
@hook.command("mcpaid")
@hook.command
def mcuser(inp):
"""mcpaid <username> -- Gets information about the Minecraft user <account>."""
user = inp.strip()
try:
# get status of name (does it exist?)
name_status = get_status(user)
except McuError as e:
return e
if name_status == "taken":
try:
# get information about user
profile = get_profile(user)
except McuError as e:
return "Error: {}".format(e)
profile["lt"] = ", legacy" if profile["legacy"] else ""
if profile["paid"]:
return u"The account \x02{name}\x02 ({id}{lt}) exists. It is a \x02paid\x02" \
u" account.".format(**profile)
else:
return u"The account \x02{name}\x02 ({id}{lt}) exists. It \x034\x02is NOT\x02\x0f a paid" \
u" account.".format(**profile)
elif name_status == "free":
return u"The account \x02{}\x02 does not exist.".format(user)
elif name_status == "invalid":
return u"The name \x02{}\x02 contains invalid characters.".format(user)
else:
# if you see this, panic
return "Unknown Error."

View File

@ -0,0 +1,51 @@
import re
from util import hook, http, text
api_url = "http://minecraft.gamepedia.com/api.php?action=opensearch"
mc_url = "http://minecraft.gamepedia.com/"
@hook.command
def mcwiki(inp):
"""mcwiki <phrase> -- Gets the first paragraph of
the Minecraft Wiki article on <phrase>."""
try:
j = http.get_json(api_url, search=inp)
except (http.HTTPError, http.URLError) as e:
return "Error fetching search results: {}".format(e)
except ValueError as e:
return "Error reading search results: {}".format(e)
if not j[1]:
return "No results found."
# we remove items with a '/' in the name, because
# gamepedia uses sub-pages for different languages
# for some stupid reason
items = [item for item in j[1] if not "/" in item]
if items:
article_name = items[0].replace(' ', '_').encode('utf8')
else:
# there are no items without /, just return a / one
article_name = j[1][0].replace(' ', '_').encode('utf8')
url = mc_url + http.quote(article_name, '')
try:
page = http.get_html(url)
except (http.HTTPError, http.URLError) as e:
return "Error fetching wiki page: {}".format(e)
for p in page.xpath('//div[@class="mw-content-ltr"]/p'):
if p.text_content():
summary = " ".join(p.text_content().splitlines())
summary = re.sub("\[\d+\]", "", summary)
summary = text.truncate_str(summary, 200)
return u"{} :: {}".format(summary, url)
# this shouldn't happen
return "Unknown Error."

34
disabled_stuff/mlia.py Normal file
View File

@ -0,0 +1,34 @@
# Plugin by Infinity - <https://github.com/infinitylabs/UguuBot>
import random
from util import hook, http
mlia_cache = []
def refresh_cache():
"""gets a page of random MLIAs and puts them into a dictionary """
url = 'http://mylifeisaverage.com/{}'.format(random.randint(1, 11000))
soup = http.get_soup(url)
for story in soup.find_all('div', {'class': 'story '}):
mlia_id = story.find('span', {'class': 'left'}).a.text
mlia_text = story.find('div', {'class': 'sc'}).text.strip()
mlia_cache.append((mlia_id, mlia_text))
# do an initial refresh of the cache
refresh_cache()
@hook.command(autohelp=False)
def mlia(inp, reply=None):
"""mlia -- Gets a random quote from MyLifeIsAverage.com."""
# grab the last item in the mlia cache and remove it
mlia_id, text = mlia_cache.pop()
# reply with the mlia we grabbed
reply('({}) {}'.format(mlia_id, text))
# refresh mlia cache if its getting empty
if len(mlia_cache) < 3:
refresh_cache()

0
disabled_plugins/mtg.py → disabled_stuff/mtg.py Executable file → Normal file
View File

View File

@ -1,7 +1,7 @@
# BING translation plugin by Lukeroge and neersighted
from util import hook
from util import http
import re
import re
import htmlentitydefs
import mygengo

60
disabled_stuff/namegen.py Normal file
View File

@ -0,0 +1,60 @@
import json
import os
from util import hook, text, textgen
GEN_DIR = "./plugins/data/name_files/"
def get_generator(_json):
data = json.loads(_json)
return textgen.TextGenerator(data["templates"],
data["parts"], default_templates=data["default_templates"])
@hook.command(autohelp=False)
def namegen(inp, notice=None):
"""namegen [generator] -- Generates some names using the chosen generator.
'namegen list' will display a list of all generators."""
# clean up the input
inp = inp.strip().lower()
# get a list of available name generators
files = os.listdir(GEN_DIR)
all_modules = []
for i in files:
if os.path.splitext(i)[1] == ".json":
all_modules.append(os.path.splitext(i)[0])
all_modules.sort()
# command to return a list of all available generators
if inp == "list":
message = "Available generators: "
message += text.get_text_list(all_modules, 'and')
notice(message)
return
if inp:
selected_module = inp.split()[0]
else:
# make some generic fantasy names
selected_module = "fantasy"
# check if the selected module is valid
if not selected_module in all_modules:
return "Invalid name generator :("
# load the name generator
with open(os.path.join(GEN_DIR, "{}.json".format(selected_module))) as f:
try:
generator = get_generator(f.read())
except ValueError as error:
return "Unable to read name file: {}".format(error)
# time to generate some names
name_list = generator.generate_strings(10)
# and finally return the final message :D
return "Some names to ponder: {}.".format(text.get_text_list(name_list, 'and'))

95
disabled_stuff/newegg.py Normal file
View File

@ -0,0 +1,95 @@
import json
import re
from util import hook, http, text, web
## CONSTANTS
ITEM_URL = "http://www.newegg.com/Product/Product.aspx?Item={}"
API_PRODUCT = "http://www.ows.newegg.com/Products.egg/{}/ProductDetails"
API_SEARCH = "http://www.ows.newegg.com/Search.egg/Advanced"
NEWEGG_RE = (r"(?:(?:www.newegg.com|newegg.com)/Product/Product\.aspx\?Item=)([-_a-zA-Z0-9]+)", re.I)
## OTHER FUNCTIONS
def format_item(item, show_url=True):
""" takes a newegg API item object and returns a description """
title = text.truncate_str(item["Title"], 50)
# format the rating nicely if it exists
if not item["ReviewSummary"]["TotalReviews"] == "[]":
rating = "Rated {}/5 ({} ratings)".format(item["ReviewSummary"]["Rating"],
item["ReviewSummary"]["TotalReviews"][1:-1])
else:
rating = "No Ratings"
if not item["FinalPrice"] == item["OriginalPrice"]:
price = "{FinalPrice}, was {OriginalPrice}".format(**item)
else:
price = item["FinalPrice"]
tags = []
if item["Instock"]:
tags.append("\x02Stock Available\x02")
else:
tags.append("\x02Out Of Stock\x02")
if item["FreeShippingFlag"]:
tags.append("\x02Free Shipping\x02")
if item["IsFeaturedItem"]:
tags.append("\x02Featured\x02")
if item["IsShellShockerItem"]:
tags.append(u"\x02SHELL SHOCKER\u00AE\x02")
# join all the tags together in a comma separated string ("tag1, tag2, tag3")
tag_text = u", ".join(tags)
if show_url:
# create the item URL and shorten it
url = web.try_isgd(ITEM_URL.format(item["NeweggItemNumber"]))
return u"\x02{}\x02 ({}) - {} - {} - {}".format(title, price, rating,
tag_text, url)
else:
return u"\x02{}\x02 ({}) - {} - {}".format(title, price, rating,
tag_text)
## HOOK FUNCTIONS
@hook.regex(*NEWEGG_RE)
def newegg_url(match):
item_id = match.group(1)
item = http.get_json(API_PRODUCT.format(item_id))
return format_item(item, show_url=False)
@hook.command
def newegg(inp):
"""newegg <item name> -- Searches newegg.com for <item name>"""
# form the search request
request = {
"Keyword": inp,
"Sort": "FEATURED"
}
# submit the search request
r = http.get_json(
'http://www.ows.newegg.com/Search.egg/Advanced',
post_data=json.dumps(request)
)
# get the first result
if r["ProductListItems"]:
return format_item(r["ProductListItems"][0])
else:
return "No results found."

View File

@ -0,0 +1,59 @@
import re
from util import hook, http
newgrounds_re = (r'(.*:)//(www.newgrounds.com|newgrounds.com)(:[0-9]+)?(.*)', re.I)
valid = set('0123456789')
def test(s):
return set(s) <= valid
@hook.regex(*newgrounds_re)
def newgrounds_url(match):
location = match.group(4).split("/")[-1]
if not test(location):
print "Not a valid Newgrounds portal ID. Example: http://www.newgrounds.com/portal/view/593993"
return None
soup = http.get_soup("http://www.newgrounds.com/portal/view/" + location)
title = "\x02{}\x02".format(soup.find('title').text)
# get author
try:
author_info = soup.find('ul', {'class': 'authorlinks'}).find('img')['alt']
author = " - \x02{}\x02".format(author_info)
except:
author = ""
# get rating
try:
rating_info = soup.find('dd', {'class': 'star-variable'})['title'].split("Stars &ndash;")[0].strip()
rating = u" - rated \x02{}\x02/\x025.0\x02".format(rating_info)
except:
rating = ""
# get amount of ratings
try:
ratings_info = soup.find('dd', {'class': 'star-variable'})['title'].split("Stars &ndash;")[1].replace("Votes",
"").strip()
numofratings = " ({})".format(ratings_info)
except:
numofratings = ""
# get amount of views
try:
views_info = soup.find('dl', {'class': 'contentdata'}).findAll('dd')[1].find('strong').text
views = " - \x02{}\x02 views".format(views_info)
except:
views = ""
# get upload data
try:
date = "on \x02{}\x02".format(soup.find('dl', {'class': 'sidestats'}).find('dd').text)
except:
date = ""
return title + rating + numofratings + views + author + date

47
plugins/todo.py → disabled_stuff/notes.py Executable file → Normal file
View File

@ -1,16 +1,18 @@
from util import hook
import re
db_inited = False
from util import hook
def cleanSQL(sql):
db_ready = False
def clean_sql(sql):
return re.sub(r'\s+', " ", sql).strip()
def db_init(db):
global db_inited
if db_inited:
global db_ready
if db_ready:
return
exists = db.execute("""
@ -20,7 +22,7 @@ def db_init(db):
""").fetchone()[0] == 1
if not exists:
db.execute(cleanSQL("""
db.execute(clean_sql("""
create virtual table todos using fts4(
user,
text,
@ -30,7 +32,7 @@ def db_init(db):
db.commit()
db_inited = True
db_ready = True
def db_getall(db, nick, limit=-1):
@ -44,14 +46,14 @@ def db_getall(db, nick, limit=-1):
""", (nick, limit))
def db_get(db, nick, id):
def db_get(db, nick, note_id):
return db.execute("""
select added, text from todos
where lower(user) = lower(?)
order by added desc
limit 1
offset ?
""", (nick, id)).fetchone()
""", (nick, note_id)).fetchone()
def db_del(db, nick, limit='all'):
@ -64,8 +66,8 @@ def db_del(db, nick, limit='all'):
limit ?
offset ?)
""", (nick,
-1 if limit == 'all' else 1,
0 if limit == 'all' else limit))
-1 if limit == 'all' else 1,
0 if limit == 'all' else limit))
db.commit()
return row
@ -88,9 +90,10 @@ def db_search(db, nick, query):
""", (query, nick))
@hook.command("notes")
@hook.command
def todo(inp, nick='', chan='', db=None, notice=None, bot=None):
"todo (add|del|list|search) args -- Manipulates your list of todos."
def note(inp, nick='', chan='', db=None, notice=None, bot=None):
"""note(s) <add|del|list|search> args -- Manipulates your list of notes."""
db_init(db)
@ -100,7 +103,7 @@ def todo(inp, nick='', chan='', db=None, notice=None, bot=None):
args = parts[1:]
# code to allow users to access each others factoids and a copy of help
# ".todo (add|del|list|search) [@user] args -- Manipulates your list of todos."
# ".note (add|del|list|search) [@user] args -- Manipulates your list of todos."
#if len(args) and args[0].startswith("@"):
# nick = args[0][1:]
# args = args[1:]
@ -113,7 +116,7 @@ def todo(inp, nick='', chan='', db=None, notice=None, bot=None):
db_add(db, nick, text)
notice("Task added!")
notice("Note added!")
return
elif cmd == 'get':
if len(args):
@ -130,7 +133,7 @@ def todo(inp, nick='', chan='', db=None, notice=None, bot=None):
if not row:
notice("No such entry.")
return
notice("[%d]: %s: %s" % (index, row[0], row[1]))
notice("[{}]: {}: {}".format(index, row[0], row[1]))
elif cmd == 'del' or cmd == 'delete' or cmd == 'remove':
if not len(args):
return "error"
@ -146,7 +149,7 @@ def todo(inp, nick='', chan='', db=None, notice=None, bot=None):
rows = db_del(db, nick, index)
notice("Deleted %d entries" % rows.rowcount)
notice("Deleted {} entries".format(rows.rowcount))
elif cmd == 'list':
limit = -1
@ -163,11 +166,11 @@ def todo(inp, nick='', chan='', db=None, notice=None, bot=None):
found = False
for (index, row) in enumerate(rows):
notice("[%d]: %s: %s" % (index, row[0], row[1]))
notice("[{}]: {}: {}".format(index, row[0], row[1]))
found = True
if not found:
notice("%s has no entries." % nick)
notice("{} has no entries.".format(nick))
elif cmd == 'search':
if not len(args):
notice("No search query given!")
@ -178,11 +181,11 @@ def todo(inp, nick='', chan='', db=None, notice=None, bot=None):
found = False
for (index, row) in enumerate(rows):
notice("[%d]: %s: %s" % (index, row[0], row[1]))
notice("[{}]: {}: {}".format(index, row[0], row[1]))
found = True
if not found:
notice("%s has no matching entries for: %s" % (nick, query))
notice("{} has no matching entries for: {}".format(nick, query))
else:
notice("Unknown command: %s" % cmd)
notice("Unknown command: {}".format(cmd))

29
disabled_stuff/osrc.py Normal file
View File

@ -0,0 +1,29 @@
from bs4 import BeautifulSoup
from util import hook, http, web
user_url = "http://osrc.dfm.io/{}"
@hook.command
def osrc(inp):
"""osrc <github user> -- Gets an Open Source Report Card for <github user>"""
user_nick = inp.strip()
url = user_url.format(user_nick)
try:
soup = http.get_soup(url)
except (http.HTTPError, http.URLError):
return "Couldn't find any stats for this user."
report = soup.find("div", {"id": "description"}).find("p").get_text()
# Split and join to remove all the excess whitespace, slice the
# string to remove the trailing full stop.
report = " ".join(report.split())[:-1]
short_url = web.try_isgd(url)
return "{} - {}".format(report, short_url)

18
plugins/password.py → disabled_stuff/password.py Executable file → Normal file
View File

@ -1,12 +1,15 @@
# based on password generation code by TheNoodle
from util import hook
# TODO: Add some kind of pronounceable password generation
# TODO: Improve randomness
import string
import random
from util import hook
@hook.command
def password(inp, notice=None):
"password <length> [types] -- Generates a password of <length> (default 10). [types] can include 'alpha', 'no caps', 'numeric', 'symbols' or any combination of the inp, eg. 'numbers symbols'"
"""password <length> [types] -- Generates a password of <length> (default 10).
[types] can include 'alpha', 'no caps', 'numeric', 'symbols' or any combination of the inp, eg. 'numbers symbols'"""
okay = []
# find the length needed for the password
@ -30,17 +33,18 @@ def password(inp, notice=None):
# add symbols
if "symbol" in inp:
sym = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '_', '+', '[', ']', '{', '}', '\\', '|', ';', ':', "'", '.', '>', ',', '<', '/', '?', '`', '~', '"']
sym = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '_', '+', '[', ']', '{', '}', '\\', '|', ';',
':', "'", '.', '>', ',', '<', '/', '?', '`', '~', '"']
okay += okay + sym
# defaults to lowercase alpha password if the okay list is empty
if not okay:
okay = okay + list(string.ascii_lowercase)
password = ""
pw = ""
# generates password
for x in range(length):
password = password + random.choice(okay)
pw = pw + random.choice(okay)
notice(password)
notice(pw)

12
disabled_stuff/plpaste.py Normal file
View File

@ -0,0 +1,12 @@
from util import hook, web
@hook.command(adminonly=True)
def plpaste(inp):
if "/" in inp and inp.split("/")[0] != "util":
return "Invalid input"
try:
with open("plugins/%s.py" % inp) as f:
return web.haste(f.read(), ext='py')
except IOError:
return "Plugin not found (must be in plugins folder)"

56
disabled_stuff/potato.py Normal file
View File

@ -0,0 +1,56 @@
# coding=utf-8
import re
import random
from util import hook
potatoes = ['AC Belmont', 'AC Blue Pride', 'AC Brador', 'AC Chaleur', 'AC Domino', 'AC Dubuc', 'AC Glacier Chip',
'AC Maple Gold', 'AC Novachip', 'AC Peregrine Red', 'AC Ptarmigan', 'AC Red Island', 'AC Saguenor',
'AC Stampede Russet', 'AC Sunbury', 'Abeille', 'Abnaki', 'Acadia', 'Acadia Russet', 'Accent',
'Adirondack Blue', 'Adirondack Red', 'Adora', 'Agria', 'All Blue', 'All Red', 'Alpha', 'Alta Russet',
'Alturas Russet', 'Amandine', 'Amisk', 'Andover', 'Anoka', 'Anson', 'Aquilon', 'Arran Consul', 'Asterix',
'Atlantic', 'Austrian Crescent', 'Avalanche', 'Banana', 'Bannock Russet', 'Batoche', 'BeRus',
'Belle De Fonteney', 'Belleisle', 'Bintje', 'Blossom', 'Blue Christie', 'Blue Mac', 'Brigus',
'Brise du Nord', 'Butte', 'Butterfinger', 'Caesar', 'CalWhite', 'CalRed', 'Caribe', 'Carlingford',
'Carlton', 'Carola', 'Cascade', 'Castile', 'Centennial Russet', 'Century Russet', 'Charlotte', 'Cherie',
'Cherokee', 'Cherry Red', 'Chieftain', 'Chipeta', 'Coastal Russet', 'Colorado Rose', 'Concurrent',
'Conestoga', 'Cowhorn', 'Crestone Russet', 'Crispin', 'Cupids', 'Daisy Gold', 'Dakota Pearl', 'Defender',
'Delikat', 'Denali', 'Desiree', 'Divina', 'Dundrod', 'Durango Red', 'Early Rose', 'Elba', 'Envol',
'Epicure', 'Eramosa', 'Estima', 'Eva', 'Fabula', 'Fambo', 'Fremont Russet', 'French Fingerling',
'Frontier Russet', 'Fundy', 'Garnet Chile', 'Gem Russet', 'GemStar Russet', 'Gemchip', 'German Butterball',
'Gigant', 'Goldrush', 'Granola', 'Green Mountain', 'Haida', 'Hertha', 'Hilite Russet', 'Huckleberry',
'Hunter', 'Huron', 'IdaRose', 'Innovator', 'Irish Cobbler', 'Island Sunshine', 'Ivory Crisp',
'Jacqueline Lee', 'Jemseg', 'Kanona', 'Katahdin', 'Kennebec', "Kerr's Pink", 'Keswick', 'Keuka Gold',
'Keystone Russet', 'King Edward VII', 'Kipfel', 'Klamath Russet', 'Krantz', 'LaRatte', 'Lady Rosetta',
'Latona', 'Lemhi Russet', 'Liberator', 'Lili', 'MaineChip', 'Marfona', 'Maris Bard', 'Maris Piper',
'Matilda', 'Mazama', 'McIntyre', 'Michigan Purple', 'Millenium Russet', 'Mirton Pearl', 'Modoc', 'Mondial',
'Monona', 'Morene', 'Morning Gold', 'Mouraska', 'Navan', 'Nicola', 'Nipigon', 'Niska', 'Nooksack',
'NorValley', 'Norchip', 'Nordonna', 'Norgold Russet', 'Norking Russet', 'Norland', 'Norwis', 'Obelix',
'Ozette', 'Peanut', 'Penta', 'Peribonka', 'Peruvian Purple', 'Pike', 'Pink Pearl', 'Prospect', 'Pungo',
'Purple Majesty', 'Purple Viking', 'Ranger Russet', 'Reba', 'Red Cloud', 'Red Gold', 'Red La Soda',
'Red Pontiac', 'Red Ruby', 'Red Thumb', 'Redsen', 'Rocket', 'Rose Finn Apple', 'Rose Gold', 'Roselys',
'Rote Erstling', 'Ruby Crescent', 'Russet Burbank', 'Russet Legend', 'Russet Norkotah', 'Russet Nugget',
'Russian Banana', 'Saginaw Gold', 'Sangre', 'Sant<EFBFBD>', 'Satina', 'Saxon', 'Sebago', 'Shepody', 'Sierra',
'Silverton Russet', 'Simcoe', 'Snowden', 'Spunta', "St. John's", 'Summit Russet', 'Sunrise', 'Superior',
'Symfonia', 'Tolaas', 'Trent', 'True Blue', 'Ulla', 'Umatilla Russet', 'Valisa', 'Van Gogh', 'Viking',
'Wallowa Russet', 'Warba', 'Western Russet', 'White Rose', 'Willamette', 'Winema', 'Yellow Finn',
'Yukon Gold']
@hook.command
def potato(inp, action=None):
"""potato <user> - Makes <user> a tasty little potato."""
inp = inp.strip()
if not re.match("^[A-Za-z0-9_|.-\]\[]*$", inp.lower()):
return "I cant make a tasty potato for that user!"
potato_type = random.choice(potatoes)
size = random.choice(['small', 'little', 'mid-sized', 'medium-sized', 'large', 'gigantic'])
flavor = random.choice(['tasty', 'delectable', 'delicious', 'yummy', 'toothsome', 'scrumptious', 'luscious'])
method = random.choice(['bakes', 'fries', 'boils', 'roasts'])
side_dish = random.choice(['side salad', 'dollop of sour cream', 'piece of chicken', 'bowl of shredded bacon'])
action("{} a {} {} {} potato for {} and serves it with a small {}!".format(method, flavor, size, potato_type, inp,
side_dish))

38
disabled_stuff/pre.py Normal file
View File

@ -0,0 +1,38 @@
import datetime
from util import hook, http, timesince
@hook.command("scene")
@hook.command
def pre(inp):
"""pre <query> -- searches scene releases using orlydb.com"""
try:
h = http.get_html("http://orlydb.com/", q=inp)
except http.HTTPError as e:
return 'Unable to fetch results: {}'.format(e)
results = h.xpath("//div[@id='releases']/div/span[@class='release']/..")
if not results:
return "No results found."
result = results[0]
date = result.xpath("span[@class='timestamp']/text()")[0]
section = result.xpath("span[@class='section']//text()")[0]
name = result.xpath("span[@class='release']/text()")[0]
# parse date/time
date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
date_string = date.strftime("%d %b %Y")
since = timesince.timesince(date)
size = result.xpath("span[@class='inforight']//text()")
if size:
size = ' - ' + size[0].split()[0]
else:
size = ''
return '{} - {}{} - {} ({} ago)'.format(section, name, size, date_string, since)

Some files were not shown because too many files have changed in this diff Show More