mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2025-08-28 10:49:22 +00:00
Compare commits
21 Commits
snapshot10
...
snapshot11
Author | SHA1 | Date | |
---|---|---|---|
4c1cad7f61 | |||
fffd98e09e | |||
a1a084bfda | |||
85e575386e | |||
2c64805eec | |||
6f2e439ddc | |||
7e42a096a5 | |||
9d2cf05a41 | |||
d7c095173d | |||
36ba6eca92 | |||
b6fa131999 | |||
c85c478595 | |||
![]() |
74e020c090 | ||
40105f37ed | |||
ca3f8779b8 | |||
a6a651d6f7 | |||
7748b4bb5d | |||
01a6c65c82 | |||
211d43aa30 | |||
c716f4aa96 | |||
9fd9d2a120 |
@@ -46,14 +46,14 @@ install:
|
|||||||
|
|
||||||
# Upgrade to the latest version of pip to avoid it displaying warnings
|
# Upgrade to the latest version of pip to avoid it displaying warnings
|
||||||
# about it being out of date.
|
# about it being out of date.
|
||||||
- "python -m pip install --upgrade pip"
|
- "python -m pip install --upgrade pip setuptools"
|
||||||
|
|
||||||
# Install the build dependencies of the project. If some dependencies contain
|
# Install the build dependencies of the project. If some dependencies contain
|
||||||
# compiled extensions and are not provided as pre-built wheel packages,
|
# compiled extensions and are not provided as pre-built wheel packages,
|
||||||
# pip will build them from source using the MSVC compiler matching the
|
# pip will build them from source using the MSVC compiler matching the
|
||||||
# target Python version and architecture
|
# target Python version and architecture
|
||||||
- "%CMD_IN_ENV% pip install -r requirements.txt"
|
- "%CMD_IN_ENV% pip install -r requirements.txt"
|
||||||
- "%CMD_IN_ENV% pip install pyenchant"
|
- "%CMD_IN_ENV% pip install pyenchant py2exe_py2"
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
# Build documentation at first, so setup.py won't fail when copying everything.
|
# Build documentation at first, so setup.py won't fail when copying everything.
|
||||||
|
@@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
## changes in this version
|
## changes in this version
|
||||||
|
|
||||||
|
* When adding or removing an user from a list, it is possible to press enter in the focused list instead of having to search for the "add" or "delete" button.
|
||||||
|
* Quoted and long tweets are displayed properly in the sent tweets buffer after being send. ([#253](https://github.com/manuelcortez/TWBlue/issues/253))
|
||||||
|
* Fixed an issue that was making the list manager keystroke unable to be shown in the keystroke editor. Now the keystroke is listed properly. ([#260](https://github.com/manuelcortez/TWBlue/issues/260))
|
||||||
|
* The volume slider, located in the account settings of TWBlue, now should decrease and increase value properly when up and down arrows are pressed. Before it was doing it in inverted order. ([#261](https://github.com/manuelcortez/TWBlue/issues/261))
|
||||||
|
* autoreading has been redesigned to work in a similar way for almost all buffers. Needs testing. ([#221](https://github.com/manuelcortez/TWBlue/issues/221))
|
||||||
|
* When displaying tweets or direct messages, a new field has been added to show the date when the item has been posted to Twitter.
|
||||||
|
* Added support for deleting direct messages by using the new Twitter API methods.
|
||||||
|
* When quoting a retweet, the quote will be made to the original tweet instead of the retweet.
|
||||||
* If the sent direct messages buffer is hidden, TWBlue should keep loading everything as expected. ([#246](https://github.com/manuelcortez/TWBlue/issues/246))
|
* If the sent direct messages buffer is hidden, TWBlue should keep loading everything as expected. ([#246](https://github.com/manuelcortez/TWBlue/issues/246))
|
||||||
* There is a new soundpack, called FreakyBlue (Thanks to [Andre Louis](https://twitter.com/FreakyFwoof)) as a new option in TWBlue. This pack can be the default in the next stable, so users can take a look and share their opinion in snapshot versions. ([#247](https://github.com/manuelcortez/TWBlue/issues/247))
|
* There is a new soundpack, called FreakyBlue (Thanks to [Andre Louis](https://twitter.com/FreakyFwoof)) as a new option in TWBlue. This pack can be the default in the next stable, so users can take a look and share their opinion in snapshot versions. ([#247](https://github.com/manuelcortez/TWBlue/issues/247))
|
||||||
* There is a new option in the help menu that allows you to visit the soundpacks section in the TWBlue website. ([#247](https://github.com/manuelcortez/TWBlue/issues/247))
|
* There is a new option in the help menu that allows you to visit the soundpacks section in the TWBlue website. ([#247](https://github.com/manuelcortez/TWBlue/issues/247))
|
||||||
@@ -10,7 +18,7 @@
|
|||||||
* When there are no more items to retrieve in direct messages and people buffers, a message will announce it.
|
* When there are no more items to retrieve in direct messages and people buffers, a message will announce it.
|
||||||
* Fixed an issue reported by some users that was making them unable to load more items in their direct messages.
|
* Fixed an issue reported by some users that was making them unable to load more items in their direct messages.
|
||||||
* It is possible to add a tweet to the likes buffer from the menu bar again.
|
* It is possible to add a tweet to the likes buffer from the menu bar again.
|
||||||
* Tweets, replies and retweets will be added to sent tweets right after being posted in the Twitter.
|
* Tweets, replies and retweets will be added to sent tweets right after being posted in Twitter.
|
||||||
* Extended Tweets should be displayed properly in list buffers.
|
* Extended Tweets should be displayed properly in list buffers.
|
||||||
|
|
||||||
## Changes in version 0.94
|
## Changes in version 0.94
|
||||||
@@ -21,14 +29,14 @@
|
|||||||
* The new method does not allow direct messages to be processed in real time. Direct messages will be updated periodically.
|
* The new method does not allow direct messages to be processed in real time. Direct messages will be updated periodically.
|
||||||
* After august 16 or when streaming is disabled, the events buffer will no longer be created in TWBlue.
|
* After august 16 or when streaming is disabled, the events buffer will no longer be created in TWBlue.
|
||||||
* You can configure frequency for buffer updates in TWBlue. By default, TWBlue will update all buffers every 2 minutes, but you can change this setting in the global settings dialog. ([#223](https://github.com/manuelcortez/TWBlue/issues/223))
|
* You can configure frequency for buffer updates in TWBlue. By default, TWBlue will update all buffers every 2 minutes, but you can change this setting in the global settings dialog. ([#223](https://github.com/manuelcortez/TWBlue/issues/223))
|
||||||
* Added a new tab called feedback, in the account settings dialog. This tab allows you to control wether automatic speech or Braille feedbak in certain events (mentions and direct messages received) is enabled. Take into account that this option will take preference over automatic reading of buffers and any kind of automatic output. ([#203](https://github.com/manuelcortez/TWBlue/issues/203))
|
* Added a new tab called feedback, in the account settings dialog. This tab allows you to control whether automatic speech or Braille feedbak in certain events (mentions and direct messages received) is enabled. Take into account that this option will take preference over automatic reading of buffers and any kind of automatic output. ([#203](https://github.com/manuelcortez/TWBlue/issues/203))
|
||||||
* The spell checking dialog now has access keys defined for the most important actions. ([#211](https://github.com/manuelcortez/TWBlue/issues/211))
|
* The spell checking dialog now has access keys defined for the most important actions. ([#211](https://github.com/manuelcortez/TWBlue/issues/211))
|
||||||
* TWBlue now Uses WXPython 4.0.1. This will allow us to migrate all important components to Python 3 in the future. ([#207](https://github.com/manuelcortez/TWBlue/issues/207))
|
* TWBlue now Uses WXPython 4.0.1. This will allow us to migrate all important components to Python 3 in the future. ([#207](https://github.com/manuelcortez/TWBlue/issues/207))
|
||||||
* When you quote a Tweet, if the original tweet was posted with Twishort, TWBlue should display properly the quoted tweet. Before it was displaying the original tweet only. ([#206](https://github.com/manuelcortez/TWBlue/issues/206))
|
* When you quote a Tweet, if the original tweet was posted with Twishort, TWBlue should display properly the quoted tweet. Before it was displaying the original tweet only. ([#206](https://github.com/manuelcortez/TWBlue/issues/206))
|
||||||
* It is possible to filter by retweets, quotes and replies when creating a new filter.
|
* It is possible to filter by retweets, quotes and replies when creating a new filter.
|
||||||
* Added support for playing youtube Links directly from the client. ([#94](https://github.com/manuelcortez/TWBlue/issues/94))
|
* Added support for playing youtube Links directly from the client. ([#94](https://github.com/manuelcortez/TWBlue/issues/94))
|
||||||
* Replaced Bass with libVLC for playing URL streams.
|
* Replaced Bass with libVLC for playing URL streams.
|
||||||
* the checkbox for indicating wether TWBlue will include everyone in a reply or not, will be unchecked by default.
|
* the checkbox for indicating whether TWBlue will include everyone in a reply or not, will be unchecked by default.
|
||||||
* You can request TWBlue to save the state for two checkboxes: Long tweet and mention all, from the global settings dialogue.
|
* You can request TWBlue to save the state for two checkboxes: Long tweet and mention all, from the global settings dialogue.
|
||||||
* For windows 10 users, some keystrokes in the invisible user interface have been changed or merged:
|
* For windows 10 users, some keystrokes in the invisible user interface have been changed or merged:
|
||||||
* control+Windows+alt+F will be used for toggling between adding and removing a tweet to user's likes. This function will execute the needed action based in the current status for the focused tweet.
|
* control+Windows+alt+F will be used for toggling between adding and removing a tweet to user's likes. This function will execute the needed action based in the current status for the focused tweet.
|
||||||
|
@@ -22,4 +22,5 @@ urllib3
|
|||||||
youtube-dl
|
youtube-dl
|
||||||
python-vlc
|
python-vlc
|
||||||
pywin32
|
pywin32
|
||||||
py2exe_py2
|
certifi
|
||||||
|
backports.functools_lru_cache
|
||||||
|
@@ -8,7 +8,7 @@ if snapshot == False:
|
|||||||
update_url = 'https://twblue.es/updates/stable.php'
|
update_url = 'https://twblue.es/updates/stable.php'
|
||||||
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/stable.json'
|
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/stable.json'
|
||||||
else:
|
else:
|
||||||
version = "9"
|
version = "11"
|
||||||
update_url = 'https://twblue.es/updates/snapshot.php'
|
update_url = 'https://twblue.es/updates/snapshot.php'
|
||||||
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/snapshots.json'
|
mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/snapshots.json'
|
||||||
authors = [u"Manuel Cortéz", u"José Manuel Delicado"]
|
authors = [u"Manuel Cortéz", u"José Manuel Delicado"]
|
||||||
|
7
src/controller/buffers/__init__.py
Normal file
7
src/controller/buffers/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
""" this package contains logic related to buffers. A buffer is a virtual representation of a group of items retrieved through the Social network API'S.
|
||||||
|
Ideally, new social networks added to TWBlue will have its own "buffers", and these buffers should be defined within this package, following the Twitter example.
|
||||||
|
Currently, the package contains the following modules:
|
||||||
|
* baseBuffers: Define a set of functions and structure to be expected in all buffers. New buffers should inherit its classes from one of the classes present here.
|
||||||
|
* twitterBuffers: All other code, specific to Twitter.
|
||||||
|
"""
|
201
src/controller/buffers/baseBuffers.py
Normal file
201
src/controller/buffers/baseBuffers.py
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
""" Common logic to all buffers in TWBlue."""
|
||||||
|
import logging
|
||||||
|
import wx
|
||||||
|
import output
|
||||||
|
import config
|
||||||
|
import sound
|
||||||
|
import widgetUtils
|
||||||
|
from pubsub import pub
|
||||||
|
from wxUI import buffers
|
||||||
|
|
||||||
|
log = logging.getLogger("controller.buffers.baseBuffers")
|
||||||
|
|
||||||
|
def _items_exist(function):
|
||||||
|
""" A decorator to execute a function only if the selected buffer contains at least one item."""
|
||||||
|
def function_(self, *args, **kwargs):
|
||||||
|
if self.buffer.list.get_count() > 0:
|
||||||
|
function(self, *args, **kwargs)
|
||||||
|
return function_
|
||||||
|
|
||||||
|
class buffer(object):
|
||||||
|
""" A basic buffer object. This should be the base class for all other derived buffers."""
|
||||||
|
|
||||||
|
def __init__(self, parent=None, function=None, session=None, *args, **kwargs):
|
||||||
|
"""Inits the main controller for this buffer:
|
||||||
|
@ parent wx.Treebook object: Container where we will put this buffer.
|
||||||
|
@ function str or None: function to be called periodically and update items on this buffer.
|
||||||
|
@ session sessionmanager.session object or None: Session handler for settings, database and data access.
|
||||||
|
"""
|
||||||
|
super(buffer, self).__init__()
|
||||||
|
self.function = function
|
||||||
|
# Compose_function will be used to render an object on this buffer. Normally, signature is as follows:
|
||||||
|
# compose_function(item, db, relative_times, show_screen_names=False, session=None)
|
||||||
|
# Read more about compose functions in twitter/compose.py.
|
||||||
|
self.compose_function = None
|
||||||
|
self.args = args
|
||||||
|
self.kwargs = kwargs
|
||||||
|
# This will be used as a reference to the wx.Panel object wich stores the buffer GUI.
|
||||||
|
self.buffer = None
|
||||||
|
# This should countains the account associated to this buffer.
|
||||||
|
self.account = ""
|
||||||
|
# This controls whether the start_stream function should be called when starting the program.
|
||||||
|
self.needs_init = True
|
||||||
|
# if this is set to False, the buffer will be ignored on the invisible interface.
|
||||||
|
self.invisible = False
|
||||||
|
# Control variable, used to track time of execution for calls to start_stream.
|
||||||
|
self.execution_time = 0
|
||||||
|
|
||||||
|
def clear_list(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_event(self, ev):
|
||||||
|
""" Catch key presses in the WX interface and generate the corresponding event names."""
|
||||||
|
if ev.GetKeyCode() == wx.WXK_RETURN and ev.ControlDown(): event = "audio"
|
||||||
|
elif ev.GetKeyCode() == wx.WXK_RETURN: event = "url"
|
||||||
|
elif ev.GetKeyCode() == wx.WXK_F5: event = "volume_down"
|
||||||
|
elif ev.GetKeyCode() == wx.WXK_F6: event = "volume_up"
|
||||||
|
elif ev.GetKeyCode() == wx.WXK_DELETE and ev.ShiftDown(): event = "clear_list"
|
||||||
|
elif ev.GetKeyCode() == wx.WXK_DELETE: event = "destroy_status"
|
||||||
|
else:
|
||||||
|
event = None
|
||||||
|
ev.Skip()
|
||||||
|
if event != None:
|
||||||
|
try:
|
||||||
|
getattr(self, event)()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def volume_down(self):
|
||||||
|
""" Decreases volume by 5%"""
|
||||||
|
if self.session.settings["sound"]["volume"] > 0.0:
|
||||||
|
if self.session.settings["sound"]["volume"] <= 0.05:
|
||||||
|
self.session.settings["sound"]["volume"] = 0.0
|
||||||
|
else:
|
||||||
|
self.session.settings["sound"]["volume"] -=0.05
|
||||||
|
sound.URLPlayer.player.audio_set_volume(int(self.session.settings["sound"]["volume"]*100.0))
|
||||||
|
self.session.sound.play("volume_changed.ogg")
|
||||||
|
self.session.settings.write()
|
||||||
|
|
||||||
|
def volume_up(self):
|
||||||
|
""" Increases volume by 5%."""
|
||||||
|
if self.session.settings["sound"]["volume"] < 1.0:
|
||||||
|
if self.session.settings["sound"]["volume"] >= 0.95:
|
||||||
|
self.session.settings["sound"]["volume"] = 1.0
|
||||||
|
else:
|
||||||
|
self.session.settings["sound"]["volume"] +=0.05
|
||||||
|
sound.URLPlayer.player.audio_set_volume(int(self.session.settings["sound"]["volume"]*100))
|
||||||
|
self.session.sound.play("volume_changed.ogg")
|
||||||
|
self.session.settings.write()
|
||||||
|
|
||||||
|
def start_stream(self, mandatory=False, play_sound=True):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_more_items(self):
|
||||||
|
output.speak(_(u"This action is not supported for this buffer"), True)
|
||||||
|
|
||||||
|
def put_items_on_list(self, items):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_buffer(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def remove_item(self, item):
|
||||||
|
f = self.buffer.list.get_selected()
|
||||||
|
self.buffer.list.remove_item(item)
|
||||||
|
self.buffer.list.select_item(f)
|
||||||
|
|
||||||
|
def bind_events(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return self.buffer
|
||||||
|
|
||||||
|
def get_message(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def set_list_position(self, reversed=False):
|
||||||
|
if reversed == False:
|
||||||
|
self.buffer.list.select_item(-1)
|
||||||
|
else:
|
||||||
|
self.buffer.list.select_item(0)
|
||||||
|
|
||||||
|
def reply(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def send_message(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def share_item(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def destroy_status(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def post_status(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def save_positions(self):
|
||||||
|
try:
|
||||||
|
self.session.db[self.name+"_pos"]=self.buffer.list.get_selected()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class accountPanel(buffer):
|
||||||
|
def __init__(self, parent, name, account, account_id):
|
||||||
|
super(accountPanel, self).__init__(parent, None, name)
|
||||||
|
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
||||||
|
self.buffer = buffers.accountPanel(parent, name)
|
||||||
|
self.type = self.buffer.type
|
||||||
|
self.compose_function = None
|
||||||
|
self.session = None
|
||||||
|
self.needs_init = False
|
||||||
|
self.account = account
|
||||||
|
self.buffer.account = account
|
||||||
|
self.name = name
|
||||||
|
self.account_id = account_id
|
||||||
|
|
||||||
|
def setup_account(self):
|
||||||
|
widgetUtils.connect_event(self.buffer, widgetUtils.CHECKBOX, self.autostart, menuitem=self.buffer.autostart_account)
|
||||||
|
if self.account_id in config.app["sessions"]["ignored_sessions"]:
|
||||||
|
self.buffer.change_autostart(False)
|
||||||
|
else:
|
||||||
|
self.buffer.change_autostart(True)
|
||||||
|
if not hasattr(self, "logged"):
|
||||||
|
self.buffer.change_login(login=False)
|
||||||
|
widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.logout)
|
||||||
|
else:
|
||||||
|
self.buffer.change_login(login=True)
|
||||||
|
widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.login)
|
||||||
|
|
||||||
|
def login(self, *args, **kwargs):
|
||||||
|
del self.logged
|
||||||
|
self.setup_account()
|
||||||
|
pub.sendMessage("login", session_id=self.account_id)
|
||||||
|
|
||||||
|
def logout(self, *args, **kwargs):
|
||||||
|
self.logged = False
|
||||||
|
self.setup_account()
|
||||||
|
pub.sendMessage("logout", session_id=self.account_id)
|
||||||
|
|
||||||
|
def autostart(self, *args, **kwargs):
|
||||||
|
if self.account_id in config.app["sessions"]["ignored_sessions"]:
|
||||||
|
self.buffer.change_autostart(True)
|
||||||
|
config.app["sessions"]["ignored_sessions"].remove(self.account_id)
|
||||||
|
else:
|
||||||
|
self.buffer.change_autostart(False)
|
||||||
|
config.app["sessions"]["ignored_sessions"].append(self.account_id)
|
||||||
|
config.app.write()
|
||||||
|
|
||||||
|
class emptyPanel(buffer):
|
||||||
|
def __init__(self, parent, name, account):
|
||||||
|
super(emptyPanel, self).__init__(parent=parent)
|
||||||
|
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
||||||
|
self.buffer = buffers.emptyPanel(parent, name)
|
||||||
|
self.type = self.buffer.type
|
||||||
|
self.compose_function = None
|
||||||
|
self.account = account
|
||||||
|
self.buffer.account = account
|
||||||
|
self.name = name
|
||||||
|
self.session = None
|
||||||
|
self.needs_init = True
|
@@ -4,11 +4,11 @@ import platform
|
|||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
import wx
|
import wx
|
||||||
from wxUI import buffers, dialogs, commonMessageDialogs, menus
|
from wxUI import buffers, dialogs, commonMessageDialogs, menus
|
||||||
import user
|
from controller import user
|
||||||
elif platform.system() == "Linux":
|
elif platform.system() == "Linux":
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
from gtkUI import buffers, dialogs, commonMessageDialogs
|
from gtkUI import buffers, dialogs, commonMessageDialogs
|
||||||
import messages
|
from controller import messages
|
||||||
import widgetUtils
|
import widgetUtils
|
||||||
import arrow
|
import arrow
|
||||||
import webbrowser
|
import webbrowser
|
||||||
@@ -18,6 +18,7 @@ import sound
|
|||||||
import languageHandler
|
import languageHandler
|
||||||
import logging
|
import logging
|
||||||
import youtube_utils
|
import youtube_utils
|
||||||
|
from controller.buffers import baseBuffers
|
||||||
from sessions.twitter import compose, utils
|
from sessions.twitter import compose, utils
|
||||||
from mysc.thread_utils import call_threaded
|
from mysc.thread_utils import call_threaded
|
||||||
from twython import TwythonError
|
from twython import TwythonError
|
||||||
@@ -33,121 +34,55 @@ def _tweets_exist(function):
|
|||||||
function(self, *args, **kwargs)
|
function(self, *args, **kwargs)
|
||||||
return function_
|
return function_
|
||||||
|
|
||||||
class bufferController(object):
|
class baseBufferController(baseBuffers.buffer):
|
||||||
""" A basic buffer object. This should be the base class for all other derived buffers."""
|
def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, compose_func="compose_tweet", *args, **kwargs):
|
||||||
|
super(baseBufferController, self).__init__(parent, function, *args, **kwargs)
|
||||||
def __init__(self, parent=None, function=None, session=None, *args, **kwargs):
|
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
||||||
"""Inits the main controller for this buffer:
|
if bufferType != None:
|
||||||
@ parent wx.Treebook object: Container where we will put this buffer.
|
self.buffer = getattr(buffers, bufferType)(parent, name)
|
||||||
@ function str or None: function to be called periodically and update items on this buffer.
|
|
||||||
@ session sessionmanager.session object or None: Session handler for settings, database and Twitter access.
|
|
||||||
"""
|
|
||||||
super(bufferController, self).__init__()
|
|
||||||
self.function = function
|
|
||||||
# Compose_function will be used to render an object on this buffer. Normally, signature is as follows:
|
|
||||||
# compose_function(item, db, relative_times, show_screen_names=False, session=None)
|
|
||||||
# Compose functions will be defined in every buffer if items are different than tweets.
|
|
||||||
# Read more about compose functions in twitter/compose.py.
|
|
||||||
self.compose_function = None
|
|
||||||
self.args = args
|
|
||||||
self.kwargs = kwargs
|
|
||||||
# This will be used as a reference to the wx.Panel object wich stores the buffer GUI.
|
|
||||||
self.buffer = None
|
|
||||||
# This should countains the account associated to this buffer.
|
|
||||||
self.account = ""
|
|
||||||
# This controls wether the start_stream function should be called when starting the program.
|
|
||||||
self.needs_init = True
|
|
||||||
# if this is set to False, the buffer will be ignored on the invisible interface.
|
|
||||||
self.invisible = False
|
|
||||||
# Control variable, used to track time of execution for calls to start_stream.
|
|
||||||
self.execution_time = 0
|
|
||||||
|
|
||||||
def clear_list(self): pass
|
|
||||||
|
|
||||||
def get_event(self, ev):
|
|
||||||
""" Catches key presses in the WX interface and generate the corresponding event names."""
|
|
||||||
if ev.GetKeyCode() == wx.WXK_RETURN and ev.ControlDown(): event = "audio"
|
|
||||||
elif ev.GetKeyCode() == wx.WXK_RETURN: event = "url"
|
|
||||||
elif ev.GetKeyCode() == wx.WXK_F5: event = "volume_down"
|
|
||||||
elif ev.GetKeyCode() == wx.WXK_F6: event = "volume_up"
|
|
||||||
elif ev.GetKeyCode() == wx.WXK_DELETE and ev.ShiftDown(): event = "clear_list"
|
|
||||||
elif ev.GetKeyCode() == wx.WXK_DELETE: event = "destroy_status"
|
|
||||||
else:
|
else:
|
||||||
event = None
|
self.buffer = buffers.basePanel(parent, name)
|
||||||
ev.Skip()
|
self.invisible = True
|
||||||
if event != None:
|
self.name = name
|
||||||
|
self.type = self.buffer.type
|
||||||
|
self.session = sessionObject
|
||||||
|
self.compose_function = getattr(compose, compose_func)
|
||||||
|
log.debug("Compose_function: %s" % (self.compose_function,))
|
||||||
|
self.account = account
|
||||||
|
self.buffer.account = account
|
||||||
|
self.bind_events()
|
||||||
|
self.sound = sound
|
||||||
|
if "-timeline" in self.name or "-favorite" in self.name:
|
||||||
|
self.finished_timeline = False
|
||||||
|
# Add a compatibility layer for username based timelines from config.
|
||||||
|
# ToDo: Remove this in some new versions of the client, when user ID timelines become mandatory.
|
||||||
try:
|
try:
|
||||||
getattr(self, event)()
|
int(self.kwargs["user_id"])
|
||||||
except AttributeError:
|
except ValueError:
|
||||||
pass
|
self.is_screen_name = True
|
||||||
|
self.kwargs["screen_name"] = self.kwargs["user_id"]
|
||||||
|
self.kwargs.pop("user_id")
|
||||||
|
|
||||||
def volume_down(self):
|
def get_buffer_name(self):
|
||||||
if self.session.settings["sound"]["volume"] > 0.0:
|
""" Get buffer name from a set of different techniques."""
|
||||||
if self.session.settings["sound"]["volume"] <= 0.05:
|
# firstly let's take the easier buffers.
|
||||||
self.session.settings["sound"]["volume"] = 0.0
|
basic_buffers = dict(home_timeline=_(u"Home"), mentions=_(u"Mentions"), direct_messages=_(u"Direct messages"), sent_direct_messages=_(u"Sent direct messages"), sent_tweets=_(u"Sent tweets"), favourites=_(u"Likes"), followers=_(u"Followers"), friends=_(u"Friends"), blocked=_(u"Blocked users"), muted=_(u"Muted users"))
|
||||||
else:
|
if self.name in basic_buffers.keys():
|
||||||
self.session.settings["sound"]["volume"] -=0.05
|
return basic_buffers[self.name]
|
||||||
sound.URLPlayer.player.audio_set_volume(int(self.session.settings["sound"]["volume"]*100.0))
|
# Check user timelines
|
||||||
self.session.sound.play("volume_changed.ogg")
|
elif hasattr(self, "username"):
|
||||||
self.session.settings.write()
|
if "-timeline" in self.name:
|
||||||
|
return _(u"{username}'s timeline").format(username=self.username,)
|
||||||
|
elif "-favorite" in self.name:
|
||||||
|
return _(u"{username}'s likes").format(username=self.username,)
|
||||||
|
elif "-followers" in self.name:
|
||||||
|
return _(u"{username}'s followers").format(username=self.username,)
|
||||||
|
elif "-friends" in self.name:
|
||||||
|
return _(u"{username}'s friends").format(username=self.username,)
|
||||||
|
log.error("Error getting name for buffer %s" % (self.name,))
|
||||||
|
return _(u"Unknown buffer")
|
||||||
|
|
||||||
def volume_up(self):
|
def post_status(self, *args, **kwargs):
|
||||||
if self.session.settings["sound"]["volume"] < 1.0:
|
|
||||||
if self.session.settings["sound"]["volume"] >= 0.95:
|
|
||||||
self.session.settings["sound"]["volume"] = 1.0
|
|
||||||
else:
|
|
||||||
self.session.settings["sound"]["volume"] +=0.05
|
|
||||||
sound.URLPlayer.player.audio_set_volume(int(self.session.settings["sound"]["volume"]*100))
|
|
||||||
self.session.sound.play("volume_changed.ogg")
|
|
||||||
self.session.settings.write()
|
|
||||||
|
|
||||||
def start_stream(self, mandatory=False, play_sound=True):
|
|
||||||
# if mandatory == True:
|
|
||||||
# output.speak(_(u"Unable to update this buffer."))
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_more_items(self):
|
|
||||||
output.speak(_(u"This action is not supported for this buffer"), True)
|
|
||||||
|
|
||||||
def put_items_on_list(self, items):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def remove_buffer(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def remove_item(self, item):
|
|
||||||
f = self.buffer.list.get_selected()
|
|
||||||
self.buffer.list.remove_item(item)
|
|
||||||
self.buffer.list.select_item(f)
|
|
||||||
|
|
||||||
def bind_events(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_object(self):
|
|
||||||
return self.buffer
|
|
||||||
|
|
||||||
def get_message(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_list_position(self, reversed=False):
|
|
||||||
if reversed == False:
|
|
||||||
self.buffer.list.select_item(-1)
|
|
||||||
else:
|
|
||||||
self.buffer.list.select_item(0)
|
|
||||||
|
|
||||||
def reply(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def direct_message(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def retweet(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def destroy_status(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def post_tweet(self, *args, **kwargs):
|
|
||||||
title = _(u"Tweet")
|
title = _(u"Tweet")
|
||||||
caption = _(u"Write the tweet here")
|
caption = _(u"Write the tweet here")
|
||||||
tweet = messages.tweet(self.session, title, caption, "")
|
tweet = messages.tweet(self.session, title, caption, "")
|
||||||
@@ -179,100 +114,6 @@ class bufferController(object):
|
|||||||
media_ids.append(img["media_id"])
|
media_ids.append(img["media_id"])
|
||||||
self.session.twitter.update_status(status=text, media_ids=media_ids)
|
self.session.twitter.update_status(status=text, media_ids=media_ids)
|
||||||
|
|
||||||
def save_positions(self):
|
|
||||||
try:
|
|
||||||
self.session.db[self.name+"_pos"]=self.buffer.list.get_selected()
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class accountPanel(bufferController):
|
|
||||||
def __init__(self, parent, name, account, account_id):
|
|
||||||
super(accountPanel, self).__init__(parent, None, name)
|
|
||||||
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
|
||||||
self.buffer = buffers.accountPanel(parent, name)
|
|
||||||
self.type = self.buffer.type
|
|
||||||
self.compose_function = None
|
|
||||||
self.session = None
|
|
||||||
self.needs_init = False
|
|
||||||
self.account = account
|
|
||||||
self.buffer.account = account
|
|
||||||
self.name = name
|
|
||||||
self.account_id = account_id
|
|
||||||
|
|
||||||
def setup_account(self):
|
|
||||||
widgetUtils.connect_event(self.buffer, widgetUtils.CHECKBOX, self.autostart, menuitem=self.buffer.autostart_account)
|
|
||||||
if self.account_id in config.app["sessions"]["ignored_sessions"]:
|
|
||||||
self.buffer.change_autostart(False)
|
|
||||||
else:
|
|
||||||
self.buffer.change_autostart(True)
|
|
||||||
if not hasattr(self, "logged"):
|
|
||||||
self.buffer.change_login(login=False)
|
|
||||||
widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.logout)
|
|
||||||
else:
|
|
||||||
self.buffer.change_login(login=True)
|
|
||||||
widgetUtils.connect_event(self.buffer.login, widgetUtils.BUTTON_PRESSED, self.login)
|
|
||||||
|
|
||||||
def login(self, *args, **kwargs):
|
|
||||||
del self.logged
|
|
||||||
self.setup_account()
|
|
||||||
pub.sendMessage("login", session_id=self.account_id)
|
|
||||||
|
|
||||||
def logout(self, *args, **kwargs):
|
|
||||||
self.logged = False
|
|
||||||
self.setup_account()
|
|
||||||
pub.sendMessage("logout", session_id=self.account_id)
|
|
||||||
|
|
||||||
def autostart(self, *args, **kwargs):
|
|
||||||
if self.account_id in config.app["sessions"]["ignored_sessions"]:
|
|
||||||
self.buffer.change_autostart(True)
|
|
||||||
config.app["sessions"]["ignored_sessions"].remove(self.account_id)
|
|
||||||
else:
|
|
||||||
self.buffer.change_autostart(False)
|
|
||||||
config.app["sessions"]["ignored_sessions"].append(self.account_id)
|
|
||||||
config.app.write()
|
|
||||||
|
|
||||||
class emptyPanel(bufferController):
|
|
||||||
def __init__(self, parent, name, account):
|
|
||||||
super(emptyPanel, self).__init__(parent=parent)
|
|
||||||
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
|
||||||
self.buffer = buffers.emptyPanel(parent, name)
|
|
||||||
self.type = self.buffer.type
|
|
||||||
self.compose_function = None
|
|
||||||
self.account = account
|
|
||||||
self.buffer.account = account
|
|
||||||
self.name = name
|
|
||||||
self.session = None
|
|
||||||
self.needs_init = True
|
|
||||||
|
|
||||||
class baseBufferController(bufferController):
|
|
||||||
def __init__(self, parent, function, name, sessionObject, account, sound=None, bufferType=None, compose_func="compose_tweet", *args, **kwargs):
|
|
||||||
super(baseBufferController, self).__init__(parent, function, *args, **kwargs)
|
|
||||||
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
|
||||||
if bufferType != None:
|
|
||||||
self.buffer = getattr(buffers, bufferType)(parent, name)
|
|
||||||
else:
|
|
||||||
self.buffer = buffers.basePanel(parent, name)
|
|
||||||
self.invisible = True
|
|
||||||
self.name = name
|
|
||||||
self.type = self.buffer.type
|
|
||||||
self.session = sessionObject
|
|
||||||
self.compose_function = getattr(compose, compose_func)
|
|
||||||
log.debug("Compose_function: %s" % (self.compose_function,))
|
|
||||||
self.account = account
|
|
||||||
self.buffer.account = account
|
|
||||||
self.bind_events()
|
|
||||||
self.sound = sound
|
|
||||||
if "-timeline" in self.name or "-favorite" in self.name:
|
|
||||||
self.finished_timeline = False
|
|
||||||
# Add a compatibility layer for username based timelines from config.
|
|
||||||
# ToDo: Remove this in some new versions of the client, when user ID timelines become mandatory.
|
|
||||||
try:
|
|
||||||
int(self.kwargs["user_id"])
|
|
||||||
except ValueError:
|
|
||||||
self.is_screen_name = True
|
|
||||||
self.kwargs["screen_name"] = self.kwargs["user_id"]
|
|
||||||
self.kwargs.pop("user_id")
|
|
||||||
|
|
||||||
def get_formatted_message(self):
|
def get_formatted_message(self):
|
||||||
if self.type == "dm" or self.name == "direct_messages":
|
if self.type == "dm" or self.name == "direct_messages":
|
||||||
return self.compose_function(self.get_right_tweet(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)[1]
|
return self.compose_function(self.get_right_tweet(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)[1]
|
||||||
@@ -317,7 +158,7 @@ class baseBufferController(bufferController):
|
|||||||
tweetsList.append(tweet)
|
tweetsList.append(tweet)
|
||||||
return (tweet, tweetsList)
|
return (tweet, tweetsList)
|
||||||
|
|
||||||
def start_stream(self, mandatory=False, play_sound=True):
|
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
||||||
@@ -339,8 +180,22 @@ class baseBufferController(bufferController):
|
|||||||
self.finished_timeline = True
|
self.finished_timeline = True
|
||||||
if number_of_items > 0 and self.name != "sent_tweets" and self.name != "sent_direct_messages" and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
if number_of_items > 0 and self.name != "sent_tweets" and self.name != "sent_direct_messages" and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
||||||
self.session.sound.play(self.sound)
|
self.session.sound.play(self.sound)
|
||||||
|
# Autoread settings
|
||||||
|
if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]:
|
||||||
|
self.auto_read(number_of_items)
|
||||||
return number_of_items
|
return number_of_items
|
||||||
|
|
||||||
|
def auto_read(self, number_of_items):
|
||||||
|
if number_of_items == 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
||||||
|
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||||
|
tweet = self.session.db[self.name][-1]
|
||||||
|
else:
|
||||||
|
tweet = self.session.db[self.name][0]
|
||||||
|
output.speak(_(u"New tweet in {0}").format(self.get_buffer_name()))
|
||||||
|
output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)))
|
||||||
|
elif number_of_items > 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
||||||
|
output.speak(_(u"{0} new tweets in {1}.").format(number_of_items, self.get_buffer_name()))
|
||||||
|
|
||||||
def get_more_items(self):
|
def get_more_items(self):
|
||||||
elements = []
|
elements = []
|
||||||
if self.session.settings["general"]["reverse_timelines"] == False:
|
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||||
@@ -460,10 +315,10 @@ class baseBufferController(bufferController):
|
|||||||
log.debug("Binding events...")
|
log.debug("Binding events...")
|
||||||
self.buffer.set_focus_function(self.onFocus)
|
self.buffer.set_focus_function(self.onFocus)
|
||||||
widgetUtils.connect_event(self.buffer.list.list, widgetUtils.KEYPRESS, self.get_event)
|
widgetUtils.connect_event(self.buffer.list.list, widgetUtils.KEYPRESS, self.get_event)
|
||||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_tweet, self.buffer.tweet)
|
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_status, self.buffer.tweet)
|
||||||
# if self.type == "baseBuffer":
|
# if self.type == "baseBuffer":
|
||||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.retweet, self.buffer.retweet)
|
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.share_item, self.buffer.retweet)
|
||||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.direct_message, self.buffer.dm)
|
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.send_message, self.buffer.dm)
|
||||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.reply, self.buffer.reply)
|
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.reply, self.buffer.reply)
|
||||||
# Replace for the correct way in other platforms.
|
# Replace for the correct way in other platforms.
|
||||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu)
|
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu)
|
||||||
@@ -475,13 +330,13 @@ class baseBufferController(bufferController):
|
|||||||
menu = menus.sentPanelMenu()
|
menu = menus.sentPanelMenu()
|
||||||
elif self.name == "direct_messages":
|
elif self.name == "direct_messages":
|
||||||
menu = menus.dmPanelMenu()
|
menu = menus.dmPanelMenu()
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.direct_message, menuitem=menu.reply)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.send_message, menuitem=menu.reply)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
||||||
else:
|
else:
|
||||||
menu = menus.basePanelMenu()
|
menu = menus.basePanelMenu()
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.reply, menuitem=menu.reply)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.reply, menuitem=menu.reply)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.retweet, menuitem=menu.retweet)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.share_item, menuitem=menu.retweet)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.fav, menuitem=menu.fav)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.fav, menuitem=menu.fav)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.unfav, menuitem=menu.unfav)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.unfav, menuitem=menu.unfav)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.url_, menuitem=menu.openUrl)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.url_, menuitem=menu.openUrl)
|
||||||
@@ -580,7 +435,7 @@ class baseBufferController(bufferController):
|
|||||||
self.session.settings.write()
|
self.session.settings.write()
|
||||||
|
|
||||||
@_tweets_exist
|
@_tweets_exist
|
||||||
def direct_message(self, *args, **kwargs):
|
def send_message(self, *args, **kwargs):
|
||||||
tweet = self.get_right_tweet()
|
tweet = self.get_right_tweet()
|
||||||
if self.type == "dm":
|
if self.type == "dm":
|
||||||
screen_name = self.session.get_user(tweet["message_create"]["sender_id"])["screen_name"]
|
screen_name = self.session.get_user(tweet["message_create"]["sender_id"])["screen_name"]
|
||||||
@@ -618,7 +473,7 @@ class baseBufferController(bufferController):
|
|||||||
if hasattr(dm.message, "destroy"): dm.message.destroy()
|
if hasattr(dm.message, "destroy"): dm.message.destroy()
|
||||||
|
|
||||||
@_tweets_exist
|
@_tweets_exist
|
||||||
def retweet(self, *args, **kwargs):
|
def share_item(self, *args, **kwargs):
|
||||||
tweet = self.get_right_tweet()
|
tweet = self.get_right_tweet()
|
||||||
id = tweet["id"]
|
id = tweet["id"]
|
||||||
if self.session.settings["general"]["retweet_mode"] == "ask":
|
if self.session.settings["general"]["retweet_mode"] == "ask":
|
||||||
@@ -633,6 +488,9 @@ class baseBufferController(bufferController):
|
|||||||
self._retweet_with_comment(tweet, id)
|
self._retweet_with_comment(tweet, id)
|
||||||
|
|
||||||
def _retweet_with_comment(self, tweet, id, comment=''):
|
def _retweet_with_comment(self, tweet, id, comment=''):
|
||||||
|
# If quoting a retweet, let's quote the original tweet instead the retweet.
|
||||||
|
if tweet.has_key("retweeted_status"):
|
||||||
|
tweet = tweet["retweeted_status"]
|
||||||
if tweet.has_key("full_text"):
|
if tweet.has_key("full_text"):
|
||||||
comments = tweet["full_text"]
|
comments = tweet["full_text"]
|
||||||
else:
|
else:
|
||||||
@@ -646,8 +504,8 @@ class baseBufferController(bufferController):
|
|||||||
if retweet.image == None:
|
if retweet.image == None:
|
||||||
item = self.session.api_call(call_name="update_status", _sound="retweet_send.ogg", status=text, in_reply_to_status_id=id, tweet_mode="extended")
|
item = self.session.api_call(call_name="update_status", _sound="retweet_send.ogg", status=text, in_reply_to_status_id=id, tweet_mode="extended")
|
||||||
if item != None:
|
if item != None:
|
||||||
item = self.session.twitter.show_status(id=item["id"], include_ext_alt_text=True, tweet_mode="extended")
|
new_item = self.session.twitter.show_status(id=item["id"], include_ext_alt_text=True, tweet_mode="extended")
|
||||||
pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"])
|
pub.sendMessage("sent-tweet", data=new_item, user=self.session.db["user_name"])
|
||||||
else:
|
else:
|
||||||
call_threaded(self.session.api_call, call_name="update_status", _sound="retweet_send.ogg", status=text, media=retweet.image)
|
call_threaded(self.session.api_call, call_name="update_status", _sound="retweet_send.ogg", status=text, media=retweet.image)
|
||||||
if hasattr(retweet.message, "destroy"): retweet.message.destroy()
|
if hasattr(retweet.message, "destroy"): retweet.message.destroy()
|
||||||
@@ -732,7 +590,6 @@ class baseBufferController(bufferController):
|
|||||||
self.session.twitter.destroy_status(id=self.get_right_tweet()["id"])
|
self.session.twitter.destroy_status(id=self.get_right_tweet()["id"])
|
||||||
self.session.db[self.name].pop(index)
|
self.session.db[self.name].pop(index)
|
||||||
self.buffer.list.remove_item(index)
|
self.buffer.list.remove_item(index)
|
||||||
# if index > 0:
|
|
||||||
except TwythonError:
|
except TwythonError:
|
||||||
self.session.sound.play("error.ogg")
|
self.session.sound.play("error.ogg")
|
||||||
|
|
||||||
@@ -851,6 +708,17 @@ class directMessagesController(baseBufferController):
|
|||||||
self.session.db[self.name]["items"] = []
|
self.session.db[self.name]["items"] = []
|
||||||
self.buffer.list.clear()
|
self.buffer.list.clear()
|
||||||
|
|
||||||
|
def auto_read(self, number_of_items):
|
||||||
|
if number_of_items == 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
||||||
|
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||||
|
tweet = self.session.db[self.name]["items"][-1]
|
||||||
|
else:
|
||||||
|
tweet = self.session.db[self.name]["items"][0]
|
||||||
|
output.speak(_(u"New direct message"))
|
||||||
|
output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)))
|
||||||
|
elif number_of_items > 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
||||||
|
output.speak(_(u"{0} new direct messages.").format(number_of_items,))
|
||||||
|
|
||||||
class sentDirectMessagesController(directMessagesController):
|
class sentDirectMessagesController(directMessagesController):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -881,9 +749,9 @@ class listBufferController(baseBufferController):
|
|||||||
self.list_id = list_id
|
self.list_id = list_id
|
||||||
self.kwargs["list_id"] = list_id
|
self.kwargs["list_id"] = list_id
|
||||||
|
|
||||||
def start_stream(self, mandatory=False, play_sound=True):
|
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||||
self.get_user_ids()
|
self.get_user_ids()
|
||||||
super(listBufferController, self).start_stream(mandatory, play_sound)
|
super(listBufferController, self).start_stream(mandatory, play_sound, avoid_autoreading)
|
||||||
|
|
||||||
def get_user_ids(self):
|
def get_user_ids(self):
|
||||||
next_cursor = -1
|
next_cursor = -1
|
||||||
@@ -909,58 +777,6 @@ class listBufferController(baseBufferController):
|
|||||||
elif dlg == widgetUtils.NO:
|
elif dlg == widgetUtils.NO:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class eventsBufferController(bufferController):
|
|
||||||
def __init__(self, parent, name, session, account, *args, **kwargs):
|
|
||||||
super(eventsBufferController, self).__init__(parent, *args, **kwargs)
|
|
||||||
log.debug("Initializing buffer %s, account %s" % (name, account,))
|
|
||||||
self.invisible = True
|
|
||||||
self.buffer = buffers.eventsPanel(parent, name)
|
|
||||||
self.name = name
|
|
||||||
self.account = account
|
|
||||||
self.buffer.account = self.account
|
|
||||||
self.compose_function = compose.compose_event
|
|
||||||
self.session = session
|
|
||||||
self.type = self.buffer.type
|
|
||||||
self.get_formatted_message = self.get_message
|
|
||||||
|
|
||||||
def get_message(self):
|
|
||||||
if self.buffer.list.get_count() == 0: return _(u"Empty")
|
|
||||||
# fix this:
|
|
||||||
return "%s. %s" % (self.buffer.list.list.GetItemText(self.buffer.list.get_selected()), self.buffer.list.list.GetItemText(self.buffer.list.get_selected(), 1))
|
|
||||||
|
|
||||||
def add_new_item(self, item):
|
|
||||||
tweet = self.compose_function(item, self.session.db["user_name"], self.session.settings["general"]["show_screen_names"])
|
|
||||||
if self.session.settings["general"]["reverse_timelines"] == False:
|
|
||||||
self.buffer.list.insert_item(False, *tweet)
|
|
||||||
else:
|
|
||||||
self.buffer.list.insert_item(True, *tweet)
|
|
||||||
if self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
|
||||||
output.speak(" ".join(tweet), speech=self.session.settings["reporting"]["speech_reporting"], braille=self.session.settings["reporting"]["braille_reporting"])
|
|
||||||
if self.buffer.list.get_count() == 1:
|
|
||||||
self.buffer.list.select_item(0)
|
|
||||||
|
|
||||||
def clear_list(self):
|
|
||||||
dlg = commonMessageDialogs.clear_list()
|
|
||||||
if dlg == widgetUtils.YES:
|
|
||||||
self.buffer.list.clear()
|
|
||||||
|
|
||||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
|
||||||
if self.buffer.list.get_count() == 0: return
|
|
||||||
menu = menus.eventsPanelMenu()
|
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.view, menuitem=menu.view)
|
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.copy, menuitem=menu.copy)
|
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.destroy_status, menuitem=menu.remove)
|
|
||||||
if pos != 0:
|
|
||||||
self.buffer.PopupMenu(menu, pos)
|
|
||||||
else:
|
|
||||||
self.buffer.PopupMenu(menu, ev.GetPosition())
|
|
||||||
|
|
||||||
def view(self, *args, **kwargs):
|
|
||||||
pub.sendMessage("execute-action", action="view_item")
|
|
||||||
|
|
||||||
def copy(self, *args, **kwargs):
|
|
||||||
pub.sendMessage("execute-action", action="copy_to_clipboard")
|
|
||||||
|
|
||||||
class peopleBufferController(baseBufferController):
|
class peopleBufferController(baseBufferController):
|
||||||
def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs):
|
def __init__(self, parent, function, name, sessionObject, account, bufferType=None, *args, **kwargs):
|
||||||
super(peopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs)
|
super(peopleBufferController, self).__init__(parent, function, name, sessionObject, account, bufferType="peoplePanel", *args, **kwargs)
|
||||||
@@ -1038,7 +854,7 @@ class peopleBufferController(baseBufferController):
|
|||||||
call_threaded(self.session.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", status=message.message.get_text(), media=message.file)
|
call_threaded(self.session.api_call, call_name="update_status_with_media", _sound="reply_send.ogg", status=message.message.get_text(), media=message.file)
|
||||||
if hasattr(message.message, "destroy"): message.message.destroy()
|
if hasattr(message.message, "destroy"): message.message.destroy()
|
||||||
|
|
||||||
def start_stream(self, mandatory=False, play_sound=True):
|
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
||||||
@@ -1052,6 +868,9 @@ class peopleBufferController(baseBufferController):
|
|||||||
self.finished_timeline = True
|
self.finished_timeline = True
|
||||||
if val > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
if val > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
||||||
self.session.sound.play(self.sound)
|
self.session.sound.play(self.sound)
|
||||||
|
# Autoread settings
|
||||||
|
if avoid_autoreading == False and mandatory == True and val > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]:
|
||||||
|
self.auto_read(val)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def get_more_items(self):
|
def get_more_items(self):
|
||||||
@@ -1126,7 +945,7 @@ class peopleBufferController(baseBufferController):
|
|||||||
|
|
||||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||||
menu = menus.peoplePanelMenu()
|
menu = menus.peoplePanelMenu()
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.direct_message, menuitem=menu.reply)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.send_message, menuitem=menu.reply)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.user_actions, menuitem=menu.userActions)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.details, menuitem=menu.details)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.details, menuitem=menu.details)
|
||||||
# widgetUtils.connect_event(menu, widgetUtils.MENU, self.lists, menuitem=menu.lists)
|
# widgetUtils.connect_event(menu, widgetUtils.MENU, self.lists, menuitem=menu.lists)
|
||||||
@@ -1140,8 +959,18 @@ class peopleBufferController(baseBufferController):
|
|||||||
def details(self, *args, **kwargs):
|
def details(self, *args, **kwargs):
|
||||||
pub.sendMessage("execute-action", action="user_details")
|
pub.sendMessage("execute-action", action="user_details")
|
||||||
|
|
||||||
|
def auto_read(self, number_of_items):
|
||||||
|
if number_of_items == 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
||||||
|
if self.session.settings["general"]["reverse_timelines"] == False:
|
||||||
|
tweet = self.session.db[self.name]["items"][-1]
|
||||||
|
else:
|
||||||
|
tweet = self.session.db[self.name["items"]][0]
|
||||||
|
output.speak(" ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)))
|
||||||
|
elif number_of_items > 1 and self.name in self.session.settings["other_buffers"]["autoread_buffers"] and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and self.session.settings["sound"]["session_mute"] == False:
|
||||||
|
output.speak(_(u"{0} new followers.").format(number_of_items))
|
||||||
|
|
||||||
class searchBufferController(baseBufferController):
|
class searchBufferController(baseBufferController):
|
||||||
def start_stream(self, mandatory=False, play_sound=True):
|
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
||||||
@@ -1157,6 +986,9 @@ class searchBufferController(baseBufferController):
|
|||||||
self.put_items_on_list(num)
|
self.put_items_on_list(num)
|
||||||
if num > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
if num > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
||||||
self.session.sound.play(self.sound)
|
self.session.sound.play(self.sound)
|
||||||
|
# Autoread settings
|
||||||
|
if avoid_autoreading == False and mandatory == True and num > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]:
|
||||||
|
self.auto_read(num)
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def remove_buffer(self, force=False):
|
def remove_buffer(self, force=False):
|
||||||
@@ -1222,7 +1054,7 @@ class searchPeopleBufferController(peopleBufferController):
|
|||||||
if self.kwargs.has_key("page") == False:
|
if self.kwargs.has_key("page") == False:
|
||||||
self.kwargs["page"] = 1
|
self.kwargs["page"] = 1
|
||||||
|
|
||||||
def start_stream(self, mandatory=False, play_sound=True):
|
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=True):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory==True:
|
||||||
@@ -1239,6 +1071,9 @@ class searchPeopleBufferController(peopleBufferController):
|
|||||||
self.put_items_on_list(number_of_items)
|
self.put_items_on_list(number_of_items)
|
||||||
if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
||||||
self.session.sound.play(self.sound)
|
self.session.sound.play(self.sound)
|
||||||
|
# Autoread settings
|
||||||
|
if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]:
|
||||||
|
self.auto_read(number_of_items)
|
||||||
return number_of_items
|
return number_of_items
|
||||||
|
|
||||||
def get_more_items(self, *args, **kwargs):
|
def get_more_items(self, *args, **kwargs):
|
||||||
@@ -1286,7 +1121,7 @@ class searchPeopleBufferController(peopleBufferController):
|
|||||||
elif dlg == widgetUtils.NO:
|
elif dlg == widgetUtils.NO:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class trendsBufferController(bufferController):
|
class trendsBufferController(baseBuffers.buffer):
|
||||||
def __init__(self, parent, name, session, account, trendsFor, *args, **kwargs):
|
def __init__(self, parent, name, session, account, trendsFor, *args, **kwargs):
|
||||||
super(trendsBufferController, self).__init__(parent=parent, session=session)
|
super(trendsBufferController, self).__init__(parent=parent, session=session)
|
||||||
self.trendsFor = trendsFor
|
self.trendsFor = trendsFor
|
||||||
@@ -1305,7 +1140,7 @@ class trendsBufferController(bufferController):
|
|||||||
self.get_formatted_message = self.get_message
|
self.get_formatted_message = self.get_message
|
||||||
self.reply = self.search_topic
|
self.reply = self.search_topic
|
||||||
|
|
||||||
def start_stream(self, mandatory=False, play_sound=True):
|
def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True:
|
||||||
@@ -1336,7 +1171,7 @@ class trendsBufferController(bufferController):
|
|||||||
log.debug("Binding events...")
|
log.debug("Binding events...")
|
||||||
self.buffer.list.list.Bind(wx.EVT_CHAR_HOOK, self.get_event)
|
self.buffer.list.list.Bind(wx.EVT_CHAR_HOOK, self.get_event)
|
||||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.tweet_about_this_trend, self.buffer.tweetTrendBtn)
|
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.tweet_about_this_trend, self.buffer.tweetTrendBtn)
|
||||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_tweet, self.buffer.tweet)
|
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.post_status, self.buffer.tweet)
|
||||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu)
|
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_ITEM_RIGHT_CLICK, self.show_menu)
|
||||||
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key)
|
widgetUtils.connect_event(self.buffer.list.list, wx.EVT_LIST_KEY_DOWN, self.show_menu_by_key)
|
||||||
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.search_topic, self.buffer.search_topic)
|
widgetUtils.connect_event(self.buffer, widgetUtils.BUTTON_PRESSED, self.search_topic, self.buffer.search_topic)
|
||||||
@@ -1410,7 +1245,7 @@ class trendsBufferController(bufferController):
|
|||||||
|
|
||||||
class conversationBufferController(searchBufferController):
|
class conversationBufferController(searchBufferController):
|
||||||
|
|
||||||
def start_stream(self, start=False, mandatory=False, play_sound=True):
|
def start_stream(self, start=False, mandatory=False, play_sound=True, avoid_autoreading=False):
|
||||||
# starts stream every 3 minutes.
|
# starts stream every 3 minutes.
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True:
|
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True:
|
||||||
@@ -1442,6 +1277,9 @@ class conversationBufferController(searchBufferController):
|
|||||||
self.put_items_on_list(number_of_items)
|
self.put_items_on_list(number_of_items)
|
||||||
if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
if number_of_items > 0 and self.sound != None and self.session.settings["sound"]["session_mute"] == False and self.name not in self.session.settings["other_buffers"]["muted_buffers"] and play_sound == True:
|
||||||
self.session.sound.play(self.sound)
|
self.session.sound.play(self.sound)
|
||||||
|
# Autoread settings
|
||||||
|
if avoid_autoreading == False and mandatory == True and number_of_items > 0 and self.name in self.session.settings["other_buffers"]["autoread_buffers"]:
|
||||||
|
self.auto_read(number_of_items)
|
||||||
return number_of_items
|
return number_of_items
|
||||||
|
|
||||||
def remove_buffer(self, force=False):
|
def remove_buffer(self, force=False):
|
@@ -4,6 +4,7 @@ system = platform.system()
|
|||||||
import application
|
import application
|
||||||
import requests
|
import requests
|
||||||
import youtube_utils
|
import youtube_utils
|
||||||
|
import arrow
|
||||||
if system == "Windows":
|
if system == "Windows":
|
||||||
from update import updater
|
from update import updater
|
||||||
from wxUI import (view, dialogs, commonMessageDialogs, sysTrayIcon)
|
from wxUI import (view, dialogs, commonMessageDialogs, sysTrayIcon)
|
||||||
@@ -22,7 +23,7 @@ elif system == "Linux":
|
|||||||
from sessions.twitter import utils, compose
|
from sessions.twitter import utils, compose
|
||||||
from sessionmanager import manager, sessionManager
|
from sessionmanager import manager, sessionManager
|
||||||
|
|
||||||
import buffersController
|
from controller.buffers import baseBuffers, twitterBuffers
|
||||||
import messages
|
import messages
|
||||||
import sessions
|
import sessions
|
||||||
from sessions.twitter import session as session_
|
from sessions.twitter import session as session_
|
||||||
@@ -57,13 +58,13 @@ class Controller(object):
|
|||||||
name_ str: The name for the buffer
|
name_ str: The name for the buffer
|
||||||
user str: The account for the buffer.
|
user str: The account for the buffer.
|
||||||
for example you may want to search the home_timeline buffer for the tw_blue2 user.
|
for example you may want to search the home_timeline buffer for the tw_blue2 user.
|
||||||
Return type: buffersController.buffer object."""
|
Return type: buffers.buffer object."""
|
||||||
for i in self.buffers:
|
for i in self.buffers:
|
||||||
if i.name == name_ and i.account == user: return i
|
if i.name == name_ and i.account == user: return i
|
||||||
|
|
||||||
def get_current_buffer(self):
|
def get_current_buffer(self):
|
||||||
""" Get the current focused bufferObject.
|
""" Get the current focused bufferObject.
|
||||||
Return type: BuffersController.buffer object."""
|
Return type: buffers.buffer object."""
|
||||||
buffer = self.view.get_current_buffer()
|
buffer = self.view.get_current_buffer()
|
||||||
if hasattr(buffer, "account"):
|
if hasattr(buffer, "account"):
|
||||||
buffer = self.search_buffer(buffer.name, buffer.account)
|
buffer = self.search_buffer(buffer.name, buffer.account)
|
||||||
@@ -72,7 +73,7 @@ class Controller(object):
|
|||||||
def get_best_buffer(self):
|
def get_best_buffer(self):
|
||||||
""" Get the best buffer for doing something using the session object.
|
""" Get the best buffer for doing something using the session object.
|
||||||
This function is useful when you need to open a timeline or post a tweet, and the user is in a buffer without a session, for example the events buffer.
|
This function is useful when you need to open a timeline or post a tweet, and the user is in a buffer without a session, for example the events buffer.
|
||||||
Return type: buffersController.buffer object."""
|
Return type: twitterBuffers.buffer object."""
|
||||||
# Gets the parent buffer to know what account is doing an action
|
# Gets the parent buffer to know what account is doing an action
|
||||||
view_buffer = self.view.get_current_buffer()
|
view_buffer = self.view.get_current_buffer()
|
||||||
# If the account has no session attached, we will need to search the first available non-empty buffer for that account to use its session.
|
# If the account has no session attached, we will need to search the first available non-empty buffer for that account to use its session.
|
||||||
@@ -273,7 +274,7 @@ class Controller(object):
|
|||||||
|
|
||||||
def create_ignored_session_buffer(self, session):
|
def create_ignored_session_buffer(self, session):
|
||||||
self.accounts.append(session.settings["twitter"]["user_name"])
|
self.accounts.append(session.settings["twitter"]["user_name"])
|
||||||
account = buffersController.accountPanel(self.view.nb, session.settings["twitter"]["user_name"], session.settings["twitter"]["user_name"], session.session_id)
|
account = baseBuffers.accountPanel(self.view.nb, session.settings["twitter"]["user_name"], session.settings["twitter"]["user_name"], session.session_id)
|
||||||
account.logged = False
|
account.logged = False
|
||||||
account.setup_account()
|
account.setup_account()
|
||||||
self.buffers.append(account)
|
self.buffers.append(account)
|
||||||
@@ -293,96 +294,96 @@ class Controller(object):
|
|||||||
session.get_user_info()
|
session.get_user_info()
|
||||||
if createAccounts == True:
|
if createAccounts == True:
|
||||||
self.accounts.append(session.db["user_name"])
|
self.accounts.append(session.db["user_name"])
|
||||||
account = buffersController.accountPanel(self.view.nb, session.db["user_name"], session.db["user_name"], session.session_id)
|
account = baseBuffers.accountPanel(self.view.nb, session.db["user_name"], session.db["user_name"], session.session_id)
|
||||||
account.setup_account()
|
account.setup_account()
|
||||||
self.buffers.append(account)
|
self.buffers.append(account)
|
||||||
self.view.add_buffer(account.buffer , name=session.db["user_name"])
|
self.view.add_buffer(account.buffer , name=session.db["user_name"])
|
||||||
for i in session.settings['general']['buffer_order']:
|
for i in session.settings['general']['buffer_order']:
|
||||||
if i == 'home':
|
if i == 'home':
|
||||||
home = buffersController.baseBufferController(self.view.nb, "get_home_timeline", "home_timeline", session, session.db["user_name"], sound="tweet_received.ogg", tweet_mode="extended")
|
home = twitterBuffers.baseBufferController(self.view.nb, "get_home_timeline", "home_timeline", session, session.db["user_name"], sound="tweet_received.ogg", tweet_mode="extended")
|
||||||
self.buffers.append(home)
|
self.buffers.append(home)
|
||||||
self.view.insert_buffer(home.buffer, name=_(u"Home"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(home.buffer, name=_(u"Home"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'mentions':
|
elif i == 'mentions':
|
||||||
mentions = buffersController.baseBufferController(self.view.nb, "get_mentions_timeline", "mentions", session, session.db["user_name"], sound="mention_received.ogg", tweet_mode="extended")
|
mentions = twitterBuffers.baseBufferController(self.view.nb, "get_mentions_timeline", "mentions", session, session.db["user_name"], sound="mention_received.ogg", tweet_mode="extended")
|
||||||
self.buffers.append(mentions)
|
self.buffers.append(mentions)
|
||||||
self.view.insert_buffer(mentions.buffer, name=_(u"Mentions"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(mentions.buffer, name=_(u"Mentions"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'dm':
|
elif i == 'dm':
|
||||||
dm = buffersController.directMessagesController(self.view.nb, "get_direct_messages", "direct_messages", session, session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message", sound="dm_received.ogg", full_text=True, items="events")
|
dm = twitterBuffers.directMessagesController(self.view.nb, "get_direct_messages", "direct_messages", session, session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message", sound="dm_received.ogg", full_text=True, items="events")
|
||||||
self.buffers.append(dm)
|
self.buffers.append(dm)
|
||||||
self.view.insert_buffer(dm.buffer, name=_(u"Direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(dm.buffer, name=_(u"Direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'sent_dm':
|
elif i == 'sent_dm':
|
||||||
sent_dm = buffersController.sentDirectMessagesController(self.view.nb, "", "sent_direct_messages", session, session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message")
|
sent_dm = twitterBuffers.sentDirectMessagesController(self.view.nb, "", "sent_direct_messages", session, session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message")
|
||||||
self.buffers.append(sent_dm)
|
self.buffers.append(sent_dm)
|
||||||
self.view.insert_buffer(sent_dm.buffer, name=_(u"Sent direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(sent_dm.buffer, name=_(u"Sent direct messages"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'sent_tweets':
|
elif i == 'sent_tweets':
|
||||||
sent_tweets = buffersController.baseBufferController(self.view.nb, "get_user_timeline", "sent_tweets", session, session.db["user_name"], screen_name=session.db["user_name"], tweet_mode="extended")
|
sent_tweets = twitterBuffers.baseBufferController(self.view.nb, "get_user_timeline", "sent_tweets", session, session.db["user_name"], screen_name=session.db["user_name"], tweet_mode="extended")
|
||||||
self.buffers.append(sent_tweets)
|
self.buffers.append(sent_tweets)
|
||||||
self.view.insert_buffer(sent_tweets.buffer, name=_(u"Sent tweets"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(sent_tweets.buffer, name=_(u"Sent tweets"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'favorites':
|
elif i == 'favorites':
|
||||||
favourites = buffersController.baseBufferController(self.view.nb, "get_favorites", "favourites", session, session.db["user_name"], sound="favourite.ogg", tweet_mode="extended")
|
favourites = twitterBuffers.baseBufferController(self.view.nb, "get_favorites", "favourites", session, session.db["user_name"], sound="favourite.ogg", tweet_mode="extended")
|
||||||
self.buffers.append(favourites)
|
self.buffers.append(favourites)
|
||||||
self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'followers':
|
elif i == 'followers':
|
||||||
followers = buffersController.peopleBufferController(self.view.nb, "get_followers_list", "followers", session, session.db["user_name"], sound="update_followers.ogg", screen_name=session.db["user_name"])
|
followers = twitterBuffers.peopleBufferController(self.view.nb, "get_followers_list", "followers", session, session.db["user_name"], sound="update_followers.ogg", screen_name=session.db["user_name"])
|
||||||
self.buffers.append(followers)
|
self.buffers.append(followers)
|
||||||
self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'friends':
|
elif i == 'friends':
|
||||||
friends = buffersController.peopleBufferController(self.view.nb, "get_friends_list", "friends", session, session.db["user_name"], screen_name=session.db["user_name"])
|
friends = twitterBuffers.peopleBufferController(self.view.nb, "get_friends_list", "friends", session, session.db["user_name"], screen_name=session.db["user_name"])
|
||||||
self.buffers.append(friends)
|
self.buffers.append(friends)
|
||||||
self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'blocks':
|
elif i == 'blocks':
|
||||||
blocks = buffersController.peopleBufferController(self.view.nb, "list_blocks", "blocked", session, session.db["user_name"])
|
blocks = twitterBuffers.peopleBufferController(self.view.nb, "list_blocks", "blocked", session, session.db["user_name"])
|
||||||
self.buffers.append(blocks)
|
self.buffers.append(blocks)
|
||||||
self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
elif i == 'muted':
|
elif i == 'muted':
|
||||||
muted = buffersController.peopleBufferController(self.view.nb, "list_mutes", "muted", session, session.db["user_name"])
|
muted = twitterBuffers.peopleBufferController(self.view.nb, "list_mutes", "muted", session, session.db["user_name"])
|
||||||
self.buffers.append(muted)
|
self.buffers.append(muted)
|
||||||
self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
timelines = buffersController.emptyPanel(self.view.nb, "timelines", session.db["user_name"])
|
timelines = baseBuffers.emptyPanel(self.view.nb, "timelines", session.db["user_name"])
|
||||||
self.buffers.append(timelines)
|
self.buffers.append(timelines)
|
||||||
self.view.insert_buffer(timelines.buffer , name=_(u"Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(timelines.buffer , name=_(u"Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
for i in session.settings["other_buffers"]["timelines"]:
|
for i in session.settings["other_buffers"]["timelines"]:
|
||||||
tl = buffersController.baseBufferController(self.view.nb, "get_user_timeline", "%s-timeline" % (i,), session, session.db["user_name"], sound="tweet_timeline.ogg", bufferType=None, user_id=i, tweet_mode="extended")
|
tl = twitterBuffers.baseBufferController(self.view.nb, "get_user_timeline", "%s-timeline" % (i,), session, session.db["user_name"], sound="tweet_timeline.ogg", bufferType=None, user_id=i, tweet_mode="extended")
|
||||||
self.buffers.append(tl)
|
self.buffers.append(tl)
|
||||||
self.view.insert_buffer(tl.buffer, name=_(u"Timeline for {}").format(i,), pos=self.view.search("timelines", session.db["user_name"]))
|
self.view.insert_buffer(tl.buffer, name=_(u"Timeline for {}").format(i,), pos=self.view.search("timelines", session.db["user_name"]))
|
||||||
favs_timelines = buffersController.emptyPanel(self.view.nb, "favs_timelines", session.db["user_name"])
|
favs_timelines = baseBuffers.emptyPanel(self.view.nb, "favs_timelines", session.db["user_name"])
|
||||||
self.buffers.append(favs_timelines)
|
self.buffers.append(favs_timelines)
|
||||||
self.view.insert_buffer(favs_timelines.buffer , name=_(u"Likes timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(favs_timelines.buffer , name=_(u"Likes timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
for i in session.settings["other_buffers"]["favourites_timelines"]:
|
for i in session.settings["other_buffers"]["favourites_timelines"]:
|
||||||
tl = buffersController.baseBufferController(self.view.nb, "get_favorites", "%s-favorite" % (i,), session, session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, tweet_mode="extended")
|
tl = twitterBuffers.baseBufferController(self.view.nb, "get_favorites", "%s-favorite" % (i,), session, session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, tweet_mode="extended")
|
||||||
self.buffers.append(tl)
|
self.buffers.append(tl)
|
||||||
self.view.insert_buffer(tl.buffer, name=_(u"Likes for {}").format(i,), pos=self.view.search("favs_timelines", session.db["user_name"]))
|
self.view.insert_buffer(tl.buffer, name=_(u"Likes for {}").format(i,), pos=self.view.search("favs_timelines", session.db["user_name"]))
|
||||||
followers_timelines = buffersController.emptyPanel(self.view.nb, "followers_timelines", session.db["user_name"])
|
followers_timelines = baseBuffers.emptyPanel(self.view.nb, "followers_timelines", session.db["user_name"])
|
||||||
self.buffers.append(followers_timelines)
|
self.buffers.append(followers_timelines)
|
||||||
self.view.insert_buffer(followers_timelines.buffer , name=_(u"Followers' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(followers_timelines.buffer , name=_(u"Followers' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
for i in session.settings["other_buffers"]["followers_timelines"]:
|
for i in session.settings["other_buffers"]["followers_timelines"]:
|
||||||
tl = buffersController.peopleBufferController(self.view.nb, "get_followers_list", "%s-followers" % (i,), session, session.db["user_name"], sound="new_event.ogg", user_id=i)
|
tl = twitterBuffers.peopleBufferController(self.view.nb, "get_followers_list", "%s-followers" % (i,), session, session.db["user_name"], sound="new_event.ogg", user_id=i)
|
||||||
self.buffers.append(tl)
|
self.buffers.append(tl)
|
||||||
self.view.insert_buffer(tl.buffer, name=_(u"Followers for {}").format(i,), pos=self.view.search("followers_timelines", session.db["user_name"]))
|
self.view.insert_buffer(tl.buffer, name=_(u"Followers for {}").format(i,), pos=self.view.search("followers_timelines", session.db["user_name"]))
|
||||||
friends_timelines = buffersController.emptyPanel(self.view.nb, "friends_timelines", session.db["user_name"])
|
friends_timelines = baseBuffers.emptyPanel(self.view.nb, "friends_timelines", session.db["user_name"])
|
||||||
self.buffers.append(friends_timelines)
|
self.buffers.append(friends_timelines)
|
||||||
self.view.insert_buffer(friends_timelines.buffer , name=_(u"Friends' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(friends_timelines.buffer , name=_(u"Friends' Timelines"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
for i in session.settings["other_buffers"]["friends_timelines"]:
|
for i in session.settings["other_buffers"]["friends_timelines"]:
|
||||||
tl = buffersController.peopleBufferController(self.view.nb, "get_friends_list", "%s-friends" % (i,), session, session.db["user_name"], sound="new_event.ogg", user_id=i)
|
tl = twitterBuffers.peopleBufferController(self.view.nb, "get_friends_list", "%s-friends" % (i,), session, session.db["user_name"], sound="new_event.ogg", user_id=i)
|
||||||
self.buffers.append(tl)
|
self.buffers.append(tl)
|
||||||
self.view.insert_buffer(tl.buffer, name=_(u"Friends for {}").format(i,), pos=self.view.search("friends_timelines", session.db["user_name"]))
|
self.view.insert_buffer(tl.buffer, name=_(u"Friends for {}").format(i,), pos=self.view.search("friends_timelines", session.db["user_name"]))
|
||||||
lists = buffersController.emptyPanel(self.view.nb, "lists", session.db["user_name"])
|
lists = baseBuffers.emptyPanel(self.view.nb, "lists", session.db["user_name"])
|
||||||
self.buffers.append(lists)
|
self.buffers.append(lists)
|
||||||
self.view.insert_buffer(lists.buffer , name=_(u"Lists"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(lists.buffer , name=_(u"Lists"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
for i in session.settings["other_buffers"]["lists"]:
|
for i in session.settings["other_buffers"]["lists"]:
|
||||||
tl = buffersController.listBufferController(self.view.nb, "get_list_statuses", "%s-list" % (i,), session, session.db["user_name"], bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), tweet_mode="extended")
|
tl = twitterBuffers.listBufferController(self.view.nb, "get_list_statuses", "%s-list" % (i,), session, session.db["user_name"], bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), tweet_mode="extended")
|
||||||
session.lists.append(tl)
|
session.lists.append(tl)
|
||||||
self.buffers.append(tl)
|
self.buffers.append(tl)
|
||||||
self.view.insert_buffer(tl.buffer, name=_(u"List for {}").format(i), pos=self.view.search("lists", session.db["user_name"]))
|
self.view.insert_buffer(tl.buffer, name=_(u"List for {}").format(i), pos=self.view.search("lists", session.db["user_name"]))
|
||||||
searches = buffersController.emptyPanel(self.view.nb, "searches", session.db["user_name"])
|
searches = baseBuffers.emptyPanel(self.view.nb, "searches", session.db["user_name"])
|
||||||
self.buffers.append(searches)
|
self.buffers.append(searches)
|
||||||
self.view.insert_buffer(searches.buffer , name=_(u"Searches"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
self.view.insert_buffer(searches.buffer , name=_(u"Searches"), pos=self.view.search(session.db["user_name"], session.db["user_name"]))
|
||||||
for i in session.settings["other_buffers"]["tweet_searches"]:
|
for i in session.settings["other_buffers"]["tweet_searches"]:
|
||||||
tl = buffersController.searchBufferController(self.view.nb, "search", "%s-searchterm" % (i,), session, session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=i, tweet_mode="extended")
|
tl = twitterBuffers.searchBufferController(self.view.nb, "search", "%s-searchterm" % (i,), session, session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=i, tweet_mode="extended")
|
||||||
self.buffers.append(tl)
|
self.buffers.append(tl)
|
||||||
self.view.insert_buffer(tl.buffer, name=_(u"Search for {}").format(i), pos=self.view.search("searches", session.db["user_name"]))
|
self.view.insert_buffer(tl.buffer, name=_(u"Search for {}").format(i), pos=self.view.search("searches", session.db["user_name"]))
|
||||||
for i in session.settings["other_buffers"]["trending_topic_buffers"]:
|
for i in session.settings["other_buffers"]["trending_topic_buffers"]:
|
||||||
buffer = buffersController.trendsBufferController(self.view.nb, "%s_tt" % (i,), session, session.db["user_name"], i, sound="trends_updated.ogg")
|
buffer = twitterBuffers.trendsBufferController(self.view.nb, "%s_tt" % (i,), session, session.db["user_name"], i, sound="trends_updated.ogg")
|
||||||
buffer.start_stream(play_sound=False)
|
buffer.start_stream(play_sound=False)
|
||||||
buffer.searchfunction = self.search
|
buffer.searchfunction = self.search
|
||||||
self.buffers.append(buffer)
|
self.buffers.append(buffer)
|
||||||
@@ -430,12 +431,12 @@ class Controller(object):
|
|||||||
buffer.session.settings["other_buffers"]["tweet_searches"].append(term)
|
buffer.session.settings["other_buffers"]["tweet_searches"].append(term)
|
||||||
buffer.session.settings.write()
|
buffer.session.settings.write()
|
||||||
args = {"lang": dlg.get_language(), "result_type": dlg.get_result_type()}
|
args = {"lang": dlg.get_language(), "result_type": dlg.get_result_type()}
|
||||||
search = buffersController.searchBufferController(self.view.nb, "search", "%s-searchterm" % (term,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=term, tweet_mode="extended", **args)
|
search = twitterBuffers.searchBufferController(self.view.nb, "search", "%s-searchterm" % (term,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=term, tweet_mode="extended", **args)
|
||||||
else:
|
else:
|
||||||
log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,))
|
log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,))
|
||||||
return
|
return
|
||||||
elif dlg.get("users") == True:
|
elif dlg.get("users") == True:
|
||||||
search = buffersController.searchPeopleBufferController(self.view.nb, "search_users", "%s-searchUser" % (term,), buffer.session, buffer.session.db["user_name"], bufferType=None, sound="search_updated.ogg", q=term)
|
search = twitterBuffers.searchPeopleBufferController(self.view.nb, "search_users", "%s-searchUser" % (term,), buffer.session, buffer.session.db["user_name"], bufferType=None, sound="search_updated.ogg", q=term)
|
||||||
search.start_stream(mandatory=True)
|
search.start_stream(mandatory=True)
|
||||||
pos=self.view.search("searches", buffer.session.db["user_name"])
|
pos=self.view.search("searches", buffer.session.db["user_name"])
|
||||||
self.insert_buffer(search, pos)
|
self.insert_buffer(search, pos)
|
||||||
@@ -742,25 +743,25 @@ class Controller(object):
|
|||||||
|
|
||||||
def post_tweet(self, event=None):
|
def post_tweet(self, event=None):
|
||||||
buffer = self.get_best_buffer()
|
buffer = self.get_best_buffer()
|
||||||
buffer.post_tweet()
|
buffer.post_status()
|
||||||
|
|
||||||
def post_reply(self, *args, **kwargs):
|
def post_reply(self, *args, **kwargs):
|
||||||
buffer = self.get_current_buffer()
|
buffer = self.get_current_buffer()
|
||||||
if buffer.name == "direct_messages":
|
if buffer.name == "direct_messages":
|
||||||
buffer.direct_message()
|
buffer.send_message()
|
||||||
else:
|
else:
|
||||||
buffer.reply()
|
buffer.reply()
|
||||||
|
|
||||||
def send_dm(self, *args, **kwargs):
|
def send_dm(self, *args, **kwargs):
|
||||||
buffer = self.get_current_buffer()
|
buffer = self.get_current_buffer()
|
||||||
buffer.direct_message()
|
buffer.send_message()
|
||||||
|
|
||||||
def post_retweet(self, *args, **kwargs):
|
def post_retweet(self, *args, **kwargs):
|
||||||
buffer = self.get_current_buffer()
|
buffer = self.get_current_buffer()
|
||||||
if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events":
|
if buffer.type == "dm" or buffer.type == "people" or buffer.type == "events":
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
buffer.retweet()
|
buffer.share_item()
|
||||||
|
|
||||||
def add_to_favourites(self, *args, **kwargs):
|
def add_to_favourites(self, *args, **kwargs):
|
||||||
buffer = self.get_current_buffer()
|
buffer = self.get_current_buffer()
|
||||||
@@ -792,14 +793,17 @@ class Controller(object):
|
|||||||
|
|
||||||
def view_item(self, *args, **kwargs):
|
def view_item(self, *args, **kwargs):
|
||||||
buffer = self.get_current_buffer()
|
buffer = self.get_current_buffer()
|
||||||
if buffer.type == "baseBuffer" or buffer.type == "favourites_timeline" or buffer.type == "list" or buffer.type == "search":
|
if buffer.type == "account" or buffer.type == "empty":
|
||||||
tweet, tweetsList = buffer.get_full_tweet()
|
|
||||||
msg = messages.viewTweet(tweet, tweetsList)
|
|
||||||
elif buffer.type == "account" or buffer.type == "empty":
|
|
||||||
return
|
return
|
||||||
elif buffer.name == "sent_tweets":
|
elif buffer.type == "baseBuffer" or buffer.type == "favourites_timeline" or buffer.type == "list" or buffer.type == "search":
|
||||||
tweet, tweetsList = buffer.get_full_tweet()
|
tweet, tweetsList = buffer.get_full_tweet()
|
||||||
msg = messages.viewTweet(tweet, tweetsList)
|
msg = messages.viewTweet(tweet, tweetsList, utc_offset=buffer.session.db["utc_offset"])
|
||||||
|
elif buffer.type == "dm":
|
||||||
|
non_tweet = buffer.get_formatted_message()
|
||||||
|
item = buffer.get_right_tweet()
|
||||||
|
original_date = arrow.get(item["created_timestamp"][:-3])
|
||||||
|
date = original_date.replace(seconds=buffer.session.db["utc_offset"]).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage())
|
||||||
|
msg = messages.viewTweet(non_tweet, [], False, date=date)
|
||||||
else:
|
else:
|
||||||
non_tweet = buffer.get_formatted_message()
|
non_tweet = buffer.get_formatted_message()
|
||||||
msg = messages.viewTweet(non_tweet, [], False)
|
msg = messages.viewTweet(non_tweet, [], False)
|
||||||
@@ -836,7 +840,7 @@ class Controller(object):
|
|||||||
if usr["id_str"] in buff.session.settings["other_buffers"]["timelines"]:
|
if usr["id_str"] in buff.session.settings["other_buffers"]["timelines"]:
|
||||||
commonMessageDialogs.timeline_exist()
|
commonMessageDialogs.timeline_exist()
|
||||||
return
|
return
|
||||||
tl = buffersController.baseBufferController(self.view.nb, "get_user_timeline", "%s-timeline" % (usr["id_str"],), buff.session, buff.session.db["user_name"], bufferType=None, sound="tweet_timeline.ogg", user_id=usr["id_str"], tweet_mode="extended")
|
tl = twitterBuffers.baseBufferController(self.view.nb, "get_user_timeline", "%s-timeline" % (usr["id_str"],), buff.session, buff.session.db["user_name"], bufferType=None, sound="tweet_timeline.ogg", user_id=usr["id_str"], tweet_mode="extended")
|
||||||
try:
|
try:
|
||||||
tl.start_stream(play_sound=False)
|
tl.start_stream(play_sound=False)
|
||||||
except TwythonAuthError:
|
except TwythonAuthError:
|
||||||
@@ -855,7 +859,7 @@ class Controller(object):
|
|||||||
if usr["id_str"] in buff.session.settings["other_buffers"]["favourites_timelines"]:
|
if usr["id_str"] in buff.session.settings["other_buffers"]["favourites_timelines"]:
|
||||||
commonMessageDialogs.timeline_exist()
|
commonMessageDialogs.timeline_exist()
|
||||||
return
|
return
|
||||||
tl = buffersController.baseBufferController(self.view.nb, "get_favorites", "%s-favorite" % (usr["id_str"],), buff.session, buff.session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=usr["id_str"], tweet_mode="extended")
|
tl = twitterBuffers.baseBufferController(self.view.nb, "get_favorites", "%s-favorite" % (usr["id_str"],), buff.session, buff.session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=usr["id_str"], tweet_mode="extended")
|
||||||
try:
|
try:
|
||||||
tl.start_stream(play_sound=False)
|
tl.start_stream(play_sound=False)
|
||||||
except TwythonAuthError:
|
except TwythonAuthError:
|
||||||
@@ -874,7 +878,7 @@ class Controller(object):
|
|||||||
if usr["id_str"] in buff.session.settings["other_buffers"]["followers_timelines"]:
|
if usr["id_str"] in buff.session.settings["other_buffers"]["followers_timelines"]:
|
||||||
commonMessageDialogs.timeline_exist()
|
commonMessageDialogs.timeline_exist()
|
||||||
return
|
return
|
||||||
tl = buffersController.peopleBufferController(self.view.nb, "get_followers_list", "%s-followers" % (usr["id_str"],), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr["id_str"])
|
tl = twitterBuffers.peopleBufferController(self.view.nb, "get_followers_list", "%s-followers" % (usr["id_str"],), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr["id_str"])
|
||||||
try:
|
try:
|
||||||
tl.start_stream(play_sound=False)
|
tl.start_stream(play_sound=False)
|
||||||
except TwythonAuthError:
|
except TwythonAuthError:
|
||||||
@@ -893,7 +897,7 @@ class Controller(object):
|
|||||||
if usr["id_str"] in buff.session.settings["other_buffers"]["friends_timelines"]:
|
if usr["id_str"] in buff.session.settings["other_buffers"]["friends_timelines"]:
|
||||||
commonMessageDialogs.timeline_exist()
|
commonMessageDialogs.timeline_exist()
|
||||||
return
|
return
|
||||||
tl = buffersController.peopleBufferController(self.view.nb, "get_friends_list", "%s-friends" % (usr["id_str"],), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr["id_str"])
|
tl = twitterBuffers.peopleBufferController(self.view.nb, "get_friends_list", "%s-friends" % (usr["id_str"],), buff.session, buff.session.db["user_name"], sound="new_event.ogg", user_id=usr["id_str"])
|
||||||
try:
|
try:
|
||||||
tl.start_stream(play_sound=False)
|
tl.start_stream(play_sound=False)
|
||||||
except TwythonAuthError:
|
except TwythonAuthError:
|
||||||
@@ -913,7 +917,7 @@ class Controller(object):
|
|||||||
buffer = self.get_current_buffer()
|
buffer = self.get_current_buffer()
|
||||||
id = buffer.get_right_tweet()["id_str"]
|
id = buffer.get_right_tweet()["id_str"]
|
||||||
user = buffer.get_right_tweet()["user"]["screen_name"]
|
user = buffer.get_right_tweet()["user"]["screen_name"]
|
||||||
search = buffersController.conversationBufferController(self.view.nb, "search", "%s-searchterm" % (id,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", since_id=id, q="@{0}".format(user,))
|
search = twitterBuffers.conversationBufferController(self.view.nb, "search", "%s-searchterm" % (id,), buffer.session, buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", since_id=id, q="@{0}".format(user,))
|
||||||
search.tweet = buffer.get_right_tweet()
|
search.tweet = buffer.get_right_tweet()
|
||||||
search.start_stream(start=True)
|
search.start_stream(start=True)
|
||||||
pos=self.view.search("searches", buffer.session.db["user_name"])
|
pos=self.view.search("searches", buffer.session.db["user_name"])
|
||||||
@@ -940,7 +944,7 @@ class Controller(object):
|
|||||||
if trends.dialog.get_response() == widgetUtils.OK:
|
if trends.dialog.get_response() == widgetUtils.OK:
|
||||||
woeid = trends.get_woeid()
|
woeid = trends.get_woeid()
|
||||||
if woeid in buff.session.settings["other_buffers"]["trending_topic_buffers"]: return
|
if woeid in buff.session.settings["other_buffers"]["trending_topic_buffers"]: return
|
||||||
buffer = buffersController.trendsBufferController(self.view.nb, "%s_tt" % (woeid,), buff.session, buff.account, woeid, sound="trends_updated.ogg")
|
buffer = twitterBuffers.trendsBufferController(self.view.nb, "%s_tt" % (woeid,), buff.session, buff.account, woeid, sound="trends_updated.ogg")
|
||||||
buffer.searchfunction = self.search
|
buffer.searchfunction = self.search
|
||||||
pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])
|
pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"])
|
||||||
self.view.insert_buffer(buffer.buffer, name=_(u"Trending topics for %s") % (trends.get_string()), pos=pos)
|
self.view.insert_buffer(buffer.buffer, name=_(u"Trending topics for %s") % (trends.get_string()), pos=pos)
|
||||||
@@ -1258,6 +1262,10 @@ class Controller(object):
|
|||||||
if buffer == None: return
|
if buffer == None: return
|
||||||
# if "sent_tweets" not in buffer.session.settings["other_buffers"]["muted_buffers"]:
|
# if "sent_tweets" not in buffer.session.settings["other_buffers"]["muted_buffers"]:
|
||||||
# self.notify(buffer.session, play_sound=play_sound)
|
# self.notify(buffer.session, play_sound=play_sound)
|
||||||
|
data = buffer.session.check_quoted_status(data)
|
||||||
|
data = buffer.session.check_long_tweet(data)
|
||||||
|
if data == False: # Long tweet deleted from twishort.
|
||||||
|
return
|
||||||
if buffer.session.settings["general"]["reverse_timelines"] == False:
|
if buffer.session.settings["general"]["reverse_timelines"] == False:
|
||||||
buffer.session.db[buffer.name].append(data)
|
buffer.session.db[buffer.name].append(data)
|
||||||
else:
|
else:
|
||||||
@@ -1341,32 +1349,32 @@ class Controller(object):
|
|||||||
buff = self.search_buffer("home_timeline", account)
|
buff = self.search_buffer("home_timeline", account)
|
||||||
if create == True:
|
if create == True:
|
||||||
if buffer == "favourites":
|
if buffer == "favourites":
|
||||||
favourites = buffersController.baseBufferController(self.view.nb, "get_favorites", "favourites", buff.session, buff.session.db["user_name"], tweet_mode="extended")
|
favourites = twitterBuffers.baseBufferController(self.view.nb, "get_favorites", "favourites", buff.session, buff.session.db["user_name"], tweet_mode="extended")
|
||||||
self.buffers.append(favourites)
|
self.buffers.append(favourites)
|
||||||
self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
self.view.insert_buffer(favourites.buffer, name=_(u"Likes"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||||
favourites.start_stream(play_sound=False)
|
favourites.start_stream(play_sound=False)
|
||||||
if buffer == "followers":
|
if buffer == "followers":
|
||||||
followers = buffersController.peopleBufferController(self.view.nb, "get_followers_list", "followers", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"])
|
followers = twitterBuffers.peopleBufferController(self.view.nb, "get_followers_list", "followers", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"])
|
||||||
self.buffers.append(followers)
|
self.buffers.append(followers)
|
||||||
self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
self.view.insert_buffer(followers.buffer, name=_(u"Followers"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||||
followers.start_stream(play_sound=False)
|
followers.start_stream(play_sound=False)
|
||||||
elif buffer == "friends":
|
elif buffer == "friends":
|
||||||
friends = buffersController.peopleBufferController(self.view.nb, "get_friends_list", "friends", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"])
|
friends = twitterBuffers.peopleBufferController(self.view.nb, "get_friends_list", "friends", buff.session, buff.session.db["user_name"], screen_name=buff.session.db["user_name"])
|
||||||
self.buffers.append(friends)
|
self.buffers.append(friends)
|
||||||
self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
self.view.insert_buffer(friends.buffer, name=_(u"Friends"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||||
friends.start_stream(play_sound=False)
|
friends.start_stream(play_sound=False)
|
||||||
elif buffer == "blocked":
|
elif buffer == "blocked":
|
||||||
blocks = buffersController.peopleBufferController(self.view.nb, "list_blocks", "blocked", buff.session, buff.session.db["user_name"])
|
blocks = twitterBuffers.peopleBufferController(self.view.nb, "list_blocks", "blocked", buff.session, buff.session.db["user_name"])
|
||||||
self.buffers.append(blocks)
|
self.buffers.append(blocks)
|
||||||
self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
self.view.insert_buffer(blocks.buffer, name=_(u"Blocked users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||||
blocks.start_stream(play_sound=False)
|
blocks.start_stream(play_sound=False)
|
||||||
elif buffer == "muted":
|
elif buffer == "muted":
|
||||||
muted = buffersController.peopleBufferController(self.view.nb, "get_muted_users_list", "muted", buff.session, buff.session.db["user_name"])
|
muted = twitterBuffers.peopleBufferController(self.view.nb, "get_muted_users_list", "muted", buff.session, buff.session.db["user_name"])
|
||||||
self.buffers.append(muted)
|
self.buffers.append(muted)
|
||||||
self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
self.view.insert_buffer(muted.buffer, name=_(u"Muted users"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||||
muted.start_stream(play_sound=False)
|
muted.start_stream(play_sound=False)
|
||||||
elif buffer == "events":
|
elif buffer == "events":
|
||||||
events = buffersController.eventsBufferController(self.view.nb, "events", buff.session, buff.session.db["user_name"], bufferType="dmPanel", screen_name=buff.session.db["user_name"])
|
events = twitterBuffers.eventsBufferController(self.view.nb, "events", buff.session, buff.session.db["user_name"], bufferType="dmPanel", screen_name=buff.session.db["user_name"])
|
||||||
self.buffers.append(events)
|
self.buffers.append(events)
|
||||||
self.view.insert_buffer(events.buffer, name=_(u"Events"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
self.view.insert_buffer(events.buffer, name=_(u"Events"), pos=self.view.search(buff.session.db["user_name"], buff.session.db["user_name"]))
|
||||||
elif create == False:
|
elif create == False:
|
||||||
@@ -1375,7 +1383,7 @@ class Controller(object):
|
|||||||
if create in buff.session.settings["other_buffers"]["lists"]:
|
if create in buff.session.settings["other_buffers"]["lists"]:
|
||||||
output.speak(_(u"This list is already opened"), True)
|
output.speak(_(u"This list is already opened"), True)
|
||||||
return
|
return
|
||||||
tl = buffersController.listBufferController(self.view.nb, "get_list_statuses", create+"-list", buff.session, buff.session.db["user_name"], bufferType=None, list_id=utils.find_list(create, buff.session.db["lists"]), tweet_mode="extended")
|
tl = twitterBuffers.listBufferController(self.view.nb, "get_list_statuses", create+"-list", buff.session, buff.session.db["user_name"], bufferType=None, list_id=utils.find_list(create, buff.session.db["lists"]), tweet_mode="extended")
|
||||||
buff.session.lists.append(tl)
|
buff.session.lists.append(tl)
|
||||||
pos=self.view.search("lists", buff.session.db["user_name"])
|
pos=self.view.search("lists", buff.session.db["user_name"])
|
||||||
self.insert_buffer(tl, pos)
|
self.insert_buffer(tl, pos)
|
||||||
@@ -1533,7 +1541,7 @@ class Controller(object):
|
|||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
output.speak(_(u"Updating buffer..."))
|
output.speak(_(u"Updating buffer..."))
|
||||||
n = bf.start_stream(mandatory=True)
|
n = bf.start_stream(mandatory=True, avoid_autoreading=True)
|
||||||
if n != None:
|
if n != None:
|
||||||
output.speak(_(u"{0} items retrieved").format(n,))
|
output.speak(_(u"{0} items retrieved").format(n,))
|
||||||
|
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
import re
|
import re
|
||||||
import platform
|
import platform
|
||||||
import attach
|
import attach
|
||||||
|
import arrow
|
||||||
|
import languageHandler
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
import widgetUtils
|
import widgetUtils
|
||||||
import output
|
import output
|
||||||
@@ -193,7 +195,7 @@ class dm(basicTweet):
|
|||||||
c.show_menu("dm")
|
c.show_menu("dm")
|
||||||
|
|
||||||
class viewTweet(basicTweet):
|
class viewTweet(basicTweet):
|
||||||
def __init__(self, tweet, tweetList, is_tweet=True):
|
def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date=""):
|
||||||
""" This represents a tweet displayer. However it could be used for showing something wich is not a tweet, like a direct message or an event.
|
""" This represents a tweet displayer. However it could be used for showing something wich is not a tweet, like a direct message or an event.
|
||||||
param tweet: A dictionary that represents a full tweet or a string for non-tweets.
|
param tweet: A dictionary that represents a full tweet or a string for non-tweets.
|
||||||
param tweetList: If is_tweet is set to True, this could be a list of quoted tweets.
|
param tweetList: If is_tweet is set to True, this could be a list of quoted tweets.
|
||||||
@@ -229,6 +231,8 @@ class viewTweet(basicTweet):
|
|||||||
favs_count = str(tweet["favorite_count"])
|
favs_count = str(tweet["favorite_count"])
|
||||||
# Gets the client from where this tweet was made.
|
# Gets the client from where this tweet was made.
|
||||||
source = str(re.sub(r"(?s)<.*?>", "", tweet["source"].encode("utf-8")))
|
source = str(re.sub(r"(?s)<.*?>", "", tweet["source"].encode("utf-8")))
|
||||||
|
original_date = arrow.get(tweet["created_at"], "ddd MMM DD H:m:s Z YYYY", locale="en")
|
||||||
|
date = original_date.replace(seconds=utc_offset).format(_(u"MMM D, YYYY. H:m"), locale=languageHandler.getLanguage())
|
||||||
if text == "":
|
if text == "":
|
||||||
if tweet.has_key("message"):
|
if tweet.has_key("message"):
|
||||||
value = "message"
|
value = "message"
|
||||||
@@ -250,13 +254,13 @@ class viewTweet(basicTweet):
|
|||||||
for z in tweet["retweeted_status"]["extended_entities"]["media"]:
|
for z in tweet["retweeted_status"]["extended_entities"]["media"]:
|
||||||
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None:
|
if z.has_key("ext_alt_text") and z["ext_alt_text"] != None:
|
||||||
image_description.append(z["ext_alt_text"])
|
image_description.append(z["ext_alt_text"])
|
||||||
self.message = message.viewTweet(text, rt_count, favs_count, source.decode("utf-8"))
|
self.message = message.viewTweet(text, rt_count, favs_count, source.decode("utf-8"), date)
|
||||||
self.message.set_title(len(text))
|
self.message.set_title(len(text))
|
||||||
[self.message.set_image_description(i) for i in image_description]
|
[self.message.set_image_description(i) for i in image_description]
|
||||||
else:
|
else:
|
||||||
self.title = _(u"View item")
|
self.title = _(u"View item")
|
||||||
text = tweet
|
text = tweet
|
||||||
self.message = message.viewNonTweet(text)
|
self.message = message.viewNonTweet(text, date)
|
||||||
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
|
widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck)
|
||||||
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
|
widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate)
|
||||||
if self.contain_urls() == True:
|
if self.contain_urls() == True:
|
||||||
|
@@ -50,6 +50,7 @@ actions = {
|
|||||||
"check_for_updates": _(u"Check and download updates"),
|
"check_for_updates": _(u"Check and download updates"),
|
||||||
"lists_manager": _(u"Opens the list manager, which allows you to create, edit, delete and open lists in buffers."),
|
"lists_manager": _(u"Opens the list manager, which allows you to create, edit, delete and open lists in buffers."),
|
||||||
"configuration": _(u"Opens the global settings dialogue"),
|
"configuration": _(u"Opens the global settings dialogue"),
|
||||||
|
"list_manager": _(u"Opens the list manager"),
|
||||||
"accountConfiguration": _(u"Opens the account settings dialogue"),
|
"accountConfiguration": _(u"Opens the account settings dialogue"),
|
||||||
"audio": _(u"Try to play an audio file"),
|
"audio": _(u"Try to play an audio file"),
|
||||||
"update_buffer": _(u"Updates the buffer and retrieves possible lost items there."),
|
"update_buffer": _(u"Updates the buffer and retrieves possible lost items there."),
|
||||||
|
@@ -19,7 +19,7 @@ Questions, comments? ryan@venodesigns.net
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'Ryan McGrath <ryan@venodesigns.net>'
|
__author__ = 'Ryan McGrath <ryan@venodesigns.net>'
|
||||||
__version__ = '3.6.0'
|
__version__ = '3.7.0'
|
||||||
|
|
||||||
from .api import Twython
|
from .api import Twython
|
||||||
from .streaming import TwythonStreamer
|
from .streaming import TwythonStreamer
|
||||||
|
@@ -19,6 +19,7 @@ from requests_oauthlib import OAuth1, OAuth2
|
|||||||
from . import __version__
|
from . import __version__
|
||||||
from .advisory import TwythonDeprecationWarning
|
from .advisory import TwythonDeprecationWarning
|
||||||
from .compat import json, urlencode, parse_qsl, quote_plus, str, is_py2
|
from .compat import json, urlencode, parse_qsl, quote_plus, str, is_py2
|
||||||
|
from .compat import urlsplit
|
||||||
from .endpoints import EndpointsMixin
|
from .endpoints import EndpointsMixin
|
||||||
from .exceptions import TwythonError, TwythonAuthError, TwythonRateLimitError
|
from .exceptions import TwythonError, TwythonAuthError, TwythonRateLimitError
|
||||||
from .helpers import _transparent_params
|
from .helpers import _transparent_params
|
||||||
@@ -134,13 +135,13 @@ class Twython(EndpointsMixin, object):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Twython: %s>' % (self.app_key)
|
return '<Twython: %s>' % (self.app_key)
|
||||||
|
|
||||||
def _request(self, url, method='GET', params=None, api_call=None, encode_json=False):
|
def _request(self, url, method='GET', params=None, api_call=None, json_encoded=False):
|
||||||
"""Internal request method"""
|
"""Internal request method"""
|
||||||
method = method.lower()
|
method = method.lower()
|
||||||
params = params or {}
|
params = params or {}
|
||||||
|
|
||||||
func = getattr(self.client, method)
|
func = getattr(self.client, method)
|
||||||
if type(params) is dict and encode_json == False:
|
if isinstance(params, dict) and json_encoded == False:
|
||||||
params, files = _transparent_params(params)
|
params, files = _transparent_params(params)
|
||||||
else:
|
else:
|
||||||
params = params
|
params = params
|
||||||
@@ -152,18 +153,17 @@ class Twython(EndpointsMixin, object):
|
|||||||
if k in ('timeout', 'allow_redirects', 'stream', 'verify'):
|
if k in ('timeout', 'allow_redirects', 'stream', 'verify'):
|
||||||
requests_args[k] = v
|
requests_args[k] = v
|
||||||
|
|
||||||
if method == 'get':
|
if method == 'get' or method == 'delete':
|
||||||
requests_args['params'] = params
|
requests_args['params'] = params
|
||||||
else:
|
else:
|
||||||
|
# Check for json_encoded so we will sent params as "data" or "json"
|
||||||
if encode_json == False:
|
if json_encoded:
|
||||||
requests_args.update({
|
data_key = "json"
|
||||||
'files': files,
|
|
||||||
'data': params,
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
|
data_key = "data"
|
||||||
requests_args.update({
|
requests_args.update({
|
||||||
'json': params,
|
data_key: params,
|
||||||
|
'files': files,
|
||||||
})
|
})
|
||||||
try:
|
try:
|
||||||
response = func(url, **requests_args)
|
response = func(url, **requests_args)
|
||||||
@@ -202,14 +202,14 @@ class Twython(EndpointsMixin, object):
|
|||||||
error_message,
|
error_message,
|
||||||
error_code=response.status_code,
|
error_code=response.status_code,
|
||||||
retry_after=response.headers.get('X-Rate-Limit-Reset'))
|
retry_after=response.headers.get('X-Rate-Limit-Reset'))
|
||||||
content=""
|
content = ''
|
||||||
try:
|
try:
|
||||||
if response.status_code == 204:
|
if response.status_code == 204:
|
||||||
content = response.content
|
content = response.content
|
||||||
else:
|
else:
|
||||||
content = response.json()
|
content = response.json()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if response.content!="":
|
if response.content != '':
|
||||||
raise TwythonError('Response was not valid JSON. \
|
raise TwythonError('Response was not valid JSON. \
|
||||||
Unable to decode.')
|
Unable to decode.')
|
||||||
|
|
||||||
@@ -235,14 +235,14 @@ class Twython(EndpointsMixin, object):
|
|||||||
|
|
||||||
return error_message
|
return error_message
|
||||||
|
|
||||||
def request(self, endpoint, method='GET', params=None, version='1.1', encode_json=False):
|
def request(self, endpoint, method='GET', params=None, version='1.1', json_encoded=False):
|
||||||
"""Return dict of response received from Twitter's API
|
"""Return dict of response received from Twitter's API
|
||||||
|
|
||||||
:param endpoint: (required) Full url or Twitter API endpoint
|
:param endpoint: (required) Full url or Twitter API endpoint
|
||||||
(e.g. search/tweets)
|
(e.g. search/tweets)
|
||||||
:type endpoint: string
|
:type endpoint: string
|
||||||
:param method: (optional) Method of accessing data, either
|
:param method: (optional) Method of accessing data, either
|
||||||
GET or POST. (default GET)
|
GET, POST or DELETE. (default GET)
|
||||||
:type method: string
|
:type method: string
|
||||||
:param params: (optional) Dict of parameters (if any) accepted
|
:param params: (optional) Dict of parameters (if any) accepted
|
||||||
the by Twitter API endpoint you are trying to
|
the by Twitter API endpoint you are trying to
|
||||||
@@ -251,6 +251,9 @@ class Twython(EndpointsMixin, object):
|
|||||||
:param version: (optional) Twitter API version to access
|
:param version: (optional) Twitter API version to access
|
||||||
(default 1.1)
|
(default 1.1)
|
||||||
:type version: string
|
:type version: string
|
||||||
|
:param json_encoded: (optional) Flag to indicate if this method should send data encoded as json
|
||||||
|
(default False)
|
||||||
|
:type json_encoded: bool
|
||||||
|
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
@@ -266,7 +269,7 @@ class Twython(EndpointsMixin, object):
|
|||||||
url = '%s/%s.json' % (self.api_url % version, endpoint)
|
url = '%s/%s.json' % (self.api_url % version, endpoint)
|
||||||
|
|
||||||
content = self._request(url, method=method, params=params,
|
content = self._request(url, method=method, params=params,
|
||||||
api_call=url, encode_json=encode_json)
|
api_call=url, json_encoded=json_encoded)
|
||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
@@ -274,9 +277,13 @@ class Twython(EndpointsMixin, object):
|
|||||||
"""Shortcut for GET requests via :class:`request`"""
|
"""Shortcut for GET requests via :class:`request`"""
|
||||||
return self.request(endpoint, params=params, version=version)
|
return self.request(endpoint, params=params, version=version)
|
||||||
|
|
||||||
def post(self, endpoint, params=None, version='1.1', encode_json=False):
|
def post(self, endpoint, params=None, version='1.1', json_encoded=False):
|
||||||
"""Shortcut for POST requests via :class:`request`"""
|
"""Shortcut for POST requests via :class:`request`"""
|
||||||
return self.request(endpoint, 'POST', params=params, version=version, encode_json=encode_json)
|
return self.request(endpoint, 'POST', params=params, version=version, json_encoded=json_encoded)
|
||||||
|
|
||||||
|
def delete(self, endpoint, params=None, version='1.1', json_encoded=False):
|
||||||
|
"""Shortcut for delete requests via :class:`request`"""
|
||||||
|
return self.request(endpoint, 'DELETE', params=params, version=version, json_encoded=json_encoded)
|
||||||
|
|
||||||
def get_lastfunction_header(self, header, default_return_value=None):
|
def get_lastfunction_header(self, header, default_return_value=None):
|
||||||
"""Returns a specific header from the last API call
|
"""Returns a specific header from the last API call
|
||||||
@@ -513,19 +520,27 @@ class Twython(EndpointsMixin, object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if function.iter_mode == 'id':
|
if function.iter_mode == 'id':
|
||||||
if 'max_id' not in params:
|
# Set max_id in params to one less than lowest tweet id
|
||||||
# Add 1 to the id because since_id and
|
|
||||||
# max_id are inclusive
|
|
||||||
if hasattr(function, 'iter_metadata'):
|
if hasattr(function, 'iter_metadata'):
|
||||||
since_id = content[function.iter_metadata].get('since_id_str')
|
# Get supplied next max_id
|
||||||
|
metadata = content.get(function.iter_metadata)
|
||||||
|
if 'next_results' in metadata:
|
||||||
|
next_results = urlsplit(metadata['next_results'])
|
||||||
|
params = dict(parse_qsl(next_results.query))
|
||||||
else:
|
else:
|
||||||
since_id = content[0]['id_str']
|
# No more results
|
||||||
params['since_id'] = (int(since_id) - 1)
|
raise StopIteration
|
||||||
|
else:
|
||||||
|
# Twitter gives tweets in reverse chronological order:
|
||||||
|
params['max_id'] = str(int(content[-1]['id_str']) - 1)
|
||||||
elif function.iter_mode == 'cursor':
|
elif function.iter_mode == 'cursor':
|
||||||
params['cursor'] = content['next_cursor_str']
|
params['cursor'] = content['next_cursor_str']
|
||||||
except (TypeError, ValueError): # pragma: no cover
|
except (TypeError, ValueError): # pragma: no cover
|
||||||
raise TwythonError('Unable to generate next page of search \
|
raise TwythonError('Unable to generate next page of search \
|
||||||
results, `page` is not a number.')
|
results, `page` is not a number.')
|
||||||
|
except (KeyError, AttributeError): #pragma no cover
|
||||||
|
raise TwythonError('Unable to generate next page of search \
|
||||||
|
results, content has unexpected structure.')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unicode2utf8(text):
|
def unicode2utf8(text):
|
||||||
@@ -587,6 +602,8 @@ class Twython(EndpointsMixin, object):
|
|||||||
|
|
||||||
if display_text_start <= temp['start'] <= display_text_end:
|
if display_text_start <= temp['start'] <= display_text_end:
|
||||||
temp['replacement'] = mention_html
|
temp['replacement'] = mention_html
|
||||||
|
temp['start'] -= display_text_start
|
||||||
|
temp['end'] -= display_text_start
|
||||||
entities.append(temp)
|
entities.append(temp)
|
||||||
else:
|
else:
|
||||||
# Make the '@username' at the start, before
|
# Make the '@username' at the start, before
|
||||||
@@ -598,8 +615,8 @@ class Twython(EndpointsMixin, object):
|
|||||||
if 'hashtags' in tweet['entities']:
|
if 'hashtags' in tweet['entities']:
|
||||||
for entity in tweet['entities']['hashtags']:
|
for entity in tweet['entities']['hashtags']:
|
||||||
temp = {}
|
temp = {}
|
||||||
temp['start'] = entity['indices'][0]
|
temp['start'] = entity['indices'][0] - display_text_start
|
||||||
temp['end'] = entity['indices'][1]
|
temp['end'] = entity['indices'][1] - display_text_start
|
||||||
|
|
||||||
url_html = '<a href="https://twitter.com/search?q=%%23%(hashtag)s" class="twython-hashtag">#%(hashtag)s</a>' % {'hashtag': entity['text']}
|
url_html = '<a href="https://twitter.com/search?q=%%23%(hashtag)s" class="twython-hashtag">#%(hashtag)s</a>' % {'hashtag': entity['text']}
|
||||||
|
|
||||||
@@ -610,8 +627,8 @@ class Twython(EndpointsMixin, object):
|
|||||||
if 'symbols' in tweet['entities']:
|
if 'symbols' in tweet['entities']:
|
||||||
for entity in tweet['entities']['symbols']:
|
for entity in tweet['entities']['symbols']:
|
||||||
temp = {}
|
temp = {}
|
||||||
temp['start'] = entity['indices'][0]
|
temp['start'] = entity['indices'][0] - display_text_start
|
||||||
temp['end'] = entity['indices'][1]
|
temp['end'] = entity['indices'][1] - display_text_start
|
||||||
|
|
||||||
url_html = '<a href="https://twitter.com/search?q=%%24%(symbol)s" class="twython-symbol">$%(symbol)s</a>' % {'symbol': entity['text']}
|
url_html = '<a href="https://twitter.com/search?q=%%24%(symbol)s" class="twython-symbol">$%(symbol)s</a>' % {'symbol': entity['text']}
|
||||||
|
|
||||||
@@ -622,8 +639,8 @@ class Twython(EndpointsMixin, object):
|
|||||||
if 'urls' in tweet['entities']:
|
if 'urls' in tweet['entities']:
|
||||||
for entity in tweet['entities']['urls']:
|
for entity in tweet['entities']['urls']:
|
||||||
temp = {}
|
temp = {}
|
||||||
temp['start'] = entity['indices'][0]
|
temp['start'] = entity['indices'][0] - display_text_start
|
||||||
temp['end'] = entity['indices'][1]
|
temp['end'] = entity['indices'][1] - display_text_start
|
||||||
|
|
||||||
if use_display_url and entity.get('display_url') and not use_expanded_url:
|
if use_display_url and entity.get('display_url') and not use_expanded_url:
|
||||||
shown_url = entity['display_url']
|
shown_url = entity['display_url']
|
||||||
@@ -640,8 +657,12 @@ class Twython(EndpointsMixin, object):
|
|||||||
else:
|
else:
|
||||||
suffix_text = suffix_text.replace(orig_tweet_text[temp['start']:temp['end']], url_html)
|
suffix_text = suffix_text.replace(orig_tweet_text[temp['start']:temp['end']], url_html)
|
||||||
|
|
||||||
if 'media' in tweet['entities']:
|
if 'media' in tweet['entities'] and len(tweet['entities']['media']) > 0:
|
||||||
for entity in tweet['entities']['media']:
|
# We just link to the overall URL for the tweet's media,
|
||||||
|
# rather than to each individual item.
|
||||||
|
# So, we get the URL from the first media item:
|
||||||
|
entity = tweet['entities']['media'][0]
|
||||||
|
|
||||||
temp = {}
|
temp = {}
|
||||||
temp['start'] = entity['indices'][0]
|
temp['start'] = entity['indices'][0]
|
||||||
temp['end'] = entity['indices'][1]
|
temp['end'] = entity['indices'][1]
|
||||||
|
@@ -25,7 +25,7 @@ except ImportError:
|
|||||||
|
|
||||||
if is_py2:
|
if is_py2:
|
||||||
from urllib import urlencode, quote_plus
|
from urllib import urlencode, quote_plus
|
||||||
from urlparse import parse_qsl
|
from urlparse import parse_qsl, urlsplit
|
||||||
|
|
||||||
str = unicode
|
str = unicode
|
||||||
basestring = basestring
|
basestring = basestring
|
||||||
@@ -33,7 +33,7 @@ if is_py2:
|
|||||||
|
|
||||||
|
|
||||||
elif is_py3:
|
elif is_py3:
|
||||||
from urllib.parse import urlencode, quote_plus, parse_qsl
|
from urllib.parse import urlencode, quote_plus, parse_qsl, urlsplit
|
||||||
|
|
||||||
str = str
|
str = str
|
||||||
basestring = (str, bytes)
|
basestring = (str, bytes)
|
||||||
|
@@ -10,8 +10,8 @@ as a keyword argument.
|
|||||||
|
|
||||||
e.g. Twython.retweet(id=12345)
|
e.g. Twython.retweet(id=12345)
|
||||||
|
|
||||||
This map is organized the order functions are documented at:
|
Official documentation for Twitter API endpoints can be found at:
|
||||||
https://dev.twitter.com/docs/api/1.1
|
https://developer.twitter.com/en/docs/api-reference-index
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
@@ -34,7 +34,7 @@ class EndpointsMixin(object):
|
|||||||
@screen_name) for the authenticating user.
|
@screen_name) for the authenticating user.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/get/statuses/mentions_timeline
|
https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-mentions_timeline
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('statuses/mentions_timeline', params=params)
|
return self.get('statuses/mentions_timeline', params=params)
|
||||||
@@ -42,9 +42,10 @@ class EndpointsMixin(object):
|
|||||||
|
|
||||||
def get_user_timeline(self, **params):
|
def get_user_timeline(self, **params):
|
||||||
"""Returns a collection of the most recent Tweets posted by the user
|
"""Returns a collection of the most recent Tweets posted by the user
|
||||||
indicated by the screen_name or user_id parameters.
|
indicated by the ``screen_name`` or ``user_id`` parameters.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('statuses/user_timeline', params=params)
|
return self.get('statuses/user_timeline', params=params)
|
||||||
@@ -54,7 +55,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a collection of the most recent Tweets and retweets
|
"""Returns a collection of the most recent Tweets and retweets
|
||||||
posted by the authenticating user and the users they follow.
|
posted by the authenticating user and the users they follow.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('statuses/home_timeline', params=params)
|
return self.get('statuses/home_timeline', params=params)
|
||||||
@@ -64,7 +66,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns the most recent tweets authored by the authenticating user
|
"""Returns the most recent tweets authored by the authenticating user
|
||||||
that have been retweeted by others.
|
that have been retweeted by others.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/retweets_of_me
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweets_of_me
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('statuses/retweets_of_me', params=params)
|
return self.get('statuses/retweets_of_me', params=params)
|
||||||
@@ -74,34 +77,38 @@ class EndpointsMixin(object):
|
|||||||
def get_retweets(self, **params):
|
def get_retweets(self, **params):
|
||||||
"""Returns up to 100 of the first retweets of a given tweet.
|
"""Returns up to 100 of the first retweets of a given tweet.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/retweets/%3Aid
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-retweet-id
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('statuses/retweets/%s' % params.get('id'),
|
return self.get('statuses/retweets/%s' % params.get('id'),
|
||||||
params=params)
|
params=params)
|
||||||
|
|
||||||
def show_status(self, **params):
|
def show_status(self, **params):
|
||||||
"""Returns a single Tweet, specified by the id parameter
|
"""Returns a single Tweet, specified by the ``id`` parameter
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/show/%3Aid
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-show-id
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('statuses/show/%s' % params.get('id'), params=params)
|
return self.get('statuses/show/%s' % params.get('id'), params=params)
|
||||||
|
|
||||||
def lookup_status(self, **params):
|
def lookup_status(self, **params):
|
||||||
"""Returns fully-hydrated tweet objects for up to 100 tweets per
|
"""Returns fully-hydrated tweet objects for up to 100 tweets per
|
||||||
request, as specified by comma-separated values passed to the id
|
request, as specified by comma-separated values passed to the ``id``
|
||||||
parameter.
|
parameter.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/lookup
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-lookup
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('statuses/lookup', params=params)
|
return self.post('statuses/lookup', params=params)
|
||||||
|
|
||||||
def destroy_status(self, **params):
|
def destroy_status(self, **params):
|
||||||
"""Destroys the status specified by the required ID parameter
|
"""Destroys the status specified by the required ``id`` parameter
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/statuses/destroy/%3Aid
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-destroy-id
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('statuses/destroy/%s' % params.get('id'))
|
return self.post('statuses/destroy/%s' % params.get('id'))
|
||||||
@@ -109,15 +116,17 @@ class EndpointsMixin(object):
|
|||||||
def update_status(self, **params):
|
def update_status(self, **params):
|
||||||
"""Updates the authenticating user's current status, also known as tweeting
|
"""Updates the authenticating user's current status, also known as tweeting
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/statuses/update
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('statuses/update', params=params)
|
return self.post('statuses/update', params=params)
|
||||||
|
|
||||||
def retweet(self, **params):
|
def retweet(self, **params):
|
||||||
"""Retweets a tweet specified by the id parameter
|
"""Retweets a tweet specified by the ``id`` parameter
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/statuses/retweet/%3Aid
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-retweet-id
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('statuses/retweet/%s' % params.get('id'))
|
return self.post('statuses/retweet/%s' % params.get('id'))
|
||||||
@@ -127,7 +136,7 @@ class EndpointsMixin(object):
|
|||||||
for upload. In other words, it creates a Tweet with a picture attached.
|
for upload. In other words, it creates a Tweet with a picture attached.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/statuses/update_with_media
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update_with_media
|
||||||
|
|
||||||
"""
|
"""
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
@@ -140,12 +149,13 @@ class EndpointsMixin(object):
|
|||||||
def upload_media(self, **params):
|
def upload_media(self, **params):
|
||||||
"""Uploads media file to Twitter servers. The file will be available to be attached
|
"""Uploads media file to Twitter servers. The file will be available to be attached
|
||||||
to a status for 60 minutes. To attach to a update, pass a list of returned media ids
|
to a status for 60 minutes. To attach to a update, pass a list of returned media ids
|
||||||
to the 'update_status' method using the 'media_ids' param.
|
to the :meth:`update_status` method using the ``media_ids`` param.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/rest/reference/post/media/upload
|
https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-upload
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# https://dev.twitter.com/rest/reference/get/media/upload-status
|
# https://developer.twitter.com/en/docs/media/upload-media/api-reference/get-media-upload-status
|
||||||
if params and params.get('command', '') == 'STATUS':
|
if params and params.get('command', '') == 'STATUS':
|
||||||
return self.get('https://upload.twitter.com/1.1/media/upload.json', params=params)
|
return self.get('https://upload.twitter.com/1.1/media/upload.json', params=params)
|
||||||
|
|
||||||
@@ -153,7 +163,10 @@ class EndpointsMixin(object):
|
|||||||
|
|
||||||
def create_metadata(self, **params):
|
def create_metadata(self, **params):
|
||||||
""" Adds metadata to a media element, such as image descriptions for visually impaired.
|
""" Adds metadata to a media element, such as image descriptions for visually impaired.
|
||||||
Docs: https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-metadata-create
|
|
||||||
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-metadata-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
params = json.dumps(params)
|
params = json.dumps(params)
|
||||||
return self.post("https://upload.twitter.com/1.1/media/metadata/create.json", params=params)
|
return self.post("https://upload.twitter.com/1.1/media/metadata/create.json", params=params)
|
||||||
@@ -161,7 +174,7 @@ class EndpointsMixin(object):
|
|||||||
def upload_video(self, media, media_type, media_category=None, size=None, check_progress=False):
|
def upload_video(self, media, media_type, media_category=None, size=None, check_progress=False):
|
||||||
"""Uploads video file to Twitter servers in chunks. The file will be available to be attached
|
"""Uploads video file to Twitter servers in chunks. The file will be available to be attached
|
||||||
to a status for 60 minutes. To attach to a update, pass a list of returned media ids
|
to a status for 60 minutes. To attach to a update, pass a list of returned media ids
|
||||||
to the 'update_status' method using the 'media_ids' param.
|
to the :meth:`update_status` method using the ``media_ids`` param.
|
||||||
|
|
||||||
Upload happens in 3 stages:
|
Upload happens in 3 stages:
|
||||||
- INIT call with size of media to be uploaded(in bytes). If this is more than 15mb, twitter will return error.
|
- INIT call with size of media to be uploaded(in bytes). If this is more than 15mb, twitter will return error.
|
||||||
@@ -171,7 +184,8 @@ class EndpointsMixin(object):
|
|||||||
Twitter media upload api expects each chunk to be not more than 5mb. We are sending chunk of 1mb each.
|
Twitter media upload api expects each chunk to be not more than 5mb. We are sending chunk of 1mb each.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/rest/public/uploading-media#chunkedupload
|
https://developer.twitter.com/en/docs/media/upload-media/uploading-media/chunked-media-upload
|
||||||
|
|
||||||
"""
|
"""
|
||||||
upload_url = 'https://upload.twitter.com/1.1/media/upload.json'
|
upload_url = 'https://upload.twitter.com/1.1/media/upload.json'
|
||||||
if not size:
|
if not size:
|
||||||
@@ -250,16 +264,18 @@ class EndpointsMixin(object):
|
|||||||
"""Returns information allowing the creation of an embedded
|
"""Returns information allowing the creation of an embedded
|
||||||
representation of a Tweet on third party sites.
|
representation of a Tweet on third party sites.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/oembed
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-oembed
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('statuses/oembed', params=params)
|
return self.get('statuses/oembed', params=params)
|
||||||
|
|
||||||
def get_retweeters_ids(self, **params):
|
def get_retweeters_ids(self, **params):
|
||||||
"""Returns a collection of up to 100 user IDs belonging to users who
|
"""Returns a collection of up to 100 user IDs belonging to users who
|
||||||
have retweeted the tweet specified by the id parameter.
|
have retweeted the tweet specified by the ``id`` parameter.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/retweeters/ids
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-retweeters-ids
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('statuses/retweeters/ids', params=params)
|
return self.get('statuses/retweeters/ids', params=params)
|
||||||
@@ -270,7 +286,8 @@ class EndpointsMixin(object):
|
|||||||
def search(self, **params):
|
def search(self, **params):
|
||||||
"""Returns a collection of relevant Tweets matching a specified query.
|
"""Returns a collection of relevant Tweets matching a specified query.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/search/tweets
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('search/tweets', params=params)
|
return self.get('search/tweets', params=params)
|
||||||
@@ -282,7 +299,8 @@ class EndpointsMixin(object):
|
|||||||
def get_direct_messages(self, **params):
|
def get_direct_messages(self, **params):
|
||||||
"""Returns the 20 most recent direct messages sent to the authenticating user.
|
"""Returns the 20 most recent direct messages sent to the authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/direct_messages
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/list-events
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('direct_messages/events/list', params=params)
|
return self.get('direct_messages/events/list', params=params)
|
||||||
@@ -291,36 +309,40 @@ class EndpointsMixin(object):
|
|||||||
def get_sent_messages(self, **params):
|
def get_sent_messages(self, **params):
|
||||||
"""Returns the 20 most recent direct messages sent by the authenticating user.
|
"""Returns the 20 most recent direct messages sent by the authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/direct_messages/sent
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-sent-message
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('direct_messages/sent', params=params)
|
return self.get('direct_messages/sent', params=params)
|
||||||
get_sent_messages.iter_mode = 'id'
|
get_sent_messages.iter_mode = 'id'
|
||||||
|
|
||||||
def get_direct_message(self, **params):
|
def get_direct_message(self, **params):
|
||||||
"""Returns a single direct message, specified by an id parameter.
|
"""Returns a single direct message, specified by an ``id`` parameter.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/direct_messages/show
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/get-event
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('direct_messages/events/show', params=params)
|
return self.get('direct_messages/events/show', params=params)
|
||||||
|
|
||||||
def destroy_direct_message(self, **params):
|
def destroy_direct_message(self, **params):
|
||||||
"""Destroys the direct message specified in the required id parameter
|
"""Destroys the direct message specified in the required ``id`` parameter
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/direct_messages/destroy
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/delete-message-event
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('direct_messages/destroy', params=params)
|
return self.delete('direct_messages/events/destroy', params=params)
|
||||||
|
|
||||||
def send_direct_message(self, **params):
|
def send_direct_message(self, **params):
|
||||||
"""Sends a new direct message to the specified user from the
|
"""Sends a new direct message to the specified user from the
|
||||||
authenticating user.
|
authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/direct_messages/new
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/api-reference/new-event
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('direct_messages/events/new', params=params, encode_json=True)
|
return self.post('direct_messages/events/new', params=params, json_encoded=True)
|
||||||
|
|
||||||
# Friends & Followers
|
# Friends & Followers
|
||||||
def get_user_ids_of_blocked_retweets(self, **params):
|
def get_user_ids_of_blocked_retweets(self, **params):
|
||||||
@@ -328,7 +350,7 @@ class EndpointsMixin(object):
|
|||||||
user does not want to receive retweets from.
|
user does not want to receive retweets from.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/get/friendships/no_retweets/ids
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-no_retweets-ids
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('friendships/no_retweets/ids', params=params)
|
return self.get('friendships/no_retweets/ids', params=params)
|
||||||
@@ -337,7 +359,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a cursored collection of user IDs for every user the
|
"""Returns a cursored collection of user IDs for every user the
|
||||||
specified user is following (otherwise known as their "friends").
|
specified user is following (otherwise known as their "friends").
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/friends/ids
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('friends/ids', params=params)
|
return self.get('friends/ids', params=params)
|
||||||
@@ -348,7 +371,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a cursored collection of user IDs for every user
|
"""Returns a cursored collection of user IDs for every user
|
||||||
following the specified user.
|
following the specified user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/followers/ids
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('followers/ids', params=params)
|
return self.get('followers/ids', params=params)
|
||||||
@@ -357,9 +381,10 @@ class EndpointsMixin(object):
|
|||||||
|
|
||||||
def lookup_friendships(self, **params):
|
def lookup_friendships(self, **params):
|
||||||
"""Returns the relationships of the authenticating user to the
|
"""Returns the relationships of the authenticating user to the
|
||||||
comma-separated list of up to 100 screen_names or user_ids provided.
|
comma-separated list of up to 100 ``screen_names`` or ``user_ids`` provided.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/friendships/lookup
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-lookup
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('friendships/lookup', params=params)
|
return self.get('friendships/lookup', params=params)
|
||||||
@@ -368,7 +393,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a collection of numeric IDs for every user who has a
|
"""Returns a collection of numeric IDs for every user who has a
|
||||||
pending request to follow the authenticating user.
|
pending request to follow the authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/friendships/incoming
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('friendships/incoming', params=params)
|
return self.get('friendships/incoming', params=params)
|
||||||
@@ -379,7 +405,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a collection of numeric IDs for every protected user for
|
"""Returns a collection of numeric IDs for every protected user for
|
||||||
whom the authenticating user has a pending follow request.
|
whom the authenticating user has a pending follow request.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/friendships/outgoing
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-outgoing
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('friendships/outgoing', params=params)
|
return self.get('friendships/outgoing', params=params)
|
||||||
@@ -388,18 +415,20 @@ class EndpointsMixin(object):
|
|||||||
|
|
||||||
def create_friendship(self, **params):
|
def create_friendship(self, **params):
|
||||||
"""Allows the authenticating users to follow the user specified
|
"""Allows the authenticating users to follow the user specified
|
||||||
in the ID parameter.
|
in the ``id`` parameter.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/friendships/create
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('friendships/create', params=params)
|
return self.post('friendships/create', params=params)
|
||||||
|
|
||||||
def destroy_friendship(self, **params):
|
def destroy_friendship(self, **params):
|
||||||
"""Allows the authenticating user to unfollow the user specified
|
"""Allows the authenticating user to unfollow the user specified
|
||||||
in the ID parameter.
|
in the ``id`` parameter.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/friendships/destroy
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-destroy
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('friendships/destroy', params=params)
|
return self.post('friendships/destroy', params=params)
|
||||||
@@ -408,7 +437,8 @@ class EndpointsMixin(object):
|
|||||||
"""Allows one to enable or disable retweets and device notifications
|
"""Allows one to enable or disable retweets and device notifications
|
||||||
from the specified user.
|
from the specified user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/friendships/update
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/post-friendships-update
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('friendships/update', params=params)
|
return self.post('friendships/update', params=params)
|
||||||
@@ -417,7 +447,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns detailed information about the relationship between two
|
"""Returns detailed information about the relationship between two
|
||||||
arbitrary users.
|
arbitrary users.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/friendships/show
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-show
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('friendships/show', params=params)
|
return self.get('friendships/show', params=params)
|
||||||
@@ -426,7 +457,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a cursored collection of user objects for every user the
|
"""Returns a cursored collection of user objects for every user the
|
||||||
specified user is following (otherwise known as their "friends").
|
specified user is following (otherwise known as their "friends").
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/friends/list
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('friends/list', params=params)
|
return self.get('friends/list', params=params)
|
||||||
@@ -437,7 +469,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a cursored collection of user objects for users
|
"""Returns a cursored collection of user objects for users
|
||||||
following the specified user.
|
following the specified user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/followers/list
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('followers/list', params=params)
|
return self.get('followers/list', params=params)
|
||||||
@@ -449,7 +482,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns settings (including current trend, geo and sleep time
|
"""Returns settings (including current trend, geo and sleep time
|
||||||
information) for the authenticating user.
|
information) for the authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/account/settings
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-settings
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('account/settings', params=params)
|
return self.get('account/settings', params=params)
|
||||||
@@ -460,7 +494,7 @@ class EndpointsMixin(object):
|
|||||||
code and an error message if not.
|
code and an error message if not.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/get/account/verify_credentials
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('account/verify_credentials', params=params)
|
return self.get('account/verify_credentials', params=params)
|
||||||
@@ -468,7 +502,8 @@ class EndpointsMixin(object):
|
|||||||
def update_account_settings(self, **params):
|
def update_account_settings(self, **params):
|
||||||
"""Updates the authenticating user's settings.
|
"""Updates the authenticating user's settings.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/account/settings
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-settings
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('account/settings', params=params)
|
return self.post('account/settings', params=params)
|
||||||
@@ -486,7 +521,8 @@ class EndpointsMixin(object):
|
|||||||
"""Sets values that users are able to set under the "Account" tab of their
|
"""Sets values that users are able to set under the "Account" tab of their
|
||||||
settings page.
|
settings page.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/account/update_profile
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('account/update_profile', params=params)
|
return self.post('account/update_profile', params=params)
|
||||||
@@ -495,26 +531,35 @@ class EndpointsMixin(object):
|
|||||||
"""Updates the authenticating user's profile background image.
|
"""Updates the authenticating user's profile background image.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/account/update_profile_background_image
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_background_image
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('account/update_profile_banner', params=params)
|
return self.post('account/update_profile_banner', params=params)
|
||||||
|
|
||||||
def update_profile_colors(self, **params):
|
def update_profile_colors(self, **params): # pragma: no cover
|
||||||
"""Sets one or more hex values that control the color scheme of the
|
"""Sets one or more hex values that control the color scheme of the
|
||||||
authenticating user's profile page on twitter.com.
|
authenticating user's profile page on twitter.com.
|
||||||
|
|
||||||
|
This method is deprecated, replaced by the ``profile_link_color``
|
||||||
|
parameter to :meth:`update_profile`.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/account/update_profile_colors
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
warnings.warn(
|
||||||
|
'This method is deprecated. You should use the'
|
||||||
|
' profile_link_color parameter in Twython.update_profile instead.',
|
||||||
|
TwythonDeprecationWarning,
|
||||||
|
stacklevel=2
|
||||||
|
)
|
||||||
return self.post('account/update_profile_colors', params=params)
|
return self.post('account/update_profile_colors', params=params)
|
||||||
|
|
||||||
def update_profile_image(self, **params): # pragma: no cover
|
def update_profile_image(self, **params): # pragma: no cover
|
||||||
"""Updates the authenticating user's profile image.
|
"""Updates the authenticating user's profile image.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/account/update_profile_image
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_image
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('account/update_profile_image', params=params)
|
return self.post('account/update_profile_image', params=params)
|
||||||
@@ -523,7 +568,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a collection of user objects that the authenticating user
|
"""Returns a collection of user objects that the authenticating user
|
||||||
is blocking.
|
is blocking.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/blocks/list
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-blocks-list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('blocks/list', params=params)
|
return self.get('blocks/list', params=params)
|
||||||
@@ -533,7 +579,8 @@ class EndpointsMixin(object):
|
|||||||
def list_block_ids(self, **params):
|
def list_block_ids(self, **params):
|
||||||
"""Returns an array of numeric user ids the authenticating user is blocking.
|
"""Returns an array of numeric user ids the authenticating user is blocking.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/blocks/ids
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-blocks-ids
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('blocks/ids', params=params)
|
return self.get('blocks/ids', params=params)
|
||||||
@@ -543,35 +590,39 @@ class EndpointsMixin(object):
|
|||||||
def create_block(self, **params):
|
def create_block(self, **params):
|
||||||
"""Blocks the specified user from following the authenticating user.
|
"""Blocks the specified user from following the authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/blocks/create
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-blocks-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('blocks/create', params=params)
|
return self.post('blocks/create', params=params)
|
||||||
|
|
||||||
def destroy_block(self, **params):
|
def destroy_block(self, **params):
|
||||||
"""Un-blocks the user specified in the ID parameter for the
|
"""Un-blocks the user specified in the ``id`` parameter for the
|
||||||
authenticating user.
|
authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/blocks/destroy
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-blocks-destroy
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('blocks/destroy', params=params)
|
return self.post('blocks/destroy', params=params)
|
||||||
|
|
||||||
def lookup_user(self, **params):
|
def lookup_user(self, **params):
|
||||||
"""Returns fully-hydrated user objects for up to 100 users per request,
|
"""Returns fully-hydrated user objects for up to 100 users per request,
|
||||||
as specified by comma-separated values passed to the user_id and/or
|
as specified by comma-separated values passed to the ``user_id`` and/or
|
||||||
screen_name parameters.
|
``screen_name`` parameters.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/users/lookup
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('users/lookup', params=params)
|
return self.get('users/lookup', params=params)
|
||||||
|
|
||||||
def show_user(self, **params):
|
def show_user(self, **params):
|
||||||
"""Returns a variety of information about the user specified by the
|
"""Returns a variety of information about the user specified by the
|
||||||
required user_id or screen_name parameter.
|
required ``user_id`` or ``screen_name`` parameter.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/users/show
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-show
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('users/show', params=params)
|
return self.get('users/show', params=params)
|
||||||
@@ -580,7 +631,8 @@ class EndpointsMixin(object):
|
|||||||
"""Provides a simple, relevance-based search interface to public user
|
"""Provides a simple, relevance-based search interface to public user
|
||||||
accounts on Twitter.
|
accounts on Twitter.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/users/search
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-search
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('users/search', params=params)
|
return self.get('users/search', params=params)
|
||||||
@@ -606,7 +658,7 @@ class EndpointsMixin(object):
|
|||||||
Returns HTTP 200 upon success.
|
Returns HTTP 200 upon success.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/account/remove_profile_banner
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-remove_profile_banner
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('account/remove_profile_banner', params=params)
|
return self.post('account/remove_profile_banner', params=params)
|
||||||
@@ -615,7 +667,7 @@ class EndpointsMixin(object):
|
|||||||
"""Uploads a profile banner on behalf of the authenticating user.
|
"""Uploads a profile banner on behalf of the authenticating user.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/account/update_profile_banner
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/post-account-update_profile_banner
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('account/update_profile_background_image',
|
return self.post('account/update_profile_background_image',
|
||||||
@@ -625,7 +677,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a map of the available size variations of the specified
|
"""Returns a map of the available size variations of the specified
|
||||||
user's profile banner.
|
user's profile banner.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/users/profile_banner
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-users-profile_banner
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('users/profile_banner', params=params)
|
return self.get('users/profile_banner', params=params)
|
||||||
@@ -634,7 +687,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns a collection of user objects that the authenticating user
|
"""Returns a collection of user objects that the authenticating user
|
||||||
is muting.
|
is muting.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/mutes/users/list
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('mutes/users/list', params=params)
|
return self.get('mutes/users/list', params=params)
|
||||||
@@ -645,7 +699,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns an array of numeric user ids the authenticating user
|
"""Returns an array of numeric user ids the authenticating user
|
||||||
is muting.
|
is muting.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/mutes/users/ids
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-mutes-users-ids
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('mutes/users/ids', params=params)
|
return self.get('mutes/users/ids', params=params)
|
||||||
@@ -656,16 +711,18 @@ class EndpointsMixin(object):
|
|||||||
"""Mutes the specified user, preventing their tweets appearing
|
"""Mutes the specified user, preventing their tweets appearing
|
||||||
in the authenticating user's timeline.
|
in the authenticating user's timeline.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/mutes/users/create
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-mutes-users-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('mutes/users/create', params=params)
|
return self.post('mutes/users/create', params=params)
|
||||||
|
|
||||||
def destroy_mute(self, **params):
|
def destroy_mute(self, **params):
|
||||||
"""Un-mutes the user specified in the user or ID parameter for
|
"""Un-mutes the user specified in the user or ``id`` parameter for
|
||||||
the authenticating user.
|
the authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/mutes/users/destroy
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-mutes-users-destroy
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('mutes/users/destroy', params=params)
|
return self.post('mutes/users/destroy', params=params)
|
||||||
@@ -675,7 +732,7 @@ class EndpointsMixin(object):
|
|||||||
"""Access the users in a given category of the Twitter suggested user list.
|
"""Access the users in a given category of the Twitter suggested user list.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/get/users/suggestions/%3Aslug
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions-slug
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('users/suggestions/%s' % params.get('slug'),
|
return self.get('users/suggestions/%s' % params.get('slug'),
|
||||||
@@ -684,7 +741,8 @@ class EndpointsMixin(object):
|
|||||||
def get_user_suggestions(self, **params):
|
def get_user_suggestions(self, **params):
|
||||||
"""Access to Twitter's suggested user list.
|
"""Access to Twitter's suggested user list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/users/suggestions
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('users/suggestions', params=params)
|
return self.get('users/suggestions', params=params)
|
||||||
@@ -695,7 +753,7 @@ class EndpointsMixin(object):
|
|||||||
user.
|
user.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/get/users/suggestions/%3Aslug/members
|
https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-suggestions-slug-members
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('users/suggestions/%s/members' % params.get('slug'),
|
return self.get('users/suggestions/%s/members' % params.get('slug'),
|
||||||
@@ -706,26 +764,29 @@ class EndpointsMixin(object):
|
|||||||
"""Returns the 20 most recent Tweets favorited by the authenticating
|
"""Returns the 20 most recent Tweets favorited by the authenticating
|
||||||
or specified user.
|
or specified user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/favorites/list
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-favorites-list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('favorites/list', params=params)
|
return self.get('favorites/list', params=params)
|
||||||
get_favorites.iter_mode = 'id'
|
get_favorites.iter_mode = 'id'
|
||||||
|
|
||||||
def destroy_favorite(self, **params):
|
def destroy_favorite(self, **params):
|
||||||
"""Un-favorites the status specified in the ID parameter as the
|
"""Un-favorites the status specified in the ``id`` parameter as the
|
||||||
authenticating user.
|
authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/favorites/destroy
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-favorites-destroy
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('favorites/destroy', params=params)
|
return self.post('favorites/destroy', params=params)
|
||||||
|
|
||||||
def create_favorite(self, **params):
|
def create_favorite(self, **params):
|
||||||
"""Favorites the status specified in the ID parameter as the
|
"""Favorites the status specified in the ``id`` parameter as the
|
||||||
authenticating user.
|
authenticating user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/favorites/create
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-favorites-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('favorites/create', params=params)
|
return self.post('favorites/create', params=params)
|
||||||
@@ -735,7 +796,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns all lists the authenticating or specified user subscribes to,
|
"""Returns all lists the authenticating or specified user subscribes to,
|
||||||
including their own.
|
including their own.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/list
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/list', params=params)
|
return self.get('lists/list', params=params)
|
||||||
@@ -743,7 +805,8 @@ class EndpointsMixin(object):
|
|||||||
def get_list_statuses(self, **params):
|
def get_list_statuses(self, **params):
|
||||||
"""Returns a timeline of tweets authored by members of the specified list.
|
"""Returns a timeline of tweets authored by members of the specified list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/statuses
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-statuses
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/statuses', params=params)
|
return self.get('lists/statuses', params=params)
|
||||||
@@ -752,7 +815,8 @@ class EndpointsMixin(object):
|
|||||||
def delete_list_member(self, **params):
|
def delete_list_member(self, **params):
|
||||||
"""Removes the specified member from the list.
|
"""Removes the specified member from the list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/lists/members/destroy
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-members-destroy
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/members/destroy', params=params)
|
return self.post('lists/members/destroy', params=params)
|
||||||
@@ -760,7 +824,8 @@ class EndpointsMixin(object):
|
|||||||
def get_list_memberships(self, **params):
|
def get_list_memberships(self, **params):
|
||||||
"""Returns the lists the specified user has been added to.
|
"""Returns the lists the specified user has been added to.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/memberships
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-memberships
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/memberships', params=params)
|
return self.get('lists/memberships', params=params)
|
||||||
@@ -770,7 +835,8 @@ class EndpointsMixin(object):
|
|||||||
def get_list_subscribers(self, **params):
|
def get_list_subscribers(self, **params):
|
||||||
"""Returns the subscribers of the specified list.
|
"""Returns the subscribers of the specified list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/subscribers
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/subscribers', params=params)
|
return self.get('lists/subscribers', params=params)
|
||||||
@@ -781,7 +847,7 @@ class EndpointsMixin(object):
|
|||||||
"""Subscribes the authenticated user to the specified list.
|
"""Subscribes the authenticated user to the specified list.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/lists/subscribers/create
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/subscribers/create', params=params)
|
return self.post('lists/subscribers/create', params=params)
|
||||||
@@ -789,7 +855,8 @@ class EndpointsMixin(object):
|
|||||||
def is_list_subscriber(self, **params):
|
def is_list_subscriber(self, **params):
|
||||||
"""Check if the specified user is a subscriber of the specified list.
|
"""Check if the specified user is a subscriber of the specified list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/subscribers/show
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers-show
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/subscribers/show', params=params)
|
return self.get('lists/subscribers/show', params=params)
|
||||||
@@ -798,7 +865,7 @@ class EndpointsMixin(object):
|
|||||||
"""Unsubscribes the authenticated user from the specified list.
|
"""Unsubscribes the authenticated user from the specified list.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/lists/subscribers/destroy
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-subscribers-destroy
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/subscribers/destroy', params=params)
|
return self.post('lists/subscribers/destroy', params=params)
|
||||||
@@ -808,7 +875,7 @@ class EndpointsMixin(object):
|
|||||||
list of member ids or screen names.
|
list of member ids or screen names.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/lists/members/create_all
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-members-create_all
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/members/create_all', params=params)
|
return self.post('lists/members/create_all', params=params)
|
||||||
@@ -816,7 +883,8 @@ class EndpointsMixin(object):
|
|||||||
def is_list_member(self, **params):
|
def is_list_member(self, **params):
|
||||||
"""Check if the specified user is a member of the specified list.
|
"""Check if the specified user is a member of the specified list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/members/show
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-members-show
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/members/show', params=params)
|
return self.get('lists/members/show', params=params)
|
||||||
@@ -824,7 +892,8 @@ class EndpointsMixin(object):
|
|||||||
def get_list_members(self, **params):
|
def get_list_members(self, **params):
|
||||||
"""Returns the members of the specified list.
|
"""Returns the members of the specified list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/members
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-members
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/members', params=params)
|
return self.get('lists/members', params=params)
|
||||||
@@ -834,7 +903,8 @@ class EndpointsMixin(object):
|
|||||||
def add_list_member(self, **params):
|
def add_list_member(self, **params):
|
||||||
"""Add a member to a list.
|
"""Add a member to a list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/lists/members/create
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-members-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/members/create', params=params)
|
return self.post('lists/members/create', params=params)
|
||||||
@@ -842,7 +912,8 @@ class EndpointsMixin(object):
|
|||||||
def delete_list(self, **params):
|
def delete_list(self, **params):
|
||||||
"""Deletes the specified list.
|
"""Deletes the specified list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/lists/destroy
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-destroy
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/destroy', params=params)
|
return self.post('lists/destroy', params=params)
|
||||||
@@ -850,7 +921,8 @@ class EndpointsMixin(object):
|
|||||||
def update_list(self, **params):
|
def update_list(self, **params):
|
||||||
"""Updates the specified list.
|
"""Updates the specified list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/lists/update
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-update
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/update', params=params)
|
return self.post('lists/update', params=params)
|
||||||
@@ -858,7 +930,8 @@ class EndpointsMixin(object):
|
|||||||
def create_list(self, **params):
|
def create_list(self, **params):
|
||||||
"""Creates a new list for the authenticated user.
|
"""Creates a new list for the authenticated user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/lists/create
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/create', params=params)
|
return self.post('lists/create', params=params)
|
||||||
@@ -866,7 +939,8 @@ class EndpointsMixin(object):
|
|||||||
def get_specific_list(self, **params):
|
def get_specific_list(self, **params):
|
||||||
"""Returns the specified list.
|
"""Returns the specified list.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/show
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-show
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/show', params=params)
|
return self.get('lists/show', params=params)
|
||||||
@@ -874,7 +948,8 @@ class EndpointsMixin(object):
|
|||||||
def get_list_subscriptions(self, **params):
|
def get_list_subscriptions(self, **params):
|
||||||
"""Obtain a collection of the lists the specified user is subscribed to.
|
"""Obtain a collection of the lists the specified user is subscribed to.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/subscriptions
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-subscriptions
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/subscriptions', params=params)
|
return self.get('lists/subscriptions', params=params)
|
||||||
@@ -886,7 +961,7 @@ class EndpointsMixin(object):
|
|||||||
comma-separated list of member ids or screen names.
|
comma-separated list of member ids or screen names.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/lists/members/destroy_all
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/post-lists-members-destroy_all
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('lists/members/destroy_all', params=params)
|
return self.post('lists/members/destroy_all', params=params)
|
||||||
@@ -894,7 +969,8 @@ class EndpointsMixin(object):
|
|||||||
def show_owned_lists(self, **params):
|
def show_owned_lists(self, **params):
|
||||||
"""Returns the lists owned by the specified Twitter user.
|
"""Returns the lists owned by the specified Twitter user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/lists/ownerships
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/create-manage-lists/api-reference/get-lists-ownerships
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('lists/ownerships', params=params)
|
return self.get('lists/ownerships', params=params)
|
||||||
@@ -905,16 +981,17 @@ class EndpointsMixin(object):
|
|||||||
def get_saved_searches(self, **params):
|
def get_saved_searches(self, **params):
|
||||||
"""Returns the authenticated user's saved search queries.
|
"""Returns the authenticated user's saved search queries.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/saved_searches/list
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/tweets/search/api-reference/get-saved_searches-list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('saved_searches/list', params=params)
|
return self.get('saved_searches/list', params=params)
|
||||||
|
|
||||||
def show_saved_search(self, **params):
|
def show_saved_search(self, **params):
|
||||||
"""Retrieve the information for the saved search represented by the given id.
|
"""Retrieve the information for the saved search represented by the given ``id``.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/get/saved_searches/show/%3Aid
|
https://developer.twitter.com/en/docs/tweets/search/api-reference/get-saved_searches-show-id
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('saved_searches/show/%s' % params.get('id'),
|
return self.get('saved_searches/show/%s' % params.get('id'),
|
||||||
@@ -923,7 +1000,8 @@ class EndpointsMixin(object):
|
|||||||
def create_saved_search(self, **params):
|
def create_saved_search(self, **params):
|
||||||
"""Create a new saved search for the authenticated user.
|
"""Create a new saved search for the authenticated user.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/saved_searches/create
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-mutes-users-create
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('saved_searches/create', params=params)
|
return self.post('saved_searches/create', params=params)
|
||||||
@@ -932,7 +1010,7 @@ class EndpointsMixin(object):
|
|||||||
"""Destroys a saved search for the authenticating user.
|
"""Destroys a saved search for the authenticating user.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/saved_searches/destroy/%3Aid
|
https://developer.twitter.com/en/docs/tweets/search/api-reference/post-saved_searches-destroy-id
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('saved_searches/destroy/%s' % params.get('id'),
|
return self.post('saved_searches/destroy/%s' % params.get('id'),
|
||||||
@@ -942,7 +1020,8 @@ class EndpointsMixin(object):
|
|||||||
def get_geo_info(self, **params):
|
def get_geo_info(self, **params):
|
||||||
"""Returns all the information about a known place.
|
"""Returns all the information about a known place.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/geo/id/%3Aplace_id
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/geo/place-information/api-reference/get-geo-id-place_id
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('geo/id/%s' % params.get('place_id'), params=params)
|
return self.get('geo/id/%s' % params.get('place_id'), params=params)
|
||||||
@@ -951,7 +1030,8 @@ class EndpointsMixin(object):
|
|||||||
"""Given a latitude and a longitude, searches for up to 20 places
|
"""Given a latitude and a longitude, searches for up to 20 places
|
||||||
that can be used as a place_id when updating a status.
|
that can be used as a place_id when updating a status.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/geo/reverse_geocode
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/geo/places-near-location/api-reference/get-geo-reverse_geocode
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('geo/reverse_geocode', params=params)
|
return self.get('geo/reverse_geocode', params=params)
|
||||||
@@ -959,7 +1039,8 @@ class EndpointsMixin(object):
|
|||||||
def search_geo(self, **params):
|
def search_geo(self, **params):
|
||||||
"""Search for places that can be attached to a statuses/update.
|
"""Search for places that can be attached to a statuses/update.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/geo/search
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/geo/places-near-location/api-reference/get-geo-search
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('geo/search', params=params)
|
return self.get('geo/search', params=params)
|
||||||
@@ -985,7 +1066,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns the top 10 trending topics for a specific WOEID, if
|
"""Returns the top 10 trending topics for a specific WOEID, if
|
||||||
trending information is available for it.
|
trending information is available for it.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/trends/place
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/trends/trends-for-location/api-reference/get-trends-place
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('trends/place', params=params)
|
return self.get('trends/place', params=params)
|
||||||
@@ -993,7 +1075,8 @@ class EndpointsMixin(object):
|
|||||||
def get_available_trends(self, **params):
|
def get_available_trends(self, **params):
|
||||||
"""Returns the locations that Twitter has trending topic information for.
|
"""Returns the locations that Twitter has trending topic information for.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/trends/available
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/trends/locations-with-trending-topics/api-reference/get-trends-available
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('trends/available', params=params)
|
return self.get('trends/available', params=params)
|
||||||
@@ -1002,7 +1085,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns the locations that Twitter has trending topic information
|
"""Returns the locations that Twitter has trending topic information
|
||||||
for, closest to a specified location.
|
for, closest to a specified location.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/trends/closest
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/trends/locations-with-trending-topics/api-reference/get-trends-closest
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('trends/closest', params=params)
|
return self.get('trends/closest', params=params)
|
||||||
@@ -1011,7 +1095,8 @@ class EndpointsMixin(object):
|
|||||||
def report_spam(self, **params): # pragma: no cover
|
def report_spam(self, **params): # pragma: no cover
|
||||||
"""Report the specified user as a spam account to Twitter.
|
"""Report the specified user as a spam account to Twitter.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/users/report_spam
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/post-users-report_spam
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('users/report_spam', params=params)
|
return self.post('users/report_spam', params=params)
|
||||||
@@ -1021,7 +1106,8 @@ class EndpointsMixin(object):
|
|||||||
"""Allows a registered application to revoke an issued OAuth 2 Bearer
|
"""Allows a registered application to revoke an issued OAuth 2 Bearer
|
||||||
Token by presenting its client credentials.
|
Token by presenting its client credentials.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/post/oauth2/invalidate_token
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/basics/authentication/api-reference/invalidate_token
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.post('oauth2/invalidate_token', params=params)
|
return self.post('oauth2/invalidate_token', params=params)
|
||||||
@@ -1030,7 +1116,8 @@ class EndpointsMixin(object):
|
|||||||
def get_twitter_configuration(self, **params):
|
def get_twitter_configuration(self, **params):
|
||||||
"""Returns the current configuration used by Twitter
|
"""Returns the current configuration used by Twitter
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/help/configuration
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/developer-utilities/configuration/api-reference/get-help-configuration
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('help/configuration', params=params)
|
return self.get('help/configuration', params=params)
|
||||||
@@ -1039,7 +1126,8 @@ class EndpointsMixin(object):
|
|||||||
"""Returns the list of languages supported by Twitter along with
|
"""Returns the list of languages supported by Twitter along with
|
||||||
their ISO 639-1 code.
|
their ISO 639-1 code.
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/help/languages
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/developer-utilities/supported-languages/api-reference/get-help-languages
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('help/languages', params=params)
|
return self.get('help/languages', params=params)
|
||||||
@@ -1047,7 +1135,8 @@ class EndpointsMixin(object):
|
|||||||
def get_privacy_policy(self, **params):
|
def get_privacy_policy(self, **params):
|
||||||
"""Returns Twitter's Privacy Policy
|
"""Returns Twitter's Privacy Policy
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/help/privacy
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/developer-utilities/privacy-policy/api-reference/get-help-privacy
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('help/privacy', params=params)
|
return self.get('help/privacy', params=params)
|
||||||
@@ -1055,7 +1144,8 @@ class EndpointsMixin(object):
|
|||||||
def get_tos(self, **params):
|
def get_tos(self, **params):
|
||||||
"""Return the Twitter Terms of Service
|
"""Return the Twitter Terms of Service
|
||||||
|
|
||||||
Docs: https://dev.twitter.com/docs/api/1.1/get/help/tos
|
Docs:
|
||||||
|
https://developer.twitter.com/en/docs/developer-utilities/terms-of-service/api-reference/get-help-tos
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('help/tos', params=params)
|
return self.get('help/tos', params=params)
|
||||||
@@ -1065,13 +1155,13 @@ class EndpointsMixin(object):
|
|||||||
specified resource families.
|
specified resource families.
|
||||||
|
|
||||||
Docs:
|
Docs:
|
||||||
https://dev.twitter.com/docs/api/1.1/get/application/rate_limit_status
|
https://developer.twitter.com/en/docs/developer-utilities/rate-limit-status/api-reference/get-application-rate_limit_status
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get('application/rate_limit_status', params=params)
|
return self.get('application/rate_limit_status', params=params)
|
||||||
|
|
||||||
|
|
||||||
# from https://dev.twitter.com/docs/error-codes-responses
|
# from https://developer.twitter.com/en/docs/ads/general/guides/response-codes
|
||||||
TWITTER_HTTP_STATUS_CODE = {
|
TWITTER_HTTP_STATUS_CODE = {
|
||||||
200: ('OK', 'Success!'),
|
200: ('OK', 'Success!'),
|
||||||
304: ('Not Modified', 'There was no new data to return.'),
|
304: ('Not Modified', 'There was no new data to return.'),
|
||||||
|
@@ -169,9 +169,9 @@ class TwythonStreamer(object):
|
|||||||
Returns True if other handlers for this message should be invoked.
|
Returns True if other handlers for this message should be invoked.
|
||||||
|
|
||||||
Feel free to override this to handle your streaming data how you
|
Feel free to override this to handle your streaming data how you
|
||||||
want it handled.
|
want it handled. See
|
||||||
See https://dev.twitter.com/docs/streaming-apis/messages for messages
|
https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/streaming-message-types
|
||||||
sent along in stream responses.
|
for messages sent along in stream responses.
|
||||||
|
|
||||||
:param data: data recieved from the stream
|
:param data: data recieved from the stream
|
||||||
:type data: dict
|
:type data: dict
|
||||||
|
@@ -44,9 +44,10 @@ class TwythonStreamerTypes(object):
|
|||||||
class TwythonStreamerTypesStatuses(object):
|
class TwythonStreamerTypesStatuses(object):
|
||||||
"""Class for different statuses endpoints
|
"""Class for different statuses endpoints
|
||||||
|
|
||||||
Available so TwythonStreamer.statuses.filter() is available.
|
Available so :meth:`TwythonStreamer.statuses.filter()` is available.
|
||||||
Just a bit cleaner than TwythonStreamer.statuses_filter(),
|
Just a bit cleaner than :meth:`TwythonStreamer.statuses_filter()`,
|
||||||
statuses_sample(), etc. all being single methods in TwythonStreamer
|
:meth:`statuses_sample()`, etc. all being single methods in
|
||||||
|
:class:`TwythonStreamer`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, streamer):
|
def __init__(self, streamer):
|
||||||
@@ -59,7 +60,7 @@ class TwythonStreamerTypesStatuses(object):
|
|||||||
:param \*\*params: Parameters to send with your stream request
|
:param \*\*params: Parameters to send with your stream request
|
||||||
|
|
||||||
Accepted params found at:
|
Accepted params found at:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/statuses/filter
|
https://developer.twitter.com/en/docs/tweets/filter-realtime/api-reference/post-statuses-filter
|
||||||
"""
|
"""
|
||||||
url = 'https://stream.twitter.com/%s/statuses/filter.json' \
|
url = 'https://stream.twitter.com/%s/statuses/filter.json' \
|
||||||
% self.streamer.api_version
|
% self.streamer.api_version
|
||||||
@@ -71,7 +72,7 @@ class TwythonStreamerTypesStatuses(object):
|
|||||||
:param \*\*params: Parameters to send with your stream request
|
:param \*\*params: Parameters to send with your stream request
|
||||||
|
|
||||||
Accepted params found at:
|
Accepted params found at:
|
||||||
https://dev.twitter.com/docs/api/1.1/get/statuses/sample
|
https://developer.twitter.com/en/docs/tweets/sample-realtime/api-reference/get-statuses-sample
|
||||||
"""
|
"""
|
||||||
url = 'https://stream.twitter.com/%s/statuses/sample.json' \
|
url = 'https://stream.twitter.com/%s/statuses/sample.json' \
|
||||||
% self.streamer.api_version
|
% self.streamer.api_version
|
||||||
@@ -95,7 +96,7 @@ class TwythonStreamerTypesStatuses(object):
|
|||||||
:param \*\*params: Parameters to send with your stream request
|
:param \*\*params: Parameters to send with your stream request
|
||||||
|
|
||||||
Accepted params found at:
|
Accepted params found at:
|
||||||
https://dev.twitter.com/docs/api/1.1/post/statuses/filter
|
https://developer.twitter.com/en/docs/tweets/filter-realtime/api-reference/post-statuses-filter
|
||||||
"""
|
"""
|
||||||
self.params = params
|
self.params = params
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ import wx
|
|||||||
import application
|
import application
|
||||||
import output
|
import output
|
||||||
import config
|
import config
|
||||||
|
import widgetUtils
|
||||||
import baseDialog
|
import baseDialog
|
||||||
from multiplatform_widgets import widgets
|
from multiplatform_widgets import widgets
|
||||||
|
|
||||||
@@ -268,6 +269,9 @@ class sound(wx.Panel):
|
|||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
volume = wx.StaticText(self, -1, _(u"Volume"))
|
volume = wx.StaticText(self, -1, _(u"Volume"))
|
||||||
self.volumeCtrl = wx.Slider(self)
|
self.volumeCtrl = wx.Slider(self)
|
||||||
|
# Connect a key handler here to handle volume slider being inverted when moving with up and down arrows.
|
||||||
|
# see https://github.com/manuelcortez/TWBlue/issues/261
|
||||||
|
widgetUtils.connect_event(self.volumeCtrl, widgetUtils.KEYPRESS, self.on_keypress)
|
||||||
self.volumeCtrl.SetRange(0, 100)
|
self.volumeCtrl.SetRange(0, 100)
|
||||||
self.volumeCtrl.SetSize(self.volumeCtrl.GetBestSize())
|
self.volumeCtrl.SetSize(self.volumeCtrl.GetBestSize())
|
||||||
volumeBox = wx.BoxSizer(wx.HORIZONTAL)
|
volumeBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
@@ -305,6 +309,18 @@ class sound(wx.Panel):
|
|||||||
sizer.Add(self.indicate_img, 0, wx.ALL, 5)
|
sizer.Add(self.indicate_img, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
|
def on_keypress(self, event, *args, **kwargs):
|
||||||
|
""" Invert movement of up and down arrow keys when dealing with a wX Slider.
|
||||||
|
See https://github.com/manuelcortez/TWBlue/issues/261
|
||||||
|
and http://trac.wxwidgets.org/ticket/2068
|
||||||
|
"""
|
||||||
|
keycode = event.GetKeyCode()
|
||||||
|
if keycode == wx.WXK_UP:
|
||||||
|
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()+1)
|
||||||
|
elif keycode == wx.WXK_DOWN:
|
||||||
|
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()-1)
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
def get(self, control):
|
def get(self, control):
|
||||||
return getattr(self, control).GetStringSelection()
|
return getattr(self, control).GetStringSelection()
|
||||||
|
|
||||||
|
@@ -113,6 +113,13 @@ class addUserListDialog(listViewer):
|
|||||||
# self.subscriptors.Disable()
|
# self.subscriptors.Disable()
|
||||||
# self.members.Disable()
|
# self.members.Disable()
|
||||||
self.deleteBtn.Disable()
|
self.deleteBtn.Disable()
|
||||||
|
widgetUtils.connect_event(self.lista.list, widgetUtils.KEYPRESS, self.on_keypress)
|
||||||
|
|
||||||
|
def on_keypress(self, event):
|
||||||
|
"""Catch return and execute ok()"""
|
||||||
|
if event.GetKeyCode() == wx.WXK_RETURN:
|
||||||
|
return self.ok()
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
def ok(self, *args, **kwargs):
|
def ok(self, *args, **kwargs):
|
||||||
self.EndModal(wx.ID_OK)
|
self.EndModal(wx.ID_OK)
|
||||||
@@ -129,6 +136,13 @@ class removeUserListDialog(listViewer):
|
|||||||
# self.subscriptors.Disable()
|
# self.subscriptors.Disable()
|
||||||
# self.members.Disable()
|
# self.members.Disable()
|
||||||
self.deleteBtn.Disable()
|
self.deleteBtn.Disable()
|
||||||
|
widgetUtils.connect_event(self.lista.list, widgetUtils.KEYPRESS, self.on_keypress)
|
||||||
|
|
||||||
|
def on_keypress(self, event):
|
||||||
|
"""Catch return and execute EndModal()"""
|
||||||
|
if event.GetKeyCode() == wx.WXK_RETURN:
|
||||||
|
return self.EndModal(wx.ID_OK)
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
def remove_list():
|
def remove_list():
|
||||||
return wx.MessageDialog(None, _("Do you really want to delete this list?"), _("Delete"), wx.YES_NO).ShowModal()
|
return wx.MessageDialog(None, _("Do you really want to delete this list?"), _("Delete"), wx.YES_NO).ShowModal()
|
||||||
|
@@ -298,7 +298,7 @@ class viewTweet(widgetUtils.BaseDialog):
|
|||||||
def set_title(self, lenght):
|
def set_title(self, lenght):
|
||||||
self.SetTitle(_(u"Tweet - %i characters ") % (lenght,))
|
self.SetTitle(_(u"Tweet - %i characters ") % (lenght,))
|
||||||
|
|
||||||
def __init__(self, text, rt_count, favs_count,source, *args, **kwargs):
|
def __init__(self, text, rt_count, favs_count, source, date="", *args, **kwargs):
|
||||||
super(viewTweet, self).__init__(None, size=(850,850))
|
super(viewTweet, self).__init__(None, size=(850,850))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
label = wx.StaticText(panel, -1, _(u"Tweet"))
|
label = wx.StaticText(panel, -1, _(u"Tweet"))
|
||||||
@@ -339,11 +339,21 @@ class viewTweet(widgetUtils.BaseDialog):
|
|||||||
sourceBox = wx.BoxSizer(wx.HORIZONTAL)
|
sourceBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sourceBox.Add(sourceLabel, 0, wx.ALL, 5)
|
sourceBox.Add(sourceLabel, 0, wx.ALL, 5)
|
||||||
sourceBox.Add(sourceTweet, 0, wx.ALL, 5)
|
sourceBox.Add(sourceTweet, 0, wx.ALL, 5)
|
||||||
|
dateLabel = wx.StaticText(panel, -1, _(u"Date: "))
|
||||||
|
dateTweet = wx.TextCtrl(panel, -1, date, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
|
dc = wx.WindowDC(dateTweet)
|
||||||
|
dc.SetFont(dateTweet.GetFont())
|
||||||
|
(x, y) = dc.GetTextExtent("0"*100)
|
||||||
|
dateTweet.SetSize((x, y))
|
||||||
|
dateBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
dateBox.Add(dateLabel, 0, wx.ALL, 5)
|
||||||
|
dateBox.Add(dateTweet, 0, wx.ALL, 5)
|
||||||
infoBox = wx.BoxSizer(wx.HORIZONTAL)
|
infoBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
infoBox.Add(rtBox, 0, wx.ALL, 5)
|
infoBox.Add(rtBox, 0, wx.ALL, 5)
|
||||||
infoBox.Add(favsBox, 0, wx.ALL, 5)
|
infoBox.Add(favsBox, 0, wx.ALL, 5)
|
||||||
infoBox.Add(sourceBox, 0, wx.ALL, 5)
|
infoBox.Add(sourceBox, 0, wx.ALL, 5)
|
||||||
mainBox.Add(infoBox, 0, wx.ALL, 5)
|
mainBox.Add(infoBox, 0, wx.ALL, 5)
|
||||||
|
mainBox.Add(dateBox, 0, wx.ALL, 5)
|
||||||
self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize)
|
self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize)
|
||||||
self.unshortenButton = wx.Button(panel, -1, _(u"&Expand URL"), size=wx.DefaultSize)
|
self.unshortenButton = wx.Button(panel, -1, _(u"&Expand URL"), size=wx.DefaultSize)
|
||||||
self.unshortenButton.Disable()
|
self.unshortenButton.Disable()
|
||||||
@@ -390,7 +400,7 @@ class viewTweet(widgetUtils.BaseDialog):
|
|||||||
|
|
||||||
class viewNonTweet(widgetUtils.BaseDialog):
|
class viewNonTweet(widgetUtils.BaseDialog):
|
||||||
|
|
||||||
def __init__(self, text, *args, **kwargs):
|
def __init__(self, text, date="", *args, **kwargs):
|
||||||
super(viewNonTweet, self).__init__(None, size=(850,850))
|
super(viewNonTweet, self).__init__(None, size=(850,850))
|
||||||
self.SetTitle(_(u"View"))
|
self.SetTitle(_(u"View"))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
@@ -406,6 +416,17 @@ class viewNonTweet(widgetUtils.BaseDialog):
|
|||||||
textBox.Add(self.text, 1, wx.EXPAND, 5)
|
textBox.Add(self.text, 1, wx.EXPAND, 5)
|
||||||
mainBox = wx.BoxSizer(wx.VERTICAL)
|
mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||||
mainBox.Add(textBox, 0, wx.ALL, 5)
|
mainBox.Add(textBox, 0, wx.ALL, 5)
|
||||||
|
if date != "":
|
||||||
|
dateLabel = wx.StaticText(panel, -1, _(u"Date: "))
|
||||||
|
date = wx.TextCtrl(panel, -1, date, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
|
dc = wx.WindowDC(date)
|
||||||
|
dc.SetFont(date.GetFont())
|
||||||
|
(x, y) = dc.GetTextExtent("0"*100)
|
||||||
|
date.SetSize((x, y))
|
||||||
|
dateBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
dateBox.Add(dateLabel, 0, wx.ALL, 5)
|
||||||
|
dateBox.Add(date, 0, wx.ALL, 5)
|
||||||
|
mainBox.Add(dateBox, 0, wx.ALL, 5)
|
||||||
self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize)
|
self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize)
|
||||||
self.unshortenButton = wx.Button(panel, -1, _(u"&Expand URL"), size=wx.DefaultSize)
|
self.unshortenButton = wx.Button(panel, -1, _(u"&Expand URL"), size=wx.DefaultSize)
|
||||||
self.unshortenButton.Disable()
|
self.unshortenButton.Disable()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{"current_version": "1",
|
{"current_version": "9",
|
||||||
"description": "Snapshot version.",
|
"description": "Snapshot version.",
|
||||||
"date": "unknown",
|
"date": "unknown",
|
||||||
"downloads":
|
"downloads":
|
||||||
{"Windows32": "https://twblue.es/pubs/snapshot.zip"}}
|
{"Windows32": "https://twblue.es/snapshot.zip"}}
|
Reference in New Issue
Block a user