-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsfd.js
258 lines (232 loc) · 10.1 KB
/
csfd.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
const CSFD_URL = "https://www.csfd.cz";
const CSFD_FILM = "/film/"
const SERIES_PATTERN = /Season|Episode|Serie|Part/i;
const MOVIE_PATTERN = /\d+h \d+m|\d+h|\d+m/i;
const SERIES_OVERVIEW_PATTERN = /TV Shows/i;
const MOVIE_OVERVIEW_PATTERN = /Movies/i;
const IMAGE_WITH_SHOW_TITLE_CLASS_NAME = "previewModal--player-titleTreatment-logo";
const CSFD_LINK_CLASS_NAME = "csfd-link";
const PREVIEW_MODAL_CLASS_NAME = "previewModal--container";
const NETFLIX = window.document;
const DOM_PARSER = new DOMParser();
const SHOW_TYPE = {
MOVIE: "MOVIE",
SERIES: "SERIES",
UNKNOWN: "UNKNOWN"
};
const BROWSER_STORAGE = browser.storage.local;
const CSFD_RATING_THUMBNAIL = 'csfd-rating-thumbnail';
const CSFD_RATING_UNKNOWN = 'csfd-rating-unknown';
const CSFD_RATING_0_29 = 'csfd-rating-0-29';
const CSFD_RATING_30_69 = 'csfd-rating-30-69';
const CSFD_RATING_70_100 = 'csfd-rating-70-100';
const sheet = NETFLIX.styleSheets[NETFLIX.styleSheets.length - 1];
sheet.insertRule(
`.${CSFD_RATING_THUMBNAIL} {
position: absolute;
top: 3px;
right: 8px;
z-index: 5;
width: 20%;
text-align: center;
padding: 4%;
font-size: initial;
display: block;
border-radius: 4px;
filter: drop-shadow(rgba(0, 0, 0, 0.2) 2px 2px 1px);
backdrop-filter: blur(6px);
}`, sheet.cssRules.length);
sheet.insertRule(
`.${CSFD_RATING_0_29} {
background: rgba(83, 83, 83, 0.7);;
}`, sheet.cssRules.length);
sheet.insertRule(
`.${CSFD_RATING_30_69} {
background: rgb(101, 141, 180, 0.7);
}`, sheet.cssRules.length);
sheet.insertRule(
`.${CSFD_RATING_70_100} {
background: rgba(186, 3, 5, 0.7);
}`, sheet.cssRules.length);
sheet.insertRule(
`.${CSFD_RATING_UNKNOWN} {
background: rgba(78, 47, 28, 0.7);
}`, sheet.cssRules.length);
// browser.storage.local.clear();
(function listenForClicks() {
document.addEventListener("mouseover", (e) => {
console.log("hovering");
if (e.target.className === "previewModal--player-titleTreatmentWrapper") {
console.log("hovering-goofd");
const previewDiv = e.target.closest(".previewModal--container");
const showTitle = previewDiv.getElementsByClassName("previewModal--boxart")[0].alt;
const showDuration = previewDiv.getElementsByClassName("duration")[0].innerHTML.trim();
const showType = checkShowType(showDuration);
console.log("from hover: show title: " + showTitle + ", duration: " + showDuration + ", type of show: " + showType);
getInfoForShow(showTitle, showType);
}
})
document.addEventListener("click", (e) => {
const showPreviewModal = NETFLIX.getElementsByClassName(PREVIEW_MODAL_CLASS_NAME)[0];
if (!showPreviewModal) {
console.log("No show currently opened");
loadForOverView();
return;
}
const showTitle = showPreviewModal.getElementsByClassName(IMAGE_WITH_SHOW_TITLE_CLASS_NAME)[0].alt;
const showDuration = showPreviewModal.getElementsByClassName("duration")[0].innerHTML.trim();
const showType = checkShowType(showDuration);
console.log("show title: " + showTitle + ", duration: " + showDuration + ", type of show: " + showType);
if (NETFLIX.getElementsByClassName(CSFD_LINK_CLASS_NAME).length !== 0) {
return;
}
addCsfdInfoWithLink(showTitle, showType);
})
function storeTitleLinkAndRating(showTitle, csfdShowUrlResult, csfdShowScoreResult) {
return BROWSER_STORAGE.set({
[showTitle]: {
url: csfdShowUrlResult,
score: csfdShowScoreResult,
date: Date.now()
}
}).then(() => {
console.log("succesfully persisted now");
return BROWSER_STORAGE.get(showTitle).then(result => {
console.log("just persisted:");
console.log(result[showTitle]);
return result[showTitle];
});
});
}
function getInfoForShow(showTitle, showType) {
return BROWSER_STORAGE.get(showTitle).then(result => {
let showTitleInfo = result[showTitle];
if (showTitleInfo !== undefined) {
console.log("We have stored this before!");
console.log(showTitleInfo);
return showTitleInfo;
} else {
if (showType === SHOW_TYPE.UNKNOWN) {
console.log("We cannot safely retrieve the information");
return;
}
console.log("We have not yet retrieved this - we will do so now");
let csfdShowUrl = getCsfdUrlForShow(showTitle, showType);
let csfdScore = csfdShowUrl.then(getScoreForCsfdUrl);
return Promise.all([csfdShowUrl, csfdScore])
.then(([csfdShowUrlResult, csfdShowScoreResult]) => {
console.log("persisting now");
return storeTitleLinkAndRating(showTitle, csfdShowUrlResult, csfdShowScoreResult);
}
);
}
})
}
//This could be modified to use callback -> so we avoid the code duplication
function addCsfdInfoWithLink(showTitle, showType) {
getInfoForShow(showTitle, showType)
.then(result => {
appendLinkWithRating(result.url, result.score);
})
}
function getScoreForCsfdUrl(csfdShowUrl) {
return fetch(CSFD_URL + CSFD_FILM + csfdShowUrl)
.then(result => result.text())
.then(resultHtml => {
return getFirstElementWithClassName(resultHtml, "film-rating-average").innerHTML.trim();
})
}
function getCsfdUrlForShow(showTitle, showType) {
const csfdShowSearchUrl = CSFD_URL + "/hledat/?q=" + encodeURIComponent(showTitle);
return fetch(csfdShowSearchUrl)
.then(result => result.text())
.then(htmlText => {
const resultsBox = getFirstElementWithClassName(htmlText, showType === SHOW_TYPE.MOVIE ? "main-movies" : "main-series");
return resultsBox.getElementsByClassName("film-title-name")[0].getAttribute('href').replace(CSFD_FILM, "");
})
}
function appendLinkWithRating(csfdShowUrlResult, csfdShowScoreResult) {
const link = prepareLink(csfdShowUrlResult, " CSFD " + csfdShowScoreResult, CSFD_LINK_CLASS_NAME)
let matchScoreSpan = NETFLIX.getElementsByClassName("year")[0];
matchScoreSpan.appendChild(link);
}
function checkShowType(showDuration) {
let showType;
if (MOVIE_PATTERN.test(showDuration)) {
showType = SHOW_TYPE.MOVIE;
} else if (SERIES_PATTERN.test(showDuration)) {
showType = SHOW_TYPE.SERIES;
} else {
showType = SHOW_TYPE.UNKNOWN;
}
if (showType === SHOW_TYPE.UNKNOWN) {
throw showDuration + " does not match either movie or series pattern";
}
return showType;
}
function getFirstElementWithClassName(htmlText, className) {
let parsedHtml = DOM_PARSER.parseFromString(htmlText, "text/html");
return parsedHtml.getElementsByClassName(className)[0];
}
function loadForOverView() {
const overviewShowType = identifyScreenOverviewType();
let showThumbnailsCollection = document.getElementsByClassName("slider-item");
let showThumbnailsWithName = Array.from(showThumbnailsCollection).filter(element => element.getElementsByClassName("slider-refocus").length !== 0);
showThumbnailsWithName.forEach(thumbnail => {
if (thumbnail.getAttribute("csfd-rated") === "true") {
return;
}
let showName = thumbnail.getElementsByClassName("slider-refocus")[0].getAttribute("aria-label");
addCsfdInfoToThumbnail(showName, overviewShowType, thumbnail);
});
//This could be modified to use callback -> so we avoid the code duplication
function addCsfdInfoToThumbnail(showTitle, showType, thumbnail) {
console.log("getting info for " + showTitle + ": " + showType);
getInfoForShow(showTitle, showType)
.then(result => {
let a = document.createElement("a");
a.className = CSFD_RATING_THUMBNAIL;
a.classList.add(resolveRatingClass(result.score))
a.innerText = result.score;
a.href = CSFD_URL + CSFD_FILM + result.url;
a.setAttribute('target', '_blank');
thumbnail.appendChild(a);
thumbnail.setAttribute("csfd-rated", "true");
function resolveRatingClass(score) {
if (score === "? %") {
return CSFD_RATING_UNKNOWN;
}
const numericalScore = score.trim().replace("%", "") * 1;
let scoreStyleClass;
if (numericalScore > 69) {
scoreStyleClass = CSFD_RATING_70_100;
} else if (numericalScore > 29) {
scoreStyleClass = CSFD_RATING_30_69;
} else {
scoreStyleClass = CSFD_RATING_0_29;
}
return scoreStyleClass;
}
})
}
function identifyScreenOverviewType() {
let screenType;
if (SERIES_OVERVIEW_PATTERN.test(NETFLIX.title)) {
screenType = SHOW_TYPE.SERIES
} else if (MOVIE_OVERVIEW_PATTERN.test(NETFLIX.title)) {
screenType = SHOW_TYPE.MOVIE
} else {
screenType = SHOW_TYPE.UNKNOWN
}
return screenType;
}
}
function prepareLink(href, text, className) {
let a = document.createElement("a");
a.href = CSFD_URL + CSFD_FILM + href;
a.text = text;
a.className = className
a.setAttribute('target', '_blank');
return a;
}
})()