brain/brain.py

956 lines
30 KiB
Python

import os, sys
from git import *
import bottle
from bottle import default_app, get, post, route, run, request, template, static_file, redirect
from os.path import isdir
from string import lower, split
import string
from urllib import unquote, urlopen
from urlparse import urlparse
import shutil
from datetime import datetime
import re
import Image
from markdown2 import markdown
import MySQLdb
from contextlib import closing
import random
try:
conn = MySQLdb.connect( host = "localhost",
user = "brain",
passwd = "horsebatteries",
db = "brain")
cursor = conn.cursor()
except:
print 'Cannot connect to database.'
conf = {}
conf['repo'] = '/srv/git/documents'
conf['ext_bundles'] = ['.pages', '.sparsebundle']
conf['ext_render'] = ['.md','.txt','.jpg','.gif','.png']
conf['ext_edit'] = ['.md','.txt','.rb','.py','.pl','.sh']
def get_secrets(url = False):
def generate_query():
if url:
query = 'SELECT base_url,username,password,id FROM `secrets` WHERE base_url LIKE "%' + url + '";'
else:
query = 'SELECT base_url,username,password,id FROM `secrets`;'
return query
cursor.execute(generate_query())
secrets = cursor.fetchall()
if not len(secrets) > 0:
print 'No secrets for ' + url + ' expanding search.'
url = get_domain(url)
print 'Trying ' + url + '.'
cursor.execute(generate_query())
secrets = cursor.fetchall()
return secrets
def get_domain(base_url):
with closing(urlopen('https://mxr.mozilla.org/mozilla/source/netwerk/dns/src/effective_tld_names.dat?raw=1')) as tldFile:
tlds = [line.strip() for line in tldFile if line[0] not in "/\n"]
urlElements = base_url.split('.')
for i in range(-len(urlElements),0):
lastIElements = urlElements[i:]
candidate = ".".join(lastIElements)
wildcardCandidate = ".".join(["*"]+lastIElements[1:])
exceptionCandidate = "!"+candidate
if (exceptionCandidate in tlds):
return ".".join(urlElements[i:])
if (candidate in tlds or wildcardCandidate in tlds):
return ".".join(urlElements[i-1:])
return base_url
def mkpass(size=10):
validChars = string.ascii_letters + string.digits
validChars = validChars.strip("oO01l")
return string.join([random.choice(validChars) for x in range(size)],"")
def mkshort(size=4):
validChars = string.ascii_letters + string.digits
validChars = validChars.strip("oO01l")
return string.join([random.choice(validChars) for x in range(size)],"")
def get_generated(domain):
get = 'SELECT password FROM secrets_gen WHERE base_url LIKE "%'+get_domain(domain)+'%" LIMIT 1'
create = 'INSERT INTO secrets_gen (base_url, password) VALUES ("'+get_domain(domain)+'","'+mkpass()+'")'
cursor.execute(get)
gen = cursor.fetchone()
if not gen:
cursor.execute(create)
cursor.execute(get)
gen = cursor.fetchone()
return str(gen[0])
def sanitize_path(path):
return path.lstrip('./')
def render_file(name,public=False):
path = os.path.join(conf['repo'], name)
filename, extension = os.path.splitext(name)
filename = os.path.basename(name)
if isdir(path) and lower(extension) in conf['ext_bundles']:
d = datetime.now()
basedir = re.sub(filename+extension, '', path)
rootdir = filename+extension
z = shutil.make_archive('/tmp/' + unquote(filename) + '_' + \
d.strftime("%Y%M%d%H%M%S"), "zip", basedir, rootdir )
return static_file(os.path.basename(z), root='/tmp')
if lower(extension) in conf['ext_render']:
try:
img = Image.open(path)
width, height = img.size
if width > 1024 or height > 1024:
if height > width:
h = 1024
w = round(1024 * (float(width)/float(height)))
else:
if height < width:
h = round(1024 * (float(height)/float(width)))
w = 1024
else:
h = 1024
w = 1024
else:
h = height
w = width
content = '<img height="'+str(h)+'" width="'+str(w)+'" src="/raw/'+sanitize_path(name)+'" />'
except:
try:
o = open(path,'r')
content = markdown(o.read())
o.close()
content += '<p><a href="/edit/'+sanitize_path(name)+'">Edit</a> - '
content += '<a href="/raw/'+sanitize_path(name)+'">Raw</a></p>'
except:
content = "<p>This cannot be rendered.</p>"
if sanitize_path(os.path.dirname(name)):
content += '<p>Back to <a href="/repo/'+sanitize_path(os.path.dirname(name))\
+'">'+os.path.dirname(name)+'</a></p>'
return template('templates/repo', content = content, \
title=filename)
else:
return static_file(unquote(name), root=conf['repo'])
# Return the static assets.
@route('/static/<name:path>')
def static(name=''):
return static_file(name, root='./static/')
# Traverse the repository
@route('/repo')
@route('/repo/')
@route('/repo/<name:path>')
def public(name=''):
repo = Repo(conf['repo'])
repo.git.pull()
tree = []
filename, extension = os.path.splitext(name)
filename = os.path.basename(filename)
path = os.path.join(conf['repo'], sanitize_path(name))
if os.path.exists(path):
if isdir(path) and not lower(extension) in conf['ext_bundles']:
tree.append('<ul>')
print "This is a regular dir: " + path
if not name == '':
n = name.rstrip('/')
l = split(n, '/')
tree.append('<li>')
if len(l) > 1:
tree.append('<a href="/repo/'+'/'.join(l[0:-1])+'">..</a>')
else:
tree.append('<a href="/repo/">..</a>')
tree.append('</li>')
dirs = []
files = []
for f in sorted(os.listdir(path)):
if not f.startswith('.') and not f.startswith('_'):
if isdir(os.path.join(path,f)):
dirs.append('<li>')
dirs.append('<a href="/repo/'+os.path.join(sanitize_path(name),f)+'">'+f+'</a>')
dirs.append('<a href="/move/'+os.path.join(sanitize_path(name),f)+'">(move)</a>')
dirs.append('<a href="/delete/'+os.path.join(sanitize_path(name),f)+'">(delete)</a>')
dirs.append('</li>')
else:
files.append('<li>')
files.append('<a href="/repo/'+os.path.join(sanitize_path(name),f)+'">'+f+'</a>')
False,e = os.path.splitext(f)
if e in conf['ext_edit']:
files.append('<a href="/edit/'+os.path.join(sanitize_path(name),f)+'">(edit)</a>')
files.append('<a href="/move/'+os.path.join(sanitize_path(name),f)+'">(move)</a>')
files.append('<a href="/delete/'+os.path.join(sanitize_path(name),f)+'">(delete)</a>')
files.append('</li>')
for d in dirs: tree.append(d)
for f in files: tree.append(f)
tree.append('</ul>')
tree.append('<p><a href="/upload/'+sanitize_path(name)+'">Upload</a> ')
tree.append('<a href="/new/'+sanitize_path(name)+'">New File</a> ')
tree.append('<a href="/mkdir/'+sanitize_path(name)+'">New Dir</a></p>')
return template('templates/repo', content="\n".join(tree), title="Files in "+sanitize_path(name))
else:
return render_file(name)
else:
return 'File does not exist.'
# Raw access to files.
@route('/raw/<path:path>')
def raw(path=False):
try:
return static_file(unquote(path),root=conf['repo'])
except:
return 'No such file'
# Uploading files.
@route('/upload/<path:path>', method="GET")
@route('/upload/', method="GET")
@route('/upload', method="GET")
def upload(path=''):
path = sanitize_path(path)
body = []
body.append('<style type="text/css">\
td.r { text-align: left; }\
td.c { text-align: center; }\
td.l { text-align: right; }\
</style>')
body.append('<h1>Upload a new file</h1>')
body.append('<form style="width:500px;" method="post" action="/upload" enctype="multipart/form-data">')
body.append('<table>')
body.append('<tr><td class="l"><label for="uploaded">Upload:</label></td>')
body.append('<td class="r"><input type="file" name="uploaded" /></td></tr>')
body.append('<tr><td class="l"><label for="path">Destination:</label></td>')
body.append('<td class="r"><input type="text" name="path" style="width:250px" ')
if not path == '':
body.append('value="'+path+'" ')
body.append('/></td></tr>')
body.append('<tr><td class="l"><label for="message">Commit Message</label></td>')
body.append('<td class="r"><textarea name="message" cols="50" rows="7"></textarea></td></tr>')
body.append('<tr><td class="c"><input type="submit" name="submit"></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/repo', content='\n'.join(body), \
title='Add')
@route('/upload', method="POST")
def do_upload():
repo = Repo(conf['repo'])
repo.git.pull()
path = request.forms.path
path = sanitize_path(path)
message = request.forms.message
u = request.files.uploaded
filename = u.filename
new_file = os.path.join(conf['repo'],path,filename)
if not os.path.exists(os.path.join(conf['repo'],path)):
os.mkdir(os.path.join(conf['repo'],path))
overwritten = False
if os.path.exists(new_file):
overwritten = True
w = open(new_file,'wb')
w.write(u.file.read())
w.close()
content = ['<p><a href="/repo/'+path+'/'+filename+'">' + filename + '</a> uploaded to\
<a href="/repo/'+path+'">/' + path + '</a>']
if overwritten:
content.append(' (original overwritten).</p>')
else:
content.append('.</p>')
if not overwritten or (overwritten and not repo.git.diff(new_file) == ""):
repo.git.add(new_file)
content.append("<p>Git: ")
commit_result = repo.git.commit(new_file,m=message)
repo.git.push()
content.append(commit_result)
content.append('</p>')
else:
content.append('<p>Git: file is not different.</p>')
content.append('<p><a href="/upload">Upload another.</a></p>')
return template('templates/repo', content='\n'.join(content), title='"'+filename+'" uploaded.')
# Deleting files.
@route('/delete', method="GET")
@route('/delete/<path:path>', method="GET")
def delete(path = ''):
body = []
path = sanitize_path(path)
body.append('<style type="text/css">\
td.r { text-align: left; }\
td.c { text-align: center; }\
td.l { text-align: right; }\
</style>')
body.append('<h1>Delete a file</h1>')
body.append('<form style="width:500px;" method="post" action="/delete" enctype="multipart/form-data">')
body.append('<table>')
body.append('<tr><td class="l"><label for="path">File to be deleted:</label></td>')
body.append('<td class="r"><input type="text" name="path" style="width:250px" ')
if path: body.append('value="'+path+'" ')
body.append('/></td></tr>')
body.append('<tr><td class="l"><label for="message">Commit Message</label></td>')
body.append('<td class="r"><textarea name="message" cols="50" rows="7"></textarea></td></tr>')
body.append('<tr><td><label for="delete">Do you really want to delete?</label></td>')
body.append('<td class="c"><input type="submit" name="delete" value="Yes."></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/repo', content='\n'.join(body), title='Delete')
@route('/delete', method='POST')
def delete():
body = []
repo = Repo(conf['repo'])
path = request.forms.path
path = sanitize_path(path)
directory,filename = os.path.split(path)
directory = '/'+directory
message = request.forms.message
result = False
repo.git.pull()
if os.path.exists(os.path.join(conf['repo'],path)):
try:
repo.git.rm(path, r=True)
result = repo.git.commit(path, m=message)
repo.git.push()
except:
if not isdir(os.path.join(conf['repo'],path)):
os.remove(os.path.join(conf['repo'],path))
body.append('<p>' + path + ' deleted from <a href="/repo'+directory+'">'+directory+'</a>.</p>')
if result: body.append('<p>Git: '+result+'</p>')
else:
body.append('<p>'+path+' does not exist.</p>')
return template('templates/repo', content='\n'.join(body), title=path+' deleted.')
# And if we want to edit a file?
@route('/edit/<path:path>', method='GET')
@route('/edit', method="GET")
def edit(path=''):
if not path and request.query.path:
path = request.query.path
path = sanitize_path(path)
body = []
if path:
full = os.path.join(conf['repo'],path)
False, ext = os.path.splitext(path)
if os.path.exists(full) and not isdir(full) and ext in conf['ext_edit']:
body.append('<style type="text/css">\
td.r { text-align: left; vertical-align:top;}\
td.c { text-align: center; }\
td.l { text-align: right; vertical-align:top;}\
</style>')
body.append('<h1>Editing '+ path +'</h1>')
body.append('<form style="width:500px;" method="post" action="/edit" enctype="multipart/form-data">')
body.append('<input type="hidden" name="path" value="'+path+'" />')
body.append('<table>')
body.append('<tr><td class="l"><label for="content">Content:</label></td>')
body.append('<td class="c" style="width:100%"><textarea name="content" cols="80" rows="80">')
with open(full,'r') as f: body.append(f.read())
body.append('</textarea></td></tr>')
body.append('<tr><td class="l"><label for="message">Commit Message</label></td>')
body.append('<td class="r"><textarea name="message" cols="50" rows="7"></textarea></td></tr>')
body.append('<tr><td class="c"><input type="submit" name="submit"></td></tr>')
body.append('</table>')
body.append('</form>')
else:
body.append('<p>Path does not exist or is not editable.')
else:
body.append('<h1>Edit a file</h1>')
body.append('<form style="width:500px;" method="get" action="/edit">')
body.append('<table>')
body.append('<tr><td><label for="path">File:</label></td>')
body.append('<td><input type="text" name="path" style="width:250px;" /></td></tr>')
body.append('<tr><td><input type="submit" /></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/repo', content='\n'.join(body), \
title='New')
@route('/edit', method='POST')
def edit():
repo = Repo(conf['repo'])
path = request.forms.path
content = request.forms.content
message = request.forms.message
full_path = os.path.join(conf['repo'],path)
repo.git.pull()
body = []
f = open(full_path, 'w')
f.write(content)
f.close()
if not repo.git.diff(path) == '':
commit = repo.git.commit(path,m=message)
repo.git.push()
body.append('<p><a href="/repo/'+path+'">' + path + '</a> edited.</p>')
body.append('<p>Git: ' + commit + '</p>')
else:
body.append('<p>' + path + ' not changed.</p>')
return template('templates/repo', content='\n'.join(body),\
title=path+' edited.')
# Let's add some functionality to make new files.
@route('/new', method='GET')
@route('/new/<path:path>', method='GET')
def new(path = ''):
path = sanitize_path(path)
body = []
body.append('<style type="text/css">\
td.r { text-align: left; vertical-align:top;}\
td.c { text-align: center; }\
td.l { text-align: right; vertical-align:top;}\
</style>')
body.append('<h1>Create a new file</h1>')
body.append('<form style="width:500px;" method="post" action="/new" enctype="multipart/form-data">')
body.append('<table>')
body.append('<tr><td class="l"><label for="name">Filename:</label></td>')
body.append('<td class="r"><input type="text" name="name" style="width:250px"/></td></tr>')
body.append('<tr><td class="l"><label for="path">Destination:</label></td>')
body.append('<td class="r"><input type="text" name="path" style="width:250px"')
if path: body.append('value="'+path+'" ')
body.append('/></td></tr>')
body.append('<tr><td class="l"><label for="content">Content:</label></td>')
body.append('<td class="c" style="width:100%"><textarea name="content" cols="80" rows="80"></textarea></td></tr>')
body.append('<tr><td class="l"><label for="message">Commit Message</label></td>')
body.append('<td class="r"><textarea name="message" cols="50" rows="7"></textarea></td></tr>')
body.append('<tr><td class="c"><input type="submit" name="submit"></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/repo', content='\n'.join(body), \
title='New')
@route('/new', method="POST")
def new():
filename = request.forms.name
directory = sanitize_path(request.forms.path)
content = request.forms.content
message = request.forms.message
full_path = os.path.join(conf['repo'], directory, filename)
w = open(full_path, 'w')
w.write(content)
w.close()
repo = Repo(conf['repo'])
repo.git.pull()
commit = False
overwritten = False
if os.path.exists(os.path.join(directory,filename)):
overwritten = True
diff = repo.git.diff(os.path.join(directory,filename))
if not overwritten or (overwritten and not diff == ''):
repo.git.add(os.path.join(directory, filename))
commit = repo.git.commit(os.path.join(directory, filename),m=message)
repo.git.push()
body = []
body.append('<p>'+filename+' added to <a href="/repo/'+directory+'">'+(directory if not directory == '' else '/')+'</a></p>')
if commit:
body.append('<p>Git: '+commit+'</p>')
return template('templates/repo', content='\n'.join(body), \
title=filename + ' created')
# Let's add in some functionality to move files.
@route('/move/<path:path>', method="GET")
@route('/move', method="GET")
def rename(path = ''):
body = []
path = sanitize_path(path)
body.append('<style type="text/css">\
td.r { text-align: left; vertical-align:top;}\
td.c { text-align: center; }\
td.l { text-align: right; vertical-align:top;}\
</style>')
body.append('<h1>Move</h1>')
body.append('<form style="width:500px;" method="post" action="/move" enctype="multipart/form-data">')
body.append('<table>')
body.append('<tr><td class="l"><label for="name">Current:</label></td>')
body.append('<td class="r"><input type="text" name="current" style="width:250px"')
if path: body.append(' value="'+path+'" ')
body.append('/></td></tr>')
body.append('<tr><td class="l"><label for="path">Destination:</label></td>')
body.append('<td class="r"><input type="text" name="destination" style="width:250px"/></td></tr>')
body.append('<tr><td class="l"><label for="message">Commit Message</label></td>')
body.append('<td class="r"><textarea name="message" cols="50" rows="7"></textarea></td></tr>')
body.append('<tr><td class="c"><input type="submit" name="submit"></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/repo', content='\n'.join(body),\
title='move')
@route('/move', method="POST")
def rename():
current = os.path.join(conf['repo'],sanitize_path(request.forms.current))
new = os.path.join(conf['repo'],sanitize_path(request.forms.destination))
message = request.forms.message
body = []
if current and new:
if os.path.exists(current):
if not os.path.exists(new):
repo = Repo(conf['repo'])
repo.git.pull()
repo.git.mv(current,new)
if not message: message = datetime.now().isoformat()
commit = repo.git.commit(current,new,m=message)
repo.git.push()
body.append('<p>'+request.forms.current+' moved to '\
+request.forms.destination+'.</p>')
body.append('<p>Git: '+commit+'</p>')
else:
body.append('<p>'+request.forms.destination+' already exists.</p>')
else:
body.append('<p>'+request.forms.current+' does not exist.</p>')
else:
body.append('<p>Must have both a current and new name.</p>')
return template('templates/repo', content='\n'.join(body),\
title=request.forms.current+' moved to '+request.forms.destination)
# What if we want to make a new directory?
@route('/mkdir/<path:path>', method="GET")
@route('/mkdir', method="GET")
def mkdir(path=''):
body = []
path = sanitize_path(path)
body.append('<style type="text/css">\
td.r { text-align: left; vertical-align:top;}\
td.c { text-align: center; }\
td.l { text-align: right; vertical-align:top;}\
</style>')
body.append('<h1>Create Directory</h1>')
body.append('<form style="width:500px;" method="post" action="/mkdir" enctype="multipart/form-data">')
body.append('<table>')
body.append('<tr><td class="l"><label for="name">Name:</label></td>')
body.append('<td class="r"><input type="text" name="path" style="width:250px"')
if path: body.append(' value="'+path+'" ')
body.append('/></td></tr>')
body.append('<tr><td class="c"><input type="submit" name="submit"></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/repo', content='\n'.join(body),\
title='Create Directory')
@route('/mkdir', method="POST")
def mkdir():
body = []
path = request.forms.path
path = sanitize_path(path)
if not os.path.exists(os.path.join(conf['repo'],path)):
os.mkdir(os.path.join(conf['repo'],path))
if isdir(os.path.join(conf['repo'],path)):
body.append('<p><a href="/repo/'+path+'">' + path + '</a> created.</p>')
else:
body.append('<p>Directory could not be created</p>')
else:
body.append('<p>Path exists.</p>')
return template('templates/repo', content='\n'.join(body),\
title='Create Directory')
# Let's build in the url shortening functionality.
@get('/short/<short>')
def short(short = ''):
body = []
if short:
query = 'SELECT url,public FROM short WHERE `key` = "'+short+'" LIMIT 1;'
cursor.execute(query)
url = cursor.fetchone()
if url:
redirect(url[0])
@get('/short/')
@get('/short')
def mkshort(short = ''):
body = []
body.append("<h3>Create Shortened URL.</h3>")
body.append('<form method="POST" action="/short">')
body.append('<input type="submit">')
body.append('</form>')
return template('templates/public', content='\n'.join(body),\
title='Create Shortened URL' + short)
# Let's make a place to store my secrets
# A big list of secrets, need a special password'
@post('/secrets/list')
@get('/secrets/list')
@get('/secrets/list/')
def secret_list(path = ''):
body = []
if request.forms.password == "allyourbasearebelongtous":
secrets = get_secrets()
for s in secrets:
body.append(s[0]+': '+s[1]+' | '+s[2])
body.append('<a href="/secrets/trash/'+str(s[3])+'">(x)</a>')
body.append('<br/>')
else:
body.append('<form method="post" action="/secrets/list" />')
body.append('<p>Are you sure?</p>')
body.append('<table>')
body.append('<tr><td>Password:</td>')
body.append('<td><input type="password" name="password" /></td></tr>')
body.append('<td><td><input type="submit" /></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/secret', content = '\n'.join(body), title = 'Secrets List')
# Show the secrets associated with a specific site.
@get('/secrets/show/<url>')
@get('/secrets/show/')
@get('/secrets/show')
def secret_lookup(url = False):
body = []
if url:
secrets = get_secrets(url)
for s in secrets:
body.append(s[0]+': '+s[1]+' | '+s[2])
body.append('<a href="/secrets/trash/'+str(s[3])+'">(x)</a>')
body.append('<br/>')
else:
body.append('Must provide a url.')
return template('templates/secret', content = '\n'.join(body), title = 'Secrets for ' + url)
# A form for trashing secrets.
@get('/secrets/trash/<key>')
@get('/secrets/trash/')
@get('/secrets/trash')
def secret_trash(key=False):
body = []
body.append('<form method="post" action="/secrets/trash/" >')
body.append('<p>Trash a secret</p>')
body.append('<table>')
body.append('<tr><td><label for="id">Secret id</label></td>')
body.append('<td><input name="id" ')
if key: body.append('value="'+key+'" ')
body.append('/></td></tr>')
body.append('<tr><td><input type="submit" /></td></tr>')
body.append('</table>')
return template('templates/secret', content = '\n'.join(body), title = 'Trash Secret')
# Actually trashing secrets.
@post('/secrets/trash')
@post('/secrets/trash/')
def secret_trash():
#query = 'SELECT base_url,username,password,id FROM `secrets` WHERE base_url LIKE "%' + url + '";'
#cursor.execute(query)
#secrets = cursor.fetchall()
original = 'SELECT id FROM `secrets` WHERE id = "' + str(request.forms.id) + '" LIMIT 1'
copy = 'INSERT INTO `secrets_trash` SELECT * FROM `secrets` WHERE id = "' + str(request.forms.id) + '"'
check = 'SELECT * FROM `secrets_trash` INNER JOIN `secrets` ON (secrets_trash.base_url = secrets.base_url AND secrets_trash.username = secrets.username AND secrets_trash.password = secrets.password)'
delete = 'DELETE FROM `secrets` WHERE id = "' + str(request.forms.id) + '" LIMIT 1'
body = []
if cursor.execute(original):
body.append('<p>Record exists.</p>')
cursor.execute(copy)
body.append('<p>Record copied.</p>')
if cursor.execute(check):
body.append('<p>Duplicate records exist.</p>')
cursor.execute(delete)
body.append('<p>Original record deleted.</p>')
if not cursor.execute(original):
body.append('<p>Original record does not exist.</p>')
body.append('<p>Record ' + str(request.forms.id) + ' trashed.</p>')
else:
body.append('<p>No such record.</p>')
return template('templates/secret', content = '\n'.join(body), title = 'Secret ' + str(request.forms.id) + ' trashed.')
# Create a new secret.
@get('/secrets/create/<url>')
@get('/secrets/create/')
@get('/secrets/create')
def secrets_create(url = False):
body = []
body.append('<h3>Create Secret</h3>')
body.append('<form method="POST" action="/secrets/create">')
body.append('<table>')
body.append('<tr><td><label for="url">URL:</label></td>')
body.append('<td><input name="url" ')
if url: body.append('value="'+url+'" ')
body.append('/></td></tr>')
body.append('<tr><td><label for="username">Username:</label></td>')
body.append('<td><input name="username" /></td></tr>')
body.append('<tr><td><label for="password">Password:</label></td>')
body.append('<td><input type="password" name="password" ')
if url: body.append('value="'+get_generated(url)+'" ')
body.append('/></td></tr>')
body.append('<tr><td><input type="submit" /></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/secret', content='\n'.join(body), title = 'Create Secret')
# Create a new secret
@post('/secrets/create')
def create_secret():
body = []
query = 'INSERT INTO secrets (base_url, username, password) VALUES (' +\
'"'+request.forms.url+'", '+\
'"'+request.forms.username+'", '+\
'"'+request.forms.password+'")'
print query
if cursor.execute(query):
body.append('<p>Secret created.</p>')
body.append('<p>View secrets for <a href="/secrets/show/'+\
request.forms.url+'">'+request.forms.url+'</a>.</p>')
else:
body.append('Secret could not be created.')
return template('templates/secret', content='\n'.join(body), title = 'Create Secret')
@get('/secrets/overlay/<url>')
def secret_overlay(url):
body = []
body.append('<p>Secrets for: '+url+'</p>')
secrets = get_secrets(url)
for s in secrets:
body.append(s[0] + ': ' + s[1] + ' | ' + s[2] + '<br/>')
gen = get_generated(url)
body.append('<p>Generated: ' + gen + '</p>')
body.append('<form method="POST" action="/secrets/create" target="_blank">')
body.append('<table>')
body.append('<tr><td>URL:</td><td><input name="base_url" value="'+url+'" /></td></tr>')
body.append('<tr><td>U:</td><td><input name="username" /></td></tr>')
body.append('<tr><td>P:</td><td><input name="password" type="password" value="'+gen+'" /></td></tr>')
body.append('<tr><td><input type="submit" /></td></tr>')
body.append('</table>')
body.append('</form>')
return template('templates/overlay', content='\n'.join(body), title = url + ' overlay')
# An API will be needed for bookmarklets and whatnot.
@route('/api')
def api():
return 'Someday there will be an API here.'
# Do something with the home page.
@route('/')
def index():
redirect('/repo')
application = bottle.default_app()
if __name__ == "__main__":
bottle.debug(True)
conf['repo'] = os.path.expanduser('~/dev/repo')
run(host='0.0.0.0', port=8000, reloader=True)