master
Voussoir 2015-08-02 21:28:40 -07:00
parent c0e7e8f5fc
commit c3c9727d49
18 changed files with 657 additions and 33 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

BIN
.GitImages/toddo01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

54
ArchiveIt/archive_it.py Normal file
View File

@ -0,0 +1,54 @@
import requests
import sys
import traceback
HEADERS = {'User-Agent': 'archive_it commandline tool for archive.is submissions v1.1',
'Referer': 'http://archive.is/',
'Origin': 'http://archive.is'}
URL_SUBMIT = 'https://archive.is/submit/'
def archive(url, anyway=0):
data = {'url': url}
if anyway is 1:
data[anyway] = 1
response = requests.post(URL_SUBMIT, data=data, headers=HEADERS)
try:
if 'link' in response.headers:
time = extract_timestamp(response.headers['link'])
raise Exception('''
Link already archived: %s
Pass parameter `anyway=1` to overwrite.
''' % time)
response = response.headers['refresh']
response = response.split(';')
for item in response:
if 'archive.is' in item:
return item.split('=')[1]
except:
return response
def extract_timestamp(link):
times = link.split(';')
d = {}
for item in times:
if '=' in item:
x = items.split('=')
d[x[0]] = x[1]
return d.get('from', d)
if __name__ == '__main__':
if len(sys.argv) == 1:
print('Use: > archive_it.py http://www.website.com/page')
quit()
url = sys.argv[1]
try:
response = archive(url)
if isinstance(response, str):
print(response)
elif isinstance(response, requests.models.Response):
print('Did not get the expected response. Here\'s what we got:')
print(response)
print(response.headers)
print(response.text)
except:
traceback.print_exc()

View File

@ -35,20 +35,23 @@ def changebase(number, frombase, tobase):
result = int(number, frombase) result = int(number, frombase)
return basex(result, tobase) return basex(result, tobase)
def intinput(prompt, greaterthan=None): def intinput(prompt, greaterthan=None, notequal=None):
''' Prompt for input until the user enters an int ''' ''' Prompt for input until the user enters an int '''
while True: while True:
result = input(prompt) result = input(prompt)
try: try:
i = int(result) i = int(result)
if greaterthan is None or i > greaterthan: if isinstance(notequal, int) and i == notequal:
return i continue
if isinstance(greaterthan, int) and i < greaterthan:
continue
return i
except ValueError: except ValueError:
pass pass
def configuration(): def configuration():
frombase = intinput(' From base: ', 1) frombase = intinput(' From base: ', 1)
tobase = intinput(' To base: ', 1) tobase = intinput(' To base: ', 1, frombase)
lower = intinput('Lower bound: ') lower = intinput('Lower bound: ')
upper = intinput('Upper bound: ', lower) upper = intinput('Upper bound: ', lower)
return { return {

View File

@ -9,6 +9,7 @@ class DataPoint:
self.color_outbound = '#999' self.color_outbound = '#999'
self.color_crossbar = '#bbb' self.color_crossbar = '#bbb'
self.color_point = '#000' self.color_point = '#000'
self.color_point_out = '#000'
self.crossbar_count = 10 self.crossbar_count = 10
self.point_diameter = 4 self.point_diameter = 4
self.margin = 0.10 self.margin = 0.10
@ -27,6 +28,7 @@ class DataPoint:
self.countdown = -1 self.countdown = -1
self.lastbump = 0 self.lastbump = 0
self.resized = True
self.t.configure(bg='#f00') self.t.configure(bg='#f00')
self.t.bind('<Configure>', self.movereplot) self.t.bind('<Configure>', self.movereplot)
self.c = tkinter.Canvas(self.t) self.c = tkinter.Canvas(self.t)
@ -35,6 +37,8 @@ class DataPoint:
self.reset() self.reset()
self.previous_w = self.w self.previous_w = self.w
self.previous_h = self.h self.previous_h = self.h
self.previous_x = self.windowx
self.previous_y = self.windowy
self.clear_screen() self.clear_screen()
self.draw_margin() self.draw_margin()
self._started = autostart self._started = autostart
@ -59,6 +63,14 @@ class DataPoint:
return self.h return self.h
return self.t.winfo_height() return self.t.winfo_height()
@property
def margin_x(self):
return self.window_width * self.margin
@property
def margin_y(self):
return self.window_height * self.margin
def mainloop(self): def mainloop(self):
self._started = True self._started = True
self.t.mainloop() self.t.mainloop()
@ -68,8 +80,8 @@ class DataPoint:
When the user expands the window, replot the graph after a When the user expands the window, replot the graph after a
short delay. short delay.
''' '''
previous = (self.previous_w, self.previous_h) previous = (self.previous_w, self.previous_h, self.previous_x, self.previous_y)
current = (self.window_width, self.window_height) current = (self.window_width, self.window_height, self.t.winfo_x(), self.t.winfo_y())
now = time.time() now = time.time()
if now - self.lastbump < 0.2: if now - self.lastbump < 0.2:
# Go away. # Go away.
@ -78,8 +90,12 @@ class DataPoint:
# Set. # Set.
self.previous_w = current[0] self.previous_w = current[0]
self.previous_h = current[1] self.previous_h = current[1]
self.previous_x = current[2]
self.previous_y = current[3]
self.countdown = 1 self.countdown = 1
self.lastbump = now self.lastbump = now
if previous[:2] != current[:2]:
self.resized = False
self.t.after(500, self.movereplot) self.t.after(500, self.movereplot)
return return
if self.countdown > -1: if self.countdown > -1:
@ -89,7 +105,9 @@ class DataPoint:
self.t.after(500, self.movereplot) self.t.after(500, self.movereplot)
if self.countdown == 0: if self.countdown == 0:
# Plot. # Plot.
self.plotpoints([]) if not self.resized:
self.plot_points([])
self.resized = True
return return
def reset(self): def reset(self):
@ -105,8 +123,6 @@ class DataPoint:
self.span_y = None self.span_y = None
self.drawable_w = None self.drawable_w = None
self.drawable_h = None self.drawable_h = None
self.margin_x = self.window_width * self.margin
self.margin_y = self.window_height * self.margin
self.clear_screen() self.clear_screen()
self.draw_margin() self.draw_margin()
@ -161,6 +177,9 @@ class DataPoint:
hi_x = hi[0] hi_x = hi[0]
hi_y = hi[1] hi_y = hi[1]
if self.crossbar_count < 1:
self.crossbar_count = 1
if self.highest_x != self.lowest_x: if self.highest_x != self.lowest_x:
# LOW X # LOW X
self.c.create_text(low_x+5, low_y+5, self.c.create_text(low_x+5, low_y+5,
@ -170,8 +189,6 @@ class DataPoint:
text=str(round(self.highest_x, 4)), anchor='nw') text=str(round(self.highest_x, 4)), anchor='nw')
increment_x = (self.highest_x - self.lowest_x) / self.crossbar_count increment_x = (self.highest_x - self.lowest_x) / self.crossbar_count
# crossbartop = (self.window_height - self.margin_y) - 5
# crossbarbot = (self.window_height - self.margin_y) + 5
crossbartop = self.margin_y crossbartop = self.margin_y
crossbarbot = self.window_height - self.margin_y crossbarbot = self.window_height - self.margin_y
for x in range(1, self.crossbar_count): for x in range(1, self.crossbar_count):
@ -190,8 +207,6 @@ class DataPoint:
self.c.create_text(low_x-5, hi_y, self.c.create_text(low_x-5, hi_y,
text=str(round(self.highest_y, 4)), anchor='e') text=str(round(self.highest_y, 4)), anchor='e')
increment_y = (self.highest_y - self.lowest_y) / self.crossbar_count increment_y = (self.highest_y - self.lowest_y) / self.crossbar_count
# crossbarlef = self.margin_x - 5
# crossbarrgt = self.margin_x + 5
crossbarlef = self.margin_x crossbarlef = self.margin_x
crossbarrgt = self.window_width - self.margin_x crossbarrgt = self.window_width - self.margin_x
for y in range(1, self.crossbar_count): for y in range(1, self.crossbar_count):
@ -215,19 +230,24 @@ class DataPoint:
or vice-versa. or vice-versa.
''' '''
if not reverse: if not reverse:
if len(self.POINTS) == 1: if self.highest_x == self.lowest_x:
return (self.window_width/2, self.window_height/2) x = self.window_width / 2
# Get percentage of the span else:
x = ((x) - self.lowest_x) / self.span_x # Get percentage of the span
y = ((y) - self.lowest_y) / self.span_y x = ((x) - self.lowest_x) / self.span_x
# Flip y # Use the percentage to get a location on the board
y = 1 - y x *= self.drawable_w
# Use the percentage to get a location on the board # Put into drawing area
x *= self.drawable_w x += self.margin_x
y *= self.drawable_h
# Put into drawing area if self.highest_y == self.lowest_y:
x += self.margin_x y = self.window_height / 2
y += self.margin_y else:
y = ((y) - self.lowest_y) / self.span_y
# Flip y
y = 1 - y
y *= self.drawable_h
y += self.margin_y
else: else:
if self.highest_x != self.lowest_x: if self.highest_x != self.lowest_x:
@ -247,12 +267,13 @@ class DataPoint:
return (x, y) return (x, y)
def plotpoints(self, points=[]): def plot_points(self, points=[]):
''' '''
Plot points onto the canvas. Plot points onto the canvas.
var points = list, where each element is a 2-length tuple, where [0] var points = list, where each element is a 2-length tuple, where [0]
is x and [1] is y coordinate. is x and [1] is y coordinate.
''' '''
original_len = len(self.POINTS)
for point in points: for point in points:
self.POINTS.add(tuple(point)) self.POINTS.add(tuple(point))
@ -292,19 +313,19 @@ class DataPoint:
outline=self.color_point) outline=self.color_point)
self.c.update() self.c.update()
def plotpoint(self, x, y): def plot_point(self, x, y):
self.plotpoints([[x, y]]) self.plot_points([[x, y]])
def set_origin(self, x, y): def set_origin(self, x, y):
self.origin = (x, y) self.origin = (x, y)
self.plotpoints([]) self.plot_points([])
def example(function): def example(function):
dp = DataPoint() dp = DataPoint()
points = list(range(100)) points = list(range(100))
points = [[p, function(p)] for p in points] points = [[p, function(p)] for p in points]
dp.plotpoints(points) dp.plot_points(points)
dp.mainloop() dp.mainloop()
@ -330,10 +351,9 @@ def example2():
(94, 22320), (95, 23703), (96, 40752), (97, 21730), (98, 27637), (94, 22320), (95, 23703), (96, 40752), (97, 21730), (98, 27637),
(99, 45931), (100, 18443), (101, 20048), (102, 18097), (103, 11430) (99, 45931), (100, 18443), (101, 20048), (102, 18097), (103, 11430)
] ]
dp.plotpoints(points) dp.plot_points(points)
dp.mainloop() dp.mainloop()
def examplefunction(x): def examplefunction(x):
x -= 50 x -= 50
x *= 0.1 x *= 0.1

4
TKCube/README.md Normal file
View File

@ -0,0 +1,4 @@
TKCube
=========
Not done yet.

117
TKCube/tkcube.py Normal file
View File

@ -0,0 +1,117 @@
import copy
import math
import random
import tkinter
class TKCube:
def __init__(self):
self.t = tkinter.Tk()
self.FACES = [
[[2, 2, 1], [2, -2, 1], [-2, -2, 1], [-2, 2, 1]],
[[2, -2, 1], [-2, -2, -1], [-2, 2, -1], [2, 2, -1]],
[[-2, -2, 1], [2, -2, 1], [2, -2, -1], [-2, -2, -1]],
[[-2, 2, 1], [2, 2, 1], [2, 2, -1], [-2, 2, -1]],
[[-2, -2, -1], [-2, 2, -1], [-2, 2, 1], [-2, -2, -1]],
[[2, -2, 1], [2, 2, 1], [2, 2, -1], [2, -2, -1]],
]
self.INFLATE_SCALE = 8
self.c = tkinter.Canvas(self.t, width=600, height=600, bg='#444')
self.c.pack(fill='both', expand=True)
self.t.bind('<Return>', self.render)
self.is_mouse_down = False
self.prev_mouse_x = None
self.prev_mouse_y = None
self.t.bind('<ButtonPress-1>', self.mouse_down)
self.t.bind('<ButtonRelease-1>', self.mouse_up)
self.t.bind('<Motion>', self.mouse_motion)
self.t.bind('<Up>', lambda event: self.arbitrarymove(0, -1))
self.t.bind('<Down>', lambda event: self.arbitrarymove(0, 1))
self.t.bind('<Left>', lambda event: self.arbitrarymove(-1, 0))
self.t.bind('<Right>', lambda event: self.arbitrarymove(1, 0))
self.render()
self.t.mainloop()
def arbitrarymove(self, deltax, deltay):
for face in self.FACES:
for point in face:
point[0] += deltax
point[1] += deltay
self.render()
def mouse_down(self, event):
self.is_mouse_down = True
def mouse_up(self, event):
self.is_mouse_down = False
def mouse_motion(self, event):
if not self.is_mouse_down:
return
if self.prev_mouse_x is None:
self.prev_mouse_x = event.x
self.prev_mouse_y = event.y
distance = math.sqrt( ((event.x - self.prev_mouse_x) ** 2) + ((event.y - self.prev_mouse_y) ** 2) )
self.prev_mouse_x = event.x
self.prev_mouse_y = event.y
print(distance)
def center_of_square(self, face):
x = 0; y = 0; z = 0
for point in face:
x += point[0]
y += point[1]
z += point[2]
return [x/4, y/4, z/4]
def plot_point_screen(self, x, y, diameter=4):
radius = diameter / 2
x1 = x - radius
y1 = y - radius
x2 = x + radius
y2 = y + radius
self.c.create_oval(x1, y1, x2, y2, fill='#000')
def render(self, *event):
self.c.delete('all')
rendered_faces = copy.deepcopy(self.FACES)
# Sort by depth from camera
# The sort key is the z value of the coordinate
# in the center of the face
rendered_faces.sort(key=lambda face: self.center_of_square(face)[2])
canvas_width_half = self.c.winfo_width() / 2
canvas_height_half = self.c.winfo_height() / 2
highest_z = max([max([point[2] for point in face]) for face in rendered_faces])
for face in self.FACES:
for point in face:
x = point[0]
y = point[1]
z = point[2]
# Push everything away from the camera so all z are <= 0
z -= highest_z
# Create vanishing point.
distance_camera = math.sqrt((x**2) + (y**2) + (z**2))
#if z != 0:
# factor = (abs(z) ** 0.2) - 1
# print(factor)
#else:
# factor = 0
x += x * factor
y += y * factor
# Inflate for display
x *= self.INFLATE_SCALE
y *= self.INFLATE_SCALE
z *= self.INFLATE_SCALE
# Shift the coordinates into the screen
x += canvas_width_half
y += canvas_height_half
self.plot_point_screen(x, y)
#print(rendered_faces)
t = TKCube()

21
TextureTile/README.md Normal file
View File

@ -0,0 +1,21 @@
Texture Tile
============
Requires `pip install pillow`
&nbsp;
Make it big!
<p align="center">
<img src="https://github.com/voussoir/else/blob/master/.GitImages/texturetile01.png?raw=true" alt="texture tile"/>
</p>
Make it small!
<p align="center">
<img src="https://github.com/voussoir/else/blob/master/.GitImages/texturetile02.png?raw=true" alt="texture tile"/>
</p>
Make it any size at all!
<p align="center">
<img src="https://github.com/voussoir/else/blob/master/.GitImages/texturetile03.png?raw=true" alt="texture tile"/>
</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

View File

@ -0,0 +1,82 @@
import os
from PIL import Image
from PIL import ImageTk
import tkinter
class TextureTile:
def __init__(self):
self.windowtitle = 'Texture Tile'
self.t = tkinter.Tk()
self.t.title(self.windowtitle)
self.w = 450
self.h = 475
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.entry_filename = tkinter.Entry(self.t, font=('Consolas', 12))
self.button_load = tkinter.Button(self.t, text='Load', command=self.file_load_display)
self.frame_filearea = tkinter.Frame(self.t)
self.label_image = tkinter.Label(self.frame_filearea, bg='#222')
self.t.columnconfigure(0, weight=1)
self.t.rowconfigure(1, weight=1)
self.entry_filename.grid(row=0, column=0, sticky='ew')
self.button_load.grid(row=0, column=1, sticky='ne')
self.frame_filearea.grid(row=1, column=0, columnspan=2, sticky='nsew')
self.label_image.pack(expand=True, fill='both')
#self.entry_filename.pack(fill='x')
#self.button_load.pack()
#self.label_image.pack()
self.entry_filename.insert(0, os.getcwd())
self.entry_filename.bind('<Return>', self.file_load_display)
self.entry_filename.focus_set()
self.t.mainloop()
def file_load_display(self, *event):
filename = self.entry_filename.get()
# Open file or turn red
try:
image = Image.open(filename)
self.entry_filename.configure(bg='#fff')
except FileNotFoundError:
self.entry_filename.configure(bg='#f00')
return
# 9x the image
w = image.size[0]
h = image.size[1]
expanded = image.copy()
expanded = expanded.resize((w * 3, h * 3))
for x in range(3):
for y in range(3):
expanded.paste(image, (w*x, h*y))
# Resize 9x'ed image into frame
w = expanded.size[0]
h = expanded.size[1]
fw = self.label_image.winfo_width()
fh = self.label_image.winfo_height()
ratio = min(fw/w, fh/h)
w = int(w * ratio)
h = int(h * ratio)
expanded = expanded.resize((w, h))
image = ImageTk.PhotoImage(expanded)
self.label_image.configure(image=image)
self.label_image.dont_garbage_me_bro = image
r'C:\Users\Owner\AppData\Roaming\.MinecraftMulti\instances\Chocolate\minecraft\texturepacks\SixtyFox\textures\blocks\melon_top.png'
r'C:\users\owner\desktop\pi\imergers\ear.jpg'
if __name__ == '__main__':
t = TextureTile()

9
Toddo/README.md Normal file
View File

@ -0,0 +1,9 @@
Toddo
======
Commandline to-do-list manager.
<p align="center">
<img src="https://github.com/voussoir/else/blob/master/.GitImages/toddo01.png?raw=true" alt="to-do list manager"/>
</p>

BIN
Toddo/toddo.db Normal file

Binary file not shown.

314
Toddo/toddo.py Normal file
View File

@ -0,0 +1,314 @@
import datetime
import shutil
import sqlite3
import sys
import textwrap
SQL_ID = 0
SQL_TODOTABLE = 1
SQL_CREATED = 2
SQL_MESSAGE = 3
HELP_FULL = [
('> toddo', 'Display the todos from the current table'),
('> toddo all', 'Display the todos from all tables'),
('> toddo 4', 'Display the todo with ID 4'),
('> toddo add', 'Add a new todo via multi-line typing prompt'),
('> toddo add "message"', 'Add a new todo with this message'),
('> toddo remove 8', 'Remove the todo with ID 8'),
('> toddo table', 'Display the name of the current table'),
('> toddo table name', 'Switch to the table named "name"')
]
HELP_NOENTRIES = '''Your todo list is empty!
Use `toddo add` or `toddo add "message"` to make entries.'''
HELP_NOACTIVE = '''Table `%s` has no entries!
Use `toddo all` to see if there are entries for other tables.'''
HELP_REMOVE = '''Provide an ID number to remove.'''
class ToddoExc(Exception):
pass
class Toddo():
def __init__(self, dbname='C:/git/else/toddo/toddo.db'):
self.sql = sqlite3.connect(dbname)
self.cur = self.sql.cursor()
self.cur.execute('CREATE TABLE IF NOT EXISTS meta(key TEXT, val TEXT)')
self.cur.execute('CREATE TABLE IF NOT EXISTS todos(id INT, todotable TEXT, created INT, message TEXT)')
self.cur.execute('CREATE INDEX IF NOT EXISTS todoindex on todos(id)')
def add_todo(self, message=None):
'''
Create new entry in the database on the active todotable.
'''
if message is None:
message = multi_line_input()
message = str(message)
if message is '':
raise ToddoExc('Todos cannot be blank.')
todoid = self.increment_lastid()
todotable = self.get_todotable()
created = int(datetime.datetime.now(datetime.timezone.utc).timestamp())
self.cur.execute('INSERT INTO todos VALUES(?, ?, ?, ?)', [todoid, todotable, created, message])
self.sql.commit()
return todoid
def remove_todo(self, idnumber):
'''
Drop todo from the database.
'''
idnumber = int(idnumber)
self.cur.execute('SELECT * FROM todos WHERE id=?', [idnumber])
todo = self.cur.fetchone()
if todo is None:
raise ToddoExc('Todo %d does not exist.' % idnumber)
activetable = self.get_todotable()
requestedtable = todo[SQL_TODOTABLE]
if requestedtable.lower() != activetable.lower():
raise ToddoExc('Todo %d is not part of the active table `%s`. It belongs to `%s`.' % (idnumber, activetable, requestedtable))
self.cur.execute('DELETE FROM todos WHERE id=?', [idnumber])
self.sql.commit()
return idnumber
def display_one_todo(self, idnumber):
'''
Make a nice display that shows a todo's entire contents.
'''
self.cur.execute('SELECT * FROM todos WHERE id=?', [idnumber])
todo = self.cur.fetchone()
if todo is None:
raise ToddoExc('Todo %d does not exist.' % idnumber)
message = todo[SQL_MESSAGE]
messageleft = len('Message: ')
width = shutil.get_terminal_size()[0] - (messageleft + 1)
message = nicewrap(message, width, messageleft)
return 'ID: %d\nTable: %s\nCreated: %s\nMessage: %s' % (
todo[SQL_ID], todo[SQL_TODOTABLE], human(todo[SQL_CREATED]), message)
def display_active_todos(self):
'''
Pass the active table name into display_todos_from_table
'''
todotable = self.get_todotable()
return self.display_todos_from_table(todotable)
def display_todos_from_table(self, todotable):
'''
Make a nice display from the database.
'''
if todotable is None:
self.cur.execute('SELECT * FROM todos ORDER BY id ASC')
else:
self.cur.execute('SELECT * FROM todos WHERE todotable=? ORDER BY id ASC', [todotable])
todos = self.cur.fetchall()
if len(todos) == 0:
return None
todos = [list(x) for x in todos]
longest_id = max(len(str(x[SQL_ID])) for x in todos)
longest_table = max(len(str(x[SQL_TODOTABLE])) for x in todos)
display = []
for todo in todos:
todoid = str(todo[SQL_ID])
todoid = (' '*(longest_id-len(todoid))) + todoid
timestamp = human(todo[SQL_CREATED])
todotable = todo[SQL_TODOTABLE]
todotable = (' '*(longest_table-len(todotable))) + todotable
message = todo[SQL_MESSAGE]
if '\n' in message:
message = message.split('\n')[0] + ' ...'
total = '%s : %s : %s : %s' % (todoid, todotable, timestamp, message)
terminal_width = shutil.get_terminal_size()[0]
if len(total) > terminal_width:
total = total[:(terminal_width-(len(total)+4))] + '...'
display.append(total)
return '\n'.join(display)
def switch_todotable(self, newtable=None):
'''
Update the meta with `newtable` as the new active todotable.
'''
self.cur.execute('SELECT val FROM meta WHERE key="todotable"')
activetable = self.cur.fetchone()
if not activetable:
activetable = self._install_default_todotable()
else:
activetable = activetable[0]
if newtable is None:
return activetable
self.cur.execute('UPDATE meta SET val=? WHERE key="todotable"', [newtable])
self.sql.commit()
return newtable
def increment_lastid(self, increment=False):
'''
Increment the lastid in the meta table, THEN return it.
'''
self.cur.execute('SELECT val FROM meta WHERE key="lastid"')
lastid = self.cur.fetchone()
if lastid is None:
self._install_default_lastid()
return 1
else:
lastid = int(lastid[0]) + 1
self.cur.execute('UPDATE meta SET val=? WHERE key="lastid"', [lastid])
return lastid
def get_todotable(self):
self.cur.execute('SELECT val FROM meta WHERE key="todotable"')
todotable = self.cur.fetchone()
if todotable is None:
self._install_default_todotable()
todotable = 'default'
else:
todotable = todotable[0]
return todotable
def _install_default_lastid(self):
'''
This method assumes that "lastid" does not already exist.
If it does, it's your fault for calling this.
'''
self.cur.execute('INSERT INTO meta VALUES("lastid", 1)')
self.sql.commit()
return 1
def _install_default_todotable(self):
'''
This method assumes that "todotable" does not already exist.
If it does, it's your fault for calling this.
'''
self.cur.execute('INSERT INTO meta VALUES("todotable", "default")')
self.sql.commit()
return 'default'
def human(timestamp):
timestamp = datetime.datetime.utcfromtimestamp(timestamp)
timestamp = datetime.datetime.strftime(timestamp, '%d %b %Y %H:%M')
return timestamp
def multi_line_input():
print('Submit a ctrl+z to finish typing.')
userinput = ''
ctrlz = '\x1a'
while True:
try:
additional = input('- ')
except EOFError:
# If you only enter a ctrlz
return userinput
if ctrlz in additional:
additional = additional.split(ctrlz)[0]
userinput += additional
break
userinput += additional + '\n'
return userinput.strip()
def nicewrap(message, width, paddingleft):
# http://stackoverflow.com/a/26538082 ##########################
message = '\n'.join(['\n'.join(textwrap.wrap(line, width,#######
break_long_words=True, replace_whitespace=False))##########
for line in message.split('\n')])##########################
################################################################
message = message.strip()
message = message.replace('\n', '\n' + (' '*paddingleft))
return message
def fullhelp():
longestleft = max(len(x[0]) for x in HELP_FULL)
width = shutil.get_terminal_size()[0] - 1
message = []
for item in HELP_FULL:
pad = width - (longestleft+ 3)
item = '%s : %s' % (item[0] + (' '*(longestleft - len(item[0]))), nicewrap(item[1], pad, longestleft + 3))
message.append(item)
message = '\n'.join(message)
return message
if __name__ == '__main__':
toddo = Toddo()
# Look, no more IndexErrors
sys.argv += [None]*10
if isinstance(sys.argv[1], str):
sys.argv[1] = sys.argv[1].lower()
if sys.argv[1] is None:
message = toddo.display_active_todos()
if message is None:
table = toddo.get_todotable()
print(HELP_NOACTIVE % table)
else:
print(message)
elif sys.argv[1] == 'all':
message = toddo.display_todos_from_table(None)
if message is None:
print(HELP_NOENTRIES)
else:
print(message)
elif sys.argv[1] == 'add':
args = list(filter(None, sys.argv))
args = args[2:]
args = ' '.join(args)
if args == '':
args = None
message = toddo.add_todo(args)
if isinstance(message, int):
print('Added %d' % message)
elif sys.argv[1] == 'remove':
idnumber = sys.argv[2]
if idnumber is None or not idnumber.replace(',', '').isdigit():
print(HELP_REMOVE)
else:
message = []
ids = [int(x) for x in idnumber.split(',')]
for x in ids:
try:
t = toddo.remove_todo(x)
message.append('Removed %d' % t)
except ToddoExc as e:
message.append(e.args[0])
print('\n'.join(message))
elif sys.argv[1] == 'table':
currenttable = toddo.get_todotable()
message = toddo.switch_todotable(sys.argv[2])
if currenttable == message:
print('You are on table `%s`' % message)
else:
print('Switched to table `%s`' % message)
elif sys.argv[1].isdigit():
try:
message = toddo.display_one_todo(int(sys.argv[1]))
print(message)
except ToddoExc as e:
print(e.args[0])
elif sys.argv[1] == 'help':
print(fullhelp())
else:
print('Command not recognized.')
print(fullhelp())