diff options
-rw-r--r-- | commands/announce.py | 8 | ||||
-rw-r--r-- | commands/event.py | 89 | ||||
-rw-r--r-- | commands/movie.py | 13 | ||||
-rw-r--r-- | commands/users.py | 34 | ||||
-rw-r--r-- | predicates.py | 34 | ||||
-rw-r--r-- | strings.py | 10 | ||||
-rw-r--r-- | utils.py | 25 |
7 files changed, 134 insertions, 79 deletions
diff --git a/commands/announce.py b/commands/announce.py index 733e8d8..46e6500 100644 --- a/commands/announce.py +++ b/commands/announce.py @@ -12,7 +12,8 @@ from telegram import Update, error from telegram.ext import ContextTypes -from strings import ANNOUNCEMENT_TEMPLATE, ANNOUNCEMENT_FINISHED_EVENT +from strings import ANNOUNCEMENT_TEMPLATE, ANNOUNCEMENT_FINISHED_EVENT, \ + ANNOUNCEMENT_EVENT_NEEDS_EDITING from utils import context_init, create_users_string, choose_next_user from predicates import has_unfinished_event @@ -31,7 +32,10 @@ async def create_announcement( last_event = events[-1] last_movie = movies[-1] - genres = " #".join(last_movie["genres"]) + if last_event["when"] is None or last_event["where"] is None or last_event["movie"] is None: + raise error.TelegramError(ANNOUNCEMENT_EVENT_NEEDS_EDITING) + + genres ="#" + " #".join(last_movie["genres"]) await update.message.reply_markdown( ANNOUNCEMENT_TEMPLATE.format( diff --git a/commands/event.py b/commands/event.py index e06ea83..034ce36 100644 --- a/commands/event.py +++ b/commands/event.py @@ -13,12 +13,12 @@ from telegram import Update, error from telegram.ext import ContextTypes from datetime import datetime -from utils import context_init -from predicates import is_past, has_finished_event +from utils import context_init, normalize_username +from predicates import is_past, has_finished_movie, has_event_without_movie from strings import EVENT_ARGS_NOT_PROVIDED, EVENT_INVALID_DATETIME, \ EVENT_CREATED, EVENT_EDITED, EVENT_CANT_BE_IN_PAST, \ EVENT_WHERE_NOT_PROVIDED, EVENT_MOVIE_NOT_CHOOSEN, EVENTS_LIST, \ - EVENT_USER_HAD_EVENT, NO_EVENTS + EVENT_FINISHED, NO_EVENTS, EVENTS_LIST_PLANNING, EVENTS_LIST_MOVIE_SET async def create_event( @@ -26,18 +26,18 @@ async def create_event( context: ContextTypes.DEFAULT_TYPE ) -> None: context_init(context) + users = context.chat_data["users"] events = context.chat_data["events"] movies = context.chat_data["movies"] - username = update.message.from_user.username last_movie = movies[-1] if movies != [] else None - if has_finished_event(context, username): - raise error.TelegramError(EVENT_USER_HAD_EVENT) - - if last_movie is None or last_movie["user"] != username: + if last_movie is None: raise error.TelegramError(EVENT_MOVIE_NOT_CHOOSEN) + if has_finished_movie(context): + raise error.TelegramError(EVENT_FINISHED) + if context.args == []: raise error.TelegramError(EVENT_ARGS_NOT_PROVIDED) @@ -61,10 +61,10 @@ async def create_event( if arguments_where == [] and events == []: raise error.TelegramError(EVENT_WHERE_NOT_PROVIDED) - event_where = " ".join(arguments_where) + old_when = events[-2]["when"] if len(events) >= 2 else None + old_where = events[-2]["where"] if len(events) >= 2 else None - if event_where == "": - event_where = events[-1]["where"] + event_where = " ".join(arguments_where) if arguments_where != [] else old_where event_dict = dict( when=event_when, @@ -73,28 +73,17 @@ async def create_event( user=last_movie["user"] ) - if events == [] or is_past(events[-1]["when"]): - events.append(event_dict) - await update.message.reply_text( - EVENT_CREATED.format( - when=event_when, - movie=event_dict["movie"], - ) - ) - else: - old_when = events[-1]["when"] - old_where = events[-1]["where"] - events[-1] = event_dict - - await update.message.reply_text( - EVENT_EDITED.format( - old_when=old_when, - old_where=old_where, - when=event_when, - where=event_where, - movie=event_dict["movie"], - ) + events[-1] = event_dict + + await update.message.reply_text( + EVENT_EDITED.format( + old_when=old_when, + old_where=old_where, + when=event_when, + where=event_where, + movie=event_dict["movie"], ) + ) async def list_events( @@ -103,21 +92,41 @@ async def list_events( ) -> None: context_init(context) + users = context.chat_data["users"] events = context.chat_data["events"] + last_event = events[-1] if events != [] else None + + if last_event and last_event["movie"] is None: + last_event["user"] = normalize_username(users[0]) events_formatted: str = "" for event in events: - event_finished = "FINISHED" \ + event_status = "FINISHED" \ if is_past(event["when"]) else "PLANNED" - events_formatted += EVENTS_LIST.format( - movie=event["movie"], - user=event["user"], - when=event["when"], - where=event["where"], - finished=event_finished - ) + if event["movie"] is None: + breakpoint() + event_status = "PLANNING" + events_formatted += EVENTS_LIST_PLANNING.format( + user=event["user"], + status=event_status + ) + elif event["when"] is None or event["where"] is None: + event_status = "PLANNING" + events_formatted += EVENTS_LIST_MOVIE_SET.format( + user=event["user"], + movie=event["movie"], + status=event_status + ) + else: + events_formatted += EVENTS_LIST.format( + movie=event["movie"], + user=event["user"], + when=event["when"], + where=event["where"], + status=event_status + ) if events_formatted == "": events_formatted = NO_EVENTS diff --git a/commands/movie.py b/commands/movie.py index adb05ac..de0092b 100644 --- a/commands/movie.py +++ b/commands/movie.py @@ -13,8 +13,9 @@ from telegram import Update, error from telegram.ext import ContextTypes from imdb import Cinemagoer -from utils import context_init, choose_next_user -from predicates import has_finished_event +from utils import context_init, choose_next_user, normalize_username, \ + init_new_event +from predicates import has_finished_movie from strings import MOVIE_NOT_PROVIDED, EXPECTED_ONE_MOVIE, \ MOVIE_ANOTHER_USER, FETCHING_MOVIE, FETCHING_ERROR, \ MOVIE_REMOVE, MOVIE_SET, MOVIES_LIST, NO_MOVIES, ADD_MORE_USERS @@ -37,9 +38,8 @@ async def movie( chooser = users[0] username = update.message.from_user.username - if has_finished_event(context, chooser): - users = context.chat_data["users"] = choose_next_user(users) - raise error.TelegramError(MOVIE_ANOTHER_USER.format(users[0])) + if has_finished_movie(context): + users = context.chat_data["users"] = choose_next_user(context) if "@"+username != chooser: raise error.TelegramError(MOVIE_ANOTHER_USER.format(user=chooser)) @@ -63,7 +63,6 @@ async def movie( title=movie.data.get("title"), id=movie.getID(), user=update.effective_user.username, - poster=movie.data.get("cover url"), rating=movie.data.get("rating"), genres=movie.data.get("genres"), runtime=movie.data.get("runtimes"), @@ -80,6 +79,7 @@ async def movie( last_event["title"] = movie_dict["title"] context.chat_data["events"][-1] = last_event else: + init_new_event(context, users[0], movie_dict["title"]) context.chat_data["movies"].append(movie_dict) await update.message.reply_text( @@ -100,7 +100,6 @@ async def movies( for movie in movies: movies_formatted += MOVIES_LIST.format( title=movie["title"], - id=movie["id"], user=movie["user"] ) diff --git a/commands/users.py b/commands/users.py index 4134a21..1d0714f 100644 --- a/commands/users.py +++ b/commands/users.py @@ -16,9 +16,10 @@ from collections import deque from strings import USER_NOT_PROVIDED, USERS_ADDED, USERS_REMOVED, \ EXPECTED_ONE_USER, USER_SET, USER_REMOVE, ADD_MORE_USERS, \ NEXT_MOVIE_USER, USER_NOT_FOUND, USER_CHOOSE, NO_USERS, \ - EVENT_USER_HAD_EVENT, NEXT_MOVIE -from utils import context_init, create_users_string, choose_next_user -from predicates import has_finished_event + NEXT_MOVIE +from utils import context_init, create_users_string, choose_next_user, \ + normalize_username +from predicates import has_finished_movie, has_event_without_movie async def set_users( @@ -60,11 +61,12 @@ async def list_users( if users == []: await update.message.reply_text(NO_USERS) - else: - if has_finished_event(context, users[0]): - users = context.chat_data["users"] = choose_next_user(users) + return - await update.message.reply_markdown(create_users_string(users)) + if has_finished_movie(context): + users = context.chat_data["users"] = choose_next_user(context) + + await update.message.reply_markdown(create_users_string(users)) async def who_is_next( @@ -82,15 +84,15 @@ async def who_is_next( if users == []: raise error.TelegramError(ADD_MORE_USERS) - if has_finished_event(context, users[0]): - users = context.chat_data["users"] = choose_next_user(users) + if has_finished_movie(context): + users = context.chat_data["users"] = choose_next_user(context) next_user_string = NEXT_MOVIE_USER.format(user=users[0]) - last_movie = context.chat_data["movies"][0] \ + last_movie = context.chat_data["movies"][-1] \ if context.chat_data["movies"] != [] else None - if last_movie and last_movie["user"] == users[0]: + if last_movie and last_movie["user"] == normalize_username(users[0]): next_user_string += NEXT_MOVIE.format(movie=last_movie["title"]) await update.message.reply_text(next_user_string) @@ -141,11 +143,11 @@ async def chooser_user( context.chat_data["users"] = users - if has_finished_event(context, users[0]): - await update.message.reply_text( - EVENT_USER_HAD_EVENT.format(user=users[0]) - ) - users = context.chat_data["users"] = choose_next_user(users) + if has_finished_movie(context): + users = context.chat_data["users"] = choose_next_user(context) + + if has_event_without_movie(context): + context.chat_data["events"][-1]["user"] = users[0] await update.message.reply_text(USER_CHOOSE.format(user=users[0])) diff --git a/predicates.py b/predicates.py index c341ccf..07b84d7 100644 --- a/predicates.py +++ b/predicates.py @@ -11,28 +11,44 @@ from telegram.ext import ContextTypes from datetime import datetime +from typing import Optional -from utils import normalize_username +def is_past(dt: Optional[datetime]) -> bool: + if dt is None: + return False -def is_past(dt: datetime) -> bool: return dt < datetime.today() -def has_finished_event( - context: ContextTypes.DEFAULT_TYPE, - username: str -) -> bool: +def has_finished_movie(context: ContextTypes.DEFAULT_TYPE) -> bool: events = context.chat_data["events"] + movies = context.chat_data["movies"] + last_event = events[-1] if events != [] else None + last_movie = movies[-1] if movies != [] else None - return last_event is not None and \ - last_event["user"] == normalize_username(username) and \ + return last_event is not None and last_movie is not None and \ + last_event["user"] == last_movie["user"] and \ is_past(last_event["when"]) +def has_event_without_movie(context: ContextTypes.DEFAULT_TYPE) -> bool: + events = context.chat_data["events"] + last_event = events[-1] if events != [] else None + + return last_event and last_event["movie"] is None + + def has_unfinished_event(context: ContextTypes.DEFAULT_TYPE) -> bool: events = context.chat_data["events"] last_event = events[-1] if events != [] else None - return False if last_event is None else not is_past(last_event["when"]) + if last_event is None: + return False + + if last_event["movie"] is None: + return False + + return not is_past(last_event["when"]) + @@ -19,7 +19,7 @@ FETCHING_MOVIE = "Movie with ID {id} is being fetched: https://imdb.com/title/tt FETCHING_ERROR = "Couldn't fetch movie or it is not found. Provide IMDB id, for example: 0133093" MOVIE_REMOVE = "Movie \"{title}\" with id {id} has been removed" MOVIE_SET = "Movie \"{title}\" proposed by {user} is succesfully set as next to watch" -MOVIES_LIST = "\"{title}\" IMDB:{id} by {user} \n" +MOVIES_LIST = "\"{title}\" by {user} \n" NO_MOVIES = "No movies. You can add movie if you are next to choose (see /next). Too add a movie use /movie <imdb_id>" USER_NOT_FOUND = "Provided user ({user}) not found. Check /list" @@ -54,14 +54,18 @@ Second <where> argument is not provided and previous event doesn't has it. EVENT_CREATED = "Event \"{movie}\" at {when} was created" EVENT_EDITED = "Event \"{movie}\" at {old_when} in {old_where} was modified to {when} in {where}" -EVENTS_LIST = "[{finished}] \"{movie}\" by {user} at {when} in {where}\n" +EVENTS_LIST = "[{status}] \"{movie}\" by {user} at {when} in {where}\n" +EVENTS_LIST_MOVIE_SET = "[{status}] \"{movie}\" by {user}\n" +EVENTS_LIST_PLANNING = "[{status}] by {user}\n" EVENT_MOVIE_NOT_CHOOSEN = "You should choose a film first using /movie <imdb_id>" EVENT_MOVIE_NOT_SET = "<None>" -EVENT_USER_HAD_EVENT = "User {user} have already finished event, so he can't choose twice. See /next or /list" +EVENT_USER_HAD_MOVIE = "User {user} can't set the sa, so he can't choose twice. See /next or /list" +EVENT_FINISHED = "Event is finished. Use /next to see who chooses a film now." NO_EVENTS = "No events." UNDEFINED_ERROR = "Exception: something unexpected happened. Check the logs." +ANNOUNCEMENT_EVENT_NEEDS_EDITING = "Event is missing either Movie, When or Where fields. See /event" ANNOUNCEMENT_FINISHED_EVENT = "There is no planned events. Create one using /event <when> <where>" ANNOUNCEMENT_TEMPLATE = """ {intro} @@ -11,6 +11,7 @@ from telegram.ext import ContextTypes from collections import deque +from typing import Optional def context_init(context: ContextTypes.DEFAULT_TYPE): """ @@ -37,8 +38,28 @@ def create_users_string(users: list[str]) -> str: return "`" + ", ".join(users) + "`" -def choose_next_user(users: list[dict]) -> list[dict]: - users = deque(users) +def choose_next_user(context: ContextTypes.DEFAULT_TYPE) -> list[dict]: + users = deque(context.chat_data["users"]) users.rotate(-1) # -1 moves list to left by 1 element + init_new_event(context, users[0]) + return list(users) + + +def init_new_event(context: ContextTypes.DEFAULT_TYPE, user: dict, movie: Optional[str] = None): + events = context.chat_data["events"] + + last_event = events[-1] if events != [] else None + + init_event = dict( + when=None, + where=None, + movie=movie, + user=user + ) + + if last_event and last_event["movie"] is None: + events[-1] = init_event + else: + events.append(init_event) |