This commit is contained in:
b3yond 2019-03-06 19:43:59 +00:00 committed by GitHub
commit 7d41a1636d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 160 additions and 37 deletions

3
.gitignore vendored
View file

@ -1,5 +1,7 @@
*.swp
*.pyc
*.egg-info/
*.eggs
.idea/
__pycache__/
last_mention
@ -17,4 +19,3 @@ include/
lib/
share/
local/
venv/

2
setup.cfg Normal file
View file

@ -0,0 +1,2 @@
[aliases]
test=pytest

37
setup.py Normal file
View file

@ -0,0 +1,37 @@
from setuptools import setup
import sys
import os
PACKAGE_NAME = "ticketfrei"
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), PACKAGE_NAME))
setup(
name=PACKAGE_NAME,
version='',
packages=[
PACKAGE_NAME
],
url='https://github.com/ticketfrei/ticketfrei',
license='ISC',
author='',
author_email='',
description='',
setup_requires=[
'pytest-runner',
],
install_requires=[
'bottle',
'gitpython',
'pyjwt',
'Markdown',
'Mastodon.py',
'pylibscrypt',
'pytoml',
'tweepy',
'twx',
],
tests_require=[
'pytest',
],
)

View file

@ -1,2 +0,0 @@
% rebase('template/wrapper.tpl', title='Login')
% include('template/login-plain.tpl')

View file

@ -17,7 +17,7 @@ def shutdown():
if __name__ == '__main__':
logger = logging.getLogger()
fh = logging.FileHandler('/var/log/ticketfrei/backend.log')
fh = logging.FileHandler(config["log"]["log_backend"])
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)

View file

View file

@ -1,6 +1,10 @@
import pytoml as toml
import os
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
TEMPLATE_DIR = os.path.join(ROOT_DIR, 'template', '')
STATIC_DIR = os.path.join(ROOT_DIR, 'static', '')
BOT_DIR = os.path.join(ROOT_DIR, 'bots')
def load_env():
"""
@ -9,7 +13,7 @@ def load_env():
:return: config dictionary of dictionaries.
"""
with open('config.toml.example') as defaultconf:
with open(os.path.join(ROOT_DIR, 'config.toml.example')) as defaultconf:
configdict = toml.load(defaultconf)
try:
@ -54,12 +58,24 @@ def load_env():
except KeyError:
pass
try:
if os.environ['LOG_FRONTEND'] != "":
configdict['log']['log_frontend'] = os.environ['LOG_FRONTEND']
except KeyError:
pass
try:
if os.environ['LOG_BACKEND'] != "":
configdict['log']['log_backend'] = os.environ['LOG_BACKEND']
except KeyError:
pass
return configdict
# read config in TOML format (https://github.com/toml-lang/toml#toml)
try:
with open('config.toml') as configfile:
with open(os.path.join(ROOT_DIR, 'config.toml')) as configfile:
config = toml.load(configfile)
except FileNotFoundError:
config = load_env()

View file

@ -11,6 +11,11 @@ contact = "b3yond@riseup.net"
[mail]
mbox_user = "root"
aliases_path = "/etc/aliases"
[database]
db_path = "/var/ticketfrei/db.sqlite"
[log]
log_frontend = "/var/ticketfrei/frontend.log"
log_backend = "/var/log/ticketfrei/backend.log"

View file

@ -243,7 +243,7 @@ u\d\d?"""
(uid, "bastard"))
else:
uid = json['uid']
with open("/etc/aliases", "a+") as f:
with open(config['mail']['aliases_path'], "a+") as f:
f.write(city + ": " + config["mail"]["mbox_user"] + "\n")
self.execute("INSERT INTO email (user_id, email) VALUES(?, ?);",
(uid, json['email']))

View file

@ -2,7 +2,7 @@
import bottle
from os import listdir, path
from bottle import get, post, redirect, request, response, view
from config import config
from config import config, STATIC_DIR, TEMPLATE_DIR
from db import db
import logging
import tweepy
@ -19,13 +19,13 @@ def url(route):
@get('/')
@view('template/propaganda.tpl')
@view('propaganda.tpl')
def propaganda():
pass
@post('/register')
@view('template/register.tpl')
@view('register.tpl')
def register_post():
try:
email = request.forms['email']
@ -55,7 +55,7 @@ def register_post():
@get('/confirm/<city>/<token>')
@view('template/propaganda.tpl')
@view('propaganda.tpl')
def confirm(city, token):
# check whether city already exists
if db.by_city(city):
@ -76,7 +76,7 @@ def version():
@post('/login')
@view('template/login.tpl')
@view('login.tpl')
def login_post():
# check login
try:
@ -95,14 +95,14 @@ def city_page(city, info=None):
citydict = db.user_facing_properties(city)
if citydict is not None:
citydict['info'] = info
return bottle.template('template/city.tpl', **citydict)
return bottle.template('template/propaganda.tpl',
return bottle.template('city.tpl', **citydict)
return bottle.template('propaganda.tpl',
**dict(info='There is no Ticketfrei bot in your city'
' yet. Create one yourself!'))
@get('/city/mail/<city>')
@view('template/mail.tpl')
@view('mail.tpl')
def display_mail_page(city):
user = db.by_city(city)
return user.state()
@ -139,34 +139,34 @@ def unsubscribe(token):
@get('/settings')
@view('template/settings.tpl')
@view('settings.tpl')
def settings(user):
return user.state()
@post('/settings/markdown')
@view('template/settings.tpl')
@view('settings.tpl')
def update_markdown(user):
user.set_markdown(request.forms['markdown'])
return user.state()
@post('/settings/mail_md')
@view('template/settings.tpl')
@view('settings.tpl')
def update_mail_md(user):
user.set_mail_md(request.forms['mail_md'])
return user.state()
@post('/settings/goodlist')
@view('template/settings.tpl')
@view('settings.tpl')
def update_trigger_patterns(user):
user.set_trigger_words(request.forms['goodlist'])
return user.state()
@post('/settings/blocklist')
@view('template/settings.tpl')
@view('settings.tpl')
def update_badwords(user):
user.set_badwords(request.forms['blocklist'])
return user.state()
@ -187,12 +187,12 @@ def register_telegram(user):
@get('/static/<filename:path>')
def static(filename):
return bottle.static_file(filename, root='static')
return bottle.static_file(filename, root=STATIC_DIR)
@get('/guides/<filename:path>')
def guides(filename):
return bottle.static_file(filename, root='guides')
# IS THIS USED?
#@get('/guides/<filename:path>')
#def guides(filename):
# return bottle.static_file(filename, root='guides')
@get('/logout/')
@ -265,14 +265,16 @@ def login_mastodon(user):
logger = logging.getLogger()
fh = logging.FileHandler('/var/log/ticketfrei/error.log')
fh = logging.FileHandler(config['log']['log_frontend'])
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
# TODO change TEMPLATE_PATH to BOTS_DIR after refactoring
bottle.TEMPLATE_PATH.insert(0, TEMPLATE_DIR)
application = bottle.default_app()
bottle.install(SessionPlugin('/'))
if __name__ == '__main__':
bottle.run(host="0.0.0.0", port=config["web"]["port"])
bottle.run(host=config["web"]["host"], port=config["web"]["port"])
else:
application.catchall = False

View file

Before

Width:  |  Height:  |  Size: 628 KiB

After

Width:  |  Height:  |  Size: 628 KiB

View file

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View file

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View file

@ -1,4 +1,4 @@
% rebase('template/wrapper.tpl')
% rebase('wrapper.tpl')
<%
import markdown as md

View file

@ -0,0 +1,2 @@
% rebase('wrapper.tpl', title='Login')
% include('login-plain.tpl')

View file

@ -1,4 +1,4 @@
% rebase('template/wrapper.tpl')
% rebase('wrapper.tpl')
<%
import markdown as md

View file

@ -1,4 +1,4 @@
% rebase('template/wrapper.tpl')
% rebase('wrapper.tpl')
% if defined('info'):
<div class="ui-widget">
<div class="ui-state-highlight ui-corner-all" style="padding: 0.7em;">
@ -7,7 +7,7 @@
</div>
<br>
% end
% include('template/login-plain.tpl')
% include('login-plain.tpl')
<h1>Features</h1>
<p>
Don't pay for public transport. Instead, warn each other
@ -45,7 +45,7 @@
share it with us, so others can use it, too!</li>
</ul></li>
</ul>
% include('template/register-plain.tpl')
% include('register-plain.tpl')
<h2>Our Mission</h2>
<p>
Public transportation is meant to provide an easy and

View file

@ -1,4 +1,4 @@
% rebase('template/wrapper.tpl', title='Register')
% rebase('wrapper.tpl', title='Register')
% if defined('info'):
<div class="ui-widget">
<div class="ui-state-highlight ui-corner-all" style="padding: 0.7em;">
@ -6,5 +6,5 @@
</div>
</div>
% else:
% include('template/register-plain.tpl')
% include('register-plain.tpl')
% end

View file

@ -1,4 +1,4 @@
% rebase('template/wrapper.tpl')
% rebase('wrapper.tpl')
<a href="/logout/"><button>Logout</button></a>
% if enabled:
@ -9,11 +9,12 @@
<%
# import all the settings templates from bots/*/settings.tpl
from config import BOT_DIR
import os
bots = os.listdir('bots')
bots = os.listdir(BOT_DIR)
for bot in bots:
include('bots/' + bot + '/settings.tpl', csrf=csrf, city=city)
include(os.path.join(BOT_DIR, bot, 'settings.tpl'), csrf=csrf, city=city)
end
%>

View file

@ -0,0 +1,20 @@
[twitter]
# You get those keys when you follow these steps:
# https://developer.twitter.com/en/docs/basics/authentication/guides/access-tokens
consumer_key = "your_consumer_key"
consumer_secret = "your_consumer_secret"
[web]
host = "0.0.0.0" # will be used by bottle as a host.
port = 80
contact = "b3yond@riseup.net"
[mail]
mbox_user = "root"
[database]
db_path = "/var/ticketfrei/db.sqlite"
[log]
log_frontend = "/var/ticketfrei/frontend.log"
log_backend = "/var/log/ticketfrei/backend.log"

View file

@ -0,0 +1,23 @@
from webtest import TestApp
import unittest
import frontend
app = TestApp(frontend.application)
class TestLogin(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_login_not_registered(self):
request = app.post('/login', {'email': '', 'pass': ''}, expect_errors=True)
self.assertEqual(401, request.status_code)
def test_login_registered(self):
request = app.post('/register', {'email': 'foo@abc.de', 'pass': 'bar', 'pass-repeat': 'bar', 'city': 'testcity'}, expect_errors=True)
request = app.post('/login', {'email': 'foor@abc.de', 'pass': 'bar'}, expect_errors=False)
self.assertEqual(200, request.status_code)

View file

@ -0,0 +1,16 @@
from webtest import TestApp
import unittest
import frontend
app = TestApp(frontend.application)
class TestRegister(unittest.TestCase):
def test_register(self):
request = app.post('/register', {'email': 'foo@abc.de', 'pass': 'bar', 'pass-repeat': 'bar', 'city': 'testcity'}, expect_errors=True)
self.assertEqual(200, request.status_code)
def test_getRoot(self):
request = app.get('/')
self.assertEqual(200, request.status_code)