^- (merghebegin work on a PoC twitter scanner
might be replaced with a streams container, but for now we'll
have something to work with, data-wise.
diff --git a/src/plugins/scanners/twitter.py b/src/plugins/scanners/twitter.py
new file mode 100644
index 0000000..ea69271
--- /dev/null
+++ b/src/plugins/scanners/twitter.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+ #the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This is a Kibble scanner plugin for Twitter sources.
+"""
+import requests
+import json
+import time
+import re
+import hashlib
+import sys
+import datetime
+import plugins.utils.jsonapi
+import twitter # If you get via pip: pip3 install python-twitter (NOT twitter)
+
+title = "Scanner plugin for Twitter"
+version = "0.1.0"
+
+def accepts(source):
+ """ Test if source matches a Twitter handle """
+ # If the source equals the plugin name, assume a yes
+ if source['type'] == 'twitter':
+ return True
+
+ # Default to not recognizing the source
+ return False
+
+
+def getFollowers(KibbleBit, source, t):
+ """ Get followers of a handle, store them for mapping and trend purposes"""
+ # Get our twitter handle
+ handle = source['sourceURL']
+
+ # Get number of followers
+ tuser = t.GetUser(screen_name=handle)
+ no_followers = tuser.followers_count
+ d = time.strftime("%Y/%m/%d 0:00:00", time.gmtime()) # Today at midnight
+ dhash = hashlib.sha224((("twitter:%s:%s:%s") % (source['organisation'], source['sourceURL'], d)).encode('ascii', errors='replace')).hexdigest()
+ jst = {
+ 'organisation': source['organisation'],
+ 'sourceURL': source['sourceURL'],
+ 'sourceID': source['sourceID'],
+ 'id': dhash,
+ 'followers': no_followers,
+ 'date': d
+ }
+ KibbleBit.pprint("%s has %u followers currently." % (handle, no_followers))
+ KibbleBit.index('twitter_followers', dhash, jst)
+
+ # Collect list of current followers
+ followers = t.GetFollowers(screen_name=handle)
+
+ # For each follower, if they're not mapped yet, add them
+ # This has a limitation of 100 new added per run, but meh...
+ KibbleBit.pprint("Looking up followers of %s" % handle)
+ for follower in followers:
+ # id, name, screen_name are useful here
+ KibbleBit.pprint ("Found %s as follower" % follower.screen_name)
+
+ # Store twitter follower profile if not already logged
+ dhash = hashlib.sha224((("twitter:%s:%s:%s") % (source['organisation'], handle, follower.id)).encode('ascii', errors='replace')).hexdigest()
+ if not KibbleBit.exists('twitter_follow',dhash):
+ jst = {
+ 'organisation': source['organisation'],
+ 'sourceURL': source['sourceURL'],
+ 'sourceID': source['sourceID'],
+ 'twitterid': follower.id,
+ 'name': follower.name,
+ 'screenname': follower.screen_name,
+ 'id': dhash,
+ 'date': time.strftime("%Y/%m/%d %H:%M:%S", time.gmtime()) # First time we spotted them following.
+
+ }
+ KibbleBit.pprint("%s is new, recording date and details." % follower.screen_name)
+ KibbleBit.index('twitter_follow', dhash, jst)
+
+
+def scan(KibbleBit, source):
+ source['steps']['twitter'] = {
+ 'time': time.time(),
+ 'status': 'Scanning Twitter activity and status',
+ 'running': True,
+ 'good': True
+ }
+ KibbleBit.updateSource(source)
+ t = None
+ if 'creds' in source and source['creds']:
+ t = twitter.Api(
+ access_token_key = source['creds'].get('token', None),
+ access_token_secret = source['creds'].get('token_secret', None),
+ consumer_key = source['creds'].get('consumer_key', None),
+ consumer_secret = source['creds'].get('consumer_secret', None),
+ )
+ KibbleBit.pprint("Verrifying twitter credentials...")
+ try:
+ t.VerifyCredentials()
+ except:
+ source['steps']['twitter'] = {
+ 'time': time.time(),
+ 'status': 'Could not verify twitter credentials',
+ 'running': False,
+ 'good': False
+ }
+ KibbleBit.updateSource(source)
+ KibbleBit.pprint("Could not verify twitter creds, aborting!")
+ return
+ # Start by getting and saving followers
+ getFollowers(KibbleBit, source, t)
+