Merge remote-tracking branch 'origin/multi-deployment' into multi-deployment

multi-deployment
b3yond 2018-10-07 18:48:05 +02:00
commit e032ecbcc3
9 changed files with 50 additions and 103 deletions

View File

@ -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)

View File

@ -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-_]+)",

View File

@ -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,

View File

@ -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
View File

@ -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,

View File

@ -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')

View File

@ -1,79 +1,22 @@
#!/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()
msg['From'] = 'Ticketfrei <%s@%s>' % (getuser(), getfqdn()) if city:
msg['From'] = 'Ticketfrei <%s@%s>' % (city, getfqdn())
else:
msg['From'] = 'Ticketfrei <%s@%s>' % (getuser(), getfqdn())
msg['To'] = to msg['To'] = to
msg['Subject'] = '[Ticketfrei] %s' % (subject, ) msg['Subject'] = '[Ticketfrei] %s' % (subject, )
msg.attach(MIMEText(body)) msg.attach(MIMEText(body))
@ -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
View 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
View File

@ -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()