Skip to content

Commit 30208ea

Browse files
Merge pull request #15 from mProjectsCode/master
version 0.1.9
2 parents 29e6712 + 889d517 commit 30208ea

25 files changed

+625
-159
lines changed

README.md

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,60 @@ A plugin that can query multiple APIs for movies, series, anime, games, music an
44

55
### Features
66
#### Search by Title
7-
Search a movie, series, anime or game by its name across multiple APIs.
7+
Search a movie, series, anime, game, music release or wiki article by its name across multiple APIs.
88

99
#### Search by ID
10-
Allows you to search by an ID that varies from API to API. Concrete info can be found in the description of the individual APIs.
10+
Allows you to search by an ID that varies from API to API. Concrete information on this feature can be found in the description of the individual APIs.
1111

1212
#### Templates
13-
The plugin allows you to set a template note that gets added to the end of any note created by this plugin.
14-
The plugin also offers simple "template tgs". E.g. if the template includes `{{ title }}`, it will be replaced by the title of the movie, show or game.
13+
The plugin allows you to set a template note that gets added to the end of any note created by this plugin.
14+
The plugin also offers simple "template tgs". E.g. if the template includes `{{ title }}`, it will be replaced by the title of the movie, show or game.
1515
Note that "template tags" are surrounded with two curly braces and that the spaces inside the curly braces are important.
1616

1717
For arrays there are two special ways of displaying them.
1818
- using `{{ LIST:variable_name }}` will result in
19-
```
20-
- element 1
21-
- element 2
22-
- element 3
23-
- ...
24-
```
19+
```
20+
- element 1
21+
- element 2
22+
- element 3
23+
- ...
24+
```
2525
- using `{{ ENUM:variable_name }}` will result in
26-
```
27-
element 1, element 2, element 3, ...
28-
```
26+
```
27+
element 1, element 2, element 3, ...
28+
```
2929

30+
Available variables that can be used in template tags are the same variables from the metadata of the note.
3031

3132
I also published my own templates [here](https://github.com/mProjectsCode/obsidian-media-db-templates).
3233

34+
### How to install
35+
Currently, you have to manually download the zip archive from the latest release here on GitHub.
36+
After downloading, extract the archive into the `.obsidian/plugins` folder in your vault.
37+
38+
The folder structure should look like this:
39+
```
40+
[path to your vault]
41+
|_ .obsidian
42+
|_ plugins
43+
|_ obsidian-media-db-plugin
44+
|_ main.js
45+
|_ manifest.json
46+
|_ styles.css
47+
```
48+
49+
Once the plugin submission goes through, the plugin will also be installable directly through obsidian's plugin installer.
50+
51+
### How to use
52+
(pictures are coming)
53+
54+
Once you have installed this plugin, you will find a database icon in the left ribbon.
55+
When using this or the `Add new Media DB entry` command, a popup will open.
56+
Here you can enter the title of what you want to search for and then select in which APIs to search.
57+
58+
After clicking search, a new popup will open prompting you to select from the search results.
59+
Now you select the result you want and the plugin will cast it's magic and create a new note in your vault, that contains the metadata of the selected search result.
60+
3361
### Currently supported media types
3462
- movies (including specials)
3563
- series (including OVAs)
@@ -39,11 +67,12 @@ I also published my own templates [here](https://github.com/mProjectsCode/obsidi
3967

4068
### Currently supported APIs:
4169
| Name | Description | Supported formats | Authentification | Rate limiting | SFW filter support |
42-
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------- | ------------------------------ | ------------------ |
70+
|------------------------------------------------------|---------------------------------------------------------------------------------------------------|--------------------------------|------------------------------------------------------------------------------|--------------------------------|--------------------|
4371
| [Jikan](https://jikan.moe/) | Jikan is an API that uses [My Anime List](https://myanimelist.net) and offers metadata for anime. | series, movies, specials, OVAs | No | 60 per minute and 3 per second | Yes |
4472
| [OMDb](https://www.omdbapi.com/) | OMDb is an API that offers metadata for movie, series and games. | series, movies, games | Yes, you can get a free key here [here](https://www.omdbapi.com/apikey.aspx) | 1000 per day | No |
4573
| [MusicBrainz](https://musicbrainz.org/) | MusicBrainz is an API that offers information about music releases. | music releases | No | 50 per second | No |
46-
| [Wikipedia](https://en.wikipedia.org/wiki/Main_Page) | The Wikipedia API allows acces to all Wikipedia articles. | wiki articles | No | None | No | | | | | | |
74+
| [Wikipedia](https://en.wikipedia.org/wiki/Main_Page) | The Wikipedia API allows access to all Wikipedia articles. | wiki articles | No | None | No |
75+
| [Steam](https://store.steampowered.com/) | The Steam API offers information on all steam games. | games | No | 10000 per day | No |
4776

4877
#### Notes
4978
- [Jikan](https://jikan.moe/)
@@ -61,9 +90,15 @@ I also published my own templates [here](https://github.com/mProjectsCode/obsidi
6190
- you can find this ID in the URL
6291
- e.g. for "Rogue One" the URL looks like this `https://www.imdb.com/title/tt3748528/` so the ID is `tt3748528`
6392
- [MusicBrainz](https://musicbrainz.org/)
64-
- the id of a release is not easily accessibe, you are better of just searching by title
93+
- the id of a release is not easily accessible, you are better off just searching by title
6594
- [Wikipedia](https://en.wikipedia.org/wiki/Main_Page)
6695
- [here](https://en.wikipedia.org/wiki/Wikipedia:Finding_a_Wikidata_ID) is a guide to finding the Wikipedia ID for an article
96+
- [Steam](https://store.steampowered.com/)
97+
- you can find this ID in the URL
98+
- e.g. for "Factorio" the URL looks like this `https://store.steampowered.com/app/427520/Factorio/` so the ID is `427520`
99+
100+
### Problems, unexpected behavior or improvement suggestions?
101+
You are more than welcome to open an issue on [GitHub](https://github.com/mProjectsCode/obsidian-media-db-plugin/issues).
67102

68103
### Contributions
69104
Thank you for wanting to contribute to this project.

src/api/APIManager.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ export class APIManager {
2525
}
2626

2727
async queryDetailedInfo(item: MediaTypeModel): Promise<MediaTypeModel> {
28+
return await this.queryDetailedInfoById(item.id, item.dataSource);
29+
}
30+
31+
async queryDetailedInfoById(id: string, dataSource: string): Promise<MediaTypeModel> {
2832
for (const api of this.apis) {
29-
if (api.apiName === item.dataSource) {
30-
return api.getById(item);
33+
if (api.apiName === dataSource) {
34+
return api.getById(id);
3135
}
3236
}
3337
}

src/api/APIModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export abstract class APIModel {
1313
*/
1414
abstract searchByTitle(title: string): Promise<MediaTypeModel[]>;
1515

16-
abstract getById(item: MediaTypeModel): Promise<MediaTypeModel>;
16+
abstract getById(id: string): Promise<MediaTypeModel>;
1717

1818
hasType(type: string): boolean {
1919
return this.types.contains(type);

src/api/apis/LocGovAPI.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ export class LocGovAPI extends APIModel {
4040
// return ret;
4141
}
4242

43-
async getById(item: MediaTypeModel): Promise<MediaTypeModel> {
43+
async getById(id: string): Promise<MediaTypeModel> {
4444
console.log(`MDB | api "${this.apiName}" queried by ID`);
4545

46-
const searchUrl = `https://www.loc.gov/item/${item.id}/?fo=json`;
46+
const searchUrl = `https://www.loc.gov/item/${encodeURIComponent(id)}/?fo=json`;
4747
const fetchData = await fetch(searchUrl);
4848
if (fetchData.status !== 200) {
4949
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);

src/api/apis/MALAPI.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ export class MALAPI extends APIModel {
6969
return ret;
7070
}
7171

72-
async getById(item: MediaTypeModel): Promise<MediaTypeModel> {
72+
async getById(id: string): Promise<MediaTypeModel> {
7373
console.log(`MDB | api "${this.apiName}" queried by ID`);
7474

75-
const searchUrl = `https://api.jikan.moe/v4/anime/${item.id}`;
75+
const searchUrl = `https://api.jikan.moe/v4/anime/${encodeURIComponent(id)}`;
7676
const fetchData = await fetch(searchUrl);
7777

7878
if (fetchData.status !== 200) {
@@ -107,9 +107,11 @@ export class MALAPI extends APIModel {
107107
released: true,
108108
premiere: (new Date(result.aired?.from)).toLocaleDateString() ?? 'unknown',
109109

110-
watched: false,
111-
lastWatched: '',
112-
personalRating: 0,
110+
userData: {
111+
watched: false,
112+
lastWatched: '',
113+
personalRating: 0,
114+
},
113115
} as MovieModel);
114116

115117
return model;
@@ -135,9 +137,11 @@ export class MALAPI extends APIModel {
135137
airedTo: (new Date(result.aired?.to)).toLocaleDateString() ?? 'unknown',
136138
airing: result.airing,
137139

138-
watched: false,
139-
lastWatched: '',
140-
personalRating: 0,
140+
userData: {
141+
watched: false,
142+
lastWatched: '',
143+
personalRating: 0,
144+
},
141145
} as SeriesModel);
142146

143147
return model;

src/api/apis/MusicBrainzAPI.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ export class MusicBrainzAPI extends APIModel {
5858
return ret;
5959
}
6060

61-
async getById(item: MediaTypeModel): Promise<MediaTypeModel> {
61+
async getById(id: string): Promise<MediaTypeModel> {
6262
console.log(`MDB | api "${this.apiName}" queried by ID`);
6363

64-
const searchUrl = `https://musicbrainz.org/ws/2/release-group/${encodeURIComponent(item.id)}?inc=releases+artists+tags+ratings+genres&fmt=json`;
64+
const searchUrl = `https://musicbrainz.org/ws/2/release-group/${encodeURIComponent(id)}?inc=releases+artists+tags+ratings+genres&fmt=json`;
6565
const fetchData = await requestUrl({
6666
url: searchUrl,
6767
headers: {
68-
'User-Agent': `${pluginName}/0.1.7 (${contactEmail})`,
68+
'User-Agent': `${pluginName}/${mediaDbVersion} (${contactEmail})`,
6969
},
7070
});
7171

@@ -90,6 +90,10 @@ export class MusicBrainzAPI extends APIModel {
9090
genres: result.genres.map((g: any) => g.name),
9191
subType: result['primary-type'],
9292
rating: result.rating.value * 2,
93+
94+
userData: {
95+
personalRating: 0,
96+
},
9397
} as MusicReleaseModel);
9498

9599
return model;

src/api/apis/OMDbAPI.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ export class OMDbAPI extends APIModel {
8888
return ret;
8989
}
9090

91-
async getById(item: MediaTypeModel): Promise<MediaTypeModel> {
91+
async getById(id: string): Promise<MediaTypeModel> {
9292
console.log(`MDB | api "${this.apiName}" queried by ID`);
9393

94-
const searchUrl = `http://www.omdbapi.com/?i=${item.id}&apikey=${this.plugin.settings.OMDbKey}`;
94+
const searchUrl = `http://www.omdbapi.com/?i=${encodeURIComponent(id)}&apikey=${this.plugin.settings.OMDbKey}`;
9595
const fetchData = await fetch(searchUrl);
9696

9797
if (fetchData.status === 401) {
@@ -132,9 +132,11 @@ export class OMDbAPI extends APIModel {
132132
released: true,
133133
premiere: (new Date(result.Released)).toLocaleDateString() ?? 'unknown',
134134

135-
watched: false,
136-
lastWatched: '',
137-
personalRating: 0,
135+
userData: {
136+
watched: false,
137+
lastWatched: '',
138+
personalRating: 0,
139+
},
138140
} as MovieModel);
139141

140142
return model;
@@ -160,9 +162,11 @@ export class OMDbAPI extends APIModel {
160162
airedFrom: (new Date(result.Released)).toLocaleDateString() ?? 'unknown',
161163
airedTo: 'unknown',
162164

163-
watched: false,
164-
lastWatched: '',
165-
personalRating: 0,
165+
userData: {
166+
watched: false,
167+
lastWatched: '',
168+
personalRating: 0,
169+
},
166170
} as SeriesModel);
167171

168172
return model;
@@ -183,8 +187,10 @@ export class OMDbAPI extends APIModel {
183187
released: true,
184188
releaseDate: (new Date(result.Released)).toLocaleDateString() ?? 'unknown',
185189

186-
played: false,
187-
personalRating: 0,
190+
userData: {
191+
played: false,
192+
personalRating: 0,
193+
},
188194
} as GameModel);
189195

190196
return model;

src/api/apis/SteamAPI.ts

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import {APIModel} from '../APIModel';
2+
import {MediaTypeModel} from '../../models/MediaTypeModel';
3+
import MediaDbPlugin from '../../main';
4+
import {GameModel} from '../../models/GameModel';
5+
import {debugLog} from '../../utils/Utils';
6+
import {requestUrl} from 'obsidian';
7+
import {MediaType} from '../../utils/MediaType';
8+
9+
export class SteamAPI extends APIModel {
10+
plugin: MediaDbPlugin;
11+
typeMappings: Map<string, string>;
12+
13+
constructor(plugin: MediaDbPlugin) {
14+
super();
15+
16+
this.plugin = plugin;
17+
this.apiName = 'SteamAPI';
18+
this.apiDescription = 'A free API for all Steam games.';
19+
this.apiUrl = 'http://www.steampowered.com/';
20+
this.types = ['games'];
21+
this.typeMappings = new Map<string, string>();
22+
this.typeMappings.set('game', 'game');
23+
}
24+
25+
async searchByTitle(title: string): Promise<MediaTypeModel[]> {
26+
console.log(`MDB | api "${this.apiName}" queried by Title`);
27+
28+
const searchUrl = `http://api.steampowered.com/ISteamApps/GetAppList/v0002/?format=json`;
29+
const fetchData = await requestUrl({
30+
url: searchUrl,
31+
});
32+
33+
if (fetchData.status !== 200) {
34+
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
35+
}
36+
37+
const data = await fetchData.json;
38+
39+
debugLog(data);
40+
41+
let filteredData = [];
42+
43+
for (const app of data.applist.apps) {
44+
if (app.name.toLowerCase().includes(title.toLowerCase())) {
45+
filteredData.push(app);
46+
}
47+
if (filteredData.length > 20) {
48+
break;
49+
}
50+
}
51+
52+
let ret: MediaTypeModel[] = [];
53+
54+
for (const result of filteredData) {
55+
ret.push(new GameModel({
56+
type: MediaType.Game,
57+
title: result.name,
58+
englishTitle: result.name,
59+
year: '',
60+
dataSource: this.apiName,
61+
id: result.appid,
62+
} as GameModel));
63+
}
64+
65+
return ret;
66+
}
67+
68+
async getById(id: string): Promise<MediaTypeModel> {
69+
console.log(`MDB | api "${this.apiName}" queried by ID`);
70+
71+
const searchUrl = `http://store.steampowered.com/api/appdetails?appids=${encodeURIComponent(id)}`;
72+
const fetchData = await requestUrl({
73+
url: searchUrl,
74+
});
75+
76+
if (fetchData.status !== 200) {
77+
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
78+
}
79+
80+
debugLog(await fetchData.json);
81+
82+
let result;
83+
for (const [key, value] of Object.entries(await fetchData.json)) {
84+
if (key == id) {
85+
result = value.data;
86+
}
87+
}
88+
if (!result) {
89+
throw Error(`MDB | API returned invalid data.`);
90+
}
91+
92+
debugLog(result);
93+
94+
const model = new GameModel({
95+
type: MediaType.Game,
96+
title: result.name,
97+
englishTitle: result.name,
98+
year: (new Date(result.release_date.date)).getFullYear().toString(),
99+
dataSource: this.apiName,
100+
url: `https://store.steampowered.com/app/${result.id}`,
101+
id: result.steam_appid,
102+
103+
genres: result.genres?.map((x: any) => x.description) ?? [],
104+
onlineRating: Number.parseFloat(result.metacritic?.score ?? 0),
105+
image: result.header_image ?? '',
106+
107+
released: !result.release_date?.comming_soon,
108+
releaseDate: (new Date(result.release_date?.date)).toLocaleDateString() ?? 'unknown',
109+
110+
userData: {
111+
played: false,
112+
personalRating: 0,
113+
},
114+
} as GameModel);
115+
116+
return model;
117+
118+
}
119+
}

0 commit comments

Comments
 (0)