Adding the latest rendition of the code...

master
John Hammond 2016-09-05 20:09:45 -04:00
parent 5faabce182
commit 4b32a9117f
31 changed files with 2985 additions and 215 deletions

1273
badwords.txt Normal file

File diff suppressed because it is too large Load Diff

21
certificate.crt Normal file
View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAP1fDj/HP2uuMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTYwODE3MTUyMTMyWhcNMTcwODE3MTUyMTMyWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA5pWsXxqGQzZ98uxLdNpOYWDEWk/dqeJJwTu1oUzkhUkZDbgTfxOzrLnO
SeePBMzGIPQKE/l4jesX58JK69657Yhqzvie9/4i5A+vyQ3V7BQnCI92YYTPHltP
HLvKJ9FkR0ves8o4vLRUFNwAz8zS4piUEhMCMbbZEYRx3+cSH3xu8RQYcwzdw0Tv
gHUu8lU/nLrOR+p+ovfh/ZlriMGQtSU1F1CBk/wyMESj0ELJx61A3omzIr7rMXiQ
fDsvfl+GcB+qt+zfuYSPJXAXoY1R6ojAJjXC2LBR1z0C6y7xS7o37HCFUBNWavHq
d1EzZqNf6Mwa1XYWmJ/appqt1brK3wIDAQABo1AwTjAdBgNVHQ4EFgQUWhlBuC7J
jiUEhpmbMIdzbC7RlK8wHwYDVR0jBBgwFoAUWhlBuC7JjiUEhpmbMIdzbC7RlK8w
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAE93tp9oWgVU1oUyjh8Hm
b0z0VCSPzp/IQ4Ja8ElmL6GF/GsJ9jeH2Yfi/EWO1XFKMY2xGbHci/MSxOX0+ZjS
EgSbYt8lKCBnxYA3OO8F2PyLKEyB7GQ9B++2giSFGnkLUHw0DmWz1LZ81n/Dd2iV
L8tFJwwhaGpoutqcWgEm4whBOgQp/IWCQ1Cy3YDHaORGB4TOAETuvcqhAeTEyltz
99Bz7+vSnZ3m3YgibTl2WdWsBEeXS7ghT0mLPBHQPH61hJxqWaBvhoiZiT0b1I73
JcuDpEJx3r2vAXj6JUIRer2TK080IMBvBKTGr4ZSacO3rg7gOweud/NYo4cCgUvC
pA==
-----END CERTIFICATE-----

View File

@ -1,10 +0,0 @@
drop table if exists users;
create table users (
id integer primary key autoincrement,
username text not null,
password text not null,
solved_challenges text not null,
score integer not null,
last_submission integer not null,
uuid text not null
);

BIN
database.db Normal file

Binary file not shown.

2
dev/depencies.sh Normal file
View File

@ -0,0 +1,2 @@
#!/bin/bash
sudo pip install python-resize-image

6
dev/get_sqlitebrowser.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
sudo add-apt-repository -y ppa:linuxgndu/sqlitebrowser
sudo apt-get update
sudo apt-get install sqlitebrowser
echo "The command is: sqlitebrowser"

29
email_test.py Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env python
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.mime.text import MIMEText
# Open a plain text file for reading. For this example, assume that
# the text file contains only ASCII characters.
# Create a text/plain message
msg = MIMEText("OH THIS IS A MESSAGE")
me = 'USCGA BearShop'
you = 'John.W.Hammond@uscga.edu'
msg['Subject'] = 'Your Registration Verification Code'
msg['From'] = me
msg['To'] = you
# Send the message via our own SMTP server, but don't include the
# envelope header.
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login('uscga.bearshop@gmail.com', 'Go Coast Guard')
server.sendmail(me, [you], msg.as_string())
server.quit()

28
privateKey.key Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDmlaxfGoZDNn3y
7Et02k5hYMRaT92p4knBO7WhTOSFSRkNuBN/E7Osuc5J548EzMYg9AoT+XiN6xfn
wkrr3rntiGrO+J73/iLkD6/JDdXsFCcIj3ZhhM8eW08cu8on0WRHS96zyji8tFQU
3ADPzNLimJQSEwIxttkRhHHf5xIffG7xFBhzDN3DRO+AdS7yVT+cus5H6n6i9+H9
mWuIwZC1JTUXUIGT/DIwRKPQQsnHrUDeibMivusxeJB8Oy9+X4ZwH6q37N+5hI8l
cBehjVHqiMAmNcLYsFHXPQLrLvFLujfscIVQE1Zq8ep3UTNmo1/ozBrVdhaYn9qm
mq3VusrfAgMBAAECggEBALMroiDUD3eyo/NawNcvuq/X7TrvzCHxf7Xym5OWmAsp
XZpXam7X9ElGp5CtqWflZh69Age7VX2RK6YeRvE4w+halAP3FC9G/f2QYtsrMQqc
LihssWPdOsMv2C1Pjimafv0XaxjxDV00EhGTUd4mHceNH6Fbu9y9Y7ZE3+dHOcHU
CO0QRIUkcJfzndM+X/EeXSRuP6G0+pXdQ+tSKDeH1rNFgTFs17RTmt/36d2JW/O/
GFLpOfoOtVJ7V8ouaE8B/3wbFbEolv85AoMDBh1Q+v3PSKhUGvbHBDf6SRwyxVQv
aOExMY2Mgdw4R1tAUckKgKktYrUVKjlh4OJ7+Yyy/0ECgYEA+rD2UXoWnqxFEWPr
J7btiyS6QBIsW9pO3bPkX+lZ6XhCMHlI2lD6dkVwCRUTxP8yPsgiyNkCE9936sCX
kK3CFBURvJQryoOrdOtCz+fFbtgifmNKQbKLxVLEm/FVJpqRReN6CV4UEdxZnnpV
Tkg1h1xw2IB2YedKYXOw3jPDlGkCgYEA63e1xMYK6L4PGdGsswAiUdKxsKflH+Tf
gGTc+6Xrc92IIDD4yZ8Bk8NS1fFwpR82endlqfwn8QhxUsxbuGfg/5Yj3AVRmeLw
7BQQUYRMCa+iuwRZTMWxZKXHACEQDoC3EPVtWeh5uxzKbd+MAbTHMvUM9STCaz55
ZU9SeaAsXAcCgYAC5z/DC83tQoN+QxD7IcQ4g1Fg4pT+71VQff/cGIDBEnJ5yz3L
wXpVGlLE2CildGspjPnSJ6k9f64M2vQmaczAnMnazECBlOrMbNkWPVHtCbXEjvPS
NPYnb+D1CWN6EfoyvAKyzxMebdXf3vzT7kQocCqiZ0J3uc0DuepHeIQAWQKBgQC2
fJ1DthRoUjvTz7sfMwBmF3scpNIfCLrqf8D/ypQSxOKlyC5X28JWKS9+nVKmtez7
tqL0vXabB+cDu1tuLBulGVALSZf3QnljDR2kf3qKmzLr66/lnuUfUpdKk1UlWD4I
h5zK7C/Dgsmjo3eXLuqepGn5ZxbCFLXyfSo3FpqqawKBgBg7W25kn/bd/aJp3yAY
gcRgpQksIKg/3l/PrWY0hCAn+a49JgRQWNIFUcWViW93lvrSjdchsZovkGIfMQp4
uuynpeQWWVGREI887XdXACI+AkQQProQme2Xh+h4CGy+4o0Q85SxYsFFUeM2oDfg
c9e+nPQ/tMMD85mSV69KEhEQ
-----END PRIVATE KEY-----

View File

@ -1,7 +1,24 @@
drop table if exists users; drop table if exists users;
create table users ( create table users (
id integer primary key autoincrement, id integer primary key autoincrement,
username text not null, email text not null,
name text not null,
password text not null, password text not null,
uuid text not null,
phone text,
room text,
your_products text not null,
verified integer not null
);
drop table if exists products;
create table products (
id integer primary key autoincrement,
name text not null,
picture text not null,
description text not null,
price text not null,
seller text not null,
interested_people text not null,
uuid text not null uuid text not null
); );

284
server.py Executable file
View File

@ -0,0 +1,284 @@
#!/usr/bin/env python
from flask import Flask
from flask import render_template, request, session, g, url_for, flash, get_flashed_messages, redirect
import sqlite3
import json
import sys, os
from colorama import *
import sys
from threading import Thread
from time import sleep
from uuid import uuid4
from passlib.hash import sha256_crypt
from contextlib import closing
debug = True
init( autoreset = True )
if (debug):
def success( string ):
print Fore.GREEN + Style.BRIGHT + "[+] " + string
def error( string ):
sys.stderr.write( Fore.RED + Style.BRIGHT + "[-] " + string + "\n" )
def warning( string ):
print Fore.YELLOW + "[!] " + string
else:
def success( string ): pass
def error( string ): pass
def warning( string ): pass
# ===========================================================================
DATABASE = '/tmp/bears.db'
CERTIFICATE = 'certificate.crt'
PRIVATE_KEY = 'privateKey.key'
SECRET_KEY = 'this_key_needs_to_be_used_for_session_variables'
if DATABASE == '$DATABASE':
error("This server has not yet been configured with a database file!")
exit(-1)
if CERTIFICATE == '$CERTIFICATE_FILE':
error("This server has not yet been configured with a certificate!")
exit(-1)
if PRIVATE_KEY == '$PRIVATEKEY_FILE':
error("This server has not yet been configured with a private key!")
exit(-1)
app = Flask( __name__ )
app.config.from_object(__name__)
def init_db():
with closing(connect_db()) as db:
with app.open_resource('schema.sql', mode='r') as f:
db.cursor().executescript(f.read())
db.commit()
def connect_db():
return sqlite3.connect( app.config['DATABASE'] )
@app.before_request
def before_request():
g.db = connect_db()
@app.teardown_request
def teardown_request(exception):
db = getattr(g, 'db', None)
if db is not None:
db.close()
# --------------------------------------------------------------------
@app.route("/")
def index():
if not ( session['logged_in'] ):
return redirect('login')
@app.route("/login", methods=["GET", "POST"])
def login():
error = ""
if request.method == "POST":
cur = g.db.execute('select email, password from users')
# username, password_hash
users = dict(( row[0], row[1] ) for row in cur.fetchall())
print "You POSTed", users
if not request.form['email'] in users.iterkeys():
flash('This e-mail is not in the database!')
else:
if not ( sha256_crypt.verify( request.form['password'], users[request.form['username']] ) ):
flash("Incorrect password!")
else:
session_login( request.form['email'] )
return redirect( "about" )
return render_template( 'login.html' )
@app.route("/register", methods=["GET", "POST"])
def register():
cur = g.db.execute('select email from users')
usernames = [row[0] for row in cur.fetchall() ]
error = ""
if request.method == "POST":
if unicode(request.form['email']) in usernames:
flash('This e-mail is already registered!')
elif (request.form['password'] == ""):
flash("You must supply a password!")
elif request.form['password'] != request.form['confirm']:
flash('Your passwords do not match!')
else:
# I use this for command-line submission...
identifier = str(uuid4())
cur = g.db.execute('insert into users (email, password, uuid) values ( ?, ?, ? )', [
request.form['email'],
sha256_crypt.encrypt( request.form['password']),
identifier # and a completely unique idenitifier
] )
g.db.commit()
flash("Hello " + request.form['username'] + ", you have successfully registered!")
session_login( request.form['email'] )
return redirect( "challenges" )
return render_template( 'register.html', error = error )
# @app.route("/scoreboard")
# def scoreboard():
# cur = g.db.execute('select username, score from users order by score desc, last_submission asc')
# response = cur.fetchall()
# users = [ { "username": row[0], "score": row[1] } for row in response]
# return render("scoreboard.html", users = users )
# @app.route("/logout")
# def logout():
# session_logout()
# return redirect("about")
# @app.route("/")
# @app.route("/about")
# def about(): return render("about.html", app_about=configuration['app_about'])
# @app.route("/challenges")
# def challenges_page():
# if not ( session['logged_in'] ):
# return render("login.html", error = "You must log in to be able to see the challenges!")
# try:
# cur = g.db.execute('select uuid from users where username =?',
# [ session['username'],] )
# uuid = cur.fetchone()[0]
# except Exception as e:
# print error(e.message)
# uuid = ''
# return render("challenges.html", challenges = configuration['services'], url=request.url_root, session_value = uuid )
# @app.route("/check_answer", methods=["GET", "POST"])
# def check_answer():
# global correct_answers
# if request.method == "POST":
# if request.form['answer'] in session['solved_challenges']:
# return json.dumps({'correct': -1});
# if ( request.form['answer'] in correct_answers.keys() ):
# flag = request.form['answer']
# new_score = int(session['score']) + correct_answers[flag]
# cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')) where username = (?)", [
# new_score,
# session['username']
# ] );
# session['solved_challenges'].append( request.form['answer'] )
# session['score'] = new_score
# g.db.commit();
# return json.dumps({'correct': 1, 'new_score': new_score});
# else:
# return json.dumps({'correct': 0});
# @app.route("/submit", methods=[ "POST" ])
# def submit():
# global correct_answers
# if request.method == "POST":
# if ( request.form['flag'] in correct_answers.keys() ):
# flag = request.form['flag']
# cur = g.db.execute('select score, solved_challenges from users where uuid = (?)',
# [ request.form['uuid'], ])
# current_score, solved_challenges = cur.fetchone()
# solved_challenges = solved_challenges.split()
# if ( flag in solved_challenges ):
# return 'You already submitted this flag!\n'
# print solved_challenges
# new_score = current_score + correct_answers[flag]
# solved_challenges.append( flag + " " )
# cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')), solved_challenges = (?) where uuid = (?)", [
# new_score,
# ' '.join(solved_challenges),
# request.form['uuid']
# ] );
# # session['solved_challenges'].append( request.form['flag'] )
# session['score'] = new_score
# g.db.commit();
# # return json.dumps({'correct': 1, 'new_score': new_score});
# return 'Correct!\n';
# else:
# # return json.dumps({'correct': 0});
# return 'Incorrect!\n';
def session_login( username ):
flash("You were successfully logged in!")
# cur = g.db.execute('select solved_challenges, score from users where username = (?)',
# [username])
# solved_challenges, score = cur.fetchone()
session['logged_in'] = True
# session['username'] = username
# session['score'] = score
# session['solved_challenges'] = []
def session_logout():
flash("You have been successfully logged out.")
session['logged_in'] = False
# session.pop('username')
# session.pop('score')
if ( __name__ == "__main__" ):
context = (CERTIFICATE, PRIVATE_KEY)
app.run( host="0.0.0.0", debug=True, ssl_context=context, threaded=True)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
from flask import Flask from flask import Flask
from flask import render_template, request, session, g, url_for, flash, get_flashed_messages, redirect from flask import render_template, request, session, g, url_for, flash, get_flashed_messages, redirect, send_from_directory
import sqlite3 import sqlite3
import json import json
import sys, os import sys, os
@ -9,17 +9,41 @@ from colorama import *
import sys import sys
from threading import Thread from threading import Thread
from time import sleep from time import sleep
from werkzeug.utils import secure_filename
from uuid import uuid4 from uuid import uuid4
from textwrap import dedent
from PIL import Image # needed to resize the image they upload
import re # Used to verify phone numbers
from resizeimage import resizeimage
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.mime.text import MIMEText
from passlib.hash import sha256_crypt from passlib.hash import sha256_crypt
from contextlib import closing from contextlib import closing
f = open("badwords.txt")
bad_words = f.read().split('\n')
f.close()
def contains_bad_word( string ):
words = string.split(" ")
for word in words:
if word in bad_words:
return True
else:
return False
price_cap = 10000
debug = True debug = True
init( autoreset = True ) init( autoreset = True )
email_from = 'USCGA BearShop'
if (debug): if (debug):
@ -37,30 +61,51 @@ else:
def error( string ): pass def error( string ): pass
def warning( string ): pass def warning( string ): pass
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
def send_email( to_address, subject, message ):
msg = MIMEText(message, 'html')
msg["Subject"] = subject
msg['From'] = email_from
msg['To'] = to_address
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login('uscga.bearshop@gmail.com', 'Go Coast Guard')
server.sendmail(email_from, [to_address], msg.as_string())
server.quit()
# =========================================================================== # ===========================================================================
DATABASE = '$DATABASE' ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
CERTIFICATE = '$CERTIFICATE_FILE' DATABASE = 'database.db'
PRIVATE_KEY = '$PRIVATEKEY_FILE' UPLOAD_FOLDER = 'uploads'
# PRIVATE_KEY = '$PRIVATEKEY_FILE'
SECRET_KEY = 'this_key_needs_to_be_used_for_session_variables' SECRET_KEY = 'this_key_needs_to_be_used_for_session_variables'
if DATABASE == '$DATABASE': # if DATABASE == '$DATABASE':
error("This server has not yet been configured with a database file!") # error("This server has not yet been configured with a database file!")
exit(-1) # exit(-1)
if CERTIFICATE == '$CERTIFICATE_FILE': # if CERTIFICATE == '$CERTIFICATE_FILE':
error("This server has not yet been configured with a certificate!") # error("This server has not yet been configured with a certificate!")
exit(-1) # exit(-1)
if PRIVATE_KEY == '$PRIVATEKEY_FILE': # if PRIVATE_KEY == '$PRIVATEKEY_FILE':
error("This server has not yet been configured with a private key!") # error("This server has not yet been configured with a private key!")
exit(-1) # exit(-1)
app = Flask( __name__ ) app = Flask( __name__ )
app.config.from_object(__name__) app.config.from_object(__name__)
@app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
def init_db(): def init_db():
with closing(connect_db()) as db: with closing(connect_db()) as db:
with app.open_resource('schema.sql', mode='r') as f: with app.open_resource('schema.sql', mode='r') as f:
@ -70,6 +115,7 @@ def init_db():
def connect_db(): def connect_db():
return sqlite3.connect( app.config['DATABASE'] ) return sqlite3.connect( app.config['DATABASE'] )
@app.before_request @app.before_request
def before_request(): def before_request():
g.db = connect_db() g.db = connect_db()
@ -85,203 +131,543 @@ def teardown_request(exception):
@app.route("/") @app.route("/")
def index(): def index():
if not ( session['logged_in'] ): if not 'logged_in' in session: return redirect('login')
return redirect('login') cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
verified = cur.fetchone()[0]
if not verified:
return redirect('verify')
return redirect('products')
@app.route("/login", methods=["GET", "POST"]) @app.route("/login", methods=["GET", "POST"])
def login(): def login():
error = "" email = password = ""
if request.method == "POST": if request.method == "POST":
cur = g.db.execute('select username, password from users') cur = g.db.execute('select email, password, uuid from users')
# username, password_hash
users = dict(( row[0], row[1] ) for row in cur.fetchall()) users = dict(( row[0], row[1] ) for row in cur.fetchall())
if not request.form['username'] in users.iterkeys(): email = request.form['email']
error = 'This username is not in the database!' password = request.form['password']
if ( email == "" ):
flash("You need to enter an e-mail address!")
elif not email.endswith("uscga.edu"):
flash("This does not look like a valid USCGA EDU e-mail address!")
elif not email in users.iterkeys():
flash('This e-mail is not in the database!')
else:
if ( password == "" ):
flash("You need to enter a password!")
elif not ( sha256_crypt.verify( request.form['password'], users[email] ) ):
flash("Incorrect password!")
else:
session_login( request.form['email'] )
return redirect( "verify" )
return render_template( 'login.html', email=email, password = password )
@app.route("/register", methods=["GET", "POST"])
def register():
cur = g.db.execute('select email from users')
usernames = [row[0] for row in cur.fetchall() ]
email = password = confirm = ""
if request.method == "POST":
email = request.form['email']
password = request.form['password']
confirm = request.form['confirm']
if unicode(request.form['email']) in usernames:
flash('This e-mail is already registered!')
elif (request.form['password'] == ""):
flash("You must supply a password!")
elif request.form['password'] != request.form['confirm']:
flash('Your passwords do not match!')
else: else:
if not ( sha256_crypt.verify( request.form['password'], users[request.form['username']] ) ): # I use this for command-line submission...
error = "Incorrect password!" identifier = str(uuid4())
cur = g.db.execute('insert into users (email, name, password, uuid, your_products, room, phone, verified) values ( ?, ?, ?, ?, ?, ?, ?, ? )', [
email,
" ".join( [email.split(".")[0], email.split(".")[2].split("@")[0] ]),
sha256_crypt.encrypt( request.form['password']),
identifier, # a completely unique idenitifier
"", # They currently have no products being sold
"", # They can enter their room number later
"", # They can enter their phone number later
0 # verified? ...since they just registered, no!
] )
g.db.commit()
session_login( request.form['email'] )
send_verification_link()
return redirect( "verify" )
return render_template( 'register.html', email = email, password = password, confirm = confirm )
@app.route("/send_verification_link")
def send_verification_link():
if not 'logged_in' in session: return redirect('login')
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
verified = cur.fetchone()[0]
if ( session['logged_in'] ):
email = session['email']
cur = g.db.execute('select uuid, verified from users where email = (?)', [email])
identifier, verified = cur.fetchone()
if ( verified == 1 ):
flash("Your e-mail address has already been verified.")
return redirect('products')
else: else:
session_login( request.form['username'] ) send_email( email,
'Your Registration Verification Code',
render_template("verification_email.html", identifier = identifier
))
return redirect( "about" ) # THIS IS ONLY FOR TESTING....
send_email( 'johnhammond010@gmail.com',
'Your Registration Verification Code',
render_template("verification_email.html", identifier = identifier
))
return render_template( 'login.html' ) flash("An e-mail has been sent!")
return redirect("verify")
# @app.route("/register", methods=["GET", "POST"]) @app.route("/products")
# def register(): def products():
# cur = g.db.execute('select username from users') if not 'logged_in' in session: return redirect('login')
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
verified = cur.fetchone()[0]
if not verified:
return redirect('verify')
cur = g.db.execute('select name, picture, price, uuid from products')
products = [ [ row[0], row[1], row[2], row[3] ] for row in cur.fetchall()[::-1]]
# usernames = [row[0] for row in cur.fetchall() ] return render_template("products.html", products = products)
# error = "" @app.route("/products/<uuid>")
# if request.method == "POST": def product(uuid):
# if unicode(request.form['username']) in usernames: if not 'logged_in' in session: return redirect('login')
# error = 'This username is already in use!' cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
# elif (request.form['password'] == ""): verified = cur.fetchone()[0]
# error = "You must supply a password!" if not verified:
# elif request.form['password'] != request.form['confirm']: return redirect('verify')
# error = 'Your passwords do not match!'
# else:
# # I use this for command-line submission... cur = g.db.execute('select name, price, picture, description, seller, interested_people from products where uuid = (?)', [uuid] )
# identifier = str(uuid4()) name, price, picture, description, seller, interested_people = cur.fetchone()
cur = g.db.execute('select uuid from users where name = (?)', [seller] )
seller_uuid = cur.fetchone()[0]
# cur = g.db.execute('insert into users (username, password, solved_challenges, score, last_submission, uuid) values ( ?, ?, ?, ?, ?, ? )', [ interested_people = [ person for person in interested_people.split('\n') if person ]
# request.form['username'],
# sha256_crypt.encrypt( request.form['password']),
# "", # No challenges completed
# 0, # no score.
# 0, # no last submission time,
# identifier # and a completely unique idenitifier
# ] )
# g.db.commit() return render_template('item.html', name=name, picture=picture, description=description, seller=seller, price=price, uuid=uuid, interested_people =interested_people, seller_uuid = seller_uuid)
@app.route("/remove_product/<uuid>")
def remove_product(uuid):
if not 'logged_in' in session: return redirect('login')
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
verified = cur.fetchone()[0]
if not verified:
return redirect('verify')
cur = g.db.execute('select seller from products where uuid = (?)', [uuid])
product_seller = cur.fetchone()[0]
if ( product_seller == session['name'] ):
cur = g.db.execute('delete from products where uuid = (?)', [uuid])
g.db.commit()
cur = g.db.execute('select your_products from users where email = (?)', [session['email']])
your_products = cur.fetchone()[0];
your_products = your_products.replace(uuid,'')
your_products = your_products.strip()
print your_products
cur = g.db.execute('update users set your_products = (?) where email = (?)', [
your_products,
session['email']
])
g.db.commit()
flash("The product has been successfully removed.")
return redirect("products")
else:
return "This product does not belong to you. Nice try, but no."
@app.route("/verify", methods=["GET", "POST"])
def verify():
identifier = ""
if not 'logged_in' in session: return redirect('login')
else:
cur = g.db.execute('select uuid, verified from users where email = (?)', [session['email']])
uuid, verified = cur.fetchone()
if ( verified ):
# flash("Your e-mail address has already been verified.")
return redirect('products')
else:
if ( request.method == "GET" ):
identifier = request.args.get('identifier')
if ( request.method == "POST" ):
identifier = request.form['identifier']
if ( identifier ):
if ( identifier == uuid ):
cur = g.db.execute("update users set verified = (?) where email = (?)", [
1,
session['email']
] );
g.db.commit();
return redirect('products')
else:
flash("Incorrect verification code.")
return render_template( 'verify.html', identifier = identifier)
@app.route("/search")
def search():
if not 'logged_in' in session: return redirect('login')
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
verified = cur.fetchone()[0]
if not verified:
return redirect('verify')
return render_template("search.html")
# flash("Hello " + request.form['username'] + ", you have successfully registered!") @app.route("/edit/<uuid>", methods=["GET", "POST"])
# session_login( request.form['username'] ) def edit(uuid):
# return redirect( "challenges" ) if not 'logged_in' in session: return redirect('login')
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
verified = cur.fetchone()[0]
if not verified:
return redirect('verify')
# return render( 'register.html', error = error ) if ( request.method == "GET" ):
# @app.route("/scoreboard") cur = g.db.execute('select name, price, picture, description, seller from products where uuid = (?)', [uuid] )
# def scoreboard(): name, price, picture, description, seller = cur.fetchone()
# cur = g.db.execute('select username, score from users order by score desc, last_submission asc') return render_template('edit.html', name=name, picture=picture, description=description, seller=seller, price=price[1:], uuid=uuid)
# response = cur.fetchall()
# users = [ { "username": row[0], "score": row[1] } for row in response] if ( request.method == "POST" ):
# return render("scoreboard.html", users = users ) name = request.form['name']
# uuid = request.form['uuid']
picture = request.form['picture']
cur = g.db.execute('select seller from products where uuid = (?)', [uuid])
product_seller = cur.fetchone()[0]
# @app.route("/logout") if ( product_seller == session['name'] ):
# def logout(): # picture = request.form['picture']
price = request.form['price']
name = request.form['name']
description = request.form['description']
# session_logout() if (contains_bad_word(price.lower()) or \
# return redirect("about") contains_bad_word(description.lower()) or \
contains_bad_word(name.lower())
):
flash("Detected a bad word. Not accepting that.")
return redirect(url_for('edit', uuid=uuid))
# @app.route("/") if ( name == "" ):
# @app.route("/about") flash("Please enter a name of the product!")
# def about(): return render("about.html", app_about=configuration['app_about']) return redirect(url_for('edit', uuid=uuid))
# @app.route("/challenges") elif ( price == "" ):
# def challenges_page(): flash("Please enter the price of the product in dollars!")
return redirect(url_for('edit', uuid=uuid))
elif ( description == "" ):
flash("Please enter a description of your product!")
return redirect(url_for('edit', uuid=uuid))
elif ( '.' in price ):
if ( price[-3] != '.' ):
flash("That does not look like a valid price!")
return redirect(url_for('edit', uuid=uuid))
try:
price_number = round(float(price),2)
warning(str(price_number))
if (price_number != abs(price_number)):
flash("That does not look like a valid price!")
return redirect(url_for('edit', uuid=uuid))
elif ( price_number >= price_cap ):
flash("Please enter a cost less than $" + str(price_cap))
return redirect(url_for('edit', uuid=uuid))
else:
# We should be good to process the form
price_number = '$' + format(price_number, '.2f')
# if not ( session['logged_in'] ): if 'picture' not in request.files:
# return render("login.html", error = "You must log in to be able to see the challenges!") pass # They don't have to update the picture
# try: else:
# cur = g.db.execute('select uuid from users where username =?', file = request.files['picture']
# [ session['username'],] )
# uuid = cur.fetchone()[0] if file and allowed_file(file.filename):
# except Exception as e: filename = secure_filename(str(uuid4()) + "." + file.filename.split('.')[-1])
# print error(e.message) save_location = os.path.join(app.config['UPLOAD_FOLDER'], filename)
# uuid = '' file.save(save_location)
p = Image.open(save_location)
p = resizeimage.resize_cover(p, (350, 350))
p.save(save_location)
# return redirect(url_for('uploaded_file', filename=filename))
picture = (url_for('uploaded_file', filename=filename))
# return render("challenges.html", challenges = configuration['services'], url=request.url_root, session_value = uuid ) cur = g.db.execute("update products set name = (?), picture = (?), description = (?), price = (?) where uuid = (?)", [
name,
str(picture),
description,
price_number,
uuid
] );
g.db.commit()
except:
# print price
flash("That does not look like a valid price!")
return redirect(url_for('edit', uuid=uuid))
# @app.route("/check_answer", methods=["GET", "POST"]) else:
# def check_answer(): flash("This is not your own product!")
return redirect(request.referrer)
# global correct_answers return redirect(url_for('product', uuid=uuid))
# if request.method == "POST":
# if request.form['answer'] in session['solved_challenges']:
# return json.dumps({'correct': -1});
# if ( request.form['answer'] in correct_answers.keys() ):
# flag = request.form['answer']
# new_score = int(session['score']) + correct_answers[flag]
# cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')) where username = (?)", [
# new_score,
# session['username']
# ] );
# session['solved_challenges'].append( request.form['answer'] )
# session['score'] = new_score
# g.db.commit();
# return json.dumps({'correct': 1, 'new_score': new_score});
# else:
# return json.dumps({'correct': 0});
# @app.route("/submit", methods=[ "POST" ])
# def submit():
# global correct_answers
# if request.method == "POST":
# if ( request.form['flag'] in correct_answers.keys() ):
# flag = request.form['flag']
# cur = g.db.execute('select score, solved_challenges from users where uuid = (?)',
# [ request.form['uuid'], ])
# current_score, solved_challenges = cur.fetchone() @app.route("/profile/<uuid>", methods= ["GET", "POST"])
def profile(uuid):
if not 'logged_in' in session: return redirect('login')
cur = g.db.execute('select verified, room, phone from users where uuid = (?)', [session['uuid']])
verified, room, phone = cur.fetchone()
if not verified:
return redirect('verify')
# solved_challenges = solved_challenges.split() cur = g.db.execute('select email, your_products from users where uuid = (?)', [uuid])
email, your_products = cur.fetchone()
name = " ".join( [email.split(".")[0], email.split(".")[2].split("@")[0] ])
your_products = your_products.split(" ")
products = []
for product in your_products:
cur = g.db.execute('select name from products where uuid = (?)', [product])
product_name = cur.fetchone()
if product_name != None:
product_name = product_name[0]
products.append( [product_name, product] )
# if ( flag in solved_challenges ): if ( request.method == "POST" ):
# return 'You already submitted this flag!\n'
# print solved_challenges if uuid == session['uuid']:
# new_score = current_score + correct_answers[flag] phone = room = ""
# solved_challenges.append( flag + " " ) phone = request.form['phone']
# cur = g.db.execute("update users set score = (?), last_submission = (SELECT strftime('%s')), solved_challenges = (?) where uuid = (?)", [ room = request.form['room']
# new_score, name = session['name']
# ' '.join(solved_challenges),
# request.form['uuid']
# ] );
# # session['solved_challenges'].append( request.form['flag'] ) if ( not re.search('\d\d\d-\d\d\d-\d\d\d\d', phone) ):
# session['score'] = new_score flash("Please enter the phone number in the form: ###-###-####")
# g.db.commit(); return render_template("profile.html", name = name, products = products, phone = phone, room = room )
elif ( not re.search('.\d\d\d', room)):
flash("Please enter a proper room number, #### or E###.")
return render_template("profile.html", name = name, products = products, phone = phone, room = room )
else:
flash("Your profile has been saved successfully!")
cur = g.db.execute('update users set room = (?), phone = (?) where uuid = (?)', [
room,
phone,
session['uuid']
])
# # return json.dumps({'correct': 1, 'new_score': new_score}); g.db.commit()
# return 'Correct!\n';
# else:
# # return json.dumps({'correct': 0});
# return 'Incorrect!\n';
def session_login( username ): return render_template("profile.html", name = name, products = products, phone = phone, room = room )
flash("You were successfully logged in!") return render_template("profile.html", name = name, products = products, room = room, phone = phone )
# cur = g.db.execute('select solved_challenges, score from users where username = (?)', @app.route("/show_interest/<seller>/<uuid>")
# [username]) def show_interest(seller, uuid):
if not 'logged_in' in session: return redirect('login')
cur = g.db.execute('select verified, room, phone from users where uuid = (?)', [session['uuid']])
verified, room, phone = cur.fetchone()
if not verified:
return redirect('verify')
# solved_challenges, score = cur.fetchone() cur = g.db.execute('select interested_people, name from products where uuid = (?)', [uuid])
interested_people, product_name = cur.fetchone();
interested_people += '\n' + session['name']
interested_people = interested_people.strip()
cur = g.db.execute('update products set interested_people = (?) where uuid = (?)', [
interested_people,
uuid
])
g.db.commit()
cur = g.db.execute('select email from users where name = (?)', [seller])
sellers_email = cur.fetchone()[0]
send_email( sellers_email,
'Someone is interested in your product!',
render_template("interest_email.html",
name = session['name'],
product_name = product_name,
room = room,
phone = phone,
email = session['email']
))
flash("You showed interest in this product! An e-mail has been sent to notify the seller.")
return redirect( request.referrer )
@app.route("/sell", methods=["GET", "POST"])
def sell():
if not 'logged_in' in session: return redirect('login')
cur = g.db.execute('select verified from users where uuid = (?)', [session['uuid']])
verified = cur.fetchone()[0]
if not verified:
return redirect('verify')
name = picture = description = price = ""
if ( request.method == "POST" ):
name = request.form['name']
price = request.form['price']
description = request.form['description']
if ( contains_bad_word(price.lower()) or \
contains_bad_word(description.lower()) or \
contains_bad_word(name.lower())
):
flash("Detected a bad word. Not accepting that.")
return render_template("sell.html", name=name, price = price, description = description)
if ( name == "" ):
flash("Please enter a name of the product!")
return render_template("sell.html", name=name, price = price, description = description)
elif ( price == "" ):
flash("Please enter the price of the product in dollars!")
return render_template("sell.html", name=name, price = price, description = description)
elif ( description == "" ):
flash("Please enter a description of your product!")
return render_template("sell.html", name=name, price = price, description = description)
elif ( '.' in price ):
if ( price[-3] != '.' ):
flash("That does not look like a valid price!")
return render_template("sell.html", name=name, price = price, description = description)
try:
price_number = round(float(price),2)
warning(str(price_number))
except:
print price
flash("That does not look like a valid price!")
return render_template("sell.html", name=name, price = price, description = description)
if (price_number != abs(price_number)):
flash("That does not look like a valid price!")
return render_template("sell.html", name=name, price = price, description = description)
elif ( price_number >= price_cap ):
flash("Please enter a cost less than $" + str(price_cap))
return render_template("sell.html", name=name, price = price, description = description)
else:
# We should be good to process the form
price_number = '$' + format(price_number, '.2f')
if 'picture' not in request.files:
pass # We make it optional for them to upload files, remember?
else:
file = request.files['picture']
if file and allowed_file(file.filename):
filename = secure_filename(str(uuid4()) + "." + file.filename.split('.')[-1])
save_location = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(save_location)
p = Image.open(save_location)
p = resizeimage.resize_cover(p, (350, 350))
p.save(save_location)
# return redirect(url_for('uploaded_file', filename=filename))
picture = (url_for('uploaded_file', filename=filename))
uuid = str(uuid4())
cur = g.db.execute('insert into products (name, picture, description, price, seller, interested_people, uuid) values ( ?, ?, ?, ?, ?, ?, ? )', [
name,
str(picture),
description,
price_number, # Since you are just selling this product, no one is interested yet!
session['name'],
"",
uuid
] );
g.db.commit()
cur = g.db.execute('select your_products from users where email = (?)', [session['email']])
your_products = cur.fetchone()[0];
your_products += ' ' + uuid
your_products = your_products.strip()
print your_products
cur = g.db.execute('update users set your_products = (?) where email = (?)', [
your_products,
session['email']
])
g.db.commit()
return redirect('products')
return render_template("sell.html", name=name, price = price, description = description)
@app.route("/log_out", methods=["GET", "POST"])
def log_out():
session_logout()
return redirect('login')
def session_login( email ):
flash("You have been successfully logged in!")
session['logged_in'] = True session['logged_in'] = True
# session['username'] = username session['email'] = email
# session['score'] = score cur = g.db.execute('select uuid from users where email = (?)', [session['email']])
# session['solved_challenges'] = [] uuid = cur.fetchone()
if uuid != None: uuid = uuid[0];
session['uuid'] = uuid
session['name'] = " ".join( [email.split(".")[0], email.split(".")[2].split("@")[0] ])
def session_logout(): def session_logout():
flash("You have been successfully logged out.") flash("You have been successfully logged out.")
session['logged_in'] = False session.pop('logged_in')
# session.pop('username') session.pop('email')
# session.pop('score') session.pop('uuid')
session.pop('name')
if ( __name__ == "__main__" ): if ( __name__ == "__main__" ):
context = (CERTIFICATE, PRIVATE_KEY) # context = (CERTIFICATE, PRIVATE_KEY)
app.run( host="0.0.0.0", debug=False, ssl_context=context, port = 444 ) # app.run( host="0.0.0.0", debug=False, ssl_context=context, port = 444, threaded=True )
app.run( host="0.0.0.0", debug=True, port=2001, threaded = True )

View File

@ -1,6 +1,7 @@
html{ html{
height: 100%; height: 100%;
width: 100%; width: 100%;
font-size: 100%;
} }
@ -14,20 +15,97 @@ body{
margin: 0px 0px; margin: 0px 0px;
padding: 0px 0px; padding: 0px 0px;
background-color: gray; background-color: white;
min-height: 70%;
/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#0043af+0,0056ce+46,ffb76b+52,ffa73d+57,ff7c00+88,ff7f04+100 */ /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#0043af+0,0056ce+46,ffb76b+52,ffa73d+57,ff7c00+88,ff7f04+100 */
background: #0043af; /* Old browsers */ /*background: #0043af;
background: -moz-linear-gradient(top, #0043af 0%, #0056ce 46%, #ffb76b 52%, #ffa73d 57%, #ff7c00 88%, #ff7f04 100%); /* FF3.6-15 */ background: -moz-linear-gradient(top, #0043af 0%, #0056ce 46%, #ffb76b 52%, #ffa73d 57%, #ff7c00 88%, #ff7f04 100%);
background: -webkit-linear-gradient(top, #0043af 0%,#0056ce 46%,#ffb76b 52%,#ffa73d 57%,#ff7c00 88%,#ff7f04 100%); /* Chrome10-25,Safari5.1-6 */ background: -webkit-linear-gradient(top, #0043af 0%,#0056ce 46%,#ffb76b 52%,#ffa73d 57%,#ff7c00 88%,#ff7f04 100%);
background: linear-gradient(to bottom, #0043af 0%,#0056ce 46%,#ffb76b 52%,#ffa73d 57%,#ff7c00 88%,#ff7f04 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ background: linear-gradient(to bottom, #0043af 0%,#0056ce 46%,#ffb76b 52%,#ffa73d 57%,#ff7c00 88%,#ff7f04 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0043af', endColorstr='#ff7f04',GradientType=0 ); /* IE6-9 */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0043af', endColorstr='#ff7f04',GradientType=0 );
*/
}
a{
/*color: white;*/
text-decoration: none;
}
a:visited{
color: blue;
/*text-decoration: none;*/
}
#navigation a{
color: white;
}
#navigation{
width: 100%;
color: white;
background-color: teal;
font-size: 35px;
padding: 5px;
font-weight: bold;
position:fixed;
top: 0px;
}
#navigation ul{
display: inline;
height:30px;
/*float: right;*/
}
#navigation ul li{
padding-left: 20px;
padding-right: 20px;
display: inline;
float: right;
}
#navigation a:hover{
text-decoration: underline;
}
#navigation ul li:hover{
text-decoration: underline;
} }
.flashed_messages{
text-align: center;
/*font-style: italic;*/
color: white;
font-size: large;
font-weight: bold;
width: 100%;
background-color: #FFF8DC;
/*border: 1px solid #EAC117;*/
/*color: #966F33;*/
padding: 8px;
background-color: darkviolet;
position: fixed;
top: 30px;
left:0px;
}
#disclaimer{
padding:0px 50px;
color: maroon;
}
#disclaimer h3{
text-decoration: underline;
}
#login_box_background{ #login_box_background{
max-width: 600px; max-width: 600px;
max-height: 400px; max-height: 420px;
padding: 2%; padding: 2%;
@ -43,16 +121,18 @@ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0043af', end
} }
#login_box{ #login_box{
/*font-family: 'Share Tech';*/
/*background-color: white;*/ color: #222;
color: white;
font-size: larger; font-size: larger;
/*margin-top: 30%;*/
border-top: 1px solid black; border-top: 1px solid black;
border-bottom: 1px solid black; border-bottom: 1px solid black;
max-width: 600px; max-width: 600px;
max-height: 400px; max-height: 420px;
min-height: 200px;
padding: 2%; padding: 2%;
@ -64,10 +144,35 @@ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0043af', end
margin: auto; margin: auto;
/*width: 100%;*/
/*padding: 10%;*/
} }
#vertical{
color: #222;
font-size: larger;
border-right: 1px solid black;
border-left: 1px solid black;
max-width: 1250px;
min-width: 600px;
/*max-height: 420px;*/
height: 100%;
min-height: 100%;
/*min-height: 99%;*/
padding: 2%;
/*position: absolute;*/
/*top:30px;*/
/*bottom: 0;*/
/*left: 0;*/
/*right: 0;*/
margin: auto;
margin-top: 100px;
margin-bottom: 100px;
}
input{ input{
display: block; display: block;
margin:auto; margin:auto;
@ -76,11 +181,20 @@ input{
font-size: x-large; font-size: x-large;
padding: 5px; padding: 5px;
} }
textarea{
display: block;
margin:auto;
font-size: x-large;
width: 90%;
height: 40px;
padding: 5px;
font-family: 'Share Tech';
}
h1{ h1{
border-bottom: 1px solid white; border-bottom: 1px solid white;
} }
#login{ #red_button{
text-transform: uppercase; text-transform: uppercase;
text-align: center; text-align: center;
@ -92,18 +206,237 @@ h1{
font-family: 'Share Tech'; font-family: 'Share Tech';
font-size: xx-large; font-size: xx-large;
color: white; color: white;
/*vertical-align: middle;*/ /*vertical-align: middle;*/
margin: 10px; margin: 10px auto;
cursor: pointer;
} }
#register{ #green_button{
text-transform: uppercase; text-transform: uppercase;
text-align: center; text-align: center;
width: 95%; width: 95%;
height: 60px;
background-color: green;
border: none;
display: block;
font-family: 'Share Tech';
font-size: xx-large;
color: white;
/*vertical-align: middle;*/
margin: 10px auto;
cursor: pointer;
}
#blue_button{
text-transform: uppercase;
text-align: center;
width: 95%;
height: 60px;
background-color: blue;
border: none;
display: block;
font-family: 'Share Tech';
font-size: xx-large;
color: white;
/*vertical-align: middle;*/
margin: 10px auto;
cursor: pointer;
}
#blue_button_link{
text-transform: uppercase;
text-align: center;
width: 95%;
color: white;
font-family: 'Share Tech';
line-height: 60px; line-height: 60px;
background-color: blue; background-color: blue;
display: block; display: block;
font-size: xx-large; font-size: xx-large;
margin: 10px; margin: 10px auto;
/*font-weight: bold;*/ cursor: pointer;
/*vertical-align: middle;*/ }
#teal_button{
text-transform: uppercase;
text-align: center;
width: 95%;
height: 60px;
background-color: teal;
border: none;
display: block;
font-family: 'Share Tech';
font-size: xx-large;
color: white;
/*vertical-align: middle;*/
margin: 10px auto;
cursor: pointer;
}
#teal_button_link{
text-transform: uppercase;
text-align: center;
width: 95%;
color: white;
font-family: 'Share Tech';
line-height: 60px;
background-color: teal;
display: block;
font-size: xx-large;
margin: 10px auto;
cursor: pointer;
}
#darkorange_button{
text-transform: uppercase;
text-align: center;
width: 95%;
height: 60px;
background-color: darkorange;
border: none;
display: block;
font-family: 'Share Tech';
font-size: xx-large;
color: white;
/*vertical-align: middle;*/
margin: 10px auto;
cursor: pointer;
}
#darkorange_button_link{
text-transform: uppercase;
text-align: center;
width: 95%;
color: white;
font-family: 'Share Tech';
line-height: 60px;
background-color: darkorange;
display: block;
font-size: xx-large;
margin: 10px auto;
cursor: pointer;
}
#grey_button{
text-transform: uppercase;
text-align: center;
width: 95%;
height: 60px;
background-color: grey;
border: none;
display: block;
font-family: 'Share Tech';
font-size: xx-large;
color: white;
/*vertical-align: middle;*/
margin: 10px auto;
cursor: pointer;
}
#grey_button_link{
text-transform: uppercase;
text-align: center;
width: 95%;
color: white;
font-family: 'Share Tech';
line-height: 60px;
background-color: grey;
display: block;
font-size: xx-large;
margin: 10px auto;
cursor: not-allowed;
}
#red_button_link{
text-transform: uppercase;
text-align: center;
width: 95%;
color: white;
font-family: 'Share Tech';
line-height: 60px;
background-color: red;
display: block;
font-size: xx-large;
margin: 10px auto;
cursor: pointer;
}
#green_button_link{
text-transform: uppercase;
text-align: center;
width: 95%;
color: white;
font-family: 'Share Tech';
line-height: 60px;
background-color: green;
display: block;
font-size: xx-large;
margin: 10px auto;
cursor: pointer;
}
#sell_box{
font-size: medium;
}
#sell_box img{
vertical-align: middle;
/*display: block;*/
margin: 0 auto;
}
.product{
color: black;
border: 1px solid silver;
text-transform: uppercase;
text-align: center;
padding-bottom: 0px;
/*padding: 0px;*/
/*margin-bottom: 0px;*/
cursor: pointer;
display:inline-block;
/*width: 400px;*/
min-width: 400px;
/*margin: 0px 0px 10px;*/
margin: 10px auto;
}
.product img{
vertical-align: middle;
display: block;
background-color: #ececec;
margin: 0 auto;
}
.product h2{
/*padding: 0px;*/
margin: 8px;
}
.product span{
color: darkgreen;
}
::-webkit-input-placeholder {
color: #afafaf;
}
:-moz-placeholder {
color: #afafaf;
opacity: 1;
}
::-moz-placeholder {
color: #afafaf;
opacity: 1;
}
:-ms-input-placeholder {
color: #afafaf;
}
#product_image{
display: block;
margin: 0 auto;
text-align: center;
} }

32
static/js/control.js Normal file
View File

@ -0,0 +1,32 @@
$(document).ready(function(){
$('.flashed_messages').delay(2000).fadeOut(1000);
$(":file").change(function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = picture_uploaded;
reader.readAsDataURL(this.files[0]);
}
});
$('img').load(function(){
if ($(this).attr('src') != "" ){
// alert('image exists');
$(this).attr('width', '325px');
$(this).attr('height', '325px');
}
});
});
function picture_uploaded(e){
picture = e.target.result;
$('img').attr('src', picture);
$('img').attr('width', 250);
$('img').attr('height', 250);
$('img').css('display', 'block');
// Center the image now that it has been uploaded
}

View File

@ -3,14 +3,33 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title> Login -- USCGA BearShop</title> <title>USCGA BearShop</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/master.css' ) }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/master.css' ) }}">
<script src="{{ url_for('static', filename='js/jquery.js' ) }}"></script> <script src="{{ url_for('static', filename='js/jquery.js' ) }}"></script>
<script src="{{ url_for('static', filename='js/notify.js' ) }}"></script> <script src="{{ url_for('static', filename='js/notify.js' ) }}"></script>
<script src="{{ url_for('static', filename='js/jquery-ui.min.js' ) }}"></script> <script src="{{ url_for('static', filename='js/jquery-ui.min.js' ) }}"></script>
<script src="{{ url_for('static', filename='js/control.js' ) }}"></script>
</head> </head>
<body> <body>
{% if session.logged_in %}
<div id="navigation">
<a href="{{url_for('profile', uuid=session.uuid) }}">{{ session.name }}</a>
<!-- {{ session.name }} -->
<ul>
<li> <a href="{{url_for('log_out')}}">LOG OUT</a> </li>
<!-- <li> <a href="{{url_for('search')}}">SEARCH</a> </li> -->
<li> <a href="{{url_for('sell')}}">SELL</a> </li>
<li> <a href="{{url_for('products')}}">SALES</a> </li>
</ul>
</div>
{% endif %}
{% for message in get_flashed_messages() %}
<p class='flashed_messages'>{{message}}</p>
{% endfor %}
{% block content %} {% block content %}
{% endblock %} {% endblock %}

33
templates/edit.html Normal file
View File

@ -0,0 +1,33 @@
{% extends "base_page.html" %}
{% block content %}
<div id="vertical">
<h1> Edit Product </h1>
<form method="POST" enctype="multipart/form-data">
<h1> <input type="text" name="name" value="{{name}}" placeholder="Product Name"> </h1>
<h2> <input style="color:darkgreen" type="text" name="price" value="{{price}}" placeholder="Price $"> </h2>
<p>
<strong>Seller:</strong> {{ seller }}
</p>
<img id="product_image" src="{{picture}}" alt="Upload a picture!">
<input style="display:inline; width:auto;" type="file" name="picture" value="">
<p>
<strong>Description:</strong> <br>
<textarea name="description" placeholder="Description of the Product">{{description}}</textarea>
</p>
<input type="hidden" name="uuid" value="{{uuid}}">
<input type="hidden" name="picture" value="{{picture}}">
<input type="submit" value="SAVE CHANGES" style="font-size:xx-large" id="green_button">
</form>
<a href="{{ url_for('remove_product', uuid=uuid)}}"><span id="red_button_link"> REMOVE PRODUCT </span></a>
</div>
{% endblock %}

View File

@ -0,0 +1,30 @@
<html>
<head></head>
<body>
<h2>You got someone's interest on <a href="http://uscgabearshop">
BearShop!</a></h2>
<p>
{{name}} showed an interest in your product, "{{product_name}}".
</p>
<p>
The contact information that they have made available is as follows:
</p>
<ul>
<li> <b> Email: </b> {{ email }}</li>
{% if phone %} <li> <b> Phone: </b> {{ phone }}</li> {% endif %}
{% if room %} <li> <b> Room: </b> {{ room }}</li> {% endif %}
</ul>
<p>
Thanks for using <a href="http://uscgabearshop">BearShop!</a> I hope you are enjoying its services. If you have any questions, concerns, or comments, be sure to let me know!
</p>
<p>
- John Hammond
</p>
</body>
</html>

63
templates/item.html Normal file
View File

@ -0,0 +1,63 @@
{% extends "base_page.html" %}
{% block content %}
<div id="vertical">
<h1> {{name}} </h1>
<h2> <span style="color:darkgreen">{{ price }}</span> </h2>
<p>
<strong>Seller:</strong> <a href="{{url_for('profile',uuid=seller_uuid)}}">{{ seller }}</a>
</p>
<img id="product_image" src="{{picture}}" alt="No image is available">
<p>
<strong>Description:</strong> {{ description }}
</p>
<br>
<hr><br>
{% if seller == session.name %}
<a href="{{ url_for('edit', uuid=uuid)}}"><span id="darkorange_button_link"> EDIT PRODUCT </span></a>
{% else %}
{% if session['name'] in interested_people %}
<span id="grey_button_link"> YOU HAVE ALREADY SHOWN INTEREST </span>
{% else %}
<div id="disclaimer">
<p>
Note that once you show interest, an e-mail will be sent to the seller noting that you are interested in the product. <b>Any contact information you enter in your profile will be included in this email.</b> </p>
<h3> Once you show interest in a product, you cannot undo this. An e-mail will be sent and you cannot "take it back". </h3>
</div>
<a href="{{ url_for('show_interest', seller=seller, uuid=uuid)}}"><span id="green_button_link"> SHOW INTEREST </span></a>
{% endif %}
{% endif %}
<br><hr><br>
<p style="color:teal">
Currently <b>{{ interested_people | length }}
{% if interested_people | length == 1 %}
person</b> is
{% else %}
people</b> are
{% endif %}
interested in this product.
</p>
{% if seller == session.name %}
<ul>
{% for person in interested_people %}
<li> {{ person }} </li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endblock %}

View File

@ -1,6 +1,7 @@
{% extends "base_page.html" %} {% extends "base_page.html" %}
{% block content %} {% block content %}
<div id="login_box_background"></div> <div id="login_box_background"></div>
<div id="login_box"> <div id="login_box">
@ -9,14 +10,14 @@
Please login below with your EDU e-mail and your BearShop password. Please login below with your EDU e-mail and your BearShop password.
</p> </p>
<form> <form method="POST">
<input type="text" name="email"> <input type="text" name="email" placeholder="E-mail" value="{{email}}">
<input type="password" name="password"> <input type="password" name="password" placeholder="Password">
<input type="submit" value="LOGIN" id="login"> <input type="submit" value="LOGIN" id="red_button">
</form> </form>
<a href="{{ url_for('register')}}"><span id="blue_button_link"> REGISTER </span></a>
<span id="register"> REGISTER </span>
</div> </div>

View File

@ -8,6 +8,7 @@
</head> </head>
<body> <body>
<div id="login_box_background"></div> <div id="login_box_background"></div>
<div id="login_box"> <div id="login_box">

27
templates/products.html Normal file
View File

@ -0,0 +1,27 @@
{% extends "base_page.html" %}
{% block content %}
<!-- <div id="login_box_background"></div> -->
<div id="vertical">
<div style="text-align:center">
{% if products|length == 0 %}
<h2 style="color:silver; text-align:center">
There is currently nothing for sale. :(
</h2>
{% else %}
{% for product in products %}
<a href="{{ url_for('product', uuid=product[3] )}}"><div class="product">
<img width=325px height=325px src="{{product[1]}}" alt="No image is available">
<h2> {{ product[0] }} <span> {{ product[2] }} </span> </h2>
</div></a>
{% endfor %}
{% endif %}
</div>
</div>
{% endblock %}

59
templates/profile.html Normal file
View File

@ -0,0 +1,59 @@
{% extends "base_page.html" %}
{% block content %}
<!-- <div id="login_box_background"></div> -->
<div id="vertical">
<h1> {{name}} </h1>
{% if name == session.name %}
<p>
To make communication easier once you show interest in some one else's product, you can enter your phone number or room number here. </p>
<p>
<b>This information will be included in any e-mail sent to notify interest, but it is completely optional for you to supply the information.</b>
</p>
<form method="POST">
<input type="text" name="phone" value="{{phone}}" placeholder="Phone: ###-###-####">
<input type="text" name="room" value="{{room}}" placeholder="Room: ####">
<input type="submit" value="SAVE CHANGES" id="green_button">
</form>
<br>
<hr><br>
{% endif %}
<p>
{% if name == session.name %}
You are
{% else %}
{{name}} is
{% endif %}
currently selling these products:
</p>
{% if products|length == 0 %}
<h2 style="color:silver; text-align: center">
Unfortunately, no products...
</h2>
{% else %}
<ul>
{% for product in products %}
<li> <a style="color:blue" href="{{url_for('product', uuid=product[1] ) }}">{{product[0]}} </a> </li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endblock %}

18
templates/register.html Normal file
View File

@ -0,0 +1,18 @@
{% extends "base_page.html" %}
{% block content %}
<div id="login_box_background"></div>
<div id="login_box">
<h1>Register an Account</h1>
<p>
To register an account with BearShop, we'll need you to supply your EDU e-mail account and decide on a secure password.
</p>
<form method="POST">
<input type="text" name="email" placeholder="E-mail" value="{{email}}">
<input type="password" name="password" placeholder="Password" value={{password}}>
<input type="password" name="confirm" placeholder="Confirm Password" value="{{confirm}}">
<input type="submit" value="REGISTER" id="blue_button">
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends "base_page.html" %}
{% block content %}
<div id="login_box_background"></div>
<div id="login_box">
<h2 style="color:silver; text-align:center">
Unfortunately this feature is not yet available.
</h2>
</div>
{% endblock %}

19
templates/search.html Normal file
View File

@ -0,0 +1,19 @@
{% extends "base_page.html" %}
{% block content %}
<div id="login_box_background"></div>
<div id="login_box">
{% for message in get_flashed_messages() %}
<p class='flashed_messages'><{{message}}</p>
{% endfor %}
<h2 style="color:silver; text-align:center">
Unfortunately this feature is not yet available.
</h2>
</div>
{% endblock %}

29
templates/sell.html Normal file
View File

@ -0,0 +1,29 @@
{% extends "base_page.html" %}
{% block content %}
<div id="text-align:center">
<div id="vertical">
<h1> Sell a Product</h1>
<div id="sell_box">
<form method="POST" enctype="multipart/form-data">
<img src="" alt="Upload a picture! (optional)">
<br> <br>
<input style="display:inline; width:auto;" type="file" name="picture" value="">
<p></p>
<input type="text" name="name" placeholder="Product Name" value="{{name}}">
<p></p>
<input style="color:darkgreen" type="text" name="price" placeholder="Price $" value={{price}}>
<p></p>
<textarea name="description" placeholder="Description of the Product">{{description}}</textarea>
<p></p>
<input type="submit" value="SELL" style="font-size:xx-large" id="red_button">
</form>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,33 @@
<html>
<head></head>
<body>
<h2>Thank you for registering with <a href="http://uscgabearshop">
BearShop!</a></h2>
<p>
To complete your registraton, you must submit this verification code:
</p>
<code>{{identifier}}</code>
<p>
You can do this more quickly by simply clicking this link:
</p>
<p>
<a href="http://uscgabearshop.com/verify?identifier={{identifier}}"> http://uscgabearshop.com/verify?identifier={{identifier}}</a>
</p>
<p>
Thanks for registering, and I hope you enjoy <a href="http://uscgabearshop">
BearShop!</a>
</p>
<p>
- John Hammond
</p>
</body>
</html>

23
templates/verify.html Normal file
View File

@ -0,0 +1,23 @@
{% extends "base_page.html" %}
{% block content %}
<div id="login_box_background"></div>
<div id="login_box">
<h1>Verify your Account</h1>
<p>
Your account, {{session.email}}, still needs to be verified.
</p>
<p>
Please check your e-mail and submit the unique identifier that has been sent to you.
</p>
<form method="POST">
<input type="text" name="identifier" placeholder="">
<input type="submit" value="Submit" id="red_button">
</form>
<a href="{{ url_for('send_verification_link')}}"><span id="blue_button_link"> SEND E-MAIL AGAIN </span></a>
</div>
{% endblock %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB