node-csfd-api-racintom 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/fetchers/fetch.polyfill.d.ts +1 -0
  2. package/fetchers/fetch.polyfill.js +9 -0
  3. package/fetchers/index.d.ts +1 -0
  4. package/fetchers/index.js +27 -0
  5. package/helpers/creator.helper.d.ts +17 -0
  6. package/helpers/creator.helper.js +87 -0
  7. package/helpers/global.helper.d.ts +17 -0
  8. package/helpers/global.helper.js +68 -0
  9. package/helpers/movie.helper.d.ts +26 -0
  10. package/helpers/movie.helper.js +270 -0
  11. package/helpers/search-user.helper.d.ts +5 -0
  12. package/helpers/search-user.helper.js +22 -0
  13. package/helpers/search.helper.d.ts +11 -0
  14. package/helpers/search.helper.js +62 -0
  15. package/helpers/user-ratings.helper.d.ts +13 -0
  16. package/helpers/user-ratings.helper.js +61 -0
  17. package/index.d.ts +24 -0
  18. package/index.js +39 -0
  19. package/interfaces/creator.interface.d.ts +12 -0
  20. package/interfaces/creator.interface.js +2 -0
  21. package/interfaces/global.d.ts +22 -0
  22. package/interfaces/global.js +2 -0
  23. package/interfaces/movie.interface.d.ts +73 -0
  24. package/interfaces/movie.interface.js +2 -0
  25. package/interfaces/search.interface.d.ts +27 -0
  26. package/interfaces/search.interface.js +2 -0
  27. package/interfaces/season.interface.d.ts +11 -0
  28. package/interfaces/season.interface.js +2 -0
  29. package/interfaces/user-ratings.interface.d.ts +18 -0
  30. package/interfaces/user-ratings.interface.js +2 -0
  31. package/package.json +62 -86
  32. package/services/creator.service.d.ts +6 -0
  33. package/services/creator.service.js +32 -0
  34. package/services/movie.service.d.ts +6 -0
  35. package/services/movie.service.js +59 -0
  36. package/services/search.service.d.ts +5 -0
  37. package/services/search.service.js +80 -0
  38. package/services/season.service.d.ts +9 -0
  39. package/services/season.service.js +42 -0
  40. package/services/user-ratings.service.d.ts +7 -0
  41. package/services/user-ratings.service.js +84 -0
  42. package/vars.d.ts +5 -0
  43. package/vars.js +13 -0
  44. package/.editorconfig +0 -13
  45. package/.eslintrc.json +0 -33
  46. package/.gitattributes +0 -2
  47. package/.github/FUNDING.yml +0 -8
  48. package/.github/pull_request_template.md +0 -19
  49. package/.github/workflows/main.yml +0 -40
  50. package/.github/workflows/publish.yml +0 -73
  51. package/.github/workflows/test.yml +0 -43
  52. package/.husky/pre-commit +0 -1
  53. package/.idea/codeStyles/Project.xml +0 -72
  54. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  55. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  56. package/.idea/misc.xml +0 -6
  57. package/.idea/modules.xml +0 -8
  58. package/.idea/node-csfd-api.iml +0 -9
  59. package/.idea/prettier.xml +0 -6
  60. package/.idea/vcs.xml +0 -7
  61. package/.nvmrc +0 -1
  62. package/.prettierignore +0 -8
  63. package/.prettierrc +0 -10
  64. package/.vscode/settings.json +0 -16
  65. package/Dockerfile +0 -19
  66. package/demo.ts +0 -35
  67. package/eslint.config.mjs +0 -55
  68. package/server.ts +0 -66
  69. package/src/fetchers/fetch.polyfill.ts +0 -7
  70. package/src/fetchers/index.ts +0 -25
  71. package/src/helpers/creator.helper.ts +0 -95
  72. package/src/helpers/global.helper.ts +0 -70
  73. package/src/helpers/movie.helper.ts +0 -276
  74. package/src/helpers/search-user.helper.ts +0 -19
  75. package/src/helpers/search.helper.ts +0 -66
  76. package/src/helpers/user-ratings.helper.ts +0 -62
  77. package/src/index.ts +0 -50
  78. package/src/interfaces/creator.interface.ts +0 -14
  79. package/src/interfaces/global.ts +0 -36
  80. package/src/interfaces/movie.interface.ts +0 -157
  81. package/src/interfaces/search.interface.ts +0 -32
  82. package/src/interfaces/season.interface.ts +0 -12
  83. package/src/interfaces/user-ratings.interface.ts +0 -21
  84. package/src/services/creator.service.ts +0 -34
  85. package/src/services/movie.service.ts +0 -89
  86. package/src/services/search.service.ts +0 -101
  87. package/src/services/season.service.ts +0 -55
  88. package/src/services/user-ratings.service.ts +0 -106
  89. package/src/vars.ts +0 -16
  90. package/tests/creator.test.ts +0 -182
  91. package/tests/fetchers.test.ts +0 -109
  92. package/tests/global.test.ts +0 -35
  93. package/tests/helpers.test.ts +0 -59
  94. package/tests/mocks/creator-actor.html.ts +0 -2244
  95. package/tests/mocks/creator-composer-empty.html.ts +0 -683
  96. package/tests/mocks/creator-director.html.ts +0 -3407
  97. package/tests/mocks/movie1.html.ts +0 -1430
  98. package/tests/mocks/movie2.html.ts +0 -740
  99. package/tests/mocks/movie3.html.ts +0 -1843
  100. package/tests/mocks/movie4.html.ts +0 -1568
  101. package/tests/mocks/search.html.ts +0 -838
  102. package/tests/mocks/series1.html.ts +0 -1540
  103. package/tests/mocks/userRatings.html.ts +0 -1354
  104. package/tests/movie.test.ts +0 -606
  105. package/tests/search.test.ts +0 -379
  106. package/tests/season.test.ts +0 -115
  107. package/tests/services.test.ts +0 -106
  108. package/tests/user-ratings.test.ts +0 -142
  109. package/tests/vars.test.ts +0 -34
  110. package/tsconfig.json +0 -23
  111. package/vitest.config.mts +0 -10
@@ -1,66 +0,0 @@
1
- import { HTMLElement } from 'node-html-parser';
2
- import { CSFDColorRating, CSFDFilmTypes } from '../interfaces/global';
3
- import { CSFDCreator } from '../interfaces/movie.interface';
4
- import { Colors } from '../interfaces/user-ratings.interface';
5
- import { addProtocol, parseColor, parseIdFromUrl } from './global.helper';
6
-
7
- type Creator = 'Režie:' | 'Hrají:';
8
-
9
- export const getType = (el: HTMLElement): CSFDFilmTypes => {
10
- const type = el.querySelectorAll('.film-title-info .info')[1];
11
- return (type?.innerText.replace(/[{()}]/g, '') || 'film') as CSFDFilmTypes;
12
- };
13
-
14
- export const getTitle = (el: HTMLElement): string => {
15
- return el.querySelector('.film-title-name').text;
16
- };
17
-
18
- export const getYear = (el: HTMLElement): number => {
19
- return +el.querySelectorAll('.film-title-info .info')[0]?.innerText.replace(/[{()}]/g, '');
20
- };
21
-
22
- export const getUrl = (el: HTMLElement): string => {
23
- return el.querySelector('.film-title-name').attributes.href;
24
- };
25
-
26
- export const getColorRating = (el: HTMLElement): CSFDColorRating => {
27
- return parseColor(
28
- el.querySelector('.article-header i.icon').classNames.split(' ').pop() as Colors
29
- );
30
- };
31
-
32
- export const getPoster = (el: HTMLElement): string => {
33
- const image = el.querySelector('img').attributes.src;
34
- return addProtocol(image);
35
- };
36
-
37
- export const getOrigins = (el: HTMLElement): string[] => {
38
- const originsRaw = el.querySelector('.article-content p .info')?.text;
39
- if (!originsRaw) return [];
40
- const originsAll = originsRaw?.split(', ')?.[0];
41
- return originsAll?.split('/').map((country) => country.trim());
42
- };
43
-
44
- export const parsePeople = (el: HTMLElement, type: 'directors' | 'actors'): CSFDCreator[] => {
45
- let who: Creator;
46
- if (type === 'directors') who = 'Režie:';
47
- if (type === 'actors') who = 'Hrají:';
48
-
49
- const peopleNode = Array.from(el && el.querySelectorAll('.article-content p')).find((el) =>
50
- el.textContent.includes(who)
51
- );
52
-
53
- if (peopleNode) {
54
- const people = Array.from(peopleNode.querySelectorAll('a')) as unknown as HTMLElement[];
55
-
56
- return people.map((person) => {
57
- return {
58
- id: parseIdFromUrl(person.attributes.href),
59
- name: person.innerText.trim(),
60
- url: `https://www.csfd.cz${person.attributes.href}`
61
- };
62
- });
63
- } else {
64
- return [];
65
- }
66
- };
@@ -1,62 +0,0 @@
1
- import { HTMLElement } from 'node-html-parser';
2
- import { CSFDColorRating, CSFDFilmTypes, CSFDStars } from '../interfaces/global';
3
- import { Colors } from '../interfaces/user-ratings.interface';
4
- import { parseIdFromUrl } from './global.helper';
5
-
6
- export const getId = (el: HTMLElement): number => {
7
- const url = el.querySelector('td.name .film-title-name').attributes.href;
8
- return parseIdFromUrl(url);
9
- };
10
-
11
- export const getUserRating = (el: HTMLElement): CSFDStars => {
12
- const ratingText = el.querySelector('td.star-rating-only .stars').classNames.split(' ').pop();
13
-
14
- const rating = ratingText.includes('stars-') ? +ratingText.split('-').pop() : 0;
15
- return rating as CSFDStars;
16
- };
17
-
18
- export const getType = (el: HTMLElement): CSFDFilmTypes => {
19
- const typeText = el.querySelectorAll('td.name .film-title-info .info');
20
-
21
- return (typeText.length > 1 ? typeText[1].text.slice(1, -1) : 'film') as CSFDFilmTypes;
22
- };
23
-
24
- export const getTitle = (el: HTMLElement): string => {
25
- return el.querySelector('td.name .film-title-name').text;
26
- };
27
-
28
- export const getYear = (el: HTMLElement): number => {
29
- return +el.querySelectorAll('td.name .film-title-info .info')[0]?.text.slice(1, -1) || null;
30
- };
31
-
32
- export const getColorRating = (el: HTMLElement): CSFDColorRating => {
33
- const color = parseColor(el.querySelector('td.name .icon').classNames.split(' ').pop() as Colors);
34
- return color;
35
- };
36
-
37
- export const getDate = (el: HTMLElement): string => {
38
- return el.querySelector('td.date-only').text.trim();
39
- };
40
-
41
- export const getUrl = (el: HTMLElement): string => {
42
- const url = el.querySelector('td.name .film-title-name').attributes.href;
43
- return `https://www.csfd.cz${url}`;
44
- };
45
-
46
- export const parseColor = (quality: Colors): CSFDColorRating => {
47
- switch (quality) {
48
- case 'lightgrey':
49
- return 'unknown';
50
- case 'red':
51
- return 'good';
52
- case 'blue':
53
- return 'average';
54
- case 'grey':
55
- return 'bad';
56
- default:
57
- return 'unknown';
58
- }
59
- };
60
-
61
- // Sleep in loop
62
- export const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));
package/src/index.ts DELETED
@@ -1,50 +0,0 @@
1
- import { CSFDCreator } from './interfaces/creator.interface';
2
- import { CSFDMovie } from './interfaces/movie.interface';
3
- import { CSFDSearch } from './interfaces/search.interface';
4
- import { CSFDUserRatingConfig, CSFDUserRatings } from './interfaces/user-ratings.interface';
5
- import { CreatorScraper } from './services/creator.service';
6
- import { MovieScraper } from './services/movie.service';
7
- import { SearchScraper } from './services/search.service';
8
- import { UserRatingsScraper } from './services/user-ratings.service';
9
- import { SeasonScraper } from './services/season.service';
10
- import { Season } from './interfaces/season.interface';
11
-
12
- export class Csfd {
13
- constructor(
14
- private userRatingsService: UserRatingsScraper,
15
- private movieService: MovieScraper,
16
- private creatorService: CreatorScraper,
17
- private searchService: SearchScraper,
18
- private seasonService: SeasonScraper,
19
- ) {}
20
-
21
- public async userRatings(
22
- user: string | number,
23
- config?: CSFDUserRatingConfig
24
- ): Promise<CSFDUserRatings[]> {
25
- return this.userRatingsService.userRatings(user, config);
26
- }
27
-
28
- public async movie(movie: number): Promise<CSFDMovie> {
29
- return this.movieService.movie(+movie);
30
- }
31
-
32
- public async creator(creator: number): Promise<CSFDCreator> {
33
- return this.creatorService.creator(+creator);
34
- }
35
-
36
- public async search(text: string): Promise<CSFDSearch> {
37
- return this.searchService.search(text);
38
- }
39
-
40
- public async seasonDetails(url: string): Promise<Season> {
41
- return this.seasonService.season(url);
42
- }
43
- }
44
-
45
- const movieScraper = new MovieScraper();
46
- const userRatingsScraper = new UserRatingsScraper();
47
- const creatorScraper = new CreatorScraper();
48
- const searchScraper = new SearchScraper();
49
- const seasonScraper = new SeasonScraper();
50
- export const csfd = new Csfd(userRatingsScraper, movieScraper, creatorScraper, searchScraper, seasonScraper);
@@ -1,14 +0,0 @@
1
- import { CSFDScreening } from './global';
2
-
3
- export interface CSFDCreator {
4
- id: number;
5
- name: string;
6
- birthday: string;
7
- birthplace: string;
8
- photo: string;
9
- age: number | string;
10
- bio: string;
11
- films: CSFDCreatorScreening[];
12
- }
13
-
14
- export type CSFDCreatorScreening = Omit<CSFDScreening, 'url' | 'type'>;
@@ -1,36 +0,0 @@
1
- export interface CSFDScreening {
2
- id: number;
3
- title: string;
4
- year: number;
5
- url: string;
6
- type: CSFDFilmTypes;
7
- /**
8
- * Overall aggregated rating. (On the web usually represented by colors).
9
- *
10
- * 'unknown': unknown (gray color)
11
- *
12
- * 'good': 70% – 100 % (red color)
13
- *
14
- * 'average': 30% - 69% (blue color)
15
- *
16
- * 'bad': 0% - 29% (black color)
17
- */
18
- colorRating: CSFDColorRating;
19
- }
20
-
21
- export type CSFDColorRating = 'bad' | 'average' | 'good' | 'unknown';
22
-
23
- export type CSFDStars = 0 | 1 | 2 | 3 | 4 | 5;
24
-
25
- export type CSFDFilmTypes =
26
- | 'film'
27
- | 'TV film'
28
- | 'pořad'
29
- | 'seriál'
30
- | 'divadelní záznam'
31
- | 'koncert'
32
- | 'série'
33
- | 'studentský film'
34
- | 'amatérský film'
35
- | 'hudební videoklip'
36
- | 'epizoda';
@@ -1,157 +0,0 @@
1
- import { CSFDScreening } from './global';
2
-
3
- export interface CSFDMovie extends CSFDScreening {
4
- rating: number | null;
5
- poster: string;
6
- photo: string;
7
- ratingCount: number | null;
8
- duration: number | string;
9
- titlesOther: CSFDTitlesOther[];
10
- origins: string[];
11
- descriptions: string[];
12
- trivia: string[];
13
- genres: CSFDGenres[] | string[];
14
- creators: CSFDCreators;
15
- vod: CSFDVod[];
16
- tags: string[];
17
- premieres: CSFDPremiere[];
18
- related: CSFDMovieListItem[];
19
- similar: CSFDMovieListItem[];
20
- seasons: CSFDSeasons | null;
21
- }
22
-
23
- export type CSFDVodService =
24
- | 'Netflix'
25
- | 'hbogo'
26
- | 'Prime Video'
27
- | 'Apple TV+'
28
- | 'iTunes'
29
- | 'KVIFF.TV'
30
- | 'Edisonline'
31
- | 'o2tv'
32
- | 'SledovaniTV'
33
- | 'Starmax'
34
- | 'DAFilms'
35
- | 'FILMY ČESKY A ZADARMO'
36
- | 'Youtube Česká filmová klasika'
37
- | 'VAPET'
38
- | 'VOREL FILM'
39
- | 'ivysilani'
40
- | 'Google Play'
41
- | 'Voyo'
42
- | 'DVD';
43
-
44
- export interface CSFDVod {
45
- title: CSFDVodService;
46
- url: string;
47
- }
48
-
49
- export interface CSFDCreators {
50
- directors: CSFDCreator[];
51
- writers: CSFDCreator[];
52
- cinematography: CSFDCreator[];
53
- music: CSFDCreator[];
54
- actors: CSFDCreator[];
55
- basedOn: CSFDCreator[];
56
- producers: CSFDCreator[];
57
- filmEditing: CSFDCreator[];
58
- costumeDesign: CSFDCreator[];
59
- productionDesign: CSFDCreator[];
60
- }
61
-
62
- export interface CSFDTitlesOther {
63
- country: string;
64
- title: string;
65
- }
66
-
67
- export interface CSFDCreator {
68
- /**
69
- * CSFD person ID.
70
- *
71
- * You can always assemble url from ID like this:
72
- *
73
- * `https://www.csfd.cz/tvurce/${id}`
74
- */
75
- id: number;
76
- name: string;
77
- url: string;
78
- }
79
-
80
- export interface CSFDMovieListItem {
81
- id: number;
82
- title: string;
83
- url: string;
84
- }
85
-
86
- export type CSFDGenres =
87
- | 'Akční'
88
- | 'Animovaný'
89
- | 'Dobrodružný'
90
- | 'Dokumentární'
91
- | 'Drama'
92
- | 'Experimentální'
93
- | 'Fantasy'
94
- | 'Film-Noir'
95
- | 'Historický'
96
- | 'Horor'
97
- | 'Hudební'
98
- | 'IMAX'
99
- | 'Katastrofický'
100
- | 'Komedie'
101
- | 'Krátkometrážní'
102
- | 'Krimi'
103
- | 'Loutkový'
104
- | 'Muzikál'
105
- | 'Mysteriózní'
106
- | 'Naučný'
107
- | 'Podobenství'
108
- | 'Poetický'
109
- | 'Pohádka'
110
- | 'Povídkový'
111
- | 'Psychologický'
112
- | 'Publicistický'
113
- | 'Reality-TV'
114
- | 'Road movie'
115
- | 'Rodinný'
116
- | 'Romantický'
117
- | 'Sci-Fi'
118
- | 'Soutěžní'
119
- | 'Sportovní'
120
- | 'Stand-up'
121
- | 'Talk-show'
122
- | 'Taneční'
123
- | 'Telenovela'
124
- | 'Thriller'
125
- | 'Válečný'
126
- | 'Western'
127
- | 'Zábavný'
128
- | 'Životopisný';
129
-
130
- export type CSFDCreatorGroups =
131
- | 'Režie'
132
- | 'Scénář'
133
- | 'Kamera'
134
- | 'Hudba'
135
- | 'Hrají'
136
- | 'Produkce'
137
- | 'Střih'
138
- | 'Předloha'
139
- | 'Scénografie'
140
- | 'Kostýmy';
141
-
142
- export interface CSFDPremiere {
143
- country: string;
144
- format: string;
145
- date: string;
146
- company: string;
147
- }
148
-
149
- export type CSFDBoxContent = 'Související' | 'Podobné';
150
-
151
- export type CSFDSeasons = CSFDSeasonInfo[]
152
-
153
- export interface CSFDSeasonInfo {
154
- name: string
155
- linkToDetail: string
156
- additionalInfo: string
157
- }
@@ -1,32 +0,0 @@
1
- import { CSFDScreening } from './global';
2
- import { CSFDCreator } from './movie.interface';
3
-
4
- export interface CSFDSearch {
5
- movies: CSFDSearchMovie[];
6
- tvSeries: CSFDSearchMovie[];
7
- creators: CSFDSearchCreator[];
8
- users: CSFDSearchUser[];
9
- }
10
-
11
- export interface CSFDSearchMovie extends CSFDScreening {
12
- poster: string;
13
- origins: string[];
14
- creators: CSFDSearchCreators;
15
- }
16
-
17
- export interface CSFDSearchUser {
18
- id: number;
19
- user: string;
20
- userRealName: string;
21
- avatar: string;
22
- url: string;
23
- }
24
-
25
- export interface CSFDSearchCreator extends CSFDCreator {
26
- image: string;
27
- }
28
-
29
- export interface CSFDSearchCreators {
30
- directors: CSFDCreator[];
31
- actors: CSFDCreator[];
32
- }
@@ -1,12 +0,0 @@
1
- export type Season = {
2
- description: string;
3
- thumbnail: string;
4
- episodeList: EpisodeInfo[]
5
- origin: string;
6
- }
7
-
8
- export type EpisodeInfo = {
9
- name: string
10
- seasonEpisodeIdentifier: string;
11
- linkToDetail: string
12
- }
@@ -1,21 +0,0 @@
1
- import { CSFDFilmTypes, CSFDScreening, CSFDStars } from './global';
2
-
3
- export interface CSFDUserRatings extends CSFDScreening {
4
- userRating: CSFDStars;
5
- userDate: string; // TODO datetime
6
- }
7
-
8
- export interface CSFDUserRatingConfig {
9
- includesOnly?: CSFDFilmTypes[];
10
- excludes?: CSFDFilmTypes[];
11
- /**
12
- * Fetch all ratings. (Warning: Use it wisely. Can be detected and banned. Consider using it together with `allPagesDelay` attribute)
13
- */
14
- allPages?: boolean;
15
- /**
16
- * Delay on each page request. In milliseconds
17
- */
18
- allPagesDelay?: number;
19
- }
20
-
21
- export type Colors = 'lightgrey' | 'blue' | 'red' | 'grey';
@@ -1,34 +0,0 @@
1
- import { HTMLElement, parse } from 'node-html-parser';
2
- import { fetchPage } from '../fetchers';
3
- import { getBio, getBirthdayInfo, getFilms, getName, getPhoto } from '../helpers/creator.helper';
4
- import { CSFDCreator } from '../interfaces/creator.interface';
5
- import { creatorUrl } from '../vars';
6
-
7
- export class CreatorScraper {
8
- private person: CSFDCreator;
9
-
10
- public async creator(creatorId: number): Promise<CSFDCreator> {
11
- const url = creatorUrl(+creatorId);
12
- const response = await fetchPage(url);
13
-
14
- const creatorHtml = parse(response);
15
-
16
- const asideNode = creatorHtml.querySelector('.creator-about');
17
- const filmsNode = creatorHtml.querySelector('.creator-filmography');
18
- this.buildCreator(+creatorId, asideNode, filmsNode);
19
- return this.person;
20
- }
21
-
22
- private buildCreator(id: number, asideEl: HTMLElement, filmsNode: HTMLElement) {
23
- this.person = {
24
- id,
25
- name: getName(asideEl),
26
- birthday: getBirthdayInfo(asideEl)?.birthday,
27
- birthplace: getBirthdayInfo(asideEl)?.birthPlace,
28
- photo: getPhoto(asideEl),
29
- age: getBirthdayInfo(asideEl)?.age || null,
30
- bio: getBio(asideEl),
31
- films: getFilms(filmsNode)
32
- };
33
- }
34
- }
@@ -1,89 +0,0 @@
1
- import { HTMLElement, parse } from 'node-html-parser';
2
- import { fetchPage } from '../fetchers';
3
- import {
4
- getBoxMovies,
5
- getColorRating,
6
- getDescriptions,
7
- getDuration,
8
- getGenres,
9
- getGroup,
10
- getOrigins,
11
- getPoster,
12
- getPremieres,
13
- getRandomPhoto,
14
- getRating,
15
- getRatingCount, getSeasonsInfo,
16
- getTags,
17
- getTitle,
18
- getTitlesOther,
19
- getTrivia,
20
- getType,
21
- getVods,
22
- getYear
23
- } from '../helpers/movie.helper';
24
- import { CSFDFilmTypes } from '../interfaces/global';
25
- import { CSFDMovie } from '../interfaces/movie.interface';
26
- import { movieUrl } from '../vars';
27
-
28
- export class MovieScraper {
29
- private film: CSFDMovie;
30
-
31
- public async movie(movieId: number): Promise<CSFDMovie> {
32
- const url = movieUrl(+movieId);
33
- const response = await fetchPage(url);
34
-
35
- const movieHtml = parse(response);
36
-
37
- const pageClasses = movieHtml.querySelector('.page-content').classNames.split(' ');
38
- const asideNode = movieHtml.querySelector('.aside-movie-profile');
39
- const movieNode = movieHtml.querySelector('.main-movie-profile');
40
- const jsonLd = movieHtml.querySelector('script[type="application/ld+json"]').innerText;
41
- this.buildMovie(+movieId, movieNode, asideNode, pageClasses, jsonLd);
42
- return this.film;
43
- }
44
-
45
- private buildMovie(
46
- movieId: number,
47
- el: HTMLElement,
48
- asideEl: HTMLElement,
49
- pageClasses: string[],
50
- jsonLd: string
51
- ) {
52
- this.film = {
53
- id: movieId,
54
- title: getTitle(el),
55
- year: getYear(jsonLd),
56
- duration: getDuration(jsonLd, el),
57
- descriptions: getDescriptions(el),
58
- genres: getGenres(el),
59
- type: getType(el) as CSFDFilmTypes,
60
- url: movieUrl(movieId),
61
- origins: getOrigins(el),
62
- colorRating: getColorRating(pageClasses),
63
- rating: getRating(asideEl),
64
- ratingCount: getRatingCount(asideEl),
65
- titlesOther: getTitlesOther(el),
66
- poster: getPoster(el),
67
- photo: getRandomPhoto(el),
68
- trivia: getTrivia(el),
69
- creators: {
70
- directors: getGroup(el, 'Režie'),
71
- writers: getGroup(el, 'Scénář'),
72
- cinematography: getGroup(el, 'Kamera'),
73
- music: getGroup(el, 'Hudba'),
74
- actors: getGroup(el, 'Hrají'),
75
- basedOn: getGroup(el, 'Předloha'),
76
- producers: getGroup(el, 'Produkce'),
77
- filmEditing: getGroup(el, 'Střih'),
78
- costumeDesign: getGroup(el, 'Kostýmy'),
79
- productionDesign: getGroup(el, 'Scénografie')
80
- },
81
- vod: getVods(asideEl),
82
- tags: getTags(asideEl),
83
- premieres: getPremieres(asideEl),
84
- related: getBoxMovies(asideEl, 'Související'),
85
- similar: getBoxMovies(asideEl, 'Podobné'),
86
- seasons: getSeasonsInfo(el)
87
- };
88
- }
89
- }
@@ -1,101 +0,0 @@
1
- import { HTMLElement, parse } from 'node-html-parser';
2
- import { fetchPage } from '../fetchers';
3
- import { parseIdFromUrl } from '../helpers/global.helper';
4
- import { getAvatar, getUser, getUserRealName, getUserUrl } from '../helpers/search-user.helper';
5
- import {
6
- getColorRating,
7
- getOrigins,
8
- getPoster,
9
- getTitle,
10
- getType,
11
- getUrl,
12
- getYear,
13
- parsePeople
14
- } from '../helpers/search.helper';
15
- import { CSFDSearch, CSFDSearchMovie, CSFDSearchUser } from '../interfaces/search.interface';
16
- import { searchUrl } from '../vars';
17
-
18
- export class SearchScraper {
19
- public async search(text: string): Promise<CSFDSearch> {
20
- const url = searchUrl(text);
21
- const response = await fetchPage(url);
22
-
23
- const html = parse(response);
24
- const moviesNode = html.querySelectorAll('.main-movies article');
25
- const usersNode = html.querySelectorAll('.main-users article');
26
- const tvSeriesNode = html.querySelectorAll('.main-series article');
27
-
28
- return this.parseSearch(moviesNode, usersNode, tvSeriesNode);
29
- }
30
-
31
- private parseSearch(
32
- moviesNode: HTMLElement[],
33
- usersNode: HTMLElement[],
34
- tvSeriesNode: HTMLElement[]
35
- ) {
36
- const movies: CSFDSearchMovie[] = [];
37
- const users: CSFDSearchUser[] = [];
38
- const tvSeries: CSFDSearchMovie[] = [];
39
-
40
- moviesNode.map((m) => {
41
- const url = getUrl(m);
42
-
43
- const movie: CSFDSearchMovie = {
44
- id: parseIdFromUrl(url),
45
- title: getTitle(m),
46
- year: getYear(m),
47
- url: `https://www.csfd.cz${url}`,
48
- type: getType(m),
49
- colorRating: getColorRating(m),
50
- poster: getPoster(m),
51
- origins: getOrigins(m),
52
- creators: {
53
- directors: parsePeople(m, 'directors'),
54
- actors: parsePeople(m, 'actors')
55
- }
56
- };
57
- movies.push(movie);
58
- });
59
-
60
- usersNode.map((m) => {
61
- const url = getUserUrl(m);
62
-
63
- const user: CSFDSearchUser = {
64
- id: parseIdFromUrl(url),
65
- user: getUser(m),
66
- userRealName: getUserRealName(m),
67
- avatar: getAvatar(m),
68
- url: `https://www.csfd.cz${url}`
69
- };
70
- users.push(user);
71
- });
72
-
73
- tvSeriesNode.map((m) => {
74
- const url = getUrl(m);
75
-
76
- const user: CSFDSearchMovie = {
77
- id: parseIdFromUrl(url),
78
- title: getTitle(m),
79
- year: getYear(m),
80
- url: `https://www.csfd.cz${url}`,
81
- type: getType(m),
82
- colorRating: getColorRating(m),
83
- poster: getPoster(m),
84
- origins: getOrigins(m),
85
- creators: {
86
- directors: parsePeople(m, 'directors'),
87
- actors: parsePeople(m, 'actors')
88
- }
89
- };
90
- tvSeries.push(user);
91
- });
92
-
93
- const search: CSFDSearch = {
94
- movies: movies,
95
- users: users,
96
- tvSeries: tvSeries,
97
- creators: []
98
- };
99
- return search;
100
- }
101
- }