Skip to content

Commit 870681f

Browse files
committed
Added README.md providing useful information for getting familiar with this project
1 parent 745aada commit 870681f

File tree

2 files changed

+330
-2
lines changed

2 files changed

+330
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88
### Added
9-
- LICENSE.txt and license file headers for [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
10-
- Added integration tests which will be executed against the real _TheTVDB.com_ remote API
9+
- README.md providing useful information for getting familiar with the project.
10+
- LICENSE.txt and license file headers for [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt).
11+
- Added integration tests which will be executed against the real _TheTVDB.com_ remote API.
1112

1213
### Changed
1314
- Fixed some typos and outdated package names in JavaDoc.

README.md

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
# thetvdb-java-api
2+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
3+
4+
A simple connector for an easy integration of the [TheTVDB.com](https://thetvdb.com/) RESTful API in Java projects.
5+
6+
## Table of contents
7+
- [Introduction](#introduction)
8+
- [Technologies](#technologies)
9+
- [Features](#features)
10+
- [Setup](#setup)
11+
- [Code Examples](#code-examples)
12+
- [Development](#development)
13+
- [Status](#status)
14+
- [License](#license)
15+
16+
## Introduction
17+
With more than [240,000+](https://www.thetvdb.com/about) TV Series and movies _TheTVDB.com_ is probably one of the largest
18+
digital media metadata databases in the world. Moreover, they offer the opportunity to access this vast amount of data
19+
on M2M-level by providing a RESTful API, which I think is pretty cool as it enables developers to virtually include
20+
all this data into their own applications. However, the majority of these applications will probably intend to actually
21+
make some good use of this information in order to create something beneficial for the end user. Talking about Java
22+
applications, that's where this connector might come in handy.
23+
24+
One of the main objectives of this little project was to keep the code of these aforementioned applications clean.
25+
Communicating with the _TheTVDB.com_ API to gather information is a necessity, but most likely not the end of whatever
26+
you're aiming to create. So in order to not bloat the code with opening connections, preparing requests, process and
27+
evaluate responses and finally parse its JSON content, all of this may be handled by the `thetvdb-java-api` connector,
28+
leaving you with only a few (but unavoidable) lines of code describing what you actually want to achieve (e.g. query
29+
a TV Series by name).
30+
31+
However, where there is light there is also shadow, they say. Simplifying things often means to also restrict their
32+
functionality to only some basics. And although this might be quite an acceptable trade-off for many people, there will
33+
always be someone who is ruled out from using certain tools due to the need of some more advanced functionality. So another
34+
important goal was to promote this simplified usage while maintaining the usability for more complex use-cases at the
35+
same time. So it's actually up to the developer whether to query by some common parameters in just a one-liner and to
36+
work with the prefabbed Java DTOs or to run more complex queries by providing a set of parameters and maybe even parse
37+
the raw JSON content returned by the _TheTVDB.com_ API all by yourself. Your decision!
38+
39+
## Technologies
40+
* [Java](https://jdk.java.net/) (1.9) - Class-based, object-oriented programming language
41+
* [Apache Maven](https://maven.apache.org/download.cgi) (3.6.0) - Software project management and comprehension tool
42+
43+
## Features
44+
In general, this connector is fully compatible with all available _TheTVDB.com_ API endpoints. However, as new versions
45+
of the RESTful API might not always be backwards compatible, each major `thetvdb-java-api` release is invariantly linked
46+
to a specific version of the _TheTVDB.com_ remote API. The API version a specific connector release is using can be derived
47+
from its version number. For example, `v3.x` uses the _TheTVDB.com_ APIv3 whereas the (not yet existent) `v4.x` would use
48+
the upcoming APIv4.
49+
50+
<details><summary>Supported _TheTVDB.com_ APIv3 routes (`thetvdb-java-api v3.x`)</summary>
51+
- Authentication
52+
+ [/login](https://api.thetvdb.com/swagger#!/Authentication/post_login)
53+
+ [/refresh_token](https://api.thetvdb.com/swagger#!/Authentication/get_refresh_token)
54+
- Episodes
55+
+ [/episodes/{id}](https://api.thetvdb.com/swagger#!/Episodes/get_episodes_id)
56+
- Languages
57+
+ [/languages](https://api.thetvdb.com/swagger#!/Languages/get_languages)
58+
+ [/languages/{id}](https://api.thetvdb.com/swagger#!/Languages/get_languages_id)
59+
- Movies
60+
+ [/movies/{id}](https://api.thetvdb.com/swagger#!/Movies/get_movies_id)
61+
+ [/movieupdates](https://api.thetvdb.com/swagger#!/Movies/get_movieupdates)
62+
- Search
63+
+ [/search/series](https://api.thetvdb.com/swagger#!/Search/get_search_series)
64+
+ [/search/series/params](https://api.thetvdb.com/swagger#!/Search/get_search_series_params)
65+
- Series
66+
+ [/series/{id}](https://api.thetvdb.com/swagger#!/Series/get_series_id)
67+
+ [/series/{id}](https://api.thetvdb.com/swagger#!/Series/head_series_id) (HEAD)
68+
+ [/series/{id}/actors](https://api.thetvdb.com/swagger#!/Series/get_series_id_actors)
69+
+ [/series/{id}/episodes](https://api.thetvdb.com/swagger#!/Series/get_series_id_episodes)
70+
+ [/series/{id}/episodes/query](https://api.thetvdb.com/swagger#!/Series/get_series_id_episodes_query)
71+
+ [/series/{id}/episodes/query/params](https://api.thetvdb.com/swagger#!/Series/get_series_id_episodes_query_params)
72+
+ [/series/{id}/episodes/summary](https://api.thetvdb.com/swagger#!/Series/get_series_id_episodes_summary)
73+
+ [/series/{id}/filter](https://api.thetvdb.com/swagger#!/Series/get_series_id_filter)
74+
+ [/series/{id}/filter/params](https://api.thetvdb.com/swagger#!/Series/get_series_id_filter_params)
75+
+ [/series/{id}/images](https://api.thetvdb.com/swagger#!/Series/get_series_id_images)
76+
+ [/series/{id}/images/query](https://api.thetvdb.com/swagger#!/Series/get_series_id_images_query)
77+
+ [/series/{id}/images/query/params](https://api.thetvdb.com/swagger#!/Series/get_series_id_images_query_params)
78+
- Updates
79+
+ [/updated/query](https://api.thetvdb.com/swagger#!/Updates/get_updated_query)
80+
+ [/updated/query/params](https://api.thetvdb.com/swagger#!/Updates/get_updated_query_params)
81+
- Users
82+
+ [/user](https://api.thetvdb.com/swagger#!/Users/get_user)
83+
+ [/user/favorites](https://api.thetvdb.com/swagger#!/Users/get_user_favorites)
84+
+ [/user/favorites/{id}](https://api.thetvdb.com/swagger#!/Users/delete_user_favorites_id) (DELETE)
85+
+ [/user/favorites/{id}](https://api.thetvdb.com/swagger#!/Users/put_user_favorites_id) (PUT)
86+
+ [/user/ratings](https://api.thetvdb.com/swagger#!/Users/get_user_ratings)
87+
+ [/user/ratings/query](https://api.thetvdb.com/swagger#!/Users/get_user_ratings_query)
88+
+ [/user/ratings/query/params](https://api.thetvdb.com/swagger#!/Users/get_user_ratings_query_params)
89+
+ [/user/ratings/{itemType}/{itemId}](https://api.thetvdb.com/swagger#!/Users/delete_user_ratings_itemType_itemId)
90+
+ [/user/ratings/{itemType}/{itemId}/{itemRating}](https://api.thetvdb.com/swagger#!/Users/put_user_ratings_itemType_itemId_itemRating)
91+
</details>
92+
93+
## Setup
94+
#### Maven
95+
The artifact is *not* available through the central maven repository, but you may still include the connector into your
96+
maven project via the [jitpack.io](https://jitpack.io/) repository.
97+
98+
1. Add the JitPack repository to your build file
99+
```xml
100+
<repositories>
101+
<repository>
102+
<id>jitpack.io</id>
103+
<url>https://jitpack.io</url>
104+
</repository>
105+
</repositories>
106+
```
107+
2. Add the dependency
108+
```xml
109+
<dependency>
110+
<groupId>com.github.m0nk3y2k4</groupId>
111+
<artifactId>thetvdb-java-api</artifactId>
112+
<version>3.0.0</version>
113+
</dependency>
114+
```
115+
116+
#### Other build automation tools
117+
For other tools like e.g. _gradle_ please check out the documentation at https://jitpack.io/.
118+
119+
#### Manually include artifact
120+
In case your build tool isn't supported, or you're not using any build framework at all you can still include the artifact
121+
manually as _.jar_ file. The files (with and without dependencies) can either be obtained from the assets section of the
122+
corresponding [release](https://github.com/m0nk3y2k4/thetvdb-java-api/releases) or by cloning the repository and building
123+
the artifacts locally:
124+
```shell script
125+
mvn clean install
126+
```
127+
128+
## Code Examples
129+
#### Basics
130+
When it comes to using the connector, there's only one entry point where all your activities start:
131+
```
132+
com.github.m0nk3y2k4.thetvdb.TheTVDBApiFactory
133+
```
134+
This class provides factory methods to create all the objects needed for working with the connector, including new API
135+
instances, free configurable query parameters and proxies.
136+
137+
So let's create a new API instance using the factory methods.
138+
```java
139+
// "Simple" authentication with API-Key only
140+
TheTVDBApi api = TheTVDBApiFactory.createApi("API_KEY");
141+
142+
// or...
143+
144+
// "Advanced" authentication with API-Key, user key and user name
145+
TheTVDBApi usersApi = TheTVDBApiFactory.createApi("API_KEY", "Userkey", "Username");
146+
```
147+
>Please keep in mind that the _username_ and _key_ are **ONLY** required for the [/user](https://api.thetvdb.com/swagger#/Users)
148+
>routes.
149+
150+
Now we're going to use the simple API object to actually request data from the _TheTVDB.com_ REST endpoints. First and
151+
foremost we have to invoke the _/login_ route once. This will induce the remote API to issue a brand new
152+
[JSON Web Token](https://en.wikipedia.org/wiki/JSON_Web_Token) which will be needed for further authentication. After we
153+
have successfully requested a JWT, we can now go on to actually retrieve some data from the API.
154+
```java
155+
api.login(); // We could also use "api.init()" which does exactly the same
156+
157+
// Set the preferred language. If possible the remote API will return the requested data in this language
158+
// If not set, "en"' is the default
159+
api.setLanguage("it");
160+
161+
// Alternatively: invoking the "/languages" endpoint will get us a list of all supported languages
162+
List<Language> allLanguages = api.getAvailableLanguages();
163+
Language italian = allLanguages.stream()
164+
.filter(l -> l.getName().equals("italiano")).findFirst().get();
165+
api.setLanguage(italian.getAbbreviation());
166+
```
167+
>The connector comes with some integrated auto-login functionality, which will automatically try to request a new JWT
168+
>in case the authorization failed. Although this might come in handy at times, it is **strongly recommended** to manually
169+
>call "/login" route before requesting any data from the _TheTVDB.com_ API.
170+
171+
As you can see the JSON content received from the remote API has already been mapped into a `Language`
172+
[DTO](https://en.wikipedia.org/wiki/Data_transfer_object). These objects are available for all routes returning complex
173+
values like TV Series information, movies or actors. The actual metadata can be accessed through various getters in the
174+
usual object-oriented way.
175+
176+
Finally, let's see how to query for specific information. Let's imagine we would like to get all episodes of season 3
177+
for a specific TV Series. We can do that by using a corresponding set of `QueryParameters`.
178+
```java
179+
long seriesID = 296762;
180+
QueryParameters query = TheTVDBApiFactory.createQueryParameters();
181+
query.addParameter(Query.Series.AIREDSEASON, "3");
182+
183+
// Use your own custom set of query parameters
184+
List<Episode> seasonThree = api.queryEpisodes(seriesID, query);
185+
186+
System.out.println("Here come all the episodes of season 3:");
187+
seasonThree.stream().forEach(e -> System.out.println(
188+
e.getAiredSeason() + "." + e.getAiredEpisodeNumber() + ": " + e.getEpisodeName()));
189+
```
190+
```
191+
Here come all the episodes of season 3:
192+
3.1: Parce Domine
193+
3.2: The Winter Line
194+
3.3: The Absence of Field
195+
...
196+
```
197+
198+
For certain use cases the connector provides additional shortcut methods. Querying for a specific season is one of them,
199+
so we could do the exact same example with even less code.
200+
```java
201+
long seriesID = 296762;
202+
203+
List<Episode> seasonThree = api.queryEpisodesByAiredSeason(seriesID, 3);
204+
205+
System.out.println("And again, all the episodes of season 3:");
206+
seasonThree.stream().forEach(e -> System.out.println(
207+
e.getAiredSeason() + "." + e.getAiredEpisodeNumber() + ": " + e.getEpisodeName()));
208+
```
209+
```
210+
And again, all the episodes of season 3:
211+
3.1: Parce Domine
212+
3.2: The Winter Line
213+
3.3: The Absence of Field
214+
...
215+
```
216+
217+
And that's basically it! Go and check out the documentation of the main API interface `com.github.m0nk3y2k4.thetvdb.api.TheTVDBApi`
218+
to find more details on the various endpoint and shortcut methods.
219+
220+
#### Advanced
221+
We could already see that the connector automatically converts the JSON content into a matching DTO. This is the default
222+
behavior as it should be quite suitable for most cases, the so called default _layout_. However, two additional _layouts_
223+
are available to support a wide variety of operational areas: `JSON` and `Extended`
224+
225+
##### JSON layout
226+
If the prefabbed DTO's do not meet your requirements or if you prefer to take care of the JSON parsing yourself, this
227+
is the layout to go with. It supports all basic routes (without shortcut methods though) but instead of mapping the metadata
228+
into a DTO it will simply return the raw JSON as it was received from the remote API.
229+
```java
230+
// Create a new API instance the usual way
231+
TheTVDBApi api = TheTVDBApiFactory.createApi("API_KEY");
232+
233+
// Create a JSON layout from the existing API by invoking the "json()" method
234+
TheTVDBApi.JSON jsonApi = api.json();
235+
236+
long seriesID = 296762;
237+
QueryParameters query = TheTVDBApiFactory.createQueryParameters(Map.of(Query.Series.AIREDSEASON, "3"));
238+
239+
JsonNode seasonThreeJSON = jsonApi.queryEpisodes(seriesID, query);
240+
// jsonApi.queryEpisodesByAiredSeason(seriesID, 3); --> This wont work! Shortcut methods are only available in the default layout
241+
```
242+
243+
##### Extended layout
244+
This layout is basically just an extension of the default layout and provides access to additional (though optional)
245+
information received from the remote API, namely the "errors" and the "links" JSON nodes. Just like the `JSON` layout,
246+
it supports all basic routes (without shortcut methods). All methods of this layout will return an `APIResponse<T>`
247+
object which wraps the actual metadata DTO together with the error and pagination information.
248+
```java
249+
// Again, create the layout from any existing API
250+
TheTVDBApi.Extended extendedApi = api.extended();
251+
252+
// Get the 2nd page of all episodes for this TV Series (max. 100 per page)
253+
final long page = 2;
254+
QueryParameters query = TheTVDBApiFactory.createQueryParameters()
255+
.addParameter(Query.Series.PAGE, String.valueOf(page));
256+
257+
APIResponse<List<Episode>> response = extendedApi.queryEpisodes(75760, query);
258+
259+
// Get the metadata. This is actually what the default layout does.
260+
List<Episode> episodesSecondPage = response.getData();
261+
262+
// Errors and Links will not always be available and therefore will be returned as Optionals
263+
response.getErrors().map(Errors::getInvalidQueryParams).ifPresent(System.err::println);
264+
boolean morePages = response.getLinks().map(Links::getLast).map(lastPage -> lastPage > page).orElse(false);
265+
```
266+
>Please note that _Errors_ and _Links_ are not always available but only for certain endpoints. See the _TheTVDB.com_ API
267+
>documentation for detailed information.
268+
269+
##### Proxy
270+
The connector will send all requests directly towards the _TheTVDB.com_ [RESTful API](https://api.thetvdb.com/). In case
271+
your runtime environment is not able to access this resource directly, you can instruct the connector to send its requests
272+
to a different host which will forward them to the remote API.
273+
```java
274+
Proxy localProxy = TheTVDBApiFactory.createProxy("https", "my.local.proxy", 10000);
275+
TheTVDBApi proxiedApi = TheTVDBApiFactory.createApi("API_KEY", localProxy);
276+
277+
// Data will be requested from "https://my.local.proxy:10000/movies/2559"
278+
Movie excellent = proxiedApi.getMovie(2559);
279+
```
280+
281+
## Development
282+
#### Build
283+
After cloning the repository the connector can be build via Apache Maven:
284+
```shell script
285+
mvn clean install
286+
```
287+
The build process will generate the following content, all stored inside the `/target` folder:
288+
- Artifacts
289+
- `thetvdb-java-api-{VERSION}.jar` contains the actual connector artifact without dependencies
290+
- `thetvdb-java-api-{VERSION}-jar-with-dependencies.jar` contains the actual connector artifact will all runtime
291+
dependencies included
292+
- `thetvdb-java-api-{VERSION}-javadoc.jar` contains the packed JavaDoc documentation
293+
- `thetvdb-java-api-{VERSION}-sources.jar` contains the packed source code of the connector
294+
- Documentation
295+
- Available through the `-javadoc.jar` artifact or directly at `/apidocs/index.html`
296+
- Tests
297+
- jacoco code coverage report available at `/site/jacoco/index.html`
298+
299+
#### Integration Tests
300+
Integration tests are not part of the default build process as they are executed against the actual _TheTVDB.com_ remote
301+
API and thus require some additional configuration as well as an active Internet connection. Integration tests can be
302+
setup and executed with the following steps:
303+
304+
1. Create a new file `/src/integration-tests/resources/thetvdbapi.properties` and set the _TheTVDB.com_ API-Key, user
305+
key and user name you'd like to be used for the tests. You can use the available `thetvdbapi.properties.sample` file as
306+
a template.
307+
308+
2. Build the project with the `integration-tests` maven profile:
309+
```shell script
310+
mvn verify -P integration-tests
311+
```
312+
313+
3. _OPTIONAL_: Instead of providing the authentication settings via the `thetvdbapi.properties` file you may also set
314+
them directly as command line arguments:
315+
```shell script
316+
mvn verify -P integration-tests -Dintegration.thetvdb.com.apikey=APIKEY -Dintegration.thetvdb.com.userkey=USERKEY -Dintegration.thetvdb.com.username=USERNAME
317+
```
318+
319+
## Status
320+
Project is: _in progress_
321+
322+
Ongoing development of a connector compliant to the upcoming _TheTVDB.com_ APIv4 interface.
323+
324+
## License
325+
This project is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
326+
>Bear in mind that you might have to negotiate a distinct [license model](https://thetvdb.com/api-information) with
327+
>_TheTVDB.com, LLC._, e.g. when using their API service as part of a commercial product.

0 commit comments

Comments
 (0)