diff --git a/README.md b/README.md index ddd35f3..336cb1e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Ticketfrei social bot -Ticketfrei is a mastodon/twitter/mail bot to dodge ticket controllers in public +Ticketfrei is a mastodon/mail bot to dodge ticket controllers in public transport systems. ## Mission @@ -28,9 +28,9 @@ your tweet and others can read the info and think twice whether they want to buy a ticket or not. If enough people, a critical mass, participate for the bot to become reliable, you have positive self-reinforcing dynamics. -Today, you can use a Twitter, Mastodon, Telegram, and Mail with the account. +Today, you can use a Mastodon, Telegram, and Mail with the account. They will communicate with each other; if someone warns others via Mail, -Telegram, Twitter and Mastodon users will also see the message. And vice versa. +Telegram and Mastodon users will also see the message. And vice versa. In version 2, this repository contains a web application. On this website, people can register an own bot for their city - the website manages multiple @@ -51,7 +51,6 @@ running. * Register on the ticketfrei site * Optionally: register bots: - * Register a Twitter account * Register a Mastodon account * Register a Telegram bot * Configure account @@ -119,7 +118,7 @@ vim config.toml ``` This configuration is only for the admin. Moderators can log into -twitter/mastodon/mail and configure their personal bot on the settings page. +mastodon/mail and configure their personal bot on the settings page. Set up LetsEncrypt: @@ -221,7 +220,7 @@ less /var/log/exim4/mainlog ### Development Install -If you want to install it locally to develop on it, note that twitter and mail +If you want to install it locally to develop on it, note that mail will probably not work. You should test them on a server instead. ```shell @@ -252,7 +251,7 @@ vim config.toml ``` This configuration is only for the admin. Users can log into -twitter/mastodon/mail and configure their personal bot on the settings page. +mastodon/mail and configure their personal bot on the settings page. ```shell # create folder for socket & database @@ -272,7 +271,7 @@ sudo chown $USER:$USER -R /var/log/ticketfrei ## Version 1 - more of less hacked together during a mate-fueled weekend -- backend-only, twitter & mastodon +- backend-only, mastodon - just a script, which crawled & retweeted tweets, if they match a whitelist & blocklist - whitelist & blocklist were just 2 files @@ -281,7 +280,7 @@ sudo chown $USER:$USER -R /var/log/ticketfrei Reasons for the rewrite: - user management: Users should be able to run a Ticketfrei bot in their city - without needing a server, without needing command line skills -- more networks; not only Twitter & Mastodon, also Email & Telegram +- more networks; not only Mastodon, also Email & Telegram 2 processes: backend & frontend. The two Processes talk via a database. diff --git a/active_bots/twitterbot.py b/active_bots/twitterbot.py deleted file mode 100755 index 4d1e283..0000000 --- a/active_bots/twitterbot.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python3 - -import logging -import tweepy -import re -import requests -from time import time -import report -from bot import Bot - - -logger = logging.getLogger("main") - - -class TwitterBot(Bot): - - def get_api(self, user): - keys = user.get_twitter_credentials() - auth = tweepy.OAuthHandler(consumer_key=keys[0], - consumer_secret=keys[1]) - auth.set_access_token(keys[2], # access_token_key - keys[3]) # access_token_secret - return tweepy.API(auth, wait_on_rate_limit=True) - - def crawl(self, user): - """ - crawls all Tweets which mention the bot from the twitter rest API. - - :return: reports: (list of report.Report objects) - """ - reports = [] - try: - if user.get_last_twitter_request() + 60 > time(): - return reports - except TypeError: - user.set_last_twitter_request(time()) - try: - api = self.get_api(user) - except TypeError: - # When there is no twitter account for this bot, we want to - # seamlessly continue. - #logger.error("Error Authenticating Twitter", exc_info=True) - return reports - last_mention = user.get_seen_tweet() - try: - if last_mention == 0: - mentions = api.mentions_timeline() - else: - mentions = api.mentions_timeline(since_id=last_mention) - user.set_last_twitter_request(time()) - for status in mentions: - if status._json['in_reply_to_status_id'] == None: - text = re.sub( - "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)", - "", status.text) - reports.append(report.Report(status.author.screen_name, - self, - text, - status.id, - status.created_at)) - user.save_seen_tweet(status.id) - return reports - except tweepy.RateLimitError: - logger.error("Twitter API Error: Rate Limit Exceeded", - exc_info=True) - # :todo implement rate limiting - except requests.exceptions.ConnectionError: - logger.error("Twitter API Error: Bad Connection", exc_info=True) - except tweepy.TweepError: - logger.error("Twitter API Error: General Error. User: " + str(user.uid), exc_info=True) - return [] - - def post(self, user, report): - try: - api = self.get_api(user) - except TypeError: - return # no twitter account for this user. - try: - if report.source == self: - api.retweet(report.id) - else: - text = report.text - if len(text) > 280: - text = text[:280 - 4] + u' ...' - api.update_status(status=text) - except requests.exceptions.ConnectionError: - logger.error("Twitter API Error: Bad Connection", - exc_info=True) - except tweepy.error.TweepError: - logger.error("Twitter API Error", exc_info=True) diff --git a/config.py b/config.py index e0ba420..81670c9 100755 --- a/config.py +++ b/config.py @@ -12,18 +12,6 @@ def load_env(): with open('config.toml.example') as defaultconf: configdict = toml.load(defaultconf) - try: - if os.environ['CONSUMER_KEY'] != "": - configdict['twitter']['consumer_key'] = os.environ['CONSUMER_KEY'] - except KeyError: - pass - - try: - if os.environ['CONSUMER_SECRET'] != "": - configdict['twitter']['consumer_secret'] = os.environ['CONSUMER_SECRET'] - except KeyError: - pass - try: if os.environ['HOST'] != "": configdict['web']['host'] = os.environ['HOST'] diff --git a/config.toml.example b/config.toml.example index eb519db..fbdf4cb 100644 --- a/config.toml.example +++ b/config.toml.example @@ -1,9 +1,3 @@ -[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 diff --git a/db.py b/db.py index 6c2c4ca..2102d1c 100644 --- a/db.py +++ b/db.py @@ -91,21 +91,6 @@ class DB(object): tg_id INTEGER, FOREIGN KEY(user_id) REFERENCES user(id) ); - CREATE TABLE IF NOT EXISTS twitter_request_tokens ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - user_id INTEGER, - request_token TEXT, - request_token_secret TEXT, - FOREIGN KEY(user_id) REFERENCES user(id) - ); - CREATE TABLE IF NOT EXISTS twitter_accounts ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - user_id INTEGER, - client_id TEXT, - client_secret TEXT, - active INTEGER, - FOREIGN KEY(user_id) REFERENCES user(id) - ); CREATE TABLE IF NOT EXISTS telegram_accounts ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, user_id INTEGER, @@ -113,21 +98,6 @@ class DB(object): active INTEGER, FOREIGN KEY(user_id) REFERENCES user(id) ); - CREATE TABLE IF NOT EXISTS seen_tweets ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - user_id INTEGER, - tweet_id INTEGER, - FOREIGN KEY(user_id) REFERENCES user(id) - ); - CREATE TABLE IF NOT EXISTS seen_dms ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - user_id INTEGER, - twitter_accounts_id INTEGER, - message_id TEXT, - FOREIGN KEY(user_id) REFERENCES user(id) - FOREIGN KEY(twitter_accounts_id) - REFERENCES twitter_accounts(id) - ); CREATE TABLE IF NOT EXISTS telegram_subscribers ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, user_id INTEGER, @@ -147,12 +117,6 @@ class DB(object): mail_date REAL, 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 cities ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, user_id INTEGER, @@ -269,8 +233,6 @@ u\d\d?""" active) VALUES(?, ?, ?);""", (uid, "", 1)) self.execute("INSERT INTO seen_telegrams (user_id, tg_id) VALUES (?, ?);", (uid, 0)) self.execute("INSERT INTO seen_mail (user_id, mail_date) VALUES (?, ?);", (uid, 0)) - self.execute("INSERT INTO seen_tweets (user_id, tweet_id) VALUES (?, ?)", (uid, 0)) - self.execute("INSERT INTO twitter_last_request (user_id, date) VALUES (?, ?)", (uid, 0)) self.commit() user = User(uid) user.set_city(city) diff --git a/frontend.py b/frontend.py index 7fbf975..ee27faa 100755 --- a/frontend.py +++ b/frontend.py @@ -4,7 +4,6 @@ from bottle import get, post, redirect, request, response, view from config import config from db import db import logging -import tweepy from sendmail import sendmail from session import SessionPlugin from mastodon import Mastodon @@ -202,45 +201,6 @@ def logout(): # :todo show info "Logout successful." redirect('/') - -@get('/login/twitter') -def login_twitter(user): - """ - Starts the twitter OAuth authentication process. - :return: redirect to twitter. - """ - consumer_key = config["twitter"]["consumer_key"] - consumer_secret = config["twitter"]["consumer_secret"] - callback_url = url("login/twitter/callback") - auth = tweepy.OAuthHandler(consumer_key, consumer_secret, callback_url) - try: - redirect_url = auth.get_authorization_url() - except tweepy.TweepError: - logger.error('Twitter OAuth Error: Failed to get request token.', - exc_info=True) - return dict(error="Failed to get request token.") - user.save_request_token(auth.request_token) - redirect(redirect_url) - - -@get('/login/twitter/callback') -def twitter_callback(user): - """ - Gets the callback - :return: - """ - # twitter passes the verifier/oauth token secret in a GET request. - verifier = request.query['oauth_verifier'] - consumer_key = config["twitter"]["consumer_key"] - consumer_secret = config["twitter"]["consumer_secret"] - auth = tweepy.OAuthHandler(consumer_key, consumer_secret) - request_token = user.get_request_token() - auth.request_token = request_token - auth.get_access_token(verifier) - user.save_twitter_token(auth.access_token, auth.access_token_secret) - redirect("/settings") - - @post('/login/mastodon') def login_mastodon(user): """ diff --git a/report.py b/report.py index dc27003..66722c0 100644 --- a/report.py +++ b/report.py @@ -14,7 +14,7 @@ class Report(object): Constructor of a ticketfrei report :param author: username of the author - :param source: mastodon, twitter, or email bot object + :param source: mastodon or email bot object :param text: the text of the report :param id: id in the network :param timestamp: time of the report diff --git a/static/bot.html b/static/bot.html index b2e2bf6..7b27e13 100644 --- a/static/bot.html +++ b/static/bot.html @@ -13,15 +13,6 @@
- -
- diff --git a/template/settings.tpl b/template/settings.tpl index 66cf873..b7b8398 100644 --- a/template/settings.tpl +++ b/template/settings.tpl @@ -7,15 +7,6 @@
% end - -
-