init commit

master
Paul Walko 2016-01-31 00:32:02 -05:00
commit 7d249b7564
25 changed files with 26172 additions and 0 deletions

View File

View File

7
default.cfg Normal file
View File

@ -0,0 +1,7 @@
[core]
nick = LennyBoi
host = irc.oftc.net
use_ssl = true
port = 6697
owner = pew
channels = #asdf

BIN
default.db Normal file

Binary file not shown.

346
logs/exceptions.log Normal file
View File

@ -0,0 +1,346 @@
Signature: AttributeError: module 'urllib' has no attribute 'open' (file "/home/paul/.sopel/modules/meme.py", line 9, in meme)
from pew at 2016-01-30 17:11:07.678183. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 9, in meme
response = urllib.open(url)
AttributeError: module 'urllib' has no attribute 'open'
----------------------------------------
Signature: AttributeError: module 'urllib' has no attribute 'open' (file "/home/paul/.sopel/modules/meme.py", line 9, in meme)
from pew at 2016-01-30 17:11:15.487568. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 9, in meme
response = urllib.open(url)
AttributeError: module 'urllib' has no attribute 'open'
----------------------------------------
Signature: AttributeError: module 'urllib' has no attribute 'urlopen' (file "/home/paul/.sopel/modules/meme.py", line 9, in meme)
from pew at 2016-01-30 17:12:25.072990. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 9, in meme
response = urllib.urlopen(url)
AttributeError: module 'urllib' has no attribute 'urlopen'
----------------------------------------
Signature: urllib.error.HTTPError: HTTP Error 403: Forbidden (file "/usr/lib64/python3.5/urllib/request.py", line 589, in http_error_default)
from pew at 2016-01-30 17:15:54.779825. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 9, in meme
response = urllib.request.urlopen(url)
File "/usr/lib64/python3.5/urllib/request.py", line 162, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib64/python3.5/urllib/request.py", line 471, in open
response = meth(req, response)
File "/usr/lib64/python3.5/urllib/request.py", line 581, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib64/python3.5/urllib/request.py", line 509, in error
return self._call_chain(*args)
File "/usr/lib64/python3.5/urllib/request.py", line 443, in _call_chain
result = func(*args)
File "/usr/lib64/python3.5/urllib/request.py", line 589, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
----------------------------------------
Signature: urllib.error.HTTPError: HTTP Error 403: Forbidden (file "/usr/lib64/python3.5/urllib/request.py", line 589, in http_error_default)
from pew at 2016-01-30 17:18:37.842089. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 9, in meme
response = urllib.request.urlopen(url)
File "/usr/lib64/python3.5/urllib/request.py", line 162, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib64/python3.5/urllib/request.py", line 471, in open
response = meth(req, response)
File "/usr/lib64/python3.5/urllib/request.py", line 581, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib64/python3.5/urllib/request.py", line 509, in error
return self._call_chain(*args)
File "/usr/lib64/python3.5/urllib/request.py", line 443, in _call_chain
result = func(*args)
File "/usr/lib64/python3.5/urllib/request.py", line 589, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
----------------------------------------
Signature: urllib.error.HTTPError: HTTP Error 403: Forbidden (file "/usr/lib64/python3.5/urllib/request.py", line 589, in http_error_default)
from pew at 2016-01-30 17:23:11.170107. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 9, in meme
with urllib.request.urlopen(url) as response, open(data.json, 'wb') as out_file:
File "/usr/lib64/python3.5/urllib/request.py", line 162, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib64/python3.5/urllib/request.py", line 471, in open
response = meth(req, response)
File "/usr/lib64/python3.5/urllib/request.py", line 581, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib64/python3.5/urllib/request.py", line 509, in error
return self._call_chain(*args)
File "/usr/lib64/python3.5/urllib/request.py", line 443, in _call_chain
result = func(*args)
File "/usr/lib64/python3.5/urllib/request.py", line 589, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
----------------------------------------
Signature: UnboundLocalError: local variable 'data' referenced before assignment (file "/home/paul/.sopel/modules/meme.py", line 14, in meme)
from pew at 2016-01-30 17:28:26.927559. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 14, in meme
with urllib.request.urlopen(request) as response, open(data.json, 'wb') as out_file:
UnboundLocalError: local variable 'data' referenced before assignment
----------------------------------------
Signature: NameError: name 'jsonResponse' is not defined (file "/home/paul/.sopel/modules/meme.py", line 21, in meme)
from pew at 2016-01-30 17:31:19.686383. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 21, in meme
jsonList = jsonResponse["data"]
NameError: name 'jsonResponse' is not defined
----------------------------------------
Signature: KeyError: 0 (file "/home/paul/workspace/memer/meme/lib/python3.5/random.py", line 256, in choice)
from pew at 2016-01-30 17:33:13.684901. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 22, in meme
memeData = random.choice(jsonList)
File "/home/paul/workspace/memer/meme/lib/python3.5/random.py", line 256, in choice
return seq[i]
KeyError: 0
----------------------------------------
Signature: AttributeError: module 'urllib' has no attribute 'urlopen' (file "/home/paul/.sopel/modules/meme.py", line 28, in meme)
from pew at 2016-01-30 17:46:36.114731. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 28, in meme
f.write(urllib.urlopen(memeURL).read())
AttributeError: module 'urllib' has no attribute 'urlopen'
----------------------------------------
Signature: urllib.error.HTTPError: HTTP Error 403: Forbidden (file "/usr/lib64/python3.5/urllib/request.py", line 589, in http_error_default)
from pew at 2016-01-30 17:47:16.339001. Message was: .meme
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/meme.py", line 28, in meme
f.write(urllib.request.urlopen(memeURL).read())
File "/usr/lib64/python3.5/urllib/request.py", line 162, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib64/python3.5/urllib/request.py", line 471, in open
response = meth(req, response)
File "/usr/lib64/python3.5/urllib/request.py", line 581, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib64/python3.5/urllib/request.py", line 509, in error
return self._call_chain(*args)
File "/usr/lib64/python3.5/urllib/request.py", line 443, in _call_chain
result = func(*args)
File "/usr/lib64/python3.5/urllib/request.py", line 589, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
----------------------------------------
Signature: NameError: name 'authii' is not defined (file "/home/paul/.sopel/modules/trump.py", line 14, in trump)
from pew at 2016-01-30 19:00:43.418647. Message was: .trump
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/trump.py", line 14, in trump
api = tweepy.API(authii)
NameError: name 'authii' is not defined
----------------------------------------
Signature: tweepy.error.TweepError: Failed to send request: local variable 'auth' referenced before assignment (file "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/tweepy/binder.py", line 189, in execute)
from pew at 2016-01-30 19:02:10.533530. Message was: .trump
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/tweepy/binder.py", line 186, in execute
auth=auth,
UnboundLocalError: local variable 'auth' referenced before assignment
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/trump.py", line 15, in trump
user = tweepy.api.get_user('realDonaldTrump')
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/tweepy/binder.py", line 245, in _call
return method.execute()
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/tweepy/binder.py", line 189, in execute
raise TweepError('Failed to send request: %s' % e)
tweepy.error.TweepError: Failed to send request: local variable 'auth' referenced before assignment
----------------------------------------
Signature: tweepy.error.TweepError: Failed to send request: local variable 'auth' referenced before assignment (file "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/tweepy/binder.py", line 189, in execute)
from pew at 2016-01-30 19:04:57.592608. Message was: .trump
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/tweepy/binder.py", line 186, in execute
auth=auth,
UnboundLocalError: local variable 'auth' referenced before assignment
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/trump.py", line 15, in trump
user = tweepy.api.get_user('realDonaldTrump')
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/tweepy/binder.py", line 245, in _call
return method.execute()
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/tweepy/binder.py", line 189, in execute
raise TweepError('Failed to send request: %s' % e)
tweepy.error.TweepError: Failed to send request: local variable 'auth' referenced before assignment
----------------------------------------
Signature: AttributeError: 'Status' object has no attribute 'decode' (file "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 300, in say)
from pew at 2016-01-30 19:06:48.399804. Message was: .trump
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/trump.py", line 18, in trump
bot.say(tweet)
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 402, in say
self._bot.say(message, destination, max_messages)
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 300, in say
text = encoded_text.decode('utf-8')
AttributeError: 'Status' object has no attribute 'decode'
----------------------------------------
Signature: AttributeError: 'list' object has no attribute 'decode' (file "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 300, in say)
from pew at 2016-01-30 19:10:47.992309. Message was: .trump
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/trump.py", line 18, in trump
bot.say(dir(tweet))
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 402, in say
self._bot.say(message, destination, max_messages)
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 300, in say
text = encoded_text.decode('utf-8')
AttributeError: 'list' object has no attribute 'decode'
----------------------------------------
Signature: AttributeError: 'User' object has no attribute 'decode' (file "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 300, in say)
from pew at 2016-01-30 19:12:08.072288. Message was: .trump
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/trump.py", line 18, in trump
bot.say(tweet.author)
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 402, in say
self._bot.say(message, destination, max_messages)
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 300, in say
text = encoded_text.decode('utf-8')
AttributeError: 'User' object has no attribute 'decode'
----------------------------------------
Signature: NameError: name 'random' is not defined (file "/home/paul/.sopel/modules/trump.py", line 17, in trump)
from pew at 2016-01-30 19:17:52.592433. Message was: .trump
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/trump.py", line 17, in trump
tweet = random.choice(tweets)
NameError: name 'random' is not defined
----------------------------------------
Signature: AttributeError: module 'facebook' has no attribute 'GraphAP' (file "/home/paul/.sopel/modules/cirque.py", line 7, in cdt)
from pew at 2016-01-30 19:43:47.337505. Message was: .cdt
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/cirque.py", line 7, in cdt
graph = facebook.GraphAP(access_token = my_token, version = "2.5")
AttributeError: module 'facebook' has no attribute 'GraphAP'
----------------------------------------
Signature: AttributeError: module 'facebook' has no attribute 'GraphAPI' (file "/home/paul/.sopel/modules/cirque.py", line 7, in cdt)
from pew at 2016-01-30 19:44:47.777992. Message was: .cdt
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/cirque.py", line 7, in cdt
graph = facebook.GraphAPI(access_token = my_token, version = "2.5")
AttributeError: module 'facebook' has no attribute 'GraphAPI'
----------------------------------------
Signature: TypeError: get_object() missing 1 required positional argument: 'id' (file "/home/paul/.sopel/modules/cirque.py", line 9, in cdt)
from pew at 2016-01-30 19:58:11.822672. Message was: .cdt
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/cirque.py", line 9, in cdt
group = graph.get_object(group = "404041393126881")
TypeError: get_object() missing 1 required positional argument: 'id'
----------------------------------------
Signature: facebook.GraphAPIError: Invalid OAuth access token. (file "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 275, in request)
from pew at 2016-01-30 19:59:29.142068. Message was: .cdt
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/cirque.py", line 9, in cdt
group = graph.get_object(id = "404041393126881")
File "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 106, in get_object
return self.request(self.version + "/" + id, args)
File "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 275, in request
raise GraphAPIError(result)
facebook.GraphAPIError: Invalid OAuth access token.
----------------------------------------
Signature: facebook.GraphAPIError: Invalid OAuth access token. (file "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 275, in request)
from pew at 2016-01-30 20:01:27.949598. Message was: .cdt
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/cirque.py", line 9, in cdt
group = graph.get_object(id = "404041393126881")
File "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 106, in get_object
return self.request(self.version + "/" + id, args)
File "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 275, in request
raise GraphAPIError(result)
facebook.GraphAPIError: Invalid OAuth access token.
----------------------------------------
Signature: facebook.GraphAPIError: Invalid OAuth access token. (file "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 275, in request)
from pew at 2016-01-30 20:07:43.032009. Message was: .cdt
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/cirque.py", line 9, in cdt
group = graph.get_object(id = "404041393126881")
File "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 106, in get_object
return self.request(self.version + "/" + id, args)
File "/home/paul/workspace/memer/meme/src/facebook-sdk/facebook/__init__.py", line 275, in request
raise GraphAPIError(result)
facebook.GraphAPIError: Invalid OAuth access token.
----------------------------------------
Signature: AttributeError: module 'facebook' has no attribute 'get_app_access_token' (file "/home/paul/.sopel/modules/cirque.py", line 6, in cdt)
from pew at 2016-01-30 20:17:50.653861. Message was: .cdt
Traceback (most recent call last):
File "/home/paul/workspace/memer/meme/lib/python3.5/site-packages/sopel/bot.py", line 441, in call
exit_code = func(sopel, trigger)
File "/home/paul/.sopel/modules/cirque.py", line 6, in cdt
my_token = facebook.get_app_access_token("1081766428540462", "12ae4a86e2a064a137c4fe10390956bf")
AttributeError: module 'facebook' has no attribute 'get_app_access_token'
----------------------------------------

4542
logs/raw.log Normal file

File diff suppressed because it is too large Load Diff

1347
logs/stdio.log Normal file

File diff suppressed because one or more lines are too long

19499
malwaredomains.txt Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
modules/ansi.pyc Normal file

Binary file not shown.

1
modules/data.json Normal file

File diff suppressed because one or more lines are too long

16
modules/graphics_util.py Normal file
View File

@ -0,0 +1,16 @@
def alpha_blend(src, dst):
# Does not assume that dst is fully opaque
# See https://en.wikipedia.org/wiki/Alpha_compositing - section on "Alpha Blending"
src_multiplier = (src[3] / 255.0)
dst_multiplier = (dst[3] / 255.0) * (1 - src_multiplier)
result_alpha = src_multiplier + dst_multiplier
if result_alpha == 0: # special case to prevent div by zero below
return (0, 0, 0, 0)
else:
return (
int(((src[0] * src_multiplier) + (dst[0] * dst_multiplier)) / result_alpha),
int(((src[1] * src_multiplier) + (dst[1] * dst_multiplier)) / result_alpha),
int(((src[2] * src_multiplier) + (dst[2] * dst_multiplier)) / result_alpha),
int(result_alpha * 255)
)

BIN
modules/graphics_util.pyc Normal file

Binary file not shown.

BIN
modules/image.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

310
modules/img2txt.py Normal file
View File

@ -0,0 +1,310 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
("""
Usage:
img2txt.py <imgfile> [--maxLen=<n>] [--fontSize=<n>] [--color] [--ansi]"""
"""[--bgcolor=<#RRGGBB>] [--targetAspect=<n>] [--antialias] [--dither]
img2txt.py (-h | --help)
Options:
-h --help show this screen.
--ansi output an ANSI rendering of the image
--color output a colored HTML rendering of the image.
--antialias causes any resizing of the image to use antialiasing
--dither dither the colors to web palette. Useful when converting
images to ANSI (which has a limited color palette)
--fontSize=<n> sets font size (in pixels) when outputting HTML,
default: 7
--maxLen=<n> resize image so that larger of width or height matches
maxLen, default: 100px
--bgcolor=<#RRGGBB> if specified, is blended with transparent pixels to
produce the output. In ansi case, if no bgcolor set, a
fully transparent pixel is not drawn at all, partially
transparent pixels drawn as if opaque
--targetAspect=<n> resize image to this ratio of width to height. Default is
1.0 (no resize). For a typical terminal where height of a
character is 2x its width, you might want to try 0.5 here
""")
import sys, os
from docopt import docopt
from PIL import Image
sys.path.append(os.getcwd())
from graphics_util import alpha_blend
def HTMLColorToRGB(colorstring):
""" convert #RRGGBB to an (R, G, B) tuple """
colorstring = colorstring.strip()
if colorstring[0] == '#':
colorstring = colorstring[1:]
if len(colorstring) != 6:
raise ValueError(
"input #{0} is not in #RRGGBB format".format(colorstring))
r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:]
r, g, b = [int(n, 16) for n in (r, g, b)]
return (r, g, b)
def generate_HTML_for_image(pixels, width, height):
string = ""
# first go through the height, otherwise will rotate
for h in range(height):
for w in range(width):
rgba = pixels[w, h]
# TODO - could optimize output size by keeping span open until we
# hit end of line or different color/alpha
# Could also output just rgb (not rgba) when fully opaque - if
# fully opaque is prevalent in an image
# those saved characters would add up
string += ("<span style=\"color:rgba({0}, {1}, {2}, {3});\">"
"▇</span>").format(
rgba[0], rgba[1], rgba[2], rgba[3] / 255.0)
string += "\n"
return string
def generate_grayscale_for_image(pixels, width, height, bgcolor):
# grayscale
color = "MNHQ$OC?7>!:-;. "
string = ""
# first go through the height, otherwise will rotate
for h in range(height):
for w in range(width):
rgba = pixels[w, h]
# If partial transparency and we have a bgcolor, combine with bg
# color
if rgba[3] != 255 and bgcolor is not None:
rgba = alpha_blend(rgba, bgcolor)
# Throw away any alpha (either because bgcolor was partially
# transparent or had no bg color)
# Could make a case to choose character to draw based on alpha but
# not going to do that now...
rgb = rgba[:3]
string += color[int(sum(rgb) / 3.0 / 256.0 * 16)]
string += "\n"
return string
def load_and_resize_image(imgname, antialias, maxLen, aspectRatio):
if aspectRatio is None:
aspectRatio = 1.0
img = Image.open(imgname)
# force image to RGBA - deals with palettized images (e.g. gif) etc.
if img.mode != 'RGBA':
img = img.convert('RGBA')
# need to change the size of the image?
if maxLen is not None or aspectRatio != 1.0:
native_width, native_height = img.size
new_width = native_width
new_height = native_height
# First apply aspect ratio change (if any) - just need to adjust one axis
# so we'll do the height.
if aspectRatio != 1.0:
new_height = int(float(aspectRatio) * new_height)
# Now isotropically resize up or down (preserving aspect ratio) such that
# longer side of image is maxLen
if maxLen is not None:
rate = float(maxLen) / max(new_width, new_height)
new_width = int(rate * new_width)
new_height = int(rate * new_height)
if native_width != new_width or native_height != new_height:
img = img.resize((new_width, new_height), Image.ANTIALIAS if antialias else Image.NEAREST)
return img
def floydsteinberg_dither_to_web_palette(img):
# Note that alpha channel is thrown away - if you want to keep it you need to deal with it yourself
#
# Here's how it works:
# 1. Convert to RGB if needed - we can't go directly from RGBA because Image.convert will not dither in this case
# 2. Convert to P(alette) mode - this lets us kick in dithering.
# 3. Convert back to RGBA, which is where we want to be
#
# Admittedly converting back and forth requires more memory than just dithering directly
# in RGBA but that's how the library works and it isn't worth writing it ourselves
# or looking for an alternative given current perf needs.
if img.mode != 'RGB':
img = img.convert('RGB')
img = img.convert(mode="P", matrix=None, dither=Image.FLOYDSTEINBERG, palette=Image.WEB, colors=256)
img = img.convert('RGBA')
return img
def dither_image_to_web_palette(img, bgcolor):
if bgcolor is not None:
# We know the background color so flatten the image and bg color together, thus getting rid of alpha
# This is important because as discussed below, dithering alpha doesn't work correctly.
img = Image.alpha_composite(Image.new("RGBA", img.size, bgcolor), img) # alpha blend onto image filled with bgcolor
dithered_img = floydsteinberg_dither_to_web_palette(img)
else:
"""
It is not possible to correctly dither in the presence of transparency without knowing the background
that the image will be composed onto. This is because dithering works by propagating error that is introduced
when we select _available_ colors that don't match the _desired_ colors. Without knowing the final color value
for a pixel, it is not possible to compute the error that must be propagated FROM it. If a pixel is fully or
partially transparent, we must know the background to determine the final color value. We can't even record
the incoming error for the pixel, and then later when/if we know the background compute the full error and
propagate that, because that error needs to propagate into the original color selection decisions for the other
pixels. Those decisions absorb error and are lossy. You can't later apply more error on top of those color
decisions and necessarily get the same results as applying that error INTO those decisions in the first place.
So having established that we could only handle transparency correctly at final draw-time, shouldn't we just
dither there instead of here? Well, if we don't know the background color here we don't know it there either.
So we can either not dither at all if we don't know the bg color, or make some approximation. We've chosen
the latter. We'll handle it here to make the drawing code simpler. So what is our approximation? We basically
just ignore any color changes dithering makes to pixels that have transparency, and prevent any error from being
propagated from those pixels. This is done by setting them all to black before dithering (using an exact-match
color in Floyd Steinberg dithering with a web-safe-palette will never cause a pixel to receive enough inbound error
to change color and thus will not propagate error), and then afterwards we set them back to their original values.
This means that transparent pixels are essentially not dithered - they ignore (and absorb) inbound error but they
keep their original colors. We could alternately play games with the alpha channel to try to propagate the error
values for transparent pixels through to when we do final drawing but it only works in certain cases and just isn't
worth the effort (which involves writing the dithering code ourselves for one thing).
"""
# Force image to RGBA if it isn't already - simplifies the rest of the code
if img.mode != 'RGBA':
img = img.convert('RGBA')
rgb_img = img.convert('RGB')
orig_pixels = img.load()
rgb_pixels = rgb_img.load()
width, height = img.size
for h in range(height): # set transparent pixels to black
for w in range(width):
if (orig_pixels[w, h])[3] != 255:
rgb_pixels[w, h] = (0, 0, 0) # bashing in a new value changes it!
dithered_img = floydsteinberg_dither_to_web_palette(rgb_img)
dithered_pixels = dithered_img.load() # must do it again
for h in range(height): # restore original RGBA for transparent pixels
for w in range(width):
if (orig_pixels[w, h])[3] != 255:
dithered_pixels[w, h] = orig_pixels[w, h] # bashing in a new value changes it!
return dithered_img
def img2str(memePath):
imgname = memePath
maxLen = 100
clr = None
fontSize = 7
bgcolor = None
antialias = None
dither = None
target_aspect_ratio = .8
try:
maxLen = float(maxLen)
except:
maxLen = 100.0 # default maxlen: 100px
try:
fontSize = int(fontSize)
except:
fontSize = 7
try:
# add fully opaque alpha value (255)
bgcolor = HTMLColorToRGB(bgcolor) + (255, )
except:
bgcolor = None
try:
target_aspect_ratio = float(target_aspect_ratio)
except:
target_aspect_ratio = 1.0 # default target_aspect_ratio: 1.0
try:
img = load_and_resize_image(imgname, antialias, maxLen, target_aspect_ratio)
except IOError:
exit("File not found: " + imgname)
# Dither _after_ resizing
if dither:
img = dither_image_to_web_palette(img, bgcolor)
# get pixels
pixel = img.load()
width, height = img.size
if clr:
# TODO - should handle bgcolor - probably by setting it as BG on
# the CSS for the pre
string = generate_HTML_for_image(pixel, width, height)
else:
string = generate_grayscale_for_image(
pixel, width, height, bgcolor)
# wrap with html
template = """<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css" media="all">
pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
font-family: 'Menlo', 'Courier New', 'Consola';
line-height: 1.0;
font-size: %dpx;
}
</style>
</head>
<body>
<pre>%s</pre>
</body>
</html>
"""
return string
sys.stdout.flush()

BIN
modules/img2txt.pyc Normal file

Binary file not shown.

51
modules/maketxt.py Normal file
View File

@ -0,0 +1,51 @@
from PIL import Image
import requests
from io import BytesIO
ASCII_CHARS = [ '#', '?', '%', '.', 'S', '+', '.', '*', ':', ',', '@']
def scale_image(image, new_width=100):
"""Resizes an image preserving the aspect ratio.
"""
(original_width, original_height) = image.size
aspect_ratio = original_height/float(original_width)
new_height = int(aspect_ratio * new_width)
new_image = image.resize((new_width, new_height))
return new_image
def convert_to_grayscale(image):
return image.convert('L')
def map_pixels_to_ascii_chars(image, range_width=25):
"""Maps each pixel to an ascii char based on the range
in which it lies.
0-255 is divided into 11 ranges of 25 pixels each.
"""
pixels_in_image = list(image.getdata())
pixels_to_chars = [ASCII_CHARS[pixel_value/range_width] for pixel_value in
pixels_in_image]
return "".join(pixels_to_chars)
def convert_image_to_ascii(image, new_width=100):
image = scale_image(image)
image = convert_to_grayscale(image)
pixels_to_chars = map_pixels_to_ascii_chars(image)
len_pixels_to_chars = len(pixels_to_chars)
image_ascii = [pixels_to_chars[index: index + new_width] for index in
xrange(0, len_pixels_to_chars, new_width)]
return "\n".join(image_ascii)
def handle_image_conversion(image_filepath):
response = requests.get(image_filepath)
image = Image.open(BytesIO(response.content))
image_ascii = convert_image_to_ascii(image)
return(image_ascii)

35
modules/meme.py Normal file
View File

@ -0,0 +1,35 @@
import sopel.module
import json, random, sys, os
sys.path.append(os.getcwd())
from img2txt import *
import urllib.request
@sopel.module.commands('meme')
def meme(bot, trigger):
user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
url = "https://api.imgflip.com/get_memes"
headers={'User-Agent':user_agent,}
request=urllib.request.Request(url,None,headers)
with urllib.request.urlopen(request) as response, open('data.json', 'wb') as out_file:
data = response.read()
out_file.write(data)
with open('data.json') as data_file:
jsonResponse = json.load(data_file)
jsonList = jsonResponse["data"]
memeList = jsonList["memes"]
memeData = random.choice(memeList)
memeURL = memeData.get("url")
print(memeURL)
request=urllib.request.Request(memeURL,None,headers)
with urllib.request.urlopen(request) as response, open('image.jpg', 'wb') as out_file:
data = response.read()
out_file.write(data)
picStr = img2str('image.jpg')
strList = picStr.split('\n')
for i in strList:
bot.say(i)

18
modules/trump.py Normal file
View File

@ -0,0 +1,18 @@
import tweepy, random
import sopel.module
@sopel.module.commands('trump')
def trump(bot, trigger):
consumer_key = "R3RIRZ9B6UxhdaHqYRPujbOBo"
consumer_secret = "OXmfGjuINfGuGy0pPHlp0xIhPirRHO84I0J9ipGGh3F2UAx2gI"
access_token = "553052831-cW2ph0YocqPeLGp9BOhoaShfUAp4gbsg1VAwOO2H"
access_token_secret = "eAVMCB7P9WSIDk3j2UCqSSb0SVlELnGSkssJsTElfwCkL"
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
tweets = api.user_timeline(screen_name = 'realDonaldTrump', count = 20, include_rts = False)
tweet = random.choice(tweets)
bot.say(tweet.text)