diff --git a/Datapoint/datapoint.py b/Datapoint/datapoint.py new file mode 100644 index 0000000..33242d3 --- /dev/null +++ b/Datapoint/datapoint.py @@ -0,0 +1,125 @@ +import tkinter + +class DataPoint: + def __init__(self, width=720, height=480): + self.windowtitle = 'DataPoint' + + self.t = tkinter.Tk() + self.t.title(self.windowtitle) + self.w = width + self.h = height + self.screenwidth = self.t.winfo_screenwidth() + self.screenheight = self.t.winfo_screenheight() + self.windowwidth = self.w + self.windowheight = self.h + self.windowx = (self.screenwidth-self.windowwidth) / 2 + self.windowy = ((self.screenheight-self.windowheight) / 2) - 27 + self.geometrystring = '%dx%d+%d+%d' % (self.windowwidth, self.windowheight, self.windowx, self.windowy) + self.t.geometry(self.geometrystring) + + self.reset_attributes() + + self.margin = 0.10 + self.c = tkinter.Canvas(self.t) + self.c.pack(fill='both', expand=True) + + self.clear() + + def mainloop(self): + self.t.mainloop() + + def reset_attributes(self): + ''' + Set the DataPoint's grid attributes back to None + so that they will be recalculated during the next plot + ''' + self.lowestx = None + self.highestx = None + self.lowesty = None + self.highesty = None + self.spanx = None + self.spany = None + self.marginx = None + self.marginy = None + self.drawablew = None + self.drawableh = None + + def clear(self): + self.c.delete('all') + + def meow(self): + return 'meow.' + + def function(self, x): + x -= 50 + x *= 0.1 + y = 1 / (1 + (2.718 ** -x)) + return y + + def verifypoints(self, points): + for item in points: + if len(item) != 2: + raise Exception('%s Incorrect number of values for coordinate. Use help(plotpoints)' % str(item)) + for subitem in item: + try: + int(subitem) + except ValueError as e: + if not e.args: + e.args = ('',) + e.args += ('Invalid format. Use help(plotpoints',) + raise + + def plotpoints(self, points, pointdiameter=4, fill='#000'): + ''' + Plot points onto the canvas + var points = list, where each element is a 2-length list, where [0] is x and [1] is y coordinate + var pointdiameter = int for how wide the plotted point should be, in pixels + ''' + self.verifypoints(points) + + if self.lowestx is None: + xs = [point[0] for point in points] + ys = [point[1] for point in points] + self.lowestx = min(xs) + self.highestx = max(xs) + self.lowesty = min(ys) + self.highesty = max(ys) + del xs + del ys + + self.spanx = abs(self.highestx - self.lowestx) + self.spany = abs(self.highesty - self.lowesty) + if self.spanx == 0: + self.spanx = 1 + if self.spany == 0: + self.spany = 1 + + self.marginx = self.w * self.margin + self.marginy = self.h * self.margin + self.drawablew = self.w - (2 * self.marginx) + self.drawableh = self.h - (2 * self.marginy) + + for point in points: + # Get percentage of the span + x = ((point[0]) - self.lowestx) / self.spanx + y = ((point[1]) - self.lowesty) / self.spany + # Flip y + y = 1 - y + # Use the percentage to get a location on the board + x *= self.drawablew + y *= self.drawableh + # Put into center + x += self.marginx + y += self.marginy + + r = pointdiameter / 2 + self.c.create_oval(x-r, y-r, x+r, y+r, fill=fill) + self.c.update() + #print(point, x, y) + +if __name__ == '__main__': + dp = DataPoint() + points = list(range(100)) + points = [[p, dp.function(p)] for p in points] + dp.plotpoints(points) + dp.mainloop() \ No newline at end of file diff --git a/HerokuBot/Procfile b/HerokuBot/Procfile new file mode 100644 index 0000000..ffcf86c --- /dev/null +++ b/HerokuBot/Procfile @@ -0,0 +1,2 @@ +# Procfile +worker: python herokubot.py \ No newline at end of file diff --git a/HerokuBot/README.md b/HerokuBot/README.md new file mode 100644 index 0000000..0fefca7 --- /dev/null +++ b/HerokuBot/README.md @@ -0,0 +1,75 @@ +Using Heroku to run a bot +============= + +[Thank you /u/cmd-t for helping me to finally understand this](http://www.reddit.com/r/botwatch/comments/34dpku/can_someone_write_a_complete_idiots_guide_to/cqts1tr) + +Inside git.zip is the .git repo that I created for this. I had to zip it so that I can push it here. + +1. Create a [Heroku account](http://heroku.com) +2. Install [Heroku toolbelt](https://toolbelt.heroku.com/) +3. Install [Git](http://git-scm.com/) +4. Create a folder to keep your repo +5. Write your bot +6. Create requirements.txt, and require a version of praw +7. Create runtime.txt, and require a version of Python +8. Create Procfile, and create a worker that will launch your bot. +9. `> heroku login` +10. `> git init` +11. `> git add .` +12. `> git commit -m "1"` +13. `> heroku create` + + Creating aqueous-plains-9797... done, stack is cedar-14 + https://aqueous-plains-9797.herokuapp.com/ | https://git.heroku.com/aqueous-plains-9797.git + Git remote heroku added +14. `> git push heroku master` + + Counting objects: 10, done. + Delta compression using up to 4 threads. + Compressing objects: 100% (7/7), done. + Writing objects: 100% (10/10), 1.06 KiB, done. + Total 10 (delta 1), reused 0 (delta 0) + remote: Compressing source files... done. + remote: Building source: + remote: + remote: -----> Python app detected + remote: -----> Installing runtime (python-3.4.2) + remote: -----> Installing dependencies with pip + remote: Collecting praw>=2.1.21 (from -r requirements.txt (line 1)) + remote: Downloading praw-2.1.21-py2.py3-none-any.whl (75kB) + remote: Collecting requests>=2.3.0 (from praw>=2.1.21->-r requirements.txt (line 1)) + remote: Downloading requests-2.6.2-py2.py3-none-any.whl (470kB) + remote: Collecting update-checker>=0.11 (from praw>=2.1.21->-r requirements.txt (line 1)) + remote: Downloading update_checker-0.11-py2.py3-none-any.whl + remote: Collecting six>=1.4 (from praw>=2.1.21->-r requirements.txt (line 1)) + remote: Downloading six-1.9.0-py2.py3-none-any.whl + remote: Installing collected packages: six, update-checker, requests, praw + remote: + remote: + remote: + remote: + remote: Successfully installed praw-2.1.21 requests-2.6.2 six-1.9.0 update-checker-0.11 + remote: + remote: -----> Discovering process types + remote: Procfile declares types -> worker + remote: + remote: -----> Compressing... done, 38.3MB + remote: -----> Launching... done, v3 + remote: https://aqueous-plains-9797.herokuapp.com/ deployed to Heroku + remote: + remote: Verifying deploy... done. + To https://git.heroku.com/aqueous-plains-9797.git + * [new branch] master -> master +15. `> heroku ps:scale worker=1` + + Scaling dynos... done, now running worker at 1:1X. +16. `> heroku logs > logs.txt` + + 2015-05-01T00:32:38.691805+00:00 app[worker.1]: Logging in. + 2015-05-01T00:32:41.396117+00:00 app[worker.1]: Getting subreddit info. + 2015-05-01T00:32:41.397202+00:00 app[worker.1]: /r/Goldtesting + 2015-05-01T00:32:45.316887+00:00 app[worker.1]: Created at: 1400997940 + 2015-05-01T00:32:45.316897+00:00 app[worker.1]: Subscribers: 17 + 2015-05-01T00:32:45.316900+00:00 app[worker.1]: All done! + +17. Celebrate \ No newline at end of file diff --git a/HerokuBot/git.zip b/HerokuBot/git.zip new file mode 100644 index 0000000..36a5d7a Binary files /dev/null and b/HerokuBot/git.zip differ diff --git a/HerokuBot/herokubot.py b/HerokuBot/herokubot.py new file mode 100644 index 0000000..5f357ac --- /dev/null +++ b/HerokuBot/herokubot.py @@ -0,0 +1,16 @@ +import praw +import time + +print('Logging in.') +r = praw.Reddit('Testing praw api usage over Heroku') +r.login('qQGusVuAHezHxhYTiYGm', 'qQGusVuAHezHxhYTiYGm') + +print('Getting subreddit info.') +sub = r.get_subreddit('Goldtesting') +print('/r/Goldtesting') +print('\tCreated at: %d' % sub.created_utc) +print('\tSubscribers: %d' % sub.subscribers) + +print('All done!') +while True: + time.sleep(60) \ No newline at end of file diff --git a/HerokuBot/requirements.txt b/HerokuBot/requirements.txt new file mode 100644 index 0000000..47c4aa5 --- /dev/null +++ b/HerokuBot/requirements.txt @@ -0,0 +1 @@ +praw >= 2.1.21 \ No newline at end of file diff --git a/HerokuBot/runtime.txt b/HerokuBot/runtime.txt new file mode 100644 index 0000000..1dc44e8 --- /dev/null +++ b/HerokuBot/runtime.txt @@ -0,0 +1 @@ +python-3.4.2 \ No newline at end of file diff --git a/Logogame/images/kagenui.png b/Logogame/images/kagenui.png deleted file mode 100644 index eb69b62..0000000 Binary files a/Logogame/images/kagenui.png and /dev/null differ diff --git a/Logogame/logos.py b/Logogame/logos.py deleted file mode 100644 index b28b669..0000000 --- a/Logogame/logos.py +++ /dev/null @@ -1,381 +0,0 @@ -import os -import tkinter -import sqlite3 -import hashlib -import string -from PIL import Image -from PIL import ImageTk - -class Generic: - def __init__(self): - pass - def set_dict_attributes(self, attributes): - for attribute in attributes: - setattr(self, attribute, attributes[attribute]) - -class LogoGame: - def __init__(self): - self.WINDOWS_BADCHARS = '\\/?:*"><|' - self.t = tkinter.Tk() - self.t.title('Logogame') - if not os.path.exists('logos.db'): - print('You\'re missing the game\'s logo database!') - print('Cannot proceed!') - quit() - - self.font_main = ('Consolas', 12) - self.font_small = ('Consolas', 8) - self.color_blue = '#0ed' - self.color_green = '#31f13a' - self.color_red = '#e23939' - - self.logos_per_row = 6 - self.logo_padx = 10 - self.logo_pady = 10 - - self.dbindex_id = 0 - self.dbindex_name = 1 - self.dbindex_solutions = 2 - self.dbindex_images = 3 - self.dbindex_tag = 4 - - self.sql = sqlite3.connect('logos.db') - self.cur = self.sql.cursor() - self.stats_main = self.stats_load('stats') - self.playerstats_load(self.stats_main.playername) - - self.tkinter_elements = [] - self.logo_elements = [] - self.tag_elements = [] - self.active_tags = set() - self.all_tags = [] - self.all_logos = [] - self.logos_load() - - self.w = 1062 - self.h = 600 - self.screenwidth = self.t.winfo_screenwidth() - self.screenheight = self.t.winfo_screenheight() - self.windowwidth = self.w - self.windowheight = self.h - self.windowx = (self.screenwidth-self.windowwidth) / 2 - self.windowy = ((self.screenheight-self.windowheight) / 2) - 27 - self.geometrystring = '%dx%d+%d+%d' % (self.windowwidth, self.windowheight, self.windowx, self.windowy) - self.t.geometry(self.geometrystring) - - - #self.t.bind('', self.update_wh) - - def start(self): - self.gui_build_main() - self.t.mainloop() - - def logos_load(self): - self.all_logos = [] - self.cur.execute('SELECT * FROM logos') - fetch = self.cur.fetchall() - for item in fetch: - logo = Generic() - logo.id = item[self.dbindex_id] - logo.images = item[self.dbindex_images].split(',') - logo.name = item[self.dbindex_name] - logo.solutions = item[self.dbindex_solutions].split(',') - logo.tags = item[self.dbindex_tag].split(',') - logo.solved = self.playerstats_hassolved(logo.id) - self.all_logos.append(logo) - self.all_tags = self.get_all_tags() - self.all_tags.append('Completed') - - def destroy_all_elements(self): - self.tag_elements = [] - self.destroy_all_logos() - while len(self.tkinter_elements) > 0: - self.tkinter_elements[0].destroy() - del self.tkinter_elements[0] - - def destroy_all_logos(self): - while len(self.logo_elements) > 0: - self.logo_elements[0].destroy() - del self.logo_elements[0] - - def gui_build_main(self, *b): - self.destroy_all_elements() - ### - self.frame_mainmenu = tkinter.Frame(self.t) - self.frame_mainmenu.pack(expand=True, anchor='center') - self.tkinter_elements.append(self.frame_mainmenu) - # - self.button_playgame = tkinter.Button( - self.frame_mainmenu, - text='Play', - #relief='flat', - font=self.font_main, - bg=self.color_green, - activebackground=self.color_green, - command=self.gui_build_game) - self.button_playgame.grid(row=10, column=5) - self.tkinter_elements.append(self.button_playgame) - # - self.label_playername = tkinter.Label( - self.frame_mainmenu, - text='Player name: ', - font=self.font_main) - self.label_playername.grid(row=30, column=4) - self.tkinter_elements.append(self.label_playername) - # - self.entry_playername = tkinter.Entry( - self.frame_mainmenu, - font=self.font_main, - relief='solid', - width=30) - self.entry_playername.bind('', lambda x: self.playername_set(self.entry_playername.get())) - self.entry_playername.insert(0, self.stats_main.playername) - self.entry_playername.grid(row=30, column=5) - self.tkinter_elements.append(self.entry_playername) - # - self.button_playername = tkinter.Button( - self.frame_mainmenu, - text='Set', - font=self.font_small, - #relief='flat', - bg=self.color_blue, - activebackground=self.color_blue, - command=lambda: self.playername_set(self.entry_playername.get())) - self.button_playername.grid(row=30, column=6) - self.tkinter_elements.append(self.button_playername) - # - self.label_playerhash = tkinter.Label( - self.frame_mainmenu, - text=self.sha8(self.stats_main.playername), - font=self.font_main) - self.label_playerhash.grid(row=30, column=7) - self.tkinter_elements.append(self.label_playerhash) - ### - - def gui_build_game(self, *b): - self.destroy_all_elements() - ### - self.frame_gametoolbar = tkinter.Frame(self.t) - self.frame_gametoolbar.pack(fill='x', anchor='n') - self.tkinter_elements.append(self.frame_gametoolbar) - # - self.button_back = tkinter.Button( - self.frame_gametoolbar, - text='X', - font=self.font_main, - bg=self.color_red, - activebackground=self.color_red, - command=self.gui_build_main) - self.button_back.grid(row=0, column=0) - self.tkinter_elements.append(self.button_back) - # - #self.frame_gamearea = tkinter.Frame(self.t, bg='#f00') - #self.frame_gamearea.pack(expand=True, fill='both', anchor='w') - # - self.frame_posttoolbar = tkinter.Frame(self.t) - self.frame_posttoolbar.pack(expand=True, fill='both') - self.tkinter_elements.append(self.frame_posttoolbar) - # - self.frame_gametaglist = tkinter.Frame(self.frame_posttoolbar) - self.frame_gametaglist.pack(expand=True, fill='y', side='left', anchor='w') - self.tkinter_elements.append(self.frame_gametaglist) - # - self.frame_logoarea = tkinter.Frame(self.frame_posttoolbar) - self.frame_logoarea.pack(expand=True, fill='both', anchor='e') - self.tkinter_elements.append(self.frame_logoarea) - # - button_applytag = tkinter.Button(self.frame_gametaglist, text='Apply', command=self.gui_rebuild_game) - button_applytag.grid(row=0, column=0, sticky='w') - # - for i in range(len(self.all_tags)): - tag = self.all_tags[i] - intvar = tkinter.IntVar() - intvar.tag=tag - checkbox = tkinter.Checkbutton(self.frame_gametaglist, text=tag, variable=intvar) - checkbox.intvar = intvar - checkbox.grid(row=i+1, column=0, sticky='w') - intvar.set(1) - self.tkinter_elements.append(checkbox) - self.tag_elements.append(checkbox) - self.active_tags.add(tag) - - self.gui_rebuild_game() - - ### - - def gui_rebuild_game(self, *b): - self.destroy_all_logos() - w = self.t.winfo_width() - h = self.t.winfo_height() - resizemeter = w / 9 - row = 0 - col = 0 - for element in self.tag_elements: - if element.intvar.get() == 1: - self.active_tags.add(element.intvar.tag) - elif element.intvar.tag in self.active_tags: - self.active_tags.remove(element.intvar.tag) - - for logo in self.all_logos: - if not any(tag in self.active_tags for tag in logo.tags): - continue - if logo.solved is True and 'Completed' not in self.active_tags: - continue - logoframe = tkinter.Frame(self.frame_logoarea) - logoframe.pack_propagate(0) - self.logo_elements.append(logoframe) - imageframe = tkinter.Frame(logoframe, width=resizemeter, height=resizemeter) - imageframe.pack_propagate(0) - imageframe.grid(row=0, column=0, sticky='n') - label_image = tkinter.Label(imageframe) - label_image.pack(anchor='center', expand=True, fill='both') - label_name = tkinter.Label(logoframe) - entry_name = tkinter.Entry(logoframe) - if logo.solved is True: - i = self.png_load(logo.images[-1], resizemeter) - label_image.configure(image=i) - label_image.i = i - label_name.configure(text=logo.name) - label_name.grid(row=1, column=0, sticky='s') - else: - i = self.png_load(logo.images[0], resizemeter) - label_image.configure(image=i) - label_image.i = i - entry_name.grid(row=1, column=0, sticky='s') - self.tkinter_elements.append(logoframe) - logoframe.id = logo.id - logoframe.entry_name = entry_name - logoframe.label_name = label_name - logoframe.label_image = label_image - logoframe.grid(row=row, column=col, padx=self.logo_padx, pady=self.logo_pady) - col += 1 - col = col % self.logos_per_row - if col == 0: - row += 1 - - - def gui_build_logo(self, *b): - self.destroy_all_elements() - ### - - def playername_set(self, newname): - if newname == '': - return - if newname != self.stats_main.playername: - self.cur.execute('UPDATE stats SET value=? WHERE key="playername"', [newname]) - self.sql.commit() - playerhash = self.playerstats_load(newname) - self.stats_main.playername = newname - - if self.label_playerhash: - self.label_playerhash.configure(text=playerhash) - for logo in self.all_logos: - logo.solved = self.playerstats_hassolved(logo.id) - print('Name: ' + self.stats_main.playername) - self.clean_empty_dbs() - - def sha8(self, text): - sha = hashlib.sha256() - sha.update(text.encode('utf-8')) - sha = sha.hexdigest() - return sha[:8] - - def png_load(self, filename, resize=None): - if filename[-4:] != '.png': - filename = filename + '.png' - filename = 'images/' + filename - i = Image.open(filename) - if resize: - ratio = resize / max(i.size) - newx = int(i.size[0] * ratio) - newy = int(i.size[1] * ratio) - i = i.resize([newx, newy], resample=Image.ANTIALIAS) - i = ImageTk.PhotoImage(i) - return i - - def stats_load(self, database): - if database == 'stats': - self.cur.execute('SELECT * FROM stats') - fetchall = self.cur.fetchall() - if database == 'player': - self.cur_player.execute('SELECT * FROM stats') - fetchall = self.cur_player.fetchall() - keyvals = {} - for fetched in fetchall: - keyvals[fetched[0]] = fetched[1] - stats = Generic() - stats.set_dict_attributes(keyvals) - return stats - - def playerstats_load(self, playername, presha=False): - if not presha: - sha = self.sha8(playername) - else: - sha = playername - filename = self.strip_to_filename(playername) + '_' + sha - self.sql_player = sqlite3.connect('playerdata/%s.db' % filename) - self.cur_player = self.sql_player.cursor() - self.cur_player.execute('CREATE TABLE IF NOT EXISTS stats(key TEXT, value TEXT)') - self.sql_player.commit() - return sha - - def playerstats_set(self, key, value): - self.cur_player.execute('SELECT * FROM stats WHERE key=?', [key]) - if cur.fetchone(): - self.cur_player.execute('UPDATE stats SET value=? WHERE key=?', [value, key]) - else: - self.cur_player.execute('INSERT INTO stats VALUES(?, ?)', [key, value]) - self.sql_player.commit() - - def playerstats_get(self, key): - self.cur_player.execute('SELECT * FROM stats WHERE key=?', [key]) - f = self.cur_player.fetchone() - if f: - return f[1] - return None - - def playerstats_hassolved(self, logoid): - key = 'hassolved_%d' % logoid - val = self.playerstats_get(key) - if val is None: - return False - return True - - def strip_to_filename(self, s): - for badchar in self.WINDOWS_BADCHARS: - s = s.replace(badchar, '') - return s - - def get_all_tags(self): - self.cur.execute('SELECT * FROM logos') - fetch = self.cur.fetchall() - alltags = [] - for item in fetch: - itemtags = item[self.dbindex_tag] - itemtags = itemtags.replace(', ', ',') - itemtags = itemtags.split(',') - alltags += itemtags - alltags = list(set(alltags)) - alltags.sort() - return alltags - - def clean_empty_dbs(self): - ls = os.listdir('playerdata') - todelete = [] - for name in ls: - name = 'playerdata/'+name - s = sqlite3.connect(name) - c = s.cursor() - c.execute('SELECT * FROM stats') - if not c.fetchone(): - del c - del s - try: - os.remove(name) - except PermissionError: - pass - - -if __name__ == '__main__': - logogame = LogoGame() - logogame.start() \ No newline at end of file diff --git a/TKdraw/tkdraw.py b/TKdraw/tkdraw.py new file mode 100644 index 0000000..4648ab8 --- /dev/null +++ b/TKdraw/tkdraw.py @@ -0,0 +1,59 @@ +import tkinter + +class TKDraw(): + def __init__(self): + self.windowtitle = 'Tkdraw' + + self.ismousedown = False + self.minwidth = 1 + self.maxwidth = 5 + + self.t = tkinter.Tk() + self.t.title(self.windowtitle) + self.w = 450 + self.h = 350 + self.screenwidth = self.t.winfo_screenwidth() + self.screenheight = self.t.winfo_screenheight() + self.windowwidth = self.w + self.windowheight = self.h + self.windowx = (self.screenwidth-self.windowwidth) / 2 + self.windowy = ((self.screenheight-self.windowheight) / 2) - 27 + self.geometrystring = '%dx%d+%d+%d' % (self.windowwidth, self.windowheight, self.windowx, self.windowy) + self.t.geometry(self.geometrystring) + + self.canvas = tkinter.Canvas(self.t, bg='#000') + self.canvas.pack(expand=True, fill='both') + #print(help(self.canvas.bind)) + self.canvas.bind('', self.mousedown) + self.canvas.bind('', self.mouseup) + self.canvas.bind('', self.mousedraw) + self.prevx = None + self.prevy = None + + def mainloop(self): + self.t.mainloop() + + def mousedown(self, *b): + self.ismousedown = True + + def mouseup(self, *b): + self.ismousedown = False + self.prevx = None + self.prevy = None + + def mousedraw(self, event): + if self.ismousedown is False: + return + x = event.x + y = event.y + if self.prevx is not None: + distance = ((self.prevx - x)**2) + ((self.prevy - y) ** 2) + distance = distance ** 0.5 + distance = max(self.minwidth, distance) + distance = min(self.maxwidth, distance) + self.canvas.create_line(self.prevx, self.prevy, x, y, width=distance, fill='#fff') + self.prevx = x + self.prevy = y + +tkd = TKDraw() +tkd.mainloop() \ No newline at end of file