refactored to be simpler

This commit is contained in:
Hellow 2024-02-13 21:25:47 +01:00
parent 75d3d5f1aa
commit 61536240f3
10 changed files with 150 additions and 122 deletions

View File

@ -4,73 +4,4 @@ import logging
import toml
from .utils import Paths, PROGRAM_NAME
from .feeds.mastodon_feed import MastodonFeed
from .feeds.twitter_feed import TwitterFeed
NAME_TO_FEED = {
"mastodon": MastodonFeed,
"twitter": TwitterFeed,
}
class PublishMeetups:
def __init__(self):
self.config_file: Path = Path(Paths.CONFIG_PATH, "publish-meetups.toml")
print(self.config_file)
self.config = {}
self.config = {
"active_feeds": [
"mastodon",
"twitter",
],
"mastodon": {},
"twitter": {},
}
self.logger = logging.getLogger(__name__)
def __enter__(self):
if self.config_file.exists():
with self.config_file.open("r", encoding="utf-8") as f:
self.config.update(toml.load(f))
return self
def run(self):
for feed in self.config['active_feeds']:
self.run_feed(feed)
def run_feed(self, feed: str):
if feed not in NAME_TO_FEED:
self.logger.error(f"Feed {feed} is not implemented.")
return
feed_config = self.config.get(feed, {})
feed_class = NAME_TO_FEED[feed]
if not len(feed_config):
feed_config.update(feed_class.prompt_auth(feed_config))
self.config[feed] = feed_config
with self.config_file.open("w", encoding="utf-8") as f:
toml.dump(self.config, f)
with feed_class(**feed_config, config=feed_config) as feed_instance:
self.config[feed].update(feed_instance.config)
with self.config_file.open("w", encoding="utf-8") as f:
toml.dump(self.config, f)
feed_instance.run()
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exiting")
with self.config_file.open("w", encoding="utf-8") as f:
toml.dump(self.config, f)
from .utils import config

View File

@ -1,9 +1,8 @@
from . import PublishMeetups
from .routines.development import Development
def cli():
with PublishMeetups() as p:
p.run()
Development().run()
if __name__ == "__main__":

View File

@ -1,23 +1,11 @@
import logging
from .interface import Feed
from .mastodon_feed import MastodonFeed
from .twitter_feed import TwitterFeed
class Feed:
@classmethod
def prompt_auth(cls, existing_config: dict) -> dict:
return existing_config
def __init__(self, config: dict = None, **kwargs):
self.logger = logging.getLogger(self.__class__.__name__)
self.config = config or {}
def __enter__(self):
return self
def post(self, message: str, **kwargs):
print(f"Posting {message}")
def run(self):
self.post("Hello, World!")
def __exit__(self, exc_type, exc_value, traceback):
pass
__all__ = ["Feed", "MastodonFeed", "TwitterFeed"]

View File

@ -0,0 +1,17 @@
import logging
class Feed:
__config_name__ = "feed"
@classmethod
def prompt_auth(cls, existing_config: dict) -> dict:
return existing_config
def __init__(self):
self.logger = logging.getLogger(self.__class__.__name__)
def post(self, message: str):
self.logger.info(f"Posting message to {self.__class__.__name__}: {message}")
pass

View File

@ -3,14 +3,15 @@ from pathlib import Path
from mastodon import Mastodon
from . import Feed
from ..utils import Paths, PROGRAM_NAME, prompt
from ..utils import PROGRAM_NAME, prompt, config
class MastodonFeed(Feed):
CLIENTCRED_PATH: Path = Paths.CONFIG_PATH.joinpath("mastodon_clientcred.secret")
__config_name__ = "mastodon"
CLIENTCRED_PATH: Path = config.CONFIG_PATH.joinpath("mastodon_clientcred.secret")
@classmethod
def prompt_auth(cls, existing_config: dict) -> dict:
def prompt_auth(cls) -> dict:
"""
mastodon needs:
- the instance used
@ -18,7 +19,6 @@ class MastodonFeed(Feed):
"""
return {
**existing_config,
"api_base_url": prompt.for_string("The instance you use", "https://mastodon.social"),
"access_token": prompt.for_password("Access token"),
}
@ -30,11 +30,9 @@ class MastodonFeed(Feed):
access_token=access_token,
)
super().__init__(**kwargs)
super().__init__()
def post(self, message: str):
kwargs = locals().copy()
self.mastodon.toot(message)
Feed.post(**kwargs)
super().post(message)

View File

@ -4,14 +4,14 @@ from twikit import Client
from twikit.errors import Forbidden, Unauthorized
from . import Feed
from ..utils import Paths, PROGRAM_NAME, prompt
from ..utils import config, PROGRAM_NAME, prompt
class TwitterFeed(Feed):
CLIENTCRED_PATH: Path = Paths.CONFIG_PATH.joinpath("mastodon_clientcred.secret")
__config_name__ = "twitter"
@classmethod
def prompt_auth(cls, existing_config: dict) -> dict:
def prompt_auth(cls) -> dict:
"""
client.login(
auth_info_1=USERNAME ,
@ -28,13 +28,12 @@ class TwitterFeed(Feed):
# https://github.com/d60/twikit
def __init__(self, auth_info_1: str, auth_info_2: str, password: str, cookies: dict = None, **kwargs):
super().__init__(**kwargs)
super().__init__()
self.client = Client('en-US')
logged_in = False
cookies = cookies or {}
if cookies is not None:
self.client.http.client.cookies = cookies
try:
@ -53,16 +52,14 @@ class TwitterFeed(Feed):
)
logged_in = True
self.config['cookies'] = dict(self.client.http.client.cookies)
print(self.client.user_id())
print(self.client._base_headers)
config.set_field(self.__config_name__, {
'cookies': dict(self.client.http.client.cookies)
}, update_dict=True)
def post(self, message: str):
kwargs = locals().copy()
self.client.create_tweet(
text=message,
)
Feed.post(**kwargs)
super().post(message)

View File

@ -0,0 +1,41 @@
from typing import Generator, Type, Dict
from ..utils import config, error
from ..feeds import *
NAME_TO_FEED: Dict[str, Type[Feed]] = {
"mastodon": MastodonFeed,
"twitter": TwitterFeed,
}
class Routine:
@staticmethod
def iter_feeds() -> Generator[Type[Feed], None, None]:
for feed in config.get_field("active_feeds", []):
if feed not in NAME_TO_FEED:
raise ValueError(f"Feed {feed} is not implemented.")
yield NAME_TO_FEED[feed]
@staticmethod
def init_feed(feed: Type[Feed]) -> Feed:
feed_config = config.get_field(feed.__config_name__, {})
try:
feed_instance = feed(**feed_config)
except (TypeError, error.InvalidCredential) as e:
print(feed_config)
raise e
config.set_field(feed.__name__, feed.prompt_auth(), update_dict=True)
feed_config = config.get_field(feed.__config_name__, {})
try:
return feed(**feed_config)
except (TypeError, error.InvalidCredential):
raise error.InvalidCredential(f"Invalid credentials for {feed.__name__}.")
def run(self):
pass

View File

@ -0,0 +1,10 @@
from . import Routine
from ..feeds import Feed
class Development(Routine):
def run(self):
for feed_class in self.iter_feeds():
feed: Feed = self.init_feed(feed_class)
feed.post(message="This worked second try!")

View File

@ -1,19 +1,9 @@
from pathlib import Path
import logging
import platformdirs
logging.basicConfig(level=logging.INFO)
PROGRAM_NAME: str = "publish-meetups"
class Paths:
CONFIG_PATH: Path = Path(platformdirs.user_config_path(appname=PROGRAM_NAME))
Paths.CONFIG_PATH.mkdir(parents=True, exist_ok=True)
__all__ = ["prompt", "CONFIG_PATH", "PROGRAM_NAME", "errors"]
__all__ = ["prompt", "CONFIG_PATH", "PROGRAM_NAME", "errors", "config"]

View File

@ -0,0 +1,57 @@
import logging
import toml
import platformdirs
from . import PROGRAM_NAME
logger = logging.getLogger("config")
_config: dict = {
"active_feeds": [
"mastodon",
"twitter",
],
"mastodon": {},
"twitter": {},
"lemmy": {},
}
CONFIG_PATH = platformdirs.user_config_path(appname=PROGRAM_NAME)
CONFIG_PATH.mkdir(parents=True, exist_ok=True)
CONFIG_FILE = CONFIG_PATH / f"{PROGRAM_NAME}.toml"
logger.info(f"Config file: {CONFIG_FILE}")
def read():
global _config, CONFIG_FILE
if CONFIG_FILE.exists():
with CONFIG_FILE.open("r", encoding="utf-8") as f:
_config.update(toml.load(f))
def write():
global _config, CONFIG_FILE
with CONFIG_FILE.open("w", encoding="utf-8") as f:
toml.dump(_config, f)
def get_field(__name: str, default=None):
global _config
return _config.get(__name, default)
def set_field(__name: str, __value, update_dict=False):
global _config
if update_dict and isinstance(__value, dict) and isinstance(_config.get(__name), dict):
_config[__name].update(__value)
else:
_config[__name] = __value
write()
read()