diff --git a/.gitignore b/.gitignore index 58bcbf8..9112c56 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +Classifieds/ + # Windows image file caches Thumbs.db ehthumbs.db diff --git a/Dodgy/dodgy.py b/Dodgy/dodgy.py index ce16650..2027ab7 100644 --- a/Dodgy/dodgy.py +++ b/Dodgy/dodgy.py @@ -8,7 +8,7 @@ class dodgygame: def __init__(self): tkvar = Tk() tkvar.resizable(0,0) - tkvar.wm_title("Dodgy") + tkvar.wm_title('Dodgy') tkvar.iconbitmap('Excl.ico') arenasize = 40 diff --git a/Editor/README.md b/Editor/README.md new file mode 100644 index 0000000..97cc1d4 --- /dev/null +++ b/Editor/README.md @@ -0,0 +1,6 @@ +Editor +========== + +A neat idea that I would one day like to make into a website or something. Users read and write text files simply by choosing the file name. If it exists, the text is returned to them for editing. If it does not, it will be created when they press Save. No logins and no file security. Since it's using a database instead of actual txt files, there are no filename character restrictions, only a maximum title length for sanity's sake. + +For now, it's just a tkinter toy. \ No newline at end of file diff --git a/Editor/editor.py b/Editor/editor.py new file mode 100644 index 0000000..92a2e54 --- /dev/null +++ b/Editor/editor.py @@ -0,0 +1,200 @@ +import tkinter +import sqlite3 +import hashlib +import random + +class Editor: + def __init__(self): + self.WINDOWS_BADCHARS = '\\/?:*"><|' + + self.sql = sqlite3.connect('textfiles.db') + self.cur = self.sql.cursor() + self.cur.execute('CREATE TABLE IF NOT EXISTS textfiles(id TEXT, filename TEXT, filetext TEXT)') + self.cur.execute('CREATE INDEX IF NOT EXISTS textfilesindex ON textfiles(id)') + self.sql.commit() + + self.font_large = ("Consolas", 16) + self.font_med = ("Consolas", 12) + self.font_small = ("Consolas", 10) + + self.kilobyte = 1024 + self.megabyte = 1048576 + self.maximum_characters = 1*self.megabyte + self.maximum_title = 64 + + self.t = tkinter.Tk() + 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.entities = [] + self.filename = None + self.gui_build_fileloader() + + self.t.mainloop() + + def annihilate(self): + for x in self.entities: + try: + x.grid_forget() + x.pack_forget() + except: + pass + x.destroy() + + def gui_build_fileloader(self, *b): + self.annihilate() + + self.frame_fileloader = tkinter.Frame(self.t) + self.entities.append(self.frame_fileloader) + self.entry_filename = tkinter.Entry(self.frame_fileloader, font=self.font_large, justify='right') + self.entry_filename.grid(row=0, column=0, columnspan=3) + self.entry_filename.focus_set() + self.entry_filename.bind("", self.loadfile_smart) + self.entities.append(self.entry_filename) + self.label_filename = tkinter.Label(self.frame_fileloader, font=self.font_large, text='.txt') + self.label_filename.grid(row=0, column=3) + self.entities.append(self.label_filename) + self.button_fileloader = tkinter.Button(self.frame_fileloader, font=self.font_large, text='Load', command=self.loadfile_smart) + self.button_fileloader.grid(row=1, column=1, pady=10) + self.entities.append(self.button_fileloader) + width = self.t.winfo_width() + height = self.t.winfo_height() + if min([width, height]) < 20: + width = self.w + height = self.h + #self.frame_fileloader.pack(expand=True, fill='both', anchor='center') + self.frame_fileloader.place(x=width/2, y=(height/2)-10, anchor='center') + + def gui_build_editor(self, filetext, *b): + self.annihilate() + + self.frame_toolbar = tkinter.Frame(self.t) + self.frame_toolbar.pack() + self.entities.append(self.frame_toolbar) + self.button_back = tkinter.Button(self.frame_toolbar, text='back', command=self.gui_build_fileloader, font=self.font_small) + self.button_back.grid(row=0, column=0) + self.entities.append(self.button_back) + self.label_filename = tkinter.Label(self.frame_toolbar, text=self.filename, font=self.font_small) + self.label_filename.grid(row=0, column=1, padx=20) + self.entities.append(self.label_filename) + self.button_save = tkinter.Button(self.frame_toolbar, text='save', command=self.savefile_smart, font=self.font_small) + self.button_save.grid(row=0, column=2) + self.entities.append(self.button_save) + self.label_filesize = tkinter.Label(self.frame_toolbar, text='', font=self.font_small) + self.label_filesize.grid(row=1, column=0, columnspan=10) + self.entities.append(self.label_filesize) + self.text_editor = tkinter.Text(self.t, wrap='word', font=self.font_med) + self.text_editor.insert('end', filetext) + self.text_editor.pack(expand=True, fill='both') + self.text_editor.focus_set() + self.text_editor.bind('', self.savefile_smart) + self.text_editor.bind('', self.gui_build_fileloader) + self.entities.append(self.text_editor) + + def savefile_smart(self, *b): + try: + filetext = self.text_editor.get('0.0', 'end') + self.savefile(self.filename, filetext) + filesize = len(filetext) - 1 + self.label_filesize.configure(text=self.filesizestring(filesize)) + except NameError: + # text editor does not exist for some reason + return + + def savefile(self, filename, filetext): + filetext = filetext[:-1] + # Text widget seems to add \n to the end at all times + # So remove it. + if self.filename is None: + return False + filesize = len(filetext) + namesize = len(filename) + if filesize > self.maximum_characters: + diff = filesize-self.maximum_characters + print('File exceeds maximum character limit. %d / %d (-%d)' % (filesize, self.maximum_characters, diff)) + return False + elif namesize > self.maximum_title: + diff = namesize - self.maximum_title + print('Filename exceeds maximum character limit: %d / %d (-%d)' % (namesize, self.maximum_title, diff)) + return False + + sha = self.sha(filename) + self.cur.execute('SELECT * FROM textfiles WHERE id=?', [sha]) + fetch = self.cur.fetchone() + if filesize == 0: + print('Deleting %s' % filename) + self.cur.execute('DELETE FROM textfiles WHERE id=?', [sha]) + else: + if fetch: + self.cur.execute('UPDATE textfiles SET filename=?, filetext=? WHERE id=?', [filename, filetext, sha]) + else: + self.cur.execute('INSERT INTO textfiles VALUES(?, ?, ?)', [sha, filename, filetext]) + print('Wrote %s: %s' % (filename, self.filesizestring(filesize))) + self.sql.commit() + return True + + def filesizestring(self, filesize): + percentage = "%0.4f" % (100 * filesize / self.maximum_characters) + diff = self.maximum_characters - filesize + out = '%d c, %s%%, +%d' % (filesize, percentage, diff) + return out + + def loadfile_smart(self, *b): + try: + filename = self.entry_filename.get() + except NameError: + # entry_filename does not exist somehow + return + filetext = self.loadfile(filename) + if filetext is not None: + self.gui_build_editor(filetext) + return + + def loadfile(self, filename): + if filename == 'random': + filename = self.loadrandom() + if len(filename) < 1: + return None + if len(filename) > self.maximum_title: + print('Title too long. %d / %d' % (len(filename), self.maximum_title)) + return None + self.filename = filename + sha = self.sha(filename) + self.cur.execute('SELECT * FROM textfiles WHERE id=?', [sha]) + fetch = self.cur.fetchone() + if fetch: + loadedtext = fetch[2] + return loadedtext + else: + print('New file: %s' % filename) + return "" + + def loadrandom(self): + self.cur.execute('SELECT * FROM textfiles') + fetch = self.cur.fetchall() + if len(fetch) < 1: + return "" + return random.choice(fetch)[1] + + def strip_to_filename(self, s): + for bad in self.WINDOWS_BADCHARS: + s = s.replace(bad, '') + return s + + def sha(self, data): + sha = hashlib.sha256() + data = data.encode('utf-8') + sha.update(data) + sha = sha.hexdigest() + return sha + +editor = Editor() \ No newline at end of file diff --git a/Editor/textfiles.db b/Editor/textfiles.db new file mode 100644 index 0000000..f1e8549 Binary files /dev/null and b/Editor/textfiles.db differ diff --git a/Logogame/README.md b/Logogame/README.md new file mode 100644 index 0000000..b276010 --- /dev/null +++ b/Logogame/README.md @@ -0,0 +1,4 @@ +Logos +======= + +Another tkinter thing that I probably won't finish, but I'm playing around with displaying PNG images. \ No newline at end of file diff --git a/Logogame/images/Degreaser.png b/Logogame/images/Degreaser.png new file mode 100644 index 0000000..987c878 Binary files /dev/null and b/Logogame/images/Degreaser.png differ diff --git a/Logogame/images/Jarate.png b/Logogame/images/Jarate.png new file mode 100644 index 0000000..a9b955c Binary files /dev/null and b/Logogame/images/Jarate.png differ diff --git a/Logogame/logos.db b/Logogame/logos.db new file mode 100644 index 0000000..924dfb1 Binary files /dev/null and b/Logogame/logos.db differ diff --git a/Logogame/logos.py b/Logogame/logos.py new file mode 100644 index 0000000..ba79763 --- /dev/null +++ b/Logogame/logos.py @@ -0,0 +1,209 @@ +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') + self.tkinter_elements = [] + 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.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.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.uirefresher = self.buildui_main + self.buildui_main() + + self.t.bind('', self.update_wh) + + self.t.mainloop() + + def update_wh(self, *b): + oldw = self.w + oldh = self.h + self.w = self.t.winfo_width() + self.h = self.t.winfo_height() + if oldw != self.w or oldh != self.h: + pass + #self.uirefresher() + + def destroy_all_elements(self): + while len(self.tkinter_elements) > 0: + self.tkinter_elements[0].destroy() + del self.tkinter_elements[0] + + def buildui_main(self, *b): + self.destroy_all_elements() + x = self.w + y = self.h + + self.button_playgame = tkinter.Button( + self.t, + text='Play', + #relief='flat', + font=self.font_main, + bg=self.color_green, + activebackground=self.color_green, + command=self.buildui_game) + self.button_playgame.grid(row=10, column=5) + + self.label_playername = tkinter.Label(self.t, text='Player name: ', font=self.font_main) + self.label_playername.grid(row=30, column=4) + + self.entry_playername = tkinter.Entry( + self.t, + 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.button_playername = tkinter.Button( + self.t, + 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.label_playerhash = tkinter.Label(self.t, text=self.sha8(self.stats_main.playername), + font=self.font_main) + self.label_playerhash.grid(row=30, column=7) + + self.tkinter_elements.append(self.button_playgame) + self.tkinter_elements.append(self.label_playername) + self.tkinter_elements.append(self.entry_playername) + self.tkinter_elements.append(self.button_playername) + self.tkinter_elements.append(self.label_playerhash) + + def buildui_game(self, *b): + self.destroy_all_elements() + + self.button_back = tkinter.Button( + self.t, + text='X', + font=self.font_main, + bg=self.color_red, + activebackground=self.color_red, + command=self.buildui_main) + self.button_back.grid(row=0, column=0) + + self.tkinter_elements.append(self.button_back) + + def playername_set(self, newname): + 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) + print('Name: ' + self.stats_main.playername) + + def sha8(self, text): + sha = hashlib.sha256() + sha.update(text.encode('utf-8')) + sha = sha.hexdigest() + return sha[:8] + + def getnext(self): + pass + + def png_load(self, filename, resize=None): + if filename[-4:] != '.png': + filename = filename + '.png' + 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]) + 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_execute.execute('SELECT * FROM stats WHERE key=?', [key]) + f = cur.fetchone() + if f: + return f[1] + return None + + def strip_to_filename(self, s): + for badchar in self.WINDOWS_BADCHARS: + s = s.replace(badchar, '') + return s + +logogame = LogoGame() \ No newline at end of file diff --git a/Logogame/playerdata/Delta_18833da3.db b/Logogame/playerdata/Delta_18833da3.db new file mode 100644 index 0000000..ecbd3ee Binary files /dev/null and b/Logogame/playerdata/Delta_18833da3.db differ diff --git a/Logogame/test.py b/Logogame/test.py new file mode 100644 index 0000000..234843c --- /dev/null +++ b/Logogame/test.py @@ -0,0 +1,14 @@ +import tkinter +from PIL import Image +from PIL import ImageTk + +t=tkinter.Tk() + + +im = Image.open('images/swirl_00.png') +im = ImageTk.PhotoImage(im) +l = tkinter.Label(t, text="heyo", image=im) +l.im = im +l.pack() + +t.mainloop()