node-csfd-api 3.0.0-next.16 → 3.0.0-next.18
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 +34 -38
- package/cjs/fetchers/fetch.polyfill.js +9 -0
- package/cjs/fetchers/index.js +2 -7
- package/cjs/helpers/cinema.helper.js +1 -8
- package/cjs/helpers/global.helper.js +9 -5
- package/cjs/services/cinema.service.js +2 -3
- package/cjs/vars.js +1 -1
- package/esm/fetchers/fetch.polyfill.js +6 -0
- package/esm/fetchers/index.js +1 -6
- package/esm/helpers/cinema.helper.js +0 -6
- package/esm/helpers/global.helper.js +7 -4
- package/esm/services/cinema.service.js +3 -4
- package/esm/vars.js +1 -1
- package/package.json +9 -6
- package/types/fetchers/fetch.polyfill.d.ts +1 -0
- package/types/helpers/cinema.helper.d.ts +2 -3
- package/types/helpers/global.helper.d.ts +10 -0
- package/types/index.ts +1 -0
- package/types/interfaces/cinema.interface.d.ts +1 -7
- package/types/services/cinema.service.d.ts +2 -2
- package/types/vars.d.ts +1 -2
package/README.md
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
[](https://github.com/bartholomej/node-csfd-api/actions)
|
|
4
4
|
[](https://codecov.io/gh/bartholomej/node-csfd-api)
|
|
5
5
|
|
|
6
|
-
# CSFD API
|
|
6
|
+
# CSFD API 🎥 2024
|
|
7
7
|
|
|
8
8
|
> JavaScript NPM library for scraping **Czech Movie Database (csfd.cz)**
|
|
9
9
|
>
|
|
10
10
|
> - JavaScript / TypeScript
|
|
11
11
|
> - Browser + Node.js (SSR)
|
|
12
12
|
> - Tested (~100% Code coverage)
|
|
13
|
-
> - ✅ Ready for new ČSFD
|
|
13
|
+
> - ✅ Ready for new ČSFD 2024!
|
|
14
14
|
> - You can use in:
|
|
15
15
|
> - Firebase function
|
|
16
16
|
> - AWS λ (lambda function)
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
> - React native app
|
|
20
20
|
> - Browsers (Pay attention to CORS)
|
|
21
21
|
|
|
22
|
-
## Install
|
|
22
|
+
## 🗜️ Install
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
npm install node-csfd-api
|
|
25
|
+
npm install node-csfd-api
|
|
26
26
|
# yarn add node-csfd-api
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
## Usage and examples
|
|
29
|
+
## 🛠️ Usage and examples
|
|
30
30
|
|
|
31
31
|
- [Movies and TV Series](#Movie)
|
|
32
32
|
- [User Ratings](#User-Ratings)
|
|
@@ -35,7 +35,7 @@ npm install node-csfd-api --save
|
|
|
35
35
|
|
|
36
36
|
### Movie
|
|
37
37
|
|
|
38
|
-
Get info about [this movie](https://www.csfd.cz/film/535121-na-spatne-strane/komentare/) _(id: 535121)_
|
|
38
|
+
> Get info about [this movie](https://www.csfd.cz/film/535121-na-spatne-strane/komentare/) _(id: 535121)_
|
|
39
39
|
|
|
40
40
|
```javascript
|
|
41
41
|
import { csfd } from 'node-csfd-api';
|
|
@@ -43,8 +43,9 @@ import { csfd } from 'node-csfd-api';
|
|
|
43
43
|
csfd.movie(535121).then((movie) => console.log(movie));
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
<details>
|
|
47
|
+
<summary>Click here to see full result example</summary>
|
|
48
|
+
|
|
48
49
|
```javascript
|
|
49
50
|
{
|
|
50
51
|
id: 535121,
|
|
@@ -136,6 +137,7 @@ csfd.movie(535121).then((movie) => console.log(movie));
|
|
|
136
137
|
]
|
|
137
138
|
}
|
|
138
139
|
```
|
|
140
|
+
</details>
|
|
139
141
|
|
|
140
142
|
### Search
|
|
141
143
|
|
|
@@ -147,10 +149,11 @@ import { csfd } from 'node-csfd-api';
|
|
|
147
149
|
csfd.search('bart').then((search) => console.log(search));
|
|
148
150
|
```
|
|
149
151
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
<details>
|
|
153
|
+
<summary>Click here to see full result example</summary>
|
|
154
|
+
|
|
152
155
|
```javascript
|
|
153
|
-
|
|
156
|
+
[
|
|
154
157
|
{
|
|
155
158
|
id: 19653,
|
|
156
159
|
title: 'Black Bart',
|
|
@@ -198,6 +201,8 @@ users: [
|
|
|
198
201
|
]
|
|
199
202
|
```
|
|
200
203
|
|
|
204
|
+
</details>
|
|
205
|
+
|
|
201
206
|
### Creators
|
|
202
207
|
|
|
203
208
|
> Get creator info + filmography
|
|
@@ -208,7 +213,8 @@ import { csfd } from 'node-csfd-api';
|
|
|
208
213
|
csfd.creator(2120).then((creator) => console.log(creator));
|
|
209
214
|
```
|
|
210
215
|
|
|
211
|
-
|
|
216
|
+
<details>
|
|
217
|
+
<summary>Click here to see full result example</summary>
|
|
212
218
|
|
|
213
219
|
```javascript
|
|
214
220
|
{
|
|
@@ -285,6 +291,8 @@ csfd.creator(2120).then((creator) => console.log(creator));
|
|
|
285
291
|
}
|
|
286
292
|
```
|
|
287
293
|
|
|
294
|
+
</details>
|
|
295
|
+
|
|
288
296
|
### User Ratings
|
|
289
297
|
|
|
290
298
|
#### Last ratings (last page)
|
|
@@ -314,7 +322,8 @@ csfd
|
|
|
314
322
|
.then((ratings) => console.log(ratings));
|
|
315
323
|
```
|
|
316
324
|
|
|
317
|
-
|
|
325
|
+
<details>
|
|
326
|
+
<summary>Click here to see full result example</summary>
|
|
318
327
|
|
|
319
328
|
```javascript
|
|
320
329
|
[
|
|
@@ -339,7 +348,9 @@ csfd
|
|
|
339
348
|
];
|
|
340
349
|
```
|
|
341
350
|
|
|
342
|
-
|
|
351
|
+
</details>
|
|
352
|
+
|
|
353
|
+
#### Options for user ratings
|
|
343
354
|
|
|
344
355
|
| Option | Type | Default | Description |
|
|
345
356
|
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------ |
|
|
@@ -348,9 +359,9 @@ csfd
|
|
|
348
359
|
| **allPages** | boolean | false | Get all pages |
|
|
349
360
|
| **allPagesDelay** | number | 0 | Delay on each page request. In milliseconds |
|
|
350
361
|
|
|
351
|
-
_Note: You can not use both parameters
|
|
362
|
+
_Note: You can not use both parameters `includesOnly` and `excludes`. Parameter `includesOnly` has a priority._
|
|
352
363
|
|
|
353
|
-
## Used by
|
|
364
|
+
## 🧑💻 Used by
|
|
354
365
|
|
|
355
366
|
### Web extensions
|
|
356
367
|
|
|
@@ -364,9 +375,9 @@ _Note: You can not use both parameters 'includesOnly' and 'excludes'. Parameter
|
|
|
364
375
|
|
|
365
376
|
### Mobile applications
|
|
366
377
|
|
|
367
|
-
- KinoKlub – Mobile application for AeroFilms (React Native: Android + iOS application)
|
|
378
|
+
- [KinoKlub](https://play.google.com/store/apps/details?id=com.aquasoup) – Mobile application for AeroFilms (React Native: Android + iOS application)
|
|
368
379
|
|
|
369
|
-
## Roadmap
|
|
380
|
+
## 🔮 Roadmap
|
|
370
381
|
|
|
371
382
|
### Scraping more pages
|
|
372
383
|
|
|
@@ -414,7 +425,7 @@ _Note: You can not use both parameters 'includesOnly' and 'excludes'. Parameter
|
|
|
414
425
|
- [x] Last ratings
|
|
415
426
|
- [x] All pages
|
|
416
427
|
|
|
417
|
-
## Development
|
|
428
|
+
## 🛠️ Development
|
|
418
429
|
|
|
419
430
|
### Developing and debugging library
|
|
420
431
|
|
|
@@ -430,22 +441,7 @@ You can find and modify it in [`./demo.ts`](https://github.com/bartholomej/node-
|
|
|
430
441
|
yarn demo
|
|
431
442
|
```
|
|
432
443
|
|
|
433
|
-
##
|
|
434
|
-
|
|
435
|
-
### Publish Stable
|
|
436
|
-
|
|
437
|
-
```shell
|
|
438
|
-
yarn release:patch
|
|
439
|
-
# yarn release:minor
|
|
440
|
-
# yarn release:major
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
### Publish next channel
|
|
444
|
-
|
|
445
|
-
1. Bump version `-beta.0` in `package.json`
|
|
446
|
-
2. `yarn release:beta`
|
|
447
|
-
|
|
448
|
-
## Contribution
|
|
444
|
+
## 🤝 Contribution
|
|
449
445
|
|
|
450
446
|
I welcome you to customize this according to your needs ;)
|
|
451
447
|
|
|
@@ -457,7 +453,7 @@ Give a ⭐️ if this project helped you!
|
|
|
457
453
|
|
|
458
454
|
Or if you are brave enough consider [making a donation](https://github.com/sponsors/bartholomej) for some 🍺 or 🍵 ;)
|
|
459
455
|
|
|
460
|
-
## Privacy Policy
|
|
456
|
+
## 🕵️♀️ Privacy Policy
|
|
461
457
|
|
|
462
458
|
I DO NOT STORE ANY DATA. PERIOD.
|
|
463
459
|
|
|
@@ -465,9 +461,9 @@ I physically can't. I have nowhere to store it. I don't even have a server datab
|
|
|
465
461
|
|
|
466
462
|
That's why, with node-csfd-api, what happens on your device stays on your device till disappear.
|
|
467
463
|
|
|
468
|
-
## License
|
|
464
|
+
## 📝 License
|
|
469
465
|
|
|
470
|
-
Copyright © 2020 –
|
|
466
|
+
Copyright © 2020 – 2024 [Lukas Bartak](http://bartweb.cz)
|
|
471
467
|
|
|
472
468
|
Proudly powered by nature 🗻, wind 💨, tea 🍵 and beer 🍺 ;)
|
|
473
469
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchSafe = void 0;
|
|
4
|
+
// Check if `fetch` is available in global scope (nodejs 18+) or in window (browser). If not, use cross-fetch polyfill.
|
|
5
|
+
const cross_fetch_1 = require("cross-fetch");
|
|
6
|
+
exports.fetchSafe = (typeof fetch === 'function' && fetch) || // ServiceWorker fetch (Cloud Functions + Chrome extension)
|
|
7
|
+
(typeof global === 'object' && global.fetch) || // Node.js 18+ fetch
|
|
8
|
+
(typeof window !== 'undefined' && window.fetch) || // Browser fetch
|
|
9
|
+
cross_fetch_1.fetch; // Polyfill fetch
|
package/cjs/fetchers/index.js
CHANGED
|
@@ -10,12 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.fetchPage = void 0;
|
|
13
|
-
|
|
14
|
-
const cross_fetch_1 = require("cross-fetch");
|
|
15
|
-
const fetchSafe = (typeof fetch === 'function' && fetch) || // ServiceWorker fetch (Cloud Functions + Chrome extension)
|
|
16
|
-
(typeof global === 'object' && global.fetch) || // Node.js 18+ fetch
|
|
17
|
-
(typeof window !== 'undefined' && window.fetch) || // Browser fetch
|
|
18
|
-
cross_fetch_1.fetch; // Polyfill fetch
|
|
13
|
+
const fetch_polyfill_1 = require("./fetch.polyfill");
|
|
19
14
|
const USER_AGENTS = [
|
|
20
15
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
|
|
21
16
|
'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',
|
|
@@ -27,7 +22,7 @@ const headers = {
|
|
|
27
22
|
};
|
|
28
23
|
const fetchPage = (url) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
24
|
try {
|
|
30
|
-
const response = yield fetchSafe(url, { headers });
|
|
25
|
+
const response = yield (0, fetch_polyfill_1.fetchSafe)(url, { headers });
|
|
31
26
|
if (response.status >= 400 && response.status < 600) {
|
|
32
27
|
throw new Error(`node-csfd-api: Bad response ${response.status} for url: ${url}`);
|
|
33
28
|
}
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
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.
|
|
3
|
+
exports.parseMeta = exports.getFilms = exports.getGroupedFilmsByDate = exports.parseCinema = exports.getCinemaUrl = exports.getCoords = exports.getName = exports.getId = exports.getColorRating = void 0;
|
|
4
4
|
const global_helper_1 = require("./global.helper");
|
|
5
5
|
const getColorRating = (el) => {
|
|
6
6
|
return (0, global_helper_1.parseColor)(el === null || el === void 0 ? void 0 : el.classNames.split(' ').pop());
|
|
7
7
|
};
|
|
8
8
|
exports.getColorRating = getColorRating;
|
|
9
|
-
const getCinemaId = (el) => {
|
|
10
|
-
var _a;
|
|
11
|
-
const id = (_a = el === null || el === void 0 ? void 0 : el.id) === null || _a === void 0 ? void 0 : _a.split('-')[1];
|
|
12
|
-
console.log('id', id);
|
|
13
|
-
return +id;
|
|
14
|
-
};
|
|
15
|
-
exports.getCinemaId = getCinemaId;
|
|
16
9
|
const getId = (url) => {
|
|
17
10
|
if (url) {
|
|
18
11
|
return (0, global_helper_1.parseIdFromUrl)(url);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseISO8601Duration = exports.addProtocol = exports.parseColor = exports.getColor = exports.parseIdFromUrl = void 0;
|
|
3
|
+
exports.parseISO8601Duration = exports.getDuration = exports.addProtocol = exports.parseColor = exports.getColor = exports.parseIdFromUrl = void 0;
|
|
4
4
|
const parseIdFromUrl = (url) => {
|
|
5
5
|
if (url) {
|
|
6
6
|
const idSlug = url === null || url === void 0 ? void 0 : url.split('/')[2];
|
|
@@ -46,10 +46,8 @@ const addProtocol = (url) => {
|
|
|
46
46
|
return url.startsWith('//') ? 'https:' + url : url;
|
|
47
47
|
};
|
|
48
48
|
exports.addProtocol = addProtocol;
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const matches = iso.match(iso8601DurationRegex);
|
|
52
|
-
const duration = {
|
|
49
|
+
const getDuration = (matches) => {
|
|
50
|
+
return {
|
|
53
51
|
sign: matches[1] === undefined ? '+' : '-',
|
|
54
52
|
years: matches[2] === undefined ? 0 : matches[2],
|
|
55
53
|
months: matches[3] === undefined ? 0 : matches[3],
|
|
@@ -59,6 +57,12 @@ const parseISO8601Duration = (iso) => {
|
|
|
59
57
|
minutes: matches[7] === undefined ? 0 : matches[7],
|
|
60
58
|
seconds: matches[8] === undefined ? 0 : matches[8]
|
|
61
59
|
};
|
|
60
|
+
};
|
|
61
|
+
exports.getDuration = getDuration;
|
|
62
|
+
const parseISO8601Duration = (iso) => {
|
|
63
|
+
const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
|
|
64
|
+
const matches = iso.match(iso8601DurationRegex);
|
|
65
|
+
const duration = (0, exports.getDuration)(matches);
|
|
62
66
|
return +duration.minutes;
|
|
63
67
|
};
|
|
64
68
|
exports.parseISO8601Duration = parseISO8601Duration;
|
|
@@ -15,9 +15,9 @@ const fetchers_1 = require("../fetchers");
|
|
|
15
15
|
const vars_1 = require("../vars");
|
|
16
16
|
const cinema_helper_1 = require("./../helpers/cinema.helper");
|
|
17
17
|
class CinemaScraper {
|
|
18
|
-
cinemas(district
|
|
18
|
+
cinemas(district) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
const url = (0, vars_1.cinemasUrl)(district,
|
|
20
|
+
const url = (0, vars_1.cinemasUrl)(district, 'week');
|
|
21
21
|
const response = yield (0, fetchers_1.fetchPage)(url);
|
|
22
22
|
const cinemasHtml = (0, node_html_parser_1.parse)(response);
|
|
23
23
|
const contentNode = cinemasHtml.querySelectorAll('#snippet--cinemas section.box');
|
|
@@ -30,7 +30,6 @@ class CinemaScraper {
|
|
|
30
30
|
contentNode.map((x) => {
|
|
31
31
|
var _a, _b;
|
|
32
32
|
const cinema = {
|
|
33
|
-
id: (0, cinema_helper_1.getCinemaId)(x),
|
|
34
33
|
name: (_a = (0, cinema_helper_1.parseCinema)(x)) === null || _a === void 0 ? void 0 : _a.name,
|
|
35
34
|
city: (_b = (0, cinema_helper_1.parseCinema)(x)) === null || _b === void 0 ? void 0 : _b.city,
|
|
36
35
|
url: (0, cinema_helper_1.getCinemaUrl)(x),
|
package/cjs/vars.js
CHANGED
|
@@ -7,7 +7,7 @@ const movieUrl = (movie) => `https://www.csfd.cz/film/${encodeURIComponent(movie
|
|
|
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, period) => {
|
|
10
|
+
const cinemasUrl = (district = 1, period = 'today') => {
|
|
11
11
|
return `https://www.csfd.cz/kino/?period=${period}&district=${district}`;
|
|
12
12
|
};
|
|
13
13
|
exports.cinemasUrl = cinemasUrl;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Check if `fetch` is available in global scope (nodejs 18+) or in window (browser). If not, use cross-fetch polyfill.
|
|
2
|
+
import { fetch as crossFetch } from 'cross-fetch';
|
|
3
|
+
export const fetchSafe = (typeof fetch === 'function' && fetch) || // ServiceWorker fetch (Cloud Functions + Chrome extension)
|
|
4
|
+
(typeof global === 'object' && global.fetch) || // Node.js 18+ fetch
|
|
5
|
+
(typeof window !== 'undefined' && window.fetch) || // Browser fetch
|
|
6
|
+
crossFetch; // Polyfill fetch
|
package/esm/fetchers/index.js
CHANGED
|
@@ -7,12 +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
|
-
|
|
11
|
-
import { fetch as crossFetch } from 'cross-fetch';
|
|
12
|
-
const fetchSafe = (typeof fetch === 'function' && fetch) || // ServiceWorker fetch (Cloud Functions + Chrome extension)
|
|
13
|
-
(typeof global === 'object' && global.fetch) || // Node.js 18+ fetch
|
|
14
|
-
(typeof window !== 'undefined' && window.fetch) || // Browser fetch
|
|
15
|
-
crossFetch; // Polyfill fetch
|
|
10
|
+
import { fetchSafe } from './fetch.polyfill';
|
|
16
11
|
const USER_AGENTS = [
|
|
17
12
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
|
|
18
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',
|
|
@@ -2,12 +2,6 @@ import { parseColor, parseIdFromUrl } from './global.helper';
|
|
|
2
2
|
export const getColorRating = (el) => {
|
|
3
3
|
return parseColor(el === null || el === void 0 ? void 0 : el.classNames.split(' ').pop());
|
|
4
4
|
};
|
|
5
|
-
export const getCinemaId = (el) => {
|
|
6
|
-
var _a;
|
|
7
|
-
const id = (_a = el === null || el === void 0 ? void 0 : el.id) === null || _a === void 0 ? void 0 : _a.split('-')[1];
|
|
8
|
-
console.log('id', id);
|
|
9
|
-
return +id;
|
|
10
|
-
};
|
|
11
5
|
export const getId = (url) => {
|
|
12
6
|
if (url) {
|
|
13
7
|
return parseIdFromUrl(url);
|
|
@@ -39,10 +39,8 @@ export const parseColor = (quality) => {
|
|
|
39
39
|
export const addProtocol = (url) => {
|
|
40
40
|
return url.startsWith('//') ? 'https:' + url : url;
|
|
41
41
|
};
|
|
42
|
-
export const
|
|
43
|
-
|
|
44
|
-
const matches = iso.match(iso8601DurationRegex);
|
|
45
|
-
const duration = {
|
|
42
|
+
export const getDuration = (matches) => {
|
|
43
|
+
return {
|
|
46
44
|
sign: matches[1] === undefined ? '+' : '-',
|
|
47
45
|
years: matches[2] === undefined ? 0 : matches[2],
|
|
48
46
|
months: matches[3] === undefined ? 0 : matches[3],
|
|
@@ -52,5 +50,10 @@ export const parseISO8601Duration = (iso) => {
|
|
|
52
50
|
minutes: matches[7] === undefined ? 0 : matches[7],
|
|
53
51
|
seconds: matches[8] === undefined ? 0 : matches[8]
|
|
54
52
|
};
|
|
53
|
+
};
|
|
54
|
+
export const parseISO8601Duration = (iso) => {
|
|
55
|
+
const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
|
|
56
|
+
const matches = iso.match(iso8601DurationRegex);
|
|
57
|
+
const duration = getDuration(matches);
|
|
55
58
|
return +duration.minutes;
|
|
56
59
|
};
|
|
@@ -10,11 +10,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { parse } from 'node-html-parser';
|
|
11
11
|
import { fetchPage } from '../fetchers';
|
|
12
12
|
import { cinemasUrl } from '../vars';
|
|
13
|
-
import {
|
|
13
|
+
import { getCinemaUrl, getCoords, getGroupedFilmsByDate, parseCinema } from './../helpers/cinema.helper';
|
|
14
14
|
export class CinemaScraper {
|
|
15
|
-
cinemas(district
|
|
15
|
+
cinemas(district) {
|
|
16
16
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
const url = cinemasUrl(district,
|
|
17
|
+
const url = cinemasUrl(district, 'week');
|
|
18
18
|
const response = yield fetchPage(url);
|
|
19
19
|
const cinemasHtml = parse(response);
|
|
20
20
|
const contentNode = cinemasHtml.querySelectorAll('#snippet--cinemas section.box');
|
|
@@ -27,7 +27,6 @@ export class CinemaScraper {
|
|
|
27
27
|
contentNode.map((x) => {
|
|
28
28
|
var _a, _b;
|
|
29
29
|
const cinema = {
|
|
30
|
-
id: getCinemaId(x),
|
|
31
30
|
name: (_a = parseCinema(x)) === null || _a === void 0 ? void 0 : _a.name,
|
|
32
31
|
city: (_b = parseCinema(x)) === null || _b === void 0 ? void 0 : _b.city,
|
|
33
32
|
url: getCinemaUrl(x),
|
package/esm/vars.js
CHANGED
|
@@ -1,7 +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, period) => {
|
|
4
|
+
export const cinemasUrl = (district = 1, period = 'today') => {
|
|
5
5
|
return `https://www.csfd.cz/kino/?period=${period}&district=${district}`;
|
|
6
6
|
};
|
|
7
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.18",
|
|
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>",
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
"barrels": "barrelsby --delete -c barrels.json",
|
|
12
12
|
"postbuild": "npm-prepare-dist -s postinstall -s prepare && yarn fix-paths",
|
|
13
13
|
"tsc": "tsc",
|
|
14
|
-
"demo": "
|
|
14
|
+
"demo": "tsx demo",
|
|
15
15
|
"lint": "eslint ./src/**/**/* --fix",
|
|
16
16
|
"test": "vitest",
|
|
17
17
|
"test:coverage": "yarn test run --coverage",
|
|
18
|
-
"fix-paths": "yarn json -I -f ./dist/package.json -e \"this.module='./esm/index.js';this.main='./cjs/index.js';this.types='./
|
|
18
|
+
"fix-paths": "yarn json -I -f ./dist/package.json -e \"this.module='./esm/index.js';this.main='./cjs/index.js';this.types='./cjs/index.d.ts'\"",
|
|
19
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 β\"",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"registry": "https://registry.npmjs.org"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"cross-fetch": "^
|
|
33
|
-
"node-html-parser": "^6.1.
|
|
32
|
+
"cross-fetch": "^4.0.0",
|
|
33
|
+
"node-html-parser": "^6.1.12"
|
|
34
34
|
},
|
|
35
35
|
"repository": {
|
|
36
36
|
"url": "git+https://github.com/bartholomej/node-csfd-api.git",
|
|
@@ -57,6 +57,9 @@
|
|
|
57
57
|
"node": ">= 14"
|
|
58
58
|
},
|
|
59
59
|
"license": "MIT",
|
|
60
|
+
"lint-staged": {
|
|
61
|
+
"*.ts": "eslint --cache --fix"
|
|
62
|
+
},
|
|
60
63
|
"module": "./esm/index.js",
|
|
61
|
-
"types": "./
|
|
64
|
+
"types": "./cjs/index.d.ts"
|
|
62
65
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const fetchSafe: typeof fetch;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CSFDCinemaMeta, CSFDCinemaMovie } from 'interfaces/cinema.interface';
|
|
2
2
|
import { HTMLElement } from 'node-html-parser';
|
|
3
3
|
import { CSFDColorRating } from '../interfaces/global';
|
|
4
4
|
export declare const getColorRating: (el: HTMLElement) => CSFDColorRating;
|
|
5
|
-
export declare const getCinemaId: (el: HTMLElement | null) => number;
|
|
6
5
|
export declare const getId: (url: string) => number;
|
|
7
6
|
export declare const getName: (el: HTMLElement | null) => string;
|
|
8
7
|
export declare const getCoords: (el: HTMLElement | null) => {
|
|
@@ -14,6 +13,6 @@ export declare const parseCinema: (el: HTMLElement | null) => {
|
|
|
14
13
|
city: string;
|
|
15
14
|
name: string;
|
|
16
15
|
};
|
|
17
|
-
export declare const getGroupedFilmsByDate: (el: HTMLElement | null) =>
|
|
16
|
+
export declare const getGroupedFilmsByDate: (el: HTMLElement | null) => any;
|
|
18
17
|
export declare const getFilms: (date: string, el: HTMLElement | null) => CSFDCinemaMovie[];
|
|
19
18
|
export declare const parseMeta: (meta: string[]) => CSFDCinemaMeta[];
|
|
@@ -4,4 +4,14 @@ export declare const parseIdFromUrl: (url: string) => number;
|
|
|
4
4
|
export declare const getColor: (cls: string) => CSFDColorRating;
|
|
5
5
|
export declare const parseColor: (quality: Colors) => CSFDColorRating;
|
|
6
6
|
export declare const addProtocol: (url: string) => string;
|
|
7
|
+
export declare const getDuration: (matches: any[]) => {
|
|
8
|
+
sign: string;
|
|
9
|
+
years: any;
|
|
10
|
+
months: any;
|
|
11
|
+
weeks: any;
|
|
12
|
+
days: any;
|
|
13
|
+
hours: any;
|
|
14
|
+
minutes: any;
|
|
15
|
+
seconds: any;
|
|
16
|
+
};
|
|
7
17
|
export declare const parseISO8601Duration: (iso: string) => number;
|
package/types/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CSFDMovieListItem } from './movie.interface';
|
|
2
2
|
export interface CSFDCinema {
|
|
3
|
-
id: number;
|
|
4
3
|
name: string;
|
|
5
4
|
city: string;
|
|
6
5
|
url: string;
|
|
@@ -9,15 +8,10 @@ export interface CSFDCinema {
|
|
|
9
8
|
lng: number;
|
|
10
9
|
};
|
|
11
10
|
region?: string;
|
|
12
|
-
screenings:
|
|
13
|
-
}
|
|
14
|
-
export interface CSFDCinemaGroupedFilmsByDate {
|
|
15
|
-
date: string;
|
|
16
|
-
films: CSFDCinemaMovie[];
|
|
11
|
+
screenings: CSFDCinemaMovie[];
|
|
17
12
|
}
|
|
18
13
|
export interface CSFDCinemaMovie extends CSFDMovieListItem {
|
|
19
14
|
meta: CSFDCinemaMeta[];
|
|
20
15
|
showTimes: string[];
|
|
21
16
|
}
|
|
22
17
|
export type CSFDCinemaMeta = 'dubbing' | '3D' | 'subtitles' | string;
|
|
23
|
-
export type CSFDCinemaPeriod = 'today' | 'weekend' | 'week' | 'tomorrow' | 'month';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CSFDCinema
|
|
1
|
+
import { CSFDCinema } from '../interfaces/cinema.interface';
|
|
2
2
|
export declare class CinemaScraper {
|
|
3
3
|
private cinema;
|
|
4
|
-
cinemas(district
|
|
4
|
+
cinemas(district: number): Promise<CSFDCinema[]>;
|
|
5
5
|
private buildCinemas;
|
|
6
6
|
}
|
package/types/vars.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { CSFDCinemaPeriod } from 'interfaces/cinema.interface';
|
|
2
1
|
export declare const userRatingsUrl: (user: string | number, page?: number) => string;
|
|
3
2
|
export declare const movieUrl: (movie: number) => string;
|
|
4
3
|
export declare const creatorUrl: (creator: number | string) => string;
|
|
5
|
-
export declare const cinemasUrl: (district
|
|
4
|
+
export declare const cinemasUrl: (district?: number | string, period?: 'today' | 'weekend' | 'week' | 'tomorrow' | 'month') => string;
|
|
6
5
|
export declare const searchUrl: (text: string) => string;
|