Skip to content

Commit

Permalink
Merge pull request #3 from navilg/fix/count-tv-shows-exclude-repeated…
Browse files Browse the repository at this point in the history
…-movies

Fix/count tv shows exclude repeated movies
  • Loading branch information
navilg authored Dec 15, 2024
2 parents 59853fd + 7d6416a commit e20301d
Show file tree
Hide file tree
Showing 15 changed files with 31 additions and 1,109 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ Generate year in review from Trakt history

## Steps

0. Install required python modules

```bash
pip install -r requirements.txt
```

1. Make your Trakt profile as public from Trakt's account setting.

2. Create `.env` file from `.env.example` file
Expand All @@ -30,4 +36,7 @@ python generate.py user_id 2024 trakt_client_id

## Screenshots

![](Screenshot.png)
![](Screenshot-1.png)


![](Screenshot-2.png)
Binary file added Screenshot-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshot-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed Screenshot.png
Binary file not shown.
77 changes: 21 additions & 56 deletions generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
from rich.layout import Layout
from rich.align import Align

from jinja2 import Environment, FileSystemLoader

if len(sys.argv) != 3:
load_dotenv()
else:
Expand All @@ -34,7 +32,6 @@
username = os.getenv('TRAKT_USER')

year=os.getenv('YEAR')
html_output_dir = 'year-in-review-outputs'

def fetch_trakt_history(username, start_date, end_date):
url = f"{TRAKT_API_BASE_URL}/users/{username}/history"
Expand Down Expand Up @@ -147,20 +144,23 @@ def get_episode_details(show_id, season_number, episode_number):
return data.get('runtime', 0), show_detail_data.get('genres', []), data.get('rating', 0)

def analyze_history(history):
tv_episodes = 0
tv_shows = {} # {tvshowid: countofplay}
tv_minutes = 0
tv_ratings = 0
tv_genres = Counter()
movies = 0
movies = {} # {movieid: countofplay}
movie_minutes = 0
movie_ratings = 0
movie_genres = Counter()
loop_count = 0

for item in history:
if item['type'] == 'episode':
tv_episodes += 1
show_id = item['show'].get('ids', {}).get('trakt')
if show_id in tv_shows:
tv_shows[show_id] += 1
else:
tv_shows[show_id] = 1
season_number = item['episode']['season']
episode_number = item['episode']['number']
if show_id:
Expand All @@ -173,8 +173,11 @@ def analyze_history(history):
genre_list = genres
tv_genres.update(genre_list)
elif item['type'] == 'movie':
movies += 1
id = item['movie'].get('ids', {}).get('trakt')
if id in movies:
movies[id] += 1
else:
movies[id] = 1
if id:
runtime, genres, rating = get_movie_details(id)
try:
Expand All @@ -185,29 +188,29 @@ def analyze_history(history):
genre_list = genres
movie_genres.update(genre_list)
loop_count += 1
if loop_count > 99:
sleep(10) # To make sure API call rate for Trakt is not breached. It waits for 10 seconds every 100th call
if loop_count >= 3:
sleep(1) # To make sure API call rate for Trakt is not breached (1000 calls every 5 minutes). It waits for 1 seconds after ecery 3rd call (max 180 calls in a minute)
loop_count = 0

return {
'tv_episodes': tv_episodes,
'tv_shows': len(tv_shows),
'tv_hours': round(tv_minutes / 60, 2),
'top_tv_genres': tv_genres.most_common(5),
'tv_genres_total_count': sum(tv_genres.values()),
'episodes_average_rating': round(tv_ratings/tv_episodes, 1),
'movies': movies,
'episodes_average_rating': round(tv_ratings/sum(tv_shows.values()), 1),
'movies': len(movies),
'movie_hours': round(movie_minutes / 60, 2),
'top_movie_genres': movie_genres.most_common(5),
'movie_genres_total_count': sum(movie_genres.values()),
'movies_average_rating': round(movie_ratings/movies,1)
'movies_average_rating': round(movie_ratings/sum(movies.values()),1)
}

start_date = datetime(int(year), 1, 1)
end_date = datetime(int(year), 12, 31)

# Fetch and analyze the history
print("Static HTML year in review page will be stored under", html_output_dir, "directory")
print('Generating Year in Review for', year+'. It may take few minutes depending on size of your watch history...')
print('Maximum 180 movies/episodes are analyzed in 1 minute to honor trakt api rate limit.')
print("\n")
history = fetch_trakt_history(username, start_date, end_date)
with open("trakt-history-"+year+".json", "w") as file:
Expand All @@ -221,7 +224,7 @@ def analyze_history(history):
"year": year,
"statistics": {
"tv_shows": {
"episodes_watched": stats['tv_episodes'],
"shows_watched": stats['tv_shows'],
"hours_watched": stats['tv_hours'],
"average_rating": stats['episodes_average_rating'],
"top_genres": [genre for genre, count in stats['top_tv_genres']]
Expand Down Expand Up @@ -257,8 +260,8 @@ def analyze_history(history):
Panel("Movies Watched\n\n[bold cyan]"+str(stats['movies'])+"[/bold cyan]", border_style="cyan"),
Panel("Movies Hours\n\n[bold green]"+str(stats['movie_hours'])+"[/bold green]", border_style="green"),
Panel("Movies Avg Rating\n\n[bold blue]"+str(stats['movies_average_rating'])+"[/bold blue]", border_style="blue"),
Panel("TV Episodes Watched\n\n[bold cyan]"+str(stats['tv_episodes'])+"[/bold cyan]", border_style="cyan"),
Panel("TV Episodes Hours\n\n[bold green]"+str(stats['tv_hours'])+"[/bold green]", border_style="green"),
Panel("TV Shows Watched\n\n[bold cyan]"+str(stats['tv_shows'])+"[/bold cyan]", border_style="cyan"),
Panel("Episode Hours\n\n[bold green]"+str(stats['tv_hours'])+"[/bold green]", border_style="green"),
Panel("Episodes Avg Rating\n\n[bold blue]"+str(stats['episodes_average_rating'])+"[/bold blue]", border_style="blue")
)

Expand Down Expand Up @@ -304,42 +307,4 @@ def create_genre_row(top_movie_genres_stat, total_count, color):
)

# Print Layout
console.print(layout)

def create_html_page(username, year, episodes_count, episode_hours, movies_count, movie_hours, tv_generes: list[str], movie_genres: list[str]):
templates_dir = 'html-templates'

# Data for substitution in the templates
data = {
'username': username,
'year': year,
'episodes_count': str(episodes_count),
'episode_hours': str(episode_hours),
'movies_count': str(movies_count),
'movie_hours': str(movie_hours),
'tv_generes': tv_generes,
'movie_genres': movie_genres
}

# Create the Jinja2 Environment to load templates
j2env = Environment(loader=FileSystemLoader(templates_dir))

# Get all template files from the templates directory
template_files = [f for f in os.listdir(templates_dir) if f.endswith('.html')]

# Iterate over each template file
for template_file in template_files:
# Load the template file
template = j2env.get_template(template_file)

# Render the template with the data
rendered_content = template.render(data)

# Define the output file path (create corresponding output files)
output_file_path = os.path.join(html_output_dir, template_file)

# Write the rendered content to a new file in the output directory
with open(output_file_path, 'w') as output_file:
output_file.write(rendered_content)

create_html_page(username, year, stats['tv_episodes'], stats['tv_hours'], stats['movies'], stats['movie_hours'], [genre for genre, count in stats['top_tv_genres']], [genre for genre, count in stats['top_movie_genres']])
console.print(layout)
141 changes: 0 additions & 141 deletions html-templates/year-in-review-theme-1.html

This file was deleted.

Loading

0 comments on commit e20301d

Please sign in to comment.