๐Ÿ Tiny CLI to post simultaneously to Mastodon and Bluesky
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allows post image(s) with no text

Closes #2

+29 -5
+3 -3
not_my_ex/cli/post.py
··· 65 65 error(err) 66 66 67 67 post = Post(text, auth.limit, imgs or None, lang) 68 + if post.is_empty(): 69 + error("No text (or image) to post") 70 + 68 71 if not lang and not yes_to_all: 69 72 post.check_language() 70 73 ··· 136 139 auth.assure_configured() 137 140 138 141 text = text or editor() 139 - if not text: 140 - error("No text to post") 141 - 142 142 loop = get_event_loop() 143 143 try: 144 144 loop.run_until_complete(main(auth, text, images, lang, yes_to_all))
+5 -2
not_my_ex/post.py
··· 1 - from collections.abc import Iterable 1 + from collections.abc import Sequence 2 2 from dataclasses import dataclass 3 3 from pathlib import Path 4 4 from tempfile import NamedTemporaryFile ··· 16 16 class Post: 17 17 text: str 18 18 limit: int = 300 19 - media: Iterable[Media] | None = None 19 + media: Sequence[Media] | None = None 20 20 lang: str | None = None 21 21 22 22 def __post_init__(self): ··· 42 42 lang = Language() 43 43 lang.ask() 44 44 self.lang = lang.name 45 + 46 + def is_empty(self) -> bool: 47 + return not bool(self.text or self.media)
+21
tests/test_post.py
··· 49 49 post.check_language() 50 50 51 51 assert post.lang == "pt" 52 + 53 + 54 + @mark.asyncio 55 + @mark.parametrize( 56 + "text, with_image, expected", 57 + ( 58 + ("forty-two", True, False), 59 + ("", True, False), 60 + ("forty-two", False, False), 61 + ("", False, True), 62 + ), 63 + ) 64 + async def test_post_is_empty(image, text, with_image, expected): 65 + kwargs = {"media": []} 66 + if with_image: 67 + img, *_ = image 68 + media = await Media.from_img(img) 69 + kwargs["media"].append(media) 70 + 71 + post = Post(text, **kwargs) 72 + assert post.is_empty() is expected