node-csfd-api 3.0.0-next.11 → 3.0.0-next.12
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/helpers/cinema.helper.js +88 -0
- package/cjs/helpers/movie.helper.js +9 -4
- package/cjs/index.js +10 -2
- package/cjs/interfaces/cinema.interface.js +2 -0
- package/cjs/services/cinema.service.js +44 -0
- package/cjs/vars.js +5 -1
- package/esm/helpers/cinema.helper.js +76 -0
- package/esm/helpers/movie.helper.js +10 -5
- package/esm/index.js +10 -2
- package/esm/interfaces/cinema.interface.js +1 -0
- package/esm/services/cinema.service.js +40 -0
- package/esm/vars.js +3 -0
- package/package.json +5 -4
- package/types/helpers/cinema.helper.d.ts +18 -0
- package/types/index.d.ts +5 -1
- package/types/index.ts +3 -0
- package/types/interfaces/cinema.interface.d.ts +17 -0
- package/types/services/cinema.service.d.ts +6 -0
- package/types/vars.d.ts +1 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseMeta = exports.getFilms = exports.getGroupedFilmsByDate = exports.parseCinema = exports.getCinemaUrl = exports.getCoords = exports.getName = exports.getId = exports.getColorRating = void 0;
|
|
4
|
+
const global_helper_1 = require("./global.helper");
|
|
5
|
+
const getColorRating = (el) => {
|
|
6
|
+
return (0, global_helper_1.parseColor)(el === null || el === void 0 ? void 0 : el.classNames.split(' ').pop());
|
|
7
|
+
};
|
|
8
|
+
exports.getColorRating = getColorRating;
|
|
9
|
+
const getId = (url) => {
|
|
10
|
+
if (url) {
|
|
11
|
+
return (0, global_helper_1.parseIdFromUrl)(url);
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
};
|
|
15
|
+
exports.getId = getId;
|
|
16
|
+
const getName = (el) => {
|
|
17
|
+
return el.querySelector('h1').innerText.trim();
|
|
18
|
+
};
|
|
19
|
+
exports.getName = getName;
|
|
20
|
+
const getCoords = (el) => {
|
|
21
|
+
const link = el === null || el === void 0 ? void 0 : el.querySelector('.box-header img[alt="Google Maps"]').closest('a').getAttribute('href');
|
|
22
|
+
const coords = link.split('q=')[1].split(',');
|
|
23
|
+
const [lat, lng] = coords;
|
|
24
|
+
return { lat: +lat, lng: +lng };
|
|
25
|
+
};
|
|
26
|
+
exports.getCoords = getCoords;
|
|
27
|
+
const getCinemaUrl = (el) => {
|
|
28
|
+
var _a;
|
|
29
|
+
return (_a = el.querySelector('.box-header .cinema-logo a')) === null || _a === void 0 ? void 0 : _a.attributes.href;
|
|
30
|
+
};
|
|
31
|
+
exports.getCinemaUrl = getCinemaUrl;
|
|
32
|
+
const parseCinema = (el) => {
|
|
33
|
+
const title = el.querySelector('.box-header h2').innerText.trim();
|
|
34
|
+
const [city, name] = title.split(' - ');
|
|
35
|
+
return { city, name };
|
|
36
|
+
};
|
|
37
|
+
exports.parseCinema = parseCinema;
|
|
38
|
+
const getGroupedFilmsByDate = (el) => {
|
|
39
|
+
const divs = el.querySelectorAll(':scope > div');
|
|
40
|
+
const getDatesAndFilms = divs
|
|
41
|
+
.map((_, index) => index)
|
|
42
|
+
.filter((index) => index % 2 === 0)
|
|
43
|
+
.map((index) => {
|
|
44
|
+
const [date, films] = divs.slice(index, index + 2);
|
|
45
|
+
const dateText = date === null || date === void 0 ? void 0 : date.innerText.trim();
|
|
46
|
+
return { date: dateText, films: (0, exports.getFilms)('', films) };
|
|
47
|
+
});
|
|
48
|
+
return getDatesAndFilms;
|
|
49
|
+
};
|
|
50
|
+
exports.getGroupedFilmsByDate = getGroupedFilmsByDate;
|
|
51
|
+
const getFilms = (date, el) => {
|
|
52
|
+
const filmNodes = el.querySelectorAll('.cinema-table tr');
|
|
53
|
+
const films = filmNodes.map((filmNode) => {
|
|
54
|
+
var _a, _b, _c, _d;
|
|
55
|
+
const url = (_a = filmNode.querySelector('td.name h3 a')) === null || _a === void 0 ? void 0 : _a.attributes.href;
|
|
56
|
+
const id = (0, exports.getId)(url);
|
|
57
|
+
const title = (_b = filmNode.querySelector('.name h3')) === null || _b === void 0 ? void 0 : _b.text.trim();
|
|
58
|
+
const colorRating = (0, exports.getColorRating)(filmNode.querySelector('.name .icon'));
|
|
59
|
+
const showTimes = (_c = filmNode.querySelectorAll('.td-time')) === null || _c === void 0 ? void 0 : _c.map((x) => x.textContent.trim());
|
|
60
|
+
const meta = (_d = filmNode.querySelectorAll('.td-title span')) === null || _d === void 0 ? void 0 : _d.map((x) => x.text.trim());
|
|
61
|
+
return {
|
|
62
|
+
id,
|
|
63
|
+
title,
|
|
64
|
+
url,
|
|
65
|
+
colorRating,
|
|
66
|
+
showTimes,
|
|
67
|
+
meta: (0, exports.parseMeta)(meta)
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
return films;
|
|
71
|
+
};
|
|
72
|
+
exports.getFilms = getFilms;
|
|
73
|
+
const parseMeta = (meta) => {
|
|
74
|
+
const metaConvert = [];
|
|
75
|
+
for (const element of meta) {
|
|
76
|
+
if (element === 'T') {
|
|
77
|
+
metaConvert.push('subtitles');
|
|
78
|
+
}
|
|
79
|
+
else if (element === 'D') {
|
|
80
|
+
metaConvert.push('dubbing');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
metaConvert.push(element);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return metaConvert;
|
|
87
|
+
};
|
|
88
|
+
exports.parseMeta = parseMeta;
|
|
@@ -28,9 +28,10 @@ const getColorRating = (bodyClasses) => {
|
|
|
28
28
|
exports.getColorRating = getColorRating;
|
|
29
29
|
const getRating = (el) => {
|
|
30
30
|
const ratingRaw = el.querySelector('.film-rating-average').textContent;
|
|
31
|
-
const rating =
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
const rating = ratingRaw === null || ratingRaw === void 0 ? void 0 : ratingRaw.replace(/%/g, '').trim();
|
|
32
|
+
const ratingInt = parseInt(rating);
|
|
33
|
+
if (Number.isInteger(ratingInt)) {
|
|
34
|
+
return ratingInt;
|
|
34
35
|
}
|
|
35
36
|
else {
|
|
36
37
|
return null;
|
|
@@ -90,7 +91,10 @@ const getDuration = (jsonLdRaw, el) => {
|
|
|
90
91
|
exports.getDuration = getDuration;
|
|
91
92
|
const getTitlesOther = (el) => {
|
|
92
93
|
const namesNode = el.querySelectorAll('.film-names li');
|
|
93
|
-
|
|
94
|
+
if (!namesNode.length) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const titlesOther = namesNode.map((el) => {
|
|
94
98
|
const country = el.querySelector('img.flag').attributes.alt;
|
|
95
99
|
const title = el.textContent.trim().split('\n')[0];
|
|
96
100
|
if (country && title) {
|
|
@@ -103,6 +107,7 @@ const getTitlesOther = (el) => {
|
|
|
103
107
|
return null;
|
|
104
108
|
}
|
|
105
109
|
});
|
|
110
|
+
return titlesOther.filter((x) => x);
|
|
106
111
|
};
|
|
107
112
|
exports.getTitlesOther = getTitlesOther;
|
|
108
113
|
const getPoster = (el) => {
|
package/cjs/index.js
CHANGED
|
@@ -10,16 +10,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.csfd = exports.Csfd = void 0;
|
|
13
|
+
const cinema_service_1 = require("./services/cinema.service");
|
|
13
14
|
const creator_service_1 = require("./services/creator.service");
|
|
14
15
|
const movie_service_1 = require("./services/movie.service");
|
|
15
16
|
const search_service_1 = require("./services/search.service");
|
|
16
17
|
const user_ratings_service_1 = require("./services/user-ratings.service");
|
|
17
18
|
class Csfd {
|
|
18
|
-
constructor(userRatingsService, movieService, creatorService, searchService) {
|
|
19
|
+
constructor(userRatingsService, movieService, creatorService, searchService, cinemaService) {
|
|
19
20
|
this.userRatingsService = userRatingsService;
|
|
20
21
|
this.movieService = movieService;
|
|
21
22
|
this.creatorService = creatorService;
|
|
22
23
|
this.searchService = searchService;
|
|
24
|
+
this.cinemaService = cinemaService;
|
|
23
25
|
}
|
|
24
26
|
userRatings(user, config) {
|
|
25
27
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -41,10 +43,16 @@ class Csfd {
|
|
|
41
43
|
return this.searchService.search(text);
|
|
42
44
|
});
|
|
43
45
|
}
|
|
46
|
+
cinema(district) {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
return this.cinemaService.cinemas(+district);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
exports.Csfd = Csfd;
|
|
46
53
|
const movieScraper = new movie_service_1.MovieScraper();
|
|
47
54
|
const userRatingsScraper = new user_ratings_service_1.UserRatingsScraper();
|
|
55
|
+
const cinemaScraper = new cinema_service_1.CinemaScraper();
|
|
48
56
|
const creatorScraper = new creator_service_1.CreatorScraper();
|
|
49
57
|
const searchScraper = new search_service_1.SearchScraper();
|
|
50
|
-
exports.csfd = new Csfd(userRatingsScraper, movieScraper, creatorScraper, searchScraper);
|
|
58
|
+
exports.csfd = new Csfd(userRatingsScraper, movieScraper, creatorScraper, searchScraper, cinemaScraper);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CinemaScraper = void 0;
|
|
13
|
+
const node_html_parser_1 = require("node-html-parser");
|
|
14
|
+
const fetchers_1 = require("../fetchers");
|
|
15
|
+
const vars_1 = require("../vars");
|
|
16
|
+
const cinema_helper_1 = require("./../helpers/cinema.helper");
|
|
17
|
+
class CinemaScraper {
|
|
18
|
+
cinemas(district) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const url = (0, vars_1.cinemasUrl)(district, 'week');
|
|
21
|
+
const response = yield (0, fetchers_1.fetchPage)(url);
|
|
22
|
+
const cinemasHtml = (0, node_html_parser_1.parse)(response);
|
|
23
|
+
const contentNode = cinemasHtml.querySelectorAll('#snippet--cinemas section.box');
|
|
24
|
+
this.buildCinemas(contentNode);
|
|
25
|
+
return this.cinema;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
buildCinemas(contentNode) {
|
|
29
|
+
const cinemas = [];
|
|
30
|
+
contentNode.map((x) => {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const cinema = {
|
|
33
|
+
name: (_a = (0, cinema_helper_1.parseCinema)(x)) === null || _a === void 0 ? void 0 : _a.name,
|
|
34
|
+
city: (_b = (0, cinema_helper_1.parseCinema)(x)) === null || _b === void 0 ? void 0 : _b.city,
|
|
35
|
+
url: (0, cinema_helper_1.getCinemaUrl)(x),
|
|
36
|
+
coords: (0, cinema_helper_1.getCoords)(x),
|
|
37
|
+
screenings: (0, cinema_helper_1.getGroupedFilmsByDate)(x)
|
|
38
|
+
};
|
|
39
|
+
cinemas.push(cinema);
|
|
40
|
+
});
|
|
41
|
+
this.cinema = cinemas;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.CinemaScraper = CinemaScraper;
|
package/cjs/vars.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.searchUrl = exports.creatorUrl = exports.movieUrl = exports.userRatingsUrl = void 0;
|
|
3
|
+
exports.searchUrl = exports.cinemasUrl = exports.creatorUrl = exports.movieUrl = exports.userRatingsUrl = void 0;
|
|
4
4
|
const userRatingsUrl = (user, page) => `https://www.csfd.cz/uzivatel/${encodeURIComponent(user)}/hodnoceni/${page ? '?page=' + page : ''}`;
|
|
5
5
|
exports.userRatingsUrl = userRatingsUrl;
|
|
6
6
|
const movieUrl = (movie) => `https://www.csfd.cz/film/${encodeURIComponent(movie)}/prehled/`;
|
|
7
7
|
exports.movieUrl = movieUrl;
|
|
8
8
|
const creatorUrl = (creator) => `https://www.csfd.cz/tvurce/${encodeURIComponent(creator)}`;
|
|
9
9
|
exports.creatorUrl = creatorUrl;
|
|
10
|
+
const cinemasUrl = (district = 1, period = 'today') => {
|
|
11
|
+
return `https://www.csfd.cz/kino/?period=${period}&district=${district}`;
|
|
12
|
+
};
|
|
13
|
+
exports.cinemasUrl = cinemasUrl;
|
|
10
14
|
const searchUrl = (text) => `https://www.csfd.cz/hledat/?q=${encodeURIComponent(text)}`;
|
|
11
15
|
exports.searchUrl = searchUrl;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { parseColor, parseIdFromUrl } from './global.helper';
|
|
2
|
+
export const getColorRating = (el) => {
|
|
3
|
+
return parseColor(el === null || el === void 0 ? void 0 : el.classNames.split(' ').pop());
|
|
4
|
+
};
|
|
5
|
+
export const getId = (url) => {
|
|
6
|
+
if (url) {
|
|
7
|
+
return parseIdFromUrl(url);
|
|
8
|
+
}
|
|
9
|
+
return null;
|
|
10
|
+
};
|
|
11
|
+
export const getName = (el) => {
|
|
12
|
+
return el.querySelector('h1').innerText.trim();
|
|
13
|
+
};
|
|
14
|
+
export const getCoords = (el) => {
|
|
15
|
+
const link = el === null || el === void 0 ? void 0 : el.querySelector('.box-header img[alt="Google Maps"]').closest('a').getAttribute('href');
|
|
16
|
+
const coords = link.split('q=')[1].split(',');
|
|
17
|
+
const [lat, lng] = coords;
|
|
18
|
+
return { lat: +lat, lng: +lng };
|
|
19
|
+
};
|
|
20
|
+
export const getCinemaUrl = (el) => {
|
|
21
|
+
var _a;
|
|
22
|
+
return (_a = el.querySelector('.box-header .cinema-logo a')) === null || _a === void 0 ? void 0 : _a.attributes.href;
|
|
23
|
+
};
|
|
24
|
+
export const parseCinema = (el) => {
|
|
25
|
+
const title = el.querySelector('.box-header h2').innerText.trim();
|
|
26
|
+
const [city, name] = title.split(' - ');
|
|
27
|
+
return { city, name };
|
|
28
|
+
};
|
|
29
|
+
export const getGroupedFilmsByDate = (el) => {
|
|
30
|
+
const divs = el.querySelectorAll(':scope > div');
|
|
31
|
+
const getDatesAndFilms = divs
|
|
32
|
+
.map((_, index) => index)
|
|
33
|
+
.filter((index) => index % 2 === 0)
|
|
34
|
+
.map((index) => {
|
|
35
|
+
const [date, films] = divs.slice(index, index + 2);
|
|
36
|
+
const dateText = date === null || date === void 0 ? void 0 : date.innerText.trim();
|
|
37
|
+
return { date: dateText, films: getFilms('', films) };
|
|
38
|
+
});
|
|
39
|
+
return getDatesAndFilms;
|
|
40
|
+
};
|
|
41
|
+
export const getFilms = (date, el) => {
|
|
42
|
+
const filmNodes = el.querySelectorAll('.cinema-table tr');
|
|
43
|
+
const films = filmNodes.map((filmNode) => {
|
|
44
|
+
var _a, _b, _c, _d;
|
|
45
|
+
const url = (_a = filmNode.querySelector('td.name h3 a')) === null || _a === void 0 ? void 0 : _a.attributes.href;
|
|
46
|
+
const id = getId(url);
|
|
47
|
+
const title = (_b = filmNode.querySelector('.name h3')) === null || _b === void 0 ? void 0 : _b.text.trim();
|
|
48
|
+
const colorRating = getColorRating(filmNode.querySelector('.name .icon'));
|
|
49
|
+
const showTimes = (_c = filmNode.querySelectorAll('.td-time')) === null || _c === void 0 ? void 0 : _c.map((x) => x.textContent.trim());
|
|
50
|
+
const meta = (_d = filmNode.querySelectorAll('.td-title span')) === null || _d === void 0 ? void 0 : _d.map((x) => x.text.trim());
|
|
51
|
+
return {
|
|
52
|
+
id,
|
|
53
|
+
title,
|
|
54
|
+
url,
|
|
55
|
+
colorRating,
|
|
56
|
+
showTimes,
|
|
57
|
+
meta: parseMeta(meta)
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
return films;
|
|
61
|
+
};
|
|
62
|
+
export const parseMeta = (meta) => {
|
|
63
|
+
const metaConvert = [];
|
|
64
|
+
for (const element of meta) {
|
|
65
|
+
if (element === 'T') {
|
|
66
|
+
metaConvert.push('subtitles');
|
|
67
|
+
}
|
|
68
|
+
else if (element === 'D') {
|
|
69
|
+
metaConvert.push('dubbing');
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
metaConvert.push(element);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return metaConvert;
|
|
76
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addProtocol, getColor,
|
|
1
|
+
import { addProtocol, getColor, parseISO8601Duration, parseIdFromUrl } from './global.helper';
|
|
2
2
|
export const getId = (el) => {
|
|
3
3
|
const url = el.querySelector('.tabs .tab-nav-list a').attributes.href;
|
|
4
4
|
return parseIdFromUrl(url);
|
|
@@ -20,9 +20,10 @@ export const getColorRating = (bodyClasses) => {
|
|
|
20
20
|
};
|
|
21
21
|
export const getRating = (el) => {
|
|
22
22
|
const ratingRaw = el.querySelector('.film-rating-average').textContent;
|
|
23
|
-
const rating =
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
const rating = ratingRaw === null || ratingRaw === void 0 ? void 0 : ratingRaw.replace(/%/g, '').trim();
|
|
24
|
+
const ratingInt = parseInt(rating);
|
|
25
|
+
if (Number.isInteger(ratingInt)) {
|
|
26
|
+
return ratingInt;
|
|
26
27
|
}
|
|
27
28
|
else {
|
|
28
29
|
return null;
|
|
@@ -78,7 +79,10 @@ export const getDuration = (jsonLdRaw, el) => {
|
|
|
78
79
|
};
|
|
79
80
|
export const getTitlesOther = (el) => {
|
|
80
81
|
const namesNode = el.querySelectorAll('.film-names li');
|
|
81
|
-
|
|
82
|
+
if (!namesNode.length) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
const titlesOther = namesNode.map((el) => {
|
|
82
86
|
const country = el.querySelector('img.flag').attributes.alt;
|
|
83
87
|
const title = el.textContent.trim().split('\n')[0];
|
|
84
88
|
if (country && title) {
|
|
@@ -91,6 +95,7 @@ export const getTitlesOther = (el) => {
|
|
|
91
95
|
return null;
|
|
92
96
|
}
|
|
93
97
|
});
|
|
98
|
+
return titlesOther.filter((x) => x);
|
|
94
99
|
};
|
|
95
100
|
export const getPoster = (el) => {
|
|
96
101
|
var _a;
|
package/esm/index.js
CHANGED
|
@@ -7,16 +7,18 @@ 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';
|
|
10
11
|
import { CreatorScraper } from './services/creator.service';
|
|
11
12
|
import { MovieScraper } from './services/movie.service';
|
|
12
13
|
import { SearchScraper } from './services/search.service';
|
|
13
14
|
import { UserRatingsScraper } from './services/user-ratings.service';
|
|
14
15
|
export class Csfd {
|
|
15
|
-
constructor(userRatingsService, movieService, creatorService, searchService) {
|
|
16
|
+
constructor(userRatingsService, movieService, creatorService, searchService, cinemaService) {
|
|
16
17
|
this.userRatingsService = userRatingsService;
|
|
17
18
|
this.movieService = movieService;
|
|
18
19
|
this.creatorService = creatorService;
|
|
19
20
|
this.searchService = searchService;
|
|
21
|
+
this.cinemaService = cinemaService;
|
|
20
22
|
}
|
|
21
23
|
userRatings(user, config) {
|
|
22
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -38,9 +40,15 @@ export class Csfd {
|
|
|
38
40
|
return this.searchService.search(text);
|
|
39
41
|
});
|
|
40
42
|
}
|
|
43
|
+
cinema(district) {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
return this.cinemaService.cinemas(+district);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
41
48
|
}
|
|
42
49
|
const movieScraper = new MovieScraper();
|
|
43
50
|
const userRatingsScraper = new UserRatingsScraper();
|
|
51
|
+
const cinemaScraper = new CinemaScraper();
|
|
44
52
|
const creatorScraper = new CreatorScraper();
|
|
45
53
|
const searchScraper = new SearchScraper();
|
|
46
|
-
export const csfd = new Csfd(userRatingsScraper, movieScraper, creatorScraper, searchScraper);
|
|
54
|
+
export const csfd = new Csfd(userRatingsScraper, movieScraper, creatorScraper, searchScraper, cinemaScraper);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { parse } from 'node-html-parser';
|
|
11
|
+
import { fetchPage } from '../fetchers';
|
|
12
|
+
import { cinemasUrl } from '../vars';
|
|
13
|
+
import { getCinemaUrl, getCoords, getGroupedFilmsByDate, parseCinema } from './../helpers/cinema.helper';
|
|
14
|
+
export class CinemaScraper {
|
|
15
|
+
cinemas(district) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const url = cinemasUrl(district, 'week');
|
|
18
|
+
const response = yield fetchPage(url);
|
|
19
|
+
const cinemasHtml = parse(response);
|
|
20
|
+
const contentNode = cinemasHtml.querySelectorAll('#snippet--cinemas section.box');
|
|
21
|
+
this.buildCinemas(contentNode);
|
|
22
|
+
return this.cinema;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
buildCinemas(contentNode) {
|
|
26
|
+
const cinemas = [];
|
|
27
|
+
contentNode.map((x) => {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
const cinema = {
|
|
30
|
+
name: (_a = parseCinema(x)) === null || _a === void 0 ? void 0 : _a.name,
|
|
31
|
+
city: (_b = parseCinema(x)) === null || _b === void 0 ? void 0 : _b.city,
|
|
32
|
+
url: getCinemaUrl(x),
|
|
33
|
+
coords: getCoords(x),
|
|
34
|
+
screenings: getGroupedFilmsByDate(x)
|
|
35
|
+
};
|
|
36
|
+
cinemas.push(cinema);
|
|
37
|
+
});
|
|
38
|
+
this.cinema = cinemas;
|
|
39
|
+
}
|
|
40
|
+
}
|
package/esm/vars.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export const userRatingsUrl = (user, page) => `https://www.csfd.cz/uzivatel/${encodeURIComponent(user)}/hodnoceni/${page ? '?page=' + page : ''}`;
|
|
2
2
|
export const movieUrl = (movie) => `https://www.csfd.cz/film/${encodeURIComponent(movie)}/prehled/`;
|
|
3
3
|
export const creatorUrl = (creator) => `https://www.csfd.cz/tvurce/${encodeURIComponent(creator)}`;
|
|
4
|
+
export const cinemasUrl = (district = 1, period = 'today') => {
|
|
5
|
+
return `https://www.csfd.cz/kino/?period=${period}&district=${district}`;
|
|
6
|
+
};
|
|
4
7
|
export const searchUrl = (text) => `https://www.csfd.cz/hledat/?q=${encodeURIComponent(text)}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-csfd-api",
|
|
3
|
-
"version": "3.0.0-next.
|
|
3
|
+
"version": "3.0.0-next.12",
|
|
4
4
|
"description": "ČSFD API in JavaScript. Amazing NPM library for scrapping csfd.cz :)",
|
|
5
5
|
"main": "./cjs/index.js",
|
|
6
6
|
"author": "BART! <bart@bartweb.cz>",
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"tsc": "tsc",
|
|
14
14
|
"demo": "ts-node demo",
|
|
15
15
|
"lint": "eslint ./src/**/**/* --fix",
|
|
16
|
-
"test": "
|
|
16
|
+
"test": "vitest",
|
|
17
|
+
"test:coverage": "yarn test run --coverage",
|
|
17
18
|
"fix-paths": "yarn json -I -f ./dist/package.json -e \"this.module='./esm/index.js';this.main='./cjs/index.js';this.types='./types/index.d.ts'\"",
|
|
18
|
-
"publish:next": "yarn && yarn build && yarn test
|
|
19
|
+
"publish:next": "yarn && yarn build && yarn test:coverage && cd dist && npm publish --tag next",
|
|
19
20
|
"postversion": "git push && git push --follow-tags",
|
|
20
21
|
"release:beta": "npm version preminor --preid=beta -m \"chore(update): prelease %s β\"",
|
|
21
22
|
"prerelease:beta": "npm version prerelease --preid=beta -m \"chore(update): prelease %s β\"",
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
"registry": "https://registry.npmjs.org"
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
|
-
"cross-fetch": "^3.1.
|
|
32
|
+
"cross-fetch": "^3.1.6",
|
|
32
33
|
"node-html-parser": "^6.1.5"
|
|
33
34
|
},
|
|
34
35
|
"repository": {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CSFDCinemaMeta, CSFDCinemaMovie } from 'interfaces/cinema.interface';
|
|
2
|
+
import { HTMLElement } from 'node-html-parser';
|
|
3
|
+
import { CSFDColorRating } from '../interfaces/global';
|
|
4
|
+
export declare const getColorRating: (el: HTMLElement) => CSFDColorRating;
|
|
5
|
+
export declare const getId: (url: string) => number;
|
|
6
|
+
export declare const getName: (el: HTMLElement | null) => string;
|
|
7
|
+
export declare const getCoords: (el: HTMLElement | null) => {
|
|
8
|
+
lat: number;
|
|
9
|
+
lng: number;
|
|
10
|
+
};
|
|
11
|
+
export declare const getCinemaUrl: (el: HTMLElement | null) => string;
|
|
12
|
+
export declare const parseCinema: (el: HTMLElement | null) => {
|
|
13
|
+
city: string;
|
|
14
|
+
name: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const getGroupedFilmsByDate: (el: HTMLElement | null) => any;
|
|
17
|
+
export declare const getFilms: (date: string, el: HTMLElement | null) => CSFDCinemaMovie[];
|
|
18
|
+
export declare const parseMeta: (meta: string[]) => CSFDCinemaMeta[];
|
package/types/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { CSFDCinema } from 'interfaces/cinema.interface';
|
|
1
2
|
import { CSFDCreator } from './interfaces/creator.interface';
|
|
2
3
|
import { CSFDMovie } from './interfaces/movie.interface';
|
|
3
4
|
import { CSFDSearch } from './interfaces/search.interface';
|
|
4
5
|
import { CSFDUserRatingConfig, CSFDUserRatings } from './interfaces/user-ratings.interface';
|
|
6
|
+
import { CinemaScraper } from './services/cinema.service';
|
|
5
7
|
import { CreatorScraper } from './services/creator.service';
|
|
6
8
|
import { MovieScraper } from './services/movie.service';
|
|
7
9
|
import { SearchScraper } from './services/search.service';
|
|
@@ -11,10 +13,12 @@ export declare class Csfd {
|
|
|
11
13
|
private movieService;
|
|
12
14
|
private creatorService;
|
|
13
15
|
private searchService;
|
|
14
|
-
|
|
16
|
+
private cinemaService;
|
|
17
|
+
constructor(userRatingsService: UserRatingsScraper, movieService: MovieScraper, creatorService: CreatorScraper, searchService: SearchScraper, cinemaService: CinemaScraper);
|
|
15
18
|
userRatings(user: string | number, config?: CSFDUserRatingConfig): Promise<CSFDUserRatings[]>;
|
|
16
19
|
movie(movie: number): Promise<CSFDMovie>;
|
|
17
20
|
creator(creator: number): Promise<CSFDCreator>;
|
|
18
21
|
search(text: string): Promise<CSFDSearch>;
|
|
22
|
+
cinema(district: number): Promise<CSFDCinema[]>;
|
|
19
23
|
}
|
|
20
24
|
export declare const csfd: Csfd;
|
package/types/index.ts
CHANGED
|
@@ -5,17 +5,20 @@
|
|
|
5
5
|
export * from "./index";
|
|
6
6
|
export * from "./vars";
|
|
7
7
|
export * from "./fetchers/index";
|
|
8
|
+
export * from "./helpers/cinema.helper";
|
|
8
9
|
export * from "./helpers/creator.helper";
|
|
9
10
|
export * from "./helpers/global.helper";
|
|
10
11
|
export * from "./helpers/movie.helper";
|
|
11
12
|
export * from "./helpers/search-user.helper";
|
|
12
13
|
export * from "./helpers/search.helper";
|
|
13
14
|
export * from "./helpers/user-ratings.helper";
|
|
15
|
+
export * from "./interfaces/cinema.interface";
|
|
14
16
|
export * from "./interfaces/creator.interface";
|
|
15
17
|
export * from "./interfaces/global";
|
|
16
18
|
export * from "./interfaces/movie.interface";
|
|
17
19
|
export * from "./interfaces/search.interface";
|
|
18
20
|
export * from "./interfaces/user-ratings.interface";
|
|
21
|
+
export * from "./services/cinema.service";
|
|
19
22
|
export * from "./services/creator.service";
|
|
20
23
|
export * from "./services/movie.service";
|
|
21
24
|
export * from "./services/search.service";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CSFDMovieListItem } from './movie.interface';
|
|
2
|
+
export interface CSFDCinema {
|
|
3
|
+
name: string;
|
|
4
|
+
city: string;
|
|
5
|
+
url: string;
|
|
6
|
+
coords: {
|
|
7
|
+
lat: number;
|
|
8
|
+
lng: number;
|
|
9
|
+
};
|
|
10
|
+
region?: string;
|
|
11
|
+
screenings: CSFDCinemaMovie[];
|
|
12
|
+
}
|
|
13
|
+
export interface CSFDCinemaMovie extends CSFDMovieListItem {
|
|
14
|
+
meta: CSFDCinemaMeta[];
|
|
15
|
+
showTimes: string[];
|
|
16
|
+
}
|
|
17
|
+
export type CSFDCinemaMeta = 'dubbing' | '3D' | 'subtitles' | string;
|
package/types/vars.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const userRatingsUrl: (user: string | number, page?: number) => string;
|
|
2
2
|
export declare const movieUrl: (movie: number) => string;
|
|
3
3
|
export declare const creatorUrl: (creator: number | string) => string;
|
|
4
|
+
export declare const cinemasUrl: (district?: number | string, period?: 'today' | 'weekend' | 'week' | 'tomorrow' | 'month') => string;
|
|
4
5
|
export declare const searchUrl: (text: string) => string;
|