Initial commit

This commit is contained in:
Kienan Stewart 2020-04-18 23:38:31 -04:00
commit 5ada93a0a4
15 changed files with 2482 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
negotiation.db
__pycache__

13
README.md Normal file
View File

@ -0,0 +1,13 @@
# Installlation
## Prerequisites
apt install python3-flask python3-pony
## Running
FLASK_DEBUG=1 FLASK_APP=negotiation.py ./negotiation.py
# License
AGPLv3+

6
credits.md Normal file
View File

@ -0,0 +1,6 @@
WIP credits:
* Banner image from https://benjaminhuen.blogspot.com/2010/12/spetch-dump.html
* Icon from https://opengameart.org/content/700-rpg-icons
* NordSudA font from https://fontlibrary.org/en/font/nord-sud
* Theme modified from https://github.com/arulrajnet/attila

139
negotiation.py Executable file
View File

@ -0,0 +1,139 @@
#!/usr/bin/env python3
import os
import random
import urllib
import uuid
import flask
import pony
from pony.flask import Pony
word_file = "/usr/share/dict/words"
WORDS = open(word_file).read().splitlines()
app = flask.Flask(__name__)
db = None
@app.route('/')
@pony.orm.db_session
def index():
r = flask.Response()
uid, user = get_uid(r)
negotiations = pony.orm.select(n for n in Negotiation if n.owner == user)
suggestion = suggest_unused_name()
r.data = render_page('index.html', {
'negotiations': list(negotiations),
'suggestion': suggestion,
})
return r
@pony.orm.db_session
def get_uid(r, create = True):
"""
Returns a tuple (uid, created) where created is true
if the user was new.
r is the flask response, so that the cookie uid may be set if necessary.
"""
uid = flask.request.cookies.get('uid')
if not uid:
if create:
uid = generate_uid()
r.set_cookie('uid', uid)
else:
return None, None
user = pony.orm.select(u for u in User if u.uid == uid).first()
if not user:
# Recreate the database user if it doesn't exist
user = User(uid = uid)
return uid, user
@app.route('/negotiation/create', methods = ['POST'])
@pony.orm.db_session
def negotiation_create():
n = flask.request.form.get('negotiation')
uid, user = get_uid(None, False)
if not uid or not user:
return flask.redirect('/') # @TODO Signal error to user. They don't have a uid cookie
if len(n) > 128:
return flask.redirect('/') # @TODO Signal error to user. Request too Large
if pony.orm.exists(nego for nego in Negotiation if nego.name == n):
# @TODO Signal to the user that the negotiation already exists and they
# are being sent to it instead.
return flask.redirect('/negotiations/{}'.format(n))
nego = Negotiation(name = n, owner = user.id)
pony.orm.commit()
return flask.redirect('/negotiations/{}'.format(n))
@app.route('/negotiations/')
def negotiation_redir():
return flask.redirect('/')
@app.route('/negotiations/<negotiation>')
def negotiation(negotiation):
r = flask.Response()
uid = get_uid(r)
return "{}".format(negotiation)
@pony.orm.db_session
def generate_uid():
while True:
uid = str(uuid.uuid4())
if pony.orm.exists(u for u in User if u.uid == uid):
continue
u = User(uid = uid)
pony.orm.commit()
return uid
@pony.orm.db_session
def suggest_unused_name():
tries = 0;
while True:
tries += 1
w = "{}{}{}{}".format(
random.choice(WORDS).title(),
random.choice(WORDS).title(),
random.choice(WORDS).title(),
random.choice(WORDS).title()
)
if not w.isalpha():
continue
if pony.orm.exists(n.name for n in Negotiation if n.name == w):
continue
app.logger.info('Took {} tries to generate a room suggestion'.format(tries))
return w
def render_page(template, context):
app_context = {
'LANGUAGE': flask.request.cookies.get('language')
if flask.request.cookies.get('language') else app.config['DEFAULT_LANGUAGE'],
}
context = {**context, **app_context}
return flask.render_template(template, **context)
if __name__ == '__main__':
port = os.environ.get('APP_PORT', 5000)
appkey = os.environ.get('APP_KEY', 'test')
bindaddr = os.environ.get('APP_BINDADDRESS', '127.0.0.1')
app.secret_key = appkey
app.config.update(dict(
PONY = {
'provider': 'sqlite',
'filename': 'negotiation.db',
'create_db': True,
},
DEFAULT_LANGUAGE = 'en',
))
db = pony.orm.Database()
class User(db.Entity):
uid = pony.orm.Required(str)
display_name = pony.orm.Optional(str)
negotiations = pony.orm.Set('Negotiation')
class Negotiation(db.Entity):
name = pony.orm.PrimaryKey(str)
owner = pony.orm.Required(User)
db.bind(**app.config['PONY'])
db.generate_mapping(create_tables=True)
Pony(app)
app.run(host = bindaddr, port = port)

View File

@ -0,0 +1,80 @@
/*
Monokai Pygments Theme
*/
pre {
white-space: pre;
overflow: auto;
word-wrap: normal; /* horizontal scrolling */
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
padding: 20px;
background: #343642;
color: #C1C2C3;
}
.hll { background-color: #49483e }
.c { color: #75715e } /* Comment */
.err { color: #960050; background-color: #1e0010 } /* Error */
.k { color: #66d9ef } /* Keyword */
.l { color: #ae81ff } /* Literal */
.n { color: #f8f8f2 } /* Name */
.o { color: #f92672 } /* Operator */
.p { color: #f8f8f2 } /* Punctuation */
.cm { color: #75715e } /* Comment.Multiline */
.cp { color: #75715e } /* Comment.Preproc */
.c1 { color: #75715e } /* Comment.Single */
.cs { color: #75715e } /* Comment.Special */
.ge { font-style: italic } /* Generic.Emph */
.gs { font-weight: bold } /* Generic.Strong */
.kc { color: #66d9ef } /* Keyword.Constant */
.kd { color: #66d9ef } /* Keyword.Declaration */
.kn { color: #f92672 } /* Keyword.Namespace */
.kp { color: #66d9ef } /* Keyword.Pseudo */
.kr { color: #66d9ef } /* Keyword.Reserved */
.kt { color: #66d9ef } /* Keyword.Type */
.ld { color: #e6db74 } /* Literal.Date */
.m { color: #ae81ff } /* Literal.Number */
.s { color: #e6db74 } /* Literal.String */
.na { color: #a6e22e } /* Name.Attribute */
.nb { color: #f8f8f2 } /* Name.Builtin */
.nc { color: #a6e22e } /* Name.Class */
.no { color: #66d9ef } /* Name.Constant */
.nd { color: #a6e22e } /* Name.Decorator */
.ni { color: #f8f8f2 } /* Name.Entity */
.ne { color: #a6e22e } /* Name.Exception */
.nf { color: #a6e22e } /* Name.Function */
.nl { color: #f8f8f2 } /* Name.Label */
.nn { color: #f8f8f2 } /* Name.Namespace */
.nx { color: #a6e22e } /* Name.Other */
.py { color: #f8f8f2 } /* Name.Property */
.nt { color: #f92672 } /* Name.Tag */
.nv { color: #f8f8f2 } /* Name.Variable */
.ow { color: #f92672 } /* Operator.Word */
.w { color: #f8f8f2 } /* Text.Whitespace */
.mf { color: #ae81ff } /* Literal.Number.Float */
.mh { color: #ae81ff } /* Literal.Number.Hex */
.mi { color: #ae81ff } /* Literal.Number.Integer */
.mo { color: #ae81ff } /* Literal.Number.Oct */
.sb { color: #e6db74 } /* Literal.String.Backtick */
.sc { color: #e6db74 } /* Literal.String.Char */
.sd { color: #e6db74 } /* Literal.String.Doc */
.s2 { color: #e6db74 } /* Literal.String.Double */
.se { color: #ae81ff } /* Literal.String.Escape */
.sh { color: #e6db74 } /* Literal.String.Heredoc */
.si { color: #e6db74 } /* Literal.String.Interpol */
.sx { color: #e6db74 } /* Literal.String.Other */
.sr { color: #e6db74 } /* Literal.String.Regex */
.s1 { color: #e6db74 } /* Literal.String.Single */
.ss { color: #e6db74 } /* Literal.String.Symbol */
.bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
.vc { color: #f8f8f2 } /* Name.Variable.Class */
.vg { color: #f8f8f2 } /* Name.Variable.Global */
.vi { color: #f8f8f2 } /* Name.Variable.Instance */
.il { color: #ae81ff } /* Literal.Number.Integer.Long */
.gh { } /* Generic Heading & Diff Header */
.gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
.gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
.gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */

1971
static/css/style.css Normal file

File diff suppressed because one or more lines are too long

BIN
static/font/icons.eot Normal file

Binary file not shown.

22
static/font/icons.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Copyright (C) 2015 by original authors @ fontello.com</metadata>
<defs>
<font id="icons" horiz-adv-x="1000" >
<font-face font-family="icons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
<missing-glyph horiz-adv-x="1000" />
<glyph glyph-name="ic-star" unicode="&#xe800;" d="m528 850c0 0 158-333 158-333 0 0 371-45 371-45 0 0-273-251-273-251 0 0 71-361 71-361 0 0-327 178-327 178 0 0-326-178-326-178 0 0 71 361 71 361 0 0-273 251-273 251 0 0 370 45 370 45 0 0 158 333 158 333z" horiz-adv-x="1057" />
<glyph glyph-name="ic-rss" unicode="&#xe801;" d="m133 117c-73 0-133-60-133-133 0-74 60-133 133-133 74 0 133 59 133 133 0 73-59 133-133 133z m-133 393c0 0 0-191 0-191 125 0 242-49 331-138 88-88 137-206 137-331 0 0 192 0 192 0 0 364-296 660-660 660z m0 340c0 0 0-192 0-192 446 0 808-362 808-808 0 0 192 0 192 0 0 551-448 1000-1000 1000z" horiz-adv-x="1000" />
<glyph glyph-name="ic-posts" unicode="&#xe802;" d="m0-150c0 0 0 1000 0 1000 0 0 586 0 586 0 0 0 200-199 200-199 0 0 0-801 0-801 0 0-786 0-786 0z m571 914c0 0 0-128 0-128 0 0 129 0 129 0 0 0-129 128-129 128z m143-200c0 0-214 0-214 0 0 0 0 215 0 215 0 0-429 0-429 0 0 0 0-858 0-858 0 0 643 0 643 0 0 0 0 643 0 643z m-71-178c0 0-500 0-500 0 0 0 0 71 0 71 0 0 500 0 500 0 0 0 0-71 0-71z m0-143c0 0-500 0-500 0 0 0 0 71 0 71 0 0 500 0 500 0 0 0 0-71 0-71z m-143-143c0 0-357 0-357 0 0 0 0 71 0 71 0 0 357 0 357 0 0 0 0-71 0-71z" horiz-adv-x="786" />
<glyph glyph-name="ic-location" unicode="&#xe803;" d="m349 850c-192 0-349-156-349-347 0-184 317-615 330-633 0 0 13-17 13-17 1-2 4-3 6-3 3 0 5 1 7 3 0 0 12 17 12 17 14 18 331 449 331 633 0 191-157 347-350 347z m0-223c69 0 125-55 125-124 0-69-56-124-125-124-69 0-125 55-125 124 0 69 56 124 125 124z" horiz-adv-x="698" />
<glyph glyph-name="ic-link" unicode="&#xe804;" d="m366 57c0 0-50-51-50-51-44-43-116-43-159 0-21 21-33 49-33 79 0 29 12 57 33 78 0 0 186 185 186 185 38 38 111 94 164 42 24-24 64-24 88 0 24 24 24 64-1 88-90 89-223 72-338-42 0 0-187-185-187-185-44-45-69-104-69-166 0-63 25-122 69-167 46-45 107-68 167-68 61 0 121 23 167 68 0 0 51 51 51 51 24 24 24 63 0 87-24 25-63 25-88 1z m565 717c-97 96-232 102-321 13 0 0-64-63-64-63-24-24-24-63 0-87 24-25 64-25 88-1 0 0 63 63 63 63 46 46 107 27 146-12 22-21 33-49 33-79 0-29-11-57-33-78 0 0-198-197-198-197-91-90-134-48-152-30-24 24-63 24-88 0-24-24-24-64 1-88 41-41 89-62 139-62 61 0 126 31 187 92 0 0 199 197 199 197 44 45 69 104 69 166 0 63-25 122-69 166z" horiz-adv-x="1000" />
<glyph glyph-name="ic-googleplus" unicode="&#xe805;" d="m978 619c0 0-110 0-110 0-12 0-22-10-22-22 0 0 0-110 0-110 0-12-10-22-22-22 0 0-33 0-33 0-12 0-22 10-22 22 0 0 0 110 0 110 0 12-10 22-22 22 0 0-110 0-110 0-12 0-22 10-22 22 0 0 0 33 0 33 0 12 10 22 22 22 0 0 110 0 110 0 12 0 22 10 22 22 0 0 0 110 0 110 0 12 10 22 22 22 0 0 33 0 33 0 12 0 22-10 22-22 0 0 0-110 0-110 0-12 10-22 22-22 0 0 110 0 110 0 12 0 22-10 22-22 0 0 0-33 0-33 0-12-10-22-22-22z m-359 220c0 0-43-25-43-25-10-7-29-12-41-12 0 0-37 0-37 0-12 0-14-5-4-12 20-17 36-38 48-63 16-33 24-67 24-102 0-29-5-56-14-79-9-23-21-41-34-55-13-14-26-27-40-39-13-12-24-24-33-37-9-12-14-26-14-40 0-11 3-21 10-31 6-10 15-20 26-29 10-9 22-19 35-29 13-10 25-21 38-33 13-12 25-25 35-40 11-14 20-31 26-51 7-20 10-41 10-64 0-64-28-120-84-169-61-53-145-79-252-79-24 0-48 2-72 6-24 4-49 11-73 20-25 10-47 21-66 35-18 14-34 32-46 53-12 22-18 47-18 74 0 24 8 51 22 81 13 25 32 47 58 66 26 19 55 33 87 43 33 10 64 17 93 21 23 4 45 6 68 8 13 0 16 8 10 18-17 27-26 50-26 72 0 5 0 10 1 14 1 5 2 9 3 12 1 3 3 7 5 13 1 2 2 4 2 6 1 4-7 5-19 5-7-1-14-1-21-1-60 0-111 19-153 59-43 39-64 88-64 147 0 56 19 107 57 151 38 44 85 72 140 85 38 8 75 12 113 12 0 0 240 0 240 0 12 0 14-5 3-11z m-326-622c-21-3-43-8-65-15-23-7-42-16-59-27-17-12-31-27-41-45-11-19-17-41-17-65 0-27 7-51 22-73 14-21 32-38 56-50 23-13 47-22 72-28 25-6 51-9 76-9 24 0 46 3 68 8 21 5 41 13 60 23 19 11 34 26 45 44 11 19 16 41 16 67 0 8 0 16-2 24-2 8-4 15-6 22-2 6-5 13-10 20-5 8-10 14-13 19-3 5-9 11-16 17-7 7-13 12-17 16-3 3-10 8-19 15-9 7-15 11-18 14-4 2-10 7-20 14-4 2-7 4-9 6-5 3-16 7-25 7-4 0-9 0-15 0-21 0-42-1-63-4z m151 424c-6 27-16 53-28 79-12 25-29 46-50 62-22 16-46 25-72 25-37 0-66-14-87-42-20-27-30-60-30-99 0-19 2-39 7-59 4-21 11-42 21-63 10-21 21-39 34-56 12-17 28-30 47-41 18-10 37-15 58-15 29 0 52 7 69 20 10 8 21 24 26 35 10 21 15 47 15 78 0 24-3 49-10 76z" horiz-adv-x="1000" />
<glyph glyph-name="ic-facebook" unicode="&#xe806;" d="m516 493c0 0-186 0-186 0 0 0 0 89 0 89 0 0-10 85 50 85 68 0 122 0 122 0 0 0 0 183 0 183 0 0-208 0-208 0 0 0-174 1-174-172 0-37 0-104 0-185 0 0-120 0-120 0 0 0 0-148 0-148 0 0 119 0 119 0 0-234-1-495-1-495 0 0 212 0 212 0 0 0 0 495 0 495 0 0 141 0 141 0 0 0 45 148 45 148z" horiz-adv-x="516" />
<glyph glyph-name="ic-arrow-right" unicode="&#xe807;" d="m103 832c0 0 430-429 430-429 24-23 24-62 0-86 0 0-430-429-430-429-24-24-62-24-86 0-24 24-24 62 0 86 0 0 387 386 387 386 0 0-387 387-387 387-24 23-24 62 0 85 24 24 62 24 86 0z" horiz-adv-x="571" />
<glyph glyph-name="ic-arrow-left" unicode="&#xe808;" d="m456-131c0 0-438 438-438 438-25 24-25 64 0 88 0 0 438 438 438 438 24 24 64 24 88 0 24-25 24-64 0-88 0 0-395-394-395-394 0 0 395-394 395-394 24-24 24-64 0-88-24-24-64-24-88 0z" horiz-adv-x="563" />
<glyph glyph-name="ic-twitter" unicode="&#xe809;" d="m1195 832c-48-29-102-50-160-62-46 49-111 80-184 80-139 0-252-113-252-252 0-20 2-39 6-58-209 11-395 111-519 264-22-37-34-81-34-127 0-88 44-165 112-210-42 1-80 13-114 32 0 0 0-4 0-4 0-122 86-224 202-247-21-6-44-9-67-9-16 0-32 2-47 4 32-100 125-173 235-175-86-68-195-108-313-108-20 0-40 1-60 3 112-71 244-113 387-113 463 0 717 385 717 718 0 0-1 33-1 33 50 36 92 80 126 131-45-20-94-34-145-40 53 31 92 81 111 140z" horiz-adv-x="1229" />
<glyph glyph-name="ic-menu" unicode="&#xe80a;" d="m1324 262c0 0-1236 0-1236 0-48 0-88 39-88 88 0 49 40 88 88 88 0 0 1236 0 1236 0 48 0 88-39 88-88 0-49-40-88-88-88z m0 412c0 0-1236 0-1236 0-48 0-88 39-88 88 0 49 40 88 88 88 0 0 1236 0 1236 0 48 0 88-39 88-88 0-49-40-88-88-88z m-1236-647c0 0 1236 0 1236 0 48 0 88-40 88-89 0-49-40-88-88-88 0 0-1236 0-1236 0-48 0-88 39-88 88 0 49 40 89 88 89z" horiz-adv-x="1412" />
</font>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
static/font/icons.ttf Normal file

Binary file not shown.

BIN
static/font/icons.woff Normal file

Binary file not shown.

BIN
static/images/home-bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

BIN
static/images/nego.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

150
static/js/script.js Normal file
View File

@ -0,0 +1,150 @@
jQuery(function($) {
var body = $('body');
var html = $('html');
var viewport = $(window);
/* ==========================================================================
Menu
========================================================================== */
function menu() {
html.toggleClass('menu-active');
};
$('#menu').on({
'click': function() {
menu();
}
});
$('.menu-button').on({
'click': function() {
menu();
}
});
$('.hidden-close').on({
'click': function() {
menu();
}
});
/* ==========================================================================
Parallax cover
========================================================================== */
var cover = $('.cover');
var coverPosition = 0;
function prlx() {
if(cover.length >= 1) {
var windowPosition = viewport.scrollTop();
(windowPosition > 0) ? coverPosition = Math.floor(windowPosition * 0.25) : coverPosition = 0;
cover.css({
'-webkit-transform' : 'translate3d(0, ' + coverPosition + 'px, 0)',
'transform' : 'translate3d(0, ' + coverPosition + 'px, 0)'
});
(viewport.scrollTop() < cover.height()) ? html.addClass('cover-active') : html.removeClass('cover-active');
}
}
prlx();
viewport.on({
'scroll': function() {
prlx();
},
'resize': function() {
prlx();
},
'orientationchange': function() {
prlx();
}
});
/* ==========================================================================
Reading Progress
========================================================================== */
var post = $('.post-content');
function readingProgress() {
if(post.length >= 1) {
var postBottom = post.offset().top + post.height();
var windowBottom = viewport.scrollTop() + viewport.height();
var progress = 100 - (((postBottom - windowBottom) / (postBottom - viewport.height())) * 100);
$('.progress-bar').css('width', progress + '%');
(progress > 100) ? $('.progress-container').addClass('ready') : $('.progress-container').removeClass('ready');
}
}
readingProgress();
viewport.on({
'scroll': function() {
readingProgress();
},
'resize': function() {
readingProgress();
},
'orientationchange': function() {
readingProgress();
}
});
/* ==========================================================================
Gallery
========================================================================== */
function gallery() {
var images = document.querySelectorAll('.kg-gallery-image img');
images.forEach(function (image) {
var container = image.closest('.kg-gallery-image');
var width = image.attributes.width.value;
var height = image.attributes.height.value;
var ratio = width / height;
container.style.flex = ratio + ' 1 0%';
});
}
gallery();
/* ==========================================================================
Style code blocks with highlight and numbered lines
========================================================================== */
function codestyling() {
$('pre code').each(function(i, e) {
hljs.highlightBlock(e);
if(!$(this).hasClass('language-text')) {
var code = $(this);
var lines = code.html().split(/\n/).length;
var numbers = [];
for (i = 1; i < lines; i++) {
numbers += '<span class="line">' + i + '</span>';
}
code.parent().append('<div class="lines">' + numbers + '</div>');
}
});
}
codestyling();
/* ==========================================================================
Initialize and load Disqus
========================================================================== */
if (typeof disqus === 'undefined') {
$('.post-comments').css({
'display' : 'none'
});
} else {
$('#show-disqus').on('click', function() {
$.ajax({
type: "GET",
url: "//" + disqus + ".disqus.com/embed.js",
dataType: "script",
cache: true
});
$(this).parent().addClass('activated');
});
}
});

38
templates/base.html Normal file
View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="{{ DEFAULT_LANG }}">
<head>
{% block head %}
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />
<title>@TODO</title>
<meta name="description" content="@TODO"/>
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="referrer" content="origin" />
<link href="{{ SITEURL }}" rel="canonical" />
<link href="/static/css/style.css" type="text/css" rel="stylesheet" />
<link href="/static/css/code_blocks/monokai.css" rel="stylesheet">
<!-- Custom fonts -->
<!-- link href='https://fonts.googleapis.com/css?family=Montserrat:400,300' rel='stylesheet' type='text/css' />
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css" /> -->
<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/nord-sud" type="text/css"/>
{% endblock head %}
</head>
<body class="home-template " {% block bodyclasses %}{% endblock bodyclasses %}>
{% block header %}{% endblock header %}
{% block content %}{% endblock content %}
<!--
<footer id="footer" style="display: none;">
{% block footer %}{% endblock footer %}
</footer>
-->
<script type="text/javascript" src="/static/js/script.js"></script>
</body>
</html>

61
templates/index.html Normal file
View File

@ -0,0 +1,61 @@
{% extends "base.html" %}
{% block bodyclasses %}
{% endblock bodyclasses %}
{% block header %}
<header id="blog-header">
<div class="inner">
<nav id="navigation">
{% if SITE_LOGO %}
<span class="blog-logo">
<a href="{{ SITEURL }}"><img src="{{SITE_LOGO}}" alt="Blog Logo" /></a>
</span>
{% endif %}
<!--
<span id="menu-button" class="nav-button">
<a class="menu-button"><i class="ic ic-menu"></i> Menu</a>
</span>
-->
</nav>
<div class="blog-cover cover" style="background-image: url('/static/images/home-bg.jpg')"></div>
<h2 class="post-title home-surtitle">Red Markets</h2>
<h1 class="post-title home-title">Negotiations</h1>
</div>
</header>
{% endblock header %}
{% block content %}
<div id="index" class="container">
<main class="content" role="main">
<form id="newroom" class="room-form" method="post" action="/negotiation/create">
<div><label for="negotiation">Now Entering</label></div>
<div>
<input id="negotiation" pattern="^[\w_\-# ]+$" type="text" value="{{suggestion}}" name="negotiation" minlength="4" maxlength="128" size="25">
</div>
<div>
<button>Negotiate!</button>
</div>
</form>
{% if negotiations %}
<div class="negotiation-list">
<h3>Your other negotiations</h3>
<ul>
{% for n in negotiations %}
<li>
<span>
<a href="/negotiations/{{ n.name | urlencode() }}">
{{ n.name }}
<img height="32" width="32" src="/static/images/nego.png"/>
</a>
</span>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
</main>
</div>
{% endblock content %}