diff --git a/.gitignore b/.gitignore index 02b4056..a1d831b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,7 @@ word-rnn-tensorflow/ .idea/ __pycache__/ config.py +*.old + +web/static/css/ +!web/static/css/.gitkeep diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a31e40c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "web/milligram"] + path = web/milligram + url = git@github.com:Findus23/milligram.git diff --git a/app.py b/app.py new file mode 100644 index 0000000..5c68e77 --- /dev/null +++ b/app.py @@ -0,0 +1,18 @@ +# Blog configuration values. + +from flask import Flask +from playhouse.flask_utils import FlaskDB +from playhouse.pool import PooledMySQLDatabase + +import config + +DATABASE = PooledMySQLDatabase("stackdata", **config.db) + + +# Create a Flask WSGI app and configure it using values from the module. +app = Flask(__name__) +app.config.from_object(__name__) + +flask_db = FlaskDB(app) + +db = flask_db.database diff --git a/models.py b/models.py index 72fb433..9fbb8e5 100644 --- a/models.py +++ b/models.py @@ -38,6 +38,7 @@ class Question(BaseModel): title = ForeignKeyField(Title) user = ForeignKeyField(User) site = ForeignKeyField(Site) + datetime = DateTimeField() class Answer(BaseModel): diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c4e128b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,20 @@ +args==0.1.0 +backports.csv==1.0.5 +beautifulsoup4==4.6.0 +certifi==2018.1.18 +chardet==3.0.4 +clint==0.5.1 +docopt==0.6.2 +html2text==2018.1.9 +idna==2.6 +internetarchive==1.7.7 +jsonlines==1.2.0 +jsonpatch==1.21 +jsonpointer==2.0 +lxml==4.2.0 +mysqlclient==1.3.12 +peewee==3.1.3 +requests==2.18.4 +schema==0.6.7 +six==1.11.0 +urllib3==1.22 diff --git a/server.py b/server.py new file mode 100644 index 0000000..3888e20 --- /dev/null +++ b/server.py @@ -0,0 +1,68 @@ +from datetime import datetime + +from flask import render_template, flash +from playhouse.shortcuts import model_to_dict +from sassutils.wsgi import SassMiddleware + +import utils +from app import app +from models import * + +app.jinja_env.globals.update(prettydate=utils.prettydate) + +def query_to_response(query, limit=10, key=False, sort=False, offset=None, list=None, **kwargs): + """ + + :param sort: boolean + :param offset: int + :type key: str + :type limit: int|boolean + :param **kwargs + :type query: peewee.ModelSelect + """ + if limit: + query = query.limit(limit) + print(query.sql()) + data = {} if key is not False else [] + order = int(offset) if offset else 0 + for i in query: + element = model_to_dict(i, **kwargs) + if list: + element = element[list] + if sort: + element["order"] = order + order += 1 + if key is not False: + if "." in key: + key1, key2 = key.split(".") + data[getattr(getattr(i, key1), key2)] = element + else: + data[getattr(i, key)] = element + else: + data.append(element) + return data + + +@app.route('/') +def index(): + query = Question.select().limit(10) + # return query_to_response(Question.select().limit(10), limit=False, max_depth=1) + # return query_to_response(query, max_depth=1) + return render_template('list.html', questions=query_to_response(query, max_depth=1)) + + +@app.route('/q/') +def question(slug): + # query = Question.select().limit(10) + # return query_to_response(Question.select().limit(10), limit=False, max_depth=1) + # return query_to_response(query, max_depth=1) + return render_template("detail.html", question=slug) + # return render_template('list.html', questions=query_to_response(query, max_depth=1)) + + +if __name__ == '__main__': + app.debug = True + app.wsgi_app = SassMiddleware(app.wsgi_app, manifests={ + 'web': ('static/sass', 'static/css', '/static/css') + }) + app.run() diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..7b7ff1e --- /dev/null +++ b/templates/base.html @@ -0,0 +1,10 @@ + +Flaskr + +
+

Flaskr

+ {% for message in get_flashed_messages() %} +
{{ message }}
+ {% endfor %} + {% block body %}{% endblock %} +
diff --git a/templates/detail.html b/templates/detail.html new file mode 100644 index 0000000..b966317 --- /dev/null +++ b/templates/detail.html @@ -0,0 +1,4 @@ +{% extends "base.html" %} +{% block body %} +

{{ question }}

+{% endblock %} diff --git a/templates/list.html b/templates/list.html new file mode 100644 index 0000000..c0ea81d --- /dev/null +++ b/templates/list.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} +{% block body %} + {% for question in questions %} +
+
+ +
{{ question.upvotes - question.downvotes }}
+ +
+
+ + {{ question.site.name }} + +
+ {{ question.title.text }} +
+ {{ question.text }} +
+ asked {{ prettydate(question.datetime) }} by {{ question.user.username }} +
+
+
+ {% else %} + Unbelievable. No entries here so far + {% endfor %} +
{{ questions[0]|pprint }}
+{% endblock %} diff --git a/todb.py b/todb.py index 74e9385..66e46e1 100644 --- a/todb.py +++ b/todb.py @@ -1,3 +1,5 @@ +from datetime import datetime + from slugify import slugify from models import * @@ -34,7 +36,8 @@ def add_question(site, count=100): print(title.text) user = users[i] print(user.username) - Question.create(text=text, title_id=title, user_id=user, site_id=site) + time = datetime.now() + Question.create(text=text, title_id=title, user_id=user, site_id=site, datetime=time) if __name__ == "__main__": diff --git a/utils.py b/utils.py index a76e7de..5ef36e8 100644 --- a/utils.py +++ b/utils.py @@ -3,6 +3,7 @@ import random import resource import string import sys +from datetime import datetime from bs4 import BeautifulSoup from internetarchive import get_item @@ -56,3 +57,27 @@ def get_settings(count): def get_random_string(length): return ''.join(random.choices(string.ascii_uppercase + string.digits, k=length)) + + +def prettydate(d): + diff = datetime.now() - d + s = diff.seconds + print(diff) + if diff.days > 7 or diff.days < 0: + return d.strftime('%d %b %y') + elif diff.days == 1: + return '1 day ago' + elif diff.days > 1: + return '{} days ago'.format(diff.days) + elif s <= 1: + return 'just now' + elif s < 60: + return '{} seconds ago'.format(s) + elif s < 120: + return '1 minute ago' + elif s < 3600: + return '{} minutes ago'.format(int(s / 60)) + elif s < 7200: + return '1 hour ago' + else: + return '{} hours ago'.format(int(s / 3600)) diff --git a/web/__init__.py b/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/milligram b/web/milligram new file mode 160000 index 0000000..0fde381 --- /dev/null +++ b/web/milligram @@ -0,0 +1 @@ +Subproject commit 0fde381605c1159f39efb5c33c9600331fec4e2e diff --git a/web/static/sass/style.scss b/web/static/sass/style.scss new file mode 100644 index 0000000..f1ae270 --- /dev/null +++ b/web/static/sass/style.scss @@ -0,0 +1,73 @@ +$link-color: #07C; +$link-hover-color: #3af; + +@import "../../milligram/src/milligram"; + +body { + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + color: #111; +} + +pre > code { + white-space: pre-wrap; +} + +.question { + position: relative; + + display: flex; + flex-direction: row; + padding: 15px 5px 30px; + border-bottom: solid lightgray 1px; + border-right: solid 10px; + .questionbox { + margin-left: 10px; + .sitename { + position: absolute; + font-size: 10px; + color: grey; + right: 5px; + &:hover { + text-decoration: underline; + } + } + .date{ + position: absolute; + right: 5px; + bottom: 5px; + font-size: 12px; + color: grey; + } + } + .title { + font-size: 20px; + color: $link-color; + &:hover { + color: $link-hover-color; + } + } + .vote { + width: 30px; + display: flex; + flex-direction: column; + div { + text-align: center; + margin: 10px 0; + } + a { + font-size: 20px; + width: 0; + height: 0; + border-style: solid; + cursor: pointer; + } + .up { + border-width: 0 15px 15px 15px; + border-color: transparent transparent #858c93 transparent; + } + .down { + border-width: 15px 15px 0 15px; + border-color: #858c93 transparent transparent transparent; + } + } +} diff --git a/web/static/sass/variables.scss b/web/static/sass/variables.scss new file mode 100644 index 0000000..e69de29