Skip to content

Instantly share code, notes, and snippets.

@nunof07
Last active February 14, 2020 14:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nunof07/fa7a0e6427c2711f5612f02af3412b27 to your computer and use it in GitHub Desktop.
Save nunof07/fa7a0e6427c2711f5612f02af3412b27 to your computer and use it in GitHub Desktop.
Search for movies in Portuguese streaming services
// ==UserScript==
// @name PT Movie Search
// @namespace https://www.quasibit.com/
// @downloadUrl https://gist.github.com/raw/fa7a0e6427c2711f5612f02af3412b27/ptmoviesearch.user.js
// @updateUrl https://gist.github.com/raw/fa7a0e6427c2711f5612f02af3412b27/ptmoviesearch.user.js
// @match *://*/*
// @grant GM_openInTab
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @noframes
// @version 1.0.7
// ==/UserScript==
(function () {
'use strict';
class Storage {
constructor(id) {
this.id = id;
}
key(key) {
return `${this.id}.${key}`;
}
get(key) {
return GM_getValue(this.key(key));
}
set(key, value) {
return GM_setValue(this.key(key), value);
}
}
class Source {
constructor({ uri, encode = encodeURI, storage = null }) {
this.uri = uri;
this.encode = encode;
this.storage = storage;
}
static from(source) {
if (source instanceof Source) {
return source;
} else if (typeof source === 'string') {
return new Source({ uri: source });
}
return new Source(source);
}
isOrigin() {
return this.uri.includes(window.location.origin);
}
queries() {
const queries = this.storage && this.storage.get('queries');
return queries || [];
}
setupStorage() {
if (this.storage) {
return;
}
const uriMatches = this.uri.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
const id = uriMatches && uriMatches[1];
this.storage = new Storage(id);
}
setup(search) {
this.setupStorage();
if (!this.isOrigin()) {
return;
}
const query = search.lastQuery();
const isQueryProcessed = this.queries().some(processed => processed.date === query.date);
if (!isQueryProcessed) {
this.processQuery(query);
this.storage.set('queries', this.queries().concat([query]));
}
}
processQuery(query) {
}
search(title) {
GM_openInTab(
this.uri.replace('{title}', this.encode(title))
);
}
}
class Filmin extends Source {
constructor(source) {
super(source);
}
processQuery(query) {
const searchButton = document.querySelector('.search-btn');
const searchInput = document.querySelector('#searcher input[name="query"]');
if (!query.title || !searchButton || !searchInput) {
return;
}
searchButton.click();
searchInput.value = query.title;
setTimeout(
() => searchInput.dispatchEvent(new KeyboardEvent('keyup')),
250
);
}
}
class Justwatch extends Source {
constructor(source) {
super(source);
}
processQuery(query) {
const delay = 2000;
setTimeout(
() => {
const searchBar = document.querySelector('ion-searchbar');
const searchInput = document.querySelector('.searchbar-input');
if (!query.title || !searchBar || !searchInput) {
return;
}
searchBar.click();
searchInput.value = query.title;
searchInput.dispatchEvent(new Event('input'));
setTimeout(
() => {
const searchButton = document.querySelector('.searchsuggester-results ion-button');
if (!searchButton) {
return;
}
searchButton.click();
},
1500
);
},
delay
);
}
}
class Netflix extends Source {
constructor(source) {
super(source);
}
processQuery(query) {
const profileLinks = document.querySelectorAll('.choose-profile .profile .profile-link');
const isAskingForProfile = profileLinks.length > 0;
if (!isAskingForProfile) {
return;
}
profileLinks[0].click();
}
}
class Search {
constructor(sources) {
this.sources = sources;
this.storage = new Storage('search');
}
setup() {
this.sources = this.sources.map(source => Source.from(source));
this.sources.forEach(source => source.setup(this));
}
lastQuery() {
return {
title: this.storage.get('title'),
date: this.storage.get('date'),
};
}
search() {
const title = window.prompt('Search for movie');
if (!title) {
return;
}
this.storage.set('title', title);
this.storage.set('date', (new Date()).toISOString());
this.sources.forEach(source => source.search(title));
}
}
function main() {
const search = new Search([
new Netflix({ uri: 'https://www.netflix.com/search?q={title}' }),
'https://www.primevideo.com/search/ref=atv_nb_sr?phrase={title}&ie=UTF8',
'https://play.google.com/store/search?q={title}&c=movies',
'https://www.cineteka.com/index.php?op=MovieSearch&s={title}',
new Filmin({ uri: 'https://www.filmin.pt/' }),
{
uri: 'https://hboportugal.com/search/{title}',
encode: title => encodeURI(title).replace(/%20/g, '-'),
},
'https://rakuten.tv/pt/search/{title}',
new Justwatch({ uri: 'https://www.justwatch.com/pt' }),
]);
search.setup();
GM_registerMenuCommand('Search', () => search.search(), 'm');
}
main();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment