else
Heroku Bot!
This commit is contained in:
parent
4192dfc32c
commit
93b72ca515
10 changed files with 279 additions and 381 deletions
125
Datapoint/datapoint.py
Normal file
125
Datapoint/datapoint.py
Normal file
|
@ -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()
|
2
HerokuBot/Procfile
Normal file
2
HerokuBot/Procfile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Procfile
|
||||||
|
worker: python herokubot.py
|
75
HerokuBot/README.md
Normal file
75
HerokuBot/README.md
Normal file
|
@ -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
|
BIN
HerokuBot/git.zip
Normal file
BIN
HerokuBot/git.zip
Normal file
Binary file not shown.
16
HerokuBot/herokubot.py
Normal file
16
HerokuBot/herokubot.py
Normal file
|
@ -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)
|
1
HerokuBot/requirements.txt
Normal file
1
HerokuBot/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
praw >= 2.1.21
|
1
HerokuBot/runtime.txt
Normal file
1
HerokuBot/runtime.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
python-3.4.2
|
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
|
@ -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('<Configure>', 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('<Return>', 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()
|
|
59
TKdraw/tkdraw.py
Normal file
59
TKdraw/tkdraw.py
Normal file
|
@ -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('<ButtonPress>', self.mousedown)
|
||||||
|
self.canvas.bind('<ButtonRelease>', self.mouseup)
|
||||||
|
self.canvas.bind('<Motion>', 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()
|
Loading…
Reference in a new issue