seanwlk / tvtimewrapper

Python Wrapper library for TVTime App (formerly TV Show Time)
GNU General Public License v2.0
15 stars 2 forks source link

myShows is broken #5

Open michidk opened 2 years ago

michidk commented 2 years ago

Seems like the API route https://api2.tozelabs.com/v2/my_shows does not work anymore:

>>> tvtime.show.myShows()
{'error': {'code': 500, 'message': None}}
michidk commented 2 years ago

Seems to be a duplicate of #3 which was never fixed. The workaround still works, but we should either fix the broken myShows() or remove it.

seanwlk commented 2 years ago

Yes i never had time to reverse engineer their new way of retrieving data in the app. Pull requests are well appreciated :D

michidk commented 2 years ago

How would I go about reverse engineering? The website does not use the API as far as I can tell. The first time I heard about this API was actually through this Python package. Is there an application using that API? Otherwise, it's just wild-guessing API routes?

seanwlk commented 2 years ago

I created this package by reverse engineering the TVTime App for android https://play.google.com/store/apps/details?id=com.tozelabs.tvshowtime

The problem is that when they added support for movie tracking, they created a new API gateway that doesn't use HTTP Basic auth but JWT login, i handled to get the routes that have the data about the movies and the profile data with tv shows list and everything but got stuck at creating a JWT token that can be accepted by the backend since i'd have to implement a way to use the refresh token to keep the session alive like the app does

michidk commented 2 years ago

Okay, interesting. So implementing the JWT refresh logic would probably mean a rewrite

seanwlk commented 2 years ago

Okay, interesting. So implementing the JWT refresh logic would probably mean a rewrite

Not necessarily, from what i've seen the token that gets sent at login expires after like 5 days but after that you'd have to refresh it to keep the requests going, so if someone had implemented an automated system that keeps the script going instead of single time runs, it would break. (ex. script that runs on a plex server that scrapes for watched episodes and marks them as watched automatically)

michidk commented 2 years ago

Do you still remember what the API routes were and where to get the TVST_ACCESS_TOKEN and X-API-Key token from?

michidk commented 2 years ago

Okay after a bit of research I found the following: Base URL is https://api2.tozelabs.com/v2/ X_API_Key is LhqxB7GE9a95beFHqiNC85GHdrX8hNi34H2uQ7QG

Exemplary requests: To get the tvst_access_token and user id:

curl --request GET 'https://api2.tozelabs.com/v2/signin?username=<USERNAME>&password=<PASSWORD>'

To then get statistics about series watched:

curl --request GET 'https://api2.tozelabs.com/v2/user/<USERID>/statistics?stat_type=watched&viewer_id=<USERID>' \
--header 'Authorization: Bearer <tvst_access_token>'

Edit: actually seems like it even works without the API key. It would be nice if we had an overview with API routes.

seanwlk commented 2 years ago

Some of those APIs dont even need auth from what i recall. I found some of my notes and one of the things that was bugging me is that you cannot mix the two sessions. If you add the headers with jwt and api key to the http basic auth session, the endpoints that use the jwt bearer will reply with error 500 Here are some of the endpoints i've noted:

https://msapi.tvtime.com/prod/v1/tracking/cgw/watchlist/movies/user/{tvtime.userId}?pageLastKey=null&sort=release_date%2Cdesc
https://users.tvtime.com/v1/users/{tvtime.userId}
https://api2.tozelabs.com/v2/user/{tvtime.userId}?fields=id,is_following,is_blocker,is_private,shows.fields(id,name,season_count,stripped_name,poster,fanart,rating,compatibility_rating,aired_episode_count,watched_episode_count,is_ended,is_started,network,is_archived,is_up_to_date,is_followed,is_favorite,is_thumbsed_down,is_for_later,sorting,filter,filters,country).limit(-1),favorite_shows.fields(id,name,season_count,stripped_name,poster,fanart,rating,compatibility_rating,aired_episode_count,watched_episode_count,is_ended,is_started,network,is_archived,is_up_to_date,is_followed,is_favorite,is_thumbsed_down,is_for_later,sorting,filter,filters,country).limit(-1),sorting,filters,shows_filtering
https://api2.tozelabs.com/v2/discover/shows
https://msapi.tvtime.com/prod/v2/lists/user/{tvtime.userId}
https://msapi.tvtime.com/prod/v1/movies/6d46fe13-36f4-4b60-86ce-40c909ba59f8

The thing now is, either i rewrite everything with the bearer implementation and drop the basic auth method or add support in a non breaking way to the bearer one with a second session internally managed but still have to decide if to implement a refresh of the jwt token

michidk commented 2 years ago

You could also let the user handle the refreshing of the token by exposing a refresh() function and exceptions that trigger if the token needs to be refreshed.

I just found this repo https://github.com/TheIndra55/tvtime-api/ which documents more of the api2/v2 routes.