import logging import threading from datetime import datetime import time from app_be.models import Tweet, Feed from app_be.views.twitter_api import twitter_api import feedparser from dateutil import parser logger = logging.getLogger(__name__) class twitter_bot(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): posted = False while True: logger.debug("Looking for new results in active feeds") feed_set = Feed.objects.filter(active=True) for feed in feed_set: if posted: break # load feed feeds = feedparser.parse(feed.url) keywords = list(x.strip() for x in feed.keywords.split(',')) # search single posts for current in feeds.entries: if not 'title' in current.keys(): continue if posted: break if search_keywords(keywords, current, feed.match_all_keywords): logger.debug("Keyword found") # preparing tweet new_tweet = Tweet() new_tweet.icon = feed.icon new_tweet.text = current.title if 'published' in current: new_tweet.date_time = parser.parse(current.published) elif 'updated' in current: new_tweet.date_time = parser.parse(current.updated) else: new_tweet.date_time = datetime.now() new_tweet.url = current.link # if tweet not in db yet if not Tweet.objects.filter(text=new_tweet.text): # call twitter api to post tweet and store to db logger.debug("Posting update on Twitter") logger.debug("new_tweet: {}".format(new_tweet)) twitter_api.post_update(new_tweet.text, new_tweet.url) new_tweet.save() posted = True time.sleep(65) posted = False def search_keywords(keywords, current_entry, match_all): if 'title' in current_entry and not 'summary' in current_entry: if match_all: return all(keyword.lower() in current_entry.title.lower() for keyword in keywords) else: return any(keyword.lower() in current_entry.title.lower() for keyword in keywords) if 'title' in current_entry and 'summary' in current_entry: if match_all: return all(keyword.lower() in current_entry.title.lower() + current_entry.summary.lower() for keyword in keywords) else: return any(keyword.lower() in current_entry.title.lower() + current_entry.summary.lower() for keyword in keywords) return False