--- /dev/null
+# -*- 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',
+ ),
+ ]
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)
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']
+++ /dev/null
-#!/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()
+++ /dev/null
-#!/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,
- })