From 0e4b13385825aafc802797af41280632a460d9c4 Mon Sep 17 00:00:00 2001 From: guredora Date: Sun, 24 Jan 2021 11:05:49 +0900 Subject: [PATCH 01/83] add: configration invalid error dialog --- src/config_utils.py | 2 ++ src/wxUI/commonMessageDialogs.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/config_utils.py b/src/config_utils.py index f2cc10e6..a680e017 100644 --- a/src/config_utils.py +++ b/src/config_utils.py @@ -4,6 +4,7 @@ from validate import Validator, ValidateError import os import string from logging import getLogger +from wxUI import commonMessageDialogs log = getLogger("config_utils") class ConfigLoadError(Exception): pass @@ -21,6 +22,7 @@ def load_config(config_path, configspec_path=None, copy=True, *args, **kwargs): return config else: log.exception("Error in config file: {0}".format(validated,)) + commonMessageDialogs.invalid_configration() def is_blank(arg): "Check if a line is blank." diff --git a/src/wxUI/commonMessageDialogs.py b/src/wxUI/commonMessageDialogs.py index 8288af68..3e683a98 100644 --- a/src/wxUI/commonMessageDialogs.py +++ b/src/wxUI/commonMessageDialogs.py @@ -92,4 +92,7 @@ def common_error(reason): return wx.MessageDialog(None, reason, _(u"Error"), wx.OK).ShowModal() def dead_pid(): - return wx.MessageDialog(None, _(u"{0} quit unexpectedly the last time it was run. If the problem persists, please report it to the {0} developers.").format(application.name), _(u"Warning"), wx.OK).ShowModal() \ No newline at end of file + return wx.MessageDialog(None, _(u"{0} quit unexpectedly the last time it was run. If the problem persists, please report it to the {0} developers.").format(application.name), _(u"Warning"), wx.OK).ShowModal() + +def invalid_configration(): + return wx.MessageDialog(None, _(u"The configuration file is invalid."), _(u"Error"), wx.OK).ShowModal() \ No newline at end of file From 2c4ec7b1c0db210dbc2cc4865b9bb42fe69919bb Mon Sep 17 00:00:00 2001 From: Oreonan Date: Wed, 3 Nov 2021 18:58:59 +0100 Subject: [PATCH 02/83] Update french interface --- src/locales/fr/LC_MESSAGES/twblue.po | 107 +++++++++++++++------------ 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/src/locales/fr/LC_MESSAGES/twblue.po b/src/locales/fr/LC_MESSAGES/twblue.po index cd6eb5be..a22173de 100644 --- a/src/locales/fr/LC_MESSAGES/twblue.po +++ b/src/locales/fr/LC_MESSAGES/twblue.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.94\n" -"POT-Creation-Date: 2021-10-28 12:29+Paris, Madrid (heure d’été)\n" -"PO-Revision-Date: 2021-10-28 18:29+0200\n" +"POT-Creation-Date: 2021-11-03 18:55+0100\n" +"PO-Revision-Date: 2021-11-03 18:57+0100\n" "Last-Translator: Oreonan \n" "Language-Team: Oreonan \n" "Language: fr\n" @@ -99,7 +99,7 @@ msgid "Unknown buffer" msgstr "Tampon inconnu" #: ../src\controller\buffers\twitter\base.py:88 -#: ../src\controller\buffers\twitter\trends.py:121 +#: ../src\controller\buffers\twitter\trends.py:122 #: ../src\controller\messages.py:214 ../src\wxUI\buffers\base.py:25 #: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 #: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:35 @@ -107,7 +107,7 @@ msgid "Tweet" msgstr "Tweet" #: ../src\controller\buffers\twitter\base.py:89 -#: ../src\controller\buffers\twitter\trends.py:122 +#: ../src\controller\buffers\twitter\trends.py:123 msgid "Write the tweet here" msgstr "Écrivez le tweet ici" @@ -120,7 +120,7 @@ msgid "{0} new tweets in {1}." msgstr "{0} nouveau tweet dans {1}" #: ../src\controller\buffers\twitter\base.py:261 -#: ../src\controller\buffers\twitter\directMessages.py:87 +#: ../src\controller\buffers\twitter\directMessages.py:88 #: ../src\controller\buffers\twitter\people.py:180 msgid "%s items retrieved" msgstr "%s éléments récupérés" @@ -144,7 +144,7 @@ msgid "Reply to %s" msgstr "Répondre à %s" #: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\buffers\twitter\directMessages.py:129 +#: ../src\controller\buffers\twitter\directMessages.py:130 msgid "New direct message" msgstr "Nouveau message privé" @@ -173,26 +173,26 @@ msgstr "Détails de l'utilisateur" msgid "Opening item in web browser..." msgstr "Ouverture de l'élément dans le navigateur Web..." -#: ../src\controller\buffers\twitter\directMessages.py:92 +#: ../src\controller\buffers\twitter\directMessages.py:93 #: ../src\controller\buffers\twitter\people.py:95 msgid "Mention to %s" msgstr "Mention pour %s" -#: ../src\controller\buffers\twitter\directMessages.py:92 +#: ../src\controller\buffers\twitter\directMessages.py:93 #: ../src\controller\buffers\twitter\people.py:95 #: ../src\wxUI\buffers\people.py:17 msgid "Mention" msgstr "Mention" -#: ../src\controller\buffers\twitter\directMessages.py:132 +#: ../src\controller\buffers\twitter\directMessages.py:133 msgid "{0} new direct messages." msgstr "{0} nouveau message privé" -#: ../src\controller\buffers\twitter\directMessages.py:135 +#: ../src\controller\buffers\twitter\directMessages.py:136 msgid "This action is not supported in the buffer yet." msgstr "Cette action n'est pas supportée dans le tampon actuel" -#: ../src\controller\buffers\twitter\directMessages.py:145 +#: ../src\controller\buffers\twitter\directMessages.py:146 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." @@ -204,7 +204,7 @@ msgstr "" msgid "{0} new followers." msgstr "{0} nouvel abonné" -#: ../src\controller\buffers\twitter\trends.py:145 +#: ../src\controller\buffers\twitter\trends.py:146 msgid "This action is not supported in the buffer, yet." msgstr "Cette action n'est pas supportée pour le tampon actuel" @@ -277,6 +277,7 @@ msgstr "Recherche de {}" #: ../src\controller\mainController.py:381 #: ../src\controller\mainController.py:982 +#: ../src\controller\mainController.py:1593 msgid "Trending topics for %s" msgstr "Tendances pour %s" @@ -425,20 +426,20 @@ msgstr "Actualisation..." msgid "{0} items retrieved" msgstr "{0} éléments récupérés" -#: ../src\controller\mainController.py:1598 -#: ../src\controller\mainController.py:1618 +#: ../src\controller\mainController.py:1600 +#: ../src\controller\mainController.py:1620 msgid "Invalid buffer" msgstr "Tampon invalide" -#: ../src\controller\mainController.py:1609 +#: ../src\controller\mainController.py:1611 msgid "Picture {0}" msgstr "Photo {0}" -#: ../src\controller\mainController.py:1610 +#: ../src\controller\mainController.py:1612 msgid "Select the picture" msgstr "Sélectionner la photo" -#: ../src\controller\mainController.py:1629 +#: ../src\controller\mainController.py:1631 msgid "Unable to extract text" msgstr "Impossible d'extraire le texte" @@ -1487,7 +1488,7 @@ msgstr "" msgid "Send report" msgstr "Envoyer le rapport" -#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:84 +#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:83 #: ../src\wxUI\dialogs\find.py:23 msgid "Cancel" msgstr "Annuler" @@ -1780,7 +1781,7 @@ msgstr "Raccourci" msgid "Action" msgstr "Action" -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:131 +#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:135 #: ../src\wxUI\dialogs\lists.py:20 ../src\wxUI\dialogs\userAliasDialogs.py:53 msgid "Edit" msgstr "Modifier" @@ -1830,7 +1831,7 @@ msgstr "Windows" msgid "Key" msgstr "Touche" -#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:82 +#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:80 #: ../src\wxUI\dialogs\find.py:21 ../src\wxUI\dialogs\userAliasDialogs.py:23 #: ../src\wxUI\dialogs\utils.py:36 msgid "OK" @@ -2007,16 +2008,16 @@ msgstr "privé" msgid "public" msgstr "public" -#: ../src\sessions\twitter\session.py:209 +#: ../src\sessions\twitter\session.py:211 msgid "%s failed. Reason: %s" msgstr "%s erreur. Raison: %s" -#: ../src\sessions\twitter\session.py:215 +#: ../src\sessions\twitter\session.py:217 msgid "%s succeeded." msgstr "%s réussi." -#: ../src\sessions\twitter\session.py:424 -#: ../src\sessions\twitter\session.py:502 +#: ../src\sessions\twitter\session.py:426 +#: ../src\sessions\twitter\session.py:504 msgid "Deleted account" msgstr "Compte supprimé" @@ -2561,7 +2562,7 @@ msgid "Status" msgstr "Statut" #: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Buffer" msgstr "Tampon" @@ -2686,91 +2687,99 @@ msgstr "Supplémentaires" msgid "Save" msgstr "Enregistrer" -#: ../src\wxUI\dialogs\filterDialogs.py:16 +#: ../src\wxUI\dialogs\filterDialogs.py:13 msgid "Create a filter for this buffer" msgstr "Créer un filtre pour ce tampon" -#: ../src\wxUI\dialogs\filterDialogs.py:17 +#: ../src\wxUI\dialogs\filterDialogs.py:14 msgid "Filter title" msgstr "Titre du filtre" -#: ../src\wxUI\dialogs\filterDialogs.py:26 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:24 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by word" msgstr "Filtrer par mot" -#: ../src\wxUI\dialogs\filterDialogs.py:27 +#: ../src\wxUI\dialogs\filterDialogs.py:25 msgid "Ignore tweets wich contain the following word" msgstr "Ignorer les tweets contenant le mot suivant" -#: ../src\wxUI\dialogs\filterDialogs.py:28 +#: ../src\wxUI\dialogs\filterDialogs.py:26 msgid "Ignore tweets without the following word" msgstr "Ignorer les tweets ne contenant pas le mot suivant" -#: ../src\wxUI\dialogs\filterDialogs.py:33 +#: ../src\wxUI\dialogs\filterDialogs.py:31 msgid "word" msgstr "Mot" -#: ../src\wxUI\dialogs\filterDialogs.py:38 +#: ../src\wxUI\dialogs\filterDialogs.py:36 msgid "Allow retweets" msgstr "Permettre les retweets" -#: ../src\wxUI\dialogs\filterDialogs.py:39 +#: ../src\wxUI\dialogs\filterDialogs.py:37 msgid "Allow quoted tweets" msgstr "Permettre les tweets cités" -#: ../src\wxUI\dialogs\filterDialogs.py:40 +#: ../src\wxUI\dialogs\filterDialogs.py:38 msgid "Allow replies" msgstr "Permettre les réponses" -#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:46 msgid "Use this term as a regular expression" msgstr "Utiliser ce terme comme une expression régulière" -#: ../src\wxUI\dialogs\filterDialogs.py:50 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by language" msgstr "Filtrer par langue" -#: ../src\wxUI\dialogs\filterDialogs.py:51 +#: ../src\wxUI\dialogs\filterDialogs.py:49 msgid "Load tweets in the following languages" msgstr "Charger tweets dans les suivantes langues" -#: ../src\wxUI\dialogs\filterDialogs.py:52 +#: ../src\wxUI\dialogs\filterDialogs.py:50 msgid "Ignore tweets in the following languages" msgstr "Ignorer tweets dans les suivantes langues" -#: ../src\wxUI\dialogs\filterDialogs.py:53 +#: ../src\wxUI\dialogs\filterDialogs.py:51 msgid "Don't filter by language" msgstr "Ne pas filtrer par langue" -#: ../src\wxUI\dialogs\filterDialogs.py:64 +#: ../src\wxUI\dialogs\filterDialogs.py:62 msgid "Supported languages" msgstr "Langues supportées" -#: ../src\wxUI\dialogs\filterDialogs.py:69 +#: ../src\wxUI\dialogs\filterDialogs.py:67 msgid "Add selected language to filter" msgstr "Ajouter la langue sélectionnée au filtre" -#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:71 msgid "Selected languages" msgstr "Langue sélectionnée" -#: ../src\wxUI\dialogs\filterDialogs.py:75 -#: ../src\wxUI\dialogs\filterDialogs.py:133 ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:137 ../src\wxUI\dialogs\lists.py:21 #: ../src\wxUI\dialogs\lists.py:132 ../src\wxUI\dialogs\userAliasDialogs.py:57 msgid "Remove" msgstr "Effacer" -#: ../src\wxUI\dialogs\filterDialogs.py:123 +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "Missing filter name" +msgstr "Nom de filtre manquant" + +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "You must define a name for the filter before creating it." +msgstr "Vous devez définir un nom pour le filtre avant de le créer." + +#: ../src\wxUI\dialogs\filterDialogs.py:127 msgid "Manage filters" msgstr "Gérer les filtres" -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:129 msgid "Filters" msgstr "Filtres" -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter" msgstr "Filtre" From 4ddb406c8d4ced858c554f68009a9d6fc037728c Mon Sep 17 00:00:00 2001 From: Oreonan Date: Thu, 4 Nov 2021 17:00:59 +0100 Subject: [PATCH 03/83] Reduce texts --- src/locales/fr/LC_MESSAGES/twblue.po | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/locales/fr/LC_MESSAGES/twblue.po b/src/locales/fr/LC_MESSAGES/twblue.po index a22173de..e31dd0e1 100644 --- a/src/locales/fr/LC_MESSAGES/twblue.po +++ b/src/locales/fr/LC_MESSAGES/twblue.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.94\n" "POT-Creation-Date: 2021-11-03 18:55+0100\n" -"PO-Revision-Date: 2021-11-03 18:57+0100\n" +"PO-Revision-Date: 2021-11-04 17:00+0100\n" "Last-Translator: Oreonan \n" "Language-Team: Oreonan \n" "Language: fr\n" @@ -37,12 +37,12 @@ msgstr "Mentions" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:341 msgid "Direct messages" -msgstr "Messages privés" +msgstr "Messages" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:343 ../src\controller\settings.py:289 msgid "Sent direct messages" -msgstr "Messages privés envoyés" +msgstr "Messages envoyés" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:345 ../src\controller\settings.py:290 @@ -146,12 +146,12 @@ msgstr "Répondre à %s" #: ../src\controller\buffers\twitter\base.py:480 #: ../src\controller\buffers\twitter\directMessages.py:130 msgid "New direct message" -msgstr "Nouveau message privé" +msgstr "Nouveau message" #: ../src\controller\buffers\twitter\base.py:480 #: ../src\controller\messages.py:200 msgid "Direct message to %s" -msgstr "Message privé à %s" +msgstr "Message à %s" #: ../src\controller\buffers\twitter\base.py:520 msgid "Add your comment to the tweet" @@ -186,7 +186,7 @@ msgstr "Mention" #: ../src\controller\buffers\twitter\directMessages.py:133 msgid "{0} new direct messages." -msgstr "{0} nouveau message privé" +msgstr "{0} nouveau message" #: ../src\controller\buffers\twitter\directMessages.py:136 msgid "This action is not supported in the buffer yet." @@ -198,7 +198,7 @@ msgid "" "buffer instead." msgstr "" "Récupérer plus d'élément est impossible dans ce tampon, utilisez le tampon " -"des messages privés à la place." +"des messages à la place." #: ../src\controller\buffers\twitter\people.py:253 msgid "{0} new followers." @@ -523,7 +523,7 @@ msgstr "Paramètres du compte de %s" #: ../src\controller\settings.py:288 msgid "Direct Messages" -msgstr "Messages privés" +msgstr "Messages" #: ../src\controller\user.py:29 ../src\controller\user.py:31 #: ../src\extra\SpellChecker\wx_ui.py:80 ../src\issueReporter\wx_ui.py:84 @@ -619,7 +619,7 @@ msgstr "Favoris: %s" #: ../src\controller\userActionsController.py:74 msgid "You can't ignore direct messages" -msgstr "Vous ne pouvez pas ignorer les messages privés" +msgstr "Vous ne pouvez pas ignorer les messages" #: ../src\controller\userAliasController.py:32 msgid "Edit alias for {}" @@ -783,11 +783,11 @@ msgstr "Tampon détruit." #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 msgid "Direct message received." -msgstr "Message privé reçu." +msgstr "Message reçu." #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 msgid "Direct message sent." -msgstr "Message privé envoyé." +msgstr "Message envoyé." #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 msgid "Error." @@ -1569,7 +1569,7 @@ msgstr "Retweet" #: ../src\keystrokeEditor\constants.py:13 msgid "Send direct message" -msgstr "Envoyer un message privé" +msgstr "Envoyer un message" #: ../src\keystrokeEditor\constants.py:14 msgid "Like a tweet" @@ -1649,7 +1649,7 @@ msgstr "Modifier le profil" #: ../src\keystrokeEditor\constants.py:33 msgid "Delete a tweet or direct message" -msgstr "Supprimer un tweet ou un message privé" +msgstr "Supprimer un tweet ou un message" #: ../src\keystrokeEditor\constants.py:34 msgid "Empty the current buffer" @@ -2116,7 +2116,7 @@ msgstr "Utilisateur" #: ../src\wxUI\buffers\base.py:28 msgid "Direct message" -msgstr "Message privé" +msgstr "Message" #: ../src\wxUI\buffers\events.py:14 msgid "Event" @@ -3235,7 +3235,7 @@ msgstr "&Actions de l'utilisateur..." #: ../src\wxUI\menus.py:40 msgid "&Show direct message" -msgstr "&Afficher le message privé" +msgstr "&Afficher le message" #: ../src\wxUI\menus.py:68 msgid "&Show event" @@ -3243,7 +3243,7 @@ msgstr "&Afficher l'événement" #: ../src\wxUI\menus.py:78 msgid "Direct &message" -msgstr "&Message privé" +msgstr "&Message" #: ../src\wxUI\menus.py:80 ../src\wxUI\view.py:50 msgid "&View lists" @@ -3343,7 +3343,7 @@ msgstr "Voir &chronologie..." #: ../src\wxUI\view.py:46 msgid "Direct me&ssage" -msgstr "&Message privé" +msgstr "&Message" #: ../src\wxUI\view.py:47 msgid "Add a&lias" From a80184bf204e303c2f8fc4a4344f589ea3fc6150 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Thu, 4 Nov 2021 11:17:07 -0600 Subject: [PATCH 04/83] Restored conversation support with API V1 as V2 hits the limits quickly. Closes #427 --- src/controller/buffers/twitter/search.py | 33 +++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/controller/buffers/twitter/search.py b/src/controller/buffers/twitter/search.py index 7a75d702..db72fd35 100644 --- a/src/controller/buffers/twitter/search.py +++ b/src/controller/buffers/twitter/search.py @@ -69,7 +69,7 @@ class ConversationBuffer(SearchBuffer): current_time = time.time() if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True: self.execution_time = current_time - results = self.get_replies(self.tweet) + results = self.get_replies_v1(self.tweet) number_of_items = self.session.order_buffer(self.name, results) log.debug("Number of items retrieved: %d" % (number_of_items,)) self.put_items_on_list(number_of_items) @@ -147,4 +147,35 @@ class ConversationBuffer(SearchBuffer): results.extend(reply_results) except TweepyException as e: log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name)) + return results + + def get_replies_v1(self, tweet): + try: + tweet = self.session.twitter.get_status(id=tweet.id, tweet_mode="extended") + except: + log.exception("Error getting tweet for making a conversation buffer.") + return [] + results = [] + results.append(tweet) + if hasattr(tweet, "in_reply_to_status_id") and tweet.in_reply_to_status_id != None: + while tweet.in_reply_to_status_id != None: + original_tweet = self.session.twitter.get_status(id=tweet.in_reply_to_status_id, tweet_mode="extended") + results.insert(0, original_tweet) + tweet = original_tweet + try: + term = "from:{} to:{}".format(tweet.user.screen_name, tweet.user.screen_name) + thread_tweets = self.session.twitter.search_tweets(term, count=100, since_id=tweet.id, tweet_mode="extended") + results.extend(thread_tweets) + except TweepyException as e: + log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name)) + + try: + term = "to:{}".format(tweet.user.screen_name) + reply_tweets = self.session.twitter.search_tweets(term, count=100, since_id=tweet.id, tweet_mode="extended") + ids = [t.id for t in results] + reply_tweets = [t for t in reply_tweets if hasattr(t, "in_reply_to_status_id") and t.in_reply_to_status_id in ids] + results.extend(reply_tweets) + except TweepyException as e: + log.exception("There was an error when attempting to retrieve the whole conversation for buffer {}".format(self.buffer.name)) + results.sort(key=lambda x: x.id) return results \ No newline at end of file From 0cf0a64f40522cc29e07adb65d6a47120898efed Mon Sep 17 00:00:00 2001 From: riku Date: Fri, 5 Nov 2021 07:15:33 +0900 Subject: [PATCH 05/83] Update Japanese translation --- src/locales/ja/lc_messages/twblue.mo | Bin 61631 -> 61905 bytes src/locales/ja/lc_messages/twblue.po | 105 +++++++++++++++------------ 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/src/locales/ja/lc_messages/twblue.mo b/src/locales/ja/lc_messages/twblue.mo index e85315e4c8b7b687bba9266d803ab2abfab0fab7..9adb0dd5fdce74e3de3f266a30143e8ff88b2185 100644 GIT binary patch delta 16936 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 U>*n9yoj9}XodO$|-3|@-A7ch34gdfE delta 16717 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 F^MBHkyAc2Y diff --git a/src/locales/ja/lc_messages/twblue.po b/src/locales/ja/lc_messages/twblue.po index 496f81c5..d58a1594 100644 --- a/src/locales/ja/lc_messages/twblue.po +++ b/src/locales/ja/lc_messages/twblue.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-11-01 11:40+0900\n" +"PO-Revision-Date: 2021-11-05 07:15+0900\n" "Last-Translator: 陸 \n" "Language-Team: \n" "Language: ja_JP\n" @@ -101,7 +101,7 @@ msgid "Unknown buffer" msgstr "不明なバッファ" #: ../src\controller\buffers\twitter\base.py:88 -#: ../src\controller\buffers\twitter\trends.py:121 +#: ../src\controller\buffers\twitter\trends.py:122 #: ../src\controller\messages.py:214 ../src\wxUI\buffers\base.py:25 #: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 #: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:35 @@ -109,7 +109,7 @@ msgid "Tweet" msgstr "ツイート" #: ../src\controller\buffers\twitter\base.py:89 -#: ../src\controller\buffers\twitter\trends.py:122 +#: ../src\controller\buffers\twitter\trends.py:123 msgid "Write the tweet here" msgstr "ツイートを入力" @@ -122,7 +122,7 @@ msgid "{0} new tweets in {1}." msgstr "「{1}」への{0}個の新規ツイート。" #: ../src\controller\buffers\twitter\base.py:261 -#: ../src\controller\buffers\twitter\directMessages.py:87 +#: ../src\controller\buffers\twitter\directMessages.py:88 #: ../src\controller\buffers\twitter\people.py:180 msgid "%s items retrieved" msgstr "%s個のアイテムを取得しました" @@ -146,7 +146,7 @@ msgid "Reply to %s" msgstr "「%s」への返信" #: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\buffers\twitter\directMessages.py:129 +#: ../src\controller\buffers\twitter\directMessages.py:130 msgid "New direct message" msgstr "新しいダイレクトメッセージ" @@ -175,26 +175,26 @@ msgstr "ユーザーの詳細" msgid "Opening item in web browser..." msgstr "ブラウザでアイテムを開いています…" -#: ../src\controller\buffers\twitter\directMessages.py:92 +#: ../src\controller\buffers\twitter\directMessages.py:93 #: ../src\controller\buffers\twitter\people.py:95 msgid "Mention to %s" msgstr "%sへのメンション" -#: ../src\controller\buffers\twitter\directMessages.py:92 +#: ../src\controller\buffers\twitter\directMessages.py:93 #: ../src\controller\buffers\twitter\people.py:95 #: ../src\wxUI\buffers\people.py:17 msgid "Mention" msgstr "メンション" -#: ../src\controller\buffers\twitter\directMessages.py:132 +#: ../src\controller\buffers\twitter\directMessages.py:133 msgid "{0} new direct messages." msgstr "{0}件の新しいダイレクトメッセージ。" -#: ../src\controller\buffers\twitter\directMessages.py:135 +#: ../src\controller\buffers\twitter\directMessages.py:136 msgid "This action is not supported in the buffer yet." msgstr "この動作は、現在のバッファではサポートされていません。" -#: ../src\controller\buffers\twitter\directMessages.py:145 +#: ../src\controller\buffers\twitter\directMessages.py:146 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." @@ -206,7 +206,7 @@ msgstr "" msgid "{0} new followers." msgstr "{0}人の新しいフォロワー。" -#: ../src\controller\buffers\twitter\trends.py:145 +#: ../src\controller\buffers\twitter\trends.py:146 msgid "This action is not supported in the buffer, yet." msgstr "この動作は、現在のバッファではサポートされていません。" @@ -279,6 +279,7 @@ msgstr "「{}」の検索結果" #: ../src\controller\mainController.py:381 #: ../src\controller\mainController.py:982 +#: ../src\controller\mainController.py:1593 msgid "Trending topics for %s" msgstr "%s のトレンド" @@ -426,20 +427,20 @@ msgstr "バッファを更新中…" msgid "{0} items retrieved" msgstr "{0}個のアイテムを取得しました" -#: ../src\controller\mainController.py:1598 -#: ../src\controller\mainController.py:1618 +#: ../src\controller\mainController.py:1600 +#: ../src\controller\mainController.py:1620 msgid "Invalid buffer" msgstr "無効なバッファ" -#: ../src\controller\mainController.py:1609 +#: ../src\controller\mainController.py:1611 msgid "Picture {0}" msgstr "画像{0}" -#: ../src\controller\mainController.py:1610 +#: ../src\controller\mainController.py:1612 msgid "Select the picture" msgstr "画像を選択" -#: ../src\controller\mainController.py:1629 +#: ../src\controller\mainController.py:1631 msgid "Unable to extract text" msgstr "テキストを抽出できません" @@ -1483,7 +1484,7 @@ msgstr "" msgid "Send report" msgstr "レポートを送信" -#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:84 +#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:83 #: ../src\wxUI\dialogs\find.py:23 msgid "Cancel" msgstr "キャンセル" @@ -1769,7 +1770,7 @@ msgstr "キーストローク" msgid "Action" msgstr "操作" -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:131 +#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:135 #: ../src\wxUI\dialogs\lists.py:20 ../src\wxUI\dialogs\userAliasDialogs.py:53 msgid "Edit" msgstr "編集" @@ -1819,7 +1820,7 @@ msgstr "ウィンドウズ" msgid "Key" msgstr "キー名" -#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:82 +#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:80 #: ../src\wxUI\dialogs\find.py:21 ../src\wxUI\dialogs\userAliasDialogs.py:23 #: ../src\wxUI\dialogs\utils.py:36 msgid "OK" @@ -1994,16 +1995,16 @@ msgstr "プライベート" msgid "public" msgstr "公式" -#: ../src\sessions\twitter\session.py:209 +#: ../src\sessions\twitter\session.py:211 msgid "%s failed. Reason: %s" msgstr "%s が失敗しました。理由: %s" -#: ../src\sessions\twitter\session.py:215 +#: ../src\sessions\twitter\session.py:217 msgid "%s succeeded." msgstr "%sに成功しました。" -#: ../src\sessions\twitter\session.py:424 -#: ../src\sessions\twitter\session.py:502 +#: ../src\sessions\twitter\session.py:426 +#: ../src\sessions\twitter\session.py:504 msgid "Deleted account" msgstr "削除されたアカウント" @@ -2541,7 +2542,7 @@ msgid "Status" msgstr "ステータス" #: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Buffer" msgstr "バッファ" @@ -2666,91 +2667,99 @@ msgstr "その他" msgid "Save" msgstr "保存" -#: ../src\wxUI\dialogs\filterDialogs.py:16 +#: ../src\wxUI\dialogs\filterDialogs.py:13 msgid "Create a filter for this buffer" msgstr "このバッファのフィルタを作成" -#: ../src\wxUI\dialogs\filterDialogs.py:17 +#: ../src\wxUI\dialogs\filterDialogs.py:14 msgid "Filter title" msgstr "フィルター名" -#: ../src\wxUI\dialogs\filterDialogs.py:26 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:24 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by word" msgstr "単語でフィルター" -#: ../src\wxUI\dialogs\filterDialogs.py:27 +#: ../src\wxUI\dialogs\filterDialogs.py:25 msgid "Ignore tweets wich contain the following word" msgstr "次の単語が含まれるツイートを無視する" -#: ../src\wxUI\dialogs\filterDialogs.py:28 +#: ../src\wxUI\dialogs\filterDialogs.py:26 msgid "Ignore tweets without the following word" msgstr "次の単語が含まれないツイートを無視する" -#: ../src\wxUI\dialogs\filterDialogs.py:33 +#: ../src\wxUI\dialogs\filterDialogs.py:31 msgid "word" msgstr "単語" -#: ../src\wxUI\dialogs\filterDialogs.py:38 +#: ../src\wxUI\dialogs\filterDialogs.py:36 msgid "Allow retweets" msgstr "リツイートを許可する" -#: ../src\wxUI\dialogs\filterDialogs.py:39 +#: ../src\wxUI\dialogs\filterDialogs.py:37 msgid "Allow quoted tweets" msgstr "引用ツイートを許可する" -#: ../src\wxUI\dialogs\filterDialogs.py:40 +#: ../src\wxUI\dialogs\filterDialogs.py:38 msgid "Allow replies" msgstr "リプライを許可するフォロワー一覧" -#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:46 msgid "Use this term as a regular expression" msgstr "正規表現を利用" -#: ../src\wxUI\dialogs\filterDialogs.py:50 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by language" msgstr "言語でフィルター" -#: ../src\wxUI\dialogs\filterDialogs.py:51 +#: ../src\wxUI\dialogs\filterDialogs.py:49 msgid "Load tweets in the following languages" msgstr "下記の言語のツイートを表示" -#: ../src\wxUI\dialogs\filterDialogs.py:52 +#: ../src\wxUI\dialogs\filterDialogs.py:50 msgid "Ignore tweets in the following languages" msgstr "下記の言語のツイートを無視する" -#: ../src\wxUI\dialogs\filterDialogs.py:53 +#: ../src\wxUI\dialogs\filterDialogs.py:51 msgid "Don't filter by language" msgstr "言語でフィルタしない" -#: ../src\wxUI\dialogs\filterDialogs.py:64 +#: ../src\wxUI\dialogs\filterDialogs.py:62 msgid "Supported languages" msgstr "サポートしている言語" -#: ../src\wxUI\dialogs\filterDialogs.py:69 +#: ../src\wxUI\dialogs\filterDialogs.py:67 msgid "Add selected language to filter" msgstr "選択した言語をフィルターに追加" -#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:71 msgid "Selected languages" msgstr "選択した言語" -#: ../src\wxUI\dialogs\filterDialogs.py:75 -#: ../src\wxUI\dialogs\filterDialogs.py:133 ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:137 ../src\wxUI\dialogs\lists.py:21 #: ../src\wxUI\dialogs\lists.py:132 ../src\wxUI\dialogs\userAliasDialogs.py:57 msgid "Remove" msgstr "削除" -#: ../src\wxUI\dialogs\filterDialogs.py:123 +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "Missing filter name" +msgstr "フィルター名がありません" + +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "You must define a name for the filter before creating it." +msgstr "フィルターを作成する前に、フィルターの名前を定義する必要があります。" + +#: ../src\wxUI\dialogs\filterDialogs.py:127 msgid "Manage filters" msgstr "フィルターの管理" -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:129 msgid "Filters" msgstr "フィルター" -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter" msgstr "フィルター" From 4f0db5537e8b60096cd548d7db340a09a0250e46 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 5 Nov 2021 11:49:51 -0600 Subject: [PATCH 06/83] Added function to send tweets and threads in session module so it will be used globally later --- src/sessions/twitter/session.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index a219016c..f9de86fd 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -590,4 +590,20 @@ class Session(base.baseSession): if self.logged == False: return if user != self.db["user_name"]: - log.debug("Connected streaming endpoint on account {}".format(user)) \ No newline at end of file + log.debug("Connected streaming endpoint on account {}".format(user)) + + def send_tweet(self, *tweets): + """ Convenience function to send a thread. """ + in_reply_to_status_id = None + for obj in tweets: + if len(obj["attachments"]) == 0: + item = self.api_call(call_name="update_status", status=obj["text"], _sound="tweet_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id) + in_reply_to_status_id = item.id + else: + media_ids = [] + for i in obj["attachments"]: + img = self.api_call("media_upload", filename=i["file"]) + self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) + media_ids.append(img.media_id) + item = self.api_call(call_name="update_status", status=obj["text"], _sound="tweet_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids) + in_reply_to_status_id = item.id \ No newline at end of file From 66bf95ee6245d515de3a306447cae1d07358edb7 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 5 Nov 2021 13:10:45 -0600 Subject: [PATCH 07/83] Added reply function to session module --- src/sessions/twitter/session.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index f9de86fd..a32ead2d 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -606,4 +606,15 @@ class Session(base.baseSession): self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) item = self.api_call(call_name="update_status", status=obj["text"], _sound="tweet_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids) - in_reply_to_status_id = item.id \ No newline at end of file + in_reply_to_status_id = item.id + + def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs): + if len(attachments) == 0: + item = self.api_call(call_name="update_status", status=text, _sound="reply_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, *args, **kwargs) + else: + media_ids = [] + for i in attachments: + img = self.api_call("media_upload", filename=i["file"]) + self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) + media_ids.append(img.media_id) + item = self.api_call(call_name="update_status", status=text, _sound="reply_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids, *args, **kwargs) From cedb290956fec7345c893054ac0121bade2e6b28 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 5 Nov 2021 22:35:12 -0600 Subject: [PATCH 08/83] fixed an issue when deleting a buffer in a session where there were trending topics opened --- doc/changelog.md | 5 +++-- src/wxUI/buffers/trends.py | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index 1222937d..513204c2 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -3,10 +3,11 @@ TWBlue Changelog ## changes in this version * TWBlue should retrieve tweets from threads and conversations in a more reliable way. Tweets in the same thread (made by the same author) will be sorted correctly, although replies to the thread (made by different people) may not be ordered in the same way they are displayed in Twitter apps. ([#417](https://github.com/manuelcortez/TWBlue/issues/417)) -* fixed a bug when clearing the direct messages buffer. ([#418](https://github.com/manuelcortez/TWBlue/issues/418)) -* fixed an issue that was making TWBlue to show incorrectly titles for trending topic buffers upon startup. ([#421](https://github.com/manuelcortez/TWBlue/issues/421)) * When creating a filter, TWBlue will show an error if user has not provided a name for the filter. Before, unnamed filters were a cause of config breaks in the application. * It is again possible to read the changelog for TWBlue from the help menu in the menu bar. +* fixed a bug when clearing the direct messages buffer. ([#418](https://github.com/manuelcortez/TWBlue/issues/418)) +* fixed an issue that was making TWBlue to show incorrectly titles for trending topic buffers upon startup. ([#421](https://github.com/manuelcortez/TWBlue/issues/421)) +* fixed an issue that was making users of the graphical user interface to delete a buffer if a trends buffer was opened in the same session. * Updated Spanish, Japanese and french translations. ## Changes in Version 2021.10.30 diff --git a/src/wxUI/buffers/trends.py b/src/wxUI/buffers/trends.py index 975a88ca..b9e67101 100644 --- a/src/wxUI/buffers/trends.py +++ b/src/wxUI/buffers/trends.py @@ -32,3 +32,5 @@ class trendsPanel(wx.Panel): else: self.list.select_item(0) + def set_focus_in_list(self): + self.list.list.SetFocus() From 556ffd832b8e827b74d8c10fa9ab664c1f443027 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Sun, 7 Nov 2021 06:34:27 -0600 Subject: [PATCH 09/83] Updated translation machine catalog for french translation --- src/locales/fr/LC_MESSAGES/twblue.mo | Bin 52802 -> 56563 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/locales/fr/LC_MESSAGES/twblue.mo b/src/locales/fr/LC_MESSAGES/twblue.mo index c83284cf0f3be22bf81f266e6aa87282f93e65b5..2d8ceb5cd79bfc8523ba19a9b3344d478969ea03 100644 GIT binary patch delta 20359 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 Date: Mon, 8 Nov 2021 15:29:23 -0600 Subject: [PATCH 10/83] Removed URL Shorteners --- src/url_shortener/__init__.py | 3 -- src/url_shortener/__main__.py | 46 ------------------- src/url_shortener/shorteners/__init__.py | 11 ----- src/url_shortener/shorteners/acortame.py | 30 ------------ src/url_shortener/shorteners/clckru.py | 22 --------- src/url_shortener/shorteners/hkcim.py | 21 --------- src/url_shortener/shorteners/isgd.py | 22 --------- src/url_shortener/shorteners/onjme.py | 21 --------- src/url_shortener/shorteners/tinyarrows.py | 21 --------- src/url_shortener/shorteners/tinyurl.py | 20 -------- src/url_shortener/shorteners/url_shortener.py | 44 ------------------ src/url_shortener/shorteners/xedcc.py | 21 --------- 12 files changed, 282 deletions(-) delete mode 100644 src/url_shortener/__init__.py delete mode 100644 src/url_shortener/__main__.py delete mode 100644 src/url_shortener/shorteners/__init__.py delete mode 100644 src/url_shortener/shorteners/acortame.py delete mode 100644 src/url_shortener/shorteners/clckru.py delete mode 100644 src/url_shortener/shorteners/hkcim.py delete mode 100644 src/url_shortener/shorteners/isgd.py delete mode 100644 src/url_shortener/shorteners/onjme.py delete mode 100644 src/url_shortener/shorteners/tinyarrows.py delete mode 100644 src/url_shortener/shorteners/tinyurl.py delete mode 100644 src/url_shortener/shorteners/url_shortener.py delete mode 100644 src/url_shortener/shorteners/xedcc.py diff --git a/src/url_shortener/__init__.py b/src/url_shortener/__init__.py deleted file mode 100644 index 419c8170..00000000 --- a/src/url_shortener/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from __future__ import unicode_literals -from . import shorteners -from . __main__ import * diff --git a/src/url_shortener/__main__.py b/src/url_shortener/__main__.py deleted file mode 100644 index 7e3dcf05..00000000 --- a/src/url_shortener/__main__.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import unicode_literals -from functools import wraps -from . import shorteners - - -def service_selecter (func): - @wraps(func) - def wrapper (*args, **kwargs): - tmp = dict(kwargs) - if 'service' in tmp: - del(tmp['service']) - kwargs['service'] = find_service(kwargs['service'], **tmp) or default_service() - else: - kwargs['service'] = default_service() - return func(*args, **kwargs) - return wrapper - -@service_selecter -def shorten (url, service=None, **kwargs): - return service(**kwargs).shorten(url) - - -@service_selecter -def unshorten (url, service=None, **kwargs): - return service(**kwargs).unshorten(url) - - -def default_service (): - return shorteners.AcortameShortener - -def find_service (service, **kwargs): - for i in shorteners.__all__: - obj = getattr(shorteners, i)(**kwargs) - if obj.name.lower() == service.lower(): - return getattr(shorteners, i) - -def list_services (): - return [getattr(shorteners, i)().name for i in shorteners.__all__] - -def unshorten_any (url): - """Unshortens an URL using any available unshortener. Check to see if unshortened URL was created by a shortener (nested) and unshorten if so.""" - unshortened_url = shorteners.URLShortener().unshorten(url) - # None is returned if URL not unshortened - if unshortened_url: - return unshorten_any(unshortened_url) - return url diff --git a/src/url_shortener/shorteners/__init__.py b/src/url_shortener/shorteners/__init__.py deleted file mode 100644 index aa0b763d..00000000 --- a/src/url_shortener/shorteners/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from __future__ import unicode_literals -from .url_shortener import URLShortener -from .hkcim import HKCShortener -from . isgd import IsgdShortener -from . onjme import OnjmeShortener -from . tinyarrows import TinyArrowsShortener -from . tinyurl import TinyurlShortener -from . xedcc import XedccShortener -from . clckru import ClckruShortener -from . acortame import AcortameShortener -__all__ = ["HKCShortener", "IsgdShortener", "OnjmeShortener", "TinyArrowsShortener", "TinyurlShortener", "XedccShortener", "ClckruShortener", "AcortameShortener"] diff --git a/src/url_shortener/shorteners/acortame.py b/src/url_shortener/shorteners/acortame.py deleted file mode 100644 index e7adafb6..00000000 --- a/src/url_shortener/shorteners/acortame.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -from . url_shortener import URLShortener -import requests -import urllib.request, urllib.parse, urllib.error -class AcortameShortener (URLShortener): - def __init__(self, *args, **kwargs): - self.name = "acorta.me" - super(AcortameShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("https://acorta.me/api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'acorta.me' in url - - def unshorten (self, url): - if not 'acorta.me' in url: - #use generic expand method - return super(AcortameShortener, self).unshorten(url) - answer = url - api = requests.get ("https://acorta.me/api.php?action=expand&format=simple&shorturl=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer diff --git a/src/url_shortener/shorteners/clckru.py b/src/url_shortener/shorteners/clckru.py deleted file mode 100644 index 9c527ea1..00000000 --- a/src/url_shortener/shorteners/clckru.py +++ /dev/null @@ -1,22 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - - -class ClckruShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "clck.ru" - super(ClckruShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://clck.ru/--?url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'clck.ru' in url diff --git a/src/url_shortener/shorteners/hkcim.py b/src/url_shortener/shorteners/hkcim.py deleted file mode 100644 index 29ecd9ea..00000000 --- a/src/url_shortener/shorteners/hkcim.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - -class HKCShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "HKC.im" - super(HKCShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://hkc.im/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'hkc.im' in url.lower() diff --git a/src/url_shortener/shorteners/isgd.py b/src/url_shortener/shorteners/isgd.py deleted file mode 100644 index ee817360..00000000 --- a/src/url_shortener/shorteners/isgd.py +++ /dev/null @@ -1,22 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - - -class IsgdShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "Is.gd" - super(IsgdShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://is.gd/api.php?longurl=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'is.gd' in url diff --git a/src/url_shortener/shorteners/onjme.py b/src/url_shortener/shorteners/onjme.py deleted file mode 100644 index c6a21315..00000000 --- a/src/url_shortener/shorteners/onjme.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - -class OnjmeShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "Onj.me" - super(OnjmeShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://onj.me/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'onj.me' in url.lower() diff --git a/src/url_shortener/shorteners/tinyarrows.py b/src/url_shortener/shorteners/tinyarrows.py deleted file mode 100644 index 45a8990c..00000000 --- a/src/url_shortener/shorteners/tinyarrows.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - -class TinyArrowsShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "TinyArro.ws" - super(TinyArrowsShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get("http://tinyarro.ws/api-create.php?utfpure=1&url=%s" % urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer.decode('UTF-8') - - def created_url(self, url): - return "tinyarro.ws" in url diff --git a/src/url_shortener/shorteners/tinyurl.py b/src/url_shortener/shorteners/tinyurl.py deleted file mode 100644 index 0a5703a3..00000000 --- a/src/url_shortener/shorteners/tinyurl.py +++ /dev/null @@ -1,20 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -from .url_shortener import URLShortener -import requests -import urllib.request, urllib.parse, urllib.error -class TinyurlShortener (URLShortener): - def __init__(self, *args, **kwargs): - self.name = "TinyURL.com" - super(TinyurlShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://tinyurl.com/api-create.php?url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'tinyurl.com' in url diff --git a/src/url_shortener/shorteners/url_shortener.py b/src/url_shortener/shorteners/url_shortener.py deleted file mode 100644 index cf1d6f76..00000000 --- a/src/url_shortener/shorteners/url_shortener.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import unicode_literals -from builtins import object -import requests - -class URLShortener (object): - - def __init__ (self, *args, **kwargs): - #Stub out arguments, silly object. :( - return super(URLShortener, self).__init__() - - def shorten (self, url): - if self.created_url(url): - return url - else: - return self._shorten(url) - - def _shorten (self, url): - raise NotImplementedError - - def created_url (self, url): - """Returns a boolean indicating whether or not this shortener created a provided url""" - raise NotImplementedError - - def unshorten(self, url): - try: - r=requests.head(url) - if 'location' in list(r.headers.keys()): - if 'dropbox.com' in r.headers['location']: - return handle_dropbox(r.headers['location']) - else: - return r.headers['location'] - else: # if the head method does not work, use get instead. Performance may decrease - r=requests.get(url, allow_redirects=False, stream=True) - # release the connection without downloading the content, we only need the response headers - r.close() - return r.headers['location'] - except: - return url #we cannot expand - -def handle_dropbox(url): - if url.endswith("dl=1"): - return url - else: - return url.replace("dl=0", "dl=1") diff --git a/src/url_shortener/shorteners/xedcc.py b/src/url_shortener/shorteners/xedcc.py deleted file mode 100644 index 117b4f7c..00000000 --- a/src/url_shortener/shorteners/xedcc.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import unicode_literals -from future import standard_library -standard_library.install_aliases() -import urllib.request, urllib.parse, urllib.error -import requests -from . url_shortener import URLShortener - -class XedccShortener (URLShortener): - def __init__ (self, *args, **kwargs): - self.name = "Xed.cc" - super(XedccShortener, self).__init__(*args, **kwargs) - - def _shorten (self, url): - answer = url - api = requests.get ("http://xed.cc/yourls-api.php?action=shorturl&format=simple&url=" + urllib.parse.quote(url)) - if api.status_code == 200: - answer = api.text - return answer - - def created_url (self, url): - return 'xed.cc' in url.lower() From 2c70fe46b7cc9f682bed849fd92072939654c8c9 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 15:30:40 -0600 Subject: [PATCH 11/83] Removed url_shortener from sound handling module --- src/sound.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sound.py b/src/sound.py index df47f221..cd0f5a93 100644 --- a/src/sound.py +++ b/src/sound.py @@ -6,7 +6,6 @@ import subprocess import platform import tempfile import glob -import url_shortener import audio_services import paths import sound_lib @@ -121,7 +120,7 @@ class URLStream(object): """ Takes an URL and prepares it to be streamed. This function will try to unshorten the passed URL and, if needed, to transform it into a valid URL.""" log.debug("Preparing URL: %s" % (url,)) self.prepared = False - self.url = url_shortener.unshorten(url) + self.url = url if self.url == None: self.url = url log.debug("Expanded URL: %s" % (self.url,)) From 38e3274adc1a59243a6768a3e6ac2104a19ad11c Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 16:09:32 -0600 Subject: [PATCH 12/83] Removed GUI for tweets/reply/dm/viewTweets items and attachment code --- src/controller/attach.py | 40 --- src/wxUI/dialogs/attach.py | 48 ---- src/wxUI/dialogs/message.py | 471 ------------------------------------ 3 files changed, 559 deletions(-) delete mode 100644 src/controller/attach.py delete mode 100644 src/wxUI/dialogs/attach.py delete mode 100644 src/wxUI/dialogs/message.py diff --git a/src/controller/attach.py b/src/controller/attach.py deleted file mode 100644 index 08427142..00000000 --- a/src/controller/attach.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals -from builtins import object -import os -import widgetUtils -import logging -from wxUI.dialogs import attach as gui -log = logging.getLogger("controller.attach") - -class attach(object): - def __init__(self): - self.attachments = list() - self.dialog = gui.attachDialog() - widgetUtils.connect_event(self.dialog.photo, widgetUtils.BUTTON_PRESSED, self.upload_image) - widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_attachment) - self.dialog.get_response() - log.debug("Attachments controller started.") - - def upload_image(self, *args, **kwargs): - image, description = self.dialog.get_image() - if image != None: - imageInfo = {"type": "photo", "file": image, "description": description} - log.debug("Image data to upload: %r" % (imageInfo,)) - self.attachments.append(imageInfo) - info = [_(u"Photo"), description] - self.dialog.attachments.insert_item(False, *info) - self.dialog.remove.Enable(True) - - def remove_attachment(self, *args, **kwargs): - current_item = self.dialog.attachments.get_selected() - log.debug("Removing item %d" % (current_item,)) - if current_item == -1: current_item = 0 - self.attachments.pop(current_item) - self.dialog.attachments.remove_item(current_item) - self.check_remove_status() - log.debug("Removed") - - def check_remove_status(self): - if len(self.attachments) == 0 and self.dialog.attachments.get_count() == 0: - self.dialog.remove.Enable(False) diff --git a/src/wxUI/dialogs/attach.py b/src/wxUI/dialogs/attach.py deleted file mode 100644 index 0b20a422..00000000 --- a/src/wxUI/dialogs/attach.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -""" Attach dialog. Taken from socializer: https://github.com/manuelcortez/socializer""" -from __future__ import unicode_literals -import wx -import widgetUtils -from multiplatform_widgets import widgets - -class attachDialog(widgetUtils.BaseDialog): - def __init__(self): - super(attachDialog, self).__init__(None, title=_(u"Add an attachment")) - panel = wx.Panel(self) - sizer = wx.BoxSizer(wx.VERTICAL) - lbl1 = wx.StaticText(panel, wx.ID_ANY, _(u"Attachments")) - self.attachments = widgets.list(panel, _(u"Type"), _(u"Title"), style=wx.LC_REPORT) - box = wx.BoxSizer(wx.HORIZONTAL) - box.Add(lbl1, 0, wx.ALL, 5) - box.Add(self.attachments.list, 0, wx.ALL, 5) - sizer.Add(box, 0, wx.ALL, 5) - static = wx.StaticBox(panel, label=_(u"Add attachments")) - self.photo = wx.Button(panel, wx.ID_ANY, _(u"&Photo")) - self.remove = wx.Button(panel, wx.ID_ANY, _(u"Remove attachment")) - self.remove.Enable(False) - btnsizer = wx.StaticBoxSizer(static, wx.HORIZONTAL) - btnsizer.Add(self.photo, 0, wx.ALL, 5) - sizer.Add(btnsizer, 0, wx.ALL, 5) - ok = wx.Button(panel, wx.ID_OK) - ok.SetDefault() - cancelBtn = wx.Button(panel, wx.ID_CANCEL) - btnSizer = wx.BoxSizer() - btnSizer.Add(ok, 0, wx.ALL, 5) - btnSizer.Add(cancelBtn, 0, wx.ALL, 5) - sizer.Add(btnSizer, 0, wx.ALL, 5) - panel.SetSizer(sizer) - self.SetClientSize(sizer.CalcMin()) - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return (None, None) - dsc = self.ask_description() - return (openFileDialog.GetPath(), dsc) - - def ask_description(self): - dlg = wx.TextEntryDialog(self, _(u"please provide a description"), _(u"Description")) - dlg.ShowModal() - result = dlg.GetValue() - dlg.Destroy() - return result diff --git a/src/wxUI/dialogs/message.py b/src/wxUI/dialogs/message.py deleted file mode 100644 index 8eadfdd9..00000000 --- a/src/wxUI/dialogs/message.py +++ /dev/null @@ -1,471 +0,0 @@ -# -*- coding: utf-8 -*- -import wx -import widgetUtils - -class textLimited(widgetUtils.BaseDialog): - def __init__(self, *args, **kwargs): - super(textLimited, self).__init__(parent=None, *args, **kwargs) - - def createTextArea(self, message="", text=""): - if not hasattr(self, "panel"): - self.panel = wx.Panel(self) - self.label = wx.StaticText(self.panel, -1, message) - self.SetTitle(str(len(text))) - self.text = wx.TextCtrl(self.panel, -1, text, size=(439, -1),style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) -# font = self.text.GetFont() -# dc = wx.WindowDC(self.text) -# dc.SetFont(font) -# x, y = dc.GetTextExtent("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") -# self.text.SetSize((x, y)) - self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) - self.text.SetFocus() - self.textBox = wx.BoxSizer(wx.HORIZONTAL) - self.textBox.Add(self.label, 0, wx.ALL, 5) - self.textBox.Add(self.text, 0, wx.ALL, 5) - - def text_focus(self): - self.text.SetFocus() - - def get_text(self): - return self.text.GetValue() - - def set_text(self, text): - return self.text.ChangeValue(text) - - def set_title(self, new_title): - return self.SetTitle(new_title) - - def enable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Enable() - - def disable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Disable() - - def onSelect(self, ev): - self.text.SelectAll() - - def handle_keys(self, event): - shift=event.ShiftDown() - if event.GetKeyCode() == wx.WXK_RETURN and shift==False and hasattr(self,'okButton'): - wx.PostEvent(self.okButton.GetEventHandler(), wx.PyCommandEvent(wx.EVT_BUTTON.typeId,wx.ID_OK)) - else: - event.Skip() - - def set_cursor_at_end(self): - self.text.SetInsertionPoint(len(self.text.GetValue())) - - def set_cursor_at_position(self, position): - self.text.SetInsertionPoint(position) - - def get_position(self): - return self.text.GetInsertionPoint() - - def popup_menu(self, menu): - self.PopupMenu(menu, self.text.GetPosition()) - -class tweet(textLimited): - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, text) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.long_tweet = wx.CheckBox(self.panel, -1, _(u"&Long tweet")) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ - (wx.ACCEL_CTRL, ord('A'), selectId), - ]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, *args, **kwargs): - super(tweet, self).__init__() - self.shift=False - self.createControls(message, title, text) - self.SetClientSize(self.mainBox.CalcMin()) - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - - -class retweet(tweet): - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, "") - label = wx.StaticText(self.panel, -1, _(u"Retweet")) - self.text2 = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE|wx.TE_READONLY) - self.retweetBox = wx.BoxSizer(wx.HORIZONTAL) - self.retweetBox.Add(label, 0, wx.ALL, 5) - self.retweetBox.Add(self.text2, 0, wx.ALL, 5) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.mainBox.Add(self.retweetBox, 0, wx.ALL, 5) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ - (wx.ACCEL_CTRL, ord('A'), selectId), - ]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, *args, **kwargs): - super(tweet, self).__init__() - self.createControls(message, title, text) -# self.onTimer(wx.EVT_CHAR_HOOK) - self.SetClientSize(self.mainBox.CalcMin()) - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - -class dm(textLimited): - def createControls(self, title, message, users): - self.panel = wx.Panel(self) - self.mainBox = wx.BoxSizer(wx.VERTICAL) - label = wx.StaticText(self.panel, -1, _(u"&Recipient")) - self.cb = wx.ComboBox(self.panel, -1, choices=users, value=users[0], size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.createTextArea(message, text="") - userBox = wx.BoxSizer(wx.HORIZONTAL) - userBox.Add(label, 0, wx.ALL, 5) - userBox.Add(self.cb, 0, wx.ALL, 5) - userBox.Add(self.autocompletionButton, 0, wx.ALL, 5) - self.mainBox.Add(userBox, 0, wx.ALL, 5) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - self.buttonsBox.Add(self.attach, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox, 0, wx.ALL, 5) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.shortenButton, 0, wx.ALL, 5) - self.buttonsBox1.Add(self.unshortenButton, 0, wx.ALL, 5) - self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 5) - self.buttonsBox3 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox3.Add(self.okButton, 0, wx.ALL, 5) - self.buttonsBox3.Add(cancelButton, 0, wx.ALL, 5) - self.mainBox.Add(self.buttonsBox3, 0, wx.ALL, 5) - self.panel.SetSizer(self.mainBox) - self.SetClientSize(self.mainBox.CalcMin()) - - def __init__(self, title, message, users, *args, **kwargs): - super(dm, self).__init__() - self.createControls(title, message, users) -# self.onTimer(wx.EVT_CHAR_HOOK) -# self.SetClientSize(self.mainBox.CalcMin()) - - def get_user(self): - return self.cb.GetValue() - - def set_user(self, user): - return self.cb.SetValue(user) - -class reply(textLimited): - - def get_image(self): - openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) - if openFileDialog.ShowModal() == wx.ID_CANCEL: - return None - return open(openFileDialog.GetPath(), "rb") - - def createControls(self, title, message, text): - self.mainBox = wx.BoxSizer(wx.VERTICAL) - self.createTextArea(message, text) - self.mainBox.Add(self.textBox, 0, wx.ALL, 5) - self.usersbox = wx.BoxSizer(wx.VERTICAL) - self.mentionAll = wx.CheckBox(self.panel, -1, _(u"&Mention to all"), size=wx.DefaultSize) - self.mentionAll.Disable() - self.usersbox.Add(self.mentionAll, 0, wx.ALL, 5) - self.checkboxes = [] - for i in self.users: - user_checkbox = wx.CheckBox(self.panel, -1, "@"+i, size=wx.DefaultSize) - self.checkboxes.append(user_checkbox) - self.usersbox.Add(self.checkboxes[-1], 0, wx.ALL, 5) - self.mainBox.Add(self.usersbox, 0, wx.ALL, 10) - self.long_tweet = wx.CheckBox(self.panel, -1, _(u"&Long tweet")) - self.upload_image = wx.Button(self.panel, -1, _(u"&Upload image..."), size=wx.DefaultSize) - self.spellcheck = wx.Button(self.panel, -1, _("Check &spelling..."), size=wx.DefaultSize) - self.attach = wx.Button(self.panel, -1, _(u"&Attach audio..."), size=wx.DefaultSize) - self.shortenButton = wx.Button(self.panel, -1, _(u"Sh&orten URL"), size=wx.DefaultSize) - self.unshortenButton = wx.Button(self.panel, -1, _(u"&Expand URL"), size=wx.DefaultSize) - self.shortenButton.Disable() - self.unshortenButton.Disable() - self.translateButton = wx.Button(self.panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - self.autocompletionButton = wx.Button(self.panel, -1, _(u"Auto&complete users")) - self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Sen&d"), size=wx.DefaultSize) - self.okButton.SetDefault() - cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox1.Add(self.upload_image, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) - self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10) - self.buttonsBox2 = wx.BoxSizer(wx.HORIZONTAL) - self.buttonsBox2.Add(self.shortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.unshortenButton, 0, wx.ALL, 10) - self.buttonsBox2.Add(self.translateButton, 0, wx.ALL, 10) - self.mainBox.Add(self.buttonsBox2, 0, wx.ALL, 10) - self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL) - self.ok_cancelSizer.Add(self.autocompletionButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10) - self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10) - self.mainBox.Add(self.ok_cancelSizer, 0, wx.ALL, 10) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ - (wx.ACCEL_CTRL, ord('A'), selectId), - ]) - self.SetAcceleratorTable(self.accel_tbl) - self.panel.SetSizer(self.mainBox) - - def __init__(self, title, message, text, users=[], *args, **kwargs): - self.users = users - super(reply, self).__init__() - self.shift=False - self.createControls(message, title, text) - self.SetClientSize(self.mainBox.CalcMin()) - -class viewTweet(widgetUtils.BaseDialog): - def set_title(self, lenght): - self.SetTitle(_(u"Tweet - %i characters ") % (lenght,)) - - def __init__(self, text, rt_count, favs_count, source, date="", *args, **kwargs): - super(viewTweet, self).__init__(None, size=(850,850)) - panel = wx.Panel(self) - label = wx.StaticText(panel, -1, _(u"Tweet")) - self.text = wx.TextCtrl(panel, -1, text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.text) - dc.SetFont(self.text.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*140) - self.text.SetSize((x, y)) - self.text.SetFocus() - textBox = wx.BoxSizer(wx.HORIZONTAL) - textBox.Add(label, 0, wx.ALL, 5) - textBox.Add(self.text, 1, wx.EXPAND, 5) - mainBox = wx.BoxSizer(wx.VERTICAL) - mainBox.Add(textBox, 0, wx.ALL, 5) - label2 = wx.StaticText(panel, -1, _(u"Image description")) - self.image_description = wx.TextCtrl(panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.image_description) - dc.SetFont(self.image_description.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*450) - self.image_description.SetSize((x, y)) - self.image_description.Enable(False) - iBox = wx.BoxSizer(wx.HORIZONTAL) - iBox.Add(label2, 0, wx.ALL, 5) - iBox.Add(self.image_description, 1, wx.EXPAND, 5) - mainBox.Add(iBox, 0, wx.ALL, 5) - rtCountLabel = wx.StaticText(panel, -1, _(u"Retweets: ")) - rtCount = wx.TextCtrl(panel, -1, rt_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - rtBox = wx.BoxSizer(wx.HORIZONTAL) - rtBox.Add(rtCountLabel, 0, wx.ALL, 5) - rtBox.Add(rtCount, 0, wx.ALL, 5) - favsCountLabel = wx.StaticText(panel, -1, _(u"Likes: ")) - favsCount = wx.TextCtrl(panel, -1, favs_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - favsBox = wx.BoxSizer(wx.HORIZONTAL) - favsBox.Add(favsCountLabel, 0, wx.ALL, 5) - favsBox.Add(favsCount, 0, wx.ALL, 5) - sourceLabel = wx.StaticText(panel, -1, _(u"Source: ")) - sourceTweet = wx.TextCtrl(panel, -1, source, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) - sourceBox = wx.BoxSizer(wx.HORIZONTAL) - sourceBox.Add(sourceLabel, 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.Add(rtBox, 0, wx.ALL, 5) - infoBox.Add(favsBox, 0, wx.ALL, 5) - infoBox.Add(sourceBox, 0, wx.ALL, 5) - mainBox.Add(infoBox, 0, wx.ALL, 5) - mainBox.Add(dateBox, 0, wx.ALL, 5) - self.share = wx.Button(panel, wx.ID_ANY, _("Copy link to clipboard")) - self.share.Enable(False) - 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.Disable() - self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - cancelButton.SetDefault() - buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - buttonsBox.Add(self.share, 0, wx.ALL, 5) - buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) - buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) - buttonsBox.Add(cancelButton, 0, wx.ALL, 5) - mainBox.Add(buttonsBox, 0, wx.ALL, 5) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ - (wx.ACCEL_CTRL, ord('A'), selectId), - ]) - self.SetAcceleratorTable(self.accel_tbl) - panel.SetSizer(mainBox) - self.SetClientSize(mainBox.CalcMin()) - - def set_text(self, text): - self.text.ChangeValue(text) - - def get_text(self): - return self.text.GetValue() - - def set_image_description(self, desc): - self.image_description.Enable(True) - if len(self.image_description.GetValue()) == 0: - self.image_description.SetValue(desc) - else: - self.image_description.SetValue(self.image_description.GetValue()+"\n"+desc) - - def text_focus(self): - self.text.SetFocus() - - def onSelect(self, ev): - self.text.SelectAll() - - def enable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Enable() - -class viewNonTweet(widgetUtils.BaseDialog): - - def __init__(self, text, date="", *args, **kwargs): - super(viewNonTweet, self).__init__(None, size=(850,850)) - self.SetTitle(_(u"View")) - panel = wx.Panel(self) - label = wx.StaticText(panel, -1, _(u"Item")) - self.text = wx.TextCtrl(parent=panel, id=-1, value=text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) - dc = wx.WindowDC(self.text) - dc.SetFont(self.text.GetFont()) - (x, y) = dc.GetMultiLineTextExtent("0"*140) - self.text.SetSize((x, y)) - self.text.SetFocus() - textBox = wx.BoxSizer(wx.HORIZONTAL) - textBox.Add(label, 0, wx.ALL, 5) - textBox.Add(self.text, 1, wx.EXPAND, 5) - mainBox = wx.BoxSizer(wx.VERTICAL) - 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.share = wx.Button(panel, wx.ID_ANY, _("Copy link to clipboard")) - self.share.Enable(False) - 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.Disable() - self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) - cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) - cancelButton.SetDefault() - buttonsBox = wx.BoxSizer(wx.HORIZONTAL) - buttonsBox.Add(self.share, 0, wx.ALL, 5) - buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) - buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) - buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) - buttonsBox.Add(cancelButton, 0, wx.ALL, 5) - mainBox.Add(buttonsBox, 0, wx.ALL, 5) - selectId = wx.ID_ANY - self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) - self.accel_tbl = wx.AcceleratorTable([ - (wx.ACCEL_CTRL, ord('A'), selectId), - ]) - self.SetAcceleratorTable(self.accel_tbl) - panel.SetSizer(mainBox) - self.SetClientSize(mainBox.CalcMin()) - - def onSelect(self, ev): - self.text.SelectAll() - - def set_text(self, text): - self.text.ChangeValue(text) - - def get_text(self): - return self.text.GetValue() - - def text_focus(self): - self.text.SetFocus() - - def enable_button(self, buttonName): - if hasattr(self, buttonName): - return getattr(self, buttonName).Enable() From 6d505c6fe7fde6772f7bfcb32dc4b9c3bd30d435 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 16:11:09 -0600 Subject: [PATCH 13/83] Added new code for Tweet GUI and attachment of photos and gifts --- src/controller/messages.py | 253 +++++----- src/wxUI/dialogs/twitterDialogs/__init__.py | 1 + .../dialogs/twitterDialogs/tweetDialogs.py | 457 ++++++++++++++++++ 3 files changed, 601 insertions(+), 110 deletions(-) create mode 100644 src/wxUI/dialogs/twitterDialogs/__init__.py create mode 100644 src/wxUI/dialogs/twitterDialogs/tweetDialogs.py diff --git a/src/controller/messages.py b/src/controller/messages.py index a748464d..9417ad90 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -1,123 +1,67 @@ # -*- coding: utf-8 -*- -import re -import platform +import os import arrow import languageHandler -system = platform.system() +import wx import widgetUtils import output -import url_shortener import sound import config from pubsub import pub from twitter_text import parse_tweet -if system == "Windows": - from wxUI.dialogs import message, urlList - from wxUI import commonMessageDialogs - from extra import translator, SpellChecker, autocompletionUsers - from extra.AudioUploader import audioUploader -elif system == "Linux": - from gtkUI.dialogs import message +from wxUI.dialogs import twitterDialogs, urlList +#from wxUI.dialogs import twitterDialogs +from wxUI import commonMessageDialogs +from extra import translator, SpellChecker, autocompletionUsers +from extra.AudioUploader import audioUploader from sessions.twitter import utils -from . import attach class basicTweet(object): """ This class handles the tweet main features. Other classes should derive from this class.""" - def __init__(self, session, title, caption, text, messageType="tweet", max=280, *args, **kwargs): + def __init__(self, session, title, caption, text="", messageType="tweet", max=280, *args, **kwargs): super(basicTweet, self).__init__() self.max = max self.title = title self.session = session - self.message = getattr(message, messageType)(title, caption, text, *args, **kwargs) + self.message = getattr(twitterDialogs, messageType)(title=title, caption=caption, message=text, *args, **kwargs) widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) - widgetUtils.connect_event(self.message.attach, widgetUtils.BUTTON_PRESSED, self.attach) + widgetUtils.connect_event(self.message.add_audio, widgetUtils.BUTTON_PRESSED, self.attach) widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor) - widgetUtils.connect_event(self.message.shortenButton, widgetUtils.BUTTON_PRESSED, self.shorten) - widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten) - widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate) - if hasattr(self.message, "long_tweet"): - widgetUtils.connect_event(self.message.long_tweet, widgetUtils.CHECKBOX, self.text_processor) - if config.app["app-settings"]["remember_mention_and_longtweet"]: - self.message.long_tweet.SetValue(config.app["app-settings"]["longtweet"]) + widgetUtils.connect_event(self.message.translate, widgetUtils.BUTTON_PRESSED, self.translate) + if hasattr(self.message, "add"): + widgetUtils.connect_event(self.message.add, widgetUtils.BUTTON_PRESSED, self.on_attach) self.attachments = [] def translate(self, event=None): dlg = translator.gui.translateDialog() if dlg.get_response() == widgetUtils.OK: - text_to_translate = self.message.get_text() + text_to_translate = self.message.text.GetValue() language_dict = translator.translator.available_languages() for k in language_dict: if language_dict[k] == dlg.dest_lang.GetStringSelection(): dst = k msg = translator.translator.translate(text=text_to_translate, target=dst) - self.message.set_text(msg) + self.message.text.ChangeValue(msg) self.text_processor() - self.message.text_focus() + self.message.text.SetFocus() output.speak(_(u"Translated")) else: return - def shorten(self, event=None): - urls = utils.find_urls_in_text(self.message.get_text()) - if len(urls) == 0: - output.speak(_(u"There's no URL to be shortened")) - self.message.text_focus() - elif len(urls) == 1: - self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.shorten(urls[0]))) - output.speak(_(u"URL shortened")) - self.text_processor() - self.message.text_focus() - elif len(urls) > 1: - list_urls = urlList.urlList() - list_urls.populate_list(urls) - if list_urls.get_response() == widgetUtils.OK: - self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.shorten(list_urls.get_string()))) - output.speak(_(u"URL shortened")) - self.text_processor() - self.message.text_focus() - - def unshorten(self, event=None): - urls = utils.find_urls_in_text(self.message.get_text()) - if len(urls) == 0: - output.speak(_(u"There's no URL to be expanded")) - self.message.text_focus() - elif len(urls) == 1: - self.message.set_text(self.message.get_text().replace(urls[0], url_shortener.unshorten(urls[0]))) - output.speak(_(u"URL expanded")) - self.text_processor() - self.message.text_focus() - elif len(urls) > 1: - list_urls = urlList.urlList() - list_urls.populate_list(urls) - if list_urls.get_response() == widgetUtils.OK: - self.message.set_text(self.message.get_text().replace(urls[list_urls.get_item()], url_shortener.unshorten(list_urls.get_string()))) - output.speak(_(u"URL expanded")) - self.text_processor() - self.message.text_focus() - def text_processor(self, *args, **kwargs): - if len(self.message.get_text()) > 1: - self.message.enable_button("shortenButton") - self.message.enable_button("unshortenButton") - else: - self.message.disable_button("shortenButton") - self.message.disable_button("unshortenButton") - if self.message.get("long_tweet") == False and hasattr(self, "max"): - text = self.message.get_text() - results = parse_tweet(text) - self.message.set_title(_(u"%s - %s of %d characters") % (self.title, results.weightedLength, self.max)) - if results.weightedLength > self.max: - self.session.sound.play("max_length.ogg") - else: - self.message.set_title(_(u"%s - %s characters") % (self.title, len(self.message.get_text()))) + text = self.message.text.GetValue() + results = parse_tweet(text) + self.message.SetTitle(_("%s - %s of %d characters") % (self.title, results.weightedLength, self.max)) + if results.weightedLength > self.max: + self.session.sound.play("max_length.ogg") def spellcheck(self, event=None): - text = self.message.get_text() + text = self.message.text.GetValue() checker = SpellChecker.spellchecker.spellChecker(text, "") if hasattr(checker, "fixed_text"): - self.message.set_text(checker.fixed_text) + self.message.text.ChangeValue(checker.fixed_text) self.text_processor() - self.message.text_focus() + self.message.text.SetFocus() def attach(self, *args, **kwargs): def completed_callback(dlg): @@ -125,48 +69,145 @@ class basicTweet(object): pub.unsubscribe(dlg.uploaderDialog.update, "uploading") dlg.uploaderDialog.destroy() if "sndup.net/" in url: - self.message.set_text(self.message.get_text()+url+" #audio") + self.message.text.ChangeValue(self.message.text.GetValue()+url+" #audio") self.text_processor() else: commonMessageDialogs.common_error(url) - dlg.cleanup() dlg = audioUploader.audioUploader(self.session.settings, completed_callback) - self.message.text_focus() + self.message.text.SetFocus() + + def can_attach(self): + if len(self.attachments) == 0: + return True + elif len(self.attachments) == 1 and (self.attachments[0]["type"] == "video" or self.attachments[0]["type"] == "gif"): + return False + elif len(self.attachments) < 4: + return True + return False + + def on_attach(self, *args, **kwargs): + can_attach = self.can_attach() + menu = self.message.attach_menu(can_attach) + self.message.Bind(wx.EVT_MENU, self.on_attach_image, self.message.add_image) + self.message.Bind(wx.EVT_MENU, self.on_attach_video, self.message.add_video) + self.message.Bind(wx.EVT_MENU, self.on_attach_poll, self.message.add_poll) + self.message.PopupMenu(menu, self.message.add.GetPosition()) + + def on_attach_image(self, *args, **kwargs): + image, description = self.message.get_image() + if image != None: + if image.endswith("gif"): + image_type = "gif" + else: + image_type = "photo" + imageInfo = {"type": image_type, "file": image, "description": description} + if len(self.attachments) > 0 and image_type == "gif": + return self.message.unable_to_attach_file() + self.attachments.append(imageInfo) + self.message.add_item(item=[os.path.basename(imageInfo["file"]), imageInfo["type"], imageInfo["description"]]) + self.text_processor() + + def on_attach_video(self, *args, **kwargs): + video = self.message.get_video() + if video != None: + videoInfo = {"type": "video", "file": video, "description": ""} + if len(self.attachments) > 0: + return self.message.unable_to_attach_file() + self.attachments.append(videoInfo) + self.message.add_item(item=[os.path.basename(videoInfo["file"]), videoInfo["type"], videoInfo["description"]]) + self.text_processor() + + def on_attach_poll(self, *args, **kwargs): + pass class tweet(basicTweet): def __init__(self, session, title, caption, text, max=280, messageType="tweet", *args, **kwargs): + self.thread = [] super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs) self.image = None - widgetUtils.connect_event(self.message.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) - widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) + widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) + if hasattr(self.message, "add_tweet"): + widgetUtils.connect_event(self.message.add_tweet, widgetUtils.BUTTON_PRESSED, self.add_tweet) + widgetUtils.connect_event(self.message.remove_tweet, widgetUtils.BUTTON_PRESSED, self.remove_tweet) + widgetUtils.connect_event(self.message.remove_attachment, widgetUtils.BUTTON_PRESSED, self.remove_attachment) self.text_processor() - def upload_image(self, *args, **kwargs): - a = attach.attach() - if len(a.attachments) != 0: - self.attachments = a.attachments - def autocomplete_users(self, *args, **kwargs): c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id) c.show_menu() + def add_tweet(self, event, update_gui=True, *args, **kwargs): + text = self.message.text.GetValue() + attachments = self.attachments[::] + tweetdata = dict(text=text, attachments=attachments) + self.thread.append(tweetdata) + if update_gui: + self.message.reset_controls() + self.message.add_item(item=[text, len(attachments)], list_type="tweet") + self.message.text.SetFocus() + self.text_processor() + + def get_tweet_data(self): + self.add_tweet(event=None, update_gui=False) + return self.thread + + def text_processor(self, *args, **kwargs): + super(tweet, self).text_processor(*args, **kwargs) + if len(self.thread) > 0: + self.message.tweets.Enable(True) + self.message.remove_tweet.Enable(True) + else: + self.message.tweets.Enable(False) + self.message.remove_tweet.Enable(False) + if len(self.attachments) > 0: + self.message.attachments.Enable(True) + self.message.remove_attachment.Enable(True) + else: + self.message.attachments.Enable(False) + self.message.remove_attachment.Enable(False) + + def remove_tweet(self, *args, **kwargs): + tweet = self.message.tweets.GetFocusedItem() + if tweet > -1 and len(self.thread) > tweet: + self.thread.pop(tweet) + self.message.remove_item(list_type="tweet") + self.text_processor() + self.message.text.SetFocus() + + def remove_attachment(self, *args, **kwargs): + attachment = self.message.attachments.GetFocusedItem() + if attachment > -1 and len(self.attachments) > attachment: + self.attachments.pop(attachment) + self.message.remove_item(list_type="attachment") + self.text_processor() + self.message.text.SetFocus() + class reply(tweet): def __init__(self, session, title, caption, text, users=[], ids=[]): super(reply, self).__init__(session, title, caption, text, messageType="reply", users=users) self.ids = ids self.users = users if len(users) > 0: - widgetUtils.connect_event(self.message.mentionAll, widgetUtils.CHECKBOX, self.mention_all) - self.message.enable_button("mentionAll") + widgetUtils.connect_event(self.message.mention_all, widgetUtils.CHECKBOX, self.mention_all) + self.message.mention_all.Enable(True) if config.app["app-settings"]["remember_mention_and_longtweet"]: - self.message.mentionAll.SetValue(config.app["app-settings"]["mention_all"]) + self.message.mention_all.SetValue(config.app["app-settings"]["mention_all"]) self.mention_all() - self.message.set_cursor_at_end() + self.message.text.SetInsertionPoint(len(self.message.text.GetValue())) self.text_processor() + def text_processor(self, *args, **kwargs): + super(tweet, self).text_processor(*args, **kwargs) + if len(self.attachments) > 0: + self.message.attachments.Enable(True) + self.message.remove_attachment.Enable(True) + else: + self.message.attachments.Enable(False) + self.message.remove_attachment.Enable(False) + def mention_all(self, *args, **kwargs): - if self.message.mentionAll.GetValue() == True: + if self.message.mention_all.GetValue() == True: for i in self.message.checkboxes: i.SetValue(True) i.Hide() @@ -190,14 +231,14 @@ class reply(tweet): return people class dm(basicTweet): - def __init__(self, session, title, caption, text): - super(dm, self).__init__(session, title, caption, text, messageType="dm", max=10000) - widgetUtils.connect_event(self.message.autocompletionButton, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) + def __init__(self, session, title, caption, users): + super(dm, self).__init__(session, title, caption, messageType="dm", max=10000, users=users) + widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) self.text_processor() widgetUtils.connect_event(self.message.cb, widgetUtils.ENTERED_TEXT, self.user_changed) def user_changed(self, *args, **kwargs): - self.title = _("Direct message to %s") % (self.message.get_user()) + self.title = _("Direct message to %s") % (self.message.cb.GetValue()) self.text_processor() def autocomplete_users(self, *args, **kwargs): @@ -264,29 +305,21 @@ class viewTweet(basicTweet): for z in tweet.retweeted_status.extended_entities["media"]: if "ext_alt_text" in z and z["ext_alt_text"] != None: image_description.append(z["ext_alt_text"]) - self.message = message.viewTweet(text, rt_count, favs_count, source, date) + self.message = twitterDialogs.viewTweet(text, rt_count, favs_count, source, date) results = parse_tweet(text) self.message.set_title(results.weightedLength) [self.message.set_image_description(i) for i in image_description] else: self.title = _(u"View item") text = tweet - self.message = message.viewNonTweet(text, date) + self.message = twitterDialogs.viewNonTweet(text, date) widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) if item_url != "": self.message.enable_button("share") widgetUtils.connect_event(self.message.share, widgetUtils.BUTTON_PRESSED, self.share) self.item_url = item_url widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate) - if self.contain_urls() == True: - self.message.enable_button("unshortenButton") - widgetUtils.connect_event(self.message.unshortenButton, widgetUtils.BUTTON_PRESSED, self.unshorten) - self.message.get_response() - - def contain_urls(self): - if len(utils.find_urls_in_text(self.message.get_text())) > 0: - return True - return False + self.message.ShowModal() def clear_text(self, text): urls = utils.find_urls_in_text(text) diff --git a/src/wxUI/dialogs/twitterDialogs/__init__.py b/src/wxUI/dialogs/twitterDialogs/__init__.py new file mode 100644 index 00000000..c6b568e0 --- /dev/null +++ b/src/wxUI/dialogs/twitterDialogs/__init__.py @@ -0,0 +1 @@ +from .tweetDialogs import tweet, reply, dm, viewTweet, viewNonTweet \ No newline at end of file diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py new file mode 100644 index 00000000..d07f10da --- /dev/null +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -0,0 +1,457 @@ +""" GUI dialogs for tweet writing and displaying. """ +import wx +from typing import List + +class tweet(wx.Dialog): + def __init__(self, title: str, caption: str, message: str = "", max_length: int = 280, thread_mode: bool = True, *args, **kwds) -> None: + """ Creates the basic Tweet dialog. This might be considered the base class for other dialogs. + title str: title to be used in the dialog. + caption str: This is the text to be placed alongside the text field. + message str: Text to be inserted in the tweet. + max_length int: Maximum amount of characters the tweet will accept. By default is 280 chahracters. + thread_mode bool: If set to False, disables the button that allows to make threads by adding more tweets. + """ + super(tweet, self).__init__(parent=None, *args, **kwds) + self.SetTitle(title) + self.create_controls(max_length=max_length, caption=caption, message=message, thread_mode=thread_mode) + + def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: + panel = wx.Panel(self) + mainBox = wx.BoxSizer(wx.VERTICAL) + text_sizer = wx.BoxSizer(wx.VERTICAL) + mainBox.Add(text_sizer, 1, wx.EXPAND, 0) + label_1 = wx.StaticText(panel, wx.ID_ANY, caption) + text_sizer.Add(label_1, 0, 0, 0) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) + self.text.SetMinSize((1000, 158)) + self.text.SetMaxLength(max_length) + text_sizer.Add(self.text, 1, wx.EXPAND, 0) + list_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(list_sizer, 1, wx.EXPAND, 0) + Attachment_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(Attachment_sizer, 1, wx.EXPAND, 0) + label_2 = wx.StaticText(panel, wx.ID_ANY, _("Attachments")) + Attachment_sizer.Add(label_2, 0, 0, 0) + self.attachments = wx.ListCtrl(panel, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.LC_HRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES) + self.attachments.AppendColumn(_("File")) + self.attachments.AppendColumn(_("Type")) + self.attachments.AppendColumn(_("Description")) + Attachment_sizer.Add(self.attachments, 1, wx.EXPAND, 0) + self.remove_attachment = wx.Button(panel, wx.ID_ANY, _("Delete attachment")) + self.remove_attachment.Enable(False) + Attachment_sizer.Add(self.remove_attachment, 0, 0, 0) + tweet_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(tweet_sizer, 1, wx.EXPAND, 0) + label_3 = wx.StaticText(panel, wx.ID_ANY, _("Added Tweets")) + tweet_sizer.Add(label_3, 0, 0, 0) + self.tweets = wx.ListCtrl(panel, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.LC_HRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES) + self.tweets.AppendColumn(_("Text")) + self.tweets.AppendColumn(_("Attachments")) + self.tweets.Enable(False) + tweet_sizer.Add(self.tweets, 1, wx.EXPAND, 0) + self.remove_tweet = wx.Button(panel, wx.ID_ANY, _("Delete tweet")) + self.remove_tweet.Enable(False) + tweet_sizer.Add(self.remove_tweet, 0, 0, 0) + btn_sizer_1 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_1, 1, wx.EXPAND, 0) + self.add = wx.Button(panel, wx.ID_ANY, _("A&dd...")) + btn_sizer_1.Add(self.add, 0, 0, 0) + self.add_tweet = wx.Button(panel, wx.ID_ANY, _("Add tweet")) + self.add_tweet.Enable(thread_mode) + btn_sizer_1.Add(self.add_tweet, 0, 0, 0) + self.add_audio = wx.Button(panel, wx.ID_ANY, _("&Attach audio...")) + btn_sizer_1.Add(self.add_audio, 0, 0, 0) + btn_sizer_2 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_2, 1, wx.EXPAND, 0) + self.autocomplete_users = wx.Button(panel, wx.ID_ANY, _("Auto&complete users")) + btn_sizer_2.Add(self.autocomplete_users, 0, 0, 0) + self.spellcheck = wx.Button(panel, wx.ID_ANY, _("Check &spelling...")) + btn_sizer_2.Add(self.spellcheck, 0, 0, 0) + self.translate = wx.Button(panel, wx.ID_ANY, _("&Translate")) + btn_sizer_2.Add(self.translate, 0, 0, 0) + ok_cancel_sizer = wx.StdDialogButtonSizer() + mainBox.Add(ok_cancel_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.send = wx.Button(panel, wx.ID_OK, _("Sen&d")) + self.send.SetDefault() + ok_cancel_sizer.Add(self.send, 0, 0, 0) + self.cancel = wx.Button(panel, wx.ID_CANCEL, "") + ok_cancel_sizer.AddButton(self.cancel) + ok_cancel_sizer.Realize() + panel.SetSizer(mainBox) + self.Fit() + self.SetAffirmativeId(self.send.GetId()) + self.SetEscapeId(self.cancel.GetId()) + self.Layout() + + def handle_keys(self, event: wx.Event, *args, **kwargs) -> None: + """ Allows to react to certain keyboard events from the text control. """ + shift=event.ShiftDown() + if event.GetKeyCode() == wx.WXK_RETURN and shift==False and hasattr(self,'send'): + self.EndModal(wx.ID_OK) + else: + event.Skip() + + def reset_controls(self) -> None: + """ Resetss text control and attachments to their default, empty values. This is used while adding more tweets in a thread. """ + self.text.ChangeValue("") + self.attachments.DeleteAllItems() + + def add_item(self, list_type: str = "attachment", item: List[str] = []) -> None: + """ Adds an item to a list control. Item should be a list with the same amount of items for each column present in the ListCtrl. """ + if list_type == "attachment": + self.attachments.Append(item) + else: + self.tweets.Append(item) + + def remove_item(self, list_type: str = "attachment") -> None: + if list_type == "attachment": + item = self.attachments.GetFocusedItem() + if item > -1: + self.attachments.DeleteItem(item) + else: + item = self.tweets.GetFocusedItem() + if item > -1: + self.tweets.DeleteItem(item) + + def attach_menu(self, event=None, enabled=True, *args, **kwargs): + menu = wx.Menu() + self.add_image = menu.Append(wx.ID_ANY, _("Image")) + self.add_image.Enable(enabled) + self.add_video = menu.Append(wx.ID_ANY, _("Video")) + self.add_video.Enable(enabled) + self.add_poll = menu.Append(wx.ID_ANY, _("Poll")) + self.add_poll.Enable(enabled) + return menu + + def ask_description(self): + dlg = wx.TextEntryDialog(self, _(u"please provide a description"), _(u"Description")) + dlg.ShowModal() + result = dlg.GetValue() + dlg.Destroy() + return result + + def get_image(self): + openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return (None, None) + dsc = self.ask_description() + return (openFileDialog.GetPath(), dsc) + + def get_video(self): + openFileDialog = wx.FileDialog(self, _("Select the video to be uploaded"), "", "", _("Video files (*.mp4)|*.mp4"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return None + return openFileDialog.GetPath() + + def unable_to_attach_file(self, *args, **kwargs): + return wx.MessageDialog(self, _("You need to delete other attachments first, as Videos and GIF's cannot be added with other attachments."), _("Error adding attachment"), wx.ICON_ERROR).ShowModal() + +class reply(tweet): + + def __init__(self, users: List[str] = [], *args, **kwargs) -> None: + self.users = users + super(reply, self).__init__(*args, **kwargs) + + def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: + panel = wx.Panel(self) + mainBox = wx.BoxSizer(wx.VERTICAL) + text_sizer = wx.BoxSizer(wx.VERTICAL) + mainBox.Add(text_sizer, 1, wx.EXPAND, 0) + label_1 = wx.StaticText(panel, wx.ID_ANY, caption) + text_sizer.Add(label_1, 0, 0, 0) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) + self.text.SetMinSize((1000, 158)) + self.text.SetMaxLength(max_length) + text_sizer.Add(self.text, 1, wx.EXPAND, 0) + list_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(list_sizer, 1, wx.EXPAND, 0) + Attachment_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(Attachment_sizer, 1, wx.EXPAND, 0) + label_2 = wx.StaticText(panel, wx.ID_ANY, _("Attachments")) + Attachment_sizer.Add(label_2, 0, 0, 0) + self.attachments = wx.ListCtrl(panel, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.LC_HRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES) + self.attachments.AppendColumn(_("File")) + self.attachments.AppendColumn(_("Type")) + self.attachments.AppendColumn(_("Description")) + Attachment_sizer.Add(self.attachments, 1, wx.EXPAND, 0) + self.remove_attachment = wx.Button(panel, wx.ID_ANY, _("Delete attachment")) + self.remove_attachment.Enable(False) + Attachment_sizer.Add(self.remove_attachment, 0, 0, 0) + user_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(user_sizer, 0, 0, 0) + self.mention_all = wx.CheckBox(panel, -1, _(u"&Mention to all"), size=wx.DefaultSize) + self.mention_all.Disable() + user_sizer.Add(self.mention_all, 0, wx.ALL, 5) + self.checkboxes = [] + for i in self.users: + user_checkbox = wx.CheckBox(panel, -1, "@"+i, size=wx.DefaultSize) + self.checkboxes.append(user_checkbox) + user_sizer.Add(self.checkboxes[-1], 0, wx.ALL, 5) + btn_sizer_1 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_1, 1, wx.EXPAND, 0) + self.add = wx.Button(panel, wx.ID_ANY, _("A&dd...")) + btn_sizer_1.Add(self.add, 0, 0, 0) + self.add_audio = wx.Button(panel, wx.ID_ANY, _("&Attach audio...")) + btn_sizer_1.Add(self.add_audio, 0, 0, 0) + btn_sizer_2 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_2, 1, wx.EXPAND, 0) + self.autocomplete_users = wx.Button(panel, wx.ID_ANY, _("Auto&complete users")) + btn_sizer_2.Add(self.autocomplete_users, 0, 0, 0) + self.spellcheck = wx.Button(panel, wx.ID_ANY, _("Check &spelling...")) + btn_sizer_2.Add(self.spellcheck, 0, 0, 0) + self.translate = wx.Button(panel, wx.ID_ANY, _("&Translate")) + btn_sizer_2.Add(self.translate, 0, 0, 0) + ok_cancel_sizer = wx.StdDialogButtonSizer() + mainBox.Add(ok_cancel_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.send = wx.Button(panel, wx.ID_OK, _("Sen&d")) + self.send.SetDefault() + ok_cancel_sizer.Add(self.send, 0, 0, 0) + self.cancel = wx.Button(panel, wx.ID_CANCEL, "") + ok_cancel_sizer.AddButton(self.cancel) + ok_cancel_sizer.Realize() + panel.SetSizer(mainBox) + self.Fit() + self.SetAffirmativeId(self.send.GetId()) + self.SetEscapeId(self.cancel.GetId()) + self.Layout() + +class dm(tweet): + + def __init__(self, users: List[str] = [], *args, **kwargs) -> None: + self.users = users + super(dm, self).__init__(*args, **kwargs) + + def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: + panel = wx.Panel(self) + mainBox = wx.BoxSizer(wx.VERTICAL) + label_recipient = wx.StaticText(panel, -1, _(u"&Recipient")) + self.cb = wx.ComboBox(panel, -1, choices=self.users, value=self.users[0], size=wx.DefaultSize) + self.autocomplete_users = wx.Button(panel, -1, _(u"Auto&complete users")) + recipient_sizer = wx.BoxSizer(wx.HORIZONTAL) + recipient_sizer.Add(label_recipient, 0, 0, 0) + recipient_sizer.Add(self.cb, 1, wx.EXPAND, 0) + mainBox.Add(recipient_sizer, 0, wx.EXPAND, 0) + text_sizer = wx.BoxSizer(wx.VERTICAL) + mainBox.Add(text_sizer, 1, wx.EXPAND, 0) + label_1 = wx.StaticText(panel, wx.ID_ANY, caption) + text_sizer.Add(label_1, 0, 0, 0) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) + self.text.SetMinSize((1000, 158)) + self.text.SetMaxLength(max_length) + self.text.SetFocus() + text_sizer.Add(self.text, 1, wx.EXPAND, 0) + list_sizer = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(list_sizer, 1, wx.EXPAND, 0) + Attachment_sizer = wx.BoxSizer(wx.VERTICAL) + list_sizer.Add(Attachment_sizer, 1, wx.EXPAND, 0) + label_2 = wx.StaticText(panel, wx.ID_ANY, _("Attachments")) + Attachment_sizer.Add(label_2, 0, 0, 0) + self.attachments = wx.ListCtrl(panel, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.LC_HRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_VRULES) + self.attachments.AppendColumn(_("File")) + self.attachments.AppendColumn(_("Type")) + self.attachments.AppendColumn(_("Description")) + Attachment_sizer.Add(self.attachments, 1, wx.EXPAND, 0) + self.remove_attachment = wx.Button(panel, wx.ID_ANY, _("Delete attachment")) + self.remove_attachment.Enable(False) + Attachment_sizer.Add(self.remove_attachment, 0, 0, 0) + btn_sizer_1 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_1, 1, wx.EXPAND, 0) + self.add = wx.Button(panel, wx.ID_ANY, _("A&dd...")) + btn_sizer_1.Add(self.add, 0, 0, 0) + self.add_audio = wx.Button(panel, wx.ID_ANY, _("&Attach audio...")) + btn_sizer_1.Add(self.add_audio, 0, 0, 0) + btn_sizer_2 = wx.BoxSizer(wx.HORIZONTAL) + mainBox.Add(btn_sizer_2, 1, wx.EXPAND, 0) + self.spellcheck = wx.Button(panel, wx.ID_ANY, _("Check &spelling...")) + btn_sizer_2.Add(self.spellcheck, 0, 0, 0) + self.translate = wx.Button(panel, wx.ID_ANY, _("&Translate")) + btn_sizer_2.Add(self.translate, 0, 0, 0) + ok_cancel_sizer = wx.StdDialogButtonSizer() + mainBox.Add(ok_cancel_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.send = wx.Button(panel, wx.ID_OK, _("Sen&d")) + self.send.SetDefault() + ok_cancel_sizer.Add(self.send, 0, 0, 0) + self.cancel = wx.Button(panel, wx.ID_CANCEL, "") + ok_cancel_sizer.AddButton(self.cancel) + ok_cancel_sizer.Realize() + panel.SetSizer(mainBox) + self.Fit() + self.SetAffirmativeId(self.send.GetId()) + self.SetEscapeId(self.cancel.GetId()) + self.Layout() + +class viewTweet(wx.Dialog): + def set_title(self, lenght): + self.SetTitle(_(u"Tweet - %i characters ") % (lenght,)) + + def __init__(self, text, rt_count, favs_count, source, date="", *args, **kwargs): + super(viewTweet, self).__init__(None, size=(850,850)) + panel = wx.Panel(self) + label = wx.StaticText(panel, -1, _(u"Tweet")) + self.text = wx.TextCtrl(panel, -1, text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.text) + dc.SetFont(self.text.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("W"*280) + self.text.SetSize((x, y)) + self.text.SetFocus() + textBox = wx.BoxSizer(wx.HORIZONTAL) + textBox.Add(label, 0, wx.ALL, 5) + textBox.Add(self.text, 1, wx.EXPAND, 5) + mainBox = wx.BoxSizer(wx.VERTICAL) + mainBox.Add(textBox, 0, wx.ALL, 5) + label2 = wx.StaticText(panel, -1, _(u"Image description")) + self.image_description = wx.TextCtrl(panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.image_description) + dc.SetFont(self.image_description.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("0"*450) + self.image_description.SetSize((x, y)) + self.image_description.Enable(False) + iBox = wx.BoxSizer(wx.HORIZONTAL) + iBox.Add(label2, 0, wx.ALL, 5) + iBox.Add(self.image_description, 1, wx.EXPAND, 5) + mainBox.Add(iBox, 0, wx.ALL, 5) + rtCountLabel = wx.StaticText(panel, -1, _(u"Retweets: ")) + rtCount = wx.TextCtrl(panel, -1, rt_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + rtBox = wx.BoxSizer(wx.HORIZONTAL) + rtBox.Add(rtCountLabel, 0, wx.ALL, 5) + rtBox.Add(rtCount, 0, wx.ALL, 5) + favsCountLabel = wx.StaticText(panel, -1, _(u"Likes: ")) + favsCount = wx.TextCtrl(panel, -1, favs_count, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + favsBox = wx.BoxSizer(wx.HORIZONTAL) + favsBox.Add(favsCountLabel, 0, wx.ALL, 5) + favsBox.Add(favsCount, 0, wx.ALL, 5) + sourceLabel = wx.StaticText(panel, -1, _(u"Source: ")) + sourceTweet = wx.TextCtrl(panel, -1, source, size=wx.DefaultSize, style=wx.TE_READONLY|wx.TE_MULTILINE) + sourceBox = wx.BoxSizer(wx.HORIZONTAL) + sourceBox.Add(sourceLabel, 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.Add(rtBox, 0, wx.ALL, 5) + infoBox.Add(favsBox, 0, wx.ALL, 5) + infoBox.Add(sourceBox, 0, wx.ALL, 5) + mainBox.Add(infoBox, 0, wx.ALL, 5) + mainBox.Add(dateBox, 0, wx.ALL, 5) + self.share = wx.Button(panel, wx.ID_ANY, _("Copy link to clipboard")) + self.share.Enable(False) + self.spellcheck = wx.Button(panel, -1, _("Check &spelling..."), size=wx.DefaultSize) + self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) + cancelButton.SetDefault() + buttonsBox = wx.BoxSizer(wx.HORIZONTAL) + buttonsBox.Add(self.share, 0, wx.ALL, 5) + buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) + buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) + buttonsBox.Add(cancelButton, 0, wx.ALL, 5) + mainBox.Add(buttonsBox, 0, wx.ALL, 5) + selectId = wx.ID_ANY + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ + (wx.ACCEL_CTRL, ord('A'), selectId), + ]) + self.SetAcceleratorTable(self.accel_tbl) + panel.SetSizer(mainBox) + self.SetClientSize(mainBox.CalcMin()) + + def set_text(self, text): + self.text.ChangeValue(text) + + def get_text(self): + return self.text.GetValue() + + def set_image_description(self, desc): + self.image_description.Enable(True) + if len(self.image_description.GetValue()) == 0: + self.image_description.SetValue(desc) + else: + self.image_description.SetValue(self.image_description.GetValue()+"\n"+desc) + + def text_focus(self): + self.text.SetFocus() + + def onSelect(self, ev): + self.text.SelectAll() + + def enable_button(self, buttonName): + if hasattr(self, buttonName): + return getattr(self, buttonName).Enable() + +class viewNonTweet(wx.Dialog): + + def __init__(self, text, date="", *args, **kwargs): + super(viewNonTweet, self).__init__(None, size=(850,850)) + self.SetTitle(_(u"View")) + panel = wx.Panel(self) + label = wx.StaticText(panel, -1, _(u"Item")) + self.text = wx.TextCtrl(parent=panel, id=-1, value=text, style=wx.TE_READONLY|wx.TE_MULTILINE, size=(250, 180)) + dc = wx.WindowDC(self.text) + dc.SetFont(self.text.GetFont()) + (x, y) = dc.GetMultiLineTextExtent("0"*140) + self.text.SetSize((x, y)) + self.text.SetFocus() + textBox = wx.BoxSizer(wx.HORIZONTAL) + textBox.Add(label, 0, wx.ALL, 5) + textBox.Add(self.text, 1, wx.EXPAND, 5) + mainBox = wx.BoxSizer(wx.VERTICAL) + 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.share = wx.Button(panel, wx.ID_ANY, _("Copy link to clipboard")) + self.share.Enable(False) + 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.Disable() + self.translateButton = wx.Button(panel, -1, _(u"&Translate..."), size=wx.DefaultSize) + cancelButton = wx.Button(panel, wx.ID_CANCEL, _(u"C&lose"), size=wx.DefaultSize) + cancelButton.SetDefault() + buttonsBox = wx.BoxSizer(wx.HORIZONTAL) + buttonsBox.Add(self.share, 0, wx.ALL, 5) + buttonsBox.Add(self.spellcheck, 0, wx.ALL, 5) + buttonsBox.Add(self.unshortenButton, 0, wx.ALL, 5) + buttonsBox.Add(self.translateButton, 0, wx.ALL, 5) + buttonsBox.Add(cancelButton, 0, wx.ALL, 5) + mainBox.Add(buttonsBox, 0, wx.ALL, 5) + selectId = wx.ID_ANY + self.Bind(wx.EVT_MENU, self.onSelect, id=selectId) + self.accel_tbl = wx.AcceleratorTable([ + (wx.ACCEL_CTRL, ord('A'), selectId), + ]) + self.SetAcceleratorTable(self.accel_tbl) + panel.SetSizer(mainBox) + self.SetClientSize(mainBox.CalcMin()) + + def onSelect(self, ev): + self.text.SelectAll() + + def set_text(self, text): + self.text.ChangeValue(text) + + def get_text(self): + return self.text.GetValue() + + def text_focus(self): + self.text.SetFocus() + + def enable_button(self, buttonName): + if hasattr(self, buttonName): + return getattr(self, buttonName).Enable() From f0456af65670127dc7b6e1f971a6633a4cd587ee Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 16:12:47 -0600 Subject: [PATCH 14/83] Fixed an issue when uploading Videos to Twitter --- src/sessions/twitter/session.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index a32ead2d..df3ab809 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -204,7 +204,7 @@ class Session(base.baseSession): except TweepyException as e: output.speak(str(e)) val = None - if type(e) != NotFound and type(e) != Forvidden: + if type(e) != NotFound and type(e) != Forbidden: tries = tries+1 time.sleep(5) elif report_failure: @@ -603,7 +603,8 @@ class Session(base.baseSession): media_ids = [] for i in obj["attachments"]: img = self.api_call("media_upload", filename=i["file"]) - self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) + if i["type"] == "photo": + self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) item = self.api_call(call_name="update_status", status=obj["text"], _sound="tweet_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids) in_reply_to_status_id = item.id @@ -615,6 +616,7 @@ class Session(base.baseSession): media_ids = [] for i in attachments: img = self.api_call("media_upload", filename=i["file"]) - self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) + if i["type"] == "photo": + self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) item = self.api_call(call_name="update_status", status=text, _sound="reply_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids, *args, **kwargs) From 2b6efef831d8fbe9ffe6a0456450785a2cc5a28a Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 16:13:59 -0600 Subject: [PATCH 15/83] Update code on autocompletion users module to use WX methods from controls in the new Tweet GUI'S --- src/extra/autocompletionUsers/completion.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/extra/autocompletionUsers/completion.py b/src/extra/autocompletionUsers/completion.py index 826dc699..9fa8c8ec 100644 --- a/src/extra/autocompletionUsers/completion.py +++ b/src/extra/autocompletionUsers/completion.py @@ -10,9 +10,9 @@ class autocompletionUsers(object): self.db = storage.storage(session_id) def show_menu(self, mode="tweet"): - position = self.window.get_position() + position = self.window.text.GetInsertionPoint() if mode == "tweet": - text = self.window.get_text() + text = self.window.text.GetValue() text = text[:position] try: pattern = text.split()[-1] @@ -24,14 +24,14 @@ class autocompletionUsers(object): users = self.db.get_users(pattern[1:]) if len(users) > 0: menu.append_options(users) - self.window.popup_menu(menu) + self.window.PopupMenu(menu, self.window.text.GetPosition()) menu.destroy() else: output.speak(_(u"There are no results in your users database")) else: output.speak(_(u"Autocompletion only works for users.")) elif mode == "dm": - text = self.window.get_user() + text = self.window.cb.GetValue() try: pattern = text.split()[-1] except IndexError: @@ -41,7 +41,7 @@ class autocompletionUsers(object): users = self.db.get_users(pattern) if len(users) > 0: menu.append_options(users) - self.window.popup_menu(menu) + self.window.PopupMenu(menu, self.window.text.GetPosition()) menu.destroy() else: output.speak(_(u"There are no results in your users database")) From cfc25eb89a3259eab292a412fa42afdec1d7b4b1 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 16:14:45 -0600 Subject: [PATCH 16/83] Implemented tweet, reply and direct message in base buffer --- src/controller/buffers/twitter/base.py | 83 +++++--------------------- 1 file changed, 16 insertions(+), 67 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 8da54709..619b7f8f 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -85,41 +85,15 @@ class BaseBuffer(base.Buffer): def post_status(self, *args, **kwargs): item = None - title = _(u"Tweet") - caption = _(u"Write the tweet here") + title = _("Tweet") + caption = _("Write the tweet here") tweet = messages.tweet(self.session, title, caption, "") - if tweet.message.get_response() == widgetUtils.OK: - if config.app["app-settings"]["remember_mention_and_longtweet"]: - config.app["app-settings"]["longtweet"] = tweet.message.long_tweet.GetValue() - config.app.write() - text = tweet.message.get_text() - if len(text) > 280 and tweet.message.get("long_tweet") == True: - if not hasattr(tweet, "attachments"): - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text) - else: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text, 1) - if not hasattr(tweet, "attachments") or len(tweet.attachments) == 0: - item = self.session.api_call(call_name="update_status", status=text, _sound="tweet_send.ogg", tweet_mode="extended") - else: - call_threaded(self.post_with_media, text=text, attachments=tweet.attachments) - # We will no longer will reuse the sent item from here as Streaming API should give us the new and correct item. - # but in case we'd need it, just uncomment the following couple of lines and make sure we reduce the item correctly. -# if item != None: -# pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - if hasattr(tweet.message, "destroy"): tweet.message.destroy() - self.session.settings.write() - - def post_with_media(self, text, attachments): - media_ids = [] - for i in attachments: - img = self.session.twitter.media_upload(i["file"]) - self.session.twitter.create_media_metadata(media_id=img.media_id, alt_text=i["description"]) - media_ids.append(img.media_id) - item = self.session.twitter.update_status(status=text, media_ids=media_ids) - # We will no longer will reuse the sent item from here as Streaming API should give us the new and correct item. - # but in case we'd need it, just uncomment the following couple of lines and make sure we reduce the item correctly. -# if item != None: -# pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) + response = tweet.message.ShowModal() + if response == wx.ID_OK: + tweet_data = tweet.get_tweet_data() + call_threaded(self.session.send_tweet, *tweet_data) + if hasattr(tweet.message, "destroy"): + tweet.message.destroy() def get_formatted_message(self): if self.type == "dm" or self.name == "direct_messages": @@ -422,7 +396,6 @@ class BaseBuffer(base.Buffer): user = self.session.get_user(tweet.user) screen_name = user.screen_name id = tweet.id - twishort_enabled = hasattr(tweet, "twishort") users = utils.get_all_mentioned(tweet, self.session.db, field="screen_name") ids = utils.get_all_mentioned(tweet, self.session.db, field="id") # Build the window title @@ -430,38 +403,14 @@ class BaseBuffer(base.Buffer): title=_("Reply to {arg0}").format(arg0=screen_name) else: title=_("Reply") - message = messages.reply(self.session, title, _(u"Reply to %s") % (screen_name,), "", users=users, ids=ids) - if message.message.get_response() == widgetUtils.OK: + message = messages.reply(self.session, title, _("Reply to %s") % (screen_name,), "", users=users, ids=ids) + if message.message.ShowModal() == widgetUtils.OK: if config.app["app-settings"]["remember_mention_and_longtweet"]: - config.app["app-settings"]["longtweet"] = message.message.long_tweet.GetValue() if len(users) > 0: - config.app["app-settings"]["mention_all"] = message.message.mentionAll.GetValue() + config.app["app-settings"]["mention_all"] = message.message.mention_all.GetValue() config.app.write() - params = {"_sound": "reply_send.ogg", "in_reply_to_status_id": id, "tweet_mode": "extended"} - text = message.message.get_text() - if twishort_enabled == False: - excluded_ids = message.get_ids() - params["exclude_reply_user_ids"] =excluded_ids - params["auto_populate_reply_metadata"] =True - else: - mentioned_people = message.get_people() - text = "@"+screen_name+" "+mentioned_people+u" "+text - if len(text) > 280 and message.message.get("long_tweet") == True: - if message.image == None: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text) - else: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text, 1) - params["status"] = text - if message.image == None: - params["call_name"] = "update_status" - else: - params["call_name"] = "update_status_with_media" - params["media"] = message.file - item = self.session.api_call(**params) - # We will no longer will reuse the sent item from here as Streaming API should give us the new and correct item. - # but in case we'd need it, just uncomment the following couple of lines and make sure we reduce the item correctly. -# if item != None: -# pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) + tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments) + call_threaded(self.session.reply, in_reply_to_status_id=id, text=message.message.text.GetValue(), attachments=message.attachments, exclude_reply_user_ids=message.get_ids(), auto_populate_reply_metadata=True) if hasattr(message.message, "destroy"): message.message.destroy() self.session.settings.write() @@ -478,11 +427,11 @@ class BaseBuffer(base.Buffer): screen_name = self.session.get_user(tweet.user).screen_name users = utils.get_all_users(tweet, self.session) dm = messages.dm(self.session, _(u"Direct message to %s") % (screen_name,), _(u"New direct message"), users) - if dm.message.get_response() == widgetUtils.OK: - screen_name = dm.message.get("cb") + if dm.message.ShowModal() == widgetUtils.OK: + screen_name = dm.message.cb.GetValue() user = self.session.get_user_by_screen_name(screen_name) recipient_id = user - text = dm.message.get_text() + text = dm.message.text.GetValue() val = self.session.api_call(call_name="send_direct_message", recipient_id=recipient_id, text=text) if val != None: sent_dms = self.session.db["sent_direct_messages"] From 269db95fe3fedc62a4b5ddeaafcf324557204a27 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 16:44:03 -0600 Subject: [PATCH 17/83] Implemented code to quote Tweets by using the new GUI --- src/controller/buffers/twitter/base.py | 37 +++++++------------------- src/controller/messages.py | 3 +-- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 619b7f8f..1113e46d 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -458,40 +458,21 @@ class BaseBuffer(base.Buffer): else: self._retweet_with_comment(tweet, id) - def _retweet_with_comment(self, tweet, id, comment=''): - # If quoting a retweet, let's quote the original tweet instead the retweet. + def _retweet_with_comment(self, tweet, id): if hasattr(tweet, "retweeted_status"): tweet = tweet.retweeted_status - if hasattr(tweet, "full_text"): - comments = tweet.full_text - else: - comments = tweet.text - retweet = messages.tweet(self.session, _(u"Quote"), _(u"Add your comment to the tweet"), u"“@%s: %s ”" % (self.session.get_user(tweet.user).screen_name, comments), max=256, messageType="retweet") - if comment != '': - retweet.message.set_text(comment) - if retweet.message.get_response() == widgetUtils.OK: - text = retweet.message.get_text() + retweet = messages.tweet(session=self.session, title=_("Quote"), caption=_("Add your comment to the tweet"), max=256, thread_mode=False) + retweet = messages.tweet(session=self.session, title=_("Quote"), caption=_("Add your comment to the tweet"), max=256, thread_mode=False) + if retweet.message.ShowModal() == widgetUtils.OK: + text = retweet.message.text.GetValue() text = text+" https://twitter.com/{0}/status/{1}".format(self.session.get_user(tweet.user).screen_name, id) - if retweet.image == None: - # We will no longer will reuse the sent item from here as Streaming API should give us the new and correct item. - # but in case we'd need it, just uncomment the following couple of lines and make sure we reduce the item correctly. - 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: -# new_item = self.session.twitter.get_status(id=item.id, include_ext_alt_text=True, tweet_mode="extended") -# pub.sendMessage("sent-tweet", data=new_item, user=self.session.db["user_name"]) - else: - 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() + tweet_data = dict(text=text, attachments=retweet.attachments) + call_threaded(self.session.send_tweet, *[tweet_data]) + if hasattr(retweet.message, "destroy"): + retweet.message.destroy() def _direct_retweet(self, id): item = self.session.api_call(call_name="retweet", _sound="retweet_send.ogg", id=id) - # We will no longer will reuse the sent item from here as Streaming API should give us the new and correct item. - # but in case we'd need it, just uncomment the following couple of lines and make sure we reduce the item correctly. -# if item != None: - # Retweets are returned as non-extended tweets, so let's get the object as extended - # just before sending the event message. See https://github.com/manuelcortez/TWBlue/issues/253 -# item = self.session.twitter.get_status(id=item.id, include_ext_alt_text=True, tweet_mode="extended") -# pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) def onFocus(self, *args, **kwargs): tweet = self.get_tweet() diff --git a/src/controller/messages.py b/src/controller/messages.py index 9417ad90..776ceb11 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -122,10 +122,9 @@ class basicTweet(object): pass class tweet(basicTweet): - def __init__(self, session, title, caption, text, max=280, messageType="tweet", *args, **kwargs): + def __init__(self, session, title, caption, text="", max=280, messageType="tweet", *args, **kwargs): self.thread = [] super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs) - self.image = None widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) if hasattr(self.message, "add_tweet"): widgetUtils.connect_event(self.message.add_tweet, widgetUtils.BUTTON_PRESSED, self.add_tweet) From 80adf381c9bf718359e06739ce5674292f99c8e4 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 17:19:12 -0600 Subject: [PATCH 18/83] Implemented new GUI in people and direct message buffers --- .../buffers/twitter/directMessages.py | 18 ++++++------------ src/controller/buffers/twitter/people.py | 18 ++++++------------ src/controller/messages.py | 3 +++ 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/controller/buffers/twitter/directMessages.py b/src/controller/buffers/twitter/directMessages.py index b0c51e5b..60090c89 100644 --- a/src/controller/buffers/twitter/directMessages.py +++ b/src/controller/buffers/twitter/directMessages.py @@ -90,18 +90,12 @@ class DirectMessagesBuffer(base.BaseBuffer): def reply(self, *args, **kwargs): tweet = self.get_right_tweet() screen_name = self.session.get_user(tweet.message_create["sender_id"]).screen_name - message = messages.reply(self.session, _(u"Mention"), _(u"Mention to %s") % (screen_name,), "@%s " % (screen_name,), [screen_name,]) - if message.message.get_response() == widgetUtils.OK: - if config.app["app-settings"]["remember_mention_and_longtweet"]: - config.app["app-settings"]["longtweet"] = message.message.long_tweet.GetValue() - config.app.write() - if message.image == None: - item = self.session.api_call(call_name="update_status", _sound="reply_send.ogg", status=message.message.get_text(), tweet_mode="extended") - if item != None: - pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - else: - 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() + message = messages.reply(session=self.session, title=_("Mention"), caption=_("Mention to %s") % (screen_name,), text="@%s " % (screen_name,), thread_mode=False, users=[screen_name,]) + if message.message.ShowModal() == widgetUtils.OK: + tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments) + call_threaded(self.session.send_tweet, *[tweet_data]) + if hasattr(message.message, "destroy"): + message.message.destroy() def onFocus(self, *args, **kwargs): tweet = self.get_tweet() diff --git a/src/controller/buffers/twitter/people.py b/src/controller/buffers/twitter/people.py index 7f5c90b1..faf03794 100644 --- a/src/controller/buffers/twitter/people.py +++ b/src/controller/buffers/twitter/people.py @@ -92,18 +92,12 @@ class PeopleBuffer(base.BaseBuffer): def reply(self, *args, **kwargs): tweet = self.get_right_tweet() screen_name = tweet.screen_name - message = messages.reply(self.session, _(u"Mention"), _(u"Mention to %s") % (screen_name,), "@%s " % (screen_name,), [screen_name,]) - if message.message.get_response() == widgetUtils.OK: - if config.app["app-settings"]["remember_mention_and_longtweet"]: - config.app["app-settings"]["longtweet"] = message.message.long_tweet.GetValue() - config.app.write() - if message.image == None: - item = self.session.api_call(call_name="update_status", _sound="reply_send.ogg", status=message.message.get_text(), tweet_mode="extended") - if item != None: - pub.sendMessage("sent-tweet", data=item, user=self.session.db["user_name"]) - else: - 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() + message = messages.tweet(session=self.session, title=_("Mention"), caption=_("Mention to %s") % (screen_name,), text="@%s " % (screen_name,), thread_mode=False) + if message.message.ShowModal() == widgetUtils.OK: + tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments) + call_threaded(self.session.send_tweet, *[tweet_data]) + if hasattr(message.message, "destroy"): + message.message.destroy() def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): # starts stream every 3 minutes. diff --git a/src/controller/messages.py b/src/controller/messages.py index 776ceb11..89ffe176 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -24,6 +24,8 @@ class basicTweet(object): self.title = title self.session = session self.message = getattr(twitterDialogs, messageType)(title=title, caption=caption, message=text, *args, **kwargs) + self.message.text.SetValue(text) + self.message.text.SetInsertionPoint(len(self.message.text.GetValue())) widgetUtils.connect_event(self.message.spellcheck, widgetUtils.BUTTON_PRESSED, self.spellcheck) widgetUtils.connect_event(self.message.add_audio, widgetUtils.BUTTON_PRESSED, self.attach) widgetUtils.connect_event(self.message.text, widgetUtils.ENTERED_TEXT, self.text_processor) @@ -42,6 +44,7 @@ class basicTweet(object): dst = k msg = translator.translator.translate(text=text_to_translate, target=dst) self.message.text.ChangeValue(msg) + self.message.text.SetInsertionPoint(len(self.message.text.GetValue())) self.text_processor() self.message.text.SetFocus() output.speak(_(u"Translated")) From a2393fe3e9eed5b36fa4d181dc33a6bc738f6358 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 8 Nov 2021 17:20:16 -0600 Subject: [PATCH 19/83] Updated dialogs package --- src/wxUI/dialogs/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/wxUI/dialogs/__init__.py b/src/wxUI/dialogs/__init__.py index a21239a7..e69de29b 100644 --- a/src/wxUI/dialogs/__init__.py +++ b/src/wxUI/dialogs/__init__.py @@ -1,3 +0,0 @@ -from __future__ import absolute_import -from __future__ import unicode_literals -from . import baseDialog, trends, configuration, lists, message, search, find, show_user, update_profile, urlList, userSelection, utils, filterDialogs, userAliasDialogs From 15d0f4c65efb708e736f22eee5ef38ebd03a48f5 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 9 Nov 2021 13:34:49 -0600 Subject: [PATCH 20/83] Restored some imports on dialogs --- src/wxUI/dialogs/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wxUI/dialogs/__init__.py b/src/wxUI/dialogs/__init__.py index e69de29b..d00a14c0 100644 --- a/src/wxUI/dialogs/__init__.py +++ b/src/wxUI/dialogs/__init__.py @@ -0,0 +1 @@ +from . import baseDialog, trends, configuration, lists, search, find, show_user, update_profile, urlList, userSelection, utils, filterDialogs, userAliasDialogs From 8fed52118fa829292f5e974ba1fa8dc6a4c5718e Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 9 Nov 2021 13:46:36 -0600 Subject: [PATCH 21/83] Finished implementation of new tweet and reply calls in buffers --- src/controller/buffers/twitter/base.py | 1 - src/controller/buffers/twitter/trends.py | 14 +++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 1113e46d..72ea6449 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -84,7 +84,6 @@ class BaseBuffer(base.Buffer): return _(u"Unknown buffer") def post_status(self, *args, **kwargs): - item = None title = _("Tweet") caption = _("Write the tweet here") tweet = messages.tweet(self.session, title, caption, "") diff --git a/src/controller/buffers/twitter/trends.py b/src/controller/buffers/twitter/trends.py index e3be681d..ab623e05 100644 --- a/src/controller/buffers/twitter/trends.py +++ b/src/controller/buffers/twitter/trends.py @@ -4,7 +4,7 @@ import platform if platform.system() == "Windows": import wx from wxUI import buffers, commonMessageDialogs, menus - from controller import user + from controller import user, messages elif platform.system() == "Linux": from gi.repository import Gtk from gtkUI import buffers, commonMessageDialogs @@ -38,6 +38,18 @@ class TrendsBuffer(base.Buffer): self.get_formatted_message = self.get_message self.reply = self.search_topic + + def post_status(self, *args, **kwargs): + title = _("Tweet") + caption = _("Write the tweet here") + tweet = messages.tweet(self.session, title, caption, "") + response = tweet.message.ShowModal() + if response == wx.ID_OK: + tweet_data = tweet.get_tweet_data() + call_threaded(self.session.send_tweet, *tweet_data) + if hasattr(tweet.message, "destroy"): + tweet.message.destroy() + def start_stream(self, mandatory=False, play_sound=True, avoid_autoreading=False): # starts stream every 3 minutes. current_time = time.time() From 605868eff9cf7bf0b563f8923c04087c980ca52a Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 09:47:53 -0600 Subject: [PATCH 22/83] Added functions to make TWBlue respect Twitter limits when adding media items --- src/controller/messages.py | 13 +++++++++++-- src/wxUI/dialogs/twitterDialogs/tweetDialogs.py | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/controller/messages.py b/src/controller/messages.py index 89ffe176..f613c436 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -10,7 +10,6 @@ import config from pubsub import pub from twitter_text import parse_tweet from wxUI.dialogs import twitterDialogs, urlList -#from wxUI.dialogs import twitterDialogs from wxUI import commonMessageDialogs from extra import translator, SpellChecker, autocompletionUsers from extra.AudioUploader import audioUploader @@ -87,7 +86,7 @@ class basicTweet(object): return False elif len(self.attachments) < 4: return True - return False + return False def on_attach(self, *args, **kwargs): can_attach = self.can_attach() @@ -98,6 +97,14 @@ class basicTweet(object): self.message.PopupMenu(menu, self.message.add.GetPosition()) def on_attach_image(self, *args, **kwargs): + can_attach = self.can_attach() + video_or_gif_present = False + for a in self.attachments: + if a["type"] == "video" or a["type"] == "gif": + video_or_gif = True + break + if can_attach == False or video_or_gif_present == True: + return self.message.unable_to_attach_file() image, description = self.message.get_image() if image != None: if image.endswith("gif"): @@ -112,6 +119,8 @@ class basicTweet(object): self.text_processor() def on_attach_video(self, *args, **kwargs): + if len(self.attachments) > 0: + return self.message.unable_to_attach_file() video = self.message.get_video() if video != None: videoInfo = {"type": "video", "file": video, "description": ""} diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py index d07f10da..a7a20059 100644 --- a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -145,7 +145,7 @@ class tweet(wx.Dialog): return openFileDialog.GetPath() def unable_to_attach_file(self, *args, **kwargs): - return wx.MessageDialog(self, _("You need to delete other attachments first, as Videos and GIF's cannot be added with other attachments."), _("Error adding attachment"), wx.ICON_ERROR).ShowModal() + return wx.MessageDialog(self, _("It is not possible to add more attachments. Please make sure your tweet complies with Twitter'S attachment rules. You can add only one video or GIF in every tweet, and a maximum of 4 photos."), _("Error adding attachment"), wx.ICON_ERROR).ShowModal() class reply(tweet): From dbecf341ece9f0445634a8f66de660cca2b59b56 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 11:24:50 -0600 Subject: [PATCH 23/83] Stop using text_processor in tweet displayer --- src/controller/messages.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/controller/messages.py b/src/controller/messages.py index f613c436..2777d2cc 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -332,6 +332,10 @@ class viewTweet(basicTweet): widgetUtils.connect_event(self.message.translateButton, widgetUtils.BUTTON_PRESSED, self.translate) self.message.ShowModal() + # We won't need text_processor in this dialog, so let's avoid it. + def text_processor(self): + pass + def clear_text(self, text): urls = utils.find_urls_in_text(text) for i in urls: From 1e2464c4faf9f97c144822ae1cac86024fe27cbe Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 11:36:06 -0600 Subject: [PATCH 24/83] Made Dm dialog to hide attachments panel when needed --- src/controller/messages.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/controller/messages.py b/src/controller/messages.py index 2777d2cc..06159457 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -133,6 +133,14 @@ class basicTweet(object): def on_attach_poll(self, *args, **kwargs): pass + def remove_attachment(self, *args, **kwargs): + attachment = self.message.attachments.GetFocusedItem() + if attachment > -1 and len(self.attachments) > attachment: + self.attachments.pop(attachment) + self.message.remove_item(list_type="attachment") + self.text_processor() + self.message.text.SetFocus() + class tweet(basicTweet): def __init__(self, session, title, caption, text="", max=280, messageType="tweet", *args, **kwargs): self.thread = [] @@ -186,13 +194,6 @@ class tweet(basicTweet): self.text_processor() self.message.text.SetFocus() - def remove_attachment(self, *args, **kwargs): - attachment = self.message.attachments.GetFocusedItem() - if attachment > -1 and len(self.attachments) > attachment: - self.attachments.pop(attachment) - self.message.remove_item(list_type="attachment") - self.text_processor() - self.message.text.SetFocus() class reply(tweet): def __init__(self, session, title, caption, text, users=[], ids=[]): @@ -256,6 +257,18 @@ class dm(basicTweet): c = autocompletionUsers.completion.autocompletionUsers(self.message, self.session.session_id) c.show_menu("dm") + def text_processor(self, *args, **kwargs): + super(dm, self).text_processor(*args, **kwargs) + if len(self.attachments) > 0: + self.message.attachments.Enable(True) + self.message.remove_attachment.Enable(True) + else: + self.message.attachments.Enable(False) + self.message.remove_attachment.Enable(False) + + def get_data(self): + return dict(text=self.message.text.GetValue(), attachments=self.attachments) + class viewTweet(basicTweet): def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date="", item_url=""): """ 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. From 6346651edf703660a11cd049ff9390ccdbaf239b Mon Sep 17 00:00:00 2001 From: Mohamed Date: Wed, 10 Nov 2021 12:53:18 -0500 Subject: [PATCH 25/83] Added a shortcut for the add new tweet button --- src/wxUI/dialogs/twitterDialogs/tweetDialogs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py index a7a20059..d8504c3e 100644 --- a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -57,7 +57,7 @@ class tweet(wx.Dialog): mainBox.Add(btn_sizer_1, 1, wx.EXPAND, 0) self.add = wx.Button(panel, wx.ID_ANY, _("A&dd...")) btn_sizer_1.Add(self.add, 0, 0, 0) - self.add_tweet = wx.Button(panel, wx.ID_ANY, _("Add tweet")) + self.add_tweet = wx.Button(panel, wx.ID_ANY, _("Add t&weet")) self.add_tweet.Enable(thread_mode) btn_sizer_1.Add(self.add_tweet, 0, 0, 0) self.add_audio = wx.Button(panel, wx.ID_ANY, _("&Attach audio...")) From 9e7542f513e80319afdcf6447c6e6429403c617f Mon Sep 17 00:00:00 2001 From: Mohamed Date: Wed, 10 Nov 2021 13:01:24 -0500 Subject: [PATCH 26/83] Removed url_shortener import --- src/sessions/twitter/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sessions/twitter/utils.py b/src/sessions/twitter/utils.py index f84dfaca..d44e0e3f 100644 --- a/src/sessions/twitter/utils.py +++ b/src/sessions/twitter/utils.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -import url_shortener, re +import re import output import config import logging From a43101e6949b33cfb588bb5f10f3d5c365416496 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 12:21:07 -0600 Subject: [PATCH 27/83] Reimplemented direct messages with support for media --- src/controller/buffers/twitter/base.py | 16 ++++++-------- src/controller/messages.py | 5 +++++ src/sessions/twitter/session.py | 21 +++++++++++++++++++ .../dialogs/twitterDialogs/tweetDialogs.py | 14 +++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 72ea6449..ae22a576 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -425,21 +425,17 @@ class BaseBuffer(base.Buffer): else: screen_name = self.session.get_user(tweet.user).screen_name users = utils.get_all_users(tweet, self.session) - dm = messages.dm(self.session, _(u"Direct message to %s") % (screen_name,), _(u"New direct message"), users) + dm = messages.dm(self.session, _("Direct message to %s") % (screen_name,), _("New direct message"), users) if dm.message.ShowModal() == widgetUtils.OK: screen_name = dm.message.cb.GetValue() user = self.session.get_user_by_screen_name(screen_name) recipient_id = user text = dm.message.text.GetValue() - val = self.session.api_call(call_name="send_direct_message", recipient_id=recipient_id, text=text) - if val != None: - sent_dms = self.session.db["sent_direct_messages"] - if self.session.settings["general"]["reverse_timelines"] == False: - sent_dms.append(val) - else: - sent_dms.insert(0, val) - self.session.db["sent_direct_messages"] = sent_dms - pub.sendMessage("sent-dm", data=val, user=self.session.db["user_name"]) + if len(dm.attachments) > 0: + attachment = dm.attachments[0] + else: + attachment = None + call_threaded(self.session.direct_message, text=text, recipient=recipient_id, attachment=attachment) if hasattr(dm.message, "destroy"): dm.message.destroy() @_tweets_exist diff --git a/src/controller/messages.py b/src/controller/messages.py index 06159457..461b155e 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -269,6 +269,11 @@ class dm(basicTweet): def get_data(self): return dict(text=self.message.text.GetValue(), attachments=self.attachments) + def can_attach(self): + if len(self.attachments) == 0: + return True + return False + class viewTweet(basicTweet): def __init__(self, tweet, tweetList, is_tweet=True, utc_offset=0, date="", item_url=""): """ 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. diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index df3ab809..4e732b22 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -620,3 +620,24 @@ class Session(base.baseSession): self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) item = self.api_call(call_name="update_status", status=text, _sound="reply_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids, *args, **kwargs) + + def direct_message(self, text, recipient, attachment=None, *args, **kwargs): + if attachment == None: + item = self.api_call(call_name="send_direct_message", recipient_id=recipient, text=text) + else: + if attachment["type"] == "photo": + media_category = "DmImage" + elif attachment["type"] == "gif": + media_category = "DmGif" + elif attachment["type"] == "video": + media_category = "DmVideo" + media = self.api_call("media_upload", filename=attachment["file"], media_category=media_category) + item = self.api_call(call_name="send_direct_message", recipient_id=recipient, text=text, attachment_type="media", attachment_media_id=media.media_id) + if item != None: + sent_dms = self.db["sent_direct_messages"] + if self.settings["general"]["reverse_timelines"] == False: + sent_dms.append(item) + else: + sent_dms.insert(0, item) + self.db["sent_direct_messages"] = sent_dms + pub.sendMessage("sent-dm", data=item, user=self.db["user_name"]) diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py index a7a20059..1e4f1a3a 100644 --- a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -283,6 +283,20 @@ class dm(tweet): self.SetEscapeId(self.cancel.GetId()) self.Layout() + def get_image(self): + openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) + if openFileDialog.ShowModal() == wx.ID_CANCEL: + return (None, None) + return (openFileDialog.GetPath(), "") + + def attach_menu(self, event=None, enabled=True, *args, **kwargs): + menu = wx.Menu() + self.add_image = menu.Append(wx.ID_ANY, _("Image")) + self.add_image.Enable(enabled) + self.add_video = menu.Append(wx.ID_ANY, _("Video")) + self.add_video.Enable(enabled) + return menu + class viewTweet(wx.Dialog): def set_title(self, lenght): self.SetTitle(_(u"Tweet - %i characters ") % (lenght,)) From d9f4b86d913e9b920ee69a4b904446e311b06ad1 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 12:35:43 -0600 Subject: [PATCH 28/83] Empty attachments after adding a new tweet --- src/controller/messages.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/controller/messages.py b/src/controller/messages.py index 461b155e..67c8ec40 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -161,6 +161,7 @@ class tweet(basicTweet): attachments = self.attachments[::] tweetdata = dict(text=text, attachments=attachments) self.thread.append(tweetdata) + self.attachments = [] if update_gui: self.message.reset_controls() self.message.add_item(item=[text, len(attachments)], list_type="tweet") @@ -185,6 +186,11 @@ class tweet(basicTweet): else: self.message.attachments.Enable(False) self.message.remove_attachment.Enable(False) + if hasattr(self.message, "add_tweet"): + if len(self.message.text.GetValue()) > 0 or len(self.attachments) > 0: + self.message.add_tweet.Enable(True) + else: + self.message.add_tweet.Enable(False) def remove_tweet(self, *args, **kwargs): tweet = self.message.tweets.GetFocusedItem() @@ -266,9 +272,6 @@ class dm(basicTweet): self.message.attachments.Enable(False) self.message.remove_attachment.Enable(False) - def get_data(self): - return dict(text=self.message.text.GetValue(), attachments=self.attachments) - def can_attach(self): if len(self.attachments) == 0: return True From 77d13fdc28334d4e660af4e63bbb037542cc55b6 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 15:14:40 -0600 Subject: [PATCH 29/83] Added support for posting polls --- src/controller/buffers/twitter/base.py | 3 +- src/controller/messages.py | 12 +++- src/sessions/twitter/session.py | 33 ++++++++-- src/wxUI/dialogs/twitterDialogs/__init__.py | 2 +- .../dialogs/twitterDialogs/tweetDialogs.py | 65 +++++++++++++++++++ 5 files changed, 106 insertions(+), 9 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index ae22a576..34196b7b 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -457,11 +457,10 @@ class BaseBuffer(base.Buffer): if hasattr(tweet, "retweeted_status"): tweet = tweet.retweeted_status retweet = messages.tweet(session=self.session, title=_("Quote"), caption=_("Add your comment to the tweet"), max=256, thread_mode=False) - retweet = messages.tweet(session=self.session, title=_("Quote"), caption=_("Add your comment to the tweet"), max=256, thread_mode=False) if retweet.message.ShowModal() == widgetUtils.OK: text = retweet.message.text.GetValue() text = text+" https://twitter.com/{0}/status/{1}".format(self.session.get_user(tweet.user).screen_name, id) - tweet_data = dict(text=text, attachments=retweet.attachments) + tweet_data = dict(text=text, attachments=retweet.attachments, poll_period=retweet.poll_period, poll_options=retweet.poll_options) call_threaded(self.session.send_tweet, *[tweet_data]) if hasattr(retweet.message, "destroy"): retweet.message.destroy() diff --git a/src/controller/messages.py b/src/controller/messages.py index 67c8ec40..3fb52d38 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -131,7 +131,11 @@ class basicTweet(object): self.text_processor() def on_attach_poll(self, *args, **kwargs): - pass + dlg = twitterDialogs.poll() + if dlg.ShowModal() == wx.ID_OK: + self.poll_options = dlg.get_options() + self.poll_period = 60*24*dlg.period.GetValue() + dlg.Destroy() def remove_attachment(self, *args, **kwargs): attachment = self.message.attachments.GetFocusedItem() @@ -144,6 +148,8 @@ class basicTweet(object): class tweet(basicTweet): def __init__(self, session, title, caption, text="", max=280, messageType="tweet", *args, **kwargs): self.thread = [] + self.poll_options = None + self.poll_period = None super(tweet, self).__init__(session, title, caption, text, messageType, max, *args, **kwargs) widgetUtils.connect_event(self.message.autocomplete_users, widgetUtils.BUTTON_PRESSED, self.autocomplete_users) if hasattr(self.message, "add_tweet"): @@ -159,9 +165,11 @@ class tweet(basicTweet): def add_tweet(self, event, update_gui=True, *args, **kwargs): text = self.message.text.GetValue() attachments = self.attachments[::] - tweetdata = dict(text=text, attachments=attachments) + tweetdata = dict(text=text, attachments=attachments, poll_options=self.poll_options, poll_period=self.poll_period) self.thread.append(tweetdata) self.attachments = [] + self.poll_options = None + self.poll_period = None if update_gui: self.message.reset_controls() self.message.add_item(item=[text, len(attachments)], list_type="tweet") diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index 4e732b22..40f40df5 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -218,6 +218,30 @@ class Session(base.baseSession): if _sound != None: self.sound.play(_sound) return val + def api_call_v2(self, call_name, action="", _sound=None, report_success=False, report_failure=True, preexec_message="", *args, **kwargs): + finished = False + tries = 0 + if preexec_message: + output.speak(preexec_message, True) + while finished==False and tries < 25: + try: + val = getattr(self.twitter_v2, call_name)(*args, **kwargs) + finished = True + except TweepyException as e: + log.exception("Error sending the tweet.") + output.speak(str(e)) + val = None + if type(e) != NotFound and type(e) != Forbidden: + tries = tries+1 + time.sleep(5) + elif report_failure: + output.speak(_("%s failed. Reason: %s") % (action, str(e))) + finished = True + if report_success: + output.speak(_("%s succeeded.") % action) + if _sound != None: self.sound.play(_sound) + return val + def search(self, name, *args, **kwargs): """ Search in twitter, passing args and kwargs as arguments to the Twython function.""" tl = self.twitter.search_tweets(*args, **kwargs) @@ -597,8 +621,9 @@ class Session(base.baseSession): in_reply_to_status_id = None for obj in tweets: if len(obj["attachments"]) == 0: - item = self.api_call(call_name="update_status", status=obj["text"], _sound="tweet_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id) - in_reply_to_status_id = item.id + item = self.api_call_v2(call_name="create_tweet", text=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"]) + print(item) + in_reply_to_status_id = item.data.id else: media_ids = [] for i in obj["attachments"]: @@ -606,8 +631,8 @@ class Session(base.baseSession): if i["type"] == "photo": self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) - item = self.api_call(call_name="update_status", status=obj["text"], _sound="tweet_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids) - in_reply_to_status_id = item.id + item = self.api_call_v2(call_name="create_tweet", status=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"]) + in_reply_to_status_id = item.data.id def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs): if len(attachments) == 0: diff --git a/src/wxUI/dialogs/twitterDialogs/__init__.py b/src/wxUI/dialogs/twitterDialogs/__init__.py index c6b568e0..6a829f06 100644 --- a/src/wxUI/dialogs/twitterDialogs/__init__.py +++ b/src/wxUI/dialogs/twitterDialogs/__init__.py @@ -1 +1 @@ -from .tweetDialogs import tweet, reply, dm, viewTweet, viewNonTweet \ No newline at end of file +from .tweetDialogs import tweet, reply, dm, viewTweet, viewNonTweet, poll \ No newline at end of file diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py index d175b033..d5fd35a6 100644 --- a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -469,3 +469,68 @@ class viewNonTweet(wx.Dialog): def enable_button(self, buttonName): if hasattr(self, buttonName): return getattr(self, buttonName).Enable() + +class poll(wx.Dialog): + def __init__(self, *args, **kwds): + super(poll, self).__init__(parent=None, id=wx.NewId(), title=_("Add a poll")) + sizer_1 = wx.BoxSizer(wx.VERTICAL) + period_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_1.Add(period_sizer, 1, wx.EXPAND, 0) + label_period = wx.StaticText(self, wx.ID_ANY, _("Participation time (in days)")) + period_sizer.Add(label_period, 0, 0, 0) + self.period = wx.SpinCtrl(self, wx.ID_ANY) + self.period.SetFocus() + self.period.SetRange(1, 7) + self.period.SetValue(7) + period_sizer.Add(self.period, 0, 0, 0) + sizer_2 = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Choices")), wx.VERTICAL) + sizer_1.Add(sizer_2, 1, wx.EXPAND, 0) + option1_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_2.Add(option1_sizer, 1, wx.EXPAND, 0) + label_2 = wx.StaticText(self, wx.ID_ANY, _("Option 1")) + option1_sizer.Add(label_2, 0, 0, 0) + self.option1 = wx.TextCtrl(self, wx.ID_ANY, "") + option1_sizer.Add(self.option1, 0, 0, 0) + option2_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_2.Add(option2_sizer, 1, wx.EXPAND, 0) + label_3 = wx.StaticText(self, wx.ID_ANY, _("Option 2")) + option2_sizer.Add(label_3, 0, 0, 0) + self.option2 = wx.TextCtrl(self, wx.ID_ANY, "") + option2_sizer.Add(self.option2, 0, 0, 0) + option3_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_2.Add(option3_sizer, 1, wx.EXPAND, 0) + label_4 = wx.StaticText(self, wx.ID_ANY, _("Option 3")) + option3_sizer.Add(label_4, 0, 0, 0) + self.option3 = wx.TextCtrl(self, wx.ID_ANY, "") + option3_sizer.Add(self.option3, 0, 0, 0) + option4_sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer_2.Add(option4_sizer, 1, wx.EXPAND, 0) + label_5 = wx.StaticText(self, wx.ID_ANY, _("Option 4")) + option4_sizer.Add(label_5, 0, 0, 0) + self.option4 = wx.TextCtrl(self, wx.ID_ANY, "") + option4_sizer.Add(self.option4, 0, 0, 0) + btn_sizer = wx.StdDialogButtonSizer() + sizer_1.Add(btn_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.button_OK = wx.Button(self, wx.ID_OK) + self.button_OK.SetDefault() + self.button_OK.Bind(wx.EVT_BUTTON, self.validate_data) + btn_sizer.AddButton(self.button_OK) + self.button_CANCEL = wx.Button(self, wx.ID_CANCEL, "") + btn_sizer.AddButton(self.button_CANCEL) + btn_sizer.Realize() + self.SetSizer(sizer_1) + sizer_1.Fit(self) + self.SetAffirmativeId(self.button_OK.GetId()) + self.SetEscapeId(self.button_CANCEL.GetId()) + self.Layout() + + def get_options(self): + controls = [self.option1, self.option2, self.option3, self.option4] + options = [option.GetValue() for option in controls if option.GetValue() != ""] + return options + + def validate_data(self, *args, **kwargs): + options = self.get_options() + if len(options) < 2: + return wx.MessageDialog(self, _("Please make sure you have provided at least two options for the poll."), _("Not enough information"), wx.ICON_ERROR).ShowModal() + self.EndModal(wx.ID_OK) \ No newline at end of file From b0cfc5978c6922169bf643c02bed7a8aecbaa5f7 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 16:32:14 -0600 Subject: [PATCH 30/83] Updated reply dialog with some changes in add menu --- src/controller/buffers/twitter/base.py | 4 ++-- .../buffers/twitter/directMessages.py | 4 ++-- src/controller/buffers/twitter/people.py | 4 ++-- src/controller/buffers/twitter/trends.py | 22 ++++++------------- src/controller/messages.py | 7 +++--- src/sessions/twitter/session.py | 2 +- .../dialogs/twitterDialogs/tweetDialogs.py | 8 +++++++ 7 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 34196b7b..1d81a604 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -408,8 +408,8 @@ class BaseBuffer(base.Buffer): if len(users) > 0: config.app["app-settings"]["mention_all"] = message.message.mention_all.GetValue() config.app.write() - tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments) - call_threaded(self.session.reply, in_reply_to_status_id=id, text=message.message.text.GetValue(), attachments=message.attachments, exclude_reply_user_ids=message.get_ids(), auto_populate_reply_metadata=True) + tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments, poll_options=message.poll_options, poll_period=message.poll_period) + call_threaded(self.session.reply, in_reply_to_status_id=id, text=message.message.text.GetValue(), attachments=message.attachments, exclude_reply_user_ids=message.get_ids()) if hasattr(message.message, "destroy"): message.message.destroy() self.session.settings.write() diff --git a/src/controller/buffers/twitter/directMessages.py b/src/controller/buffers/twitter/directMessages.py index 60090c89..06cbed9a 100644 --- a/src/controller/buffers/twitter/directMessages.py +++ b/src/controller/buffers/twitter/directMessages.py @@ -92,8 +92,8 @@ class DirectMessagesBuffer(base.BaseBuffer): screen_name = self.session.get_user(tweet.message_create["sender_id"]).screen_name message = messages.reply(session=self.session, title=_("Mention"), caption=_("Mention to %s") % (screen_name,), text="@%s " % (screen_name,), thread_mode=False, users=[screen_name,]) if message.message.ShowModal() == widgetUtils.OK: - tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments) - call_threaded(self.session.send_tweet, *[tweet_data]) + tweet_data = message.get_tweet_data() + call_threaded(self.session.send_tweet, tweet_data) if hasattr(message.message, "destroy"): message.message.destroy() diff --git a/src/controller/buffers/twitter/people.py b/src/controller/buffers/twitter/people.py index faf03794..d29a46dc 100644 --- a/src/controller/buffers/twitter/people.py +++ b/src/controller/buffers/twitter/people.py @@ -94,8 +94,8 @@ class PeopleBuffer(base.BaseBuffer): screen_name = tweet.screen_name message = messages.tweet(session=self.session, title=_("Mention"), caption=_("Mention to %s") % (screen_name,), text="@%s " % (screen_name,), thread_mode=False) if message.message.ShowModal() == widgetUtils.OK: - tweet_data = dict(text=message.message.text.GetValue(), attachments=message.attachments) - call_threaded(self.session.send_tweet, *[tweet_data]) + tweet_data = message.get_tweet_data() + call_threaded(self.session.send_tweet, tweet_data) if hasattr(message.message, "destroy"): message.message.destroy() diff --git a/src/controller/buffers/twitter/trends.py b/src/controller/buffers/twitter/trends.py index ab623e05..39809df1 100644 --- a/src/controller/buffers/twitter/trends.py +++ b/src/controller/buffers/twitter/trends.py @@ -131,21 +131,13 @@ class TrendsBuffer(base.Buffer): def tweet_about_this_trend(self, *args, **kwargs): if self.buffer.list.get_count() == 0: return - title = _(u"Tweet") - caption = _(u"Write the tweet here") - tweet = messages.tweet(self.session, title, caption, self.get_message()+ " ") - tweet.message.set_cursor_at_end() - if tweet.message.get_response() == widgetUtils.OK: - text = tweet.message.get_text() - if len(text) > 280 and tweet.message.get("long_tweet") == True: - if tweet.image == None: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text) - else: - text = twishort.create_tweet(self.session.settings["twitter"]["user_key"], self.session.settings["twitter"]["user_secret"], text, 1) - if tweet.image == None: - call_threaded(self.session.api_call, call_name="update_status", status=text) - else: - call_threaded(self.session.api_call, call_name="update_status_with_media", status=text, media=tweet.image) + title = _("Tweet") + caption = _("Write the tweet here") + tweet = messages.tweet(session=self.session, title=title, caption=caption, text=self.get_message()+ " ") + tweet.message.SetInsertionPoint(len(tweet.message.GetValue())) + if tweet.message.ShowModal() == widgetUtils.OK: + tweet_data = tweet.get_tweet_data() + call_threaded(self.session.send_tweet, *tweet_data) if hasattr(tweet.message, "destroy"): tweet.message.destroy() def show_menu_by_key(self, ev): diff --git a/src/controller/messages.py b/src/controller/messages.py index 3fb52d38..421be6d7 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -93,7 +93,8 @@ class basicTweet(object): menu = self.message.attach_menu(can_attach) self.message.Bind(wx.EVT_MENU, self.on_attach_image, self.message.add_image) self.message.Bind(wx.EVT_MENU, self.on_attach_video, self.message.add_video) - self.message.Bind(wx.EVT_MENU, self.on_attach_poll, self.message.add_poll) + if hasattr(self.message, "add_poll"): + self.message.Bind(wx.EVT_MENU, self.on_attach_poll, self.message.add_poll) self.message.PopupMenu(menu, self.message.add.GetPosition()) def on_attach_image(self, *args, **kwargs): @@ -243,10 +244,10 @@ class reply(tweet): i.Show() def get_ids(self): - excluded_ids = "" + excluded_ids = [] for i in range(0, len(self.message.checkboxes)): if self.message.checkboxes[i].GetValue() == False: - excluded_ids = excluded_ids + "{0},".format(self.ids[i],) + excluded_ids.append(self.ids[i]) return excluded_ids def get_people(self): diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index 40f40df5..38f4baae 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -636,7 +636,7 @@ class Session(base.baseSession): def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs): if len(attachments) == 0: - item = self.api_call(call_name="update_status", status=text, _sound="reply_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, *args, **kwargs) + item = self.api_call_v2(call_name="create_tweet", text=text, _sound="reply_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, *args, **kwargs) else: media_ids = [] for i in attachments: diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py index d5fd35a6..84ea5fde 100644 --- a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -217,6 +217,14 @@ class reply(tweet): self.SetEscapeId(self.cancel.GetId()) self.Layout() + def attach_menu(self, event=None, enabled=True, *args, **kwargs): + menu = wx.Menu() + self.add_image = menu.Append(wx.ID_ANY, _("Image")) + self.add_image.Enable(enabled) + self.add_video = menu.Append(wx.ID_ANY, _("Video")) + self.add_video.Enable(enabled) + return menu + class dm(tweet): def __init__(self, users: List[str] = [], *args, **kwargs) -> None: From e9f6fd529efd96a5db327a2fb39ee41c50059e18 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 16:32:39 -0600 Subject: [PATCH 31/83] Updated changelog --- doc/changelog.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/changelog.md b/doc/changelog.md index 513204c2..cc097af8 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,15 @@ TWBlue Changelog ## changes in this version +* Now it is possible to create a tweet from a trending topics buffer again. +* TWBlue now includes a completely new set of dialogs to handle tweeting, replying and sending direct messages that takes advantage of more Twitter features. + * It is possible to add videos in tweets and direct messages by using the new "add" button, located in every dialog where media can be added. Twitter suggests to add videos from 5 seconds up to 2 minutes lenght, in mp4 format (video Codec H.264 and audio codec AAC). Currently, TWBlue does not check if the uploaded video complies with Twitter media requirements. You can add only a video in a tweet or direct message. No other kind of media can be added after a video is in a tweet. If the video was unable to be uploaded successfully, the tweet or direct message won't be created. + * Now you can add a poll to tweets. Polls can have up to 4 different options and allow voting up to 7 days after being created. Take into account, though, that currently TWBlue does not support reading polls in tweets. + * TWBlue now support threads while creating a new tweet. There is a new button, called add tweet which will add the current tweet to the thread and will allow you to write another tweet in the thread. Every tweet might include media (up to 4 photos, or one GIF image or a video) or up to one poll. + * Some functionality was removed from tweet dialogs within TWBlue. Particularly, URL shorteners and long tweets via Twishort. You still can read long tweets posted via Twishort, though. + +## Changes in version 2021.11.07 + * TWBlue should retrieve tweets from threads and conversations in a more reliable way. Tweets in the same thread (made by the same author) will be sorted correctly, although replies to the thread (made by different people) may not be ordered in the same way they are displayed in Twitter apps. ([#417](https://github.com/manuelcortez/TWBlue/issues/417)) * When creating a filter, TWBlue will show an error if user has not provided a name for the filter. Before, unnamed filters were a cause of config breaks in the application. * It is again possible to read the changelog for TWBlue from the help menu in the menu bar. From b3bf0ab8e683625e1fa4d36b09528e6bf8cdf5b3 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 10 Nov 2021 17:35:24 -0600 Subject: [PATCH 32/83] Removed calls to SetMaxLength in dialogs --- src/wxUI/dialogs/twitterDialogs/tweetDialogs.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py index 84ea5fde..e42bd9f4 100644 --- a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -25,7 +25,6 @@ class tweet(wx.Dialog): self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) self.text.SetMinSize((1000, 158)) - self.text.SetMaxLength(max_length) text_sizer.Add(self.text, 1, wx.EXPAND, 0) list_sizer = wx.BoxSizer(wx.HORIZONTAL) mainBox.Add(list_sizer, 1, wx.EXPAND, 0) @@ -163,7 +162,6 @@ class reply(tweet): self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) self.text.SetMinSize((1000, 158)) - self.text.SetMaxLength(max_length) text_sizer.Add(self.text, 1, wx.EXPAND, 0) list_sizer = wx.BoxSizer(wx.HORIZONTAL) mainBox.Add(list_sizer, 1, wx.EXPAND, 0) @@ -248,7 +246,6 @@ class dm(tweet): self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) self.text.SetMinSize((1000, 158)) - self.text.SetMaxLength(max_length) self.text.SetFocus() text_sizer.Add(self.text, 1, wx.EXPAND, 0) list_sizer = wx.BoxSizer(wx.HORIZONTAL) From 8abcb3623dff45e3b21ba93af72ca23d332aaec1 Mon Sep 17 00:00:00 2001 From: Oreonan Date: Thu, 11 Nov 2021 01:09:19 +0100 Subject: [PATCH 33/83] Update french interface --- src/locales/fr/LC_MESSAGES/twblue.po | 522 +++++++++++++++------------ 1 file changed, 294 insertions(+), 228 deletions(-) diff --git a/src/locales/fr/LC_MESSAGES/twblue.po b/src/locales/fr/LC_MESSAGES/twblue.po index e31dd0e1..3842a448 100644 --- a/src/locales/fr/LC_MESSAGES/twblue.po +++ b/src/locales/fr/LC_MESSAGES/twblue.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.94\n" -"POT-Creation-Date: 2021-11-03 18:55+0100\n" -"PO-Revision-Date: 2021-11-04 17:00+0100\n" +"POT-Creation-Date: 2021-11-11 01:00+0100\n" +"PO-Revision-Date: 2021-11-11 01:08+0100\n" "Last-Translator: Oreonan \n" "Language-Team: Oreonan \n" "Language: fr\n" @@ -16,10 +16,6 @@ msgstr "" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-Bookmarks: -1,-1,-1,-1,-1,384,-1,-1,-1,-1\n" -#: ../src\controller\attach.py:25 -msgid "Photo" -msgstr "Photo" - #: ../src\controller\buffers\base\base.py:91 msgid "This action is not supported for this buffer" msgstr "Cette action n'est pas supportée pour ce tampon" @@ -98,78 +94,81 @@ msgstr "Abonnements de {username}" msgid "Unknown buffer" msgstr "Tampon inconnu" -#: ../src\controller\buffers\twitter\base.py:88 -#: ../src\controller\buffers\twitter\trends.py:122 -#: ../src\controller\messages.py:214 ../src\wxUI\buffers\base.py:25 +#: ../src\controller\buffers\twitter\base.py:87 +#: ../src\controller\buffers\twitter\trends.py:43 +#: ../src\controller\buffers\twitter\trends.py:134 +#: ../src\controller\messages.py:296 ../src\wxUI\buffers\base.py:25 #: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:35 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:312 +#: ../src\wxUI\sysTrayIcon.py:35 msgid "Tweet" msgstr "Tweet" -#: ../src\controller\buffers\twitter\base.py:89 -#: ../src\controller\buffers\twitter\trends.py:123 +#: ../src\controller\buffers\twitter\base.py:88 +#: ../src\controller\buffers\twitter\trends.py:44 +#: ../src\controller\buffers\twitter\trends.py:135 msgid "Write the tweet here" msgstr "Écrivez le tweet ici" -#: ../src\controller\buffers\twitter\base.py:219 +#: ../src\controller\buffers\twitter\base.py:192 msgid "New tweet in {0}" msgstr "Nouveau tweet dans {0}" -#: ../src\controller\buffers\twitter\base.py:222 +#: ../src\controller\buffers\twitter\base.py:195 msgid "{0} new tweets in {1}." msgstr "{0} nouveau tweet dans {1}" -#: ../src\controller\buffers\twitter\base.py:261 +#: ../src\controller\buffers\twitter\base.py:234 #: ../src\controller\buffers\twitter\directMessages.py:88 -#: ../src\controller\buffers\twitter\people.py:180 +#: ../src\controller\buffers\twitter\people.py:174 msgid "%s items retrieved" msgstr "%s éléments récupérés" -#: ../src\controller\buffers\twitter\base.py:293 +#: ../src\controller\buffers\twitter\base.py:266 #: ../src\controller\buffers\twitter\people.py:80 msgid "This buffer is not a timeline; it can't be deleted." msgstr "Ce tampon n'est pas une chronologie ; Impossible de le supprimé." -#: ../src\controller\buffers\twitter\base.py:430 +#: ../src\controller\buffers\twitter\base.py:402 msgid "Reply to {arg0}" msgstr "Répondre à {arg0}" -#: ../src\controller\buffers\twitter\base.py:432 +#: ../src\controller\buffers\twitter\base.py:404 #: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "Répondre" -#: ../src\controller\buffers\twitter\base.py:433 +#: ../src\controller\buffers\twitter\base.py:405 msgid "Reply to %s" msgstr "Répondre à %s" -#: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\buffers\twitter\directMessages.py:130 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "Nouveau message" -#: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\messages.py:200 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\messages.py:268 msgid "Direct message to %s" msgstr "Message à %s" -#: ../src\controller\buffers\twitter\base.py:520 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Add your comment to the tweet" msgstr "Ajoutez votre commentaire pour le tweet" -#: ../src\controller\buffers\twitter\base.py:520 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Quote" msgstr "Citer" -#: ../src\controller\buffers\twitter\base.py:596 +#: ../src\controller\buffers\twitter\base.py:520 msgid "Opening URL..." msgstr "Ouverture de l'URL..." -#: ../src\controller\buffers\twitter\base.py:633 +#: ../src\controller\buffers\twitter\base.py:557 msgid "User details" msgstr "Détails de l'utilisateur" -#: ../src\controller\buffers\twitter\base.py:654 +#: ../src\controller\buffers\twitter\base.py:578 msgid "Opening item in web browser..." msgstr "Ouverture de l'élément dans le navigateur Web..." @@ -184,15 +183,15 @@ msgstr "Mention pour %s" msgid "Mention" msgstr "Mention" -#: ../src\controller\buffers\twitter\directMessages.py:133 +#: ../src\controller\buffers\twitter\directMessages.py:127 msgid "{0} new direct messages." msgstr "{0} nouveau message" -#: ../src\controller\buffers\twitter\directMessages.py:136 +#: ../src\controller\buffers\twitter\directMessages.py:130 msgid "This action is not supported in the buffer yet." msgstr "Cette action n'est pas supportée dans le tampon actuel" -#: ../src\controller\buffers\twitter\directMessages.py:146 +#: ../src\controller\buffers\twitter\directMessages.py:140 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." @@ -200,11 +199,11 @@ msgstr "" "Récupérer plus d'élément est impossible dans ce tampon, utilisez le tampon " "des messages à la place." -#: ../src\controller\buffers\twitter\people.py:253 +#: ../src\controller\buffers\twitter\people.py:247 msgid "{0} new followers." msgstr "{0} nouvel abonné" -#: ../src\controller\buffers\twitter\trends.py:146 +#: ../src\controller\buffers\twitter\trends.py:150 msgid "This action is not supported in the buffer, yet." msgstr "Cette action n'est pas supportée pour le tampon actuel" @@ -222,7 +221,7 @@ msgstr "Chronologies" #: ../src\controller\mainController.py:359 #: ../src\controller\mainController.py:883 -#: ../src\controller\mainController.py:1585 +#: ../src\controller\mainController.py:1582 msgid "Timeline for {}" msgstr "Chronologie de {}" @@ -232,7 +231,7 @@ msgstr "Chronologies des favoris" #: ../src\controller\mainController.py:363 #: ../src\controller\mainController.py:902 -#: ../src\controller\mainController.py:1587 +#: ../src\controller\mainController.py:1584 msgid "Likes for {}" msgstr "Favoris de {}" @@ -242,7 +241,7 @@ msgstr "Chronologies des abonnés" #: ../src\controller\mainController.py:367 #: ../src\controller\mainController.py:921 -#: ../src\controller\mainController.py:1589 +#: ../src\controller\mainController.py:1586 msgid "Followers for {}" msgstr "Abonnés de {}" @@ -252,7 +251,7 @@ msgstr "Chronologies des abonnements" #: ../src\controller\mainController.py:371 #: ../src\controller\mainController.py:940 -#: ../src\controller\mainController.py:1591 +#: ../src\controller\mainController.py:1588 msgid "Friends for {}" msgstr "Abonnements de {}" @@ -277,7 +276,7 @@ msgstr "Recherche de {}" #: ../src\controller\mainController.py:381 #: ../src\controller\mainController.py:982 -#: ../src\controller\mainController.py:1593 +#: ../src\controller\mainController.py:1590 msgid "Trending topics for %s" msgstr "Tendances pour %s" @@ -320,7 +319,7 @@ msgstr "Ajoute un alias pour l'utilisateur" msgid "Alias has been set correctly for {}." msgstr "L'alias pour {} a correctement été définie" -#: ../src\controller\mainController.py:829 ../src\controller\messages.py:245 +#: ../src\controller\mainController.py:829 ../src\controller\messages.py:327 msgid "MMM D, YYYY. H:m" msgstr "D MMM YYYY à H:m" @@ -410,72 +409,52 @@ msgstr "Tampon muet" msgid "Buffer mute off" msgstr "Tampon non muet" -#: ../src\controller\mainController.py:1545 +#: ../src\controller\mainController.py:1542 msgid "Copied" msgstr "Copié" -#: ../src\controller\mainController.py:1575 +#: ../src\controller\mainController.py:1572 msgid "Unable to update this buffer." msgstr "Impossible de mettre à jour ce tampon." -#: ../src\controller\mainController.py:1578 +#: ../src\controller\mainController.py:1575 msgid "Updating buffer..." msgstr "Actualisation..." -#: ../src\controller\mainController.py:1581 +#: ../src\controller\mainController.py:1578 msgid "{0} items retrieved" msgstr "{0} éléments récupérés" -#: ../src\controller\mainController.py:1600 -#: ../src\controller\mainController.py:1620 +#: ../src\controller\mainController.py:1597 +#: ../src\controller\mainController.py:1617 msgid "Invalid buffer" msgstr "Tampon invalide" -#: ../src\controller\mainController.py:1611 +#: ../src\controller\mainController.py:1608 msgid "Picture {0}" msgstr "Photo {0}" -#: ../src\controller\mainController.py:1612 +#: ../src\controller\mainController.py:1609 msgid "Select the picture" msgstr "Sélectionner la photo" -#: ../src\controller\mainController.py:1631 +#: ../src\controller\mainController.py:1628 msgid "Unable to extract text" msgstr "Impossible d'extraire le texte" -#: ../src\controller\messages.py:56 +#: ../src\controller\messages.py:49 msgid "Translated" msgstr "Traduit" -#: ../src\controller\messages.py:63 -msgid "There's no URL to be shortened" -msgstr "Aucune URL à réduire" - -#: ../src\controller\messages.py:67 ../src\controller\messages.py:75 -msgid "URL shortened" -msgstr "URL réduite" - -#: ../src\controller\messages.py:82 -msgid "There's no URL to be expanded" -msgstr "Aucune URL à élargir" - -#: ../src\controller\messages.py:86 ../src\controller\messages.py:94 -msgid "URL expanded" -msgstr "URL élargi" - -#: ../src\controller\messages.py:108 +#: ../src\controller\messages.py:56 msgid "%s - %s of %d characters" msgstr "%s - %s/%d caractères" -#: ../src\controller\messages.py:112 -msgid "%s - %s characters" -msgstr "%s - %s caractères" - -#: ../src\controller\messages.py:272 +#: ../src\controller\messages.py:354 msgid "View item" msgstr "Voir l'élément" -#: ../src\controller\messages.py:301 +#: ../src\controller\messages.py:379 msgid "Link copied to clipboard." msgstr "Lien copié dans le Presse-papiers" @@ -666,7 +645,7 @@ msgstr "Arrêté" msgid "&Record" msgstr "&Enregistrer" -#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:148 +#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:147 msgid "Playing..." msgstr "Lecture..." @@ -718,6 +697,9 @@ msgid "%s seconds" msgstr "%s secondes" #: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:258 msgid "File" msgstr "Fichier" @@ -1563,7 +1545,7 @@ msgid "New tweet" msgstr "Nouveau tweet" #: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:26 -#: ../src\wxUI\commonMessageDialogs.py:10 ../src\wxUI\dialogs\message.py:126 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Retweet" msgstr "Retweet" @@ -2009,15 +1991,17 @@ msgid "public" msgstr "public" #: ../src\sessions\twitter\session.py:211 +#: ../src\sessions\twitter\session.py:238 msgid "%s failed. Reason: %s" msgstr "%s erreur. Raison: %s" #: ../src\sessions\twitter\session.py:217 +#: ../src\sessions\twitter\session.py:241 msgid "%s succeeded." msgstr "%s réussi." -#: ../src\sessions\twitter\session.py:426 -#: ../src\sessions\twitter\session.py:504 +#: ../src\sessions\twitter\session.py:450 +#: ../src\sessions\twitter\session.py:528 msgid "Deleted account" msgstr "Compte supprimé" @@ -2045,7 +2029,7 @@ msgstr "Compte en cours d'autorisation..." msgid "Enter your PIN code here" msgstr "Entrer votre code PIN ici" -#: ../src\sound.py:161 +#: ../src\sound.py:160 msgid "Stopped." msgstr "Arrêté." @@ -2099,10 +2083,6 @@ msgstr "" msgid "Client" msgstr "Client" -#: ../src\wxUI\buffers\base.py:12 -msgid "Text" -msgstr "Texte" - #: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\events.py:14 msgid "Date" msgstr "Date" @@ -2114,6 +2094,11 @@ msgstr "Date" msgid "User" msgstr "Utilisateur" +#: ../src\wxUI\buffers\base.py:12 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +msgid "Text" +msgstr "Texte" + #: ../src\wxUI\buffers\base.py:28 msgid "Direct message" msgstr "Message" @@ -2375,55 +2360,6 @@ msgstr "" "{0} a été quitté inopinément lors de sa dernière exécution. Si ce problème " "perciste, veuillez le signaler aux développeurs de {0}." -#: ../src\wxUI\dialogs\attach.py:10 -msgid "Add an attachment" -msgstr "Ajouter un fichier" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Attachments" -msgstr "Fichiers joints" - -#: ../src\wxUI\dialogs\attach.py:14 -msgid "Title" -msgstr "Titre" - -#: ../src\wxUI\dialogs\attach.py:14 -msgid "Type" -msgstr "Type" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "Add attachments" -msgstr "Joindre des fichiers" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "&Photo" -msgstr "&Image" - -#: ../src\wxUI\dialogs\attach.py:21 -msgid "Remove attachment" -msgstr "Supprimer le fichier joint" - -#: ../src\wxUI\dialogs\attach.py:37 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:82 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Fichiers image (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:37 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:82 -msgid "Select the picture to be uploaded" -msgstr "Sélectionnez la photo à charger" - -#: ../src\wxUI\dialogs\attach.py:44 -msgid "please provide a description" -msgstr "Veuillez fournir une description" - -#: ../src\wxUI\dialogs\attach.py:44 ../src\wxUI\dialogs\lists.py:14 -#: ../src\wxUI\dialogs\lists.py:70 -msgid "Description" -msgstr "Description" - #: ../src\wxUI\dialogs\configuration.py:15 msgid "Language" msgstr "Langue" @@ -2811,6 +2747,14 @@ msgstr "Propriétaire" msgid "mode" msgstr "mode" +#: ../src\wxUI\dialogs\lists.py:14 ../src\wxUI\dialogs\lists.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:38 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:260 +msgid "Description" +msgstr "Description" + #: ../src\wxUI\dialogs\lists.py:19 ../src\wxUI\dialogs\lists.py:62 msgid "Create a new list" msgstr "Créer une nouvelle liste" @@ -2867,103 +2811,6 @@ msgstr "Sélectionnez une liste pour supprimer l'utilisateur" msgid "Do you really want to delete this list?" msgstr "Voulez-vous vraiment supprimer cette liste ?" -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "&Tweet long" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "&Joindre une image..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:359 ../src\wxUI\dialogs\message.py:435 -msgid "Check &spelling..." -msgstr "Correction &orthographique..." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "&Joindre un audio..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "&Réduire URL" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:436 -msgid "&Expand URL" -msgstr "&Élargir URL" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:362 ../src\wxUI\dialogs\message.py:438 -msgid "&Translate..." -msgstr "&Traduire..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "Sai&sie automatique utilisateurs" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "Envoye&r" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:363 ../src\wxUI\dialogs\message.py:439 -msgid "C&lose" -msgstr "F&ermer" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "&Destinataire" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "&Répondre à tout le monde" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tweet - %i caractères " - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Description de l'image" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Retweets: " - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Favoris: " - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Source: " - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:423 -msgid "Date: " -msgstr "Date: " - -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:433 -msgid "Copy link to clipboard" -msgstr "Copier le lien dans le Presse-papiers" - -#: ../src\wxUI\dialogs\message.py:408 -msgid "View" -msgstr "Voir" - -#: ../src\wxUI\dialogs\message.py:410 -msgid "Item" -msgstr "Élément" - #: ../src\wxUI\dialogs\search.py:12 msgid "Search on Twitter" msgstr "Rechercher sur Twitter" @@ -3045,6 +2892,225 @@ msgstr "Ville" msgid "&Location" msgstr "&Localisation" +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:33 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:49 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:170 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 +msgid "Attachments" +msgstr "Fichiers joints" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:174 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 +msgid "Type" +msgstr "Type" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:40 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:177 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:262 +msgid "Delete attachment" +msgstr "Supprimer la pièce jointe" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:45 +msgid "Added Tweets" +msgstr "Tweets ajoutés" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:52 +msgid "Delete tweet" +msgstr "Supprimer le tweet" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:57 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:267 +msgid "A&dd..." +msgstr "&Ajouter" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:59 +msgid "Add t&weet" +msgstr "A&jouter un tweet" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:62 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:194 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:269 +msgid "&Attach audio..." +msgstr "&Joindre un audio..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:66 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:237 +msgid "Auto&complete users" +msgstr "Sai&sie automatique utilisateurs" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:68 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:273 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:367 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 +msgid "Check &spelling..." +msgstr "Correction &orthographique..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:202 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:275 +msgid "&Translate" +msgstr "&Traduire" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:74 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:206 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:279 +msgid "Sen&d" +msgstr "Envoye&r" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:118 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:299 +msgid "Image" +msgstr "Image" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:120 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:222 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:301 +msgid "Video" +msgstr "Vidéo" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:122 +msgid "Poll" +msgstr "Sondage" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +msgid "please provide a description" +msgstr "Veuillez fournir une description" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +msgstr "Fichiers image (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Select the picture to be uploaded" +msgstr "Sélectionnez la photo à charger" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Select the video to be uploaded" +msgstr "Sélectionnez la vidéo à téléverser" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Video files (*.mp4)|*.mp4" +msgstr "Fichiers vidéo (*.mp4)|*.mp4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "Error adding attachment" +msgstr "Erreur à l'ajout de la pièce jointe" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "" +"It is not possible to add more attachments. Please make sure your tweet " +"complies with Twitter'S attachment rules. You can add only one video or GIF " +"in every tweet, and a maximum of 4 photos." +msgstr "" +"Il est impossible de joindre plus de contenu. Assurez-vous que votre tweet " +"respecte les règles d'attachement de Twitter. Vous pouvez seulement inclure " +"une vidéo ou un GIF par tweet, et 4 photos au maximum." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:182 +msgid "&Mention to all" +msgstr "&Répondre à tout le monde" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 +msgid "&Recipient" +msgstr "&Destinataire" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:307 +msgid "Tweet - %i characters " +msgstr "Tweet - %i caractères " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:324 +msgid "Image description" +msgstr "Description de l'image" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:335 +msgid "Retweets: " +msgstr "Retweets: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:340 +msgid "Likes: " +msgstr "Favoris: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:345 +msgid "Source: " +msgstr "Source: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:350 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:428 +msgid "Date: " +msgstr "Date: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 +msgid "Copy link to clipboard" +msgstr "Copier le lien dans le Presse-papiers" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:368 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:443 +msgid "&Translate..." +msgstr "&Traduire..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:369 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:444 +msgid "C&lose" +msgstr "F&ermer" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:413 +msgid "View" +msgstr "Voir" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:415 +msgid "Item" +msgstr "Élément" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 +msgid "&Expand URL" +msgstr "&Élargir URL" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:480 +msgid "Add a poll" +msgstr "Ajouter un sondage" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:484 +msgid "Participation time (in days)" +msgstr "Temps de participation (en jours)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:491 +msgid "Choices" +msgstr "Choix" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:495 +msgid "Option 1" +msgstr "Option 1" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:501 +msgid "Option 2" +msgstr "Option 2" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:507 +msgid "Option 3" +msgstr "Option 3" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:513 +msgid "Option 4" +msgstr "Option 4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Not enough information" +msgstr "Pas assez d'informations" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Please make sure you have provided at least two options for the poll." +msgstr "Assurez-vous d'avoir spécifier au moins 2 options pour le sondage." + #: ../src\wxUI\dialogs\update_profile.py:10 msgid "Update your profile" msgstr "Actualiser votre profil" From 0e91ca3d4d4007cc4d6a9875117fcda451160c22 Mon Sep 17 00:00:00 2001 From: Nikola Jovic Date: Thu, 11 Nov 2021 01:30:30 +0100 Subject: [PATCH 34/83] Updated Serbian translation --- src/locales/sr/LC_MESSAGES/twblue.mo | Bin 54001 -> 55001 bytes src/locales/sr/LC_MESSAGES/twblue.po | 631 ++++++++++++++++----------- 2 files changed, 371 insertions(+), 260 deletions(-) diff --git a/src/locales/sr/LC_MESSAGES/twblue.mo b/src/locales/sr/LC_MESSAGES/twblue.mo index 7701f9b14bede7ec7876a98982ea0b1f7f0d5221..4406f6caba50b773402c2458aa993947e8c8a32d 100644 GIT binary patch delta 18395 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 ZBwAVjX)*KI125N_6P-O>wNB6T{U3KBnK=Le diff --git a/src/locales/sr/LC_MESSAGES/twblue.po b/src/locales/sr/LC_MESSAGES/twblue.po index af9ba210..79d3e91d 100644 --- a/src/locales/sr/LC_MESSAGES/twblue.po +++ b/src/locales/sr/LC_MESSAGES/twblue.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: TwBlue 0.80\n" -"POT-Creation-Date: 2021-10-28 16:43+Central Europe Daylight Time\n" -"PO-Revision-Date: 2021-10-28 17:03+0100\n" +"POT-Creation-Date: 2021-11-11 01:16+0100\n" +"PO-Revision-Date: 2021-11-11 01:30+0100\n" "Last-Translator: Nikola Jović \n" "Language-Team: Aleksandar Đurić \n" "Language: sr_RS@latin\n" @@ -18,10 +18,6 @@ msgstr "" "X-Poedit-Bookmarks: -1,442,-1,-1,-1,-1,-1,-1,-1,-1\n" "X-Poedit-SourceCharset: UTF-8\n" -#: ../src\controller\attach.py:25 -msgid "Photo" -msgstr "Slika" - #: ../src\controller\buffers\base\base.py:91 msgid "This action is not supported for this buffer" msgstr "Ova radnja nije podržana na ovom kanalu" @@ -100,101 +96,104 @@ msgstr "Prijatelji korisnika {username}" msgid "Unknown buffer" msgstr "Nepoznat kanal" -#: ../src\controller\buffers\twitter\base.py:88 -#: ../src\controller\buffers\twitter\trends.py:121 -#: ../src\controller\messages.py:214 ../src\wxUI\buffers\base.py:25 +#: ../src\controller\buffers\twitter\base.py:87 +#: ../src\controller\buffers\twitter\trends.py:43 +#: ../src\controller\buffers\twitter\trends.py:134 +#: ../src\controller\messages.py:296 ../src\wxUI\buffers\base.py:25 #: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:35 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:312 +#: ../src\wxUI\sysTrayIcon.py:35 msgid "Tweet" msgstr "Tvit" -#: ../src\controller\buffers\twitter\base.py:89 -#: ../src\controller\buffers\twitter\trends.py:122 +#: ../src\controller\buffers\twitter\base.py:88 +#: ../src\controller\buffers\twitter\trends.py:44 +#: ../src\controller\buffers\twitter\trends.py:135 msgid "Write the tweet here" msgstr "Otkucajte tvit ovde:" -#: ../src\controller\buffers\twitter\base.py:219 +#: ../src\controller\buffers\twitter\base.py:192 msgid "New tweet in {0}" msgstr "Novi tvit u kanalu {0}" -#: ../src\controller\buffers\twitter\base.py:222 +#: ../src\controller\buffers\twitter\base.py:195 msgid "{0} new tweets in {1}." msgstr "{0} novih tvitova u kanalu {1}." -#: ../src\controller\buffers\twitter\base.py:261 -#: ../src\controller\buffers\twitter\directMessages.py:87 -#: ../src\controller\buffers\twitter\people.py:180 +#: ../src\controller\buffers\twitter\base.py:234 +#: ../src\controller\buffers\twitter\directMessages.py:88 +#: ../src\controller\buffers\twitter\people.py:174 msgid "%s items retrieved" msgstr "%s primljenih stavki" -#: ../src\controller\buffers\twitter\base.py:293 +#: ../src\controller\buffers\twitter\base.py:266 #: ../src\controller\buffers\twitter\people.py:80 msgid "This buffer is not a timeline; it can't be deleted." msgstr "Ovaj kanal nije vremenska linija i ne može biti izbrisan." -#: ../src\controller\buffers\twitter\base.py:430 +#: ../src\controller\buffers\twitter\base.py:402 msgid "Reply to {arg0}" msgstr "Odgovori {arg0}" -#: ../src\controller\buffers\twitter\base.py:432 +#: ../src\controller\buffers\twitter\base.py:404 #: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "Odgovori" -#: ../src\controller\buffers\twitter\base.py:433 +#: ../src\controller\buffers\twitter\base.py:405 msgid "Reply to %s" msgstr "Odgovori %s" -#: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\buffers\twitter\directMessages.py:129 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "Nova direktna poruka" -#: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\messages.py:200 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\messages.py:268 msgid "Direct message to %s" msgstr "Direktna poruka za %s" -#: ../src\controller\buffers\twitter\base.py:520 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Add your comment to the tweet" msgstr "Dodajte vaš komentar u tvit" -#: ../src\controller\buffers\twitter\base.py:520 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Quote" msgstr "Citiraj" -#: ../src\controller\buffers\twitter\base.py:596 +#: ../src\controller\buffers\twitter\base.py:520 msgid "Opening URL..." msgstr "Otvaram vezu..." -#: ../src\controller\buffers\twitter\base.py:633 +#: ../src\controller\buffers\twitter\base.py:557 msgid "User details" msgstr "Podaci o korisniku" -#: ../src\controller\buffers\twitter\base.py:654 +#: ../src\controller\buffers\twitter\base.py:578 msgid "Opening item in web browser..." msgstr "Otvaram stavku u Web pretraživaču..." -#: ../src\controller\buffers\twitter\directMessages.py:92 +#: ../src\controller\buffers\twitter\directMessages.py:93 #: ../src\controller\buffers\twitter\people.py:95 msgid "Mention to %s" msgstr "Spomeni %s" -#: ../src\controller\buffers\twitter\directMessages.py:92 +#: ../src\controller\buffers\twitter\directMessages.py:93 #: ../src\controller\buffers\twitter\people.py:95 #: ../src\wxUI\buffers\people.py:17 msgid "Mention" msgstr "Spomeni" -#: ../src\controller\buffers\twitter\directMessages.py:132 +#: ../src\controller\buffers\twitter\directMessages.py:127 msgid "{0} new direct messages." msgstr "{0} novih direktnih poruka." -#: ../src\controller\buffers\twitter\directMessages.py:135 +#: ../src\controller\buffers\twitter\directMessages.py:130 msgid "This action is not supported in the buffer yet." msgstr "Ova radnja još uvek nije podržana na ovom kanalu." -#: ../src\controller\buffers\twitter\directMessages.py:145 +#: ../src\controller\buffers\twitter\directMessages.py:140 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." @@ -202,11 +201,11 @@ msgstr "" "Nemoguće preuzeti dodatne stavke za ovaj kanal. Umesto toga, koristite kanal " "direktne poruke." -#: ../src\controller\buffers\twitter\people.py:253 +#: ../src\controller\buffers\twitter\people.py:247 msgid "{0} new followers." msgstr "{0} novih pratilaca." -#: ../src\controller\buffers\twitter\trends.py:145 +#: ../src\controller\buffers\twitter\trends.py:150 msgid "This action is not supported in the buffer, yet." msgstr "Ova radnja još uvek nije podržana na ovom kanalu" @@ -224,7 +223,7 @@ msgstr "Vremenske linije" #: ../src\controller\mainController.py:359 #: ../src\controller\mainController.py:883 -#: ../src\controller\mainController.py:1585 +#: ../src\controller\mainController.py:1582 msgid "Timeline for {}" msgstr "Vremenska linija od {}" @@ -234,7 +233,7 @@ msgstr "Vremenska linija omiljenih tvitova" #: ../src\controller\mainController.py:363 #: ../src\controller\mainController.py:902 -#: ../src\controller\mainController.py:1587 +#: ../src\controller\mainController.py:1584 msgid "Likes for {}" msgstr "Sviđanja od {}" @@ -244,7 +243,7 @@ msgstr "Vremenske linije pratilaca" #: ../src\controller\mainController.py:367 #: ../src\controller\mainController.py:921 -#: ../src\controller\mainController.py:1589 +#: ../src\controller\mainController.py:1586 msgid "Followers for {}" msgstr "Pratioci od {}" @@ -254,7 +253,7 @@ msgstr "Vremenske linije praćenih korisnika" #: ../src\controller\mainController.py:371 #: ../src\controller\mainController.py:940 -#: ../src\controller\mainController.py:1591 +#: ../src\controller\mainController.py:1588 msgid "Friends for {}" msgstr "Prijatelji od {}" @@ -279,6 +278,7 @@ msgstr "Pretraga za {}" #: ../src\controller\mainController.py:381 #: ../src\controller\mainController.py:982 +#: ../src\controller\mainController.py:1590 msgid "Trending topics for %s" msgstr "Teme u trendu za %s" @@ -321,7 +321,7 @@ msgstr "Dodaj nadimak za korisnika" msgid "Alias has been set correctly for {}." msgstr "Nadimak za {} je uspešno podešen." -#: ../src\controller\mainController.py:829 ../src\controller\messages.py:245 +#: ../src\controller\mainController.py:829 ../src\controller\messages.py:327 msgid "MMM D, YYYY. H:m" msgstr "MMM D, YYYY. H:m" @@ -410,72 +410,52 @@ msgstr "Utišavanje kanala uključeno" msgid "Buffer mute off" msgstr "Utišavanje kanala isključeno" -#: ../src\controller\mainController.py:1545 +#: ../src\controller\mainController.py:1542 msgid "Copied" msgstr "Kopirano" -#: ../src\controller\mainController.py:1575 +#: ../src\controller\mainController.py:1572 msgid "Unable to update this buffer." msgstr "Ne mogu da ažuriram ovaj kanal." -#: ../src\controller\mainController.py:1578 +#: ../src\controller\mainController.py:1575 msgid "Updating buffer..." msgstr "Ažuriram kanal..." -#: ../src\controller\mainController.py:1581 +#: ../src\controller\mainController.py:1578 msgid "{0} items retrieved" msgstr "{0} primljenih stavki" -#: ../src\controller\mainController.py:1598 -#: ../src\controller\mainController.py:1618 +#: ../src\controller\mainController.py:1597 +#: ../src\controller\mainController.py:1617 msgid "Invalid buffer" msgstr "Nevažeći kanal" -#: ../src\controller\mainController.py:1609 +#: ../src\controller\mainController.py:1608 msgid "Picture {0}" msgstr "Slika {0}" -#: ../src\controller\mainController.py:1610 +#: ../src\controller\mainController.py:1609 msgid "Select the picture" msgstr "Izaberite sliku" -#: ../src\controller\mainController.py:1629 +#: ../src\controller\mainController.py:1628 msgid "Unable to extract text" msgstr "Ne mogu da izdvojim tekst." -#: ../src\controller\messages.py:56 +#: ../src\controller\messages.py:49 msgid "Translated" msgstr "Prevedeno" -#: ../src\controller\messages.py:63 -msgid "There's no URL to be shortened" -msgstr "Nema veze koja bi mogla biti skraćena" - -#: ../src\controller\messages.py:67 ../src\controller\messages.py:75 -msgid "URL shortened" -msgstr "Veza je skraćena" - -#: ../src\controller\messages.py:82 -msgid "There's no URL to be expanded" -msgstr "Nema veze koja bi mogla biti proširena" - -#: ../src\controller\messages.py:86 ../src\controller\messages.py:94 -msgid "URL expanded" -msgstr "Veza je proširena" - -#: ../src\controller\messages.py:108 +#: ../src\controller\messages.py:56 msgid "%s - %s of %d characters" msgstr "%s - %s od %d znakova" -#: ../src\controller\messages.py:112 -msgid "%s - %s characters" -msgstr "%s - %s znakova" - -#: ../src\controller\messages.py:272 +#: ../src\controller\messages.py:354 msgid "View item" msgstr "Prikaži stavku" -#: ../src\controller\messages.py:301 +#: ../src\controller\messages.py:379 msgid "Link copied to clipboard." msgstr "Link kopiran u privremenu memoriju." @@ -667,7 +647,7 @@ msgstr "Zaustavljeno" msgid "&Record" msgstr "&Snimi" -#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:148 +#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:147 msgid "Playing..." msgstr "Reprodukujem..." @@ -719,6 +699,9 @@ msgid "%s seconds" msgstr "%s sekundi" #: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:258 msgid "File" msgstr "Datoteka" @@ -1486,7 +1469,7 @@ msgstr "" msgid "Send report" msgstr "Pošalji izveštaj" -#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:84 +#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:83 #: ../src\wxUI\dialogs\find.py:23 msgid "Cancel" msgstr "Otkaži" @@ -1560,7 +1543,7 @@ msgid "New tweet" msgstr "Novi tvit" #: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:26 -#: ../src\wxUI\commonMessageDialogs.py:10 ../src\wxUI\dialogs\message.py:126 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Retweet" msgstr "Retvituj" @@ -1773,7 +1756,7 @@ msgstr "Prečica" msgid "Action" msgstr "Radnja" -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:131 +#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:135 #: ../src\wxUI\dialogs\lists.py:20 ../src\wxUI\dialogs\userAliasDialogs.py:53 msgid "Edit" msgstr "Izmeni" @@ -1823,7 +1806,7 @@ msgstr "Windows" msgid "Key" msgstr "Taster" -#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:82 +#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:80 #: ../src\wxUI\dialogs\find.py:21 ../src\wxUI\dialogs\userAliasDialogs.py:23 #: ../src\wxUI\dialogs\utils.py:36 msgid "OK" @@ -1999,16 +1982,18 @@ msgstr "Privatno" msgid "public" msgstr "Javno" -#: ../src\sessions\twitter\session.py:209 +#: ../src\sessions\twitter\session.py:211 +#: ../src\sessions\twitter\session.py:238 msgid "%s failed. Reason: %s" msgstr "%s nije uspelo. Razlog: %s" -#: ../src\sessions\twitter\session.py:215 +#: ../src\sessions\twitter\session.py:217 +#: ../src\sessions\twitter\session.py:241 msgid "%s succeeded." msgstr "%s uspelo." -#: ../src\sessions\twitter\session.py:424 -#: ../src\sessions\twitter\session.py:502 +#: ../src\sessions\twitter\session.py:450 +#: ../src\sessions\twitter\session.py:528 msgid "Deleted account" msgstr "Obrisan nalog" @@ -2036,7 +2021,7 @@ msgstr "Autorizacija naloga..." msgid "Enter your PIN code here" msgstr "Ovde upišite vaš PIN kod" -#: ../src\sound.py:161 +#: ../src\sound.py:160 msgid "Stopped." msgstr "Zaustavljeno" @@ -2088,10 +2073,6 @@ msgstr "" msgid "Client" msgstr "Klijent" -#: ../src\wxUI\buffers\base.py:12 -msgid "Text" -msgstr "Tekst" - #: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\events.py:14 msgid "Date" msgstr "Datum" @@ -2103,6 +2084,11 @@ msgstr "Datum" msgid "User" msgstr "Korisnik" +#: ../src\wxUI\buffers\base.py:12 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +msgid "Text" +msgstr "Tekst" + #: ../src\wxUI\buffers\base.py:28 msgid "Direct message" msgstr "Direktna poruka" @@ -2359,55 +2345,6 @@ msgstr "" "{0} je neočekivano zatvoren pri poslednjem pokretanju. Ako se problem " "nastavi, molimo prijavite ga{0} programerima." -#: ../src\wxUI\dialogs\attach.py:10 -msgid "Add an attachment" -msgstr "Dodaj prilog" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Attachments" -msgstr "Prilozi" - -#: ../src\wxUI\dialogs\attach.py:14 -msgid "Title" -msgstr "Naslov" - -#: ../src\wxUI\dialogs\attach.py:14 -msgid "Type" -msgstr "Vrsta" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "Add attachments" -msgstr "Dodaj priloge" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "&Photo" -msgstr "Slika" - -#: ../src\wxUI\dialogs\attach.py:21 -msgid "Remove attachment" -msgstr "Ukloni prilog" - -#: ../src\wxUI\dialogs\attach.py:37 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:82 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Datoteke sa slikama" - -#: ../src\wxUI\dialogs\attach.py:37 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:82 -msgid "Select the picture to be uploaded" -msgstr "Izaberite sliku koju želite da otpremite" - -#: ../src\wxUI\dialogs\attach.py:44 -msgid "please provide a description" -msgstr "Molimo vas navedite opis:" - -#: ../src\wxUI\dialogs\attach.py:44 ../src\wxUI\dialogs\lists.py:14 -#: ../src\wxUI\dialogs\lists.py:70 -msgid "Description" -msgstr "Opis" - #: ../src\wxUI\dialogs\configuration.py:15 msgid "Language" msgstr "Jezik" @@ -2544,7 +2481,7 @@ msgid "Status" msgstr "Status" #: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Buffer" msgstr "Kanal" @@ -2669,91 +2606,99 @@ msgstr "Dodaci" msgid "Save" msgstr "Sačuvaj" -#: ../src\wxUI\dialogs\filterDialogs.py:16 +#: ../src\wxUI\dialogs\filterDialogs.py:13 msgid "Create a filter for this buffer" msgstr "Napravi filter za ovaj kanal" -#: ../src\wxUI\dialogs\filterDialogs.py:17 +#: ../src\wxUI\dialogs\filterDialogs.py:14 msgid "Filter title" msgstr "Naziv filtera" -#: ../src\wxUI\dialogs\filterDialogs.py:26 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:24 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by word" msgstr "Filtriraj na osnovu reči" -#: ../src\wxUI\dialogs\filterDialogs.py:27 +#: ../src\wxUI\dialogs\filterDialogs.py:25 msgid "Ignore tweets wich contain the following word" msgstr "Zanemari tvitove koji sadrže sledeću reč" -#: ../src\wxUI\dialogs\filterDialogs.py:28 +#: ../src\wxUI\dialogs\filterDialogs.py:26 msgid "Ignore tweets without the following word" msgstr "Zanemari tvitove bez sledeće reči" -#: ../src\wxUI\dialogs\filterDialogs.py:33 +#: ../src\wxUI\dialogs\filterDialogs.py:31 msgid "word" msgstr "Reč" -#: ../src\wxUI\dialogs\filterDialogs.py:38 +#: ../src\wxUI\dialogs\filterDialogs.py:36 msgid "Allow retweets" msgstr "Dozvoli retvitove" -#: ../src\wxUI\dialogs\filterDialogs.py:39 +#: ../src\wxUI\dialogs\filterDialogs.py:37 msgid "Allow quoted tweets" msgstr "Dozvoli citirane tvitove" -#: ../src\wxUI\dialogs\filterDialogs.py:40 +#: ../src\wxUI\dialogs\filterDialogs.py:38 msgid "Allow replies" msgstr "Dozvoli odgovore" -#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:46 msgid "Use this term as a regular expression" msgstr "Koristi ovaj termin kao regulara nizraz" -#: ../src\wxUI\dialogs\filterDialogs.py:50 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter by language" msgstr "Filtriraj na osnovu jezika" -#: ../src\wxUI\dialogs\filterDialogs.py:51 +#: ../src\wxUI\dialogs\filterDialogs.py:49 msgid "Load tweets in the following languages" msgstr "Učitaj tvitove na sledećim jezicima" -#: ../src\wxUI\dialogs\filterDialogs.py:52 +#: ../src\wxUI\dialogs\filterDialogs.py:50 msgid "Ignore tweets in the following languages" msgstr "Zanemari tvitove na sledećim jezicima" -#: ../src\wxUI\dialogs\filterDialogs.py:53 +#: ../src\wxUI\dialogs\filterDialogs.py:51 msgid "Don't filter by language" msgstr "Ne filtriraj na osnovu jezika" -#: ../src\wxUI\dialogs\filterDialogs.py:64 +#: ../src\wxUI\dialogs\filterDialogs.py:62 msgid "Supported languages" msgstr "Podržani jezici" -#: ../src\wxUI\dialogs\filterDialogs.py:69 +#: ../src\wxUI\dialogs\filterDialogs.py:67 msgid "Add selected language to filter" msgstr "Dodaj izabrani jezik u filter" -#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:71 msgid "Selected languages" msgstr "Izabrani jezici" -#: ../src\wxUI\dialogs\filterDialogs.py:75 -#: ../src\wxUI\dialogs\filterDialogs.py:133 ../src\wxUI\dialogs\lists.py:21 +#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: ../src\wxUI\dialogs\filterDialogs.py:137 ../src\wxUI\dialogs\lists.py:21 #: ../src\wxUI\dialogs\lists.py:132 ../src\wxUI\dialogs\userAliasDialogs.py:57 msgid "Remove" msgstr "Ukloni" -#: ../src\wxUI\dialogs\filterDialogs.py:123 +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "Missing filter name" +msgstr "Ime filtera nedostaje" + +#: ../src\wxUI\dialogs\filterDialogs.py:120 +msgid "You must define a name for the filter before creating it." +msgstr "Morate upisati ime za filter pre nego što ga napravite." + +#: ../src\wxUI\dialogs\filterDialogs.py:127 msgid "Manage filters" msgstr "Upravljanje filterima" -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: ../src\wxUI\dialogs\filterDialogs.py:129 msgid "Filters" msgstr "Filteri" -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: ../src\wxUI\dialogs\filterDialogs.py:130 msgid "Filter" msgstr "Filter" @@ -2785,6 +2730,14 @@ msgstr "Vlasnik" msgid "mode" msgstr "Način" +#: ../src\wxUI\dialogs\lists.py:14 ../src\wxUI\dialogs\lists.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:38 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:260 +msgid "Description" +msgstr "Opis" + #: ../src\wxUI\dialogs\lists.py:19 ../src\wxUI\dialogs\lists.py:62 msgid "Create a new list" msgstr "Stvori novu listu" @@ -2841,103 +2794,6 @@ msgstr "Izaberite listu sa koje želite da uklonite korisnika" msgid "Do you really want to delete this list?" msgstr "Želite li zaista da izbrišete ovu listu?" -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "Dug tvit" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "Otpremi sliku..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:359 ../src\wxUI\dialogs\message.py:435 -msgid "Check &spelling..." -msgstr "Proveri pravopis..." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "Priloži zvučni zapis..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "Skrati vezu" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:436 -msgid "&Expand URL" -msgstr "Proširi vezu" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:362 ../src\wxUI\dialogs\message.py:438 -msgid "&Translate..." -msgstr "Prevedi..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "&Automatsko dovršavanje" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "Pošalji" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:363 ../src\wxUI\dialogs\message.py:439 -msgid "C&lose" -msgstr "Zatvori" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "Primalac" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "Spomeni sve" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tvit - %i znakova" - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Opis slike" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Retvitova" - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Sviđanja:" - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Izvor:" - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:423 -msgid "Date: " -msgstr "Datum:" - -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:433 -msgid "Copy link to clipboard" -msgstr "Kopiraj link u privremenu memoriju" - -#: ../src\wxUI\dialogs\message.py:408 -msgid "View" -msgstr "Vidi" - -#: ../src\wxUI\dialogs\message.py:410 -msgid "Item" -msgstr "Stavka" - #: ../src\wxUI\dialogs\search.py:12 msgid "Search on Twitter" msgstr "Pretraži ttwitter" @@ -3019,6 +2875,225 @@ msgstr "Gradu" msgid "&Location" msgstr "Mesto" +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:33 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:49 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:170 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 +msgid "Attachments" +msgstr "Prilozi" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:174 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 +msgid "Type" +msgstr "Vrsta" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:40 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:177 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:262 +msgid "Delete attachment" +msgstr "Ukloni prilog" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:45 +msgid "Added Tweets" +msgstr "Dodati tvitovi" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:52 +msgid "Delete tweet" +msgstr "Obriši tvit" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:57 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:267 +msgid "A&dd..." +msgstr "&Dodaj..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:59 +msgid "Add t&weet" +msgstr "Dodaj t&vit" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:62 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:194 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:269 +msgid "&Attach audio..." +msgstr "Priloži zvučni zapis..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:66 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:237 +msgid "Auto&complete users" +msgstr "&Automatsko dovršavanje" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:68 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:273 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:367 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 +msgid "Check &spelling..." +msgstr "Proveri pravopis..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:202 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:275 +msgid "&Translate" +msgstr "&Prevedi" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:74 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:206 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:279 +msgid "Sen&d" +msgstr "Pošalji" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:118 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:299 +msgid "Image" +msgstr "Slika" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:120 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:222 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:301 +msgid "Video" +msgstr "Video" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:122 +msgid "Poll" +msgstr "Anketa" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +msgid "please provide a description" +msgstr "Molimo vas navedite opis:" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +msgstr "Datoteke sa slikama" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Select the picture to be uploaded" +msgstr "Izaberite sliku koju želite da otpremite" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Select the video to be uploaded" +msgstr "Izaberite video zapis koji želite da otpremite" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Video files (*.mp4)|*.mp4" +msgstr "Datoteke video zapisa (*.mp4)|*.mp4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "Error adding attachment" +msgstr "Greška pri dodavanju priloga" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "" +"It is not possible to add more attachments. Please make sure your tweet " +"complies with Twitter'S attachment rules. You can add only one video or GIF " +"in every tweet, and a maximum of 4 photos." +msgstr "" +"Nije moguće dodati više priloga. Molimo uverite se da vaš tvit poštuje " +"Twitter pravila o prilozima. Možete dodati samo jedan video ili GIF u svaki " +"tvit, i najviše 4 slike." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:182 +msgid "&Mention to all" +msgstr "Spomeni sve" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 +msgid "&Recipient" +msgstr "Primalac" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:307 +msgid "Tweet - %i characters " +msgstr "Tvit - %i znakova" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:324 +msgid "Image description" +msgstr "Opis slike" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:335 +msgid "Retweets: " +msgstr "Retvitova" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:340 +msgid "Likes: " +msgstr "Sviđanja:" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:345 +msgid "Source: " +msgstr "Izvor:" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:350 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:428 +msgid "Date: " +msgstr "Datum:" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 +msgid "Copy link to clipboard" +msgstr "Kopiraj link u privremenu memoriju" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:368 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:443 +msgid "&Translate..." +msgstr "Prevedi..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:369 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:444 +msgid "C&lose" +msgstr "Zatvori" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:413 +msgid "View" +msgstr "Vidi" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:415 +msgid "Item" +msgstr "Stavka" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 +msgid "&Expand URL" +msgstr "Proširi vezu" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:480 +msgid "Add a poll" +msgstr "Dodaj anketu" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:484 +msgid "Participation time (in days)" +msgstr "Vreme učešća (u danima)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:491 +msgid "Choices" +msgstr "Opcije" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:495 +msgid "Option 1" +msgstr "Opcija 1" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:501 +msgid "Option 2" +msgstr "Opcija 2" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:507 +msgid "Option 3" +msgstr "Opcija 3" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:513 +msgid "Option 4" +msgstr "Opcija 4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Not enough information" +msgstr "Nema dovoljno informacija" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Please make sure you have provided at least two options for the poll." +msgstr "Molimo uverite se da ste ponudili bar dve opcije u anketi." + #: ../src\wxUI\dialogs\update_profile.py:10 msgid "Update your profile" msgstr "Ažurirajte vaš profil" @@ -3435,6 +3510,42 @@ msgstr "Ažuriraj" msgid "Your {0} version is up to date" msgstr "Imate najnoviju verziju {0}." +#~ msgid "Photo" +#~ msgstr "Slika" + +#~ msgid "There's no URL to be shortened" +#~ msgstr "Nema veze koja bi mogla biti skraćena" + +#~ msgid "URL shortened" +#~ msgstr "Veza je skraćena" + +#~ msgid "There's no URL to be expanded" +#~ msgstr "Nema veze koja bi mogla biti proširena" + +#~ msgid "URL expanded" +#~ msgstr "Veza je proširena" + +#~ msgid "%s - %s characters" +#~ msgstr "%s - %s znakova" + +#~ msgid "Title" +#~ msgstr "Naslov" + +#~ msgid "Add attachments" +#~ msgstr "Dodaj priloge" + +#~ msgid "&Photo" +#~ msgstr "Slika" + +#~ msgid "&Long tweet" +#~ msgstr "Dug tvit" + +#~ msgid "&Upload image..." +#~ msgstr "Otpremi sliku..." + +#~ msgid "Sh&orten URL" +#~ msgstr "Skrati vezu" + #~ msgid "Friends' Timelines" #~ msgstr "Vremenska linija prijatelja" From 622b0e6128228de20d0b7ec913bed795809d4e8e Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Thu, 11 Nov 2021 08:36:29 -0600 Subject: [PATCH 35/83] Access correctly on_reply_to_tweet_id from the dict response returned by call to V2 API --- src/sessions/twitter/session.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index 38f4baae..1b985c9c 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -622,8 +622,7 @@ class Session(base.baseSession): for obj in tweets: if len(obj["attachments"]) == 0: item = self.api_call_v2(call_name="create_tweet", text=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"]) - print(item) - in_reply_to_status_id = item.data.id + in_reply_to_status_id = item.data["id"] else: media_ids = [] for i in obj["attachments"]: @@ -632,7 +631,7 @@ class Session(base.baseSession): self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) item = self.api_call_v2(call_name="create_tweet", status=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"]) - in_reply_to_status_id = item.data.id + in_reply_to_status_id = item.data["id"] def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs): if len(attachments) == 0: From 538d6137d044e3f0f2eb0e61acc241b479d6cf2e Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Thu, 11 Nov 2021 08:37:07 -0600 Subject: [PATCH 36/83] Limit Poll options to 25 characters each --- src/wxUI/dialogs/twitterDialogs/tweetDialogs.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py index e42bd9f4..8db397ec 100644 --- a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -495,24 +495,28 @@ class poll(wx.Dialog): label_2 = wx.StaticText(self, wx.ID_ANY, _("Option 1")) option1_sizer.Add(label_2, 0, 0, 0) self.option1 = wx.TextCtrl(self, wx.ID_ANY, "") + self.option1.SetMaxLength(25) option1_sizer.Add(self.option1, 0, 0, 0) option2_sizer = wx.BoxSizer(wx.HORIZONTAL) sizer_2.Add(option2_sizer, 1, wx.EXPAND, 0) label_3 = wx.StaticText(self, wx.ID_ANY, _("Option 2")) option2_sizer.Add(label_3, 0, 0, 0) self.option2 = wx.TextCtrl(self, wx.ID_ANY, "") + self.option2.SetMaxLength(25) option2_sizer.Add(self.option2, 0, 0, 0) option3_sizer = wx.BoxSizer(wx.HORIZONTAL) sizer_2.Add(option3_sizer, 1, wx.EXPAND, 0) label_4 = wx.StaticText(self, wx.ID_ANY, _("Option 3")) option3_sizer.Add(label_4, 0, 0, 0) self.option3 = wx.TextCtrl(self, wx.ID_ANY, "") + self.option3.SetMaxLength(25) option3_sizer.Add(self.option3, 0, 0, 0) option4_sizer = wx.BoxSizer(wx.HORIZONTAL) sizer_2.Add(option4_sizer, 1, wx.EXPAND, 0) label_5 = wx.StaticText(self, wx.ID_ANY, _("Option 4")) option4_sizer.Add(label_5, 0, 0, 0) self.option4 = wx.TextCtrl(self, wx.ID_ANY, "") + self.option4.SetMaxLength(25) option4_sizer.Add(self.option4, 0, 0, 0) btn_sizer = wx.StdDialogButtonSizer() sizer_1.Add(btn_sizer, 0, wx.ALIGN_RIGHT | wx.ALL, 4) From b329ac8e3e6a59076da3fa690b416b82fae85ec0 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Thu, 11 Nov 2021 12:33:38 -0600 Subject: [PATCH 37/83] Improved a little bit text dialogs's size for sending tweets, replies and dm's --- src/wxUI/dialogs/twitterDialogs/tweetDialogs.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py index 8db397ec..b917a25b 100644 --- a/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/tweetDialogs.py @@ -18,13 +18,12 @@ class tweet(wx.Dialog): def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: panel = wx.Panel(self) mainBox = wx.BoxSizer(wx.VERTICAL) - text_sizer = wx.BoxSizer(wx.VERTICAL) + text_sizer = wx.BoxSizer(wx.HORIZONTAL) mainBox.Add(text_sizer, 1, wx.EXPAND, 0) label_1 = wx.StaticText(panel, wx.ID_ANY, caption) text_sizer.Add(label_1, 0, 0, 0) - self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", size=(444, -1), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) - self.text.SetMinSize((1000, 158)) text_sizer.Add(self.text, 1, wx.EXPAND, 0) list_sizer = wx.BoxSizer(wx.HORIZONTAL) mainBox.Add(list_sizer, 1, wx.EXPAND, 0) @@ -155,13 +154,12 @@ class reply(tweet): def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: panel = wx.Panel(self) mainBox = wx.BoxSizer(wx.VERTICAL) - text_sizer = wx.BoxSizer(wx.VERTICAL) + text_sizer = wx.BoxSizer(wx.HORIZONTAL) mainBox.Add(text_sizer, 1, wx.EXPAND, 0) label_1 = wx.StaticText(panel, wx.ID_ANY, caption) text_sizer.Add(label_1, 0, 0, 0) - self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", size=(500, 200), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) - self.text.SetMinSize((1000, 158)) text_sizer.Add(self.text, 1, wx.EXPAND, 0) list_sizer = wx.BoxSizer(wx.HORIZONTAL) mainBox.Add(list_sizer, 1, wx.EXPAND, 0) @@ -232,20 +230,19 @@ class dm(tweet): def create_controls(self, message: str, caption: str, max_length: int, thread_mode: bool) -> None: panel = wx.Panel(self) mainBox = wx.BoxSizer(wx.VERTICAL) - label_recipient = wx.StaticText(panel, -1, _(u"&Recipient")) + label_recipient = wx.StaticText(panel, -1, _("&Recipient")) self.cb = wx.ComboBox(panel, -1, choices=self.users, value=self.users[0], size=wx.DefaultSize) self.autocomplete_users = wx.Button(panel, -1, _(u"Auto&complete users")) recipient_sizer = wx.BoxSizer(wx.HORIZONTAL) recipient_sizer.Add(label_recipient, 0, 0, 0) recipient_sizer.Add(self.cb, 1, wx.EXPAND, 0) mainBox.Add(recipient_sizer, 0, wx.EXPAND, 0) - text_sizer = wx.BoxSizer(wx.VERTICAL) + text_sizer = wx.BoxSizer(wx.HORIZONTAL) mainBox.Add(text_sizer, 1, wx.EXPAND, 0) label_1 = wx.StaticText(panel, wx.ID_ANY, caption) text_sizer.Add(label_1, 0, 0, 0) - self.text = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) + self.text = wx.TextCtrl(panel, wx.ID_ANY, "", size=(500, 200), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_CHAR_HOOK, self.handle_keys, self.text) - self.text.SetMinSize((1000, 158)) self.text.SetFocus() text_sizer.Add(self.text, 1, wx.EXPAND, 0) list_sizer = wx.BoxSizer(wx.HORIZONTAL) From d6571a95cb35563a4b88fcc57a8f4aa3b58ab071 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Thu, 11 Nov 2021 15:13:58 -0600 Subject: [PATCH 38/83] Quote tweets properly according to Twitter's API V2 docs --- src/controller/buffers/twitter/base.py | 4 ++-- src/sessions/twitter/session.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 1d81a604..3ad5b77c 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -459,11 +459,11 @@ class BaseBuffer(base.Buffer): retweet = messages.tweet(session=self.session, title=_("Quote"), caption=_("Add your comment to the tweet"), max=256, thread_mode=False) if retweet.message.ShowModal() == widgetUtils.OK: text = retweet.message.text.GetValue() - text = text+" https://twitter.com/{0}/status/{1}".format(self.session.get_user(tweet.user).screen_name, id) tweet_data = dict(text=text, attachments=retweet.attachments, poll_period=retweet.poll_period, poll_options=retweet.poll_options) + tweet_data.update(quote_tweet_id=id) call_threaded(self.session.send_tweet, *[tweet_data]) if hasattr(retweet.message, "destroy"): - retweet.message.destroy() + retweet.message.Destroy() def _direct_retweet(self, id): item = self.session.api_call(call_name="retweet", _sound="retweet_send.ogg", id=id) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index 1b985c9c..a311ab42 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -620,8 +620,9 @@ class Session(base.baseSession): """ Convenience function to send a thread. """ in_reply_to_status_id = None for obj in tweets: + # When quoting a tweet, the tweet_data dict might contain a parameter called quote_tweet_id. Let's add it, or None, so quotes will be posted successfully. if len(obj["attachments"]) == 0: - item = self.api_call_v2(call_name="create_tweet", text=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"]) + item = self.api_call_v2(call_name="create_tweet", text=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"], quote_tweet_id=obj.get("quote_tweet_id")) in_reply_to_status_id = item.data["id"] else: media_ids = [] @@ -630,7 +631,7 @@ class Session(base.baseSession): if i["type"] == "photo": self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) - item = self.api_call_v2(call_name="create_tweet", status=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"]) + item = self.api_call_v2(call_name="create_tweet", status=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"], quote_tweet_id=obj.get("quote_tweet_id")) in_reply_to_status_id = item.data["id"] def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs): From f7a50d22e2f8ef3722baffdb730d37a63ee72230 Mon Sep 17 00:00:00 2001 From: riku Date: Fri, 12 Nov 2021 08:18:55 +0900 Subject: [PATCH 39/83] Update Japanese translation --- src/locales/ja/lc_messages/twblue.mo | Bin 61905 -> 62862 bytes src/locales/ja/lc_messages/twblue.po | 520 +++++++++++++++------------ 2 files changed, 293 insertions(+), 227 deletions(-) diff --git a/src/locales/ja/lc_messages/twblue.mo b/src/locales/ja/lc_messages/twblue.mo index 9adb0dd5fdce74e3de3f266a30143e8ff88b2185..aab8b3f01678e364549a838e3c41d175765a9c7e 100644 GIT binary patch delta 18267 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 diff --git a/src/locales/ja/lc_messages/twblue.po b/src/locales/ja/lc_messages/twblue.po index d58a1594..1354cdac 100644 --- a/src/locales/ja/lc_messages/twblue.po +++ b/src/locales/ja/lc_messages/twblue.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-11-05 07:15+0900\n" +"PO-Revision-Date: 2021-11-12 08:18+0900\n" "Last-Translator: 陸 \n" "Language-Team: \n" "Language: ja_JP\n" @@ -18,10 +18,6 @@ msgstr "" "X-Generator: Poedit 3.0\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../src\controller\attach.py:25 -msgid "Photo" -msgstr "画像" - #: ../src\controller\buffers\base\base.py:91 msgid "This action is not supported for this buffer" msgstr "この動作は、現在のバッファではサポートされていません" @@ -100,78 +96,81 @@ msgstr "「{username}」のフォロー" msgid "Unknown buffer" msgstr "不明なバッファ" -#: ../src\controller\buffers\twitter\base.py:88 -#: ../src\controller\buffers\twitter\trends.py:122 -#: ../src\controller\messages.py:214 ../src\wxUI\buffers\base.py:25 +#: ../src\controller\buffers\twitter\base.py:87 +#: ../src\controller\buffers\twitter\trends.py:43 +#: ../src\controller\buffers\twitter\trends.py:134 +#: ../src\controller\messages.py:296 ../src\wxUI\buffers\base.py:25 #: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:35 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:312 +#: ../src\wxUI\sysTrayIcon.py:35 msgid "Tweet" msgstr "ツイート" -#: ../src\controller\buffers\twitter\base.py:89 -#: ../src\controller\buffers\twitter\trends.py:123 +#: ../src\controller\buffers\twitter\base.py:88 +#: ../src\controller\buffers\twitter\trends.py:44 +#: ../src\controller\buffers\twitter\trends.py:135 msgid "Write the tweet here" msgstr "ツイートを入力" -#: ../src\controller\buffers\twitter\base.py:219 +#: ../src\controller\buffers\twitter\base.py:192 msgid "New tweet in {0}" msgstr "「{0}」への新規ツイート" -#: ../src\controller\buffers\twitter\base.py:222 +#: ../src\controller\buffers\twitter\base.py:195 msgid "{0} new tweets in {1}." msgstr "「{1}」への{0}個の新規ツイート。" -#: ../src\controller\buffers\twitter\base.py:261 +#: ../src\controller\buffers\twitter\base.py:234 #: ../src\controller\buffers\twitter\directMessages.py:88 -#: ../src\controller\buffers\twitter\people.py:180 +#: ../src\controller\buffers\twitter\people.py:174 msgid "%s items retrieved" msgstr "%s個のアイテムを取得しました" -#: ../src\controller\buffers\twitter\base.py:293 +#: ../src\controller\buffers\twitter\base.py:266 #: ../src\controller\buffers\twitter\people.py:80 msgid "This buffer is not a timeline; it can't be deleted." msgstr "このバッファは、タイムラインではないため、削除できません。" -#: ../src\controller\buffers\twitter\base.py:430 +#: ../src\controller\buffers\twitter\base.py:402 msgid "Reply to {arg0}" msgstr "「{arg0}」への返信:" -#: ../src\controller\buffers\twitter\base.py:432 +#: ../src\controller\buffers\twitter\base.py:404 #: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "返信" -#: ../src\controller\buffers\twitter\base.py:433 +#: ../src\controller\buffers\twitter\base.py:405 msgid "Reply to %s" msgstr "「%s」への返信" -#: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\buffers\twitter\directMessages.py:130 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "新しいダイレクトメッセージ" -#: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\messages.py:200 +#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\messages.py:268 msgid "Direct message to %s" msgstr "「%s」へのダイレクトメッセージ" -#: ../src\controller\buffers\twitter\base.py:520 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Add your comment to the tweet" msgstr "ツイートにコメントを追加" -#: ../src\controller\buffers\twitter\base.py:520 +#: ../src\controller\buffers\twitter\base.py:459 msgid "Quote" msgstr "引用" -#: ../src\controller\buffers\twitter\base.py:596 +#: ../src\controller\buffers\twitter\base.py:520 msgid "Opening URL..." msgstr "URLを開いています…" -#: ../src\controller\buffers\twitter\base.py:633 +#: ../src\controller\buffers\twitter\base.py:557 msgid "User details" msgstr "ユーザーの詳細" -#: ../src\controller\buffers\twitter\base.py:654 +#: ../src\controller\buffers\twitter\base.py:578 msgid "Opening item in web browser..." msgstr "ブラウザでアイテムを開いています…" @@ -186,15 +185,15 @@ msgstr "%sへのメンション" msgid "Mention" msgstr "メンション" -#: ../src\controller\buffers\twitter\directMessages.py:133 +#: ../src\controller\buffers\twitter\directMessages.py:127 msgid "{0} new direct messages." msgstr "{0}件の新しいダイレクトメッセージ。" -#: ../src\controller\buffers\twitter\directMessages.py:136 +#: ../src\controller\buffers\twitter\directMessages.py:130 msgid "This action is not supported in the buffer yet." msgstr "この動作は、現在のバッファではサポートされていません。" -#: ../src\controller\buffers\twitter\directMessages.py:146 +#: ../src\controller\buffers\twitter\directMessages.py:140 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." @@ -202,11 +201,11 @@ msgstr "" "このバッファでは、さらにアイテムを取得することはできません。代わりにダイレク" "トメッセージバッファを使用してください。" -#: ../src\controller\buffers\twitter\people.py:253 +#: ../src\controller\buffers\twitter\people.py:247 msgid "{0} new followers." msgstr "{0}人の新しいフォロワー。" -#: ../src\controller\buffers\twitter\trends.py:146 +#: ../src\controller\buffers\twitter\trends.py:150 msgid "This action is not supported in the buffer, yet." msgstr "この動作は、現在のバッファではサポートされていません。" @@ -224,7 +223,7 @@ msgstr "タイムライン" #: ../src\controller\mainController.py:359 #: ../src\controller\mainController.py:883 -#: ../src\controller\mainController.py:1585 +#: ../src\controller\mainController.py:1582 msgid "Timeline for {}" msgstr "「{}」のタイムライン" @@ -234,7 +233,7 @@ msgstr "ほかのユーザーのいいね一覧" #: ../src\controller\mainController.py:363 #: ../src\controller\mainController.py:902 -#: ../src\controller\mainController.py:1587 +#: ../src\controller\mainController.py:1584 msgid "Likes for {}" msgstr "{}のいいね一覧" @@ -244,7 +243,7 @@ msgstr "フォロワー一覧" #: ../src\controller\mainController.py:367 #: ../src\controller\mainController.py:921 -#: ../src\controller\mainController.py:1589 +#: ../src\controller\mainController.py:1586 msgid "Followers for {}" msgstr "{}をフォローしているユーザー" @@ -254,7 +253,7 @@ msgstr "フォロー一覧" #: ../src\controller\mainController.py:371 #: ../src\controller\mainController.py:940 -#: ../src\controller\mainController.py:1591 +#: ../src\controller\mainController.py:1588 msgid "Friends for {}" msgstr "{}がフォローしているユーザー" @@ -279,7 +278,7 @@ msgstr "「{}」の検索結果" #: ../src\controller\mainController.py:381 #: ../src\controller\mainController.py:982 -#: ../src\controller\mainController.py:1593 +#: ../src\controller\mainController.py:1590 msgid "Trending topics for %s" msgstr "%s のトレンド" @@ -322,7 +321,7 @@ msgstr "ユーザーエイリアスを追加" msgid "Alias has been set correctly for {}." msgstr "{}のエイリアスが正しく設定されています。" -#: ../src\controller\mainController.py:829 ../src\controller\messages.py:245 +#: ../src\controller\mainController.py:829 ../src\controller\messages.py:327 msgid "MMM D, YYYY. H:m" msgstr "YYYY年MMMMD日 H時m分" @@ -411,72 +410,52 @@ msgstr "このバッファのミュートを設定" msgid "Buffer mute off" msgstr "このバッファのミュートを解除" -#: ../src\controller\mainController.py:1545 +#: ../src\controller\mainController.py:1542 msgid "Copied" msgstr "コピーしました" -#: ../src\controller\mainController.py:1575 +#: ../src\controller\mainController.py:1572 msgid "Unable to update this buffer." msgstr "このバッファを更新できません。" -#: ../src\controller\mainController.py:1578 +#: ../src\controller\mainController.py:1575 msgid "Updating buffer..." msgstr "バッファを更新中…" -#: ../src\controller\mainController.py:1581 +#: ../src\controller\mainController.py:1578 msgid "{0} items retrieved" msgstr "{0}個のアイテムを取得しました" -#: ../src\controller\mainController.py:1600 -#: ../src\controller\mainController.py:1620 +#: ../src\controller\mainController.py:1597 +#: ../src\controller\mainController.py:1617 msgid "Invalid buffer" msgstr "無効なバッファ" -#: ../src\controller\mainController.py:1611 +#: ../src\controller\mainController.py:1608 msgid "Picture {0}" msgstr "画像{0}" -#: ../src\controller\mainController.py:1612 +#: ../src\controller\mainController.py:1609 msgid "Select the picture" msgstr "画像を選択" -#: ../src\controller\mainController.py:1631 +#: ../src\controller\mainController.py:1628 msgid "Unable to extract text" msgstr "テキストを抽出できません" -#: ../src\controller\messages.py:56 +#: ../src\controller\messages.py:49 msgid "Translated" msgstr "翻訳完了" -#: ../src\controller\messages.py:63 -msgid "There's no URL to be shortened" -msgstr "短縮されたURLは、ありません" - -#: ../src\controller\messages.py:67 ../src\controller\messages.py:75 -msgid "URL shortened" -msgstr "URLを短縮しました" - -#: ../src\controller\messages.py:82 -msgid "There's no URL to be expanded" -msgstr "短縮を解除するURLはありません" - -#: ../src\controller\messages.py:86 ../src\controller\messages.py:94 -msgid "URL expanded" -msgstr "URLの短縮を解除しました" - -#: ../src\controller\messages.py:108 +#: ../src\controller\messages.py:56 msgid "%s - %s of %d characters" msgstr "%s - %s/%d" -#: ../src\controller\messages.py:112 -msgid "%s - %s characters" -msgstr "%s - %s文字" - -#: ../src\controller\messages.py:272 +#: ../src\controller\messages.py:354 msgid "View item" msgstr "アイテムを見る" -#: ../src\controller\messages.py:301 +#: ../src\controller\messages.py:379 msgid "Link copied to clipboard." msgstr "リンクをクリップボードへコピーしました。" @@ -667,7 +646,7 @@ msgstr "停止" msgid "&Record" msgstr "録音(&R)" -#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:148 +#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:147 msgid "Playing..." msgstr "再生中…" @@ -719,6 +698,9 @@ msgid "%s seconds" msgstr "%s秒" #: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:258 msgid "File" msgstr "ファイル" @@ -1558,7 +1540,7 @@ msgid "New tweet" msgstr "新規ツイート" #: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:26 -#: ../src\wxUI\commonMessageDialogs.py:10 ../src\wxUI\dialogs\message.py:126 +#: ../src\wxUI\commonMessageDialogs.py:10 msgid "Retweet" msgstr "リツイート" @@ -1996,15 +1978,17 @@ msgid "public" msgstr "公式" #: ../src\sessions\twitter\session.py:211 +#: ../src\sessions\twitter\session.py:238 msgid "%s failed. Reason: %s" msgstr "%s が失敗しました。理由: %s" #: ../src\sessions\twitter\session.py:217 +#: ../src\sessions\twitter\session.py:241 msgid "%s succeeded." msgstr "%sに成功しました。" -#: ../src\sessions\twitter\session.py:426 -#: ../src\sessions\twitter\session.py:504 +#: ../src\sessions\twitter\session.py:450 +#: ../src\sessions\twitter\session.py:528 msgid "Deleted account" msgstr "削除されたアカウント" @@ -2032,7 +2016,7 @@ msgstr "アカウントを連携中…" msgid "Enter your PIN code here" msgstr "PINコードを入力" -#: ../src\sound.py:161 +#: ../src\sound.py:160 msgid "Stopped." msgstr "停止。" @@ -2086,10 +2070,6 @@ msgstr "" msgid "Client" msgstr "クライアント" -#: ../src\wxUI\buffers\base.py:12 -msgid "Text" -msgstr "内容" - #: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\events.py:14 msgid "Date" msgstr "日時" @@ -2101,6 +2081,11 @@ msgstr "日時" msgid "User" msgstr "ユーザー" +#: ../src\wxUI\buffers\base.py:12 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +msgid "Text" +msgstr "内容" + #: ../src\wxUI\buffers\base.py:28 msgid "Direct message" msgstr "ダイレクトメッセージ" @@ -2357,55 +2342,6 @@ msgstr "" "{0}は、前回の実行時に予期せず終了しました。問題が解決しない場合は、{0}開発者" "に報告してください。" -#: ../src\wxUI\dialogs\attach.py:10 -msgid "Add an attachment" -msgstr "添付ファイルを追加" - -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Attachments" -msgstr "添付ファイル" - -#: ../src\wxUI\dialogs\attach.py:14 -msgid "Title" -msgstr "タイトル" - -#: ../src\wxUI\dialogs\attach.py:14 -msgid "Type" -msgstr "形式" - -#: ../src\wxUI\dialogs\attach.py:19 -msgid "Add attachments" -msgstr "添付ファイルを追加" - -#: ../src\wxUI\dialogs\attach.py:20 -msgid "&Photo" -msgstr "画像(&P)" - -#: ../src\wxUI\dialogs\attach.py:21 -msgid "Remove attachment" -msgstr "添付ファイルを削除" - -#: ../src\wxUI\dialogs\attach.py:37 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:82 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "画像ファイル (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" - -#: ../src\wxUI\dialogs\attach.py:37 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:82 -msgid "Select the picture to be uploaded" -msgstr "アップロードする画像を選択" - -#: ../src\wxUI\dialogs\attach.py:44 -msgid "please provide a description" -msgstr "説明を入力" - -#: ../src\wxUI\dialogs\attach.py:44 ../src\wxUI\dialogs\lists.py:14 -#: ../src\wxUI\dialogs\lists.py:70 -msgid "Description" -msgstr "説明" - #: ../src\wxUI\dialogs\configuration.py:15 msgid "Language" msgstr "言語" @@ -2791,6 +2727,14 @@ msgstr "所有者" msgid "mode" msgstr "モード" +#: ../src\wxUI\dialogs\lists.py:14 ../src\wxUI\dialogs\lists.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:38 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:260 +msgid "Description" +msgstr "説明" + #: ../src\wxUI\dialogs\lists.py:19 ../src\wxUI\dialogs\lists.py:62 msgid "Create a new list" msgstr "新しいリストを作成" @@ -2847,103 +2791,6 @@ msgstr "ユーザーを削除するには、リストを選択" msgid "Do you really want to delete this list?" msgstr "本当に、このリストを削除しますか?" -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "ツイートを短縮して投稿(&L)" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "画像をアップロード(&U)" - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:359 ../src\wxUI\dialogs\message.py:435 -msgid "Check &spelling..." -msgstr "スペルチェック(&S)" - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "音声を添付(&A)" - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "URLを短縮(&O)" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:436 -msgid "&Expand URL" -msgstr "URLを元に戻す(&E)" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:362 ../src\wxUI\dialogs\message.py:438 -msgid "&Translate..." -msgstr "翻訳(&T)..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "ユーザーを自動保管(&C)" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "送信(&D)" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:363 ../src\wxUI\dialogs\message.py:439 -msgid "C&lose" -msgstr "閉じる(&C)" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "送信先(&R)" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "全員にリプライ(&M)" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "ツイート - %i文字" - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "画像の説明" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "リツイート: " - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "いいね: " - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "ソース: " - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:423 -msgid "Date: " -msgstr "日付: " - -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:433 -msgid "Copy link to clipboard" -msgstr "リンクをクリップボードへコピー" - -#: ../src\wxUI\dialogs\message.py:408 -msgid "View" -msgstr "ツイート" - -#: ../src\wxUI\dialogs\message.py:410 -msgid "Item" -msgstr "アイテム" - #: ../src\wxUI\dialogs\search.py:12 msgid "Search on Twitter" msgstr "ツイッターを検索" @@ -3025,6 +2872,225 @@ msgstr "都市" msgid "&Location" msgstr "場所(&L)" +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:33 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:49 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:170 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 +msgid "Attachments" +msgstr "添付ファイル" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:174 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 +msgid "Type" +msgstr "形式" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:40 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:177 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:262 +msgid "Delete attachment" +msgstr "添付ファイルを削除" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:45 +msgid "Added Tweets" +msgstr "ツイートを追加" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:52 +msgid "Delete tweet" +msgstr "ツイートを削除" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:57 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:267 +msgid "A&dd..." +msgstr "追加(&D)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:59 +msgid "Add t&weet" +msgstr "ツイートを追加(&W)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:62 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:194 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:269 +msgid "&Attach audio..." +msgstr "音声を添付(&A)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:66 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:237 +msgid "Auto&complete users" +msgstr "ユーザーを自動保管(&C)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:68 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:273 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:367 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 +msgid "Check &spelling..." +msgstr "スペルチェック(&S)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:70 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:202 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:275 +msgid "&Translate" +msgstr "翻訳(&T)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:74 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:206 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:279 +msgid "Sen&d" +msgstr "送信(&D)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:118 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:299 +msgid "Image" +msgstr "画像" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:120 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:222 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:301 +msgid "Video" +msgstr "動画" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:122 +msgid "Poll" +msgstr "投票" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +msgid "please provide a description" +msgstr "説明を入力" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +msgstr "画像ファイル (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\update_profile.py:82 +msgid "Select the picture to be uploaded" +msgstr "アップロードする画像を選択" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Select the video to be uploaded" +msgstr "アップロードする動画を選択" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +msgid "Video files (*.mp4)|*.mp4" +msgstr "動画ファイル (*.mp4)|*.mp4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "Error adding attachment" +msgstr "添付ファイルの追加中にエラーが発生しました" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +msgid "" +"It is not possible to add more attachments. Please make sure your tweet " +"complies with Twitter'S attachment rules. You can add only one video or GIF " +"in every tweet, and a maximum of 4 photos." +msgstr "" +"これ以上添付ファイルを追加することはできません。ツイートがTwitterの添付ルール" +"に準拠していることを確認してください。すべてのツイートに追加できるビデオまた" +"はGIFは1つだけで、最大4枚の写真を追加できます。" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:182 +msgid "&Mention to all" +msgstr "全員にリプライ(&M)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 +msgid "&Recipient" +msgstr "送信先(&R)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:307 +msgid "Tweet - %i characters " +msgstr "ツイート - %i文字" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:324 +msgid "Image description" +msgstr "画像の説明" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:335 +msgid "Retweets: " +msgstr "リツイート: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:340 +msgid "Likes: " +msgstr "いいね: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:345 +msgid "Source: " +msgstr "ソース: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:350 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:428 +msgid "Date: " +msgstr "日付: " + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 +msgid "Copy link to clipboard" +msgstr "リンクをクリップボードへコピー" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:368 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:443 +msgid "&Translate..." +msgstr "翻訳(&T)..." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:369 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:444 +msgid "C&lose" +msgstr "閉じる(&C)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:413 +msgid "View" +msgstr "ツイート" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:415 +msgid "Item" +msgstr "アイテム" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 +msgid "&Expand URL" +msgstr "URLを元に戻す(&E)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:480 +msgid "Add a poll" +msgstr "投票を追加" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:484 +msgid "Participation time (in days)" +msgstr "投票期間(日数)" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:491 +msgid "Choices" +msgstr "選択肢" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:495 +msgid "Option 1" +msgstr "オプション1" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:501 +msgid "Option 2" +msgstr "オプション2" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:507 +msgid "Option 3" +msgstr "オプション3" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:513 +msgid "Option 4" +msgstr "オプション4" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Not enough information" +msgstr "十分な情報がありません" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +msgid "Please make sure you have provided at least two options for the poll." +msgstr "投票に少なくとも2つのオプションを提供していることを確認してください。" + #: ../src\wxUI\dialogs\update_profile.py:10 msgid "Update your profile" msgstr "プロフィールを更新" From f264f3807fa3985ccc06622d386ef5f4774d5f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Manuel=20Delicado=20Alcolea?= Date: Fri, 12 Nov 2021 09:08:50 +0100 Subject: [PATCH 40/83] Updated Windows dependencies --- windows-dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows-dependencies b/windows-dependencies index 27a7c419..1ee41752 160000 --- a/windows-dependencies +++ b/windows-dependencies @@ -1 +1 @@ -Subproject commit 27a7c419835c5fed4ba77bc31d0e1aff50a78f2a +Subproject commit 1ee4175276e8dcb04c23cd0b76ff516d5986c698 From 3ccb3a5be5295ebb2466eedcc02cfaafcfb4747d Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 12 Nov 2021 13:33:54 -0600 Subject: [PATCH 41/83] Updated Spanish locale --- .../es/LC_MESSAGES/twblue-changelog.mo | Bin 67651 -> 73092 bytes .../es/LC_MESSAGES/twblue-changelog.po | 565 +- src/locales/es/LC_MESSAGES/twblue.mo | Bin 54968 -> 56939 bytes src/locales/es/LC_MESSAGES/twblue.po | 5308 +++++++++-------- src/locales/fr/LC_MESSAGES/twblue.mo | Bin 56563 -> 57445 bytes src/locales/fr/LC_MESSAGES/twblue.po | 2 +- 6 files changed, 3082 insertions(+), 2793 deletions(-) diff --git a/doc/locales/es/LC_MESSAGES/twblue-changelog.mo b/doc/locales/es/LC_MESSAGES/twblue-changelog.mo index 5ec37f0df226da8ceb9fac1b713bf929238b459a..82dbe54fb0451a70a178fe67e3e052bca381eae2 100644 GIT binary patch delta 9018 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

H>=P;eDhkK-&N1F!(qgUZp4U04um zRh(nl1wYYC#HO@_A{xLqC z{Hq>S@qz5fhFR=Qe1^4Xqc_EvkwNdV)oeYtm+({K$xNtPBd%FGLv!#Raq~Hxj`##s zJ3ScgaP(mw)xngEs$TV6^3Q^o*c|;b*^Fv#u3-RX%;OZpV%&jl^Y!99h*88oxgwwA zG*r8zHLWwPG8R=m2b$4;p?>g0R2jR8JVG8VB>(EhWTZ?gurW@_)7v8+TN4*xAt_yt zF^#xJ{_YdcS*&-DC10O}&u{|w4=m8Dy%?j2TQAiekHHe+gLoOI**;*TG!(?1`I3T( z%k+MCTh59mj={m$vyk%}Gtn3A=#O8a58icNmlgUxAE!~M?wjh2mpI+#)K=#FP>G)0 zXjrK$c%ynyH2wu=VmGYE&U83nmEOlASL=gjFTSKalAF~CBiHE6{D=%za@TSya=pnq zeZrnAYRHgHlGn3Jxo{i3aM1>RvTb4I#ZmDlhGFWjr` zWCO{~&HCLj;3NH3tifYU-JiB_o%{NKqRtx|H*I6ysqp4@MvESFKb0HeaR~8+9lHGW zoq82d#=Den$MM{kUn)W}q+*xe*J-=;+wo^y$n{jV%4n|Fe5Q9(-#z+WaTE9Rd>Ok} z@ZtgeKDAxsT;i<1@^Gxh z1-R!Me$h^k<4hwTP4sdrwk+d&BJROWTu(WvPsZk_^$B|5G>=W?hE8YnH<*-rniBvhFkYP+FV>q)dz5J=Ug5cZf44J<=7lHCSF!&@w?k)h%5hDWG665H6&kbxF_3CJQ&#~l0#hhbb3 zLqo=QVz@5_(M=8dj7OD;dQ=tOZ)RwC8$L%h1>$OG_>(Na)!@i(Yjv>)c&xK;@+@}v zcC<8cl)PaGbv&6+J*5&&tV2PMVQvJW*;44l;+B_!Zv6 zILeZiWlb>-O3%o&&I`1=7y8*F3xoZ}nFeK8Et$#bX{N!JOlt&Hg3Ttg*%V|pn!_T@ z;ijOlpdfonp{J`V36BUe+gBEjY!_j)&TjseB`qn-l4LcFvszLkjCR|KZuW\n" "Language-Team: \n" "Language: es\n" @@ -22,12 +22,90 @@ msgstr "" msgid "TWBlue Changelog" msgstr "Lista de cambios de TWBlue" -#: changelog.py:5 changelog.py:7 +#: changelog.py:5 msgid "## changes in this version" msgstr "## Cambios en esta versión" +#: changelog.py:7 +msgid "" +"* Now it is possible to create a tweet from a trending topics buffer again." +msgstr "" +"* De nuevo es posible crear un tweet desde un buffer de Tendencias.* Es " +"posible añadir tuits al buffer de me gusta desde la barra de menú otra vez." + +#: changelog.py:8 +msgid "" +"* TWBlue now includes a completely new set of dialogs to handle tweeting, " +"replying and sending direct messages that takes advantage of more Twitter " +"features." +msgstr "" +"* TWBlue incluye ahora un conjunto completamente nuevo de diálogos para " +"gestionar los tweets, las respuestas y el envío de mensajes directos que " +"aprovechan más funciones de la API de Twitter." + #: changelog.py:9 msgid "" +" * It is possible to add videos in tweets and direct messages by using " +"the new \"add\" button, located in every dialog where media can be added. " +"Twitter suggests to add videos from 5 seconds up to 2 minutes lenght, in mp4 " +"format (video Codec H.264 and audio codec AAC). Currently, TWBlue does not " +"check if the uploaded video complies with Twitter media requirements. You " +"can add only a video in a tweet or direct message. No other kind of media " +"can be added after a video is in a tweet. If the video was unable to be " +"uploaded successfully, the tweet or direct message won't be created." +msgstr "" +" * Ahora ya es posible añadir vídeos en los tweets y mensajes directos " +"utilizando el nuevo botón \"añadir\", situado en todos los diálogos donde se " +"pueden añadir medios. Twitter sugiere añadir vídeos de entre 5 segundos y 2 " +"minutos de duración, en formato mp4 (códec de vídeo H.264 y códec de audio " +"AAC). Actualmente, TWBlue no comprueba si el vídeo subido cumple con los " +"requisitos de los medios de comunicación de Twitter. Sólo se puede añadir un " +"vídeo en un tweet o mensaje directo. No se puede añadir ningún otro tipo de " +"medio después de que un vídeo esté en un tweet. Si el vídeo no se ha podido " +"subir con éxito, el tuit o el mensaje directo no se creará." + +#: changelog.py:10 +msgid "" +" * Now you can add a poll to tweets. Polls can have up to 4 different " +"options and allow voting up to 7 days after being created. Take into " +"account, though, that currently TWBlue does not support reading polls in " +"tweets." +msgstr "" +" * Ahora puedes añadir una encuesta a los tweets. Las encuestas pueden " +"tener hasta 4 opciones diferentes y permiten votar hasta 7 días después de " +"ser creadas. Ten en cuenta, sin embargo, que actualmente TWBlue no soporta " +"la lectura de encuestas en los tweets." + +#: changelog.py:11 +msgid "" +" * TWBlue now support threads while creating a new tweet. There is a new " +"button, called add tweet which will add the current tweet to the thread and " +"will allow you to write another tweet in the thread. Every tweet might " +"include media (up to 4 photos, or one GIF image or a video) or up to one " +"poll." +msgstr "" +" * TWBlue ahora soporta hilos mientras se crea un nuevo tweet. Hay un " +"nuevo botón, llamado añadir tweet, que añadirá el tweet actual al hilo y te " +"permitirá escribir otro tweet en el hilo. Cada tweet puede incluir medios " +"(hasta 4 fotos, o una imagen GIF o un video) y una encuesta." + +#: changelog.py:12 +msgid "" +" * Some functionality was removed from tweet dialogs within TWBlue. " +"Particularly, URL shorteners and long tweets via Twishort. You still can " +"read long tweets posted via Twishort, though." +msgstr "" +" * Se han eliminado algunas características de los diálogos de tweets en " +"TWBlue. En particular, los acortadores de URL y los tweets largos a través " +"de Twishort. Sin embargo, todavía se pueden leer los tweets largos " +"publicados a través de Twishort." + +#: changelog.py:14 +msgid "## Changes in version 2021.11.07" +msgstr "## Cambios en la versión 2021.11.07" + +#: changelog.py:16 +msgid "" "* TWBlue should retrieve tweets from threads and conversations in a more " "reliable way. Tweets in the same thread (made by the same author) will be " "sorted correctly, although replies to the thread (made by different people) " @@ -40,7 +118,29 @@ msgstr "" "mostrar en un orden diferente al que se muestra en las aplicaciones de " "Twitter. ([#417](https://github.com/manuelcortez/TWBlue/issues/417))" -#: changelog.py:10 +#: changelog.py:17 +msgid "" +"* When creating a filter, TWBlue will show an error if user has not provided " +"a name for the filter. Before, unnamed filters were a cause of config breaks " +"in the application." +msgstr "" +"* Al crear un filtro, TWBlue mostrará un error si el usuario no ha " +"proporcionado un nombre para el filtro. Antes, los filtros sin nombre se " +"guardaban en la configuración y causaban errores al iniciar la aplicación." + +#: changelog.py:18 +#, fuzzy +#| msgid "" +#| "* It is possible to add a tweet to the likes buffer from the menu bar " +#| "again." +msgid "" +"* It is again possible to read the changelog for TWBlue from the help menu " +"in the menu bar." +msgstr "" +"* Es posible añadir tuits al buffer de me gusta desde la barra de menú otra " +"vez." + +#: changelog.py:19 msgid "" "* fixed a bug when clearing the direct messages buffer. ([#418](https://" "github.com/manuelcortez/TWBlue/issues/418))" @@ -50,7 +150,7 @@ msgstr "" "problema en el Streaming API que causaba que TWBlue desconectara el " "Streaming. ([#103](https://github.com/manuelcortez/TWBlue/issues/103))" -#: changelog.py:11 +#: changelog.py:20 msgid "" "* fixed an issue that was making TWBlue to show incorrectly titles for " "trending topic buffers upon startup. ([#421](https://github.com/manuelcortez/" @@ -60,11 +160,26 @@ msgstr "" "incorrecta los títulos de los buffers de trending topics al iniciarse. " "([#421](https://github.com/manuelcortez/TWBlue/issues/421))" -#: changelog.py:13 +#: changelog.py:21 +msgid "" +"* fixed an issue that was making users of the graphical user interface to " +"delete a buffer if a trends buffer was opened in the same session." +msgstr "" +"* Se ha solucionado un problema que hacía que los usuarios de la interfaz " +"gráfica no pudieran borrar algunos buffers si se abría un buffer de " +"tendencias en la misma sesión." + +#: changelog.py:22 +#, fuzzy +#| msgid "* Updated romanian translation." +msgid "* Updated Spanish, Japanese and french translations." +msgstr "* Actualizada la traducción al rumano." + +#: changelog.py:24 msgid "## Changes in Version 2021.10.30" msgstr "## Cambios en la versión 2021.10.30" -#: changelog.py:15 +#: changelog.py:26 msgid "" "* Fixed many errors in the way we compile TWBlue, so users of 64 bits " "systems and particularly windows 7 users would be able to install TWBlue " @@ -84,7 +199,7 @@ msgstr "" "próximos 23 meses.([#416,](https://github.com/manuelcortez/TWBlue/" "issues/416), [#415,](https://github.com/manuelcortez/TWBlue/issues/415))" -#: changelog.py:16 +#: changelog.py:27 msgid "" "* fixed an issue that was making impossible to manually add an user to the " "autocomplete users database." @@ -92,7 +207,7 @@ msgstr "" "* Corregido un error que causaba que fuera imposible añadir manualmente un " "usuario a la base de datos de autocompletado." -#: changelog.py:17 +#: changelog.py:28 msgid "" "* Started to improve support to conversations by searching for " "conversation_id." @@ -100,11 +215,11 @@ msgstr "" "* Se ha comenzado a mejorar el soporte a las conversaciones e hilos buscando " "por el parámetro conversation_id en Twitter." -#: changelog.py:19 +#: changelog.py:30 msgid "## changes in version 2021.10.27" msgstr "## Cambios en la versión 2021.10.27" -#: changelog.py:21 +#: changelog.py:32 msgid "" "* Added an user alias manager, located in the application menu in the menu " "bar. From this dialog, it is possible to review, add, edit or remove user " @@ -116,7 +231,7 @@ msgstr "" "editar y eliminar el alias para los usuarios de la cuenta seleccionada. " "([#401](https://github.com/manuelcortez/TWBlue/issues/401))" -#: changelog.py:22 +#: changelog.py:33 msgid "" "* TWBlue now closes the VLC player window automatically when a video reaches " "its end. ([#399](https://github.com/manuelcortez/TWBlue/issues/399))" @@ -125,7 +240,7 @@ msgstr "" "reproducción de un video. ([#399](https://github.com/manuelcortez/TWBlue/" "issues/399))" -#: changelog.py:23 +#: changelog.py:34 msgid "" "* After a lot of time, TWBlue now uses a new default Soundpack, called " "FreakyBlue. This soundpack will be set by default in all new sessions " @@ -139,7 +254,7 @@ msgstr "" "por tomarse el trabajo de diseñar el paquete de sonidos para TWBlue. ([#247]" "(https://github.com/manuelcortez/TWBlue/issues/247))" -#: changelog.py:24 +#: changelog.py:35 msgid "" "* When reading a tweet, if the tweet contains more than 2 consecutive " "mentions, TWBlue will announce how many more users the tweet includes, as " @@ -153,7 +268,7 @@ msgstr "" "conjunto de usuarios mencionados en el tweet utilizando el diálogo de ver " "tweets." -#: changelog.py:25 +#: changelog.py:36 msgid "" "* In the tweet displayer, It is possible to copy a link to the current tweet " "or person by pressing a button called \"copy link to clipboard\"." @@ -162,7 +277,7 @@ msgstr "" "directo al tweet o usuario seleccionando el botón llamado \"copiar vínculo " "al portapapeles\"." -#: changelog.py:26 +#: changelog.py:37 msgid "" "* Added a keymap capable to work under Windows 11. ([#391](https://github." "com/manuelcortez/TWBlue/pull/391))" @@ -170,7 +285,7 @@ msgstr "" "* Se ha añadido un mapa de teclado capaz de funcionar correctamente en " "Windows 11. ([#391](https://github.com/manuelcortez/TWBlue/pull/391))" -#: changelog.py:27 +#: changelog.py:38 msgid "" "* Added user aliases to TWBlue. This feature allows you to rename user's " "display names on Twitter, so the next time you'll read an user it will be " @@ -192,11 +307,11 @@ msgstr "" "a ninguna combinación de teclado por defecto. ([#389](https://github.com/" "manuelcortez/TWBlue/pull/389))" -#: changelog.py:28 +#: changelog.py:39 msgid "* There are some changes to the autocomplete users feature:" msgstr "* Hemos introducido algunos cambios al autocompletado de usuarios:" -#: changelog.py:29 +#: changelog.py:40 msgid "" " * Now users can search for twitter screen names or display names in the " "database." @@ -204,7 +319,7 @@ msgstr "" " * Ahora, es posible buscar utilizando los nombres de pantalla o nombres " "para mostrar de los usuarios de Twitter." -#: changelog.py:30 +#: changelog.py:41 msgid "" "* It is possible to undefine keystrokes in the current keymap in TWBlue. " "This allows you, for example, to redefine keystrokes completely." @@ -213,7 +328,7 @@ msgstr "" "uso en TWBlue. Esto permite, por ejemplo, desasignar combinaciones de " "teclado para utilizarlas en otras funciones." -#: changelog.py:31 +#: changelog.py:42 msgid "" "* We have changed our Geocoding service to the Nominatim API from " "OpenStreetMap. Addresses present in tweets are going to be determined by " @@ -226,7 +341,7 @@ msgstr "" "ahora una clave API de pago. ([#390](https://github.com/manuelcortez/TWBlue/" "issues/390))" -#: changelog.py:32 +#: changelog.py:43 msgid "" "* Added a limited version of the Twitter's Streaming API: The Streaming API " "will work only for tweets, and will receive tweets only by people you " @@ -243,7 +358,7 @@ msgstr "" "debería ser capaz de detectar este problema y reconectar el stream de nuevo. " "([#385](https://github.com/manuelcortez/TWBlue/pull/385))" -#: changelog.py:33 +#: changelog.py:44 msgid "" "* Fixed an issue that made TWBlue to not show a dialog when attempting to " "show a profile for a suspended user. ([#387](https://github.com/manuelcortez/" @@ -253,7 +368,7 @@ msgstr "" "mostrar nada al intentar ver el perfil de un usuario suspendido. ([#387]" "(https://github.com/manuelcortez/TWBlue/issues/387))" -#: changelog.py:34 +#: changelog.py:45 msgid "" "* Added support for Twitter audio and videos: Tweets which contains audio or " "videos will be detected as audio items, and you can playback those with the " @@ -265,7 +380,7 @@ msgstr "" "reproducirlos con el comando habitual para reproducir audios. ([#384,]" "(https://github.com/manuelcortez/TWBlue/pull/384))" -#: changelog.py:35 +#: changelog.py:46 msgid "" "* We just implemented some changes in the way TWBlue handles tweets in order " "to reduce its RAM memory usage [#380](https://github.com/manuelcortez/TWBlue/" @@ -275,7 +390,7 @@ msgstr "" "los tweets, con el objetivo de mejorar el consumo de memoria y CPU. [#380]" "(https://github.com/manuelcortez/TWBlue/pull/380):" -#: changelog.py:36 +#: changelog.py:47 msgid "" " * We reduced the tweets size by storing only the tweet fields we " "currently use. This should reduce tweet's size in memory for every object up " @@ -285,7 +400,7 @@ msgstr "" "campos de información que usamos actualmente. Esto debería reducir el tamaño " "del tweet en la memoria para cada objeto hasta un 75%." -#: changelog.py:37 +#: changelog.py:48 msgid "" " * When using the cache database to store your tweets, there is a new " "setting present in the account settings dialog, in the general tab. This " @@ -297,7 +412,7 @@ msgstr "" "pestaña general. Este ajuste te permite controlar si TWBlue cargará toda la " "base de datos en la memoria RAM (Opción predeterminada) o no." -#: changelog.py:38 +#: changelog.py:49 msgid "" " * Loading the whole database into memory has the advantage of being " "extremely fast to access any element (for example when moving through tweets " @@ -314,7 +429,7 @@ msgstr "" "los objetos de tweets. Si tienes una máquina con suficiente memoria, esta " "debería ser una buena opción para ti." -#: changelog.py:39 +#: changelog.py:50 msgid "" " * If you uncheck this setting, TWBlue will read the whole database " "from disk. This is significantly slower, but the advantage of this setting " @@ -333,7 +448,7 @@ msgstr "" "sugiere para ordenadores con poca memoria o para aquellas personas que no " "quieran mantener una cantidad realmente grande de tweets almacenados." -#: changelog.py:40 +#: changelog.py:51 msgid "" "* Changed the label in the direct message's text control so it will indicate " "that the user needs to write the text there, without referring to any " @@ -344,7 +459,7 @@ msgstr "" "de un mensaje directo. Ahora en dicho campo no se especifica ningún nombre " "de usuario. ([#366,](https://github.com/manuelcortez/TWBlue/issues/366))" -#: changelog.py:41 +#: changelog.py:52 msgid "" "* TWBlue will take Shift+F10 again as the contextual menu key in the list of " "items in a buffer. This stopped working after we have migrated to WX 4.1. " @@ -353,7 +468,7 @@ msgstr "" "* TWBlue puede volver a usar la combinación de teclado Shift+F10 como la " "tecla de menú contextual." -#: changelog.py:42 +#: changelog.py:53 msgid "" "* TWBlue should render correctly retweets of quoted tweets. ([#365,](https://" "github.com/manuelcortez/TWBlue/issues/365))" @@ -361,7 +476,7 @@ msgstr "" "* TWBlue debería mostrar apropiadamente los retweets de un tweet citado. " "([#365,](https://github.com/manuelcortez/TWBlue/issues/365))" -#: changelog.py:43 +#: changelog.py:54 msgid "" "* Fixed an error that was causing TWBlue to be unable to output to screen " "readers at times. ([#369,](https://github.com/manuelcortez/TWBlue/" @@ -371,7 +486,7 @@ msgstr "" "enviar texto a los lectores de pantalla. ([#369,](https://github.com/" "manuelcortez/TWBlue/issues/369))" -#: changelog.py:44 +#: changelog.py:55 msgid "" "* Fixed autocomplete users feature. ([#367,](https://github.com/manuelcortez/" "TWBlue/issues/367))" @@ -379,7 +494,7 @@ msgstr "" "* Corregida la característica de autocompletado de usuarios. ([#367,]" "(https://github.com/manuelcortez/TWBlue/issues/367))" -#: changelog.py:45 +#: changelog.py:56 msgid "" "* Fixed error when displaying an URL at the end of a line, when the tweet or " "direct message contained multiple lines. Now the URL should be displayed " @@ -391,7 +506,7 @@ msgstr "" "todas las direcciones. ([#305,](https://github.com/manuelcortez/TWBlue/" "issues/305) [#272,](https://github.com/manuelcortez/TWBlue/issues/272))" -#: changelog.py:46 +#: changelog.py:57 msgid "" "* TWBlue has been migrated completely to Python 3 (currently, the software " "builds with Python 3.8)." @@ -399,7 +514,7 @@ msgstr "" "* TWBlue ha sido migrado completamente a Python 3 (actualmente, el software " "se construye con Python 3.8)." -#: changelog.py:47 +#: changelog.py:58 msgid "" "* TWBlue should be restarted gracefully. Before, the application was " "alerting users of not being closed properly every time the application " @@ -409,7 +524,7 @@ msgstr "" "los usuarios de que no se cerraba correctamente cada vez que debía efectuar " "un reinicio." -#: changelog.py:48 +#: changelog.py:59 msgid "" "* If TWBlue attemps to load an account with invalid tokens (this happens " "when reactivating a previously deactivated account, or when access to the ap " @@ -423,7 +538,7 @@ msgstr "" "sesión. Antes, la aplicación no podía iniciarse debido a un error crítico. " "([#328,](https://github.com/manuelcortez/TWBlue/issues/328))" -#: changelog.py:49 +#: changelog.py:60 msgid "" "* When sending a direct message, the title of the window will change " "appropiately when the recipient is edited. ([#276,](https://github.com/" @@ -433,7 +548,7 @@ msgstr "" "apropiadamente cada vez que el recipiente es editado. ([#276,](https://" "github.com/manuelcortez/TWBlue/issues/276))" -#: changelog.py:50 +#: changelog.py:61 msgid "" "* URL'S in user profiles are expanded automatically. ([#275,](https://github." "com/manuelcortez/TWBlue/issues/275))" @@ -441,7 +556,7 @@ msgstr "" "* Las direcciones URL de los perfiles de usuario estarán expandidas " "automáticamente. ([#275,](https://github.com/manuelcortez/TWBlue/issues/275))" -#: changelog.py:51 +#: changelog.py:62 msgid "" "* TWBlue now uses [Tweepy,](https://github.com/tweepy/tweepy) to connect " "with Twitter. We have adopted this change in order to support Twitter'S API " @@ -454,7 +569,7 @@ msgstr "" "de Twitter en un futuro cercano. ([#333,](https://github.com/manuelcortez/" "TWBlue/issues/337) [#347](https://github.com/manuelcortez/TWBlue/pull/347))" -#: changelog.py:52 +#: changelog.py:63 msgid "" "* TWBlue can upload images in Tweets and replies again. ([#240,](https://" "github.com/manuelcortez/TWBlue/issues/240))" @@ -462,7 +577,7 @@ msgstr "" "* TWBlue puede subir imágenes en tweets y respuestas de nuevo. ([#240,]" "(https://github.com/manuelcortez/TWBlue/issues/240))" -#: changelog.py:53 +#: changelog.py:64 msgid "" "* Fixed the way we use to count characters in Twitter. The new methods in " "TWBlue take into account special characters and URLS as documented in " @@ -474,11 +589,11 @@ msgstr "" "especificaciones de Twitter. ([#199,](https://github.com/manuelcortez/TWBlue/" "issues/199) [#315](https://github.com/manuelcortez/TWBlue/issues/315))" -#: changelog.py:54 +#: changelog.py:65 msgid "* Proxy support now works as expected." msgstr "* El soporte Proxy ahora debería funcionar como es debido." -#: changelog.py:55 +#: changelog.py:66 msgid "" "* Changed translation service from yandex.translate to Google Translator. " "([#355,](https://github.com/manuelcortez/TWBlue/issues/355))" @@ -486,7 +601,7 @@ msgstr "" "* Hemos cambiado el servicio de traducción de yandex.translate a Google " "Translate. ([#355,](https://github.com/manuelcortez/TWBlue/issues/355))" -#: changelog.py:56 +#: changelog.py:67 msgid "" "* Improved method to load direct messages in the buffers. Now it should be " "faster due to less calls to Twitter API performed from the client." @@ -495,16 +610,16 @@ msgstr "" "Ahora debería ser más rápido debido a que se realizan menos llamadas a la " "API de Twitter desde el cliente." -#: changelog.py:57 +#: changelog.py:68 msgid "" "* And more. ([#352,](https://github.com/manuelcortez/TWBlue/issues/352))" msgstr "* Y más ([#352,](https://github.com/manuelcortez/TWBlue/issues/352))" -#: changelog.py:59 +#: changelog.py:70 msgid "## Changes in version 0.95" msgstr "## Cambios en la versión 0.95" -#: changelog.py:61 +#: changelog.py:72 msgid "" "* TWBlue can open a Tweet or user directly in Twitter. There is a new option " "in the context menu for people and tweet buffers, and also, the shortcut " @@ -515,12 +630,12 @@ msgstr "" "también el atajo control+win+alt+enter para abrir en Twitter el elemento con " "el foco." -#: changelog.py:62 +#: changelog.py:73 msgid "* Some keystrokes were remapped in the Windows 10 Keymap:" msgstr "" "* Cambiados algunos atajos de teclado en el mapa de teclado de Windows 10:" -#: changelog.py:63 +#: changelog.py:74 msgid "" " * Read location of a tweet: Ctrl+Win+G. ([#177](https://github.com/" "manuelcortez/TWBlue/pull/177))" @@ -528,17 +643,17 @@ msgstr "" " * Leer ubicación de un tuit: CTRL+Win+G. ([#177](https://github.com/" "manuelcortez/TWBlue/pull/177))" -#: changelog.py:64 +#: changelog.py:75 msgid " * Open global settings dialogue: Ctrl+Win+Alt+O." msgstr " * Abrir diálogo de configuración global: Ctrl+Win+Alt+O." -#: changelog.py:65 +#: changelog.py:76 msgid " * Mute/unmute current session: Control + Windows + Alt + M." msgstr "" " * Silenciar / desactivar silencio en la sesión actual: Control + Windows " "+ Alt + M." -#: changelog.py:66 +#: changelog.py:77 msgid "" "* Fixed an error that was preventing TWBlue to load the direct messages " "buffer if an user who sent a message has been deleted." @@ -546,7 +661,7 @@ msgstr "" "* Corregido un error que impedía a TWBlue cargar el buffer de mensajes " "directos si se ha eliminado un usuario que envió un mensaje." -#: changelog.py:67 +#: changelog.py:78 msgid "" "* Added support for playing audios posted in [AnyAudio.net](http://anyaudio." "net) directly from TWBlue. Thanks to [Sam Tupy](http://www.samtupy.com/)" @@ -555,7 +670,7 @@ msgstr "" "(http://anyaudio.net) directamente desde TWBlue. Gracias a [Sam Tupy](http://" "www.samtupy.com/)" -#: changelog.py:68 +#: changelog.py:79 msgid "" "* Custom buffer ordering will not be reset every time the application " "restarts after an account setting has been modified." @@ -563,7 +678,7 @@ msgstr "" "* El orden personalizado de buffers no se restablecerá cada vez que la " "aplicación se reinicie tras modificar un ajuste de la cuenta." -#: changelog.py:69 +#: changelog.py:80 msgid "" "* 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" @@ -573,7 +688,7 @@ msgstr "" "la lista con el foco en vez de tener que buscar los botones \"Añadir\" o " "\"Eliminar\"." -#: changelog.py:70 +#: changelog.py:81 msgid "" "* Quoted and long tweets are displayed properly in the sent tweets buffer " "after being send. ([#253](https://github.com/manuelcortez/TWBlue/issues/253))" @@ -582,7 +697,7 @@ msgstr "" "enviados después de enviarse. ([#253](https://github.com/manuelcortez/TWBlue/" "issues/253))" -#: changelog.py:71 +#: changelog.py:82 msgid "" "* 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]" @@ -593,7 +708,7 @@ msgstr "" "se lista adecuadamente. ([#260](https://github.com/manuelcortez/TWBlue/" "issues/260))" -#: changelog.py:72 +#: changelog.py:83 msgid "" "* The volume slider, located in the account settings of TWBlue, now should " "decrease and increase value properly when up and down arrows are pressed. " @@ -605,7 +720,7 @@ msgstr "" "arriba y abajo. Antes lo hacía en orden inverso. ([#261](https://github.com/" "manuelcortez/TWBlue/issues/261))" -#: changelog.py:73 +#: changelog.py:84 msgid "" "* autoreading has been redesigned to work in a similar way for almost all " "buffers. Needs testing. ([#221](https://github.com/manuelcortez/TWBlue/" @@ -615,7 +730,7 @@ msgstr "" "casi todos los buffers. Necesita pruebas. ([#221](https://github.com/" "manuelcortez/TWBlue/issues/221))" -#: changelog.py:74 +#: changelog.py:85 msgid "" "* When displaying tweets or direct messages, a new field has been added to " "show the date when the item has been posted to Twitter." @@ -623,7 +738,7 @@ msgstr "" "* Al mostrar tuits o mensajes directos, ahora hay un nuevo campo que muestra " "la fecha en la que se publicó ese elemento en Twitter." -#: changelog.py:75 +#: changelog.py:86 msgid "" "* Added support for deleting direct messages by using the new Twitter API " "methods." @@ -631,14 +746,14 @@ msgstr "" "* Se ha añadido soporte para eliminar mensajes directos usando los nuevos " "métodos de la API de Twitter." -#: changelog.py:76 +#: changelog.py:87 msgid "" "* When quoting a retweet, the quote will be made to the original tweet " "instead of the retweet." msgstr "" "* Al citar un retuit, la cita apuntará al tuit original en vez del retuit." -#: changelog.py:77 +#: changelog.py:88 msgid "" "* If the sent direct messages buffer is hidden, TWBlue should keep loading " "everything as expected. ([#246](https://github.com/manuelcortez/TWBlue/" @@ -648,7 +763,7 @@ msgstr "" "cargar todo como se espera. ([#246](https://github.com/manuelcortez/TWBlue/" "issues/246))" -#: changelog.py:78 +#: changelog.py:89 msgid "" "* There is a new soundpack, called FreakyBlue (Thanks to [Andre Louis]" "(https://twitter.com/FreakyFwoof)) as a new option in TWBlue. This pack can " @@ -662,7 +777,7 @@ msgstr "" "que los usuarios deberían echar un vistazo y dar su opinión en las " "snapshots. ([#247](https://github.com/manuelcortez/TWBlue/issues/247))" -#: changelog.py:79 +#: changelog.py:90 msgid "" "* 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/" @@ -672,7 +787,7 @@ msgstr "" "paquetes de sonidos en el sitio web de TWBlue. ([#247](https://github.com/" "manuelcortez/TWBlue/issues/247))" -#: changelog.py:80 +#: changelog.py:91 msgid "" "* When reading location of a geotagged tweet, it will be translated for " "users of other languages. ([#251](https://github.com/manuelcortez/TWBlue/" @@ -682,7 +797,7 @@ msgstr "" "usuarios de otros idiomas. ([#251](https://github.com/manuelcortez/TWBlue/" "pull/251))" -#: changelog.py:81 +#: changelog.py:92 msgid "" "* When there are no more items to retrieve in direct messages and people " "buffers, a message will announce it." @@ -690,7 +805,7 @@ msgstr "" "* Cuando no haya más elementos que recuperar en los buffers de mensajes " "directos y personas, un mensaje lo indicará." -#: changelog.py:82 +#: changelog.py:93 msgid "" "* Fixed an issue reported by some users that was making them unable to load " "more items in their direct messages." @@ -698,14 +813,14 @@ msgstr "" "* Corregido un problema reportado por algunos usuarios que les impedía " "cargar más elementos en sus mensajes directos." -#: changelog.py:83 +#: changelog.py:94 msgid "" "* It is possible to add a tweet to the likes buffer from the menu bar again." msgstr "" "* Es posible añadir tuits al buffer de me gusta desde la barra de menú otra " "vez." -#: changelog.py:84 +#: changelog.py:95 msgid "" "* Tweets, replies and retweets will be added to sent tweets right after " "being posted in Twitter." @@ -713,16 +828,16 @@ msgstr "" "* Los tuits, respuestas y retuits se añadirán a los tuits enviados justo al " "publicarse en Twitter." -#: changelog.py:85 +#: changelog.py:96 msgid "* Extended Tweets should be displayed properly in list buffers." msgstr "" "* Los tuits largos deberían mostrarse correctamente en los buffers de listas." -#: changelog.py:87 +#: changelog.py:98 msgid "## Changes in version 0.94" msgstr "## Cambios en la versión 0.94" -#: changelog.py:89 +#: changelog.py:100 msgid "" "* Added an option in the global settings dialog to disable the Streaming " "features of TWBlue. TWBlue will remove all Streaming features after August " @@ -736,7 +851,7 @@ msgstr "" "permite saber cómo se comportará la aplicación al llegar ese día. ([#219]" "(https://github.com/manuelcortez/TWBlue/issues/219))" -#: changelog.py:90 +#: changelog.py:101 msgid "" "* Due to Twitter API changes, Switched authorisation method to Pin-code " "based authorisation. When you add new accounts to TWBlue, you will be " @@ -749,7 +864,7 @@ msgstr "" "autorizar recibirás un número que deberás pegar en la ventana de TWBlue para " "poder continuar. ([#216](https://github.com/manuelcortez/TWBlue/issues/216))" -#: changelog.py:91 +#: changelog.py:102 msgid "" "* In order to comply with latest Twitter changes, TWBlue has switched to the " "new method used to send and receive direct messages, according to issue " @@ -760,7 +875,7 @@ msgstr "" "directos, de acuerdo con lo dispuesto en el issue [#215.](https://github.com/" "manuelcortez/twblue/issues/215)" -#: changelog.py:92 +#: changelog.py:103 msgid "" " * The new method does not allow direct messages to be processed in real " "time. Direct messages will be updated periodically." @@ -769,7 +884,7 @@ msgstr "" "tiempo real. Los mensajes directos se actualizarán periódicamente, pero no " "en tiempo real." -#: changelog.py:93 +#: changelog.py:104 msgid "" "* After august 16 or when streaming is disabled, the events buffer will no " "longer be created in TWBlue." @@ -777,7 +892,7 @@ msgstr "" "* Luego del 16 de agosto o si las características en tiempo real han sido " "desactivadas, el buffer de eventos dejará de ser utilizado en TWBlue." -#: changelog.py:94 +#: changelog.py:105 msgid "" "* You can configure frequency for buffer updates in TWBlue. By default, " "TWBlue will update all buffers every 2 minutes, but you can change this " @@ -789,7 +904,7 @@ msgstr "" "esto puede cambiarse desde el diálogo de opciones globales. ([#223](https://" "github.com/manuelcortez/TWBlue/issues/223))" -#: changelog.py:95 +#: changelog.py:106 msgid "" "* 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 " @@ -806,7 +921,7 @@ msgstr "" "salida automática. ([#203](https://github.com/manuelcortez/TWBlue/" "issues/203))" -#: changelog.py:96 +#: changelog.py:107 msgid "" "* The spell checking dialog now has access keys defined for the most " "important actions. ([#211](https://github.com/manuelcortez/TWBlue/" @@ -816,7 +931,7 @@ msgstr "" "para las acciones más importantes. ([#211](https://github.com/manuelcortez/" "TWBlue/issues/211))" -#: changelog.py:97 +#: changelog.py:108 msgid "" "* 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/" @@ -826,7 +941,7 @@ msgstr "" "componentes importantes a Python 3 en el futuro. ([#207](https://github.com/" "manuelcortez/TWBlue/issues/207))" -#: changelog.py:98 +#: changelog.py:109 msgid "" "* When you quote a Tweet, if the original tweet was posted with Twishort, " "TWBlue should display properly the quoted tweet. Before it was displaying " @@ -837,7 +952,7 @@ msgstr "" "debería mostrar correctamente el tuit citado. Antes sólo mostraba el tuit " "original. ([#206](https://github.com/manuelcortez/TWBlue/issues/206))" -#: changelog.py:99 +#: changelog.py:110 msgid "" "* It is possible to filter by retweets, quotes and replies when creating a " "new filter." @@ -845,7 +960,7 @@ msgstr "" "* Es posible filtrar por retuits, tuits citados y respuestas al crear nuevos " "filtros." -#: changelog.py:100 +#: changelog.py:111 msgid "" "* Added support for playing youtube Links directly from the client. ([#94]" "(https://github.com/manuelcortez/TWBlue/issues/94))" @@ -853,11 +968,11 @@ msgstr "" "* Se ha añadido soporte para reproducir enlaces de Youtube directamente " "desde el cliente. ([#94](https://github.com/manuelcortez/TWBlue/issues/94))" -#: changelog.py:101 +#: changelog.py:112 msgid "* Replaced Bass with libVLC for playing URL streams." msgstr "* Se ha reemplazado bass por LibVlc para reproducir audio desde URLS." -#: changelog.py:102 +#: changelog.py:113 msgid "" "* the checkbox for indicating whether TWBlue will include everyone in a " "reply or not, will be unchecked by default." @@ -865,7 +980,7 @@ msgstr "" "* La casilla que indica si TWBlue debe incluir a todos los participantes en " "una respuesta estará desmarcada por defecto." -#: changelog.py:103 +#: changelog.py:114 msgid "" "* You can request TWBlue to save the state for two checkboxes: Long tweet " "and mention all, from the global settings dialogue." @@ -873,7 +988,7 @@ msgstr "" "* Puedes pedir a TWBlue que guarde el estado de dos casillas: tuit largo y " "mencionar a todos, desde el diálogo de opciones globales." -#: changelog.py:104 +#: changelog.py:115 msgid "" "* For windows 10 users, some keystrokes in the invisible user interface have " "been changed or merged:" @@ -881,7 +996,7 @@ msgstr "" "* Para usuarios de Windows 10, algunas combinaciones de teclado en el modo " "invisible han sufrido cambios o han sido combinadas:" -#: changelog.py:105 +#: changelog.py:116 msgid "" " * 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 " @@ -891,22 +1006,22 @@ msgstr "" "un tuit a los tuits que le gustan a un usuario. Esta función ejecutará la " "acción necesaria basándose en el estado actual del tuit con el foco." -#: changelog.py:106 +#: changelog.py:117 msgid "* TWBlue will show an error if something goes wrong in an audio upload." msgstr "" "* TWBlue mostrará un error si algo sale mal durante la carga de un archivo " "de audio." -#: changelog.py:107 +#: changelog.py:118 msgid "" "* And more. ([#171,](https://github.com/manuelcortez/TWBlue/issues/171) " msgstr "* Y más. ([#171,](https://github.com/manuelcortez/TWBlue/issues/171) " -#: changelog.py:109 +#: changelog.py:120 msgid "## Changes in version 0.93" msgstr "## Cambios en la versión 0.93" -#: changelog.py:111 +#: changelog.py:122 msgid "" "* A new soundpack has been added to TWBlue. Thanks to [@ValeriaK305](https://" "twitter.com/ValeriaK305)" @@ -914,7 +1029,7 @@ msgstr "" "* Se ha añadido un nuevo paquete de sonidos a la instalación predeterminada " "de TWBlue, gracias a [@ValeriaK305](https://twitter.com/ValeriaK305)" -#: changelog.py:112 +#: changelog.py:123 msgid "" "* In the Windows 10 keymap, we have changed some default keystrokes as " "windows now uses some previously assigned shortcuts:" @@ -923,16 +1038,16 @@ msgstr "" "de teclado, ya que Windows ahora utiliza algunos de los atajos que utilizaba " "TWBlue:" -#: changelog.py:113 +#: changelog.py:124 msgid " * For liking a tweet, press Control+Windows+alt+f" msgstr "" " * Para marcar como me gusta un tweet, presiona control+windows+alt+f" -#: changelog.py:114 +#: changelog.py:125 msgid " * for opening a trends buffer, press control+Windows+T" msgstr " * Para abrir un buffer de tendencias, presiona Control+Windows+T" -#: changelog.py:115 +#: changelog.py:126 msgid "" "* TWBlue has received improvements in some functions for handling extended " "tweets, long tweets and quoted retweets. It should render some tweets in a " @@ -942,7 +1057,7 @@ msgstr "" "extendidos y retuits citados. Debería ser capaz de mostrar mejor algunos " "tuits." -#: changelog.py:116 +#: changelog.py:127 msgid "" "* In the spell checker module, there is a new button that will allow you to " "add your own words to your personal dictionary so the module won't mark them " @@ -952,7 +1067,7 @@ msgstr "" "la palabra a tu diccionario. De esta forma,en un futuro esa palabra no " "aparecerá marcada como mal escrita." -#: changelog.py:117 +#: changelog.py:128 msgid "" "* Added filtering capabilities to TWBlue. ([#102](https://github.com/" "manuelcortez/TWBlue/issues/102))" @@ -960,7 +1075,7 @@ msgstr "" "* Se han añadido filtros a TWBlue. ([#102](https://github.com/manuelcortez/" "TWBlue/issues/102))" -#: changelog.py:118 +#: changelog.py:129 msgid "" " * You can create a filter for the current buffer from the buffer menu in " "the menu bar. At this moment, invisible interface does not have any shorcut " @@ -970,11 +1085,11 @@ msgstr "" "ubicado en la barra de menú. Por el momento, la interfaz invisible no cuenta " "con un atajo para esta acción." -#: changelog.py:119 +#: changelog.py:130 msgid " * You can create filters by word or languages." msgstr " * Puedes crear filtros de palabras o de idiomas en el tuit." -#: changelog.py:120 +#: changelog.py:131 msgid "" " * For deleting already created filters, you can go to the filter manager " "in the buffer menu and delete the filters you won't need." @@ -982,7 +1097,7 @@ msgstr "" " * Para eliminar filtros previamente creados, puedes acceder al gestor de " "filtros en el menú buffer, y eliminar desde ahí los que ya no necesites." -#: changelog.py:121 +#: changelog.py:132 msgid "" "* Links should be opened properly in quoted tweets ([#167,](https://github." "com/manuelcortez/TWBlue/issues/167) [#184](https://github.com/manuelcortez/" @@ -992,14 +1107,14 @@ msgstr "" "(https://github.com/manuelcortez/TWBlue/issues/167) [#184](https://github." "com/manuelcortez/TWBlue/issues/184))" -#: changelog.py:122 +#: changelog.py:133 msgid "" "* Increased display name limit up to 50 characters in update profile dialog." msgstr "" "* Se ha aumentado el número de caracteres permitidos en los nombres para " "mostrar en Twitter a 50 caracteres." -#: changelog.py:123 +#: changelog.py:134 msgid "" "* When authorising an account, you will see a dialogue with a cancel button, " "in case you want to abort the process. Also, NVDA will not be blocked when " @@ -1011,7 +1126,7 @@ msgstr "" "autorización para la cuenta. ([#101](https://github.com/manuelcortez/TWBlue/" "issues/101))" -#: changelog.py:124 +#: changelog.py:135 msgid "" "* In the translator module, the list of available languages is fetched " "automatically from the provider. That means all of these languages will work " @@ -1026,7 +1141,7 @@ msgstr "" "determina de forma automática por el API de Yandex. ([#153](https://github." "com/manuelcortez/TWBlue/issues/153))" -#: changelog.py:125 +#: changelog.py:136 msgid "" "* Trending topics, searches and conversation buffers will use mute settings " "set for the session in wich they were opened. ([#157](https://github.com/" @@ -1036,7 +1151,7 @@ msgstr "" "opciones de silencio en la sesión de TWBlue donde fueron creados. ([#157]" "(https://github.com/manuelcortez/TWBlue/issues/157))" -#: changelog.py:126 +#: changelog.py:137 msgid "" "* The Tweet limit is now 280 characters lenght instead 140. It means you can " "tweet longer tweets. ([#172](https://github.com/manuelcortez/TWBlue/" @@ -1046,7 +1161,7 @@ msgstr "" "significa que se pueden escribir tuits más largos. [#172](https://github.com/" "manuelcortez/TWBlue/issues/172))" -#: changelog.py:127 +#: changelog.py:138 msgid "" "* Per popular request, Status for mention to all and long tweet checkboxes " "will not be saved in settings. ([#170](https://github.com/manuelcortez/" @@ -1056,7 +1171,7 @@ msgstr "" "escribir un tuit largo y responder a todos. ([#170](https://github.com/" "manuelcortez/TWBlue/issues/170))" -#: changelog.py:128 +#: changelog.py:139 msgid "" "* Fixed a problem that was making TWBlue unable to start if it was being ran " "in Windows with Serbian language. ([#175](https://github.com/manuelcortez/" @@ -1066,11 +1181,11 @@ msgstr "" "el equipo se detectaba el idioma serbio. ([#175](https://github.com/" "manuelcortez/TWBlue/issues/175))" -#: changelog.py:129 +#: changelog.py:140 msgid "* Added Danish translation." msgstr "* Se ha añadido la traducción al Danés." -#: changelog.py:130 +#: changelog.py:141 msgid "" "* And more. ([#156,](https://github.com/manuelcortez/TWBlue/issues/156) " "[#163,](https://github.com/manuelcortez/TWBlue/issues/163) [#159,](https://" @@ -1085,11 +1200,11 @@ msgstr "" "TWBlue/issues/173) [#174,](https://github.com/manuelcortez/TWBlue/" "issues/174) [#176,](https://github.com/manuelcortez/TWBlue/issues/176))" -#: changelog.py:132 +#: changelog.py:143 msgid "## changes in version 0.91 and 0.92" msgstr "## Cambios en las versiones 0.91 y 0.92" -#: changelog.py:134 +#: changelog.py:145 msgid "" "* Fixed incorrect unicode handling when copying tweet to clipboard. ([#150]" "(https://github.com/manuelcortez/TWBlue/issues/150))" @@ -1097,7 +1212,7 @@ msgstr "" "* Se ha corregido un error de Unicode al copiar tuits al portapapeles. " "([#150](https://github.com/manuelcortez/TWBlue/issues/150))" -#: changelog.py:135 +#: changelog.py:146 msgid "" "* TWBlue will show an error when trying to open a timeline for a suspended " "user. ([#128](https://github.com/manuelcortez/TWBlue/issues/128))" @@ -1106,7 +1221,7 @@ msgstr "" "usuario suspendido. ([#128](https://github.com/manuelcortez/TWBlue/" "issues/128))" -#: changelog.py:136 +#: changelog.py:147 msgid "" "* Removed TwUp as service as it no longer exists. ([#112](https://github.com/" "manuelcortez/TWBlue/issues/112))" @@ -1114,7 +1229,7 @@ msgstr "" "* Se ha removido el servicio de audio TWUp, debido a que ya no existe. " "([#112](https://github.com/manuelcortez/TWBlue/issues/112))" -#: changelog.py:137 +#: changelog.py:148 msgid "" "* Release audio files after uploading them. ([#130](https://github.com/" "manuelcortez/TWBlue/issues/130))" @@ -1123,7 +1238,7 @@ msgstr "" "luego de haber sido subidos a algún servicio de audio. ([#130](https://" "github.com/manuelcortez/TWBlue/issues/130))" -#: changelog.py:138 +#: changelog.py:149 msgid "" "* Now TWBlue will use Yandex's translation services instead microsoft " "translator. ([#132](https://github.com/manuelcortez/TWBlue/issues/132))" @@ -1132,7 +1247,7 @@ msgstr "" "Microsoft Translator. ([#132](https://github.com/manuelcortez/TWBlue/" "issues/132))" -#: changelog.py:139 +#: changelog.py:150 msgid "" "* SndUp users will be able to upload audio in their account by using their " "API Key again. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" @@ -1140,7 +1255,7 @@ msgstr "" "* Los usuarios con cuenta de SNDUp podrán subir audios utilizando su clave " "de API de nuevo. ([#134](https://github.com/manuelcortez/TWBlue/issues/134))" -#: changelog.py:140 +#: changelog.py:151 msgid "" "* old tweets shouldn't be added as new items in buffers. ([#116,](https://" "github.com/manuelcortez/TWBlue/issues/116)) ([#133](https://github.com/" @@ -1150,7 +1265,7 @@ msgstr "" "github.com/manuelcortez/TWBlue/issues/116)) ([#133](https://github.com/" "manuelcortez/TWBlue/issues/133))" -#: changelog.py:141 +#: changelog.py:152 msgid "" "* All mentionned users should be displayed correctly in Twishort's long " "tweets. ([#116,](https://github.com/manuelcortez/TWBlue/issues/116)) ([#135]" @@ -1160,7 +1275,7 @@ msgstr "" "hechos mediante Twishort. ([#116,](https://github.com/manuelcortez/TWBlue/" "issues/116)) ([#135](https://github.com/manuelcortez/TWBlue/issues/135))" -#: changelog.py:142 +#: changelog.py:153 msgid "" "* It is possible to select a language for OCR service from the extras panel, " "in the account settings dialogue. You can, however, set this to detect " @@ -1175,7 +1290,7 @@ msgstr "" "especiales o símbolos que no forman parte del alfabeto inglés. ([#107]" "(https://github.com/manuelcortez/TWBlue/issues/107))" -#: changelog.py:143 +#: changelog.py:154 msgid "" "* Fixed a problem with JAWS for Windows and TWBlue. Now JAWS will work " "normally in this update. [#100](https://github.com/manuelcortez/twblue/" @@ -1185,15 +1300,15 @@ msgstr "" "funcionar de forma correcta con este lector de pantalla. [#100](https://" "github.com/manuelcortez/twblue/issues/100)" -#: changelog.py:144 +#: changelog.py:155 msgid "* And more ([#136,](https://github.com/manuelcortez/TWBlue/issues/136))" msgstr "* Y más ([#136,](https://github.com/manuelcortez/TWBlue/issues/136))" -#: changelog.py:146 +#: changelog.py:157 msgid "## Changes in version 0.90" msgstr "## Cambios en la versión 0.90" -#: changelog.py:148 +#: changelog.py:159 msgid "" "* Fixed a bug in long tweet parsing that was making TWBlue to disconnect the " "streaming API. ([#103](https://github.com/manuelcortez/TWBlue/issues/103))" @@ -1202,7 +1317,7 @@ msgstr "" "desconectara el Streaming. ([#103](https://github.com/manuelcortez/TWBlue/" "issues/103))" -#: changelog.py:149 +#: changelog.py:160 msgid "" "* Now OCR will work in images from retweets. It fixes a bug where TWBlue was " "detecting images but couldn't apply OCR on them. ([#105](https://github.com/" @@ -1213,7 +1328,7 @@ msgstr "" "pudiera aplicar OCR en ellas. ([#105](https://github.com/manuelcortez/TWBlue/" "issues/105))" -#: changelog.py:150 +#: changelog.py:161 msgid "" "* TWBlue won't try to load tweets already deleted, made with Twishort. " "Before, if someone posted a long tweet but deleted it in the Twishort's " @@ -1226,7 +1341,7 @@ msgstr "" "problemas en todo el cliente. ([#113](https://github.com/manuelcortez/TWBlue/" "issues/113))" -#: changelog.py:151 +#: changelog.py:162 msgid "" "* TWBlue shows an error message when you try to view the profile of an user " "that does not exist or has been suspended. ([#114,](https://github.com/" @@ -1238,7 +1353,7 @@ msgstr "" "manuelcortez/TWBlue/issues/114) [#115](https://github.com/manuelcortez/" "TWBlue/issues/115))" -#: changelog.py:152 +#: changelog.py:163 msgid "" "* The spellchecker module should select the right language when is set to " "\"user default\". ([#117](https://github.com/manuelcortez/TWBlue/issues/117))" @@ -1247,7 +1362,7 @@ msgstr "" "apropiado cuando el idioma del cliente se establece en \"Idioma " "predeterminado\". ([#117](https://github.com/manuelcortez/TWBlue/issues/117))" -#: changelog.py:153 +#: changelog.py:164 msgid "" "* Image description will be displayed in retweets too. ([#119](https://" "github.com/manuelcortez/TWBlue/issues/119))" @@ -1255,7 +1370,7 @@ msgstr "" "* La descripción de imágenes se mostrará en retuits también. ([#119](https://" "github.com/manuelcortez/TWBlue/issues/119))" -#: changelog.py:154 +#: changelog.py:165 msgid "" "* When reading a long tweet, you shouldn't read strange entities anymore. " "([#118](https://github.com/manuelcortez/twblue/issues/118))" @@ -1263,7 +1378,7 @@ msgstr "" "* cuando se lea un tuit largo, no deberían aparecer símbolos extraños. " "([#118](https://github.com/manuelcortez/twblue/issues/118))" -#: changelog.py:155 +#: changelog.py:166 msgid "" "* TWBlue will not try to load timelines if the user is blocking you. ([#125]" "(https://github.com/manuelcortez/twblue/issues/125))" @@ -1272,28 +1387,28 @@ msgstr "" "a la cuenta actual. ([#125](https://github.com/manuelcortez/twblue/" "issues/125))" -#: changelog.py:157 +#: changelog.py:168 msgid "## Changes in version 0.88 and 0.89" msgstr "## Cambios en las versiones 0.88 y 0.89" -#: changelog.py:159 +#: changelog.py:170 msgid "* Fixed more issues with streams and reconnections." msgstr "* Corregidos más problemas con los streams y la reconexión." -#: changelog.py:160 +#: changelog.py:171 msgid "* newer updates will indicate the release date in the updater." msgstr "" "* Las actualizaciones más nuevas indicarán la fecha de lanzamiento en el " "módulo de actualización." -#: changelog.py:161 +#: changelog.py:172 msgid "" "* Changes to keystrokes are reflected in keystroke editor automatically." msgstr "" "* Los cambios en las combinaciones de teclado se reflejarán automáticamente " "en el editor de combinaciones de teclado." -#: changelog.py:162 +#: changelog.py:173 msgid "" "* In replies with multiple users, if the mention to all checkbox is " "unchecked, you will see a checkbox per user so you will be able to control " @@ -1303,7 +1418,7 @@ msgstr "" "todos no está marcada, verás una casilla para cada usuario, lo que te " "permitirá seleccionar a los usuarios que serán mencionados en la respuesta." -#: changelog.py:163 +#: changelog.py:174 msgid "" "* Fixed a bug that caused duplicated user mentions in replies when the tweet " "was made with Twishort." @@ -1311,7 +1426,7 @@ msgstr "" "* Corregido un error que causaba que TWBlue mostrara menciones duplicadas si " "el tuit había sido enviado mediante Twishort." -#: changelog.py:164 +#: changelog.py:175 msgid "" "* Retweets should be displayed normally again when the originating tweet is " "a Twishort's long tweet." @@ -1319,7 +1434,7 @@ msgstr "" "* Los Retuits deben mostrarse correctamente si el tuit original había sido " "enviado mediante Twishort." -#: changelog.py:165 +#: changelog.py:176 msgid "" "* Changed the way TWBlue saves user timelines in configuration. Now it uses " "user IDS instead usernames. With user IDS, if an user changes the username, " @@ -1332,7 +1447,7 @@ msgstr "" "cambia su nombre de usuario TWBlue todavía será capaz de crear la línea " "temporal. Esto no era posible anteriormente." -#: changelog.py:166 +#: changelog.py:177 msgid "" "* Added a new setting in the account settings dialogue that makes TWBlue to " "show twitter usernames instead the full name." @@ -1340,7 +1455,7 @@ msgstr "" "* Añadida una opción en el diálogo de opciones de cuenta que hace que TWBlue " "muestre el nombre de pantalla del usuario en lugar del nombre completo." -#: changelog.py:167 +#: changelog.py:178 msgid "" "* Added OCR in twitter pictures. There is a new item in the tweet menu that " "allows you to extract and display text in images. Also the keystroke alt+Win" @@ -1351,18 +1466,18 @@ msgstr "" "imagen del tuit seleccionado. También se ha añadido la combinación Alt + " "Windows +O para el mismo propósito en la interfaz invisible." -#: changelog.py:168 +#: changelog.py:179 msgid "* Now TWBlue will play a sound when the focused tweet contains images." msgstr "" "* Ahora TWBlue reproducirá un sonido cuando el tuit seleccionado contenga " "imágenes." -#: changelog.py:169 +#: changelog.py:180 msgid "" "* Your own quoted tweets will not appear in the mentions buffer anymore." msgstr "* Tus tuits citados dejarán de mostrarse en el buffer de menciones." -#: changelog.py:170 +#: changelog.py:181 msgid "" "* The config file is saved in a different way, it should fix the bug where " "TWBlue needs to be restarted after the config folder is deleted." @@ -1371,13 +1486,13 @@ msgstr "" "solucionar el error que requería borrar el directorio de configuraciones y " "reiniciar TWBlue." -#: changelog.py:171 +#: changelog.py:182 msgid "* Mentioning people from friends or followers buffers works again." msgstr "" "* Es posible de nuevo mencionar usuarios desde los buffers de seguidores y " "amigos." -#: changelog.py:172 +#: changelog.py:183 msgid "" "* Support for proxy servers has been improved. Now TWBlue supports http, " "https, socks4 and socks5 proxies, with and without autentication." @@ -1385,15 +1500,15 @@ msgstr "" "* Se ha mejorado el soporte para servidores proxy. Ahora TWBlue soporta " "proxys http, https, socks4 y socks5, con o sin autenticación." -#: changelog.py:174 +#: changelog.py:185 msgid "## Changes in version 0.87" msgstr "## Cambios en la versión 0.87" -#: changelog.py:176 +#: changelog.py:187 msgid "* Fixed stream connection errors." msgstr "* Arreglados errores en la conexión de los streams." -#: changelog.py:177 +#: changelog.py:188 msgid "" "* Now TWBlue can handle properly a reply to the sender without including all " "other mentioned users." @@ -1401,11 +1516,11 @@ msgstr "" "* Ahora TWBlue puede manejar correctamente las respuestas sin incluir a " "todos los usuarios del tuit original." -#: changelog.py:178 +#: changelog.py:189 msgid "* Updated translations." msgstr "* Traducciones actualizadas." -#: changelog.py:179 +#: changelog.py:190 msgid "" "* The status of the mention to all checkbox will be remembered the next time " "you reply to multiple users." @@ -1413,11 +1528,11 @@ msgstr "" "* El estado de la casilla para mencionar a todos se recordará la próxima vez " "que escribas una respuesta." -#: changelog.py:181 +#: changelog.py:192 msgid "## Changes in version 0.86" msgstr "## Cambios en la versión 0.86" -#: changelog.py:183 +#: changelog.py:194 msgid "" "* Fixed a very important security issue. Now TWBlue will send tweets to " "twishort without using any other server." @@ -1425,7 +1540,7 @@ msgstr "" "* Arreglado un error de seguridad muy importante. Ahora TWBlue enviará tuits " "hacia Twishort sin utilizar un servidor intermedio." -#: changelog.py:184 +#: changelog.py:195 msgid "" "* When you add a comment to a tweet, it will be sent as a quoted tweet, even " "if your reply plus the original tweet is not exceeding 140 characters." @@ -1434,7 +1549,7 @@ msgstr "" "citado, incluso si el comentario más el tuit original no supera los 140 " "caracteres." -#: changelog.py:185 +#: changelog.py:196 msgid "" "* Updated windows 10 keymap for reflecting changes made in the last windows " "10 build." @@ -1442,11 +1557,11 @@ msgstr "" "* Actualizado el mapa de teclado de Windows 10 debido a los cambios de la " "última build." -#: changelog.py:186 +#: changelog.py:197 msgid "* Added last changes in the twitter API." msgstr "* Añadidos los últimos cambios en el API de Twitter." -#: changelog.py:187 +#: changelog.py:198 msgid "" "* When replying, it will not show the twitter username in the text box. When " "you send the tweet, the username will be added automatically." @@ -1455,7 +1570,7 @@ msgstr "" "campo de texto. El nombre de usuario será añadido de forma automática al " "enviar el tuit." -#: changelog.py:188 +#: changelog.py:199 msgid "" "* When replying to multiple users, you'll have a checkbox instead a button " "for mentioning all people. If this is checked, twitter usernames will be " @@ -1465,44 +1580,44 @@ msgstr "" "lugar de un botón para mencionar a todos. Si es marcada, los nombres de " "usuario de Twitter se añadirán automáticamente al enviar el tuit." -#: changelog.py:190 +#: changelog.py:201 msgid "## Changes in version 0.85" msgstr "## Cambios en la versión 0.85" -#: changelog.py:192 +#: changelog.py:203 msgid "* Long and quoted tweets should be displayed properly In lists." msgstr "" "* Los tuits largos y citados deberían mostrarse correctamente en las listas." -#: changelog.py:193 +#: changelog.py:204 msgid "* The connection should be more stable." msgstr "* La conexión debería ser más estable." -#: changelog.py:194 +#: changelog.py:205 msgid "* Added an autostart option in the global settings dialogue." msgstr "" "* Se ha añadido la opción para iniciar después de iniciar sesión en Windows " "en el diálogo de opciones globales." -#: changelog.py:195 +#: changelog.py:206 msgid "* Updated translation." msgstr "* Se han actualizado las traducciones." -#: changelog.py:196 +#: changelog.py:207 msgid "* Updated russian documentation." msgstr "* Actualizada la documentación en ruso." -#: changelog.py:197 +#: changelog.py:208 msgid "* Tweets in cached database should be loaded properly." msgstr "* Se deben cargar correctamente los tuits en la base de datos." -#: changelog.py:198 +#: changelog.py:209 msgid "* Added some missed dictionaries for spelling correction." msgstr "" "* Se han añadido algunos nuevos diccionarios en el módulo de corrección " "ortográfica." -#: changelog.py:199 +#: changelog.py:210 msgid "" "* Timelines, lists and other buffer should be created in the right order at " "startup." @@ -1510,15 +1625,15 @@ msgstr "" "* Líneas temporales, listas y otros buffers deberían ser creados en el orden " "correcto al iniciar TWBlue." -#: changelog.py:201 +#: changelog.py:212 msgid "## Changes in version 0.84 " msgstr "## Cambios en la versión 0.84 " -#: changelog.py:203 +#: changelog.py:214 msgid "* More improvements in quoted and long tweets." msgstr "* Más mejoras en los tuits largos y citados." -#: changelog.py:204 +#: changelog.py:215 msgid "" "* Updated translations: Russian, Italian, French, Romanian, Galician and " "Finnish." @@ -1526,7 +1641,7 @@ msgstr "" "* Actualizadas las siguientes traducciones: Ruso, italiano, francés, rumano, " "gallego y finlandés." -#: changelog.py:205 +#: changelog.py:216 msgid "" "* Improvements in the audio uploader module: Now it can handle audio with " "non-english characters." @@ -1534,7 +1649,7 @@ msgstr "" "* Mejoras en el módulo de carga de archivos de audio: Ahora es capaz de " "manejar archivos de audio con caracteres especiales." -#: changelog.py:206 +#: changelog.py:217 msgid "" "* the title of the window should be updated properly when spellcheck, " "translate or shorten/unshorten URL buttons are pressed." @@ -1542,7 +1657,7 @@ msgstr "" "* El título de la ventana debe actualizarse correctamente cuando se utilizan " "funciones como corrección ortográfica, traducción o acortar / expandir URL." -#: changelog.py:207 +#: changelog.py:218 msgid "" "* the bug that changes the selected tweet in the home timeline shouldn't be " "happening so often." @@ -1550,11 +1665,11 @@ msgstr "" "* El error que hacía que el tuit seleccionado cambiara en la interfaz " "visible debería estar parcialmente corregido." -#: changelog.py:209 +#: changelog.py:220 msgid "## Changes in version 0.82 and 0.83" msgstr "## Cambios en las versiones 0.82 y 0.83" -#: changelog.py:211 +#: changelog.py:222 msgid "" "* If the tweet source (client) is an application with unicode characters " "(example: российская газета) it will not break the tweet displayer." @@ -1563,7 +1678,7 @@ msgstr "" "caracteres Unicode en su nombre (por ejemplo: российская газета), el " "visualizador de tuits lo podrá mostrar adecuadamente." -#: changelog.py:212 +#: changelog.py:223 msgid "" "* Added a new field for image description in tweet displayer. When " "available, it will show description for images posted in tweets." @@ -1572,7 +1687,7 @@ msgstr "" "tuits. Cuando estén disponibles, se mostrarán descripciones para las " "imágenes en el tuit." -#: changelog.py:213 +#: changelog.py:224 msgid "" "* users can add image descriptions to their photos. When uploading an image, " "a dialog will show for asking a description." @@ -1580,15 +1695,15 @@ msgstr "" "* Los usuarios ahora pueden añadir descripción a sus fotos. Al subir la " "imagen, aparecerá un diálogo para que se proporcione una descripción." -#: changelog.py:214 +#: changelog.py:225 msgid "* Redesigned upload image dialog." msgstr "* El diálogo para subir imágenes ha sido rediseñado." -#: changelog.py:215 +#: changelog.py:226 msgid "* Fixed photo uploads when posting tweets." msgstr "* Se ha corregido la carga de imágenes al publicar tuits." -#: changelog.py:216 +#: changelog.py:227 msgid "" "* When getting tweets for a conversation, ignores deleted tweets or some " "errors, now TWBlue will try to get as much tweets as possible, even if some " @@ -1598,23 +1713,23 @@ msgstr "" "los tuits eliminados y algunos errores comunes. TWBlue cargará la mayor " "cantidad de tuits posible." -#: changelog.py:217 +#: changelog.py:228 msgid "* Added audio playback from soundcloud." msgstr "* Añadida la reproducción de audio desde Soundcloud." -#: changelog.py:218 +#: changelog.py:229 msgid "* Now the session mute option don't makes the screen reader speaks." msgstr "" "* Al silenciar una sesión, el lector de pantalla ya no anunciará ningún " "contenido automáticamente." -#: changelog.py:219 +#: changelog.py:230 msgid "* Fixed the direct message dialog. Now it should be displayed properly." msgstr "" "* Corregido el diálogo de mensaje directo. Ahora debería mostrarse " "correctamente." -#: changelog.py:220 +#: changelog.py:231 msgid "" "* when a tweet is deleted in twitter, TWBlue should reflect this change and " "delete that tweet in every buffer it is displayed." @@ -1622,7 +1737,7 @@ msgstr "" "* Cuando se elimina un tuit, TWBlue debería reflejar el cambio y eliminar el " "tuit de todos los buffers donde se muestra." -#: changelog.py:221 +#: changelog.py:232 msgid "" "* If your session is broken, TWBlue will be able to remove it automatically " "instead just crashing." @@ -1630,12 +1745,12 @@ msgstr "" "* Si la configuración de una sesión ha sido dañada, TWBlue debería ser capaz " "de eliminarla y continuar en lugar de no abrirse." -#: changelog.py:222 +#: changelog.py:233 msgid "* audio uploader should display the current progress." msgstr "" "* El diálogo de carga de archivos de audio ahora muestra el progreso actual." -#: changelog.py:223 +#: changelog.py:234 msgid "" "* users can disable the check for updates feature at startup from the " "general tab, in the global settings dialogue." @@ -1643,7 +1758,7 @@ msgstr "" "* Es posible desactivar la comprobación automática de actualizaciones en el " "diálogo de opciones globales, en la pestaña General." -#: changelog.py:224 +#: changelog.py:235 msgid "" "* The invisible interface and the window should be synchronized when the " "client reconnects." @@ -1651,12 +1766,12 @@ msgstr "" "* La interfaz invisible y la ventana gráfica deben estar sincronizadas " "cuando el cliente se reconecta." -#: changelog.py:225 +#: changelog.py:236 msgid "* The documentation option in the systray icon should be enabled." msgstr "" "* La opción de documentación en la bandeja del sistema se encuentra activa." -#: changelog.py:226 +#: changelog.py:237 msgid "" "* In trending buffers, you can press enter for posting a tweet about the " "focused trend." @@ -1664,7 +1779,7 @@ msgstr "" "* En buffers de tendencias, puedes pulsar enter sobre cada tendencia para " "publicar un tuit acerca de ella." -#: changelog.py:227 +#: changelog.py:238 msgid "" "* Updated russian documentation and main program interface (thanks to " "Natalia Hedlund (Наталья Хедлунд), [@lifestar_n](https://twitter.com/" @@ -1673,19 +1788,19 @@ msgstr "" "* Actualizada la documentación e interfaz en ruso (gracias a Natalia Hedlund " "(Наталья Хедлунд), [@lifestar_n](https://twitter.com/lifestar_n) en twitter)" -#: changelog.py:228 +#: changelog.py:239 msgid "* updated translations." msgstr "* Actualizadas algunas traducciones." -#: changelog.py:230 +#: changelog.py:241 msgid "## Changes in Version 0.81" msgstr "## Cambios en la versión 0.81" -#: changelog.py:232 +#: changelog.py:243 msgid "* Updated translations" msgstr "* Traducciones actualizadas" -#: changelog.py:233 +#: changelog.py:244 msgid "" "* The updater module has received some improvements. Now it includes a " "Mirror URL for checking updates if the main URL is not available at the " @@ -1696,24 +1811,24 @@ msgstr "" "una URL con información de actualizaciones de respaldo por si la dirección " "principal no funciona." -#: changelog.py:234 +#: changelog.py:245 msgid "* some GUI elements now use keyboard shortcuts for common actions." msgstr "" "* Algunos elementos de la interfaz gráfica ahora utilizan atajos de teclado " "para acciones comunes." -#: changelog.py:235 +#: changelog.py:246 msgid "* fixed a bug in the geolocation dialog." msgstr "" "* Corregido un error en el diálogo para mostrar la información geográfica en " "Tuits." -#: changelog.py:236 +#: changelog.py:247 msgid "* the chicken nugget keymap should work properly." msgstr "" "* El mapa de teclado de chicken Nugget debería funcionar correctamente." -#: changelog.py:237 +#: changelog.py:248 msgid "" "* Added a new soundpack to the default installation of TWBlue, thanks to " "[@Deng90](https://twitter.com/deng90)" @@ -1721,11 +1836,11 @@ msgstr "" "* Se ha añadido un nuevo paquete de sonidos a la instalación predeterminada " "de TWBlue, gracias a [@Deng90](https://twitter.com/deng90)" -#: changelog.py:238 +#: changelog.py:249 msgid "* Now the changelog is written in an html File." msgstr "* La lista de cambios ahora está escrita en un archivo HTML." -#: changelog.py:239 +#: changelog.py:250 msgid "" "* Added some missed dictionaries in last version for the spell checking " "feature." @@ -1733,7 +1848,7 @@ msgstr "" "* Se han añadido algunos diccionarios al módulo de corrección ortográfica " "que no habían sido añadidos en la última versión." -#: changelog.py:240 +#: changelog.py:251 msgid "" "* Trimmed the beginnings of the sounds in the default soundpack. Thanks to " "[@masonasons](https://github.com/masonasons)" @@ -1742,7 +1857,7 @@ msgstr "" "de sonidos predeterminado. Gracias a [@masonasons](https://github.com/" "masonasons)" -#: changelog.py:241 +#: changelog.py:252 msgid "" "* Added Opus support for sound playback in TWBlue. Thanks to [@masonasons]" "(https://github.com/masonasons)" @@ -1750,7 +1865,7 @@ msgstr "" "* Añadido soporte al códec Opus en TWBlue. Gracias a [@masonasons](https://" "github.com/masonasons)" -#: changelog.py:242 +#: changelog.py:253 msgid "" "* Added a source field in view tweet dialogue. Thanks to [@masonasons]" "(https://github.com/masonasons)" @@ -1759,14 +1874,14 @@ msgstr "" "el visualizador de tuits. Gracias a [@masonasons](https://github.com/" "masonasons)" -#: changelog.py:243 +#: changelog.py:254 msgid "" "* You can load previous items in followers and friend buffers for others." msgstr "" "* Se pueden cargar más elementos en los buffers de seguidores y amigos de " "otros usuarios." -#: changelog.py:244 +#: changelog.py:255 msgid "" "* The Spell Checker dialogue should not display an error message when you " "have set \"default language\" in the global settings dialogue if your " @@ -1777,20 +1892,20 @@ msgstr "" "tu idioma se encuentra soportado. [#168](http://twblue.es/bugs/view.php?" "id=168)" -#: changelog.py:245 +#: changelog.py:256 msgid "* Updated romanian translation." msgstr "* Actualizada la traducción al rumano." -#: changelog.py:246 +#: changelog.py:257 msgid "* Some code cleanups." msgstr "* Limpieza del código." -#: changelog.py:247 +#: changelog.py:258 msgid "* The bug reports feature is fully operational again." msgstr "" "* El sistema de reporte de errores es completamente operativo de nuevo." -#: changelog.py:248 +#: changelog.py:259 msgid "" "* TWBlue should work again for users that contains special characters in " "windows usernames." @@ -1798,24 +1913,24 @@ msgstr "" "* TWBlue debería funcionar de nuevo para usuarios que contienen caracteres " "especiales en sus nombres de usuario de Windows." -#: changelog.py:249 +#: changelog.py:260 msgid "* Added more options for the tweet searches." msgstr "* Añadidas más opciones para las búsquedas en Twitter." -#: changelog.py:250 +#: changelog.py:261 msgid "* Added play_audio to the keymap editor." msgstr "* Añadida la función play_audio al editor de mapas de teclado." -#: changelog.py:251 +#: changelog.py:262 msgid "* Windows key is no longer required in the keymap editor" msgstr "" "* La tecla Windows ya no es obligatoria en el editor de mapas de teclado" -#: changelog.py:252 +#: changelog.py:263 msgid "* Switched to the Microsoft translator." msgstr "* hemos pasado a usar el servicio Microsoft translator." -#: changelog.py:253 +#: changelog.py:264 msgid "" "* You can update the current buffer by pressing ctrl+win+shift+u in the " "default keymap or in the buffer menu." @@ -1823,21 +1938,23 @@ msgstr "" "* Puedes actualizar el buffer actual pulsando ctrl+win+shift+u en la " "interfaz invisible o desde el menú buffer." -#: changelog.py:254 +#: changelog.py:265 msgid "* Changed some keystrokes in the windows 10 default keymap" msgstr "" "* Cambiados algunos atajos de teclado en el mapa de teclado de Windows 10" -#: changelog.py:255 +#: changelog.py:266 msgid "* New followers and friends buffer for user timelines." msgstr "* Nuevos buffers de amigos y seguidores para otros usuarios." -#: changelog.py:257 +#: changelog.py:268 msgid "---" msgstr "---" -#: changelog.py:258 -msgid "Copyright © 2014-2017, Manuel Cortez." +#: changelog.py:269 +#, fuzzy +#| msgid "Copyright © 2014-2017, Manuel Cortez." +msgid "Copyright © 2014-2021, Manuel Cortez." msgstr "Copyright © 2014-2017, Manuel Cortéz." #~ msgid "" diff --git a/src/locales/es/LC_MESSAGES/twblue.mo b/src/locales/es/LC_MESSAGES/twblue.mo index 6a57f84e650ac26c3934f0a4a884f79bd6af5c08..41660d8d59c96d760f0f2d4bdfc1dd408d1143f9 100644 GIT binary patch delta 19359 zcmZwO2Yggj-p26>DI~PedzsK%BB2VR^xms4A)>tJDQj79JP?1w$DJU)wM zaTk`vR(I>emY^;V@gCfVyus#^6#c zg-@f#*@jhcPq;nkaC}OpAQk7W-=bD{1+}1vPG+EZRDD@g|9Ys1BwJfyG0GiK3+Rv0 zn2K7s2X$XAYQxj8IP*Imu@x&Yn(}(o&Ynlz@G4fr{a6maz-asvwZmJeiK99@9Hp@o zYNvHk3u%n;*ugpgb$==b6$%fTNSued@iEkmPht#iMBT6zwUZEP2m4VAJc^3MDb#&u zQ4{`X+i%+Ts4k{|QPe`qbm94HNA;=Dj@#RYKB$S(P!r|Y@)TR1hg#4QTYd`lsGh?Z z+>RP|Hx|Sb*3+m+T|h1HY8T?Kfo@Zwl}C3q6PLvjl&hn5))e)2+>dQ=7#75psDA5E z3*BMs_oEhc*tUO+TF`g4{x)i%MT6bUK&7!Y6_rtsVkm0Bk=6{1qwGgbIL+2CMxBk7 zw)`3@a&KcSozD;~?Ck_kTN?%~TBUX+jd!%i(B5xiC(|)|iYt zPz(4LHSkqb2(O_waKl=#w~0V$)WV(E4C|x%J%lwd3(GRU;|VfFso0F#`7YFs-a|d} z3#gsm!ireEkD1_p)B?I;A?%CV>2O=0idyhk)cAhXqnnBR$C1yE80L3ev<;Uqp7KpB zhDG|Ci7H`r%5_i^bVu#1zb%hIEhNo4&er=-AFRo!g)g+_&8P_M#h_OB1sM(ez3uQb zDgu%HOno_wqFfC%QBBktXkgoutu3wXP?7A0>OUIw?H_|Ba2jg9#r=qXaWc!PaN=g$ z;Rx!qo<%M2Z`6cQ{mp=dPzx$y%Vkj$R~XQDFdFf~H;?}6Ic5Y$4(U;+lwiEB}jJ&1awM^XJQAqx#U zA|EuL#yC_+6R;sRLjEk`7>Q+YA}VwXQHN@|b(O8(fI2JNP!ZUT8t)C%29Kk5`~`Nx zuQ5jNfBhlm#$;%cMPM>&hx4#5F2+RMjg9bIEQ{rantn;B za&xT6{El8^w6hG<+u*}eI2(0%mfQA_t>1@Q&`H$9r%?;KfQrCXTYnwPQFaV75iE~t zPeRSt0)rZ;9T}b0u2=zwAon_aw*EcTFOAPpkKzWZUvWOc+lBh3UqnrO1+~x{sApbuw0R9Hq88c- z^$7Z)CK`q6pM%`un2p-tSNH~gkBZc$;6o-v+favM2P$;OP#=houpTN5wV*yGVPDh$ zK~!kxp?)havgIYHg{?rHspn7&*kRjW!|?qFY{e1O#3xWUd}hm+P#v$KcK$c&aK@&X z0V|_ISsm4WFDmq%Q1=Z&Eo3C>%%r2v#7rczLC0J&`hYA!t#FMkZ$v$U9mvPfu^($= zsZ`Uy73vGu6?NZ8R3uVS8yJhae~N9Ni(1G6)WViwRlWbK$mm(^Lp{S2s2zTR;hkIm zwnnCzXIvPy@G8~@s0g-1-QOM+iNUr!2DQ-17=<%1j`RQy056)?7SRSrCb%&|9;fQx}hR50=3|D)P1=atWG9KMj=~=x*>!G@Et6V zN02wl@fB*~wqwiyBTkD!&u&$V6BhQv^PQRu%#_`K`po!#^6{~B*xqJsTst-AQiKyP{`(^ z7PQQE+=-nizlj^LOQ;({s1M2>)D6c_{ZFG#{}-r!zuEd5sQwXS%_Ay>I*e5?5tC8(k47ylIEIWu zmW!HTHtH-qj&*S@Dl$h=1Ak)Mzei2{muMw_8F(jhF* ze-N1>RHUOO44@(~4YiO(r~y`>ZhRTFpo6H_^c*_zZ>))xv&>&u+M!On9}{pcDngr4 zuk~)VGr!|B8HMsP>RJ7Qg)utYJmV6ma&1%u8lwhkg+;JCYQYcM`V7=~lTc@AI%>k% zs5A2%*1_EvR0uDS(N1rmRvhg$ho?O1nN_#tdbZremRsQ<+B;%0u0&1z9%{T(sD+)w zc)Ws&@IR=H6wKlMS7_pM%o#{VP1pt1p*QM=!M1)h#!()FibxJBVpCE5AGbb*#VD`A z{ac!~tuP{B-uu?r zi1GwX#7(F(@i9JvH?S|x&NY8D`zT1JHWfc&b1XH%{NC@5^mRx8e@`7WJuqdXo90*@+d0Qr%)03 z-1?)fzlo)(kC|fHD`8Q}4N#A!CF*VIggOfkq8>>K>M)K+&RWp%1evl_tVbQjy{H9z zjCwTZZ2Lv)4b+(_G1Z*@Ca49r#p2i(wE!3D5oXzPz_!moJ<=yIPQU+`kA5rl%HnqtBHDR5>XLri`r>->rm8&GBA8-QS(g2c;o2?EM}hioq+n1P zFPU;U6|3M<)CylgMP?6bM+Z@lZpEoP#bJE zgZS%^bfrSia2RSwV^KQ}SRX|#Xcem822@CQqVC^^TG$5|K0BC1`5bDTA~VgOjuTMr zwa|%)Gg+ZR*_(=d9F2|e8fphMXPNi<0aRorp$1-t3HUaq;dfXKd(Jlhwv&lfDZh?d z_*sm^uTW>|ThxMY1#KpBj`^U(p;lNO74rJ1fm_=4p{O1CP-kWyYQU#$`4ucf`5o)$ zw*FVtBaV64++P(dQw}z<6@5_yx~+M(exWU|v+lxZ`W>~Nz$nU}pawjP+Q4Y!)WxQ7LJf}XO*8|wpnUu( zg6{{mqP+Yuv(rzd`l;!`4SEG>5kss=XoVEZmRb_kR!>?IZ|FV?l1U+u>=;UTnV+{hPJ*L>dXY&kkRYb6BU~NsF3EM2Aqgm z;5_R})IeKN&vqATr|;YH8C0ZxMV*;jsMovZ5>xL%-4`(Bpko0UO}HFO;wsb*w__!I z8?}QkQ4#qSwSXI_fg|%xeOFY!zNk>UtX@=vrlB^p3~S*=ETZ54@7adWtUq9NI{bx6 zSb3@Wx1JuTvoZlSP(Es>&!Ha8OIQ!zMlJBF^*SoT5l@=mDFsmxNWfCe?`TOzEANH+ zB{2#$Knf1SahQtl;9FRK87CgEq9V6+?uAw^KMEyY|W`)^ld#p>jKbFBMsQaG4(zqJ6qaCPc{vIacHB>|rR+@$OKt-ZI zDsn?s5`V2I)pp3l5|sT|3LnNAxB|Q5KGcq5pEmvCQHM4GD`Fee&W2%g^q|hn8q_?S zZF#$O&(p+T4F_z8qo|#Hh}y|z)W9X5F@G#iMD-tv+DQtQ#0=EJr`Yy|sD&;=E#O&O z-hhhmi>PsS1#O4@sL&p^<#VW=eSVr{el{pjTQ1{ir3fKrWaCcPy{-}ke z+Hx-Ht(lAJzYNPWzvE>xIz&fMH=IX3^Pf=*DZSbpmKvx-m4upj1Uk`;b#bnB8`hzG z8hfB)jcMLX0>h~o!#6M8|YpgRHOU9y_zbzT3`6c$D$_kp(dJQ+h?I(=OrSECcRqat$(wZki@M{ymsu<{$tcnPRSQFkNp*GigGAs;|Jiq5Esyr_X5!RojK z)o&+i=lie@p1@SRj#|)&O=cn4sMl;h>d>vl%J?eA;736+TG?6DL| zf*G(KD&$?UHKw3;vKnjRE^L8ku`ZT+(M;4D^_}R9I!gmk_obmWG6l7uji#OVpNvlV z0o1d*h-r8m)iG@={}zDR7>gZWGWNn6ln2}LWNb=#Ha5fE=)^0i@#D9d`;t)+YlYEz z|J#v?r=kn$+y5ZyS$k0nSb_@uGpLZSM=j)e)IcFrziK{M4R9Fcj;P44wr;V8tou-BDtMTTCOD1?%|+DfaupT&61z<#%A;q1ojeCvADquYt)@J&?z(-{8uzw>0uQt>@%;M=HY8~d91XS9l_os2*& zAQko2_-%QXbqUs`ew}SUh7~BE!SeVUDgs6K+S8BWfB&ydMiaKQ4LwkgWEg5eIj9BX z+4dQzL$(+-@GGc+kD>Z~jMeaS)LU~CHBQ9qrhg$+xdsL`KtnPLQ76JLuG{%d~!7J(9gx5s%vPH>imGh8p*8EQQ7PoAIje51Jd=Q=vmK z5;brt*2i&J8<$~A+=q$yCn|)s-ZY0Q33WC)qb3}TdL$!J{nD*Dm`OPgo8h-XGP=wblgy0bT^pKgT(c8ursE9p)IvX8P0}i(Jqflom4dZ_B^bEGf@+7!G*XR@4?QWn21ck_LP^R4(F%X41Yl<*7?-@HM}cU z*YE#*WX92O0c&E<(`Lf)s7U0YA~VObDy8x^1-W z2d(d-#(N)YGr!|QGFre5)W8MKm=G66t+XPly(VhHhS&oe+xqFK3Fl%tTxjbzU|~Mp zTT!pyp0nmKAI1ulPh7I)!(GiwtSiV zY};?D>F)TDwoj?cp*)oQBcy23e##q2I<()={sAeDv0tZLE|U1KBJ(npH|VTa=?3{d z_$p=I7RPSN|Lv+seQ~`aT;Gt!&|hzeE=5gO3wy7VwgWb=->SM+kX{W^`6Cs3Dbywn zB!AF$jI~njI8A+3(%;l2sKQ>)Q>RBYADhz_$%4Knuj>%yzU14G;_O%x$&Vn_qr3@& zMfsuYVf5Qh!%dZ=I(5~l`y4Y!f09onH6nkAboW(^`dXwr*SF;N+dj$UV@PF4?^1Wh z*3T`#^FPKNy+{p79qCZShExOH&<}ex7ik!&n4Q2jIc`yY zgLIL$+4vFas-Wku>j^4#A}666IiQZxbov(c4Txq@W$eO4CDK2%zeO6xJ(X}2=`#6m zN&CoWl0G2+D1CK3Mqbxd>ucnn()_2WC`&rQ4X>&Pmxt7gx~aDFU$p7+QZ7h-Iv+}`hKVHe`hi!sr&)wlHR7Xt~pql z`r)Jjwr(1(C2gd=6gwMCTP{i0Ls*lx8u&J8C+QK&>q)WXPmoHH=90?VN4dHH@&A<$ zy8a;*qhTK%bbUd3i+oek7o@4S-&pJK)b%8-p!^*v6u!&+h@<`_bzMoVsCtA{pZxEn z)wJEY?$P`II28k^@sq|-K8g!b*ASdR>Tk=Y_CG)0A={Gs>yR4Sfv;O@Vl?+HwdIcZ zC20w%3#kE#{hRAOI{u(Wimh=1X%cm7C_h9>BL4~&z|ur1hxWHA>q;kIk-D?Ac`5%v zxeWeE`i#1}uLmeJrah7LoaS#!hYv~DNnL5&i`Pi{v%m+W`{}rsq+dMcsDBUpk;*fn zu0hnTpk3EXm_*9A<>|CFp?(ypG5HKq8`1>Q7SfM;{<`u>yTZBu{1{=g+16ii2{$b# zeMQ$S;|6c8FVWZUiJ;=;L7pW6By-&G2X(_25b-EJC z-%rxDz!3h~jh}DW^4F+e)1~OQ5{t5kUgXa*rvB}BCi(YqH*I;OM=1vvQ1Js9T@R9; z3Fpi|xhk7X`$Ceg&Gd`L4)|BNhJW#(Z9VzZq!dyTski#mr=q>DF~yOjanvoNt_SHn z`8T!ybrd|L&*`A+HS%xJI0f&%^rq-qU{!t!=}pR~Njpd}+%wAFcayeF)J-9cC4Y_j z5#;Y&+bIu;u+M*}ZD>tvj6GPh=uprO_7(M4>GKom7xHWGjDiiQTWR~nQ9eppS8FUy z{YRwQwoZSHdm`Lw{`z%&Drp~Sw4VR=y9WD|4!_Ybk@Nud50j#ppd4i%=`qTR zSSS3F6iNSM_#t)iIFB@r{QteS-BmH4KL5EGttk~F8K|Xgh`N=1QU{lJc@IjKUJS;@&LjEiI+_~D4f0^`_t*Bu82VbNj%2v86XVdtX;Pq>fyLY@I2w{{!T{B-P=jIhc+v zI-Mkc5~q>wBmG7?Oxt374t1qqB|`owdAI6Gy6PIjKSR_Nr(a1@6!}>CzlW8=eTjcb zDyq=^{EN+hLj85ht!#N0WnC}eyC&<{M%zuw-`Tc4 z=%lT^%6k5{>9CmejvZt?4f<=7uC3%_a2(DfJxso`?RQHZ>{S6XNlj?WvhCgJufKX1 zM_mQ174R5o5p}_P$qctQsM9r4E$W`dj-<)76($A9AE!Q&d~cG6bey^xm`j>L+s`^MOF zG4d~yYT3F$m}c`o;UwkhcLK&M&sB)W?PR={!ebKuQ&bkA)01|Ra4&wGA&s|nKhb`{ zHvEnUDgQ$%Ouo0RKS$r2q#tehZtkN#f{CY5d4#moHqO++T14XuR6LJsDc2z1l2m{j z%23u7fqk(Wb@j;KN4^6on|tnDSIBrN7qNBs-)XS^YR9Td`(f&uQw}zLM6kPTlGZMhAlkI5&Hp0W3C#LuYDwq@NglN3*Sk-9$gJ!9`z+eq^Hq)+tsKV6T~ z=_yh?>CV-T%v1KJ?c}e}_WE6es9yqgn@O{%FG~4wQab58bvd^0XXHndze;^&qIZ$< zovU!fKwdjr@f)39Ag!T1-}dNfoq#2{xj2@k&%O9HULpNKz6JNBkZzM_Z>!pV8hWJN zq5}EVJ5J5t(D7RS!cL>}Z*^K3Q#&m!DJd!c$<7C&ojKmj%>2Gxs>J2`-9D!))8op2 zs!QYO+7sRGK>k}@=Eu3yoC8(xhq`w?5EGN(^`yG}p}0OBBFZ~mfq*MDBg>r~aCCHM zx&v-!KwU$f`Ywxdy3*1-+39!p>E!cyea=*Gn%g<0(X`M<1AmAKy*m69-|ftDjdMHwxwPhabA4u32F}XK^tk=biJm|P zi}nNpZeN`NcMah5B&Zf?s3~#{ePYTT)xh67RTOH%cWJYJUE6W{9aFr@h znk~7ry}9Wb3^&H>%W?%g-cWMt(ukos-?e$jJ>j z)7%q?yQ9y6ni53qk z#qG?^$@IDyGXJ{gxzOgZ{@BnEf5oWKq>0Z&gzm{399f0HItGWsON@9zb?YZ(vB6&eQx$lq&WuQ3G>*88P(Sj51MW`@3^kYGN;cx+g8MeQvrxaiF)AbIHTy zY82|*C$T^0&(CQ~?C1)(TR9syYMh*y%zqj?lbf_^+%j}#&X5A3PV*{7=4Z}d5{i1P zT10+@1v&XE7wj$6?$CBun#ZRv&cKD=#JaOniAKPc-)K?Q{I-jV>xEpC)sB8VI_<%JoRrn)$(_vyEX{T2 z>lEH5OXTYm-d+Z;wTn-bhdMUKH!t+Vrk|oJ4Lr0pkejJ4nc=UM&&$#?1Fr0VJM{63 z{R&j*X1-IYofz^AOaa@0Q8w!)0>%a+zGy{9@bdB@Fbq zvvR!79GB0fALfJQbJk_$X@|DD_)<0BUOj*G_7184C4B5X!EySK*Wb{|!Qh)^&V-pH(?wLw*$RKST&Z41CtDHPxc%vfP`}W%$Z7-lMU@&JFdWuH zTlLWouhO5J;_>Boc=dFs?(X;FLM;x)MTfc`{x~9Z?~%l)TH%h4c6UwyD>RSf-=DJ7 z<82DG4u8r#K8+u+0nZ7~@SmtF;^AYE!*4^MlaH7$&E?DVCWW5_2!Eswt<84uWy*A?dmVg>OiTFdb7(6c>+lyxo%zUk9pR4(q44K$ ooV=M1z8DP5H-ewt%vZsyFTCQF>hh)YUgfu$UnUfPYD?7r0F%+~{r~^~ delta 17412 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 D&n251 diff --git a/src/locales/es/LC_MESSAGES/twblue.po b/src/locales/es/LC_MESSAGES/twblue.po index 452cd695..55b892fd 100644 --- a/src/locales/es/LC_MESSAGES/twblue.po +++ b/src/locales/es/LC_MESSAGES/twblue.po @@ -1,8 +1,9 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.84\n" -"POT-Creation-Date: 2021-11-01 05:25-0600\n" -"PO-Revision-Date: 2021-11-01 05:44-0600\n" +"Report-Msgid-Bugs-To: manuel@manuelcortez.net\n" +"POT-Creation-Date: 2021-11-12 13:22-0600\n" +"PO-Revision-Date: 2021-11-12 13:29-0600\n" "Last-Translator: Manuel Cortez \n" "Language-Team: Manuel Cortez \n" "Language: es\n" @@ -15,1839 +16,90 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SourceCharset: UTF-8\n" -#: ../src\controller\attach.py:25 -msgid "Photo" -msgstr "Imagen" - -#: ../src\controller\buffers\base\base.py:91 -msgid "This action is not supported for this buffer" -msgstr "Esta acción no se encuentra soportada para este buffer" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:337 ../src\controller\settings.py:286 -msgid "Home" -msgstr "Inicio" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:339 ../src\controller\settings.py:287 -msgid "Mentions" -msgstr "Menciones" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:341 -msgid "Direct messages" -msgstr "Mensajes directos" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:343 ../src\controller\settings.py:289 -msgid "Sent direct messages" -msgstr "Mensajes directos enviados" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:345 ../src\controller\settings.py:290 -msgid "Sent tweets" -msgstr "Tuits enviados" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:347 -#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:291 -msgid "Likes" -msgstr "Tuits marcados como me gusta" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:292 -msgid "Followers" -msgstr "Seguidores" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:353 -#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:294 -msgid "Blocked users" -msgstr "Usuarios bloqueados" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:355 -#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:295 -msgid "Muted users" -msgstr "Usuarios silenciados" - -#: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:293 -msgid "Friends" -msgstr "Amigos" - -#: ../src\controller\buffers\twitter\base.py:76 -msgid "{username}'s timeline" -msgstr "Línea temporal de {username}" - -#: ../src\controller\buffers\twitter\base.py:78 -msgid "{username}'s likes" -msgstr "Tuits que le gustan a {username}" - -#: ../src\controller\buffers\twitter\base.py:80 -msgid "{username}'s followers" -msgstr "Seguidores de {username}" - -#: ../src\controller\buffers\twitter\base.py:82 -msgid "{username}'s friends" -msgstr "Amigos de {username}" - -#: ../src\controller\buffers\twitter\base.py:84 -msgid "Unknown buffer" -msgstr "Buffer desconocido" - -#: ../src\controller\buffers\twitter\base.py:88 -#: ../src\controller\buffers\twitter\trends.py:122 -#: ../src\controller\messages.py:214 ../src\wxUI\buffers\base.py:25 -#: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 -#: ../src\wxUI\dialogs\message.py:304 ../src\wxUI\sysTrayIcon.py:35 -msgid "Tweet" -msgstr "Tuit" - -#: ../src\controller\buffers\twitter\base.py:89 -#: ../src\controller\buffers\twitter\trends.py:123 -msgid "Write the tweet here" -msgstr "Escribe el tuit aquí" - -#: ../src\controller\buffers\twitter\base.py:219 -msgid "New tweet in {0}" -msgstr "Nuevo tuit en {0}" - -#: ../src\controller\buffers\twitter\base.py:222 -msgid "{0} new tweets in {1}." -msgstr "{0} nuevos tuits en {1}." - -#: ../src\controller\buffers\twitter\base.py:261 -#: ../src\controller\buffers\twitter\directMessages.py:88 -#: ../src\controller\buffers\twitter\people.py:180 -msgid "%s items retrieved" -msgstr "%s elementos recuperados" - -#: ../src\controller\buffers\twitter\base.py:293 -#: ../src\controller\buffers\twitter\people.py:80 -msgid "This buffer is not a timeline; it can't be deleted." -msgstr "Este buffer no es una línea temporal. No se puede eliminar." - -#: ../src\controller\buffers\twitter\base.py:430 -msgid "Reply to {arg0}" -msgstr "Responder a {arg0}" - -#: ../src\controller\buffers\twitter\base.py:432 -#: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 -msgid "Reply" -msgstr "Responder" - -#: ../src\controller\buffers\twitter\base.py:433 -msgid "Reply to %s" -msgstr "Responder a %s" - -#: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\buffers\twitter\directMessages.py:130 -msgid "New direct message" -msgstr "Nuevo mensaje directo" - -#: ../src\controller\buffers\twitter\base.py:480 -#: ../src\controller\messages.py:200 -msgid "Direct message to %s" -msgstr "Mensaje directo a %s" - -#: ../src\controller\buffers\twitter\base.py:520 -msgid "Add your comment to the tweet" -msgstr "Añade tu comentario al tuit" - -#: ../src\controller\buffers\twitter\base.py:520 -msgid "Quote" -msgstr "Citar" - -#: ../src\controller\buffers\twitter\base.py:596 -msgid "Opening URL..." -msgstr "Abriendo URL..." - -#: ../src\controller\buffers\twitter\base.py:633 -msgid "User details" -msgstr "Detalles del usuario" - -#: ../src\controller\buffers\twitter\base.py:654 -msgid "Opening item in web browser..." -msgstr "Abriendo elemento en el navegador..." - -#: ../src\controller\buffers\twitter\directMessages.py:93 -#: ../src\controller\buffers\twitter\people.py:95 -msgid "Mention to %s" -msgstr "Mencionar a %s" - -#: ../src\controller\buffers\twitter\directMessages.py:93 -#: ../src\controller\buffers\twitter\people.py:95 -#: ../src\wxUI\buffers\people.py:17 -msgid "Mention" -msgstr "Mención" - -#: ../src\controller\buffers\twitter\directMessages.py:133 -msgid "{0} new direct messages." -msgstr "{0} mensajes directos nuevos." - -#: ../src\controller\buffers\twitter\directMessages.py:136 -msgid "This action is not supported in the buffer yet." -msgstr "Esta acción todavía no se soporta en este buffer." - -#: ../src\controller\buffers\twitter\directMessages.py:146 -msgid "" -"Getting more items cannot be done in this buffer. Use the direct messages " -"buffer instead." -msgstr "" -"No se pueden obtener más elementos en este buffer. Usa el buffer de mensajes " -"directos en su lugar." - -#: ../src\controller\buffers\twitter\people.py:253 -msgid "{0} new followers." -msgstr "{0} nuevos seguidores." - -#: ../src\controller\buffers\twitter\trends.py:146 -msgid "This action is not supported in the buffer, yet." -msgstr "Esta acción todavía no se soporta en este buffer." - -#: ../src\controller\mainController.py:277 -msgid "Ready" -msgstr "Listo" - -#: ../src\controller\mainController.py:351 -msgid "Following" -msgstr "Siguiendo" - -#: ../src\controller\mainController.py:356 -msgid "Timelines" -msgstr "Líneas temporales" - -#: ../src\controller\mainController.py:359 -#: ../src\controller\mainController.py:883 -#: ../src\controller\mainController.py:1585 -msgid "Timeline for {}" -msgstr "Línea temporal de {0}" - -#: ../src\controller\mainController.py:360 -msgid "Likes timelines" -msgstr "Líneas temporales de tuits marcados con me gusta" - -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:902 -#: ../src\controller\mainController.py:1587 -msgid "Likes for {}" -msgstr "Tuits que le gustan a {0}" - -#: ../src\controller\mainController.py:364 -msgid "Followers timelines" -msgstr "Líneas temporales de seguidores" - -#: ../src\controller\mainController.py:367 -#: ../src\controller\mainController.py:921 -#: ../src\controller\mainController.py:1589 -msgid "Followers for {}" -msgstr "Seguidores de {0}" - -#: ../src\controller\mainController.py:368 -msgid "Following timelines" -msgstr "Líneas temporales de siguiendo" - -#: ../src\controller\mainController.py:371 -#: ../src\controller\mainController.py:940 -#: ../src\controller\mainController.py:1591 -msgid "Friends for {}" -msgstr "Amigos de {0}" - -#: ../src\controller\mainController.py:372 ../src\wxUI\dialogs\lists.py:13 -msgid "Lists" -msgstr "Listas" - -#: ../src\controller\mainController.py:375 -#: ../src\controller\mainController.py:1422 -msgid "List for {}" -msgstr "Lista {0}" - -#: ../src\controller\mainController.py:376 -msgid "Searches" -msgstr "Búsquedas" - -#: ../src\controller\mainController.py:379 -#: ../src\controller\mainController.py:426 -#: ../src\controller\mainController.py:431 -msgid "Search for {}" -msgstr "Buscar {0}" - -#: ../src\controller\mainController.py:381 -#: ../src\controller\mainController.py:982 -#: ../src\controller\mainController.py:1593 -msgid "Trending topics for %s" -msgstr "Tendencias para %s" - -#: ../src\controller\mainController.py:448 -#: ../src\controller\mainController.py:464 -#: ../src\controller\mainController.py:1080 -#: ../src\controller\mainController.py:1099 -#: ../src\controller\mainController.py:1118 -#: ../src\controller\mainController.py:1137 -msgid "" -"No session is currently in focus. Focus a session with the next or previous " -"session shortcut." -msgstr "No estás en ninguna sesión. Cambia a una sesión activa." - -#: ../src\controller\mainController.py:452 -msgid "Empty buffer." -msgstr "Buffer vacío." - -#: ../src\controller\mainController.py:459 -msgid "{0} not found." -msgstr "{0} no encontrado." - -#: ../src\controller\mainController.py:469 -msgid "Filters cannot be applied on this buffer" -msgstr "No pueden aplicarse filtros sobre este buffer" - -#: ../src\controller\mainController.py:522 -#: ../src\controller\mainController.py:539 -#: ../src\controller\mainController.py:568 -msgid "Select the user" -msgstr "Selecciona un usuario" - -#: ../src\controller\mainController.py:753 -msgid "Add an user alias" -msgstr "Añadir alias de usuario" - -#: ../src\controller\mainController.py:761 -msgid "Alias has been set correctly for {}." -msgstr "Añadido el alias para {}" - -#: ../src\controller\mainController.py:829 ../src\controller\messages.py:245 -msgid "MMM D, YYYY. H:m" -msgstr "D MMM, YYYY. H:m" - -#: ../src\controller\mainController.py:957 -msgid "Conversation with {0}" -msgstr "Conversación con {0}" - -#: ../src\controller\mainController.py:998 -#: ../src\controller\mainController.py:1015 -msgid "There are no coordinates in this tweet" -msgstr "No hay coordenadas en este tuit" - -#: ../src\controller\mainController.py:1000 -#: ../src\controller\mainController.py:1019 -msgid "Error decoding coordinates. Try again later." -msgstr "Error decodificando las coordenadas. Inténtalo nuevamente más tarde." - -#: ../src\controller\mainController.py:1004 -msgid "Unable to find address in OpenStreetMap." -msgstr "Imposible encontrar dirección en Open Street Map." - -#: ../src\controller\mainController.py:1017 -msgid "There are no results for the coordinates in this tweet" -msgstr "No hay resultados para las coordenadas en este tuit" - -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1147 -msgid "%s, %s of %s" -msgstr "%s, %s de %s" - -#: ../src\controller\mainController.py:1130 -#: ../src\controller\mainController.py:1149 -#: ../src\controller\mainController.py:1174 -#: ../src\controller\mainController.py:1199 -msgid "%s. Empty" -msgstr "%s. Vacío" - -#: ../src\controller\mainController.py:1162 -#: ../src\controller\mainController.py:1166 -#: ../src\controller\mainController.py:1187 -msgid "{0}: This account is not logged into Twitter." -msgstr "{0}: No has iniciado sesión con esta cuenta en Twitter." - -#: ../src\controller\mainController.py:1172 -#: ../src\controller\mainController.py:1197 -msgid "%s. %s, %s of %s" -msgstr "%s. %s, %s de %s" - -#: ../src\controller\mainController.py:1191 -msgid "{0}: This account is not logged into twitter." -msgstr "{0}: No has iniciado sesión con esta cuenta en Twitter." - -#: ../src\controller\mainController.py:1416 -msgid "This list is already opened" -msgstr "Esta lista ya ha sido abierta" - -#: ../src\controller\mainController.py:1446 -#: ../src\controller\mainController.py:1462 -msgid "" -"An error happened while trying to connect to the server. Please try later." -msgstr "" -"Ha ocurrido un error al intentar conectarse al servidor. Por favor, " -"inténtalo más tarde." - -#: ../src\controller\mainController.py:1498 -msgid "The auto-reading of new tweets is enabled for this buffer" -msgstr "La lectura automática de nuevos tuits para este buffer está activada" - -#: ../src\controller\mainController.py:1501 -msgid "The auto-reading of new tweets is disabled for this buffer" -msgstr "" -"La lectura automática de nuevos tuits para este buffer está desactivada" - -#: ../src\controller\mainController.py:1508 -msgid "Session mute on" -msgstr "Silencio de sesión activo" - -#: ../src\controller\mainController.py:1511 -msgid "Session mute off" -msgstr "Silencio de sesión desactivado" - -#: ../src\controller\mainController.py:1519 -msgid "Buffer mute on" -msgstr "Silenciar buffer, activado" - -#: ../src\controller\mainController.py:1522 -msgid "Buffer mute off" -msgstr "Silenciar buffer, desactivado" - -#: ../src\controller\mainController.py:1545 -msgid "Copied" -msgstr "Copiado" - -#: ../src\controller\mainController.py:1575 -msgid "Unable to update this buffer." -msgstr "Imposible actualizar este buffer." - -#: ../src\controller\mainController.py:1578 -msgid "Updating buffer..." -msgstr "Actualizando buffer..." - -#: ../src\controller\mainController.py:1581 -msgid "{0} items retrieved" -msgstr "{0} elementos descargados" - -#: ../src\controller\mainController.py:1600 -#: ../src\controller\mainController.py:1620 -msgid "Invalid buffer" -msgstr "Buffer inválido" - -#: ../src\controller\mainController.py:1611 -msgid "Picture {0}" -msgstr "Foto {0}" - -#: ../src\controller\mainController.py:1612 -msgid "Select the picture" -msgstr "Selecciona la foto" - -#: ../src\controller\mainController.py:1631 -msgid "Unable to extract text" -msgstr "Imposible extraer texto" - -#: ../src\controller\messages.py:56 -msgid "Translated" -msgstr "Traducido" - -#: ../src\controller\messages.py:63 -msgid "There's no URL to be shortened" -msgstr "No hay ninguna URL para acortar" - -#: ../src\controller\messages.py:67 ../src\controller\messages.py:75 -msgid "URL shortened" -msgstr "URL Acortada" - -#: ../src\controller\messages.py:82 -msgid "There's no URL to be expanded" -msgstr "No hay ninguna URL para expandir" - -#: ../src\controller\messages.py:86 ../src\controller\messages.py:94 -msgid "URL expanded" -msgstr "URL expandida" - -#: ../src\controller\messages.py:108 -msgid "%s - %s of %d characters" -msgstr "%s - %s de %d caracteres" - -#: ../src\controller\messages.py:112 -msgid "%s - %s characters" -msgstr "%s - %s caracteres" - -#: ../src\controller\messages.py:272 -msgid "View item" -msgstr "Ver elemento" - -#: ../src\controller\messages.py:301 -msgid "Link copied to clipboard." -msgstr "Enlace copiado al portapapeles" - -#: ../src\controller\settings.py:74 -msgid "HTTP" -msgstr "HTTP" - -#: ../src\controller\settings.py:74 -msgid "SOCKS v4" -msgstr "SOCKS v4" - -#: ../src\controller\settings.py:74 -msgid "SOCKS v4 with DNS support" -msgstr "SOCKS v4 con soporte DNS" - -#: ../src\controller\settings.py:74 -msgid "SOCKS v5" -msgstr "SOCKS v5" - -#: ../src\controller\settings.py:74 -msgid "SOCKS v5 with DNS support" -msgstr "SOCKS v5 con soporte DNS" - -#: ../src\controller\settings.py:74 -msgid "System default" -msgstr "Predeterminado del sistema" - -#: ../src\controller\settings.py:145 ../src\controller\settings.py:211 -#: ../src\wxUI\dialogs\configuration.py:116 -msgid "Ask" -msgstr "Preguntar" - -#: ../src\controller\settings.py:147 ../src\controller\settings.py:213 -#: ../src\wxUI\dialogs\configuration.py:116 -msgid "Retweet without comments" -msgstr "Retuitear sin comentario" - -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:116 -msgid "Retweet with comments" -msgstr "Retuitear añadiendo un comentario" - -#: ../src\controller\settings.py:185 -msgid "Account settings for %s" -msgstr "Opciones de la cuenta de %s" - -#: ../src\controller\settings.py:288 -msgid "Direct Messages" -msgstr "Mensajes directos" - -#: ../src\controller\user.py:29 ../src\controller\user.py:31 -#: ../src\extra\SpellChecker\wx_ui.py:80 ../src\issueReporter\wx_ui.py:84 -#: ../src\issueReporter\wx_ui.py:87 ../src\wxUI\commonMessageDialogs.py:39 -#: ../src\wxUI\commonMessageDialogs.py:51 -#: ../src\wxUI\commonMessageDialogs.py:58 -#: ../src\wxUI\commonMessageDialogs.py:61 -#: ../src\wxUI\commonMessageDialogs.py:64 -#: ../src\wxUI\commonMessageDialogs.py:67 -#: ../src\wxUI\commonMessageDialogs.py:77 -#: ../src\wxUI\commonMessageDialogs.py:80 -#: ../src\wxUI\commonMessageDialogs.py:83 -#: ../src\wxUI\commonMessageDialogs.py:89 -#: ../src\wxUI\commonMessageDialogs.py:92 -msgid "Error" -msgstr "Error" - -#: ../src\controller\user.py:29 ../src\wxUI\commonMessageDialogs.py:39 -msgid "That user does not exist" -msgstr "El usuario no existe" - -#: ../src\controller\user.py:31 -msgid "User has been suspended" -msgstr "El usuario ha sido suspendido" - -#: ../src\controller\user.py:37 -msgid "Information for %s" -msgstr "Detalles para %s" - -#: ../src\controller\user.py:67 ../src\extra\AudioUploader\audioUploader.py:127 -msgid "Discarded" -msgstr "Descartado" - -#: ../src\controller\user.py:95 -msgid "Username: @%s\n" -msgstr "Nombre de usuario: @%s\n" - -#: ../src\controller\user.py:96 -msgid "Name: %s\n" -msgstr "Nombre: %s\n" - -#: ../src\controller\user.py:98 -msgid "Location: %s\n" -msgstr "Ubicación: %s\n" - -#: ../src\controller\user.py:100 -msgid "URL: %s\n" -msgstr "URL: %s\n" - -#: ../src\controller\user.py:104 -msgid "Bio: %s\n" -msgstr "Descripción: %s\n" - -#: ../src\controller\user.py:105 ../src\controller\user.py:120 -msgid "Yes" -msgstr "Sí" - -#: ../src\controller\user.py:106 ../src\controller\user.py:121 -msgid "No" -msgstr "No" - -#: ../src\controller\user.py:107 -msgid "Protected: %s\n" -msgstr "Protegido: %s\n" - -#: ../src\controller\user.py:112 -msgid "You follow {0}. " -msgstr "Sigues a {0}. " - -#: ../src\controller\user.py:115 -msgid "{0} is following you." -msgstr "{0} te sigue." - -#: ../src\controller\user.py:119 -msgid "" -"Followers: %s\n" -" Friends: %s\n" -msgstr "" -"Seguidores: %s\n" -" Amigos: %s\n" - -#: ../src\controller\user.py:122 -msgid "Verified: %s\n" -msgstr "Verificado: %s\n" - -#: ../src\controller\user.py:123 -msgid "Tweets: %s\n" -msgstr "Tuits: %s\n" - -#: ../src\controller\user.py:124 -msgid "Likes: %s" -msgstr "Me gusta: %s" - -#: ../src\controller\userActionsController.py:74 -msgid "You can't ignore direct messages" -msgstr "No puedes ignorar los mensajes directos" - -#: ../src\controller\userAliasController.py:32 -msgid "Edit alias for {}" -msgstr "Editar alias para {}" - -#: ../src\extra\AudioUploader\audioUploader.py:57 -msgid "Attaching..." -msgstr "Adjuntando..." - -#: ../src\extra\AudioUploader\audioUploader.py:74 -msgid "Pause" -msgstr "Pausa" - -#: ../src\extra\AudioUploader\audioUploader.py:76 -msgid "&Resume" -msgstr "&Reanudar" - -#: ../src\extra\AudioUploader\audioUploader.py:77 -msgid "Resume" -msgstr "Reanudar" - -#: ../src\extra\AudioUploader\audioUploader.py:79 -#: ../src\extra\AudioUploader\audioUploader.py:106 -#: ../src\extra\AudioUploader\wx_ui.py:37 -msgid "&Pause" -msgstr "&Pausa" - -#: ../src\extra\AudioUploader\audioUploader.py:94 -#: ../src\extra\AudioUploader\audioUploader.py:140 -msgid "&Stop" -msgstr "&Detener" - -#: ../src\extra\AudioUploader\audioUploader.py:95 -msgid "Recording" -msgstr "Grabando" - -#: ../src\extra\AudioUploader\audioUploader.py:100 -#: ../src\extra\AudioUploader\audioUploader.py:151 -msgid "Stopped" -msgstr "Stopped" - -#: ../src\extra\AudioUploader\audioUploader.py:102 -#: ../src\extra\AudioUploader\wx_ui.py:39 -msgid "&Record" -msgstr "&Grabar" - -#: ../src\extra\AudioUploader\audioUploader.py:136 ../src\sound.py:148 -msgid "Playing..." -msgstr "Reproduciendo..." - -#: ../src\extra\AudioUploader\audioUploader.py:144 -#: ../src\extra\AudioUploader\audioUploader.py:154 -#: ../src\extra\AudioUploader\wx_ui.py:35 -msgid "&Play" -msgstr "&Reproducir" - -#: ../src\extra\AudioUploader\audioUploader.py:159 -msgid "Recoding audio..." -msgstr "Recodificando audio..." - -#: ../src\extra\AudioUploader\transfer.py:82 -#: ../src\extra\AudioUploader\transfer.py:88 -msgid "Error in file upload: {0}" -msgstr "Error al subir el archivo: {0}" - -#: ../src\extra\AudioUploader\utils.py:29 ../src\update\utils.py:29 -msgid "%d day, " -msgstr "%d día, " - -#: ../src\extra\AudioUploader\utils.py:31 ../src\update\utils.py:31 -msgid "%d days, " -msgstr "%d días, " - -#: ../src\extra\AudioUploader\utils.py:33 ../src\update\utils.py:33 -msgid "%d hour, " -msgstr "%d hora, " - -#: ../src\extra\AudioUploader\utils.py:35 ../src\update\utils.py:35 -msgid "%d hours, " -msgstr "%d horas, " - -#: ../src\extra\AudioUploader\utils.py:37 ../src\update\utils.py:37 -msgid "%d minute, " -msgstr "%d minuto, " - -#: ../src\extra\AudioUploader\utils.py:39 ../src\update\utils.py:39 -msgid "%d minutes, " -msgstr "%d minutos, " - -#: ../src\extra\AudioUploader\utils.py:41 ../src\update\utils.py:41 -msgid "%s second" -msgstr "%s segundo" - -#: ../src\extra\AudioUploader\utils.py:43 ../src\update\utils.py:43 -msgid "%s seconds" -msgstr "%s segundos" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 -msgid "File" -msgstr "Archivo" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:21 -msgid "Transferred" -msgstr "Transferido" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:26 -msgid "Total file size" -msgstr "Tamaño total del archivo" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:31 -msgid "Transfer rate" -msgstr "Velocidad de transferencia" - -#: ../src\extra\AudioUploader\wx_transfer_dialogs.py:36 -msgid "Time left" -msgstr "Tiempo restante" - -#: ../src\extra\AudioUploader\wx_ui.py:29 -msgid "Attach audio" -msgstr "Adjuntar audio" - -#: ../src\extra\AudioUploader\wx_ui.py:41 -msgid "&Add an existing file" -msgstr "&Añadir un archivo existente" - -#: ../src\extra\AudioUploader\wx_ui.py:42 -msgid "&Discard" -msgstr "&Descartar" - -#: ../src\extra\AudioUploader\wx_ui.py:44 -msgid "Upload to" -msgstr "Subir a" - -#: ../src\extra\AudioUploader\wx_ui.py:49 -msgid "Attach" -msgstr "Adjuntar" - -#: ../src\extra\AudioUploader\wx_ui.py:51 -msgid "&Cancel" -msgstr "&Cancelar" - -#: ../src\extra\AudioUploader\wx_ui.py:76 -msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" -msgstr "Archivos de audio (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" - -#: ../src\extra\AudioUploader\wx_ui.py:76 -msgid "Select the audio file to be uploaded" -msgstr "Selecciona el archivo de audio que deseas subir" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:7 -msgid "Audio tweet." -msgstr "Tuit con audio." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:8 -msgid "User timeline buffer created." -msgstr "Línea temporal de un usuario creada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:9 -msgid "Buffer destroied." -msgstr "Buffer eliminado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:10 -msgid "Direct message received." -msgstr "Mensaje directo recibido." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:11 -msgid "Direct message sent." -msgstr "Mensaje directo enviado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:12 -msgid "Error." -msgstr "Error." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:13 -msgid "Tweet liked." -msgstr "Tuit marcado como me gusta." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:14 -msgid "Likes buffer updated." -msgstr "Un Buffer de tuits marcados como me gusta se ha actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:15 -msgid "Geotweet." -msgstr "Tuit con información geográfica." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:16 -msgid "Tweet contains one or more images" -msgstr "El tuit contiene una o más imágenes" - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:17 -msgid "Boundary reached." -msgstr "No hay más elementos en el buffer." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:18 -msgid "List updated." -msgstr "Lista actualizada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:19 -msgid "Too many characters." -msgstr "Demasiados caracteres." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:20 -msgid "Mention received." -msgstr "Mención recibida." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 -msgid "New event." -msgstr "Nuevo evento." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 -msgid "{0} is ready." -msgstr "{0} está listo." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:23 -msgid "Mention sent." -msgstr "Mención enviada." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:24 -msgid "Tweet retweeted." -msgstr "Tuit retuiteado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:25 -msgid "Search buffer updated." -msgstr "Buffer de búsqueda actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:26 -msgid "Tweet received." -msgstr "Tuit recibido." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:27 -msgid "Tweet sent." -msgstr "Tuit enviado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:28 -msgid "Trending topics buffer updated." -msgstr "Buffer de trending topics actualizado." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:29 -msgid "New tweet in user timeline buffer." -msgstr "Nuevo tuit en línea temporal de un usuario." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:30 -msgid "New follower." -msgstr "Nuevo seguidor." - -#: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:31 -msgid "Volume changed." -msgstr "Volumen modificado." - -#: ../src\extra\SoundsTutorial\wx_ui.py:9 -msgid "Sounds tutorial" -msgstr "Tutorial de sonidos" - -#: ../src\extra\SoundsTutorial\wx_ui.py:12 -msgid "Press enter to listen to the sound for the selected event" -msgstr "Pulsa enter para escuchar el sonido para el evento seleccionado" - -#: ../src\extra\SpellChecker\spellchecker.py:60 -msgid "Misspelled word: %s" -msgstr "Palabra mal escrita: %s" - -#: ../src\extra\SpellChecker\wx_ui.py:28 -msgid "Misspelled word" -msgstr "Palabra mal escrita" - -#: ../src\extra\SpellChecker\wx_ui.py:33 -msgid "Context" -msgstr "Contexto" - -#: ../src\extra\SpellChecker\wx_ui.py:38 -msgid "Suggestions" -msgstr "Sugerencias" - -#: ../src\extra\SpellChecker\wx_ui.py:43 -msgid "&Ignore" -msgstr "&Ignorar" - -#: ../src\extra\SpellChecker\wx_ui.py:44 -msgid "I&gnore all" -msgstr "Ignorar &todo" - -#: ../src\extra\SpellChecker\wx_ui.py:45 -msgid "&Replace" -msgstr "&Reemplazar" - -#: ../src\extra\SpellChecker\wx_ui.py:46 -msgid "R&eplace all" -msgstr "R&eemplazar todo" - -#: ../src\extra\SpellChecker\wx_ui.py:47 -msgid "&Add to personal dictionary" -msgstr "Añadir al &diccionario" - -#: ../src\extra\SpellChecker\wx_ui.py:80 -msgid "" -"An error has occurred. There are no dictionaries available for the selected " -"language in {0}" -msgstr "" -"Ha ocurrido un error. No se encuentran diccionarios disponibles para el " -"idioma seleccionado en {0}." - -#: ../src\extra\SpellChecker\wx_ui.py:83 -msgid "Spell check complete." -msgstr "Corrección ortográfica finalizada." - -#: ../src\extra\autocompletionUsers\completion.py:20 -#: ../src\extra\autocompletionUsers\completion.py:38 -msgid "You have to start writing" -msgstr "Tienes que empezar a escribir" - -#: ../src\extra\autocompletionUsers\completion.py:30 -#: ../src\extra\autocompletionUsers\completion.py:47 -msgid "There are no results in your users database" -msgstr "No hay resultados en tu base de datos de usuarios" - -#: ../src\extra\autocompletionUsers\completion.py:32 -msgid "Autocompletion only works for users." -msgstr "El autocompletado solo funciona con usuarios." - -#: ../src\extra\autocompletionUsers\settings.py:25 -msgid "" -"Updating database... You can close this window now. A message will tell you " -"when the process finishes." -msgstr "" -"Actualizando base de datos... Puedes cerrar esta ventana ahora. Un mensaje " -"te informará cuando el proceso haya terminado." - -#: ../src\extra\autocompletionUsers\wx_manage.py:9 -msgid "Manage Autocompletion database" -msgstr "Gestionar la base de datos del autocompletado de usuarios" - -#: ../src\extra\autocompletionUsers\wx_manage.py:12 -msgid "Editing {0} users database" -msgstr "Editando la base de datos de usuarios de {0}" - -#: ../src\extra\autocompletionUsers\wx_manage.py:13 -msgid "Username" -msgstr "Nombre de usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:13 -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Name" -msgstr "Nombre" - -#: ../src\extra\autocompletionUsers\wx_manage.py:16 -msgid "Add user" -msgstr "Añadir usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:17 -msgid "Remove user" -msgstr "Quitar usuario" - -#: ../src\extra\autocompletionUsers\wx_manage.py:38 -msgid "Add user to database" -msgstr "Añadir usuario a la base de datos" - -#: ../src\extra\autocompletionUsers\wx_manage.py:38 -msgid "Twitter username" -msgstr "Nombre de usuario de Twitter" - -#: ../src\extra\autocompletionUsers\wx_manage.py:44 -msgid "The user does not exist" -msgstr "El usuario no existe" - -#: ../src\extra\autocompletionUsers\wx_manage.py:44 -#: ../src\wxUI\commonMessageDialogs.py:45 -msgid "Error!" -msgstr "¡Error!" - -#: ../src\extra\autocompletionUsers\wx_settings.py:8 -msgid "Autocomplete users' settings" -msgstr "Opciones de autocompletado de usuarios" - -#: ../src\extra\autocompletionUsers\wx_settings.py:11 -msgid "Add users from followers buffer" -msgstr "Añadir usuarios desde el buffer de seguidores" - -#: ../src\extra\autocompletionUsers\wx_settings.py:12 -msgid "Add users from friends buffer" -msgstr "Añadir usuarios desde el buffer de amigos" - -#: ../src\extra\autocompletionUsers\wx_settings.py:15 -msgid "Manage database..." -msgstr "Administrar base de datos..." - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "Done" -msgstr "¡Hecho" - -#: ../src\extra\autocompletionUsers\wx_settings.py:27 -msgid "{0}'s database of users has been updated." -msgstr "La base de datos de usuarios de {0} ha sido actualizada." - -#: ../src\extra\ocr\OCRSpace.py:7 -msgid "Detect automatically" -msgstr "Detectar automáticamente" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:41 -msgid "Danish" -msgstr "Danés" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:43 -msgid "Dutch" -msgstr "Holandés" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:44 -msgid "English" -msgstr "Inglés" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:48 -msgid "Finnish" -msgstr "Finés" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:49 -msgid "French" -msgstr "Francés" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:52 -msgid "German" -msgstr "Alemán" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:58 -msgid "Hungarian" -msgstr "Húngaro" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:63 -msgid "Italian" -msgstr "Italiano" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:64 -msgid "Japanese" -msgstr "Japonés" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:68 -msgid "Korean" -msgstr "Coreano" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:85 -msgid "Polish" -msgstr "Polaco" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:86 -msgid "Portuguese" -msgstr "Portugués" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:89 -msgid "Russian" -msgstr "Ruso" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:96 -msgid "Spanish" -msgstr "Español" - -#: ../src\extra\ocr\OCRSpace.py:7 ../src\extra\translator\translator.py:105 -msgid "Turkish" -msgstr "Turco" - -#: ../src\extra\translator\translator.py:22 -msgid "Afrikaans" -msgstr "Africano" - -#: ../src\extra\translator\translator.py:23 -msgid "Albanian" -msgstr "Albanés" - -#: ../src\extra\translator\translator.py:24 +#: languageHandler.py:61 +msgctxt "languageName" msgid "Amharic" msgstr "Amárico" -#: ../src\extra\translator\translator.py:25 -msgid "Arabic" -msgstr "Árabe" +#: languageHandler.py:62 +msgctxt "languageName" +msgid "Aragonese" +msgstr "Aragonés" -#: ../src\extra\translator\translator.py:26 -msgid "Armenian" -msgstr "Armenio" +#: languageHandler.py:63 +msgctxt "languageName" +msgid "Spanish" +msgstr "Español" -#: ../src\extra\translator\translator.py:27 -msgid "Azerbaijani" -msgstr "Acerí" +#: languageHandler.py:64 +msgctxt "languageName" +msgid "Portuguese" +msgstr "Portugués" -#: ../src\extra\translator\translator.py:28 -msgid "Basque" -msgstr "Vasco" +#: languageHandler.py:65 +msgctxt "languageName" +msgid "Russian" +msgstr "Ruso" -#: ../src\extra\translator\translator.py:29 -msgid "Belarusian" -msgstr "Bielorruso" +#: languageHandler.py:66 +msgctxt "languageName" +msgid "italian" +msgstr "Italiano" -#: ../src\extra\translator\translator.py:30 -msgid "Bengali" -msgstr "Bengalí" +#: languageHandler.py:67 +msgctxt "languageName" +msgid "Turkey" +msgstr "Turco" -#: ../src\extra\translator\translator.py:31 -msgid "Bihari" -msgstr "Bihari" - -#: ../src\extra\translator\translator.py:32 -msgid "Bulgarian" -msgstr "Búlgaro" - -#: ../src\extra\translator\translator.py:33 -msgid "Burmese" -msgstr "Birmano" - -#: ../src\extra\translator\translator.py:34 -msgid "Catalan" -msgstr "Catalán" - -#: ../src\extra\translator\translator.py:35 -msgid "Cherokee" -msgstr "Cheroqui" - -#: ../src\extra\translator\translator.py:36 -msgid "Chinese" -msgstr "Chino" - -#: ../src\extra\translator\translator.py:37 -msgid "Chinese_simplified" -msgstr "Chino simplificado" - -#: ../src\extra\translator\translator.py:38 -msgid "Chinese_traditional" -msgstr "Chino tradicional" - -#: ../src\extra\translator\translator.py:39 -msgid "Croatian" -msgstr "Croata" - -#: ../src\extra\translator\translator.py:40 -msgid "Czech" -msgstr "Checo" - -#: ../src\extra\translator\translator.py:42 -msgid "Dhivehi" -msgstr "Dhivehi" - -#: ../src\extra\translator\translator.py:45 -msgid "Esperanto" -msgstr "Esperanto" - -#: ../src\extra\translator\translator.py:46 -msgid "Estonian" -msgstr "Estonio" - -#: ../src\extra\translator\translator.py:47 -msgid "Filipino" -msgstr "Filipino" - -#: ../src\extra\translator\translator.py:50 +#: languageHandler.py:68 +msgctxt "languageName" msgid "Galician" msgstr "Gallego" -#: ../src\extra\translator\translator.py:51 -msgid "Georgian" -msgstr "Georgiano" +#: languageHandler.py:69 +msgctxt "languageName" +msgid "Catala" +msgstr "Catalán" -#: ../src\extra\translator\translator.py:53 -msgid "Greek" -msgstr "Griego" +#: languageHandler.py:70 +msgctxt "languageName" +msgid "Vasque" +msgstr "Vasco" -#: ../src\extra\translator\translator.py:54 -msgid "Guarani" -msgstr "Guaraní" +#: languageHandler.py:71 +msgctxt "languageName" +msgid "polish" +msgstr "Polaco" -#: ../src\extra\translator\translator.py:55 -msgid "Gujarati" -msgstr "Guyaratí" +#: languageHandler.py:72 +msgctxt "languageName" +msgid "Arabic" +msgstr "Árabe" -#: ../src\extra\translator\translator.py:56 -msgid "Hebrew" -msgstr "Hebreo" - -#: ../src\extra\translator\translator.py:57 -msgid "Hindi" -msgstr "Hindi" - -#: ../src\extra\translator\translator.py:59 -msgid "Icelandic" -msgstr "Islandés" - -#: ../src\extra\translator\translator.py:60 -msgid "Indonesian" -msgstr "Indonesio" - -#: ../src\extra\translator\translator.py:61 -msgid "Inuktitut" -msgstr "Inuktitut" - -#: ../src\extra\translator\translator.py:62 -msgid "Irish" -msgstr "Irlandés" - -#: ../src\extra\translator\translator.py:65 -msgid "Kannada" -msgstr "Canarés" - -#: ../src\extra\translator\translator.py:66 -msgid "Kazakh" -msgstr "Kazajo" - -#: ../src\extra\translator\translator.py:67 -msgid "Khmer" -msgstr "Camboyano" - -#: ../src\extra\translator\translator.py:69 -msgid "Kurdish" -msgstr "Kurdo" - -#: ../src\extra\translator\translator.py:70 -msgid "Kyrgyz" -msgstr "Kirguís" - -#: ../src\extra\translator\translator.py:71 -msgid "Laothian" -msgstr "Lao" - -#: ../src\extra\translator\translator.py:72 -msgid "Latvian" -msgstr "Letón" - -#: ../src\extra\translator\translator.py:73 -msgid "Lithuanian" -msgstr "Lituano" - -#: ../src\extra\translator\translator.py:74 -msgid "Macedonian" -msgstr "Macedonio" - -#: ../src\extra\translator\translator.py:75 -msgid "Malay" -msgstr "Malayo" - -#: ../src\extra\translator\translator.py:76 -msgid "Malayalam" -msgstr "Malayalam" - -#: ../src\extra\translator\translator.py:77 -msgid "Maltese" -msgstr "Maltés" - -#: ../src\extra\translator\translator.py:78 -msgid "Marathi" -msgstr "Maratí" - -#: ../src\extra\translator\translator.py:79 -msgid "Mongolian" -msgstr "Mongol" - -#: ../src\extra\translator\translator.py:80 +#: languageHandler.py:73 +msgctxt "languageName" msgid "Nepali" msgstr "Nepalí" -#: ../src\extra\translator\translator.py:81 -msgid "Norwegian" -msgstr "Noruego" - -#: ../src\extra\translator\translator.py:82 -msgid "Oriya" -msgstr "Oriya" - -#: ../src\extra\translator\translator.py:83 -msgid "Pashto" -msgstr "Pastú" - -#: ../src\extra\translator\translator.py:84 -msgid "Persian" -msgstr "Persa" - -#: ../src\extra\translator\translator.py:87 -msgid "Punjabi" -msgstr "Panyabí" - -#: ../src\extra\translator\translator.py:88 -msgid "Romanian" -msgstr "Rumano" - -#: ../src\extra\translator\translator.py:90 -msgid "Sanskrit" -msgstr "Sánscrito" - -#: ../src\extra\translator\translator.py:91 -msgid "Serbian" +#: languageHandler.py:74 +msgctxt "languageName" +msgid "Serbian (Latin)" msgstr "Serbio" -#: ../src\extra\translator\translator.py:92 -msgid "Sindhi" -msgstr "Sindhi" +#: languageHandler.py:75 +msgctxt "languageName" +msgid "Japanese" +msgstr "Japonés" -#: ../src\extra\translator\translator.py:93 -msgid "Sinhalese" -msgstr "Cingalés" - -#: ../src\extra\translator\translator.py:94 -msgid "Slovak" -msgstr "Eslovaco" - -#: ../src\extra\translator\translator.py:95 -msgid "Slovenian" -msgstr "Esloveno" - -#: ../src\extra\translator\translator.py:97 -msgid "Swahili" -msgstr "Suajili" - -#: ../src\extra\translator\translator.py:98 -msgid "Swedish" -msgstr "Sueco" - -#: ../src\extra\translator\translator.py:99 -msgid "Tajik" -msgstr "Tayiko" - -#: ../src\extra\translator\translator.py:100 -msgid "Tamil" -msgstr "Tamil" - -#: ../src\extra\translator\translator.py:101 -msgid "Tagalog" -msgstr "Tagalo" - -#: ../src\extra\translator\translator.py:102 -msgid "Telugu" -msgstr "Telugú" - -#: ../src\extra\translator\translator.py:103 -msgid "Thai" -msgstr "Tailandés" - -#: ../src\extra\translator\translator.py:104 -msgid "Tibetan" -msgstr "Tibetano" - -#: ../src\extra\translator\translator.py:106 -msgid "Ukrainian" -msgstr "Ucraniano" - -#: ../src\extra\translator\translator.py:107 -msgid "Urdu" -msgstr "Urdu" - -#: ../src\extra\translator\translator.py:108 -msgid "Uzbek" -msgstr "Uzbeco" - -#: ../src\extra\translator\translator.py:109 -msgid "Uighur" -msgstr "Uigur" - -#: ../src\extra\translator\translator.py:110 -msgid "Vietnamese" -msgstr "Vietnamita" - -#: ../src\extra\translator\translator.py:111 -msgid "Welsh" -msgstr "Galés" - -#: ../src\extra\translator\translator.py:112 -msgid "Yiddish" -msgstr "Yídish" - -#: ../src\extra\translator\wx_ui.py:29 -msgid "Translate message" -msgstr "Traducir mensaje" - -#: ../src\extra\translator\wx_ui.py:32 -msgid "Target language" -msgstr "Idioma de destino" - -#: ../src\issueReporter\issueReporter.py:32 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 -msgid "General" -msgstr "General" - -#: ../src\issueReporter\issueReporter.py:33 -msgid "always" -msgstr "siempre" - -#: ../src\issueReporter\issueReporter.py:33 -msgid "have not tried" -msgstr "no se ha intentado" - -#: ../src\issueReporter\issueReporter.py:33 -msgid "random" -msgstr "aleatoriamente" - -#: ../src\issueReporter\issueReporter.py:33 -msgid "sometimes" -msgstr "a veces" - -#: ../src\issueReporter\issueReporter.py:33 -msgid "unable to duplicate" -msgstr "imposible de reproducir" - -#: ../src\issueReporter\issueReporter.py:34 -msgid "block" -msgstr "bloqueo" - -#: ../src\issueReporter\issueReporter.py:34 -msgid "crash" -msgstr "fallo" - -#: ../src\issueReporter\issueReporter.py:34 -msgid "feature" -msgstr "característica" - -#: ../src\issueReporter\issueReporter.py:34 -msgid "major" -msgstr "mayor" - -#: ../src\issueReporter\issueReporter.py:34 -msgid "minor" -msgstr "menor" - -#: ../src\issueReporter\issueReporter.py:34 -msgid "text" -msgstr "texto" - -#: ../src\issueReporter\issueReporter.py:34 -msgid "trivial" -msgstr "trivial" - -#: ../src\issueReporter\issueReporter.py:34 -msgid "tweak" -msgstr "ajuste" - -#: ../src\issueReporter\wx_ui.py:26 -msgid "Report an error" -msgstr "Reportar un error" - -#: ../src\issueReporter\wx_ui.py:29 -msgid "Select a category" -msgstr "Selecciona una categoría" - -#: ../src\issueReporter\wx_ui.py:37 -msgid "" -"Briefly describe what happened. You will be able to thoroughly explain it " -"later" -msgstr "" -"Describe en pocas palabras lo que ha pasado (después podrás profundizar)" - -#: ../src\issueReporter\wx_ui.py:46 -msgid "Here, you can describe the bug in detail" -msgstr "Aquí puedes describir el error en detalle" - -#: ../src\issueReporter\wx_ui.py:56 -msgid "how often does this bug happen?" -msgstr "¿Qué tan a menudo ocurre este error?" - -#: ../src\issueReporter\wx_ui.py:63 -msgid "Select the importance that you think this bug has" -msgstr "Selecciona la importancia que consideras que tiene este error" - -#: ../src\issueReporter\wx_ui.py:70 -msgid "" -"I know that the {0} bug system will get my Twitter username to contact me " -"and fix the bug quickly" -msgstr "" -"Sé que el sistema de errores de {0} obtendrá mi nombre de usuario de Twitter " -"para contactarme y resolver el error rápidamente" - -#: ../src\issueReporter\wx_ui.py:73 -msgid "Send report" -msgstr "Enviar reporte" - -#: ../src\issueReporter\wx_ui.py:75 ../src\wxUI\dialogs\filterDialogs.py:84 -#: ../src\wxUI\dialogs\find.py:23 -msgid "Cancel" -msgstr "Cancelar" - -#: ../src\issueReporter\wx_ui.py:84 -msgid "You must fill out both fields" -msgstr "Debes llenar ambos campos" - -#: ../src\issueReporter\wx_ui.py:87 -msgid "" -"You need to mark the checkbox to provide us your twitter username to contact " -"you if it is necessary." -msgstr "" -"Debes marcar la casilla para proporcionarnos tu nombre de usuario de Twitter " -"para poder contactarte si es necesario." - -#: ../src\issueReporter\wx_ui.py:90 -msgid "" -"Thanks for reporting this bug! In future versions, you may be able to find " -"it in the changes list. You've reported the bug number %i" -msgstr "" -"¡Gracias por reportar este error! Quizá puedas verlo entre la lista de " -"cambios de próximas versiones. Has reportado el error número %i" - -#: ../src\issueReporter\wx_ui.py:90 -msgid "reported" -msgstr "reportado" - -#: ../src\issueReporter\wx_ui.py:94 -msgid "Error while reporting" -msgstr "Error al reportar" - -#: ../src\issueReporter\wx_ui.py:94 -msgid "" -"Something unexpected occurred while trying to report the bug. Please, try " -"again later" -msgstr "" -"Algo inesperado ocurrió mientras intentábamos reportar tu error. Por favor, " -"vuelve a intentarlo más tarde" - -#: ../src\keystrokeEditor\constants.py:3 -msgid "Go up in the current buffer" -msgstr "Va arriba en la lista actual" - -#: ../src\keystrokeEditor\constants.py:4 -msgid "Go down in the current buffer" -msgstr "Va abajo en la lista actual" - -#: ../src\keystrokeEditor\constants.py:5 -msgid "Go to the previous buffer" -msgstr "Va al buffer anterior" - -#: ../src\keystrokeEditor\constants.py:6 -msgid "Go to the next buffer" -msgstr "Va al buffer siguiente" - -#: ../src\keystrokeEditor\constants.py:7 -msgid "Focus the next session" -msgstr "Ir a la siguiente sesión" - -#: ../src\keystrokeEditor\constants.py:8 -msgid "Focus the previous session" -msgstr "Va a la sesión anterior" - -#: ../src\keystrokeEditor\constants.py:9 -msgid "Show or hide the GUI" -msgstr "Muestra o esconde la interfaz gráfica" - -#: ../src\keystrokeEditor\constants.py:10 -msgid "New tweet" -msgstr "Nuevo tuit" - -#: ../src\keystrokeEditor\constants.py:12 ../src\wxUI\buffers\base.py:26 -#: ../src\wxUI\commonMessageDialogs.py:10 ../src\wxUI\dialogs\message.py:126 -msgid "Retweet" -msgstr "Retuit" - -#: ../src\keystrokeEditor\constants.py:13 -msgid "Send direct message" -msgstr "Enviar mensaje directo" - -#: ../src\keystrokeEditor\constants.py:14 -msgid "Like a tweet" -msgstr "Marcar tuit como me gusta" - -#: ../src\keystrokeEditor\constants.py:15 -msgid "Like/unlike a tweet" -msgstr "Marcar o remover tuit como me gusta" - -#: ../src\keystrokeEditor\constants.py:16 -msgid "Unlike a tweet" -msgstr "Marcar tuit como ya no me gusta" - -#: ../src\keystrokeEditor\constants.py:17 -msgid "Open the user actions dialogue" -msgstr "Abrir el diálogo de acciones" - -#: ../src\keystrokeEditor\constants.py:18 -msgid "See user details" -msgstr "Ver detalles del usuario" - -#: ../src\keystrokeEditor\constants.py:19 -msgid "Show tweet" -msgstr "Ver tuit" - -#: ../src\keystrokeEditor\constants.py:20 -msgid "Quit" -msgstr "Salir" - -#: ../src\keystrokeEditor\constants.py:21 -msgid "Open user timeline" -msgstr "Abrir línea temporal" - -#: ../src\keystrokeEditor\constants.py:22 -msgid "Destroy buffer" -msgstr "Eliminar buffer" - -#: ../src\keystrokeEditor\constants.py:23 -msgid "Interact with the currently focused tweet." -msgstr "Interactuar con el tuit que tiene el foco." - -#: ../src\keystrokeEditor\constants.py:24 -msgid "Open URL" -msgstr "Abrir URL" - -#: ../src\keystrokeEditor\constants.py:25 -msgid "View in Twitter" -msgstr "Ver en Twitter" - -#: ../src\keystrokeEditor\constants.py:26 -msgid "Increase volume by 5%" -msgstr "Subir volumen en un 5%" - -#: ../src\keystrokeEditor\constants.py:27 -msgid "Decrease volume by 5%" -msgstr "Bajar volumen en un 5%" - -#: ../src\keystrokeEditor\constants.py:28 -msgid "Jump to the first element of a buffer" -msgstr "Ir al primer elemento del buffer" - -#: ../src\keystrokeEditor\constants.py:29 -msgid "Jump to the last element of the current buffer" -msgstr "Ir al último elemento del buffer" - -#: ../src\keystrokeEditor\constants.py:30 -msgid "Jump 20 elements up in the current buffer" -msgstr "Moverse 20 elementos hacia arriba en el buffer actual" - -#: ../src\keystrokeEditor\constants.py:31 -msgid "Jump 20 elements down in the current buffer" -msgstr "Moverse 20 elementos hacia abajo en el buffer actual" - -#: ../src\keystrokeEditor\constants.py:32 -msgid "Edit profile" -msgstr "Editar perfil" - -#: ../src\keystrokeEditor\constants.py:33 -msgid "Delete a tweet or direct message" -msgstr "Eliminar tuit o mensaje directo" - -#: ../src\keystrokeEditor\constants.py:34 -msgid "Empty the current buffer" -msgstr "Vaciar buffer" - -#: ../src\keystrokeEditor\constants.py:35 -msgid "Repeat last item" -msgstr "Repetir último elemento" - -#: ../src\keystrokeEditor\constants.py:36 -msgid "Copy to clipboard" -msgstr "Copiar al portapapeles" - -#: ../src\keystrokeEditor\constants.py:37 -msgid "Add to list" -msgstr "Añadir a lista" - -#: ../src\keystrokeEditor\constants.py:38 -msgid "Remove from list" -msgstr "Quitar de lista" - -#: ../src\keystrokeEditor\constants.py:39 -msgid "Mute/unmute the active buffer" -msgstr "Silenciar o des-silenciar el buffer activo" - -#: ../src\keystrokeEditor\constants.py:40 -msgid "Mute/unmute the current session" -msgstr "Activar o desactivar el silencio para la sesión activa" - -#: ../src\keystrokeEditor\constants.py:41 -msgid "toggle the automatic reading of incoming tweets in the active buffer" -msgstr "" -"conmutar entre la lectura automática de nuevos tuits para el buffer actual" - -#: ../src\keystrokeEditor\constants.py:42 -msgid "Search on twitter" -msgstr "Buscar en Twitter" - -#: ../src\keystrokeEditor\constants.py:43 -msgid "Find a string in the currently focused buffer" -msgstr "Buscar un término en el buffer actual" - -#: ../src\keystrokeEditor\constants.py:44 -msgid "Show the keystroke editor" -msgstr "Mostrar el editor de combinaciones de teclado" - -#: ../src\keystrokeEditor\constants.py:45 -msgid "Show lists for a specified user" -msgstr "Mostrar listas para un usuario específico" - -#: ../src\keystrokeEditor\constants.py:46 -msgid "load previous items" -msgstr "cargar elementos anteriores" - -#: ../src\keystrokeEditor\constants.py:47 -msgid "Get geolocation" -msgstr "Obtener ubicación" - -#: ../src\keystrokeEditor\constants.py:48 -msgid "Display the tweet's geolocation in a dialog" -msgstr "Mostrar la ubicación del tuit en un diálogo" - -#: ../src\keystrokeEditor\constants.py:49 -msgid "Create a trending topics buffer" -msgstr "Crear un buffer de tendencias" - -#: ../src\keystrokeEditor\constants.py:50 -msgid "View conversation" -msgstr "Ver conversación" - -#: ../src\keystrokeEditor\constants.py:51 -msgid "Check and download updates" -msgstr "&Comprobar y descargar actualizaciones" - -#: ../src\keystrokeEditor\constants.py:52 -msgid "" -"Opens the list manager, which allows you to create, edit, delete and open " -"lists in buffers." -msgstr "" -"Abre el gestor de listas, que permite crear, editar, eliminar y abrir listas " -"como buffers." - -#: ../src\keystrokeEditor\constants.py:53 -msgid "Opens the global settings dialogue" -msgstr "Abre el diálogo de opciones globales" - -#: ../src\keystrokeEditor\constants.py:54 -msgid "Opens the list manager" -msgstr "Abre el gestor de listas" - -#: ../src\keystrokeEditor\constants.py:55 -msgid "Opens the account settings dialogue" -msgstr "Abre el diálogo de opciones de cuenta" - -#: ../src\keystrokeEditor\constants.py:56 -msgid "Try to play an audio file" -msgstr "Intentar reproducir audio" - -#: ../src\keystrokeEditor\constants.py:57 -msgid "Updates the buffer and retrieves possible lost items there." -msgstr "Actualiza el buffer e intenta descargar los elementos perdidos." - -#: ../src\keystrokeEditor\constants.py:58 -msgid "Extracts the text from a picture and displays the result in a dialog." -msgstr "Extrae el texto de una foto y muestra el resultado en un diálogo." - -#: ../src\keystrokeEditor\constants.py:59 -msgid "Adds an alias to an user" -msgstr "Añade un alias a un usuario específico." - -#: ../src\keystrokeEditor\wx_ui.py:8 -msgid "Keystroke editor" -msgstr "Editor de combinaciones de teclado" - -#: ../src\keystrokeEditor\wx_ui.py:12 -msgid "Select a keystroke to edit" -msgstr "Selecciona una combinación de teclado para editarla" - -#: ../src\keystrokeEditor\wx_ui.py:13 -msgid "Keystroke" -msgstr "Combinación de teclado" - -#: ../src\keystrokeEditor\wx_ui.py:13 ../src\wxUI\dialogs\userActions.py:10 -#: ../src\wxUI\dialogs\userActions.py:19 ../src\wxUI\dialogs\userActions.py:20 -msgid "Action" -msgstr "Acción" - -#: ../src\keystrokeEditor\wx_ui.py:18 ../src\wxUI\dialogs\filterDialogs.py:131 -#: ../src\wxUI\dialogs\lists.py:20 ../src\wxUI\dialogs\userAliasDialogs.py:53 -msgid "Edit" -msgstr "Editar" - -#: ../src\keystrokeEditor\wx_ui.py:20 ../src\keystrokeEditor\wx_ui.py:50 -msgid "Undefine keystroke" -msgstr "Desasignar combinación de teclas" - -#: ../src\keystrokeEditor\wx_ui.py:21 -msgid "Execute action" -msgstr "Ejecutar acción" - -#: ../src\keystrokeEditor\wx_ui.py:22 ../src\wxUI\dialogs\configuration.py:396 -#: ../src\wxUI\dialogs\userAliasDialogs.py:25 ../src\wxUI\dialogs\utils.py:39 -msgid "Close" -msgstr "Cerrar" - -#: ../src\keystrokeEditor\wx_ui.py:42 -msgid "Undefined" -msgstr "Sin definir" - -#: ../src\keystrokeEditor\wx_ui.py:50 -msgid "Are you sure you want to undefine this keystroke?" -msgstr "¿Seguro que deseas desasignar esta combinación de teclado?" - -#: ../src\keystrokeEditor\wx_ui.py:54 -msgid "Editing keystroke" -msgstr "Editando combinación de teclas" - -#: ../src\keystrokeEditor\wx_ui.py:57 -msgid "Control" -msgstr "Control" - -#: ../src\keystrokeEditor\wx_ui.py:58 -msgid "Alt" -msgstr "Alt" - -#: ../src\keystrokeEditor\wx_ui.py:59 -msgid "Shift" -msgstr "Shift" - -#: ../src\keystrokeEditor\wx_ui.py:60 -msgid "Windows" -msgstr "Windows" - -#: ../src\keystrokeEditor\wx_ui.py:66 -msgid "Key" -msgstr "Tecla" - -#: ../src\keystrokeEditor\wx_ui.py:71 ../src\wxUI\dialogs\filterDialogs.py:82 -#: ../src\wxUI\dialogs\find.py:21 ../src\wxUI\dialogs\userAliasDialogs.py:23 -#: ../src\wxUI\dialogs\utils.py:36 -msgid "OK" -msgstr "Aceptar" - -#: ../src\keystrokeEditor\wx_ui.py:84 -msgid "You need to use the Windows key" -msgstr "Necesitas usar la tecla de windows" - -#: ../src\keystrokeEditor\wx_ui.py:84 ../src\keystrokeEditor\wx_ui.py:87 -msgid "Invalid keystroke" -msgstr "Combinación de teclado inválida" - -#: ../src\keystrokeEditor\wx_ui.py:87 -msgid "You must provide a character for the keystroke" -msgstr "Debes proporcionar una letra para el atajo de teclado" - -#: ../src\languageHandler.py:99 +#: languageHandler.py:99 msgid "User default" msgstr "Idioma predeterminado" -#: ../src\main.py:120 +#: main.py:120 msgid "https://twblue.es/donate" msgstr "https://twblue.es/donate" -#: ../src\main.py:137 +#: main.py:137 msgid "" "{0} is already running. Close the other instance before starting this one. " "If you're sure that {0} isn't running, try deleting the file at {1}. If " @@ -1858,43 +110,1839 @@ msgstr "" "archivo que se encuentra en {1}. Si no sabes cómo hacerlo con seguridad, " "contacta con los desarrolladores de {0}." -#: ../src\sessionmanager\wxUI.py:9 +#: extra/AudioUploader/audioUploader.py:136 sound.py:147 +msgid "Playing..." +msgstr "Reproduciendo..." + +#: sound.py:160 +msgid "Stopped." +msgstr "Detenido." + +#: controller/mainController.py:277 +msgid "Ready" +msgstr "Listo" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:337 +#: controller/settings.py:286 +msgid "Home" +msgstr "Inicio" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:339 +#: controller/settings.py:287 +msgid "Mentions" +msgstr "Menciones" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:341 +msgid "Direct messages" +msgstr "Mensajes directos" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:343 +#: controller/settings.py:289 +msgid "Sent direct messages" +msgstr "Mensajes directos enviados" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:345 +#: controller/settings.py:290 +msgid "Sent tweets" +msgstr "Tuits enviados" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:347 +#: controller/mainController.py:1390 controller/settings.py:291 +msgid "Likes" +msgstr "Tuits marcados como me gusta" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:349 +#: controller/mainController.py:1395 controller/settings.py:292 +msgid "Followers" +msgstr "Seguidores" + +#: controller/mainController.py:351 +msgid "Following" +msgstr "Siguiendo" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:353 +#: controller/mainController.py:1405 controller/settings.py:294 +msgid "Blocked users" +msgstr "Usuarios bloqueados" + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:355 +#: controller/mainController.py:1410 controller/settings.py:295 +msgid "Muted users" +msgstr "Usuarios silenciados" + +#: controller/mainController.py:356 +msgid "Timelines" +msgstr "Líneas temporales" + +#: controller/mainController.py:359 controller/mainController.py:883 +#: controller/mainController.py:1582 +msgid "Timeline for {}" +msgstr "Línea temporal de {0}" + +#: controller/mainController.py:360 +msgid "Likes timelines" +msgstr "Líneas temporales de tuits marcados con me gusta" + +#: controller/mainController.py:363 controller/mainController.py:902 +#: controller/mainController.py:1584 +msgid "Likes for {}" +msgstr "Tuits que le gustan a {0}" + +#: controller/mainController.py:364 +msgid "Followers timelines" +msgstr "Líneas temporales de seguidores" + +#: controller/mainController.py:367 controller/mainController.py:921 +#: controller/mainController.py:1586 +msgid "Followers for {}" +msgstr "Seguidores de {0}" + +#: controller/mainController.py:368 +msgid "Following timelines" +msgstr "Líneas temporales de siguiendo" + +#: controller/mainController.py:371 controller/mainController.py:940 +#: controller/mainController.py:1588 +msgid "Friends for {}" +msgstr "Amigos de {0}" + +#: controller/mainController.py:372 wxUI/dialogs/lists.py:13 +msgid "Lists" +msgstr "Listas" + +#: controller/mainController.py:375 controller/mainController.py:1422 +msgid "List for {}" +msgstr "Lista {0}" + +#: controller/mainController.py:376 +msgid "Searches" +msgstr "Búsquedas" + +#: controller/mainController.py:379 controller/mainController.py:426 +#: controller/mainController.py:431 +msgid "Search for {}" +msgstr "Buscar {0}" + +#: controller/mainController.py:381 controller/mainController.py:982 +#: controller/mainController.py:1590 +#, python-format +msgid "Trending topics for %s" +msgstr "Tendencias para %s" + +#: controller/mainController.py:448 controller/mainController.py:464 +#: controller/mainController.py:1080 controller/mainController.py:1099 +#: controller/mainController.py:1118 controller/mainController.py:1137 +msgid "" +"No session is currently in focus. Focus a session with the next or previous " +"session shortcut." +msgstr "No estás en ninguna sesión. Cambia a una sesión activa." + +#: controller/mainController.py:452 +msgid "Empty buffer." +msgstr "Buffer vacío." + +#: controller/mainController.py:459 +msgid "{0} not found." +msgstr "{0} no encontrado." + +#: controller/mainController.py:469 +msgid "Filters cannot be applied on this buffer" +msgstr "No pueden aplicarse filtros sobre este buffer" + +#: controller/mainController.py:522 controller/mainController.py:539 +#: controller/mainController.py:568 +msgid "Select the user" +msgstr "Selecciona un usuario" + +#: controller/mainController.py:753 +msgid "Add an user alias" +msgstr "Añadir alias de usuario" + +#: controller/mainController.py:761 +msgid "Alias has been set correctly for {}." +msgstr "Añadido el alias para {}" + +#: controller/mainController.py:829 controller/messages.py:327 +msgid "MMM D, YYYY. H:m" +msgstr "D MMM, YYYY. H:m" + +#: controller/mainController.py:957 +msgid "Conversation with {0}" +msgstr "Conversación con {0}" + +#: controller/mainController.py:998 controller/mainController.py:1015 +msgid "There are no coordinates in this tweet" +msgstr "No hay coordenadas en este tuit" + +#: controller/mainController.py:1000 controller/mainController.py:1019 +msgid "Error decoding coordinates. Try again later." +msgstr "Error decodificando las coordenadas. Inténtalo nuevamente más tarde." + +#: controller/mainController.py:1004 +msgid "Unable to find address in OpenStreetMap." +msgstr "Imposible encontrar dirección en Open Street Map." + +#: controller/mainController.py:1017 +msgid "There are no results for the coordinates in this tweet" +msgstr "No hay resultados para las coordenadas en este tuit" + +#: controller/mainController.py:1128 controller/mainController.py:1147 +#, python-format +msgid "%s, %s of %s" +msgstr "%s, %s de %s" + +#: controller/mainController.py:1130 controller/mainController.py:1149 +#: controller/mainController.py:1174 controller/mainController.py:1199 +#, python-format +msgid "%s. Empty" +msgstr "%s. Vacío" + +#: controller/mainController.py:1162 controller/mainController.py:1166 +#: controller/mainController.py:1187 +msgid "{0}: This account is not logged into Twitter." +msgstr "{0}: No has iniciado sesión con esta cuenta en Twitter." + +#: controller/mainController.py:1172 controller/mainController.py:1197 +#, python-format +msgid "%s. %s, %s of %s" +msgstr "%s. %s, %s de %s" + +#: controller/mainController.py:1191 +msgid "{0}: This account is not logged into twitter." +msgstr "{0}: No has iniciado sesión con esta cuenta en Twitter." + +#: controller/buffers/twitter/base.py:70 controller/mainController.py:1400 +#: controller/settings.py:293 +msgid "Friends" +msgstr "Amigos" + +#: controller/mainController.py:1416 +msgid "This list is already opened" +msgstr "Esta lista ya ha sido abierta" + +#: controller/mainController.py:1446 controller/mainController.py:1462 +msgid "" +"An error happened while trying to connect to the server. Please try later." +msgstr "" +"Ha ocurrido un error al intentar conectarse al servidor. Por favor, " +"inténtalo más tarde." + +#: controller/mainController.py:1498 +msgid "The auto-reading of new tweets is enabled for this buffer" +msgstr "La lectura automática de nuevos tuits para este buffer está activada" + +#: controller/mainController.py:1501 +msgid "The auto-reading of new tweets is disabled for this buffer" +msgstr "" +"La lectura automática de nuevos tuits para este buffer está desactivada" + +#: controller/mainController.py:1508 +msgid "Session mute on" +msgstr "Silencio de sesión activo" + +#: controller/mainController.py:1511 +msgid "Session mute off" +msgstr "Silencio de sesión desactivado" + +#: controller/mainController.py:1519 +msgid "Buffer mute on" +msgstr "Silenciar buffer, activado" + +#: controller/mainController.py:1522 +msgid "Buffer mute off" +msgstr "Silenciar buffer, desactivado" + +#: controller/mainController.py:1542 +msgid "Copied" +msgstr "Copiado" + +#: controller/mainController.py:1572 +msgid "Unable to update this buffer." +msgstr "Imposible actualizar este buffer." + +#: controller/mainController.py:1575 +msgid "Updating buffer..." +msgstr "Actualizando buffer..." + +#: controller/mainController.py:1578 +msgid "{0} items retrieved" +msgstr "{0} elementos descargados" + +#: controller/mainController.py:1597 controller/mainController.py:1617 +msgid "Invalid buffer" +msgstr "Buffer inválido" + +#: controller/mainController.py:1608 +msgid "Picture {0}" +msgstr "Foto {0}" + +#: controller/mainController.py:1609 +msgid "Select the picture" +msgstr "Selecciona la foto" + +#: controller/mainController.py:1628 +msgid "Unable to extract text" +msgstr "Imposible extraer texto" + +#: controller/messages.py:49 +msgid "Translated" +msgstr "Traducido" + +#: controller/messages.py:56 +#, python-format +msgid "%s - %s of %d characters" +msgstr "%s - %s de %d caracteres" + +#: controller/buffers/twitter/base.py:428 controller/messages.py:268 +#, python-format +msgid "Direct message to %s" +msgstr "Mensaje directo a %s" + +#: controller/buffers/twitter/base.py:87 +#: controller/buffers/twitter/trends.py:43 +#: controller/buffers/twitter/trends.py:134 controller/messages.py:296 +#: wxUI/buffers/base.py:25 wxUI/buffers/events.py:15 wxUI/buffers/trends.py:18 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:309 wxUI/sysTrayIcon.py:35 +msgid "Tweet" +msgstr "Tuit" + +#: controller/messages.py:354 +msgid "View item" +msgstr "Ver elemento" + +#: controller/messages.py:379 +msgid "Link copied to clipboard." +msgstr "Enlace copiado al portapapeles" + +#: controller/settings.py:74 +msgid "System default" +msgstr "Predeterminado del sistema" + +#: controller/settings.py:74 +msgid "HTTP" +msgstr "HTTP" + +#: controller/settings.py:74 +msgid "SOCKS v4" +msgstr "SOCKS v4" + +#: controller/settings.py:74 +msgid "SOCKS v4 with DNS support" +msgstr "SOCKS v4 con soporte DNS" + +#: controller/settings.py:74 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: controller/settings.py:74 +msgid "SOCKS v5 with DNS support" +msgstr "SOCKS v5 con soporte DNS" + +#: controller/settings.py:145 controller/settings.py:211 +#: wxUI/dialogs/configuration.py:116 +msgid "Ask" +msgstr "Preguntar" + +#: controller/settings.py:147 controller/settings.py:213 +#: wxUI/dialogs/configuration.py:116 +msgid "Retweet without comments" +msgstr "Retuitear sin comentario" + +#: controller/settings.py:149 wxUI/dialogs/configuration.py:116 +msgid "Retweet with comments" +msgstr "Retuitear añadiendo un comentario" + +#: controller/settings.py:185 +#, python-format +msgid "Account settings for %s" +msgstr "Opciones de la cuenta de %s" + +#: controller/settings.py:288 +msgid "Direct Messages" +msgstr "Mensajes directos" + +#: controller/user.py:29 wxUI/commonMessageDialogs.py:39 +msgid "That user does not exist" +msgstr "El usuario no existe" + +#: controller/user.py:29 controller/user.py:31 extra/SpellChecker/wx_ui.py:80 +#: issueReporter/wx_ui.py:84 issueReporter/wx_ui.py:87 +#: wxUI/commonMessageDialogs.py:39 wxUI/commonMessageDialogs.py:51 +#: wxUI/commonMessageDialogs.py:58 wxUI/commonMessageDialogs.py:61 +#: wxUI/commonMessageDialogs.py:64 wxUI/commonMessageDialogs.py:67 +#: wxUI/commonMessageDialogs.py:77 wxUI/commonMessageDialogs.py:80 +#: wxUI/commonMessageDialogs.py:83 wxUI/commonMessageDialogs.py:89 +#: wxUI/commonMessageDialogs.py:92 +msgid "Error" +msgstr "Error" + +#: controller/user.py:31 +msgid "User has been suspended" +msgstr "El usuario ha sido suspendido" + +#: controller/user.py:37 +#, python-format +msgid "Information for %s" +msgstr "Detalles para %s" + +#: controller/user.py:67 extra/AudioUploader/audioUploader.py:127 +msgid "Discarded" +msgstr "Descartado" + +#: controller/user.py:95 +#, python-format +msgid "Username: @%s\n" +msgstr "Nombre de usuario: @%s\n" + +#: controller/user.py:96 +#, python-format +msgid "Name: %s\n" +msgstr "Nombre: %s\n" + +#: controller/user.py:98 +#, python-format +msgid "Location: %s\n" +msgstr "Ubicación: %s\n" + +#: controller/user.py:100 +#, python-format +msgid "URL: %s\n" +msgstr "URL: %s\n" + +#: controller/user.py:104 +#, python-format +msgid "Bio: %s\n" +msgstr "Descripción: %s\n" + +#: controller/user.py:105 controller/user.py:120 +msgid "Yes" +msgstr "Sí" + +#: controller/user.py:106 controller/user.py:121 +msgid "No" +msgstr "No" + +#: controller/user.py:107 +#, python-format +msgid "Protected: %s\n" +msgstr "Protegido: %s\n" + +#: controller/user.py:112 +msgid "You follow {0}. " +msgstr "Sigues a {0}. " + +#: controller/user.py:115 +msgid "{0} is following you." +msgstr "{0} te sigue." + +#: controller/user.py:119 +#, python-format +msgid "" +"Followers: %s\n" +" Friends: %s\n" +msgstr "" +"Seguidores: %s\n" +" Amigos: %s\n" + +#: controller/user.py:122 +#, python-format +msgid "Verified: %s\n" +msgstr "Verificado: %s\n" + +#: controller/user.py:123 +#, python-format +msgid "Tweets: %s\n" +msgstr "Tuits: %s\n" + +#: controller/user.py:124 +#, python-format +msgid "Likes: %s" +msgstr "Me gusta: %s" + +#: controller/userActionsController.py:74 +msgid "You can't ignore direct messages" +msgstr "No puedes ignorar los mensajes directos" + +#: controller/userAliasController.py:32 +msgid "Edit alias for {}" +msgstr "Editar alias para {}" + +#: controller/buffers/base/base.py:91 +msgid "This action is not supported for this buffer" +msgstr "Esta acción no se encuentra soportada para este buffer" + +#: controller/buffers/twitter/base.py:76 +msgid "{username}'s timeline" +msgstr "Línea temporal de {username}" + +#: controller/buffers/twitter/base.py:78 +msgid "{username}'s likes" +msgstr "Tuits que le gustan a {username}" + +#: controller/buffers/twitter/base.py:80 +msgid "{username}'s followers" +msgstr "Seguidores de {username}" + +#: controller/buffers/twitter/base.py:82 +msgid "{username}'s friends" +msgstr "Amigos de {username}" + +#: controller/buffers/twitter/base.py:84 +msgid "Unknown buffer" +msgstr "Buffer desconocido" + +#: controller/buffers/twitter/base.py:88 +#: controller/buffers/twitter/trends.py:44 +#: controller/buffers/twitter/trends.py:135 +msgid "Write the tweet here" +msgstr "Escribe el tuit aquí" + +#: controller/buffers/twitter/base.py:192 +msgid "New tweet in {0}" +msgstr "Nuevo tuit en {0}" + +#: controller/buffers/twitter/base.py:195 +msgid "{0} new tweets in {1}." +msgstr "{0} nuevos tuits en {1}." + +#: controller/buffers/twitter/base.py:234 +#: controller/buffers/twitter/directMessages.py:88 +#: controller/buffers/twitter/people.py:174 +#, python-format +msgid "%s items retrieved" +msgstr "%s elementos recuperados" + +#: controller/buffers/twitter/base.py:266 +#: controller/buffers/twitter/people.py:80 +msgid "This buffer is not a timeline; it can't be deleted." +msgstr "Este buffer no es una línea temporal. No se puede eliminar." + +#: controller/buffers/twitter/base.py:402 +msgid "Reply to {arg0}" +msgstr "Responder a {arg0}" + +#: controller/buffers/twitter/base.py:404 keystrokeEditor/constants.py:11 +#: wxUI/buffers/base.py:27 +msgid "Reply" +msgstr "Responder" + +#: controller/buffers/twitter/base.py:405 +#, python-format +msgid "Reply to %s" +msgstr "Responder a %s" + +#: controller/buffers/twitter/base.py:428 +#: controller/buffers/twitter/directMessages.py:124 +msgid "New direct message" +msgstr "Nuevo mensaje directo" + +#: controller/buffers/twitter/base.py:459 +msgid "Quote" +msgstr "Citar" + +#: controller/buffers/twitter/base.py:459 +msgid "Add your comment to the tweet" +msgstr "Añade tu comentario al tuit" + +#: controller/buffers/twitter/base.py:520 +msgid "Opening URL..." +msgstr "Abriendo URL..." + +#: controller/buffers/twitter/base.py:557 +msgid "User details" +msgstr "Detalles del usuario" + +#: controller/buffers/twitter/base.py:578 +msgid "Opening item in web browser..." +msgstr "Abriendo elemento en el navegador..." + +#: controller/buffers/twitter/directMessages.py:93 +#: controller/buffers/twitter/people.py:95 wxUI/buffers/people.py:17 +msgid "Mention" +msgstr "Mención" + +#: controller/buffers/twitter/directMessages.py:93 +#: controller/buffers/twitter/people.py:95 +#, python-format +msgid "Mention to %s" +msgstr "Mencionar a %s" + +#: controller/buffers/twitter/directMessages.py:127 +msgid "{0} new direct messages." +msgstr "{0} mensajes directos nuevos." + +#: controller/buffers/twitter/directMessages.py:130 +msgid "This action is not supported in the buffer yet." +msgstr "Esta acción todavía no se soporta en este buffer." + +#: controller/buffers/twitter/directMessages.py:140 +msgid "" +"Getting more items cannot be done in this buffer. Use the direct messages " +"buffer instead." +msgstr "" +"No se pueden obtener más elementos en este buffer. Usa el buffer de mensajes " +"directos en su lugar." + +#: controller/buffers/twitter/people.py:247 +msgid "{0} new followers." +msgstr "{0} nuevos seguidores." + +#: controller/buffers/twitter/trends.py:150 +msgid "This action is not supported in the buffer, yet." +msgstr "Esta acción todavía no se soporta en este buffer." + +#: extra/AudioUploader/audioUploader.py:57 +msgid "Attaching..." +msgstr "Adjuntando..." + +#: extra/AudioUploader/audioUploader.py:74 +msgid "Pause" +msgstr "Pausa" + +#: extra/AudioUploader/audioUploader.py:76 +msgid "&Resume" +msgstr "&Reanudar" + +#: extra/AudioUploader/audioUploader.py:77 +msgid "Resume" +msgstr "Reanudar" + +#: extra/AudioUploader/audioUploader.py:79 +#: extra/AudioUploader/audioUploader.py:106 extra/AudioUploader/wx_ui.py:37 +msgid "&Pause" +msgstr "&Pausa" + +#: extra/AudioUploader/audioUploader.py:94 +#: extra/AudioUploader/audioUploader.py:140 +msgid "&Stop" +msgstr "&Detener" + +#: extra/AudioUploader/audioUploader.py:95 +msgid "Recording" +msgstr "Grabando" + +#: extra/AudioUploader/audioUploader.py:100 +#: extra/AudioUploader/audioUploader.py:151 +msgid "Stopped" +msgstr "Stopped" + +#: extra/AudioUploader/audioUploader.py:102 extra/AudioUploader/wx_ui.py:39 +msgid "&Record" +msgstr "&Grabar" + +#: extra/AudioUploader/audioUploader.py:144 +#: extra/AudioUploader/audioUploader.py:154 extra/AudioUploader/wx_ui.py:35 +msgid "&Play" +msgstr "&Reproducir" + +#: extra/AudioUploader/audioUploader.py:159 +msgid "Recoding audio..." +msgstr "Recodificando audio..." + +#: extra/AudioUploader/transfer.py:82 extra/AudioUploader/transfer.py:88 +msgid "Error in file upload: {0}" +msgstr "Error al subir el archivo: {0}" + +#: extra/AudioUploader/utils.py:29 update/utils.py:29 +#, python-format +msgid "%d day, " +msgstr "%d día, " + +#: extra/AudioUploader/utils.py:31 update/utils.py:31 +#, python-format +msgid "%d days, " +msgstr "%d días, " + +#: extra/AudioUploader/utils.py:33 update/utils.py:33 +#, python-format +msgid "%d hour, " +msgstr "%d hora, " + +#: extra/AudioUploader/utils.py:35 update/utils.py:35 +#, python-format +msgid "%d hours, " +msgstr "%d horas, " + +#: extra/AudioUploader/utils.py:37 update/utils.py:37 +#, python-format +msgid "%d minute, " +msgstr "%d minuto, " + +#: extra/AudioUploader/utils.py:39 update/utils.py:39 +#, python-format +msgid "%d minutes, " +msgstr "%d minutos, " + +#: extra/AudioUploader/utils.py:41 update/utils.py:41 +#, python-format +msgid "%s second" +msgstr "%s segundo" + +#: extra/AudioUploader/utils.py:43 update/utils.py:43 +#, python-format +msgid "%s seconds" +msgstr "%s segundos" + +#: extra/AudioUploader/wx_transfer_dialogs.py:15 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:35 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:171 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:255 +msgid "File" +msgstr "Archivo" + +#: extra/AudioUploader/wx_transfer_dialogs.py:21 +msgid "Transferred" +msgstr "Transferido" + +#: extra/AudioUploader/wx_transfer_dialogs.py:26 +msgid "Total file size" +msgstr "Tamaño total del archivo" + +#: extra/AudioUploader/wx_transfer_dialogs.py:31 +msgid "Transfer rate" +msgstr "Velocidad de transferencia" + +#: extra/AudioUploader/wx_transfer_dialogs.py:36 +msgid "Time left" +msgstr "Tiempo restante" + +#: extra/AudioUploader/wx_ui.py:29 +msgid "Attach audio" +msgstr "Adjuntar audio" + +#: extra/AudioUploader/wx_ui.py:41 +msgid "&Add an existing file" +msgstr "&Añadir un archivo existente" + +#: extra/AudioUploader/wx_ui.py:42 +msgid "&Discard" +msgstr "&Descartar" + +#: extra/AudioUploader/wx_ui.py:44 +msgid "Upload to" +msgstr "Subir a" + +#: extra/AudioUploader/wx_ui.py:49 +msgid "Attach" +msgstr "Adjuntar" + +#: extra/AudioUploader/wx_ui.py:51 +msgid "&Cancel" +msgstr "&Cancelar" + +#: extra/AudioUploader/wx_ui.py:76 +msgid "Select the audio file to be uploaded" +msgstr "Selecciona el archivo de audio que deseas subir" + +#: extra/AudioUploader/wx_ui.py:76 +msgid "Audio Files (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" +msgstr "Archivos de audio (*.mp3, *.ogg, *.wav)|*.mp3; *.ogg; *.wav" + +#: extra/SoundsTutorial/soundsTutorial_constants.py:7 +msgid "Audio tweet." +msgstr "Tuit con audio." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:8 +msgid "User timeline buffer created." +msgstr "Línea temporal de un usuario creada." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:9 +msgid "Buffer destroied." +msgstr "Buffer eliminado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:10 +msgid "Direct message received." +msgstr "Mensaje directo recibido." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:11 +msgid "Direct message sent." +msgstr "Mensaje directo enviado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:12 +msgid "Error." +msgstr "Error." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:13 +msgid "Tweet liked." +msgstr "Tuit marcado como me gusta." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:14 +msgid "Likes buffer updated." +msgstr "Un Buffer de tuits marcados como me gusta se ha actualizado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:15 +msgid "Geotweet." +msgstr "Tuit con información geográfica." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:16 +msgid "Tweet contains one or more images" +msgstr "El tuit contiene una o más imágenes" + +#: extra/SoundsTutorial/soundsTutorial_constants.py:17 +msgid "Boundary reached." +msgstr "No hay más elementos en el buffer." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:18 +msgid "List updated." +msgstr "Lista actualizada." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:19 +msgid "Too many characters." +msgstr "Demasiados caracteres." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:20 +msgid "Mention received." +msgstr "Mención recibida." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:21 +msgid "New event." +msgstr "Nuevo evento." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:22 +msgid "{0} is ready." +msgstr "{0} está listo." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:23 +msgid "Mention sent." +msgstr "Mención enviada." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:24 +msgid "Tweet retweeted." +msgstr "Tuit retuiteado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:25 +msgid "Search buffer updated." +msgstr "Buffer de búsqueda actualizado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:26 +msgid "Tweet received." +msgstr "Tuit recibido." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:27 +msgid "Tweet sent." +msgstr "Tuit enviado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:28 +msgid "Trending topics buffer updated." +msgstr "Buffer de trending topics actualizado." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:29 +msgid "New tweet in user timeline buffer." +msgstr "Nuevo tuit en línea temporal de un usuario." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:30 +msgid "New follower." +msgstr "Nuevo seguidor." + +#: extra/SoundsTutorial/soundsTutorial_constants.py:31 +msgid "Volume changed." +msgstr "Volumen modificado." + +#: extra/SoundsTutorial/wx_ui.py:9 +msgid "Sounds tutorial" +msgstr "Tutorial de sonidos" + +#: extra/SoundsTutorial/wx_ui.py:12 +msgid "Press enter to listen to the sound for the selected event" +msgstr "Pulsa enter para escuchar el sonido para el evento seleccionado" + +#: extra/SpellChecker/spellchecker.py:60 +#, python-format +msgid "Misspelled word: %s" +msgstr "Palabra mal escrita: %s" + +#: extra/SpellChecker/wx_ui.py:28 +msgid "Misspelled word" +msgstr "Palabra mal escrita" + +#: extra/SpellChecker/wx_ui.py:33 +msgid "Context" +msgstr "Contexto" + +#: extra/SpellChecker/wx_ui.py:38 +msgid "Suggestions" +msgstr "Sugerencias" + +#: extra/SpellChecker/wx_ui.py:43 +msgid "&Ignore" +msgstr "&Ignorar" + +#: extra/SpellChecker/wx_ui.py:44 +msgid "I&gnore all" +msgstr "Ignorar &todo" + +#: extra/SpellChecker/wx_ui.py:45 +msgid "&Replace" +msgstr "&Reemplazar" + +#: extra/SpellChecker/wx_ui.py:46 +msgid "R&eplace all" +msgstr "R&eemplazar todo" + +#: extra/SpellChecker/wx_ui.py:47 +msgid "&Add to personal dictionary" +msgstr "Añadir al &diccionario" + +#: extra/SpellChecker/wx_ui.py:80 +msgid "" +"An error has occurred. There are no dictionaries available for the selected " +"language in {0}" +msgstr "" +"Ha ocurrido un error. No se encuentran diccionarios disponibles para el " +"idioma seleccionado en {0}." + +#: extra/SpellChecker/wx_ui.py:83 +msgid "Spell check complete." +msgstr "Corrección ortográfica finalizada." + +#: extra/autocompletionUsers/completion.py:20 +#: extra/autocompletionUsers/completion.py:38 +msgid "You have to start writing" +msgstr "Tienes que empezar a escribir" + +#: extra/autocompletionUsers/completion.py:30 +#: extra/autocompletionUsers/completion.py:47 +msgid "There are no results in your users database" +msgstr "No hay resultados en tu base de datos de usuarios" + +#: extra/autocompletionUsers/completion.py:32 +msgid "Autocompletion only works for users." +msgstr "El autocompletado solo funciona con usuarios." + +#: extra/autocompletionUsers/settings.py:25 +msgid "" +"Updating database... You can close this window now. A message will tell you " +"when the process finishes." +msgstr "" +"Actualizando base de datos... Puedes cerrar esta ventana ahora. Un mensaje " +"te informará cuando el proceso haya terminado." + +#: extra/autocompletionUsers/wx_manage.py:9 +msgid "Manage Autocompletion database" +msgstr "Gestionar la base de datos del autocompletado de usuarios" + +#: extra/autocompletionUsers/wx_manage.py:12 +msgid "Editing {0} users database" +msgstr "Editando la base de datos de usuarios de {0}" + +#: extra/autocompletionUsers/wx_manage.py:13 +msgid "Username" +msgstr "Nombre de usuario" + +#: extra/autocompletionUsers/wx_manage.py:13 wxUI/dialogs/configuration.py:144 +msgid "Name" +msgstr "Nombre" + +#: extra/autocompletionUsers/wx_manage.py:16 +msgid "Add user" +msgstr "Añadir usuario" + +#: extra/autocompletionUsers/wx_manage.py:17 +msgid "Remove user" +msgstr "Quitar usuario" + +#: extra/autocompletionUsers/wx_manage.py:38 +msgid "Twitter username" +msgstr "Nombre de usuario de Twitter" + +#: extra/autocompletionUsers/wx_manage.py:38 +msgid "Add user to database" +msgstr "Añadir usuario a la base de datos" + +#: extra/autocompletionUsers/wx_manage.py:44 +msgid "The user does not exist" +msgstr "El usuario no existe" + +#: extra/autocompletionUsers/wx_manage.py:44 wxUI/commonMessageDialogs.py:45 +msgid "Error!" +msgstr "¡Error!" + +#: extra/autocompletionUsers/wx_settings.py:8 +msgid "Autocomplete users' settings" +msgstr "Opciones de autocompletado de usuarios" + +#: extra/autocompletionUsers/wx_settings.py:11 +msgid "Add users from followers buffer" +msgstr "Añadir usuarios desde el buffer de seguidores" + +#: extra/autocompletionUsers/wx_settings.py:12 +msgid "Add users from friends buffer" +msgstr "Añadir usuarios desde el buffer de amigos" + +#: extra/autocompletionUsers/wx_settings.py:15 +msgid "Manage database..." +msgstr "Administrar base de datos..." + +#: extra/autocompletionUsers/wx_settings.py:27 +msgid "{0}'s database of users has been updated." +msgstr "La base de datos de usuarios de {0} ha sido actualizada." + +#: extra/autocompletionUsers/wx_settings.py:27 +msgid "Done" +msgstr "¡Hecho" + +#: extra/ocr/OCRSpace.py:7 +msgid "Detect automatically" +msgstr "Detectar automáticamente" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:41 +msgid "Danish" +msgstr "Danés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:43 +msgid "Dutch" +msgstr "Holandés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:44 +msgid "English" +msgstr "Inglés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:48 +msgid "Finnish" +msgstr "Finés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:49 +msgid "French" +msgstr "Francés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:52 +msgid "German" +msgstr "Alemán" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:58 +msgid "Hungarian" +msgstr "Húngaro" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:68 +msgid "Korean" +msgstr "Coreano" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:63 +msgid "Italian" +msgstr "Italiano" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:64 +msgid "Japanese" +msgstr "Japonés" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:85 +msgid "Polish" +msgstr "Polaco" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:86 +msgid "Portuguese" +msgstr "Portugués" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:89 +msgid "Russian" +msgstr "Ruso" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:96 +msgid "Spanish" +msgstr "Español" + +#: extra/ocr/OCRSpace.py:7 extra/translator/translator.py:105 +msgid "Turkish" +msgstr "Turco" + +#: extra/translator/translator.py:22 +msgid "Afrikaans" +msgstr "Africano" + +#: extra/translator/translator.py:23 +msgid "Albanian" +msgstr "Albanés" + +#: extra/translator/translator.py:24 +msgid "Amharic" +msgstr "Amárico" + +#: extra/translator/translator.py:25 +msgid "Arabic" +msgstr "Árabe" + +#: extra/translator/translator.py:26 +msgid "Armenian" +msgstr "Armenio" + +#: extra/translator/translator.py:27 +msgid "Azerbaijani" +msgstr "Acerí" + +#: extra/translator/translator.py:28 +msgid "Basque" +msgstr "Vasco" + +#: extra/translator/translator.py:29 +msgid "Belarusian" +msgstr "Bielorruso" + +#: extra/translator/translator.py:30 +msgid "Bengali" +msgstr "Bengalí" + +#: extra/translator/translator.py:31 +msgid "Bihari" +msgstr "Bihari" + +#: extra/translator/translator.py:32 +msgid "Bulgarian" +msgstr "Búlgaro" + +#: extra/translator/translator.py:33 +msgid "Burmese" +msgstr "Birmano" + +#: extra/translator/translator.py:34 +msgid "Catalan" +msgstr "Catalán" + +#: extra/translator/translator.py:35 +msgid "Cherokee" +msgstr "Cheroqui" + +#: extra/translator/translator.py:36 +msgid "Chinese" +msgstr "Chino" + +#: extra/translator/translator.py:37 +msgid "Chinese_simplified" +msgstr "Chino simplificado" + +#: extra/translator/translator.py:38 +msgid "Chinese_traditional" +msgstr "Chino tradicional" + +#: extra/translator/translator.py:39 +msgid "Croatian" +msgstr "Croata" + +#: extra/translator/translator.py:40 +msgid "Czech" +msgstr "Checo" + +#: extra/translator/translator.py:42 +msgid "Dhivehi" +msgstr "Dhivehi" + +#: extra/translator/translator.py:45 +msgid "Esperanto" +msgstr "Esperanto" + +#: extra/translator/translator.py:46 +msgid "Estonian" +msgstr "Estonio" + +#: extra/translator/translator.py:47 +msgid "Filipino" +msgstr "Filipino" + +#: extra/translator/translator.py:50 +msgid "Galician" +msgstr "Gallego" + +#: extra/translator/translator.py:51 +msgid "Georgian" +msgstr "Georgiano" + +#: extra/translator/translator.py:53 +msgid "Greek" +msgstr "Griego" + +#: extra/translator/translator.py:54 +msgid "Guarani" +msgstr "Guaraní" + +#: extra/translator/translator.py:55 +msgid "Gujarati" +msgstr "Guyaratí" + +#: extra/translator/translator.py:56 +msgid "Hebrew" +msgstr "Hebreo" + +#: extra/translator/translator.py:57 +msgid "Hindi" +msgstr "Hindi" + +#: extra/translator/translator.py:59 +msgid "Icelandic" +msgstr "Islandés" + +#: extra/translator/translator.py:60 +msgid "Indonesian" +msgstr "Indonesio" + +#: extra/translator/translator.py:61 +msgid "Inuktitut" +msgstr "Inuktitut" + +#: extra/translator/translator.py:62 +msgid "Irish" +msgstr "Irlandés" + +#: extra/translator/translator.py:65 +msgid "Kannada" +msgstr "Canarés" + +#: extra/translator/translator.py:66 +msgid "Kazakh" +msgstr "Kazajo" + +#: extra/translator/translator.py:67 +msgid "Khmer" +msgstr "Camboyano" + +#: extra/translator/translator.py:69 +msgid "Kurdish" +msgstr "Kurdo" + +#: extra/translator/translator.py:70 +msgid "Kyrgyz" +msgstr "Kirguís" + +#: extra/translator/translator.py:71 +msgid "Laothian" +msgstr "Lao" + +#: extra/translator/translator.py:72 +msgid "Latvian" +msgstr "Letón" + +#: extra/translator/translator.py:73 +msgid "Lithuanian" +msgstr "Lituano" + +#: extra/translator/translator.py:74 +msgid "Macedonian" +msgstr "Macedonio" + +#: extra/translator/translator.py:75 +msgid "Malay" +msgstr "Malayo" + +#: extra/translator/translator.py:76 +msgid "Malayalam" +msgstr "Malayalam" + +#: extra/translator/translator.py:77 +msgid "Maltese" +msgstr "Maltés" + +#: extra/translator/translator.py:78 +msgid "Marathi" +msgstr "Maratí" + +#: extra/translator/translator.py:79 +msgid "Mongolian" +msgstr "Mongol" + +#: extra/translator/translator.py:80 +msgid "Nepali" +msgstr "Nepalí" + +#: extra/translator/translator.py:81 +msgid "Norwegian" +msgstr "Noruego" + +#: extra/translator/translator.py:82 +msgid "Oriya" +msgstr "Oriya" + +#: extra/translator/translator.py:83 +msgid "Pashto" +msgstr "Pastú" + +#: extra/translator/translator.py:84 +msgid "Persian" +msgstr "Persa" + +#: extra/translator/translator.py:87 +msgid "Punjabi" +msgstr "Panyabí" + +#: extra/translator/translator.py:88 +msgid "Romanian" +msgstr "Rumano" + +#: extra/translator/translator.py:90 +msgid "Sanskrit" +msgstr "Sánscrito" + +#: extra/translator/translator.py:91 +msgid "Serbian" +msgstr "Serbio" + +#: extra/translator/translator.py:92 +msgid "Sindhi" +msgstr "Sindhi" + +#: extra/translator/translator.py:93 +msgid "Sinhalese" +msgstr "Cingalés" + +#: extra/translator/translator.py:94 +msgid "Slovak" +msgstr "Eslovaco" + +#: extra/translator/translator.py:95 +msgid "Slovenian" +msgstr "Esloveno" + +#: extra/translator/translator.py:97 +msgid "Swahili" +msgstr "Suajili" + +#: extra/translator/translator.py:98 +msgid "Swedish" +msgstr "Sueco" + +#: extra/translator/translator.py:99 +msgid "Tajik" +msgstr "Tayiko" + +#: extra/translator/translator.py:100 +msgid "Tamil" +msgstr "Tamil" + +#: extra/translator/translator.py:101 +msgid "Tagalog" +msgstr "Tagalo" + +#: extra/translator/translator.py:102 +msgid "Telugu" +msgstr "Telugú" + +#: extra/translator/translator.py:103 +msgid "Thai" +msgstr "Tailandés" + +#: extra/translator/translator.py:104 +msgid "Tibetan" +msgstr "Tibetano" + +#: extra/translator/translator.py:106 +msgid "Ukrainian" +msgstr "Ucraniano" + +#: extra/translator/translator.py:107 +msgid "Urdu" +msgstr "Urdu" + +#: extra/translator/translator.py:108 +msgid "Uzbek" +msgstr "Uzbeco" + +#: extra/translator/translator.py:109 +msgid "Uighur" +msgstr "Uigur" + +#: extra/translator/translator.py:110 +msgid "Vietnamese" +msgstr "Vietnamita" + +#: extra/translator/translator.py:111 +msgid "Welsh" +msgstr "Galés" + +#: extra/translator/translator.py:112 +msgid "Yiddish" +msgstr "Yídish" + +#: extra/translator/wx_ui.py:29 +msgid "Translate message" +msgstr "Traducir mensaje" + +#: extra/translator/wx_ui.py:32 +msgid "Target language" +msgstr "Idioma de destino" + +#: issueReporter/issueReporter.py:32 wxUI/dialogs/configuration.py:359 +#: wxUI/dialogs/configuration.py:368 +msgid "General" +msgstr "General" + +#: issueReporter/issueReporter.py:33 +msgid "always" +msgstr "siempre" + +#: issueReporter/issueReporter.py:33 +msgid "sometimes" +msgstr "a veces" + +#: issueReporter/issueReporter.py:33 +msgid "random" +msgstr "aleatoriamente" + +#: issueReporter/issueReporter.py:33 +msgid "have not tried" +msgstr "no se ha intentado" + +#: issueReporter/issueReporter.py:33 +msgid "unable to duplicate" +msgstr "imposible de reproducir" + +#: issueReporter/issueReporter.py:34 +msgid "block" +msgstr "bloqueo" + +#: issueReporter/issueReporter.py:34 +msgid "crash" +msgstr "fallo" + +#: issueReporter/issueReporter.py:34 +msgid "major" +msgstr "mayor" + +#: issueReporter/issueReporter.py:34 +msgid "minor" +msgstr "menor" + +#: issueReporter/issueReporter.py:34 +msgid "tweak" +msgstr "ajuste" + +#: issueReporter/issueReporter.py:34 +msgid "text" +msgstr "texto" + +#: issueReporter/issueReporter.py:34 +msgid "trivial" +msgstr "trivial" + +#: issueReporter/issueReporter.py:34 +msgid "feature" +msgstr "característica" + +#: issueReporter/wx_ui.py:26 +msgid "Report an error" +msgstr "Reportar un error" + +#: issueReporter/wx_ui.py:29 +msgid "Select a category" +msgstr "Selecciona una categoría" + +#: issueReporter/wx_ui.py:37 +msgid "" +"Briefly describe what happened. You will be able to thoroughly explain it " +"later" +msgstr "" +"Describe en pocas palabras lo que ha pasado (después podrás profundizar)" + +#: issueReporter/wx_ui.py:46 +msgid "Here, you can describe the bug in detail" +msgstr "Aquí puedes describir el error en detalle" + +#: issueReporter/wx_ui.py:56 +msgid "how often does this bug happen?" +msgstr "¿Qué tan a menudo ocurre este error?" + +#: issueReporter/wx_ui.py:63 +msgid "Select the importance that you think this bug has" +msgstr "Selecciona la importancia que consideras que tiene este error" + +#: issueReporter/wx_ui.py:70 +msgid "" +"I know that the {0} bug system will get my Twitter username to contact me " +"and fix the bug quickly" +msgstr "" +"Sé que el sistema de errores de {0} obtendrá mi nombre de usuario de Twitter " +"para contactarme y resolver el error rápidamente" + +#: issueReporter/wx_ui.py:73 +msgid "Send report" +msgstr "Enviar reporte" + +#: issueReporter/wx_ui.py:75 wxUI/dialogs/filterDialogs.py:83 +#: wxUI/dialogs/find.py:23 +msgid "Cancel" +msgstr "Cancelar" + +#: issueReporter/wx_ui.py:84 +msgid "You must fill out both fields" +msgstr "Debes llenar ambos campos" + +#: issueReporter/wx_ui.py:87 +msgid "" +"You need to mark the checkbox to provide us your twitter username to contact " +"you if it is necessary." +msgstr "" +"Debes marcar la casilla para proporcionarnos tu nombre de usuario de Twitter " +"para poder contactarte si es necesario." + +#: issueReporter/wx_ui.py:90 +#, python-format +msgid "" +"Thanks for reporting this bug! In future versions, you may be able to find " +"it in the changes list. You've reported the bug number %i" +msgstr "" +"¡Gracias por reportar este error! Quizá puedas verlo entre la lista de " +"cambios de próximas versiones. Has reportado el error número %i" + +#: issueReporter/wx_ui.py:90 +msgid "reported" +msgstr "reportado" + +#: issueReporter/wx_ui.py:94 +msgid "" +"Something unexpected occurred while trying to report the bug. Please, try " +"again later" +msgstr "" +"Algo inesperado ocurrió mientras intentábamos reportar tu error. Por favor, " +"vuelve a intentarlo más tarde" + +#: issueReporter/wx_ui.py:94 +msgid "Error while reporting" +msgstr "Error al reportar" + +#: keystrokeEditor/constants.py:3 +msgid "Go up in the current buffer" +msgstr "Va arriba en la lista actual" + +#: keystrokeEditor/constants.py:4 +msgid "Go down in the current buffer" +msgstr "Va abajo en la lista actual" + +#: keystrokeEditor/constants.py:5 +msgid "Go to the previous buffer" +msgstr "Va al buffer anterior" + +#: keystrokeEditor/constants.py:6 +msgid "Go to the next buffer" +msgstr "Va al buffer siguiente" + +#: keystrokeEditor/constants.py:7 +msgid "Focus the next session" +msgstr "Ir a la siguiente sesión" + +#: keystrokeEditor/constants.py:8 +msgid "Focus the previous session" +msgstr "Va a la sesión anterior" + +#: keystrokeEditor/constants.py:9 +msgid "Show or hide the GUI" +msgstr "Muestra o esconde la interfaz gráfica" + +#: keystrokeEditor/constants.py:10 +msgid "New tweet" +msgstr "Nuevo tuit" + +#: keystrokeEditor/constants.py:12 wxUI/buffers/base.py:26 +#: wxUI/commonMessageDialogs.py:10 +msgid "Retweet" +msgstr "Retuit" + +#: keystrokeEditor/constants.py:13 +msgid "Send direct message" +msgstr "Enviar mensaje directo" + +#: keystrokeEditor/constants.py:14 +msgid "Like a tweet" +msgstr "Marcar tuit como me gusta" + +#: keystrokeEditor/constants.py:15 +msgid "Like/unlike a tweet" +msgstr "Marcar o remover tuit como me gusta" + +#: keystrokeEditor/constants.py:16 +msgid "Unlike a tweet" +msgstr "Marcar tuit como ya no me gusta" + +#: keystrokeEditor/constants.py:17 +msgid "Open the user actions dialogue" +msgstr "Abrir el diálogo de acciones" + +#: keystrokeEditor/constants.py:18 +msgid "See user details" +msgstr "Ver detalles del usuario" + +#: keystrokeEditor/constants.py:19 +msgid "Show tweet" +msgstr "Ver tuit" + +#: keystrokeEditor/constants.py:20 +msgid "Quit" +msgstr "Salir" + +#: keystrokeEditor/constants.py:21 +msgid "Open user timeline" +msgstr "Abrir línea temporal" + +#: keystrokeEditor/constants.py:22 +msgid "Destroy buffer" +msgstr "Eliminar buffer" + +#: keystrokeEditor/constants.py:23 +msgid "Interact with the currently focused tweet." +msgstr "Interactuar con el tuit que tiene el foco." + +#: keystrokeEditor/constants.py:24 +msgid "Open URL" +msgstr "Abrir URL" + +#: keystrokeEditor/constants.py:25 +msgid "View in Twitter" +msgstr "Ver en Twitter" + +#: keystrokeEditor/constants.py:26 +msgid "Increase volume by 5%" +msgstr "Subir volumen en un 5%" + +#: keystrokeEditor/constants.py:27 +msgid "Decrease volume by 5%" +msgstr "Bajar volumen en un 5%" + +#: keystrokeEditor/constants.py:28 +msgid "Jump to the first element of a buffer" +msgstr "Ir al primer elemento del buffer" + +#: keystrokeEditor/constants.py:29 +msgid "Jump to the last element of the current buffer" +msgstr "Ir al último elemento del buffer" + +#: keystrokeEditor/constants.py:30 +msgid "Jump 20 elements up in the current buffer" +msgstr "Moverse 20 elementos hacia arriba en el buffer actual" + +#: keystrokeEditor/constants.py:31 +msgid "Jump 20 elements down in the current buffer" +msgstr "Moverse 20 elementos hacia abajo en el buffer actual" + +#: keystrokeEditor/constants.py:32 +msgid "Edit profile" +msgstr "Editar perfil" + +#: keystrokeEditor/constants.py:33 +msgid "Delete a tweet or direct message" +msgstr "Eliminar tuit o mensaje directo" + +#: keystrokeEditor/constants.py:34 +msgid "Empty the current buffer" +msgstr "Vaciar buffer" + +#: keystrokeEditor/constants.py:35 +msgid "Repeat last item" +msgstr "Repetir último elemento" + +#: keystrokeEditor/constants.py:36 +msgid "Copy to clipboard" +msgstr "Copiar al portapapeles" + +#: keystrokeEditor/constants.py:37 +msgid "Add to list" +msgstr "Añadir a lista" + +#: keystrokeEditor/constants.py:38 +msgid "Remove from list" +msgstr "Quitar de lista" + +#: keystrokeEditor/constants.py:39 +msgid "Mute/unmute the active buffer" +msgstr "Silenciar o des-silenciar el buffer activo" + +#: keystrokeEditor/constants.py:40 +msgid "Mute/unmute the current session" +msgstr "Activar o desactivar el silencio para la sesión activa" + +#: keystrokeEditor/constants.py:41 +msgid "toggle the automatic reading of incoming tweets in the active buffer" +msgstr "" +"conmutar entre la lectura automática de nuevos tuits para el buffer actual" + +#: keystrokeEditor/constants.py:42 +msgid "Search on twitter" +msgstr "Buscar en Twitter" + +#: keystrokeEditor/constants.py:43 +msgid "Find a string in the currently focused buffer" +msgstr "Buscar un término en el buffer actual" + +#: keystrokeEditor/constants.py:44 +msgid "Show the keystroke editor" +msgstr "Mostrar el editor de combinaciones de teclado" + +#: keystrokeEditor/constants.py:45 +msgid "Show lists for a specified user" +msgstr "Mostrar listas para un usuario específico" + +#: keystrokeEditor/constants.py:46 +msgid "load previous items" +msgstr "cargar elementos anteriores" + +#: keystrokeEditor/constants.py:47 +msgid "Get geolocation" +msgstr "Obtener ubicación" + +#: keystrokeEditor/constants.py:48 +msgid "Display the tweet's geolocation in a dialog" +msgstr "Mostrar la ubicación del tuit en un diálogo" + +#: keystrokeEditor/constants.py:49 +msgid "Create a trending topics buffer" +msgstr "Crear un buffer de tendencias" + +#: keystrokeEditor/constants.py:50 +msgid "View conversation" +msgstr "Ver conversación" + +#: keystrokeEditor/constants.py:51 +msgid "Check and download updates" +msgstr "&Comprobar y descargar actualizaciones" + +#: keystrokeEditor/constants.py:52 +msgid "" +"Opens the list manager, which allows you to create, edit, delete and open " +"lists in buffers." +msgstr "" +"Abre el gestor de listas, que permite crear, editar, eliminar y abrir listas " +"como buffers." + +#: keystrokeEditor/constants.py:53 +msgid "Opens the global settings dialogue" +msgstr "Abre el diálogo de opciones globales" + +#: keystrokeEditor/constants.py:54 +msgid "Opens the list manager" +msgstr "Abre el gestor de listas" + +#: keystrokeEditor/constants.py:55 +msgid "Opens the account settings dialogue" +msgstr "Abre el diálogo de opciones de cuenta" + +#: keystrokeEditor/constants.py:56 +msgid "Try to play an audio file" +msgstr "Intentar reproducir audio" + +#: keystrokeEditor/constants.py:57 +msgid "Updates the buffer and retrieves possible lost items there." +msgstr "Actualiza el buffer e intenta descargar los elementos perdidos." + +#: keystrokeEditor/constants.py:58 +msgid "Extracts the text from a picture and displays the result in a dialog." +msgstr "Extrae el texto de una foto y muestra el resultado en un diálogo." + +#: keystrokeEditor/constants.py:59 +msgid "Adds an alias to an user" +msgstr "Añade un alias a un usuario específico." + +#: keystrokeEditor/wx_ui.py:8 +msgid "Keystroke editor" +msgstr "Editor de combinaciones de teclado" + +#: keystrokeEditor/wx_ui.py:12 +msgid "Select a keystroke to edit" +msgstr "Selecciona una combinación de teclado para editarla" + +#: keystrokeEditor/wx_ui.py:13 wxUI/dialogs/userActions.py:10 +#: wxUI/dialogs/userActions.py:19 wxUI/dialogs/userActions.py:20 +msgid "Action" +msgstr "Acción" + +#: keystrokeEditor/wx_ui.py:13 +msgid "Keystroke" +msgstr "Combinación de teclado" + +#: keystrokeEditor/wx_ui.py:18 wxUI/dialogs/filterDialogs.py:135 +#: wxUI/dialogs/lists.py:20 wxUI/dialogs/userAliasDialogs.py:53 +msgid "Edit" +msgstr "Editar" + +#: keystrokeEditor/wx_ui.py:20 keystrokeEditor/wx_ui.py:50 +msgid "Undefine keystroke" +msgstr "Desasignar combinación de teclas" + +#: keystrokeEditor/wx_ui.py:21 +msgid "Execute action" +msgstr "Ejecutar acción" + +#: keystrokeEditor/wx_ui.py:22 wxUI/dialogs/configuration.py:396 +#: wxUI/dialogs/userAliasDialogs.py:25 wxUI/dialogs/utils.py:39 +msgid "Close" +msgstr "Cerrar" + +#: keystrokeEditor/wx_ui.py:42 +msgid "Undefined" +msgstr "Sin definir" + +#: keystrokeEditor/wx_ui.py:50 +msgid "Are you sure you want to undefine this keystroke?" +msgstr "¿Seguro que deseas desasignar esta combinación de teclado?" + +#: keystrokeEditor/wx_ui.py:54 +msgid "Editing keystroke" +msgstr "Editando combinación de teclas" + +#: keystrokeEditor/wx_ui.py:57 +msgid "Control" +msgstr "Control" + +#: keystrokeEditor/wx_ui.py:58 +msgid "Alt" +msgstr "Alt" + +#: keystrokeEditor/wx_ui.py:59 +msgid "Shift" +msgstr "Shift" + +#: keystrokeEditor/wx_ui.py:60 +msgid "Windows" +msgstr "Windows" + +#: keystrokeEditor/wx_ui.py:66 +msgid "Key" +msgstr "Tecla" + +#: keystrokeEditor/wx_ui.py:71 wxUI/dialogs/filterDialogs.py:80 +#: wxUI/dialogs/find.py:21 wxUI/dialogs/userAliasDialogs.py:23 +#: wxUI/dialogs/utils.py:36 +msgid "OK" +msgstr "Aceptar" + +#: keystrokeEditor/wx_ui.py:84 +msgid "You need to use the Windows key" +msgstr "Necesitas usar la tecla de windows" + +#: keystrokeEditor/wx_ui.py:84 keystrokeEditor/wx_ui.py:87 +msgid "Invalid keystroke" +msgstr "Combinación de teclado inválida" + +#: keystrokeEditor/wx_ui.py:87 +msgid "You must provide a character for the keystroke" +msgstr "Debes proporcionar una letra para el atajo de teclado" + +#: sessionmanager/wxUI.py:9 msgid "Session manager" msgstr "Gestor de sesiones" -#: ../src\sessionmanager\wxUI.py:12 +#: sessionmanager/wxUI.py:12 msgid "Accounts list" msgstr "Lista de cuentas" -#: ../src\sessionmanager\wxUI.py:14 +#: sessionmanager/wxUI.py:14 msgid "Account" msgstr "Cuenta" -#: ../src\sessionmanager\wxUI.py:18 +#: sessionmanager/wxUI.py:18 msgid "New account" msgstr "Nueva cuenta" -#: ../src\sessionmanager\wxUI.py:19 ../src\sessionmanager\wxUI.py:65 +#: sessionmanager/wxUI.py:19 sessionmanager/wxUI.py:65 msgid "Remove account" msgstr "Eliminar cuenta" -#: ../src\sessionmanager\wxUI.py:20 +#: sessionmanager/wxUI.py:20 msgid "Global Settings" msgstr "Opciones globales" -#: ../src\sessionmanager\wxUI.py:43 -msgid "Account Error" -msgstr "Error en la cuenta" - -#: ../src\sessionmanager\wxUI.py:43 +#: sessionmanager/wxUI.py:43 msgid "You need to configure an account." msgstr "Necesitas configurar una cuenta." -#: ../src\sessionmanager\wxUI.py:49 -msgid "Authorization" -msgstr "Autorización" +#: sessionmanager/wxUI.py:43 +msgid "Account Error" +msgstr "Error en la cuenta" -#: ../src\sessionmanager\wxUI.py:49 +#: sessionmanager/wxUI.py:49 msgid "" "The request to authorize your Twitter account will be opened in your " "browser. You only need to do this once. Would you like to continue?" @@ -1902,15 +1950,16 @@ msgstr "" "La solicitud de autorización de Twitter será abierta en tu navegador. Esto " "es necesario hacerlo solo una vez. ¿Quieres continuar?" -#: ../src\sessionmanager\wxUI.py:53 +#: sessionmanager/wxUI.py:49 +msgid "Authorization" +msgstr "Autorización" + +#: sessionmanager/wxUI.py:53 +#, python-format msgid "Authorized account %d" msgstr "Cuenta autorizada %d" -#: ../src\sessionmanager\wxUI.py:59 -msgid "Invalid user token" -msgstr "Código de acceso inválido" - -#: ../src\sessionmanager\wxUI.py:59 +#: sessionmanager/wxUI.py:59 msgid "" "Your access token is invalid or the authorization has failed. Please try " "again." @@ -1918,15 +1967,15 @@ msgstr "" "El código de autorización es inválido o el proceso ha fallado. Por favor " "inténtalo de nuevo más tarde." -#: ../src\sessionmanager\wxUI.py:65 +#: sessionmanager/wxUI.py:59 +msgid "Invalid user token" +msgstr "Código de acceso inválido" + +#: sessionmanager/wxUI.py:65 msgid "Do you really want to delete this account?" msgstr "¿Realmente deseas eliminar esta cuenta?" -#: ../src\sessionmanager\wxUI.py:81 -msgid "Authentication error for session {}" -msgstr "Error de autenticación en la sesión {}" - -#: ../src\sessionmanager\wxUI.py:81 +#: sessionmanager/wxUI.py:81 msgid "" "TWBlue is unable to authenticate the account for {} in Twitter. It might be " "due to an invalid or expired token, revoqued access to the application, or " @@ -1939,7 +1988,11 @@ msgstr "" "favor, elimina esta cuenta manualmente desde tus sesiones de Twitter en la " "aplicación para dejar de ver este mensaje." -#: ../src\sessions\base.py:113 +#: sessionmanager/wxUI.py:81 +msgid "Authentication error for session {}" +msgstr "Error de autenticación en la sesión {}" + +#: sessions/base.py:113 msgid "" "An exception occurred while saving the {app} database. It will be deleted " "and rebuilt automatically. If this error persists, send the error log to the " @@ -1949,7 +2002,7 @@ msgstr "" "será creada desde cero automáticamente. Si este error persiste, contacta con " "los desarrolladores de {app} para obtener ayuda." -#: ../src\sessions\base.py:153 +#: sessions/base.py:153 msgid "" "An exception occurred while loading the {app} database. It will be deleted " "and rebuilt automatically. If this error persists, send the error log to the " @@ -1959,26 +2012,46 @@ msgstr "" "de datos nueva automáticamente. Si este error persiste, contacta con los " "desarrolladores de {app} para obtener ayuda." -#: ../src\sessions\twitter\compose.py:38 ../src\sessions\twitter\compose.py:81 -#: ../src\sessions\twitter\compose.py:146 -#: ../src\sessions\twitter\compose.py:155 +#: sessions/session_utils.py:231 sessions/twitter/utils.py:231 +msgid "Sorry, you are not authorised to see this status." +msgstr "Lo sentimos, no estás autorizado para ver este tuit." + +#: sessions/session_utils.py:233 sessions/twitter/utils.py:233 +msgid "No status found with that ID" +msgstr "No existe un tuit con este ID" + +#: sessions/session_utils.py:235 +msgid "Error code {0}" +msgstr "Código de error {0}" + +#: sessions/session_utils.py:262 sessions/twitter/utils.py:262 +msgid "{user_1}, {user_2} and {all_users} more: {text}" +msgstr "{user_1}, {user_2} y {all_users} más: {text}" + +#: sessions/twitter/compose.py:38 sessions/twitter/compose.py:81 +#: sessions/twitter/compose.py:146 sessions/twitter/compose.py:155 +#: sessions/twitter/templates.py:38 sessions/twitter/templates.py:81 +#: sessions/twitter/templates.py:146 sessions/twitter/templates.py:155 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "dddd, MMMM D, YYYY H:m:s" -#: ../src\sessions\twitter\compose.py:89 ../src\sessions\twitter\compose.py:91 +#: sessions/twitter/compose.py:89 sessions/twitter/compose.py:91 +#: sessions/twitter/templates.py:89 sessions/twitter/templates.py:91 +#, python-format msgid "Dm to %s " msgstr "Dm a %s " -#: ../src\sessions\twitter\compose.py:130 +#: sessions/twitter/compose.py:130 sessions/twitter/templates.py:130 msgid "{0}. Quoted tweet from @{1}: {2}" msgstr "{0} citó el tuit de {1}: {2}" -#: ../src\sessions\twitter\compose.py:157 -#: ../src\sessions\twitter\compose.py:159 +#: sessions/twitter/compose.py:157 sessions/twitter/compose.py:159 +#: sessions/twitter/templates.py:157 sessions/twitter/templates.py:159 msgid "Unavailable" msgstr "No disponible" -#: ../src\sessions\twitter\compose.py:160 +#: sessions/twitter/compose.py:160 sessions/twitter/templates.py:160 +#, python-format msgid "" "%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " "Twitter %s" @@ -1986,64 +2059,46 @@ msgstr "" "%s (@%s). %s seguidores, %s amigos, %s tuits. Último tuit %s. Se unió a " "Twitter %s" -#: ../src\sessions\twitter\compose.py:164 +#: sessions/twitter/compose.py:164 sessions/twitter/templates.py:164 msgid "No description available" msgstr "No hay una descripción disponible" -#: ../src\sessions\twitter\compose.py:168 +#: sessions/twitter/compose.py:168 sessions/twitter/templates.py:168 msgid "private" msgstr "privado" -#: ../src\sessions\twitter\compose.py:169 +#: sessions/twitter/compose.py:169 sessions/twitter/templates.py:169 msgid "public" msgstr "público" -#: ../src\sessions\twitter\session.py:211 +#: sessions/twitter/session.py:211 sessions/twitter/session.py:238 +#, python-format msgid "%s failed. Reason: %s" msgstr "%s falló. Razón: %s" -#: ../src\sessions\twitter\session.py:217 +#: sessions/twitter/session.py:217 sessions/twitter/session.py:241 +#, python-format msgid "%s succeeded." msgstr "%s con éxito." -#: ../src\sessions\twitter\session.py:426 -#: ../src\sessions\twitter\session.py:504 +#: sessions/twitter/session.py:450 sessions/twitter/session.py:528 msgid "Deleted account" msgstr "Cuenta eliminada" -#: ../src\sessions\twitter\utils.py:231 -msgid "Sorry, you are not authorised to see this status." -msgstr "Lo sentimos, no estás autorizado para ver este tuit." - -#: ../src\sessions\twitter\utils.py:233 -msgid "No status found with that ID" -msgstr "No existe un tuit con este ID" - -#: ../src\sessions\twitter\utils.py:235 +#: sessions/twitter/utils.py:235 msgid "Error {0}" msgstr "Código de error {0}" -#: ../src\sessions\twitter\utils.py:262 -msgid "{user_1}, {user_2} and {all_users} more: {text}" -msgstr "{user_1}, {user_2} y {all_users} más: {text}" - -#: ../src\sessions\twitter\wxUI.py:7 +#: sessions/twitter/wxUI.py:7 msgid "Authorising account..." msgstr "Autorizando cuenta..." -#: ../src\sessions\twitter\wxUI.py:10 +#: sessions/twitter/wxUI.py:10 msgid "Enter your PIN code here" msgstr "Introduce el código PIN aquí" -#: ../src\sound.py:161 -msgid "Stopped." -msgstr "Detenido." - -#: ../src\update\wxUpdater.py:14 -msgid "New version for %s" -msgstr "Nueva versión de %s" - -#: ../src\update\wxUpdater.py:14 +#: update/wxUpdater.py:14 +#, python-format msgid "" "There's a new %s version available, released on %s. Would you like to " "download it now?\n" @@ -2060,23 +2115,25 @@ msgstr "" "Novedades:\n" "%s" -#: ../src\update\wxUpdater.py:22 +#: update/wxUpdater.py:14 +#, python-format +msgid "New version for %s" +msgstr "Nueva versión de %s" + +#: update/wxUpdater.py:22 msgid "Download in Progress" msgstr "Descarga en progreso" -#: ../src\update\wxUpdater.py:22 +#: update/wxUpdater.py:22 msgid "Downloading the new version..." msgstr "Descargando la nueva versión..." -#: ../src\update\wxUpdater.py:32 +#: update/wxUpdater.py:32 +#, python-format msgid "Updating... %s of %s" msgstr "Actualizando... %s de %s" -#: ../src\update\wxUpdater.py:35 -msgid "Done!" -msgstr "¡Hecho!" - -#: ../src\update\wxUpdater.py:35 +#: update/wxUpdater.py:35 msgid "" "The update has been downloaded and installed successfully. Press OK to " "continue." @@ -2084,62 +2141,11 @@ msgstr "" "La actualización ha sido descargada e instalada. Presiona aceptar para " "iniciar la aplicación." -#: ../src\wxUI\buffers\base.py:12 -msgid "Client" -msgstr "Cliente" +#: update/wxUpdater.py:35 +msgid "Done!" +msgstr "¡Hecho!" -#: ../src\wxUI\buffers\base.py:12 -msgid "Text" -msgstr "Texto" - -#: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\events.py:14 -msgid "Date" -msgstr "Fecha" - -#: ../src\wxUI\buffers\base.py:12 ../src\wxUI\buffers\people.py:12 -#: ../src\wxUI\buffers\user_searches.py:11 -#: ../src\wxUI\dialogs\userAliasDialogs.py:14 -#: ../src\wxUI\dialogs\userSelection.py:11 ../src\wxUI\dialogs\utils.py:32 -msgid "User" -msgstr "Usuario" - -#: ../src\wxUI\buffers\base.py:28 -msgid "Direct message" -msgstr "Mensaje directo" - -#: ../src\wxUI\buffers\events.py:14 -msgid "Event" -msgstr "Evento" - -#: ../src\wxUI\buffers\events.py:16 -msgid "Remove event" -msgstr "Eliminar evento" - -#: ../src\wxUI\buffers\panels.py:12 ../src\wxUI\buffers\panels.py:20 -msgid "Login" -msgstr "Iniciar sesión" - -#: ../src\wxUI\buffers\panels.py:14 -msgid "Log in automatically" -msgstr "Iniciar sesión automáticamente" - -#: ../src\wxUI\buffers\panels.py:22 -msgid "Logout" -msgstr "Cerrar sesión" - -#: ../src\wxUI\buffers\trends.py:9 -msgid "Trending topic" -msgstr "Tendencia" - -#: ../src\wxUI\buffers\trends.py:19 -msgid "Tweet about this trend" -msgstr "Tuitear sobre esta tendencia" - -#: ../src\wxUI\buffers\trends.py:20 ../src\wxUI\menus.py:97 -msgid "Search topic" -msgstr "Buscar tema" - -#: ../src\wxUI\commonMessageDialogs.py:7 +#: wxUI/commonMessageDialogs.py:7 msgid "" "This retweet is over 140 characters. Would you like to post it as a mention " "to the poster with your comments and a link to the original tweet?" @@ -2148,38 +2154,38 @@ msgstr "" "comentarios con una mención al usuario que publicó el tuit original y un " "enlace al mismo?" -#: ../src\wxUI\commonMessageDialogs.py:10 +#: wxUI/commonMessageDialogs.py:10 msgid "Would you like to add a comment to this tweet?" msgstr "¿Te gustaría añadir un comentario a este tuit?" -#: ../src\wxUI\commonMessageDialogs.py:13 +#: wxUI/commonMessageDialogs.py:13 msgid "" "Do you really want to delete this tweet? It will be deleted from Twitter as " "well." msgstr "" "¿Realmente quieres borrar este mensaje? También se eliminará de Twitter." -#: ../src\wxUI\commonMessageDialogs.py:13 ../src\wxUI\dialogs\lists.py:149 +#: wxUI/commonMessageDialogs.py:13 wxUI/dialogs/lists.py:149 msgid "Delete" msgstr "Eliminar" -#: ../src\wxUI\commonMessageDialogs.py:16 +#: wxUI/commonMessageDialogs.py:16 msgid "Do you really want to close {0}?" msgstr "¿Realmente deseas salir de {0}?" -#: ../src\wxUI\commonMessageDialogs.py:16 +#: wxUI/commonMessageDialogs.py:16 msgid "Exit" msgstr "Salir" -#: ../src\wxUI\commonMessageDialogs.py:20 +#: wxUI/commonMessageDialogs.py:20 msgid " {0} must be restarted for these changes to take effect." msgstr " Debes reiniciar {0} para que estos cambios tengan efecto." -#: ../src\wxUI\commonMessageDialogs.py:20 +#: wxUI/commonMessageDialogs.py:20 msgid "Restart {0} " msgstr "Reiniciar {0} " -#: ../src\wxUI\commonMessageDialogs.py:23 +#: wxUI/commonMessageDialogs.py:23 msgid "" "Are you sure you want to delete this user from the database? This user will " "not appear in autocomplete results anymore." @@ -2187,20 +2193,19 @@ msgstr "" "¿Estás seguro de querer eliminar este usuario de la base de datos? Este ya " "no aparecerá en los resultados del autocompletado." -#: ../src\wxUI\commonMessageDialogs.py:23 +#: wxUI/commonMessageDialogs.py:23 msgid "Confirm" msgstr "Confirmar" -#: ../src\wxUI\commonMessageDialogs.py:26 +#: wxUI/commonMessageDialogs.py:26 msgid "Enter the name of the client : " msgstr "Introduce el nombre del cliente: " -#: ../src\wxUI\commonMessageDialogs.py:26 -#: ../src\wxUI\dialogs\configuration.py:246 +#: wxUI/commonMessageDialogs.py:26 wxUI/dialogs/configuration.py:246 msgid "Add client" msgstr "Añadir cliente" -#: ../src\wxUI\commonMessageDialogs.py:32 +#: wxUI/commonMessageDialogs.py:32 msgid "" "Do you really want to empty this buffer? It's items will be removed from " "the list but not from Twitter" @@ -2208,32 +2213,31 @@ msgstr "" "¿Realmente quieres vaciar el contenido de este buffer? Los tweets serán " "eliminados de la lista, pero no de Twitter" -#: ../src\wxUI\commonMessageDialogs.py:32 +#: wxUI/commonMessageDialogs.py:32 msgid "Empty buffer" msgstr "Vaciar buffer" -#: ../src\wxUI\commonMessageDialogs.py:36 +#: wxUI/commonMessageDialogs.py:36 msgid "Do you really want to destroy this buffer?" msgstr "¿Realmente deseas eliminar este buffer?" -#: ../src\wxUI\commonMessageDialogs.py:36 -#: ../src\wxUI\commonMessageDialogs.py:86 +#: wxUI/commonMessageDialogs.py:36 wxUI/commonMessageDialogs.py:86 msgid "Attention" msgstr "Atención" -#: ../src\wxUI\commonMessageDialogs.py:42 +#: wxUI/commonMessageDialogs.py:42 msgid "A timeline for this user already exists. You can't open another" msgstr "Ya hay una línea temporal para este usuario. No se puede abrir otra" -#: ../src\wxUI\commonMessageDialogs.py:42 +#: wxUI/commonMessageDialogs.py:42 msgid "Existing timeline" msgstr "Línea temporal existente" -#: ../src\wxUI\commonMessageDialogs.py:45 +#: wxUI/commonMessageDialogs.py:45 msgid "This user has no tweets, so you can't open a timeline for them." msgstr "Este usuario no tiene tuits. No puedes abrirle una línea temporal." -#: ../src\wxUI\commonMessageDialogs.py:48 +#: wxUI/commonMessageDialogs.py:48 msgid "" "This is a protected Twitter user, which means you can't open a timeline " "using the Streaming API. The user's tweets will not update due to a twitter " @@ -2244,12 +2248,11 @@ msgstr "" "este usuario no se actualizarán debido a una política de Twitter. ¿Deseas " "continuar?" -#: ../src\wxUI\commonMessageDialogs.py:48 -#: ../src\wxUI\commonMessageDialogs.py:95 +#: wxUI/commonMessageDialogs.py:48 wxUI/commonMessageDialogs.py:95 msgid "Warning" msgstr "Atención" -#: ../src\wxUI\commonMessageDialogs.py:51 +#: wxUI/commonMessageDialogs.py:51 msgid "" "This is a protected user account, you need to follow this user to view their " "tweets or likes." @@ -2257,7 +2260,7 @@ msgstr "" "Esta es una cuenta protegida, debes seguir al usuario para poder ver sus " "tuits y los tuits marcados con me gusta." -#: ../src\wxUI\commonMessageDialogs.py:54 +#: wxUI/commonMessageDialogs.py:54 msgid "" "If you like {0} we need your help to keep it going. Help us by donating to " "the project. This will help us pay for the server, the domain and some other " @@ -2272,42 +2275,38 @@ msgstr "" "permitirá seguir escribiendo características para {0} y que estas sean " "libres en {0}. ¿Te gustaría donar ahora?" -#: ../src\wxUI\commonMessageDialogs.py:54 +#: wxUI/commonMessageDialogs.py:54 msgid "We need your help" msgstr "Necesitamos tu ayuda" -#: ../src\wxUI\commonMessageDialogs.py:58 +#: wxUI/commonMessageDialogs.py:58 msgid "This user has no tweets. {0} can't create a timeline." msgstr "Este usuario no tiene tuits. {0} no puede abrirle una línea temporal." -#: ../src\wxUI\commonMessageDialogs.py:61 +#: wxUI/commonMessageDialogs.py:61 msgid "This user has no favorited tweets. {0} can't create a timeline." msgstr "" "Este usuario no tiene tuits favoritos. {0} no puede abrirle una línea " "temporal." -#: ../src\wxUI\commonMessageDialogs.py:64 +#: wxUI/commonMessageDialogs.py:64 msgid "This user has no followers. {0} can't create a timeline." msgstr "" "Este usuario no tiene seguidores. {0} no puede abrirle una línea temporal." -#: ../src\wxUI\commonMessageDialogs.py:67 +#: wxUI/commonMessageDialogs.py:67 msgid "This user has no friends. {0} can't create a timeline." msgstr "Este usuario no tiene amigos. {0} no puede abrirle una línea temporal." -#: ../src\wxUI\commonMessageDialogs.py:71 -msgid "Geo data for this tweet" -msgstr "Información geográfica para este tweet" - -#: ../src\wxUI\commonMessageDialogs.py:71 +#: wxUI/commonMessageDialogs.py:71 msgid "Geolocation data: {0}" msgstr "Datos de ubicación: {0}" -#: ../src\wxUI\commonMessageDialogs.py:74 -msgid "Information" -msgstr "Información" +#: wxUI/commonMessageDialogs.py:71 +msgid "Geo data for this tweet" +msgstr "Información geográfica para este tweet" -#: ../src\wxUI\commonMessageDialogs.py:74 +#: wxUI/commonMessageDialogs.py:74 msgid "" "TWBlue has detected that you're running windows 10 and has changed the " "default keymap to the Windows 10 keymap. It means that some keyboard " @@ -2320,11 +2319,15 @@ msgstr "" "el editor de combinaciones de teclado y ver todas las combinaciones " "disponibles en este mapa de teclado." -#: ../src\wxUI\commonMessageDialogs.py:77 +#: wxUI/commonMessageDialogs.py:74 +msgid "Information" +msgstr "Información" + +#: wxUI/commonMessageDialogs.py:77 msgid "You have been blocked from viewing this content" msgstr "Te han bloqueado y no puedes ver este contenido" -#: ../src\wxUI\commonMessageDialogs.py:80 +#: wxUI/commonMessageDialogs.py:80 msgid "" "You have been blocked from viewing someone's content. In order to avoid " "conflicts with the full session, TWBlue will remove the affected timeline." @@ -2332,7 +2335,7 @@ msgstr "" "Alguien te ha bloqueado y no puedes ver su contenido. Para evitar conflictos " "en la sesión entera, TWBlue quitará el hilo temporal afectado." -#: ../src\wxUI\commonMessageDialogs.py:83 +#: wxUI/commonMessageDialogs.py:83 msgid "" "TWBlue cannot load this timeline because the user has been suspended from " "Twitter." @@ -2340,15 +2343,15 @@ msgstr "" "TWBlue no puede cargar este hilo temporal porque el usuario ha sido " "suspendido por Twitter." -#: ../src\wxUI\commonMessageDialogs.py:86 +#: wxUI/commonMessageDialogs.py:86 msgid "Do you really want to delete this filter?" msgstr "¿Realmente deseas eliminar este filtro?" -#: ../src\wxUI\commonMessageDialogs.py:89 +#: wxUI/commonMessageDialogs.py:89 msgid "This filter already exists. Please use a different title" msgstr "Este filtro ya existe, por favor utiliza un título diferente" -#: ../src\wxUI\commonMessageDialogs.py:95 +#: wxUI/commonMessageDialogs.py:95 msgid "" "{0} quit unexpectedly the last time it was run. If the problem persists, " "please report it to the {0} developers." @@ -2356,146 +2359,441 @@ msgstr "" "{0} se cerró de forma inesperada la última vez que se usó. Si el problema " "persiste, por favor informa de él a los desarrolladores de {0}." -#: ../src\wxUI\dialogs\attach.py:10 -msgid "Add an attachment" -msgstr "Adjuntar un archivo" +#: wxUI/menus.py:8 wxUI/view.py:33 +msgid "&Retweet" +msgstr "&Retuit" -#: ../src\wxUI\dialogs\attach.py:13 -msgid "Attachments" -msgstr "Adjuntos" +#: wxUI/menus.py:10 wxUI/menus.py:34 wxUI/view.py:32 +msgid "Re&ply" +msgstr "Res&ponder" -#: ../src\wxUI\dialogs\attach.py:14 -msgid "Title" -msgstr "Título" +#: wxUI/menus.py:12 wxUI/view.py:34 +msgid "&Like" +msgstr "Me &gusta" -#: ../src\wxUI\dialogs\attach.py:14 -msgid "Type" -msgstr "Tipo" +#: wxUI/menus.py:14 wxUI/view.py:35 +msgid "&Unlike" +msgstr "&Ya no me gusta" -#: ../src\wxUI\dialogs\attach.py:19 -msgid "Add attachments" -msgstr "Añadir adjuntos" +#: wxUI/menus.py:16 wxUI/menus.py:36 wxUI/menus.py:52 +msgid "&Open URL" +msgstr "&Abrir URL" -#: ../src\wxUI\dialogs\attach.py:20 -msgid "&Photo" -msgstr "&Foto" +#: wxUI/menus.py:18 wxUI/menus.py:54 wxUI/menus.py:87 +msgid "&Open in Twitter" +msgstr "&Abrir en Twitter" -#: ../src\wxUI\dialogs\attach.py:21 -msgid "Remove attachment" -msgstr "Remover archivo" +#: wxUI/menus.py:20 wxUI/menus.py:38 wxUI/menus.py:56 +msgid "&Play audio" +msgstr "&Reproducir audio" -#: ../src\wxUI\dialogs\attach.py:37 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:82 -msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -msgstr "Archivos de imagen (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +#: wxUI/menus.py:22 wxUI/menus.py:58 wxUI/view.py:36 +msgid "&Show tweet" +msgstr "&Ver tuit" -#: ../src\wxUI\dialogs\attach.py:37 ../src\wxUI\dialogs\message.py:116 -#: ../src\wxUI\dialogs\message.py:175 ../src\wxUI\dialogs\message.py:235 -#: ../src\wxUI\dialogs\update_profile.py:82 -msgid "Select the picture to be uploaded" -msgstr "Selecciona una foto para subir" +#: wxUI/menus.py:24 wxUI/menus.py:42 wxUI/menus.py:60 wxUI/menus.py:70 +#: wxUI/menus.py:89 wxUI/menus.py:103 +msgid "&Copy to clipboard" +msgstr "&Copiar al portapapeles" -#: ../src\wxUI\dialogs\attach.py:44 -msgid "please provide a description" -msgstr "por favor proporciona una descripción" +#: wxUI/menus.py:26 wxUI/menus.py:44 wxUI/menus.py:62 wxUI/menus.py:72 +#: wxUI/view.py:40 +msgid "&Delete" +msgstr "&Eliminar" -#: ../src\wxUI\dialogs\attach.py:44 ../src\wxUI\dialogs\lists.py:14 -#: ../src\wxUI\dialogs\lists.py:70 -msgid "Description" -msgstr "Descripción" +#: wxUI/menus.py:28 wxUI/menus.py:46 wxUI/menus.py:91 +msgid "&User actions..." +msgstr "&Acciones de usuario..." -#: ../src\wxUI\dialogs\configuration.py:15 +#: wxUI/menus.py:40 +msgid "&Show direct message" +msgstr "&Mostrar mensaje directo" + +#: wxUI/menus.py:68 +msgid "&Show event" +msgstr "&Mostrar evento" + +#: wxUI/menus.py:78 +msgid "Direct &message" +msgstr "Mensaje &directo" + +#: wxUI/menus.py:80 wxUI/view.py:50 +msgid "&View lists" +msgstr "&Ver listas" + +#: wxUI/menus.py:83 wxUI/view.py:51 +msgid "Show user &profile" +msgstr "Ve&r perfil del usuario" + +#: wxUI/menus.py:85 +msgid "&Show user" +msgstr "&Mostrar usuario" + +#: wxUI/buffers/trends.py:20 wxUI/menus.py:97 +msgid "Search topic" +msgstr "Buscar tema" + +#: wxUI/menus.py:99 +msgid "&Tweet about this trend" +msgstr "&Tuitear sobre esta tendencia" + +#: wxUI/menus.py:101 +msgid "&Show item" +msgstr "&Ver tuit" + +#: wxUI/sysTrayIcon.py:36 wxUI/view.py:26 +msgid "&Global settings" +msgstr "Opciones &globales" + +#: wxUI/sysTrayIcon.py:37 wxUI/view.py:25 +msgid "Account se&ttings" +msgstr "Opciones de &cuenta" + +#: wxUI/sysTrayIcon.py:38 +msgid "Update &profile" +msgstr "Actualizar &perfil" + +#: wxUI/sysTrayIcon.py:39 +msgid "&Show / hide" +msgstr "&Mostrar / esconder" + +#: wxUI/sysTrayIcon.py:40 wxUI/view.py:75 +msgid "&Documentation" +msgstr "&Documentación" + +#: wxUI/sysTrayIcon.py:41 +msgid "Check for &updates" +msgstr "Comprobar &actualizaciones" + +#: wxUI/sysTrayIcon.py:42 +msgid "&Exit" +msgstr "&Salir" + +#: wxUI/view.py:18 +msgid "&Manage accounts" +msgstr "Gestionar &cuentas" + +#: wxUI/dialogs/update_profile.py:35 wxUI/view.py:19 +msgid "&Update profile" +msgstr "Actuali&zar perfil" + +#: wxUI/view.py:20 +msgid "&Hide window" +msgstr "Esconder &ventana" + +#: wxUI/dialogs/search.py:13 wxUI/view.py:21 +msgid "&Search" +msgstr "&Buscar" + +#: wxUI/view.py:22 +msgid "&Lists manager" +msgstr "Gestor de &listas" + +#: wxUI/view.py:23 +msgid "Manage user aliases" +msgstr "Gestionar alias de usuario" + +#: wxUI/view.py:24 +msgid "&Edit keystrokes" +msgstr "Editar combinaciones de &teclas" + +#: wxUI/view.py:27 +msgid "E&xit" +msgstr "S&alir" + +#: wxUI/view.py:31 wxUI/view.py:86 +msgid "&Tweet" +msgstr "&Tuit" + +#: wxUI/view.py:37 +msgid "View &address" +msgstr "Ver &dirección" + +#: wxUI/view.py:38 +msgid "View conversa&tion" +msgstr "Ver conversa&ción" + +#: wxUI/view.py:39 +msgid "Read text in picture" +msgstr "Leer texto en imágenes" + +#: wxUI/view.py:44 +msgid "&Actions..." +msgstr "&Acciones..." + +#: wxUI/view.py:45 +msgid "&View timeline..." +msgstr "&Ver línea temporal..." + +#: wxUI/view.py:46 +msgid "Direct me&ssage" +msgstr "&Mensaje directo" + +#: wxUI/view.py:47 +msgid "Add a&lias" +msgstr "Añadir alias" + +#: wxUI/view.py:48 +msgid "&Add to list" +msgstr "&Añadir a lista" + +#: wxUI/view.py:49 +msgid "R&emove from list" +msgstr "&Quitar de lista" + +#: wxUI/view.py:52 +msgid "V&iew likes" +msgstr "&Ver tuits marcados con me gusta" + +#: wxUI/view.py:56 +msgid "&Update buffer" +msgstr "&actualizar buffer" + +#: wxUI/view.py:57 +msgid "New &trending topics buffer..." +msgstr "Nuevo buffer de &tendencias..." + +#: wxUI/view.py:58 +msgid "Create a &filter" +msgstr "Crear &filtro" + +#: wxUI/view.py:59 +msgid "&Manage filters" +msgstr "Gestionar &filtros" + +#: wxUI/view.py:60 +msgid "Find a string in the currently focused buffer..." +msgstr "Buscar término en el buffer actual..." + +#: wxUI/view.py:61 +msgid "&Load previous items" +msgstr "&Cargar elementos anteriores" + +#: wxUI/dialogs/userActions.py:22 wxUI/view.py:63 +msgid "&Mute" +msgstr "S&ilenciar" + +#: wxUI/view.py:64 +msgid "&Autoread" +msgstr "&lectura automática" + +#: wxUI/view.py:65 +msgid "&Clear buffer" +msgstr "&Vaciar buffer" + +#: wxUI/view.py:66 +msgid "&Destroy" +msgstr "&Eliminar" + +#: wxUI/view.py:70 +msgid "&Seek back 5 seconds" +msgstr "&Retroceder 5 segundos" + +#: wxUI/view.py:71 +msgid "&Seek forward 5 seconds" +msgstr "A&vanzar 5 segundos" + +#: wxUI/view.py:76 +msgid "Sounds &tutorial" +msgstr "Tutorial de &sonidos" + +#: wxUI/view.py:77 +msgid "&What's new in this version?" +msgstr "¿&Qué hay de nuevo en esta versión?" + +#: wxUI/view.py:78 +msgid "&Check for updates" +msgstr "&Comprobar actualizaciones" + +#: wxUI/view.py:79 +msgid "&Report an error" +msgstr "&Reportar un error" + +#: wxUI/view.py:80 +msgid "{0}'s &website" +msgstr "Sitio &web de {0}" + +#: wxUI/view.py:81 +msgid "Get soundpacks for TWBlue" +msgstr "Obtener paquetes de sonidos para TWBlue" + +#: wxUI/view.py:82 +msgid "About &{0}" +msgstr "Sobre &{0}" + +#: wxUI/view.py:85 +msgid "&Application" +msgstr "&Aplicación" + +#: wxUI/dialogs/userActions.py:11 wxUI/view.py:87 +msgid "&User" +msgstr "&Usuario" + +#: wxUI/view.py:88 +msgid "&Buffer" +msgstr "&Buffer" + +#: wxUI/view.py:89 +msgid "&Audio" +msgstr "&Audio" + +#: wxUI/view.py:90 +msgid "&Help" +msgstr "Ay&uda" + +#: wxUI/view.py:176 +msgid "Address" +msgstr "Dirección" + +#: wxUI/view.py:207 +msgid "Your {0} version is up to date" +msgstr "Tu versión de {0} está actualizada" + +#: wxUI/view.py:207 +msgid "Update" +msgstr "Actualización" + +#: wxUI/buffers/base.py:12 wxUI/buffers/people.py:12 +#: wxUI/buffers/user_searches.py:11 wxUI/dialogs/userAliasDialogs.py:14 +#: wxUI/dialogs/userSelection.py:11 wxUI/dialogs/utils.py:32 +msgid "User" +msgstr "Usuario" + +#: wxUI/buffers/base.py:12 wxUI/dialogs/twitterDialogs/tweetDialogs.py:47 +msgid "Text" +msgstr "Texto" + +#: wxUI/buffers/base.py:12 wxUI/buffers/events.py:14 +msgid "Date" +msgstr "Fecha" + +#: wxUI/buffers/base.py:12 +msgid "Client" +msgstr "Cliente" + +#: wxUI/buffers/base.py:28 +msgid "Direct message" +msgstr "Mensaje directo" + +#: wxUI/buffers/events.py:14 +msgid "Event" +msgstr "Evento" + +#: wxUI/buffers/events.py:16 +msgid "Remove event" +msgstr "Eliminar evento" + +#: wxUI/buffers/panels.py:12 wxUI/buffers/panels.py:20 +msgid "Login" +msgstr "Iniciar sesión" + +#: wxUI/buffers/panels.py:14 +msgid "Log in automatically" +msgstr "Iniciar sesión automáticamente" + +#: wxUI/buffers/panels.py:22 +msgid "Logout" +msgstr "Cerrar sesión" + +#: wxUI/buffers/trends.py:9 +msgid "Trending topic" +msgstr "Tendencia" + +#: wxUI/buffers/trends.py:19 +msgid "Tweet about this trend" +msgstr "Tuitear sobre esta tendencia" + +#: wxUI/dialogs/configuration.py:15 msgid "Language" msgstr "Idioma" -#: ../src\wxUI\dialogs\configuration.py:22 +#: wxUI/dialogs/configuration.py:22 msgid "Run {0} at Windows startup" msgstr "Ejecutar {0} al iniciar Windows" -#: ../src\wxUI\dialogs\configuration.py:23 +#: wxUI/dialogs/configuration.py:23 msgid "ask before exiting {0}" msgstr "preguntar antes de salir de {0}" -#: ../src\wxUI\dialogs\configuration.py:26 +#: wxUI/dialogs/configuration.py:26 msgid "Disable Streaming functions" msgstr "Desactivar funciones en tiempo real" -#: ../src\wxUI\dialogs\configuration.py:29 +#: wxUI/dialogs/configuration.py:29 msgid "Buffer update interval, in minutes" msgstr "Intervalo de actualización de los buffers, en minutos" -#: ../src\wxUI\dialogs\configuration.py:35 +#: wxUI/dialogs/configuration.py:35 msgid "Play a sound when {0} launches" msgstr "Reproducir un sonido cuando inicia {0}" -#: ../src\wxUI\dialogs\configuration.py:37 +#: wxUI/dialogs/configuration.py:37 msgid "Speak a message when {0} launches" msgstr "Hablar un mensaje cuando {0} inicie" -#: ../src\wxUI\dialogs\configuration.py:39 +#: wxUI/dialogs/configuration.py:39 msgid "Use invisible interface's keyboard shortcuts while GUI is visible" msgstr "" "Usar los atajos de teclado de la interfaz invisible en la ventana gráfica" -#: ../src\wxUI\dialogs\configuration.py:41 +#: wxUI/dialogs/configuration.py:41 msgid "Activate Sapi5 when any other screen reader is not being run" msgstr "Activar Sapi5 cuando no hay ningún lector de pantalla ejecutándose" -#: ../src\wxUI\dialogs\configuration.py:43 +#: wxUI/dialogs/configuration.py:43 msgid "Hide GUI on launch" msgstr "Esconder interfaz gráfica al iniciar" -#: ../src\wxUI\dialogs\configuration.py:45 +#: wxUI/dialogs/configuration.py:45 msgid "Use Codeofdusk's longtweet handlers (may decrease client performance)" msgstr "" "Lectura completa de Tuits largos (puede disminuir el rendimiento del cliente)" -#: ../src\wxUI\dialogs\configuration.py:47 +#: wxUI/dialogs/configuration.py:47 msgid "Remember state for mention all and long tweet" msgstr "Recordar estado para casillas de mencionar a todos y tweet largos" -#: ../src\wxUI\dialogs\configuration.py:50 +#: wxUI/dialogs/configuration.py:50 msgid "Keymap" msgstr "Mapa de teclado" -#: ../src\wxUI\dialogs\configuration.py:55 +#: wxUI/dialogs/configuration.py:55 msgid "Check for updates when {0} launches" msgstr "Comprobar actualizaciones cuando {0} inicie" -#: ../src\wxUI\dialogs\configuration.py:65 +#: wxUI/dialogs/configuration.py:65 msgid "Proxy type: " msgstr "Tipo de proxy: " -#: ../src\wxUI\dialogs\configuration.py:72 +#: wxUI/dialogs/configuration.py:72 msgid "Proxy server: " msgstr "Servidor proxy: " -#: ../src\wxUI\dialogs\configuration.py:78 +#: wxUI/dialogs/configuration.py:78 msgid "Port: " msgstr "Puerto: " -#: ../src\wxUI\dialogs\configuration.py:84 +#: wxUI/dialogs/configuration.py:84 msgid "User: " msgstr "Usuario: " -#: ../src\wxUI\dialogs\configuration.py:90 +#: wxUI/dialogs/configuration.py:90 msgid "Password: " msgstr "Contraseña: " -#: ../src\wxUI\dialogs\configuration.py:102 +#: wxUI/dialogs/configuration.py:102 msgid "Autocompletion settings..." msgstr "Opciones de autocompletado de usuarios..." -#: ../src\wxUI\dialogs\configuration.py:104 +#: wxUI/dialogs/configuration.py:104 msgid "Relative timestamps" msgstr "Tiempos relativos" -#: ../src\wxUI\dialogs\configuration.py:107 +#: wxUI/dialogs/configuration.py:107 msgid "Items on each API call" msgstr "Elementos por cada llamada a la API" -#: ../src\wxUI\dialogs\configuration.py:113 +#: wxUI/dialogs/configuration.py:113 msgid "" "Inverted buffers: The newest tweets will be shown at the beginning while the " "oldest at the end" @@ -2503,15 +2801,15 @@ msgstr "" "Buffers invertidos: los nuevos tweets se mostrarán al principio de las " "listas y los viejos al final" -#: ../src\wxUI\dialogs\configuration.py:115 +#: wxUI/dialogs/configuration.py:115 msgid "Retweet mode" msgstr "Modo de retuit" -#: ../src\wxUI\dialogs\configuration.py:121 +#: wxUI/dialogs/configuration.py:121 msgid "Show screen names instead of full names" msgstr "Mostrar nombres de pantalla en lugar de nombres completos" -#: ../src\wxUI\dialogs\configuration.py:123 +#: wxUI/dialogs/configuration.py:123 msgid "" "Number of items per buffer to cache in database (0 to disable caching, blank " "for unlimited)" @@ -2520,7 +2818,7 @@ msgstr "" "blanco para guardarlos de forma ilimitada, 0 para desactivar la base de " "datos)" -#: ../src\wxUI\dialogs\configuration.py:127 +#: wxUI/dialogs/configuration.py:127 msgid "" "Load cache for tweets in memory (much faster in big datasets but requires " "more RAM)" @@ -2528,909 +2826,786 @@ msgstr "" "Cargar cache para Tweets en RAM (es más rápido para listas muy grandes de " "elementos, pero requiere más memoria)" -#: ../src\wxUI\dialogs\configuration.py:134 +#: wxUI/dialogs/configuration.py:134 msgid "Enable automatic speech feedback" msgstr "Activar mensajes automáticos hablados" -#: ../src\wxUI\dialogs\configuration.py:136 +#: wxUI/dialogs/configuration.py:136 msgid "Enable automatic Braille feedback" msgstr "Activar mensajes automáticos en Braille" -#: ../src\wxUI\dialogs\configuration.py:144 -msgid "Status" -msgstr "Estado" - -#: ../src\wxUI\dialogs\configuration.py:144 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: wxUI/dialogs/configuration.py:144 wxUI/dialogs/filterDialogs.py:130 msgid "Buffer" msgstr "Buffer" -#: ../src\wxUI\dialogs\configuration.py:147 +#: wxUI/dialogs/configuration.py:144 +msgid "Status" +msgstr "Estado" + +#: wxUI/dialogs/configuration.py:147 msgid "Show/hide" msgstr "Mostrar/ocultar" -#: ../src\wxUI\dialogs\configuration.py:148 +#: wxUI/dialogs/configuration.py:148 msgid "Move up" msgstr "Mover arriba" -#: ../src\wxUI\dialogs\configuration.py:149 +#: wxUI/dialogs/configuration.py:149 msgid "Move down" msgstr "Mover abajo" -#: ../src\wxUI\dialogs\configuration.py:159 -#: ../src\wxUI\dialogs\configuration.py:224 -#: ../src\wxUI\dialogs\configuration.py:227 -#: ../src\wxUI\dialogs\configuration.py:232 +#: wxUI/dialogs/configuration.py:159 wxUI/dialogs/configuration.py:224 +#: wxUI/dialogs/configuration.py:227 wxUI/dialogs/configuration.py:232 msgid "Show" msgstr "Mostrar" -#: ../src\wxUI\dialogs\configuration.py:161 -#: ../src\wxUI\dialogs\configuration.py:171 -#: ../src\wxUI\dialogs\configuration.py:195 -#: ../src\wxUI\dialogs\configuration.py:225 +#: wxUI/dialogs/configuration.py:161 wxUI/dialogs/configuration.py:171 +#: wxUI/dialogs/configuration.py:195 wxUI/dialogs/configuration.py:225 msgid "Hide" msgstr "Ocultar" -#: ../src\wxUI\dialogs\configuration.py:169 -#: ../src\wxUI\dialogs\configuration.py:193 +#: wxUI/dialogs/configuration.py:169 wxUI/dialogs/configuration.py:193 msgid "Select a buffer first." msgstr "Primero selecciona un buffer." -#: ../src\wxUI\dialogs\configuration.py:172 -#: ../src\wxUI\dialogs\configuration.py:196 +#: wxUI/dialogs/configuration.py:172 wxUI/dialogs/configuration.py:196 msgid "The buffer is hidden, show it first." msgstr "El buffer está oculto, muéstralo primero." -#: ../src\wxUI\dialogs\configuration.py:175 +#: wxUI/dialogs/configuration.py:175 msgid "The buffer is already at the top of the list." msgstr "El buffer ya se encuentra al principio de la lista." -#: ../src\wxUI\dialogs\configuration.py:199 +#: wxUI/dialogs/configuration.py:199 msgid "The buffer is already at the bottom of the list." msgstr "El buffer ya se encuentra al final de la lista." -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 +#: wxUI/dialogs/configuration.py:240 wxUI/dialogs/configuration.py:381 msgid "Ignored clients" msgstr "Clientes ignorados" -#: ../src\wxUI\dialogs\configuration.py:247 +#: wxUI/dialogs/configuration.py:247 msgid "Remove client" msgstr "Quitar cliente" -#: ../src\wxUI\dialogs\configuration.py:271 +#: wxUI/dialogs/configuration.py:271 msgid "Volume" msgstr "Volumen" -#: ../src\wxUI\dialogs\configuration.py:282 +#: wxUI/dialogs/configuration.py:282 msgid "Session mute" msgstr "Silencio de sesión" -#: ../src\wxUI\dialogs\configuration.py:284 +#: wxUI/dialogs/configuration.py:284 msgid "Output device" msgstr "Dispositivo de salida" -#: ../src\wxUI\dialogs\configuration.py:291 +#: wxUI/dialogs/configuration.py:291 msgid "Input device" msgstr "Dispositivo de entrada" -#: ../src\wxUI\dialogs\configuration.py:299 +#: wxUI/dialogs/configuration.py:299 msgid "Sound pack" msgstr "Paquete de sonidos" -#: ../src\wxUI\dialogs\configuration.py:305 +#: wxUI/dialogs/configuration.py:305 msgid "Indicate audio tweets with sound" msgstr "Reproducir sonido en tuits con audio" -#: ../src\wxUI\dialogs\configuration.py:307 +#: wxUI/dialogs/configuration.py:307 msgid "Indicate geotweets with sound" msgstr "Reproducir sonido en tuits con información geográfica" -#: ../src\wxUI\dialogs\configuration.py:309 +#: wxUI/dialogs/configuration.py:309 msgid "Indicate tweets containing images with sound" msgstr "Reproducir sonido en tuits con imágenes" -#: ../src\wxUI\dialogs\configuration.py:332 +#: wxUI/dialogs/configuration.py:332 msgid "Language for OCR" msgstr "Idioma para el OCR" -#: ../src\wxUI\dialogs\configuration.py:338 +#: wxUI/dialogs/configuration.py:338 msgid "API Key for SndUp" msgstr "Clave de api para SNDUp" -#: ../src\wxUI\dialogs\configuration.py:353 +#: wxUI/dialogs/configuration.py:353 msgid "{0} preferences" msgstr "Preferencias de {0}" -#: ../src\wxUI\dialogs\configuration.py:364 +#: wxUI/dialogs/configuration.py:364 msgid "Proxy" msgstr "Proxy" -#: ../src\wxUI\dialogs\configuration.py:373 +#: wxUI/dialogs/configuration.py:373 msgid "Feedback" msgstr "Retroalimentación" -#: ../src\wxUI\dialogs\configuration.py:377 +#: wxUI/dialogs/configuration.py:377 msgid "Buffers" msgstr "Buffers" -#: ../src\wxUI\dialogs\configuration.py:385 +#: wxUI/dialogs/configuration.py:385 msgid "Sound" msgstr "Sonido" -#: ../src\wxUI\dialogs\configuration.py:389 +#: wxUI/dialogs/configuration.py:389 msgid "Extras" msgstr "Extras" -#: ../src\wxUI\dialogs\configuration.py:394 +#: wxUI/dialogs/configuration.py:394 msgid "Save" msgstr "Guardar" -#: ../src\wxUI\dialogs\filterDialogs.py:16 +#: wxUI/dialogs/filterDialogs.py:13 msgid "Create a filter for this buffer" msgstr "Crear filtro para este buffer" -#: ../src\wxUI\dialogs\filterDialogs.py:17 +#: wxUI/dialogs/filterDialogs.py:14 msgid "Filter title" msgstr "Nombre del filtro" -#: ../src\wxUI\dialogs\filterDialogs.py:26 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: wxUI/dialogs/filterDialogs.py:24 wxUI/dialogs/filterDialogs.py:130 msgid "Filter by word" msgstr "Filtrar por palabra" -#: ../src\wxUI\dialogs\filterDialogs.py:27 +#: wxUI/dialogs/filterDialogs.py:25 msgid "Ignore tweets wich contain the following word" msgstr "Ignorar tuits que contengan la siguiente palabra" -#: ../src\wxUI\dialogs\filterDialogs.py:28 +#: wxUI/dialogs/filterDialogs.py:26 msgid "Ignore tweets without the following word" msgstr "Ignorar tuits que no contengan la siguiente palabra" -#: ../src\wxUI\dialogs\filterDialogs.py:33 +#: wxUI/dialogs/filterDialogs.py:31 msgid "word" msgstr "palabra" -#: ../src\wxUI\dialogs\filterDialogs.py:38 +#: wxUI/dialogs/filterDialogs.py:36 msgid "Allow retweets" msgstr "Permitir retuits" -#: ../src\wxUI\dialogs\filterDialogs.py:39 +#: wxUI/dialogs/filterDialogs.py:37 msgid "Allow quoted tweets" msgstr "Permitir tweets citados" -#: ../src\wxUI\dialogs\filterDialogs.py:40 +#: wxUI/dialogs/filterDialogs.py:38 msgid "Allow replies" msgstr "Permitir respuestas" -#: ../src\wxUI\dialogs\filterDialogs.py:48 +#: wxUI/dialogs/filterDialogs.py:46 msgid "Use this term as a regular expression" msgstr "Usar término como expresión regular" -#: ../src\wxUI\dialogs\filterDialogs.py:50 -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: wxUI/dialogs/filterDialogs.py:48 wxUI/dialogs/filterDialogs.py:130 msgid "Filter by language" msgstr "Filtrar por idioma" -#: ../src\wxUI\dialogs\filterDialogs.py:51 +#: wxUI/dialogs/filterDialogs.py:49 msgid "Load tweets in the following languages" msgstr "Cargar tuits en los siguientes idiomas" -#: ../src\wxUI\dialogs\filterDialogs.py:52 +#: wxUI/dialogs/filterDialogs.py:50 msgid "Ignore tweets in the following languages" msgstr "Ignorar tuits en los siguientes idiomas" -#: ../src\wxUI\dialogs\filterDialogs.py:53 +#: wxUI/dialogs/filterDialogs.py:51 msgid "Don't filter by language" msgstr "No filtrar por idioma" -#: ../src\wxUI\dialogs\filterDialogs.py:64 +#: wxUI/dialogs/filterDialogs.py:62 msgid "Supported languages" msgstr "Idiomas soportados" -#: ../src\wxUI\dialogs\filterDialogs.py:69 +#: wxUI/dialogs/filterDialogs.py:67 msgid "Add selected language to filter" msgstr "Añadir idioma seleccionado al filtro" -#: ../src\wxUI\dialogs\filterDialogs.py:73 +#: wxUI/dialogs/filterDialogs.py:71 msgid "Selected languages" msgstr "Idiomas seleccionados" -#: ../src\wxUI\dialogs\filterDialogs.py:75 -#: ../src\wxUI\dialogs\filterDialogs.py:133 ../src\wxUI\dialogs\lists.py:21 -#: ../src\wxUI\dialogs\lists.py:132 ../src\wxUI\dialogs\userAliasDialogs.py:57 +#: wxUI/dialogs/filterDialogs.py:73 wxUI/dialogs/filterDialogs.py:137 +#: wxUI/dialogs/lists.py:21 wxUI/dialogs/lists.py:132 +#: wxUI/dialogs/userAliasDialogs.py:57 msgid "Remove" msgstr "Borrar" -#: ../src\wxUI\dialogs\filterDialogs.py:123 +#: wxUI/dialogs/filterDialogs.py:120 +msgid "You must define a name for the filter before creating it." +msgstr "Debes definir un título ppara el filtro antes de poder guardarlo." + +#: wxUI/dialogs/filterDialogs.py:120 +msgid "Missing filter name" +msgstr "Título del filtro faltante" + +#: wxUI/dialogs/filterDialogs.py:127 msgid "Manage filters" msgstr "Gestionar filtros" -#: ../src\wxUI\dialogs\filterDialogs.py:125 +#: wxUI/dialogs/filterDialogs.py:129 msgid "Filters" msgstr "Filtros" -#: ../src\wxUI\dialogs\filterDialogs.py:126 +#: wxUI/dialogs/filterDialogs.py:130 msgid "Filter" msgstr "Filtro" -#: ../src\wxUI\dialogs\find.py:13 +#: wxUI/dialogs/find.py:13 msgid "Find in current buffer" msgstr "Buscar en el buffer actual" -#: ../src\wxUI\dialogs\find.py:14 +#: wxUI/dialogs/find.py:14 msgid "String" msgstr "Término" -#: ../src\wxUI\dialogs\lists.py:11 +#: wxUI/dialogs/lists.py:11 msgid "Lists manager" msgstr "Gestor de listas" -#: ../src\wxUI\dialogs\lists.py:14 +#: wxUI/dialogs/lists.py:14 msgid "List" msgstr "Lista" -#: ../src\wxUI\dialogs\lists.py:14 -msgid "Members" -msgstr "Miembros" +#: wxUI/dialogs/lists.py:14 wxUI/dialogs/lists.py:70 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:37 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:126 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:173 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:257 +msgid "Description" +msgstr "Descripción" -#: ../src\wxUI\dialogs\lists.py:14 +#: wxUI/dialogs/lists.py:14 msgid "Owner" msgstr "Propietario" -#: ../src\wxUI\dialogs\lists.py:14 +#: wxUI/dialogs/lists.py:14 +msgid "Members" +msgstr "Miembros" + +#: wxUI/dialogs/lists.py:14 msgid "mode" msgstr "modo" -#: ../src\wxUI\dialogs\lists.py:19 ../src\wxUI\dialogs\lists.py:62 +#: wxUI/dialogs/lists.py:19 wxUI/dialogs/lists.py:62 msgid "Create a new list" msgstr "Crear nueva lista" -#: ../src\wxUI\dialogs\lists.py:22 +#: wxUI/dialogs/lists.py:22 msgid "Open in buffer" msgstr "Abrir en buffer" -#: ../src\wxUI\dialogs\lists.py:52 +#: wxUI/dialogs/lists.py:52 +#, python-format msgid "Viewing lists for %s" msgstr "Viendo las listas de %s" -#: ../src\wxUI\dialogs\lists.py:53 +#: wxUI/dialogs/lists.py:53 msgid "Subscribe" msgstr "Darte de alta" -#: ../src\wxUI\dialogs\lists.py:54 +#: wxUI/dialogs/lists.py:54 msgid "Unsubscribe" msgstr "Darse de baja" -#: ../src\wxUI\dialogs\lists.py:65 +#: wxUI/dialogs/lists.py:65 msgid "Name (20 characters maximun)" msgstr "Nombre (máximo 20 caracteres)" -#: ../src\wxUI\dialogs\lists.py:75 +#: wxUI/dialogs/lists.py:75 msgid "Mode" msgstr "Modo" -#: ../src\wxUI\dialogs\lists.py:76 +#: wxUI/dialogs/lists.py:76 msgid "Public" msgstr "Público" -#: ../src\wxUI\dialogs\lists.py:77 +#: wxUI/dialogs/lists.py:77 msgid "Private" msgstr "Privado" -#: ../src\wxUI\dialogs\lists.py:97 +#: wxUI/dialogs/lists.py:97 +#, python-format msgid "Editing the list %s" msgstr "Editando la lista %s" -#: ../src\wxUI\dialogs\lists.py:108 +#: wxUI/dialogs/lists.py:108 msgid "Select a list to add the user" msgstr "Selecciona una lista para añadir al usuario" -#: ../src\wxUI\dialogs\lists.py:109 +#: wxUI/dialogs/lists.py:109 msgid "Add" msgstr "Añadir" -#: ../src\wxUI\dialogs\lists.py:131 +#: wxUI/dialogs/lists.py:131 msgid "Select a list to remove the user" msgstr "Selecciona una lista para quitar al usuario" -#: ../src\wxUI\dialogs\lists.py:149 +#: wxUI/dialogs/lists.py:149 msgid "Do you really want to delete this list?" msgstr "¿Realmente deseas eliminar esta lista?" -#: ../src\wxUI\dialogs\message.py:73 ../src\wxUI\dialogs\message.py:254 -msgid "&Long tweet" -msgstr "Tuit &largo" - -#: ../src\wxUI\dialogs\message.py:74 ../src\wxUI\dialogs\message.py:133 -#: ../src\wxUI\dialogs\message.py:255 -msgid "&Upload image..." -msgstr "&Subir imagen..." - -#: ../src\wxUI\dialogs\message.py:75 ../src\wxUI\dialogs\message.py:134 -#: ../src\wxUI\dialogs\message.py:194 ../src\wxUI\dialogs\message.py:256 -#: ../src\wxUI\dialogs\message.py:359 ../src\wxUI\dialogs\message.py:435 -msgid "Check &spelling..." -msgstr "Revisar &ortografía..." - -#: ../src\wxUI\dialogs\message.py:76 ../src\wxUI\dialogs\message.py:135 -#: ../src\wxUI\dialogs\message.py:195 ../src\wxUI\dialogs\message.py:257 -msgid "&Attach audio..." -msgstr "&Adjuntar audio..." - -#: ../src\wxUI\dialogs\message.py:77 ../src\wxUI\dialogs\message.py:136 -#: ../src\wxUI\dialogs\message.py:196 ../src\wxUI\dialogs\message.py:258 -msgid "Sh&orten URL" -msgstr "Acortar &URL" - -#: ../src\wxUI\dialogs\message.py:78 ../src\wxUI\dialogs\message.py:137 -#: ../src\wxUI\dialogs\message.py:197 ../src\wxUI\dialogs\message.py:259 -#: ../src\wxUI\dialogs\message.py:360 ../src\wxUI\dialogs\message.py:436 -msgid "&Expand URL" -msgstr "&Expandir URL" - -#: ../src\wxUI\dialogs\message.py:81 ../src\wxUI\dialogs\message.py:140 -#: ../src\wxUI\dialogs\message.py:200 ../src\wxUI\dialogs\message.py:262 -#: ../src\wxUI\dialogs\message.py:362 ../src\wxUI\dialogs\message.py:438 -msgid "&Translate..." -msgstr "&Traducir..." - -#: ../src\wxUI\dialogs\message.py:82 ../src\wxUI\dialogs\message.py:141 -#: ../src\wxUI\dialogs\message.py:186 ../src\wxUI\dialogs\message.py:263 -msgid "Auto&complete users" -msgstr "Auto&completar usuarios" - -#: ../src\wxUI\dialogs\message.py:83 ../src\wxUI\dialogs\message.py:142 -#: ../src\wxUI\dialogs\message.py:201 ../src\wxUI\dialogs\message.py:264 -msgid "Sen&d" -msgstr "En&viar" - -#: ../src\wxUI\dialogs\message.py:85 ../src\wxUI\dialogs\message.py:144 -#: ../src\wxUI\dialogs\message.py:203 ../src\wxUI\dialogs\message.py:266 -#: ../src\wxUI\dialogs\message.py:363 ../src\wxUI\dialogs\message.py:439 -msgid "C&lose" -msgstr "Ce&rrar" - -#: ../src\wxUI\dialogs\message.py:184 -msgid "&Recipient" -msgstr "&Destinatario" - -#: ../src\wxUI\dialogs\message.py:245 -msgid "&Mention to all" -msgstr "&Mencionar a todos" - -#: ../src\wxUI\dialogs\message.py:299 -msgid "Tweet - %i characters " -msgstr "Tuit - %i caracteres " - -#: ../src\wxUI\dialogs\message.py:316 -msgid "Image description" -msgstr "Descripción de la imagen" - -#: ../src\wxUI\dialogs\message.py:327 -msgid "Retweets: " -msgstr "Retuits: " - -#: ../src\wxUI\dialogs\message.py:332 -msgid "Likes: " -msgstr "Me gusta: " - -#: ../src\wxUI\dialogs\message.py:337 -msgid "Source: " -msgstr "Desde: " - -#: ../src\wxUI\dialogs\message.py:342 ../src\wxUI\dialogs\message.py:423 -msgid "Date: " -msgstr "Fecha: " - -#: ../src\wxUI\dialogs\message.py:357 ../src\wxUI\dialogs\message.py:433 -msgid "Copy link to clipboard" -msgstr "Copiar enlace al portapapeles" - -#: ../src\wxUI\dialogs\message.py:408 -msgid "View" -msgstr "Ver" - -#: ../src\wxUI\dialogs\message.py:410 -msgid "Item" -msgstr "Elemento" - -#: ../src\wxUI\dialogs\search.py:12 +#: wxUI/dialogs/search.py:12 msgid "Search on Twitter" msgstr "Buscar en Twitter" -#: ../src\wxUI\dialogs\search.py:13 ../src\wxUI\view.py:21 -msgid "&Search" -msgstr "&Buscar" - -#: ../src\wxUI\dialogs\search.py:21 +#: wxUI/dialogs/search.py:21 msgid "Tweets" msgstr "Tuits" -#: ../src\wxUI\dialogs\search.py:22 ../src\wxUI\dialogs\userAliasDialogs.py:43 +#: wxUI/dialogs/search.py:22 wxUI/dialogs/userAliasDialogs.py:43 msgid "Users" msgstr "Usuarios" -#: ../src\wxUI\dialogs\search.py:29 +#: wxUI/dialogs/search.py:29 msgid "&Language for results: " msgstr "&Idioma para los resultados: " -#: ../src\wxUI\dialogs\search.py:31 ../src\wxUI\dialogs\search.py:55 +#: wxUI/dialogs/search.py:31 wxUI/dialogs/search.py:55 msgid "any" msgstr "cualquiera" -#: ../src\wxUI\dialogs\search.py:37 +#: wxUI/dialogs/search.py:37 msgid "Results &type: " msgstr "&Tipo de resultados: " -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:63 +#: wxUI/dialogs/search.py:38 wxUI/dialogs/search.py:63 msgid "Mixed" msgstr "Mixtos" -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:64 +#: wxUI/dialogs/search.py:38 wxUI/dialogs/search.py:64 msgid "Recent" msgstr "Recientes" -#: ../src\wxUI\dialogs\search.py:38 ../src\wxUI\dialogs\search.py:65 +#: wxUI/dialogs/search.py:38 wxUI/dialogs/search.py:65 msgid "Popular" msgstr "Populares" -#: ../src\wxUI\dialogs\search.py:43 ../src\wxUI\dialogs\trends.py:25 -#: ../src\wxUI\dialogs\userActions.py:41 -#: ../src\wxUI\dialogs\userSelection.py:33 +#: wxUI/dialogs/search.py:43 wxUI/dialogs/trends.py:25 +#: wxUI/dialogs/userActions.py:41 wxUI/dialogs/userSelection.py:33 msgid "&OK" msgstr "&Aceptar" -#: ../src\wxUI\dialogs\search.py:45 ../src\wxUI\dialogs\show_user.py:19 -#: ../src\wxUI\dialogs\trends.py:27 ../src\wxUI\dialogs\update_profile.py:37 -#: ../src\wxUI\dialogs\userActions.py:43 -#: ../src\wxUI\dialogs\userSelection.py:35 +#: wxUI/dialogs/search.py:45 wxUI/dialogs/show_user.py:19 +#: wxUI/dialogs/trends.py:27 wxUI/dialogs/update_profile.py:37 +#: wxUI/dialogs/userActions.py:43 wxUI/dialogs/userSelection.py:35 msgid "&Close" msgstr "Ce&rrar" -#: ../src\wxUI\dialogs\show_user.py:12 +#: wxUI/dialogs/show_user.py:12 msgid "Details" msgstr "Detalles" -#: ../src\wxUI\dialogs\show_user.py:17 +#: wxUI/dialogs/show_user.py:17 msgid "&Go to URL" msgstr "&Ir a URL" -#: ../src\wxUI\dialogs\trends.py:10 +#: wxUI/dialogs/trends.py:10 msgid "View trending topics" msgstr "Ver tendencias" -#: ../src\wxUI\dialogs\trends.py:11 +#: wxUI/dialogs/trends.py:11 msgid "Trending topics by" msgstr "Tendencias por" -#: ../src\wxUI\dialogs\trends.py:12 +#: wxUI/dialogs/trends.py:12 msgid "Country" msgstr "País" -#: ../src\wxUI\dialogs\trends.py:13 +#: wxUI/dialogs/trends.py:13 msgid "City" msgstr "Ciudad" -#: ../src\wxUI\dialogs\trends.py:19 ../src\wxUI\dialogs\update_profile.py:18 +#: wxUI/dialogs/trends.py:19 wxUI/dialogs/update_profile.py:18 msgid "&Location" msgstr "&Ubicación" -#: ../src\wxUI\dialogs\update_profile.py:10 +#: wxUI/dialogs/update_profile.py:10 msgid "Update your profile" msgstr "Actualizar tu perfil" -#: ../src\wxUI\dialogs\update_profile.py:12 +#: wxUI/dialogs/update_profile.py:12 msgid "&Name (50 characters maximum)" msgstr "&Nombre (máximo 50 caracteres)" -#: ../src\wxUI\dialogs\update_profile.py:23 +#: wxUI/dialogs/update_profile.py:23 msgid "&Website" msgstr "Sitio &web" -#: ../src\wxUI\dialogs\update_profile.py:28 +#: wxUI/dialogs/update_profile.py:28 msgid "&Bio (160 characters maximum)" msgstr "&Descripción (máximo 160 caracteres)" -#: ../src\wxUI\dialogs\update_profile.py:34 +#: wxUI/dialogs/update_profile.py:34 msgid "Upload a &picture" msgstr "Subir una &foto" -#: ../src\wxUI\dialogs\update_profile.py:35 ../src\wxUI\view.py:19 -msgid "&Update profile" -msgstr "Actuali&zar perfil" - -#: ../src\wxUI\dialogs\update_profile.py:77 +#: wxUI/dialogs/update_profile.py:77 msgid "Upload a picture" msgstr "Subir una foto" -#: ../src\wxUI\dialogs\update_profile.py:79 +#: wxUI/dialogs/update_profile.py:79 msgid "Discard image" msgstr "Descartar foto" -#: ../src\wxUI\dialogs\urlList.py:6 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:133 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:289 +#: wxUI/dialogs/update_profile.py:82 +msgid "Select the picture to be uploaded" +msgstr "Selecciona una foto para subir" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:133 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:289 +#: wxUI/dialogs/update_profile.py:82 +msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" +msgstr "Archivos de imagen (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" + +#: wxUI/dialogs/urlList.py:6 msgid "Select URL" msgstr "Selecciona la URL" -#: ../src\wxUI\dialogs\userActions.py:11 ../src\wxUI\view.py:87 -msgid "&User" -msgstr "&Usuario" - -#: ../src\wxUI\dialogs\userActions.py:14 -#: ../src\wxUI\dialogs\userAliasDialogs.py:13 -#: ../src\wxUI\dialogs\userSelection.py:14 ../src\wxUI\dialogs\utils.py:31 +#: wxUI/dialogs/userActions.py:14 wxUI/dialogs/userAliasDialogs.py:13 +#: wxUI/dialogs/userSelection.py:14 wxUI/dialogs/utils.py:31 msgid "&Autocomplete users" msgstr "&Autocompletar usuarios" -#: ../src\wxUI\dialogs\userActions.py:20 +#: wxUI/dialogs/userActions.py:20 msgid "&Follow" msgstr "&Seguir" -#: ../src\wxUI\dialogs\userActions.py:21 +#: wxUI/dialogs/userActions.py:21 msgid "U&nfollow" msgstr "&Dejar de seguir" -#: ../src\wxUI\dialogs\userActions.py:22 ../src\wxUI\view.py:63 -msgid "&Mute" -msgstr "S&ilenciar" - -#: ../src\wxUI\dialogs\userActions.py:23 +#: wxUI/dialogs/userActions.py:23 msgid "Unmu&te" msgstr "D&esactivar silencio" -#: ../src\wxUI\dialogs\userActions.py:24 +#: wxUI/dialogs/userActions.py:24 msgid "&Block" msgstr "&Bloquear" -#: ../src\wxUI\dialogs\userActions.py:25 +#: wxUI/dialogs/userActions.py:25 msgid "Unbl&ock" msgstr "Desb&loquear" -#: ../src\wxUI\dialogs\userActions.py:26 +#: wxUI/dialogs/userActions.py:26 msgid "&Report as spam" msgstr "&Reportar como spam" -#: ../src\wxUI\dialogs\userActions.py:27 +#: wxUI/dialogs/userActions.py:27 msgid "&Ignore tweets from this client" msgstr "&Ignorar tuits de este cliente" -#: ../src\wxUI\dialogs\userAliasDialogs.py:18 +#: wxUI/dialogs/userAliasDialogs.py:18 msgid "Alias" msgstr "Alias" -#: ../src\wxUI\dialogs\userAliasDialogs.py:41 +#: wxUI/dialogs/userAliasDialogs.py:41 msgid "Edit user aliases" msgstr "Editar alias de usuarios" -#: ../src\wxUI\dialogs\userAliasDialogs.py:48 +#: wxUI/dialogs/userAliasDialogs.py:48 msgid "Actions" msgstr "Acciones" -#: ../src\wxUI\dialogs\userAliasDialogs.py:50 +#: wxUI/dialogs/userAliasDialogs.py:50 msgid "Add alias" msgstr "Añadir alias" -#: ../src\wxUI\dialogs\userAliasDialogs.py:51 +#: wxUI/dialogs/userAliasDialogs.py:51 msgid "Adds a new user alias" msgstr "Añadir un nuevo alias" -#: ../src\wxUI\dialogs\userAliasDialogs.py:54 +#: wxUI/dialogs/userAliasDialogs.py:54 msgid "Edit the currently focused user Alias." msgstr "Editar alias del usuario seleccionado" -#: ../src\wxUI\dialogs\userAliasDialogs.py:58 +#: wxUI/dialogs/userAliasDialogs.py:58 msgid "Remove the currently focused user alias." msgstr "Eliminar alias del usuario seleccionado." -#: ../src\wxUI\dialogs\userAliasDialogs.py:82 +#: wxUI/dialogs/userAliasDialogs.py:82 msgid "Are you sure you want to delete this user alias?" msgstr "¿Estás seguro que deseas eliminar este alias de usuario?" -#: ../src\wxUI\dialogs\userAliasDialogs.py:82 +#: wxUI/dialogs/userAliasDialogs.py:82 msgid "Remove user alias" msgstr "Eliminar alias de usuario" -#: ../src\wxUI\dialogs\userAliasDialogs.py:93 +#: wxUI/dialogs/userAliasDialogs.py:93 msgid "User alias" msgstr "Alias de usuario" -#: ../src\wxUI\dialogs\userSelection.py:10 +#: wxUI/dialogs/userSelection.py:10 +#, python-format msgid "Timeline for %s" msgstr "Línea temporal de %s" -#: ../src\wxUI\dialogs\userSelection.py:19 +#: wxUI/dialogs/userSelection.py:19 msgid "Buffer type" msgstr "Tipo de buffer" -#: ../src\wxUI\dialogs\userSelection.py:20 +#: wxUI/dialogs/userSelection.py:20 msgid "&Tweets" msgstr "&Tuits" -#: ../src\wxUI\dialogs\userSelection.py:21 +#: wxUI/dialogs/userSelection.py:21 msgid "&Likes" msgstr "Tuits marcados como &me gusta" -#: ../src\wxUI\dialogs\userSelection.py:22 +#: wxUI/dialogs/userSelection.py:22 msgid "&Followers" msgstr "&Seguidores" -#: ../src\wxUI\dialogs\userSelection.py:23 +#: wxUI/dialogs/userSelection.py:23 msgid "F&riends" msgstr "&Amigos" -#: ../src\wxUI\menus.py:8 ../src\wxUI\view.py:33 -msgid "&Retweet" -msgstr "&Retuit" - -#: ../src\wxUI\menus.py:10 ../src\wxUI\menus.py:34 ../src\wxUI\view.py:32 -msgid "Re&ply" -msgstr "Res&ponder" - -#: ../src\wxUI\menus.py:12 ../src\wxUI\view.py:34 -msgid "&Like" -msgstr "Me &gusta" - -#: ../src\wxUI\menus.py:14 ../src\wxUI\view.py:35 -msgid "&Unlike" -msgstr "&Ya no me gusta" - -#: ../src\wxUI\menus.py:16 ../src\wxUI\menus.py:36 ../src\wxUI\menus.py:52 -msgid "&Open URL" -msgstr "&Abrir URL" - -#: ../src\wxUI\menus.py:18 ../src\wxUI\menus.py:54 ../src\wxUI\menus.py:87 -msgid "&Open in Twitter" -msgstr "&Abrir en Twitter" - -#: ../src\wxUI\menus.py:20 ../src\wxUI\menus.py:38 ../src\wxUI\menus.py:56 -msgid "&Play audio" -msgstr "&Reproducir audio" - -#: ../src\wxUI\menus.py:22 ../src\wxUI\menus.py:58 ../src\wxUI\view.py:36 -msgid "&Show tweet" -msgstr "&Ver tuit" - -#: ../src\wxUI\menus.py:24 ../src\wxUI\menus.py:42 ../src\wxUI\menus.py:60 -#: ../src\wxUI\menus.py:70 ../src\wxUI\menus.py:89 ../src\wxUI\menus.py:103 -msgid "&Copy to clipboard" -msgstr "&Copiar al portapapeles" - -#: ../src\wxUI\menus.py:26 ../src\wxUI\menus.py:44 ../src\wxUI\menus.py:62 -#: ../src\wxUI\menus.py:72 ../src\wxUI\view.py:40 -msgid "&Delete" -msgstr "&Eliminar" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:32 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:48 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:168 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:252 +msgid "Attachments" +msgstr "Adjuntos" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:36 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:172 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:256 +msgid "Type" +msgstr "Tipo" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:39 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:175 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:259 +msgid "Delete attachment" +msgstr "Quitar archivo" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:44 +msgid "Added Tweets" +msgstr "Tuits añadidos" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:51 +msgid "Delete tweet" +msgstr "Quitar tuit" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:56 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:190 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:264 +msgid "A&dd..." +msgstr "Añadir..." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:58 +msgid "Add t&weet" +msgstr "Añadir Tuit" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:61 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:192 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:266 +msgid "&Attach audio..." +msgstr "&Adjuntar audio..." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:65 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:196 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:235 +msgid "Auto&complete users" +msgstr "Auto&completar usuarios" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:67 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:198 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:270 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:364 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:437 +msgid "Check &spelling..." +msgstr "Revisar &ortografía..." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:69 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:200 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:272 +msgid "&Translate" +msgstr "&Traducir" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:73 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:204 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:276 +msgid "Sen&d" +msgstr "En&viar" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:117 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:218 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:296 +msgid "Image" +msgstr "Imagen" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:119 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:220 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:298 +msgid "Video" +msgstr "Vídeo" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:121 +msgid "Poll" +msgstr "Encuesta" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:126 +msgid "please provide a description" +msgstr "por favor proporciona una descripción" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:140 +msgid "Select the video to be uploaded" +msgstr "Selecciona un vídeo para subir" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:140 +msgid "Video files (*.mp4)|*.mp4" +msgstr "Archivos de video (*.mp4)|*.mp4" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:146 +msgid "" +"It is not possible to add more attachments. Please make sure your tweet " +"complies with Twitter'S attachment rules. You can add only one video or GIF " +"in every tweet, and a maximum of 4 photos." +msgstr "" +"No es posible añadir más archivos multimedia. Por favor asegúrate que " +"cumples con los requisitos de archivos de Twitter. Solo se puede añadir un " +"video o un GIF en cada tweet, o un máximo de hasta 4 imágenes." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:146 +msgid "Error adding attachment" +msgstr "Error añadiendo un archivo" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:180 +msgid "&Mention to all" +msgstr "&Mencionar a todos" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:233 +msgid "&Recipient" +msgstr "&Destinatario" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:304 +#, python-format +msgid "Tweet - %i characters " +msgstr "Tuit - %i caracteres " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:321 +msgid "Image description" +msgstr "Descripción de la imagen" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:332 +msgid "Retweets: " +msgstr "Retuits: " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:337 +msgid "Likes: " +msgstr "Me gusta: " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:342 +msgid "Source: " +msgstr "Desde: " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:347 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:425 +msgid "Date: " +msgstr "Fecha: " + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:362 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:435 +msgid "Copy link to clipboard" +msgstr "Copiar enlace al portapapeles" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:365 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:440 +msgid "&Translate..." +msgstr "&Traducir..." + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:366 +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:441 +msgid "C&lose" +msgstr "Ce&rrar" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:410 +msgid "View" +msgstr "Ver" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:412 +msgid "Item" +msgstr "Elemento" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:438 +msgid "&Expand URL" +msgstr "&Expandir URL" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:477 +msgid "Add a poll" +msgstr "Añadir encuesta" + +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:481 +msgid "Participation time (in days)" +msgstr "Tiempo para participar (en días)" -#: ../src\wxUI\menus.py:28 ../src\wxUI\menus.py:46 ../src\wxUI\menus.py:91 -msgid "&User actions..." -msgstr "&Acciones de usuario..." +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:488 +msgid "Choices" +msgstr "Opciones" -#: ../src\wxUI\menus.py:40 -msgid "&Show direct message" -msgstr "&Mostrar mensaje directo" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:492 +msgid "Option 1" +msgstr "Opción 1" -#: ../src\wxUI\menus.py:68 -msgid "&Show event" -msgstr "&Mostrar evento" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:499 +msgid "Option 2" +msgstr "Opción 2" -#: ../src\wxUI\menus.py:78 -msgid "Direct &message" -msgstr "Mensaje &directo" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:506 +msgid "Option 3" +msgstr "Opción 3" -#: ../src\wxUI\menus.py:80 ../src\wxUI\view.py:50 -msgid "&View lists" -msgstr "&Ver listas" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:513 +msgid "Option 4" +msgstr "Opción 4" -#: ../src\wxUI\menus.py:83 ../src\wxUI\view.py:51 -msgid "Show user &profile" -msgstr "Ve&r perfil del usuario" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:541 +msgid "Please make sure you have provided at least two options for the poll." +msgstr "" +"Por favor asegúrate de haber proporcionado, al menos, dos opciones para la " +"encuesta." -#: ../src\wxUI\menus.py:85 -msgid "&Show user" -msgstr "&Mostrar usuario" +#: wxUI/dialogs/twitterDialogs/tweetDialogs.py:541 +msgid "Not enough information" +msgstr "Información insuficiente" -#: ../src\wxUI\menus.py:99 -msgid "&Tweet about this trend" -msgstr "&Tuitear sobre esta tendencia" +#~ msgid "Photo" +#~ msgstr "Imagen" -#: ../src\wxUI\menus.py:101 -msgid "&Show item" -msgstr "&Ver tuit" +#~ msgid "There's no URL to be shortened" +#~ msgstr "No hay ninguna URL para acortar" -#: ../src\wxUI\sysTrayIcon.py:36 ../src\wxUI\view.py:26 -msgid "&Global settings" -msgstr "Opciones &globales" +#~ msgid "URL shortened" +#~ msgstr "URL Acortada" -#: ../src\wxUI\sysTrayIcon.py:37 ../src\wxUI\view.py:25 -msgid "Account se&ttings" -msgstr "Opciones de &cuenta" +#~ msgid "There's no URL to be expanded" +#~ msgstr "No hay ninguna URL para expandir" -#: ../src\wxUI\sysTrayIcon.py:38 -msgid "Update &profile" -msgstr "Actualizar &perfil" +#~ msgid "URL expanded" +#~ msgstr "URL expandida" -#: ../src\wxUI\sysTrayIcon.py:39 -msgid "&Show / hide" -msgstr "&Mostrar / esconder" +#~ msgid "%s - %s characters" +#~ msgstr "%s - %s caracteres" -#: ../src\wxUI\sysTrayIcon.py:40 ../src\wxUI\view.py:75 -msgid "&Documentation" -msgstr "&Documentación" +#~ msgid "Title" +#~ msgstr "Título" -#: ../src\wxUI\sysTrayIcon.py:41 -msgid "Check for &updates" -msgstr "Comprobar &actualizaciones" +#~ msgid "Add attachments" +#~ msgstr "Añadir adjuntos" -#: ../src\wxUI\sysTrayIcon.py:42 -msgid "&Exit" -msgstr "&Salir" +#~ msgid "&Photo" +#~ msgstr "&Foto" -#: ../src\wxUI\view.py:18 -msgid "&Manage accounts" -msgstr "Gestionar &cuentas" +#~ msgid "&Long tweet" +#~ msgstr "Tuit &largo" -#: ../src\wxUI\view.py:20 -msgid "&Hide window" -msgstr "Esconder &ventana" +#~ msgid "&Upload image..." +#~ msgstr "&Subir imagen..." -#: ../src\wxUI\view.py:22 -msgid "&Lists manager" -msgstr "Gestor de &listas" - -#: ../src\wxUI\view.py:23 -msgid "Manage user aliases" -msgstr "Gestionar alias de usuario" - -#: ../src\wxUI\view.py:24 -msgid "&Edit keystrokes" -msgstr "Editar combinaciones de &teclas" - -#: ../src\wxUI\view.py:27 -msgid "E&xit" -msgstr "S&alir" - -#: ../src\wxUI\view.py:31 ../src\wxUI\view.py:86 -msgid "&Tweet" -msgstr "&Tuit" - -#: ../src\wxUI\view.py:37 -msgid "View &address" -msgstr "Ver &dirección" - -#: ../src\wxUI\view.py:38 -msgid "View conversa&tion" -msgstr "Ver conversa&ción" - -#: ../src\wxUI\view.py:39 -msgid "Read text in picture" -msgstr "Leer texto en imágenes" - -#: ../src\wxUI\view.py:44 -msgid "&Actions..." -msgstr "&Acciones..." - -#: ../src\wxUI\view.py:45 -msgid "&View timeline..." -msgstr "&Ver línea temporal..." - -#: ../src\wxUI\view.py:46 -msgid "Direct me&ssage" -msgstr "&Mensaje directo" - -#: ../src\wxUI\view.py:47 -msgid "Add a&lias" -msgstr "Añadir alias" - -#: ../src\wxUI\view.py:48 -msgid "&Add to list" -msgstr "&Añadir a lista" - -#: ../src\wxUI\view.py:49 -msgid "R&emove from list" -msgstr "&Quitar de lista" - -#: ../src\wxUI\view.py:52 -msgid "V&iew likes" -msgstr "&Ver tuits marcados con me gusta" - -#: ../src\wxUI\view.py:56 -msgid "&Update buffer" -msgstr "&actualizar buffer" - -#: ../src\wxUI\view.py:57 -msgid "New &trending topics buffer..." -msgstr "Nuevo buffer de &tendencias..." - -#: ../src\wxUI\view.py:58 -msgid "Create a &filter" -msgstr "Crear &filtro" - -#: ../src\wxUI\view.py:59 -msgid "&Manage filters" -msgstr "Gestionar &filtros" - -#: ../src\wxUI\view.py:60 -msgid "Find a string in the currently focused buffer..." -msgstr "Buscar término en el buffer actual..." - -#: ../src\wxUI\view.py:61 -msgid "&Load previous items" -msgstr "&Cargar elementos anteriores" - -#: ../src\wxUI\view.py:64 -msgid "&Autoread" -msgstr "&lectura automática" - -#: ../src\wxUI\view.py:65 -msgid "&Clear buffer" -msgstr "&Vaciar buffer" - -#: ../src\wxUI\view.py:66 -msgid "&Destroy" -msgstr "&Eliminar" - -#: ../src\wxUI\view.py:70 -msgid "&Seek back 5 seconds" -msgstr "&Retroceder 5 segundos" - -#: ../src\wxUI\view.py:71 -msgid "&Seek forward 5 seconds" -msgstr "A&vanzar 5 segundos" - -#: ../src\wxUI\view.py:76 -msgid "Sounds &tutorial" -msgstr "Tutorial de &sonidos" - -#: ../src\wxUI\view.py:77 -msgid "&What's new in this version?" -msgstr "¿&Qué hay de nuevo en esta versión?" - -#: ../src\wxUI\view.py:78 -msgid "&Check for updates" -msgstr "&Comprobar actualizaciones" - -#: ../src\wxUI\view.py:79 -msgid "&Report an error" -msgstr "&Reportar un error" - -#: ../src\wxUI\view.py:80 -msgid "{0}'s &website" -msgstr "Sitio &web de {0}" - -#: ../src\wxUI\view.py:81 -msgid "Get soundpacks for TWBlue" -msgstr "Obtener paquetes de sonidos para TWBlue" - -#: ../src\wxUI\view.py:82 -msgid "About &{0}" -msgstr "Sobre &{0}" - -#: ../src\wxUI\view.py:85 -msgid "&Application" -msgstr "&Aplicación" - -#: ../src\wxUI\view.py:88 -msgid "&Buffer" -msgstr "&Buffer" - -#: ../src\wxUI\view.py:89 -msgid "&Audio" -msgstr "&Audio" - -#: ../src\wxUI\view.py:90 -msgid "&Help" -msgstr "Ay&uda" - -#: ../src\wxUI\view.py:176 -msgid "Address" -msgstr "Dirección" - -#: ../src\wxUI\view.py:207 -msgid "Update" -msgstr "Actualización" - -#: ../src\wxUI\view.py:207 -msgid "Your {0} version is up to date" -msgstr "Tu versión de {0} está actualizada" +#~ msgid "Sh&orten URL" +#~ msgstr "Acortar &URL" #~ msgid "Friends' Timelines" #~ msgstr "Líneas temporales de amigos" @@ -3682,9 +3857,6 @@ msgstr "Tu versión de {0} está actualizada" #~ msgid "GIF images" #~ msgstr "Imágenes GIF" -#~ msgid "PNG Images" -#~ msgstr "Imágenes PNG" - #~ msgid "Select an URL" #~ msgstr "Selecciona una URL" diff --git a/src/locales/fr/LC_MESSAGES/twblue.mo b/src/locales/fr/LC_MESSAGES/twblue.mo index 2d8ceb5cd79bfc8523ba19a9b3344d478969ea03..a6de84039f627abb6c7670462284eface51f20bf 100644 GIT binary patch delta 18273 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 TH*FJBADo}%le+Y~BYyt}NNleu diff --git a/src/locales/fr/LC_MESSAGES/twblue.po b/src/locales/fr/LC_MESSAGES/twblue.po index 3842a448..f9587d45 100644 --- a/src/locales/fr/LC_MESSAGES/twblue.po +++ b/src/locales/fr/LC_MESSAGES/twblue.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.94\n" "POT-Creation-Date: 2021-11-11 01:00+0100\n" -"PO-Revision-Date: 2021-11-11 01:08+0100\n" +"PO-Revision-Date: 2021-11-12 13:32-0600\n" "Last-Translator: Oreonan \n" "Language-Team: Oreonan \n" "Language: fr\n" From 7bfbadc254604e1b01fb5f88bd53274fe6bf95a5 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 12 Nov 2021 15:01:54 -0600 Subject: [PATCH 42/83] Update write_version_data --- src/write_version_data.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/write_version_data.py b/src/write_version_data.py index a634030f..2136c3a0 100644 --- a/src/write_version_data.py +++ b/src/write_version_data.py @@ -28,11 +28,3 @@ file2 = open("..\\scripts\\twblue.nsi", "w", encoding="utf-8") file2.write(contents) file2.close() print("done") -print("Writing keys to module...") -file3 = open("appkeys.py", "w") -keys = """twitter_api_key = "{}" -twitter_api_secret = "{}" -""".format(os.environ.get("TWITTER_API_KEY"), os.environ.get("TWITTER_API_SECRET")) -file3.write(keys) -file3.close() -print("Wrote set of keys for consumer of {}".format(os.environ.get("TWITTER_API_KEY"))) \ No newline at end of file From 806111c36e87679348a225824fa7081dc5086632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Manuel=20Delicado=20Alcolea?= Date: Mon, 15 Nov 2021 13:04:18 +0100 Subject: [PATCH 43/83] Included more dependencies in the setup script --- src/setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/setup.py b/src/setup.py index f5bc1f17..b0734eaa 100644 --- a/src/setup.py +++ b/src/setup.py @@ -8,9 +8,9 @@ from requests import certs def get_architecture_files(): if platform.architecture()[0][:2] == "32": - return ["../windows-dependencies/x86/oggenc2.exe", "../windows-dependencies/x86/bootstrap.exe", "../windows-dependencies/x86/libvlc.dll", "../windows-dependencies/x86/libvlccore.dll", "../windows-dependencies/x86/plugins", ["../windows-dependencies/dictionaries", "lib/enchant/data/mingw32/share/enchant/hunspell"], ["../windows-dependencies/x86/Microsoft.VC142.CRT", "."], ["../windows-dependencies/x86/Microsoft.VC142.MFC", "."]] + return ["../windows-dependencies/x86/oggenc2.exe", "../windows-dependencies/x86/bootstrap.exe", "../windows-dependencies/x86/libvlc.dll", "../windows-dependencies/x86/libvlccore.dll", "../windows-dependencies/x86/plugins", ["../windows-dependencies/dictionaries", "lib/enchant/data/mingw32/share/enchant/hunspell"], ["../windows-dependencies/x86/Microsoft.VC142.CRT", "."], ["../windows-dependencies/x86/Microsoft.VC142.MFC", "."], ["../windows-dependencies/x86/Microsoft.VC142.MFCLOC", "."], ["../windows-dependencies/x86/ucrt", "."]] elif platform.architecture()[0][:2] == "64": - return ["../windows-dependencies/x64/oggenc2.exe", "../windows-dependencies/x64/bootstrap.exe", "../windows-dependencies/x64/libvlc.dll", "../windows-dependencies/x64/libvlccore.dll", "../windows-dependencies/x64/plugins", ["../windows-dependencies/dictionaries", "lib/enchant/data/mingw64/share/enchant/hunspell"], ["../windows-dependencies/x64/Microsoft.VC142.CRT", "."], ["../windows-dependencies/x64/Microsoft.VC142.MFC", "."]] + return ["../windows-dependencies/x64/oggenc2.exe", "../windows-dependencies/x64/bootstrap.exe", "../windows-dependencies/x64/libvlc.dll", "../windows-dependencies/x64/libvlccore.dll", "../windows-dependencies/x64/plugins", ["../windows-dependencies/dictionaries", "lib/enchant/data/mingw64/share/enchant/hunspell"], ["../windows-dependencies/x64/Microsoft.VC142.CRT", "."], ["../windows-dependencies/x64/Microsoft.VC142.MFC", "."], ["../windows-dependencies/x64/Microsoft.VC142.MFCLOC", "."], ["../windows-dependencies/x64/ucrt", "."]] def find_sound_lib_datafiles(): import os From cfd4fd12d32cd981a25a3c2fe175cc30b475c891 Mon Sep 17 00:00:00 2001 From: Nikola Jovic Date: Wed, 17 Nov 2021 19:35:02 +0100 Subject: [PATCH 44/83] Updated Windows 11 keymap --- doc/changelog.md | 1 + src/keymaps/Windows11.keymap | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/changelog.md b/doc/changelog.md index cc097af8..7871504d 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,7 @@ TWBlue Changelog ## changes in this version +* In the Windows 11 Keymap, the default shortcut to open the keystrokes editor is now CTRL plus Alt plus Windows plus K to avoid conflicts with the new global mute microphone shortcut. * Now it is possible to create a tweet from a trending topics buffer again. * TWBlue now includes a completely new set of dialogs to handle tweeting, replying and sending direct messages that takes advantage of more Twitter features. * It is possible to add videos in tweets and direct messages by using the new "add" button, located in every dialog where media can be added. Twitter suggests to add videos from 5 seconds up to 2 minutes lenght, in mp4 format (video Codec H.264 and audio codec AAC). Currently, TWBlue does not check if the uploaded video complies with Twitter media requirements. You can add only a video in a tweet or direct message. No other kind of media can be added after a video is in a tweet. If the video was unable to be uploaded successfully, the tweet or direct message won't be created. diff --git a/src/keymaps/Windows11.keymap b/src/keymaps/Windows11.keymap index 57ca311e..acda0961 100644 --- a/src/keymaps/Windows11.keymap +++ b/src/keymaps/Windows11.keymap @@ -42,7 +42,7 @@ toggle_buffer_mute = string(default="alt+win+shift+m") toggle_session_mute = string(default="control+alt+win+m") toggle_autoread = string(default="alt+win+e") search = string(default="alt+win+-") -edit_keystrokes = string(default="alt+win+k") +edit_keystrokes = string(default="control+alt+win+k") view_user_lists = string(default="alt+win+l") get_more_items = string(default="alt+win+pageup") reverse_geocode = string(default="control+win+g") From 78c10b38e5d9cc455eef725deb729f1af275fde2 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 8 Dec 2021 12:49:20 -0600 Subject: [PATCH 45/83] Fixed issue when sending tweets and replies with images --- src/sessions/twitter/session.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index a311ab42..55373aa7 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -631,7 +631,7 @@ class Session(base.baseSession): if i["type"] == "photo": self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) - item = self.api_call_v2(call_name="create_tweet", status=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"], quote_tweet_id=obj.get("quote_tweet_id")) + item = self.api_call_v2(call_name="create_tweet", text=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"], quote_tweet_id=obj.get("quote_tweet_id")) in_reply_to_status_id = item.data["id"] def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs): @@ -644,7 +644,7 @@ class Session(base.baseSession): if i["type"] == "photo": self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) media_ids.append(img.media_id) - item = self.api_call(call_name="update_status", status=text, _sound="reply_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids, *args, **kwargs) + item = self.api_call_v2(call_name="create_tweet", text=text, _sound="reply_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, *args, **kwargs) def direct_message(self, text, recipient, attachment=None, *args, **kwargs): if attachment == None: From 86a2eb7c0d8ed7bf2c326a30e615a7ddec9bc3f1 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Thu, 9 Dec 2021 10:46:07 -0600 Subject: [PATCH 46/83] Restored conversation and threads support powered by Twitter API V2 --- doc/changelog.md | 5 +++++ src/controller/buffers/twitter/search.py | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index cc097af8..13d35a74 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,11 @@ TWBlue Changelog ## changes in this version +* We have restored conversation and threads support powered by Twitter API V2 thanks to a set of improvements we have done in the application, as well as more generous limits to Tweet monthly cap by Twitter. +* Fixed issue when uploading attachments (images, videos or gif files) while sending tweets or replies. + +## Changes in version 2021.11.12 + * Now it is possible to create a tweet from a trending topics buffer again. * TWBlue now includes a completely new set of dialogs to handle tweeting, replying and sending direct messages that takes advantage of more Twitter features. * It is possible to add videos in tweets and direct messages by using the new "add" button, located in every dialog where media can be added. Twitter suggests to add videos from 5 seconds up to 2 minutes lenght, in mp4 format (video Codec H.264 and audio codec AAC). Currently, TWBlue does not check if the uploaded video complies with Twitter media requirements. You can add only a video in a tweet or direct message. No other kind of media can be added after a video is in a tweet. If the video was unable to be uploaded successfully, the tweet or direct message won't be created. diff --git a/src/controller/buffers/twitter/search.py b/src/controller/buffers/twitter/search.py index db72fd35..55205069 100644 --- a/src/controller/buffers/twitter/search.py +++ b/src/controller/buffers/twitter/search.py @@ -64,12 +64,16 @@ class SearchPeopleBuffer(people.PeopleBuffer): return False class ConversationBuffer(SearchBuffer): + last_thread_id = None + last_reply_id = None def start_stream(self, start=False, mandatory=False, play_sound=True, avoid_autoreading=False): current_time = time.time() if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True: self.execution_time = current_time - results = self.get_replies_v1(self.tweet) + log.debug("Retrieving conversation. Last thread ID is {}, last reply ID is {}".format(self.last_thread_id, self.last_reply_id)) + results = self.get_replies(self.tweet) + log.debug("Retrieved {} items before filters.".format(len(results))) number_of_items = self.session.order_buffer(self.name, results) log.debug("Number of items retrieved: %d" % (number_of_items,)) self.put_items_on_list(number_of_items) @@ -117,12 +121,12 @@ class ConversationBuffer(SearchBuffer): # find all tweets replying to the original thread only. Those tweets are sent by the same author who originally posted the first tweet. try: term = "conversation_id:{} from:{} to:{}".format(conversation_id, original_tweet.data.author_id, original_tweet.data.author_id) - thread_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=98, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"]) + thread_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=98, since_id=self.last_thread_id, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"]) if thread_tweets.data != None: thread_results.extend(thread_tweets.data) # Search only replies to conversation_id. term = "conversation_id:{}".format(conversation_id, original_tweet.data.author_id) - reply_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=50, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"]) + reply_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=50, since_id=self.last_reply_id, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"]) if reply_tweets.data != None: reply_results.extend(reply_tweets.data) except TweepyException as e: @@ -135,6 +139,7 @@ class ConversationBuffer(SearchBuffer): try: thread_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended") thread_results.sort(key=lambda x: x.id) + self.last_thread_id = thread_results[-1].id results.extend(thread_results) except TweepyException as e: log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name)) @@ -144,6 +149,7 @@ class ConversationBuffer(SearchBuffer): try: reply_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended") reply_results.sort(key=lambda x: x.id) + self.last_reply_id = reply_results[-1].id results.extend(reply_results) except TweepyException as e: log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name)) From b67fc0ff3822b980a8eaaf9f8ab1761a1876230e Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 10 Dec 2021 09:53:49 -0600 Subject: [PATCH 47/83] Made some cleanup in unneeded imports --- src/sessions/twitter/utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sessions/twitter/utils.py b/src/sessions/twitter/utils.py index d44e0e3f..47cef7a7 100644 --- a/src/sessions/twitter/utils.py +++ b/src/sessions/twitter/utils.py @@ -1,11 +1,9 @@ # -*- coding: utf-8 -*- import re import output -import config import logging import requests import time -import sound from tweepy.errors import TweepyException, NotFound, Forbidden log = logging.getLogger("twitter.utils") """ Some utilities for the twitter interface.""" From 0bd366c5392bb025c2b8e24ac00e730f7deee6e4 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 10 Dec 2021 13:32:46 -0600 Subject: [PATCH 48/83] Added first draft to a new templating system which could be used in invisible interface for now --- src/sessions/twitter/templates.py | 78 +++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/sessions/twitter/templates.py diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py new file mode 100644 index 00000000..bfccddb8 --- /dev/null +++ b/src/sessions/twitter/templates.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +import re +import arrow +import languageHandler +from string import Template +from . import utils + +def process_date(field, relative_times=True, offset_seconds=0): + original_date = arrow.get(field, locale="en") + if relative_times == True: + ts = original_date.humanize(locale=languageHandler.curLang[:2]) + else: + ts = original_date.shift(seconds=offset_seconds).format(_("dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2]) + return ts + +def process_text(tweet): + if hasattr(tweet, "text"): + text = tweet.text + elif hasattr(tweet, "full_text"): + text = tweet.full_text + # Cleanup mentions, so we'll remove more than 2 mentions to make the tweet easier to read. + text = utils.clean_mentions(text) + # Replace URLS for extended version of those. + if hasattr(tweet, "entities"): + text = utils.expand_urls(text, tweet.entities) + text = re.sub(r"https://twitter.com/\w+/status/\d+", "", text) + return text + +def process_image_descriptions(entities): + """ Attempt to extract information for image descriptions. """ + image_descriptions = [] + for media in entities["media"]: + if media.get("ext_alt_text") != None: + image_descriptions.append(media.get("ext_alt_text")) + idescriptions = "" + for image in image_descriptions: + idescriptions += "Image description: {}.".format(image) + return idescriptions + +def render_tweet(tweet, template, relative_times=False, offset_seconds=0): + """ Renders any given Tweet according to the passed template. + Available data for tweets will be stored in the following variables: + $date: Creation date. + $display_name: User profile name. + $screen_name: User screen name, this is the same name used to reference the user in Twitter. + $ source: Source client from where the current tweet was sent. + $lang: Two letter code for the automatically detected language for the tweet. This detection is performed by Twitter. + $text: Tweet text. + $image_descriptions: Information regarding image descriptions added by twitter users. + """ + available_data = dict() + created_at = process_date(tweet.created_at, relative_times, offset_seconds) + available_data.update(date=created_at) + # user. + available_data.update(display_name=tweet.user.name, screen_name=tweet.user.screen_name) + # Source client from where tweet was originated. + available_data.update(source=tweet.source) + if hasattr(tweet, "retweeted_status"): + if hasattr(tweet.retweeted_status, "quoted_status"): + text = "RT @{}: {} Quote from @{}: {}".format(tweet.retweeted_status.user.screen_name, process_text(tweet.retweeted_status), tweet.retweeted_status.quoted_status.user.screen_name, process_text(tweet.retweeted_status.quoted_status)) + else: + text = "RT @{}: {}".format(tweet.retweeted_status.user.screen_name, process_text(tweet.retweeted_status)) + elif hasattr(tweet, "quoted_status"): + text = "{} Quote from @{}: {}".format(process_text(tweet), tweet.quoted_status.user.screen_name, process_text(tweet.quoted_status)) + else: + text = process_text(tweet) + available_data.update(lang=tweet.lang, text=text) + # process image descriptions + image_descriptions = "" + if hasattr(tweet, "quoted_status") and hasattr(tweet.quoted_status, "extended_entities"): + image_descriptions = process_image_descriptions(tweet.quoted_status.extended_entities) + elif hasattr(tweet.retweeted_status, "quoted_status") and hasattr(tweet.retweeted_status.quoted_status, "extended_entities"): + image_descriptions = process_image_descriptions(tweet.retweeted_status.quoted_status.extended_entities) + if image_descriptions != "": + available_data.update(image_descriptions=image_descriptions) + result = Template(template).safe_substitute(**available_data) + result = re.sub(r"\$\w+", "", result) + return result \ No newline at end of file From 40e13250ca7cbcd6b1a9eb6a032b23f0cd80b759 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 10 Dec 2021 13:36:08 -0600 Subject: [PATCH 49/83] Added a base template for tweets --- src/Conf.defaults | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Conf.defaults b/src/Conf.defaults index a2b3760a..3d684a65 100644 --- a/src/Conf.defaults +++ b/src/Conf.defaults @@ -48,6 +48,9 @@ ocr_language = string(default="") braille_reporting = boolean(default=True) speech_reporting = boolean(default=True) +[templates] +tweet = string(default="$display_name, $text $image_descriptions $date. $source") + [filters] [user-aliases] \ No newline at end of file From a47fa3134616313620a8fc8de84965291b10e943 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 10 Dec 2021 15:03:15 -0600 Subject: [PATCH 50/83] Use session to retrieve users in templates, when applied to reduced tweets --- src/sessions/twitter/templates.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index bfccddb8..b35c1e8c 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -37,7 +37,7 @@ def process_image_descriptions(entities): idescriptions += "Image description: {}.".format(image) return idescriptions -def render_tweet(tweet, template, relative_times=False, offset_seconds=0): +def render_tweet(tweet, template, session, relative_times=False, offset_seconds=0): """ Renders any given Tweet according to the passed template. Available data for tweets will be stored in the following variables: $date: Creation date. @@ -52,16 +52,16 @@ def render_tweet(tweet, template, relative_times=False, offset_seconds=0): created_at = process_date(tweet.created_at, relative_times, offset_seconds) available_data.update(date=created_at) # user. - available_data.update(display_name=tweet.user.name, screen_name=tweet.user.screen_name) + available_data.update(display_name=session.get_user(tweet.user).name, screen_name=session.get_user(tweet.user).screen_name) # Source client from where tweet was originated. available_data.update(source=tweet.source) if hasattr(tweet, "retweeted_status"): if hasattr(tweet.retweeted_status, "quoted_status"): - text = "RT @{}: {} Quote from @{}: {}".format(tweet.retweeted_status.user.screen_name, process_text(tweet.retweeted_status), tweet.retweeted_status.quoted_status.user.screen_name, process_text(tweet.retweeted_status.quoted_status)) + text = "RT @{}: {} Quote from @{}: {}".format(session.get_user(tweet.retweeted_status.user).screen_name, process_text(tweet.retweeted_status), session.get_user(tweet.retweeted_status.quoted_status.user).screen_name, process_text(tweet.retweeted_status.quoted_status)) else: - text = "RT @{}: {}".format(tweet.retweeted_status.user.screen_name, process_text(tweet.retweeted_status)) + text = "RT @{}: {}".format(session.get_user(tweet.retweeted_status.user).screen_name, process_text(tweet.retweeted_status)) elif hasattr(tweet, "quoted_status"): - text = "{} Quote from @{}: {}".format(process_text(tweet), tweet.quoted_status.user.screen_name, process_text(tweet.quoted_status)) + text = "{} Quote from @{}: {}".format(process_text(tweet), session.get_user(tweet.quoted_status.user).screen_name, process_text(tweet.quoted_status)) else: text = process_text(tweet) available_data.update(lang=tweet.lang, text=text) @@ -69,8 +69,10 @@ def render_tweet(tweet, template, relative_times=False, offset_seconds=0): image_descriptions = "" if hasattr(tweet, "quoted_status") and hasattr(tweet.quoted_status, "extended_entities"): image_descriptions = process_image_descriptions(tweet.quoted_status.extended_entities) - elif hasattr(tweet.retweeted_status, "quoted_status") and hasattr(tweet.retweeted_status.quoted_status, "extended_entities"): + elif hasattr(tweet, "retweeted_status") and hasattr(tweet.retweeted_status, "quoted_status") and hasattr(tweet.retweeted_status.quoted_status, "extended_entities"): image_descriptions = process_image_descriptions(tweet.retweeted_status.quoted_status.extended_entities) + elif hasattr(tweet, "extended_entities"): + image_descriptions = process_image_descriptions(tweet.extended_entities) if image_descriptions != "": available_data.update(image_descriptions=image_descriptions) result = Template(template).safe_substitute(**available_data) From af4594f16c5d4e95d524fb0bb0ca3c35f7146dd6 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 10 Dec 2021 15:22:42 -0600 Subject: [PATCH 51/83] Render tweets for invisible interface from template specified in config --- src/controller/buffers/twitter/base.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 3ad5b77c..3d7c1767 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -19,7 +19,7 @@ import languageHandler import logging from audio_services import youtube_utils from controller.buffers.base import base -from sessions.twitter import compose, utils, reduce +from sessions.twitter import compose, utils, reduce, templates from mysc.thread_utils import call_threaded from tweepy.errors import TweepyException from tweepy.cursor import Cursor @@ -100,8 +100,10 @@ class BaseBuffer(base.Buffer): return self.get_message() def get_message(self): + template = self.session.settings["templates"]["tweet"] tweet = self.get_right_tweet() - return " ".join(self.compose_function(tweet, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)) + t = templates.render_tweet(tweet, template, self.session, relative_times=self.session.settings["general"]["relative_times"], offset_seconds=self.session.db["utc_offset"]) + return t def get_full_tweet(self): tweet = self.get_right_tweet() From 416151570c82735dd373a566844add638228dba0 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 10 Dec 2021 15:23:41 -0600 Subject: [PATCH 52/83] Request image description features for all created buffers by default --- src/controller/mainController.py | 82 ++++++++++++++++---------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/controller/mainController.py b/src/controller/mainController.py index ddedb068..a8f4130d 100644 --- a/src/controller/mainController.py +++ b/src/controller/mainController.py @@ -334,17 +334,17 @@ class Controller(object): root_position =self.view.search(session.db["user_name"], session.db["user_name"]) for i in session.settings['general']['buffer_order']: if i == 'home': - pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Home"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="home_timeline", name="home_timeline", sessionObject=session, account=session.db["user_name"], sound="tweet_received.ogg", tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Home"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="home_timeline", name="home_timeline", sessionObject=session, account=session.db["user_name"], sound="tweet_received.ogg", include_ext_alt_text=True, tweet_mode="extended")) elif i == 'mentions': - pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Mentions"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="mentions_timeline", name="mentions", sessionObject=session, account=session.db["user_name"], sound="mention_received.ogg", tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Mentions"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="mentions_timeline", name="mentions", sessionObject=session, account=session.db["user_name"], sound="mention_received.ogg", include_ext_alt_text=True, tweet_mode="extended")) elif i == 'dm': pub.sendMessage("createBuffer", buffer_type="DirectMessagesBuffer", session_type=session.type, buffer_title=_("Direct messages"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_direct_messages", name="direct_messages", sessionObject=session, account=session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message", sound="dm_received.ogg")) elif i == 'sent_dm': pub.sendMessage("createBuffer", buffer_type="SentDirectMessagesBuffer", session_type=session.type, buffer_title=_("Sent direct messages"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function=None, name="sent_direct_messages", sessionObject=session, account=session.db["user_name"], bufferType="dmPanel", compose_func="compose_direct_message")) elif i == 'sent_tweets': - pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Sent tweets"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="user_timeline", name="sent_tweets", sessionObject=session, account=session.db["user_name"], screen_name=session.db["user_name"], tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Sent tweets"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="user_timeline", name="sent_tweets", sessionObject=session, account=session.db["user_name"], screen_name=session.db["user_name"], include_ext_alt_text=True, tweet_mode="extended")) elif i == 'favorites': - pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_favorites", name="favourites", sessionObject=session, account=session.db["user_name"], sound="favourite.ogg", tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_favorites", name="favourites", sessionObject=session, account=session.db["user_name"], sound="favourite.ogg", include_ext_alt_text=True, tweet_mode="extended")) elif i == 'followers': pub.sendMessage("createBuffer", buffer_type="PeopleBuffer", session_type=session.type, buffer_title=_("Followers"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, function="get_followers", name="followers", sessionObject=session, account=session.db["user_name"], sound="update_followers.ogg", screen_name=session.db["user_name"])) elif i == 'friends': @@ -356,11 +356,11 @@ class Controller(object): pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="timelines", account=session.db["user_name"])) timelines_position =self.view.search("timelines", session.db["user_name"]) for i in session.settings["other_buffers"]["timelines"]: - pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_(u"Timeline for {}").format(i,), parent_tab=timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="user_timeline", name="%s-timeline" % (i,), sessionObject=session, account=session.db["user_name"], sound="tweet_timeline.ogg", bufferType=None, user_id=i, tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_(u"Timeline for {}").format(i,), parent_tab=timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="user_timeline", name="%s-timeline" % (i,), sessionObject=session, account=session.db["user_name"], sound="tweet_timeline.ogg", bufferType=None, user_id=i, include_ext_alt_text=True, tweet_mode="extended")) pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Likes timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="favs_timelines", account=session.db["user_name"])) favs_timelines_position =self.view.search("favs_timelines", session.db["user_name"]) for i in session.settings["other_buffers"]["favourites_timelines"]: - pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes for {}").format(i,), parent_tab=favs_timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="get_favorites", name="%s-favorite" % (i,), sessionObject=session, account=session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="BaseBuffer", session_type=session.type, buffer_title=_("Likes for {}").format(i,), parent_tab=favs_timelines_position, start=False, kwargs=dict(parent=self.view.nb, function="get_favorites", name="%s-favorite" % (i,), sessionObject=session, account=session.db["user_name"], bufferType=None, sound="favourites_timeline_updated.ogg", user_id=i, include_ext_alt_text=True, tweet_mode="extended")) pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Followers timelines"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="followers_timelines", account=session.db["user_name"])) followers_timelines_position =self.view.search("followers_timelines", session.db["user_name"]) for i in session.settings["other_buffers"]["followers_timelines"]: @@ -372,11 +372,11 @@ class Controller(object): pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Lists"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="lists", account=session.db["user_name"])) lists_position =self.view.search("lists", session.db["user_name"]) for i in session.settings["other_buffers"]["lists"]: - pub.sendMessage("createBuffer", buffer_type="ListBuffer", session_type=session.type, buffer_title=_(u"List for {}").format(i), parent_tab=lists_position, start=False, kwargs=dict(parent=self.view.nb, function="list_timeline", name="%s-list" % (i,), sessionObject=session, account=session.db["user_name"], bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="ListBuffer", session_type=session.type, buffer_title=_(u"List for {}").format(i), parent_tab=lists_position, start=False, kwargs=dict(parent=self.view.nb, function="list_timeline", name="%s-list" % (i,), sessionObject=session, account=session.db["user_name"], bufferType=None, sound="list_tweet.ogg", list_id=utils.find_list(i, session.db["lists"]), include_ext_alt_text=True, tweet_mode="extended")) pub.sendMessage("createBuffer", buffer_type="EmptyBuffer", session_type="base", buffer_title=_("Searches"), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="searches", account=session.db["user_name"])) searches_position =self.view.search("searches", session.db["user_name"]) for i in session.settings["other_buffers"]["tweet_searches"]: - pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=session.type, buffer_title=_(u"Search for {}").format(i), parent_tab=searches_position, start=False, kwargs=dict(parent=self.view.nb, function="search_tweets", name="%s-searchterm" % (i,), sessionObject=session, account=session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=i, tweet_mode="extended")) + pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=session.type, buffer_title=_(u"Search for {}").format(i), parent_tab=searches_position, start=False, kwargs=dict(parent=self.view.nb, function="search_tweets", name="%s-searchterm" % (i,), sessionObject=session, account=session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=i, include_ext_alt_text=True, tweet_mode="extended")) for i in session.settings["other_buffers"]["trending_topic_buffers"]: pub.sendMessage("createBuffer", buffer_type="TrendsBuffer", session_type=session.type, buffer_title=_("Trending topics for %s") % (i), parent_tab=root_position, start=False, kwargs=dict(parent=self.view.nb, name="%s_tt" % (i,), sessionObject=session, account=session.db["user_name"], trendsFor=i, sound="trends_updated.ogg")) @@ -423,7 +423,7 @@ class Controller(object): buffer.session.settings["other_buffers"]["tweet_searches"].append(term) buffer.session.settings.write() args = {"lang": dlg.get_language(), "result_type": dlg.get_result_type()} - pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=buffer.session.type, buffer_title=_("Search for {}").format(term), parent_tab=searches_position, start=True, kwargs=dict(parent=self.view.nb, function="search_tweets", name="%s-searchterm" % (term,), sessionObject=buffer.session, account=buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=term, tweet_mode="extended", **args)) + pub.sendMessage("createBuffer", buffer_type="SearchBuffer", session_type=buffer.session.type, buffer_title=_("Search for {}").format(term), parent_tab=searches_position, start=True, kwargs=dict(parent=self.view.nb, function="search_tweets", name="%s-searchterm" % (term,), sessionObject=buffer.session, account=buffer.session.db["user_name"], bufferType="searchPanel", sound="search_updated.ogg", q=term, include_ext_alt_text=True, tweet_mode="extended", **args)) else: log.error("A buffer for the %s search term is already created. You can't create a duplicate buffer." % (term,)) return @@ -872,7 +872,7 @@ class Controller(object): if usr.id_str in buff.session.settings["other_buffers"]["timelines"]: commonMessageDialogs.timeline_exist() return - tl = buffers.twitter.BaseBuffer(self.view.nb, "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 = buffers.twitter.BaseBuffer(self.view.nb, "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, include_ext_alt_text=True, tweet_mode="extended") try: tl.start_stream(play_sound=False) except ValueError: @@ -891,7 +891,7 @@ class Controller(object): if usr.id_str in buff.session.settings["other_buffers"]["favourites_timelines"]: commonMessageDialogs.timeline_exist() return - tl = buffers.twitter.BaseBuffer(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 = buffers.twitter.BaseBuffer(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, include_ext_alt_text=True, tweet_mode="extended") try: tl.start_stream(play_sound=False) except ValueError: @@ -1088,10 +1088,10 @@ class Controller(object): if position == page.buffer.list.get_selected(): page.session.sound.play("limit.ogg") - try: - output.speak(page.get_message(), True) - except: - pass +# try: + output.speak(page.get_message(), True) +# except: +# pass def down(self, *args, **kwargs): page = self.get_current_buffer() @@ -1100,16 +1100,16 @@ class Controller(object): return position = page.buffer.list.get_selected() index = position+1 - try: - page.buffer.list.select_item(index) - except: - pass +# try: + page.buffer.list.select_item(index) +# except: +# pass if position == page.buffer.list.get_selected(): page.session.sound.play("limit.ogg") - try: - output.speak(page.get_message(), True) - except: - pass +# try: + output.speak(page.get_message(), True) +# except: +# pass def left(self, *args, **kwargs): buff = self.view.get_current_buffer_pos() @@ -1202,18 +1202,18 @@ class Controller(object): def go_home(self): buffer = self.get_current_buffer() buffer.buffer.list.select_item(0) - try: - output.speak(buffer.get_message(), True) - except: - pass +# try: + output.speak(buffer.get_message(), True) +# except: +# pass def go_end(self): buffer = self.get_current_buffer() buffer.buffer.list.select_item(buffer.buffer.list.get_count()-1) - try: - output.speak(buffer.get_message(), True) - except: - pass +# try: + output.speak(buffer.get_message(), True) +# except: +# pass def go_page_up(self): buffer = self.get_current_buffer() @@ -1222,10 +1222,10 @@ class Controller(object): else: index = buffer.buffer.list.get_selected() - 20 buffer.buffer.list.select_item(index) - try: - output.speak(buffer.get_message(), True) - except: - pass +# try: + output.speak(buffer.get_message(), True) +# except: +# pass def go_page_down(self): buffer = self.get_current_buffer() @@ -1234,10 +1234,10 @@ class Controller(object): else: index = buffer.buffer.list.get_selected() + 20 buffer.buffer.list.select_item(index) - try: - output.speak(buffer.get_message(), True) - except: - pass +# try: + output.speak(buffer.get_message(), True) +# except: +# pass def url(self, *args, **kwargs): buffer = self.get_current_buffer() @@ -1385,7 +1385,7 @@ class Controller(object): buff = self.search_buffer("home_timeline", account) if create == True: if buffer == "favourites": - favourites = buffers.twitter.BaseBuffer(self.view.nb, "get_favorites", "favourites", buff.session, buff.session.db["user_name"], tweet_mode="extended") + favourites = buffers.twitter.BaseBuffer(self.view.nb, "get_favorites", "favourites", buff.session, buff.session.db["user_name"], include_ext_alt_text=True, tweet_mode="extended") 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"])) favourites.start_stream(play_sound=False) @@ -1415,7 +1415,7 @@ class Controller(object): if create in buff.session.settings["other_buffers"]["lists"]: output.speak(_(u"This list is already opened"), True) return - tl = buffers.twitter.ListBuffer(self.view.nb, "list_timeline", 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 = buffers.twitter.ListBuffer(self.view.nb, "list_timeline", create+"-list", buff.session, buff.session.db["user_name"], bufferType=None, list_id=utils.find_list(create, buff.session.db["lists"]), include_ext_alt_text=True, tweet_mode="extended") buff.session.lists.append(tl) pos=self.view.search("lists", buff.session.db["user_name"]) self.insert_buffer(tl, pos) From 58ba722bd771cba973d265468ccd778697e388c1 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Fri, 10 Dec 2021 17:15:24 -0600 Subject: [PATCH 53/83] Added templates for direct messages and sent direct messages --- src/Conf.defaults | 2 ++ .../buffers/twitter/directMessages.py | 16 +++++++-- src/sessions/twitter/templates.py | 33 +++++++++++++++++-- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/Conf.defaults b/src/Conf.defaults index 3d684a65..8777227b 100644 --- a/src/Conf.defaults +++ b/src/Conf.defaults @@ -50,6 +50,8 @@ speech_reporting = boolean(default=True) [templates] tweet = string(default="$display_name, $text $image_descriptions $date. $source") +dm = string(default="$sender_display_name, $text $date") +dm_sent = string(default=">$recipient_display_name, $text $date") [filters] diff --git a/src/controller/buffers/twitter/directMessages.py b/src/controller/buffers/twitter/directMessages.py index 06cbed9a..776521d0 100644 --- a/src/controller/buffers/twitter/directMessages.py +++ b/src/controller/buffers/twitter/directMessages.py @@ -8,7 +8,7 @@ import config import languageHandler import logging from controller import messages -from sessions.twitter import compose, utils +from sessions.twitter import compose, utils, templates from mysc.thread_utils import call_threaded from tweepy.errors import TweepyException from pubsub import pub @@ -129,6 +129,12 @@ class DirectMessagesBuffer(base.BaseBuffer): def open_in_browser(self, *args, **kwargs): output.speak(_(u"This action is not supported in the buffer yet.")) + def get_message(self): + template = self.session.settings["templates"]["dm"] + dm = self.get_right_tweet() + t = templates.render_dm(dm, template, self.session, relative_times=self.session.settings["general"]["relative_times"], offset_seconds=self.session.db["utc_offset"]) + return t + class SentDirectMessagesBuffer(DirectMessagesBuffer): def __init__(self, *args, **kwargs): @@ -150,4 +156,10 @@ class SentDirectMessagesBuffer(DirectMessagesBuffer): else: for i in items: tweet = self.compose_function(i, self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session) - self.buffer.list.insert_item(False, *tweet) \ No newline at end of file + self.buffer.list.insert_item(False, *tweet) + + def get_message(self): + template = self.session.settings["templates"]["dm_sent"] + dm = self.get_right_tweet() + t = templates.render_dm(dm, template, self.session, relative_times=self.session.settings["general"]["relative_times"], offset_seconds=self.session.db["utc_offset"]) + return t diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index b35c1e8c..5a5cdf86 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -14,10 +14,10 @@ def process_date(field, relative_times=True, offset_seconds=0): return ts def process_text(tweet): - if hasattr(tweet, "text"): - text = tweet.text - elif hasattr(tweet, "full_text"): + if hasattr(tweet, "full_text"): text = tweet.full_text + elif hasattr(tweet, "text"): + text = tweet.text # Cleanup mentions, so we'll remove more than 2 mentions to make the tweet easier to read. text = utils.clean_mentions(text) # Replace URLS for extended version of those. @@ -77,4 +77,31 @@ def render_tweet(tweet, template, session, relative_times=False, offset_seconds= available_data.update(image_descriptions=image_descriptions) result = Template(template).safe_substitute(**available_data) result = re.sub(r"\$\w+", "", result) + return result + +def render_dm(dm, template, session, relative_times=False, offset_seconds=0): + """ Renders direct messages by using the provided template. + Available data will be stored in the following variables: + $date: Creation date. + $sender_display_name: User profile name for user who sent the dm. + $sender_screen_name: User screen name for user sending the dm, this is the same name used to reference the user in Twitter. + $recipient_display_name: User profile name for user who received the dm. + $recipient_screen_name: User screen name for user receiving the dm, this is the same name used to reference the user in Twitter. + $text: Text of the direct message. + """ + available_data = dict() + available_data.update(text=utils.expand_urls(dm.message_create["message_data"]["text"], dm.message_create["message_data"]["entities"])) + # Let's remove the last 3 digits in the timestamp string. + # Twitter sends their "epoch" timestamp with 3 digits for milliseconds and arrow doesn't like it. + original_date = arrow.get(int(dm.created_timestamp)) + if relative_times == True: + ts = original_date.humanize(locale=languageHandler.curLang[:2]) + else: + ts = original_date.shift(seconds=offset_seconds) + available_data.update(date=ts) + sender = session.get_user(dm.message_create["sender_id"]) + recipient = session.get_user(dm.message_create["target"]["recipient_id"]) + available_data.update(sender_display_name=sender.name, sender_screen_name=sender.screen_name, recipient_display_name=recipient.name, recipient_screen_name=recipient.screen_name) + result = Template(template).safe_substitute(**available_data) + result = re.sub(r"\$\w+", "", result) return result \ No newline at end of file From ab1a0946a49e684b97392e9d555377b930152515 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 13 Dec 2021 09:52:52 -0600 Subject: [PATCH 54/83] Added rendering function for twitter user objects --- src/sessions/twitter/templates.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index 5a5cdf86..3dcaddfa 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -104,4 +104,31 @@ def render_dm(dm, template, session, relative_times=False, offset_seconds=0): available_data.update(sender_display_name=sender.name, sender_screen_name=sender.screen_name, recipient_display_name=recipient.name, recipient_screen_name=recipient.screen_name) result = Template(template).safe_substitute(**available_data) result = re.sub(r"\$\w+", "", result) + return result + +# Sesion object is not used in this function but we keep compatibility across all rendering functions. +def render_person(user, template, session=None, relative_times=True, offset_seconds=0): + """ Renders persons (any Twitter user) by using the provided template. + Available data will be stored in the following variables: + $display_name: The name of the user, as they’ve defined it. Not necessarily a person’s name. Typically capped at 50 characters, but subject to change. + $screen_name: The screen name, handle, or alias that this user identifies themselves with. + $location: The user-defined location for this account’s profile. Not necessarily a location, nor machine-parseable. + $description: The user-defined UTF-8 string describing their account. + $followers: The number of followers this account currently has. This value might be inaccurate. + $following: The number of users this account is following (AKA their “followings”). This value might be inaccurate. + $listed: The number of public lists that this user is a member of. This value might be inaccurate. + $likes: The number of Tweets this user has liked in the account’s lifetime. This value might be inaccurate. + $tweets: The number of Tweets (including retweets) issued by the user. This value might be inaccurate. + $created_at: The date and time that the user account was created on Twitter. + """ + available_data = dict(display_name=user.name, screen_name=user.screen_name, followers=user.followers_count, following=user.friends_count, likes=user.favourites_count, listed=user.listed_count, tweets=user.statuses_count) + # Nullable values. + nullables = ["location", "description"] + for nullable in nullables: + if hasattr(user, nullable) and getattr(user, nullable) != None: + available_data[nullable] = getattr(user, nullable) + created_at = process_date(user.created_at, relative_times=relative_times, offset_seconds=offset_seconds) + available_data.update(created_at=created_at) + result = Template(template).safe_substitute(**available_data) + result = re.sub(r"\$\w+", "", result) return result \ No newline at end of file From 03c330c0a4f2e0dd8829ddd59c9263954d32b555 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 13 Dec 2021 09:53:44 -0600 Subject: [PATCH 55/83] Added default template for Twitter user objects --- src/Conf.defaults | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Conf.defaults b/src/Conf.defaults index 8777227b..2264e8a9 100644 --- a/src/Conf.defaults +++ b/src/Conf.defaults @@ -52,6 +52,7 @@ speech_reporting = boolean(default=True) tweet = string(default="$display_name, $text $image_descriptions $date. $source") dm = string(default="$sender_display_name, $text $date") dm_sent = string(default=">$recipient_display_name, $text $date") +person = string(default="$display_name (@$screen_name). $followers followers, $following following, $tweets tweets. Joined Twitter $created_at.") [filters] From a6ecd37547f47b348538df190370f8d5915c77c3 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 13 Dec 2021 09:54:06 -0600 Subject: [PATCH 56/83] Implement users template in Twitter buffers --- src/controller/buffers/twitter/people.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/controller/buffers/twitter/people.py b/src/controller/buffers/twitter/people.py index d29a46dc..6d6c387d 100644 --- a/src/controller/buffers/twitter/people.py +++ b/src/controller/buffers/twitter/people.py @@ -16,7 +16,7 @@ import logging from mysc.thread_utils import call_threaded from tweepy.errors import TweepyException from pubsub import pub -from sessions.twitter import compose +from sessions.twitter import compose, templates from . import base log = logging.getLogger("controller.buffers.twitter.peopleBuffer") @@ -84,7 +84,10 @@ class PeopleBuffer(base.BaseBuffer): pass def get_message(self): - return " ".join(self.compose_function(self.get_tweet(), self.session.db, self.session.settings["general"]["relative_times"], self.session.settings["general"]["show_screen_names"], self.session)) + template = self.session.settings["templates"]["person"] + user = self.get_right_tweet() + t = templates.render_person(user, template, self.session, relative_times=True, offset_seconds=self.session.db["utc_offset"]) + return t def delete_item(self): pass From 2de9f8f9b34bbf4d91be04e3d0faeb424abd3666 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 20 Dec 2021 16:03:21 -0600 Subject: [PATCH 57/83] added all variables available for template objects --- src/sessions/twitter/templates.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index 3dcaddfa..8d6929d0 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -5,6 +5,13 @@ import languageHandler from string import Template from . import utils +# Define variables that would be available for all template objects. +# This will be used for the edit template dialog. +# Available variables for tweet objects. +tweet_variables = ["date", "display_name", "screen_name", "source", "lang", "text", "image_descriptions"] +dm_variables = ["date", "sender_display_name", "sender_screen_name", "recipient_display_name", "recipient_display_name", "text"] +person_variables = ["display_name", "screen_name", "location", "description", "followers", "following", "listed", "likes", "tweets", "created_at"] + def process_date(field, relative_times=True, offset_seconds=0): original_date = arrow.get(field, locale="en") if relative_times == True: From 4434a5b971d0915f4ddf9496759ab664566593ca Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 09:20:59 -0600 Subject: [PATCH 58/83] Added dialog for editing templates --- src/wxUI/dialogs/twitterDialogs/__init__.py | 3 +- .../dialogs/twitterDialogs/templateDialogs.py | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/wxUI/dialogs/twitterDialogs/templateDialogs.py diff --git a/src/wxUI/dialogs/twitterDialogs/__init__.py b/src/wxUI/dialogs/twitterDialogs/__init__.py index 6a829f06..f067ea11 100644 --- a/src/wxUI/dialogs/twitterDialogs/__init__.py +++ b/src/wxUI/dialogs/twitterDialogs/__init__.py @@ -1 +1,2 @@ -from .tweetDialogs import tweet, reply, dm, viewTweet, viewNonTweet, poll \ No newline at end of file +from .tweetDialogs import tweet, reply, dm, viewTweet, viewNonTweet, poll +from .templateDialogs import EditTemplateDialog \ No newline at end of file diff --git a/src/wxUI/dialogs/twitterDialogs/templateDialogs.py b/src/wxUI/dialogs/twitterDialogs/templateDialogs.py new file mode 100644 index 00000000..3b9d5243 --- /dev/null +++ b/src/wxUI/dialogs/twitterDialogs/templateDialogs.py @@ -0,0 +1,37 @@ +# -*- coding: UTF-8 -*- +import wx + +class EditTemplateDialog(wx.Dialog): + def __init__(self, template, variables=[], *args, **kwds): + super(EditTemplateDialog, self).__init__(parent=None, title=_("Edit Template"), *args, **kwds) + mainSizer = wx.BoxSizer(wx.VERTICAL) + sizer_1 = wx.BoxSizer(wx.HORIZONTAL) + mainSizer.Add(sizer_1, 1, wx.EXPAND, 0) + label_1 = wx.StaticText(self, wx.ID_ANY, _("Edit template")) + sizer_1.Add(label_1, 0, 0, 0) + self.template = wx.TextCtrl(self, wx.ID_ANY, template) + sizer_1.Add(self.template, 0, 0, 0) + sizer_2 = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Available variables")), wx.HORIZONTAL) + mainSizer.Add(sizer_2, 1, wx.EXPAND, 0) + self.variables = wx.ListBox(self, wx.ID_ANY, choices=["$"+v for v in variables]) + self.variables.Bind(wx.EVT_CHAR_HOOK, self.on_keypress) + sizer_2.Add(self.variables, 0, 0, 0) + sizer_3 = wx.StdDialogButtonSizer() + mainSizer.Add(sizer_3, 0, wx.ALIGN_RIGHT | wx.ALL, 4) + self.button_SAVE = wx.Button(self, wx.ID_SAVE) + self.button_SAVE.SetDefault() + sizer_3.AddButton(self.button_SAVE) + self.button_CANCEL = wx.Button(self, wx.ID_CANCEL) + sizer_3.AddButton(self.button_CANCEL) + sizer_3.Realize() + self.SetSizer(mainSizer) + mainSizer.Fit(self) + self.SetAffirmativeId(self.button_SAVE.GetId()) + self.SetEscapeId(self.button_CANCEL.GetId()) + self.Layout() + + def on_keypress(self, event, *args, **kwargs): + if event.GetKeyCode() == wx.WXK_RETURN: + self.template.ChangeValue(self.template.GetValue()+self.variables.GetStringSelection()+", ") + return + event.Skip() \ No newline at end of file From 95063cd472918be083bfbb8be4ff829c33b4f929 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 12:10:15 -0600 Subject: [PATCH 59/83] Added restore button for template edit dialog --- .../dialogs/twitterDialogs/templateDialogs.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/wxUI/dialogs/twitterDialogs/templateDialogs.py b/src/wxUI/dialogs/twitterDialogs/templateDialogs.py index 3b9d5243..9efa96aa 100644 --- a/src/wxUI/dialogs/twitterDialogs/templateDialogs.py +++ b/src/wxUI/dialogs/twitterDialogs/templateDialogs.py @@ -1,9 +1,12 @@ # -*- coding: UTF-8 -*- import wx +import output +from typing import List class EditTemplateDialog(wx.Dialog): - def __init__(self, template, variables=[], *args, **kwds): + def __init__(self, template: str, variables: List[str] = [], default_template: str = "", *args, **kwds) -> None: super(EditTemplateDialog, self).__init__(parent=None, title=_("Edit Template"), *args, **kwds) + self.default_template = default_template mainSizer = wx.BoxSizer(wx.VERTICAL) sizer_1 = wx.BoxSizer(wx.HORIZONTAL) mainSizer.Add(sizer_1, 1, wx.EXPAND, 0) @@ -23,6 +26,9 @@ class EditTemplateDialog(wx.Dialog): sizer_3.AddButton(self.button_SAVE) self.button_CANCEL = wx.Button(self, wx.ID_CANCEL) sizer_3.AddButton(self.button_CANCEL) + self.button_RESTORE = wx.Button(self, wx.ID_ANY, _("Restore template")) + self.button_RESTORE.Bind(wx.EVT_BUTTON, self.on_restore) + sizer_3.AddButton(self.button_CANCEL) sizer_3.Realize() self.SetSizer(mainSizer) mainSizer.Fit(self) @@ -33,5 +39,14 @@ class EditTemplateDialog(wx.Dialog): def on_keypress(self, event, *args, **kwargs): if event.GetKeyCode() == wx.WXK_RETURN: self.template.ChangeValue(self.template.GetValue()+self.variables.GetStringSelection()+", ") + output.speak(self.template.GetValue()+self.variables.GetStringSelection()+", ") return - event.Skip() \ No newline at end of file + event.Skip() + + def on_restore(self, *args, **kwargs) -> None: + self.template.ChangeValue(self.default_template) + output.speak(_("Restored template to {}.").format(self.default_template)) + self.template.SetFocus() + +def invalid_template() -> None: + wx.MessageDialog(None, _("the template you have specified include variables that do not exists for the object. Please fix the template and try again. For your reference, you can see a list of all available variables in the variables list while editing your template."), _("Invalid template"), wx.ICON_ERROR).ShowModal() \ No newline at end of file From b2f9aef7f79ebe8733599485493f36c310852a32 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 12:11:12 -0600 Subject: [PATCH 60/83] Added edit template controller --- src/controller/editTemplateController.py | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/controller/editTemplateController.py diff --git a/src/controller/editTemplateController.py b/src/controller/editTemplateController.py new file mode 100644 index 00000000..9d85bbda --- /dev/null +++ b/src/controller/editTemplateController.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +import re +import wx +from typing import List +from sessions.twitter.templates import tweet_variables, dm_variables, person_variables +from wxUI.dialogs.twitterDialogs import templateDialogs + +class editTemplateController(object): + def __init__(self, template: str, type: str) -> None: + super(editTemplateController, self).__init__() + self.default_template = template + if type == "tweet": + self.variables = tweet_variables + elif type == "dm": + self.variables = dm_variables + else: + self.variables = person_variables + self.template: str = template + + def validate_template(self, template: str) -> bool: + used_variables: List[str] = re.findall("\$\w+", template) + validated: bool = True + for var in used_variables: + if var[1:] not in self.variables: + validated = False + return validated + + def run_dialog(self) -> str: + dialog = templateDialogs.EditTemplateDialog(template=self.template, variables=self.variables, default_template=self.default_template) + response = dialog.ShowModal() + if response == wx.ID_SAVE: + validated: bool = self.validate_template(dialog.template.GetValue()) + if validated == False: + templateDialogs.invalid_template() + self.template = dialog.template.GetValue() + return self.run_dialog() + else: + return dialog.template.GetValue() + else: + return "" \ No newline at end of file From b4526c12c9cfd7f3466e090bb21207b4ebda4f25 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 13:21:58 -0600 Subject: [PATCH 61/83] Integrate template edition into account settings dialog --- src/controller/editTemplateController.py | 4 +- src/controller/settings.py | 60 +++++++++++++++++++++--- src/wxUI/dialogs/configuration.py | 18 +++++++ 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/controller/editTemplateController.py b/src/controller/editTemplateController.py index 9d85bbda..7251153c 100644 --- a/src/controller/editTemplateController.py +++ b/src/controller/editTemplateController.py @@ -5,9 +5,9 @@ from typing import List from sessions.twitter.templates import tweet_variables, dm_variables, person_variables from wxUI.dialogs.twitterDialogs import templateDialogs -class editTemplateController(object): +class EditTemplate(object): def __init__(self, template: str, type: str) -> None: - super(editTemplateController, self).__init__() + super(EditTemplate, self).__init__() self.default_template = template if type == "tweet": self.variables = tweet_variables diff --git a/src/controller/settings.py b/src/controller/settings.py index 84040d2e..d203adc3 100644 --- a/src/controller/settings.py +++ b/src/controller/settings.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import os import webbrowser +import logging import sound_lib import paths import widgetUtils @@ -8,17 +9,18 @@ import config import languageHandler import output import application +import config_utils +import keys +from collections import OrderedDict +from pubsub import pub +from mysc import autostart as autostart_windows from wxUI.dialogs import configuration from wxUI import commonMessageDialogs from extra.autocompletionUsers import settings from extra.ocr import OCRSpace -from pubsub import pub -import logging -import config_utils +from .editTemplateController import EditTemplate + log = logging.getLogger("Settings") -import keys -from collections import OrderedDict -from mysc import autostart as autostart_windows class globalSettingsController(object): def __init__(self): @@ -152,6 +154,15 @@ class accountSettingsController(globalSettingsController): self.dialog.create_reporting() self.dialog.set_value("reporting", "speech_reporting", self.config["reporting"]["speech_reporting"]) self.dialog.set_value("reporting", "braille_reporting", self.config["reporting"]["braille_reporting"]) + tweet_template = self.config["templates"]["tweet"] + dm_template = self.config["templates"]["dm"] + sent_dm_template = self.config["templates"]["dm_sent"] + person_template = self.config["templates"]["person"] + self.dialog.create_templates(tweet_template=tweet_template, dm_template=dm_template, sent_dm_template=sent_dm_template, person_template=person_template) + widgetUtils.connect_event(self.dialog.templates.tweet, widgetUtils.BUTTON_PRESSED, self.edit_tweet_template) + widgetUtils.connect_event(self.dialog.templates.dm, widgetUtils.BUTTON_PRESSED, self.edit_dm_template) + widgetUtils.connect_event(self.dialog.templates.sent_dm, widgetUtils.BUTTON_PRESSED, self.edit_sent_dm_template) + widgetUtils.connect_event(self.dialog.templates.person, widgetUtils.BUTTON_PRESSED, self.edit_person_template) self.dialog.create_other_buffers() buffer_values = self.get_buffers_list() self.dialog.buffers.insert_buffers(buffer_values) @@ -160,7 +171,6 @@ class accountSettingsController(globalSettingsController): widgetUtils.connect_event(self.dialog.buffers.up, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_up) widgetUtils.connect_event(self.dialog.buffers.down, widgetUtils.BUTTON_PRESSED, self.dialog.buffers.move_down) - self.dialog.create_ignored_clients(self.config["twitter"]["ignored_clients"]) widgetUtils.connect_event(self.dialog.ignored_clients.add, widgetUtils.BUTTON_PRESSED, self.add_ignored_client) widgetUtils.connect_event(self.dialog.ignored_clients.remove, widgetUtils.BUTTON_PRESSED, self.remove_ignored_client) @@ -185,6 +195,42 @@ class accountSettingsController(globalSettingsController): self.dialog.set_title(_(u"Account settings for %s") % (self.user,)) self.response = self.dialog.get_response() + def edit_tweet_template(self, *args, **kwargs): + template = self.config["templates"]["tweet"] + control = EditTemplate(template=template, type="tweet") + result = control.run_dialog() + if result != "": # Template has been saved. + self.config["templates"]["tweet"] = result + self.config.write() + self.dialog.templates.tweet.SetLabel(_("Edit template for tweets. Current template: {}").format(result)) + + def edit_dm_template(self, *args, **kwargs): + template = self.config["templates"]["dm"] + control = EditTemplate(template=template, type="dm") + result = control.run_dialog() + if result != "": # Template has been saved. + self.config["templates"]["dm"] = result + self.config.write() + self.dialog.templates.dm.SetLabel(_("Edit template for direct messages. Current template: {}").format(result)) + + def edit_sent_dm_template(self, *args, **kwargs): + template = self.config["templates"]["dm_sent"] + control = EditTemplate(template=template, type="dm") + result = control.run_dialog() + if result != "": # Template has been saved. + self.config["templates"]["dm_sent"] = result + self.config.write() + self.dialog.templates.sent_dm.SetLabel(_("Edit template for sent direct messages. Current template: {}").format(result)) + + def edit_person_template(self, *args, **kwargs): + template = self.settings["templates"]["person"] + control = EditTemplate(template=template, type="person") + result = control.run_dialog() + if result != "": # Template has been saved. + self.config["templates"]["person"] = result + self.config.write() + self.dialog.templates.person.SetLabel(_("Edit template for persons. Current template: {}").format(result)) + def save_configuration(self): if self.config["general"]["relative_times"] != self.dialog.get_value("general", "relative_time"): self.needs_restart = True diff --git a/src/wxUI/dialogs/configuration.py b/src/wxUI/dialogs/configuration.py index 1bc5de9c..e8220ae9 100644 --- a/src/wxUI/dialogs/configuration.py +++ b/src/wxUI/dialogs/configuration.py @@ -233,6 +233,20 @@ class other_buffers(wx.Panel): buffers_list.append(self.buffers.get_text_column(i, 0)) return buffers_list +class templates(wx.Panel, baseDialog.BaseWXDialog): + def __init__(self, parent, tweet_template, dm_template, sent_dm_template, person_template): + super(templates, self).__init__(parent) + sizer = wx.BoxSizer(wx.VERTICAL) + self.tweet = wx.Button(self, wx.ID_ANY, _("Edit template for tweets. Current template: {}").format(tweet_template)) + sizer.Add(self.tweet, 0, wx.ALL, 5) + self.dm = wx.Button(self, wx.ID_ANY, _("Edit template for direct messages. Current template: {}").format(dm_template)) + sizer.Add(self.dm, 0, wx.ALL, 5) + self.sent_dm = wx.Button(self, wx.ID_ANY, _("Edit template for sent direct messages. Current template: {}").format(sent_dm_template)) + sizer.Add(self.sent_dm, 0, wx.ALL, 5) + self.person = wx.Button(self, wx.ID_ANY, _("Edit template for persons. Current template: {}").format(person_template)) + sizer.Add(self.person, 0, wx.ALL, 5) + self.SetSizer(sizer) + class ignoredClients(wx.Panel): def __init__(self, parent, choices): super(ignoredClients, self).__init__(parent=parent) @@ -380,6 +394,10 @@ class configurationDialog(baseDialog.BaseWXDialog): self.ignored_clients = ignoredClients(self.notebook, ignored_clients_list) self.notebook.AddPage(self.ignored_clients, _(u"Ignored clients")) + def create_templates(self, tweet_template, dm_template, sent_dm_template, person_template): + self.templates = templates(self.notebook, tweet_template=tweet_template, dm_template=dm_template, sent_dm_template=sent_dm_template, person_template=person_template) + self.notebook.AddPage(self.templates, _("Templates")) + def create_sound(self, output_devices, input_devices, soundpacks): self.sound = sound(self.notebook, output_devices, input_devices, soundpacks) self.notebook.AddPage(self.sound, _(u"Sound")) From 81963dbb53ddc418f980e09aab17734123340120 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 13:55:48 -0600 Subject: [PATCH 62/83] Updated sent direct messages template --- src/Conf.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Conf.defaults b/src/Conf.defaults index 2264e8a9..e25c5002 100644 --- a/src/Conf.defaults +++ b/src/Conf.defaults @@ -51,7 +51,7 @@ speech_reporting = boolean(default=True) [templates] tweet = string(default="$display_name, $text $image_descriptions $date. $source") dm = string(default="$sender_display_name, $text $date") -dm_sent = string(default=">$recipient_display_name, $text $date") +dm_sent = string(default="Dm to $recipient_display_name, $text $date") person = string(default="$display_name (@$screen_name). $followers followers, $following following, $tweets tweets. Joined Twitter $created_at.") [filters] From 445c33f003020ab78ac6249db7cf055d5abb8654 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 13:56:29 -0600 Subject: [PATCH 63/83] Add default templates to translation catalog --- src/sessions/twitter/templates.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index 8d6929d0..7c20d608 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -12,6 +12,12 @@ tweet_variables = ["date", "display_name", "screen_name", "source", "lang", "tex dm_variables = ["date", "sender_display_name", "sender_screen_name", "recipient_display_name", "recipient_display_name", "text"] person_variables = ["display_name", "screen_name", "location", "description", "followers", "following", "listed", "likes", "tweets", "created_at"] +# Default, translatable templates. +tweet_default_template = _("$display_name, $text $image_descriptions $date. $source") +dm_default_template = _("$sender_display_name, $text $date") +dm_sent_default_template = _("Dm to $recipient_display_name, $text $date") +person_default_template = _("$display_name (@$screen_name). $followers followers, $following following, $tweets tweets. Joined Twitter $created_at.") + def process_date(field, relative_times=True, offset_seconds=0): original_date = arrow.get(field, locale="en") if relative_times == True: @@ -82,7 +88,7 @@ def render_tweet(tweet, template, session, relative_times=False, offset_seconds= image_descriptions = process_image_descriptions(tweet.extended_entities) if image_descriptions != "": available_data.update(image_descriptions=image_descriptions) - result = Template(template).safe_substitute(**available_data) + result = Template(_(template)).safe_substitute(**available_data) result = re.sub(r"\$\w+", "", result) return result @@ -109,7 +115,7 @@ def render_dm(dm, template, session, relative_times=False, offset_seconds=0): sender = session.get_user(dm.message_create["sender_id"]) recipient = session.get_user(dm.message_create["target"]["recipient_id"]) available_data.update(sender_display_name=sender.name, sender_screen_name=sender.screen_name, recipient_display_name=recipient.name, recipient_screen_name=recipient.screen_name) - result = Template(template).safe_substitute(**available_data) + result = Template(_(template)).safe_substitute(**available_data) result = re.sub(r"\$\w+", "", result) return result @@ -136,6 +142,6 @@ def render_person(user, template, session=None, relative_times=True, offset_seco available_data[nullable] = getattr(user, nullable) created_at = process_date(user.created_at, relative_times=relative_times, offset_seconds=offset_seconds) available_data.update(created_at=created_at) - result = Template(template).safe_substitute(**available_data) + result = Template(_(template)).safe_substitute(**available_data) result = re.sub(r"\$\w+", "", result) return result \ No newline at end of file From a74825a0f614d9c58e9b08cdff0ddeffb08f87ef Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 13:57:32 -0600 Subject: [PATCH 64/83] Add missing string to translation catalogs --- src/sessions/twitter/templates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index 7c20d608..156a2d67 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -47,7 +47,7 @@ def process_image_descriptions(entities): image_descriptions.append(media.get("ext_alt_text")) idescriptions = "" for image in image_descriptions: - idescriptions += "Image description: {}.".format(image) + idescriptions += _("Image description: {}.").format(image) return idescriptions def render_tweet(tweet, template, session, relative_times=False, offset_seconds=0): From b6ae9f4b79ce6473c2ad528e64487730053a9ef9 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 15:10:12 -0600 Subject: [PATCH 65/83] Updated changelog --- doc/changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/changelog.md b/doc/changelog.md index 13d35a74..d8b47484 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -2,6 +2,10 @@ TWBlue Changelog ## changes in this version +* We have added Experimental support for templates in the invisible interface. The GUI will remain unchanged for now: + * Each object (tweet, received direct message, sent direct message and people) has its own template in the settings. You can edit those templates from the account settings dialog, in the new "templates" tab. + * Every template is composed of the group of variables you want to display for each object. Each variable will start with a dollar sign ($) and cannot contain spaces or special characters. Templates can include arbitrary text that will not be processed. When editing the example templates, you can get an idea of the variables that are available for each object by using the template editing dialog. When you press enter on a variable from the list of available variables, it will be added to the template automatically. When you try to save a template, TWBlue will warn you if the template is incorrectly formatted or if it includes variables that do not exist in the information provided by objects. It is also possible to return to default values from the same dialog when editing a template. + * TWBlue can display image descriptions within Tweet templates. For that, you can use the $image_description variable in your template. * We have restored conversation and threads support powered by Twitter API V2 thanks to a set of improvements we have done in the application, as well as more generous limits to Tweet monthly cap by Twitter. * Fixed issue when uploading attachments (images, videos or gif files) while sending tweets or replies. From 911e8d3cfd272a91d860a93a703256875791cb79 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 21 Dec 2021 15:35:35 -0600 Subject: [PATCH 66/83] Fixed TWBlue asking for a restart due to old reference to the events buffer in settings. Fixes #413 --- doc/changelog.md | 1 + src/Conf.defaults | 2 +- src/controller/settings.py | 27 +++++++++------------------ 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index 13d35a74..e14e3d49 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -4,6 +4,7 @@ TWBlue Changelog * We have restored conversation and threads support powered by Twitter API V2 thanks to a set of improvements we have done in the application, as well as more generous limits to Tweet monthly cap by Twitter. * Fixed issue when uploading attachments (images, videos or gif files) while sending tweets or replies. +* Fixed an error that was making TWBlue to ask for a restart after saving account settings, even if such restart was not required. ([#413,](https://github.com/manuelcortez/TWBlue/issues/413)) ## Changes in version 2021.11.12 diff --git a/src/Conf.defaults b/src/Conf.defaults index a2b3760a..63c72e97 100644 --- a/src/Conf.defaults +++ b/src/Conf.defaults @@ -14,7 +14,7 @@ retweet_mode = string(default="ask") persist_size = integer(default=0) load_cache_in_memory=boolean(default=True) show_screen_names = boolean(default=False) -buffer_order = list(default=list('home','mentions', 'dm', 'sent_dm', 'sent_tweets','favorites','followers','friends','blocks','muted','events')) +buffer_order = list(default=list('home','mentions', 'dm', 'sent_dm', 'sent_tweets','favorites','followers','friends','blocks','muted')) [sound] volume = float(default=1.0) diff --git a/src/controller/settings.py b/src/controller/settings.py index 84040d2e..ded9552f 100644 --- a/src/controller/settings.py +++ b/src/controller/settings.py @@ -90,10 +90,12 @@ class globalSettingsController(object): config.app["app-settings"]["language"] = self.codes[self.dialog.general.language.GetSelection()] languageHandler.setLanguage(config.app["app-settings"]["language"]) self.needs_restart = True + log.debug("Triggered app restart due to interface language changes.") if self.kmnames[self.dialog.general.km.GetSelection()] != config.app["app-settings"]["load_keymap"]: config.app["app-settings"]["load_keymap"] =self.kmnames[self.dialog.general.km.GetSelection()] kmFile = open(os.path.join(paths.config_path(), "keymap.keymap"), "w") kmFile.close() + log.debug("Triggered app restart due to a keymap change.") self.needs_restart = True if config.app["app-settings"]["autostart"] != self.dialog.get_value("general", "autostart") and paths.mode == "installed": config.app["app-settings"]["autostart"] = self.dialog.get_value("general", "autostart") @@ -104,9 +106,11 @@ class globalSettingsController(object): if config.app["app-settings"]["no_streaming"] != self.dialog.get_value("general", "no_streaming"): config.app["app-settings"]["no_streaming"] = self.dialog.get_value("general", "no_streaming") self.needs_restart = True + log.debug("Triggered app restart due to change in streaming availability.") if config.app["app-settings"]["update_period"] != self.dialog.get_value("general", "update_period"): config.app["app-settings"]["update_period"] = self.dialog.get_value("general", "update_period") self.needs_restart = True + log.debug("Triggered app restart due to changes in update period.") config.app["app-settings"]["voice_enabled"] = self.dialog.get_value("general", "disable_sapi5") config.app["app-settings"]["hide_gui"] = self.dialog.get_value("general", "hide_gui") config.app["app-settings"]["ask_at_exit"] = self.dialog.get_value("general", "ask_at_exit") @@ -118,6 +122,7 @@ class globalSettingsController(object): if config.app["proxy"]["type"]!=self.dialog.get_value("proxy", "type") or config.app["proxy"]["server"] != self.dialog.get_value("proxy", "server") or config.app["proxy"]["port"] != self.dialog.get_value("proxy", "port") or config.app["proxy"]["user"] != self.dialog.get_value("proxy", "user") or config.app["proxy"]["password"] != self.dialog.get_value("proxy", "password"): if self.is_started == True: self.needs_restart = True + log.debug("Triggered app restart due to change in proxy settings.") config.app["proxy"]["type"] = self.dialog.proxy.type.Selection config.app["proxy"]["server"] = self.dialog.get_value("proxy", "server") config.app["proxy"]["port"] = self.dialog.get_value("proxy", "port") @@ -188,12 +193,14 @@ class accountSettingsController(globalSettingsController): def save_configuration(self): if self.config["general"]["relative_times"] != self.dialog.get_value("general", "relative_time"): self.needs_restart = True + log.debug("Triggered app restart due to change in relative times.") self.config["general"]["relative_times"] = self.dialog.get_value("general", "relative_time") self.config["general"]["show_screen_names"] = self.dialog.get_value("general", "show_screen_names") self.config["general"]["max_tweets_per_call"] = self.dialog.get_value("general", "itemsPerApiCall") if self.config["general"]["load_cache_in_memory"] != self.dialog.get_value("general", "load_cache_in_memory"): self.config["general"]["load_cache_in_memory"] = self.dialog.get_value("general", "load_cache_in_memory") self.needs_restart = True + log.debug("Triggered app restart due to change in database strategy management.") if self.config["general"]["persist_size"] != self.dialog.get_value("general", "persist_size"): if self.dialog.get_value("general", "persist_size") == '': self.config["general"]["persist_size"] =-1 @@ -206,6 +213,7 @@ class accountSettingsController(globalSettingsController): if self.config["general"]["reverse_timelines"] != self.dialog.get_value("general", "reverse_timelines"): self.needs_restart = True + log.debug("Triggered app restart due to change in timeline order.") self.config["general"]["reverse_timelines"] = self.dialog.get_value("general", "reverse_timelines") rt = self.dialog.get_value("general", "retweet_mode") if rt == _(u"Ask"): @@ -217,28 +225,11 @@ class accountSettingsController(globalSettingsController): buffers_list = self.dialog.buffers.get_list() if buffers_list != self.config["general"]["buffer_order"]: self.needs_restart = True + log.debug("Triggered app restart due to change in buffer ordering.") self.config["general"]["buffer_order"] = buffers_list self.config["reporting"]["speech_reporting"] = self.dialog.get_value("reporting", "speech_reporting") self.config["reporting"]["braille_reporting"] = self.dialog.get_value("reporting", "braille_reporting") self.config["mysc"]["ocr_language"] = OCRSpace.OcrLangs[self.dialog.extras.ocr_lang.GetSelection()] -# if self.config["other_buffers"]["show_followers"] != self.dialog.get_value("buffers", "followers"): -# self.config["other_buffers"]["show_followers"] = self.dialog.get_value("buffers", "followers") -# pub.sendMessage("create-new-buffer", buffer="followers", account=self.user, create=self.config["other_buffers"]["show_followers"]) -# if self.config["other_buffers"]["show_friends"] != self.dialog.get_value("buffers", "friends"): -# self.config["other_buffers"]["show_friends"] = self.dialog.get_value("buffers", "friends") -# pub.sendMessage("create-new-buffer", buffer="friends", account=self.user, create=self.config["other_buffers"]["show_friends"]) -# if self.config["other_buffers"]["show_favourites"] != self.dialog.get_value("buffers", "favs"): -# self.config["other_buffers"]["show_favourites"] = self.dialog.get_value("buffers", "favs") -# pub.sendMessage("create-new-buffer", buffer="favourites", account=self.user, create=self.config["other_buffers"]["show_favourites"]) -# if self.config["other_buffers"]["show_blocks"] != self.dialog.get_value("buffers", "blocks"): -# self.config["other_buffers"]["show_blocks"] = self.dialog.get_value("buffers", "blocks") -# pub.sendMessage("create-new-buffer", buffer="blocked", account=self.user, create=self.config["other_buffers"]["show_blocks"]) -# if self.config["other_buffers"]["show_muted_users"] != self.dialog.get_value("buffers", "mutes"): -# self.config["other_buffers"]["show_muted_users"] = self.dialog.get_value("buffers", "mutes") -# pub.sendMessage("create-new-buffer", buffer="muted", account=self.user, create=self.config["other_buffers"]["show_muted_users"]) -# if self.config["other_buffers"]["show_events"] != self.dialog.get_value("buffers", "events"): -# self.config["other_buffers"]["show_events"] = self.dialog.get_value("buffers", "events") -# pub.sendMessage("create-new-buffer", buffer="events", account=self.user, create=self.config["other_buffers"]["show_events"]) if self.config["sound"]["input_device"] != self.dialog.sound.get("input"): self.config["sound"]["input_device"] = self.dialog.sound.get("input") try: From c8da3bdfdb8895c73e843352b77da2d4df268e3c Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 22 Dec 2021 08:22:36 -0600 Subject: [PATCH 67/83] Fixed indentation error --- src/wxUI/commonMessageDialogs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wxUI/commonMessageDialogs.py b/src/wxUI/commonMessageDialogs.py index 1f4a77e6..949589ec 100644 --- a/src/wxUI/commonMessageDialogs.py +++ b/src/wxUI/commonMessageDialogs.py @@ -91,7 +91,7 @@ def existing_filter(): def common_error(reason): return wx.MessageDialog(None, reason, _(u"Error"), wx.OK).ShowModal() - def invalid_configuration(): +def invalid_configuration(): return wx.MessageDialog(None, _("The configuration file is invalid."), _("Error"), wx.ICON_ERROR).ShowModal() def dead_pid(): From b23915e5464d88567a3ab36119581023f981d78f Mon Sep 17 00:00:00 2001 From: Oreonan Date: Wed, 22 Dec 2021 18:30:46 +0100 Subject: [PATCH 68/83] Update french interface --- src/locales/fr/LC_MESSAGES/twblue.po | 398 ++++++++++++++++----------- 1 file changed, 242 insertions(+), 156 deletions(-) diff --git a/src/locales/fr/LC_MESSAGES/twblue.po b/src/locales/fr/LC_MESSAGES/twblue.po index f9587d45..e283345d 100644 --- a/src/locales/fr/LC_MESSAGES/twblue.po +++ b/src/locales/fr/LC_MESSAGES/twblue.po @@ -1,18 +1,18 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.94\n" -"POT-Creation-Date: 2021-11-11 01:00+0100\n" -"PO-Revision-Date: 2021-11-12 13:32-0600\n" +"POT-Creation-Date: 2021-12-22 18:18+0100\n" +"PO-Revision-Date: 2021-12-22 18:30+0100\n" "Last-Translator: Oreonan \n" "Language-Team: Oreonan \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.0.1\n" "X-Poedit-KeywordsList: _;gettext;gettext_noop\n" "X-Poedit-Basepath: .\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-Bookmarks: -1,-1,-1,-1,-1,384,-1,-1,-1,-1\n" @@ -21,12 +21,12 @@ msgid "This action is not supported for this buffer" msgstr "Cette action n'est pas supportée pour ce tampon" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:337 ../src\controller\settings.py:286 +#: ../src\controller\mainController.py:337 ../src\controller\settings.py:323 msgid "Home" msgstr "Accueil" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:339 ../src\controller\settings.py:287 +#: ../src\controller\mainController.py:339 ../src\controller\settings.py:324 msgid "Mentions" msgstr "Mentions" @@ -36,41 +36,41 @@ msgid "Direct messages" msgstr "Messages" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:343 ../src\controller\settings.py:289 +#: ../src\controller\mainController.py:343 ../src\controller\settings.py:326 msgid "Sent direct messages" msgstr "Messages envoyés" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:345 ../src\controller\settings.py:290 +#: ../src\controller\mainController.py:345 ../src\controller\settings.py:327 msgid "Sent tweets" msgstr "Tweets envoyés" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:347 -#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:291 +#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:328 msgid "Likes" msgstr "Favoris" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:292 +#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:329 msgid "Followers" msgstr "Abonnés" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:353 -#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:294 +#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:331 msgid "Blocked users" msgstr "Utilisateurs bloqués" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:355 -#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:295 +#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:332 msgid "Muted users" msgstr "Utilisateurs masqués" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:293 +#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:330 msgid "Friends" msgstr "Abonnements" @@ -99,7 +99,7 @@ msgstr "Tampon inconnu" #: ../src\controller\buffers\twitter\trends.py:134 #: ../src\controller\messages.py:296 ../src\wxUI\buffers\base.py:25 #: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:312 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:309 #: ../src\wxUI\sysTrayIcon.py:35 msgid "Tweet" msgstr "Tweet" @@ -110,75 +110,75 @@ msgstr "Tweet" msgid "Write the tweet here" msgstr "Écrivez le tweet ici" -#: ../src\controller\buffers\twitter\base.py:192 +#: ../src\controller\buffers\twitter\base.py:194 msgid "New tweet in {0}" msgstr "Nouveau tweet dans {0}" -#: ../src\controller\buffers\twitter\base.py:195 +#: ../src\controller\buffers\twitter\base.py:197 msgid "{0} new tweets in {1}." msgstr "{0} nouveau tweet dans {1}" -#: ../src\controller\buffers\twitter\base.py:234 +#: ../src\controller\buffers\twitter\base.py:236 #: ../src\controller\buffers\twitter\directMessages.py:88 -#: ../src\controller\buffers\twitter\people.py:174 +#: ../src\controller\buffers\twitter\people.py:177 msgid "%s items retrieved" msgstr "%s éléments récupérés" -#: ../src\controller\buffers\twitter\base.py:266 +#: ../src\controller\buffers\twitter\base.py:268 #: ../src\controller\buffers\twitter\people.py:80 msgid "This buffer is not a timeline; it can't be deleted." msgstr "Ce tampon n'est pas une chronologie ; Impossible de le supprimé." -#: ../src\controller\buffers\twitter\base.py:402 +#: ../src\controller\buffers\twitter\base.py:404 msgid "Reply to {arg0}" msgstr "Répondre à {arg0}" -#: ../src\controller\buffers\twitter\base.py:404 +#: ../src\controller\buffers\twitter\base.py:406 #: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "Répondre" -#: ../src\controller\buffers\twitter\base.py:405 +#: ../src\controller\buffers\twitter\base.py:407 msgid "Reply to %s" msgstr "Répondre à %s" -#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\base.py:430 #: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "Nouveau message" -#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\base.py:430 #: ../src\controller\messages.py:268 msgid "Direct message to %s" msgstr "Message à %s" -#: ../src\controller\buffers\twitter\base.py:459 +#: ../src\controller\buffers\twitter\base.py:461 msgid "Add your comment to the tweet" msgstr "Ajoutez votre commentaire pour le tweet" -#: ../src\controller\buffers\twitter\base.py:459 +#: ../src\controller\buffers\twitter\base.py:461 msgid "Quote" msgstr "Citer" -#: ../src\controller\buffers\twitter\base.py:520 +#: ../src\controller\buffers\twitter\base.py:522 msgid "Opening URL..." msgstr "Ouverture de l'URL..." -#: ../src\controller\buffers\twitter\base.py:557 +#: ../src\controller\buffers\twitter\base.py:559 msgid "User details" msgstr "Détails de l'utilisateur" -#: ../src\controller\buffers\twitter\base.py:578 +#: ../src\controller\buffers\twitter\base.py:580 msgid "Opening item in web browser..." msgstr "Ouverture de l'élément dans le navigateur Web..." #: ../src\controller\buffers\twitter\directMessages.py:93 -#: ../src\controller\buffers\twitter\people.py:95 +#: ../src\controller\buffers\twitter\people.py:98 msgid "Mention to %s" msgstr "Mention pour %s" #: ../src\controller\buffers\twitter\directMessages.py:93 -#: ../src\controller\buffers\twitter\people.py:95 +#: ../src\controller\buffers\twitter\people.py:98 #: ../src\wxUI\buffers\people.py:17 msgid "Mention" msgstr "Mention" @@ -191,7 +191,7 @@ msgstr "{0} nouveau message" msgid "This action is not supported in the buffer yet." msgstr "Cette action n'est pas supportée dans le tampon actuel" -#: ../src\controller\buffers\twitter\directMessages.py:140 +#: ../src\controller\buffers\twitter\directMessages.py:146 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." @@ -199,7 +199,7 @@ msgstr "" "Récupérer plus d'élément est impossible dans ce tampon, utilisez le tampon " "des messages à la place." -#: ../src\controller\buffers\twitter\people.py:247 +#: ../src\controller\buffers\twitter\people.py:250 msgid "{0} new followers." msgstr "{0} nouvel abonné" @@ -458,49 +458,65 @@ msgstr "Voir l'élément" msgid "Link copied to clipboard." msgstr "Lien copié dans le Presse-papiers" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "HTTP" msgstr "HTTP" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "SOCKS v4" msgstr "SOCKS v4" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "SOCKS v4 with DNS support" msgstr "SOCKS v4 avec support DNS" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "SOCKS v5" msgstr "SOCKS v5" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "SOCKS v5 with DNS support" msgstr "SOCKS v5 avec support DNS" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "System default" msgstr "Système par défaut" -#: ../src\controller\settings.py:145 ../src\controller\settings.py:211 +#: ../src\controller\settings.py:152 ../src\controller\settings.py:265 #: ../src\wxUI\dialogs\configuration.py:116 msgid "Ask" msgstr "Demander" -#: ../src\controller\settings.py:147 ../src\controller\settings.py:213 +#: ../src\controller\settings.py:154 ../src\controller\settings.py:267 #: ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet without comments" msgstr "Retweet sans commentaires" -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:116 +#: ../src\controller\settings.py:156 ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet with comments" msgstr "Retweet avec commentaires" -#: ../src\controller\settings.py:185 +#: ../src\controller\settings.py:200 msgid "Account settings for %s" msgstr "Paramètres du compte de %s" -#: ../src\controller\settings.py:288 +#: ../src\controller\settings.py:210 ../src\wxUI\dialogs\configuration.py:240 +msgid "Edit template for tweets. Current template: {}" +msgstr "Éditer le modèle des tweets. Modèle actuel : {}" + +#: ../src\controller\settings.py:219 ../src\wxUI\dialogs\configuration.py:242 +msgid "Edit template for direct messages. Current template: {}" +msgstr "Éditer le modèle pour les messages. Modèle actuel : {}" + +#: ../src\controller\settings.py:228 ../src\wxUI\dialogs\configuration.py:244 +msgid "Edit template for sent direct messages. Current template: {}" +msgstr "Éditer le modèle des messages envoyés. Modèle actuel : {}" + +#: ../src\controller\settings.py:237 ../src\wxUI\dialogs\configuration.py:246 +msgid "Edit template for persons. Current template: {}" +msgstr "Éditer le modèles pour les personnes. Modèle actuel : {}" + +#: ../src\controller\settings.py:325 msgid "Direct Messages" msgstr "Messages" @@ -517,6 +533,7 @@ msgstr "Messages" #: ../src\wxUI\commonMessageDialogs.py:83 #: ../src\wxUI\commonMessageDialogs.py:89 #: ../src\wxUI\commonMessageDialogs.py:92 +#: ../src\wxUI\commonMessageDialogs.py:95 msgid "Error" msgstr "Erreur" @@ -697,9 +714,9 @@ msgid "%s seconds" msgstr "%s secondes" #: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:258 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:35 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:171 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 msgid "File" msgstr "Fichier" @@ -1373,8 +1390,8 @@ msgid "Target language" msgstr "Langue cible" #: ../src\issueReporter\issueReporter.py:32 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 +#: ../src\wxUI\dialogs\configuration.py:373 +#: ../src\wxUI\dialogs\configuration.py:382 msgid "General" msgstr "Général" @@ -1776,7 +1793,7 @@ msgstr "Indéfinir le raccourcis clavier" msgid "Execute action" msgstr "Exécuter une action" -#: ../src\keystrokeEditor\wx_ui.py:22 ../src\wxUI\dialogs\configuration.py:396 +#: ../src\keystrokeEditor\wx_ui.py:22 ../src\wxUI\dialogs\configuration.py:414 #: ../src\wxUI\dialogs\userAliasDialogs.py:25 ../src\wxUI\dialogs\utils.py:39 msgid "Close" msgstr "Fermer" @@ -1954,6 +1971,7 @@ msgstr "" #: ../src\sessions\twitter\compose.py:38 ../src\sessions\twitter\compose.py:81 #: ../src\sessions\twitter\compose.py:146 #: ../src\sessions\twitter\compose.py:155 +#: ../src\sessions\twitter\templates.py:26 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "dddd D MMMM YYYY à H:m:s" @@ -2005,19 +2023,43 @@ msgstr "%s réussi." msgid "Deleted account" msgstr "Compte supprimé" -#: ../src\sessions\twitter\utils.py:231 +#: ../src\sessions\twitter\templates.py:16 +msgid "$display_name, $text $image_descriptions $date. $source" +msgstr "$display_name, $text $image_descriptions $date. $source" + +#: ../src\sessions\twitter\templates.py:17 +msgid "$sender_display_name, $text $date" +msgstr "$sender_display_name, $text $date" + +#: ../src\sessions\twitter\templates.py:18 +msgid "Dm to $recipient_display_name, $text $date" +msgstr "MP à $recipient_display_name, $text $date" + +#: ../src\sessions\twitter\templates.py:19 +msgid "" +"$display_name (@$screen_name). $followers followers, $following following, " +"$tweets tweets. Joined Twitter $created_at." +msgstr "" +"$display_name (@$screen_name). $followers abonnés, $following abonnements, " +"$tweets tweets. À rejoint Twitter $created_at." + +#: ../src\sessions\twitter\templates.py:50 +msgid "Image description: {}." +msgstr "Description de l'image: {}." + +#: ../src\sessions\twitter\utils.py:229 msgid "Sorry, you are not authorised to see this status." msgstr "Désolé, vous n'êtes pas autorisé à voir ce Tweet." -#: ../src\sessions\twitter\utils.py:233 +#: ../src\sessions\twitter\utils.py:231 msgid "No status found with that ID" msgstr "Aucun Tweet trouvée avec cet ID" -#: ../src\sessions\twitter\utils.py:235 +#: ../src\sessions\twitter\utils.py:233 msgid "Error {0}" msgstr "Erreur {0}" -#: ../src\sessions\twitter\utils.py:262 +#: ../src\sessions\twitter\utils.py:260 msgid "{user_1}, {user_2} and {all_users} more: {text}" msgstr "{user_1}, {user_2} et {all_users} de plus : {text}" @@ -2095,7 +2137,7 @@ msgid "User" msgstr "Utilisateur" #: ../src\wxUI\buffers\base.py:12 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:47 msgid "Text" msgstr "Texte" @@ -2194,7 +2236,7 @@ msgid "Enter the name of the client : " msgstr "Entrez le nom du client: " #: ../src\wxUI\commonMessageDialogs.py:26 -#: ../src\wxUI\dialogs\configuration.py:246 +#: ../src\wxUI\dialogs\configuration.py:260 msgid "Add client" msgstr "Ajouter un client" @@ -2247,7 +2289,7 @@ msgstr "" "vous continuer ?" #: ../src\wxUI\commonMessageDialogs.py:48 -#: ../src\wxUI\commonMessageDialogs.py:95 +#: ../src\wxUI\commonMessageDialogs.py:98 msgid "Warning" msgstr "Attention" @@ -2353,6 +2395,10 @@ msgid "This filter already exists. Please use a different title" msgstr "Ce filtre existe déjà. Veuillez utiliser un titre différent" #: ../src\wxUI\commonMessageDialogs.py:95 +msgid "The configuration file is invalid." +msgstr "Le fichier de configuration est invalide." + +#: ../src\wxUI\commonMessageDialogs.py:98 msgid "" "{0} quit unexpectedly the last time it was run. If the problem persists, " "please report it to the {0} developers." @@ -2546,80 +2592,84 @@ msgstr "Le tampon est déjà en haut de la liste." msgid "The buffer is already at the bottom of the list." msgstr "Le tampon est déjà en bas de la liste." -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 +#: ../src\wxUI\dialogs\configuration.py:254 +#: ../src\wxUI\dialogs\configuration.py:395 msgid "Ignored clients" msgstr "Clients ignorés" -#: ../src\wxUI\dialogs\configuration.py:247 +#: ../src\wxUI\dialogs\configuration.py:261 msgid "Remove client" msgstr "Supprimer le client" -#: ../src\wxUI\dialogs\configuration.py:271 +#: ../src\wxUI\dialogs\configuration.py:285 msgid "Volume" msgstr "Volume" -#: ../src\wxUI\dialogs\configuration.py:282 +#: ../src\wxUI\dialogs\configuration.py:296 msgid "Session mute" msgstr "Session muet" -#: ../src\wxUI\dialogs\configuration.py:284 +#: ../src\wxUI\dialogs\configuration.py:298 msgid "Output device" msgstr "Périphérique de sortie" -#: ../src\wxUI\dialogs\configuration.py:291 +#: ../src\wxUI\dialogs\configuration.py:305 msgid "Input device" msgstr "Périphérique d'entrée" -#: ../src\wxUI\dialogs\configuration.py:299 +#: ../src\wxUI\dialogs\configuration.py:313 msgid "Sound pack" msgstr "Pack de sons" -#: ../src\wxUI\dialogs\configuration.py:305 +#: ../src\wxUI\dialogs\configuration.py:319 msgid "Indicate audio tweets with sound" msgstr "Indiquer les tweets audio avec son" -#: ../src\wxUI\dialogs\configuration.py:307 +#: ../src\wxUI\dialogs\configuration.py:321 msgid "Indicate geotweets with sound" msgstr "Indiquer les Tweet avec localisation géographique avec son" -#: ../src\wxUI\dialogs\configuration.py:309 +#: ../src\wxUI\dialogs\configuration.py:323 msgid "Indicate tweets containing images with sound" msgstr "Indiquer les tweets contenant des images avec du son" -#: ../src\wxUI\dialogs\configuration.py:332 +#: ../src\wxUI\dialogs\configuration.py:346 msgid "Language for OCR" msgstr "Langue pour l'OCR" -#: ../src\wxUI\dialogs\configuration.py:338 +#: ../src\wxUI\dialogs\configuration.py:352 msgid "API Key for SndUp" msgstr "Clé API pour SndUp" -#: ../src\wxUI\dialogs\configuration.py:353 +#: ../src\wxUI\dialogs\configuration.py:367 msgid "{0} preferences" msgstr "Préférences de {0}" -#: ../src\wxUI\dialogs\configuration.py:364 +#: ../src\wxUI\dialogs\configuration.py:378 msgid "Proxy" msgstr "Proxy" -#: ../src\wxUI\dialogs\configuration.py:373 +#: ../src\wxUI\dialogs\configuration.py:387 msgid "Feedback" msgstr "Retour" -#: ../src\wxUI\dialogs\configuration.py:377 +#: ../src\wxUI\dialogs\configuration.py:391 msgid "Buffers" msgstr "Tampons" -#: ../src\wxUI\dialogs\configuration.py:385 +#: ../src\wxUI\dialogs\configuration.py:399 +msgid "Templates" +msgstr "Modèles" + +#: ../src\wxUI\dialogs\configuration.py:403 msgid "Sound" msgstr "Audio" -#: ../src\wxUI\dialogs\configuration.py:389 +#: ../src\wxUI\dialogs\configuration.py:407 msgid "Extras" msgstr "Supplémentaires" -#: ../src\wxUI\dialogs\configuration.py:394 +#: ../src\wxUI\dialogs\configuration.py:412 msgid "Save" msgstr "Enregistrer" @@ -2748,10 +2798,10 @@ msgid "mode" msgstr "mode" #: ../src\wxUI\dialogs\lists.py:14 ../src\wxUI\dialogs\lists.py:70 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:38 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:260 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:126 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:257 msgid "Description" msgstr "Description" @@ -2892,120 +2942,156 @@ msgstr "Ville" msgid "&Location" msgstr "&Localisation" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:33 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:49 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:170 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:8 +msgid "Edit Template" +msgstr "Éditer le Modèle" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:13 +msgid "Edit template" +msgstr "Éditer le modèle" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:17 +msgid "Available variables" +msgstr "Variables disponibles" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:29 +msgid "Restore template" +msgstr "Restaurer le modèle" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:48 +msgid "Restored template to {}." +msgstr "Modèle restauré à {}." + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:52 +msgid "Invalid template" +msgstr "Modèle invalide" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:52 +msgid "" +"the template you have specified include variables that do not exists for the " +"object. Please fix the template and try again. For your reference, you can " +"see a list of all available variables in the variables list while editing " +"your template." +msgstr "" +"Le modèle que vous avez spécifié contient des variables qui ne sont pas " +"disponibles pour cet objet. Veuillez corriger le modèle et réessayer. Pour " +"votre information, vous pouvez consulter une liste des variables disponibles " +"dans la liste de variables lorsque vous éditez le modèle." + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:32 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:168 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:252 msgid "Attachments" msgstr "Fichiers joints" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:174 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:172 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:256 msgid "Type" msgstr "Type" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:40 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:177 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:262 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:39 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 msgid "Delete attachment" msgstr "Supprimer la pièce jointe" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:45 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:44 msgid "Added Tweets" msgstr "Tweets ajoutés" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:52 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:51 msgid "Delete tweet" msgstr "Supprimer le tweet" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:57 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:267 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:56 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:190 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:264 msgid "A&dd..." msgstr "&Ajouter" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:59 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:58 msgid "Add t&weet" msgstr "A&jouter un tweet" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:62 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:194 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:269 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:61 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:266 msgid "&Attach audio..." msgstr "&Joindre un audio..." -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:66 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:237 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:65 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:196 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 msgid "Auto&complete users" msgstr "Sai&sie automatique utilisateurs" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:68 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:273 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:367 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:67 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:270 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:364 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:437 msgid "Check &spelling..." msgstr "Correction &orthographique..." -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:70 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:202 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:275 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:69 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:272 msgid "&Translate" msgstr "&Traduire" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:74 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:206 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:279 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:73 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:204 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:276 msgid "Sen&d" msgstr "Envoye&r" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:118 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:299 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:117 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:218 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:296 msgid "Image" msgstr "Image" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:120 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:222 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:301 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:119 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:298 msgid "Video" msgstr "Vidéo" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:122 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:121 msgid "Poll" msgstr "Sondage" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:126 msgid "please provide a description" msgstr "Veuillez fournir une description" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:133 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:289 #: ../src\wxUI\dialogs\update_profile.py:82 msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" msgstr "Fichiers image (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:133 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:289 #: ../src\wxUI\dialogs\update_profile.py:82 msgid "Select the picture to be uploaded" msgstr "Sélectionnez la photo à charger" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:140 msgid "Select the video to be uploaded" msgstr "Sélectionnez la vidéo à téléverser" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:140 msgid "Video files (*.mp4)|*.mp4" msgstr "Fichiers vidéo (*.mp4)|*.mp4" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:146 msgid "Error adding attachment" msgstr "Erreur à l'ajout de la pièce jointe" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:146 msgid "" "It is not possible to add more attachments. Please make sure your tweet " "complies with Twitter'S attachment rules. You can add only one video or GIF " @@ -3015,87 +3101,87 @@ msgstr "" "respecte les règles d'attachement de Twitter. Vous pouvez seulement inclure " "une vidéo ou un GIF par tweet, et 4 photos au maximum." -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:182 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:180 msgid "&Mention to all" msgstr "&Répondre à tout le monde" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:233 msgid "&Recipient" msgstr "&Destinataire" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:307 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:304 msgid "Tweet - %i characters " msgstr "Tweet - %i caractères " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:324 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:321 msgid "Image description" msgstr "Description de l'image" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:335 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:332 msgid "Retweets: " msgstr "Retweets: " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:340 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:337 msgid "Likes: " msgstr "Favoris: " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:345 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:342 msgid "Source: " msgstr "Source: " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:350 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:428 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:347 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:425 msgid "Date: " msgstr "Date: " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:362 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:435 msgid "Copy link to clipboard" msgstr "Copier le lien dans le Presse-papiers" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:368 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:443 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 msgid "&Translate..." msgstr "&Traduire..." -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:369 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:444 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:366 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 msgid "C&lose" msgstr "F&ermer" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:413 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:410 msgid "View" msgstr "Voir" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:415 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:412 msgid "Item" msgstr "Élément" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 msgid "&Expand URL" msgstr "&Élargir URL" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:480 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:477 msgid "Add a poll" msgstr "Ajouter un sondage" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:484 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:481 msgid "Participation time (in days)" msgstr "Temps de participation (en jours)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:491 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:488 msgid "Choices" msgstr "Choix" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:495 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:492 msgid "Option 1" msgstr "Option 1" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:501 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:499 msgid "Option 2" msgstr "Option 2" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:507 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:506 msgid "Option 3" msgstr "Option 3" @@ -3103,11 +3189,11 @@ msgstr "Option 3" msgid "Option 4" msgstr "Option 4" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:541 msgid "Not enough information" msgstr "Pas assez d'informations" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:541 msgid "Please make sure you have provided at least two options for the poll." msgstr "Assurez-vous d'avoir spécifier au moins 2 options pour le sondage." From 5d0e1f38abd85936374f244df0d17a2fa71f1dca Mon Sep 17 00:00:00 2001 From: Oreonan Date: Mon, 27 Dec 2021 23:26:40 +0100 Subject: [PATCH 69/83] Some french fixes --- contributors.txt | 2 +- src/application.py | 2 +- src/locales/fr/LC_MESSAGES/twblue.po | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contributors.txt b/contributors.txt index 436c4ba8..90686177 100644 --- a/contributors.txt +++ b/contributors.txt @@ -39,5 +39,5 @@ florian Ionașcu Christian Leo Mameli Natalia Hedlund (Наталья Хедлунд) Valeria (Валерия) -Oreonan +Corentin Bacqué-Cazenave Artem Plaksin (maniyax) diff --git a/src/application.py b/src/application.py index 07632f4c..1c7fb3e1 100644 --- a/src/application.py +++ b/src/application.py @@ -9,7 +9,7 @@ authors = ["Manuel Cortéz", "José Manuel Delicado"] authorEmail = "manuel@manuelcortez.net" copyright = "Copyright (C) 2013-2021, Manuel cortéz." description = name+" is an app designed to use Twitter simply and efficiently while using minimal system resources. This app provides access to most Twitter features." -translators = ["Manuel Cortéz (English)", "Mohammed Al Shara, Hatoun Felemban (Arabic)", "Francisco Torres (Catalan)", "Manuel cortéz (Spanish)", "Sukil Etxenike Arizaleta (Basque)", "Jani Kinnunen (finnish)", "Oreonan (Français)", "Juan Buño (Galician)", "Steffen Schultz (German)", "Zvonimir Stanečić (Croatian)", "Robert Osztolykan (Hungarian)", "Christian Leo Mameli (Italian)", "Riku (Japanese)", "Paweł Masarczyk (Polish)", "Odenilton Júnior Santos (Portuguese)", "Florian Ionașcu, Nicușor Untilă (Romanian)", "Natalia Hedlund, Valeria Kuznetsova (Russian)", "Aleksandar Đurić (Serbian)", "Burak Yüksek (Turkish)"] +translators = ["Manuel Cortéz (English)", "Mohammed Al Shara, Hatoun Felemban (Arabic)", "Francisco Torres (Catalan)", "Manuel cortéz (Spanish)", "Sukil Etxenike Arizaleta (Basque)", "Jani Kinnunen (finnish)", "Corentin Bacqué-Cazenave (Français)", "Juan Buño (Galician)", "Steffen Schultz (German)", "Zvonimir Stanečić (Croatian)", "Robert Osztolykan (Hungarian)", "Christian Leo Mameli (Italian)", "Riku (Japanese)", "Paweł Masarczyk (Polish)", "Odenilton Júnior Santos (Portuguese)", "Florian Ionașcu, Nicușor Untilă (Romanian)", "Natalia Hedlund, Valeria Kuznetsova (Russian)", "Aleksandar Đurić (Serbian)", "Burak Yüksek (Turkish)"] url = u"https://twblue.es" report_bugs_url = "https://github.com/manuelcortez/twblue/issues" supported_languages = [] diff --git a/src/locales/fr/LC_MESSAGES/twblue.po b/src/locales/fr/LC_MESSAGES/twblue.po index e283345d..02c9859b 100644 --- a/src/locales/fr/LC_MESSAGES/twblue.po +++ b/src/locales/fr/LC_MESSAGES/twblue.po @@ -2,9 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.94\n" "POT-Creation-Date: 2021-12-22 18:18+0100\n" -"PO-Revision-Date: 2021-12-22 18:30+0100\n" -"Last-Translator: Oreonan \n" -"Language-Team: Oreonan \n" +"PO-Revision-Date: 2021-12-27 23:24+0100\n" +"Last-Translator: Corentin Bacqué-Cazenave \n" +"Language-Team: Corentin Bacqué-Cazenave \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -826,7 +826,7 @@ msgstr "Mention reçue." #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:21 msgid "New event." -msgstr "Nouvel événement." +msgstr "Nouvel évènement." #: ../src\extra\SoundsTutorial\soundsTutorial_constants.py:22 msgid "{0} is ready." @@ -874,7 +874,7 @@ msgstr "Apprentissage des sons" #: ../src\extra\SoundsTutorial\wx_ui.py:12 msgid "Press enter to listen to the sound for the selected event" -msgstr "Pressez sur entrée pour entendre le son lié à l'événement sélectionné" +msgstr "Pressez entrée pour entendre le son lié à l'évènement sélectionné" #: ../src\extra\SpellChecker\spellchecker.py:60 msgid "Misspelled word: %s" @@ -2147,11 +2147,11 @@ msgstr "Message" #: ../src\wxUI\buffers\events.py:14 msgid "Event" -msgstr "Événement" +msgstr "Évènement" #: ../src\wxUI\buffers\events.py:16 msgid "Remove event" -msgstr "Supprimer l'événement" +msgstr "Supprimer l'évènement" #: ../src\wxUI\buffers\panels.py:12 ../src\wxUI\buffers\panels.py:20 msgid "Login" @@ -3391,7 +3391,7 @@ msgstr "&Afficher le message" #: ../src\wxUI\menus.py:68 msgid "&Show event" -msgstr "&Afficher l'événement" +msgstr "&Afficher l'évènement" #: ../src\wxUI\menus.py:78 msgid "Direct &message" From 9e6740253ca7510c2b126770536647bee35b11d1 Mon Sep 17 00:00:00 2001 From: riku Date: Wed, 29 Dec 2021 15:54:17 +0900 Subject: [PATCH 70/83] Update Japanese translation --- src/locales/ja/lc_messages/twblue.mo | Bin 62862 -> 65368 bytes src/locales/ja/lc_messages/twblue.po | 397 ++++++++++++++++----------- 2 files changed, 242 insertions(+), 155 deletions(-) diff --git a/src/locales/ja/lc_messages/twblue.mo b/src/locales/ja/lc_messages/twblue.mo index aab8b3f01678e364549a838e3c41d175765a9c7e..b138d79086bdc1b7958a3ea4f178a36a42d07500 100644 GIT binary patch delta 19356 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 R%A3CF=V)_l-073+{{fY@A_xEg delta 17055 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 ZVEpC8jPU_a!V;=n7!r~2;#sR?{{snQG64Vp diff --git a/src/locales/ja/lc_messages/twblue.po b/src/locales/ja/lc_messages/twblue.po index 1354cdac..a3164f6e 100644 --- a/src/locales/ja/lc_messages/twblue.po +++ b/src/locales/ja/lc_messages/twblue.po @@ -7,28 +7,28 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-11-12 08:18+0900\n" +"PO-Revision-Date: 2021-12-29 15:52+0900\n" "Last-Translator: 陸 \n" "Language-Team: \n" "Language: ja_JP\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 3.0\n" "Plural-Forms: nplurals=1; plural=0;\n" +"Generated-By: pygettext.py 1.5\n" +"X-Generator: Poedit 3.0.1\n" #: ../src\controller\buffers\base\base.py:91 msgid "This action is not supported for this buffer" msgstr "この動作は、現在のバッファではサポートされていません" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:337 ../src\controller\settings.py:286 +#: ../src\controller\mainController.py:337 ../src\controller\settings.py:323 msgid "Home" msgstr "ホーム" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:339 ../src\controller\settings.py:287 +#: ../src\controller\mainController.py:339 ../src\controller\settings.py:324 msgid "Mentions" msgstr "メンション" @@ -38,41 +38,41 @@ msgid "Direct messages" msgstr "ダイレクトメッセージ" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:343 ../src\controller\settings.py:289 +#: ../src\controller\mainController.py:343 ../src\controller\settings.py:326 msgid "Sent direct messages" msgstr "送信済みのダイレクトメッセージ" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:345 ../src\controller\settings.py:290 +#: ../src\controller\mainController.py:345 ../src\controller\settings.py:327 msgid "Sent tweets" msgstr "送信済みのツイート" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:347 -#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:291 +#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:328 msgid "Likes" msgstr "いいね" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:292 +#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:329 msgid "Followers" msgstr "フォロワー" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:353 -#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:294 +#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:331 msgid "Blocked users" msgstr "ブロックしたユーザー" #: ../src\controller\buffers\twitter\base.py:70 #: ../src\controller\mainController.py:355 -#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:295 +#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:332 msgid "Muted users" msgstr "ミューとしたユーザー" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:293 +#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:330 msgid "Friends" msgstr "フォロー" @@ -101,7 +101,7 @@ msgstr "不明なバッファ" #: ../src\controller\buffers\twitter\trends.py:134 #: ../src\controller\messages.py:296 ../src\wxUI\buffers\base.py:25 #: ../src\wxUI\buffers\events.py:15 ../src\wxUI\buffers\trends.py:18 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:312 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:309 #: ../src\wxUI\sysTrayIcon.py:35 msgid "Tweet" msgstr "ツイート" @@ -112,75 +112,75 @@ msgstr "ツイート" msgid "Write the tweet here" msgstr "ツイートを入力" -#: ../src\controller\buffers\twitter\base.py:192 +#: ../src\controller\buffers\twitter\base.py:194 msgid "New tweet in {0}" msgstr "「{0}」への新規ツイート" -#: ../src\controller\buffers\twitter\base.py:195 +#: ../src\controller\buffers\twitter\base.py:197 msgid "{0} new tweets in {1}." msgstr "「{1}」への{0}個の新規ツイート。" -#: ../src\controller\buffers\twitter\base.py:234 +#: ../src\controller\buffers\twitter\base.py:236 #: ../src\controller\buffers\twitter\directMessages.py:88 -#: ../src\controller\buffers\twitter\people.py:174 +#: ../src\controller\buffers\twitter\people.py:177 msgid "%s items retrieved" msgstr "%s個のアイテムを取得しました" -#: ../src\controller\buffers\twitter\base.py:266 +#: ../src\controller\buffers\twitter\base.py:268 #: ../src\controller\buffers\twitter\people.py:80 msgid "This buffer is not a timeline; it can't be deleted." msgstr "このバッファは、タイムラインではないため、削除できません。" -#: ../src\controller\buffers\twitter\base.py:402 +#: ../src\controller\buffers\twitter\base.py:404 msgid "Reply to {arg0}" msgstr "「{arg0}」への返信:" -#: ../src\controller\buffers\twitter\base.py:404 +#: ../src\controller\buffers\twitter\base.py:406 #: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "返信" -#: ../src\controller\buffers\twitter\base.py:405 +#: ../src\controller\buffers\twitter\base.py:407 msgid "Reply to %s" msgstr "「%s」への返信" -#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\base.py:430 #: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "新しいダイレクトメッセージ" -#: ../src\controller\buffers\twitter\base.py:428 +#: ../src\controller\buffers\twitter\base.py:430 #: ../src\controller\messages.py:268 msgid "Direct message to %s" msgstr "「%s」へのダイレクトメッセージ" -#: ../src\controller\buffers\twitter\base.py:459 +#: ../src\controller\buffers\twitter\base.py:461 msgid "Add your comment to the tweet" msgstr "ツイートにコメントを追加" -#: ../src\controller\buffers\twitter\base.py:459 +#: ../src\controller\buffers\twitter\base.py:461 msgid "Quote" msgstr "引用" -#: ../src\controller\buffers\twitter\base.py:520 +#: ../src\controller\buffers\twitter\base.py:522 msgid "Opening URL..." msgstr "URLを開いています…" -#: ../src\controller\buffers\twitter\base.py:557 +#: ../src\controller\buffers\twitter\base.py:559 msgid "User details" msgstr "ユーザーの詳細" -#: ../src\controller\buffers\twitter\base.py:578 +#: ../src\controller\buffers\twitter\base.py:580 msgid "Opening item in web browser..." msgstr "ブラウザでアイテムを開いています…" #: ../src\controller\buffers\twitter\directMessages.py:93 -#: ../src\controller\buffers\twitter\people.py:95 +#: ../src\controller\buffers\twitter\people.py:98 msgid "Mention to %s" msgstr "%sへのメンション" #: ../src\controller\buffers\twitter\directMessages.py:93 -#: ../src\controller\buffers\twitter\people.py:95 +#: ../src\controller\buffers\twitter\people.py:98 #: ../src\wxUI\buffers\people.py:17 msgid "Mention" msgstr "メンション" @@ -193,7 +193,7 @@ msgstr "{0}件の新しいダイレクトメッセージ。" msgid "This action is not supported in the buffer yet." msgstr "この動作は、現在のバッファではサポートされていません。" -#: ../src\controller\buffers\twitter\directMessages.py:140 +#: ../src\controller\buffers\twitter\directMessages.py:146 msgid "" "Getting more items cannot be done in this buffer. Use the direct messages " "buffer instead." @@ -201,7 +201,7 @@ msgstr "" "このバッファでは、さらにアイテムを取得することはできません。代わりにダイレク" "トメッセージバッファを使用してください。" -#: ../src\controller\buffers\twitter\people.py:247 +#: ../src\controller\buffers\twitter\people.py:250 msgid "{0} new followers." msgstr "{0}人の新しいフォロワー。" @@ -459,49 +459,67 @@ msgstr "アイテムを見る" msgid "Link copied to clipboard." msgstr "リンクをクリップボードへコピーしました。" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "HTTP" msgstr "HTTP" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "SOCKS v4" msgstr "SOCKS v4" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "SOCKS v4 with DNS support" msgstr "DNSをサポートする SOCKS v4" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "SOCKS v5" msgstr "SOCKS v5" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "SOCKS v5 with DNS support" msgstr "DNSをサポートする SOCKS v5" -#: ../src\controller\settings.py:74 +#: ../src\controller\settings.py:76 msgid "System default" msgstr "システムのデフォルト" -#: ../src\controller\settings.py:145 ../src\controller\settings.py:211 +#: ../src\controller\settings.py:152 ../src\controller\settings.py:265 #: ../src\wxUI\dialogs\configuration.py:116 msgid "Ask" msgstr "その都度、質問する" -#: ../src\controller\settings.py:147 ../src\controller\settings.py:213 +#: ../src\controller\settings.py:154 ../src\controller\settings.py:267 #: ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet without comments" msgstr "コメントを付けずにリツイート(公式RT)" -#: ../src\controller\settings.py:149 ../src\wxUI\dialogs\configuration.py:116 +#: ../src\controller\settings.py:156 ../src\wxUI\dialogs\configuration.py:116 msgid "Retweet with comments" msgstr "コメントをつけてリツイート(非公式RT)" -#: ../src\controller\settings.py:185 +#: ../src\controller\settings.py:200 msgid "Account settings for %s" msgstr "%sのアカウント設定" -#: ../src\controller\settings.py:288 +#: ../src\controller\settings.py:210 ../src\wxUI\dialogs\configuration.py:240 +msgid "Edit template for tweets. Current template: {}" +msgstr "ツイートのテンプレートを編集します。現在のテンプレート: {}" + +#: ../src\controller\settings.py:219 ../src\wxUI\dialogs\configuration.py:242 +msgid "Edit template for direct messages. Current template: {}" +msgstr "ダイレクトメッセージのテンプレートを編集します。現在のテンプレート: {}" + +#: ../src\controller\settings.py:228 ../src\wxUI\dialogs\configuration.py:244 +msgid "Edit template for sent direct messages. Current template: {}" +msgstr "" +"送信済みのダイレクトメッセージのテンプレートを編集します。現在のテンプレー" +"ト: {}" + +#: ../src\controller\settings.py:237 ../src\wxUI\dialogs\configuration.py:246 +msgid "Edit template for persons. Current template: {}" +msgstr "人のテンプレートを編集します。現在のテンプレート: {}" + +#: ../src\controller\settings.py:325 msgid "Direct Messages" msgstr "ダイレクトメッセージ" @@ -518,6 +536,7 @@ msgstr "ダイレクトメッセージ" #: ../src\wxUI\commonMessageDialogs.py:83 #: ../src\wxUI\commonMessageDialogs.py:89 #: ../src\wxUI\commonMessageDialogs.py:92 +#: ../src\wxUI\commonMessageDialogs.py:95 msgid "Error" msgstr "エラー" @@ -698,9 +717,9 @@ msgid "%s seconds" msgstr "%s秒" #: ../src\extra\AudioUploader\wx_transfer_dialogs.py:15 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:258 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:35 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:171 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 msgid "File" msgstr "ファイル" @@ -1371,8 +1390,8 @@ msgid "Target language" msgstr "翻訳先の言語" #: ../src\issueReporter\issueReporter.py:32 -#: ../src\wxUI\dialogs\configuration.py:359 -#: ../src\wxUI\dialogs\configuration.py:368 +#: ../src\wxUI\dialogs\configuration.py:373 +#: ../src\wxUI\dialogs\configuration.py:382 msgid "General" msgstr "一般" @@ -1765,7 +1784,7 @@ msgstr "キーストロークの定義を解除" msgid "Execute action" msgstr "現在の動作を実行" -#: ../src\keystrokeEditor\wx_ui.py:22 ../src\wxUI\dialogs\configuration.py:396 +#: ../src\keystrokeEditor\wx_ui.py:22 ../src\wxUI\dialogs\configuration.py:414 #: ../src\wxUI\dialogs\userAliasDialogs.py:25 ../src\wxUI\dialogs\utils.py:39 msgid "Close" msgstr "閉じる" @@ -1941,6 +1960,7 @@ msgstr "" #: ../src\sessions\twitter\compose.py:38 ../src\sessions\twitter\compose.py:81 #: ../src\sessions\twitter\compose.py:146 #: ../src\sessions\twitter\compose.py:155 +#: ../src\sessions\twitter\templates.py:26 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "YYYY年MMMMD日(dddd) H時m分s秒" @@ -1992,19 +2012,43 @@ msgstr "%sに成功しました。" msgid "Deleted account" msgstr "削除されたアカウント" -#: ../src\sessions\twitter\utils.py:231 +#: ../src\sessions\twitter\templates.py:16 +msgid "$display_name, $text $image_descriptions $date. $source" +msgstr "$display_name, $text $image_descriptions $date. $source" + +#: ../src\sessions\twitter\templates.py:17 +msgid "$sender_display_name, $text $date" +msgstr "$sender_display_name, $text $date" + +#: ../src\sessions\twitter\templates.py:18 +msgid "Dm to $recipient_display_name, $text $date" +msgstr "$recipient_display_name へのDM, $text $date" + +#: ../src\sessions\twitter\templates.py:19 +msgid "" +"$display_name (@$screen_name). $followers followers, $following following, " +"$tweets tweets. Joined Twitter $created_at." +msgstr "" +"$display_name (@$screen_name)。$followers フォロワー、$following フォロー" +"中、$tweets 件のツイート。Twitter への参加 $created_at。" + +#: ../src\sessions\twitter\templates.py:50 +msgid "Image description: {}." +msgstr "画像の説明: {}。" + +#: ../src\sessions\twitter\utils.py:229 msgid "Sorry, you are not authorised to see this status." msgstr "申し訳ありませんが、あなたはこのステータスを表示する権限がありません。" -#: ../src\sessions\twitter\utils.py:233 +#: ../src\sessions\twitter\utils.py:231 msgid "No status found with that ID" msgstr "そのIDのステータスが見つかりませんでした" -#: ../src\sessions\twitter\utils.py:235 +#: ../src\sessions\twitter\utils.py:233 msgid "Error {0}" msgstr "エラー {0}" -#: ../src\sessions\twitter\utils.py:262 +#: ../src\sessions\twitter\utils.py:260 msgid "{user_1}, {user_2} and {all_users} more: {text}" msgstr "{user_1}、{user_2}、ほか{all_users}ユーザー: {text}" @@ -2082,7 +2126,7 @@ msgid "User" msgstr "ユーザー" #: ../src\wxUI\buffers\base.py:12 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:47 msgid "Text" msgstr "内容" @@ -2178,7 +2222,7 @@ msgid "Enter the name of the client : " msgstr "クライアントの名前: " #: ../src\wxUI\commonMessageDialogs.py:26 -#: ../src\wxUI\dialogs\configuration.py:246 +#: ../src\wxUI\dialogs\configuration.py:260 msgid "Add client" msgstr "クライアントを追加" @@ -2229,7 +2273,7 @@ msgstr "" "リシーにより更新されません。続行しますか?" #: ../src\wxUI\commonMessageDialogs.py:48 -#: ../src\wxUI\commonMessageDialogs.py:95 +#: ../src\wxUI\commonMessageDialogs.py:98 msgid "Warning" msgstr "警告" @@ -2335,6 +2379,10 @@ msgid "This filter already exists. Please use a different title" msgstr "このフィルターはすでに利用されています。別の名前を利用してください" #: ../src\wxUI\commonMessageDialogs.py:95 +msgid "The configuration file is invalid." +msgstr "設定ファイルが不正です。" + +#: ../src\wxUI\commonMessageDialogs.py:98 msgid "" "{0} quit unexpectedly the last time it was run. If the problem persists, " "please report it to the {0} developers." @@ -2526,80 +2574,84 @@ msgstr "既にそのバッファは、リストの先頭です。" msgid "The buffer is already at the bottom of the list." msgstr "既にそのバッファは、リストの最後です。" -#: ../src\wxUI\dialogs\configuration.py:240 -#: ../src\wxUI\dialogs\configuration.py:381 +#: ../src\wxUI\dialogs\configuration.py:254 +#: ../src\wxUI\dialogs\configuration.py:395 msgid "Ignored clients" msgstr "無視するクライアント" -#: ../src\wxUI\dialogs\configuration.py:247 +#: ../src\wxUI\dialogs\configuration.py:261 msgid "Remove client" msgstr "クライアントを削除" -#: ../src\wxUI\dialogs\configuration.py:271 +#: ../src\wxUI\dialogs\configuration.py:285 msgid "Volume" msgstr "ボリューム" -#: ../src\wxUI\dialogs\configuration.py:282 +#: ../src\wxUI\dialogs\configuration.py:296 msgid "Session mute" msgstr "セッションのミュート" -#: ../src\wxUI\dialogs\configuration.py:284 +#: ../src\wxUI\dialogs\configuration.py:298 msgid "Output device" msgstr "出力先デバイス" -#: ../src\wxUI\dialogs\configuration.py:291 +#: ../src\wxUI\dialogs\configuration.py:305 msgid "Input device" msgstr "入力デバイス" -#: ../src\wxUI\dialogs\configuration.py:299 +#: ../src\wxUI\dialogs\configuration.py:313 msgid "Sound pack" msgstr "サウンドパック" -#: ../src\wxUI\dialogs\configuration.py:305 +#: ../src\wxUI\dialogs\configuration.py:319 msgid "Indicate audio tweets with sound" msgstr "音声付きツイートを音で報告" -#: ../src\wxUI\dialogs\configuration.py:307 +#: ../src\wxUI\dialogs\configuration.py:321 msgid "Indicate geotweets with sound" msgstr "位置情報付きツイートを音で報告" -#: ../src\wxUI\dialogs\configuration.py:309 +#: ../src\wxUI\dialogs\configuration.py:323 msgid "Indicate tweets containing images with sound" msgstr "画像付きツイートを音で報告" -#: ../src\wxUI\dialogs\configuration.py:332 +#: ../src\wxUI\dialogs\configuration.py:346 msgid "Language for OCR" msgstr "OCRの言語" -#: ../src\wxUI\dialogs\configuration.py:338 +#: ../src\wxUI\dialogs\configuration.py:352 msgid "API Key for SndUp" msgstr "SndUpのAPIキー" -#: ../src\wxUI\dialogs\configuration.py:353 +#: ../src\wxUI\dialogs\configuration.py:367 msgid "{0} preferences" msgstr "{0}の設定" -#: ../src\wxUI\dialogs\configuration.py:364 +#: ../src\wxUI\dialogs\configuration.py:378 msgid "Proxy" msgstr "プロキシ" -#: ../src\wxUI\dialogs\configuration.py:373 +#: ../src\wxUI\dialogs\configuration.py:387 msgid "Feedback" msgstr "フィードバック" -#: ../src\wxUI\dialogs\configuration.py:377 +#: ../src\wxUI\dialogs\configuration.py:391 msgid "Buffers" msgstr "バッファ" -#: ../src\wxUI\dialogs\configuration.py:385 +#: ../src\wxUI\dialogs\configuration.py:399 +msgid "Templates" +msgstr "テンプレート" + +#: ../src\wxUI\dialogs\configuration.py:403 msgid "Sound" msgstr "サウンド" -#: ../src\wxUI\dialogs\configuration.py:389 +#: ../src\wxUI\dialogs\configuration.py:407 msgid "Extras" msgstr "その他" -#: ../src\wxUI\dialogs\configuration.py:394 +#: ../src\wxUI\dialogs\configuration.py:412 msgid "Save" msgstr "保存" @@ -2728,10 +2780,10 @@ msgid "mode" msgstr "モード" #: ../src\wxUI\dialogs\lists.py:14 ../src\wxUI\dialogs\lists.py:70 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:38 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:260 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:126 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:173 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:257 msgid "Description" msgstr "説明" @@ -2872,120 +2924,155 @@ msgstr "都市" msgid "&Location" msgstr "場所(&L)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:33 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:49 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:170 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:255 +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:8 +msgid "Edit Template" +msgstr "テンプレートを編集" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:13 +msgid "Edit template" +msgstr "テンプレートを編集" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:17 +msgid "Available variables" +msgstr "使用可能な変数" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:29 +msgid "Restore template" +msgstr "テンプレートを復元" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:48 +msgid "Restored template to {}." +msgstr "テンプレートを {} に復元しました。" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:52 +msgid "Invalid template" +msgstr "無効なテンプレート" + +#: ../src\wxUI\dialogs\twitterDialogs\templateDialogs.py:52 +msgid "" +"the template you have specified include variables that do not exists for the " +"object. Please fix the template and try again. For your reference, you can " +"see a list of all available variables in the variables list while editing " +"your template." +msgstr "" +"指定したテンプレートには、オブジェクトに存在しない変数が含まれています。テン" +"プレートを修正して、再試行してください。参考までに、テンプレートの編集中に、" +"変数リストで使用可能なすべての変数のリストを確認できます。" + +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:32 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:48 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:168 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:252 msgid "Attachments" msgstr "添付ファイル" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:37 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:174 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:36 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:172 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:256 msgid "Type" msgstr "形式" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:40 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:177 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:262 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:39 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:175 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:259 msgid "Delete attachment" msgstr "添付ファイルを削除" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:45 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:44 msgid "Added Tweets" msgstr "ツイートを追加" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:52 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:51 msgid "Delete tweet" msgstr "ツイートを削除" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:57 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:267 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:56 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:190 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:264 msgid "A&dd..." msgstr "追加(&D)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:59 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:58 msgid "Add t&weet" msgstr "ツイートを追加(&W)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:62 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:194 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:269 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:61 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:192 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:266 msgid "&Attach audio..." msgstr "音声を添付(&A)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:66 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:237 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:65 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:196 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 msgid "Auto&complete users" msgstr "ユーザーを自動保管(&C)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:68 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:273 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:367 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:67 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:198 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:270 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:364 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:437 msgid "Check &spelling..." msgstr "スペルチェック(&S)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:70 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:202 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:275 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:69 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:200 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:272 msgid "&Translate" msgstr "翻訳(&T)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:74 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:206 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:279 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:73 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:204 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:276 msgid "Sen&d" msgstr "送信(&D)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:118 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:299 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:117 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:218 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:296 msgid "Image" msgstr "画像" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:120 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:222 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:301 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:119 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:220 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:298 msgid "Video" msgstr "動画" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:122 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:121 msgid "Poll" msgstr "投票" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:127 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:126 msgid "please provide a description" msgstr "説明を入力" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:133 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:289 #: ../src\wxUI\dialogs\update_profile.py:82 msgid "Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" msgstr "画像ファイル (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:134 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:292 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:133 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:289 #: ../src\wxUI\dialogs\update_profile.py:82 msgid "Select the picture to be uploaded" msgstr "アップロードする画像を選択" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:140 msgid "Select the video to be uploaded" msgstr "アップロードする動画を選択" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:141 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:140 msgid "Video files (*.mp4)|*.mp4" msgstr "動画ファイル (*.mp4)|*.mp4" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:146 msgid "Error adding attachment" msgstr "添付ファイルの追加中にエラーが発生しました" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:147 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:146 msgid "" "It is not possible to add more attachments. Please make sure your tweet " "complies with Twitter'S attachment rules. You can add only one video or GIF " @@ -2995,87 +3082,87 @@ msgstr "" "に準拠していることを確認してください。すべてのツイートに追加できるビデオまた" "はGIFは1つだけで、最大4枚の写真を追加できます。" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:182 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:180 msgid "&Mention to all" msgstr "全員にリプライ(&M)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:235 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:233 msgid "&Recipient" msgstr "送信先(&R)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:307 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:304 msgid "Tweet - %i characters " msgstr "ツイート - %i文字" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:324 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:321 msgid "Image description" msgstr "画像の説明" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:335 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:332 msgid "Retweets: " msgstr "リツイート: " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:340 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:337 msgid "Likes: " msgstr "いいね: " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:345 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:342 msgid "Source: " msgstr "ソース: " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:350 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:428 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:347 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:425 msgid "Date: " msgstr "日付: " -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:362 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:435 msgid "Copy link to clipboard" msgstr "リンクをクリップボードへコピー" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:368 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:443 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:365 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:440 msgid "&Translate..." msgstr "翻訳(&T)..." -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:369 -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:444 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:366 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 msgid "C&lose" msgstr "閉じる(&C)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:413 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:410 msgid "View" msgstr "ツイート" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:415 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:412 msgid "Item" msgstr "アイテム" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:441 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:438 msgid "&Expand URL" msgstr "URLを元に戻す(&E)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:480 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:477 msgid "Add a poll" msgstr "投票を追加" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:484 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:481 msgid "Participation time (in days)" msgstr "投票期間(日数)" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:491 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:488 msgid "Choices" msgstr "選択肢" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:495 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:492 msgid "Option 1" msgstr "オプション1" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:501 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:499 msgid "Option 2" msgstr "オプション2" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:507 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:506 msgid "Option 3" msgstr "オプション3" @@ -3083,11 +3170,11 @@ msgstr "オプション3" msgid "Option 4" msgstr "オプション4" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:541 msgid "Not enough information" msgstr "十分な情報がありません" -#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:540 +#: ../src\wxUI\dialogs\twitterDialogs\tweetDialogs.py:541 msgid "Please make sure you have provided at least two options for the poll." msgstr "投票に少なくとも2つのオプションを提供していることを確認してください。" From 6a839baed72cac5f541af58a1a73363ba9ba7d4c Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 10 Jan 2022 00:07:36 +0000 Subject: [PATCH 71/83] Change author information --- scripts/twblue.nsi | 2 +- src/application.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/twblue.nsi b/scripts/twblue.nsi index 9f1bfe95..f0a37095 100644 --- a/scripts/twblue.nsi +++ b/scripts/twblue.nsi @@ -14,7 +14,7 @@ SetCompress auto SetCompressor /solid lzma SetDatablockOptimize on VIAddVersionKey ProductName "TWBlue" -VIAddVersionKey LegalCopyright "Copyright 2014-2021 Manuel Cortéz." +VIAddVersionKey LegalCopyright "Copyright 2014-2022 MCV Software." VIAddVersionKey ProductVersion "0.95.0" VIAddVersionKey FileVersion "0.95.0" VIProductVersion "0.95.0" diff --git a/src/application.py b/src/application.py index 1c7fb3e1..f173a916 100644 --- a/src/application.py +++ b/src/application.py @@ -1,16 +1,14 @@ # -*- coding: utf-8 -*- -import datetime - name = 'TWBlue' short_name='twblue' update_url = 'https://twblue.es/updates/updates.php' mirror_update_url = 'https://raw.githubusercontent.com/manuelcortez/TWBlue/next-gen/updates/updates.json' authors = ["Manuel Cortéz", "José Manuel Delicado"] authorEmail = "manuel@manuelcortez.net" -copyright = "Copyright (C) 2013-2021, Manuel cortéz." +copyright = "Copyright (C) 2013-2022, MCV Software." description = name+" is an app designed to use Twitter simply and efficiently while using minimal system resources. This app provides access to most Twitter features." translators = ["Manuel Cortéz (English)", "Mohammed Al Shara, Hatoun Felemban (Arabic)", "Francisco Torres (Catalan)", "Manuel cortéz (Spanish)", "Sukil Etxenike Arizaleta (Basque)", "Jani Kinnunen (finnish)", "Corentin Bacqué-Cazenave (Français)", "Juan Buño (Galician)", "Steffen Schultz (German)", "Zvonimir Stanečić (Croatian)", "Robert Osztolykan (Hungarian)", "Christian Leo Mameli (Italian)", "Riku (Japanese)", "Paweł Masarczyk (Polish)", "Odenilton Júnior Santos (Portuguese)", "Florian Ionașcu, Nicușor Untilă (Romanian)", "Natalia Hedlund, Valeria Kuznetsova (Russian)", "Aleksandar Đurić (Serbian)", "Burak Yüksek (Turkish)"] -url = u"https://twblue.es" +url = "https://twblue.es" report_bugs_url = "https://github.com/manuelcortez/twblue/issues" supported_languages = [] version = "11" From a645e0b96458722cd363730a8669ebdde4109324 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 10 Jan 2022 04:35:23 -0600 Subject: [PATCH 72/83] TWBlue should no longer load old items in buffer --- doc/changelog.md | 1 + src/controller/buffers/twitter/base.py | 2 +- src/sessions/twitter/session.py | 17 +++++++++-------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index 92b41c2e..6916756a 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -7,6 +7,7 @@ TWBlue Changelog * TWBlue can display image descriptions within Tweet templates. For that, you can use the $image_description variable in your template. * We have restored conversation and threads support powered by Twitter API V2 thanks to a set of improvements we have done in the application, as well as more generous limits to Tweet monthly cap by Twitter. * In the Windows 11 Keymap, the default shortcut to open the keystrokes editor is now CTRL+Alt+Windows+K to avoid conflicts with the new global mute microphone shortcut. +* TWBlue should no longer load old tweets in buffers. * Fixed issue when uploading attachments (images, videos or gif files) while sending tweets or replies. * Fixed an error that was making TWBlue to ask for a restart after saving account settings, even if such restart was not required. ([#413,](https://github.com/manuelcortez/TWBlue/issues/413)) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 3d7c1767..98005c85 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -142,7 +142,7 @@ class BaseBuffer(base.Buffer): log.debug("Starting stream for buffer %s, account %s and type %s" % (self.name, self.account, self.type)) log.debug("args: %s, kwargs: %s" % (self.args, self.kwargs)) if self.name != "direct_messages": - val = self.session.call_paged(self.function, *self.args, **self.kwargs) + val = self.session.call_paged(self.function, self.name, *self.args, **self.kwargs) else: # 50 results are allowed per API call, so let's assume max value can be 50. # reference: https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/list-events diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index 55373aa7..63a970a4 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -256,21 +256,22 @@ class Session(base.baseSession): tl = self.call_paged("favorites", *args, **kwargs) return self.order_buffer(name, tl) - def call_paged(self, update_function, *args, **kwargs): + def call_paged(self, update_function, name, *args, **kwargs): """ Makes a call to the Twitter API methods several times. Useful for get methods. this function is needed for retrieving more than 200 items. update_function str: The function to call. This function must be child of self.twitter args and kwargs are passed to update_function. returns a list with all items retrieved.""" - max = 0 results = [] - data = getattr(self.twitter, update_function)(count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) + if self.db.get(name) == None or self.db.get(name) == []: + last_id = None + else: + if self.settings["general"]["reverse_timelines"] == False: + last_id = self.db[name][0].id + else: + last_id = self.db[name][-1].id + data = getattr(self.twitter, update_function)(count=self.settings["general"]["max_tweets_per_call"], since_id=last_id, *args, **kwargs) results.extend(data) - for i in range(0, max): - if i == 0: max_id = results[-1].id - else: max_id = results[0].id - data = getattr(self.twitter, update_function)(max_id=max_id, count=self.settings["general"]["max_tweets_per_call"], *args, **kwargs) - results.extend(data) results.reverse() return results From d7afa77c4915eb8a51070360276ddcb36035cc1e Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 10 Jan 2022 05:05:27 -0600 Subject: [PATCH 73/83] Changed params names to avoid confussions --- src/sessions/twitter/session.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index 63a970a4..b964b1de 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -36,9 +36,9 @@ class Session(base.baseSession): return self.order_direct_messages(data) num = 0 last_id = None - if (name in self.db) == False: + if self.db.get(name) == None: self.db[name] = [] - if ("users" in self.db) == False: + if self.db.get("users") == None: self.db["users"] = {} objects = self.db[name] if ignore_older and len(self.db[name]) > 0: @@ -267,10 +267,10 @@ class Session(base.baseSession): last_id = None else: if self.settings["general"]["reverse_timelines"] == False: - last_id = self.db[name][0].id + since_id = self.db[name][-1].id else: - last_id = self.db[name][-1].id - data = getattr(self.twitter, update_function)(count=self.settings["general"]["max_tweets_per_call"], since_id=last_id, *args, **kwargs) + since_id = self.db[name][0].id + data = getattr(self.twitter, update_function)(count=self.settings["general"]["max_tweets_per_call"], since_id=since_id, *args, **kwargs) results.extend(data) results.reverse() return results From 7a78accd1fe3b86730927348b025d001e5200afa Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 10 Jan 2022 05:06:31 -0600 Subject: [PATCH 74/83] Fixed a typo --- src/sessions/twitter/session.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index b964b1de..3c84d0e0 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -264,7 +264,7 @@ class Session(base.baseSession): returns a list with all items retrieved.""" results = [] if self.db.get(name) == None or self.db.get(name) == []: - last_id = None + since_id = None else: if self.settings["general"]["reverse_timelines"] == False: since_id = self.db[name][-1].id From 301e3d436170570369168d4134a068e12e049065 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Mon, 10 Jan 2022 05:30:14 -0600 Subject: [PATCH 75/83] Display properly HTML Entities in tweets --- doc/changelog.md | 1 + src/controller/messages.py | 1 + src/sessions/twitter/compose.py | 15 +-------------- src/sessions/twitter/templates.py | 2 +- src/sessions/twitter/utils.py | 14 ++++++++++++++ 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/doc/changelog.md b/doc/changelog.md index 6916756a..83d7022f 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -7,6 +7,7 @@ TWBlue Changelog * TWBlue can display image descriptions within Tweet templates. For that, you can use the $image_description variable in your template. * We have restored conversation and threads support powered by Twitter API V2 thanks to a set of improvements we have done in the application, as well as more generous limits to Tweet monthly cap by Twitter. * In the Windows 11 Keymap, the default shortcut to open the keystrokes editor is now CTRL+Alt+Windows+K to avoid conflicts with the new global mute microphone shortcut. +* TWBlue show display properly HTML entities in tweet's text. * TWBlue should no longer load old tweets in buffers. * Fixed issue when uploading attachments (images, videos or gif files) while sending tweets or replies. * Fixed an error that was making TWBlue to ask for a restart after saving account settings, even if such restart was not required. ([#413,](https://github.com/manuelcortez/TWBlue/issues/413)) diff --git a/src/controller/messages.py b/src/controller/messages.py index 421be6d7..9b93ed58 100644 --- a/src/controller/messages.py +++ b/src/controller/messages.py @@ -367,6 +367,7 @@ class viewTweet(basicTweet): pass def clear_text(self, text): + text = utils.StripChars(text) urls = utils.find_urls_in_text(text) for i in urls: if "https://twitter.com/" in i: diff --git a/src/sessions/twitter/compose.py b/src/sessions/twitter/compose.py index 1b761390..539b4df7 100644 --- a/src/sessions/twitter/compose.py +++ b/src/sessions/twitter/compose.py @@ -3,7 +3,6 @@ import platform system = platform.system() from . import utils import re -import html.entities import time import output import languageHandler @@ -11,21 +10,9 @@ import arrow import logging import config from .long_tweets import twishort, tweets +from .utils import StripChars log = logging.getLogger("compose") -def StripChars(s): - """Converts any html entities in s to their unicode-decoded equivalents and returns a string.""" - entity_re = re.compile(r"&(#\d+|\w+);") - def matchFunc(match): - """Nested function to handle a match object. - If we match &blah; and it's not found, &blah; will be returned. - if we match #\d+, unichr(digits) will be returned. - Else, a unicode string will be returned.""" - if match.group(1).startswith('#'): return chr(int(match.group(1)[1:])) - replacement = html.entities.entitydefs.get(match.group(1), "&%s;" % match.group(1)) - return replacement - return str(entity_re.sub(matchFunc, s)) - chars = "abcdefghijklmnopqrstuvwxyz" def compose_tweet(tweet, db, relative_times, show_screen_names=False, session=None): diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index 156a2d67..bd4067b0 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -32,7 +32,7 @@ def process_text(tweet): elif hasattr(tweet, "text"): text = tweet.text # Cleanup mentions, so we'll remove more than 2 mentions to make the tweet easier to read. - text = utils.clean_mentions(text) + text = utils.clean_mentions(utils.StripChars(text)) # Replace URLS for extended version of those. if hasattr(tweet, "entities"): text = utils.expand_urls(text, tweet.entities) diff --git a/src/sessions/twitter/utils.py b/src/sessions/twitter/utils.py index 47cef7a7..c13d3088 100644 --- a/src/sessions/twitter/utils.py +++ b/src/sessions/twitter/utils.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import re +import html.entities import output import logging import requests @@ -16,6 +17,19 @@ url_re = re.compile(r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4 url_re2 = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ \\n\\t]*") bad_chars = '\'\\\n.,[](){}:;"' +def StripChars(s): + """Converts any html entities in s to their unicode-decoded equivalents and returns a string.""" + entity_re = re.compile(r"&(#\d+|\w+);") + def matchFunc(match): + """Nested function to handle a match object. + If we match &blah; and it's not found, &blah; will be returned. + if we match #\d+, unichr(digits) will be returned. + Else, a unicode string will be returned.""" + if match.group(1).startswith('#'): return chr(int(match.group(1)[1:])) + replacement = html.entities.entitydefs.get(match.group(1), "&%s;" % match.group(1)) + return replacement + return str(entity_re.sub(matchFunc, s)) + def find_urls_in_text(text): return url_re2.findall(text) From c048c3ff32f0f95be72914acfe6bc6954a52bed3 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 25 Jan 2022 01:26:23 -0600 Subject: [PATCH 76/83] Retrieve usernames for timelines from the local database, as opposed to use the last API call as this might not contain items at times --- src/controller/buffers/twitter/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 98005c85..838d0cf1 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -174,9 +174,9 @@ class BaseBuffer(base.Buffer): self.put_items_on_list(number_of_items) if hasattr(self, "finished_timeline") and self.finished_timeline == False: if "-timeline" in self.name: - self.username = val[0].user.screen_name + self.username = self.session.get_user(self.kwargs.get("user_id")).screen_name elif "-favorite" in self.name: - self.username = self.session.api_call("get_user", **self.kwargs).screen_name + self.username = self.session.get_user(self.kwargs.get("user_id")).screen_name 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: self.session.sound.play(self.sound) From e43ddad6786d6e392e82a1d8512573984f8d2960 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 25 Jan 2022 01:27:52 -0600 Subject: [PATCH 77/83] Catch image description sent by Streaming API. Should be enough to fix #449 --- src/sessions/twitter/templates.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index bd4067b0..46913220 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -45,6 +45,10 @@ def process_image_descriptions(entities): for media in entities["media"]: if media.get("ext_alt_text") != None: image_descriptions.append(media.get("ext_alt_text")) + # Tweets retrieved via the Streaming API have a description field in media photos with image description available. + elif media.get("description") != None: + image_descriptions.append(media.get("description")) + idescriptions = "" for image in image_descriptions: idescriptions += _("Image description: {}.").format(image) From 6e0a94355f7836a4a512204b01b3da27cbe4fca8 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 25 Jan 2022 10:42:39 -0600 Subject: [PATCH 78/83] Improvements to template substitutions. Closes #452 --- src/sessions/twitter/templates.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/sessions/twitter/templates.py b/src/sessions/twitter/templates.py index 46913220..ec54a13d 100644 --- a/src/sessions/twitter/templates.py +++ b/src/sessions/twitter/templates.py @@ -54,6 +54,11 @@ def process_image_descriptions(entities): idescriptions += _("Image description: {}.").format(image) return idescriptions +def remove_unneeded_variables(template, variables): + for variable in variables: + template = re.sub("\$"+variable, "", template) + return template + def render_tweet(tweet, template, session, relative_times=False, offset_seconds=0): """ Renders any given Tweet according to the passed template. Available data for tweets will be stored in the following variables: @@ -65,6 +70,7 @@ def render_tweet(tweet, template, session, relative_times=False, offset_seconds= $text: Tweet text. $image_descriptions: Information regarding image descriptions added by twitter users. """ + global tweet_variables available_data = dict() created_at = process_date(tweet.created_at, relative_times, offset_seconds) available_data.update(date=created_at) @@ -93,7 +99,7 @@ def render_tweet(tweet, template, session, relative_times=False, offset_seconds= if image_descriptions != "": available_data.update(image_descriptions=image_descriptions) result = Template(_(template)).safe_substitute(**available_data) - result = re.sub(r"\$\w+", "", result) + result = remove_unneeded_variables(result, tweet_variables) return result def render_dm(dm, template, session, relative_times=False, offset_seconds=0): @@ -106,6 +112,7 @@ def render_dm(dm, template, session, relative_times=False, offset_seconds=0): $recipient_screen_name: User screen name for user receiving the dm, this is the same name used to reference the user in Twitter. $text: Text of the direct message. """ + global dm_variables available_data = dict() available_data.update(text=utils.expand_urls(dm.message_create["message_data"]["text"], dm.message_create["message_data"]["entities"])) # Let's remove the last 3 digits in the timestamp string. @@ -120,7 +127,7 @@ def render_dm(dm, template, session, relative_times=False, offset_seconds=0): recipient = session.get_user(dm.message_create["target"]["recipient_id"]) available_data.update(sender_display_name=sender.name, sender_screen_name=sender.screen_name, recipient_display_name=recipient.name, recipient_screen_name=recipient.screen_name) result = Template(_(template)).safe_substitute(**available_data) - result = re.sub(r"\$\w+", "", result) + result = remove_unneeded_variables(result, dm_variables) return result # Sesion object is not used in this function but we keep compatibility across all rendering functions. @@ -138,6 +145,7 @@ def render_person(user, template, session=None, relative_times=True, offset_seco $tweets: The number of Tweets (including retweets) issued by the user. This value might be inaccurate. $created_at: The date and time that the user account was created on Twitter. """ + global person_variables available_data = dict(display_name=user.name, screen_name=user.screen_name, followers=user.followers_count, following=user.friends_count, likes=user.favourites_count, listed=user.listed_count, tweets=user.statuses_count) # Nullable values. nullables = ["location", "description"] @@ -147,5 +155,5 @@ def render_person(user, template, session=None, relative_times=True, offset_seco created_at = process_date(user.created_at, relative_times=relative_times, offset_seconds=offset_seconds) available_data.update(created_at=created_at) result = Template(_(template)).safe_substitute(**available_data) - result = re.sub(r"\$\w+", "", result) + result = remove_unneeded_variables(result, person_variables) return result \ No newline at end of file From ac0e7380b058f45b259994f8ffc5de207655cc7d Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 25 Jan 2022 12:01:03 -0600 Subject: [PATCH 79/83] TWBlue should not allow users to retweet or quote any protected account. Closes #454 --- src/controller/buffers/base/base.py | 3 +++ src/controller/buffers/twitter/base.py | 11 +++++++++++ src/controller/mainController.py | 5 +++++ 3 files changed, 19 insertions(+) diff --git a/src/controller/buffers/base/base.py b/src/controller/buffers/base/base.py index 41b31219..178dbd10 100644 --- a/src/controller/buffers/base/base.py +++ b/src/controller/buffers/base/base.py @@ -125,6 +125,9 @@ class Buffer(object): def share_item(self): pass + def can_share(self): + pass + def destroy_status(self): pass diff --git a/src/controller/buffers/twitter/base.py b/src/controller/buffers/twitter/base.py index 838d0cf1..7ebea416 100644 --- a/src/controller/buffers/twitter/base.py +++ b/src/controller/buffers/twitter/base.py @@ -391,6 +391,12 @@ class BaseBuffer(base.Buffer): tweet = self.session.db[self.name][self.buffer.list.get_selected()] return tweet + def can_share(self): + tweet = self.get_right_tweet() + user = self.session.get_user(tweet.user) + is_protected = user.protected + return is_protected==False + @_tweets_exist def reply(self, *args, **kwargs): tweet = self.get_right_tweet() @@ -442,6 +448,8 @@ class BaseBuffer(base.Buffer): @_tweets_exist def share_item(self, *args, **kwargs): + if self.can_share() == False: + return output.speak(_("This action is not supported on protected accounts.")) tweet = self.get_right_tweet() id = tweet.id if self.session.settings["general"]["retweet_mode"] == "ask": @@ -483,6 +491,9 @@ class BaseBuffer(base.Buffer): self.session.sound.play("geo.ogg") if self.session.settings['sound']['indicate_img'] and utils.is_media(tweet): self.session.sound.play("image.ogg") + can_share = self.can_share() + pub.sendMessage("toggleShare", shareable=can_share) + self.buffer.retweet.Enable(can_share) def audio(self, url='', *args, **kwargs): if sound.URLPlayer.player.is_playing(): diff --git a/src/controller/mainController.py b/src/controller/mainController.py index a8f4130d..cc24c47a 100644 --- a/src/controller/mainController.py +++ b/src/controller/mainController.py @@ -134,6 +134,7 @@ class Controller(object): pub.subscribe(self.manage_blocked_user, "blocked-user") pub.subscribe(self.manage_unblocked_user, "unblocked-user") pub.subscribe(self.create_buffer, "createBuffer") + pub.subscribe(self.toggle_share_settings, "toggleShare") if system == "Windows": pub.subscribe(self.invisible_shorcuts_changed, "invisible-shorcuts-changed") widgetUtils.connect_event(self.view, widgetUtils.MENU, self.show_hide, menuitem=self.view.show_hide) @@ -1657,6 +1658,10 @@ class Controller(object): if sound_to_play != None and buff not in buffer.session.settings["other_buffers"]["muted_buffers"]: self.notify(buffer.session, sound_to_play) + def toggle_share_settings(self, shareable=True): + self.view.retweet.Enable(shareable) + + def check_streams(self): if self.started == False: return From 3d452b3db89d10500c94b3d134eb82cb1889d854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20Bacqu=C3=A9-Cazenave?= Date: Wed, 26 Jan 2022 18:27:32 +0100 Subject: [PATCH 80/83] Update french translations --- src/locales/fr/LC_MESSAGES/twblue.po | 254 ++++++++++++++------------- 1 file changed, 129 insertions(+), 125 deletions(-) diff --git a/src/locales/fr/LC_MESSAGES/twblue.po b/src/locales/fr/LC_MESSAGES/twblue.po index 02c9859b..82c2c0b9 100644 --- a/src/locales/fr/LC_MESSAGES/twblue.po +++ b/src/locales/fr/LC_MESSAGES/twblue.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: TW Blue 0.94\n" -"POT-Creation-Date: 2021-12-22 18:18+0100\n" -"PO-Revision-Date: 2021-12-27 23:24+0100\n" +"POT-Creation-Date: 2022-01-26 18:25+0100\n" +"PO-Revision-Date: 2022-01-26 18:26+0100\n" "Last-Translator: Corentin Bacqué-Cazenave \n" "Language-Team: Corentin Bacqué-Cazenave \n" "Language: fr\n" @@ -21,56 +21,56 @@ msgid "This action is not supported for this buffer" msgstr "Cette action n'est pas supportée pour ce tampon" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:337 ../src\controller\settings.py:323 +#: ../src\controller\mainController.py:338 ../src\controller\settings.py:323 msgid "Home" msgstr "Accueil" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:339 ../src\controller\settings.py:324 +#: ../src\controller\mainController.py:340 ../src\controller\settings.py:324 msgid "Mentions" msgstr "Mentions" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:341 +#: ../src\controller\mainController.py:342 msgid "Direct messages" msgstr "Messages" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:343 ../src\controller\settings.py:326 +#: ../src\controller\mainController.py:344 ../src\controller\settings.py:326 msgid "Sent direct messages" msgstr "Messages envoyés" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:345 ../src\controller\settings.py:327 +#: ../src\controller\mainController.py:346 ../src\controller\settings.py:327 msgid "Sent tweets" msgstr "Tweets envoyés" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:347 -#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:328 +#: ../src\controller\mainController.py:348 +#: ../src\controller\mainController.py:1391 ../src\controller\settings.py:328 msgid "Likes" msgstr "Favoris" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:329 +#: ../src\controller\mainController.py:350 +#: ../src\controller\mainController.py:1396 ../src\controller\settings.py:329 msgid "Followers" msgstr "Abonnés" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:353 -#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:331 +#: ../src\controller\mainController.py:354 +#: ../src\controller\mainController.py:1406 ../src\controller\settings.py:331 msgid "Blocked users" msgstr "Utilisateurs bloqués" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:355 -#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:332 +#: ../src\controller\mainController.py:356 +#: ../src\controller\mainController.py:1411 ../src\controller\settings.py:332 msgid "Muted users" msgstr "Utilisateurs masqués" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:330 +#: ../src\controller\mainController.py:1401 ../src\controller\settings.py:330 msgid "Friends" msgstr "Abonnements" @@ -129,46 +129,50 @@ msgstr "%s éléments récupérés" msgid "This buffer is not a timeline; it can't be deleted." msgstr "Ce tampon n'est pas une chronologie ; Impossible de le supprimé." -#: ../src\controller\buffers\twitter\base.py:404 +#: ../src\controller\buffers\twitter\base.py:410 msgid "Reply to {arg0}" msgstr "Répondre à {arg0}" -#: ../src\controller\buffers\twitter\base.py:406 +#: ../src\controller\buffers\twitter\base.py:412 #: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "Répondre" -#: ../src\controller\buffers\twitter\base.py:407 +#: ../src\controller\buffers\twitter\base.py:413 msgid "Reply to %s" msgstr "Répondre à %s" -#: ../src\controller\buffers\twitter\base.py:430 +#: ../src\controller\buffers\twitter\base.py:436 #: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "Nouveau message" -#: ../src\controller\buffers\twitter\base.py:430 +#: ../src\controller\buffers\twitter\base.py:436 #: ../src\controller\messages.py:268 msgid "Direct message to %s" msgstr "Message à %s" -#: ../src\controller\buffers\twitter\base.py:461 +#: ../src\controller\buffers\twitter\base.py:452 +msgid "This action is not supported on protected accounts." +msgstr "Cette action n'est pas supportée pour les comptes protégés." + +#: ../src\controller\buffers\twitter\base.py:469 msgid "Add your comment to the tweet" msgstr "Ajoutez votre commentaire pour le tweet" -#: ../src\controller\buffers\twitter\base.py:461 +#: ../src\controller\buffers\twitter\base.py:469 msgid "Quote" msgstr "Citer" -#: ../src\controller\buffers\twitter\base.py:522 +#: ../src\controller\buffers\twitter\base.py:533 msgid "Opening URL..." msgstr "Ouverture de l'URL..." -#: ../src\controller\buffers\twitter\base.py:559 +#: ../src\controller\buffers\twitter\base.py:570 msgid "User details" msgstr "Détails de l'utilisateur" -#: ../src\controller\buffers\twitter\base.py:580 +#: ../src\controller\buffers\twitter\base.py:591 msgid "Opening item in web browser..." msgstr "Ouverture de l'élément dans le navigateur Web..." @@ -207,85 +211,85 @@ msgstr "{0} nouvel abonné" msgid "This action is not supported in the buffer, yet." msgstr "Cette action n'est pas supportée pour le tampon actuel" -#: ../src\controller\mainController.py:277 +#: ../src\controller\mainController.py:278 msgid "Ready" msgstr "Prêt" -#: ../src\controller\mainController.py:351 +#: ../src\controller\mainController.py:352 msgid "Following" msgstr "Abonnements" -#: ../src\controller\mainController.py:356 +#: ../src\controller\mainController.py:357 msgid "Timelines" msgstr "Chronologies" -#: ../src\controller\mainController.py:359 -#: ../src\controller\mainController.py:883 -#: ../src\controller\mainController.py:1582 +#: ../src\controller\mainController.py:360 +#: ../src\controller\mainController.py:884 +#: ../src\controller\mainController.py:1583 msgid "Timeline for {}" msgstr "Chronologie de {}" -#: ../src\controller\mainController.py:360 +#: ../src\controller\mainController.py:361 msgid "Likes timelines" msgstr "Chronologies des favoris" -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:902 -#: ../src\controller\mainController.py:1584 +#: ../src\controller\mainController.py:364 +#: ../src\controller\mainController.py:903 +#: ../src\controller\mainController.py:1585 msgid "Likes for {}" msgstr "Favoris de {}" -#: ../src\controller\mainController.py:364 +#: ../src\controller\mainController.py:365 msgid "Followers timelines" msgstr "Chronologies des abonnés" -#: ../src\controller\mainController.py:367 -#: ../src\controller\mainController.py:921 -#: ../src\controller\mainController.py:1586 +#: ../src\controller\mainController.py:368 +#: ../src\controller\mainController.py:922 +#: ../src\controller\mainController.py:1587 msgid "Followers for {}" msgstr "Abonnés de {}" -#: ../src\controller\mainController.py:368 +#: ../src\controller\mainController.py:369 msgid "Following timelines" msgstr "Chronologies des abonnements" -#: ../src\controller\mainController.py:371 -#: ../src\controller\mainController.py:940 -#: ../src\controller\mainController.py:1588 +#: ../src\controller\mainController.py:372 +#: ../src\controller\mainController.py:941 +#: ../src\controller\mainController.py:1589 msgid "Friends for {}" msgstr "Abonnements de {}" -#: ../src\controller\mainController.py:372 ../src\wxUI\dialogs\lists.py:13 +#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:13 msgid "Lists" msgstr "Listes" -#: ../src\controller\mainController.py:375 -#: ../src\controller\mainController.py:1422 +#: ../src\controller\mainController.py:376 +#: ../src\controller\mainController.py:1423 msgid "List for {}" msgstr "Liste {}" -#: ../src\controller\mainController.py:376 +#: ../src\controller\mainController.py:377 msgid "Searches" msgstr "Recherches" -#: ../src\controller\mainController.py:379 -#: ../src\controller\mainController.py:426 -#: ../src\controller\mainController.py:431 +#: ../src\controller\mainController.py:380 +#: ../src\controller\mainController.py:427 +#: ../src\controller\mainController.py:432 msgid "Search for {}" msgstr "Recherche de {}" -#: ../src\controller\mainController.py:381 -#: ../src\controller\mainController.py:982 -#: ../src\controller\mainController.py:1590 +#: ../src\controller\mainController.py:382 +#: ../src\controller\mainController.py:983 +#: ../src\controller\mainController.py:1591 msgid "Trending topics for %s" msgstr "Tendances pour %s" -#: ../src\controller\mainController.py:448 -#: ../src\controller\mainController.py:464 -#: ../src\controller\mainController.py:1080 -#: ../src\controller\mainController.py:1099 -#: ../src\controller\mainController.py:1118 -#: ../src\controller\mainController.py:1137 +#: ../src\controller\mainController.py:449 +#: ../src\controller\mainController.py:465 +#: ../src\controller\mainController.py:1081 +#: ../src\controller\mainController.py:1100 +#: ../src\controller\mainController.py:1119 +#: ../src\controller\mainController.py:1138 msgid "" "No session is currently in focus. Focus a session with the next or previous " "session shortcut." @@ -293,152 +297,152 @@ msgstr "" "Aucune session n'a actuellement le focus. Sélectionnez-en une avec le " "raccourci pour la session précédente ou suivante." -#: ../src\controller\mainController.py:452 +#: ../src\controller\mainController.py:453 msgid "Empty buffer." msgstr "Tampon vide." -#: ../src\controller\mainController.py:459 +#: ../src\controller\mainController.py:460 msgid "{0} not found." msgstr "{0} introuvable." -#: ../src\controller\mainController.py:469 +#: ../src\controller\mainController.py:470 msgid "Filters cannot be applied on this buffer" msgstr "Les filtres ne peuvent pas s'appliquer à ce tampon" -#: ../src\controller\mainController.py:522 -#: ../src\controller\mainController.py:539 -#: ../src\controller\mainController.py:568 +#: ../src\controller\mainController.py:523 +#: ../src\controller\mainController.py:540 +#: ../src\controller\mainController.py:569 msgid "Select the user" msgstr "Sélectionnez l'utilisateur" -#: ../src\controller\mainController.py:753 +#: ../src\controller\mainController.py:754 msgid "Add an user alias" msgstr "Ajoute un alias pour l'utilisateur" -#: ../src\controller\mainController.py:761 +#: ../src\controller\mainController.py:762 msgid "Alias has been set correctly for {}." msgstr "L'alias pour {} a correctement été définie" -#: ../src\controller\mainController.py:829 ../src\controller\messages.py:327 +#: ../src\controller\mainController.py:830 ../src\controller\messages.py:327 msgid "MMM D, YYYY. H:m" msgstr "D MMM YYYY à H:m" -#: ../src\controller\mainController.py:957 +#: ../src\controller\mainController.py:958 msgid "Conversation with {0}" msgstr "Conversation avec {0}" -#: ../src\controller\mainController.py:998 -#: ../src\controller\mainController.py:1015 +#: ../src\controller\mainController.py:999 +#: ../src\controller\mainController.py:1016 msgid "There are no coordinates in this tweet" msgstr "Il n'y a aucune coordonnée dans ce tweet" -#: ../src\controller\mainController.py:1000 -#: ../src\controller\mainController.py:1019 +#: ../src\controller\mainController.py:1001 +#: ../src\controller\mainController.py:1020 msgid "Error decoding coordinates. Try again later." msgstr "Erreur pendant le décodage des coordonnées. Réessayez plus tard." -#: ../src\controller\mainController.py:1004 +#: ../src\controller\mainController.py:1005 msgid "Unable to find address in OpenStreetMap." msgstr "Impossible de trouver l'adresse dans OpenStreetMap" -#: ../src\controller\mainController.py:1017 +#: ../src\controller\mainController.py:1018 msgid "There are no results for the coordinates in this tweet" msgstr "Il n'y a aucun résultat pour les coordonnées dans ce tweet" -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1147 +#: ../src\controller\mainController.py:1129 +#: ../src\controller\mainController.py:1148 msgid "%s, %s of %s" msgstr "%s, %s de %s" -#: ../src\controller\mainController.py:1130 -#: ../src\controller\mainController.py:1149 -#: ../src\controller\mainController.py:1174 -#: ../src\controller\mainController.py:1199 +#: ../src\controller\mainController.py:1131 +#: ../src\controller\mainController.py:1150 +#: ../src\controller\mainController.py:1175 +#: ../src\controller\mainController.py:1200 msgid "%s. Empty" msgstr "%s. Vide" -#: ../src\controller\mainController.py:1162 -#: ../src\controller\mainController.py:1166 -#: ../src\controller\mainController.py:1187 +#: ../src\controller\mainController.py:1163 +#: ../src\controller\mainController.py:1167 +#: ../src\controller\mainController.py:1188 msgid "{0}: This account is not logged into Twitter." msgstr "{0}: Ce compte n'est pas connecté à twitter." -#: ../src\controller\mainController.py:1172 -#: ../src\controller\mainController.py:1197 +#: ../src\controller\mainController.py:1173 +#: ../src\controller\mainController.py:1198 msgid "%s. %s, %s of %s" msgstr "%s. %s, %s de %s" -#: ../src\controller\mainController.py:1191 +#: ../src\controller\mainController.py:1192 msgid "{0}: This account is not logged into twitter." msgstr "{0}: Ce compte n'est pas connecté à twitter." -#: ../src\controller\mainController.py:1416 +#: ../src\controller\mainController.py:1417 msgid "This list is already opened" msgstr "Cette liste est déjà ouverte" -#: ../src\controller\mainController.py:1446 -#: ../src\controller\mainController.py:1462 +#: ../src\controller\mainController.py:1447 +#: ../src\controller\mainController.py:1463 msgid "" "An error happened while trying to connect to the server. Please try later." msgstr "" "Une erreur s'est produite en essayant de se connecter au serveur. Veuillez " "réessayer plus tard." -#: ../src\controller\mainController.py:1498 +#: ../src\controller\mainController.py:1499 msgid "The auto-reading of new tweets is enabled for this buffer" msgstr "La lecture automatique des nouveaux tweets est activée pour ce tampon" -#: ../src\controller\mainController.py:1501 +#: ../src\controller\mainController.py:1502 msgid "The auto-reading of new tweets is disabled for this buffer" msgstr "" "La lecture automatique des nouveaux tweets est désactivée pour ce tampon" -#: ../src\controller\mainController.py:1508 +#: ../src\controller\mainController.py:1509 msgid "Session mute on" msgstr "Session muet" -#: ../src\controller\mainController.py:1511 +#: ../src\controller\mainController.py:1512 msgid "Session mute off" msgstr "Session non muet" -#: ../src\controller\mainController.py:1519 +#: ../src\controller\mainController.py:1520 msgid "Buffer mute on" msgstr "Tampon muet" -#: ../src\controller\mainController.py:1522 +#: ../src\controller\mainController.py:1523 msgid "Buffer mute off" msgstr "Tampon non muet" -#: ../src\controller\mainController.py:1542 +#: ../src\controller\mainController.py:1543 msgid "Copied" msgstr "Copié" -#: ../src\controller\mainController.py:1572 +#: ../src\controller\mainController.py:1573 msgid "Unable to update this buffer." msgstr "Impossible de mettre à jour ce tampon." -#: ../src\controller\mainController.py:1575 +#: ../src\controller\mainController.py:1576 msgid "Updating buffer..." msgstr "Actualisation..." -#: ../src\controller\mainController.py:1578 +#: ../src\controller\mainController.py:1579 msgid "{0} items retrieved" msgstr "{0} éléments récupérés" -#: ../src\controller\mainController.py:1597 -#: ../src\controller\mainController.py:1617 +#: ../src\controller\mainController.py:1598 +#: ../src\controller\mainController.py:1618 msgid "Invalid buffer" msgstr "Tampon invalide" -#: ../src\controller\mainController.py:1608 +#: ../src\controller\mainController.py:1609 msgid "Picture {0}" msgstr "Photo {0}" -#: ../src\controller\mainController.py:1609 +#: ../src\controller\mainController.py:1610 msgid "Select the picture" msgstr "Sélectionner la photo" -#: ../src\controller\mainController.py:1628 +#: ../src\controller\mainController.py:1629 msgid "Unable to extract text" msgstr "Impossible d'extraire le texte" @@ -454,7 +458,7 @@ msgstr "%s - %s/%d caractères" msgid "View item" msgstr "Voir l'élément" -#: ../src\controller\messages.py:379 +#: ../src\controller\messages.py:380 msgid "Link copied to clipboard." msgstr "Lien copié dans le Presse-papiers" @@ -1968,27 +1972,27 @@ msgstr "" "elle va être détruite et recréée automatiquement. Si ce problème perciste, " "veuillez envoyer le journal d'erreur aux développeurs de {app}." -#: ../src\sessions\twitter\compose.py:38 ../src\sessions\twitter\compose.py:81 -#: ../src\sessions\twitter\compose.py:146 -#: ../src\sessions\twitter\compose.py:155 +#: ../src\sessions\twitter\compose.py:25 ../src\sessions\twitter\compose.py:68 +#: ../src\sessions\twitter\compose.py:133 +#: ../src\sessions\twitter\compose.py:142 #: ../src\sessions\twitter\templates.py:26 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "dddd D MMMM YYYY à H:m:s" -#: ../src\sessions\twitter\compose.py:89 ../src\sessions\twitter\compose.py:91 +#: ../src\sessions\twitter\compose.py:76 ../src\sessions\twitter\compose.py:78 msgid "Dm to %s " msgstr "Mp à %s" -#: ../src\sessions\twitter\compose.py:130 +#: ../src\sessions\twitter\compose.py:117 msgid "{0}. Quoted tweet from @{1}: {2}" msgstr "{0}. Tweet de @{1} cité : {2}" -#: ../src\sessions\twitter\compose.py:157 -#: ../src\sessions\twitter\compose.py:159 +#: ../src\sessions\twitter\compose.py:144 +#: ../src\sessions\twitter\compose.py:146 msgid "Unavailable" msgstr "Indisponible" -#: ../src\sessions\twitter\compose.py:160 +#: ../src\sessions\twitter\compose.py:147 msgid "" "%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " "Twitter %s" @@ -1996,15 +2000,15 @@ msgstr "" "%s (@%s). %s abonnés, %s abonnements, %s tweets. Dernier tweet envoyé %s. À " "rejoint Twitter %s" -#: ../src\sessions\twitter\compose.py:164 +#: ../src\sessions\twitter\compose.py:151 msgid "No description available" msgstr "Aucune description disponible" -#: ../src\sessions\twitter\compose.py:168 +#: ../src\sessions\twitter\compose.py:155 msgid "private" msgstr "privé" -#: ../src\sessions\twitter\compose.py:169 +#: ../src\sessions\twitter\compose.py:156 msgid "public" msgstr "public" @@ -2018,8 +2022,8 @@ msgstr "%s erreur. Raison: %s" msgid "%s succeeded." msgstr "%s réussi." -#: ../src\sessions\twitter\session.py:450 -#: ../src\sessions\twitter\session.py:528 +#: ../src\sessions\twitter\session.py:451 +#: ../src\sessions\twitter\session.py:529 msgid "Deleted account" msgstr "Compte supprimé" @@ -2043,23 +2047,23 @@ msgstr "" "$display_name (@$screen_name). $followers abonnés, $following abonnements, " "$tweets tweets. À rejoint Twitter $created_at." -#: ../src\sessions\twitter\templates.py:50 +#: ../src\sessions\twitter\templates.py:54 msgid "Image description: {}." msgstr "Description de l'image: {}." -#: ../src\sessions\twitter\utils.py:229 +#: ../src\sessions\twitter\utils.py:243 msgid "Sorry, you are not authorised to see this status." msgstr "Désolé, vous n'êtes pas autorisé à voir ce Tweet." -#: ../src\sessions\twitter\utils.py:231 +#: ../src\sessions\twitter\utils.py:245 msgid "No status found with that ID" msgstr "Aucun Tweet trouvée avec cet ID" -#: ../src\sessions\twitter\utils.py:233 +#: ../src\sessions\twitter\utils.py:247 msgid "Error {0}" msgstr "Erreur {0}" -#: ../src\sessions\twitter\utils.py:260 +#: ../src\sessions\twitter\utils.py:274 msgid "{user_1}, {user_2} and {all_users} more: {text}" msgstr "{user_1}, {user_2} et {all_users} de plus : {text}" From 8e95843634c70a0b4f1ecc925249e8ddbdd25dde Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 15 Feb 2022 15:59:35 -0600 Subject: [PATCH 81/83] Updated to Tweepy V4.5.0 --- src/sessions/twitter/session.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sessions/twitter/session.py b/src/sessions/twitter/session.py index 3c84d0e0..e3ac4139 100644 --- a/src/sessions/twitter/session.py +++ b/src/sessions/twitter/session.py @@ -136,7 +136,7 @@ class Session(base.baseSession): if self.settings["twitter"]["user_key"] != None and self.settings["twitter"]["user_secret"] != None: try: log.debug("Logging in to twitter...") - self.auth = tweepy.OAuthHandler(appkeys.twitter_api_key, appkeys.twitter_api_secret) + self.auth = tweepy.OAuth1UserHandler(appkeys.twitter_api_key, appkeys.twitter_api_secret) self.auth.set_access_token(self.settings["twitter"]["user_key"], self.settings["twitter"]["user_secret"]) self.twitter = tweepy.API(self.auth) self.twitter_v2 = tweepy.Client(consumer_key=appkeys.twitter_api_key, consumer_secret=appkeys.twitter_api_secret, access_token=self.settings["twitter"]["user_key"], access_token_secret=self.settings["twitter"]["user_secret"]) @@ -158,7 +158,7 @@ class Session(base.baseSession): if self.logged == True: raise Exceptions.AlreadyAuthorisedError("The authorisation process is not needed at this time.") else: - self.auth = tweepy.OAuthHandler(appkeys.twitter_api_key, appkeys.twitter_api_secret) + self.auth = tweepy.OAuth1UserHandler(appkeys.twitter_api_key, appkeys.twitter_api_secret) redirect_url = self.auth.get_authorization_url() webbrowser.open_new_tab(redirect_url) self.authorisation_dialog = authorisationDialog() From 540a99f02fdd0ae33b3be107056e6bdfd07c5826 Mon Sep 17 00:00:00 2001 From: riku Date: Wed, 16 Feb 2022 08:03:27 +0900 Subject: [PATCH 82/83] Update Japanese translation --- src/locales/ja/lc_messages/twblue.mo | Bin 65368 -> 65599 bytes src/locales/ja/lc_messages/twblue.po | 252 ++++++++++++++------------- 2 files changed, 128 insertions(+), 124 deletions(-) diff --git a/src/locales/ja/lc_messages/twblue.mo b/src/locales/ja/lc_messages/twblue.mo index b138d79086bdc1b7958a3ea4f178a36a42d07500..d95b4f062b4b4f20537e18c91fdaa9087265a9e3 100644 GIT binary patch delta 17433 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 delta 17286 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 bsKT+OV~cFqJ8|0w)1n@x*zntp78(B!wjxGH diff --git a/src/locales/ja/lc_messages/twblue.po b/src/locales/ja/lc_messages/twblue.po index a3164f6e..0caa2a10 100644 --- a/src/locales/ja/lc_messages/twblue.po +++ b/src/locales/ja/lc_messages/twblue.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-29 15:52+0900\n" +"PO-Revision-Date: 2022-02-16 08:01+0900\n" "Last-Translator: 陸 \n" "Language-Team: \n" "Language: ja_JP\n" @@ -23,56 +23,56 @@ msgid "This action is not supported for this buffer" msgstr "この動作は、現在のバッファではサポートされていません" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:337 ../src\controller\settings.py:323 +#: ../src\controller\mainController.py:338 ../src\controller\settings.py:323 msgid "Home" msgstr "ホーム" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:339 ../src\controller\settings.py:324 +#: ../src\controller\mainController.py:340 ../src\controller\settings.py:324 msgid "Mentions" msgstr "メンション" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:341 +#: ../src\controller\mainController.py:342 msgid "Direct messages" msgstr "ダイレクトメッセージ" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:343 ../src\controller\settings.py:326 +#: ../src\controller\mainController.py:344 ../src\controller\settings.py:326 msgid "Sent direct messages" msgstr "送信済みのダイレクトメッセージ" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:345 ../src\controller\settings.py:327 +#: ../src\controller\mainController.py:346 ../src\controller\settings.py:327 msgid "Sent tweets" msgstr "送信済みのツイート" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:347 -#: ../src\controller\mainController.py:1390 ../src\controller\settings.py:328 +#: ../src\controller\mainController.py:348 +#: ../src\controller\mainController.py:1391 ../src\controller\settings.py:328 msgid "Likes" msgstr "いいね" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:349 -#: ../src\controller\mainController.py:1395 ../src\controller\settings.py:329 +#: ../src\controller\mainController.py:350 +#: ../src\controller\mainController.py:1396 ../src\controller\settings.py:329 msgid "Followers" msgstr "フォロワー" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:353 -#: ../src\controller\mainController.py:1405 ../src\controller\settings.py:331 +#: ../src\controller\mainController.py:354 +#: ../src\controller\mainController.py:1406 ../src\controller\settings.py:331 msgid "Blocked users" msgstr "ブロックしたユーザー" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:355 -#: ../src\controller\mainController.py:1410 ../src\controller\settings.py:332 +#: ../src\controller\mainController.py:356 +#: ../src\controller\mainController.py:1411 ../src\controller\settings.py:332 msgid "Muted users" msgstr "ミューとしたユーザー" #: ../src\controller\buffers\twitter\base.py:70 -#: ../src\controller\mainController.py:1400 ../src\controller\settings.py:330 +#: ../src\controller\mainController.py:1401 ../src\controller\settings.py:330 msgid "Friends" msgstr "フォロー" @@ -131,46 +131,50 @@ msgstr "%s個のアイテムを取得しました" msgid "This buffer is not a timeline; it can't be deleted." msgstr "このバッファは、タイムラインではないため、削除できません。" -#: ../src\controller\buffers\twitter\base.py:404 +#: ../src\controller\buffers\twitter\base.py:410 msgid "Reply to {arg0}" msgstr "「{arg0}」への返信:" -#: ../src\controller\buffers\twitter\base.py:406 +#: ../src\controller\buffers\twitter\base.py:412 #: ../src\keystrokeEditor\constants.py:11 ../src\wxUI\buffers\base.py:27 msgid "Reply" msgstr "返信" -#: ../src\controller\buffers\twitter\base.py:407 +#: ../src\controller\buffers\twitter\base.py:413 msgid "Reply to %s" msgstr "「%s」への返信" -#: ../src\controller\buffers\twitter\base.py:430 +#: ../src\controller\buffers\twitter\base.py:436 #: ../src\controller\buffers\twitter\directMessages.py:124 msgid "New direct message" msgstr "新しいダイレクトメッセージ" -#: ../src\controller\buffers\twitter\base.py:430 +#: ../src\controller\buffers\twitter\base.py:436 #: ../src\controller\messages.py:268 msgid "Direct message to %s" msgstr "「%s」へのダイレクトメッセージ" -#: ../src\controller\buffers\twitter\base.py:461 +#: ../src\controller\buffers\twitter\base.py:452 +msgid "This action is not supported on protected accounts." +msgstr "この動作は、保護されたアカウントではサポートされていません。" + +#: ../src\controller\buffers\twitter\base.py:469 msgid "Add your comment to the tweet" msgstr "ツイートにコメントを追加" -#: ../src\controller\buffers\twitter\base.py:461 +#: ../src\controller\buffers\twitter\base.py:469 msgid "Quote" msgstr "引用" -#: ../src\controller\buffers\twitter\base.py:522 +#: ../src\controller\buffers\twitter\base.py:533 msgid "Opening URL..." msgstr "URLを開いています…" -#: ../src\controller\buffers\twitter\base.py:559 +#: ../src\controller\buffers\twitter\base.py:570 msgid "User details" msgstr "ユーザーの詳細" -#: ../src\controller\buffers\twitter\base.py:580 +#: ../src\controller\buffers\twitter\base.py:591 msgid "Opening item in web browser..." msgstr "ブラウザでアイテムを開いています…" @@ -209,85 +213,85 @@ msgstr "{0}人の新しいフォロワー。" msgid "This action is not supported in the buffer, yet." msgstr "この動作は、現在のバッファではサポートされていません。" -#: ../src\controller\mainController.py:277 +#: ../src\controller\mainController.py:278 msgid "Ready" msgstr "準備完了" -#: ../src\controller\mainController.py:351 +#: ../src\controller\mainController.py:352 msgid "Following" msgstr "フォロー中" -#: ../src\controller\mainController.py:356 +#: ../src\controller\mainController.py:357 msgid "Timelines" msgstr "タイムライン" -#: ../src\controller\mainController.py:359 -#: ../src\controller\mainController.py:883 -#: ../src\controller\mainController.py:1582 +#: ../src\controller\mainController.py:360 +#: ../src\controller\mainController.py:884 +#: ../src\controller\mainController.py:1583 msgid "Timeline for {}" msgstr "「{}」のタイムライン" -#: ../src\controller\mainController.py:360 +#: ../src\controller\mainController.py:361 msgid "Likes timelines" msgstr "ほかのユーザーのいいね一覧" -#: ../src\controller\mainController.py:363 -#: ../src\controller\mainController.py:902 -#: ../src\controller\mainController.py:1584 +#: ../src\controller\mainController.py:364 +#: ../src\controller\mainController.py:903 +#: ../src\controller\mainController.py:1585 msgid "Likes for {}" msgstr "{}のいいね一覧" -#: ../src\controller\mainController.py:364 +#: ../src\controller\mainController.py:365 msgid "Followers timelines" msgstr "フォロワー一覧" -#: ../src\controller\mainController.py:367 -#: ../src\controller\mainController.py:921 -#: ../src\controller\mainController.py:1586 +#: ../src\controller\mainController.py:368 +#: ../src\controller\mainController.py:922 +#: ../src\controller\mainController.py:1587 msgid "Followers for {}" msgstr "{}をフォローしているユーザー" -#: ../src\controller\mainController.py:368 +#: ../src\controller\mainController.py:369 msgid "Following timelines" msgstr "フォロー一覧" -#: ../src\controller\mainController.py:371 -#: ../src\controller\mainController.py:940 -#: ../src\controller\mainController.py:1588 +#: ../src\controller\mainController.py:372 +#: ../src\controller\mainController.py:941 +#: ../src\controller\mainController.py:1589 msgid "Friends for {}" msgstr "{}がフォローしているユーザー" -#: ../src\controller\mainController.py:372 ../src\wxUI\dialogs\lists.py:13 +#: ../src\controller\mainController.py:373 ../src\wxUI\dialogs\lists.py:13 msgid "Lists" msgstr "リスト" -#: ../src\controller\mainController.py:375 -#: ../src\controller\mainController.py:1422 +#: ../src\controller\mainController.py:376 +#: ../src\controller\mainController.py:1423 msgid "List for {}" msgstr "{}のリスト" -#: ../src\controller\mainController.py:376 +#: ../src\controller\mainController.py:377 msgid "Searches" msgstr "検索" -#: ../src\controller\mainController.py:379 -#: ../src\controller\mainController.py:426 -#: ../src\controller\mainController.py:431 +#: ../src\controller\mainController.py:380 +#: ../src\controller\mainController.py:427 +#: ../src\controller\mainController.py:432 msgid "Search for {}" msgstr "「{}」の検索結果" -#: ../src\controller\mainController.py:381 -#: ../src\controller\mainController.py:982 -#: ../src\controller\mainController.py:1590 +#: ../src\controller\mainController.py:382 +#: ../src\controller\mainController.py:983 +#: ../src\controller\mainController.py:1591 msgid "Trending topics for %s" msgstr "%s のトレンド" -#: ../src\controller\mainController.py:448 -#: ../src\controller\mainController.py:464 -#: ../src\controller\mainController.py:1080 -#: ../src\controller\mainController.py:1099 -#: ../src\controller\mainController.py:1118 -#: ../src\controller\mainController.py:1137 +#: ../src\controller\mainController.py:449 +#: ../src\controller\mainController.py:465 +#: ../src\controller\mainController.py:1081 +#: ../src\controller\mainController.py:1100 +#: ../src\controller\mainController.py:1119 +#: ../src\controller\mainController.py:1138 msgid "" "No session is currently in focus. Focus a session with the next or previous " "session shortcut." @@ -295,151 +299,151 @@ msgstr "" "セッションが選択されていません。「次のセッション」または「前のセッション」の" "ショートカットを利用して、セッションを選択してください。" -#: ../src\controller\mainController.py:452 +#: ../src\controller\mainController.py:453 msgid "Empty buffer." msgstr "からのバッファ。" -#: ../src\controller\mainController.py:459 +#: ../src\controller\mainController.py:460 msgid "{0} not found." msgstr "{0}が見つかりませんでした。" -#: ../src\controller\mainController.py:469 +#: ../src\controller\mainController.py:470 msgid "Filters cannot be applied on this buffer" msgstr "このバッファにはフィルターを適応できません" -#: ../src\controller\mainController.py:522 -#: ../src\controller\mainController.py:539 -#: ../src\controller\mainController.py:568 +#: ../src\controller\mainController.py:523 +#: ../src\controller\mainController.py:540 +#: ../src\controller\mainController.py:569 msgid "Select the user" msgstr "ユーザーを選択" -#: ../src\controller\mainController.py:753 +#: ../src\controller\mainController.py:754 msgid "Add an user alias" msgstr "ユーザーエイリアスを追加" -#: ../src\controller\mainController.py:761 +#: ../src\controller\mainController.py:762 msgid "Alias has been set correctly for {}." msgstr "{}のエイリアスが正しく設定されています。" -#: ../src\controller\mainController.py:829 ../src\controller\messages.py:327 +#: ../src\controller\mainController.py:830 ../src\controller\messages.py:327 msgid "MMM D, YYYY. H:m" msgstr "YYYY年MMMMD日 H時m分" -#: ../src\controller\mainController.py:957 +#: ../src\controller\mainController.py:958 msgid "Conversation with {0}" msgstr "{0}との会話" -#: ../src\controller\mainController.py:998 -#: ../src\controller\mainController.py:1015 +#: ../src\controller\mainController.py:999 +#: ../src\controller\mainController.py:1016 msgid "There are no coordinates in this tweet" msgstr "このツイートに位置情報は存在しません" -#: ../src\controller\mainController.py:1000 -#: ../src\controller\mainController.py:1019 +#: ../src\controller\mainController.py:1001 +#: ../src\controller\mainController.py:1020 msgid "Error decoding coordinates. Try again later." msgstr "位置情報の取得に失敗しました。あとで再試行してください。" -#: ../src\controller\mainController.py:1004 +#: ../src\controller\mainController.py:1005 msgid "Unable to find address in OpenStreetMap." msgstr "OpenStreetMapでアドレスが見つかりません。" -#: ../src\controller\mainController.py:1017 +#: ../src\controller\mainController.py:1018 msgid "There are no results for the coordinates in this tweet" msgstr "このツイートの位置情報には、なにも含まれていません" -#: ../src\controller\mainController.py:1128 -#: ../src\controller\mainController.py:1147 +#: ../src\controller\mainController.py:1129 +#: ../src\controller\mainController.py:1148 msgid "%s, %s of %s" msgstr "%s %s/%s" -#: ../src\controller\mainController.py:1130 -#: ../src\controller\mainController.py:1149 -#: ../src\controller\mainController.py:1174 -#: ../src\controller\mainController.py:1199 +#: ../src\controller\mainController.py:1131 +#: ../src\controller\mainController.py:1150 +#: ../src\controller\mainController.py:1175 +#: ../src\controller\mainController.py:1200 msgid "%s. Empty" msgstr "%sは、からです" -#: ../src\controller\mainController.py:1162 -#: ../src\controller\mainController.py:1166 -#: ../src\controller\mainController.py:1187 +#: ../src\controller\mainController.py:1163 +#: ../src\controller\mainController.py:1167 +#: ../src\controller\mainController.py:1188 msgid "{0}: This account is not logged into Twitter." msgstr "{0}: このアカウントは、まだTwitterにログインしていません。" -#: ../src\controller\mainController.py:1172 -#: ../src\controller\mainController.py:1197 +#: ../src\controller\mainController.py:1173 +#: ../src\controller\mainController.py:1198 msgid "%s. %s, %s of %s" msgstr "セッション:%s %s %s/%s" -#: ../src\controller\mainController.py:1191 +#: ../src\controller\mainController.py:1192 msgid "{0}: This account is not logged into twitter." msgstr "{0}: このアカウントは、まだTwitterにログインしていません。" -#: ../src\controller\mainController.py:1416 +#: ../src\controller\mainController.py:1417 msgid "This list is already opened" msgstr "既に開かれています" -#: ../src\controller\mainController.py:1446 -#: ../src\controller\mainController.py:1462 +#: ../src\controller\mainController.py:1447 +#: ../src\controller\mainController.py:1463 msgid "" "An error happened while trying to connect to the server. Please try later." msgstr "" "サーバーへの接続中に、予期しないエラーが発生しました。あとで再試行してくださ" "い。" -#: ../src\controller\mainController.py:1498 +#: ../src\controller\mainController.py:1499 msgid "The auto-reading of new tweets is enabled for this buffer" msgstr "自動読み上げ 有効" -#: ../src\controller\mainController.py:1501 +#: ../src\controller\mainController.py:1502 msgid "The auto-reading of new tweets is disabled for this buffer" msgstr "自動読み上げ 無効" -#: ../src\controller\mainController.py:1508 +#: ../src\controller\mainController.py:1509 msgid "Session mute on" msgstr "このセッションのミュートを設定" -#: ../src\controller\mainController.py:1511 +#: ../src\controller\mainController.py:1512 msgid "Session mute off" msgstr "このセッションのミュートを解除" -#: ../src\controller\mainController.py:1519 +#: ../src\controller\mainController.py:1520 msgid "Buffer mute on" msgstr "このバッファのミュートを設定" -#: ../src\controller\mainController.py:1522 +#: ../src\controller\mainController.py:1523 msgid "Buffer mute off" msgstr "このバッファのミュートを解除" -#: ../src\controller\mainController.py:1542 +#: ../src\controller\mainController.py:1543 msgid "Copied" msgstr "コピーしました" -#: ../src\controller\mainController.py:1572 +#: ../src\controller\mainController.py:1573 msgid "Unable to update this buffer." msgstr "このバッファを更新できません。" -#: ../src\controller\mainController.py:1575 +#: ../src\controller\mainController.py:1576 msgid "Updating buffer..." msgstr "バッファを更新中…" -#: ../src\controller\mainController.py:1578 +#: ../src\controller\mainController.py:1579 msgid "{0} items retrieved" msgstr "{0}個のアイテムを取得しました" -#: ../src\controller\mainController.py:1597 -#: ../src\controller\mainController.py:1617 +#: ../src\controller\mainController.py:1598 +#: ../src\controller\mainController.py:1618 msgid "Invalid buffer" msgstr "無効なバッファ" -#: ../src\controller\mainController.py:1608 +#: ../src\controller\mainController.py:1609 msgid "Picture {0}" msgstr "画像{0}" -#: ../src\controller\mainController.py:1609 +#: ../src\controller\mainController.py:1610 msgid "Select the picture" msgstr "画像を選択" -#: ../src\controller\mainController.py:1628 +#: ../src\controller\mainController.py:1629 msgid "Unable to extract text" msgstr "テキストを抽出できません" @@ -455,7 +459,7 @@ msgstr "%s - %s/%d" msgid "View item" msgstr "アイテムを見る" -#: ../src\controller\messages.py:379 +#: ../src\controller\messages.py:380 msgid "Link copied to clipboard." msgstr "リンクをクリップボードへコピーしました。" @@ -1957,27 +1961,27 @@ msgstr "" "されます。このエラーが続く場合は、エラーログを {app} 開発者に送信してくださ" "い。" -#: ../src\sessions\twitter\compose.py:38 ../src\sessions\twitter\compose.py:81 -#: ../src\sessions\twitter\compose.py:146 -#: ../src\sessions\twitter\compose.py:155 +#: ../src\sessions\twitter\compose.py:25 ../src\sessions\twitter\compose.py:68 +#: ../src\sessions\twitter\compose.py:133 +#: ../src\sessions\twitter\compose.py:142 #: ../src\sessions\twitter\templates.py:26 msgid "dddd, MMMM D, YYYY H:m:s" msgstr "YYYY年MMMMD日(dddd) H時m分s秒" -#: ../src\sessions\twitter\compose.py:89 ../src\sessions\twitter\compose.py:91 +#: ../src\sessions\twitter\compose.py:76 ../src\sessions\twitter\compose.py:78 msgid "Dm to %s " msgstr "「%s」へのDM " -#: ../src\sessions\twitter\compose.py:130 +#: ../src\sessions\twitter\compose.py:117 msgid "{0}. Quoted tweet from @{1}: {2}" msgstr "{0} 引用:@{1}:{2}" -#: ../src\sessions\twitter\compose.py:157 -#: ../src\sessions\twitter\compose.py:159 +#: ../src\sessions\twitter\compose.py:144 +#: ../src\sessions\twitter\compose.py:146 msgid "Unavailable" msgstr "無効" -#: ../src\sessions\twitter\compose.py:160 +#: ../src\sessions\twitter\compose.py:147 msgid "" "%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined " "Twitter %s" @@ -1985,15 +1989,15 @@ msgstr "" "%s: @%s フォロワー: %s フォロー: %s ツイート数: %s 最後のツイート: %s ツイッ" "ターへの参加: %s" -#: ../src\sessions\twitter\compose.py:164 +#: ../src\sessions\twitter\compose.py:151 msgid "No description available" msgstr "説明はありません" -#: ../src\sessions\twitter\compose.py:168 +#: ../src\sessions\twitter\compose.py:155 msgid "private" msgstr "プライベート" -#: ../src\sessions\twitter\compose.py:169 +#: ../src\sessions\twitter\compose.py:156 msgid "public" msgstr "公式" @@ -2007,8 +2011,8 @@ msgstr "%s が失敗しました。理由: %s" msgid "%s succeeded." msgstr "%sに成功しました。" -#: ../src\sessions\twitter\session.py:450 -#: ../src\sessions\twitter\session.py:528 +#: ../src\sessions\twitter\session.py:451 +#: ../src\sessions\twitter\session.py:529 msgid "Deleted account" msgstr "削除されたアカウント" @@ -2032,23 +2036,23 @@ msgstr "" "$display_name (@$screen_name)。$followers フォロワー、$following フォロー" "中、$tweets 件のツイート。Twitter への参加 $created_at。" -#: ../src\sessions\twitter\templates.py:50 +#: ../src\sessions\twitter\templates.py:54 msgid "Image description: {}." msgstr "画像の説明: {}。" -#: ../src\sessions\twitter\utils.py:229 +#: ../src\sessions\twitter\utils.py:243 msgid "Sorry, you are not authorised to see this status." msgstr "申し訳ありませんが、あなたはこのステータスを表示する権限がありません。" -#: ../src\sessions\twitter\utils.py:231 +#: ../src\sessions\twitter\utils.py:245 msgid "No status found with that ID" msgstr "そのIDのステータスが見つかりませんでした" -#: ../src\sessions\twitter\utils.py:233 +#: ../src\sessions\twitter\utils.py:247 msgid "Error {0}" msgstr "エラー {0}" -#: ../src\sessions\twitter\utils.py:260 +#: ../src\sessions\twitter\utils.py:274 msgid "{user_1}, {user_2} and {all_users} more: {text}" msgstr "{user_1}、{user_2}、ほか{all_users}ユーザー: {text}" From 2f0515a44900e7a5d0a7740f4acdc435e427a280 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Wed, 23 Feb 2022 15:19:49 -0600 Subject: [PATCH 83/83] prepared everything for new version --- src/locales/fr/LC_MESSAGES/twblue.mo | Bin 57445 -> 59913 bytes updates/updates.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/fr/LC_MESSAGES/twblue.mo b/src/locales/fr/LC_MESSAGES/twblue.mo index a6de84039f627abb6c7670462284eface51f20bf..456e437a9f70f695fe7c76672976cf176567cdf4 100644 GIT binary patch delta 19529 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 diff --git a/updates/updates.json b/updates/updates.json index ad94bf92..15f31f98 100644 --- a/updates/updates.json +++ b/updates/updates.json @@ -1,4 +1,4 @@ -{"current_version": "11", +{"current_version": "2021.02.23", "description": "Snapshot version.", "date": "unknown", "downloads":