Compare commits
10 commits
71441f42ff
...
9017cddbce
Author | SHA1 | Date | |
---|---|---|---|
9017cddbce | |||
22efbe5929 | |||
58ba4ca769 | |||
f235cc8af4 | |||
daff5c46ca | |||
f6a2e30ce0 | |||
ee63abc16c | |||
c700bf798e | |||
4ee5a22e90 | |||
0b13da0e6c |
11 changed files with 556 additions and 62 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@
|
|||
*.pyc
|
||||
*.pid
|
||||
*.log
|
||||
.unison*
|
||||
|
|
491
brain.py
491
brain.py
|
@ -1,28 +1,191 @@
|
|||
import os, sys
|
||||
from git import *
|
||||
import bottle
|
||||
from bottle import default_app, route, run, request, template, static_file, redirect
|
||||
from bottle import default_app, get, post, route, run, request, template, static_file, redirect
|
||||
from os.path import isdir
|
||||
from string import lower, split
|
||||
from urllib import unquote
|
||||
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']
|
||||
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>')
|
||||
|
@ -84,58 +247,18 @@ def public(name=''):
|
|||
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/yield', content="\n".join(tree), title="Files in "+sanitize_path(name))
|
||||
return template('templates/repo', content="\n".join(tree), title="Files in "+sanitize_path(name))
|
||||
|
||||
else:
|
||||
|
||||
if isdir(path) and lower(extension) in conf['ext_bundles']:
|
||||
|
||||
print "This is a bundle: " + sanitize_path(name)
|
||||
|
||||
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']:
|
||||
|
||||
print "This is a render: " + sanitize_path(name)
|
||||
|
||||
try:
|
||||
Image.open(path)
|
||||
content = '<img 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> - \
|
||||
<a href="/raw/'+sanitize_path(name)+'">Raw</a></p>'
|
||||
|
||||
except:
|
||||
content = "<p>This cannot be rendered.</p>"
|
||||
|
||||
|
||||
return template('templates/yield', content = content, \
|
||||
title=filename+extension)
|
||||
|
||||
else:
|
||||
|
||||
print "This is a file: " + unquote(name)
|
||||
|
||||
return static_file(unquote(name), root=conf['repo'])
|
||||
return render_file(name)
|
||||
|
||||
else:
|
||||
|
||||
return 'File does not exist.'
|
||||
|
||||
|
||||
# Raw access to files.
|
||||
|
||||
@route('/raw/<path:path>')
|
||||
def raw(path=False):
|
||||
try:
|
||||
|
@ -144,7 +267,10 @@ def raw(path=False):
|
|||
return 'No such file'
|
||||
|
||||
|
||||
@route('/upload/:path', method="GET")
|
||||
|
||||
# Uploading files.
|
||||
|
||||
@route('/upload/<path:path>', method="GET")
|
||||
@route('/upload/', method="GET")
|
||||
@route('/upload', method="GET")
|
||||
def upload(path=''):
|
||||
|
@ -176,7 +302,7 @@ def upload(path=''):
|
|||
body.append('</form>')
|
||||
|
||||
|
||||
return template('templates/yield', content='\n'.join(body), \
|
||||
return template('templates/repo', content='\n'.join(body), \
|
||||
title='Add')
|
||||
|
||||
|
||||
|
@ -228,9 +354,12 @@ def do_upload():
|
|||
|
||||
content.append('<p><a href="/upload">Upload another.</a></p>')
|
||||
|
||||
return template('templates/yield', content='\n'.join(content), title='"'+filename+'" uploaded.')
|
||||
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 = ''):
|
||||
|
@ -260,7 +389,7 @@ def delete(path = ''):
|
|||
body.append('</table>')
|
||||
body.append('</form>')
|
||||
|
||||
return template('templates/yield', content='\n'.join(body), title='Delete')
|
||||
return template('templates/repo', content='\n'.join(body), title='Delete')
|
||||
|
||||
|
||||
@route('/delete', method='POST')
|
||||
|
@ -293,9 +422,12 @@ def delete():
|
|||
body.append('<p>'+path+' does not exist.</p>')
|
||||
|
||||
|
||||
return template('templates/yield', content='\n'.join(body), title=path+' deleted.')
|
||||
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=''):
|
||||
|
@ -344,7 +476,7 @@ def edit(path=''):
|
|||
body.append('</table>')
|
||||
body.append('</form>')
|
||||
|
||||
return template('templates/yield', content='\n'.join(body), \
|
||||
return template('templates/repo', content='\n'.join(body), \
|
||||
title='New')
|
||||
|
||||
|
||||
|
@ -378,9 +510,14 @@ def edit():
|
|||
else:
|
||||
body.append('<p>' + path + ' not changed.</p>')
|
||||
|
||||
return template('templates/yield', content='\n'.join(body),\
|
||||
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 = ''):
|
||||
|
@ -413,7 +550,7 @@ def new(path = ''):
|
|||
body.append('</form>')
|
||||
|
||||
|
||||
return template('templates/yield', content='\n'.join(body), \
|
||||
return template('templates/repo', content='\n'.join(body), \
|
||||
title='New')
|
||||
|
||||
@route('/new', method="POST")
|
||||
|
@ -450,10 +587,14 @@ def new():
|
|||
if commit:
|
||||
body.append('<p>Git: '+commit+'</p>')
|
||||
|
||||
return template('templates/yield', content='\n'.join(body), \
|
||||
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 = ''):
|
||||
|
@ -483,7 +624,7 @@ def rename(path = ''):
|
|||
body.append('</form>')
|
||||
|
||||
|
||||
return template('templates/yield', content='\n'.join(body),\
|
||||
return template('templates/repo', content='\n'.join(body),\
|
||||
title='move')
|
||||
|
||||
@route('/move', method="POST")
|
||||
|
@ -518,9 +659,15 @@ def rename():
|
|||
else:
|
||||
body.append('<p>Must have both a current and new name.</p>')
|
||||
|
||||
return template('templates/yield', content='\n'.join(body),\
|
||||
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=''):
|
||||
|
@ -545,7 +692,7 @@ def mkdir(path=''):
|
|||
body.append('</form>')
|
||||
|
||||
|
||||
return template('templates/yield', content='\n'.join(body),\
|
||||
return template('templates/repo', content='\n'.join(body),\
|
||||
title='Create Directory')
|
||||
|
||||
@route('/mkdir', method="POST")
|
||||
|
@ -565,15 +712,236 @@ def mkdir():
|
|||
body.append('<p>Path exists.</p>')
|
||||
|
||||
|
||||
return template('templates/yield', content='\n'.join(body),\
|
||||
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')
|
||||
|
@ -583,5 +951,6 @@ def index():
|
|||
application = bottle.default_app()
|
||||
|
||||
if __name__ == "__main__":
|
||||
bottle.debug(True)
|
||||
conf['repo'] = os.path.expanduser('~/dev/repo')
|
||||
run(host="127.0.0.1", port=8000, reloader=True)
|
||||
run(host='0.0.0.0', port=8000, reloader=True)
|
||||
|
|
9
serve.sh
Executable file
9
serve.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
while [ 1 ]
|
||||
do
|
||||
echo "Starting server."
|
||||
python brain.py
|
||||
echo "Server died.\nSleeping for 5 seconds."
|
||||
sleep 5
|
||||
done
|
15
static/brain.css
Normal file
15
static/brain.css
Normal file
|
@ -0,0 +1,15 @@
|
|||
body, table {
|
||||
background-color: #CCC;
|
||||
color: #3c3c3c;
|
||||
font-family: Helvetica;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #3c3c3c;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #800;
|
||||
}
|
||||
|
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
77
static/overlay.js
Normal file
77
static/overlay.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
(function() {
|
||||
function cleanHouse() {
|
||||
elements = document.querySelectorAll('.myS');
|
||||
for (i=0; i<elements.length; i++) {
|
||||
elements[i].parentNode.removeChild(elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
cleanHouse();
|
||||
|
||||
s=document.createElement('style');
|
||||
s.id='myS-style';
|
||||
s.type='text/css';
|
||||
s.className+='myS';
|
||||
s.innerHTML='\
|
||||
.myS{\
|
||||
font-family:Georgia;\
|
||||
color:#3C3C3C;\
|
||||
text-align:center;\
|
||||
text-size:14px;\
|
||||
}\
|
||||
.myS iframe {\
|
||||
border: none;\
|
||||
}\
|
||||
.myS p {\
|
||||
color:#3C3C3C;\
|
||||
padding:10px;\
|
||||
}\
|
||||
.myS a {\
|
||||
text-decoration:none;\
|
||||
color:#3C3C3C;\
|
||||
}\
|
||||
.myS a:hover{\
|
||||
text-decoration:underline;\
|
||||
}\
|
||||
.myS a.close:hover {\
|
||||
border:1px solid #F00;\
|
||||
text-decoration:none;\
|
||||
color:#F00;\
|
||||
}\
|
||||
';
|
||||
document.body.appendChild(s);
|
||||
|
||||
o=document.createElement('div');
|
||||
o.id='myS-overlay';
|
||||
o.className+='myS';
|
||||
o.style.position='fixed';
|
||||
o.style.left=o.style.right=o.style.top=o.style.bottom='0%';
|
||||
o.style.zIndex='1337';
|
||||
o.style.backgroundColor='rgba(0,0,0,0.7)';
|
||||
document.body.appendChild(o);
|
||||
|
||||
i=document.createElement('div');
|
||||
i.id='myS-inner';
|
||||
i.className+='myS';
|
||||
i.style.position='relative';
|
||||
i.style.margin='0em auto';
|
||||
i.style.marginTop='20px';
|
||||
i.style.backgroundColor='rgba(255,255,255,1)';
|
||||
o.appendChild(i);
|
||||
|
||||
f=document.createElement('iframe');
|
||||
f.id='myS-iframe';
|
||||
f.className+='myS';
|
||||
f.width=320;
|
||||
f.height=320;
|
||||
f.style.overflow='auto';
|
||||
f.src='https://amdavidson.net/secrets/overlay/'+document.domain;
|
||||
i.appendChild(f);
|
||||
|
||||
e=document.createElement('p');
|
||||
e.className+='myS';
|
||||
e.onclick=function(){cleanHouse();};
|
||||
e.innerHTML='<a style="font-size:10pt;" class="myS close">Close</a>';
|
||||
i.appendChild(e);
|
||||
|
||||
})();
|
|
@ -1,6 +1,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>{{title or 'myStuff'}}</title>
|
||||
<link rel="shortcut icon" href="/static/favicon.ico" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/brain.css" />
|
||||
</head>
|
||||
<body>
|
||||
%include
|
||||
|
|
15
templates/overlay.tpl
Normal file
15
templates/overlay.tpl
Normal file
|
@ -0,0 +1,15 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>{{title or 'myStuff'}}</title>
|
||||
<link rel="shortcut icon" href="/static/favicon.ico" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/brain.css" />
|
||||
<style type="text/css">
|
||||
body, table {
|
||||
background: #FFF !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{!content}}
|
||||
</body>
|
||||
</html>
|
3
templates/public.tpl
Normal file
3
templates/public.tpl
Normal file
|
@ -0,0 +1,3 @@
|
|||
{{!content}}
|
||||
|
||||
%rebase templates/layout title=title
|
|
@ -1,5 +1,5 @@
|
|||
{{!content}}
|
||||
|
||||
<p><a href="/repo">Back to Repo</a></p>
|
||||
<p>Back to <a href="/repo">Repo</a></p>
|
||||
|
||||
%rebase templates/layout title=title
|
3
templates/secret.tpl
Normal file
3
templates/secret.tpl
Normal file
|
@ -0,0 +1,3 @@
|
|||
{{!content}}
|
||||
|
||||
%rebase templates/layout title=title
|
Loading…
Reference in a new issue