node-csfd-api 2.3.1 → 3.0.0-next.0

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.
Files changed (59) hide show
  1. package/README.md +4 -1
  2. package/{fetchers → cjs/fetchers}/index.js +13 -4
  3. package/{helpers → cjs/helpers}/creator.helper.js +0 -0
  4. package/{helpers → cjs/helpers}/global.helper.js +8 -3
  5. package/{helpers → cjs/helpers}/movie.helper.js +23 -1
  6. package/{helpers → cjs/helpers}/search-user.helper.js +0 -0
  7. package/{helpers → cjs/helpers}/search.helper.js +0 -0
  8. package/{helpers → cjs/helpers}/user-ratings.helper.js +0 -0
  9. package/cjs/index.js +50 -0
  10. package/{interfaces → cjs/interfaces}/creator.interface.js +0 -0
  11. package/{interfaces → cjs/interfaces}/global.js +0 -0
  12. package/{interfaces → cjs/interfaces}/movie.interface.js +0 -0
  13. package/{interfaces → cjs/interfaces}/search.interface.js +0 -0
  14. package/{interfaces → cjs/interfaces}/user-ratings.interface.js +0 -0
  15. package/cjs/services/creator.service.js +43 -0
  16. package/{services → cjs/services}/movie.service.js +23 -10
  17. package/{services → cjs/services}/search.service.js +18 -7
  18. package/{services → cjs/services}/user-ratings.service.js +36 -25
  19. package/{vars.js → cjs/vars.js} +1 -1
  20. package/esm/fetchers/index.js +32 -0
  21. package/esm/helpers/creator.helper.js +72 -0
  22. package/esm/helpers/global.helper.js +56 -0
  23. package/esm/helpers/movie.helper.js +220 -0
  24. package/esm/helpers/search-user.helper.js +15 -0
  25. package/esm/helpers/search.helper.js +38 -0
  26. package/esm/helpers/user-ratings.helper.js +47 -0
  27. package/esm/index.js +46 -0
  28. package/esm/interfaces/creator.interface.js +1 -0
  29. package/esm/interfaces/global.js +1 -0
  30. package/esm/interfaces/movie.interface.js +1 -0
  31. package/esm/interfaces/search.interface.js +1 -0
  32. package/esm/interfaces/user-ratings.interface.js +1 -0
  33. package/esm/services/creator.service.js +39 -0
  34. package/esm/services/movie.service.js +65 -0
  35. package/esm/services/search.service.js +67 -0
  36. package/esm/services/user-ratings.service.js +91 -0
  37. package/esm/vars.js +4 -0
  38. package/package.json +10 -7
  39. package/{fetchers → types/fetchers}/index.d.ts +0 -0
  40. package/{helpers → types/helpers}/creator.helper.d.ts +0 -0
  41. package/{helpers → types/helpers}/global.helper.d.ts +0 -0
  42. package/{helpers → types/helpers}/movie.helper.d.ts +2 -0
  43. package/{helpers → types/helpers}/search-user.helper.d.ts +0 -0
  44. package/{helpers → types/helpers}/search.helper.d.ts +0 -0
  45. package/{helpers → types/helpers}/user-ratings.helper.d.ts +0 -0
  46. package/{index.d.ts → types/index.d.ts} +0 -0
  47. package/types/index.ts +22 -0
  48. package/{interfaces → types/interfaces}/creator.interface.d.ts +0 -0
  49. package/{interfaces → types/interfaces}/global.d.ts +0 -0
  50. package/{interfaces → types/interfaces}/movie.interface.d.ts +2 -0
  51. package/{interfaces → types/interfaces}/search.interface.d.ts +0 -0
  52. package/{interfaces → types/interfaces}/user-ratings.interface.d.ts +0 -0
  53. package/{services → types/services}/creator.service.d.ts +0 -0
  54. package/{services → types/services}/movie.service.d.ts +0 -0
  55. package/{services → types/services}/search.service.d.ts +0 -0
  56. package/{services → types/services}/user-ratings.service.d.ts +0 -0
  57. package/{vars.d.ts → types/vars.d.ts} +0 -0
  58. package/index.js +0 -33
  59. package/services/creator.service.js +0 -32
package/README.md CHANGED
@@ -60,6 +60,8 @@ csfd.movie(535121).then((movie) => console.log(movie));
60
60
  colorRating: 'good',
61
61
  rating: 73,
62
62
  ratingCount: 6654,
63
+ photo: '//image.pmgstatic.com/cache/resized/w1326/files/images/film/photos/162/980/162980090_bbffbb.jpg',
64
+ trivia: ['Když Henry (Tory Kittles) se svým mladším bratrem...', 'Ve filmu se střídají...'],
63
65
  titlesOther: [
64
66
  { country: 'USA', title: 'Dragged Across Concrete' },
65
67
  { country: 'Kanada', title: 'Dragged Across Concrete' },
@@ -372,7 +374,8 @@ _Note: You can not use both parameters 'includesOnly' and 'excludes'. Parameter
372
374
  - [x] Premieres
373
375
  - [x] Related movies
374
376
  - [x] Similar movies
375
- - [ ] All images
377
+ - [x] Trivia
378
+ - [x] Photo from movie (random)
376
379
  - [ ] Reviews
377
380
  - [ ] OST
378
381
  - [ ] Search
@@ -1,4 +1,13 @@
1
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
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
@@ -14,17 +23,17 @@ const USER_AGENTS = [
14
23
  const headers = {
15
24
  'User-Agent': USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)]
16
25
  };
17
- const fetchPage = async (url) => {
26
+ const fetchPage = (url) => __awaiter(void 0, void 0, void 0, function* () {
18
27
  try {
19
- const response = await (0, cross_fetch_1.default)(url, { headers });
28
+ const response = yield (0, cross_fetch_1.default)(url, { headers });
20
29
  if (response.status >= 400 && response.status < 600) {
21
30
  throw new Error(`node-csfd-api: Bad response ${response.status} for url: ${url}`);
22
31
  }
23
- return await response.text();
32
+ return yield response.text();
24
33
  }
25
34
  catch (e) {
26
35
  console.error(e);
27
36
  return 'Error';
28
37
  }
29
- };
38
+ });
30
39
  exports.fetchPage = fetchPage;
File without changes
@@ -2,9 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseISO8601Duration = exports.addProtocol = exports.parseColor = exports.getColor = exports.parseIdFromUrl = void 0;
4
4
  const parseIdFromUrl = (url) => {
5
- const idSlug = url.split('/')[2];
6
- const id = idSlug.split('-')[0];
7
- return +id;
5
+ if (url) {
6
+ const idSlug = url === null || url === void 0 ? void 0 : url.split('/')[2];
7
+ const id = idSlug === null || idSlug === void 0 ? void 0 : idSlug.split('-')[0];
8
+ return +id || null;
9
+ }
10
+ else {
11
+ return null;
12
+ }
8
13
  };
9
14
  exports.parseIdFromUrl = parseIdFromUrl;
10
15
  const getColor = (cls) => {
@@ -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.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;
3
+ exports.getTags = exports.getPremieres = exports.getBoxMovies = exports.getBoxContent = exports.getVods = exports.getType = exports.getGroup = exports.parsePeople = exports.getDescriptions = exports.getTrivia = exports.getRandomPhoto = 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;
@@ -125,6 +125,28 @@ const getPoster = (el) => {
125
125
  }
126
126
  };
127
127
  exports.getPoster = getPoster;
128
+ const getRandomPhoto = (el) => {
129
+ var _a;
130
+ const imageNode = el.querySelector('.gallery-item picture img');
131
+ const image = (_a = imageNode === null || imageNode === void 0 ? void 0 : imageNode.attributes) === null || _a === void 0 ? void 0 : _a.src;
132
+ if (image) {
133
+ return image.replace(/\/w663\//, '/w1326/');
134
+ }
135
+ else {
136
+ return null;
137
+ }
138
+ };
139
+ exports.getRandomPhoto = getRandomPhoto;
140
+ const getTrivia = (el) => {
141
+ const triviaNodes = el.querySelectorAll('.article-trivia ul li');
142
+ if (triviaNodes === null || triviaNodes === void 0 ? void 0 : triviaNodes.length) {
143
+ return triviaNodes.map((node) => node.textContent.trim().replace(/(\r\n|\n|\r|\t)/gm, ''));
144
+ }
145
+ else {
146
+ return null;
147
+ }
148
+ };
149
+ exports.getTrivia = getTrivia;
128
150
  const getDescriptions = (el) => {
129
151
  return el
130
152
  .querySelectorAll('.body--plots .plot-full p, .body--plots .plots .plots-item p')
File without changes
File without changes
File without changes
package/cjs/index.js ADDED
@@ -0,0 +1,50 @@
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.csfd = exports.Csfd = void 0;
13
+ const creator_service_1 = require("./services/creator.service");
14
+ const movie_service_1 = require("./services/movie.service");
15
+ const search_service_1 = require("./services/search.service");
16
+ const user_ratings_service_1 = require("./services/user-ratings.service");
17
+ class Csfd {
18
+ constructor(userRatingsService, movieService, creatorService, searchService) {
19
+ this.userRatingsService = userRatingsService;
20
+ this.movieService = movieService;
21
+ this.creatorService = creatorService;
22
+ this.searchService = searchService;
23
+ }
24
+ userRatings(user, config) {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ return this.userRatingsService.userRatings(user, config);
27
+ });
28
+ }
29
+ movie(movie) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ return this.movieService.movie(+movie);
32
+ });
33
+ }
34
+ creator(creator) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ return this.creatorService.creator(+creator);
37
+ });
38
+ }
39
+ search(text) {
40
+ return __awaiter(this, void 0, void 0, function* () {
41
+ return this.searchService.search(text);
42
+ });
43
+ }
44
+ }
45
+ exports.Csfd = Csfd;
46
+ const movieScraper = new movie_service_1.MovieScraper();
47
+ const userRatingsScraper = new user_ratings_service_1.UserRatingsScraper();
48
+ const creatorScraper = new creator_service_1.CreatorScraper();
49
+ const searchScraper = new search_service_1.SearchScraper();
50
+ exports.csfd = new Csfd(userRatingsScraper, movieScraper, creatorScraper, searchScraper);
File without changes
@@ -0,0 +1,43 @@
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.CreatorScraper = void 0;
13
+ const node_html_parser_1 = require("node-html-parser");
14
+ const fetchers_1 = require("../fetchers");
15
+ const creator_helper_1 = require("../helpers/creator.helper");
16
+ const vars_1 = require("../vars");
17
+ class CreatorScraper {
18
+ creator(creatorId) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const url = (0, vars_1.creatorUrl)(+creatorId);
21
+ const response = yield (0, fetchers_1.fetchPage)(url);
22
+ const creatorHtml = (0, node_html_parser_1.parse)(response);
23
+ const asideNode = creatorHtml.querySelector('.creator-about');
24
+ const filmsNode = creatorHtml.querySelector('.creator-filmography');
25
+ this.buildCreator(+creatorId, asideNode, filmsNode);
26
+ return this.person;
27
+ });
28
+ }
29
+ buildCreator(id, asideEl, filmsNode) {
30
+ var _a, _b, _c;
31
+ this.person = {
32
+ id,
33
+ name: (0, creator_helper_1.getName)(asideEl),
34
+ birthday: (_a = (0, creator_helper_1.getBirthdayInfo)(asideEl)) === null || _a === void 0 ? void 0 : _a.birthday,
35
+ birthplace: (_b = (0, creator_helper_1.getBirthdayInfo)(asideEl)) === null || _b === void 0 ? void 0 : _b.birthPlace,
36
+ photo: (0, creator_helper_1.getPhoto)(asideEl),
37
+ age: ((_c = (0, creator_helper_1.getBirthdayInfo)(asideEl)) === null || _c === void 0 ? void 0 : _c.age) || null,
38
+ bio: (0, creator_helper_1.getBio)(asideEl),
39
+ films: (0, creator_helper_1.getFilms)(filmsNode)
40
+ };
41
+ }
42
+ }
43
+ exports.CreatorScraper = CreatorScraper;
@@ -1,4 +1,13 @@
1
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
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.MovieScraper = void 0;
4
13
  const node_html_parser_1 = require("node-html-parser");
@@ -6,16 +15,18 @@ const fetchers_1 = require("../fetchers");
6
15
  const movie_helper_1 = require("../helpers/movie.helper");
7
16
  const vars_1 = require("../vars");
8
17
  class MovieScraper {
9
- async movie(movieId) {
10
- const url = (0, vars_1.movieUrl)(+movieId);
11
- const response = await (0, fetchers_1.fetchPage)(url);
12
- const movieHtml = (0, node_html_parser_1.parse)(response);
13
- const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');
14
- const asideNode = movieHtml.querySelector('.aside-movie-profile');
15
- const movieNode = movieHtml.querySelector('.main-movie-profile');
16
- const jsonLd = movieHtml.querySelector('script[type="application/ld+json"]').innerText;
17
- this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd);
18
- return this.film;
18
+ movie(movieId) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const url = (0, vars_1.movieUrl)(+movieId);
21
+ const response = yield (0, fetchers_1.fetchPage)(url);
22
+ const movieHtml = (0, node_html_parser_1.parse)(response);
23
+ const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');
24
+ const asideNode = movieHtml.querySelector('.aside-movie-profile');
25
+ const movieNode = movieHtml.querySelector('.main-movie-profile');
26
+ const jsonLd = movieHtml.querySelector('script[type="application/ld+json"]').innerText;
27
+ this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd);
28
+ return this.film;
29
+ });
19
30
  }
20
31
  buildMovie(movieId, el, asideEl, pageClasses, jsonLd) {
21
32
  this.film = {
@@ -33,6 +44,8 @@ class MovieScraper {
33
44
  ratingCount: (0, movie_helper_1.getRatingCount)(asideEl),
34
45
  titlesOther: (0, movie_helper_1.getTitlesOther)(el),
35
46
  poster: (0, movie_helper_1.getPoster)(el),
47
+ photo: (0, movie_helper_1.getRandomPhoto)(el),
48
+ trivia: (0, movie_helper_1.getTrivia)(el),
36
49
  creators: {
37
50
  directors: (0, movie_helper_1.getGroup)(el, 'Režie'),
38
51
  writers: (0, movie_helper_1.getGroup)(el, 'Scénář'),
@@ -1,4 +1,13 @@
1
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
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.SearchScraper = void 0;
4
13
  const node_html_parser_1 = require("node-html-parser");
@@ -8,13 +17,15 @@ const search_user_helper_1 = require("../helpers/search-user.helper");
8
17
  const search_helper_1 = require("../helpers/search.helper");
9
18
  const vars_1 = require("../vars");
10
19
  class SearchScraper {
11
- async search(text) {
12
- const url = (0, vars_1.searchUrl)(text);
13
- const response = await (0, fetchers_1.fetchPage)(url);
14
- const html = (0, node_html_parser_1.parse)(response);
15
- const moviesNode = html.querySelectorAll('.main-movies article');
16
- const usersNode = html.querySelectorAll('.main-users article');
17
- return this.parseSearch(moviesNode, usersNode);
20
+ search(text) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const url = (0, vars_1.searchUrl)(text);
23
+ const response = yield (0, fetchers_1.fetchPage)(url);
24
+ const html = (0, node_html_parser_1.parse)(response);
25
+ const moviesNode = html.querySelectorAll('.main-movies article');
26
+ const usersNode = html.querySelectorAll('.main-users article');
27
+ return this.parseSearch(moviesNode, usersNode);
28
+ });
18
29
  }
19
30
  parseSearch(moviesNode, usersNode) {
20
31
  const movies = [];
@@ -1,4 +1,13 @@
1
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
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.UserRatingsScraper = void 0;
4
13
  const node_html_parser_1 = require("node-html-parser");
@@ -9,34 +18,36 @@ class UserRatingsScraper {
9
18
  constructor() {
10
19
  this.films = [];
11
20
  }
12
- async userRatings(user, config) {
13
- let allMovies = [];
14
- const url = (0, vars_1.userRatingsUrl)(user);
15
- const response = await (0, fetchers_1.fetchPage)(url);
16
- const items = (0, node_html_parser_1.parse)(response);
17
- const movies = items.querySelectorAll('.box-user-rating .table-container tbody tr');
18
- // Get number of pages
19
- const pagesNode = items.querySelector('.pagination');
20
- const pages = +(pagesNode === null || pagesNode === void 0 ? void 0 : pagesNode.childNodes[pagesNode.childNodes.length - 4].rawText) || 1;
21
- allMovies = this.getPage(config, movies);
22
- if (config === null || config === void 0 ? void 0 : config.allPages) {
23
- console.log('User', user, url);
24
- console.log('Fetching all pages', pages);
25
- for (let i = 2; i <= pages; i++) {
26
- console.log('Fetching page', i, 'out of', pages, '...');
27
- const url = (0, vars_1.userRatingsUrl)(user, i);
28
- const response = await (0, fetchers_1.fetchPage)(url);
29
- const items = (0, node_html_parser_1.parse)(response);
30
- const movies = items.querySelectorAll('.box-user-rating .table-container tbody tr');
31
- allMovies = [...this.getPage(config, movies)];
32
- // Sleep
33
- if (config.allPagesDelay) {
34
- await (0, user_ratings_helper_1.sleep)(config.allPagesDelay);
21
+ userRatings(user, config) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ let allMovies = [];
24
+ const url = (0, vars_1.userRatingsUrl)(user);
25
+ const response = yield (0, fetchers_1.fetchPage)(url);
26
+ const items = (0, node_html_parser_1.parse)(response);
27
+ const movies = items.querySelectorAll('.box-user-rating .table-container tbody tr');
28
+ // Get number of pages
29
+ const pagesNode = items.querySelector('.pagination');
30
+ const pages = +(pagesNode === null || pagesNode === void 0 ? void 0 : pagesNode.childNodes[pagesNode.childNodes.length - 4].rawText) || 1;
31
+ allMovies = this.getPage(config, movies);
32
+ if (config === null || config === void 0 ? void 0 : config.allPages) {
33
+ console.log('User', user, url);
34
+ console.log('Fetching all pages', pages);
35
+ for (let i = 2; i <= pages; i++) {
36
+ console.log('Fetching page', i, 'out of', pages, '...');
37
+ const url = (0, vars_1.userRatingsUrl)(user, i);
38
+ const response = yield (0, fetchers_1.fetchPage)(url);
39
+ const items = (0, node_html_parser_1.parse)(response);
40
+ const movies = items.querySelectorAll('.box-user-rating .table-container tbody tr');
41
+ allMovies = [...this.getPage(config, movies)];
42
+ // Sleep
43
+ if (config.allPagesDelay) {
44
+ yield (0, user_ratings_helper_1.sleep)(config.allPagesDelay);
45
+ }
35
46
  }
47
+ return allMovies;
36
48
  }
37
49
  return allMovies;
38
- }
39
- return allMovies;
50
+ });
40
51
  }
41
52
  getPage(config, movies) {
42
53
  var _a, _b, _c, _d;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.searchUrl = 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
- const movieUrl = (movie) => `https://www.csfd.cz/film/${encodeURIComponent(movie)}`;
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;
@@ -0,0 +1,32 @@
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 fetch from 'cross-fetch';
11
+ const USER_AGENTS = [
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
+ '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',
14
+ 'Mozilla/5.0 (Linux; Android 10; SM-A205U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Mobile Safari/537.36',
15
+ 'Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Mobile Safari/537.36'
16
+ ];
17
+ const headers = {
18
+ 'User-Agent': USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)]
19
+ };
20
+ export const fetchPage = (url) => __awaiter(void 0, void 0, void 0, function* () {
21
+ try {
22
+ const response = yield fetch(url, { headers });
23
+ if (response.status >= 400 && response.status < 600) {
24
+ throw new Error(`node-csfd-api: Bad response ${response.status} for url: ${url}`);
25
+ }
26
+ return yield response.text();
27
+ }
28
+ catch (e) {
29
+ console.error(e);
30
+ return 'Error';
31
+ }
32
+ });
@@ -0,0 +1,72 @@
1
+ import { addProtocol, 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 getBirthdayInfo = (el) => {
15
+ const text = el.querySelector('h1 + p').innerHTML.trim();
16
+ const parts = text.split('\n');
17
+ let birthday;
18
+ let age;
19
+ let birthPlace;
20
+ if (parts.length) {
21
+ const birthdayRow = parts.find((x) => x.includes('nar.'));
22
+ const ageRow = parts.find((x) => x.includes('let)'));
23
+ const birthPlaceRow = parts.find((x) => x.includes('<br>')); // Ugly but there is no other way to detect
24
+ birthday = birthdayRow ? parseBirthday(birthdayRow) : '';
25
+ age = ageRow ? +parseAge(ageRow) : null;
26
+ birthPlace = birthPlaceRow ? parseBirthPlace(birthPlaceRow) : '';
27
+ }
28
+ return { birthday, age, birthPlace };
29
+ };
30
+ export const getBio = (el) => {
31
+ return el.querySelector('.article-content p').text.trim().split('\n')[0].trim();
32
+ };
33
+ export const getPhoto = (el) => {
34
+ const image = el.querySelector('img').attributes.src;
35
+ return addProtocol(image);
36
+ };
37
+ export const parseBirthday = (text) => {
38
+ return text.replace(/nar./g, '').trim();
39
+ };
40
+ export const parseAge = (text) => {
41
+ return text.trim().replace(/\(/g, '').replace(/let\)/g, '').trim();
42
+ };
43
+ export const parseBirthPlace = (text) => {
44
+ return text.trim().replace(/<br>/g, '').trim();
45
+ };
46
+ export const getFilms = (el) => {
47
+ const filmNodes = el.querySelectorAll('.box:first-of-type table tr');
48
+ let yearCache;
49
+ const films = filmNodes.map((filmNode) => {
50
+ var _a, _b, _c;
51
+ const id = getId((_a = filmNode.querySelector('td.name .film-title-name')) === null || _a === void 0 ? void 0 : _a.attributes.href);
52
+ const title = (_b = filmNode.querySelector('.name')) === null || _b === void 0 ? void 0 : _b.text.trim();
53
+ const year = +((_c = filmNode.querySelector('.year')) === null || _c === void 0 ? void 0 : _c.text.trim());
54
+ const colorRating = getColorRating(filmNode.querySelector('.name .icon'));
55
+ // Cache year from previous film because there is a gap between movies with same year
56
+ if (year) {
57
+ yearCache = +year;
58
+ }
59
+ if (id && title) {
60
+ return {
61
+ id,
62
+ title,
63
+ year: year || yearCache,
64
+ colorRating
65
+ };
66
+ }
67
+ return {};
68
+ });
69
+ // Remove empty objects
70
+ const filmsUnique = films.filter((value) => Object.keys(value).length !== 0);
71
+ return filmsUnique;
72
+ };
@@ -0,0 +1,56 @@
1
+ export const parseIdFromUrl = (url) => {
2
+ if (url) {
3
+ const idSlug = url === null || url === void 0 ? void 0 : url.split('/')[2];
4
+ const id = idSlug === null || idSlug === void 0 ? void 0 : idSlug.split('-')[0];
5
+ return +id || null;
6
+ }
7
+ else {
8
+ return null;
9
+ }
10
+ };
11
+ export const getColor = (cls) => {
12
+ switch (cls) {
13
+ case 'page-lightgrey':
14
+ return 'unknown';
15
+ case 'page-red':
16
+ return 'good';
17
+ case 'page-blue':
18
+ return 'average';
19
+ case 'page-grey':
20
+ return 'bad';
21
+ default:
22
+ return 'unknown';
23
+ }
24
+ };
25
+ export const parseColor = (quality) => {
26
+ switch (quality) {
27
+ case 'lightgrey':
28
+ return 'unknown';
29
+ case 'red':
30
+ return 'good';
31
+ case 'blue':
32
+ return 'average';
33
+ case 'grey':
34
+ return 'bad';
35
+ default:
36
+ return 'unknown';
37
+ }
38
+ };
39
+ export const addProtocol = (url) => {
40
+ return url.startsWith('//') ? 'https:' + url : url;
41
+ };
42
+ export const parseISO8601Duration = (iso) => {
43
+ const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
44
+ const matches = iso.match(iso8601DurationRegex);
45
+ const duration = {
46
+ sign: matches[1] === undefined ? '+' : '-',
47
+ years: matches[2] === undefined ? 0 : matches[2],
48
+ months: matches[3] === undefined ? 0 : matches[3],
49
+ weeks: matches[4] === undefined ? 0 : matches[4],
50
+ days: matches[5] === undefined ? 0 : matches[5],
51
+ hours: matches[6] === undefined ? 0 : matches[6],
52
+ minutes: matches[7] === undefined ? 0 : matches[7],
53
+ seconds: matches[8] === undefined ? 0 : matches[8]
54
+ };
55
+ return +duration.minutes;
56
+ };