you can now set goodlist & blacklist in settings. render city page #18. fixed #24 and #25.

master
b3yond 2018-05-25 15:57:20 +02:00
parent 6b05686379
commit d633506c83
6 changed files with 188 additions and 108 deletions

View File

@ -91,7 +91,7 @@ virtualenv -p python3 .
Install the dependencies:
```shell
pip install tweepy pytoml Mastodon.py bottle pyjwt pylibscrypt
pip install tweepy pytoml Mastodon.py bottle pyjwt pylibscrypt Markdown
```
Configure the bot:

31
db.py
View File

@ -42,13 +42,13 @@ class DB(object):
CREATE TABLE IF NOT EXISTS triggerpatterns (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
user_id INTEGER,
pattern TEXT,
patterns TEXT,
FOREIGN KEY(user_id) REFERENCES user(id)
);
CREATE TABLE IF NOT EXISTS badwords (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
user_id INTEGER,
word TEXT,
words TEXT,
FOREIGN KEY(user_id) REFERENCES user(id)
);
CREATE TABLE IF NOT EXISTS mastodon_instances (
@ -146,10 +146,29 @@ class DB(object):
self.execute("INSERT INTO user (passhash) VALUES(?);",
(json['passhash'], ))
uid = self.cur.lastrowid
self.execute("""
INSERT INTO triggerpatterns (user_id, pattern)
VALUES(?, ?);
""", (uid, '.*'))
default_triggerpatterns = """
kontroll?e
konti
db
vgn
vag
zivil
sicherheit
uniform
station
bus
bahn
tram
linie
nuernberg
nürnberg
s\d
u\d\d?
"""
self.execute("""INSERT INTO triggerpatterns (user_id, patterns)
VALUES(?, ?); """, (uid, default_triggerpatterns))
self.execute("INSERT INTO badwords (user_id, words) VALUES(?, ?);",
(uid, ""))
else:
uid = json['uid']
self.execute("INSERT INTO email (user_id, email) VALUES(?, ?);",

View File

@ -38,7 +38,7 @@ def register_post():
return dict(error='Email address already in use.')
# send confirmation mail
try:
# print(url('confirm/' + city + '/%s' % db.user_token(email, password))) # only for local testing
print(url('confirm/' + city + '/%s' % db.user_token(email, password))) # only for local testing
sendmail(
email,
"Confirm your account",
@ -93,6 +93,20 @@ def settings(user):
return user.state()
@post('/settings/goodlist')
@view('template/settings.tpl')
def update_trigger_patterns(user):
user.set_trigger_words(request.forms['goodlist'])
return user.state()
@post('/settings/blacklist')
@view('template/settings.tpl')
def update_badwords(user):
user.set_badwords(request.forms['blacklist'])
return user.state()
@get('/api/state')
def api_enable(user):
return user.state()

View File

@ -1,4 +1,9 @@
% rebase('template/wrapper.tpl')
$markdown.render()
<%
import markdown as md
html = md.markdown(markdown)
%>
{{html}}

View File

@ -1,7 +1,11 @@
% rebase('template/wrapper.tpl')
<a href="/logout/"><button>Logout</button></a>
<div id="enablebutton" style="float: right; padding: 2em;">asdf</div>
% if enabled:
<div id="enablebutton" style="float: right; padding: 2em;">Disable</div>
% else:
<div id="enablebutton" style="float: right; padding: 2em;" color="red">Enable</div>
% end
<a class='button' style="padding: 1.5em;" href="/login/twitter">
<picture>
@ -72,7 +76,7 @@
suggest:
</p>
<form action="/settings/goodlist" method="post">
<textarea id="markdown" rows="20" cols="70" name="goodlist" wrap="physical">$markdown</textarea>
<textarea id="markdown" rows="20" cols="70" name="goodlist" wrap="physical">{{markdown}}</textarea>
<input name='confirm' value='Save' type='submit'/>
</form>
</div>
@ -86,7 +90,7 @@
</p>
<form action="/settings/goodlist" method="post">
<!-- find a way to display current good list. js which reads from a cookie? template? -->
<textarea id="goodlist" rows="8" cols="70" name="goodlist" wrap="physical">$triggerwords</textarea>
<textarea id="goodlist" rows="8" cols="70" name="goodlist" wrap="physical">{{triggerwords}}</textarea>
<input name='confirm' value='Submit' type='submit'/>
</form>
</div>
@ -100,7 +104,7 @@
</p>
<form action="/settings/blacklist" method="post">
<!-- find a way to display current blacklist. js which reads from a cookie? template? -->
<textarea id="blacklist" rows="8" cols="70" name="blacklist" wrap="physical">$badwords</textarea>
<textarea id="blacklist" rows="8" cols="70" name="blacklist" wrap="physical">{{badwords}}</textarea>
<input name='confirm' value='Submit' type='submit'/>
</form>
</div>

70
user.py
View File

@ -27,7 +27,7 @@ class User(object):
@property
def enabled(self):
db.execute("SELECT enabled FROM user WHERE user_id=?;", (self.uid, ))
db.execute("SELECT enabled FROM user WHERE id=?;", (self.uid, ))
return bool(db.cur.fetchone()[0])
@enabled.setter
@ -59,16 +59,35 @@ class User(object):
def is_appropriate(self, report):
db.execute("SELECT pattern FROM triggerpatterns WHERE user_id=?;",
(self.uid, ))
for pattern, in db.cur.fetchall():
patterns = db.cur.fetchone()
for pattern in patterns.splitlines():
if pattern.search(report.text) is not None:
break
else:
# no pattern matched
return False
default_badwords = """
bastard
bitch
whore
hitler
slut
hure
jude
schwuchtel
fag
faggot
nigger
neger
schlitz
"""
db.execute("SELECT word FROM badwords WHERE user_id=?;",
(self.uid, ))
badwords = [word.lower() for word, in db.cur.fetchall()]
for word in report.text.lower().split():
badwords = db.cur.fetchone()
for word in report.text.lower().splitlines():
if word in badwords:
return False
for word in default_badwords.splitlines():
if word in badwords:
return False
return True
@ -129,8 +148,22 @@ class User(object):
db.execute("UPDATE seen_mail SET mail_date = ? WHERE user_id = ?;",
(mail_date, self.uid))
def get_trigger_words(self, table):
db.execute("SELECT words FROM ? WHERE user_id = ?;", (table, self.uid,))
def set_trigger_words(self, patterns):
db.execute("UPDATE triggerpatterns SET patterns = ? WHERE user_id = ?;",
(patterns, self.uid))
def get_trigger_words(self):
db.execute("SELECT patterns FROM triggerpatterns WHERE user_id = ?;",
(self.uid,))
return db.cur.fetchone()[0]
def set_badwords(self, words):
db.execute("UPDATE badwords SET words = ? WHERE user_id = ?;",
(words, self.uid))
def get_badwords(self):
db.execute("SELECT words FROM badwords WHERE user_id = ?;",
(self.uid,))
return db.cur.fetchone()[0]
def state(self):
@ -142,7 +175,12 @@ class User(object):
# - logged in with twitter?
# - logged in with mastodon?
# - enabled?
return dict(foo='bar')
citydict = db.user_facing_properties(self.get_city())
return dict(city=citydict['city'],
markdown=citydict['markdown'],
triggerwords=self.get_trigger_words(),
badwords=self.get_badwords(),
enabled=self.enabled)
def save_request_token(self, token):
db.execute("INSERT INTO twitter_request_tokens(user_id, request_token, request_token_secret) VALUES(?, ?, ?);",
@ -191,20 +229,20 @@ class User(object):
db.commit()
def get_city(self):
db.execute("SELECT city FROM user WHERE id == ?;", (self.uid, ))
db.execute("SELECT city FROM cities WHERE user_id == ?;", (self.uid, ))
return db.cur.fetchone()[0]
def set_city(self, city):
masto_link = "masto.social/@" + city # get masto_link
twit_link = "twitter.com/" + city # get twit_link
masto_link = "example.mastodon.social/@" + city # get masto_link
twit_link = "example.twitter.com/" + city # get twit_link
mailinglist = city + "@" + config['web']['host']
markdown = """
= Wie funktioniert Ticketfrei? =
# Wie funktioniert Ticketfrei?
Willst du mithelfen, Ticketkontrolleure zu überwachen?
Willst du einen Fahrscheinfreien ÖPNV erkämpfen?
== Ist es gerade sicher, schwarz zu fahren? ==
## Ist es gerade sicher, schwarz zu fahren?
Schau einfach auf das Profil unseres Bots: """ + twit_link + """
@ -224,7 +262,7 @@ class User(object):
Also, wenn du weniger Glück hast, und der erste bist, der einen
Kontrolleur sieht:
== Was mache ich, wenn ich Kontis sehe? ==
## Was mache ich, wenn ich Kontis sehe?
Ganz einfach, du schreibst es den anderen. Das geht entweder
@ -251,8 +289,8 @@ class User(object):
Danke, dass du mithilfst, öffentlichen Verkehr für alle
sicherzustellen!
== Kann ich darauf vertrauen, was random stranger from the
Internet mir da erzählen? ==
## Kann ich darauf vertrauen, was random stranger from the
Internet mir da erzählen?
Aber natürlich! Wir haben Katzenbilder!
@ -272,7 +310,7 @@ class User(object):
Also ja - es macht Sinn, uns zu vertrauen, wenn wir sagen, wo
gerade Kontis sind.
== Was ist Mastodon und warum sollte ich es benutzen? ==
## Was ist Mastodon und warum sollte ich es benutzen?
Mastodon ist ein dezentrales soziales Netzwerk - so wie
Twitter, nur ohne Monopol und Zentralismus.