node-csfd-api 5.3.0 → 5.5.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.
- package/bin/{export-ratings.mjs → export-ratings.js} +1 -1
- package/bin/{mcp-server.mjs → mcp-server.js} +2 -2
- package/bin/{server.mjs → server.js} +2 -2
- package/{cli.mjs → cli.js} +3 -3
- package/dto/{cinema.d.mts → cinema.d.cts} +2 -2
- package/dto/{creator.d.mts → creator.d.cts} +2 -2
- package/dto/{global.d.mts → global.d.cts} +1 -1
- package/dto/{movie.d.mts → movie.d.cts} +2 -2
- package/dto/{options.d.mts → options.d.cts} +1 -1
- package/dto/{search.d.mts → search.d.cts} +3 -3
- package/dto/{user-ratings.d.mts → user-ratings.d.cts} +2 -2
- package/dto/{user-reviews.d.mts → user-reviews.d.cts} +2 -2
- package/fetchers/{fetch.polyfill.mjs → fetch.polyfill.cjs} +3 -4
- package/fetchers/fetch.polyfill.cjs.map +1 -0
- package/fetchers/fetch.polyfill.js +2 -3
- package/fetchers/fetch.polyfill.js.map +1 -1
- package/fetchers/index.cjs +75 -0
- package/fetchers/index.cjs.map +1 -0
- package/fetchers/index.js +56 -12
- package/fetchers/index.js.map +1 -1
- package/helpers/cinema.helper.cjs +83 -0
- package/helpers/cinema.helper.cjs.map +1 -0
- package/helpers/cinema.helper.js +4 -8
- package/helpers/cinema.helper.js.map +1 -1
- package/helpers/creator.helper.cjs +72 -0
- package/helpers/creator.helper.cjs.map +1 -0
- package/helpers/creator.helper.js +6 -10
- package/helpers/creator.helper.js.map +1 -1
- package/helpers/global.helper.cjs +109 -0
- package/helpers/{global.helper.mjs.map → global.helper.cjs.map} +1 -1
- package/helpers/global.helper.js +1 -9
- package/helpers/movie.helper.cjs +324 -0
- package/helpers/movie.helper.cjs.map +1 -0
- package/helpers/movie.helper.js +12 -35
- package/helpers/movie.helper.js.map +1 -1
- package/helpers/search-creator.helper.cjs +18 -0
- package/helpers/search-creator.helper.cjs.map +1 -0
- package/helpers/search-creator.helper.js +3 -5
- package/helpers/search-creator.helper.js.map +1 -1
- package/helpers/search-user.helper.cjs +26 -0
- package/helpers/search-user.helper.cjs.map +1 -0
- package/helpers/search-user.helper.js +5 -8
- package/helpers/search-user.helper.js.map +1 -1
- package/helpers/search.helper.cjs +52 -0
- package/helpers/search.helper.cjs.map +1 -0
- package/helpers/search.helper.js +6 -13
- package/helpers/search.helper.js.map +1 -1
- package/helpers/user-ratings.helper.cjs +41 -0
- package/helpers/user-ratings.helper.cjs.map +1 -0
- package/helpers/user-ratings.helper.js +6 -13
- package/helpers/user-ratings.helper.js.map +1 -1
- package/helpers/user-reviews.helper.cjs +56 -0
- package/helpers/user-reviews.helper.cjs.map +1 -0
- package/helpers/user-reviews.helper.js +6 -15
- package/helpers/user-reviews.helper.js.map +1 -1
- package/index.cjs +64 -0
- package/index.cjs.map +1 -0
- package/{index.d.mts → index.d.cts} +15 -15
- package/index.js +13 -14
- package/index.js.map +1 -1
- package/{package.mjs → package.js} +1 -1
- package/package.json +13 -7
- package/services/cinema.service.cjs +31 -0
- package/services/cinema.service.cjs.map +1 -0
- package/services/{cinema.service.d.mts → cinema.service.d.cts} +3 -3
- package/services/cinema.service.js +11 -11
- package/services/cinema.service.js.map +1 -1
- package/services/creator.service.cjs +32 -0
- package/services/creator.service.cjs.map +1 -0
- package/services/{creator.service.d.mts → creator.service.d.cts} +3 -3
- package/services/creator.service.js +11 -11
- package/services/creator.service.js.map +1 -1
- package/services/movie.service.cjs +61 -0
- package/services/movie.service.cjs.map +1 -0
- package/services/{movie.service.d.mts → movie.service.d.cts} +3 -3
- package/services/movie.service.js +33 -33
- package/services/movie.service.js.map +1 -1
- package/services/search.service.cjs +75 -0
- package/services/search.service.cjs.map +1 -0
- package/services/{search.service.d.mts → search.service.d.cts} +3 -3
- package/services/search.service.js +29 -29
- package/services/search.service.js.map +1 -1
- package/services/user-ratings.service.cjs +65 -0
- package/services/user-ratings.service.cjs.map +1 -0
- package/services/{user-ratings.service.d.mts → user-ratings.service.d.cts} +3 -3
- package/services/user-ratings.service.js +18 -18
- package/services/user-ratings.service.js.map +1 -1
- package/services/user-reviews.service.cjs +67 -0
- package/services/user-reviews.service.cjs.map +1 -0
- package/services/{user-reviews.service.d.mts → user-reviews.service.d.cts} +3 -3
- package/services/user-reviews.service.js +20 -20
- package/services/user-reviews.service.js.map +1 -1
- package/src/fetchers/fetch.polyfill.js +6 -0
- package/src/fetchers/index.js +76 -0
- package/{helpers/cinema.helper.mjs → src/helpers/cinema.helper.js} +5 -4
- package/{helpers/creator.helper.mjs → src/helpers/creator.helper.js} +5 -4
- package/{helpers/global.helper.mjs → src/helpers/global.helper.js} +3 -3
- package/{helpers/movie.helper.mjs → src/helpers/movie.helper.js} +5 -4
- package/{helpers/search-creator.helper.mjs → src/helpers/search-creator.helper.js} +5 -4
- package/{helpers/search-user.helper.mjs → src/helpers/search-user.helper.js} +5 -4
- package/{helpers/search.helper.mjs → src/helpers/search.helper.js} +5 -4
- package/{helpers/user-ratings.helper.mjs → src/helpers/user-ratings.helper.js} +5 -4
- package/{helpers/user-reviews.helper.mjs → src/helpers/user-reviews.helper.js} +5 -4
- package/{index.mjs → src/index.js} +14 -10
- package/{services/cinema.service.mjs → src/services/cinema.service.js} +7 -6
- package/{services/creator.service.mjs → src/services/creator.service.js} +7 -6
- package/{services/movie.service.mjs → src/services/movie.service.js} +7 -6
- package/{services/search.service.mjs → src/services/search.service.js} +10 -9
- package/{services/user-ratings.service.mjs → src/services/user-ratings.service.js} +8 -7
- package/{services/user-reviews.service.mjs → src/services/user-reviews.service.js} +8 -7
- package/{vars.mjs → src/vars.js} +3 -3
- package/vars.cjs +28 -0
- package/{vars.mjs.map → vars.cjs.map} +1 -1
- package/vars.js +1 -7
- package/fetchers/fetch.polyfill.mjs.map +0 -1
- package/fetchers/index.mjs +0 -31
- package/fetchers/index.mjs.map +0 -1
- package/helpers/cinema.helper.mjs.map +0 -1
- package/helpers/creator.helper.mjs.map +0 -1
- package/helpers/movie.helper.mjs.map +0 -1
- package/helpers/search-creator.helper.mjs.map +0 -1
- package/helpers/search-user.helper.mjs.map +0 -1
- package/helpers/search.helper.mjs.map +0 -1
- package/helpers/user-ratings.helper.mjs.map +0 -1
- package/helpers/user-reviews.helper.mjs.map +0 -1
- package/index.mjs.map +0 -1
- package/services/cinema.service.mjs.map +0 -1
- package/services/creator.service.mjs.map +0 -1
- package/services/movie.service.mjs.map +0 -1
- package/services/search.service.mjs.map +0 -1
- package/services/user-ratings.service.mjs.map +0 -1
- package/services/user-reviews.service.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-ratings.service.js","names":[
|
|
1
|
+
{"version":3,"file":"user-ratings.service.js","names":[],"sources":["../../src/services/user-ratings.service.ts"],"sourcesContent":["import { HTMLElement, parse } from 'node-html-parser';\nimport { CSFDColorRating, CSFDFilmTypes, CSFDStars } from '../dto/global';\nimport { CSFDUserRatingConfig, CSFDUserRatings } from '../dto/user-ratings';\nimport { fetchPage } from '../fetchers';\nimport { sleep } from '../helpers/global.helper';\nimport {\n getUserRating,\n getUserRatingColorRating,\n getUserRatingDate,\n getUserRatingId,\n getUserRatingTitle,\n getUserRatingType,\n getUserRatingUrl,\n getUserRatingYear\n} from '../helpers/user-ratings.helper';\nimport { CSFDOptions } from '../types';\nimport { userRatingsUrl } from '../vars';\n\nexport class UserRatingsScraper {\n public async userRatings(\n user: string | number,\n config?: CSFDUserRatingConfig,\n options?: CSFDOptions\n ): Promise<CSFDUserRatings[]> {\n let allMovies: CSFDUserRatings[] = [];\n const pageToFetch = config?.page || 1;\n const url = userRatingsUrl(user, pageToFetch > 1 ? pageToFetch : undefined, {\n language: options?.language\n });\n const response = await fetchPage(url, { ...options?.request });\n const items = parse(response);\n const movies = items.querySelectorAll('#snippet--ratings table tr');\n\n // Get number of pages\n const pagesNode = items.querySelector('.pagination');\n const pages = +pagesNode?.childNodes[pagesNode.childNodes.length - 4].rawText || 1;\n\n allMovies = this.getPage(config, movies);\n\n if (config?.allPages) {\n console.log('User', user, url);\n console.log('Fetching all pages', pages);\n for (let i = 2; i <= pages; i++) {\n console.log('Fetching page', i, 'out of', pages, '...');\n const url = userRatingsUrl(user, i, { language: options?.language });\n const response = await fetchPage(url, { ...options?.request });\n\n const items = parse(response);\n const movies = items.querySelectorAll('#snippet--ratings table tr');\n allMovies = [...allMovies, ...this.getPage(config, movies)];\n\n // Sleep\n if (config.allPagesDelay) {\n await sleep(config.allPagesDelay);\n }\n }\n return allMovies;\n }\n\n return allMovies;\n }\n\n private getPage(config: CSFDUserRatingConfig, movies: HTMLElement[]) {\n const films: CSFDUserRatings[] = [];\n if (config) {\n if (config.includesOnly?.length && config.excludes?.length) {\n console.warn(\n `node-csfd-api:\n You can not use both parameters 'includesOnly' and 'excludes'.\n Parameter 'includesOnly' will be used now:`,\n config.includesOnly\n );\n }\n }\n\n const includesSet = config?.includesOnly?.length ? new Set(config.includesOnly) : null;\n const excludesSet = config?.excludes?.length ? new Set(config.excludes) : null;\n\n for (const el of movies) {\n const type = getUserRatingType(el);\n\n // Filtering includesOnly\n if (includesSet) {\n if (includesSet.has(type)) {\n films.push(this.buildUserRatings(el, type));\n }\n // Filter excludes\n } else if (excludesSet) {\n if (!excludesSet.has(type)) {\n films.push(this.buildUserRatings(el, type));\n }\n } else {\n // Without filtering\n films.push(this.buildUserRatings(el, type));\n }\n }\n return films;\n }\n\n private buildUserRatings(el: HTMLElement, type: CSFDFilmTypes): CSFDUserRatings {\n return {\n id: getUserRatingId(el),\n title: getUserRatingTitle(el),\n year: getUserRatingYear(el),\n type,\n url: getUserRatingUrl(el),\n colorRating: getUserRatingColorRating(el) as CSFDColorRating,\n userDate: getUserRatingDate(el),\n userRating: getUserRating(el) as CSFDStars\n };\n }\n}\n"],"mappings":";;;;;;AAkBA,IAAa,qBAAb,MAAgC;CAC9B,MAAa,YACX,MACA,QACA,SAC4B;EAC5B,IAAI,YAA+B,EAAE;EACrC,MAAM,cAAc,QAAQ,QAAQ;EACpC,MAAM,MAAM,eAAe,MAAM,cAAc,IAAI,cAAc,KAAA,GAAW,EAC1E,UAAU,SAAS,UACpB,CAAC;EAEF,MAAM,QAAQ,MADG,MAAM,UAAU,KAAK,EAAE,GAAG,SAAS,SAAS,CAAC,CACjC;EAC7B,MAAM,SAAS,MAAM,iBAAiB,6BAA6B;EAGnE,MAAM,YAAY,MAAM,cAAc,cAAc;EACpD,MAAM,QAAQ,CAAC,WAAW,WAAW,UAAU,WAAW,SAAS,GAAG,WAAW;AAEjF,cAAY,KAAK,QAAQ,QAAQ,OAAO;AAExC,MAAI,QAAQ,UAAU;AACpB,WAAQ,IAAI,QAAQ,MAAM,IAAI;AAC9B,WAAQ,IAAI,sBAAsB,MAAM;AACxC,QAAK,IAAI,IAAI,GAAG,KAAK,OAAO,KAAK;AAC/B,YAAQ,IAAI,iBAAiB,GAAG,UAAU,OAAO,MAAM;IAKvD,MAAM,SADQ,MAFG,MAAM,UADX,eAAe,MAAM,GAAG,EAAE,UAAU,SAAS,UAAU,CAAC,EAC9B,EAAE,GAAG,SAAS,SAAS,CAAC,CAEjC,CACR,iBAAiB,6BAA6B;AACnE,gBAAY,CAAC,GAAG,WAAW,GAAG,KAAK,QAAQ,QAAQ,OAAO,CAAC;AAG3D,QAAI,OAAO,cACT,OAAM,MAAM,OAAO,cAAc;;AAGrC,UAAO;;AAGT,SAAO;;CAGT,QAAgB,QAA8B,QAAuB;EACnE,MAAM,QAA2B,EAAE;AACnC,MAAI;OACE,OAAO,cAAc,UAAU,OAAO,UAAU,OAClD,SAAQ,KACN;;qDAGA,OAAO,aACR;;EAIL,MAAM,cAAc,QAAQ,cAAc,SAAS,IAAI,IAAI,OAAO,aAAa,GAAG;EAClF,MAAM,cAAc,QAAQ,UAAU,SAAS,IAAI,IAAI,OAAO,SAAS,GAAG;AAE1E,OAAK,MAAM,MAAM,QAAQ;GACvB,MAAM,OAAO,kBAAkB,GAAG;AAGlC,OAAI;QACE,YAAY,IAAI,KAAK,CACvB,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;cAGpC;QACL,CAAC,YAAY,IAAI,KAAK,CACxB,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;SAI7C,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;;AAG/C,SAAO;;CAGT,iBAAyB,IAAiB,MAAsC;AAC9E,SAAO;GACL,IAAI,gBAAgB,GAAG;GACvB,OAAO,mBAAmB,GAAG;GAC7B,MAAM,kBAAkB,GAAG;GAC3B;GACA,KAAK,iBAAiB,GAAG;GACzB,aAAa,yBAAyB,GAAG;GACzC,UAAU,kBAAkB,GAAG;GAC/B,YAAY,cAAc,GAAG;GAC9B"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const require_index = require("../fetchers/index.cjs");
|
|
2
|
+
const require_vars = require("../vars.cjs");
|
|
3
|
+
const require_global_helper = require("../helpers/global.helper.cjs");
|
|
4
|
+
const require_user_reviews_helper = require("../helpers/user-reviews.helper.cjs");
|
|
5
|
+
let node_html_parser = require("node-html-parser");
|
|
6
|
+
//#region src/services/user-reviews.service.ts
|
|
7
|
+
var UserReviewsScraper = class {
|
|
8
|
+
async userReviews(user, config, options) {
|
|
9
|
+
let allReviews = [];
|
|
10
|
+
const pageToFetch = config?.page || 1;
|
|
11
|
+
const url = require_vars.userReviewsUrl(user, pageToFetch > 1 ? pageToFetch : void 0, { language: options?.language });
|
|
12
|
+
const items = (0, node_html_parser.parse)(await require_index.fetchPage(url, { ...options?.request }));
|
|
13
|
+
const reviews = items.querySelectorAll(".user-tab-reviews .article");
|
|
14
|
+
const pagesNode = items.querySelector(".pagination");
|
|
15
|
+
const pages = +pagesNode?.childNodes[pagesNode.childNodes.length - 4].rawText || 1;
|
|
16
|
+
allReviews = this.getPage(config, reviews);
|
|
17
|
+
if (config?.allPages) {
|
|
18
|
+
console.log("User", user, url);
|
|
19
|
+
console.log("Fetching all pages", pages);
|
|
20
|
+
for (let i = 2; i <= pages; i++) {
|
|
21
|
+
console.log("Fetching page", i, "out of", pages, "...");
|
|
22
|
+
const reviews = (0, node_html_parser.parse)(await require_index.fetchPage(require_vars.userReviewsUrl(user, i, { language: options?.language }), { ...options?.request })).querySelectorAll(".user-tab-reviews .article");
|
|
23
|
+
allReviews = [...allReviews, ...this.getPage(config, reviews)];
|
|
24
|
+
if (config.allPagesDelay) await require_global_helper.sleep(config.allPagesDelay);
|
|
25
|
+
}
|
|
26
|
+
return allReviews;
|
|
27
|
+
}
|
|
28
|
+
return allReviews;
|
|
29
|
+
}
|
|
30
|
+
getPage(config, reviews) {
|
|
31
|
+
const films = [];
|
|
32
|
+
if (config) {
|
|
33
|
+
if (config.includesOnly?.length && config.excludes?.length) console.warn(`node-csfd-api:
|
|
34
|
+
You can not use both parameters 'includesOnly' and 'excludes'.
|
|
35
|
+
Parameter 'includesOnly' will be used now:`, config.includesOnly);
|
|
36
|
+
}
|
|
37
|
+
const includesSet = config?.includesOnly?.length ? new Set(config.includesOnly) : null;
|
|
38
|
+
const excludesSet = config?.excludes?.length ? new Set(config.excludes) : null;
|
|
39
|
+
for (const el of reviews) {
|
|
40
|
+
const type = require_user_reviews_helper.getUserReviewType(el);
|
|
41
|
+
if (includesSet) {
|
|
42
|
+
if (includesSet.has(type)) films.push(this.buildUserReviews(el, type));
|
|
43
|
+
} else if (excludesSet) {
|
|
44
|
+
if (!excludesSet.has(type)) films.push(this.buildUserReviews(el, type));
|
|
45
|
+
} else films.push(this.buildUserReviews(el, type));
|
|
46
|
+
}
|
|
47
|
+
return films;
|
|
48
|
+
}
|
|
49
|
+
buildUserReviews(el, type) {
|
|
50
|
+
return {
|
|
51
|
+
id: require_user_reviews_helper.getUserReviewId(el),
|
|
52
|
+
title: require_user_reviews_helper.getUserReviewTitle(el),
|
|
53
|
+
year: require_user_reviews_helper.getUserReviewYear(el),
|
|
54
|
+
type,
|
|
55
|
+
url: require_user_reviews_helper.getUserReviewUrl(el),
|
|
56
|
+
colorRating: require_user_reviews_helper.getUserReviewColorRating(el),
|
|
57
|
+
userDate: require_user_reviews_helper.getUserReviewDate(el),
|
|
58
|
+
userRating: require_user_reviews_helper.getUserReviewRating(el),
|
|
59
|
+
text: require_user_reviews_helper.getUserReviewText(el),
|
|
60
|
+
poster: require_user_reviews_helper.getUserReviewPoster(el)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
exports.UserReviewsScraper = UserReviewsScraper;
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=user-reviews.service.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-reviews.service.cjs","names":["userReviewsUrl","fetchPage","sleep","getUserReviewType","getUserReviewId","getUserReviewTitle","getUserReviewYear","getUserReviewUrl","getUserReviewColorRating","getUserReviewDate","getUserReviewRating","getUserReviewText","getUserReviewPoster"],"sources":["../../src/services/user-reviews.service.ts"],"sourcesContent":["import { HTMLElement, parse } from 'node-html-parser';\nimport { CSFDColorRating, CSFDFilmTypes, CSFDStars } from '../dto/global';\nimport { CSFDUserReviews, CSFDUserReviewsConfig } from '../dto/user-reviews';\nimport { fetchPage } from '../fetchers';\nimport { sleep } from '../helpers/global.helper';\nimport {\n getUserReviewColorRating,\n getUserReviewDate,\n getUserReviewId,\n getUserReviewPoster,\n getUserReviewRating,\n getUserReviewText,\n getUserReviewTitle,\n getUserReviewType,\n getUserReviewUrl,\n getUserReviewYear\n} from '../helpers/user-reviews.helper';\nimport { CSFDOptions } from '../types';\nimport { userReviewsUrl } from '../vars';\n\nexport class UserReviewsScraper {\n public async userReviews(\n user: string | number,\n config?: CSFDUserReviewsConfig,\n options?: CSFDOptions\n ): Promise<CSFDUserReviews[]> {\n let allReviews: CSFDUserReviews[] = [];\n const pageToFetch = config?.page || 1;\n const url = userReviewsUrl(user, pageToFetch > 1 ? pageToFetch : undefined, {\n language: options?.language\n });\n const response = await fetchPage(url, { ...options?.request });\n const items = parse(response);\n const reviews = items.querySelectorAll('.user-tab-reviews .article');\n\n // Get number of pages\n const pagesNode = items.querySelector('.pagination');\n const pages = +pagesNode?.childNodes[pagesNode.childNodes.length - 4].rawText || 1;\n\n allReviews = this.getPage(config, reviews);\n\n if (config?.allPages) {\n console.log('User', user, url);\n console.log('Fetching all pages', pages);\n for (let i = 2; i <= pages; i++) {\n console.log('Fetching page', i, 'out of', pages, '...');\n const url = userReviewsUrl(user, i, { language: options?.language });\n const response = await fetchPage(url, { ...options?.request });\n\n const items = parse(response);\n const reviews = items.querySelectorAll('.user-tab-reviews .article');\n allReviews = [...allReviews, ...this.getPage(config, reviews)];\n\n // Sleep\n if (config.allPagesDelay) {\n await sleep(config.allPagesDelay);\n }\n }\n return allReviews;\n }\n\n return allReviews;\n }\n\n private getPage(config: CSFDUserReviewsConfig, reviews: HTMLElement[]) {\n const films: CSFDUserReviews[] = [];\n if (config) {\n if (config.includesOnly?.length && config.excludes?.length) {\n console.warn(\n `node-csfd-api:\n You can not use both parameters 'includesOnly' and 'excludes'.\n Parameter 'includesOnly' will be used now:`,\n config.includesOnly\n );\n }\n }\n\n const includesSet = config?.includesOnly?.length ? new Set(config.includesOnly) : null;\n const excludesSet = config?.excludes?.length ? new Set(config.excludes) : null;\n\n for (const el of reviews) {\n const type = getUserReviewType(el);\n\n // Filtering includesOnly\n if (includesSet) {\n if (includesSet.has(type)) {\n films.push(this.buildUserReviews(el, type));\n }\n // Filter excludes\n } else if (excludesSet) {\n if (!excludesSet.has(type)) {\n films.push(this.buildUserReviews(el, type));\n }\n } else {\n // Without filtering\n films.push(this.buildUserReviews(el, type));\n }\n }\n return films;\n }\n\n private buildUserReviews(el: HTMLElement, type: CSFDFilmTypes): CSFDUserReviews {\n return {\n id: getUserReviewId(el),\n title: getUserReviewTitle(el),\n year: getUserReviewYear(el),\n type,\n url: getUserReviewUrl(el),\n colorRating: getUserReviewColorRating(el) as CSFDColorRating,\n userDate: getUserReviewDate(el),\n userRating: getUserReviewRating(el) as CSFDStars,\n text: getUserReviewText(el),\n poster: getUserReviewPoster(el)\n };\n }\n}\n"],"mappings":";;;;;;AAoBA,IAAa,qBAAb,MAAgC;CAC9B,MAAa,YACX,MACA,QACA,SAC4B;EAC5B,IAAI,aAAgC,EAAE;EACtC,MAAM,cAAc,QAAQ,QAAQ;EACpC,MAAM,MAAMA,aAAAA,eAAe,MAAM,cAAc,IAAI,cAAc,KAAA,GAAW,EAC1E,UAAU,SAAS,UACpB,CAAC;EAEF,MAAM,SAAA,GAAA,iBAAA,OADW,MAAMC,cAAAA,UAAU,KAAK,EAAE,GAAG,SAAS,SAAS,CAAC,CACjC;EAC7B,MAAM,UAAU,MAAM,iBAAiB,6BAA6B;EAGpE,MAAM,YAAY,MAAM,cAAc,cAAc;EACpD,MAAM,QAAQ,CAAC,WAAW,WAAW,UAAU,WAAW,SAAS,GAAG,WAAW;AAEjF,eAAa,KAAK,QAAQ,QAAQ,QAAQ;AAE1C,MAAI,QAAQ,UAAU;AACpB,WAAQ,IAAI,QAAQ,MAAM,IAAI;AAC9B,WAAQ,IAAI,sBAAsB,MAAM;AACxC,QAAK,IAAI,IAAI,GAAG,KAAK,OAAO,KAAK;AAC/B,YAAQ,IAAI,iBAAiB,GAAG,UAAU,OAAO,MAAM;IAKvD,MAAM,WAAA,GAAA,iBAAA,OAHW,MAAMA,cAAAA,UADXD,aAAAA,eAAe,MAAM,GAAG,EAAE,UAAU,SAAS,UAAU,CAAC,EAC9B,EAAE,GAAG,SAAS,SAAS,CAAC,CAEjC,CACP,iBAAiB,6BAA6B;AACpE,iBAAa,CAAC,GAAG,YAAY,GAAG,KAAK,QAAQ,QAAQ,QAAQ,CAAC;AAG9D,QAAI,OAAO,cACT,OAAME,sBAAAA,MAAM,OAAO,cAAc;;AAGrC,UAAO;;AAGT,SAAO;;CAGT,QAAgB,QAA+B,SAAwB;EACrE,MAAM,QAA2B,EAAE;AACnC,MAAI;OACE,OAAO,cAAc,UAAU,OAAO,UAAU,OAClD,SAAQ,KACN;;qDAGA,OAAO,aACR;;EAIL,MAAM,cAAc,QAAQ,cAAc,SAAS,IAAI,IAAI,OAAO,aAAa,GAAG;EAClF,MAAM,cAAc,QAAQ,UAAU,SAAS,IAAI,IAAI,OAAO,SAAS,GAAG;AAE1E,OAAK,MAAM,MAAM,SAAS;GACxB,MAAM,OAAOC,4BAAAA,kBAAkB,GAAG;AAGlC,OAAI;QACE,YAAY,IAAI,KAAK,CACvB,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;cAGpC;QACL,CAAC,YAAY,IAAI,KAAK,CACxB,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;SAI7C,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;;AAG/C,SAAO;;CAGT,iBAAyB,IAAiB,MAAsC;AAC9E,SAAO;GACL,IAAIC,4BAAAA,gBAAgB,GAAG;GACvB,OAAOC,4BAAAA,mBAAmB,GAAG;GAC7B,MAAMC,4BAAAA,kBAAkB,GAAG;GAC3B;GACA,KAAKC,4BAAAA,iBAAiB,GAAG;GACzB,aAAaC,4BAAAA,yBAAyB,GAAG;GACzC,UAAUC,4BAAAA,kBAAkB,GAAG;GAC/B,YAAYC,4BAAAA,oBAAoB,GAAG;GACnC,MAAMC,4BAAAA,kBAAkB,GAAG;GAC3B,QAAQC,4BAAAA,oBAAoB,GAAG;GAChC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CSFDUserReviews, CSFDUserReviewsConfig } from "../dto/user-reviews.
|
|
2
|
-
import { CSFDOptions } from "../dto/options.
|
|
1
|
+
import { CSFDUserReviews, CSFDUserReviewsConfig } from "../dto/user-reviews.cjs";
|
|
2
|
+
import { CSFDOptions } from "../dto/options.cjs";
|
|
3
3
|
|
|
4
4
|
//#region src/services/user-reviews.service.d.ts
|
|
5
5
|
declare class UserReviewsScraper {
|
|
@@ -9,4 +9,4 @@ declare class UserReviewsScraper {
|
|
|
9
9
|
}
|
|
10
10
|
//#endregion
|
|
11
11
|
export { UserReviewsScraper };
|
|
12
|
-
//# sourceMappingURL=user-reviews.service.d.
|
|
12
|
+
//# sourceMappingURL=user-reviews.service.d.cts.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { fetchPage } from "../fetchers/index.js";
|
|
2
|
+
import { userReviewsUrl } from "../vars.js";
|
|
3
|
+
import { sleep } from "../helpers/global.helper.js";
|
|
4
|
+
import { getUserReviewColorRating, getUserReviewDate, getUserReviewId, getUserReviewPoster, getUserReviewRating, getUserReviewText, getUserReviewTitle, getUserReviewType, getUserReviewUrl, getUserReviewYear } from "../helpers/user-reviews.helper.js";
|
|
5
|
+
import { parse } from "node-html-parser";
|
|
6
6
|
//#region src/services/user-reviews.service.ts
|
|
7
7
|
var UserReviewsScraper = class {
|
|
8
8
|
async userReviews(user, config, options) {
|
|
9
9
|
let allReviews = [];
|
|
10
10
|
const pageToFetch = config?.page || 1;
|
|
11
|
-
const url =
|
|
12
|
-
const items =
|
|
11
|
+
const url = userReviewsUrl(user, pageToFetch > 1 ? pageToFetch : void 0, { language: options?.language });
|
|
12
|
+
const items = parse(await fetchPage(url, { ...options?.request }));
|
|
13
13
|
const reviews = items.querySelectorAll(".user-tab-reviews .article");
|
|
14
14
|
const pagesNode = items.querySelector(".pagination");
|
|
15
15
|
const pages = +pagesNode?.childNodes[pagesNode.childNodes.length - 4].rawText || 1;
|
|
@@ -19,9 +19,9 @@ var UserReviewsScraper = class {
|
|
|
19
19
|
console.log("Fetching all pages", pages);
|
|
20
20
|
for (let i = 2; i <= pages; i++) {
|
|
21
21
|
console.log("Fetching page", i, "out of", pages, "...");
|
|
22
|
-
const reviews =
|
|
22
|
+
const reviews = parse(await fetchPage(userReviewsUrl(user, i, { language: options?.language }), { ...options?.request })).querySelectorAll(".user-tab-reviews .article");
|
|
23
23
|
allReviews = [...allReviews, ...this.getPage(config, reviews)];
|
|
24
|
-
if (config.allPagesDelay) await
|
|
24
|
+
if (config.allPagesDelay) await sleep(config.allPagesDelay);
|
|
25
25
|
}
|
|
26
26
|
return allReviews;
|
|
27
27
|
}
|
|
@@ -37,7 +37,7 @@ var UserReviewsScraper = class {
|
|
|
37
37
|
const includesSet = config?.includesOnly?.length ? new Set(config.includesOnly) : null;
|
|
38
38
|
const excludesSet = config?.excludes?.length ? new Set(config.excludes) : null;
|
|
39
39
|
for (const el of reviews) {
|
|
40
|
-
const type =
|
|
40
|
+
const type = getUserReviewType(el);
|
|
41
41
|
if (includesSet) {
|
|
42
42
|
if (includesSet.has(type)) films.push(this.buildUserReviews(el, type));
|
|
43
43
|
} else if (excludesSet) {
|
|
@@ -48,20 +48,20 @@ var UserReviewsScraper = class {
|
|
|
48
48
|
}
|
|
49
49
|
buildUserReviews(el, type) {
|
|
50
50
|
return {
|
|
51
|
-
id:
|
|
52
|
-
title:
|
|
53
|
-
year:
|
|
51
|
+
id: getUserReviewId(el),
|
|
52
|
+
title: getUserReviewTitle(el),
|
|
53
|
+
year: getUserReviewYear(el),
|
|
54
54
|
type,
|
|
55
|
-
url:
|
|
56
|
-
colorRating:
|
|
57
|
-
userDate:
|
|
58
|
-
userRating:
|
|
59
|
-
text:
|
|
60
|
-
poster:
|
|
55
|
+
url: getUserReviewUrl(el),
|
|
56
|
+
colorRating: getUserReviewColorRating(el),
|
|
57
|
+
userDate: getUserReviewDate(el),
|
|
58
|
+
userRating: getUserReviewRating(el),
|
|
59
|
+
text: getUserReviewText(el),
|
|
60
|
+
poster: getUserReviewPoster(el)
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
//#endregion
|
|
65
|
-
|
|
65
|
+
export { UserReviewsScraper };
|
|
66
66
|
|
|
67
67
|
//# sourceMappingURL=user-reviews.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-reviews.service.js","names":[
|
|
1
|
+
{"version":3,"file":"user-reviews.service.js","names":[],"sources":["../../src/services/user-reviews.service.ts"],"sourcesContent":["import { HTMLElement, parse } from 'node-html-parser';\nimport { CSFDColorRating, CSFDFilmTypes, CSFDStars } from '../dto/global';\nimport { CSFDUserReviews, CSFDUserReviewsConfig } from '../dto/user-reviews';\nimport { fetchPage } from '../fetchers';\nimport { sleep } from '../helpers/global.helper';\nimport {\n getUserReviewColorRating,\n getUserReviewDate,\n getUserReviewId,\n getUserReviewPoster,\n getUserReviewRating,\n getUserReviewText,\n getUserReviewTitle,\n getUserReviewType,\n getUserReviewUrl,\n getUserReviewYear\n} from '../helpers/user-reviews.helper';\nimport { CSFDOptions } from '../types';\nimport { userReviewsUrl } from '../vars';\n\nexport class UserReviewsScraper {\n public async userReviews(\n user: string | number,\n config?: CSFDUserReviewsConfig,\n options?: CSFDOptions\n ): Promise<CSFDUserReviews[]> {\n let allReviews: CSFDUserReviews[] = [];\n const pageToFetch = config?.page || 1;\n const url = userReviewsUrl(user, pageToFetch > 1 ? pageToFetch : undefined, {\n language: options?.language\n });\n const response = await fetchPage(url, { ...options?.request });\n const items = parse(response);\n const reviews = items.querySelectorAll('.user-tab-reviews .article');\n\n // Get number of pages\n const pagesNode = items.querySelector('.pagination');\n const pages = +pagesNode?.childNodes[pagesNode.childNodes.length - 4].rawText || 1;\n\n allReviews = this.getPage(config, reviews);\n\n if (config?.allPages) {\n console.log('User', user, url);\n console.log('Fetching all pages', pages);\n for (let i = 2; i <= pages; i++) {\n console.log('Fetching page', i, 'out of', pages, '...');\n const url = userReviewsUrl(user, i, { language: options?.language });\n const response = await fetchPage(url, { ...options?.request });\n\n const items = parse(response);\n const reviews = items.querySelectorAll('.user-tab-reviews .article');\n allReviews = [...allReviews, ...this.getPage(config, reviews)];\n\n // Sleep\n if (config.allPagesDelay) {\n await sleep(config.allPagesDelay);\n }\n }\n return allReviews;\n }\n\n return allReviews;\n }\n\n private getPage(config: CSFDUserReviewsConfig, reviews: HTMLElement[]) {\n const films: CSFDUserReviews[] = [];\n if (config) {\n if (config.includesOnly?.length && config.excludes?.length) {\n console.warn(\n `node-csfd-api:\n You can not use both parameters 'includesOnly' and 'excludes'.\n Parameter 'includesOnly' will be used now:`,\n config.includesOnly\n );\n }\n }\n\n const includesSet = config?.includesOnly?.length ? new Set(config.includesOnly) : null;\n const excludesSet = config?.excludes?.length ? new Set(config.excludes) : null;\n\n for (const el of reviews) {\n const type = getUserReviewType(el);\n\n // Filtering includesOnly\n if (includesSet) {\n if (includesSet.has(type)) {\n films.push(this.buildUserReviews(el, type));\n }\n // Filter excludes\n } else if (excludesSet) {\n if (!excludesSet.has(type)) {\n films.push(this.buildUserReviews(el, type));\n }\n } else {\n // Without filtering\n films.push(this.buildUserReviews(el, type));\n }\n }\n return films;\n }\n\n private buildUserReviews(el: HTMLElement, type: CSFDFilmTypes): CSFDUserReviews {\n return {\n id: getUserReviewId(el),\n title: getUserReviewTitle(el),\n year: getUserReviewYear(el),\n type,\n url: getUserReviewUrl(el),\n colorRating: getUserReviewColorRating(el) as CSFDColorRating,\n userDate: getUserReviewDate(el),\n userRating: getUserReviewRating(el) as CSFDStars,\n text: getUserReviewText(el),\n poster: getUserReviewPoster(el)\n };\n }\n}\n"],"mappings":";;;;;;AAoBA,IAAa,qBAAb,MAAgC;CAC9B,MAAa,YACX,MACA,QACA,SAC4B;EAC5B,IAAI,aAAgC,EAAE;EACtC,MAAM,cAAc,QAAQ,QAAQ;EACpC,MAAM,MAAM,eAAe,MAAM,cAAc,IAAI,cAAc,KAAA,GAAW,EAC1E,UAAU,SAAS,UACpB,CAAC;EAEF,MAAM,QAAQ,MADG,MAAM,UAAU,KAAK,EAAE,GAAG,SAAS,SAAS,CAAC,CACjC;EAC7B,MAAM,UAAU,MAAM,iBAAiB,6BAA6B;EAGpE,MAAM,YAAY,MAAM,cAAc,cAAc;EACpD,MAAM,QAAQ,CAAC,WAAW,WAAW,UAAU,WAAW,SAAS,GAAG,WAAW;AAEjF,eAAa,KAAK,QAAQ,QAAQ,QAAQ;AAE1C,MAAI,QAAQ,UAAU;AACpB,WAAQ,IAAI,QAAQ,MAAM,IAAI;AAC9B,WAAQ,IAAI,sBAAsB,MAAM;AACxC,QAAK,IAAI,IAAI,GAAG,KAAK,OAAO,KAAK;AAC/B,YAAQ,IAAI,iBAAiB,GAAG,UAAU,OAAO,MAAM;IAKvD,MAAM,UADQ,MAFG,MAAM,UADX,eAAe,MAAM,GAAG,EAAE,UAAU,SAAS,UAAU,CAAC,EAC9B,EAAE,GAAG,SAAS,SAAS,CAAC,CAEjC,CACP,iBAAiB,6BAA6B;AACpE,iBAAa,CAAC,GAAG,YAAY,GAAG,KAAK,QAAQ,QAAQ,QAAQ,CAAC;AAG9D,QAAI,OAAO,cACT,OAAM,MAAM,OAAO,cAAc;;AAGrC,UAAO;;AAGT,SAAO;;CAGT,QAAgB,QAA+B,SAAwB;EACrE,MAAM,QAA2B,EAAE;AACnC,MAAI;OACE,OAAO,cAAc,UAAU,OAAO,UAAU,OAClD,SAAQ,KACN;;qDAGA,OAAO,aACR;;EAIL,MAAM,cAAc,QAAQ,cAAc,SAAS,IAAI,IAAI,OAAO,aAAa,GAAG;EAClF,MAAM,cAAc,QAAQ,UAAU,SAAS,IAAI,IAAI,OAAO,SAAS,GAAG;AAE1E,OAAK,MAAM,MAAM,SAAS;GACxB,MAAM,OAAO,kBAAkB,GAAG;AAGlC,OAAI;QACE,YAAY,IAAI,KAAK,CACvB,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;cAGpC;QACL,CAAC,YAAY,IAAI,KAAK,CACxB,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;SAI7C,OAAM,KAAK,KAAK,iBAAiB,IAAI,KAAK,CAAC;;AAG/C,SAAO;;CAGT,iBAAyB,IAAiB,MAAsC;AAC9E,SAAO;GACL,IAAI,gBAAgB,GAAG;GACvB,OAAO,mBAAmB,GAAG;GAC7B,MAAM,kBAAkB,GAAG;GAC3B;GACA,KAAK,iBAAiB,GAAG;GACzB,aAAa,yBAAyB,GAAG;GACzC,UAAU,kBAAkB,GAAG;GAC/B,YAAY,oBAAoB,GAAG;GACnC,MAAM,kBAAkB,GAAG;GAC3B,QAAQ,oBAAoB,GAAG;GAChC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fetchSafe } from "./fetch.polyfill.js";
|
|
3
|
+
|
|
4
|
+
//#region src/fetchers/index.ts
|
|
5
|
+
const browserProfiles = [
|
|
6
|
+
{
|
|
7
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
8
|
+
"Sec-Ch-Ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
|
|
9
|
+
"Sec-Ch-Ua-Platform": "\"Windows\""
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
|
|
13
|
+
"Sec-Ch-Ua": "\"Google Chrome\";v=\"130\", \"Chromium\";v=\"130\", \"Not_A Brand\";v=\"24\"",
|
|
14
|
+
"Sec-Ch-Ua-Platform": "\"Windows\""
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
18
|
+
"Sec-Ch-Ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
|
|
19
|
+
"Sec-Ch-Ua-Platform": "\"macOS\""
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
|
|
23
|
+
"Sec-Ch-Ua": "\"Google Chrome\";v=\"130\", \"Chromium\";v=\"130\", \"Not_A Brand\";v=\"24\"",
|
|
24
|
+
"Sec-Ch-Ua-Platform": "\"macOS\""
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0",
|
|
28
|
+
"Sec-Ch-Ua": "\"Microsoft Edge\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
|
|
29
|
+
"Sec-Ch-Ua-Platform": "\"Windows\""
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0",
|
|
33
|
+
"Sec-Ch-Ua": "\"Microsoft Edge\";v=\"130\", \"Chromium\";v=\"130\", \"Not_A Brand\";v=\"24\"",
|
|
34
|
+
"Sec-Ch-Ua-Platform": "\"Windows\""
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
const randomProfile = () => browserProfiles[Math.floor(Math.random() * browserProfiles.length)];
|
|
38
|
+
const baseHeaders = {
|
|
39
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
40
|
+
"Accept-Language": "cs-CZ,cs;q=0.9,en-US;q=0.8,en;q=0.7",
|
|
41
|
+
"Accept-Encoding": "gzip, deflate, br",
|
|
42
|
+
"Cache-Control": "max-age=0",
|
|
43
|
+
Connection: "keep-alive",
|
|
44
|
+
"Sec-Ch-Ua-Mobile": "?0",
|
|
45
|
+
"Sec-Fetch-Dest": "document",
|
|
46
|
+
"Sec-Fetch-Mode": "navigate",
|
|
47
|
+
"Sec-Fetch-Site": "none",
|
|
48
|
+
"Sec-Fetch-User": "?1",
|
|
49
|
+
"Upgrade-Insecure-Requests": "1"
|
|
50
|
+
};
|
|
51
|
+
const fetchPage = async (url, optionsRequest) => {
|
|
52
|
+
try {
|
|
53
|
+
const mergedHeaders = new Headers({
|
|
54
|
+
...baseHeaders,
|
|
55
|
+
...randomProfile()
|
|
56
|
+
});
|
|
57
|
+
if (optionsRequest?.headers) new Headers(optionsRequest.headers).forEach((value, key) => mergedHeaders.set(key, value));
|
|
58
|
+
const { headers: _, ...restOptions } = optionsRequest || {};
|
|
59
|
+
const response = await fetchSafe(url, {
|
|
60
|
+
credentials: "omit",
|
|
61
|
+
...restOptions,
|
|
62
|
+
headers: mergedHeaders
|
|
63
|
+
});
|
|
64
|
+
if (!response.ok) throw new Error(`node-csfd-api: Bad response ${response.status} for url: ${url}`);
|
|
65
|
+
const html = await response.text();
|
|
66
|
+
if (html.includes("Making sure you're not a bot!")) console.warn("node-csfd-api: Trap detected.");
|
|
67
|
+
return html;
|
|
68
|
+
} catch (e) {
|
|
69
|
+
if (e instanceof Error) console.error(e.message);
|
|
70
|
+
else console.error(String(e));
|
|
71
|
+
return "Error";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
export { fetchPage };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseColor, parseIdFromUrl } from "./global.helper.js";
|
|
3
|
+
|
|
2
4
|
//#region src/helpers/cinema.helper.ts
|
|
3
5
|
const getCinemaColorRating = (el) => {
|
|
4
6
|
const classes = el?.classNames.split(" ") ?? [];
|
|
@@ -73,7 +75,6 @@ const parseMeta = (meta) => {
|
|
|
73
75
|
else metaConvert.push(element);
|
|
74
76
|
return metaConvert;
|
|
75
77
|
};
|
|
76
|
-
//#endregion
|
|
77
|
-
export { getCinemaCoords, getCinemaId, getCinemaUrl, getGroupedFilmsByDate, parseCinema };
|
|
78
78
|
|
|
79
|
-
//#
|
|
79
|
+
//#endregion
|
|
80
|
+
export { getCinemaCoords, getCinemaId, getCinemaUrl, getGroupedFilmsByDate, parseCinema };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { addProtocol, parseColor, parseDate, parseIdFromUrl } from "./global.helper.js";
|
|
3
|
+
|
|
2
4
|
//#region src/helpers/creator.helper.ts
|
|
3
5
|
const getCreatorColorRating = (el) => {
|
|
4
6
|
const classes = el?.classNames.split(" ") ?? [];
|
|
@@ -62,7 +64,6 @@ const getCreatorFilms = (el) => {
|
|
|
62
64
|
return null;
|
|
63
65
|
}).filter(Boolean);
|
|
64
66
|
};
|
|
65
|
-
//#endregion
|
|
66
|
-
export { getCreatorBio, getCreatorBirthdayInfo, getCreatorFilms, getCreatorName, getCreatorPhoto };
|
|
67
67
|
|
|
68
|
-
//#
|
|
68
|
+
//#endregion
|
|
69
|
+
export { getCreatorBio, getCreatorBirthdayInfo, getCreatorFilms, getCreatorName, getCreatorPhoto };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
//#region src/helpers/global.helper.ts
|
|
2
3
|
const LANG_PREFIX_REGEX = /^[a-z]{2,3}$/;
|
|
3
4
|
const ISO8601_DURATION_REGEX = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
|
|
@@ -95,7 +96,6 @@ const parseDate = (date) => {
|
|
|
95
96
|
return null;
|
|
96
97
|
};
|
|
97
98
|
const sleep = (ms) => new Promise((res) => setTimeout(res, ms));
|
|
98
|
-
//#endregion
|
|
99
|
-
export { addProtocol, getColor, parseColor, parseDate, parseFilmType, parseISO8601Duration, parseIdFromUrl, parseLastIdFromUrl, sleep };
|
|
100
99
|
|
|
101
|
-
//#
|
|
100
|
+
//#endregion
|
|
101
|
+
export { addProtocol, getColor, parseColor, parseDate, parseFilmType, parseISO8601Duration, parseIdFromUrl, parseLastIdFromUrl, sleep };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { addProtocol, getColor, parseDate, parseFilmType, parseISO8601Duration, parseIdFromUrl, parseLastIdFromUrl } from "./global.helper.js";
|
|
3
|
+
|
|
2
4
|
//#region src/helpers/movie.helper.ts
|
|
3
5
|
const CREATOR_LABELS = {
|
|
4
6
|
en: {
|
|
@@ -295,7 +297,6 @@ const getMoviePremieres = (el) => {
|
|
|
295
297
|
const getMovieTags = (el) => {
|
|
296
298
|
return el.querySelectorAll(".box-content a[href*=\"/tag/\"]").map((tag) => tag.textContent);
|
|
297
299
|
};
|
|
298
|
-
//#endregion
|
|
299
|
-
export { detectSeasonOrEpisodeListType, getEpisodeCode, getMovieBoxMovies, getMovieColorRating, getMovieCreators, getMovieDescriptions, getMovieDuration, getMovieGenres, getMovieOrigins, getMoviePoster, getMoviePremieres, getMovieRandomPhoto, getMovieRating, getMovieRatingCount, getMovieTags, getMovieTitle, getMovieTitlesOther, getMovieTrivia, getMovieType, getMovieVods, getMovieYear, getSeasonOrEpisodeParent, getSeasonsOrEpisodes, getSeriesAndSeasonTitle };
|
|
300
300
|
|
|
301
|
-
//#
|
|
301
|
+
//#endregion
|
|
302
|
+
export { detectSeasonOrEpisodeListType, getEpisodeCode, getMovieBoxMovies, getMovieColorRating, getMovieCreators, getMovieDescriptions, getMovieDuration, getMovieGenres, getMovieOrigins, getMoviePoster, getMoviePremieres, getMovieRandomPhoto, getMovieRating, getMovieRatingCount, getMovieTags, getMovieTitle, getMovieTitlesOther, getMovieTrivia, getMovieType, getMovieVods, getMovieYear, getSeasonOrEpisodeParent, getSeasonsOrEpisodes, getSeriesAndSeasonTitle };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { addProtocol } from "./global.helper.js";
|
|
3
|
+
|
|
2
4
|
//#region src/helpers/search-creator.helper.ts
|
|
3
5
|
const getCreatorName = (el) => {
|
|
4
6
|
return el.querySelector(".user-title").text.trim();
|
|
@@ -10,7 +12,6 @@ const getCreatorImage = (el) => {
|
|
|
10
12
|
const getCreatorUrl = (el) => {
|
|
11
13
|
return el.querySelector(".user-title a").attributes.href;
|
|
12
14
|
};
|
|
13
|
-
//#endregion
|
|
14
|
-
export { getCreatorImage, getCreatorName, getCreatorUrl };
|
|
15
15
|
|
|
16
|
-
//#
|
|
16
|
+
//#endregion
|
|
17
|
+
export { getCreatorImage, getCreatorName, getCreatorUrl };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { addProtocol } from "./global.helper.js";
|
|
2
3
|
import { NodeType } from "node-html-parser";
|
|
4
|
+
|
|
3
5
|
//#region src/helpers/search-user.helper.ts
|
|
4
6
|
const getUser = (el) => {
|
|
5
7
|
return el.querySelector(".user-title-name").text;
|
|
@@ -17,7 +19,6 @@ const getAvatar = (el) => {
|
|
|
17
19
|
const getUserUrl = (el) => {
|
|
18
20
|
return el.querySelector(".user-title-name").attributes.href;
|
|
19
21
|
};
|
|
20
|
-
//#endregion
|
|
21
|
-
export { getAvatar, getUser, getUserRealName, getUserUrl };
|
|
22
22
|
|
|
23
|
-
//#
|
|
23
|
+
//#endregion
|
|
24
|
+
export { getAvatar, getUser, getUserRealName, getUserUrl };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { addProtocol, parseColor, parseFilmType, parseIdFromUrl } from "./global.helper.js";
|
|
3
|
+
|
|
2
4
|
//#region src/helpers/search.helper.ts
|
|
3
5
|
const getSearchType = (el) => {
|
|
4
6
|
const type = el.querySelectorAll(".film-title-info .info")[1];
|
|
@@ -39,7 +41,6 @@ const parseSearchPeople = (el, type) => {
|
|
|
39
41
|
});
|
|
40
42
|
else return [];
|
|
41
43
|
};
|
|
42
|
-
//#endregion
|
|
43
|
-
export { getSearchColorRating, getSearchOrigins, getSearchPoster, getSearchTitle, getSearchType, getSearchUrl, getSearchYear, parseSearchPeople };
|
|
44
44
|
|
|
45
|
-
//#
|
|
45
|
+
//#endregion
|
|
46
|
+
export { getSearchColorRating, getSearchOrigins, getSearchPoster, getSearchTitle, getSearchType, getSearchUrl, getSearchYear, parseSearchPeople };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseColor, parseDate, parseFilmType, parseIdFromUrl } from "./global.helper.js";
|
|
3
|
+
|
|
2
4
|
//#region src/helpers/user-ratings.helper.ts
|
|
3
5
|
const getUserRatingId = (el) => {
|
|
4
6
|
const url = el.querySelector("td.name .film-title-name").attributes.href;
|
|
@@ -28,7 +30,6 @@ const getUserRatingDate = (el) => {
|
|
|
28
30
|
const getUserRatingUrl = (el) => {
|
|
29
31
|
return `https://www.csfd.cz${el.querySelector("td.name .film-title-name").attributes.href}`;
|
|
30
32
|
};
|
|
31
|
-
//#endregion
|
|
32
|
-
export { getUserRating, getUserRatingColorRating, getUserRatingDate, getUserRatingId, getUserRatingTitle, getUserRatingType, getUserRatingUrl, getUserRatingYear };
|
|
33
33
|
|
|
34
|
-
//#
|
|
34
|
+
//#endregion
|
|
35
|
+
export { getUserRating, getUserRatingColorRating, getUserRatingDate, getUserRatingId, getUserRatingTitle, getUserRatingType, getUserRatingUrl, getUserRatingYear };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseColor, parseDate, parseFilmType, parseIdFromUrl } from "./global.helper.js";
|
|
3
|
+
|
|
2
4
|
//#region src/helpers/user-reviews.helper.ts
|
|
3
5
|
const getUserReviewId = (el) => {
|
|
4
6
|
const url = el.querySelector(".film-title-name").attributes.href;
|
|
@@ -41,7 +43,6 @@ const getUserReviewPoster = (el) => {
|
|
|
41
43
|
const src = img?.attributes.src;
|
|
42
44
|
return src ? `https:${src}` : null;
|
|
43
45
|
};
|
|
44
|
-
//#endregion
|
|
45
|
-
export { getUserReviewColorRating, getUserReviewDate, getUserReviewId, getUserReviewPoster, getUserReviewRating, getUserReviewText, getUserReviewTitle, getUserReviewType, getUserReviewUrl, getUserReviewYear };
|
|
46
46
|
|
|
47
|
-
//#
|
|
47
|
+
//#endregion
|
|
48
|
+
export { getUserReviewColorRating, getUserReviewDate, getUserReviewId, getUserReviewPoster, getUserReviewRating, getUserReviewText, getUserReviewTitle, getUserReviewType, getUserReviewUrl, getUserReviewYear };
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { CinemaScraper } from "./services/cinema.service.js";
|
|
3
|
+
import { CreatorScraper } from "./services/creator.service.js";
|
|
4
|
+
import { MovieScraper } from "./services/movie.service.js";
|
|
5
|
+
import { SearchScraper } from "./services/search.service.js";
|
|
6
|
+
import { UserRatingsScraper } from "./services/user-ratings.service.js";
|
|
7
|
+
import { UserReviewsScraper } from "./services/user-reviews.service.js";
|
|
8
|
+
|
|
7
9
|
//#region src/index.ts
|
|
8
10
|
var Csfd = class {
|
|
11
|
+
defaultOptions;
|
|
9
12
|
constructor(userRatingsService, userReviewsService, movieService, creatorService, searchService, cinemaService, defaultOptions) {
|
|
10
13
|
this.userRatingsService = userRatingsService;
|
|
11
14
|
this.userReviewsService = userReviewsService;
|
|
@@ -54,8 +57,9 @@ const movieScraper = new MovieScraper();
|
|
|
54
57
|
const userRatingsScraper = new UserRatingsScraper();
|
|
55
58
|
const userReviewsScraper = new UserReviewsScraper();
|
|
56
59
|
const cinemaScraper = new CinemaScraper();
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
const creatorScraper = new CreatorScraper();
|
|
61
|
+
const searchScraper = new SearchScraper();
|
|
62
|
+
const csfd = new Csfd(userRatingsScraper, userReviewsScraper, movieScraper, creatorScraper, searchScraper, cinemaScraper);
|
|
60
63
|
|
|
61
|
-
//#
|
|
64
|
+
//#endregion
|
|
65
|
+
export { csfd };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fetchPage } from "../fetchers/index.js";
|
|
3
|
+
import { cinemasUrl } from "../vars.js";
|
|
4
|
+
import { getCinemaCoords, getCinemaId, getCinemaUrl, getGroupedFilmsByDate, parseCinema } from "../helpers/cinema.helper.js";
|
|
4
5
|
import { parse } from "node-html-parser";
|
|
6
|
+
|
|
5
7
|
//#region src/services/cinema.service.ts
|
|
6
8
|
var CinemaScraper = class {
|
|
7
9
|
async cinemas(district = 1, period = "today", options) {
|
|
@@ -25,7 +27,6 @@ var CinemaScraper = class {
|
|
|
25
27
|
return cinemas;
|
|
26
28
|
}
|
|
27
29
|
};
|
|
28
|
-
//#endregion
|
|
29
|
-
export { CinemaScraper };
|
|
30
30
|
|
|
31
|
-
//#
|
|
31
|
+
//#endregion
|
|
32
|
+
export { CinemaScraper };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fetchPage } from "../fetchers/index.js";
|
|
3
|
+
import { creatorUrl } from "../vars.js";
|
|
4
|
+
import { getCreatorBio, getCreatorBirthdayInfo, getCreatorFilms, getCreatorName, getCreatorPhoto } from "../helpers/creator.helper.js";
|
|
4
5
|
import { parse } from "node-html-parser";
|
|
6
|
+
|
|
5
7
|
//#region src/services/creator.service.ts
|
|
6
8
|
var CreatorScraper = class {
|
|
7
9
|
async creator(creatorId, options) {
|
|
@@ -26,7 +28,6 @@ var CreatorScraper = class {
|
|
|
26
28
|
};
|
|
27
29
|
}
|
|
28
30
|
};
|
|
29
|
-
//#endregion
|
|
30
|
-
export { CreatorScraper };
|
|
31
31
|
|
|
32
|
-
//#
|
|
32
|
+
//#endregion
|
|
33
|
+
export { CreatorScraper };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fetchPage } from "../fetchers/index.js";
|
|
3
|
+
import { movieUrl } from "../vars.js";
|
|
4
|
+
import { detectSeasonOrEpisodeListType, getEpisodeCode, getMovieBoxMovies, getMovieColorRating, getMovieCreators, getMovieDescriptions, getMovieDuration, getMovieGenres, getMovieOrigins, getMoviePoster, getMoviePremieres, getMovieRandomPhoto, getMovieRating, getMovieRatingCount, getMovieTags, getMovieTitle, getMovieTitlesOther, getMovieTrivia, getMovieType, getMovieVods, getMovieYear, getSeasonOrEpisodeParent, getSeasonsOrEpisodes, getSeriesAndSeasonTitle } from "../helpers/movie.helper.js";
|
|
4
5
|
import { parse } from "node-html-parser";
|
|
6
|
+
|
|
5
7
|
//#region src/services/movie.service.ts
|
|
6
8
|
var MovieScraper = class {
|
|
7
9
|
async movie(movieId, options) {
|
|
@@ -55,7 +57,6 @@ var MovieScraper = class {
|
|
|
55
57
|
};
|
|
56
58
|
}
|
|
57
59
|
};
|
|
58
|
-
//#endregion
|
|
59
|
-
export { MovieScraper };
|
|
60
60
|
|
|
61
|
-
//#
|
|
61
|
+
//#endregion
|
|
62
|
+
export { MovieScraper };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fetchPage } from "../fetchers/index.js";
|
|
3
|
+
import { getUrlByLanguage, searchUrl } from "../vars.js";
|
|
4
|
+
import { parseIdFromUrl } from "../helpers/global.helper.js";
|
|
5
|
+
import { getCreatorImage, getCreatorName, getCreatorUrl } from "../helpers/search-creator.helper.js";
|
|
6
|
+
import { getAvatar, getUser, getUserRealName, getUserUrl } from "../helpers/search-user.helper.js";
|
|
7
|
+
import { getSearchColorRating, getSearchOrigins, getSearchPoster, getSearchTitle, getSearchType, getSearchUrl, getSearchYear, parseSearchPeople } from "../helpers/search.helper.js";
|
|
7
8
|
import { parse } from "node-html-parser";
|
|
9
|
+
|
|
8
10
|
//#region src/services/search.service.ts
|
|
9
11
|
var SearchScraper = class {
|
|
10
12
|
async search(text, options) {
|
|
@@ -69,7 +71,6 @@ var SearchScraper = class {
|
|
|
69
71
|
};
|
|
70
72
|
}
|
|
71
73
|
};
|
|
72
|
-
//#endregion
|
|
73
|
-
export { SearchScraper };
|
|
74
74
|
|
|
75
|
-
//#
|
|
75
|
+
//#endregion
|
|
76
|
+
export { SearchScraper };
|