This repository has been archived by the owner on Apr 20, 2019. It is now read-only.
/
rainbodl.py
206 lines (170 loc) · 6.37 KB
/
rainbodl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import argparse
import os
import random
import stat
import sys
import tempfile
import tweepy
import yaml
from PIL import Image, ImageColor
import ffz
class ConfNotValid(Exception):
pass
def get_conf():
try:
with open(conf_file, 'r') as f:
return yaml.safe_load(f)
except Exception:
return {}
def set_conf(module, conf):
try:
with open(conf_file, 'a+') as f:
f.seek(0)
orig_conf = yaml.safe_load(f)
if not orig_conf:
orig_conf = {}
orig_conf[module] = conf
f.seek(0)
f.truncate()
yaml.dump(orig_conf, f, default_flow_style=False, default_style='"')
except Exception as e:
print(e)
def auth_dance():
try:
conf = expect_conf("twitter", {"consumer_key": None, "consumer_secret": None})
except ConfNotValid:
print("Please fill in your API key and secret in %s" % (conf_file,), file=sys.stderr)
exit(1)
auth = tweepy.OAuthHandler(conf['consumer_key'], conf['consumer_secret'])
url = auth.get_authorization_url()
print("Please go to %s and accept, then paste the authorization code here." % url)
code = input("Authorization code:")
try:
auth.get_access_token(code)
conf['access_token'] = auth.access_token
conf['access_token_secret'] = auth.access_token_secret
set_conf('twitter', conf)
return conf
except tweepy.TweepError:
print("Something went awry. Try again soon.")
exit(2)
def expect_conf(module, values):
conf = get_conf()
valid = True
if module not in conf:
valid = False
conf[module] = dict()
for key in values:
if key not in conf[module] or conf[module][key] == "FILL ME IN":
if values[key] != None:
conf[module][key] = values[key]
else:
valid = False
conf[module][key] = "FILL ME IN"
if not valid:
set_conf(module, conf[module])
raise ConfNotValid()
else:
return conf[module]
def rgb_tuple_to_hex(color):
return '#%02X%02X%02X' % color
def rainbodl(api):
try:
conf = expect_conf("rainbodl", {"path": None, "change_profile_color": True})
except ConfNotValid:
print("Please fill in the location of the image(s) in %s" % (conf_file,), file=sys.stderr)
exit(1)
sourcefile = os.path.expanduser(conf['path'])
if(stat.S_ISDIR(os.stat(sourcefile).st_mode)):
sourcefile += os.sep + random.choice(os.listdir(sourcefile))
_, filename = tempfile.mkstemp(suffix='.png')
im = Image.open(sourcefile)
im = im.convert(mode="RGBA")
size = im.size
hue = random.randint(0, 360);
avcolor = ImageColor.getrgb("hsl(%s,100%%,70%%)" % (hue,))
linkcolor = ImageColor.getrgb("hsl(%s,100%%,40%%)" % (hue,))
background = Image.new("RGBA", size, avcolor)
final = Image.alpha_composite(background, im)
final.save(filename)
set_avatar(api, filename)
if conf['change_profile_color']:
api.update_profile(profile_link_color=rgb_tuple_to_hex(linkcolor))
os.unlink(filename)
def set_avatar(api, filename):
api.update_profile_image(filename)
def post_image(api):
try:
conf = expect_conf("post_image", {"directory": None, "message": ""})
except ConfNotValid:
print("Please fill in the location of the image directory in %s" % (conf_file,), file=sys.stderr)
exit(1)
files = os.listdir(conf["directory"])
filename = conf["directory"] + os.sep + random.choice(files)
try:
media = api.media_upload(filename);
api.update_status(media_ids=[media.media_id,], status=conf["message"]);
except tweepy.TweepError as e:
print(e.with_traceback())
exit(1)
def post_status(api):
try:
conf = expect_conf("post_status", {"path": None, "separator": "\n"})
except ConfNotValid:
print("Please fill in the location of the tweet list in %s" % (conf_file,), file=sys.stderr)
exit(1)
with open(conf['path'], 'r') as f:
statuses = f.read().split(conf['separator'])
# filter out any empty lines
statuses = [status for status in statuses if status != ""]
status = random.choice(statuses)
if status[0] == '|':
try:
os.chdir(os.path.dirname(conf['path']))
media = api.media_upload(status[1:]);
api.update_status(media_ids=[media.media_id,]);
except tweepy.TweepError as e:
print(e.with_traceback())
exit(1)
else:
api.update_status(status=status)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.set_defaults(command='help')
parser.add_argument('-c', '--config', help="set the config file path", default="~/.rainbodl")
command = parser.add_subparsers(help='command to run', dest='command')
command.add_parser('auth', help='test twitter credentials')
command.add_parser('rainbodl',
help='set avatar to specified image or random image from specified directory, overlaid on a random solid color')
command.add_parser('post-image', help='post a random image from directory')
command.add_parser('post-status', help='post a random status from file')
command.add_parser('post-ffz', help='post an ffz, see @ffz_png')
parser_set_avatar = command.add_parser('set-avatar',
help='set avatar to file passed on the command line')
parser_set_avatar.add_argument('file')
args = parser.parse_args()
global conf_file
conf_file = os.path.expanduser(args.config)
try:
conf = expect_conf("twitter", {'access_token': None, 'access_token_secret': None})
except ConfNotValid:
conf = auth_dance()
auth = tweepy.OAuthHandler(conf['consumer_key'], conf['consumer_secret'])
auth.set_access_token(conf['access_token'], conf['access_token_secret'])
api = tweepy.API(auth)
if args.command == 'rainbodl':
rainbodl(api)
elif args.command == 'post-image':
post_image(api)
elif args.command == 'post-status':
post_status(api)
elif args.command == 'post-ffz':
ffz.tweet(api)
elif args.command == 'set-avatar':
set_avatar(api, args.file)
elif args.command == 'auth':
u = api.verify_credentials()
if u:
print("Successfully authed as @%s (%s)" % (u.screen_name, u.id_str))
else:
parser.print_help()