def test_dm_goes_to_correct_users(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'Cancelled' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Bob,Geoff") rt.do_it() self.assertEqual(len(tweeter.messages), 2) assert { "user": "******", "timestamp": datetime.now(), "message": "{0} 11:18 from London Paddington to Bedwyn has been cancelled". format(emoji_skull) } in tweeter.messages assert { "user": "******", "timestamp": datetime.now(), "message": "{0} 11:18 from London Paddington to Bedwyn has been cancelled". format(emoji_skull) } in tweeter.messages
def lambda_handler(event, context): home = os.environ['HOME'] work = os.environ['WORK'] users = os.environ['USERS'] consumer_key = decrypt_env('CONSUMER_KEY') consumer_secret = decrypt_env('CONSUMER_SECRET') access_token = decrypt_env('ACCESS_TOKEN') access_token_secret = decrypt_env('ACCESS_TOKEN_SECRET') rail_key = decrypt_env('RAIL_KEY') logger = logging.getLogger("TwitterRail") streamHandler = logging.StreamHandler() streamHandler.setFormatter( logging.Formatter('%(asctime)s %(levelname)s: %(message)s')) logger.setLevel("INFO") logger.addHandler(streamHandler) twitter = TweeterApi(consumer_key, consumer_secret, access_token, access_token_secret) queries = Queries( "http://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb9.asmx", rail_key) rt = RailTweeter(twitter, queries, home=home, work=work, users=users, logger=logger) rt.do_it() return "done"
def test_home_to_work_in_the_morning(self): tweeter = MockTweeterApi() queries = MockQueries(services=[]) rt = RailTweeter(tweeter, queries, "THA", "PAD", "Fred") rt.do_it() tweet = tweeter.tweets[0] assert "{0} PAD - THA".format(emoji_train) in tweet
def test_tweet_cropped_at_280_chars(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Station 1', 'platform': '1', 'std': u'01:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 2', 'platform': '2', 'std': u'02:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 3', 'platform': '3', 'std': u'03:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 4', 'platform': '4', 'std': u'04:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 5', 'platform': '5', 'std': u'05:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 6', 'platform': '6', 'std': u'06:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 7', 'platform': '7', 'std': u'07:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 8', 'platform': '8', 'std': u'08:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 9', 'platform': '9', 'std': u'09:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 10', 'platform': '10', 'std': u'10:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 10', 'platform': '11', 'std': u'11:18', 'etd': u'On time'}, {'origin': 'London Paddington', 'destination': u'Station 10', 'platform': '12', 'std': u'12:18', 'etd': u'On time'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] self.assertTrue("{0} PAD - THA".format(emoji_train) in tweet) self.assertFalse("12:18" in tweet)
def test_no_services(self): tweeter = MockTweeterApi() queries = MockQueries(services=[]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] assert "{0} PAD - THA".format(emoji_train) in tweet assert "No services" in tweet
def test_no_dm_on_short_delay(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'17:18', 'etd': u'17:22'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() self.assertEqual(len(tweeter.messages), 0)
def test_no_messages_if_no_cancellations(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'On time'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() self.assertEqual(len(tweeter.messages), 0)
def test_late_train(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'11:24'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] self.assertTrue("{0} PAD - THA".format(emoji_train) in tweet) self.assertTrue("{0} 11:18 Bedwyn 11:24".format(emoji_late) in tweet)
def test_do_not_duplicate_tweets(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'Cancelled'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() rt.do_it() rt.do_it() self.assertEqual(len(tweeter.tweets), 1)
def test_long_station_names_cropped_at_ten_chars(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'This is a very long station name', 'platform': '-', 'std': u'11:18', 'etd': u'On time'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] self.assertTrue("{0} PAD - THA".format(emoji_train) in tweet) self.assertTrue("{0} 11:18 This is a".format(emoji_tick) in tweet)
def test_normal_train_with_platform(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '2', 'std': u'11:18', 'etd': u'On time'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] assert "{0} PAD - THA".format(emoji_train) in tweet assert "{0} 11:18 Bedwyn P2".format(emoji_tick) in tweet
def test_no_dm_on_short_delay(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'17:18', 'etd': u'17:22' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() self.assertEqual(len(tweeter.messages), 0)
def test_no_messages_if_no_cancellations(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'On time' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() self.assertEqual(len(tweeter.messages), 0)
def test_long_station_names_cropped_at_ten_chars(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'This is a very long station name', 'platform': '-', 'std': u'11:18', 'etd': u'On time' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] self.assertTrue("{0} PAD - THA".format(emoji_train) in tweet) self.assertTrue("{0} 11:18 This is a".format(emoji_tick) in tweet)
def test_late_train(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'11:24' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] self.assertTrue("{0} PAD - THA".format(emoji_train) in tweet) self.assertTrue("{0} 11:18 Bedwyn 11:24".format(emoji_late) in tweet)
def test_normal_train_with_platform(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '2', 'std': u'11:18', 'etd': u'On time' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] assert "{0} PAD - THA".format(emoji_train) in tweet assert "{0} 11:18 Bedwyn P2".format(emoji_tick) in tweet
def test_cancelled_train(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'Cancelled'}, {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'12:18', 'etd': u'On time'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] assert "{0} PAD - THA".format(emoji_train) in tweet assert "{0} 11:18 Bedwyn".format(emoji_cross) in tweet assert "{0} 12:18 Bedwyn".format(emoji_tick) in tweet
def test_dm_on_long_delay(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'11:45'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() self.assertEqual(len(tweeter.messages), 1) assert { "user": "******", "timestamp": datetime.now(), "message": "{0} 11:18 from London Paddington to Bedwyn delayed expected 11:45".format(emoji_late) } in tweeter.messages
def test_do_not_duplicate_messages(self): tweeter = MockTweeterApi() queries = MockQueries(services=[ {'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'Cancelled'} ]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() rt.do_it() rt.do_it() self.assertEqual(len(tweeter.messages), 1) assert { "user": "******", "timestamp": datetime.now(), "message": "{0} 11:18 from London Paddington to Bedwyn has been cancelled".format(emoji_skull) } in tweeter.messages
def test_cancelled_train(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'Cancelled' }, { 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'12:18', 'etd': u'On time' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] assert "{0} PAD - THA".format(emoji_train) in tweet assert "{0} 11:18 Bedwyn".format(emoji_cross) in tweet assert "{0} 12:18 Bedwyn".format(emoji_tick) in tweet
def test_dm_on_long_delay(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'11:45' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() self.assertEqual(len(tweeter.messages), 1) assert { "user": "******", "timestamp": datetime.now(), "message": "{0} 11:18 from London Paddington to Bedwyn delayed expected 11:45" .format(emoji_late) } in tweeter.messages
def lambda_handler(event, context): home = os.environ['HOME'] work = os.environ['WORK'] users = os.environ['USERS'] consumer_key = decrypt_env('CONSUMER_KEY') consumer_secret = decrypt_env('CONSUMER_SECRET') access_token = decrypt_env('ACCESS_TOKEN') access_token_secret = decrypt_env('ACCESS_TOKEN_SECRET') rail_key = decrypt_env('RAIL_KEY') logger = logging.getLogger("TwitterRail") streamHandler = logging.StreamHandler() streamHandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s')) logger.setLevel("INFO") logger.addHandler(streamHandler) twitter = TweeterApi(consumer_key, consumer_secret, access_token, access_token_secret) queries = Queries("http://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb9.asmx", rail_key) rt = RailTweeter(twitter, queries, home=home, work=work, users=users, logger=logger) rt.do_it() return "done"
def test_do_not_duplicate_tweets(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Bedwyn', 'platform': '-', 'std': u'11:18', 'etd': u'Cancelled' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() rt.do_it() rt.do_it() self.assertEqual(len(tweeter.tweets), 1)
def test_tweet_cropped_at_280_chars(self): tweeter = MockTweeterApi() queries = MockQueries(services=[{ 'origin': 'London Paddington', 'destination': u'Station 1', 'platform': '1', 'std': u'01:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 2', 'platform': '2', 'std': u'02:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 3', 'platform': '3', 'std': u'03:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 4', 'platform': '4', 'std': u'04:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 5', 'platform': '5', 'std': u'05:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 6', 'platform': '6', 'std': u'06:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 7', 'platform': '7', 'std': u'07:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 8', 'platform': '8', 'std': u'08:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 9', 'platform': '9', 'std': u'09:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 10', 'platform': '10', 'std': u'10:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 10', 'platform': '11', 'std': u'11:18', 'etd': u'On time' }, { 'origin': 'London Paddington', 'destination': u'Station 10', 'platform': '12', 'std': u'12:18', 'etd': u'On time' }]) rt = RailTweeter(tweeter, queries, "PAD", "THA", "Fred") rt.do_it() tweet = tweeter.tweets[0] self.assertTrue("{0} PAD - THA".format(emoji_train) in tweet) self.assertFalse("12:18" in tweet)
parser.add_argument('--home', help='Home station CRS (default "THA")', default="THA") parser.add_argument('--work', help='Work station CRS (default "PAD")', default="PAD") parser.add_argument('--users', help='Users to DM (comma separated)', default="") parser.add_argument('--forever', help='Use this switch to run the script forever (once ever 5 mins)', action='store_true', default=False) parser.add_argument('--rail-key', help='API Key for National Rail', required=True) parser.add_argument('--consumer-key', help='Consumer Key for Twitter', required=True) parser.add_argument('--consumer-secret', help='Consumer Secret for Twitter', required=True) parser.add_argument('--access-token', help='Access Token for Twitter', required=True) parser.add_argument('--access-token-secret', help='Access Token Secret for Twitter', required=True) parser.add_argument('--log-level', help='Log level to use. Default=INFO', default="INFO") args = parser.parse_args() logger = logging.getLogger("TwitterRail") streamHandler = logging.StreamHandler() streamHandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s')) logger.setLevel(args.log_level) logger.addHandler(streamHandler) twitter = TweeterApi(args.consumer_key, args.consumer_secret, args.access_token, args.access_token_secret) queries = Queries("http://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb9.asmx", args.rail_key) rt = RailTweeter(twitter, queries, home=args.home, work=args.work, users=args.users, logger=logger) while True: try: rt.do_it() except Exception as e: logger.exception("I crashed") if not args.forever: break sleep(300)
default="INFO") args = parser.parse_args() logger = logging.getLogger("TwitterRail") streamHandler = logging.StreamHandler() streamHandler.setFormatter( logging.Formatter('%(asctime)s %(levelname)s: %(message)s')) logger.setLevel(args.log_level) logger.addHandler(streamHandler) twitter = TweeterApi(args.consumer_key, args.consumer_secret, args.access_token, args.access_token_secret) queries = Queries( "http://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb9.asmx", args.rail_key) rt = RailTweeter(twitter, queries, home=args.home, work=args.work, users=args.users, logger=logger) while True: try: rt.do_it() except Exception as e: logger.exception("I crashed") if not args.forever: break sleep(300)