node-csfd-api 3.0.0-next.10 → 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/README.md CHANGED
@@ -7,16 +7,17 @@
7
7
 
8
8
  > JavaScript NPM library for scraping **Czech Movie Database (csfd.cz)**
9
9
  >
10
- > - Browser + Node.js (SSR)
11
10
  > - JavaScript / TypeScript
11
+ > - Browser + Node.js (SSR)
12
12
  > - Tested (~100% Code coverage)
13
13
  > - ✅ Ready for new ČSFD 2021!
14
14
  > - You can use in:
15
15
  > - Firebase function
16
16
  > - AWS λ (lambda function)
17
+ > - CloudFlare Worker
17
18
  > - Chrome extension
18
19
  > - React native app
19
- > - ...
20
+ > - Browsers (Pay attention to CORS)
20
21
 
21
22
  ## Install
22
23
 
@@ -138,7 +139,7 @@ csfd.movie(535121).then((movie) => console.log(movie));
138
139
 
139
140
  ### Search
140
141
 
141
- > Search movies and users
142
+ > Search movies, users and TV series
142
143
 
143
144
  ```javascript
144
145
  import { csfd } from 'node-csfd-api';
@@ -199,7 +200,7 @@ users: [
199
200
 
200
201
  ### Creators
201
202
 
202
- > Search creators and filmography
203
+ > Get creator info + filmography
203
204
 
204
205
  ```javascript
205
206
  import { csfd } from 'node-csfd-api';
@@ -351,9 +352,19 @@ _Note: You can not use both parameters 'includesOnly' and 'excludes'. Parameter
351
352
 
352
353
  ## Used by
353
354
 
354
- - [Dafilms web extension](https://chrome.google.com/webstore/detail/dafilms/hgcgneddmgflnbmhkjnefiobjgobbmdm?hl=en) ([code](https://github.com/bartholomej/dafilms-ext)) – Parser for film ratings (web extension)
355
- - [bartweb.cz](https://bartweb.cz) – **Last seen** section (Firebase function)
356
- - KinoKlub Mobile application for AeroFilms (native Android + iOS application)
355
+ ### Web extensions
356
+
357
+ - [Netflix: chrome extension](https://chrome.google.com/webstore/detail/netflix-csfd/eomgekccbddnlpmehgdjmlphndjgnlni) ([code](https://github.com/bartholomej/netflix-csfd-ext))
358
+ - [Dafilms: chrome extension](https://chrome.google.com/webstore/detail/dafilms/hgcgneddmgflnbmhkjnefiobjgobbmdm) ([code](https://github.com/bartholomej/dafilms-ext))
359
+ - [Kviff.tv: chrome extension](https://chrome.google.com/webstore/detail/kvifftv-%20-csfd/ihpngekoejodiligajlppbeedofhnmfm) ([code](https://github.com/bartholomej/kviff-ext))
360
+
361
+ ### Web applications
362
+
363
+ - [bartweb.cz](https://bartweb.cz) – **Last seen** section (**Firebase function**)
364
+
365
+ ### Mobile applications
366
+
367
+ - KinoKlub – Mobile application for AeroFilms (React Native: Android + iOS application)
357
368
 
358
369
  ## Roadmap
359
370
 
@@ -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 = +(ratingRaw === null || ratingRaw === void 0 ? void 0 : ratingRaw.replace(/%/g, '').trim());
32
- if (Number.isInteger(rating)) {
33
- return rating;
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
- return namesNode.map((el) => {
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,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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, parseIdFromUrl, parseISO8601Duration } from './global.helper';
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 = +(ratingRaw === null || ratingRaw === void 0 ? void 0 : ratingRaw.replace(/%/g, '').trim());
24
- if (Number.isInteger(rating)) {
25
- return rating;
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
- return namesNode.map((el) => {
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 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -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.10",
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>",
@@ -8,15 +8,15 @@
8
8
  "start": "tsc -w",
9
9
  "prebuild": "rimraf dist",
10
10
  "build": "tsc && tsc -p tsconfig-cjs.json && yarn barrels",
11
- "barrels": "barrelsby -c barrels.json",
12
- "postbuild": "npm-prepare-dist -s postinstall -s prepare && yarn delete:unused-folders && yarn fix-paths",
11
+ "barrels": "barrelsby --delete -c barrels.json",
12
+ "postbuild": "npm-prepare-dist -s postinstall -s prepare && yarn fix-paths",
13
13
  "tsc": "tsc",
14
14
  "demo": "ts-node demo",
15
15
  "lint": "eslint ./src/**/**/* --fix",
16
- "test": "jest",
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
- "delete:unused-folders": "rimraf ./dist/esm/interfaces ./dist/cjs/interfaces",
19
- "publish:next": "yarn && yarn build && yarn test --coverage true && cd dist && npm publish --tag next",
19
+ "publish:next": "yarn && yarn build && yarn test:coverage && cd dist && npm publish --tag next",
20
20
  "postversion": "git push && git push --follow-tags",
21
21
  "release:beta": "npm version preminor --preid=beta -m \"chore(update): prelease %s β\"",
22
22
  "prerelease:beta": "npm version prerelease --preid=beta -m \"chore(update): prelease %s β\"",
@@ -29,8 +29,8 @@
29
29
  "registry": "https://registry.npmjs.org"
30
30
  },
31
31
  "dependencies": {
32
- "cross-fetch": "^3.1.5",
33
- "node-html-parser": "^6.1.4"
32
+ "cross-fetch": "^3.1.6",
33
+ "node-html-parser": "^6.1.5"
34
34
  },
35
35
  "repository": {
36
36
  "url": "git+https://github.com/bartholomej/node-csfd-api.git",
@@ -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
- constructor(userRatingsService: UserRatingsScraper, movieService: MovieScraper, creatorService: CreatorScraper, searchService: SearchScraper);
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;
@@ -0,0 +1,6 @@
1
+ import { CSFDCinema } from '../interfaces/cinema.interface';
2
+ export declare class CinemaScraper {
3
+ private cinema;
4
+ cinemas(district: number): Promise<CSFDCinema[]>;
5
+ private buildCinemas;
6
+ }
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;