node-csfd-api 1.11.0-next.0 → 2.1.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -36
- package/fetchers/index.js +2 -2
- package/helpers/creator.helper.js +2 -1
- package/helpers/global.helper.d.ts +2 -0
- package/helpers/global.helper.js +21 -1
- package/helpers/movie.helper.d.ts +2 -3
- package/helpers/movie.helper.js +35 -22
- package/helpers/search-user.helper.js +3 -1
- package/helpers/search.helper.d.ts +1 -1
- package/helpers/search.helper.js +6 -5
- package/interfaces/global.d.ts +2 -2
- package/interfaces/movie.interface.d.ts +1 -1
- package/package.json +5 -5
- package/services/movie.service.js +6 -5
- package/test.d.ts +0 -0
- package/test.js +0 -1
package/README.md
CHANGED
|
@@ -5,33 +5,33 @@
|
|
|
5
5
|
|
|
6
6
|
# CSFD API 2021
|
|
7
7
|
|
|
8
|
-
>
|
|
8
|
+
> JavaScript NPM library for scraping **Czech Movie Database (csfd.cz)**
|
|
9
9
|
>
|
|
10
10
|
> - Browser + Node.js (SSR)
|
|
11
|
-
> - TypeScript
|
|
12
|
-
> -
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
>
|
|
17
|
-
>
|
|
18
|
-
>
|
|
11
|
+
> - JavaScript / TypeScript
|
|
12
|
+
> - Tested (~100% Code coverage)
|
|
13
|
+
> - ✅ Ready for new ČSFD 2021!
|
|
14
|
+
> - You can use in:
|
|
15
|
+
> - Firebase function
|
|
16
|
+
> - AWS λ (lambda function)
|
|
17
|
+
> - Chrome extension
|
|
18
|
+
> - React native app
|
|
19
|
+
> - ...
|
|
19
20
|
|
|
20
21
|
## Install
|
|
21
22
|
|
|
22
|
-
via yarn
|
|
23
|
-
|
|
24
23
|
```bash
|
|
25
|
-
|
|
24
|
+
npm install node-csfd-api --save
|
|
25
|
+
# yarn add node-csfd-api
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
## Usage and examples
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
- [Movies and TV Series](#Movie)
|
|
31
|
+
- [User Ratings](#User-Ratings)
|
|
32
|
+
- [Search](#Search)
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
### Movie
|
|
35
35
|
|
|
36
36
|
Get info about [this movie](https://www.csfd.cz/film/535121-na-spatne-strane/komentare/) _(id: 535121)_
|
|
37
37
|
|
|
@@ -41,7 +41,7 @@ import { csfd } from 'node-csfd-api';
|
|
|
41
41
|
csfd.movie(535121).then((movie) => console.log(movie));
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
#### Results
|
|
45
45
|
|
|
46
46
|
```javascript
|
|
47
47
|
{
|
|
@@ -66,7 +66,7 @@ csfd.movie(535121).then((movie) => console.log(movie));
|
|
|
66
66
|
{ country: 'Austrálie', title: 'Dragged Across Concrete' },
|
|
67
67
|
{ country: 'Velká Británie', title: 'Dragged Across Concrete' }
|
|
68
68
|
],
|
|
69
|
-
poster: '
|
|
69
|
+
poster: 'https://image.pmgstatic.com/cache/resized/w1080/files/images/film/posters/163/579/163579352_bf8737.jpg',
|
|
70
70
|
creators: {
|
|
71
71
|
directors: [
|
|
72
72
|
{
|
|
@@ -133,7 +133,7 @@ csfd.movie(535121).then((movie) => console.log(movie));
|
|
|
133
133
|
}
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
### Search
|
|
137
137
|
|
|
138
138
|
> Search movies and users
|
|
139
139
|
|
|
@@ -143,7 +143,7 @@ import { csfd } from 'node-csfd-api';
|
|
|
143
143
|
csfd.search('bart').then((search) => console.log(search));
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
#### Results
|
|
147
147
|
|
|
148
148
|
```javascript
|
|
149
149
|
movies: [
|
|
@@ -175,13 +175,13 @@ users: [
|
|
|
175
175
|
id: 912,
|
|
176
176
|
user: 'BART!',
|
|
177
177
|
userRealName: 'Lukáš Barták',
|
|
178
|
-
avatar: '
|
|
178
|
+
avatar: 'https://image.pmgstatic.com/cache/resized/w45h60/files/images/user/avatars/000/281/281554_1c0fef.jpg',
|
|
179
179
|
url: 'https://www.csfd.cz/uzivatel/912-bart/'
|
|
180
180
|
}
|
|
181
181
|
]
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
-
|
|
184
|
+
### Creators
|
|
185
185
|
|
|
186
186
|
> Search creators and filmography
|
|
187
187
|
|
|
@@ -191,7 +191,7 @@ import { csfd } from 'node-csfd-api';
|
|
|
191
191
|
csfd.creator(2120).then((creator) => console.log(creator));
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
#### Results
|
|
195
195
|
|
|
196
196
|
```javascript
|
|
197
197
|
{
|
|
@@ -199,7 +199,7 @@ csfd.creator(2120).then((creator) => console.log(creator));
|
|
|
199
199
|
name: 'Quentin Tarantino',
|
|
200
200
|
birthday: '27.03.1963',
|
|
201
201
|
birthplace: 'Knoxville, Tennessee, USA',
|
|
202
|
-
photo: '
|
|
202
|
+
photo: 'https://image.pmgstatic.com/cache/resized/w100h132crop/files/images/creator/photos/164/515/164515525_b98f8a.jpg',
|
|
203
203
|
age: 58,
|
|
204
204
|
bio: 'Quentin Tarantino se narodil 27. března roku 1963 v americkém Knoxville teprve šestnáctileté Connie Tarantinové. Své jméno Quentin dostal podle matčiny oblíbené televizní postavy Quinta ze seriálu "Gunsmoke". Quentinův otec byl jistý Tony Tarantino, který rodinu opustil když byl Quentin ještě malinký. Jeho dětství a dospívání ovlivnily nejen filmy, ale pop kultura obecně. Televizní seriály, komiksy, populární hudba, to vše jako mladý hltal ve velkém a stále neměl…',
|
|
205
205
|
films: [
|
|
@@ -268,9 +268,9 @@ csfd.creator(2120).then((creator) => console.log(creator));
|
|
|
268
268
|
}
|
|
269
269
|
```
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
### User Ratings
|
|
272
272
|
|
|
273
|
-
|
|
273
|
+
#### Last ratings (last page)
|
|
274
274
|
|
|
275
275
|
Get [my last 50 ratings](https://www.csfd.cz/uzivatel/912-bart/hodnoceni/)
|
|
276
276
|
|
|
@@ -280,7 +280,7 @@ import { csfd } from 'node-csfd-api';
|
|
|
280
280
|
csfd.userRatings('912-bart').then((ratings) => console.log(ratings));
|
|
281
281
|
```
|
|
282
282
|
|
|
283
|
-
|
|
283
|
+
#### All ratings (all pages)
|
|
284
284
|
|
|
285
285
|
> Warning: Use it wisely. Can be detected and banned. Consider using it together with `allPagesDelay` attribute.
|
|
286
286
|
|
|
@@ -297,7 +297,7 @@ csfd
|
|
|
297
297
|
.then((ratings) => console.log(ratings));
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
-
|
|
300
|
+
#### Results
|
|
301
301
|
|
|
302
302
|
```javascript
|
|
303
303
|
[
|
|
@@ -322,14 +322,14 @@ csfd
|
|
|
322
322
|
];
|
|
323
323
|
```
|
|
324
324
|
|
|
325
|
-
|
|
325
|
+
#### Options
|
|
326
326
|
|
|
327
|
-
| Option | Type | Default | Description
|
|
328
|
-
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
|
|
329
|
-
| **includesOnly** | [CSFDFilmTypes[]](https://github.com/bartholomej/node-csfd-api/blob/8fa5f9cbc7e7f2b62b0bd2c2b5a24c9a63444f6a/src/interfaces/global.ts#L25) | null | Including only film types. eg. `['
|
|
330
|
-
| **exclude** | [CSFDFilmTypes[]](https://github.com/bartholomej/node-csfd-api/blob/8fa5f9cbc7e7f2b62b0bd2c2b5a24c9a63444f6a/src/interfaces/global.ts#L25) | null | Excluding film types eg. `['epizoda', 'série']`
|
|
331
|
-
| **allPages** | boolean | false | Get all pages
|
|
332
|
-
| **allPagesDelay** | number | 0 | Delay on each page request. In milliseconds
|
|
327
|
+
| Option | Type | Default | Description |
|
|
328
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------ |
|
|
329
|
+
| **includesOnly** | [CSFDFilmTypes[]](https://github.com/bartholomej/node-csfd-api/blob/8fa5f9cbc7e7f2b62b0bd2c2b5a24c9a63444f6a/src/interfaces/global.ts#L25) | null | Including only film types. eg. `['seriál', 'koncert']` |
|
|
330
|
+
| **exclude** | [CSFDFilmTypes[]](https://github.com/bartholomej/node-csfd-api/blob/8fa5f9cbc7e7f2b62b0bd2c2b5a24c9a63444f6a/src/interfaces/global.ts#L25) | null | Excluding film types eg. `['epizoda', 'série']` |
|
|
331
|
+
| **allPages** | boolean | false | Get all pages |
|
|
332
|
+
| **allPagesDelay** | number | 0 | Delay on each page request. In milliseconds |
|
|
333
333
|
|
|
334
334
|
_Note: You can not use both parameters 'includesOnly' and 'excludes'. Parameter 'includesOnly' has a priority._
|
|
335
335
|
|
package/fetchers/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.fetchPage = void 0;
|
|
7
|
-
const
|
|
7
|
+
const cross_fetch_1 = __importDefault(require("cross-fetch"));
|
|
8
8
|
const USER_AGENTS = [
|
|
9
9
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
|
|
10
10
|
'Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1',
|
|
@@ -16,7 +16,7 @@ const headers = {
|
|
|
16
16
|
};
|
|
17
17
|
const fetchPage = async (url) => {
|
|
18
18
|
try {
|
|
19
|
-
const response = await (0,
|
|
19
|
+
const response = await (0, cross_fetch_1.default)(url, { headers });
|
|
20
20
|
if (response.status >= 400 && response.status < 600) {
|
|
21
21
|
throw new Error(`node-csfd-api: Bad response ${response.status} for url: ${url}`);
|
|
22
22
|
}
|
|
@@ -39,7 +39,8 @@ const getBio = (el) => {
|
|
|
39
39
|
};
|
|
40
40
|
exports.getBio = getBio;
|
|
41
41
|
const getPhoto = (el) => {
|
|
42
|
-
|
|
42
|
+
const image = el.querySelector('img').attributes.src;
|
|
43
|
+
return (0, global_helper_1.addProtocol)(image);
|
|
43
44
|
};
|
|
44
45
|
exports.getPhoto = getPhoto;
|
|
45
46
|
const parseBirthday = (text) => {
|
|
@@ -3,3 +3,5 @@ import { Colors } from '../interfaces/user-ratings.interface';
|
|
|
3
3
|
export declare const parseIdFromUrl: (url: string) => number;
|
|
4
4
|
export declare const getColor: (cls: string) => CSFDColorRating;
|
|
5
5
|
export declare const parseColor: (quality: Colors) => CSFDColorRating;
|
|
6
|
+
export declare const addProtocol: (url: string) => string;
|
|
7
|
+
export declare const parseISO8601Duration: (iso: string) => number;
|
package/helpers/global.helper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseColor = exports.getColor = exports.parseIdFromUrl = void 0;
|
|
3
|
+
exports.parseISO8601Duration = exports.addProtocol = exports.parseColor = exports.getColor = exports.parseIdFromUrl = void 0;
|
|
4
4
|
const parseIdFromUrl = (url) => {
|
|
5
5
|
const idSlug = url.split('/')[2];
|
|
6
6
|
const id = idSlug.split('-')[0];
|
|
@@ -37,3 +37,23 @@ const parseColor = (quality) => {
|
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
exports.parseColor = parseColor;
|
|
40
|
+
const addProtocol = (url) => {
|
|
41
|
+
return url.startsWith('//') ? 'https:' + url : url;
|
|
42
|
+
};
|
|
43
|
+
exports.addProtocol = addProtocol;
|
|
44
|
+
const parseISO8601Duration = (iso) => {
|
|
45
|
+
const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
|
|
46
|
+
const matches = iso.match(iso8601DurationRegex);
|
|
47
|
+
const duration = {
|
|
48
|
+
sign: matches[1] === undefined ? '+' : '-',
|
|
49
|
+
years: matches[2] === undefined ? 0 : matches[2],
|
|
50
|
+
months: matches[3] === undefined ? 0 : matches[3],
|
|
51
|
+
weeks: matches[4] === undefined ? 0 : matches[4],
|
|
52
|
+
days: matches[5] === undefined ? 0 : matches[5],
|
|
53
|
+
hours: matches[6] === undefined ? 0 : matches[6],
|
|
54
|
+
minutes: matches[7] === undefined ? 0 : matches[7],
|
|
55
|
+
seconds: matches[8] === undefined ? 0 : matches[8]
|
|
56
|
+
};
|
|
57
|
+
return +duration.minutes;
|
|
58
|
+
};
|
|
59
|
+
exports.parseISO8601Duration = parseISO8601Duration;
|
|
@@ -8,12 +8,11 @@ export declare const getOrigins: (el: HTMLElement) => string[];
|
|
|
8
8
|
export declare const getColorRating: (bodyClasses: string[]) => CSFDColorRating;
|
|
9
9
|
export declare const getRating: (el: HTMLElement) => number;
|
|
10
10
|
export declare const getRatingCount: (el: HTMLElement) => number;
|
|
11
|
-
export declare const getYear: (el:
|
|
12
|
-
export declare const getDuration: (el: HTMLElement) => number;
|
|
11
|
+
export declare const getYear: (el: string) => number;
|
|
12
|
+
export declare const getDuration: (jsonLdRaw: string, el: HTMLElement) => number;
|
|
13
13
|
export declare const getTitlesOther: (el: HTMLElement) => CSFDTitlesOther[];
|
|
14
14
|
export declare const getPoster: (el: HTMLElement) => string;
|
|
15
15
|
export declare const getDescriptions: (el: HTMLElement) => string[];
|
|
16
|
-
export declare const getDirectors: (el: HTMLElement) => CSFDCreator[];
|
|
17
16
|
export declare const parsePeople: (el: HTMLElement) => CSFDCreator[];
|
|
18
17
|
export declare const getGroup: (el: HTMLElement, group: CSFDCreatorGroups) => CSFDCreator[];
|
|
19
18
|
export declare const getType: (el: HTMLElement) => string;
|
package/helpers/movie.helper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getTags = exports.getPremieres = exports.getBoxMovies = exports.getBoxContent = exports.getVods = exports.getType = exports.getGroup = exports.parsePeople = exports.
|
|
3
|
+
exports.getTags = exports.getPremieres = exports.getBoxMovies = exports.getBoxContent = exports.getVods = exports.getType = exports.getGroup = exports.parsePeople = exports.getDescriptions = exports.getPoster = exports.getTitlesOther = exports.getDuration = exports.getYear = exports.getRatingCount = exports.getRating = exports.getColorRating = exports.getOrigins = exports.getGenres = exports.getTitle = exports.getId = void 0;
|
|
4
4
|
const global_helper_1 = require("./global.helper");
|
|
5
5
|
const getId = (el) => {
|
|
6
6
|
const url = el.querySelector('.tabs .tab-nav-list a').attributes.href;
|
|
@@ -50,23 +50,41 @@ const getRatingCount = (el) => {
|
|
|
50
50
|
};
|
|
51
51
|
exports.getRatingCount = getRatingCount;
|
|
52
52
|
const getYear = (el) => {
|
|
53
|
-
|
|
53
|
+
try {
|
|
54
|
+
const jsonLd = JSON.parse(el);
|
|
55
|
+
return +jsonLd.dateCreated;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('node-csfd-api: Error parsing JSON-LD', error);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
54
61
|
};
|
|
55
62
|
exports.getYear = getYear;
|
|
56
|
-
const getDuration = (el) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const hoursMinsRaw = timeRaw.split('min')[0];
|
|
63
|
-
const hoursMins = hoursMinsRaw.split('h');
|
|
64
|
-
// Resolve hours + minutes format
|
|
65
|
-
const duration = hoursMins.length > 1 ? +hoursMins[0] * 60 + +hoursMins[1] : +hoursMins[0];
|
|
66
|
-
return duration;
|
|
63
|
+
const getDuration = (jsonLdRaw, el) => {
|
|
64
|
+
let duration = null;
|
|
65
|
+
try {
|
|
66
|
+
const jsonLd = JSON.parse(jsonLdRaw);
|
|
67
|
+
duration = jsonLd.duration;
|
|
68
|
+
return (0, global_helper_1.parseISO8601Duration)(duration);
|
|
67
69
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
catch (error) {
|
|
71
|
+
const origin = el.querySelector('.origin').innerText;
|
|
72
|
+
const timeString = origin.split(',');
|
|
73
|
+
if (timeString.length > 2) {
|
|
74
|
+
// Get last time elelment
|
|
75
|
+
const timeString2 = timeString.pop().trim();
|
|
76
|
+
// Clean it
|
|
77
|
+
const timeRaw = timeString2.split('(')[0].trim();
|
|
78
|
+
// Split by minutes and hours
|
|
79
|
+
const hoursMinsRaw = timeRaw.split('min')[0];
|
|
80
|
+
const hoursMins = hoursMinsRaw.split('h');
|
|
81
|
+
// Resolve hours + minutes format
|
|
82
|
+
duration = hoursMins.length > 1 ? +hoursMins[0] * 60 + +hoursMins[1] : +hoursMins[0];
|
|
83
|
+
return duration;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
70
88
|
}
|
|
71
89
|
};
|
|
72
90
|
exports.getDuration = getDuration;
|
|
@@ -98,7 +116,8 @@ const getPoster = (el) => {
|
|
|
98
116
|
else {
|
|
99
117
|
// Full sized image (not thumb)
|
|
100
118
|
const imageThumb = poster.attributes.src.split('?')[0];
|
|
101
|
-
|
|
119
|
+
const image = imageThumb.replace(/\/w140\//, '/w1080/');
|
|
120
|
+
return (0, global_helper_1.addProtocol)(image);
|
|
102
121
|
}
|
|
103
122
|
}
|
|
104
123
|
else {
|
|
@@ -114,12 +133,6 @@ const getDescriptions = (el) => {
|
|
|
114
133
|
return plot ? [plot] : [];
|
|
115
134
|
};
|
|
116
135
|
exports.getDescriptions = getDescriptions;
|
|
117
|
-
const getDirectors = (el) => {
|
|
118
|
-
const creators = el.querySelectorAll('.creators span');
|
|
119
|
-
const directorsSpan = creators.filter((creator) => creator.attributes.itemprop === 'director')[0];
|
|
120
|
-
return (directorsSpan && (0, exports.parsePeople)(directorsSpan)) || [];
|
|
121
|
-
};
|
|
122
|
-
exports.getDirectors = getDirectors;
|
|
123
136
|
const parsePeople = (el) => {
|
|
124
137
|
const people = el.querySelectorAll('a');
|
|
125
138
|
return (people
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getUserUrl = exports.getAvatar = exports.getUserRealName = exports.getUser = void 0;
|
|
4
|
+
const global_helper_1 = require("./global.helper");
|
|
4
5
|
const getUser = (el) => {
|
|
5
6
|
return el.querySelector('.user-title-name').text;
|
|
6
7
|
};
|
|
@@ -11,7 +12,8 @@ const getUserRealName = (el) => {
|
|
|
11
12
|
};
|
|
12
13
|
exports.getUserRealName = getUserRealName;
|
|
13
14
|
const getAvatar = (el) => {
|
|
14
|
-
|
|
15
|
+
const image = el.querySelector('.article-img img').attributes.src;
|
|
16
|
+
return (0, global_helper_1.addProtocol)(image);
|
|
15
17
|
};
|
|
16
18
|
exports.getAvatar = getAvatar;
|
|
17
19
|
const getUserUrl = (el) => {
|
|
@@ -3,7 +3,7 @@ import { CSFDColorRating, CSFDFilmTypes } from '../interfaces/global';
|
|
|
3
3
|
import { CSFDCreator } from '../interfaces/movie.interface';
|
|
4
4
|
export declare const getType: (el: HTMLElement) => CSFDFilmTypes;
|
|
5
5
|
export declare const getTitle: (el: HTMLElement) => string;
|
|
6
|
-
export declare const getYear: (el: HTMLElement) =>
|
|
6
|
+
export declare const getYear: (el: HTMLElement) => number;
|
|
7
7
|
export declare const getUrl: (el: HTMLElement) => string;
|
|
8
8
|
export declare const getColorRating: (el: HTMLElement) => CSFDColorRating;
|
|
9
9
|
export declare const getPoster: (el: HTMLElement) => string;
|
package/helpers/search.helper.js
CHANGED
|
@@ -13,7 +13,7 @@ const getTitle = (el) => {
|
|
|
13
13
|
exports.getTitle = getTitle;
|
|
14
14
|
const getYear = (el) => {
|
|
15
15
|
var _a;
|
|
16
|
-
return (_a = el.querySelectorAll('.film-title-info .info')[0]) === null || _a === void 0 ? void 0 : _a.innerText.replace(/[{()}]/g, '');
|
|
16
|
+
return +((_a = el.querySelectorAll('.film-title-info .info')[0]) === null || _a === void 0 ? void 0 : _a.innerText.replace(/[{()}]/g, ''));
|
|
17
17
|
};
|
|
18
18
|
exports.getYear = getYear;
|
|
19
19
|
const getUrl = (el) => {
|
|
@@ -25,14 +25,15 @@ const getColorRating = (el) => {
|
|
|
25
25
|
};
|
|
26
26
|
exports.getColorRating = getColorRating;
|
|
27
27
|
const getPoster = (el) => {
|
|
28
|
-
|
|
28
|
+
const image = el.querySelector('img').attributes.src;
|
|
29
|
+
return (0, global_helper_1.addProtocol)(image);
|
|
29
30
|
};
|
|
30
31
|
exports.getPoster = getPoster;
|
|
31
32
|
const getOrigins = (el) => {
|
|
33
|
+
var _a;
|
|
32
34
|
const originsRaw = el.querySelector('.article-content p .info').text;
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
return origins;
|
|
35
|
+
const originsAll = (_a = originsRaw === null || originsRaw === void 0 ? void 0 : originsRaw.split(', ')) === null || _a === void 0 ? void 0 : _a[0];
|
|
36
|
+
return originsAll === null || originsAll === void 0 ? void 0 : originsAll.split('/').map((country) => country.trim());
|
|
36
37
|
};
|
|
37
38
|
exports.getOrigins = getOrigins;
|
|
38
39
|
const parsePeople = (el, type) => {
|
package/interfaces/global.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface CSFDScreening {
|
|
2
2
|
id: number;
|
|
3
3
|
title: string;
|
|
4
|
-
year: number
|
|
4
|
+
year: number;
|
|
5
5
|
url: string;
|
|
6
6
|
type: CSFDFilmTypes;
|
|
7
7
|
/**
|
|
@@ -19,4 +19,4 @@ export interface CSFDScreening {
|
|
|
19
19
|
}
|
|
20
20
|
export declare type CSFDColorRating = 'bad' | 'average' | 'good' | 'unknown';
|
|
21
21
|
export declare type CSFDStars = 0 | 1 | 2 | 3 | 4 | 5;
|
|
22
|
-
export declare type CSFDFilmTypes = 'film' | 'TV film' | '
|
|
22
|
+
export declare type CSFDFilmTypes = 'film' | 'TV film' | 'pořad' | 'seriál' | 'divadelní záznam' | 'koncert' | 'série' | 'studentský film' | 'amatérský film' | 'hudební videoklip' | 'epizoda';
|
|
@@ -16,7 +16,7 @@ export interface CSFDMovie extends CSFDScreening {
|
|
|
16
16
|
similar: CSFDMovieListItem[];
|
|
17
17
|
}
|
|
18
18
|
export interface CSFDVod {
|
|
19
|
-
title: 'Netflix' | 'hbogo' | 'Prime Video' | 'Apple TV+' | '
|
|
19
|
+
title: 'Netflix' | 'hbogo' | 'Prime Video' | 'Apple TV+' | 'iTunes' | 'Aerovod' | 'Edisonline' | 'o2tv' | 'SledovaniTV' | 'Starmax' | 'DAFilms' | 'FILMY ČESKY A ZADARMO' | 'Youtube Česká filmová klasika' | 'VAPET' | 'VOREL FILM' | 'ivysilani' | 'Google Play' | 'Voyo' | string;
|
|
20
20
|
url: string;
|
|
21
21
|
}
|
|
22
22
|
export interface CSFDCreators {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-csfd-api",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.1.0-next.1",
|
|
4
|
+
"description": "ČSFD API in JavaScript. Amazing NPM library for scrapping csfd.cz :)",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"author": "BART! <bart@bartweb.cz>",
|
|
7
7
|
"scripts": {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"release:major": "git checkout master && npm version major -m \"chore(update): major release %s 💥\""
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"node-html-parser": "^5.
|
|
24
|
+
"cross-fetch": "^3.1.5",
|
|
25
|
+
"node-html-parser": "^5.2.0"
|
|
26
26
|
},
|
|
27
27
|
"repository": {
|
|
28
28
|
"url": "git+https://github.com/bartholomej/node-csfd-api.git",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"api"
|
|
47
47
|
],
|
|
48
48
|
"engines": {
|
|
49
|
-
"node": ">=
|
|
49
|
+
"node": ">= 12"
|
|
50
50
|
},
|
|
51
51
|
"license": "MIT",
|
|
52
52
|
"module": "./index.js",
|
|
@@ -13,15 +13,16 @@ class MovieScraper {
|
|
|
13
13
|
const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');
|
|
14
14
|
const asideNode = movieHtml.querySelector('.aside-movie-profile');
|
|
15
15
|
const movieNode = movieHtml.querySelector('.main-movie-profile');
|
|
16
|
-
|
|
16
|
+
const jsonLd = movieHtml.querySelector('script[type="application/ld+json"]').innerText;
|
|
17
|
+
this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd);
|
|
17
18
|
return this.film;
|
|
18
19
|
}
|
|
19
|
-
buildMovie(movieId, el, asideEl, pageClasses) {
|
|
20
|
+
buildMovie(movieId, el, asideEl, pageClasses, jsonLd) {
|
|
20
21
|
this.film = {
|
|
21
22
|
id: movieId,
|
|
22
23
|
title: (0, movie_helper_1.getTitle)(el),
|
|
23
|
-
year: (0, movie_helper_1.getYear)(
|
|
24
|
-
duration: (0, movie_helper_1.getDuration)(el),
|
|
24
|
+
year: (0, movie_helper_1.getYear)(jsonLd),
|
|
25
|
+
duration: (0, movie_helper_1.getDuration)(jsonLd, el),
|
|
25
26
|
descriptions: (0, movie_helper_1.getDescriptions)(el),
|
|
26
27
|
genres: (0, movie_helper_1.getGenres)(el),
|
|
27
28
|
type: (0, movie_helper_1.getType)(el),
|
|
@@ -33,7 +34,7 @@ class MovieScraper {
|
|
|
33
34
|
titlesOther: (0, movie_helper_1.getTitlesOther)(el),
|
|
34
35
|
poster: (0, movie_helper_1.getPoster)(el),
|
|
35
36
|
creators: {
|
|
36
|
-
directors: (0, movie_helper_1.
|
|
37
|
+
directors: (0, movie_helper_1.getGroup)(el, 'Režie'),
|
|
37
38
|
writers: (0, movie_helper_1.getGroup)(el, 'Scénář'),
|
|
38
39
|
cinematography: (0, movie_helper_1.getGroup)(el, 'Kamera'),
|
|
39
40
|
music: (0, movie_helper_1.getGroup)(el, 'Hudba'),
|
package/test.d.ts
DELETED
|
File without changes
|
package/test.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|