From 072bb401305e697a73ba1968576b7dd8290762a5 Mon Sep 17 00:00:00 2001 From: Blagovest Petrov Date: Fri, 28 Oct 2016 02:53:45 +0300 Subject: [PATCH 1/6] First commit of the Python server --- server/config.py | 6 +++ server/server.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 server/config.py create mode 100644 server/server.py diff --git a/server/config.py b/server/config.py new file mode 100644 index 0000000..351214e --- /dev/null +++ b/server/config.py @@ -0,0 +1,6 @@ +twitter_conf = { +'TW_CONSUMER_KEY' : 'env', +'TW_CONSUMER_SECRET' : 'env', +'TW_ACCESS_TOKEN' : 'env', +'TW_ACCESS_TOKEN_SECRET' : 'env', +} diff --git a/server/server.py b/server/server.py new file mode 100644 index 0000000..b2aa277 --- /dev/null +++ b/server/server.py @@ -0,0 +1,104 @@ +#!/usr/bin/python + +import os, sys +import logging +import argparse +import eventlet +import tweepy +import config +from telnetsrv.evtlet import TelnetHandler, command +#from str import join + +for key in config.twitter_conf: + if config.twitter_conf[key] == 'env': + try: + os.environ[key] + except KeyError: + print "Please, set the environment variable %s or set it in the config" % key + sys.exit(1) + +logging.getLogger('').setLevel(logging.DEBUG) + +TELNET_IP_BINDING = '' #all + +parser = argparse.ArgumentParser( description='Run a fttp server.') +parser.add_argument( 'port', metavar="PORT", type=int, help="The port on which to listen on." ) +console_args = parser.parse_args() + +TELNET_PORT_BINDING = console_args.port + +class TwitterApi(): + '''Twitter Api''' + + auth = tweepy.OAuthHandler(config.twitter_conf['TW_CONSUMER_KEY'], config.twitter_conf['TW_CONSUMER_SECRET']) + auth.set_access_token(config.twitter_conf['TW_ACCESS_TOKEN'], config.twitter_conf['TW_ACCESS_TOKEN_SECRET']) + api = tweepy.API(auth) + + def send(tweet): + api.update_status(tweet) + + def get_tweets_by_tag(tag): + print "NotImplemented" + + +class TestTelnetHandler(TelnetHandler): + + # -- Override items to customize the server -- + + WELCOME = 'You have connected to the fttp server.' + PROMPT = "fttp% " + authNeedUser = False + authNeedPass = False + + twitter = TwitterApi() + + def session_start(self): + '''Called after the user successfully logs in.''' + + def session_end(self): + '''Called after the user logs off.''' + + def writeerror(self, text): + '''Called to write any error information (like a mistyped command). + Add a splash of color using ANSI to render the error text in red. + see http://en.wikipedia.org/wiki/ANSI_escape_code''' + TelnetHandler.writeerror(self, "\x1b[91m%s\x1b[0m" % text ) + + # -- Twitter Commands -- + + @command(['tweet', 'send']) + def command_tweet(self, params): + ''' + Sends the message as a tweet from @USR + ''' + message = " ".join(params) + print type(message) + self.twitter.send(message) + + +if __name__ == '__main__': + Handler = TestTelnetHandler + + class EvtletStreamServer(object): + def __init__(self, addr, handle): + self.ip = addr[0] + self.port = addr[1] + self.handle = handle + + def serve_forever(self): + eventlet.serve( + eventlet.listen((self.ip, self.port)), + self.handle + ) + + # Multi-eventlet server + server = EvtletStreamServer( + (TELNET_IP_BINDING, TELNET_PORT_BINDING), + Handler.streamserver_handle + ) + + logging.info("Starting fttp server at port %d. (Ctrl-C to stop)" % (TELNET_PORT_BINDING) ) + try: + server.serve_forever() + except KeyboardInterrupt: + logging.info("Server shut down.") From db2086d316fb2e195b39763a6535baa54e238710 Mon Sep 17 00:00:00 2001 From: Blagovest Petrov Date: Fri, 28 Oct 2016 16:50:01 +0300 Subject: [PATCH 2/6] Fixed object ownership problem --- server/server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/server.py b/server/server.py index b2aa277..c268f0c 100644 --- a/server/server.py +++ b/server/server.py @@ -34,8 +34,8 @@ class TwitterApi(): auth.set_access_token(config.twitter_conf['TW_ACCESS_TOKEN'], config.twitter_conf['TW_ACCESS_TOKEN_SECRET']) api = tweepy.API(auth) - def send(tweet): - api.update_status(tweet) + def send(self, tweet): + self.api.update_status(tweet) def get_tweets_by_tag(tag): print "NotImplemented" From d455295d63bf031b7922bf6b69d6297ce883b528 Mon Sep 17 00:00:00 2001 From: Blagovest Petrov Date: Fri, 28 Oct 2016 16:52:54 +0300 Subject: [PATCH 3/6] Fixed config values problem --- server/server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/server/server.py b/server/server.py index c268f0c..38a9ea1 100644 --- a/server/server.py +++ b/server/server.py @@ -16,6 +16,7 @@ for key in config.twitter_conf: except KeyError: print "Please, set the environment variable %s or set it in the config" % key sys.exit(1) + config.twitter_conf[key] = os.environ[key] logging.getLogger('').setLevel(logging.DEBUG) From 2893c533dd4189fcf1a2f7a78e342d3b0f9fc06e Mon Sep 17 00:00:00 2001 From: Blagovest Petrov Date: Mon, 31 Oct 2016 12:25:03 +0200 Subject: [PATCH 4/6] feed is now implemened - fetches the latest twitter feed for a given tag --- server/server.py | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/server/server.py b/server/server.py index 38a9ea1..b30e5fd 100644 --- a/server/server.py +++ b/server/server.py @@ -38,8 +38,16 @@ class TwitterApi(): def send(self, tweet): self.api.update_status(tweet) - def get_tweets_by_tag(tag): - print "NotImplemented" + def get_tweets_by_tag(self, tag): + tweets = "" + feed = self.api.search(tag, count=20) + for i in feed: + # tweets.join(i, "\n") + tweets = tweets + i.text + "\n" + # print type(tweets) + return tweets + # return '\n'.join(tweets) + class TestTelnetHandler(TelnetHandler): @@ -52,12 +60,18 @@ class TestTelnetHandler(TelnetHandler): authNeedPass = False twitter = TwitterApi() + get_tweets_event = [] def session_start(self): '''Called after the user successfully logs in.''' + message = self.twitter.get_tweets_by_tag("OpenFest2015") + event = eventlet.spawn_after(180, self.writemessage, message) + self.get_tweets_event.append(event) def session_end(self): '''Called after the user logs off.''' + for event in self.get_tweets_event: + event.kill() def writeerror(self, text): '''Called to write any error information (like a mistyped command). @@ -70,12 +84,22 @@ class TestTelnetHandler(TelnetHandler): @command(['tweet', 'send']) def command_tweet(self, params): ''' - Sends the message as a tweet from @USR + Sends the message as a tweet from @OpenFest_Fttp ''' message = " ".join(params) - print type(message) self.twitter.send(message) + @command(['feed', 'get_tweets']) + def command_get(self, params): + ''' <#tag> + Gets latest tweets by a given tag (Default: #OpenFest2016) + ''' + # if not params[0]: + # params[0] = "#OpenFest2016" + + self.feed = self.twitter.get_tweets_by_tag("#openfest") + self.writeresponse(self.feed.encode('utf-8').strip()) + if __name__ == '__main__': Handler = TestTelnetHandler From 333776177483c82c9d2d21f22e05608d26ef9469 Mon Sep 17 00:00:00 2001 From: Blagovest Petrov Date: Mon, 31 Oct 2016 15:00:15 +0200 Subject: [PATCH 5/6] Working version but the automatic feed is still not spawned correctly. --- server/config.py | 1 + server/server.py | 28 +++++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/server/config.py b/server/config.py index 351214e..5d381bc 100644 --- a/server/config.py +++ b/server/config.py @@ -3,4 +3,5 @@ twitter_conf = { 'TW_CONSUMER_SECRET' : 'env', 'TW_ACCESS_TOKEN' : 'env', 'TW_ACCESS_TOKEN_SECRET' : 'env', +'TW_DEFAULT_TAG' : 'OpenFest2016', } diff --git a/server/server.py b/server/server.py index b30e5fd..4d66be0 100644 --- a/server/server.py +++ b/server/server.py @@ -6,17 +6,17 @@ import argparse import eventlet import tweepy import config +import time from telnetsrv.evtlet import TelnetHandler, command -#from str import join for key in config.twitter_conf: if config.twitter_conf[key] == 'env': try: os.environ[key] + config.twitter_conf[key] = os.environ[key] except KeyError: print "Please, set the environment variable %s or set it in the config" % key sys.exit(1) - config.twitter_conf[key] = os.environ[key] logging.getLogger('').setLevel(logging.DEBUG) @@ -42,11 +42,8 @@ class TwitterApi(): tweets = "" feed = self.api.search(tag, count=20) for i in feed: - # tweets.join(i, "\n") tweets = tweets + i.text + "\n" - # print type(tweets) - return tweets - # return '\n'.join(tweets) + return tweets.encode('utf-8').strip() @@ -60,12 +57,21 @@ class TestTelnetHandler(TelnetHandler): authNeedPass = False twitter = TwitterApi() - get_tweets_event = [] + + # queue = eventlet.queue.Queue(10000) + # wait = eventlet.semaphore.CappedSemaphore(1000) + + def feed_auto(self): + # while True: + self.feed = self.twitter.get_tweets_by_tag(config.twitter_conf['TW_DEFAULT_TAG']) + self.writeresponse(self.feed) + # time.sleep(5) def session_start(self): '''Called after the user successfully logs in.''' - message = self.twitter.get_tweets_by_tag("OpenFest2015") - event = eventlet.spawn_after(180, self.writemessage, message) + self.get_tweets_event = [] + message = self.feed_auto() + event = eventlet.spawn(self.writemessage, message) self.get_tweets_event.append(event) def session_end(self): @@ -97,8 +103,8 @@ class TestTelnetHandler(TelnetHandler): # if not params[0]: # params[0] = "#OpenFest2016" - self.feed = self.twitter.get_tweets_by_tag("#openfest") - self.writeresponse(self.feed.encode('utf-8').strip()) + self.feed = self.twitter.get_tweets_by_tag(config.twitter_conf['TW_DEFAULT_TAG']) + self.writeresponse(self.feed) if __name__ == '__main__': From c6af01045850228f2a086b3ca5492d8ad13f9dbd Mon Sep 17 00:00:00 2001 From: Blagovest Petrov Date: Mon, 31 Oct 2016 15:05:49 +0200 Subject: [PATCH 6/6] added requirements.txt --- server/requirements.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 server/requirements.txt diff --git a/server/requirements.txt b/server/requirements.txt new file mode 100644 index 0000000..b8323fa --- /dev/null +++ b/server/requirements.txt @@ -0,0 +1,18 @@ +colorama==0.3.7 +eventlet==0.19.0 +funcsigs==1.0.2 +gevent==1.1.2 +green==2.5.2 +greenlet==0.4.10 +logging==0.4.9.6 +mock==2.0.0 +oauthlib==2.0.0 +pbr==1.10.0 +pkg-resources==0.0.0 +python-termstyle==0.1.10 +requests==2.4.3 +requests-oauthlib==0.4.1 +six==1.7.3 +telnetsrv==0.4 +tweepy==3.2.0 +Unidecode==0.4.19