Merge remote-tracking branch 'origin/multi-deployment' into multi-deployment
This commit is contained in:
commit
e032ecbcc3
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sendmail
|
from sendmail import sendmail
|
||||||
import datetime
|
import datetime
|
||||||
import mailbox
|
import mailbox
|
||||||
import email
|
import email
|
||||||
|
@ -36,8 +36,9 @@ class Mailbot(Bot):
|
||||||
+ db.mail_subscription_token(rec, user.get_city())
|
+ db.mail_subscription_token(rec, user.get_city())
|
||||||
if report.author != rec:
|
if report.author != rec:
|
||||||
try:
|
try:
|
||||||
sendmail.sendmail(rec, "Ticketfrei " + user.get_city() +
|
city = user.get_city()
|
||||||
" Report", body=body)
|
sendmail(rec, "Ticketfrei " + city + " Report",
|
||||||
|
city=city, body=body)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error("Sending Mail failed.", exc_info=True)
|
logger.error("Sending Mail failed.", exc_info=True)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ import tweepy
|
||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
import report
|
import report
|
||||||
|
import tfglobals
|
||||||
|
from time import time
|
||||||
from bot import Bot
|
from bot import Bot
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +29,8 @@ class TwitterBot(Bot):
|
||||||
:return: reports: (list of report.Report objects)
|
:return: reports: (list of report.Report objects)
|
||||||
"""
|
"""
|
||||||
reports = []
|
reports = []
|
||||||
|
if tfglobals.last_twitter_request + 60 > time():
|
||||||
|
return reports
|
||||||
try:
|
try:
|
||||||
api = self.get_api(user)
|
api = self.get_api(user)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@ -37,6 +41,7 @@ class TwitterBot(Bot):
|
||||||
mentions = api.direct_messages()
|
mentions = api.direct_messages()
|
||||||
else:
|
else:
|
||||||
mentions = api.mentions_timeline(since_id=last_dm[0])
|
mentions = api.mentions_timeline(since_id=last_dm[0])
|
||||||
|
tfglobals.last_twitter_request = time()
|
||||||
for status in mentions:
|
for status in mentions:
|
||||||
text = re.sub(
|
text = re.sub(
|
||||||
"(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
|
"(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
|
||||||
|
|
|
@ -7,6 +7,7 @@ import requests
|
||||||
from time import time
|
from time import time
|
||||||
import report
|
import report
|
||||||
from bot import Bot
|
from bot import Bot
|
||||||
|
import tfglobals
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -29,14 +30,14 @@ class TwitterBot(Bot):
|
||||||
:return: reports: (list of report.Report objects)
|
:return: reports: (list of report.Report objects)
|
||||||
"""
|
"""
|
||||||
reports = []
|
reports = []
|
||||||
try:
|
#global last_twitter_request
|
||||||
if user.get_last_twitter_request() + 60 > time():
|
if tfglobals.last_twitter_request + 60 > time():
|
||||||
return reports
|
return reports
|
||||||
except TypeError:
|
|
||||||
user.set_last_twitter_request(time())
|
|
||||||
try:
|
try:
|
||||||
api = self.get_api(user)
|
api = self.get_api(user)
|
||||||
except Exception:
|
except TypeError:
|
||||||
|
# When there is no twitter account for this bot, we want to
|
||||||
|
# seamlessly continue.
|
||||||
#logger.error("Error Authenticating Twitter", exc_info=True)
|
#logger.error("Error Authenticating Twitter", exc_info=True)
|
||||||
return reports
|
return reports
|
||||||
last_mention = user.get_seen_tweet()
|
last_mention = user.get_seen_tweet()
|
||||||
|
@ -45,12 +46,12 @@ class TwitterBot(Bot):
|
||||||
mentions = api.mentions_timeline()
|
mentions = api.mentions_timeline()
|
||||||
else:
|
else:
|
||||||
mentions = api.mentions_timeline(since_id=last_mention)
|
mentions = api.mentions_timeline(since_id=last_mention)
|
||||||
user.set_last_twitter_request(time())
|
tfglobals.last_twitter_request = time()
|
||||||
for status in mentions:
|
for status in mentions:
|
||||||
text = re.sub(
|
text = re.sub(
|
||||||
"(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
|
"(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
|
||||||
"", status.text)
|
"", status.text)
|
||||||
username = api.me()
|
username = "@" + api.me().screen_name
|
||||||
if username in status.text:
|
if username in status.text:
|
||||||
reports.append(report.Report(status.author.screen_name,
|
reports.append(report.Report(status.author.screen_name,
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -5,7 +5,7 @@ from config import config
|
||||||
from db import db
|
from db import db
|
||||||
import logging
|
import logging
|
||||||
from sendmail import sendmail
|
from sendmail import sendmail
|
||||||
import time
|
from time import time
|
||||||
|
|
||||||
|
|
||||||
def shutdown():
|
def shutdown():
|
||||||
|
@ -16,12 +16,15 @@ def shutdown():
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
last_twitter_request = time()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
fh = logging.FileHandler('/var/log/ticketfrei/backend.log')
|
fh = logging.FileHandler('/var/log/ticketfrei/backend.log')
|
||||||
fh.setLevel(logging.DEBUG)
|
fh.setLevel(logging.DEBUG)
|
||||||
logger.addHandler(fh)
|
logger.addHandler(fh)
|
||||||
|
|
||||||
|
|
||||||
bots = []
|
bots = []
|
||||||
for ActiveBot in active_bots.__dict__.values():
|
for ActiveBot in active_bots.__dict__.values():
|
||||||
if isinstance(ActiveBot, type) and issubclass(ActiveBot, Bot):
|
if isinstance(ActiveBot, type) and issubclass(ActiveBot, Bot):
|
||||||
|
|
8
db.py
8
db.py
|
@ -1,7 +1,7 @@
|
||||||
from config import config
|
from config import config
|
||||||
import jwt
|
import jwt
|
||||||
import logging
|
import logging
|
||||||
from os import urandom, system
|
from os import urandom
|
||||||
from pylibscrypt import scrypt_mcf
|
from pylibscrypt import scrypt_mcf
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
|
@ -93,12 +93,6 @@ class DB(object):
|
||||||
active INTEGER,
|
active INTEGER,
|
||||||
FOREIGN KEY(user_id) REFERENCES user(id)
|
FOREIGN KEY(user_id) REFERENCES user(id)
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS twitter_last_request (
|
|
||||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
|
||||||
user_id INTEGER,
|
|
||||||
date INTEGER,
|
|
||||||
FOREIGN KEY(user_id) REFERENCES user(id)
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS telegram_accounts (
|
CREATE TABLE IF NOT EXISTS telegram_accounts (
|
||||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
user_id INTEGER,
|
user_id INTEGER,
|
||||||
|
|
|
@ -231,8 +231,8 @@ def twitter_callback(user):
|
||||||
@post('/login/mastodon')
|
@post('/login/mastodon')
|
||||||
def login_mastodon(user):
|
def login_mastodon(user):
|
||||||
"""
|
"""
|
||||||
Starts the mastodon OAuth authentication process.
|
Mastodon OAuth authentication process.
|
||||||
:return: redirect to twitter.
|
:return: redirect to city page.
|
||||||
"""
|
"""
|
||||||
# get app tokens
|
# get app tokens
|
||||||
instance_url = request.forms.get('instance_url')
|
instance_url = request.forms.get('instance_url')
|
||||||
|
|
69
sendmail.py
69
sendmail.py
|
@ -1,78 +1,21 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from config import config
|
from config import config
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from email.mime.application import MIMEApplication
|
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
import logging
|
import logging
|
||||||
from getpass import getuser
|
from getpass import getuser
|
||||||
import smtplib
|
import smtplib
|
||||||
from socket import getfqdn
|
from socket import getfqdn
|
||||||
import ssl
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Mailer(object):
|
def sendmail(to, subject, city=None, body=''):
|
||||||
"""
|
|
||||||
Maintains the connection to the mailserver and sends text to users.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""
|
|
||||||
Creates an SMTP client to send a mail. Is called only once
|
|
||||||
when you actually want to send a mail. After you sent the
|
|
||||||
mail, the SMTP client is shut down again.
|
|
||||||
|
|
||||||
"""
|
|
||||||
# This generates the From address by stripping the part until the first
|
|
||||||
# period from the mail server address and won't work always.
|
|
||||||
self.fromaddr = config["mail"]["user"] + "@" + config["mail"]["mailserver"].partition(".")[2]
|
|
||||||
|
|
||||||
# starts a client session with the SMTP server
|
|
||||||
self.s = smtplib.SMTP(config["mail"]["mailserver"])
|
|
||||||
try:
|
|
||||||
context = ssl.create_default_context()
|
|
||||||
self.s.starttls(context=context)
|
|
||||||
except BaseException: # TODO: Amend specific exception
|
|
||||||
logger.error('StartTLS failed.', exc_info=True)
|
|
||||||
self.s.login(config["mail"]["user"], config["mail"]["passphrase"])
|
|
||||||
|
|
||||||
def send(self, text, recipient, subject, attachment=None):
|
|
||||||
"""
|
|
||||||
|
|
||||||
:param text: (string) the content of the mail
|
|
||||||
:param recipient: (string) the recipient of the mail
|
|
||||||
:param subject: (string) the subject of the mail
|
|
||||||
:param attachment: (string) the path to the logfile
|
|
||||||
:return: string for logging purposes, contains recipient & subject
|
|
||||||
"""
|
|
||||||
msg = MIMEMultipart()
|
|
||||||
msg.attach(MIMEText(text))
|
|
||||||
|
|
||||||
msg["From"] = self.fromaddr
|
|
||||||
msg["To"] = recipient
|
|
||||||
msg["Subject"] = subject
|
|
||||||
|
|
||||||
# attach logfile
|
|
||||||
if attachment:
|
|
||||||
with open(attachment, "rb") as fil:
|
|
||||||
part = MIMEApplication(
|
|
||||||
fil.read(),
|
|
||||||
Name="logfile"
|
|
||||||
)
|
|
||||||
# After the file is closed
|
|
||||||
part['Content-Disposition'] = 'attachment; filename="logfile"'
|
|
||||||
msg.attach(part)
|
|
||||||
|
|
||||||
self.s.send_message(msg)
|
|
||||||
self.s.close()
|
|
||||||
|
|
||||||
return "Sent mail to " + recipient + ": " + subject
|
|
||||||
|
|
||||||
|
|
||||||
def sendmail(to, subject, body=''):
|
|
||||||
msg = MIMEMultipart()
|
msg = MIMEMultipart()
|
||||||
|
if city:
|
||||||
|
msg['From'] = 'Ticketfrei <%s@%s>' % (city, getfqdn())
|
||||||
|
else:
|
||||||
msg['From'] = 'Ticketfrei <%s@%s>' % (getuser(), getfqdn())
|
msg['From'] = 'Ticketfrei <%s@%s>' % (getuser(), getfqdn())
|
||||||
msg['To'] = to
|
msg['To'] = to
|
||||||
msg['Subject'] = '[Ticketfrei] %s' % (subject, )
|
msg['Subject'] = '[Ticketfrei] %s' % (subject, )
|
||||||
|
@ -84,5 +27,5 @@ def sendmail(to, subject, body=''):
|
||||||
|
|
||||||
# For testing:
|
# For testing:
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
m = Mailer()
|
sendmail(config['mail']['contact'], "Test Mail",
|
||||||
print(m.send("This is a test mail.", m.fromaddr, "Test"))
|
body="This is a test mail.")
|
||||||
|
|
10
tfglobals.py
Normal file
10
tfglobals.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
"""
|
||||||
|
This file is for shared global variables. They only stay during runtime.
|
||||||
|
|
||||||
|
For reference:
|
||||||
|
https://stackoverflow.com/questions/15959534/visibility-of-global-variables-in-imported-modules
|
||||||
|
"""
|
||||||
|
|
||||||
|
last_twitter_request = time()
|
26
user.py
26
user.py
|
@ -136,24 +136,6 @@ schlitz
|
||||||
instance = db.cur.fetchone()
|
instance = db.cur.fetchone()
|
||||||
return instance[1], instance[2], row[0], instance[0]
|
return instance[1], instance[2], row[0], instance[0]
|
||||||
|
|
||||||
def get_twitter_credentials(self):
|
|
||||||
keys = [config['twitter']['consumer_key'],
|
|
||||||
config['twitter']['consumer_secret']]
|
|
||||||
row = self.get_twitter_token()
|
|
||||||
keys.append(row[0])
|
|
||||||
keys.append(row[1])
|
|
||||||
return keys
|
|
||||||
|
|
||||||
def get_last_twitter_request(self):
|
|
||||||
db.execute("SELECT date FROM twitter_last_request WHERE user_id = ?;",
|
|
||||||
(self.uid,))
|
|
||||||
return db.cur.fetchone()[0]
|
|
||||||
|
|
||||||
def set_last_twitter_request(self, date):
|
|
||||||
db.execute("UPDATE twitter_last_request SET date = ? WHERE user_id = ?;",
|
|
||||||
(date, self.uid))
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
def toot_is_seen(self, toot_uri):
|
def toot_is_seen(self, toot_uri):
|
||||||
db.execute("SELECT COUNT(*) FROM seen_toots WHERE user_id = ? AND toot_uri = ?;",
|
db.execute("SELECT COUNT(*) FROM seen_toots WHERE user_id = ? AND toot_uri = ?;",
|
||||||
(self.uid, toot_uri))
|
(self.uid, toot_uri))
|
||||||
|
@ -286,6 +268,14 @@ schlitz
|
||||||
(self.uid, ))
|
(self.uid, ))
|
||||||
return db.cur.fetchone()
|
return db.cur.fetchone()
|
||||||
|
|
||||||
|
def get_twitter_credentials(self):
|
||||||
|
keys = [config['twitter']['consumer_key'],
|
||||||
|
config['twitter']['consumer_secret']]
|
||||||
|
row = self.get_twitter_token()
|
||||||
|
keys.append(row[0])
|
||||||
|
keys.append(row[1])
|
||||||
|
return keys
|
||||||
|
|
||||||
def update_telegram_key(self, apikey):
|
def update_telegram_key(self, apikey):
|
||||||
db.execute("UPDATE telegram_accounts SET apikey = ? WHERE user_id = ?;", (apikey, self.uid))
|
db.execute("UPDATE telegram_accounts SET apikey = ? WHERE user_id = ?;", (apikey, self.uid))
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
Loading…
Reference in a new issue