def setup_class(self, monkeypatch): self.acc_id = "dummy-twitter" self.core = Core(load_accounts=False) self.account = Account.new("twitter", "dummy") self.account.columns = [Column(self.account.id_, ColumnType.TIMELINE)] self.account2 = Account.new("twitter", "qux") self.account2.columns = [Column(self.account2.id_, ColumnType.TIMELINE)] self.all_accounts = [self.account, self.account2] monkeypatch.setattr(self.core.accman, "get", lambda x: self.account)
def __init__(self): parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) (options, args) = parser.parse_args() if options.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.core = Core() self.followers = [] self.following = [] self.last_dm = None self.log = logging.getLogger('Server') self.start_login()
def __init__(self): cmd.Cmd.__init__(self) parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) parser.add_option('-m', '--command', dest='command', action='store_true', help='execute a single command', default=False) parser.add_option('-c', '--clean', dest='clean', action='store_true', help='clean all bytecodes', default=False) parser.add_option('-s', '--save-credentials', dest='save', action='store_true', help='save user credentials', default=False) parser.add_option('--version', dest='version', action='store_true', help='show the version of Turpial and exit', default=False) (options, args) = parser.parse_args() if options.debug or options.clean: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.log = logging.getLogger('Turpial:Cmd') #self.config = None self.prompt = 'turpial> ' self.intro = '\n'.join(INTRO) self.core = Core() #self.app_cfg = ConfigApp() #self.version = self.app_cfg.read('App', 'version') if options.clean: clean_bytecodes(__file__, self.log) sys.exit(0) if options.version: print "turpial (cmd) v%s" % self.version print "libturpial v%s" % libturpial_ver print "python v%X" % sys.hexversion sys.exit(0) self.account = None try: self.cmdloop() except KeyboardInterrupt: self.do_exit() except EOFError: self.do_exit()
def init(max_tries = 5, wait_time = 60, reinit_allowed = False): global _core if (_core != None) and not reinit_allowed: raise InitAlreadyDoneError tries = 0 while True: try: _core = Core() break except ServiceOverCapacity: tries += 1 sys.stderr.write('Tried to init _core it {0} times\n'.format(tries)) sys.stderr.flush() if tries >= max_tries: raise time.sleep(wait_time)
def __init__(self): self.turpial = Core() for controller in Controller.objects.all(): self.turpial.register_account(controller.user,controller.password,self.turpial.list_protocols()[int(controller.service)]) for acc in self.turpial.list_accounts(): rtn = self.turpial.login(acc) if rtn.code > 0: print rtn.errmsg else: print 'Logged in with account %s' % acc.split('-')[0] print "Ciclo de extraccion *****************" while True: for acc in self.turpial.list_accounts(): # rtn = self.turpial.get_column_statuses(acc, ColumnType.DIRECTS) # self.process_statuses(rtn) rtn = self.turpial.get_column_statuses(acc, ColumnType.REPLIES) self.process_statuses(rtn)
# * Test register and unregister columns # To run this test make sure you have an account_id file inside tests folder # with the id of the account you want to use to test. This test is not # optimized, so it will connect to Twitter and it will perform some actions # with the specified account try: fd = open('tests/account_id', 'r') account_id = fd.read().strip() fd.close() except Exception: print "Error opening the tests/account_id file" exit(-1) core = Core() def assert_column_as_content(rtn): if len(rtn) > 0: acc = rtn.keys()[0] assert type(rtn[acc]) == list assert rtn[acc][0].__class__ == Column def test_list_accounts(): rtn = core.list_accounts() assert type(rtn) == list def test_all_columns():
class TestCore: @classmethod @pytest.fixture(autouse=True) def setup_class(self, monkeypatch): self.acc_id = "dummy-twitter" self.core = Core(load_accounts=False) self.account = Account.new("twitter", "dummy") self.account.columns = [Column(self.account.id_, ColumnType.TIMELINE)] self.account2 = Account.new("twitter", "qux") self.account2.columns = [Column(self.account2.id_, ColumnType.TIMELINE)] self.all_accounts = [self.account, self.account2] monkeypatch.setattr(self.core.accman, "get", lambda x: self.account) def test_core_is_a_valid_instance(self): assert isinstance(self.core, Core) def test_local_variables(self): assert self.core.config != None assert isinstance(self.core.config, AppConfig) assert self.core.accman != None assert isinstance(self.core.accman, AccountManager) assert self.core.column_manager != None assert isinstance(self.core.column_manager, ColumnManager) def test_filter_statuses(self, monkeypatch): status = Status() status.id_ = "123" status.username = "******" status.repeated_by = "bar" status.text = "Please, filter me" statuses = [status] monkeypatch.setattr(self.core.config, "load_filters", lambda: []) response = self.core.filter_statuses(statuses) assert response == statuses monkeypatch.setattr(self.core.config, "load_filters", lambda: ['@foo']) response = self.core.filter_statuses(statuses) assert response == [] monkeypatch.setattr(self.core.config, "load_filters", lambda: ['@bar']) response = self.core.filter_statuses(statuses) assert response == [] monkeypatch.setattr(self.core.config, "load_filters", lambda: ['filter']) response = self.core.filter_statuses(statuses) assert response == [] monkeypatch.setattr(self.core.config, "load_filters", lambda: ['dummy']) response = self.core.filter_statuses(statuses) assert response == statuses def test_fetch_image(self, monkeypatch): monkeypatch.setattr(requests, 'get', lambda x: DummyResponse('binarydata')) assert self.core.fetch_image('http://my_image.png') == 'binarydata' def test_list_methods(self): accounts = self.core.list_accounts() assert isinstance(accounts, list) for item in accounts: assert isinstance(item, str) protocols = self.core.list_protocols() assert isinstance(protocols, list) for item in protocols: assert isinstance(item, str) filters = self.core.list_filters() assert isinstance(filters, list) for item in filters: assert isinstance(item, str) def test_registering(self, monkeypatch): dummy = Account('twitter') monkeypatch.setattr(self.core.accman, "register", lambda x: self.acc_id) monkeypatch.setattr(self.core.column_manager, "register", lambda x: "dummy-twitter-column1") result = self.core.register_account(dummy) assert isinstance(result, str) result = self.core.register_column("dummy-twitter-column1") assert isinstance(result, str) def test_unregistering(self, monkeypatch): monkeypatch.setattr(self.core.accman, "unregister", lambda x,y: self.acc_id) monkeypatch.setattr(self.core.column_manager, "unregister", lambda x: "dummy-twitter-column1") result = self.core.unregister_account(self.acc_id) assert isinstance(result, str) result = self.core.unregister_column("dummy-twitter-column1") assert isinstance(result, str) def test_all_columns(self, monkeypatch): monkeypatch.setattr(self.core, 'registered_accounts', lambda: self.all_accounts) columns = self.core.all_columns() assert isinstance(columns, dict) for key, value in columns.iteritems(): assert isinstance(value, list) for col in value: assert (isinstance(col, Column) or isinstance(col, List)) def test_available_columns(self, monkeypatch): monkeypatch.setattr(self.core, 'registered_accounts', lambda: self.all_accounts) columns = self.core.available_columns() assert isinstance(columns, dict) for key, value in columns.iteritems(): assert isinstance(value, list) for col in value: assert (isinstance(col, Column) or isinstance(col, List)) def test_registered_columns(self): columns = self.core.registered_columns() assert isinstance(columns, dict) for key, value in columns.iteritems(): assert isinstance(value, list) for col in value: assert (isinstance(col, Column) or isinstance(col, List)) def test_registered_columns_by_order(self): columns = self.core.registered_columns_by_order() assert isinstance(columns, list) for col in columns: assert (isinstance(col, Column) or isinstance(col, List)) def test_registered_accounts(self): accounts = self.core.registered_accounts() assert isinstance(accounts, list) for acc in accounts: assert isinstance(acc, Account) def test_get_single_column(self, monkeypatch): dummy = Column(self.acc_id, "foo") monkeypatch.setattr(self.core.column_manager, "get", lambda x: dummy) column = self.core.get_single_column("dummy-twitter-column") assert isinstance(column, Column) def test_get_single_account(self): account = self.core.get_single_account(self.acc_id) assert isinstance(account, Account) def test_get_column_statuses(self, monkeypatch): status = Status() result = [status] monkeypatch.setattr(self.account, "get_timeline", lambda x, y: result) response = self.core.get_column_statuses(self.acc_id, "timeline") assert response == result monkeypatch.setattr(self.account, "get_replies", lambda x, y: result) response = self.core.get_column_statuses(self.acc_id, "replies") assert response == result monkeypatch.setattr(self.account, "get_directs", lambda x, y: result) response = self.core.get_column_statuses(self.acc_id, "directs") assert response == result monkeypatch.setattr(self.account, "get_favorites", lambda x: result) response = self.core.get_column_statuses(self.acc_id, "favorites") assert response == result monkeypatch.setattr(self.account, "get_sent", lambda x, y: result) response = self.core.get_column_statuses(self.acc_id, "sent") assert response == result monkeypatch.setattr(self.account, "get_public_timeline", lambda x, y: result) response = self.core.get_column_statuses(self.acc_id, "public") assert response == result list_ = List() list_.id_ = "666" monkeypatch.setattr(self.account, "get_list_id", lambda x: list_) status.id_ = "127" monkeypatch.setattr(self.account, "get_list_statuses", lambda x, y, z: result) response = self.core.get_column_statuses(self.acc_id, "my-list") assert isinstance(response, list) assert response[0].id_, "127" monkeypatch.setattr(self.account, "get_list_id", lambda x: None) with pytest.raises(UserListNotFound): self.core.get_column_statuses(self.acc_id, "unknown-list") monkeypatch.setattr(self.core, 'search', lambda w, x, y, z: result) response = self.core.get_column_statuses(self.acc_id, "search-dummy") assert response == result def test_get_public_timeline(self, monkeypatch): status = Status() status.id_ = "123" result = [status] monkeypatch.setattr(self.account, "get_public_timeline", lambda x, y: result) response = self.core.get_public_timeline(self.acc_id) assert isinstance(response, list) assert response[0].id_, "123" def test_get_followers(self, monkeypatch): profile = Profile() profile.id_ = "dummy" result = [profile] monkeypatch.setattr(self.account, "get_followers", lambda x: result) response = self.core.get_followers(self.acc_id) assert isinstance(response, list) assert response[0].id_, "dummy" def test_get_following(self, monkeypatch): profile = Profile() profile.id_ = "dummy" result = [profile] monkeypatch.setattr(self.account, "get_following", lambda x: result) response = self.core.get_following(self.acc_id) assert isinstance(response, list) assert response[0].id_, "dummy" def test_get_all_friends_list(self, monkeypatch): account = Account.new("twitter") accounts = [account] profile = Profile() profile.username = "******" result = [profile] monkeypatch.setattr(self.core.accman, "accounts", lambda: accounts) monkeypatch.setattr(account, "get_following", lambda: result) friends = self.core.get_all_friends_list() assert isinstance(friends, list) assert friends[0], "dummy" def test_load_all_friends_list(self): result = self.core.load_all_friends_list() assert isinstance(result, list) for friend in result: assert isinstance(friend, str) def test_get_user_profile(self, monkeypatch): profile = Profile() self.account.profile = profile result = [profile] monkeypatch.setattr(self.account, "get_profile", lambda x: profile) monkeypatch.setattr(self.account, "is_friend", lambda x: True) monkeypatch.setattr(self.core, "is_muted", lambda x: False) profile.id_ = "dummy" response = self.core.get_user_profile(self.acc_id) assert isinstance(response, Profile) assert response.id_, "dummy" profile.id_ = "user" response = self.core.get_user_profile(self.acc_id, "user") assert isinstance(response, Profile) assert response.id_, "user" assert response.followed_by, True assert not response.muted, True def test_get_conversation(self, monkeypatch): status = Status() status.id_ = "321" conversation = [status] monkeypatch.setattr(self.account, "get_conversation", lambda x: conversation) response = self.core.get_conversation(self.acc_id, "123") assert isinstance(response, list) assert isinstance(response[0], Status) assert response[0].id_, "321" def test_update_status(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "update_status", lambda x, y, z: status) response = self.core.update_status(self.acc_id, "Dummy message") assert response == status response = self.core.update_status(self.acc_id, "Dummy message", "123456") assert response == status response = self.core.update_status(self.acc_id, "Dummy message", "123456", "/path/to/media") assert response == status def test_broadcast_status(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "update_status", lambda x: status) monkeypatch.setattr(self.core, "registered_accounts", lambda: [self.account]) response = self.core.broadcast_status(None, "Dummy message") assert isinstance(response, dict) assert isinstance(response["dummy-twitter"], Status) assert response["dummy-twitter"] == status response = self.core.broadcast_status(["foo-twitter", "bar-twitter"], "Dummy message") assert isinstance(response, dict) assert isinstance(response["foo-twitter"], Status) assert response["foo-twitter"] == status assert isinstance(response["bar-twitter"], Status) assert response["bar-twitter"] == status monkeypatch.setattr(self.core.accman, "get", lambda x: 'whatever') response = self.core.broadcast_status(["foo-twitter"], "Dummy message") assert isinstance(response["foo-twitter"], Exception) def test_destroy_status(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "destroy_status", lambda x: status) response = self.core.destroy_status("dummy-twitter", "123") assert isinstance(response, Status) assert response == status def test_get_single_status(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "get_status", lambda x: status) response = self.core.get_single_status("dummy-twitter", "123") assert isinstance(response, Status) assert response == status def test_repeat_status(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "repeat_status", lambda x: status) response = self.core.repeat_status("dummy-twitter", "123") assert isinstance(response, Status) assert response == status def test_mark_status_as_favorite(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "mark_as_favorite", lambda x: status) response = self.core.mark_status_as_favorite("dummy-twitter", "123") assert isinstance(response, Status) assert response == status def test_unmark_status_as_favorite(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "unmark_as_favorite", lambda x: status) response = self.core.unmark_status_as_favorite("dummy-twitter", "123") assert isinstance(response, Status) assert response == status def test_send_direct_message(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "send_direct_message", lambda x, y: status) response = self.core.send_direct_message("dummy-twitter", "foo", "Dummy message") assert isinstance(response, Status) assert response == status def test_destroy_direct_message(self, monkeypatch): status = Status() monkeypatch.setattr(self.account, "destroy_direct_message", lambda x: status) response = self.core.destroy_direct_message("dummy-twitter", "123") assert isinstance(response, Status) assert response == status def test_update_profile(self, monkeypatch): profile = Profile() monkeypatch.setattr(self.account, "update_profile", lambda w, x, y, z: profile) # TODO: Test with no params # response = self.core.update_profile(self.acc_id) # raise excetion response = self.core.update_profile(self.acc_id, fullname="Another fullname") assert response == profile response = self.core.update_profile(self.acc_id, bio="Dummy bio") assert response == profile response = self.core.update_profile(self.acc_id, url="http://crazy.url") assert response == profile response = self.core.update_profile(self.acc_id, location="Nowhere") assert response == profile response = self.core.update_profile(self.acc_id, "Another fullname", "http://crazy.url", "Dummy bio", "Nowhere") assert response == profile def test_follow(self, monkeypatch): profile = Profile() profile.username = "******" monkeypatch.setattr(self.account, "follow", lambda x, y: profile) monkeypatch.setattr(self.core, "add_friend", lambda x: None) response = self.core.follow(self.acc_id, "foo") assert response == profile response = self.core.follow(self.acc_id, "123", True) assert response == profile def test_unfollow(self, monkeypatch): profile = Profile() profile.username = "******" monkeypatch.setattr(self.account, "unfollow", lambda x: profile) monkeypatch.setattr(self.core, "remove_friend", lambda x: None) response = self.core.unfollow(self.acc_id, "foo") assert response == profile def test_block(self, monkeypatch): profile = Profile() profile.username = "******" monkeypatch.setattr(self.account, "block", lambda x: profile) monkeypatch.setattr(self.core, "remove_friend", lambda x: None) response = self.core.block(self.acc_id, "foo") assert response == profile def test_unblock(self, monkeypatch): profile = Profile() profile.username = "******" monkeypatch.setattr(self.account, "unblock", lambda x: profile) response = self.core.unblock(self.acc_id, "foo") assert response == profile def test_report_as_spam(self, monkeypatch): profile = Profile() profile.username = "******" monkeypatch.setattr(self.account, "report_as_spam", lambda x: profile) monkeypatch.setattr(self.core, "remove_friend", lambda x: None) response = self.core.report_as_spam(self.acc_id, "foo") assert response == profile def test_mute(self, monkeypatch): monkeypatch.setattr(self.core.config, "append_filter", lambda x: "foo") response = self.core.mute("foo") assert response == "foo" def test_unmute(self, monkeypatch): monkeypatch.setattr(self.core.config, "remove_filter", lambda x: "foo") response = self.core.unmute("foo") assert response == "foo" def test_verify_friendship(self, monkeypatch): monkeypatch.setattr(self.account, "is_friend", lambda x: True) response = self.core.verify_friendship(self.acc_id, "foo") assert response is True monkeypatch.setattr(self.account, "is_friend", lambda x: False) response = self.core.verify_friendship(self.acc_id, "foo") assert response is False def test_search(self, monkeypatch): search = [Status()] monkeypatch.setattr(self.account, "search", lambda w, x, y, z: search) response = self.core.search(self.acc_id, "dummy", since_id="123", count=200, extra="ble") assert isinstance(response, list) assert isinstance(response[0], Status) response = self.core.search(self.acc_id, "dummy") assert isinstance(response, list) assert isinstance(response[0], Status) response = self.core.search(self.acc_id, "dummy", 200, "123", "ble") assert isinstance(response, list) assert isinstance(response[0], Status) def test_get_profile_image(self, monkeypatch): monkeypatch.setattr(os.path, "join", lambda x, y: '/path/to/ble') monkeypatch.setattr(os.path, "isfile", lambda x: True) monkeypatch.setattr(self.core.accman, 'get', lambda x: DummyAccount()) monkeypatch.setattr(__builtin__, 'open', lambda x, y: DummyFileHandler()) response = self.core.get_profile_image(self.acc_id, "foo") assert response == "/path/to/ble" monkeypatch.setattr(self.core, 'fetch_image', lambda x: 'binary') monkeypatch.setattr(os.path, "join", lambda x, y: '/path/to/bla') response = self.core.get_profile_image(self.acc_id, "foo", False) assert response == "/path/to/bla" def test_get_status_avatar(self, monkeypatch): status = Status() status.id_ = "123456789" status.account_id = "foo-twitter" status.username = "******" status.avatar = "http://my.dummy/avatar" monkeypatch.setattr(os.path, "join", lambda x, y: '/path/to/ble') monkeypatch.setattr(os.path, "isfile", lambda x: True) monkeypatch.setattr(self.core.accman, 'get', lambda x: DummyAccount()) response = self.core.get_status_avatar(status) assert response == "/path/to/ble" monkeypatch.setattr(os.path, "join", lambda x, y: '/path/to/bla') monkeypatch.setattr(os.path, "isfile", lambda x: False) monkeypatch.setattr(__builtin__, 'open', lambda x, y: DummyFileHandler()) monkeypatch.setattr(self.core, 'fetch_image', lambda x: 'binary') response = self.core.get_status_avatar(status) assert response == "/path/to/bla" def test_get_available_trend_locations(self, monkeypatch): location = TrendLocation('Global', 1) monkeypatch.setattr(self.account, "available_trend_locations", lambda: [location]) response = self.core.get_available_trend_locations(self.acc_id) assert isinstance(response, list) assert response[0] == location def test_get_trending_topics(self, monkeypatch): trend = Trend('Foo') monkeypatch.setattr(self.account, "trends", lambda x: [trend]) response = self.core.get_trending_topics(self.acc_id, "here") assert isinstance(response, list) assert response[0] == trend def test_update_profile_image(self, monkeypatch): profile = Profile() monkeypatch.setattr(self.account, "update_profile_image", lambda x: profile) response = self.core.update_profile_image(self.acc_id, "/path/to/ble") assert response == profile # Services def test_available_short_url_services(self): response = self.core.available_short_url_services() assert isinstance(response, list) assert isinstance(response[0], str) def test_short_single_url(self, monkeypatch): monkeypatch.setattr(self.core, "get_shorten_url_service", lambda: 'is.gd') with pytest.raises(URLAlreadyShort): self.core.short_single_url('http://is.gd/blable') monkeypatch.setattr(self.core, "_Core__get_short_url_object", lambda x: DummyService('http://is.gd/ble')) response = self.core.short_single_url('http://my.looooon.url') assert response == 'http://is.gd/ble' def test_short_url_in_message(self, monkeypatch): monkeypatch.setattr(self.core, "get_shorten_url_service", lambda: 'is.gd') message = "Hello, this is a message with a dumb url http://dumb.url.com" message_with_short_url = "Hello, this is a message with a short url http://is.gd/dumb" message_with_no_url = "Hello, this is a message with no url" message_expected = "Hello, this is a message with a dumb url http://is.gd/dumb" with pytest.raises(NoURLToShorten): self.core.short_url_in_message(message_with_no_url) monkeypatch.setattr(self.core, "short_single_url", lambda x: 'http://is.gd/dumb') response = self.core.short_url_in_message(message) assert response == message_expected def raise_ex(): raise URLAlreadyShort response = self.core.short_url_in_message(message_with_short_url) assert response == message_with_short_url def test_available_preview_media_services(self): response = self.core.available_preview_media_services() assert isinstance(response, list) assert isinstance(response[0], str) def test_preview_media(self, monkeypatch): media = Media.new_image('foo', 'binary content') with pytest.raises(PreviewServiceNotSupported): self.core.preview_media('http://unsupported.service.com/ble') monkeypatch.setattr('libturpial.lib.services.media.preview.pictwitter.PicTwitterMediaContent._get_content_from_url', lambda x, y: '123') response = self.core.preview_media('http://pic.twitter.com/ble') assert isinstance(response, Media) def test_available_upload_media_services(self): response = self.core.available_upload_media_services() assert isinstance(response, list) assert isinstance(response[0], str) def test_upload_media(self, monkeypatch): monkeypatch.setattr(self.core, "get_upload_media_service", lambda: 'ima.ge') monkeypatch.setattr(self.core, "_Core__get_upload_media_object", lambda x: DummyService('http://ima.ge/bla')) response = self.core.upload_media(self.acc_id, '/path/to/file', "Dummy message") assert response == 'http://ima.ge/bla' # Configuration def test_register_new_config_option(self, monkeypatch): monkeypatch.setattr(self.core.config, 'register_extra_option', lambda x, y, z: None) # TODO: How to test that this works? Return 0 maybe? assert self.core.register_new_config_option('foo', 'bar', 'baz') == None def test_get_shorten_url_service(self): response = self.core.get_shorten_url_service() assert isinstance(response, str) def test_get_upload_media_service(self): response = self.core.get_upload_media_service() assert isinstance(response, str) def test_set_shorten_url_service(self, monkeypatch): monkeypatch.setattr(self.core.config, "write", lambda x, y, z: None) response = self.core.set_shorten_url_service('foo') assert response is None def test_set_upload_media_service(self, monkeypatch): monkeypatch.setattr(self.core.config, "write", lambda x, y, z: None) response = self.core.set_upload_media_service('foo') assert response is None def test_has_stored_passwwd(self, monkeypatch): account = Account.new("twitter") profile = Profile() profile.username = "******" account.profile = profile monkeypatch.setattr(self.core.accman, "get", lambda x: account) profile.password = None response = self.core.has_stored_passwd("foo") assert response == False profile.password = '' response = self.core.has_stored_passwd("foo") assert response == False profile.password = '******' response = self.core.has_stored_passwd("foo") assert response == True def test_is_account_logged_in(self, monkeypatch): account = Account.new("twitter") monkeypatch.setattr(self.core.accman, "get", lambda x: account) account.logged_in = False response = self.core.is_account_logged_in("foo") assert response == False account.logged_in = True response = self.core.is_account_logged_in("foo") assert response == True def test_is_muted(self, monkeypatch): monkeypatch.setattr(self.core.config, "load_filters", lambda: ['@foo', '@bar', 'baz']) response = self.core.is_muted('foo') assert response == True response = self.core.is_muted('baz') assert response == False def test_get_default_browser(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: None) response = self.core.get_default_browser() assert response is None monkeypatch.setattr(self.core.config, "read", lambda x, y: 'chromium') response = self.core.get_default_browser() assert response == 'chromium' def test_show_notifications_in_login(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: 'on') response = self.core.show_notifications_in_login() assert response == True monkeypatch.setattr(self.core.config, "read", lambda x, y: 'off') response = self.core.show_notifications_in_login() assert response == False def test_show_notifications_in_updates(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: 'on') response = self.core.show_notifications_in_updates() assert response == True monkeypatch.setattr(self.core.config, "read", lambda x, y: 'off') response = self.core.show_notifications_in_updates() assert response == False def test_play_sounds_in_login(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: 'on') response = self.core.play_sounds_in_login() assert response == True monkeypatch.setattr(self.core.config, "read", lambda x, y: 'off') response = self.core.play_sounds_in_login() assert response == False def test_play_sounds_in_updates(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: 'on') response = self.core.play_sounds_in_updates() assert response == True monkeypatch.setattr(self.core.config, "read", lambda x, y: 'off') response = self.core.play_sounds_in_updates() assert response == False def test_get_max_statuses_per_column(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: '200') response = self.core.get_max_statuses_per_column() assert isinstance(response, int) def test_get_proxy(self, monkeypatch): proxy = Proxy('1.2.3.4', '666') monkeypatch.setattr(self.core.config, "get_proxy", lambda: proxy) response = self.core.get_proxy() assert isinstance(response, Proxy) def test_get_socket_timeout(self, monkeypatch): monkeypatch.setattr(self.core.config, "get_socket_timeout", lambda: '20') response = self.core.get_socket_timeout() assert isinstance(response, int) def test_get_update_interval(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: '200') response = self.core.get_update_interval() assert isinstance(response, int) def test_minimize_on_close(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: 'on') response = self.core.minimize_on_close() assert response == True monkeypatch.setattr(self.core.config, "read", lambda x, y: 'off') response = self.core.minimize_on_close() assert response == False def test_get_config(self, monkeypatch): monkeypatch.setattr(self.core.config, "read_all", lambda: APP_CFG) response = self.core.get_config() assert isinstance(response, dict) def test_read_config_value(self, monkeypatch): monkeypatch.setattr(self.core.config, "read", lambda x, y: "foo") response = self.core.read_config_value("bar", "baz") assert response == "foo" def test_write_config_value(self, monkeypatch): monkeypatch.setattr(self.core.config, "write", lambda x, y, z: None) response = self.core.write_config_value("foo", "bar", "baz") assert response is None def test_save_all_config(self, monkeypatch): monkeypatch.setattr(self.core.config, "save", lambda x: None) response = self.core.save_all_config({}) assert response is None def test_list_filters(self): response = self.core.list_filters() assert isinstance(response, list) def test_save_filters(self, monkeypatch): monkeypatch.setattr(self.core.config, "save_filters", lambda x: None) response = self.core.save_filters([]) assert response is None def test_delete_current_config(self, monkeypatch): monkeypatch.setattr(self.core.config, "delete", lambda: None) response = self.core.delete_current_config() assert response is None def test_delete_cache(self, monkeypatch): monkeypatch.setattr(self.account, "delete_cache", lambda: None) monkeypatch.setattr(self.core, "registered_accounts", lambda: [self.account]) response = self.core.delete_cache() assert response is None def test_get_cache_size(self, monkeypatch): monkeypatch.setattr(self.account, "get_cache_size", lambda: 10) monkeypatch.setattr(self.core, "registered_accounts", lambda: [self.account]) response = self.core.get_cache_size() assert response == 10 def test_add_friend(self, monkeypatch): monkeypatch.setattr(self.core.config, "save_friends", lambda x: None) response = self.core.add_friend("foo") assert response is None def test_remove_friend(self, monkeypatch): monkeypatch.setattr(self.core.config, "save_friends", lambda x: None) monkeypatch.setattr(self.core.config, "load_friends", lambda: ['foo']) response = self.core.remove_friend("foo") assert response is None
def __init__(self): parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) parser.add_option('--setup', dest='setup', action='store_true', help='execute the setup wizard', default=False) parser.add_option('--add-account', dest='add_account', default=False, action='store_true', help='add a microblogging account to database') parser.add_option('--del-account', dest='delete_account', action='store_true', help='delete a microblogging account from \ database', default=False) parser.add_option('--list-accounts', dest='list_accounts', action='store_true', help='list all microblogging accounts', default=False) parser.add_option('--add-feed', dest='add_feed', action='store_true', help='add feed to database', default=False) parser.add_option('--del-feed', dest='delete_feed', action='store_true', help='delete feed from database', default=False) parser.add_option('--list-feeds', dest='list_feeds', action='store_true', help='list all registered feeds', default=False) parser.add_option('--associate', dest='associate_feed', action='store_true', help='associate feed with account', default=False) parser.add_option('--deassociate', dest='deassociate_feed', action='store_true', help='deassociate feed from account', default=False) parser.add_option('--change-prefix', dest='change_prefix', action='store_true', default=False, help='change the publish prefix for certain feed/account') parser.add_option('--show-info', dest='show_info', action='store_true', help='show information about feeds and accounts', default=False) parser.add_option('--test', dest='test', action='store_true', help='poll feeds without posting or saving in db', default=False) parser.add_option('--empty-records', dest='empty_records', action='store_true', default=False, help='delete posts and update records from database') (options, args) = parser.parse_args() if options.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.log = logging.getLogger('TwitRSS') self.db = DBEngine() Feed.db = self.db Account.db = self.db AccountFeed.db = self.db Post.db = self.db self.core = Core() Account.core = self.core if options.setup: self.setup() self.quit() if options.add_account: self.add_account() self.quit() if options.delete_account: self.delete_account() self.quit() if options.add_feed: self.add_feed() self.quit() if options.delete_feed: self.delete_feed() self.quit() if options.associate_feed: self.associate_feed() self.quit() if options.deassociate_feed: self.deassociate_feed() self.quit() if options.show_info: self.show_info() self.quit() if options.empty_records: self.empty_records() self.quit() self.test = options.test self.log.info("Starting service") self.queue = Queue.Queue() Post.queue = self.queue self.start()
class TwitRss: def __init__(self): parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) parser.add_option('--setup', dest='setup', action='store_true', help='execute the setup wizard', default=False) parser.add_option('--add-account', dest='add_account', default=False, action='store_true', help='add a microblogging account to database') parser.add_option('--del-account', dest='delete_account', action='store_true', help='delete a microblogging account from \ database', default=False) parser.add_option('--list-accounts', dest='list_accounts', action='store_true', help='list all microblogging accounts', default=False) parser.add_option('--add-feed', dest='add_feed', action='store_true', help='add feed to database', default=False) parser.add_option('--del-feed', dest='delete_feed', action='store_true', help='delete feed from database', default=False) parser.add_option('--list-feeds', dest='list_feeds', action='store_true', help='list all registered feeds', default=False) parser.add_option('--associate', dest='associate_feed', action='store_true', help='associate feed with account', default=False) parser.add_option('--deassociate', dest='deassociate_feed', action='store_true', help='deassociate feed from account', default=False) parser.add_option('--change-prefix', dest='change_prefix', action='store_true', default=False, help='change the publish prefix for certain feed/account') parser.add_option('--show-info', dest='show_info', action='store_true', help='show information about feeds and accounts', default=False) parser.add_option('--test', dest='test', action='store_true', help='poll feeds without posting or saving in db', default=False) parser.add_option('--empty-records', dest='empty_records', action='store_true', default=False, help='delete posts and update records from database') (options, args) = parser.parse_args() if options.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.log = logging.getLogger('TwitRSS') self.db = DBEngine() Feed.db = self.db Account.db = self.db AccountFeed.db = self.db Post.db = self.db self.core = Core() Account.core = self.core if options.setup: self.setup() self.quit() if options.add_account: self.add_account() self.quit() if options.delete_account: self.delete_account() self.quit() if options.add_feed: self.add_feed() self.quit() if options.delete_feed: self.delete_feed() self.quit() if options.associate_feed: self.associate_feed() self.quit() if options.deassociate_feed: self.deassociate_feed() self.quit() if options.show_info: self.show_info() self.quit() if options.empty_records: self.empty_records() self.quit() self.test = options.test self.log.info("Starting service") self.queue = Queue.Queue() Post.queue = self.queue self.start() def __user_input(self, message, blank=False): while 1: text = raw_input(message) if text == '' and not blank: print "You can't leave this field blank" continue break return text def __user_password(self, message): passwd = None while 1: passwd = getpass.unix_getpass(message) if passwd: return passwd else: print "Password can't be blank" def __build_confirm_menu(self, message): confirm = raw_input(message + ' [y/N]: ') if confirm.lower() == 'y': return True else: return False def __build_protocols_menu(self): index = None protocols = self.core.list_protocols() while 1: print "Available protocols:" for i in range(len(protocols)): print "[%i] %s" % (i, protocols[i]) index = raw_input('Select protocol: ') if not self.__validate_index(index, protocols): print "Invalid protocol" else: break return protocols[int(index)] def __build_accounts_menu(self, _all=False): index = None while 1: accounts = self.__show_accounts() if _all: index = raw_input('Select account (or Enter for all): ') else: index = raw_input('Select account: ') if not self.__validate_index(index, accounts, _all): print "Invalid account" else: break if index == '': return accounts else: return accounts[int(index)] def __show_accounts(self, just_list=False): accounts = [] reg_accs = Account.get_from_libturpial() if len(reg_accs) == 0: return None print "\nAvailable accounts:" for acc in reg_accs: if just_list: print "* %s (%s)" % (acc.username, acc.protocol) else: print "[%i] %s - %s" % (len(accounts), acc.username, acc.protocol) full_acc = Account.save_from_obj(acc) accounts.append(full_acc) return accounts def __build_feeds_menu(self): index = None while 1: feeds = self.__show_feeds() index = raw_input('Select feed: ') if not self.__validate_index(index, feeds, False): print "Invalid feed" else: break return feeds[int(index)] def __show_feeds(self, just_list=False): rtn = Feed.get_all() if len(rtn) == 0: self.log.info("There are no registered feeds") return None feeds = [] print "\nAvailable feeds:" for feed in rtn: if just_list: print "* %s" % (feed.url) else: print "[%i] %s" % (len(feeds), feed.url) feeds.append(feed) return feeds def __build_account_feeds_menu(self): index = None while 1: afs = self.__show_account_feeds() index = raw_input('Select account/feed: ') if not self.__validate_index(index, afs, False): print "Invalid account/feed" else: break return afs[int(index)] def __show_account_feeds(self, just_list=False): rtn = AccountFeed.get_all() if len(rtn) == 0: self.log.info("There are no feeds associated with accounts") return None account_feeds = [] print "\nFeeds associated with accounts:" for af in rtn: if just_list: print "* %-35s %-35s" % (af.account, af.feed.url) else: print "[%i] %-35s %-35s" % (len(account_feeds), af.account, af.feed.url) account_feeds.append(af) return account_feeds def __validate_index(self, index, array, blank=False): try: a = array[int(index)] return True except IndexError: return False except ValueError: if blank and index == '': return True elif not blank and index == '': return False elif blank and index != '': return False except TypeError: if index is None: return False def start(self): accounts = Account.count() feeds = Feed.count() account_feeds = AccountFeed.count() if (accounts == 0) or (feeds == 0) or (account_feeds == 0): self.log.info('You need to fully configure your bot. Please execute script with --setup param') return self.login() def login(self): accounts = self.core.all_accounts() for acc in accounts: response = self.core.login(acc.id_) if response.code > 0: print "Login error:", response.errmsg return auth_obj = response.items if auth_obj.must_auth(): print "Please visit %s, authorize Turpial and type the pin \ returned" % auth_obj.url pin = self.user_input('Pin: ') self.core.authorize_oauth_token(acc.id_, pin) rtn = self.core.auth(acc.id_) if rtn.code > 0: print rtn.errmsg return else: self.log.debug('Logged in with account %s' % acc.id_) self.main() # ======================================================================= # Commands # ======================================================================= def setup(self): accounts = self.__show_accounts(True) if not accounts: print 'You need to create at least one account' self.add_account() while 1: if self.__build_confirm_menu('Do you want to add more accounts?'): self.add_account() else: break self.__show_feeds(True) while 1: if self.__build_confirm_menu('Do you want to add more feeds?'): self.add_feed() else: break while 1: if self.__build_confirm_menu('\nDo you want to associate feeds with accounts?'): self.associate_feed() else: break def add_account(self): username = self.__user_input('Username: '******'' if protocol == ProtocolType.IDENTICA: passwd = self.__user_password('Password: '******'Pin: ') self.core.authorize_oauth_token(acc_id, pin) rtn = self.core.auth(acc_id) if rtn.code > 0: self.log.error(response.errmsg) return # Save in DB Account.save(acc_id, username, protocol) self.log.info('Account added successfully') except Exception, e: self.log.exception(e) self.log.error('Error registering account. Please try again')
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import argparse import sqlite3 from libturpial.api.models.account import Account from libturpial.api.core import Core from libturpial.common import get_username_from MAX_STATUS_LENGTH = 140 core = Core() accounts = core.list_accounts() def build_account_id(username): return '{username}-twitter'.format(username=username) def register_account(username): account = build_account_id(username) if account in accounts: print 'Your account is already registered. Nothing to do' else: new_access = Account.new('twitter') url = new_access.request_oauth_access() print "Please go to the following URL, log-in and allow access for libturpial. Then write the PIN in here." print url cod = raw_input('PIN:') new_access.authorize_oauth_access(cod)
#!/usr/bin/python # -*- coding: utf-8 -*- # Libturpial usage example # # Author: Carlos Guerrero <*****@*****.**> # 24 June 2013 from libturpial.api.models.account import Account from libturpial.api.core import Core account = "username-twitter" #Replace <username> with the user you want to send tweet with message = "Tweet sent using Libturpial" c = Core() accounts = c.list_accounts() if account in accounts: c.update_status(account,message) else: #If account is not already registered in libturpial, acces must be granted: a = Account.new('twitter') #you can also create identi.ca accounts url = a.request_oauth_access() print "Please go to the following URL, log-in and allow access for Libturpial. Then write the PIN in here." print url cod = raw_input("PIN:") a.authorize_oauth_access(cod) c.register_account(a)
class TwitRss: def __init__(self): parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) parser.add_option('--setup', dest='setup', action='store_true', help='execute the setup wizard', default=False) parser.add_option('--add-account', dest='add_account', default=False, action='store_true', help='add a microblogging account to database') parser.add_option('--del-account', dest='delete_account', action='store_true', help='delete a microblogging account from \ database', default=False) parser.add_option('--list-accounts', dest='list_accounts', action='store_true', help='list all microblogging accounts', default=False) parser.add_option('--add-feed', dest='add_feed', action='store_true', help='add feed to database', default=False) parser.add_option('--del-feed', dest='delete_feed', action='store_true', help='delete feed from database', default=False) parser.add_option('--list-feeds', dest='list_feeds', action='store_true', help='list all registered feeds', default=False) parser.add_option('--associate', dest='associate_feed', action='store_true', help='associate feed with account', default=False) parser.add_option('--deassociate', dest='deassociate_feed', action='store_true', help='deassociate feed from account', default=False) parser.add_option( '--change-prefix', dest='change_prefix', action='store_true', default=False, help='change the publish prefix for certain feed/account') parser.add_option('--show-info', dest='show_info', action='store_true', help='show information about feeds and accounts', default=False) parser.add_option('--test', dest='test', action='store_true', help='poll feeds without posting or saving in db', default=False) parser.add_option('--empty-records', dest='empty_records', action='store_true', default=False, help='delete posts and update records from database') (options, args) = parser.parse_args() if options.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.log = logging.getLogger('TwitRSS') self.db = DBEngine() Feed.db = self.db Account.db = self.db AccountFeed.db = self.db Post.db = self.db self.core = Core() Account.core = self.core if options.setup: self.setup() self.quit() if options.add_account: self.add_account() self.quit() if options.delete_account: self.delete_account() self.quit() if options.add_feed: self.add_feed() self.quit() if options.delete_feed: self.delete_feed() self.quit() if options.associate_feed: self.associate_feed() self.quit() if options.deassociate_feed: self.deassociate_feed() self.quit() if options.show_info: self.show_info() self.quit() if options.empty_records: self.empty_records() self.quit() self.test = options.test self.log.info("Starting service") self.queue = Queue.Queue() Post.queue = self.queue self.start() def __user_input(self, message, blank=False): while 1: text = raw_input(message) if text == '' and not blank: print "You can't leave this field blank" continue break return text def __user_password(self, message): passwd = None while 1: passwd = getpass.unix_getpass(message) if passwd: return passwd else: print "Password can't be blank" def __build_confirm_menu(self, message): confirm = raw_input(message + ' [y/N]: ') if confirm.lower() == 'y': return True else: return False def __build_protocols_menu(self): index = None protocols = self.core.list_protocols() while 1: print "Available protocols:" for i in range(len(protocols)): print "[%i] %s" % (i, protocols[i]) index = raw_input('Select protocol: ') if not self.__validate_index(index, protocols): print "Invalid protocol" else: break return protocols[int(index)] def __build_accounts_menu(self, _all=False): index = None while 1: accounts = self.__show_accounts() if _all: index = raw_input('Select account (or Enter for all): ') else: index = raw_input('Select account: ') if not self.__validate_index(index, accounts, _all): print "Invalid account" else: break if index == '': return accounts else: return accounts[int(index)] def __show_accounts(self, just_list=False): accounts = [] reg_accs = Account.get_from_libturpial() if len(reg_accs) == 0: return None print "\nAvailable accounts:" for acc in reg_accs: if just_list: print "* %s (%s)" % (acc.username, acc.protocol) else: print "[%i] %s - %s" % (len(accounts), acc.username, acc.protocol) full_acc = Account.save_from_obj(acc) accounts.append(full_acc) return accounts def __build_feeds_menu(self): index = None while 1: feeds = self.__show_feeds() index = raw_input('Select feed: ') if not self.__validate_index(index, feeds, False): print "Invalid feed" else: break return feeds[int(index)] def __show_feeds(self, just_list=False): rtn = Feed.get_all() if len(rtn) == 0: self.log.info("There are no registered feeds") return None feeds = [] print "\nAvailable feeds:" for feed in rtn: if just_list: print "* %s" % (feed.url) else: print "[%i] %s" % (len(feeds), feed.url) feeds.append(feed) return feeds def __build_account_feeds_menu(self): index = None while 1: afs = self.__show_account_feeds() index = raw_input('Select account/feed: ') if not self.__validate_index(index, afs, False): print "Invalid account/feed" else: break return afs[int(index)] def __show_account_feeds(self, just_list=False): rtn = AccountFeed.get_all() if len(rtn) == 0: self.log.info("There are no feeds associated with accounts") return None account_feeds = [] print "\nFeeds associated with accounts:" for af in rtn: if just_list: print "* %-35s %-35s" % (af.account, af.feed.url) else: print "[%i] %-35s %-35s" % (len(account_feeds), af.account, af.feed.url) account_feeds.append(af) return account_feeds def __validate_index(self, index, array, blank=False): try: a = array[int(index)] return True except IndexError: return False except ValueError: if blank and index == '': return True elif not blank and index == '': return False elif blank and index != '': return False except TypeError: if index is None: return False def start(self): accounts = Account.count() feeds = Feed.count() account_feeds = AccountFeed.count() if (accounts == 0) or (feeds == 0) or (account_feeds == 0): self.log.info( 'You need to fully configure your bot. Please execute script with --setup param' ) return self.login() def login(self): accounts = self.core.all_accounts() for acc in accounts: response = self.core.login(acc.id_) if response.code > 0: print "Login error:", response.errmsg return auth_obj = response.items if auth_obj.must_auth(): print "Please visit %s, authorize Turpial and type the pin \ returned" % auth_obj.url pin = self.user_input('Pin: ') self.core.authorize_oauth_token(acc.id_, pin) rtn = self.core.auth(acc.id_) if rtn.code > 0: print rtn.errmsg return else: self.log.debug('Logged in with account %s' % acc.id_) self.main() # ======================================================================= # Commands # ======================================================================= def setup(self): accounts = self.__show_accounts(True) if not accounts: print 'You need to create at least one account' self.add_account() while 1: if self.__build_confirm_menu('Do you want to add more accounts?'): self.add_account() else: break self.__show_feeds(True) while 1: if self.__build_confirm_menu('Do you want to add more feeds?'): self.add_feed() else: break while 1: if self.__build_confirm_menu( '\nDo you want to associate feeds with accounts?'): self.associate_feed() else: break def add_account(self): username = self.__user_input('Username: '******'' if protocol == ProtocolType.IDENTICA: passwd = self.__user_password('Password: '******'Pin: ') self.core.authorize_oauth_token(acc_id, pin) rtn = self.core.auth(acc_id) if rtn.code > 0: self.log.error(response.errmsg) return # Save in DB Account.save(acc_id, username, protocol) self.log.info('Account added successfully') except Exception, e: self.log.exception(e) self.log.error('Error registering account. Please try again')
def login(self): self.core = Core() self.queue_path = os.path.join(self.core.config.basedir, 'queue') if not os.path.isfile(self.queue_path): open(self.queue_path, 'w').close()
import sys from libturpial.api.core import Core message = sys.argv[1] if not message or message == '': sys.exit(-1) ACCOUNT = 'turpialve-twitter' BROADCAST = ['satanas82', 'guerrerocarlos'] c = Core() c.login(ACCOUNT) c.auth(ACCOUNT) for acc in BROADCAST: c.send_direct(ACCOUNT, acc, message)
class Adopta: def __init__(self): parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) (options, args) = parser.parse_args() if options.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.core = Core() self.followers = [] self.following = [] self.last_dm = None self.log = logging.getLogger('Server') self.start_login() def start_login(self): self.core.register_account(ACCOUNT.split('-')[0], ACCOUNT.split('-')[1], '') response = self.core.login(ACCOUNT) if response.code > 0: print "Login error:", response.errmsg return auth_obj = response.items if auth_obj.must_auth(): print "Please visit %s, authorize Turpial and type the pin returned" % auth_obj.url pin = self.user_input('Pin: ') self.core.authorize_oauth_token(ACCOUNT, pin) rtn = self.core.auth(ACCOUNT) if rtn.code > 0: print rtn.errmsg else: self.log.debug('Logged in with account %s' % ACCOUNT.split('-')[0]) self.main() def user_input(self, message, blank=False): while 1: text = raw_input(message) if text == '' and not blank: print "You can't leave this field blank" continue break return text def get_followers(self): response = self.core.get_followers(ACCOUNT, True) if response.code > 0: self.log.error("Error getting followers list:", response.errmsg) else: self.followers = response.items def get_following(self): response = self.core.get_following(ACCOUNT, True) if response.code > 0: self.log.error("Error getting following list:", response.errmsg) else: self.following = response.items def process_follow_back(self): temp = [] for item in self.followers: if item not in self.following: if len(temp) < MAX_FOLLOW: temp.append(item) else: break for item in temp: response = self.core.follow(ACCOUNT, str(item), by_id=True) if response.code > 0: self.log.error("Error following to %s: %s" % (item, response.errmsg)) else: self.log.debug("Follow back to %s" % item) self.following.append(item) def process_dms(self): response = self.core.get_column_statuses(ACCOUNT, ColumnType.DIRECTS, 200) if response.code > 0: self.log.error("Error fetching DMs: %s" % response.errmsg) else: for dm in response.items: msg_id = dm.id_ valid = self.validate_dm(dm) if not valid: continue via = ' (via @%s)' % dm.username text = dm.text length = len(text) + len(via) if length > 140: text = text[:len(text) - len(via)] message = text + via message.encode('utf-8') rtn = self.core.update_status(ACCOUNT, message) if rtn.code > 0: self.log.error("Error posting message '%s': %s" % (message, rtn.errmsg)) else: self.register_message(dm) def validate_dm(self, dm): # TODO: Search in database for msg_id, if exist then return False # otherwiser return True if len(Tweet.objects.filter(status_id=dm.id_)) > 0: return False else: return True def register_message(self, dm): # TODO: Add dm to database t = Tweet(status_id=dm.id_,username=dm.username,content=dm.text) t.save() pass def main(self): while True: try: # Processing followbacks self.get_followers() self.get_following() self.process_follow_back() # Processing DMs self.process_dms() time.sleep(POLLING_TIME * 60) except KeyboardInterrupt: break self.log.debug('Bye')
class Remote(): def __init__(self): self.turpial = Core() for controller in Controller.objects.all(): self.turpial.register_account(controller.user,controller.password,self.turpial.list_protocols()[int(controller.service)]) for acc in self.turpial.list_accounts(): rtn = self.turpial.login(acc) if rtn.code > 0: print rtn.errmsg else: print 'Logged in with account %s' % acc.split('-')[0] print "Ciclo de extraccion *****************" while True: for acc in self.turpial.list_accounts(): # rtn = self.turpial.get_column_statuses(acc, ColumnType.DIRECTS) # self.process_statuses(rtn) rtn = self.turpial.get_column_statuses(acc, ColumnType.REPLIES) self.process_statuses(rtn) def procesar(self,tweet): if tweet.text.find("#") > -1: pos=tweet.text[tweet.text.find("#"):].find(" ") if pos == -1: pos = len(tweet.text[tweet.text.find("#"):]) print "pos: "+str(pos) print "buscando :"+tweet.text[tweet.text.find("#"):tweet.text.find("#")+pos] song = Song.objects.get(id=int(tweet.text[tweet.text.find("#")+1:int(tweet.text.find("#")+pos)])) if SongRequest.objects.get_active_requests().filter(song=song): # Don't allow requesting a song that is currently in the queue. print "Song has already been requested." else: # Song isn't already in the SongRequest queue, add it. request = SongRequest(song=song, twitter=tweet.username) request.save() rtn = self.turpial.update_status(self.turpial.list_accounts()[0], "@"+tweet.username+" puso en cola de reproduccion a: "+song.title+" - "+song.artist) if rtn.code > 0: print rtn.errmsg else: print '\n\n\n\nMessage posted in account %s' % self.turpial.list_accounts()[0].split('-')[0] print "***************Song Requested.\n\n\n\n\n" def process_statuses(self,statuses): if statuses.code > 0: print statuses.errmsg return count = 1 for status in statuses[::-1]: text = status.text.replace('\n', ' ') inreply = '' if status.in_reply_to_user: inreply = ' en respuesta a %s' % status.in_reply_to_user tweet, create =Tweet.objects.get_or_create(username=status.username,\ text=text,datetime=status.datetime,\ source=status.source,inreply=inreply) if create : print "added" self.procesar(tweet) if status.reposted_by: users = '' for u in status.reposted_by: users += u + ' ' print 'Retweeted by %s' % status.reposted_by print count += 1
def __init__(self): parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) parser.add_option('--setup', dest='setup', action='store_true', help='execute the setup wizard', default=False) parser.add_option('--add-account', dest='add_account', default=False, action='store_true', help='add a microblogging account to database') parser.add_option('--del-account', dest='delete_account', action='store_true', help='delete a microblogging account from \ database', default=False) parser.add_option('--list-accounts', dest='list_accounts', action='store_true', help='list all microblogging accounts', default=False) parser.add_option('--add-feed', dest='add_feed', action='store_true', help='add feed to database', default=False) parser.add_option('--del-feed', dest='delete_feed', action='store_true', help='delete feed from database', default=False) parser.add_option('--list-feeds', dest='list_feeds', action='store_true', help='list all registered feeds', default=False) parser.add_option('--associate', dest='associate_feed', action='store_true', help='associate feed with account', default=False) parser.add_option('--deassociate', dest='deassociate_feed', action='store_true', help='deassociate feed from account', default=False) parser.add_option( '--change-prefix', dest='change_prefix', action='store_true', default=False, help='change the publish prefix for certain feed/account') parser.add_option('--show-info', dest='show_info', action='store_true', help='show information about feeds and accounts', default=False) parser.add_option('--test', dest='test', action='store_true', help='poll feeds without posting or saving in db', default=False) parser.add_option('--empty-records', dest='empty_records', action='store_true', default=False, help='delete posts and update records from database') (options, args) = parser.parse_args() if options.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.log = logging.getLogger('TwitRSS') self.db = DBEngine() Feed.db = self.db Account.db = self.db AccountFeed.db = self.db Post.db = self.db self.core = Core() Account.core = self.core if options.setup: self.setup() self.quit() if options.add_account: self.add_account() self.quit() if options.delete_account: self.delete_account() self.quit() if options.add_feed: self.add_feed() self.quit() if options.delete_feed: self.delete_feed() self.quit() if options.associate_feed: self.associate_feed() self.quit() if options.deassociate_feed: self.deassociate_feed() self.quit() if options.show_info: self.show_info() self.quit() if options.empty_records: self.empty_records() self.quit() self.test = options.test self.log.info("Starting service") self.queue = Queue.Queue() Post.queue = self.queue self.start()
import os import sys import argparse try: from libturpial.api.models.account import Account from libturpial.api.core import Core except ImportError: path = \ os.path.join(os.path.dirname(os.path.abspath(__file__)), '..') sys.path.append(path) from libturpial.api.models.account import Account from libturpial.api.core import Core core = Core() # Parsing the command line description = "Send a message from libturpial" parser = argparse.ArgumentParser(description=description) parser.add_argument("-u", "--username", dest="username", help="Username", required=True) parser.add_argument("-p", "--protocol", dest="protocol", choices=core.list_protocols(), help="Protocol", required=True) parser.add_argument("-m", "--message", dest="message", help="Message", required=True) args = parser.parse_args() username = args.username
class Adopta: def __init__(self): parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) (options, args) = parser.parse_args() if options.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.core = Core() self.followers = [] self.following = [] self.last_dm = None self.log = logging.getLogger('Server') self.start_login() def start_login(self): self.core.register_account( ACCOUNT.split('-')[0], ACCOUNT.split('-')[1], '') response = self.core.login(ACCOUNT) if response.code > 0: print "Login error:", response.errmsg return auth_obj = response.items if auth_obj.must_auth(): print "Please visit %s, authorize Turpial and type the pin returned" % auth_obj.url pin = self.user_input('Pin: ') self.core.authorize_oauth_token(ACCOUNT, pin) rtn = self.core.auth(ACCOUNT) if rtn.code > 0: print rtn.errmsg else: self.log.debug('Logged in with account %s' % ACCOUNT.split('-')[0]) self.main() def user_input(self, message, blank=False): while 1: text = raw_input(message) if text == '' and not blank: print "You can't leave this field blank" continue break return text def get_followers(self): response = self.core.get_followers(ACCOUNT, True) if response.code > 0: self.log.error("Error getting followers list:", response.errmsg) else: self.followers = response.items def get_following(self): response = self.core.get_following(ACCOUNT, True) if response.code > 0: self.log.error("Error getting following list:", response.errmsg) else: self.following = response.items def process_follow_back(self): temp = [] for item in self.followers: if item not in self.following: if len(temp) < MAX_FOLLOW: temp.append(item) else: break for item in temp: response = self.core.follow(ACCOUNT, str(item), by_id=True) if response.code > 0: self.log.error("Error following to %s: %s" % (item, response.errmsg)) else: self.log.debug("Follow back to %s" % item) self.following.append(item) def process_dms(self): response = self.core.get_column_statuses(ACCOUNT, ColumnType.DIRECTS, 200) if response.code > 0: self.log.error("Error fetching DMs: %s" % response.errmsg) else: for dm in response.items: msg_id = dm.id_ valid = self.validate_dm(dm) if not valid: continue via = ' (via @%s)' % dm.username text = dm.text length = len(text) + len(via) if length > 140: text = text[:len(text) - len(via)] message = text + via message.encode('utf-8') rtn = self.core.update_status(ACCOUNT, message) if rtn.code > 0: self.log.error("Error posting message '%s': %s" % (message, rtn.errmsg)) else: self.register_message(dm) def validate_dm(self, dm): # TODO: Search in database for msg_id, if exist then return False # otherwiser return True if len(Tweet.objects.filter(status_id=dm.id_)) > 0: return False else: return True def register_message(self, dm): # TODO: Add dm to database t = Tweet(status_id=dm.id_, username=dm.username, content=dm.text) t.save() pass def main(self): while True: try: # Processing followbacks self.get_followers() self.get_following() self.process_follow_back() # Processing DMs self.process_dms() time.sleep(POLLING_TIME * 60) except KeyboardInterrupt: break self.log.debug('Bye')
class CoreWorker(QThread): ready = pyqtSignal(object) status_updated = pyqtSignal(object, str) status_broadcasted = pyqtSignal(object) status_repeated = pyqtSignal(object, str, str, str) status_deleted = pyqtSignal(object, str, str, str) status_pushed_to_queue = pyqtSignal(str) status_poped_from_queue = pyqtSignal(object) status_deleted_from_queue = pyqtSignal() queue_cleared = pyqtSignal() status_posted_from_queue = pyqtSignal(object, str, str) message_deleted = pyqtSignal(object, str, str) message_sent = pyqtSignal(object, str) column_updated = pyqtSignal(object, tuple) account_saved = pyqtSignal() account_loaded = pyqtSignal() account_deleted = pyqtSignal() column_saved = pyqtSignal(str) column_deleted = pyqtSignal(str) status_marked_as_favorite = pyqtSignal(object, str, str, str) status_unmarked_as_favorite = pyqtSignal(object, str, str, str) fetched_user_profile = pyqtSignal(object, str) urls_shorted = pyqtSignal(object) media_uploaded = pyqtSignal(object) friends_list_updated = pyqtSignal() user_muted = pyqtSignal(str) user_unmuted = pyqtSignal(str) user_blocked = pyqtSignal(object) user_reported_as_spam = pyqtSignal(object) user_followed = pyqtSignal(object, str) user_unfollowed = pyqtSignal(object, str) exception_raised = pyqtSignal(object) status_from_conversation = pyqtSignal(object, str, str) fetched_profile_image = pyqtSignal(object) fetched_avatar = pyqtSignal(object, str) fetched_image_preview = pyqtSignal(object) cache_deleted = pyqtSignal() ERROR = -1 LOADING = 0 READY = 1 def __init__(self): QThread.__init__(self) self.queue = Queue.Queue() self.exit_ = False self.status = self.LOADING #self.core = Core() #self.queue_path = os.path.join(self.core.config.basedir, 'queue') #if not os.path.isfile(self.queue_path): # open(self.queue_path, 'w').close() self.core = None self.restart() #def __del__(self): # self.wait() def restart(self): self.register(self.login, (), self.__after_login, None) def add_friend(self, username): # FIXME: On libturpial friends = self.core.config.load_friends() friends.append(username) self.core.config.save_friends(friends) def remove_friend(self, username): # FIXME: On libturpial friends = self.core.config.load_friends() if username in friends: friends.remove(username) self.core.config.save_friends(friends) def __get_from_queue(self, index=0): lines = open(self.queue_path).readlines() if not lines: return None row = lines[index].strip() account_id, message = row.split("\1") del lines[index] open(self.queue_path, 'w').writelines(lines) status = Status() status.account_id = account_id status.text = message return status def __get_column_num_from_id(self, column_id): column_key = None for i in range(1, len(self.get_registered_columns()) + 1): column_num = "column%s" % i stored_id = self.core.config.read('Columns', column_num) if stored_id == column_id: column_key = column_num else: i += 1 return column_key #================================================================ # Core methods #================================================================ def login(self): self.core = Core() self.queue_path = os.path.join(self.core.config.basedir, 'queue') if not os.path.isfile(self.queue_path): open(self.queue_path, 'w').close() def get_default_browser(self): return self.core.get_default_browser() def get_update_interval(self): return self.core.get_update_interval() def get_statuses_per_column(self): return self.core.get_max_statuses_per_column() def get_minimize_on_close(self): return self.core.minimize_on_close() # FIXME: Implement support on libturpial def get_proxy_configuration(self): return self.core.config.read_section('Proxy') # FIXME: Implement support on libturpial def get_socket_timeout(self): return int(self.core.config.read('Advanced', 'socket-timeout')) def get_show_user_avatars(self): show_avatars = self.core.config.read('Advanced', 'show-user-avatars') return True if show_avatars == 'on' else False def get_update_interval_per_column(self, column_id): column_key = self.__get_column_num_from_id(column_id) key = "%s-update-interval" % column_key interval = self.core.config.read('Intervals', key) if not interval: # FIXME: Fix in libturpial config = self.core.config.read_all() if not config.has_key('Intervals'): config['Intervals'] = {key: 5} self.core.config.save(config) else: self.core.config.write('Intervals', key, 5) config = self.core.config.read_all() interval = "5" return int(interval) def set_update_interval_in_column(self, column_id, interval): column_key = self.__get_column_num_from_id(column_id) key = "%s-update-interval" % column_key self.core.config.write('Intervals', key, interval) return interval def get_show_notifications_in_column(self, column_id): column_key = self.__get_column_num_from_id(column_id) key = "%s-notifications" % column_key notifications = self.core.config.read('Notifications', key) if not notifications: # FIXME: Fix in libturpial config = self.core.config.read_all() if not config.has_key('Notifications'): config['Notifications'] = {} self.core.config.save(config) self.core.config.write('Notifications', key, 'on') notifications = 'on' if notifications == 'on': return True return False def set_show_notifications_in_column(self, column_id, value): column_key = self.__get_column_num_from_id(column_id) key = "%s-notifications" % column_key if value: notifications = 'on' else: notifications = 'off' self.core.config.write('Notifications', key, notifications) return value # FIXME: Fix this on libturpial def get_cache_size(self): total_size = 0 for account in self.get_all_accounts(): total_size += account.get_cache_size() return total_size # FIXME: Fix this on libturpial def delete_cache(self): for account in self.get_all_accounts(): account.delete_cache() def get_sound_on_login(self): sound_on_login = self.core.config.read('Sounds', 'login') if sound_on_login is None: self.core.config.write('Sounds', 'login', 'on') return True else: if sound_on_login == 'on': return True return False def get_sound_on_updates(self): sound_on_update = self.core.config.read('Sounds', 'updates') if sound_on_update is None: self.core.config.write('Sounds', 'updates', 'on') return True else: if sound_on_update == 'on': return True return False def get_notify_on_updates(self): try: notify_on_update = self.core.config.cfg.get('Notifications', 'updates', raw=True) if notify_on_update == 'on': return True return False except: config = self.read_config() config['Notifications']['on-updates'] = 'on' self.core.save_all_config(config) return True def get_notify_on_actions(self): try: notify_on_actions = self.core.config.cfg.get('Notifications', 'actions', raw=True) if notify_on_actions == 'on': return True return False except: config = self.read_config() config['Notifications']['actions'] = 'on' self.core.save_all_config(config) return True def get_queue_interval(self): try: queue_interval = self.core.config.cfg.get('General', 'queue-interval', raw=True) return int(queue_interval) except: config = self.read_config() config['General']['queue-interval'] = 30 self.core.save_all_config(config) return config['General']['queue-interval'] def read_config(self): config = {} # FIXME: Implemen this on libturpial for section in self.core.config.cfg.sections(): if not config.has_key(section): config[section] = {} for item in self.core.config.cfg.items(section, raw=True): for value in item: config[section][item[0]] = item[1] return config def update_config(self, new_config): self.core.save_all_config(new_config) def get_shorten_url_service(self): return self.core.get_shorten_url_service() def get_upload_media_service(self): return self.core.get_upload_media_service() def get_available_columns(self): return self.core.available_columns() def get_all_accounts(self): return self.core.registered_accounts() def get_all_columns(self): return self.core.all_columns() def get_registered_accounts(self): return self.core.registered_accounts() def get_available_short_url_services(self): return self.core.available_short_url_services() def get_available_upload_media_services(self): return self.core.available_upload_media_services() def get_registered_columns(self): i = 1 columns = [] while True: column_num = "column%s" % i column_id = self.core.config.read('Columns', column_num) if column_id: account_id = get_account_id_from(column_id) column_slug = get_column_slug_from(column_id) columns.append(Column(account_id, column_slug)) i += 1 else: break return columns def is_muted(self, username): return self.core.is_muted(username) def load_friends_list(self): return self.core.load_all_friends_list() def save_account(self, account): account_id = self.core.register_account(account) self.load_account(account_id, trigger_signal=False) self.__after_save_account() # FIXME: Remove this after implement this in libturpial def load_account(self, account_id, trigger_signal=True): if trigger_signal: self.register(self.core.accman.load, (account_id), self.__after_load_account) else: self.core.accman.load(account_id) self.__after_load_account() def delete_account(self, account_id): # FIXME: Implement try/except for col in self.get_registered_columns(): if col.account_id == account_id: self.delete_column(col.id_) self.core.unregister_account(str(account_id), True) self.__after_delete_account() def save_column(self, column_id): #FIXME: Hack to avoid the libturpial error saving config self.update_config(self.read_config()) reg_column_id = self.core.register_column(column_id) self.__after_save_column(reg_column_id) def delete_column(self, column_id): deleted_column = self.core.unregister_column(column_id) self.__after_delete_column(column_id) def get_column_statuses(self, column, last_id): count = self.core.get_max_statuses_per_column() self.register(self.core.get_column_statuses, (column.account_id, column.slug, count, last_id), self.__after_update_column, (column, count)) def update_status(self, account_id, message, in_reply_to_id=None): self.register(self.core.update_status, (account_id, message, in_reply_to_id), self.__after_update_status, account_id) def broadcast_status(self, accounts, message): self.register(self.core.broadcast_status, (accounts, message), self.__after_broadcast_status) def repeat_status(self, column_id, account_id, status_id): self.register(self.core.repeat_status, (account_id, status_id), self.__after_repeat_status, (column_id, account_id, status_id)) def delete_status(self, column_id, account_id, status_id): self.register(self.core.destroy_status, (account_id, status_id), self.__after_delete_status, (column_id, account_id, status_id)) def delete_direct_message(self, column_id, account_id, status_id): self.register(self.core.destroy_direct_message, (account_id, status_id), self.__after_delete_direct_message, (column_id, account_id)) def send_direct_message(self, account_id, username, message): self.register(self.core.send_direct_message, (account_id, username, message), self.__after_send_direct_message, account_id) def mark_status_as_favorite(self, column_id, account_id, status_id): self.register(self.core.mark_status_as_favorite, (account_id, status_id), self.__after_mark_status_as_favorite, (column_id, account_id, status_id)) def unmark_status_as_favorite(self, column_id, account_id, status_id): self.register(self.core.unmark_status_as_favorite, (account_id, status_id), self.__after_unmark_status_as_favorite, (column_id, account_id, status_id)) def get_user_profile(self, account_id, user_profile=None): self.register(self.core.get_user_profile, (account_id, user_profile), self.__after_get_user_profile, account_id) def short_urls(self, message): self.register(self.core.short_url_in_message, (message), self.__after_short_urls) def upload_media(self, account_id, filepath): self.register(self.core.upload_media, (account_id, filepath), self.__after_upload_media) def get_friends_list(self): self.register(self.core.get_all_friends_list, None, self.__after_get_friends_list) def mute(self, username): self.register(self.core.mute, username, self.__after_mute_user) def unmute(self, username): self.register(self.core.unmute, username, self.__after_unmute_user) def block(self, account_id, username): self.register(self.core.block, (account_id, username), self.__after_block_user) def report_as_spam(self, account_id, username): self.register(self.core.report_as_spam, (account_id, username), self.__after_report_user_as_spam) def follow(self, account_id, username): self.register(self.core.follow, (account_id, username), self.__after_follow_user, account_id) def unfollow(self, account_id, username): self.register(self.core.unfollow, (account_id, username), self.__after_unfollow_user, account_id) def get_status_from_conversation(self, account_id, status_id, column_id, status_root_id): self.register(self.core.get_single_status, (account_id, status_id), self.__after_get_status_from_conversation, (column_id, status_root_id)) def get_profile_image(self, account_id, username): self.register(self.core.get_profile_image, (account_id, username), self.__after_get_profile_image) def get_avatar_from_status(self, status): self.register(self.core.get_status_avatar, (status), self.__after_get_avatar_from_status, status.username) def get_image_preview(self, preview_service, url): self.register(preview_service.do_service, (url), self.__after_get_image_preview) def push_status_to_queue(self, account_id, message): fd = open(self.queue_path, 'a+') row = "%s\1%s\n" % (account_id, message) fd.write(row.encode('utf-8')) fd.close() self.__after_push_status_to_queue(account_id) def pop_status_from_queue(self): status = self.__get_from_queue() self.__after_pop_status_from_queue(status) def delete_status_from_queue(self, index=0): status = self.__get_from_queue(index) self.__after_delete_status_from_queue() def list_statuses_queue(self): statuses = [] lines = [] if os.path.exists(self.queue_path): lines = open(self.queue_path).readlines() for line in lines: account_id, message = line.strip().split("\1") status = Status() status.account_id = account_id status.text = message statuses.append(status) return statuses def clear_statuses_queue(self): open(self.queue_path, 'w').writelines([]) self.__after_clear_queue() def post_status_from_queue(self, account_id, message): self.register(self.core.update_status, (account_id, message), self.__after_post_status_from_queue, (account_id, message)) def delete_cache(self): self.register(self.core.delete_cache, None, self.__after_delete_cache) def list_filters(self): return self.core.list_filters() def save_filters(self, filters): self.core.save_filters(filters) def restore_config(self): self.core.delete_current_config() def get_window_size(self): try: size = self.core.config.cfg.get('Window', 'size', raw=True) window_size = int(size.split(',')[0]), int(size.split(',')[1]) return window_size except: config = self.read_config() config['Window']['size'] = "320,480" self.core.save_all_config(config) return config['Window']['size'] def set_window_size(self, width, height): window_size = "%s,%s" % (width, height) #FIXME: Hack to avoid the libturpial error saving config self.update_config(self.read_config()) self.core.config.write('Window', 'size', window_size) #================================================================ # Callbacks #================================================================ def __after_login(self, response): self.ready.emit(response) def __after_save_account(self): self.account_saved.emit() def __after_load_account(self, response=None): self.account_loaded.emit() def __after_delete_account(self): self.account_deleted.emit() def __after_save_column(self, column_id): self.column_saved.emit(column_id) def __after_delete_column(self, column_id): self.column_deleted.emit(column_id) def __after_update_column(self, response, data): self.column_updated.emit(response, data) def __after_update_status(self, response, account_id): self.status_updated.emit(response, account_id) def __after_broadcast_status(self, response): self.status_broadcasted.emit(response) def __after_repeat_status(self, response, args): column_id = args[0] account_id = args[1] status_id = args[2] self.status_repeated.emit(response, column_id, account_id, status_id) def __after_delete_status(self, response, args): column_id = args[0] account_id = args[1] status_id = args[2] self.status_deleted.emit(response, column_id, account_id, status_id) def __after_delete_direct_message(self, response, args): column_id = args[0] account_id = args[1] self.message_deleted.emit(response, column_id, account_id) def __after_send_direct_message(self, response, account_id): self.message_sent.emit(response, account_id) def __after_mark_status_as_favorite(self, response, args): column_id = args[0] account_id = args[1] status_id = args[2] self.status_marked_as_favorite.emit(response, column_id, account_id, status_id) def __after_unmark_status_as_favorite(self, response, args): column_id = args[0] account_id = args[1] status_id = args[2] self.status_unmarked_as_favorite.emit(response, column_id, account_id, status_id) def __after_get_user_profile(self, response, account_id): self.fetched_user_profile.emit(response, account_id) def __after_short_urls(self, response): self.urls_shorted.emit(response) def __after_upload_media(self, response): self.media_uploaded.emit(response) def __after_get_friends_list(self, response): self.friends_list_updated.emit() def __after_mute_user(self, response): self.user_muted.emit(response) def __after_unmute_user(self, response): self.user_unmuted.emit(response) def __after_block_user(self, response): self.user_blocked.emit(response) def __after_report_user_as_spam(self, response): self.user_reported_as_spam.emit(response) def __after_follow_user(self, response, account_id): self.user_followed.emit(response, account_id) def __after_unfollow_user(self, response, account_id): self.user_unfollowed.emit(response, account_id) def __after_get_status_from_conversation(self, response, args): column_id = args[0] status_root_id = args[1] self.status_from_conversation.emit(response, column_id, status_root_id) def __after_get_profile_image(self, response): self.fetched_profile_image.emit(response) def __after_get_avatar_from_status(self, response, args): username = args self.fetched_avatar.emit(response, username) def __after_get_image_preview(self, response): self.fetched_image_preview.emit(response) def __after_push_status_to_queue(self, account_id): self.status_pushed_to_queue.emit(account_id) def __after_pop_status_from_queue(self, status): self.status_poped_from_queue.emit(status) def __after_delete_status_from_queue(self): self.status_deleted_from_queue.emit() def __after_clear_queue(self): self.queue_cleared.emit() def __after_post_status_from_queue(self, response, args): account_id = args[0] message = args[1] self.status_posted_from_queue.emit(response, account_id, message) def __after_delete_cache(self): self.cache_deleted.emit() #================================================================ # Worker methods #================================================================ def register(self, funct, args, callback, user_data=None): self.queue.put((funct, args, callback, user_data)) def quit(self): self.exit_ = True def run(self): while not self.exit_: try: req = self.queue.get(True, 0.3) except Queue.Empty: continue except: continue (funct, args, callback, user_data) = req try: if type(args) == tuple: rtn = funct(*args) elif args: rtn = funct(args) else: rtn = funct() except Exception, e: #self.exception_raised.emit(e) #continue rtn = e if callback: if user_data: callback(rtn, user_data) else: callback(rtn)
class Turpial(cmd.Cmd): def __init__(self): cmd.Cmd.__init__(self) parser = OptionParser() parser.add_option('-d', '--debug', dest='debug', action='store_true', help='show debug info in shell during execution', default=False) parser.add_option('-m', '--command', dest='command', action='store_true', help='execute a single command', default=False) parser.add_option('-c', '--clean', dest='clean', action='store_true', help='clean all bytecodes', default=False) parser.add_option('-s', '--save-credentials', dest='save', action='store_true', help='save user credentials', default=False) parser.add_option('--version', dest='version', action='store_true', help='show the version of Turpial and exit', default=False) (options, args) = parser.parse_args() if options.debug or options.clean: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) self.log = logging.getLogger('Turpial:Cmd') #self.config = None self.prompt = 'turpial> ' self.intro = '\n'.join(INTRO) self.core = Core() #self.app_cfg = ConfigApp() #self.version = self.app_cfg.read('App', 'version') if options.clean: clean_bytecodes(__file__, self.log) sys.exit(0) if options.version: print "turpial (cmd) v%s" % self.version print "libturpial v%s" % libturpial_ver print "python v%X" % sys.hexversion sys.exit(0) self.account = None try: self.cmdloop() except KeyboardInterrupt: self.do_exit() except EOFError: self.do_exit() def __validate_index(self, index, array, blank=False): try: a = array[int(index)] return True except IndexError: return False except ValueError: if blank and index == '': return True elif not blank and index == '': return False elif blank and index != '': return False except TypeError: if index is None: return False def __validate_accounts(self): if len(self.core.list_accounts()) > 0: return True print "You don't have any registered account. Run 'account add' command" return False def __validate_default_account(self): if self.account: return True print "You don't have a default account. Run 'account change' command" return False def __validate_arguments(self, arg_array, value): if value in arg_array: return True else: print 'Invalid Argument' return False def __build_message_menu(self): text = raw_input('Message: ') if text == '': print 'You must write something to post' return None if len(text) > 140: trunc = raw_input ('Your message has more than 140 characters. Do you want truncate it? [Y/n]: ') if trunc.lower() == 'y' or trunc == '': return text[:140] return None return text def __build_accounts_menu(self, _all=False): if len(self.core.list_accounts()) == 1: return self.core.list_accounts()[0] index = None while 1: accounts = self.__show_accounts() if _all: index = raw_input('Select account (or Enter for all): ') else: index = raw_input('Select account: ') if not self.__validate_index(index, accounts, _all): print "Invalid account" else: break if index == '': return '' else: return accounts[int(index)] def __build_password_menu(self, account): passwd = None while 1: passwd = getpass.unix_getpass("Password for '%s' in '%s': " % ( account.split('-')[0], account.split('-')[1])) if passwd: return passwd else: print "Password can't be blank" def __build_change_account_menu(self): if len(self.core.list_accounts()) == 1: if self.account: print "Your unique account is already your default" else: self.__add_first_account_as_default() elif len(self.core.list_accounts()) > 1: while 1: accounts = self.__show_accounts() index = raw_input('Select you new default account (or Enter for keep current): ') if index == '': print "Default account remain with no changes" return True if not self.__validate_index(index, accounts): print "Invalid account" else: break self.account = accounts[int(index)] print "Set %s in %s as your new default account" % ( self.account.split('-')[0], self.account.split('-')[1]) def __build_protocols_menu(self): index = None protocols = self.core.list_protocols() while 1: print "Available protocols:" for i in range(len(protocols)): print "[%i] %s" % (i, protocols[i]) index = raw_input('Select protocol: ') if not self.__validate_index(index, protocols): print "Invalid protocol" else: break return protocols[int(index)] def __build_confirm_menu(self, message): confirm = raw_input(message + ' [y/N]: ') if confirm.lower() == 'y': return True else: return False def __user_input(self, message, blank=False): while 1: text = raw_input(message) if text == '' and not blank: print "You can't leave this field blank" continue break return text def __add_first_account_as_default(self): self.account = self.core.list_accounts()[0] print "Selected account %s in %s as default (*)" % ( self.account.split('-')[0], self.account.split('-')[1]) def __show_accounts(self): if len(self.core.list_accounts()) == 0: print "There are no registered accounts" return accounts = [] print "Available accounts:" for acc in self.core.list_accounts(): ch = '' if acc == self.account: ch = ' (*)' print "[%i] %s - %s%s" % (len(accounts), acc.split('-')[0], acc.split('-')[1], ch) accounts.append(acc) return accounts def __show_profiles(self, people): if not statuses: print "There are no profiles to show" return if people.code > 0: print people.errmsg return for p in people: protected = '<protected>' if p.protected else '' following = '<following>' if p.following else '' header = "@%s (%s) %s %s" % (p.username, p.fullname, following, protected) print header print '-' * len(header) print "URL: %s" % p.url print "Location: %s" % p.location print "Bio: %s" % p.bio if p.last_update: print "Last: %s" % p.last_update print '' def __show_statuses(self, statuses): if not statuses: print "There are no statuses to show" return if statuses.code > 0: print statuses.errmsg return count = 1 for status in statuses: text = status.text.replace('\n', ' ') inreply = '' client = '' if status.in_reply_to_user: inreply = ' in reply to %s' % status.in_reply_to_user if status.source: client = ' from %s' % status.source print "%d. @%s: %s (id: %s)" % (count, status.username, text, status.id_) print "%s%s%s" % (status.datetime, client, inreply) if status.reposted_by: users = '' for u in status.reposted_by: users += u + ' ' print 'Retweeted by %s' % status.reposted_by print count += 1 def __process_login(self, acc): if not self.core.has_stored_passwd(acc): passwd = self.__build_password_menu(acc) username = acc.split('-')[0] protocol = acc.split('-')[1] self.core.register_account(username, protocol, passwd) rtn = self.core.login(acc) if rtn.code > 0: print rtn.errmsg return auth_obj = rtn.items if auth_obj.must_auth(): print "Please visit %s, authorize Turpial and type the pin returned" % auth_obj.url pin = self.__user_input('Pin: ') self.core.authorize_oauth_token(acc, pin) rtn = self.core.auth(acc) if rtn.code > 0: print rtn.errmsg else: print 'Logged in with account %s' % acc.split('-')[0] def default(self, line): print '\n'.join(['Command not found.', INTRO[1], INTRO[2]]) def emptyline(self): pass def do_account(self, arg): if not self.__validate_arguments(ARGUMENTS['account'], arg): self.help_account(False) return False if arg == 'add': username = raw_input('Username: '******'Password: '******'Remember password') protocol = self.__build_protocols_menu() acc_id = self.core.register_account(username, protocol, password, remember) print 'Account added' if len(self.core.list_accounts()) == 1: self.__add_first_account_as_default() elif arg == 'edit': if not self.__validate_default_account(): return False password = getpass.unix_getpass('New Password: '******'-')[0] protocol = self.account.split('-')[1] remember = self.__build_confirm_menu('Remember password') self.core.register_account(username, protocol, password, remember) print 'Account edited' elif arg == 'delete': if not self.__validate_accounts(): return False account = self.__build_accounts_menu() conf = self.__build_confirm_menu('Do you want to delete account %s?' % account) if not conf: print 'Command cancelled' return False del_all = self.__build_confirm_menu('Do you want to delete all data?') self.core.unregister_account(account, del_all) if self.account == account: self.account = None print 'Account deleted' elif arg == 'change': if not self.__validate_accounts(): return False self.__build_change_account_menu() elif arg == 'list': self.__show_accounts() elif arg == 'default': print "Your default account is %s in %s" % ( self.account.split('-')[0], self.account.split('-')[1]) def help_account(self, desc=True): text = 'Manage user accounts' if not desc: text = '' print '\n'.join([text, 'Usage: account <arg>\n', 'Possible arguments are:', ' add:\t\t Add a new user account', ' edit:\t\t Edit an existing user account', ' delete:\t Delete a user account', ' list:\t\t Show all registered accounts', ' default:\t Show default account', ]) def do_login(self, arg): if not self.__validate_accounts(): return False _all = True if len(self.core.list_accounts()) > 1: _all = self.__build_confirm_menu('Do you want to login with all available accounts?') if _all: work = False for acc in self.core.list_accounts(): if self.core.is_account_logged_in(acc): continue work = True self.__process_login(acc) if not work: print "Already logged in with all available accounts" else: acc = self.__build_accounts_menu() self.__process_login(acc) def help_login(self): print 'Login with one or many accounts' def do_profile(self, arg): if not self.__validate_arguments(ARGUMENTS['profile'], arg): self.help_profile(False) return False if not self.__validate_default_account(): return False if arg == 'me': profile = self.core.get_own_profile(self.account) if profile is None: print 'You must be logged in' else: self.__show_profiles(profile) elif arg == 'user': username = raw_input('Type the username: '******'': print 'You must specify a username' return False profile = self.core.get_user_profile(self.account, username) if profile is None: print 'You must be logged in' else: self.__show_profiles(profile) elif arg == 'update': args = {} name = raw_input('Type your name (ENTER for none): ') bio = raw_input('Type your bio (ENTER for none): ') url = raw_input('Type your url (ENTER for none): ') location = raw_input('Type your location (ENTER for none): ') if name != '': args['name'] = name if bio != '': args['description'] = bio if url != '': args['url'] = url if location != '': args['location'] = location result = self.core.update_profile(self.account, args) if result.code > 0: print result.errmsg else: print 'Profile updated' def help_profile(self, desc=True): text = 'Manage user profile' if not desc: text = '' print '\n'.join([text, 'Usage: profile <arg>\n', 'Possible arguments are:', ' me:\t\t Show own profile', ' user:\t\t Show profile for a specific user', ' update:\t Update own profile', ]) def do_status(self, arg): if not self.__validate_default_account(): return False if not self.__validate_arguments(ARGUMENTS['status'], arg): self.help_status(False) return False if arg == 'update': message = self.__build_message_menu() if not message: print 'You must to write something' return False broadcast = self.__build_confirm_menu('Do you want to post the message in all available accounts?') if broadcast: for acc in self.core.list_accounts(): rtn = self.core.update_status(acc, message) if rtn.code > 0: print rtn.errmsg else: print 'Message posted in account %s' % acc.split('-')[0] else: rtn = self.core.update_status(self.account, message) if rtn.code > 0: print rtn.errmsg else: print 'Message posted in account %s' % self.account.split('-')[0] elif arg == 'reply': reply_id = raw_input('Status ID: ') if reply_id == '': print "You must specify a valid id" return False message = self.__build_message_menu() if not message: print 'You must to write something' return False rtn = self.core.update_status(self.account, message, reply_id) if rtn.code > 0: print rtn.errmsg else: print 'Reply posted in account %s' % self.account.split('-')[0] elif arg == 'delete': status_id = raw_input('Status ID: ') if status_id == '': print "You must specify a valid id" return False rtn = self.core.destroy_status(self.account, status_id) if rtn.code > 0: print rtn.errmsg else: print 'Status deleted' elif arg == 'conversation': status_id = raw_input('Status ID: ') if status_id == '': print "You must specify a valid id" return False rtn = self.core.get_conversation(self.account, status_id) if rtn.code > 0: print rtn.errmsg else: self.__show_statuses(rtn) def help_status(self, desc=True): text = 'Manage statuses for each protocol' if not desc: text = '' print '\n'.join([text, 'Usage: status <arg>\n', 'Possible arguments are:', ' update:\t Update status ', ' delete:\t Delete status', ' conversation:\t Show related tweets as conversation', ]) def do_column(self, arg): if not self.__validate_default_account(): return False lists = self.core.list_columns(self.account) if arg == '': self.help_column(False) elif arg == 'list': if len(lists) == 0: print "No column available. Maybe you need to login" return False print "Available columns:" for li in lists: print " %s" % li elif arg == 'public': rtn = self.core.get_public_timeline(self.account) self.__show_statuses(rtn) else: if len(lists) == 0: print "No column available. Maybe you need to login" return False if arg in lists: rtn = self.core.get_column_statuses(self.account, arg) self.__show_statuses(rtn) else: print "Invalid column '%s'" % arg def help_column(self, desc=True): text = 'Show user columns' if not desc: text = '' print '\n'.join([text, 'Usage: column <arg>\n', 'Possible arguments are:', ' list:\t\t List all available columns for that account', ' timeline:\t Show timeline', ' replies:\t Show replies', ' directs:\t Show directs messages', ' favorites:\t Show statuses marked as favorites', ' public:\t Show public timeline', ' <list_id>:\t Show statuses for the user list with id <list_id>', ]) def do_friend(self, arg): if not self.__validate_default_account(): return False if not self.__validate_arguments(ARGUMENTS['friend'], arg): self.help_friend(False) return False if arg == 'list': friends = self.core.get_friends(self.account) if friends.code > 0: print rtn.errmsg return False if len(friends) == 0: print "Hey! What's wrong with you? You've no friends" return False print "Friends list:" for fn in friends: print "+ @%s (%s)" % (fn.username, fn.fullname) elif arg == 'follow': username = raw_input('Username: '******'': print "You must specify a valid user" return False rtn = self.core.follow(self.account, username) if rtn.code > 0: print rtn.errmsg return False print "Following %s" % user elif arg == 'unfollow': username = raw_input('Username: '******'': print "You must specify a valid user" return False rtn = self.core.unfollow(self.account, username) if rtn.code > 0: print rtn.errmsg return False print "Not following %s" % user elif arg == 'block': username = raw_input('Username: '******'': print "You must specify a valid user" return False rtn = self.core.block(self.account, username) if rtn.code > 0: print rtn.errmsg return False print "Blocking user %s" % username elif arg == 'unblock': username = raw_input('Username: '******'': print "You must specify a valid user" return False rtn = self.core.unblock(self.account, username) if rtn.code > 0: print rtn.errmsg return False print "Unblocking user %s" % username elif arg == 'spammer': username = raw_input('Username: '******'': print "You must specify a valid user" return False rtn = self.core.report_spam(self.account, username) if rtn.code > 0: print rtn.errmsg return False print "Reporting user %s as spammer" % username elif arg == 'check': username = raw_input('Username: '******'': print "You must specify a valid user" return False rtn = self.core.is_friend(self.account, username) if rtn.code > 0: print rtn.errmsg return False if rtn.items: print "%s is following you" % username else: print "%s is not following you" % username def help_friend(self, desc=True): text = 'Manage user friends' if not desc: text = '' print '\n'.join([text, 'Usage: friend <arg>\n', 'Possible arguments are:', ' list:\t\t List all friends', ' follow:\t Follow user', ' unfollow:\t Unfollow friend', ' block:\t Block user', ' unblock:\t Unblock user', ' spammer:\t Report user as spammer', ' check:\t Verify if certain user is following you', ]) def do_direct(self, arg): if not self.__validate_default_account(): return False if not self.__validate_arguments(ARGUMENTS['direct'], arg): self.help_direct(False) return False if arg == 'send': username = raw_input('Username: '******'': print "You must specify a valid user" return False message = self.__build_message_menu() if not message: print 'You must to write something' return False rtn = self.core.send_direct(self.account, username, message) if rtn.code > 0: print rtn.errmsg else: print 'Direct message sent' elif arg == 'delete': dm_id = raw_input('Direct message ID: ') if dm_id == '': print "You must specify a valid id" return False rtn = self.core.destroy_direct(self.account, dm_id) if rtn.code > 0: print rtn.errmsg else: print 'Direct message deleted' def help_direct(self, desc=True): text = 'Manage user direct messages' if not desc: text = '' print '\n'.join([text, 'Usage: direct <arg>\n', 'Possible arguments are:', ' send:\t\t Send direct message', ' delete:\t Destroy direct message', ]) def do_favorite(self, arg): if not self.__validate_default_account(): return False if not self.__validate_arguments(ARGUMENTS['favorite'], arg): self.help_status(False) return False if arg == 'mark': status_id = raw_input('Status ID: ') if status_id == '': print "You must specify a valid id" return False rtn = self.core.mark_favorite(self.account, status_id) if rtn.code > 0: print rtn.errmsg else: print 'Status marked as favorite' elif arg == 'unmark': status_id = raw_input('Status ID: ') if status_id == '': print "You must specify a valid id" return False rtn = self.core.unmark_favorite(self.account, status_id) if rtn.code > 0: print rtn.errmsg else: print 'Status unmarked as favorite' def help_favorite(self, desc=True): text = 'Manage favorite marks of statuses' if not desc: text = '' print '\n'.join([text, 'Usage: direct <arg>\n', 'Possible arguments are:', ' mark:\t\t Mark a status as favorite', ' unmark:\t Remove favorite mark from a status', ]) def do_search(self, arg=None): if not self.__validate_default_account(): return False if arg: self.help_search() return False query = raw_input('Type what you want to search for: ') rtn = self.core.search(self.account, query) self.__show_statuses(rtn) def help_search(self): print 'Search for a pattern' def do_trends(self, arg=None): if not self.__validate_default_account(): return False if arg: self.help_trends() return False trends = self.core.trends(self.account) if trends.code > 0: print trends.errmsg return False for trend in trends: print trend.title print "=" * len(trend.title) for topic in trend.items: promoted = '' if topic.promoted: promoted = '*' print "%s%s |" % (topic.name, promoted), print def help_trends(self): print 'Show global and local trends' def do_EOF(self, line): return self.do_exit('') def do_exit(self, line=None): print self.log.debug('Bye') return True def help_help(self): print 'Show help. Dah!' def help_exit(self): print 'Close the application' def help_EOF(self): print 'Close the application' def show_shorten_url(self, text): print "URL Cortada:", text