From e3e3dc0227f8fd83c53a611bfb63c37595cd35cf Mon Sep 17 00:00:00 2001 From: marty hiatt Date: Fri, 25 Nov 2022 19:53:37 +0100 Subject: filter user posts by language. NB: we flip mastodon-iso-639-1! --- lisp/mastodon-iso.el | 370 +++++++++++++++++++++++++------------------------- lisp/mastodon-tl.el | 89 ++++++++---- lisp/mastodon-toot.el | 11 +- 3 files changed, 251 insertions(+), 219 deletions(-) diff --git a/lisp/mastodon-iso.el b/lisp/mastodon-iso.el index 8baff3c..341593c 100644 --- a/lisp/mastodon-iso.el +++ b/lisp/mastodon-iso.el @@ -33,191 +33,191 @@ ;; https://github.com/Shinmera/language-codes/blob/master/data/iso-639-3.lisp (defvar mastodon-iso-639-1 - '(("ab" "Abkhazian") - ("aa" "Afar") - ("af" "Afrikaans") - ("ak" "Akan") - ("sq" "Albanian") - ("am" "Amharic") - ("ar" "Arabic") - ("an" "Aragonese") - ("hy" "Armenian") - ("as" "Assamese") - ("av" "Avaric") - ("ae" "Avestan") - ("ay" "Aymara") - ("az" "Azerbaijani") - ("bm" "Bambara") - ("ba" "Bashkir") - ("eu" "Basque") - ("be" "Belarusian") - ("bn" "Bengali") - ("bh" "Bihari languages") - ("bi" "Bislama") - ("bs" "Bosnian") - ("br" "Breton") - ("bg" "Bulgarian") - ("my" "Burmese") - ("km" "Central Khmer") - ("ch" "Chamorro") - ("ce" "Chechen") - ("zh" "Chinese") - ("cv" "Chuvash") - ("kw" "Cornish") - ("co" "Corsican") - ("cr" "Cree") - ("hr" "Croatian") - ("cs" "Czech") - ("da" "Danish") - ("dz" "Dzongkha") - ("en" "English") - ("eo" "Esperanto") - ("et" "Estonian") - ("ee" "Ewe") - ("fo" "Faroese") - ("fj" "Fijian") - ("fi" "Finnish") - ("nl" "Dutch" "Flemish") - ("fr" "French") - ("ff" "Fulah") - ("gl" "Galician") - ("lg" "Ganda") - ("ka" "Georgian") - ("de" "German") - ("el" "Greek") - ("gn" "Guarani") - ("gu" "Gujarati") - ("ht" "Haitian" "Haitian Creole") - ("ha" "Hausa") - ("he" "Hebrew") - ("hz" "Herero") - ("hi" "Hindi") - ("ho" "Hiri Motu") - ("hu" "Hungarian") - ("is" "Icelandic") - ("io" "Ido") - ("ig" "Igbo") - ("id" "Indonesian") - ("ia" "Interlingua" "Interlingua (International Auxiliary Language Association)") - ("iu" "Inuktitut") - ("ik" "Inupiaq") - ("ga" "Irish") - ("it" "Italian") - ("ja" "Japanese") - ("jp" "Japanese") - ("jv" "Javanese") - ("kl" "Kalaallisut" "Greenlandic") - ("kn" "Kannada") - ("kr" "Kanuri") - ("ks" "Kashmiri") - ("kk" "Kazakh") - ("ki" "Kikuyu" "Gikuyu") - ("rw" "Kinyarwanda") - ("kv" "Komi") - ("kg" "Kongo") - ("ko" "Korean") - ("ku" "Kurdish") - ("kj" "Kuanyama" "Kwanyama") - ("ky" "Kirghiz" "Kyrgyz") - ("lo" "Lao") - ("la" "Latin") - ("lv" "Latvian") - ("li" "Limburgan" "Limburger" "Limburgish") - ("ln" "Lingala") - ("lt" "Lithuanian") - ("lu" "Luba-Katanga") - ("lb" "Luxembourgish" "Letzeburgesch") - ("mk" "Macedonian") - ("mg" "Malagasy") - ("ms" "Malay") - ("ml" "Malayalam") - ("dv" "Divehi" "Dhivehi" "Maldivian") - ("mt" "Maltese") - ("gv" "Manx") - ("mi" "Maori") - ("mr" "Marathi") - ("mh" "Marshallese") - ("mn" "Mongolian") - ("na" "Nauru") - ("nv" "Navajo" "Navaho") - ("ng" "Ndonga") - ("ne" "Nepali") - ("nd" "Ndebele, North" "North Ndebele") - ("se" "Northern Sami") - ("no" "Norwegian") - ("nb" "Bokmål, Norwegian" "Norwegian Bokmål") - ("ny" "Chichewa" "Chewa" "Nyanja") - ("nn" "Norwegian Nynorsk" "Nynorsk, Norwegian") - ("ie" "Interlingue" "Occidental") - ("oc" "Occitan") - ("oj" "Ojibwa") - ("cu" "Church Slavic" "Old Slavonic" "Church Slavonic" "Old Bulgarian" "Old Church Slavonic") - ("or" "Oriya") - ("om" "Oromo") - ("os" "Ossetian" "Ossetic") - ("pi" "Pali") - ("fa" "Persian") - ("pl" "Polish") - ("pt" "Portuguese") - ("pa" "Panjabi" "Punjabi") - ("ps" "Pushto" "Pashto") - ("qu" "Quechua") - ("ro" "Romanian" "Moldavian" "Moldovan") - ("rm" "Romansh") - ("rn" "Rundi") - ("ru" "Russian") - ("sm" "Samoan") - ("sg" "Sango") - ("sa" "Sanskrit") - ("sc" "Sardinian") - ("gd" "Gaelic" "Scottish Gaelic") - ("sr" "Serbian") - ("sn" "Shona") - ("ii" "Sichuan Yi" "Nuosu") - ("sd" "Sindhi") - ("si" "Sinhala" "Sinhalese") - ("sk" "Slovak") - ("sl" "Slovenian") - ("so" "Somali") - ("st" "Sotho, Southern") - ("nr" "Ndebele, South" "South Ndebele") - ("es" "Spanish" "Castilian") - ("su" "Sundanese") - ("sw" "Swahili") - ("ss" "Swati") - ("sv" "Swedish") - ("tl" "Tagalog") - ("ty" "Tahitian") - ("tg" "Tajik") - ("ta" "Tamil") - ("tt" "Tatar") - ("te" "Telugu") - ("th" "Thai") - ("bo" "Tibetan") - ("ti" "Tigrinya") - ("to" "Tonga (Tonga Islands)") - ("ts" "Tsonga") - ("tn" "Tswana") - ("tr" "Turkish") - ("tk" "Turkmen") - ("tw" "Twi") - ("uk" "Ukrainian") - ("ur" "Urdu") - ("ug" "Uighur" "Uyghur") - ("uz" "Uzbek") - ("ca" "Catalan" "Valencian") - ("ve" "Venda") - ("vi" "Vietnamese") - ("vo" "Volapük") - ("wa" "Walloon") - ("cy" "Welsh") - ("fy" "Western Frisian") - ("wo" "Wolof") - ("xh" "Xhosa") - ("yi" "Yiddish") - ("yo" "Yoruba") - ("za" "Zhuang" "Chuang") - ("zu" "Zulu"))) + '(("Abkhazian" . "ab") + ("Afar" . "aa") + ("Afrikaans" . "af") + ("Akan" . "ak") + ("Albanian" . "sq") + ("Amharic" . "am") + ("Arabic" . "ar") + ("Aragonese" . "an") + ("Armenian" . "hy") + ("Assamese" . "as") + ("Avaric" . "av") + ("Avestan" . "ae") + ("Aymara" . "ay") + ("Azerbaijani" . "az") + ("Bambara" . "bm") + ("Bashkir" . "ba") + ("Basque" . "eu") + ("Belarusian" . "be") + ("Bengali" . "bn") + ("Bihari languages" . "bh") + ("Bislama" . "bi") + ("Bosnian" . "bs") + ("Breton" . "br") + ("Bulgarian" . "bg") + ("Burmese" . "my") + ("Central Khmer" . "km") + ("Chamorro" . "ch") + ("Chechen" . "ce") + ("Chinese" . "zh") + ("Chuvash" . "cv") + ("Cornish" . "kw") + ("Corsican" . "co") + ("Cree" . "cr") + ("Croatian" . "hr") + ("Czech" . "cs") + ("Danish" . "da") + ("Dzongkha" . "dz") + ("English" . "en") + ("Esperanto" . "eo") + ("Estonian" . "et") + ("Ewe" . "ee") + ("Faroese" . "fo") + ("Fijian" . "fj") + ("Finnish" . "fi") + ("Dutch" . "nl") + ("French" . "fr") + ("Fulah" . "ff") + ("Galician" . "gl") + ("Ganda" . "lg") + ("Georgian" . "ka") + ("German" . "de") + ("Greek" . "el") + ("Guarani" . "gn") + ("Gujarati" . "gu") + ("Haitian" . "ht") + ("Hausa" . "ha") + ("Hebrew" . "he") + ("Herero" . "hz") + ("Hindi" . "hi") + ("Hiri Motu" . "ho") + ("Hungarian" . "hu") + ("Icelandic" . "is") + ("Ido" . "io") + ("Igbo" . "ig") + ("Indonesian" . "id") + ("Interlingua" . "ia") + ("Inuktitut" . "iu") + ("Inupiaq" . "ik") + ("Irish" . "ga") + ("Italian" . "it") + ("Japanese" . "ja") + ("Japanese" . "jp") + ("Javanese" . "jv") + ("Kalaallisut" . "kl") + ("Kannada" . "kn") + ("Kanuri" . "kr") + ("Kashmiri" . "ks") + ("Kazakh" . "kk") + ("Kikuyu" . "ki") + ("Kinyarwanda" . "rw") + ("Komi" . "kv") + ("Kongo" . "kg") + ("Korean" . "ko") + ("Kurdish" . "ku") + ("Kuanyama" . "kj") + ("Kirghiz" . "ky") + ("Lao" . "lo") + ("Latin" . "la") + ("Latvian" . "lv") + ("Limburgan" . "li") + ("Lingala" . "ln") + ("Lithuanian" . "lt") + ("Luba-Katanga" . "lu") + ("Luxembourgish" . "lb") + ("Macedonian" . "mk") + ("Malagasy" . "mg") + ("Malay" . "ms") + ("Malayalam" . "ml") + ("Divehi" . "dv") + ("Maltese" . "mt") + ("Manx" . "gv") + ("Maori" . "mi") + ("Marathi" . "mr") + ("Marshallese" . "mh") + ("Mongolian" . "mn") + ("Nauru" . "na") + ("Navajo" . "nv") + ("Ndonga" . "ng") + ("Nepali" . "ne") + ("Ndebele, North" . "nd") + ("Northern Sami" . "se") + ("Norwegian" . "no") + ("Bokmål, Norwegian" . "nb") + ("Chichewa" . "ny") + ("Norwegian Nynorsk" . "nn") + ("Interlingue" . "ie") + ("Occitan" . "oc") + ("Ojibwa" . "oj") + ("Church Slavic" . "cu") + ("Oriya" . "or") + ("Oromo" . "om") + ("Ossetian" . "os") + ("Pali" . "pi") + ("Persian" . "fa") + ("Polish" . "pl") + ("Portuguese" . "pt") + ("Panjabi" . "pa") + ("Pushto" . "ps") + ("Quechua" . "qu") + ("Romanian" . "ro") + ("Romansh" . "rm") + ("Rundi" . "rn") + ("Russian" . "ru") + ("Samoan" . "sm") + ("Sango" . "sg") + ("Sanskrit" . "sa") + ("Sardinian" . "sc") + ("Gaelic" . "gd") + ("Serbian" . "sr") + ("Shona" . "sn") + ("Sichuan Yi" . "ii") + ("Sindhi" . "sd") + ("Sinhala" . "si") + ("Slovak" . "sk") + ("Slovenian" . "sl") + ("Somali" . "so") + ("Sotho, Southern" . "st") + ("Ndebele, South" . "nr") + ("Spanish" . "es") + ("Sundanese" . "su") + ("Swahili" . "sw") + ("Swati" . "ss") + ("Swedish" . "sv") + ("Tagalog" . "tl") + ("Tahitian" . "ty") + ("Tajik" . "tg") + ("Tamil" . "ta") + ("Tatar" . "tt") + ("Telugu" . "te") + ("Thai" . "th") + ("Tibetan" . "bo") + ("Tigrinya" . "ti") + ("Tonga (Tonga Islands)" . "to") + ("Tsonga" . "ts") + ("Tswana" . "tn") + ("Turkish" . "tr") + ("Turkmen" . "tk") + ("Twi" . "tw") + ("Ukrainian" . "uk") + ("Urdu" . "ur") + ("Uighur" . "ug") + ("Uzbek" . "uz") + ("Catalan" . "ca") + ("Venda" . "ve") + ("Vietnamese" . "vi") + ("Volapük" . "vo") + ("Walloon" . "wa") + ("Welsh" . "cy") + ("Western Frisian" . "fy") + ("Wolof" . "wo") + ("Xhosa" . "xh") + ("Yiddish" . "yi") + ("Yoruba" . "yo") + ("Zhuang" . "za") + ("Zulu" . "zu"))) ;; web UI doesn't respect these for now (defvar mastodon-iso-639-regional diff --git a/lisp/mastodon-tl.el b/lisp/mastodon-tl.el index 1a726c4..dd3ce1b 100644 --- a/lisp/mastodon-tl.el +++ b/lisp/mastodon-tl.el @@ -36,6 +36,7 @@ (require 'thingatpt) ; for word-at-point (require 'time-date) (require 'cl-lib) +(require 'mastodon-iso) (require 'mpv nil :no-error) @@ -2079,16 +2080,18 @@ IND is the optional indentation level to print at." ;;; FOLLOW/BLOCK/MUTE, ETC -(defun mastodon-tl--follow-user (user-handle &optional notify) +(defun mastodon-tl--follow-user (user-handle &optional notify langs) "Query for USER-HANDLE from current status and follow that user. If NOTIFY is \"true\", enable notifications when that user posts. If NOTIFY is \"false\", disable notifications when that user posts. -Can be called to toggle NOTIFY on users already being followed." +Can be called to toggle NOTIFY on users already being followed. +LANGS is an array parameters alist of languages to filer user's posts by." (interactive (list (mastodon-tl--interactive-user-handles-get "follow"))) (mastodon-tl--do-if-toot - (mastodon-tl--do-user-action-and-response user-handle "follow" nil notify))) + (mastodon-tl--do-user-action-and-response + user-handle "follow" nil notify langs))) (defun mastodon-tl--enable-notify-user-posts (user-handle) "Query for USER-HANDLE and enable notifications when they post." @@ -2105,6 +2108,31 @@ Can be called to toggle NOTIFY on users already being followed." (mastodon-tl--interactive-user-handles-get "disable"))) (mastodon-tl--follow-user user-handle "false")) +(defun mastodon-tl--filter-user-user-posts-by-language (user-handle) + "Query for USER-HANDLE and enable notifications when they post." + (interactive + (list + (mastodon-tl--interactive-user-handles-get "filter by language"))) + (let ((langs (mastodon-tl--read-filter-langs))) + (mastodon-tl--do-if-toot + (mastodon-tl--follow-user user-handle nil langs)))) + +(defun mastodon-tl--read-filter-langs (&optional langs) + "Read language choices and return an alist array parameter. +LANGS is the accumulated array param alist if we re-run recursively." + (let* ((langs-alist langs) + (choice (completing-read "Filter user's posts by language: " + mastodon-iso-639-1))) + (when choice + (setq langs-alist + (push `("languages[]" . ,(alist-get choice mastodon-iso-639-1 + nil nil + #'string=)) + langs-alist)) + (if (y-or-n-p "Filter by another language? ") + (mastodon-tl--read-filter-langs langs-alist) + langs-alist)))) + (defun mastodon-tl--unfollow-user (user-handle) "Query for USER-HANDLE from current status and unfollow that user." (interactive @@ -2197,12 +2225,13 @@ Action must be either \"unblock\" or \"unmute\"." nil ; predicate t)))) -(defun mastodon-tl--do-user-action-and-response (user-handle action &optional negp notify) +(defun mastodon-tl--do-user-action-and-response (user-handle action &optional negp notify langs) "Do ACTION on user USER-HANDLE. NEGP is whether the action involves un-doing something. If NOTIFY is \"true\", enable notifications when that user posts. If NOTIFY is \"false\", disable notifications when that user posts. -NOTIFY is only non-nil when called by `mastodon-tl--follow-user'." +NOTIFY is only non-nil when called by `mastodon-tl--follow-user'. +LANGS is an array parameters alist of languages to filer user's posts by." (let* ((account (if negp ;; if unmuting/unblocking, we got handle from mute/block list (mastodon-profile--search-account-by-handle @@ -2218,35 +2247,41 @@ NOTIFY is only non-nil when called by `mastodon-tl--follow-user'." (name (if (not (string-empty-p (mastodon-profile--account-field account 'display_name))) (mastodon-profile--account-field account 'display_name) (mastodon-profile--account-field account 'username))) - (url (mastodon-http--api - (if notify - (format "accounts/%s/%s?notify=%s" user-id action notify) - (format "accounts/%s/%s" user-id action))))) + (args (cond (notify + `(("notify" . ,notify))) + (langs langs) + (t nil))) + (url (mastodon-http--api (format "accounts/%s/%s" user-id action)))) (if account (if (equal action "follow") ; y-or-n for all but follow - (mastodon-tl--do-user-action-function url name user-handle action notify) + (mastodon-tl--do-user-action-function url name user-handle action notify args) (when (y-or-n-p (format "%s user %s? " action name)) - (mastodon-tl--do-user-action-function url name user-handle action))) + (mastodon-tl--do-user-action-function url name user-handle action args))) (message "Cannot find a user with handle %S" user-handle)))) -(defun mastodon-tl--do-user-action-function (url name user-handle action &optional notify) +(defun mastodon-tl--do-user-action-function (url name user-handle action &optional notify args) "Post ACTION on user NAME/USER-HANDLE to URL. NOTIFY is either \"true\" or \"false\", and used when we have been called -by `mastodon-tl--follow-user' to enable or disable notifications." - (let ((response (mastodon-http--post url))) - (mastodon-http--triage response - (lambda () - (cond ((string-equal notify "true") - (message "Receiving notifications for user %s (@%s)!" - name user-handle)) - ((string-equal notify "false") - (message "Not receiving notifications for user %s (@%s)!" - name user-handle)) - ((or (string-equal action "mute") - (string-equal action "unmute")) - (message "User %s (@%s) %sd!" name user-handle action)) - ((eq notify nil) - (message "User %s (@%s) %sed!" name user-handle action))))))) +by `mastodon-tl--follow-user' to enable or disable notifications. +ARGS is an alist of any parameters to send with the request." + (let ((response (mastodon-http--post url args))) + (mastodon-http--triage + response + (lambda () + (cond ((string-equal notify "true") + (message "Receiving notifications for user %s (@%s)!" + name user-handle)) + ((string-equal notify "false") + (message "Not receiving notifications for user %s (@%s)!" + name user-handle)) + ((or (string-equal action "mute") + (string-equal action "unmute")) + (message "User %s (@%s) %sd!" name user-handle action)) + ((assoc "languages[]" args #'equal) + (message "User %s filtered by language(s): %s" name + (mapconcat #'cdr args " "))) + ((eq notify nil) + (message "User %s (@%s) %sed!" name user-handle action))))))) ;; FOLLOW TAGS diff --git a/lisp/mastodon-toot.el b/lisp/mastodon-toot.el index 59a3813..21bfe96 100644 --- a/lisp/mastodon-toot.el +++ b/lisp/mastodon-toot.el @@ -1117,14 +1117,11 @@ LENGTH is the maximum character length allowed for a poll option." (defun mastodon-toot--set-toot-lang () "Prompt for a language and return its two letter ISO 639 1 code." (interactive) - (let* ((langs (mapcar (lambda (x) - (cons (cadr x) - (car x))) - mastodon-iso-639-1)) - (choice (completing-read "Language for this toot: " - langs))) + (let* ((choice (completing-read "Language for this toot: " + mastodon-iso-639-1))) (setq mastodon-toot--language - (alist-get choice langs nil nil 'equal)))) + (alist-get choice mastodon-iso-639-1 nil nil 'equal)) + (message "Language set to %s" choice))) ;; we'll need to revisit this if the binds get ;; more diverse than two-chord bindings -- cgit v1.2.3