From 97e99ac1896ec5f0a2c7d78dd9637f1e026e1a87 Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Tue, 9 Oct 2018 14:37:05 +0200 Subject: [PATCH] Remove twitter list synchronization This never worked well across multiple years anyway, so it hasn't been used for a long time. Will be replaced with more useful twitter posting functionality in the future. --- .../migrations/0030_remove_twitter_lists.py | 27 +++++ postgresqleu/confreg/models.py | 3 - postgresqleu/confsponsor/forms.py | 3 - tools/confreg/twitter_sync.py | 100 ------------------ tools/confreg/twitterclient.py | 90 ---------------- 5 files changed, 27 insertions(+), 196 deletions(-) create mode 100644 postgresqleu/confreg/migrations/0030_remove_twitter_lists.py delete mode 100755 tools/confreg/twitter_sync.py delete mode 100644 tools/confreg/twitterclient.py diff --git a/postgresqleu/confreg/migrations/0030_remove_twitter_lists.py b/postgresqleu/confreg/migrations/0030_remove_twitter_lists.py new file mode 100644 index 0000000..93e7f04 --- /dev/null +++ b/postgresqleu/confreg/migrations/0030_remove_twitter_lists.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-10-09 14:33 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('confreg', '0029_drop_mailman_sync'), + ] + + operations = [ + migrations.RemoveField( + model_name='conference', + name='twitter_attendeelist', + ), + migrations.RemoveField( + model_name='conference', + name='twitter_speakerlist', + ), + migrations.RemoveField( + model_name='conference', + name='twitter_sponsorlist', + ), + ] diff --git a/postgresqleu/confreg/models.py b/postgresqleu/confreg/models.py index d52ac4c..e1720c7 100644 --- a/postgresqleu/confreg/models.py +++ b/postgresqleu/confreg/models.py @@ -122,9 +122,6 @@ class Conference(models.Model): confurl = models.CharField(max_length=128, blank=False, null=False, validators=[validate_lowercase,], verbose_name="Conference URL") twittersync_active = models.BooleanField(null=False, default=False) twitter_user = models.CharField(max_length=32, blank=True, null=False) - twitter_attendeelist = models.CharField(max_length=32, blank=True, null=False) - twitter_speakerlist = models.CharField(max_length=32, blank=True, null=False) - twitter_sponsorlist = models.CharField(max_length=32, blank=True, null=False) twitter_token = models.CharField(max_length=128, blank=True, null=False) twitter_secret = models.CharField(max_length=128, blank=True, null=False) diff --git a/postgresqleu/confsponsor/forms.py b/postgresqleu/confsponsor/forms.py index 55ce99e..fe3c73f 100644 --- a/postgresqleu/confsponsor/forms.py +++ b/postgresqleu/confsponsor/forms.py @@ -38,9 +38,6 @@ class SponsorSignupForm(forms.Form): super(SponsorSignupForm, self).__init__(*args, **kwargs) - if not self.conference.twitter_sponsorlist: - del self.fields['twittername'] - if not settings.EU_VAT: del self.fields['vatstatus'] del self.fields['vatnumber'] diff --git a/tools/confreg/twitter_sync.py b/tools/confreg/twitter_sync.py deleted file mode 100755 index f4294fc..0000000 --- a/tools/confreg/twitter_sync.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python -# -# Tool to synchronize conference attendees with twitter lists -# - -import ConfigParser -import psycopg2 -import sys -from twitterclient import TwitterClient - -class TwitterConfWrapper(object): - # do a wrapper so we can use the planet interface unmodified - - def __init__(self, cparser, user, listname, token, secret): - self.cparser = cparser - self.user = user - self.listname = listname - self.token = token - self.secret = secret - - def get(self, section, setting): - if not section=='twitter': - raise Exception("Don't know how to handle this section") - if setting == "account": - return self.user - if setting == "listname": - return self.listname - if setting == "token": - return self.token - if setting == "secret": - return self.secret - return self.cparser.get(section, setting) - -class TwitterListSync(TwitterClient): - def __init__(self, cparser, user, listname, token, secret, members): - self.confwrap = TwitterConfWrapper(cparser, user, listname, - token, secret) - self.members = set([self._normalize_handle(r[0]) for r in members]) - - TwitterClient.__init__(self, self.confwrap) - - def _normalize_handle(self, handle): - h = handle.lower() - if h[0] == '@': h = h[1:] - return h - - def run(self): - current = set([t.lower() for t in self.list_subscribers()]) - - map(self.remove_subscriber, current.difference(self.members)) - map(self.add_subscriber, self.members.difference(current)) - - -if __name__=="__main__": - c = ConfigParser.ConfigParser() - c.read("twitter_sync.ini") - - db = psycopg2.connect(c.get('settings','db')) - curs = db.cursor() - - # Look for any conflicts - curs.execute("SELECT twitter_user, count(conferencename) FROM confreg_conference WHERE twittersync_active AND NOT twitter_user='' GROUP BY twitter_user HAVING count(*) > 1") - dupes = curs.fetchall() - if dupes: - print "Twitter user %s is duplicated for multiple active conference. Twitter sync disabled." - sys.exit(1) - - # Figure out lists to sync - curs.execute("SELECT id, twitter_user, twitter_attendeelist, twitter_speakerlist, twitter_sponsorlist, twitter_token, twitter_secret FROM confreg_conference WHERE twittersync_active AND NOT (twitter_user IS NULL OR twitter_user='')") - for confid, user, attlist, spklist, sponsorlist, token, secret in curs.fetchall(): - if attlist: - # Synchronize the attendee list - curs.execute("""SELECT DISTINCT twittername FROM confreg_conferenceregistration cr - INNER JOIN confreg_registrationtype rt ON cr.regtype_id=rt.id - WHERE cr.conference_id=%(id)s AND cr.payconfirmedat IS NOT NULL AND rt.inlist - AND NOT (twittername='' OR twittername IS NULL)""", - {'id': confid, } - ) - TwitterListSync(c, user, attlist, token, secret, - curs.fetchall()).run() - - if spklist: - curs.execute("""SELECT DISTINCT twittername FROM auth_user au - INNER JOIN confreg_speaker s ON au.id=s.user_id - INNER JOIN confreg_conferencesession_speaker csp ON csp.speaker_id=s.id - INNER JOIN confreg_conferencesession cs ON cs.id=csp.conferencesession_id - WHERE cs.conference_id=%(id)s AND cs.status=1 - AND NOT (twittername='' OR twittername IS NULL)""", - { 'id': confid, } - ) - TwitterListSync(c, user, spklist, token, secret, - curs.fetchall()).run() - - if sponsorlist: - curs.execute("SELECT DISTINCT twittername FROM confsponsor_sponsor WHERE conference_id=%(id)s AND confirmed AND NOT twittername=''", { - 'id': confid, - }) - - TwitterListSync(c, user, sponsorlist, token, secret, - curs.fetchall()).run() diff --git a/tools/confreg/twitterclient.py b/tools/confreg/twitterclient.py deleted file mode 100644 index 3ba724c..0000000 --- a/tools/confreg/twitterclient.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python -# vim: ai ts=4 sts=4 sw=4 -"""PostgreSQL Planet Aggregator - -This file contains a base class for twitter integration -scripts. - -Copyright (C) 2009-2010 PostgreSQL Global Development Group -""" -import oauth2 as oauth -import json -import time -import urllib - -class TwitterClient(object): - """ - Base class representing a twitter client, implementing all those twitter - API calls that are in use. - Does not attempt to be a complete twitter client, just to fill the needs - for the planet software. - """ - - def __init__(self, cfg): - """ - Initialize the instance. The parameter cfg is a ConfigParser object - that has loaded the planet.ini file. - """ - self.twittername = cfg.get('twitter', 'account') - self.twitterlist = cfg.get('twitter', 'listname') - self.oauth_token = oauth.Token(cfg.get('twitter', 'token'), cfg.get('twitter', 'secret')) - self.oauth_consumer = oauth.Consumer(cfg.get('twitter', 'consumer'), cfg.get('twitter', 'consumersecret')) - - def twitter_request(self, apicall, method='GET', ext_params=None): - params = { - 'oauth_version': "1.0", - 'oauth_nonce': oauth.generate_nonce(), - 'oauth_timestamp': int(time.time()), - 'oauth_token': self.oauth_token.key, - 'oauth_consumer_key': self.oauth_consumer.key, - } - if ext_params: - params.update(ext_params) - - url = "https://api.twitter.com/1.1/%s" % apicall - - req = oauth.Request(method=method, - url=url, - parameters=params) - req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), self.oauth_consumer, self.oauth_token) - if method=='GET': - instream = urllib.urlopen(req.to_url()) - else: - instream=urllib.urlopen(url, req.to_postdata()) - - # Make the actual call to twitter - ret=instream.read() - instream.close() - return json.loads(ret) - - def list_subscribers(self): - # Eek. It seems subscribers are paged even if we don't ask for it - # Thus, we need to loop with multiple requests - cursor=-1 - handles = [] - while cursor != 0: - response = self.twitter_request('lists/members.json', 'GET', { - 'owner_screen_name': self.twittername, - 'slug': self.twitterlist, - 'cursor': cursor, - }) - handles.extend([x['screen_name'] for x in response['users']]) - cursor = response['next_cursor'] - - return handles - - def remove_subscriber(self, name): - print "Removing twitter user %s from list." % name - self.twitter_request('lists/members/destroy.json', 'POST', { - 'owner_screen_name': self.twittername, - 'slug': self.twitterlist, - 'screen_name': name, - }) - - def add_subscriber(self, name): - print "Adding twitter user %s to list." % name - self.twitter_request('lists/members/create.json', 'POST', { - 'owner_screen_name': self.twittername, - 'slug': self.twitterlist, - 'screen_name': name, - }) -- 2.39.5