You can now set data for the city page. #22
This commit is contained in:
parent
d4d58daf40
commit
04a6b82c1b
12
db.py
12
db.py
|
@ -122,7 +122,8 @@ class DB(object):
|
||||||
markdown TEXT,
|
markdown TEXT,
|
||||||
masto_link TEXT,
|
masto_link TEXT,
|
||||||
twit_link TEXT,
|
twit_link TEXT,
|
||||||
FOREIGN KEY(user_id) REFERENCES user(id)
|
FOREIGN KEY(user_id) REFERENCES user(id),
|
||||||
|
UNIQUE(user_id, city) ON CONFLICT IGNORE
|
||||||
);
|
);
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ class DB(object):
|
||||||
).decode('ascii')
|
).decode('ascii')
|
||||||
}, self.secret).decode('ascii')
|
}, self.secret).decode('ascii')
|
||||||
|
|
||||||
def confirm(self, token):
|
def confirm(self, token, city):
|
||||||
from user import User
|
from user import User
|
||||||
try:
|
try:
|
||||||
json = jwt.decode(token, self.secret)
|
json = jwt.decode(token, self.secret)
|
||||||
|
@ -154,7 +155,9 @@ class DB(object):
|
||||||
self.execute("INSERT INTO email (user_id, email) VALUES(?, ?);",
|
self.execute("INSERT INTO email (user_id, email) VALUES(?, ?);",
|
||||||
(uid, json['email']))
|
(uid, json['email']))
|
||||||
self.commit()
|
self.commit()
|
||||||
return User(uid)
|
user = User(uid)
|
||||||
|
user.set_city(city)
|
||||||
|
return user
|
||||||
|
|
||||||
def by_email(self, email):
|
def by_email(self, email):
|
||||||
from user import User
|
from user import User
|
||||||
|
@ -174,7 +177,8 @@ class DB(object):
|
||||||
return dict(city=city,
|
return dict(city=city,
|
||||||
markdown=markdown,
|
markdown=markdown,
|
||||||
masto_link=masto_link,
|
masto_link=masto_link,
|
||||||
twit_link=twit_link)
|
twit_link=twit_link,
|
||||||
|
mailinglist=city + "@" + config["web"]["host"])
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
18
frontend.py
18
frontend.py
|
@ -29,6 +29,7 @@ def register_post():
|
||||||
email = request.forms['email']
|
email = request.forms['email']
|
||||||
password = request.forms['pass']
|
password = request.forms['pass']
|
||||||
password_repeat = request.forms['pass-repeat']
|
password_repeat = request.forms['pass-repeat']
|
||||||
|
city = request.forms['city']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return dict(error='Please, fill the form.')
|
return dict(error='Please, fill the form.')
|
||||||
if password != password_repeat:
|
if password != password_repeat:
|
||||||
|
@ -37,11 +38,12 @@ def register_post():
|
||||||
return dict(error='Email address already in use.')
|
return dict(error='Email address already in use.')
|
||||||
# send confirmation mail
|
# send confirmation mail
|
||||||
try:
|
try:
|
||||||
|
# print(url('confirm/' + city + '/%s' % db.user_token(email, password))) # only for local testing
|
||||||
sendmail(
|
sendmail(
|
||||||
email,
|
email,
|
||||||
"Confirm your account",
|
"Confirm your account",
|
||||||
"Complete your registration here: %s" % (
|
"Complete your registration here: %s" % (
|
||||||
url('confirm/%s' % db.user_token(email, password))
|
url('confirm/' + city + '/%s' % db.user_token(email, password))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return dict(info='Confirmation mail sent.')
|
return dict(info='Confirmation mail sent.')
|
||||||
|
@ -50,11 +52,11 @@ def register_post():
|
||||||
return dict(error='Could not send confirmation mail.')
|
return dict(error='Could not send confirmation mail.')
|
||||||
|
|
||||||
|
|
||||||
@get('/confirm/<token>')
|
@get('/confirm/<city>/<token>')
|
||||||
@view('template/propaganda.tpl')
|
@view('template/propaganda.tpl')
|
||||||
def confirm(token):
|
def confirm(city, token):
|
||||||
# create db-entry
|
# create db-entry
|
||||||
if db.confirm(token):
|
if db.confirm(token, city):
|
||||||
# :todo show info "Account creation successful."
|
# :todo show info "Account creation successful."
|
||||||
redirect('/settings')
|
redirect('/settings')
|
||||||
return dict(error='Email confirmation failed.')
|
return dict(error='Email confirmation failed.')
|
||||||
|
@ -76,9 +78,13 @@ def login_post():
|
||||||
|
|
||||||
|
|
||||||
@get('/city/<city>')
|
@get('/city/<city>')
|
||||||
@view('template/user-facing.tpl')
|
@view('template/city.tpl')
|
||||||
def city_page(city):
|
def city_page(city):
|
||||||
return db.user_facing_properties(city)
|
citydict = db.user_facing_properties(city)
|
||||||
|
if citydict is not None:
|
||||||
|
return citydict
|
||||||
|
redirect('/')
|
||||||
|
return dict(info='There is no Ticketfrei bot in your city yet. Create one yourself!')
|
||||||
|
|
||||||
|
|
||||||
@get('/settings')
|
@get('/settings')
|
||||||
|
|
BIN
promotion/vag-zeitung.xcf
Normal file
BIN
promotion/vag-zeitung.xcf
Normal file
Binary file not shown.
4
template/city.tpl
Normal file
4
template/city.tpl
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
% rebase('template/wrapper.tpl')
|
||||||
|
|
||||||
|
$markdown.render()
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
<label for="email">Email</label>
|
<label for="email">Email</label>
|
||||||
<input type="text" placeholder="Enter Email" name="email" id="email" required>
|
<input type="text" placeholder="Enter Email" name="email" id="email" required>
|
||||||
|
|
||||||
|
<label for="city">City</label>
|
||||||
|
<input type='text' name='city' placeholder='Barcelona'/>
|
||||||
|
|
||||||
<label for="pass">Password</label>
|
<label for="pass">Password</label>
|
||||||
<input type="password" placeholder="Enter Password" name="pass" id="pass" required>
|
<input type="password" placeholder="Enter Password" name="pass" id="pass" required>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<picture>
|
<picture>
|
||||||
<source type='image/webp' sizes='20px' srcset="/static-cb/1517673283/twitter-20.webp 20w,/static-cb/1517673283/twitter-40.webp 40w,/static-cb/1517673283/twitter-80.webp 80w,"/>
|
<source type='image/webp' sizes='20px' srcset="/static-cb/1517673283/twitter-20.webp 20w,/static-cb/1517673283/twitter-40.webp 40w,/static-cb/1517673283/twitter-80.webp 80w,"/>
|
||||||
<source type='image/png' sizes='20px' srcset="/static-cb/1517673283/twitter-20.png 20w,/static-cb/1517673283/twitter-40.png 40w,/static-cb/1517673283/twitter-80.png 80w,"/>
|
<source type='image/png' sizes='20px' srcset="/static-cb/1517673283/twitter-20.png 20w,/static-cb/1517673283/twitter-40.png 40w,/static-cb/1517673283/twitter-80.png 80w,"/>
|
||||||
<img src="https://codl.forget.fr/static-cb/1517673283/twitter-20.png" alt="" />
|
<img src="https://patriciaannbridewell.files.wordpress.com/2014/04/official-twitter-logo-tile.png" alt="" />
|
||||||
</picture>
|
</picture>
|
||||||
Log in with Twitter
|
Log in with Twitter
|
||||||
</a>
|
</a>
|
||||||
|
@ -63,10 +63,22 @@
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- offer mailing list creation button -->
|
<div style="float: left; padding: 1.5em;">
|
||||||
|
<h2>Edit your city page</h2>
|
||||||
|
<p>
|
||||||
|
With your bot, we generated you a page, which you can use for promotion: <a href="city/$city"
|
||||||
|
target="_blank">Ticketfrei $city</a> You can change what your users will read there, and adjust it to your
|
||||||
|
needs. <b>You should definitely adjust the Social Media profile links.</b> This is just the default text we
|
||||||
|
suggest:
|
||||||
|
</p>
|
||||||
|
<form action="/settings/goodlist" method="post">
|
||||||
|
<textarea id="markdown" rows="20" cols="70" name="goodlist" wrap="physical">$markdown</textarea>
|
||||||
|
<input name='confirm' value='Save' type='submit'/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="float: left; padding: 1.5em;">
|
<div style="float: left; padding: 1.5em;">
|
||||||
<!-- good list entry field -->
|
<h2>Edit your trigger patterns</h2>
|
||||||
<p>
|
<p>
|
||||||
These words have to be contained in a report.
|
These words have to be contained in a report.
|
||||||
If none of these expressions is in the report, it will be ignored by the bot.
|
If none of these expressions is in the report, it will be ignored by the bot.
|
||||||
|
@ -74,13 +86,13 @@
|
||||||
</p>
|
</p>
|
||||||
<form action="/settings/goodlist" method="post">
|
<form action="/settings/goodlist" method="post">
|
||||||
<!-- find a way to display current good list. js which reads from a cookie? template? -->
|
<!-- 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"></textarea>
|
<textarea id="goodlist" rows="8" cols="70" name="goodlist" wrap="physical">$triggerwords</textarea>
|
||||||
<input name='confirm' value='Submit' type='submit'/>
|
<input name='confirm' value='Submit' type='submit'/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- blacklist entry field -->
|
|
||||||
<div style="float:right; padding: 1.5em;">
|
<div style="float:right; padding: 1.5em;">
|
||||||
|
<h2>Edit the blacklist</h2>
|
||||||
<p>
|
<p>
|
||||||
These words are not allowed in reports.
|
These words are not allowed in reports.
|
||||||
If you encounter spam, you can add more here - the bot will ignore reports which use such words.
|
If you encounter spam, you can add more here - the bot will ignore reports which use such words.
|
||||||
|
@ -88,7 +100,7 @@
|
||||||
</p>
|
</p>
|
||||||
<form action="/settings/blacklist" method="post">
|
<form action="/settings/blacklist" method="post">
|
||||||
<!-- find a way to display current blacklist. js which reads from a cookie? template? -->
|
<!-- 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"></textarea>
|
<textarea id="blacklist" rows="8" cols="70" name="blacklist" wrap="physical">$badwords</textarea>
|
||||||
<input name='confirm' value='Submit' type='submit'/>
|
<input name='confirm' value='Submit' type='submit'/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
% rebase('template/wrapper.tpl')
|
|
||||||
|
|
||||||
<h1>Wie funktioniert Ticketfrei?</h1>
|
|
||||||
<p>
|
|
||||||
Willst du mithelfen, Ticketkontrolleure zu überwachen? Willst du einen
|
|
||||||
Fahrscheinfreien ÖPNV erkämpfen?
|
|
||||||
</p>
|
|
||||||
<h2>Ist es gerade sicher, schwarz zu fahren?</h2>
|
|
||||||
<p>
|
|
||||||
Schau dir einfach das Profil unseres Bots an:
|
|
||||||
<a class="https" href="https://twitter.com/nbg_ticketfrei">https://twitter.com/nbg_ticketfrei</a>
|
|
||||||
</p>
|
|
||||||
<p>Hat jemand vor kurzem etwas über Kontrolleur*innen gepostet?</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Wenn ja, dann kauf dir vllt lieber ein Ticket. In Nürnberg haben wir
|
|
||||||
die Erfahrung gemacht, dass Kontis normalerweile ungefähr ne Woche
|
|
||||||
aktiv sind, ein paar Stunden am Tag. Wenn es also in den letzten
|
|
||||||
Stunden einen Bericht gab, pass lieber auf.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Wenn nicht, ist es wahrscheinlich kein Problem :)
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
Also, wenn du weniger Glück hast, und der erste bist, der einen Kontrolleur
|
|
||||||
sieht:
|
|
||||||
</p>
|
|
||||||
<h2>Was mache ich, wenn ich Kontis sehe?</h2>
|
|
||||||
<p>Ganz einfach, du schreibst es den anderen. Das geht entweder</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
mit Mastodon
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
über Twitter
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
oder per Mail, falls ihr kein Social Media habt.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>
|
|
||||||
Schreibe einfach einen Toot oder einen Tweet, der den Bot mentioned, und
|
|
||||||
gib an
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Wo du die Kontis gesehen hast
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Welche Linie sie benutzen und in welche Richtung sie fahren.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<p>Zum Beispiel so:</p>
|
|
||||||
|
|
||||||
<img src="/guides/tooting_screenshot.png" alt="Screenshot of writing a toot" />
|
|
||||||
<img src="/guides/toot_screenshot.png" alt="A toot ready to be boosted" />
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Der Bot wird die Nachricht dann weiterverbreiten, auch zu den anderen
|
|
||||||
Netzwerken. Dann können andere Leute das lesen und sicher vor Kontis sein.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>Danke, dass du mithilfst, öffentlichen Verkehr für alle sicherzustellen!</p>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
Kann ich darauf vertrauen, was random stranger from the Internet mir da
|
|
||||||
erzählen?
|
|
||||||
</h2>
|
|
||||||
<p>Aber natürlich! Wir haben Katzenbilder!</p>
|
|
||||||
<img src="https://lorempixel.com/550/300/cats" />
|
|
||||||
<p>
|
|
||||||
Glaubt besser nicht, wenn jemand postet, dass die Luft da und da gerade
|
|
||||||
rein ist. Das ist vielleicht sogar gut gemeint - aber klar könnte die VAG
|
|
||||||
sich hinsetzen und einfach lauter Falschmeldungen posten.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Aber Falschmeldungen darüber, dass gerade Kontis i-wo unterwegs sind?
|
|
||||||
Das macht keinen Sinn. Im schlimmsten Fall kauft jmd mal eine Fahrkarte
|
|
||||||
mehr - aber kann sonst immer schwarz fahren.</p>
|
|
||||||
<p>
|
|
||||||
Also ja - es macht Sinn, uns zu vertrauen, wenn wir sagen, wo gerade Kontis
|
|
||||||
sind.
|
|
||||||
</p>
|
|
||||||
<h2>Was ist Mastodon und warum sollte ich es benutzen?</h2>
|
|
||||||
<p>
|
|
||||||
Mastodon ist ein dezentrales soziales Netzwerk - so wie Twitter, nur ohne
|
|
||||||
Monopol und Zentralismus. Ihr könnt Kurznachrichten (Toots) über alles
|
|
||||||
mögliche schreiben, und euch mit anderen austauschen.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Mastodon ist Open Source, Privatsphäre-freundlich und relativ sicher vor
|
|
||||||
Zensur.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Um Mastodon zu benutzen, könnt ihr euch einen Account zB bei einer dieser
|
|
||||||
Websiten besorgen:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="https://queer.party/about">https://queer.party/about</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://soc.ialis.me/about">https://soc.ialis.me/about</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://kitty.town/about">https://kitty.town/about</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="https" href="https://social.coop/about">https://social.coop/about</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="https" href="https://awoo.space/about">https://awoo.space/about</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
104
user.py
104
user.py
|
@ -134,6 +134,14 @@ class User(object):
|
||||||
return db.cur.fetchone()[0]
|
return db.cur.fetchone()[0]
|
||||||
|
|
||||||
def state(self):
|
def state(self):
|
||||||
|
# necessary:
|
||||||
|
# - city
|
||||||
|
# - markdown
|
||||||
|
# - goodlist
|
||||||
|
# - blacklist
|
||||||
|
# - logged in with twitter?
|
||||||
|
# - logged in with mastodon?
|
||||||
|
# - enabled?
|
||||||
return dict(foo='bar')
|
return dict(foo='bar')
|
||||||
|
|
||||||
def save_request_token(self, token):
|
def save_request_token(self, token):
|
||||||
|
@ -185,3 +193,99 @@ class User(object):
|
||||||
def get_city(self):
|
def get_city(self):
|
||||||
db.execute("SELECT city FROM user WHERE id == ?;", (self.uid, ))
|
db.execute("SELECT city FROM user WHERE id == ?;", (self.uid, ))
|
||||||
return db.cur.fetchone()[0]
|
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
|
||||||
|
mailinglist = city + "@" + config['web']['host']
|
||||||
|
markdown = """
|
||||||
|
= Wie funktioniert Ticketfrei? =
|
||||||
|
|
||||||
|
Willst du mithelfen, Ticketkontrolleure zu überwachen?
|
||||||
|
Willst du einen Fahrscheinfreien ÖPNV erkämpfen?
|
||||||
|
|
||||||
|
== Ist es gerade sicher, schwarz zu fahren? ==
|
||||||
|
|
||||||
|
Schau einfach auf das Profil unseres Bots: """ + twit_link + """
|
||||||
|
|
||||||
|
Hat jemand vor kurzem etwas über Kontrolleur*innen gepostet?
|
||||||
|
* Wenn ja, dann kauf dir vllt lieber ein Ticket. In Nürnberg
|
||||||
|
haben wir die Erfahrung gemacht, dass Kontis normalerweile
|
||||||
|
ungefähr ne Woche aktiv sind, ein paar Stunden am Tag. Wenn es
|
||||||
|
also in den letzten Stunden einen Bericht gab, pass lieber
|
||||||
|
auf.
|
||||||
|
* Wenn nicht, ist es wahrscheinlich kein Problem :)
|
||||||
|
|
||||||
|
Wir können natürlich nicht garantieren, dass es sicher ist,
|
||||||
|
also pass trotzdem auf, wer auf dem Bahnsteig steht.
|
||||||
|
Aber je mehr Leute mitmachen, desto eher kannst du dir sicher
|
||||||
|
sein, dass wir sie finden, bevor sie uns finden.
|
||||||
|
|
||||||
|
Also, wenn du weniger Glück hast, und der erste bist, der einen
|
||||||
|
Kontrolleur sieht:
|
||||||
|
|
||||||
|
== Was mache ich, wenn ich Kontis sehe? ==
|
||||||
|
|
||||||
|
Ganz einfach, du schreibst es den anderen. Das geht entweder
|
||||||
|
|
||||||
|
<!-- * mit Mastodon: """ + masto_link + """ -->
|
||||||
|
<!-- * über Twitter: """ + twit_link + """ -->
|
||||||
|
* Oder per Mail an """ + mailinglist + """, wenn ihr kein
|
||||||
|
Social Media benutzen wollt.
|
||||||
|
|
||||||
|
Schreibe einfach einen Toot oder einen Tweet, der den Bot
|
||||||
|
mentioned, und gib an
|
||||||
|
* Wo du die Kontis gesehen hast
|
||||||
|
* Welche Linie sie benutzen und in welche Richtung sie fahren.
|
||||||
|
|
||||||
|
Zum Beispiel so:
|
||||||
|
|
||||||
|
[[https://github.com/b3yond/ticketfrei/blob/master/guides/tooting_screenshot.png|Screenshot of writing a toot]]
|
||||||
|
|
||||||
|
[[https://github.com/b3yond/ticketfrei/blob/master/guides/toot_screenshot.png|A toot ready to be boosted]]
|
||||||
|
|
||||||
|
Der Bot wird die Nachricht dann weiterverbreiten, auch zu den
|
||||||
|
anderen Netzwerken.
|
||||||
|
Dann können andere Leute das lesen und sicher vor Kontis sein.
|
||||||
|
|
||||||
|
Danke, dass du mithilfst, öffentlichen Verkehr für alle
|
||||||
|
sicherzustellen!
|
||||||
|
|
||||||
|
== Kann ich darauf vertrauen, was random stranger from the
|
||||||
|
Internet mir da erzählen? ==
|
||||||
|
|
||||||
|
Aber natürlich! Wir haben Katzenbilder!
|
||||||
|
|
||||||
|
[[https://lorempixel.com/550/300/cats|Katzenbilder...]]
|
||||||
|
|
||||||
|
Glaubt besser nicht, wenn jemand postet, dass die Luft da und
|
||||||
|
da gerade rein ist.
|
||||||
|
Das ist vielleicht sogar gut gemeint - aber klar könnte die
|
||||||
|
VAG sich hinsetzen und einfach lauter Falschmeldungen posten.
|
||||||
|
|
||||||
|
Aber Falschmeldungen darüber, dass gerade Kontis i-wo unterwegs
|
||||||
|
sind?
|
||||||
|
Das macht keinen Sinn.
|
||||||
|
Im schlimmsten Fall kauft jmd mal eine Fahrkarte mehr - aber
|
||||||
|
kann sonst immer schwarz fahren.
|
||||||
|
|
||||||
|
Also ja - es macht Sinn, uns zu vertrauen, wenn wir sagen, wo
|
||||||
|
gerade Kontis sind.
|
||||||
|
|
||||||
|
== Was ist Mastodon und warum sollte ich es benutzen? ==
|
||||||
|
|
||||||
|
Mastodon ist ein dezentrales soziales Netzwerk - so wie
|
||||||
|
Twitter, nur ohne Monopol und Zentralismus.
|
||||||
|
Ihr könnt Kurznachrichten (Toots) über alles mögliche
|
||||||
|
schreiben, und euch mit anderen austauschen.
|
||||||
|
|
||||||
|
Mastodon ist Open Source, Privatsphäre-freundlich und relativ
|
||||||
|
sicher vor Zensur.
|
||||||
|
|
||||||
|
Um Mastodon zu benutzen, besucht diese Seite:
|
||||||
|
https://joinmastodon.org/
|
||||||
|
"""
|
||||||
|
db.execute("""INSERT INTO cities(user_id, city, markdown, masto_link,
|
||||||
|
twit_link) VALUES(?,?,?,?,?)""",
|
||||||
|
(self.uid, city, markdown, masto_link, twit_link))
|
||||||
|
db.commit()
|
||||||
|
|
Loading…
Reference in a new issue