def __init__(self, config): QObject.__init__(self) self.account_model = AccountModel(self) self.subscriptions = LockableDict() self.panel_model = PanelModel( self, self.subscriptions, ) self.thread = TwitterThread(self, self.subscriptions, config["limits"]) self.thread.newTweets.connect(self.newTweets.emit) self.logger = Logger("twitter")
class Twitter(QObject): newTweets = pyqtSignal(object, list) newSubscription = pyqtSignal("QVariant") accountCreated = pyqtSignal(QObject) tweetRemoved = pyqtSignal("QVariant") tweetChanged = pyqtSignal(bool, unicode, object) newTweetsForModel = pyqtSignal(TweetModel, list, int) requestSent = pyqtSignal("QVariant", "QVariant") def __init__(self, config): QObject.__init__(self) self.account_model = AccountModel(self) self.subscriptions = LockableDict() self.panel_model = PanelModel( self, self.subscriptions, ) self.thread = TwitterThread(self, self.subscriptions, config["limits"]) self.thread.newTweets.connect(self.newTweets.emit) self.logger = Logger("twitter") def locking(func): @wraps(func) def wrapper(self, *args, **kwds): try: func(self, *args, **kwds) except Exception as error: self.requestSent.emit(False, unicode(error)) else: self.requestSent.emit(True, None) return wrapper def check_selected_accounts(self, accounts): if not accounts: raise NoAccountSelectedException( "You have to select at least one account" ) def on_account_connected(self, account): self.panel_model.setScreenName(account.uuid, account.me.screen_name) @pyqtSlot("QVariant") def subscribe(self, request): subscription = create_subscription( request["type"], request["account"], request.get("args", "") ) tweet_model = self.panel_model.addPanel(subscription) self.tweetRemoved.connect(tweet_model.removeTweet) self.tweetChanged.connect(tweet_model.replaceTweet) self.thread.force_check.set() @pyqtSlot("QVariant", "QVariant", "QVariant") @async @locking def tweet(self, accounts, tweet, in_reply=None): self.check_selected_accounts(accounts) in_reply = in_reply if in_reply else None for account in accounts: safe_api_request( lambda api=account.api: api.update_status(tweet, in_reply) ) @pyqtSlot("QVariant", "QVariant") @async @locking def retweet(self, accounts, tweet_id): self.check_selected_accounts(accounts) for account in accounts: # warum die beiden so unterschiedlich? status = safe_api_request( lambda api=account.api: api.retweet(tweet_id), ) old_status = safe_api_request( lambda: account.api.get_status(tweet_id) ) status.retweeted = True status.created_at = old_status.created_at if hasattr(old_status, "retweeted_status"): # RTed a retweet status.other_retweet = old_status self.tweetChanged.emit(False, tweet_id, status) @pyqtSlot("QVariant", "QVariant") @async @locking def undo_retweet(self, accounts, tweet_id): self.check_selected_accounts(accounts) for account in accounts: status = safe_api_request( lambda: account.api.destroy_status(tweet_id) ) self.tweetChanged.emit(True, tweet_id, status.retweeted_status) @pyqtSlot("QVariant", "QVariant") @async @locking def favorite(self, accounts, tweet_id): self.check_selected_accounts(accounts) for account in accounts: self.logger.debug("api.create_favorite({0})", tweet_id) status = safe_api_request( lambda api=account.api: api.create_favorite(tweet_id), ) status.favorited = True self.tweetChanged.emit(False, tweet_id, status) @pyqtSlot("QVariant", "QVariant") @async @locking def undo_favorite(self, accounts, tweet_id): self.check_selected_accounts(accounts) for account in accounts: self.logger.debug("api.destroy_favorite({0})", tweet_id) status = safe_api_request( lambda: account.api.destroy_favorite(tweet_id) ) status.favorited = False self.tweetChanged.emit(True, tweet_id, status) # Remove tweet from Favorites-Panels for subscription, model in self.panel_model.panels: print repr(tweet_id), subscription.subscription_type, subscription.account, account if subscription.subscription_type == "favorites" \ and subscription.account == account: call_in_mainloop(model.removeTweet, tweet_id) @pyqtSlot("QVariant", "QVariant", "QVariant") @async @locking def send_direct_message(self, account, to_twitter_id, text): safe_api_request( lambda: account.api.send_direct_message( user_id=to_twitter_id, text=text ) ) @pyqtSlot("QVariant") @async @locking def destroy_tweet(self, tweet_id): # FIXME status = self.account_model.accounts[0].api.get_status(tweet_id) author_id = status.author.id for account in self.account_model.accounts: if author_id == account.me.id: account.api.destroy_status(tweet_id) self.requestSent.emit(True, None) self.tweetRemoved.emit(tweet_id) break else: raise TweepError( "This tweet doesn't belong to any of your accounts" ) @pyqtSlot("QVariant", "QVariant") @async @locking def destroy_direct_message(self, account, tweet_id): safe_api_request( lambda: account.api.destroy_direct_message(tweet_id) ) self.tweetRemoved.emit(tweet_id) @pyqtSlot(result=QObject) def new_account(self): account = Account() account.setParent(self) #account.ready.connect(partial(self.announce_account, account)) self.accountCreated.emit(account) return account def add_account(self, account): self.account_model.addAccount(account) account.connected.connect(self.on_account_connected) def connect(self): """ Connects all account and starts the TwitterThread which fetches new tweets """ for account in self.account_model.accounts: account.connect() self.thread.start() @pyqtSlot("QVariant") @async @locking def debug_tweet(self, tweet): self.logger.debug("debug_tweet: {0}", tweet)