2020-12-09 22:26:29 +01:00
|
|
|
<!doctype html>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<title>Multiwatch</title>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
|
|
|
|
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
|
|
|
|
<style type="text/css">
|
|
|
|
body {
|
|
|
|
max-width: 600px;
|
|
|
|
margin: auto;
|
|
|
|
text-align: center;
|
|
|
|
font-family: sans-serif;
|
|
|
|
}
|
|
|
|
|
|
|
|
h1 a {
|
|
|
|
text-decoration: none;
|
|
|
|
color: black;
|
|
|
|
}
|
|
|
|
|
2020-12-12 12:28:54 +01:00
|
|
|
.flex {
|
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
}
|
|
|
|
|
|
|
|
.flex div {
|
|
|
|
width: 200px;
|
|
|
|
text-align: left;
|
|
|
|
}
|
|
|
|
|
2020-12-09 22:26:29 +01:00
|
|
|
.left {
|
|
|
|
text-align: left;
|
|
|
|
}
|
|
|
|
|
|
|
|
.error {
|
|
|
|
color: red;
|
|
|
|
font-weight: bold;
|
|
|
|
}
|
|
|
|
|
|
|
|
.pointer {
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
2020-12-14 20:34:17 +01:00
|
|
|
.poster {
|
|
|
|
height: 392px;
|
|
|
|
width: 276px;
|
|
|
|
display: inline-block;
|
|
|
|
background-color: gray;
|
|
|
|
margin: 1em;
|
|
|
|
}
|
|
|
|
|
2020-12-09 22:26:29 +01:00
|
|
|
.no-bullet {
|
|
|
|
list-style-type: none;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="app">
|
2020-12-12 12:28:54 +01:00
|
|
|
<h1><a href="./index.html">Multiwatch</a></h1>
|
|
|
|
<p v-if="step > 1"><a href="./index.html">Back</a></p>
|
2020-12-09 22:26:29 +01:00
|
|
|
|
|
|
|
<p v-if="error" class="error">{{ error }}</p>
|
|
|
|
|
|
|
|
<div v-if="step == 1">
|
|
|
|
<h2>Search</h2>
|
|
|
|
|
|
|
|
<form id="searchForm" v-on:submit.prevent="search">
|
|
|
|
<p>
|
|
|
|
<label for="title">Title:</label>
|
|
|
|
<input type="text" v-model="title" id="title" />
|
|
|
|
</p>
|
2020-12-12 12:28:54 +01:00
|
|
|
<h3>Countries</h3>
|
|
|
|
<div class="flex">
|
|
|
|
<div v-for="(localeId, country) in availableCountries">
|
|
|
|
<input type="checkbox" v-bind:id="localeId" v-bind:checked="checkedLocales.indexOf(localeId) !== -1" v-on:click="() => toggleCheckbox(localeId)">
|
|
|
|
<label v-bind:for="localeId">{{ country }}</label>
|
|
|
|
</div>
|
|
|
|
</div>
|
2020-12-09 22:26:29 +01:00
|
|
|
<p>
|
|
|
|
<input type="submit" value="Search"/>
|
|
|
|
</p>
|
|
|
|
</form>
|
|
|
|
</div>
|
2020-12-16 21:11:46 +01:00
|
|
|
<div v-else-if="step == 2">
|
|
|
|
<ul class="no-bullet">
|
2020-12-09 22:26:29 +01:00
|
|
|
<li v-for="(item, index) in searchItems">
|
2020-12-16 21:11:46 +01:00
|
|
|
<img class="pointer poster" v-bind:src="item.poster_url" v-bind:alt="item.title" v-on:click="() => preloadItem(index)" />
|
2020-12-09 22:26:29 +01:00
|
|
|
</li>
|
|
|
|
</ul>
|
2020-12-16 21:11:46 +01:00
|
|
|
</div>
|
|
|
|
<div v-else-if="step == 3">
|
|
|
|
<ul class="no-bullet">
|
|
|
|
<li v-for="(item, index) in seasons">
|
|
|
|
<img class="pointer poster" v-bind:src="item.poster_url" v-bind:alt="item.title" v-on:click="() => loadItem(index, true)" />
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<div v-else-if="step == 4">
|
|
|
|
<div v-for="(localeOffers, locale) in offers">
|
|
|
|
<h3>{{ availableLocales[locale] }}</h3>
|
|
|
|
<ul v-if="localeOffers.length > 0" class="left">
|
|
|
|
<li v-for="offer in localeOffers"><a v-bind:href="offer.url">{{ offer.url }}</a> [{{ offer.type.toUpperCase() }}]</li>
|
|
|
|
</ul>
|
|
|
|
<p v-else>None</p>
|
2020-12-09 22:26:29 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
2020-12-14 20:35:30 +01:00
|
|
|
var JUSTWATCH_API_DOMAIN = 'https://apis.justwatch.com';
|
|
|
|
|
2020-12-14 20:52:22 +01:00
|
|
|
var checkedLocales = JSON.parse(localStorage.getItem('checkedLocales'));
|
|
|
|
if (!checkedLocales) {
|
2020-12-16 21:11:46 +01:00
|
|
|
checkedLocales = ['fr_FR', 'en_AU', 'en_CA', 'de_DE', 'pl_PL', 'en_SG', 'en_GB'];
|
2020-12-14 20:52:22 +01:00
|
|
|
}
|
|
|
|
|
2020-12-09 22:26:29 +01:00
|
|
|
var app = new Vue({
|
|
|
|
el: '#app',
|
2020-12-12 12:28:54 +01:00
|
|
|
computed: {
|
|
|
|
availableLocales() {
|
|
|
|
var out = {};
|
|
|
|
Object.keys(this.availableCountries).forEach((country) => {
|
|
|
|
out[this.availableCountries[country]] = country;
|
|
|
|
});
|
|
|
|
return out;
|
|
|
|
},
|
|
|
|
},
|
2020-12-09 22:26:29 +01:00
|
|
|
data: {
|
2020-12-14 20:52:22 +01:00
|
|
|
checkedLocales: checkedLocales,
|
2020-12-12 12:28:54 +01:00
|
|
|
availableCountries: {
|
|
|
|
"Afghanistan": "ps_AF",
|
|
|
|
"Albania": "sq_AL",
|
|
|
|
"Algeria": "ar_DZ",
|
|
|
|
"Andorra": "ca_AD",
|
|
|
|
"Antigua And Barbuda": "en_AG",
|
|
|
|
"Argentina": "es_AR",
|
|
|
|
"Armenia": "hy_AM",
|
|
|
|
"Aruba": "nl_AW",
|
|
|
|
"Australia": "en_AU",
|
|
|
|
"Austria": "de_AT",
|
|
|
|
"Azerbaijan": "az_AZ",
|
|
|
|
"Bahrain": "ar_BH",
|
|
|
|
"Bangladesh": "bn_BD",
|
|
|
|
"Belarus": "be_BY",
|
|
|
|
"Belgium": "fr_BE",
|
|
|
|
"Bhutan": "dz_BT",
|
|
|
|
"Bolivia": "es_BO",
|
|
|
|
"Bosnia And Herzegovina": "bs_BA",
|
|
|
|
"Botswana": "en_BW",
|
|
|
|
"Brazil": "pt_BR",
|
|
|
|
"Bulgaria": "bg_BG",
|
|
|
|
"Cambodia": "km_KH",
|
|
|
|
"Canada": "en_CA",
|
|
|
|
"Chile": "es_CL",
|
|
|
|
"China": "zh_CN",
|
|
|
|
"Colombia": "es_CO",
|
|
|
|
"Costa Rica": "es_CR",
|
|
|
|
"Croatia": "hr_HR",
|
|
|
|
"Cyprus": "el_CY",
|
|
|
|
"Czech Republic": "cs_CZ",
|
|
|
|
"Denmark": "da_DK",
|
|
|
|
"Djibouti": "so_DJ",
|
|
|
|
"Dominican Republic": "es_DO",
|
|
|
|
"Ecuador": "es_EC",
|
|
|
|
"Egypt": "ar_EG",
|
|
|
|
"El Salvador": "es_SV",
|
|
|
|
"Eritrea": "tig_ER",
|
|
|
|
"Estonia": "et_EE",
|
|
|
|
"Ethiopia": "am_ET",
|
|
|
|
"Faroe Islands": "fo_FO",
|
|
|
|
"Finland": "fi_FI",
|
|
|
|
"France": "fr_FR",
|
|
|
|
"Georgia": "ka_GE",
|
|
|
|
"Germany": "de_DE",
|
|
|
|
"Greece": "el_GR",
|
|
|
|
"Greenland": "kl_GL",
|
|
|
|
"Guatemala": "es_GT",
|
|
|
|
"Haiti": "ht_HT",
|
|
|
|
"Honduras": "es_HN",
|
|
|
|
"Hong Kong": "en_HK",
|
|
|
|
"Hungary": "hu_HU",
|
|
|
|
"Iceland": "is_IS",
|
|
|
|
"India": "en_IN",
|
|
|
|
"Indonesia": "id_ID",
|
|
|
|
"Iran, Islamic Republic Of": "fa_IR",
|
|
|
|
"Iraq": "ar_IQ",
|
|
|
|
"Ireland": "en_IE",
|
|
|
|
"Israel": "he_IL",
|
|
|
|
"Italy": "it_IT",
|
|
|
|
"Japan": "ja_JP",
|
|
|
|
"Jordan": "ar_JO",
|
|
|
|
"Kazakhstan": "kk_KZ",
|
|
|
|
"Kenya": "om_KE",
|
|
|
|
"Korea, Republic Of": "ko_KR",
|
|
|
|
"Kuwait": "ar_KW",
|
|
|
|
"Kyrgyzstan": "ky_KG",
|
|
|
|
"Latvia": "lv_LV",
|
|
|
|
"Lebanon": "ar_LB",
|
|
|
|
"Libyan Arab Jamahiriya": "ar_LY",
|
|
|
|
"Liechtenstein": "de_LI",
|
|
|
|
"Lithuania": "lt_LT",
|
|
|
|
"Luxembourg": "fr_LU",
|
|
|
|
"Macedonia": "mk_MK",
|
|
|
|
"Madagascar": "mg_MG",
|
|
|
|
"Malaysia": "ms_MY",
|
|
|
|
"Maldives": "dv_MV",
|
|
|
|
"Malta": "mt_MT",
|
|
|
|
"Mexico": "es_MX",
|
|
|
|
"Mongolia": "mn_MN",
|
|
|
|
"Morocco": "ar_MA",
|
|
|
|
"Myanmar": "my_MM",
|
|
|
|
"Nepal": "ne_NP",
|
|
|
|
"Netherlands": "nl_NL",
|
|
|
|
"Netherlands Antilles": "pap_AN",
|
|
|
|
"New Zealand": "en_NZ",
|
|
|
|
"Nicaragua": "es_NI",
|
|
|
|
"Nigeria": "en_NG",
|
|
|
|
"Norway": "no_NO",
|
|
|
|
"Oman": "ar_OM",
|
|
|
|
"Pakistan": "pa_PK",
|
|
|
|
"Panama": "es_PA",
|
|
|
|
"Paraguay": "es_PY",
|
|
|
|
"Peru": "es_PE",
|
|
|
|
"Philippines": "en_PH",
|
|
|
|
"Poland": "pl_PL",
|
|
|
|
"Portugal": "pt_PT",
|
|
|
|
"Puerto Rico": "es_PR",
|
|
|
|
"Qatar": "ar_QA",
|
|
|
|
"Romania": "ro_RO",
|
|
|
|
"Russian Federation": "ru_RU",
|
|
|
|
"Rwanda": "rw_RW",
|
|
|
|
"Saudi Arabia": "ar_SA",
|
|
|
|
"Senegal": "wo_SN",
|
|
|
|
"Serbia And Montenegro": "sr_CS",
|
|
|
|
"Singapore": "en_SG",
|
|
|
|
"Slovakia": "sk_SK",
|
|
|
|
"Slovenia": "sl_SI",
|
|
|
|
"Somalia": "so_SO",
|
|
|
|
"South Africa": "af_ZA",
|
|
|
|
"Spain": "es_ES",
|
|
|
|
"Sri Lanka": "si_LK",
|
|
|
|
"Sudan": "ar_SD",
|
|
|
|
"Sweden": "sv_SE",
|
|
|
|
"Switzerland": "fr_CH",
|
|
|
|
"Syrian Arab Republic": "ar_SY",
|
|
|
|
"Taiwan": "zh_TW",
|
|
|
|
"Tajikistan": "tg_TJ",
|
|
|
|
"Thailand": "th_TH",
|
|
|
|
"Tunisia": "ar_TN",
|
|
|
|
"Turkey": "tr_TR",
|
|
|
|
"Turkmenistan": "tk_TM",
|
|
|
|
"Uganda": "lg_UG",
|
|
|
|
"Ukraine": "uk_UA",
|
|
|
|
"United Arab Emirates": "ar_AE",
|
|
|
|
"United Kingdom": "en_GB",
|
|
|
|
"United States": "en_US",
|
|
|
|
"Uruguay": "es_UY",
|
|
|
|
"Uzbekistan": "uz_UZ",
|
|
|
|
"Venezuela": "es_VE",
|
|
|
|
"Viet Nam": "vi_VN",
|
|
|
|
"Yemen": "ar_YE",
|
|
|
|
"Zimbabwe": "en_ZW"
|
2020-12-09 22:26:29 +01:00
|
|
|
},
|
|
|
|
error: null,
|
|
|
|
title: '',
|
|
|
|
searchItems: [],
|
|
|
|
offers: {},
|
2020-12-16 21:11:46 +01:00
|
|
|
seasons: {},
|
2020-12-09 22:26:29 +01:00
|
|
|
step: 1,
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
search() {
|
2020-12-14 20:48:51 +01:00
|
|
|
fetch(`${JUSTWATCH_API_DOMAIN}/content/titles/fr_FR/popular?language=fr&body={"page_size":20,"page":1,"query":"${this.title}","content_types":["show","movie"]}`)
|
2020-12-09 22:26:29 +01:00
|
|
|
.then(response => response.json())
|
|
|
|
.then(response => {
|
|
|
|
this.error = null;
|
|
|
|
if (!response.items || response.items.length == 0) {
|
|
|
|
this.error = 'Not found'
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.searchItems = response.items.map((item) => {
|
2020-12-14 20:34:17 +01:00
|
|
|
var poster = null;
|
|
|
|
if (item['poster']) {
|
|
|
|
poster = item['poster'].replace('{profile}', 's276');
|
|
|
|
}
|
2020-12-09 22:26:29 +01:00
|
|
|
return {
|
|
|
|
id: item.id,
|
|
|
|
title: item.title,
|
|
|
|
type: item.object_type,
|
2020-12-14 20:34:17 +01:00
|
|
|
poster_url: `https://images.justwatch.com${poster}`
|
2020-12-09 22:26:29 +01:00
|
|
|
};
|
|
|
|
});
|
2020-12-16 21:11:46 +01:00
|
|
|
|
2020-12-09 22:26:29 +01:00
|
|
|
this.step += 1;
|
|
|
|
})
|
|
|
|
.catch(exc => this.error = exc);
|
|
|
|
},
|
2020-12-12 12:28:54 +01:00
|
|
|
toggleCheckbox(localeId) {
|
|
|
|
if (this.checkedLocales.indexOf(localeId) !== -1) {
|
|
|
|
var index = this.checkedLocales.indexOf(localeId);
|
|
|
|
this.checkedLocales.splice(index, 1);
|
|
|
|
} else {
|
|
|
|
this.checkedLocales.push(localeId);
|
|
|
|
}
|
2020-12-14 20:52:22 +01:00
|
|
|
|
|
|
|
localStorage.setItem('checkedLocales', JSON.stringify(this.checkedLocales));
|
2020-12-12 12:28:54 +01:00
|
|
|
},
|
2020-12-16 21:11:46 +01:00
|
|
|
preloadItem(index) {
|
|
|
|
var searchItem = this.searchItems[index];
|
|
|
|
fetch(`${JUSTWATCH_API_DOMAIN}/content/titles/${searchItem.type}/${searchItem.id}/locale/fr-FR?language=fr`)
|
|
|
|
.then(response => response.json())
|
|
|
|
.then(response => {
|
|
|
|
this.seasons = {};
|
|
|
|
if (response.seasons && response.seasons.length > 0) {
|
|
|
|
this.seasons = response.seasons.map((item) => {
|
|
|
|
var poster = null;
|
|
|
|
if (item['poster']) {
|
|
|
|
poster = item['poster'].replace('{profile}', 's276');
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
id: item.id,
|
|
|
|
title: item.title,
|
|
|
|
type: item.object_type,
|
|
|
|
poster_url: `https://images.justwatch.com${poster}`
|
|
|
|
};
|
|
|
|
});
|
|
|
|
this.step += 1;
|
|
|
|
} else {
|
|
|
|
this.step += 1;
|
|
|
|
this.loadItem(index, false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
loadItem(index, isSeason) {
|
2020-12-09 22:26:29 +01:00
|
|
|
this.offers = {};
|
|
|
|
this.error = null;
|
|
|
|
|
|
|
|
var promises = [];
|
2020-12-12 12:28:54 +01:00
|
|
|
this.checkedLocales.forEach((locale) => {
|
2020-12-09 22:26:29 +01:00
|
|
|
var searchItem = this.searchItems[index];
|
2020-12-16 21:11:46 +01:00
|
|
|
if (isSeason) {
|
|
|
|
searchItem = this.seasons[index];
|
|
|
|
}
|
2020-12-14 20:35:30 +01:00
|
|
|
var url = `${JUSTWATCH_API_DOMAIN}/content/titles/${searchItem.type}/${searchItem.id}/locale/${locale}?language=fr`
|
2020-12-09 22:26:29 +01:00
|
|
|
promises.push(fetch(url)
|
|
|
|
.then(response => response.json())
|
|
|
|
.then(response => {
|
|
|
|
if (!response.offers) {
|
2020-12-12 12:38:20 +01:00
|
|
|
this.offers[locale] = [];
|
2020-12-09 22:26:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.offers[locale] = response.offers
|
|
|
|
.filter(item => item.monetization_type == 'flatrate')
|
2020-12-16 21:11:46 +01:00
|
|
|
.map(item => {
|
|
|
|
return {
|
|
|
|
url: item.urls.standard_web,
|
|
|
|
type: item.presentation_type,
|
|
|
|
}
|
|
|
|
});
|
2020-12-09 22:26:29 +01:00
|
|
|
this.offers[locale] = [...new Set(this.offers[locale])];
|
|
|
|
})
|
|
|
|
.catch(exc => this.error = exc)
|
|
|
|
);
|
|
|
|
})
|
|
|
|
Promise.all(promises).then(() => this.step += 1);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|