Skip to content

Commit

Permalink
Merge pull request #55 from mBaratta96/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
mBaratta96 authored Aug 8, 2023
2 parents 3ff9d3d + 9e97618 commit e868576
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 57 deletions.
39 changes: 12 additions & 27 deletions letterboxd_stats/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
IMAGE_URL = "https://www.themoviedb.org/t/p/w600_and_h900_bestv2"


def select_value(values: list[str], message: str, default: str | None = None):
def select_value(values: list[str], message: str, default: str | None = None) -> str:
value = inquirer.select( # type: ignore
message=message,
choices=values,
Expand All @@ -20,23 +20,20 @@ def select_value(values: list[str], message: str, default: str | None = None):
return value


def select_movie_id(movies_info: pd.DataFrame) -> int:
movie_id = inquirer.fuzzy( # type: ignore
message="Write movie id for more information",
def select_movie(movies: pd.Series, results: pd.Series) -> str:
result = inquirer.fuzzy( # type: ignore
message="Select movie for more information",
mandatory=False,
max_height="25%",
choices=[
Choice(value=id, name=f"{id} - {title}") for id, title in zip(movies_info["Id"], movies_info["Title"])
],
choices=[Choice(value=result, name=title) for result, title in zip(results, movies)],
keybindings={"skip": [{"key": "escape"}]},
validate=lambda result: result in movies_info["Id"].values,
filter=lambda result: None if result is None else int(result),
invalid_message="Input must be in the resulting IDs",
invalid_message="Input not in list of movies.",
validate=lambda result: result in results.values,
).execute()
return movie_id
return result


def select_list(names: list[str]) -> int:
def select_list(names: list[str]) -> str:
name = inquirer.fuzzy( # type: ignore
message="Select your list:",
mandatory=True,
Expand Down Expand Up @@ -68,19 +65,7 @@ def select_range(options: list[str]) -> list[str]:
return result


def select_movie(movie_df: pd.DataFrame) -> str:
result = inquirer.fuzzy( # type: ignore
message="Select movie for more information",
mandatory=False,
max_height="25%",
choices=[Choice(value=url, name=f"{title}") for url, title in zip(movie_df["Url"], movie_df["Title"])],
keybindings={"skip": [{"key": "escape"}]},
invalid_message="Input must be in the resulting IDs",
).execute()
return result


def print_film(film, expand=True):
def print_film(film: dict, expand=True):
grid = Table.grid(expand=expand, padding=1)
grid.add_column(style="bold yellow")
grid.add_column()
Expand All @@ -107,15 +92,15 @@ def download_poster(poster: str):
art.to_terminal(columns=int(config["CLI"]["poster_columns"]))


def _validate_date(s: str):
def _validate_date(s: str) -> bool:
try:
datetime.strptime(s, "%Y-%m-%d")
except ValueError:
return False
return True


def add_film_questions():
def add_film_questions() -> dict[str, str]:
print("Set all the infos for the film:\n")
specify_date = inquirer.confirm(message="Specify date?").execute() # type: ignore
today = datetime.today().strftime("%Y-%m-%d")
Expand Down
28 changes: 14 additions & 14 deletions letterboxd_stats/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
tqdm.pandas(desc="Fetching ids...")


def check_if_watched(df: pd.DataFrame, row: pd.Series):
def check_if_watched(df: pd.DataFrame, row: pd.Series) -> bool:
if row["Title"] in df["Name"].values:
watched_films_same_name = df[df["Name"] == row["Title"]]
for _, film in watched_films_same_name.iterrows():
film_id = get_tmdb_id(film["Letterboxd URI"])
if film_id == row["Id"]:
if film_id == row.name:
return True
return False


def read_watched_films(df: pd.DataFrame, path: str, name: str):
def read_watched_films(df: pd.DataFrame, path: str, name: str) -> pd.DataFrame:
df_profile = pd.read_csv(path)
df.insert(0, "watched", np.where([check_if_watched(df_profile, row) for _, row in df.iterrows()], "[X]", "[ ]"))
df["Release Date"] = pd.to_datetime(df["Release Date"])
Expand All @@ -31,39 +31,39 @@ def read_watched_films(df: pd.DataFrame, path: str, name: str):
return df


def select_film_of_person(df):
movie_id = cli.select_movie_id(df[["Id", "Title"]])
def select_film_of_person(df: pd.DataFrame) -> pd.Series | None:
movie_id = cli.select_movie(df["Title"], df.index.to_series().parallel_map(str))
if movie_id is None:
return None
movie_row = df.loc[df["Id"] == movie_id].iloc[0, :]
movie_row = df.loc[int(movie_id)]
return movie_row


def get_list_name(path: str):
def get_list_name(path: str) -> str:
df = pd.read_csv(path, header=1)
return df["Name"].iloc[0]


def open_list(path: str, limit, acending):
def open_list(path: str, limit: int, acending: bool) -> str:
list_names = {
get_list_name(os.path.join(path, letterboxd_list)): letterboxd_list for letterboxd_list in os.listdir(path)
}
name = cli.select_list(sorted(list(list_names.keys())))
return open_file("Lists", os.path.join(path, list_names[name]), limit, acending, header=3)


def open_file(filetype: str, path: str, limit, ascending, header=0):
def open_file(filetype: str, path: str, limit, ascending, header=0) -> str:
df = pd.read_csv(path, header=header)
df.rename(columns={"Name": "Title", "Letterboxd URI": "Url"}, inplace=True)
df["Year"] = df["Year"].fillna(0).astype(int)
df = FILE_OPERATIONS[filetype](df, ascending)
if limit is not None:
df = df.iloc[:limit, :]
cli.render_table(df, filetype)
return cli.select_movie(df[["Title", "Url"]])
return cli.select_movie(df["Title"], df["Url"])


def _show_lists(df: pd.DataFrame, ascending: bool):
def _show_lists(df: pd.DataFrame, ascending: bool) -> pd.DataFrame:
ratings_path = os.path.expanduser(os.path.join(config["root_folder"], "static", "ratings.csv"))
df_ratings = pd.read_csv(ratings_path)
df_ratings.rename(columns={"Letterboxd URI": "URL"}, inplace=True)
Expand All @@ -84,7 +84,7 @@ def _show_lists(df: pd.DataFrame, ascending: bool):
return df


def _show_watchlist(df: pd.DataFrame, ascending: bool):
def _show_watchlist(df: pd.DataFrame, ascending: bool) -> pd.DataFrame:
sort_column = cli.select_value(
df.columns.values.tolist() + ["Shuffle"], "Select the order of your watchlist entries:"
)
Expand All @@ -95,15 +95,15 @@ def _show_watchlist(df: pd.DataFrame, ascending: bool):
return df


def _show_diary(df: pd.DataFrame, ascending: bool):
def _show_diary(df: pd.DataFrame, ascending: bool) -> pd.DataFrame:
df["Watched Date"] = pd.to_datetime(df["Watched Date"])
sort_column = cli.select_value(df.columns.values.tolist(), "Select the order of your diary entries:")
df.sort_values(by=sort_column, ascending=ascending, inplace=True)
df = df.drop(["Rewatch", "Tags"], axis=1)
return df


def _show_ratings(df: pd.DataFrame, ascending: bool):
def _show_ratings(df: pd.DataFrame, ascending: bool) -> pd.DataFrame:
df["Date"] = pd.to_datetime(df["Date"])
sort_column = cli.select_value(df.columns.values.tolist(), "Select the order of your ratings:")
df.sort_values(by=sort_column, ascending=ascending, inplace=True)
Expand Down
8 changes: 4 additions & 4 deletions letterboxd_stats/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def download_data():
downloader.download_stats()


def get_movie_detail_from_url(letterboxd_url, is_diary=False):
def get_movie_detail_from_url(letterboxd_url: str, is_diary=False):
if letterboxd_url is not None:
id = ws.get_tmdb_id(letterboxd_url, is_diary)
if id is not None:
Expand All @@ -41,9 +41,9 @@ def search_person(args_search: str):
df = data.read_watched_films(df, path, name)
movie = data.select_film_of_person(df)
while movie is not None:
search_film_query = f"{movie['Title']} {movie['Release Date'].year}"
search_film_query = f"{movie['Title']} {movie['Release Date'].year}" # type: ignore
title_url = ws.search_film(search_film_query)
tmdb.get_movie_detail(movie["Id"], ws.create_movie_url(title_url, "film_page"))
tmdb.get_movie_detail(int(movie.name), ws.create_movie_url(title_url, "film_page")) # type: ignore
movie = data.select_film_of_person(df)


Expand All @@ -58,7 +58,7 @@ def search_film(args_search_film: str):
downloader.perform_operation(answer, title_url)


def get_data(args_limit, args_ascending, data_type):
def get_data(args_limit: int, args_ascending: bool, data_type: str):
path = os.path.expanduser(os.path.join(config["root_folder"], "static", DATA_FILES[data_type]))
check_path(path)
letterboxd_url = (
Expand Down
14 changes: 8 additions & 6 deletions letterboxd_stats/tmdb.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from typing import Any, Tuple
from tmdbv3api import TMDb, Person, Movie, Search
from tmdbv3api.exceptions import TMDbException
import pandas as pd
from tmdbv3api.objs.account import AsObj
from letterboxd_stats import cli
from letterboxd_stats import config
from pandarallel import pandarallel
Expand All @@ -13,7 +15,7 @@
pandarallel.initialize(verbose=0)


def get_person(name: str):
def get_person(name: str) -> Tuple[pd.DataFrame, str]:
print(f"Searching for '{name}'")
search_results = search.people({"query": name})
names = [result.name for result in search_results] # type: ignore
Expand All @@ -26,27 +28,27 @@ def get_person(name: str):
movie_credits = person.movie_credits(search_result["id"])
list_of_films = [
{
"Id": m.id,
"Title": m.title,
"Release Date": m.release_date,
"Department": m.department,
"Id": m.id,
}
for m in movie_credits["crew"]
]
if len(list_of_films) == 0:
raise ValueError("The selected person doesn't have any film.")
df = pd.DataFrame(list_of_films)
df = pd.DataFrame(list_of_films).set_index("Id")
department = cli.select_value(
df["Department"].unique(), f"Select a department for {p['name']}", known_for_department
)
df = df[df["Department"] == department]
df = df.drop("Department", axis=1)
if config["TMDB"]["get_list_runtimes"] is True:
df["Duration"] = df["Id"].parallel_map(get_film_duration) # type: ignore
df["Duration"] = df.index.to_series().parallel_map(get_film_duration) # type: ignore
return df, p["name"]


def get_movie(movie_query: str):
def get_movie(movie_query: str) -> Any | AsObj:
print(f"Searching for movie '{movie_query}'")
search_results = search.movies({"query": movie_query})
titles = [f"{result.title} ({result.release_date})" for result in search_results] # type: ignore
Expand Down Expand Up @@ -75,7 +77,7 @@ def get_movie_detail(movie_id: int, letterboxd_url=None):
cli.print_film(selected_details)


def get_film_duration(tmdb_id: str):
def get_film_duration(tmdb_id: str) -> int:
try:
runtime = movie.details(int(tmdb_id)).runtime # type: ignore
except TMDbException:
Expand Down
10 changes: 5 additions & 5 deletions letterboxd_stats/web_scraper.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ def perform_operation(self, answer: str, link: str):
getattr(self, MOVIE_OPERATIONS[answer])(link)


def create_movie_url(title: str, operation: str):
def create_movie_url(title: str, operation: str) -> str:
return URL + OPERATIONS_URLS[operation](title)


def _get_tmdb_id_from_web(link: str, is_diary: bool):
def _get_tmdb_id_from_web(link: str, is_diary: bool) -> int:
res = requests.get(link)
movie_page = html.fromstring(res.text)
if is_diary:
Expand All @@ -113,7 +113,7 @@ def _get_tmdb_id_from_web(link: str, is_diary: bool):
return int(id)


def get_tmdb_id(link: str, is_diary=False):
def get_tmdb_id(link: str, is_diary=False) -> int | None:
tmdb_id_cache = shelve.open(cache_path, writeback=False, protocol=5)
prefix, key = link.rsplit("/", 1)
if prefix in tmdb_id_cache and key in tmdb_id_cache[prefix]:
Expand All @@ -131,11 +131,11 @@ def get_tmdb_id(link: str, is_diary=False):
return id


def select_optional_operation():
def select_optional_operation() -> str:
return cli.select_value(["Exit"] + list(MOVIE_OPERATIONS.keys()), "Select operation:")


def search_film(title: str, allow_selection=False):
def search_film(title: str, allow_selection=False) -> str:
search_url = create_movie_url(title, "search")
res = requests.get(search_url)
if res.status_code != 200:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "letterboxd_stats"
version = "0.2.8"
version = "0.2.9"
authors = [{ name = "mBaratta96" }]
description = "Get information about your Letterboxd activity."
readme = "README.md"
Expand Down

0 comments on commit e868576

Please sign in to comment.