コード例 #1
0
 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)
コード例 #2
0
ファイル: main.py プロジェクト: satanas/twitdirect
    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()
コード例 #3
0
ファイル: turpial-cmd.py プロジェクト: satanas/turpial-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()
コード例 #4
0
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)
コード例 #5
0
ファイル: main.py プロジェクト: arepadev/twitdirect
 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()
コード例 #6
0
    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)
コード例 #7
0
# * 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():
コード例 #8
0
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
コード例 #9
0
ファイル: twitrss.py プロジェクト: arepadev/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()
コード例 #10
0
ファイル: twitrss.py プロジェクト: arepadev/twitrss
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')
コード例 #11
0
#!/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)
コード例 #12
0
ファイル: send_tweet.py プロジェクト: Bouska/libturpial
#!/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)
コード例 #13
0
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')
コード例 #14
0
ファイル: worker.py プロジェクト: Bouska/Turpial
 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()
コード例 #15
0
ファイル: twitbackup.py プロジェクト: satanas/twitbackup
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)
コード例 #16
0
ファイル: main.py プロジェクト: arepadev/twitdirect
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')
コード例 #17
0
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
コード例 #18
0
    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()
コード例 #19
0
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
コード例 #20
0
ファイル: main.py プロジェクト: satanas/twitdirect
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')
コード例 #21
0
ファイル: worker.py プロジェクト: Bouska/Turpial
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)
コード例 #22
0
ファイル: turpial-cmd.py プロジェクト: satanas/turpial-cmd
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