diff --git a/EntryWithHistory/entrywithhistory.py b/EntryWithHistory/entrywithhistory.py new file mode 100644 index 0000000..680f054 --- /dev/null +++ b/EntryWithHistory/entrywithhistory.py @@ -0,0 +1,46 @@ +import tkinter + +class EntryWithHistory(tkinter.Entry): + def __init__(self, master, submithook, *args, **kwargs): + super(EntryWithHistory, self).__init__(master, *args, **kwargs) + self.previousinputs = [] + self.previousinputstep = 0 + + self.submithook = submithook + + self.bind('', self.submit) + self.bind('', lambda b: self.delete(0, 'end')) + self.bind('', self.previous_back) + self.bind('', self.previous_forward) + + def submit(self, *b): + x = self.get() + x = x.lower() + noskip = '!' in x + if 2 < len(x) < 21: + if len(self.previousinputs) == 0 or self.previousinputs[-1] != x: + self.previousinputs.append(x) + self.previousinputstep = 0 + self.submithook(x) + self.delete(0, 'end') + + def previous_back(self, *b): + self.previous_step(-1) + + def previous_forward(self, *b): + self.previous_step(1) + + def previous_step(self, direction): + self.previousinputstep += direction + if abs(self.previousinputstep) > len(self.previousinputs): + self.previousinputstep -= direction + return + self.delete(0, 'end') + if self.previousinputstep >= 0: + self.previousinputstep = 0 + return + self.insert(0, self.previousinputs[self.previousinputstep]) +t = tkinter.Tk() +e=EntryWithHistory(t, print) +e.pack() +t.mainloop() \ No newline at end of file diff --git a/Jobs/job_example.py b/Jobs/job_example.py new file mode 100644 index 0000000..14e45ca --- /dev/null +++ b/Jobs/job_example.py @@ -0,0 +1,15 @@ +import jobs +import time + +def continuous_register(): + print('w') + jobs.register(2, continuous_register) + +jobs.register(5, print, args=('heyo',)) +time.sleep(10) +print('x') +jobs.register(5, print, args=('heyo',)) +time.sleep(2) +jobs.unregister(print, args=('heyo', ), kwargs={}) +time.sleep(10) +print('y') \ No newline at end of file diff --git a/Jobs/jobs.py b/Jobs/jobs.py new file mode 100644 index 0000000..0036528 --- /dev/null +++ b/Jobs/jobs.py @@ -0,0 +1,52 @@ +import signal +import time +import threading + +class JobInterruption(Exception): + pass + +class JobSchedulingError(Exception): + pass + +THREAD = None +JOBS = {} +def thread_manager(): + while True: + now = time.time() + for (functionid, joblist) in JOBS.items(): + for job in joblist: + if now < job[0]: + continue + job[1](*job[2], **job[3]) + joblist.remove(job) + time.sleep(0.5) + +def launch_thread(): + global THREAD + if THREAD is None or THREAD.is_alive is False: + THREAD = threading.Thread(target=thread_manager) + THREAD.daemon = True + THREAD.start() + +def register(seconds_from_now, function, args=[], kwargs={}): + if seconds_from_now <= 0: + raise JobSchedulingError('cannot schedule jobs for the past') + iid = id(function) + schedule = time.time() + seconds_from_now + if iid not in JOBS: + JOBS[iid] = [(schedule, function, args, kwargs)] + else: + JOBS[iid].append( (schedule, function, args, kwargs) ) + launch_thread() + +def unregister_all(function): + iid = id(function) + if iid in JOBS: + del JOBS[iid] + +def unregister(function, args, kwargs): + joblist = JOBS[id(function)] + for job in joblist: + if job[1:] != (function, args, kwargs): + continue + joblist.remove(job) \ No newline at end of file diff --git a/Syshub/README.md b/Syshub/README.md new file mode 100644 index 0000000..657a5ca --- /dev/null +++ b/Syshub/README.md @@ -0,0 +1,4 @@ +SysHub +======= + +This is probably a terrible idea. It actually kind of works but not 100%. \ No newline at end of file diff --git a/Syshub/syshub.py b/Syshub/syshub.py new file mode 100644 index 0000000..7ce48e0 --- /dev/null +++ b/Syshub/syshub.py @@ -0,0 +1,118 @@ +''' +This module allows the user to redirect sys.stdout, stdin, and exceptions +streams (referred to as std* collectively) on a per-module basis. That is, +a main program can import both moduleA and moduleB, then register them here +so that any print statements or prompts in the modules will behave differently. +''' + +import inspect +import sys +import traceback + +class SysRouter: + def __init__(self): + if self.__class__.ROUTER_EXISTS: + raise ValueError('You may only instantiate one of each SysRouter') + self.__class__.ROUTER_EXISTS = True + + def router_get_caller(self, key, default, jumps=0): + stack = inspect.stack() + + calling_frame = stack[2+jumps][0] + calling_module = inspect.getmodule(calling_frame) + if calling_module is None: + try: + calling_frame = stack[3+jumps][0] + calling_module = inspect.getmodule(calling_frame) + calling_name = calling_module.__name__ + except: + calling_name = '' + else: + calling_name = calling_module.__name__ + + rerouted = SYSHUB_MAP.get(calling_name, {}).get(key, default) + return rerouted + +class SysRouterOut(SysRouter): + ROUTER_EXISTS = False + + def flush(self): + STDOUT.flush() + + def write(self, data): + rerouted = self.router_get_caller('out', STDOUT.write) + return rerouted(data) + +class SysRouterIn(SysRouter): + ROUTER_EXISTS = False + + def readline(self): + rerouted = self.router_get_caller('in', STDIN.readline) + return rerouted() + +#class SysRouterErr(SysRouter): +# ROUTER_EXISTS = False +# +# def flush(self): +# STDERR.flush() +# +# def write(self, data): +# rerouted = self.router_get_caller('out', STDERR.write) +# return rerouted(data) + +class SysRouterExc(SysRouter): + ROUTER_EXISTS = False + + def __call__(self, exception_type, exception_instance, trace): + caller = traceback._format_exception_iter(ValueError, exception_instance, trace,None, None) + caller = list(caller)[-2] + caller = caller.split('"')[1] + caller = caller.replace('\\', '/') + caller = caller.split('/')[-1] + caller = caller.split('.')[0] + rerouted = SYSHUB_MAP.get(caller, {}).get('exc', EXCEPTHOOK) + rerouted(exception_type, exception_instance, trace) + +SYSHUB_MAP = {} + +STDOUT = sys.stdout +STDIN = sys.stdin +#STDERR = sys.stderr +EXCEPTHOOK = sys.excepthook +sys.stdout = SysRouterOut() +sys.stdin = SysRouterIn() +#sys.stderr = SysRouterErr() +sys.excepthook = SysRouterExc() + +def register(module, calltype, method): + ''' + Register a module in the syshub map. + + When the module performs an input, output, or err operation, Syshub will + check the map so see if it should redirect the call to the provided + method. + + Registered modules will not affect the behavior of unregistered modules. + + Rerouting a module's 'out' will not affect that module's 'in', etc. + + ----- + + parameters: + module = the module object from which calls will be rerouted. + calltype = one of {'out', 'in', 'exc}, corresponding to sys.std* + and sys.excepthook + method = the method to which any arguments intended for the std* method + will be passed. + + ----- + + SYSHUB_MAP is kept in the format: + + {module: {'out': method, 'in': method, 'exc': method}} + ''' + i = module.__name__ + if i in SYSHUB_MAP: + SYSHUB_MAP[i][calltype] = method + else: + SYSHUB_MAP[i] = {calltype: method} diff --git a/Syshub/syshub_example_manager.py b/Syshub/syshub_example_manager.py new file mode 100644 index 0000000..57010a3 --- /dev/null +++ b/Syshub/syshub_example_manager.py @@ -0,0 +1,48 @@ +import inspect +import syshub +import syshub_example_slave as slave +import syshub_example_slave2 as slave2 +import sys +import traceback + +def print_from_slave(data): + if data not in ('\n', ''): + data = 'SLAVE]: ' + data + sys.stdout.write(data) + sys.stdout.flush() + return len(data) + +def input_from_slave(): + sys.stdout.write('\n') + return 'robots' + +def exception_from_slave(exception_type, exception_instance, trace): + message = traceback.format_exception(exception_type, exception_instance, trace) + message = ''.join(message) + message = 'SLAVE]: ' + message.replace('\n', '\nSLAVE]: ') + sys.stderr.write(message) + sys.stderr.flush() + return len(message) + +def print_from_slave2(data): + if data not in ('\n', ''): + data = 'SLAV2]: ' + data + sys.stdout.write(data) + sys.stdout.flush() + return len(data) + +def input_from_slave2(): + return input('type here> ') + +syshub.register(module=slave, calltype='out', method=print_from_slave) +syshub.register(module=slave, calltype='in', method=input_from_slave) +syshub.register(module=slave, calltype='exc', method=exception_from_slave) + +syshub.register(module=slave2, calltype='out', method=print_from_slave2) +syshub.register(module=slave2, calltype='in', method=input_from_slave2) +#print(syshub.SYSHUB_MAP) +slave.say_something() +slave.input_something() +slave2.say_something() +slave2.input_something() +slave.raise_something() \ No newline at end of file diff --git a/Syshub/syshub_example_slave.py b/Syshub/syshub_example_slave.py new file mode 100644 index 0000000..0f74024 --- /dev/null +++ b/Syshub/syshub_example_slave.py @@ -0,0 +1,14 @@ +''' +Notice how this file does not import syshub or know about it +in any way. +''' +import sys +def say_something(): + print('hello') + +def input_something(): + print('prompt: ', end='') + print(sys.stdin.readline()) + +def raise_something(): + raise ValueError \ No newline at end of file diff --git a/Syshub/syshub_example_slave2.py b/Syshub/syshub_example_slave2.py new file mode 100644 index 0000000..39f10b0 --- /dev/null +++ b/Syshub/syshub_example_slave2.py @@ -0,0 +1,16 @@ +''' +Notice how this file does not import syshub or know about it +in any way. +''' +import sys +def say_something(): + print('hello') + +def input_something(): + print('prompt: ', end='') + b = sys.stdin.readline() + print(b) + +def raise_something(): + print(sys.excepthook) + raise ValueError \ No newline at end of file diff --git a/Syshub/syshub_reddits.py b/Syshub/syshub_reddits.py new file mode 100644 index 0000000..43192c6 --- /dev/null +++ b/Syshub/syshub_reddits.py @@ -0,0 +1,172 @@ +import sys +import syshub +import tkinter + +class EntryWithHistory(tkinter.Entry): + def __init__(self, master, submithook, *args, **kwargs): + super(EntryWithHistory, self).__init__(master, *args, **kwargs) + self.previousinputs = [] + self.previousinputstep = 0 + + self.submithook = submithook + + self.bind('', self.submit) + self.bind('', lambda b: self.delete(0, 'end')) + self.bind('', self.previous_back) + self.bind('', self.previous_forward) + + def submit(self, *b): + x = self.get() + x = x.lower() + noskip = '!' in x + if 2 < len(x) < 21: + if len(self.previousinputs) == 0 or self.previousinputs[-1] != x: + self.previousinputs.append(x) + self.previousinputstep = 0 + self.submithook(x) + self.delete(0, 'end') + + def previous_back(self, *b): + self.previous_step(-1) + + def previous_forward(self, *b): + self.previous_step(1) + + def previous_step(self, direction): + self.previousinputstep += direction + if abs(self.previousinputstep) > len(self.previousinputs): + self.previousinputstep -= direction + return + self.delete(0, 'end') + if self.previousinputstep >= 0: + self.previousinputstep = 0 + return + self.insert(0, self.previousinputs[self.previousinputstep]) + +class InterpreterWindow(tkinter.Frame): + def __init__(self, master, module, *args, **kwargs): + super(InterpreterWindow, self).__init__(master, *args, **kwargs) + + self.module = module + + self.frame = tkinter.Frame(master, height=512) + self.display = tkinter.Label(self.frame, anchor='sw', justify='left', font=('Terminal',10)) + self.display.configure(wraplength=self.display.winfo_width(), bg='#272822', fg='#e6db74') + self.input = EntryWithHistory(self.frame, self.input_text, font=('Terminal', 10), bg='#000', fg='#e6db74') + self.input.configure(insertbackground='#e6db74') + + self.frame.bind('', self.update_wraplength) + + self.display_buffer = ['wtf', 'w'] + self.frame.rowconfigure(0, weight=1) + self.frame.columnconfigure(0, weight=1) + self.display.grid(row=0, column=0, sticky='news') + self.input.grid(row=1, column=0, sticky='ew') + master.update() + self.frame.pack_propagate(0) + self.frame.grid_propagate(0) + + self.update_display() + + def update_display(self): + display = '\n'.join(self.display_buffer) + self.display.configure(text=display) + self.display.update() + + def input_text(self, text): + text = text.strip() + if text is '': + return + d = '>>> ' + text + self.display_buffer.append(d) + self.update_display() + self.input.configure(state='disabled') + self.input.update() + self.module.execit(text) + self.input.configure(state='normal') + + def update_wraplength(self, *trash): + self.display.configure(wraplength=self.display.winfo_width()) + + def syshub_receiver(self, text): + text = text.strip() + if text is '': + return + self.display_buffer.append(text) + self.update_display() + + def previous_back(self, *b): + self.previous_step(-1) + + def previous_forward(self, *b): + self.previous_step(1) + + def previous_step(self, direction): + self.previousinputstep += direction + if abs(self.previousinputstep) > len(self.previousinputs): + self.previousinputstep -= direction + return + self.input.delete(0, 'end') + if self.previousinputstep >= 0: + self.previousinputstep = 0 + return + self.input.insert(0, self.previousinputs[self.previousinputstep]) + + def pack(self, *args, **kwargs): + self.frame.pack(*args, **kwargs) + + def grid(self, *args, **kwargs): + self.frame.grid(*args, **kwargs) + + def place(self, *args, **kwargs): + self.frame.place(*args, **kwargs) + +class QuadTK: + def __init__(self): + self.windowtitle = 'QuadTK' + + self.t = tkinter.Tk() + self.t.title(self.windowtitle) + self.w = 800 + self.h = 525 + 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.build_gui_manager() + + self.t.mainloop() + +p = sys.path[0] + +sys.path[0] = 'C:/git/reddit/subredditbirthdays/' +import sb +sys.path[0] = 'C:/git/reddit/usernames/' +import un +sys.path[0] = 'C:/git/reddit/t3/' +import t3 + +t = tkinter.Tk() +t.columnconfigure(0, weight=1) +t.rowconfigure(0, weight=1) +t.rowconfigure(1, weight=1) +t.rowconfigure(2, weight=1) + +sbi = InterpreterWindow(t, sb) +sbi.grid(row=0, column=0, sticky='news') +syshub.register(module=sb, calltype='out', method=sbi.syshub_receiver) + +uni = InterpreterWindow(t, un) +uni.grid(row=1, column=0, sticky='news') +syshub.register(module=un, calltype='out', method=uni.syshub_receiver) + +t3i = InterpreterWindow(t, t3) +t3i.grid(row=2, column=0, sticky='news') +syshub.register(module=t3, calltype='out', method=t3i.syshub_receiver) + +t.mainloop() \ No newline at end of file diff --git a/Toddo/toddo.db b/Toddo/toddo.db index 22a8302..74c78bb 100644 Binary files a/Toddo/toddo.db and b/Toddo/toddo.db differ