node-csfd-api 3.0.0-next.27 → 3.0.0-next.28
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/cjs/fetchers/{index.js → fetchers.js} +2 -2
- package/cjs/helpers/cinema.helper.js +9 -7
- package/cjs/helpers/creator.helper.js +34 -35
- package/cjs/helpers/global.helper.js +12 -1
- package/cjs/helpers/movie.helper.js +85 -9
- package/cjs/helpers/search-user.helper.js +9 -4
- package/cjs/helpers/search.helper.js +6 -5
- package/cjs/helpers/user-ratings.helper.js +2 -2
- package/cjs/index.js +10 -10
- package/cjs/services/cinema.service.js +10 -10
- package/cjs/services/creator.service.js +16 -12
- package/cjs/services/movie.service.js +48 -35
- package/cjs/services/search.service.js +32 -32
- package/cjs/services/user-ratings.service.js +17 -17
- package/esm/fetchers/{index.js → fetchers.js} +1 -1
- package/esm/helpers/cinema.helper.js +9 -7
- package/esm/helpers/creator.helper.js +34 -35
- package/esm/helpers/global.helper.js +10 -0
- package/esm/helpers/movie.helper.js +73 -2
- package/esm/helpers/search-user.helper.js +8 -3
- package/esm/helpers/search.helper.js +3 -2
- package/esm/helpers/user-ratings.helper.js +1 -1
- package/esm/index.js +5 -5
- package/esm/services/cinema.service.js +3 -3
- package/esm/services/creator.service.js +8 -4
- package/esm/services/movie.service.js +21 -8
- package/esm/services/search.service.js +5 -5
- package/esm/services/user-ratings.service.js +3 -3
- package/index.dto.d.ts +1 -1
- package/package.json +1 -1
- package/types/dto/movie.d.ts +22 -1
- package/types/helpers/cinema.helper.d.ts +2 -2
- package/types/helpers/creator.helper.d.ts +4 -4
- package/types/helpers/global.helper.d.ts +1 -0
- package/types/helpers/movie.helper.d.ts +15 -1
- package/types/index.d.ts +5 -5
- /package/types/fetchers/{index.d.ts → fetchers.d.ts} +0 -0
|
@@ -11,14 +11,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.MovieScraper = void 0;
|
|
13
13
|
const node_html_parser_1 = require("node-html-parser");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
14
|
+
const fetchers_js_1 = require("../fetchers/fetchers.js");
|
|
15
|
+
const movie_helper_js_1 = require("../helpers/movie.helper.js");
|
|
16
|
+
const vars_js_1 = require("../vars.js");
|
|
17
17
|
class MovieScraper {
|
|
18
18
|
movie(movieId) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
const
|
|
21
|
-
|
|
20
|
+
const id = Number(movieId);
|
|
21
|
+
if (isNaN(id)) {
|
|
22
|
+
throw new Error('node-csfd-api: movieId must be a valid number');
|
|
23
|
+
}
|
|
24
|
+
const url = (0, vars_js_1.movieUrl)(id);
|
|
25
|
+
const response = yield (0, fetchers_js_1.fetchPage)(url);
|
|
22
26
|
const movieHtml = (0, node_html_parser_1.parse)(response);
|
|
23
27
|
const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');
|
|
24
28
|
const asideNode = movieHtml.querySelector('.aside-movie-profile');
|
|
@@ -29,40 +33,49 @@ class MovieScraper {
|
|
|
29
33
|
});
|
|
30
34
|
}
|
|
31
35
|
buildMovie(movieId, el, asideEl, pageClasses, jsonLd) {
|
|
36
|
+
const type = (0, movie_helper_js_1.getMovieType)(el);
|
|
37
|
+
const { seriesName = null, seasonName = null } = type === 'série' ? (0, movie_helper_js_1.getSerieasAndSeasonTitle)(el) : {};
|
|
38
|
+
const seasonOrEpisodeListType = (0, movie_helper_js_1.detectSeasonOrEpisodeListType)(el);
|
|
39
|
+
const title = type === 'série' && seriesName ? seriesName : (0, movie_helper_js_1.getMovieTitle)(el);
|
|
32
40
|
this.film = {
|
|
33
41
|
id: movieId,
|
|
34
|
-
title
|
|
35
|
-
year: (0,
|
|
36
|
-
duration: (0,
|
|
37
|
-
descriptions: (0,
|
|
38
|
-
genres: (0,
|
|
39
|
-
type
|
|
40
|
-
url: (0,
|
|
41
|
-
origins: (0,
|
|
42
|
-
colorRating: (0,
|
|
43
|
-
rating: (0,
|
|
44
|
-
ratingCount: (0,
|
|
45
|
-
titlesOther: (0,
|
|
46
|
-
poster: (0,
|
|
47
|
-
photo: (0,
|
|
48
|
-
trivia: (0,
|
|
42
|
+
title,
|
|
43
|
+
year: (0, movie_helper_js_1.getMovieYear)(jsonLd),
|
|
44
|
+
duration: (0, movie_helper_js_1.getMovieDuration)(jsonLd, el),
|
|
45
|
+
descriptions: (0, movie_helper_js_1.getMovieDescriptions)(el),
|
|
46
|
+
genres: (0, movie_helper_js_1.getMovieGenres)(el),
|
|
47
|
+
type,
|
|
48
|
+
url: (0, vars_js_1.movieUrl)(movieId),
|
|
49
|
+
origins: (0, movie_helper_js_1.getMovieOrigins)(el),
|
|
50
|
+
colorRating: (0, movie_helper_js_1.getMovieColorRating)(pageClasses),
|
|
51
|
+
rating: (0, movie_helper_js_1.getMovieRating)(asideEl),
|
|
52
|
+
ratingCount: (0, movie_helper_js_1.getMovieRatingCount)(asideEl),
|
|
53
|
+
titlesOther: (0, movie_helper_js_1.getMovieTitlesOther)(el),
|
|
54
|
+
poster: (0, movie_helper_js_1.getMoviePoster)(el),
|
|
55
|
+
photo: (0, movie_helper_js_1.getMovieRandomPhoto)(el),
|
|
56
|
+
trivia: (0, movie_helper_js_1.getMovieTrivia)(el),
|
|
49
57
|
creators: {
|
|
50
|
-
directors: (0,
|
|
51
|
-
writers: (0,
|
|
52
|
-
cinematography: (0,
|
|
53
|
-
music: (0,
|
|
54
|
-
actors: (0,
|
|
55
|
-
basedOn: (0,
|
|
56
|
-
producers: (0,
|
|
57
|
-
filmEditing: (0,
|
|
58
|
-
costumeDesign: (0,
|
|
59
|
-
productionDesign: (0,
|
|
58
|
+
directors: (0, movie_helper_js_1.getMovieGroup)(el, 'Režie'),
|
|
59
|
+
writers: (0, movie_helper_js_1.getMovieGroup)(el, 'Scénář'),
|
|
60
|
+
cinematography: (0, movie_helper_js_1.getMovieGroup)(el, 'Kamera'),
|
|
61
|
+
music: (0, movie_helper_js_1.getMovieGroup)(el, 'Hudba'),
|
|
62
|
+
actors: (0, movie_helper_js_1.getMovieGroup)(el, 'Hrají'),
|
|
63
|
+
basedOn: (0, movie_helper_js_1.getMovieGroup)(el, 'Předloha'),
|
|
64
|
+
producers: (0, movie_helper_js_1.getMovieGroup)(el, 'Produkce'),
|
|
65
|
+
filmEditing: (0, movie_helper_js_1.getMovieGroup)(el, 'Střih'),
|
|
66
|
+
costumeDesign: (0, movie_helper_js_1.getMovieGroup)(el, 'Kostýmy'),
|
|
67
|
+
productionDesign: (0, movie_helper_js_1.getMovieGroup)(el, 'Scénografie'),
|
|
60
68
|
},
|
|
61
|
-
vod: (0,
|
|
62
|
-
tags: (0,
|
|
63
|
-
premieres: (0,
|
|
64
|
-
related: (0,
|
|
65
|
-
similar: (0,
|
|
69
|
+
vod: (0, movie_helper_js_1.getMovieVods)(asideEl),
|
|
70
|
+
tags: (0, movie_helper_js_1.getMovieTags)(asideEl),
|
|
71
|
+
premieres: (0, movie_helper_js_1.getMoviePremieres)(asideEl),
|
|
72
|
+
related: (0, movie_helper_js_1.getMovieBoxMovies)(asideEl, 'Související'),
|
|
73
|
+
similar: (0, movie_helper_js_1.getMovieBoxMovies)(asideEl, 'Podobné'),
|
|
74
|
+
seasons: seasonOrEpisodeListType === 'seasons' ? (0, movie_helper_js_1.getSeasonsOrEpisodes)(el) : null,
|
|
75
|
+
episodes: seasonOrEpisodeListType === 'episodes' ? (0, movie_helper_js_1.getSeasonsOrEpisodes)(el) : null,
|
|
76
|
+
parent: (type === 'seriál') ? null : (0, movie_helper_js_1.getSeasonorEpisodeParent)(el, { id: movieId, name: title }),
|
|
77
|
+
episodeCode: type === 'epizoda' ? (0, movie_helper_js_1.getEpisodeCode)(el) : null,
|
|
78
|
+
seasonName,
|
|
66
79
|
};
|
|
67
80
|
}
|
|
68
81
|
}
|
|
@@ -11,16 +11,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.SearchScraper = void 0;
|
|
13
13
|
const node_html_parser_1 = require("node-html-parser");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
14
|
+
const fetchers_js_1 = require("../fetchers/fetchers.js");
|
|
15
|
+
const global_helper_js_1 = require("../helpers/global.helper.js");
|
|
16
|
+
const search_user_helper_js_1 = require("../helpers/search-user.helper.js");
|
|
17
|
+
const search_helper_js_1 = require("../helpers/search.helper.js");
|
|
18
|
+
const vars_js_1 = require("../vars.js");
|
|
19
19
|
class SearchScraper {
|
|
20
20
|
search(text) {
|
|
21
21
|
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
-
const url = (0,
|
|
23
|
-
const response = yield (0,
|
|
22
|
+
const url = (0, vars_js_1.searchUrl)(text);
|
|
23
|
+
const response = yield (0, fetchers_js_1.fetchPage)(url);
|
|
24
24
|
const html = (0, node_html_parser_1.parse)(response);
|
|
25
25
|
const moviesNode = html.querySelectorAll('.main-movies article');
|
|
26
26
|
const usersNode = html.querySelectorAll('.main-users article');
|
|
@@ -33,48 +33,48 @@ class SearchScraper {
|
|
|
33
33
|
const users = [];
|
|
34
34
|
const tvSeries = [];
|
|
35
35
|
moviesNode.forEach((m) => {
|
|
36
|
-
const url = (0,
|
|
36
|
+
const url = (0, search_helper_js_1.getSearchUrl)(m);
|
|
37
37
|
const movie = {
|
|
38
|
-
id: (0,
|
|
39
|
-
title: (0,
|
|
40
|
-
year: (0,
|
|
38
|
+
id: (0, global_helper_js_1.parseIdFromUrl)(url),
|
|
39
|
+
title: (0, search_helper_js_1.getSearchTitle)(m),
|
|
40
|
+
year: (0, search_helper_js_1.getSearchYear)(m),
|
|
41
41
|
url: `https://www.csfd.cz${url}`,
|
|
42
|
-
type: (0,
|
|
43
|
-
colorRating: (0,
|
|
44
|
-
poster: (0,
|
|
45
|
-
origins: (0,
|
|
42
|
+
type: (0, search_helper_js_1.getSearchType)(m),
|
|
43
|
+
colorRating: (0, search_helper_js_1.getSearchColorRating)(m),
|
|
44
|
+
poster: (0, search_helper_js_1.getSearchPoster)(m),
|
|
45
|
+
origins: (0, search_helper_js_1.getSearchOrigins)(m),
|
|
46
46
|
creators: {
|
|
47
|
-
directors: (0,
|
|
48
|
-
actors: (0,
|
|
47
|
+
directors: (0, search_helper_js_1.parseSearchPeople)(m, 'directors'),
|
|
48
|
+
actors: (0, search_helper_js_1.parseSearchPeople)(m, 'actors')
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
movies.push(movie);
|
|
52
52
|
});
|
|
53
53
|
usersNode.forEach((m) => {
|
|
54
|
-
const url = (0,
|
|
54
|
+
const url = (0, search_user_helper_js_1.getUserUrl)(m);
|
|
55
55
|
const user = {
|
|
56
|
-
id: (0,
|
|
57
|
-
user: (0,
|
|
58
|
-
userRealName: (0,
|
|
59
|
-
avatar: (0,
|
|
56
|
+
id: (0, global_helper_js_1.parseIdFromUrl)(url),
|
|
57
|
+
user: (0, search_user_helper_js_1.getUser)(m),
|
|
58
|
+
userRealName: (0, search_user_helper_js_1.getUserRealName)(m),
|
|
59
|
+
avatar: (0, search_user_helper_js_1.getAvatar)(m),
|
|
60
60
|
url: `https://www.csfd.cz${url}`
|
|
61
61
|
};
|
|
62
62
|
users.push(user);
|
|
63
63
|
});
|
|
64
64
|
tvSeriesNode.forEach((m) => {
|
|
65
|
-
const url = (0,
|
|
65
|
+
const url = (0, search_helper_js_1.getSearchUrl)(m);
|
|
66
66
|
const user = {
|
|
67
|
-
id: (0,
|
|
68
|
-
title: (0,
|
|
69
|
-
year: (0,
|
|
67
|
+
id: (0, global_helper_js_1.parseIdFromUrl)(url),
|
|
68
|
+
title: (0, search_helper_js_1.getSearchTitle)(m),
|
|
69
|
+
year: (0, search_helper_js_1.getSearchYear)(m),
|
|
70
70
|
url: `https://www.csfd.cz${url}`,
|
|
71
|
-
type: (0,
|
|
72
|
-
colorRating: (0,
|
|
73
|
-
poster: (0,
|
|
74
|
-
origins: (0,
|
|
71
|
+
type: (0, search_helper_js_1.getSearchType)(m),
|
|
72
|
+
colorRating: (0, search_helper_js_1.getSearchColorRating)(m),
|
|
73
|
+
poster: (0, search_helper_js_1.getSearchPoster)(m),
|
|
74
|
+
origins: (0, search_helper_js_1.getSearchOrigins)(m),
|
|
75
75
|
creators: {
|
|
76
|
-
directors: (0,
|
|
77
|
-
actors: (0,
|
|
76
|
+
directors: (0, search_helper_js_1.parseSearchPeople)(m, 'directors'),
|
|
77
|
+
actors: (0, search_helper_js_1.parseSearchPeople)(m, 'actors')
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
80
|
tvSeries.push(user);
|
|
@@ -11,9 +11,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.UserRatingsScraper = void 0;
|
|
13
13
|
const node_html_parser_1 = require("node-html-parser");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
14
|
+
const fetchers_js_1 = require("../fetchers/fetchers.js");
|
|
15
|
+
const user_ratings_helper_js_1 = require("../helpers/user-ratings.helper.js");
|
|
16
|
+
const vars_js_1 = require("../vars.js");
|
|
17
17
|
class UserRatingsScraper {
|
|
18
18
|
constructor() {
|
|
19
19
|
this.films = [];
|
|
@@ -21,8 +21,8 @@ class UserRatingsScraper {
|
|
|
21
21
|
userRatings(user, config) {
|
|
22
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
23
23
|
let allMovies = [];
|
|
24
|
-
const url = (0,
|
|
25
|
-
const response = yield (0,
|
|
24
|
+
const url = (0, vars_js_1.userRatingsUrl)(user);
|
|
25
|
+
const response = yield (0, fetchers_js_1.fetchPage)(url);
|
|
26
26
|
const items = (0, node_html_parser_1.parse)(response);
|
|
27
27
|
const movies = items.querySelectorAll('.box-user-rating .table-container tbody tr');
|
|
28
28
|
// Get number of pages
|
|
@@ -34,14 +34,14 @@ class UserRatingsScraper {
|
|
|
34
34
|
console.log('Fetching all pages', pages);
|
|
35
35
|
for (let i = 2; i <= pages; i++) {
|
|
36
36
|
console.log('Fetching page', i, 'out of', pages, '...');
|
|
37
|
-
const url = (0,
|
|
38
|
-
const response = yield (0,
|
|
37
|
+
const url = (0, vars_js_1.userRatingsUrl)(user, i);
|
|
38
|
+
const response = yield (0, fetchers_js_1.fetchPage)(url);
|
|
39
39
|
const items = (0, node_html_parser_1.parse)(response);
|
|
40
40
|
const movies = items.querySelectorAll('.box-user-rating .table-container tbody tr');
|
|
41
41
|
allMovies = [...this.getPage(config, movies)];
|
|
42
42
|
// Sleep
|
|
43
43
|
if (config.allPagesDelay) {
|
|
44
|
-
yield (0,
|
|
44
|
+
yield (0, user_ratings_helper_js_1.sleep)(config.allPagesDelay);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
return allMovies;
|
|
@@ -59,7 +59,7 @@ class UserRatingsScraper {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
for (const el of movies) {
|
|
62
|
-
const type = (0,
|
|
62
|
+
const type = (0, user_ratings_helper_js_1.getUserRatingType)(el);
|
|
63
63
|
// Filtering includesOnly
|
|
64
64
|
if ((_c = config === null || config === void 0 ? void 0 : config.includesOnly) === null || _c === void 0 ? void 0 : _c.length) {
|
|
65
65
|
if (config.includesOnly.some((include) => type === include)) {
|
|
@@ -81,14 +81,14 @@ class UserRatingsScraper {
|
|
|
81
81
|
}
|
|
82
82
|
buildUserRatings(el) {
|
|
83
83
|
this.films.push({
|
|
84
|
-
id: (0,
|
|
85
|
-
title: (0,
|
|
86
|
-
year: (0,
|
|
87
|
-
type: (0,
|
|
88
|
-
url: (0,
|
|
89
|
-
colorRating: (0,
|
|
90
|
-
userDate: (0,
|
|
91
|
-
userRating: (0,
|
|
84
|
+
id: (0, user_ratings_helper_js_1.getUserRatingId)(el),
|
|
85
|
+
title: (0, user_ratings_helper_js_1.getUserRatingTitle)(el),
|
|
86
|
+
year: (0, user_ratings_helper_js_1.getUserRatingYear)(el),
|
|
87
|
+
type: (0, user_ratings_helper_js_1.getUserRatingType)(el),
|
|
88
|
+
url: (0, user_ratings_helper_js_1.getUserRatingUrl)(el),
|
|
89
|
+
colorRating: (0, user_ratings_helper_js_1.getUserRatingColorRating)(el),
|
|
90
|
+
userDate: (0, user_ratings_helper_js_1.getUserRatingDate)(el),
|
|
91
|
+
userRating: (0, user_ratings_helper_js_1.getUserRating)(el)
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { fetchSafe } from './fetch.polyfill';
|
|
10
|
+
import { fetchSafe } from './fetch.polyfill.js';
|
|
11
11
|
const USER_AGENTS = [
|
|
12
12
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
|
|
13
13
|
'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',
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { parseColor, parseIdFromUrl } from './global.helper';
|
|
1
|
+
import { parseColor, parseIdFromUrl } from './global.helper.js';
|
|
2
2
|
export const getCinemaColorRating = (el) => {
|
|
3
|
-
|
|
3
|
+
var _a;
|
|
4
|
+
const classes = (_a = el === null || el === void 0 ? void 0 : el.classNames.split(' ')) !== null && _a !== void 0 ? _a : [];
|
|
5
|
+
const last = classes.length ? classes[classes.length - 1] : undefined;
|
|
6
|
+
return last ? parseColor(last) : 'unknown';
|
|
4
7
|
};
|
|
5
8
|
export const getCinemaId = (el) => {
|
|
6
9
|
var _a;
|
|
@@ -8,10 +11,9 @@ export const getCinemaId = (el) => {
|
|
|
8
11
|
return +id;
|
|
9
12
|
};
|
|
10
13
|
export const getCinemaUrlId = (url) => {
|
|
11
|
-
if (url)
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
return null;
|
|
14
|
+
if (!url)
|
|
15
|
+
return null;
|
|
16
|
+
return parseIdFromUrl(url);
|
|
15
17
|
};
|
|
16
18
|
export const getCinemaCoords = (el) => {
|
|
17
19
|
if (!el)
|
|
@@ -60,7 +62,7 @@ export const getCinemaFilms = (date, el) => {
|
|
|
60
62
|
const films = filmNodes.map((filmNode) => {
|
|
61
63
|
var _a, _b, _c, _d;
|
|
62
64
|
const url = (_a = filmNode.querySelector('td.name h3 a')) === null || _a === void 0 ? void 0 : _a.attributes.href;
|
|
63
|
-
const id = getCinemaUrlId(url);
|
|
65
|
+
const id = url ? getCinemaUrlId(url) : null;
|
|
64
66
|
const title = (_b = filmNode.querySelector('.name h3')) === null || _b === void 0 ? void 0 : _b.text.trim();
|
|
65
67
|
const colorRating = getCinemaColorRating(filmNode.querySelector('.name .icon'));
|
|
66
68
|
const showTimes = (_c = filmNode.querySelectorAll('.td-time')) === null || _c === void 0 ? void 0 : _c.map((x) => x.textContent.trim());
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { addProtocol, parseColor, parseIdFromUrl } from './global.helper';
|
|
1
|
+
import { addProtocol, parseColor, parseIdFromUrl } from './global.helper.js';
|
|
2
2
|
const getCreatorColorRating = (el) => {
|
|
3
|
-
|
|
3
|
+
var _a;
|
|
4
|
+
const classes = (_a = el === null || el === void 0 ? void 0 : el.classNames.split(' ')) !== null && _a !== void 0 ? _a : [];
|
|
5
|
+
const last = classes[classes.length - 1];
|
|
6
|
+
return parseColor(last);
|
|
4
7
|
};
|
|
5
8
|
export const getCreatorId = (url) => {
|
|
6
|
-
|
|
7
|
-
return parseIdFromUrl(url);
|
|
8
|
-
}
|
|
9
|
-
return null;
|
|
9
|
+
return url ? parseIdFromUrl(url) : null;
|
|
10
10
|
};
|
|
11
11
|
export const getCreatorName = (el) => {
|
|
12
|
-
|
|
12
|
+
var _a, _b;
|
|
13
|
+
const h1 = el === null || el === void 0 ? void 0 : el.querySelector('h1');
|
|
14
|
+
return (_b = (_a = h1 === null || h1 === void 0 ? void 0 : h1.innerText) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : null;
|
|
13
15
|
};
|
|
14
16
|
export const getCreatorBirthdayInfo = (el) => {
|
|
15
17
|
var _a, _b;
|
|
@@ -28,47 +30,44 @@ export const getCreatorBirthdayInfo = (el) => {
|
|
|
28
30
|
return { birthday, age, birthPlace };
|
|
29
31
|
};
|
|
30
32
|
export const getCreatorBio = (el) => {
|
|
31
|
-
var _a;
|
|
32
|
-
|
|
33
|
+
var _a, _b;
|
|
34
|
+
const p = el === null || el === void 0 ? void 0 : el.querySelector('.article-content p');
|
|
35
|
+
const first = (_b = (_a = p === null || p === void 0 ? void 0 : p.text) === null || _a === void 0 ? void 0 : _a.trim().split('\n')[0]) === null || _b === void 0 ? void 0 : _b.trim();
|
|
36
|
+
return first || null;
|
|
33
37
|
};
|
|
34
38
|
export const getCreatorPhoto = (el) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const parseBirthday = (text) => {
|
|
39
|
-
return text.replace(/nar./g, '').trim();
|
|
39
|
+
var _a;
|
|
40
|
+
const src = (_a = el === null || el === void 0 ? void 0 : el.querySelector('img')) === null || _a === void 0 ? void 0 : _a.getAttribute('src');
|
|
41
|
+
return src ? addProtocol(src) : null;
|
|
40
42
|
};
|
|
43
|
+
const parseBirthday = (text) => text.replace(/nar\./g, '').trim();
|
|
41
44
|
const parseAge = (text) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const parseBirthPlace = (text) => {
|
|
45
|
-
return text.trim().replace(/<br>/g, '').trim();
|
|
45
|
+
const digits = text.replace(/[^\d]/g, '');
|
|
46
|
+
return digits ? Number(digits) : null;
|
|
46
47
|
};
|
|
48
|
+
const parseBirthPlace = (text) => text.trim().replace(/<br>/g, '').trim();
|
|
47
49
|
export const getCreatorFilms = (el) => {
|
|
48
|
-
var _a;
|
|
49
|
-
const filmNodes = (_a = el.querySelectorAll('.box')[0]) === null ||
|
|
50
|
-
let yearCache;
|
|
50
|
+
var _a, _b, _c;
|
|
51
|
+
const filmNodes = (_c = (_b = (_a = el === null || el === void 0 ? void 0 : el.querySelectorAll('.box')) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.querySelectorAll('table tr')) !== null && _c !== void 0 ? _c : [];
|
|
52
|
+
let yearCache = null;
|
|
51
53
|
const films = filmNodes.map((filmNode) => {
|
|
52
|
-
var _a, _b, _c;
|
|
53
|
-
const id = getCreatorId((_a = filmNode.querySelector('td.name .film-title-name')) === null || _a === void 0 ? void 0 : _a.attributes.href);
|
|
54
|
-
const title = (
|
|
55
|
-
const
|
|
54
|
+
var _a, _b, _c, _d, _e, _f;
|
|
55
|
+
const id = getCreatorId((_b = (_a = filmNode.querySelector('td.name .film-title-name')) === null || _a === void 0 ? void 0 : _a.attributes) === null || _b === void 0 ? void 0 : _b.href);
|
|
56
|
+
const title = (_d = (_c = filmNode.querySelector('.name')) === null || _c === void 0 ? void 0 : _c.text) === null || _d === void 0 ? void 0 : _d.trim();
|
|
57
|
+
const yearText = (_f = (_e = filmNode.querySelector('.year')) === null || _e === void 0 ? void 0 : _e.text) === null || _f === void 0 ? void 0 : _f.trim();
|
|
58
|
+
const year = yearText ? +yearText : null;
|
|
56
59
|
const colorRating = getCreatorColorRating(filmNode.querySelector('.name .icon'));
|
|
57
60
|
// Cache year from previous film because there is a gap between movies with same year
|
|
58
|
-
if (year) {
|
|
61
|
+
if (typeof year === 'number' && !isNaN(year)) {
|
|
59
62
|
yearCache = +year;
|
|
60
63
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
title,
|
|
65
|
-
year: year || yearCache,
|
|
66
|
-
colorRating
|
|
67
|
-
};
|
|
64
|
+
const finalYear = year !== null && year !== void 0 ? year : yearCache;
|
|
65
|
+
if (id != null && title && finalYear != null) {
|
|
66
|
+
return { id, title, year: finalYear, colorRating };
|
|
68
67
|
}
|
|
69
|
-
return
|
|
68
|
+
return null;
|
|
70
69
|
});
|
|
71
70
|
// Remove empty objects
|
|
72
|
-
const filmsUnique = films.filter(
|
|
71
|
+
const filmsUnique = films.filter(Boolean);
|
|
73
72
|
return filmsUnique;
|
|
74
73
|
};
|
|
@@ -8,6 +8,16 @@ export const parseIdFromUrl = (url) => {
|
|
|
8
8
|
return null;
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
|
+
export const parseLastIdFromUrl = (url) => {
|
|
12
|
+
if (url) {
|
|
13
|
+
const idSlug = url === null || url === void 0 ? void 0 : url.split('/')[3];
|
|
14
|
+
const id = idSlug === null || idSlug === void 0 ? void 0 : idSlug.split('-')[0];
|
|
15
|
+
return +id || null;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
11
21
|
export const getColor = (cls) => {
|
|
12
22
|
switch (cls) {
|
|
13
23
|
case 'page-lightgrey':
|
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
import { addProtocol, getColor, parseISO8601Duration, parseIdFromUrl } from './global.helper';
|
|
1
|
+
import { addProtocol, getColor, parseISO8601Duration, parseIdFromUrl, parseLastIdFromUrl } from './global.helper.js';
|
|
2
2
|
export const getMovieId = (el) => {
|
|
3
3
|
const url = el.querySelector('.tabs .tab-nav-list a').attributes.href;
|
|
4
4
|
return parseIdFromUrl(url);
|
|
5
5
|
};
|
|
6
|
+
export const getSerieasAndSeasonTitle = (el) => {
|
|
7
|
+
const titleElement = el.querySelector('h1');
|
|
8
|
+
if (!titleElement) {
|
|
9
|
+
return { seriesName: null, seasonName: null };
|
|
10
|
+
}
|
|
11
|
+
const fullText = titleElement.innerText.trim();
|
|
12
|
+
// Check if there's a series part indicated by ' - '
|
|
13
|
+
if (fullText.includes(' - ')) {
|
|
14
|
+
const [seriesName, seasonName] = fullText.split(' - ').map(part => part.trim());
|
|
15
|
+
return { seriesName, seasonName };
|
|
16
|
+
}
|
|
17
|
+
// If no series part found, return just the name
|
|
18
|
+
return { seriesName: fullText, seasonName: null };
|
|
19
|
+
};
|
|
6
20
|
export const getMovieTitle = (el) => {
|
|
7
21
|
return el.querySelector('h1').innerText.split(`(`)[0].trim();
|
|
8
22
|
};
|
|
@@ -154,6 +168,63 @@ const parseMoviePeople = (el) => {
|
|
|
154
168
|
};
|
|
155
169
|
}));
|
|
156
170
|
};
|
|
171
|
+
export const getSeasonsOrEpisodes = (el, serie) => {
|
|
172
|
+
const childrenList = el.querySelector('.film-episodes-list');
|
|
173
|
+
if (!childrenList)
|
|
174
|
+
return null;
|
|
175
|
+
const childrenNodes = childrenList.querySelectorAll('.film-title');
|
|
176
|
+
if (!(childrenNodes === null || childrenNodes === void 0 ? void 0 : childrenNodes.length))
|
|
177
|
+
return [];
|
|
178
|
+
return childrenNodes.map((season) => {
|
|
179
|
+
var _a, _b;
|
|
180
|
+
const nameContainer = season.querySelector('.film-title-name');
|
|
181
|
+
const infoContainer = season.querySelector('.info');
|
|
182
|
+
return {
|
|
183
|
+
id: parseLastIdFromUrl((nameContainer === null || nameContainer === void 0 ? void 0 : nameContainer.getAttribute('href')) || ''),
|
|
184
|
+
name: ((_a = nameContainer === null || nameContainer === void 0 ? void 0 : nameContainer.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || null,
|
|
185
|
+
url: (nameContainer === null || nameContainer === void 0 ? void 0 : nameContainer.getAttribute('href')) || null,
|
|
186
|
+
info: ((_b = infoContainer === null || infoContainer === void 0 ? void 0 : infoContainer.textContent) === null || _b === void 0 ? void 0 : _b.replace(/[{()}]/g, '').trim()) || null,
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
export const getEpisodeCode = (el) => {
|
|
191
|
+
var _a;
|
|
192
|
+
const filmHeaderName = el.querySelector('.film-header-name h1');
|
|
193
|
+
if (!filmHeaderName)
|
|
194
|
+
return null;
|
|
195
|
+
const text = ((_a = filmHeaderName.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || '';
|
|
196
|
+
const match = text.match(/\(([^)]+)\)/);
|
|
197
|
+
const code = match ? match[1] : null;
|
|
198
|
+
return code;
|
|
199
|
+
};
|
|
200
|
+
export const detectSeasonOrEpisodeListType = (el) => {
|
|
201
|
+
var _a, _b;
|
|
202
|
+
const headerText = (_b = (_a = el.querySelector('.box-header h3')) === null || _a === void 0 ? void 0 : _a.innerText.trim()) !== null && _b !== void 0 ? _b : '';
|
|
203
|
+
if (headerText.includes('Série'))
|
|
204
|
+
return 'seasons';
|
|
205
|
+
if (headerText.startsWith('Epizody'))
|
|
206
|
+
return 'episodes';
|
|
207
|
+
return null;
|
|
208
|
+
};
|
|
209
|
+
export const getSeasonorEpisodeParent = (el, serie) => {
|
|
210
|
+
var _a, _b;
|
|
211
|
+
const parents = el.querySelectorAll('.film-header h2 a');
|
|
212
|
+
if (parents.length === 0) {
|
|
213
|
+
if (!serie)
|
|
214
|
+
return null;
|
|
215
|
+
return { series: serie, season: null };
|
|
216
|
+
}
|
|
217
|
+
const [parentSeries, parentSeason] = parents;
|
|
218
|
+
const seriesId = parseIdFromUrl(parentSeries === null || parentSeries === void 0 ? void 0 : parentSeries.getAttribute('href'));
|
|
219
|
+
const seasonId = parseIdFromUrl(parentSeason === null || parentSeason === void 0 ? void 0 : parentSeason.getAttribute('href'));
|
|
220
|
+
const seriesName = ((_a = parentSeries === null || parentSeries === void 0 ? void 0 : parentSeries.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || null;
|
|
221
|
+
const seasonName = ((_b = parentSeason === null || parentSeason === void 0 ? void 0 : parentSeason.textContent) === null || _b === void 0 ? void 0 : _b.trim()) || null;
|
|
222
|
+
const series = seriesId && seriesName ? { id: seriesId, name: seriesName } : null;
|
|
223
|
+
const season = seasonId && seasonName ? { id: seasonId, name: seasonName } : null;
|
|
224
|
+
if (!series && !season)
|
|
225
|
+
return null;
|
|
226
|
+
return { series, season };
|
|
227
|
+
};
|
|
157
228
|
export const getMovieGroup = (el, group) => {
|
|
158
229
|
const creators = el.querySelectorAll('.creators h4');
|
|
159
230
|
const element = creators.filter((elem) => elem.textContent.trim().includes(group))[0];
|
|
@@ -223,6 +294,6 @@ export const getMoviePremieres = (el) => {
|
|
|
223
294
|
return premiere;
|
|
224
295
|
};
|
|
225
296
|
export const getMovieTags = (el) => {
|
|
226
|
-
const tagsRaw = el.querySelectorAll('.box-content a[href*="/
|
|
297
|
+
const tagsRaw = el.querySelectorAll('.box-content a[href*="/tag/"]');
|
|
227
298
|
return tagsRaw.map((tag) => tag.textContent);
|
|
228
299
|
};
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NodeType } from 'node-html-parser';
|
|
2
|
+
import { addProtocol } from './global.helper.js';
|
|
2
3
|
export const getUser = (el) => {
|
|
3
4
|
return el.querySelector('.user-title-name').text;
|
|
4
5
|
};
|
|
5
6
|
export const getUserRealName = (el) => {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
const p = el.querySelector('.article-content p');
|
|
8
|
+
if (!p)
|
|
9
|
+
return null;
|
|
10
|
+
const textNodes = p.childNodes.filter(n => n.nodeType === NodeType.TEXT_NODE && n.rawText.trim() !== '');
|
|
11
|
+
const name = textNodes.length ? textNodes[0].rawText.trim() : null;
|
|
12
|
+
return name;
|
|
8
13
|
};
|
|
9
14
|
export const getAvatar = (el) => {
|
|
10
15
|
const image = el.querySelector('.article-img img').attributes.src;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { addProtocol, parseColor, parseIdFromUrl } from './global.helper';
|
|
1
|
+
import { addProtocol, parseColor, parseIdFromUrl } from './global.helper.js';
|
|
2
2
|
export const getSearchType = (el) => {
|
|
3
|
+
var _a, _b;
|
|
3
4
|
const type = el.querySelectorAll('.film-title-info .info')[1];
|
|
4
|
-
return ((type === null || type === void 0 ? void 0 : type.innerText.replace(/[{()}]/g, '')) || 'film');
|
|
5
|
+
return (((_b = (_a = type === null || type === void 0 ? void 0 : type.innerText) === null || _a === void 0 ? void 0 : _a.replace(/[{()}]/g, '')) === null || _b === void 0 ? void 0 : _b.trim()) || 'film');
|
|
5
6
|
};
|
|
6
7
|
export const getSearchTitle = (el) => {
|
|
7
8
|
return el.querySelector('.film-title-name').text;
|
package/esm/index.js
CHANGED
|
@@ -7,11 +7,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { CinemaScraper } from './services/cinema.service';
|
|
11
|
-
import { CreatorScraper } from './services/creator.service';
|
|
12
|
-
import { MovieScraper } from './services/movie.service';
|
|
13
|
-
import { SearchScraper } from './services/search.service';
|
|
14
|
-
import { UserRatingsScraper } from './services/user-ratings.service';
|
|
10
|
+
import { CinemaScraper } from './services/cinema.service.js';
|
|
11
|
+
import { CreatorScraper } from './services/creator.service.js';
|
|
12
|
+
import { MovieScraper } from './services/movie.service.js';
|
|
13
|
+
import { SearchScraper } from './services/search.service.js';
|
|
14
|
+
import { UserRatingsScraper } from './services/user-ratings.service.js';
|
|
15
15
|
export class Csfd {
|
|
16
16
|
constructor(userRatingsService, movieService, creatorService, searchService, cinemaService) {
|
|
17
17
|
this.userRatingsService = userRatingsService;
|
|
@@ -8,9 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { parse } from 'node-html-parser';
|
|
11
|
-
import { fetchPage } from '../fetchers';
|
|
12
|
-
import { cinemasUrl } from '../vars';
|
|
13
|
-
import { getCinemaCoords, getCinemaId, getCinemaUrl, getGroupedFilmsByDate, parseCinema } from './../helpers/cinema.helper';
|
|
11
|
+
import { fetchPage } from '../fetchers/fetchers.js';
|
|
12
|
+
import { cinemasUrl } from '../vars.js';
|
|
13
|
+
import { getCinemaCoords, getCinemaId, getCinemaUrl, getGroupedFilmsByDate, parseCinema } from './../helpers/cinema.helper.js';
|
|
14
14
|
export class CinemaScraper {
|
|
15
15
|
cinemas() {
|
|
16
16
|
return __awaiter(this, arguments, void 0, function* (district = 1, period = 'today') {
|
|
@@ -8,13 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { parse } from 'node-html-parser';
|
|
11
|
-
import { fetchPage } from '../fetchers';
|
|
12
|
-
import { getCreatorBio, getCreatorBirthdayInfo, getCreatorFilms, getCreatorName, getCreatorPhoto } from '../helpers/creator.helper';
|
|
13
|
-
import { creatorUrl } from '../vars';
|
|
11
|
+
import { fetchPage } from '../fetchers/fetchers.js';
|
|
12
|
+
import { getCreatorBio, getCreatorBirthdayInfo, getCreatorFilms, getCreatorName, getCreatorPhoto } from '../helpers/creator.helper.js';
|
|
13
|
+
import { creatorUrl } from '../vars.js';
|
|
14
14
|
export class CreatorScraper {
|
|
15
15
|
creator(creatorId) {
|
|
16
16
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
const
|
|
17
|
+
const id = Number(creatorId);
|
|
18
|
+
if (isNaN(id)) {
|
|
19
|
+
throw new Error('node-csfd-api: creatorId must be a valid number');
|
|
20
|
+
}
|
|
21
|
+
const url = creatorUrl(id);
|
|
18
22
|
const response = yield fetchPage(url);
|
|
19
23
|
const creatorHtml = parse(response);
|
|
20
24
|
const asideNode = creatorHtml.querySelector('.creator-about');
|