您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
nopremium.pl and premiumize.me. Inserts a direct download link on several one-click-hosters and some container/folder providers.
当前为
- // ==UserScript==
- // @name Multi-OCH Helper
- // @namespace cuzi
- // @license MIT
- // @description nopremium.pl and premiumize.me. Inserts a direct download link on several one-click-hosters and some container/folder providers.
- // @homepageURL https://openuserjs.org/scripts/cuzi/Multi-OCH_Helper
- // @contributionURL https://buymeacoff.ee/cuzi
- // @contributionURL https://ko-fi.com/cuzicvzi
- // @icon https://raw.githubusercontent.com/cvzi/Userscripts/master/Multi-OCH/icons/helper.png
- // @version 17.1.2
- // @match https://cvzi.github.io/Userscripts/index.html?link=*
- // @match https://www.nopremium.pl/files*
- // @match https://www.premiumize.me/hosters/*
- // @match https://www.premiumize.me/services/*
- // @match https://www.premiumize.me/downloader*
- // @match https://*.filecrypt.cc/Container/*
- // @match https://*.filecrypt.cc/helper.html*
- // @match https://protected.to/*
- // @match https://rapidgator.net/folder/*
- // @match https://safelinking.net/p/*
- // @match https://multiup.org/*
- // @match https://1fichier.com/*
- // @match https://*.1fichier.com/*
- // @match https://www.4shared.com/*
- // @match https://alfafile.net/*
- // @match https://*.alfafile.net/*
- // @match https://anonfiles.com/*
- // @match https://bayfiles.com/*
- // @match https://*.bayfiles.com/*
- // @match http://clicknupload.link/*
- // @match https://clicknupload.to/*
- // @match https://clicknupload.org/*
- // @match https://clicknupload.co/*
- // @match https://clicknupload.cc/*
- // @match https://clicknupload.to/*
- // @match https://clicknupload.club/*
- // @match https://clicknupload.click/*
- // @match https://dailyuploads.net/*
- // @match https://ddl.to/*
- // @match https://ddownload.com/*
- // @match https://*.dropapk.com/*
- // @match https://dropapk.com/*
- // @match https://*.drop.download.com/*
- // @match https://drop.download.com/*
- // @match https://fastclick.to/*
- // @match https://fastshare.cz/*
- // @match https://file.al/*
- // @match https://www.file.al/*
- // @match https://filefactory.com/*
- // @match https://www.filefactory.com/*
- // @match https://filenext.com/*
- // @match https://www.filenext.com/*
- // @match https://filer.net/*
- // @match https://filerice.com/*
- // @match https://filespace.com/*
- // @match https://filestore.to/*
- // @match http://fireget.com/*
- // @match https://fireget.com/*
- // @match https://hitfile.net/*
- // @match https://hil.to/*
- // @match https://isra.cloud/*
- // @match https://katfile.com/*
- // @match https://www.mediafire.com/*
- // @match https://mediafire.com/*
- // @match https://mega.nz/*
- // @match https://megaup.net/*
- // @match https://mixdrop.co/*
- // @match https://modsbase.com/*
- // @match https://nitroflare.com/*
- // @match https://rapidgator.net/file/*
- // @match https://rg.to/file/*
- // @match https://spicyfile.com/*
- // @match https://www.spicyfile.com/*
- // @match https://turbobit.net/*
- // @match https://turb.to/*
- // @match https://tusfiles.net/*
- // @match https://ubiqfile.com/*
- // @match https://uploadboy.com/*
- // @match https://uploadgig.com/*
- // @match https://uptobox.com/*
- // @match https://userscloud.com/*
- // @match https://vidoza.org/*
- // @match https://worldbytez.com/*
- // @match https://wrzucajpliki.pl/*
- // @match https://xubster.com/*
- // @match https://*.zippyshare.com/*
- // @require https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js
- // @require https://greasyfork.org/scripts/13883-aes-js/code/aesjs.js
- // @grant GM.registerMenuCommand
- // @grant unsafeWindow
- // @grant GM_setClipboard
- // @grant GM.xmlHttpRequest
- // @grant GM.openInTab
- // @grant GM.setClipboard
- // @grant GM.setValue
- // @grant GM.getValue
- // @grant GM.deleteValue
- // @grant GM.listValues
- // ==/UserScript==
- /* globals confirm, alert, GM, GM_setClipboard, unsafeWindow, $, atob, slowAES, cloneInto */
- /* eslint n/no-callback-literal: 0 */
- (async function () {
- 'use strict'
- // And to keep for myself whatever I may find? - Certainly. For yourself, and any friends you want to share with you.
- // This program inserts a download link on One-Click-Hosters and a few folder services.
- // If you click on the button, the current website address (or the links on the relink website) will be sent to nopremium.pl and you'll receive a nopremium.pl download link.
- //
- // Standard actions for the button are
- // * left mouse click: copy the link to the clipboard
- // * middle/wheel click: start download of the link
- // * right mouse click: open the nopremium.pl website and insert the link in the text box
- // * hovering the mouse over the button: open a menu with all the above option
- //
- const scriptName = 'Multi-OCH Helper'
- const scriptReferer = 'multiochhelper'
- const scriptHightligherName = 'Multi-OCH Helper Highlight links'
- const chrome = ~navigator.userAgent.indexOf('Chrome')
- const greasemonkey = 'info' in GM && 'scriptHandler' in GM.info && GM.info.scriptHandler === 'Greasemonkey'
- const config = {
- position: [['bottom', 'top'], ['left', 'right']],
- position_desc: ['vertical', 'horizontal'],
- position_quest: 'Position of the Button. If you use "' + scriptHightligherName + '" this has to be set to bottom left',
- leftClick: ['clipboard', 'download', 'showLinks', 'openWebsite', 'menu', 'sendToJD', 'none'],
- leftClick_desc: ['Copy link to clipboard', 'Direct download', 'Show links like on website', 'Open the multihoster website', 'Show the extended menu', 'Send links to JDownloader', 'Do nothing'],
- leftClick_quest: 'Action on left mouse click on button',
- middleClick: ['download', 'clipboard', 'showLinks', 'openWebsite', 'menu', 'sendToJD', 'none'],
- middleClick_desc: ['Direct download', 'Copy link to clipboard', 'Show links like on website', 'Open the multihoster website', 'Show the extended menu', 'Send links to JDownloader', 'Do nothing'],
- middleClick_quest: 'Action on middle mouse/wheel click on button',
- rightClick: ['openWebsite', 'clipboard', 'showLinks', 'download', 'menu', 'sendToJD', 'none'],
- rightClick_desc: ['Show links like on website', 'Copy link to clipboard', 'Direct download', 'Open the multihoster website', 'Show the extended menu', 'Send links to JDownloader', 'Do nothing'],
- rightClick_quest: 'Action on right mouse click on button',
- mouseOver: ['menu', 'clipboard', 'download', 'showLinks', 'openWebsite', 'sendToJD', 'none'],
- mouseOver_desc: ['Show the extended menu', 'Copy link to clipboard', 'Direct download', 'Show links like on website', 'Open the multihoster website', 'Send links to JDownloader', 'Do nothing'],
- mouseOver_quest: 'Action on mouse hover over button',
- mouseOverDelay: 'int',
- mouseOverDelay_range: [0, 700, 3000],
- mouseOverDelay_quest: 'Mouse hover time before action is executed.',
- mouseOverDelay_suffix: 'milliseconds',
- newTab: 'bool',
- newTab_desc: ['Open in a new tab', 'Open in the same window'],
- newTab_quest: 'Should websites be opened in a new tab?',
- updateHosterStatusInterval: 'int',
- updateHosterStatusInterval_range: [1, 168, 9999],
- updateHosterStatusInterval_quest: 'How often should the status of the hosters be updated?',
- updateHosterStatusInterval_prefix: 'Every',
- updateHosterStatusInterval_suffix: 'hours',
- jDownloaderSupport: 'bool',
- jDownloaderSupport_desc: ['Show JDownloader button if JDownloader is runnning', 'Never show JDownloader button'],
- jDownloaderSupport_quest: ['Show a JDownloader button in the menu?']
- }
- const settings = {}
- // Load settings
- const savedsettings = JSON.parse(await GM.getValue('settings', '{}')) // e.g. { position : [0,1], newTab : 1 }
- for (const key in config) {
- if (key in savedsettings) { // Saved
- if (config[key] === 'int') { // Int
- settings[key] = parseInt(savedsettings[key], 10)
- } else if (config[key] === 'string') { // String
- settings[key] = savedsettings[key].toString()
- } else if (config[key] === 'bool') { // Bool
- settings[key] = (savedsettings[key] === 'true' || savedsettings[key] === true)
- } else if (Array.isArray(config[key][0])) { // Nested array
- if (!Array.isArray(savedsettings[key])) {
- try {
- const tmp = JSON.parse(savedsettings[key])
- if (Array.isArray(tmp)) {
- savedsettings[key] = tmp
- }
- } catch (e) {}
- }
- settings[key] = []
- for (let i = 0; i < savedsettings[key].length; i++) {
- settings[key].push(savedsettings[key][i])
- }
- } else { // Array
- settings[key] = savedsettings[key]
- }
- } else { // Default
- if (config[key] === 'int') { // Int
- settings[key] = config[key + '_range'][1]
- } else if (config[key] === 'string') { // String
- settings[key] = '' // String defaults to empty string
- } else if (config[key] === 'bool') { // Bool
- settings[key] = true
- } else if (Array.isArray(config[key][0])) { // Nested array defaults to first value for each array
- settings[key] = []
- for (let i = 0; i < config[key].length; i++) {
- settings[key].push(config[key][i][0])
- }
- } else {
- settings[key] = config[key][0] // Array defaults to first value
- }
- }
- }
- const JDOWNLOADER = 'http://127.0.0.1:9666/'
- const SPINNERCSS = `/* http://www.designcouch.com/home/why/2013/05/23/dead-simple-pure-css-loading-spinner/ */
- .ochspinner {
- height:16px;
- width:16px;
- margin:0px auto;
- position:relative;
- animation: rotation .6s infinite linear;
- border-left:6px solid rgba(0,174,239,.15);
- border-right:6px solid rgba(0,174,239,.15);
- border-bottom:6px solid rgba(0,174,239,.15);
- border-top:6px solid rgba(0,174,239,.8);
- border-radius:100%;
- }
- @keyframes rotation {
- from {transform: rotate(0deg)}
- to {transform: rotate(359deg)}
- }
- `
- // const LOADINGBARBG = 'background: #b4e391;background: linear-gradient(to bottom, #b4e391 0%,#61c419 50%,#b4e391 100%);'
- let showOneclickButton = false
- let showOneclickLink = ''
- let showOneclickFromHighlighScriptAllLinks = document.location.host === 'cvzi.github.io'
- let showOneclickFromHighlighScriptAllLinksLoc = false
- let showOneclickFromHighlighScriptAllLinksLinks = ''
- let showOneclickFromHighlighScriptSelectedLinks = false
- let showOneclickFromHighlighScriptSelectedLinksLoc = false
- let showOneclickFromHighlighScriptSelectedLinksLinks = ''
- let linksBeforeSelection = false
- const multi = {
- 'premiumize.me': new function () {
- const self = this
- this.config = {
- apikey: 'string',
- apikey_hidden: true,
- apikey_quest: 'Enter your premiumize.me API key',
- apikey_prefix: 'API key: ',
- apikey_suffix: ' find it under <a target="_blank" href="https://www.premiumize.me/account">https://www.premiumize.me/account</a>'
- }
- this.key = 'premiumize.me'
- this.name = 'premiumize'
- this.homepage = 'https://www.premiumize.me/'
- // this.updateStatusURL = 'https://www.premiumize.me/services';
- this.updateStatusURLpattern = /https:\/\/www\.premiumize\.me\/services\/?/
- this.updateDownloadProgressInterval = 5000
- this.updateDownloadProgressInterfaceInterval = 500
- this.status = {}
- this.init = async function () {
- self.status = JSON.parse(await GM.getValue(self.key + '_status', '{}'))
- self.lastUpdate = new Date(await GM.getValue(self.key + '_status_time', 0))
- }
- this.settings = {}
- this.loadSettings = async function (silent) {
- // Load settings, use first value as default
- const savedsettings = JSON.parse(await GM.getValue(self.key + '_settings', '{}'))
- for (const key in self.config) {
- if (key.endsWith('desc') || key.endsWith('range') || key.endsWith('quest') || key.endsWith('prefix') || key.endsWith('suffix')) {
- continue
- }
- if (key in savedsettings) { // Saved
- if (self.config[key] === 'int') { // Int
- self.settings[key] = parseInt(savedsettings[key], 10)
- } else if (self.config[key] === 'string') { // String
- self.settings[key] = savedsettings[key].toString()
- } else if (config[key] === 'bool') { // Bool
- self.settings[key] = savedsettings[key] === 'true' || savedsettings[key] === true
- } else if (Array.isArray(savedsettings[key])) { // Nested array
- self.settings[key] = []
- for (let i = 0; i < savedsettings[key].length; i++) {
- self.settings[key].push(savedsettings[key][i])
- }
- } else { // Array
- self.settings[key] = savedsettings[key]
- }
- } else { // Default
- if (self.config[key] === 'int') { // Int
- self.settings[key] = self.config[key + '_range'][1]
- } else if (self.config[key] === 'string') { // String
- self.settings[key] = '' // String defaults to empty string
- } else if (config[key] === 'bool') { // Bool
- self.settings[key] = true
- } else if (Array.isArray(self.config[key][0])) { // Nested array defaults to first value for each array
- self.settings[key] = []
- for (let i = 0; i < self.config[key].length; i++) {
- self.settings[key].push(self.config[key][i][0])
- }
- } else {
- self.settings[key] = self.config[key][0] // Array defaults to first value
- }
- }
- }
- if (!self.settings.apikey && !silent) {
- // Try to get the apikey from the website
- GM.xmlHttpRequest({
- method: 'GET',
- url: self.homepage + 'account',
- onerror: function (response) {
- console.log(scriptName + ': premiumize.me API Key could not be loaded')
- setStatus('You have not set you premiumize.me Api key ')
- },
- onload: function (response) {
- let s = ''
- try {
- s = response.responseText.split('class="apipass"')[1].split('</')[0].split('>')[1]
- } catch (e) {
- }
- if (s) {
- self.settings.apikey = s
- GM.setValue(self.key + '_settings', JSON.stringify(self.settings))
- console.log(scriptName + ': premiumize.me API Key was loaded from account and saved!')
- } else {
- setStatus('You need to set you premiumize.me Api key')
- }
- }
- })
- }
- }
- this.updateStatus = async function () { // Update list of online hosters
- await self.loadSettings()
- if (document.location.href.match(self.updateStatusURL)) {
- // Read and save current status of all hosters
- if ($('table.table tr>td:first-child').length) {
- self.status = {}
- await GM.setValue(self.key + '_status_time', '' + (new Date()))
- $('table.table tr>td:first-child').each(function () {
- const text = $(this).text()
- if (text.match(/^\s*[0-9a-z-]+\.\w{0,6}\s*$/i)) {
- const name = text.match(/^\s*([0-9a-z-]+)\.\w{0,6}\s*$/i)[1]
- self.status[name.toLowerCase()] = true
- }
- })
- await GM.setValue(self.key + '_status', JSON.stringify(self.status))
- console.log(scriptName + ': ' + self.name + ': Hosters (' + Object.keys(self.status).length + ') updated')
- } else if (self.settings.apikey) {
- GM.xmlHttpRequest({
- method: 'GET',
- url: self.homepage + 'api/services/list?apikey=' + encodeURIComponent(self.settings.apikey),
- onerror: function (response) {
- console.log(scriptName + ': GM.xmlHttpRequest error: ' + self.homepage + 'api/services/list')
- console.log(response)
- },
- onload: async function (response) {
- const result = JSON.parse(response.responseText)
- /*
- { "cache": [ "uploaded.to", "filefactory.com", ... ], "directdl": [ "uploaded.to", "filefactory.com", ... ] }
- */
- if ('cache' in result && 'directdl' in result) {
- self.status = {}
- await GM.setValue(self.key + '_status_time', '' + (new Date()))
- result.cache.forEach(function (host) {
- const name = host.match(/^\s*([0-9a-z-]+)\.\w{0,6}\s*$/i)[1]
- self.status[name.toLowerCase()] = result.directdl.indexOf(host) !== -1
- })
- await GM.setValue(self.key + '_status', JSON.stringify(self.status))
- console.log(scriptName + ': ' + self.name + ': Hosters (' + Object.keys(self.status).length + ') updated')
- } else {
- console.log(scriptName + ': GM.xmlHttpRequest error: ' + self.homepage + 'api/services/list')
- console.log(response)
- }
- }
- })
- } else {
- console.log(scriptName + ': Cannot update hosters, no html and no api key found')
- }
- } else {
- alert(scriptName + '\n\nError: wrong update URL')
- }
- }
- this.isOnline = hostername => hostername in self.status && self.status[hostername]
- this.getOpenWebsiteURL = function (urls) {
- // Return a link to the premiumize.me website that will insert the links
- const url = this.homepage + 'downloader?link:' + encodeURIComponent(urls.join('\n'))
- return url
- }
- this.checkLink = function (url, cb) { // check whether the link is supported and online
- const host = url.match(/https?:\/\/(.+?)\//)[1]
- let hoster = host.split('.')
- hoster.pop()
- hoster = hoster.pop().replace('-', '')
- cb(this.isOnline(hoster))
- }
- this.getResults = function (urls, cb) {
- // cb($node,linkNumber) -- $node contains the result, linkNumber is the number of links that should be online i.e. number of hashes
- alert('This function does not work for ' + this.name)
- }
- this._notLoggedIn = false
- this.getLinks = async function (urls, cb) {
- await showConfirm('fairPointsWarning', 'You will be charged premiumize fair points for generating ' + (urls.length > 1 ? ('<b>' + urls.length + '</b> files') : ('<b>one</b> file')) + '!<br><br>Generate links?', function () { self._getLinks(urls, cb) }, function () { setStatus('Operation canceled!', 0); cb([], -1) }, self)
- }
- this._getLinks = function (urls, cb) {
- setTitle('✈️' + urls.length + '🔗 ')
- const N = urls.length
- const downloadLinks = []
- const errors = []
- for (let i = 0; i < urls.length; i++) {
- this._addSingleTransfer(urls[i], function (downloadlink, originallink, message) {
- if (downloadlink) {
- downloadLinks.push(downloadlink)
- } else {
- errors.push([originallink, message])
- }
- })
- }
- const checkprogress = function () {
- if (self._notLoggedIn) {
- // Stop checking and open premiumize homepage
- setTitle('🔑 ')
- setStatus(self.name + ' error: Not logged in!\nMaybe update your API key?', 0)
- GM.openInTab(self.homepage)
- cb([], -2)
- return
- }
- if (N === errors.length) { // All errors
- setTitle('❌ ')
- cb(false, -1)
- if (errors.length === 1 && errors[0][1]) {
- setStatus(errors[0][1], 0)
- } else {
- alert('Errors occured\n' + errors.length + ' links failed:\n\n' + errors.join('\n'))
- }
- } else if (N === downloadLinks.length + errors.length) { // All finished
- setTitle(downloadLinks.length + '/' + errors.length + '✅ ')
- cb(downloadLinks)
- if (errors.length > 0) { // Errors occured
- alert('Errors occured\n' + errors.length + ' links failed:\n\n' + errors.join('\n'))
- }
- } else { // not finished yet
- setTitle(downloadLinks.length + '/' + N + '⏳ ')
- window.setTimeout(checkprogress, self.updateDownloadProgressInterfaceInterval)
- }
- }
- window.setTimeout(checkprogress, self.updateDownloadProgressInterfaceInterval * Math.max(5, N))
- }
- this._addSingleTransfer = function (url, cb) {
- GM.xmlHttpRequest({
- method: 'POST',
- url: self.homepage + 'api/transfer/create',
- data: 'apikey=' + encodeURIComponent(self.settings.apikey) + '&src=' + encodeURIComponent(url),
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Cache-Control': 'no-cache'
- },
- onerror: function (response) {
- console.log(scriptName + ': GM.xmlHttpRequest error: ' + self.homepage + 'api/transfer/create')
- console.log(response)
- cb(false, url, 'GM.xmlHttpRequest error: api/transfer/create')
- },
- onload: function (response) {
- const result = JSON.parse(response.responseText)
- /*
- {"status":"success","type":"savetocloud","id":"gfwRtdgd5fgdfgfhgfhf","name":"test.zip"}
- {"status":"error","error":"duplicate","id":"gfdgd5fgFddfgfhgfhf","message":"You already have this job added."}
- {"status":"error","message":"This link is not available on the file hoster website"}
- */
- if ('id' in result && result.id) {
- window.setTimeout(function () {
- self._getFileFromTransfer(url, result.id, cb)
- }, 1000)
- if ('message' in result) {
- addStatus(result.message, -1)
- }
- } else {
- if ('message' in result && !self._notLoggedIn) {
- addStatus(result.message, -1)
- if (~result.message.indexOf('log')) {
- self._notLoggedIn = true
- }
- }
- cb(false, url, 'message' in result ? result.message : response.responseText)
- }
- }
- })
- }
- this._getFileFromTransfer = function (url, transferId, cb) {
- GM.xmlHttpRequest({
- method: 'GET',
- url: self.homepage + 'api/transfer/list?apikey=' + encodeURIComponent(self.settings.apikey),
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Cache-Control': 'no-cache'
- },
- onerror: function (response) {
- console.log(scriptName + ': GM.xmlHttpRequest error: ' + self.homepage + 'api/transfer/list')
- console.log(response)
- cb(false, url, 'GM.xmlHttpRequest error: /api/transfer/list')
- },
- onload: function (response) {
- const result = JSON.parse(response.responseText)
- /*
- {
- "status": "success",
- "transfers": [
- {
- "id": "xXFDSXXFDSGD",
- "name": "test.zip",
- "message": null,
- "status": "finished",
- "progress": 0,
- "folder_id": "gfjdfsuigjfdoikfsadf",
- "file_id": "trhgf982u30fjklfsdag"
- }
- ]
- }
- {
- "status": "success",
- "transfers": [
- {
- "id":"xXFDSXXFDSGD",
- "name":"test.zip",
- "message":"Initializing Download...",
- "status":"running",
- "progress":0,
- "folder_id":"gfjdfsuigjfdoikfsadf",
- "file_id":null
- }
- ]
- }
- */
- if (result.status === 'success' && 'transfers' in result) {
- for (let i = 0; i < result.transfers.length; i++) {
- if (result.transfers[i].id === transferId) {
- if (result.transfers[i].file_id) {
- // Finished
- window.setTimeout(function () {
- self._getSingleLink(url, result.transfers[i].file_id, cb)
- }, result.transfers[i].status === 'finished' ? 10 : self.updateDownloadProgressInterval)
- } else {
- // Downloading
- if ('message' in result.transfers[i] && result.transfers[i].message) {
- setStatus(result.transfers[i].message, -1)
- }
- window.setTimeout(function () {
- self._getFileFromTransfer(url, transferId, cb)
- }, self.updateDownloadProgressInterval)
- }
- return
- }
- }
- }
- if ('message' in result && result.message) {
- alert(scriptName + '\n\nCould not get /api/transfer/list\nError:\n' + result.message)
- }
- cb(false, url, 'Could not find url in transfer list')
- }
- })
- }
- this._getSingleLink = function (url, fileId, cb) {
- GM.xmlHttpRequest({
- method: 'POST',
- url: self.homepage + 'api/item/details',
- data: 'apikey=' + encodeURIComponent(self.settings.apikey) + '&id=' + encodeURIComponent(fileId),
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Cache-Control': 'no-cache'
- },
- onerror: function (response) {
- console.log(scriptName + ': GM.xmlHttpRequest error: ' + self.homepage + 'api/item/details')
- console.log(response)
- cb(false, url, 'GM.xmlHttpRequest error: /api/item/details')
- },
- onload: function (response) {
- const result = JSON.parse(response.responseText)
- /*
- {
- "id": "xxXxXxxxXxxx",
- "name": "test.zip",
- "size": 156,
- "created_at": 1572458477,
- "transcode_status": "not_applicable",
- "folder_id": "XxXXXxxxxxx",
- "ip": "1.1.1.1",
- "acodec": "",
- "vcodec": "",
- "mime_type": "application/zip",
- "opensubtitles_hash": "",
- "resx": "",
- "resy": "",
- "duration": "",
- "virus_scan": "ok",
- "type": "file",
- "link": "https://down.host.example.com/dl/abcdefg/test.zip",
- "stream_link": null
- }
- */
- if ('link' in result && result.link) {
- cb(result.link, url)
- } else {
- window.setTimeout(function () {
- self._getSingleLink(url, fileId, cb)
- }, self.updateDownloadProgressInterval)
- }
- }
- })
- }
- }(),
- 'nopremium.pl': new function () {
- const self = this
- this.config = {
- mode: ['transfer', 'premium', 'none'],
- mode_desc: ['Transfer User (Pakiety Transferowe)', 'Premium User (Konta Premium)', 'No account'],
- mode_quest: 'What kind of account do you have at nopremium.pl',
- downloadmode: ['direct', 'server'],
- downloadmode_desc: ['Direct download (TRYB SZYBKIEGO POBIERANIA)', 'Downloading via NoPremium.pl server (TRYB POBIERANIA NA SERWERY)'],
- downloadmode_quest: ['Which download mode do you want to use?']
- }
- this.key = 'nopremium.pl'
- this.name = 'NoPremium.pl'
- this.homepage = 'https://www.nopremium.pl/'
- this.updateStatusURL = 'https://www.nopremium.pl/files'
- this.updateStatusURLpattern = /https?:\/\/www\.nopremium\.pl\/files\/?/
- this.updateDownloadProgressInterval = 5000
- const mapHosterName = name => name.replace('-', '')
- this.status = {}
- this.init = async function () {
- self.status = JSON.parse(await GM.getValue(self.key + '_status', '{}'))
- self.lastUpdate = new Date(await GM.getValue(self.key + '_status_time', 0))
- }
- this.settings = {}
- this.loadSettings = async function (silent) {
- // Load settings, use first value as default
- const savedsettings = JSON.parse(await GM.getValue(self.key + '_settings', '{}'))
- for (const key in self.config) {
- if (key.endsWith('desc') || key.endsWith('range') || key.endsWith('quest') || key.endsWith('prefix') || key.endsWith('suffix')) {
- continue
- }
- if (key in savedsettings) { // Saved
- if (self.config[key] === 'int') { // Int
- self.settings[key] = parseInt(savedsettings[key], 10)
- } else if (self.config[key] === 'string') { // String
- self.settings[key] = savedsettings[key].toString()
- } else if (config[key] === 'bool') { // Bool
- self.settings[key] = savedsettings[key] === 'true' || savedsettings[key] === true
- } else if (Array.isArray(savedsettings[key])) { // Nested array
- self.settings[key] = []
- for (let i = 0; i < savedsettings[key].length; i++) {
- self.settings[key].push(savedsettings[key][i])
- }
- } else { // Array
- self.settings[key] = savedsettings[key]
- }
- } else { // Default
- if (self.config[key] === 'int') { // Int
- self.settings[key] = self.config[key + '_range'][1]
- } else if (self.config[key] === 'string') { // String
- self.settings[key] = '' // String defaults to empty string
- } else if (config[key] === 'bool') { // Bool
- self.settings[key] = true
- } else if (Array.isArray(self.config[key][0])) { // Nested array defaults to first value for each array
- self.settings[key] = []
- for (let i = 0; i < self.config[key].length; i++) {
- self.settings[key].push(self.config[key][i][0])
- }
- } else {
- self.settings[key] = self.config[key][0] // Array defaults to first value
- }
- }
- }
- }
- this.updateStatus = async function () { // Update list of online hosters
- if (document.location.href.match(self.updateStatusURL)) {
- // Read and save current status of all hosters
- await GM.setValue(self.key + '_status_time', '' + (new Date()))
- self.status = {}
- $('#servers a[title]').each(function () {
- const name = mapHosterName(this.title)
- self.status[name] = true
- })
- await GM.setValue(self.key + '_status', JSON.stringify(self.status))
- console.log(scriptName + ': ' + self.name + ': Hosters (' + Object.keys(self.status).length + ') updated')
- } else {
- alert(scriptName + '\n\nError: wrong update URL')
- }
- }
- this.isOnline = hostername => hostername in self.status && self.status[hostername]
- this.getOpenWebsiteURL = function (urls) {
- // Return a link to the nopremium.pl website that will insert the links
- const url = this.homepage + 'files?link:' + encodeURIComponent(urls.join('\n'))
- return url
- }
- const getHashs = function (urls, cb, silent) {
- // cb(hashes,sizestring)
- setTitle('✈️ ')
- setStatus('Sending ' + (urls.length === 1 ? 'one link' : (urls.length + ' links')), -1)
- GM.xmlHttpRequest({
- method: 'POST',
- url: self.homepage + 'files',
- data: 'watchonline=&session=' + (Math.round(Math.random() * 1234567)) + '&links=' + encodeURIComponent(urls.join('\n')),
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Cache-Control': 'no-cache'
- // "Referer" : "https://www.nopremium.pl/files" // FIREFOX57
- },
- onload: function (response) {
- if (response.responseText.indexOf('<input type="text" name="login" placeholder="Login"/>') !== -1) {
- setTitle('🔑 ')
- setStatus(self.name + ' error: Not logged in!', 0)
- GM.openInTab(self.homepage)
- return cb([], -1)
- }
- const hashes = []
- // Find hashes
- const re = /name="hash(\d+)" value="(\w+)"/g // <input type="checkbox" id="hash0" name="hash0" value="fab3c41988" onclick="UpdateCounter();" c
- let ma = re.exec(response.responseText)
- while (ma) {
- hashes.push(ma[2])
- ma = re.exec(response.responseText)
- }
- // Find errors
- ma = response.responseText.match(/Pliki nieprzetworzone \((\d+)\)/)
- if (ma && !silent) {
- addStatus('Error: ' + (parseInt(ma[1], 10) === 1 ? ('One file is offline or unsupported') : (ma[1] + ' files are offline or unsupported')), 0)
- }
- // Find size
- let size = '0 Byte'
- if (response.responseText.indexOf('id="countSize"') !== -1) {
- ma = response.responseText.split('id="countSize"')[1].match(/value="(\d+.?\d*) (\w+)"/) // <input type="text" name="countSize" id="countSize" style="width:80px;" readonly="readonly" value="1.38 GB">
- size = ma[1] + ' ' + ma[2]
- }
- setStatus(self.name + ' identified ' + (hashes.length === 1 ? 'one online file' : (hashes.length + ' online files')), -1)
- setTitle(hashes.length + '🔗 ')
- cb(hashes, size)
- }
- })
- }
- this.checkLink = function (url, cb) { // check whether the link is supported and online
- // cb(boolresult)
- return getHashs([url], function (hashes, size) {
- cb(hashes.length === 1)
- }, true)
- }
- this.getResults = function (urls, cb, hashes) {
- // cb($node,linkNumber) -- $node contains the result, linkNumber is the number of links that should be online i.e. number of hashes
- // Get download links from nopremium.pl and show the usual info about the file, that is normally shown on nopremium.pl
- if (typeof hashes === 'undefined') {
- // 1. Get hashes and show transfer warning
- getHashs(urls, async function (hashes, size) {
- if (settings.mode === 'transfer') {
- await showConfirm('transferWarning', 'You will be charged <b>' + size + "</b> 'Transfer' for generating " + (hashes.length > 1 ? ('<b>' + hashes.length + '</b> files') : ('<b>one</b> file')) + '!<br><br>Generate links?', function () { this.getResults(urls, cb, hashes) }, null, self)
- } else if (hashes.length > 0) {
- self.getResults(urls, cb, hashes)
- } else if (size === -1) { // Error was already handled (probably not logged in)
- console.log('getHashs->cb: Error was already handled (probably not logged in)')
- cb(false, -2)
- } else { // No files found
- setStatus('No online/available files', 0)
- cb(false, 0)
- }
- })
- return
- }
- // 2. Work with hashes
- const $resultContainer = $('<div></div>').attr('id', 'generated-links')
- const mode = self.settings.downloadmode === 'direct' ? 0 : 1 // 0 -> direct , 1 -> via server
- GM.xmlHttpRequest({
- method: 'POST',
- url: self.homepage + 'files',
- data: 'insert=1&mode=' + mode + '&hh=0&hash[]=' + hashes.join('&hash[]=') + '&',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Cache-Control': 'no-cache'
- // "Referer" : "https://www.nopremium.pl/files" // FIREFOX57
- },
- onload: function (response) {
- GM.xmlHttpRequest({
- method: 'POST',
- url: self.homepage + 'files',
- data: 'loadfiles=1',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Cache-Control': 'no-cache'
- // "Referer" : "https://www.nopremium.pl/files" // FIREFOX57
- },
- onload: function (response) {
- if (mode === 0) {
- $resultContainer.append($('<div></div>').append(response.responseText).find('#fastFilesArea'))
- } else {
- $resultContainer.append($('<div></div>').append(response.responseText).find('#downloadFilesArea'))
- }
- $resultContainer.find('input[type=checkbox]').remove()
- cb($resultContainer, hashes.length)
- }
- })
- }
- })
- }
- this.getLinks = function (urls, cb) {
- // cb(downloadlinks)
- if (this.settings.downloadmode === 'direct') {
- return this._getDirectLinks(urls, cb)
- } else {
- return this._getServerLinks(urls, cb)
- }
- }
- this._getDirectLinks = function (urls, cb) {
- // Get Direct download links
- this.getResults(urls, async function ($node, N) {
- if (!$node || N < 1) {
- cb(false)
- return
- }
- const text = $node.html()
- /*
- <td>16-08-2014 20:22</td>
- <td class="dlBox"><a href="http://direct.nopremium.pl/9091456/7895ca02bfcb2c2e43806f1079b7ff069129e/result.file"><img src="https://www.nopremium.pl/images/download_ico.png" alt="Sciagnij" title="Sciagnij"></a></td>
- */
- const files = []
- const re = /<td>(\d+)-(\d+)-(\d+) (\d+):(\d+)<\/td>(\s|\n)+<td class="dlBox"><a href="(.*?)"/gm
- let m = re.exec(text) // wholeString, 16,08,2014,20,37,#newline#,http://direct.nopremium.pl/9091456/7895ca02bfcb2c2e43806f1079b7ff069129e/result.file
- while (m) {
- if (m[7].indexOf('//direct.nopremium.pl') === -1) {
- continue // Skip files via server, only use direct download links
- }
- const d = new Date(m[3], m[2], m[1], m[4], m[5], 0, 0)
- files.push([d, m[7]])
- m = re.exec(text)
- }
- if (files.length === 0) {
- alert(scriptName + '\n\nAn error occured.\nCould not find download links in response.')
- cb(false)
- return
- }
- // Find youngest files by comparing their ids
- const pattern = /\.pl\/(\d+)\//
- files.sort(function (a, b) {
- const x = a[1].match(pattern)[1]
- const y = a[1].match(pattern)[1]
- return x > y ? -1 : x < y ? 1 : 0
- })
- const result = []
- for (let i = 0; i < N; i++) {
- result.push(files[i][1])
- await cacheLink([urls[i]], files[i][0], [files[i][1]], self.key) // CACHE single URLs
- }
- await cacheLink(urls, new Date(), result, self.key) // CACHE all URLs
- cb(result)
- })
- }
- this._getServerLinks = function (urls, cb) {
- this.getResults(urls, function ($node, N) {
- if (N === 0) {
- cb(false)
- } else {
- self._getProgress(cb, $node, N)
- }
- })
- }
- this._getProgress = function (cb, $node, N, ids) {
- GM.xmlHttpRequest({
- method: 'POST',
- url: self.homepage + 'files',
- data: 'downloadprogress=1',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Cache-Control': 'no-cache'
- // "Referer" : "https://www.nopremium.pl/files" // FIREFOX57
- },
- onerror: function () {
- self._getProgressBlocked = false
- window.setTimeout(function () {
- self._getProgress(cb, $node, N, ids)
- }, self.updateDownloadProgressInterval)
- },
- onload: function (response) {
- self._getProgressBlocked = false
- let data
- try {
- data = JSON.parse(response.responseText)
- } catch (e) {
- console.log(scriptName + ': ' + e)
- console.log(response.responseText)
- if (response.responseText.indexOf('<input type="text" name="login" placeholder="Login"/>') !== -1) {
- setTitle('🔑 ')
- setStatus(self.name + ' error: Not logged in!', 0)
- GM.openInTab(self.homepage)
- cb(false, -2)
- } else {
- window.setTimeout(function () {
- self._getProgress(cb, $node, N, ids)
- }, self.updateDownloadProgressInterval)
- }
- return
- }
- data.StandardFiles.sort(function (a, b) {
- const x = new Date(a.insert_date.split('-').join('/'))
- const y = new Date(b.insert_date.split('-').join('/'))
- return x > y ? -1 : x < y ? 1 : 0
- })
- const result = []
- const runnning = []
- let percent = 0
- const progess = []
- if (!ids) { // First run: Find the correct files: just use the first N files
- ids = []
- for (let i = 0; i < data.StandardFiles.length && i < N; i++) {
- ids.push(data.StandardFiles[i].id)
- if (data.StandardFiles[i].status === 'finish') {
- result.push(data.StandardFiles[i].download_url)
- progess.push(100)
- percent += 100
- } else {
- runnning.push(data.StandardFiles[i])
- if (parseInt(data.StandardFiles[i].status, 10) > 0) {
- progess.push(parseInt(data.StandardFiles[i].status, 10))
- percent += parseInt(data.StandardFiles[i].status, 10)
- }
- }
- }
- } else { // Consecutive runs: Use the ids from first run
- for (let i = 0; i < data.StandardFiles.length; i++) {
- if (ids.indexOf(data.StandardFiles[i].id) === -1) continue
- if (data.StandardFiles[i].status === 'finish') {
- result.push(data.StandardFiles[i].download_url)
- progess.push(100)
- percent += 100
- } else {
- runnning.push(data.StandardFiles[i])
- if (parseInt(data.StandardFiles[i].status, 10) > 0) {
- progess.push(parseInt(data.StandardFiles[i].status, 10))
- percent += parseInt(data.StandardFiles[i].status, 10)
- }
- }
- }
- }
- /*
- Regarding caching in server mode:
- If you add a file, that is already on the server (or currently downloading), you will not be charged additional bandwith - therefore caching is not necessary at the moment.
- */
- if (result.length === N) {
- setStatus((result.length === 1 ? 'One file' : (result.length + ' files')) + ' downloaded to server', 1)
- setTitle(result.length + '✅ ')
- cb(result)
- } else {
- // Waiting
- percent = percent / N
- // setStatus('Download '+result.length+'/'+N+' ('+Math.floor(percent)+'%)\n<span title="'+round(percent,2)+'%" style="display:block; width:120px; height:18px; background:white; border:1px solid black; border-radius:5px;"><span style="display:block; border-radius:5px; height:18px; width:'+Math.ceil(percent*1.2)+'px; '+LOADINGBARBG+'"> </span></span>',-1);
- const dotheight = N > 2 ? 2 : 4
- let h = 'Download ' + result.length + '/' + N + ' (' + Math.floor(percent) + '%)\n<div style="display:block; width:130px; height:auto; background:white; border:1px solid black; border-radius:5px; padding:2px; ">'
- for (let i = 0; i < N; i++) {
- if (progess[i]) {
- h += '<span style="display:block; width:' + Math.ceil(progess[i] * 1.2) + 'px; height:1px; background:white; border-top:' + dotheight + 'px ' + (progess[i] > 99.9 ? 'solid' : 'dotted') + ' green; margin-bottom:1px;"></span>'
- } else {
- h += '<span style="display:block; width:0x; height:1px; background:white; border-top:' + dotheight + 'px dotted silver; margin-bottom:1px;"></span>'
- }
- }
- h += '</div>'
- setTitle(Math.floor(percent) + '%⏳ ')
- setStatus(h)
- showOnlyStatus()
- window.setTimeout(function () {
- self._getProgress(cb, $node, N, ids)
- }, self.updateDownloadProgressInterval)
- }
- }
- })
- }
- }()
- }
- const debridprovider = Object.keys(multi)
- let currentdebrid = await GM.getValue('currentdebrid', debridprovider[0])
- for (const key in multi) {
- await multi[key].init()
- if (key === currentdebrid) {
- await multi[key].loadSettings()
- continue
- }
- if (!greasemonkey) {
- GM.registerMenuCommand(scriptName + ' - Switch to ' + multi[key].name, (function (key) {
- return async function () {
- if (!confirm(scriptName + '\n\nSet multi-download provider:\n' + multi[key].name)) return
- await GM.setValue('currentdebrid', key)
- currentdebrid = key
- document.location.reload()
- }
- })(key)
- )
- }
- }
- if (!greasemonkey) {
- GM.registerMenuCommand(scriptName + ' - Delete cached links', async function () {
- if (!confirm(scriptName + '\n\nReally delete cached links?')) return
- await GM.setValue('cachedDownloadLinks', '{}')
- alert(scriptName + '\n\nCache is empty!')
- })
- GM.registerMenuCommand(scriptName + ' - Restore dialogs and warnings', async function () {
- if (!confirm(scriptName + '\n\nReally restore all dialogs and warnings?')) return
- await GM.setValue('dialogs', '[]')
- alert(scriptName + '\n\nDialogs and warnings restored')
- })
- }
- /*
- function round (f, p) {
- // Round f to p places after the comma
- return parseFloat(parseFloat(f).toFixed(p))
- }
- */
- const orgDocumentTitle = document.title
- function setTitle (message) {
- if (window.parent.parent !== window) {
- window.parent.parent.postMessage({ iAm: 'Unrestrict.li', type: 'title', str: message }, '*')
- }
- if (message) {
- document.title = message + orgDocumentTitle
- } else {
- document.title = orgDocumentTitle
- }
- }
- function popUp (id, onClose, thisArg, doNotCloseOnOutsideClick) {
- // Remove window scrolling
- $(document.body).css('overflow', 'hidden')
- let zi = getNextZIndex()
- id = id || ('popup' + (new Date()).getTime())
- const $par = $('<div style="position:absolute; top:0px;"></div>').attr('id', id).appendTo(document.body)
- const $background = $('<div style="position:fixed; top:0px; left:0px; right:0px; bottom:0px; background:black; opacity:0.5; z-index:' + (zi++) + '"></div>').appendTo($par)
- const $div = $('<div style="position:fixed; top:50px; left:100px; overflow:auto; z-index:' + (zi++) + '; background:#E6E6E6; color:Black; border:#B555C5 2px solid;border-radius:5px; padding:10px; font-family: "Ubuntu",Arial,Sans-Serif"></div>').css('maxHeight', window.innerHeight - 100).css('maxWidth', window.innerWidth - 200).appendTo($par)
- const close = function () {
- $par.remove()
- if (onClose) onClose.call(thisArg)
- // Restore scrolling
- $(document.body).css('overflow', 'initial')
- }
- if (!doNotCloseOnOutsideClick) {
- $background.click(close)
- }
- return { node: $div, close }
- }
- function configForm ($form, c, s, formid) {
- for (const key in c) {
- if (key.endsWith('desc') || key.endsWith('range') || key.endsWith('quest') || key.endsWith('prefix') || key.endsWith('suffix') || key.endsWith('hidden')) {
- continue
- }
- const $p = $('<p>').appendTo($form)
- if (c[key + '_quest']) {
- $p.append(c[key + '_quest'])
- } else {
- $p.append(key)
- }
- $p.append('<br>')
- if (c[key + '_prefix']) {
- $p.append(c[key + '_prefix'] + ' ')
- }
- const hidden = (key + '_hidden') in c && c[key + '_hidden']
- if (c[key] === 'int') { // Int
- const $input = $('<input type="number">').addClass('form_' + formid).data('key', key).data('parse', 'int').val(s[key]).appendTo($p)
- if (c[key + '_range']) {
- $input.prop('min', c[key + '_range'][0])
- $input.prop('max', c[key + '_range'][2])
- $input.prop('title', c[key + '_range'][0] + ' - ' + c[key + '_range'][2])
- }
- } else if (c[key] === 'string') { // String
- const $inputText = $('<input type="text">').addClass('form_' + formid).data('key', key).data('parse', 'string').appendTo($p)
- if (hidden && s[key]) {
- $inputText.val('## HIDDEN ##')
- $inputText.data('hidden', '1')
- } else {
- $inputText.val(s[key])
- }
- } else if (c[key] === 'bool') { // Bool
- const $select = $('<select></select>').addClass('form_' + formid).data('key', key).data('parse', 'bool').appendTo($p)
- const $optionYes = $('<option></option>').val('true').appendTo($select)
- if (c[key + '_desc']) {
- $optionYes.html(c[key + '_desc'][0])
- } else {
- $optionYes.html('Yes')
- }
- if (s[key]) {
- $optionYes[0].selected = true
- }
- const $optionNo = $('<option></option>').val('false').appendTo($select)
- if (c[key + '_desc']) {
- $optionNo.html(c[key + '_desc'][1])
- } else {
- $optionNo.html('No')
- }
- if (!s[key]) {
- $optionNo[0].selected = true
- }
- } else if (Array.isArray(c[key][0])) { // Nested array
- for (let j = 0; j < c[key].length; j++) {
- if (c[key + '_desc'] && !Array.isArray(c[key + '_desc'][j])) {
- $p.append(c[key + '_desc'][j] + ': ')
- }
- const $select = $('<select></select>').addClass('form_' + formid).data('key', key).data('index', j).appendTo($p)
- for (let i = 0; i < c[key][j].length; i++) {
- const $option = $('<option></option>').val(c[key][j][i]).appendTo($select)
- if (c[key + '_desc'] && Array.isArray(c[key + '_desc'][0])) {
- $option.html(c[key + '_desc'][j][i])
- } else {
- $option.html(c[key][j][i])
- }
- if (s[key][j] === c[key][j][i]) { $option[0].selected = true }
- }
- $p.append('<br>')
- }
- } else { // Array
- const $select = $('<select></select>').addClass('form_' + formid).data('key', key).appendTo($p)
- for (let i = 0; i < c[key].length; i++) {
- const $option = $('<option></option>').val(c[key][i]).appendTo($select)
- if (c[key + '_desc']) {
- $option.html(c[key + '_desc'][i])
- } else {
- $option.html(c[key][i])
- }
- if (s[key] === c[key][i]) { $option[0].selected = true }
- }
- }
- if (c[key + '_suffix']) {
- $p.append(' ' + c[key + '_suffix'])
- }
- }
- }
- async function saveSettings (ev) {
- const $body = ev.data
- const $form = $body.find('.form')
- // Save preferred hoster:
- currentdebrid = $form.find('.debridhoster').val()
- // Save options:
- const newsettings = { general: {} }
- for (const key in multi) {
- newsettings[key] = {}
- }
- $form.find('*[class^=form_]').each(function () {
- const $this = $(this)
- const namespace = $this.prop('class').split('_', 2)[1]
- const key = $this.data('key')
- const index = $this.data('index')
- let value = $this.val()
- const parse = $this.data('parse')
- const hiddenAndUnchanged = $this.data('hidden') && value === '## HIDDEN ##'
- if (typeof index !== 'undefined') { // Nested Array
- if (!(key in newsettings[namespace]) || !Array.isArray(newsettings[namespace][key])) {
- newsettings[namespace][key] = []
- }
- newsettings[namespace][key][index] = value
- } else { // Normal
- if (hiddenAndUnchanged) {
- value = multi[namespace].settings[key]
- } else if (parse === 'int') {
- value = parseInt(value, 10)
- } else if (parse === 'bool') {
- value = (value === 'true')
- }
- newsettings[namespace][key] = value
- }
- })
- await GM.setValue('setup', true)
- await GM.setValue('currentdebrid', currentdebrid)
- await GM.setValue('settings', JSON.stringify(newsettings.general))
- for (const key in multi) {
- await GM.setValue(key + '_settings', JSON.stringify(newsettings[key]))
- }
- alert(scriptName + '\n\nSettings were successfully saved!')
- document.location.reload()
- }
- async function aboutMe () {
- const popup = popUp('multiochhelper_about', null, null, true)
- const $popup = popup.node
- const $frame = $('<iframe width="' + (window.innerWidth - 250) + '" height="' + (window.innerHeight - 150) + '" style="border:0">').appendTo($popup)
- $frame.bind('load', async function (e) {
- // Load settings for all
- for (const key in multi) {
- await multi[key].loadSettings(true)
- }
- const $body = $($frame[0].contentDocument.getElementsByTagName('body')[0])
- $body.css('fontFamily', 'Ubuntu,Arial,Sans-Serif')
- $('<div style="position:fixed; top:0px; right:5px; cursor:pointer; color:White; background:#b555c5; border: 1px solid White; border-radius:3px; padding:0px; font-weight:bold ; " title="Close menu">X</span>').click(function () { if (confirm('Settings will NOT be saved!')) popup.close() }).appendTo($body)
- $body.append('<h2>' + scriptName + '</h2>')
- $('<a>').appendTo($body).attr('target', '_blank').css('fontSize', 'small').html('https://openuserjs.org/scripts/cuzi/Multi-OCH_Helper').attr('href', 'https://openuserjs.org/scripts/cuzi/Multi-OCH_Helper')
- const $form = $('<div class="form">').appendTo($body)
- // General options
- $form.append('<h3>Settings</h3>')
- configForm($form, config, settings, 'general')
- // Preferred multihoster
- const $p = $('<p>').appendTo($form)
- $p.append('Preferred multihoster:<br>')
- const $select = $('<select></select>').addClass('debridhoster').appendTo($p)
- for (const key in multi) {
- const $option = $('<option></option>').val(key).appendTo($select)
- $option.html(multi[key].name)
- $option[0].selected = key === currentdebrid
- }
- // Options for multihosters
- for (const key in multi) {
- $('<h3>').appendTo($form).html(multi[key].name)
- $('<a>').appendTo($form).css('fontSize', 'small').attr('target', '_blank').html(multi[key].homepage).attr('href', multi[key].homepage)
- if (multi[key].config) {
- configForm($form, multi[key].config, multi[key].settings, key)
- } else {
- $('<p>').appendTo($form).text('No settings available for this service.')
- }
- }
- $form.append('<br>')
- $('<input type="button">').val('Cancel').click(function () {
- if (confirm('Settings will NOT be saved!')) {
- popup.close()
- }
- }).appendTo($form)
- $('<input type="button">').val('Save').click($body, saveSettings).appendTo($form)
- $form.append('<h3>Other options</h3>')
- $('<input type="button">').val('Clear cache (' + humanBytes((await GM.getValue('cachedDownloadLinks', '{}')).length - 2) + ')').appendTo($form).click(async function () {
- if (!confirm(scriptName + '\n\nReally delete cached links?')) {
- return
- }
- await GM.setValue('cachedDownloadLinks', '{}')
- this.value = 'Clear cache (' + humanBytes((await GM.getValue('cachedDownloadLinks', '{}')).length - 2) + ')'
- alert(scriptName + '\n\nCache is empty!')
- })
- $form.append('<br>')
- $form.append('<br>')
- $('<input type="button">').val('Restore dialogs and warnings').appendTo($form).click(async function () {
- if (!confirm(scriptName + '\n\nReally restore all dialogs and warnings?')) {
- return
- }
- await GM.setValue('dialogs', '[]')
- alert(scriptName + '\n\nDialogs and warnings restored')
- })
- let greasemonkeyIssue = ''
- if (greasemonkey) {
- greasemonkeyIssue = `<li>In Greasymonkey it is not possible to select multiple links with the mouse and send them at once.<br>
- The reason is this bug: <a href="https://github.com/greasemonkey/greasemonkey/issues/2574">https://github.com/greasemonkey/greasemonkey/issues/2574</a><br>
- If you need this functionality, you can use Tampermonkey instead of Greasemonkey</li>`
- }
- $(`<div>
- <br>
- <br>
- <h3>Known issues:</h3>
- <ul>
- <li>nopremium.pl sometimes omits a few links in folders</li>
- <li>In Firefox the script sometimes does not work if the "Accept thid-parts cookies" policy is set to "Never".<br>
- To resolve this problem open the Firefox options and go to the tab "Privacy". Set the "Accept thid-parts cookies" to "From visited" or "Always"<br>
- Close and re-open Firefox. Log out and then log in your nopremium.pl account. Everything should work fine now.</li>
- ${greasemonkeyIssue}
- </ul>
- </div><br><br><br>`).appendTo($body)
- $('<input type="button">').val('Debug info').appendTo($body).click(inspectGMvalues)
- })
- if (chrome) {
- $frame.attr('src', 'about:blank')
- }
- }
- function inspectGMvalues () {
- let iv
- const popup = popUp('multiochhelper_inspectGM', function () {
- clearInterval(iv)
- })
- const $popup = popup.node
- const $frame = $('<iframe width="' + (window.innerWidth - 250) + '" height="' + (window.innerHeight - 150) + '" style="border:0">').appendTo($popup)
- $frame.bind('load', async function (e) {
- $($frame[0].contentDocument.getElementsByTagName('head')[0]).append('<style type="text/css">' + SPINNERCSS + '</style>')
- const $body = $($frame[0].contentDocument.getElementsByTagName('body')[0])
- $body.append('<h2>' + scriptName + '</h2>')
- let keys = await GM.listValues()
- if (keys.length && typeof keys[0] === 'undefined') { // Firefox 35+ workaround
- keys = cloneInto(await GM.listValues(), window)
- }
- const $table = $('<table>').appendTo($body)
- let $tr
- $tr = $('<tr>').appendTo($table)
- $('<th>').html('Key').appendTo($tr)
- $('<th>').html('Value').appendTo($tr)
- $('<th>').html('Type').appendTo($tr)
- $('<th>').html('').appendTo($tr)
- const deleteValue = async function (ev) {
- const key = $(this).data('key')
- await GM.deleteValue(key)
- $(this).parent().parent().remove()
- }
- let total = 0
- for (let i = 0; i < keys.length; i++) {
- const value = await GM.getValue(keys[i])
- let svalue = '' + value
- let len = 1
- if (typeof value === 'undefined') {
- svalue = 'undefined'
- } else if (typeof value === 'string') {
- len = value.length
- }
- total += len
- $tr = $('<tr>').appendTo($table)
- $('<td>').html(keys[i]).appendTo($tr)
- $('<td>').append($('<input type="text" style="width:600px">').val(svalue)).appendTo($tr)
- $('<td>').append('' + (typeof value) + (typeof value === 'string' ? ('(' + len + ')') : '')).appendTo($tr)
- $('<td>').append($('<input type="button">').val('Delete').data('key', keys[i]).click(deleteValue)).appendTo($tr)
- }
- $tr = $('<tr>').appendTo($table)
- $('<th>').html('Total').appendTo($tr)
- $('<th>').html(keys.length).appendTo($tr)
- $('<th>').html('approx. ' + humanBytes(total)).appendTo($tr)
- const $reload = $('<div>').appendTo($body)
- $('<div style="display:inline-block;width:20px; height:20px;" class="ochspinner"></div>').appendTo($reload)
- $reload.append(' Reload in ')
- const $timer = $('<span style="pointer:cursor;" title="Click to reload now"></span>').html('20 seconds').click(function () { this.innerHTML = 0 }).appendTo($reload)
- iv = window.setInterval(function () {
- let s = parseInt($timer.html(), 10)
- if (s === 0) {
- clearInterval(iv)
- popup.close()
- inspectGMvalues()
- } else {
- s--
- $timer.html(s + ' seconds')
- }
- }, 1000)
- })
- if (chrome) {
- $frame.attr('src', 'about:blank')
- }
- }
- function hexToBytes (s) {
- return s.match(/([0-9a-fA-F]{2})/g).map(v => parseInt(v, 16))
- }
- function stringToBytes (s) {
- return s.split('').map(v => v.charCodeAt(0))
- }
- function bytesToString (a) {
- return String.fromCharCode.apply(String, a)
- }
- function addCSSHead (body) {
- const style = document.createElement('style')
- style.type = 'text/css'
- style.innerHTML = body
- document.head.appendChild(style)
- }
- function humanBytes (bytes, precision) {
- // http://stackoverflow.com/a/18650828
- bytes = parseInt(bytes, 10)
- if (bytes === 0) return '0 Byte'
- const k = 1024
- const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
- const i = Math.floor(Math.log(bytes) / Math.log(k))
- return parseFloat((bytes / Math.pow(k, i)).toPrecision(2)) + ' ' + sizes[i]
- }
- function getNextZIndex () {
- // Calculate: max(zIndex) + 1
- let zIndexMax = 0
- try {
- $('div').each(function () {
- const z = parseInt($(this).css('z-index'), 10)
- if (z > zIndexMax) {
- zIndexMax = z
- }
- })
- } catch (e) {} finally {
- if (zIndexMax < 20000) {
- zIndexMax = 20006
- }
- }
- return zIndexMax + 1
- }
- async function showConfirm (id, text, onConfirm, onNotConfirm, thisArg) {
- // Skip
- const dialogs = JSON.parse(await GM.getValue('dialogs', '[]'))
- if (dialogs.indexOf(id) !== -1) {
- onConfirm.call(thisArg)
- return
- }
- const popup = popUp('confirm' + id, function () {}, thisArg)
- const $div = popup.node
- $div.append(text)
- $div.append('<br>')
- $('<input type="button" value="Yes">').click(function () {
- popup.close()
- onConfirm.call(thisArg)
- }).appendTo($div)
- $('<input type="button" value="No">').click(function () {
- popup.close()
- if (onNotConfirm) {
- onNotConfirm.call(thisArg)
- }
- }).appendTo($div)
- $div.append('<br>')
- $('<input type="checkbox" value="remember">').click(async function () {
- const dialogs = JSON.parse(await GM.getValue('dialogs', '[]'))
- if (this.checked) {
- if (dialogs.indexOf(id) === -1) {
- dialogs.push(id)
- await GM.setValue('dialogs', JSON.stringify(dialogs))
- }
- } else {
- if (dialogs.indexOf(id) !== -1) {
- dialogs.splice(dialogs.indexOf(id), 1)
- await GM.setValue('dialogs', JSON.stringify(dialogs))
- }
- }
- }).appendTo($div)
- $div.append(' Always "Yes". Do not show this message again!')
- }
- function setStatus (text, success) {
- addStatus(text, success, true)
- }
- function addStatus (text, success, clear) {
- if (!document.getElementById('multiochhelper')) {
- alert(`${scriptName}\n\n${text}`)
- return
- }
- let $status = $('#multiochhelper_status')
- if (!document.getElementById('multiochhelper_status_text')) {
- if (!document.getElementById('multiochhelper_status')) {
- const $div = $('#multiochhelper')
- $status = $('<div>').prependTo($div)
- $status.attr('id', 'multiochhelper_status')
- } else {
- $status.empty()
- }
- const $loader = $('<div>').appendTo($status)
- $loader.attr('id', 'multiochhelper_status_loader')
- const $statustext = $('<div>').appendTo($status)
- $statustext.attr('id', 'multiochhelper_status_text')
- const $statusclear = $('<div>').appendTo($status)
- $statusclear.attr('id', 'multiochhelper_status_clear')
- }
- const $statustext = $('#multiochhelper_status_text')
- if (clear) {
- $statustext.empty()
- } else if ($statustext.html().trim() !== '') {
- $statustext.append(document.createElement('br'))
- }
- $status.show()
- $statustext.append(text)
- if (success === 1) {
- $statustext.css('color', '#33FF99')
- } else if (success === 0) {
- $statustext.css('color', 'orange')
- } else if (success === -1) {
- $statustext.css('color', 'cyan')
- } else {
- $statustext.css('color', 'white')
- }
- }
- function showOnlyStatus () {
- const $status = $('#multiochhelper_status')
- $status.siblings().not('#multiochhelper_status').remove()
- }
- function getMultiOCHWebsiteURL (links) {
- return multi[currentdebrid].getOpenWebsiteURL(links)
- }
- function openWebsite (links, cb) {
- // Call cb() and navigate to the website
- if (!links) {
- cb(false)
- return
- }
- if (cb) {
- cb()
- }
- const url = getMultiOCHWebsiteURL(links)
- if (settings.newTab) {
- if (typeof GM.openInTab === 'undefined') {
- window.open(url)
- } else {
- GM.openInTab(url)
- }
- } else {
- document.location.href = url
- }
- }
- async function useCache (urls, cb) {
- urls = '' + urls
- const cachedDownloadLinks = JSON.parse(await GM.getValue('cachedDownloadLinks', '{}')) // [datestring,downloadlink,multihoster]
- if (urls in cachedDownloadLinks) {
- if (confirm(scriptName + '\n\nLink was found in cache.\nUse cached link?\n\nFrom: ' + (new Date(cachedDownloadLinks[urls][0])) + '\nWith: ' + cachedDownloadLinks[urls][2] + '\n' + cachedDownloadLinks[urls][1].join('\n'))) {
- cb(cachedDownloadLinks[urls][1])
- return true
- }
- }
- return false
- }
- async function cacheLink (urls, datetime, downloadLinks, multihoster) {
- if (!Array.isArray(downloadLinks)) {
- const parts = downloadLinks.split('\n')
- downloadLinks = []
- for (let i = 0; i < parts.length; i++) {
- if ($.trim(parts[i])) {
- downloadLinks.push($.trim(parts[i]))
- }
- }
- }
- if (downloadLinks.length === 0) return
- urls = '' + urls
- const cachedDownloadLinks = JSON.parse(await GM.getValue('cachedDownloadLinks', '{}'))
- cachedDownloadLinks[urls] = [datetime, downloadLinks, multihoster]
- await GM.setValue('cachedDownloadLinks', JSON.stringify(cachedDownloadLinks))
- }
- function showExtractedLinks (links) {
- if (document.querySelector('.alertlinkscont')) {
- alert(links.join('\n'))
- $('.alertlinkscont').remove()
- return
- }
- $('<style type="text/css">.alertlinkscont{transition: left 500ms;}.alertlinkscont a{font-size:12px;user-select:all; font-family: monospace;} .alertlinkscont a:link,.alertlinkscont a:hover{color:black; text-decoration:none;}.alertlinkscont a:visited{color:rgb(70,0,120); text-decoration:none;}</style>').appendTo('head')
- const $div = $('<div class="alertlinkscont"></div>')
- $div.appendTo(document.body)
- $div.css({
- zIndex: 10000,
- position: 'fixed',
- top: '20px',
- left: '20px',
- minWidth: '300px',
- minHeight: '300px',
- background: 'white',
- color: 'black',
- border: '2px solid black',
- borderRadius: '5px',
- padding: '20px 25px 10px',
- fontFamily: 'monospace',
- fontSize: '12px',
- overflow: 'auto'
- })
- for (let i = 0; i < links.length; i++) {
- $div[0].innerHTML += '<a target="_blank" href="' + links[i] + '">' + links[i] + '</a><br>\n'
- }
- $div[0].innerHTML += '<br><br>\n'
- window.setTimeout(function moveMenuIntoView () {
- $div.css('maxHeight', (document.documentElement.clientHeight - 100) + 'px')
- $div.css('maxWidth', (document.documentElement.clientWidth - 40) + 'px')
- $div.css('left', Math.max(20, 0.5 * (document.body.clientWidth - $div[0].clientWidth)) + 'px')
- }, 0)
- }
- async function generateLinks (urls, cb) {
- // Check cache
- if (await useCache(urls, cb)) {
- return
- }
- await multi[currentdebrid].getLinks(urls, cb)
- }
- async function download (urls, cb) {
- // Get one/first download link and open it immediately/start download
- if (urls.length > 1) {
- alert(scriptName + '\n\nOnly the first link will be opened!')
- }
- await generateLinks(urls, function (result, code) {
- if (cb) {
- cb()
- }
- if (result && result[0]) {
- addStatus('Opening download...', -1)
- if (window.top === window) {
- document.location.href = result[0]
- } else {
- // Changing location may be blocked by sandboxed iframe
- window.top.location.href = result[0]
- }
- } else if (code === -2) {
- // Error was already handled
- console.log('download() in generateLinks(): error already handled')
- } else if (!code) {
- addStatus('An error occured: No downloadlink to open', 0)
- }
- })
- }
- async function clipboard (urls, cb) {
- // Get download links and copy them into clipboard
- generateLinks(urls, function (result, code) {
- if (result) {
- let succeeded = false
- setStatus('Trying to set clipboard', -1)
- window.setTimeout(function () {
- if (succeeded) {
- return
- }
- setStatus('Trying GM_setClipboard()', -1)
- try {
- GM_setClipboard(result.join('\r\n'))
- setStatus('Copied to clipboard', 1)
- } catch (e) {
- setStatus('Failed to access clipboard 02', 0)
- alert('Failed to access clipboard.\n\nLinks will appear in next dialog window')
- alert(result.join('\r\n'))
- }
- }, 3000)
- try {
- GM.setClipboard(result.join('\r\n')).then(function () {
- setStatus('Copied to clipboard', 1)
- succeeded = true
- }, function () {
- setStatus('Failed to access clipboard 01', 0)
- })
- } catch (e) {
- setStatus('Clipboard not supported by this browser', 0)
- alert(result.join('\n'))
- };
- } else if (code === -2) {
- // Error was already handled
- console.log('clipboard() in generateLinks(): error already handled')
- } else {
- setStatus('An error occured: No downloadlinks found', 0)
- }
- if (cb) {
- cb()
- }
- })
- }
- async function sendToJD (urls, cb) {
- // Get download links and send them to JDownloader
- generateLinks(urls, function (result, code) {
- if (result) {
- setStatus('Waiting for JDownloader', -1)
- // Comment should be the original page in case of multiple links
- let comment = urls[0]
- if (urls.length > 1) {
- if (showOneclickFromHighlighScriptAllLinksLoc) {
- comment = showOneclickFromHighlighScriptAllLinksLoc
- } else if (showOneclickFromHighlighScriptSelectedLinksLoc) {
- comment = showOneclickFromHighlighScriptAllLinksLoc
- } else {
- comment = document.location.href
- }
- }
- GM.xmlHttpRequest({
- method: 'POST',
- url: JDOWNLOADER + 'flash/add',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- Referer: scriptReferer,
- 'User-Agent': scriptReferer
- },
- // data: "source="+encodeURIComponent(scriptReferer)+"&urls="+encodeURIComponent(result.join("\r\n")), // Moved "source" to Referer
- // data: "comment="+encodeURIComponent(comment)+"&urls="+encodeURIComponent(result.join("\r\n")), // See ExternInterfaceImpl.java
- data: 'source=' + encodeURIComponent(scriptReferer) + '&comment=' + encodeURIComponent(comment) + '&urls=' + encodeURIComponent(result.join('\r\n')), // See ExternInterfaceImpl.java
- onload: function (resp) {
- if (cb) {
- cb()
- }
- if (resp.status === 204 || resp.responseText.startsWith('success')) {
- setStatus('Sent to JDownloader', 1)
- } else {
- setStatus('JDownloader rejected the request', 0)
- }
- },
- onerror: function (resp) {
- if (cb) {
- cb()
- }
- setStatus('JDownloader is not running', 0)
- }
- })
- } else if (code === -2) {
- // Error was already handled
- console.log('sendToJD() in generateLinks(): error already handled')
- if (cb) {
- cb()
- }
- } else {
- if (cb) {
- cb()
- }
- addStatus('No links to send', 0)
- }
- })
- }
- function showLinks (urls, cb, append, n) {
- const popup = popUp('showLinks')
- const $div = popup.node
- const $loader = $('<div style="width:20px; height:20px;" class="ochspinner"></div>').appendTo($div)
- const $frame = $('<iframe width="900" height="500" style="border:0">').appendTo($div)
- $frame.bind('load', function (e) {
- $($frame[0].contentDocument.getElementsByTagName('head')[0]).append('<link rel="stylesheet" href="https://www.nopremium.pl/css/style.css" type="text/css" />')
- const $body = $($frame[0].contentDocument.getElementsByTagName('body')[0])
- multi[currentdebrid].getResults(urls, function ($node) {
- $loader.remove()
- $body.append($node)
- $body.find('a').each(function () {
- // Open links in new window
- this.setAttribute('target', '_blank')
- })
- if (cb) {
- cb()
- }
- })
- })
- if (chrome) {
- $frame.attr('src', 'about:blank')
- }
- }
- function decryptClickNLoad (cb, jk, cryptedBase64) {
- // Get all the links by decrypting the Click'n'Load form
- // return False for any error
- // return True, run cb() and open the menu if Click'n'Load was successfully decoded
- if (!cryptedBase64 && !(document.getElementsByName('crypted').length && document.getElementsByName('jk').length)) {
- return false // Click'n'Load not avaiblabe
- }
- setStatus("Trying to decrypt Click'n'Load", -1)
- try {
- // Key/IV
- if (!jk) {
- jk = document.getElementsByName('jk')[0].value
- }
- if (jk.indexOf('return') !== -1) {
- jk = eval(jk + '; f();') // eslint-disable-line no-eval
- }
- const key = hexToBytes(jk)
- const iv = key.slice(0)
- // Text
- if (!cryptedBase64) {
- cryptedBase64 = document.getElementsByName('crypted')[0].value
- }
- const cryptedString = atob(cryptedBase64)
- const cryptedBytes = stringToBytes(cryptedString)
- // Decrypt
- const textBytes = slowAES.decrypt(cryptedBytes, slowAES.modeOfOperation.CBC, key, iv)
- let text = bytesToString(textBytes)
- text = text.replace('\r', '')
- const splitted = text.split('\n')
- const links = []
- for (let i = 0; i < splitted.length; i++) {
- // Remove any line that is not a http link
- const t = $.trim(splitted[i])
- if (t && t.substring(0, 4) === 'http') {
- links.push(t)
- }
- }
- const N = links.length
- if (N === 0) {
- return false // Click'n'Load probably failed, try another method...
- }
- if (cb) {
- cb()
- }
- menu(links)
- setStatus('Found ' + (N === 1 ? 'one link' : (N + ' links')), 1)
- return true
- } catch (e) {
- alert("Click'N'Load failed:\n" + e)
- return false // Click'n'Load probably failed, try another method...
- }
- /*
- // Get all the links by decrypting the Click'n'Load form
- if(!document.getElementsByName('crypted').length || !document.getElementsByName('jk').length) {
- if(cb) {
- cb();
- }
- return;
- }
- setStatus("Trying linkdecrypter.com",-1);
- const crypted = document.getElementsByName('crypted')[0].value;
- const jk = document.getElementsByName('jk')[0].value;
- GM.xmlHttpRequest( {
- method: "POST",
- url: "http://linkdecrypter.com/api/?t=cnl2",
- data: 'crypted=' + encodeURIComponent(crypted) + '&jk=' + encodeURIComponent(btoa(jk)),
- headers: {
- "User-agent": "Mozilla/5.0 (X11;U;Linux i686;es-ES;rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8",
- "Accept": "application/atom+xml,application/xml,text/xml",
- "Content-type" : "application/x-www-form-urlencoded"
- },
- onload: function(response) {
- if(cb) {
- cb();
- }
- const N = response.responseText.split("\n").length;
- if(!response.responseText || response.responseText.indexOf("ERROR(CNL2)") !== -1 || N === 0) {
- setStatus("An error occurred while handling the response of linkdecrypter.com",0);
- } else {
- menu(response.responseText);
- setStatus("Found "+(N===1?"one link":(N+" links")),1);
- }
- }
- });
- */
- }
- function getAllSerienjunkiesLinks (cb) {
- // Get all download links from a serienjunkies.org download page (i.e. the page right after the captcha)
- const urls = [] // [ [partnumber0,link0] , [partnumber1,link1] , .... ]
- let total = 0
- const rap = document.getElementById('rap')
- const table = rap.getElementsByTagName('table')[0]
- const forms = table.getElementsByTagName('form')
- let j = 1 // part number, in order to make sure that sorting of the links is the same as on the page.
- // This is only a fallback in case there is no visible part number in the actual downloadlink/filename.
- for (let i = 0; i < forms.length; i++) {
- const url = forms[i].action
- if (url.indexOf('mirror') !== -1 || url.indexOf('firstload') !== -1) {
- continue
- }
- GM.xmlHttpRequest({
- method: 'GET',
- url,
- onload: (function (j) {
- return function (response) {
- const loc = response.finalUrl // Actual link after posible redirections
- if (response.finalUrl.match(/part*(\d+)\./)) { // Try to guess part number
- const part = response.finalUrl.match(/part*(\d+)\./)[1]
- urls.push([parseInt(part, 10), loc])
- } else { // fallback part number
- urls.push([j, loc])
- }
- setStatus('Decrypting: ' + urls.length + '/' + total, total === urls.length ? 1 : -1)
- if (total === urls.length) {
- // Got all links
- cb(urls)
- }
- }
- }(j))
- })
- j++
- }
- total = j - 1
- };
- function getSerienjunkiesLinks (cb) {
- // Get all the links from the page
- getAllSerienjunkiesLinks(function (urls) {
- if (cb) {
- cb()
- }
- urls = urls.sort(function (a, b) {
- if (a[0] > b[0]) return 1
- else if (a[0] < b[0]) return -1
- return 0
- })
- let alllinks = ''
- for (let i = 0; i < urls.length; ++i) {
- alllinks += urls[i][1] + '\n'
- }
- menu(alllinks)
- })
- }
- function getFilecryptcc (jddata, cb) {
- // Get all the links by decrypting the Click'n'Load form
- const fieldJk = jddata[0]
- const fieldCrypted = jddata[1]
- const r = decryptClickNLoad(cb, fieldJk, fieldCrypted)
- if (!r) {
- setStatus("Could not find Click'n'Load", -1)
- if (cb) {
- cb()
- }
- }
- }
- function getSafeLinkingNetLinks (cb) {
- // Get all the links by following each link
- const crypticUrls = []
- $('div.links-container.result-form a.result-a').each(function () {
- if (this.getAttribute('href') && this.getAttribute('href').indexOf('/d/') !== -1) { crypticUrls.push(this.getAttribute('href')) }
- })
- const urls = []
- let total = 0
- let j = 1
- for (let i = 0; i < crypticUrls.length; i++) {
- GM.xmlHttpRequest({
- method: 'GET',
- url: crypticUrls[i],
- onload: (function (j) {
- return function (response) {
- const loc = response.finalUrl // Actual link after posible redirections
- urls.push(loc)
- setStatus('Decrypting: ' + urls.length + '/' + total, -1)
- if (total === urls.length) {
- // Got all links
- cb()
- menu(urls)
- setStatus('Found ' + (total === 1 ? 'one link' : (total + ' links')), 1)
- }
- }
- }(j))
- })
- j++
- }
- total = j - 1
- };
- const linkSelectorFilter = {
- _filter: function (key) {
- const a = Array.prototype.slice.call(arguments, 1)
- return function () {
- linkSelectorFilter[key].apply(linkSelectorFilter, a)
- }
- },
- all: function (trs) {
- for (let i = 0; i < trs.length; i++) {
- trs[i].$check.prop('checked', true)
- }
- },
- none: function (trs) {
- for (let i = 0; i < trs.length; i++) {
- trs[i].$check.prop('checked', false)
- }
- },
- flip: function (trs) {
- for (let i = 0; i < trs.length; i++) {
- trs[i].$check.prop('checked', !trs[i].$check.prop('checked'))
- }
- },
- has: function (trs, inpFilter) {
- const s = inpFilter.val()
- for (let i = 0; i < trs.length; i++) {
- if (trs[i].link.indexOf(s) !== -1) {
- trs[i].$check.prop('checked', !trs[i].$check.prop('checked'))
- }
- }
- },
- host: function (trs, $selHost) {
- const h = $selHost.val()
- for (let i = 0; i < trs.length; i++) {
- if (trs[i].host === h) {
- trs[i].$check.prop('checked', !trs[i].$check.prop('checked'))
- }
- }
- },
- fromto: function (trs, $table, $thead, $th) {
- const _self = this
- for (let i = 0; i < trs.length; i++) {
- trs[i].$check.prop('disabled', true)
- }
- $table.find('td').hover(function () {
- $(this).parent().find('td').each(function (i, e) {
- $(e).css('background', 'PaleGreen')
- })
- }, function () {
- $(this).parent().find('td').each(function (i, e) {
- $(e).css('background', '')
- })
- })
- $thead.find('th').css('display', 'none')
- $th.css('display', '')
- $th.html('Select from where to start')
- $table.find('td').click(function () {
- const from = $(this.parentNode).data('index')
- $(this).parent().find('td').css('background', 'PaleGreen')
- $table.find('td').unbind('click mouseenter mouseleave')
- $th.html('Select where to stop')
- $table.find('td').hover(function () {
- const to = $(this.parentNode).data('index')
- $table.find('td').each(function (i, e) {
- const $e = $(e)
- const j = $e.parent().data('index')
- if (j > from && j <= to) {
- $e.css('background', 'DarkSeaGreen')
- } else if (j > from && j > to) {
- $e.css('background', '')
- }
- })
- if ($(this).parent().data('index') > from) $(this).parent().find('td').css('background', 'PaleGreen')
- })
- $table.find('td').filter(function (i, e) { return $(e.parentNode).data('index') > from }).click(function () {
- const to = $(this.parentNode).data('index') + 1
- $table.find('td').unbind('click mouseenter mouseleave')
- $(this).parent().find('td').css('background', 'PaleGreen')
- $table.find('td').each(function (i, e) {
- const $e = $(e)
- const j = $e.parent().data('index')
- if (j < from || j >= to) {
- $e.css('display', 'none')
- }
- })
- const ntrs = trs.slice(from, to)
- for (let i = 0; i < ntrs.length; i++) {
- ntrs[i].$check.prop('disabled', false)
- }
- $th.html('Select ')
- $('<button>').appendTo($th).text('all').click(_self._filter('all', ntrs))
- $('<button>').appendTo($th).text('none').click(_self._filter('none', ntrs))
- $('<button>').appendTo($th).text('flip').click(_self._filter('flip', ntrs))
- $('<button>').appendTo($th).text('return to all links').click(function () {
- $table.find('td').each(function (i, e) {
- const $e = $(e)
- $e.css('display', '')
- $e.css('background', '')
- })
- $thead.find('th').css('display', '')
- $th.css('display', 'none')
- $th.html('')
- for (let i = 0; i < trs.length; i++) {
- trs[i].$check.prop('disabled', false)
- }
- })
- $th[0].scrollIntoView()
- return false
- })
- })
- },
- every: function (trs, $table, $thead, $th) {
- const _self = this
- for (let i = 0; i < trs.length; i++) {
- trs[i].$check.prop('disabled', true)
- }
- $table.find('td').hover(function () {
- $(this).parent().find('td').each(function (i, e) {
- $(e).css('background', 'PaleGreen')
- })
- }, function () {
- $(this).parent().find('td').each(function (i, e) {
- $(e).css('background', '')
- })
- })
- $thead.find('th').css('display', 'none')
- $th.css('display', '')
- $th.html('Select from where to start')
- $table.find('td').click(function () {
- const from = $(this.parentNode).data('index')
- $(this).parent().find('td').css('background', 'PaleGreen')
- $table.find('td').unbind('click mouseenter mouseleave')
- $th.html('Select next')
- $table.find('td').hover(function () {
- const to = $(this.parentNode).data('index')
- const diff = to - from
- if (to < from + 2) {
- $table.find('td').filter(function (i, e) { return $(e.parentNode).data('index') > from + 1 }).css('background', '')
- } else {
- $table.find('td').filter(function (i, e) { return $(e.parentNode).data('index') > from + 1 }).each(function (i, e) {
- const j = $(this.parentNode).data('index')
- if ((j - from) % diff === 0 && j > from + 1) {
- $(this).css('background', 'PaleGreen')
- } else {
- $(this).css('background', '')
- }
- })
- $(this).parent().find('td').css('background', 'DarkSeaGreen')
- }
- }).click(function () {
- const to = $(this.parentNode).data('index')
- if (to < from + 2) return false
- $(this).parent().find('td').css('background', 'PaleGreen')
- const diff = to - from
- $table.find('td').unbind('click mouseenter mouseleave')
- $table.find('td').each(function (i, e) {
- const $e = $(e)
- const j = $e.parent().data('index')
- if ((j - from) % diff !== 0 || j < from) {
- $e.css('display', 'none')
- }
- })
- const ntrs = []
- for (let i = 0; i < trs.length; i++) {
- if ((i - from) % diff === 0 && i >= from) {
- trs[i].$check.prop('disabled', false)
- ntrs.push(trs[i])
- }
- }
- $th.html('Select ')
- $('<button>').appendTo($th).text('all').click(_self._filter('all', ntrs))
- $('<button>').appendTo($th).text('none').click(_self._filter('none', ntrs))
- $('<button>').appendTo($th).text('flip').click(_self._filter('flip', ntrs))
- $('<button>').appendTo($th).text('return to all links').click(function () {
- $table.find('td').each(function (i, e) {
- const $e = $(e)
- $e.css('display', '')
- $e.css('background', '')
- })
- $thead.find('th').css('display', '')
- $th.css('display', 'none')
- $th.html('')
- for (let i = 0; i < trs.length; i++) {
- trs[i].$check.prop('disabled', false)
- }
- })
- $th[0].scrollIntoView()
- return false
- })
- })
- }
- }
- function linkSelector (links) {
- const filter = function (key) {
- const a = Array.prototype.slice.call(arguments, 1)
- return function () {
- linkSelectorFilter[key].apply(linkSelectorFilter, a)
- }
- }
- const trs = []
- const selectedLinks = []
- // Coyp array and remove empty elements
- for (let i = 0; i < links.length; i++) {
- const t = $.trim(links[i])
- if (t) {
- selectedLinks.push(t)
- }
- }
- if (linksBeforeSelection === false) {
- linksBeforeSelection = links.slice(0) // Save all links for later selections
- }
- const allLinks = linksBeforeSelection.slice(0)
- const popup = popUp('linkSelector')
- const $div = popup.node
- const $loader = $('<div style="width:20px; height:20px;" class="ochspinner"></div>').appendTo($div)
- $div.css('overflow', 'none')
- const $frame = $('<iframe style="border:0">').appendTo($div)
- $frame.attr('width', window.innerWidth - 190)
- $frame.attr('height', window.innerHeight - 120)
- $frame.bind('load', function (e) {
- const $body = $($frame[0].contentDocument.getElementsByTagName('body')[0])
- const $main = $('<div>').appendTo($body)
- const $table = $('<table>').appendTo($main)
- const $thead = $('<thead>').appendTo($table)
- const $tr0 = $('<tr>').appendTo($thead)
- const $th0 = $('<th>').appendTo($tr0).attr('colspan', 2)
- const $tr1 = $('<tr>').appendTo($thead)
- const $th1 = $('<th>').appendTo($tr1).attr('colspan', 2)
- const $tr2 = $('<tr>').appendTo($thead)
- const $th2 = $('<th>').appendTo($tr2).attr('colspan', 2)
- const $tr3 = $('<tr>').appendTo($thead)
- const $th3 = $('<th>').appendTo($tr3).attr('colspan', 2)
- const $tr4 = $('<tr>').appendTo($thead)
- const $th4 = $('<th>').appendTo($tr4).attr('colspan', 2)
- $('<span>Select: <span>').appendTo($th0)
- $('<button>').appendTo($th0).text('all').click(filter('all', trs))
- $('<button>').appendTo($th0).text('none').click(filter('none', trs))
- $('<button>').appendTo($th0).text('flip').click(filter('flip', trs))
- $('<button>').appendTo($th1).text('Select from ... to ...').click(filter('fromto', trs, $table, $thead, $th4))
- $('<button>').appendTo($th1).text('Select every ...').click(filter('every', trs, $table, $thead, $th4))
- $('<span> Filter:<span>').appendTo($th2)
- const inpFilter = $('<input>').appendTo($th2).attr('type', 'text')
- $('<button>').appendTo($th2).text('Flip with filter').click(filter('has', trs, inpFilter))
- $('<span> Host filter:<span>').appendTo($th3)
- const $selHost = $('<select>').appendTo($th3)
- $('<button>').appendTo($th3).text('Flip with host filter').click(filter('has', trs, $selHost))
- const allhosts = []
- for (let i = 0; i < allLinks.length; i++) {
- const $tr = $('<tr>').data('index', i).appendTo($table)
- const $td0 = $('<td>').appendTo($tr)
- const $check = $('<input>').appendTo($td0).attr('type', 'checkbox').attr('id', 'link_checkbox_' + i).prop('checked', selectedLinks.indexOf(allLinks[i]) !== -1)
- const $td1 = $('<td>').appendTo($tr)
- $('<label>').attr('for', 'link_checkbox_' + i).text(allLinks[i]).css('font-family', 'monospace').appendTo($td1)
- const host = allLinks[i].split('/')[2].replace(/^www\./, '')
- if (allhosts.indexOf(host) === -1) {
- allhosts.push(host)
- }
- trs.push({ $tr, $check, link: allLinks[i], host })
- }
- for (let i = 0; i < allhosts.length; i++) {
- $('<option>').val(allhosts[i]).text(allhosts[i]).appendTo($selHost)
- }
- $('<button>').appendTo($main).text('Apply').click(function () {
- const nlinks = []
- for (let i = 0; i < trs.length; i++) {
- if (trs[i].$check.prop('checked')) {
- nlinks.push(trs[i].link)
- }
- }
- if (nlinks.length === 0) {
- alert('No links selected?!')
- return
- }
- menu(nlinks)
- setStatus((nlinks.length === 1 ? 'One link' : (nlinks.length + ' links')) + ' selected', 1)
- popup.close()
- })
- $loader.remove()
- })
- if (chrome) {
- $frame.attr('src', 'about:blank')
- }
- }
- function menu (links) {
- // normalize links:
- if (!Array.isArray(links)) {
- const parts = links.split('\n')
- links = []
- for (let i = 0; i < parts.length; i++) {
- if ($.trim(parts[i])) {
- links.push($.trim(parts[i]))
- }
- }
- }
- const $c = $('#multiochhelper ul')
- $c.html('')
- const $select = $('<select>')
- const m = links[0].match(/https?:\/\/(.+?)\//)
- if (!m) {
- console.log(scriptName + ": Not a valid link: '" + links[0] + "'")
- return
- }
- const host = m[1]
- let hoster = host.split('.')
- hoster.pop()
- hoster = hoster.pop().replace('-', '')
- $.each(multi, function (key, val) {
- const $option = $('<option></option>').val(key).html(val.name).appendTo($select)
- if (key === currentdebrid) {
- $option[0].selected = true
- }
- if (multi[key].isOnline(hoster)) {
- $option.css('color', 'green')
- } else {
- $option.css('color', '#F00')
- }
- })
- let $entry = menuentry($select)
- $select.bind('change', function (ev) {
- const $this = $(this)
- // Change hoster
- currentdebrid = $this.val()
- // Check general support
- if (multi[currentdebrid].isOnline(hoster)) {
- // Check first link for support on this multi hoster
- multi[currentdebrid].checkLink(links[0], function (result) {
- if (!result) {
- alert(scriptName + '\n\n' + host + ' is not supported by this hoster or the file is offline.\n\nChecked: ' + links[0])
- }
- })
- } else {
- alert(scriptName + '\n\n' + host + ' is not supported by ' + multi[currentdebrid].name)
- }
- // Add "Remember" checkbox
- if (!$this.parent().find('#remember').length) {
- const $div = $('<div>')
- const $check = $('<input id="remember" type="checkbox" value="remember" title="Remember selection">').click(async function () {
- if (this.checked) {
- currentdebrid = $select.val()
- await GM.setValue('currentdebrid', currentdebrid)
- setStatus('Switched to ' + multi[currentdebrid].name, 1)
- $div.remove()
- }
- })
- $div.append($check).append('Remember')
- $this.parent().append($div)
- }
- })
- $entry = menuentry('Direct download')
- $entry.click(function () { mouse('download', links) })
- $entry = menuentry('Copy to clipboard')
- $entry.click(function () { mouse('clipboard', links) })
- if (settings.jDownloaderSupport) {
- $entry = menuentry('Send to JDownloader')
- $entry.attr('id', 'multiochhelperjdbutton')
- $entry.hide()
- $entry.click(function () { mouse('sendToJD', links) })
- GM.xmlHttpRequest({
- method: 'GET',
- url: JDOWNLOADER + 'flash/',
- onerror: function () {
- },
- onload: function (resp) {
- if (resp && resp.responseText && resp.responseText.startsWith('JDownloader')) {
- $('#multiochhelperjdbutton').show()
- }
- }
- })
- }
- if (!showOneclickFromHighlighScriptAllLinks) {
- $entry = menuentry('Show generated links')
- $entry.click(function () { mouse('showLinks', links) })
- }
- $entry = menuentry('Show extracted links')
- $entry.click(function () {
- if (window.parent.parent !== window) {
- window.parent.parent.postMessage({ iAm: 'Unrestrict.li', type: 'alert', str: links.join('\n') }, '*')
- alert(links.join('\n'))
- } else {
- showExtractedLinks(links)
- }
- })
- if (!showOneclickFromHighlighScriptAllLinks && (links.length > 1 || linksBeforeSelection !== false)) {
- $entry = menuentry('Select links')
- $entry.click(function () { linkSelector(links) })
- }
- if (!showOneclickFromHighlighScriptAllLinks) {
- $entry = menuentry()
- $('<a style="color:white !important;">Open Website</a>').attr('href', getMultiOCHWebsiteURL(links)).appendTo($entry)
- }
- if (showOneclickFromHighlighScriptAllLinks && showOneclickFromHighlighScriptAllLinksLinks) {
- $entry = $(menuentry('Use all links on page...'))
- $entry.click(function () {
- // Switch to all links instead of one
- const links = showOneclickFromHighlighScriptAllLinksLinks
- showOneclickFromHighlighScriptAllLinksLinks = ''
- menu(links)
- $('#multiochhelper div:empty:not(:first)').remove()
- setStatus('All links!', 1)
- })
- }
- if (showOneclickFromHighlighScriptSelectedLinks && showOneclickFromHighlighScriptSelectedLinksLinks) {
- $entry = $(menuentry('Use selected links...'))
- $entry.click(function () {
- // Switch to selected links instead of one
- const links = showOneclickFromHighlighScriptSelectedLinksLinks
- showOneclickFromHighlighScriptSelectedLinksLinks = ''
- menu(links)
- $('#multiochhelper div:empty:not(:first)').remove()
- setStatus('Using selected links!', 1)
- })
- }
- if (!showOneclickFromHighlighScriptAllLinks) {
- $entry = menuentry($('<span style="cursor:default; color:silver">Userscript menu</span>').click(function (ev) { ev.stopPropagation(); aboutMe() }))
- $entry.css('cursor', 'default')
- $('<span style="cursor:pointer; color:White; border: 1px solid White; border-radius:3px; padding:0px; margin-left:20px; font-weight:bold ; " title="Close menu">X</span>').click(function () { $('#multiochhelper').remove() }).appendTo($entry)
- }
- }
- function loader () {
- // Show an animation, return function to remove the loader
- $('#multiochhelper_status_loader').parent().show()
- const $div = $('<div class="ochspinner"></div>').appendTo($('#multiochhelper_status_loader'))
- return function () {
- $div.remove()
- }
- }
- async function mouse (action, linkText) {
- // decide what to do after a mouse click
- const removeImg = loader()
- if (action === 'download') {
- await download(linkText, removeImg)
- } else if (action === 'showLinks') {
- showLinks(linkText, removeImg)
- } else if (action === 'openWebsite') {
- openWebsite(linkText)
- } else if (action === 'clipboard') {
- await clipboard(linkText, removeImg)
- } else if (action === 'menu') {
- removeImg()
- menu(linkText)
- } else if (action === 'sendToJD') {
- await sendToJD(linkText, removeImg)
- }
- }
- function menuentry (html) {
- const $li = $('<li>')
- if (html) {
- $li.append(html)
- }
- $li.appendTo('#multiochhelper ul')
- return $li
- }
- function button (label) {
- addCSSHead(`
- #multiochhelper,#multiochhelper * {
- font-family:Sans-Serif !important;
- padding:0px; margin:0px;
- }
- #multiochhelper a, #multiochhelper a:link,#multiochhelper a:visited {
- text-decoration:underline !important;
- color:#3788e8 !important;
- font-style:none !important;
- }
- #multiochhelper a:hover {
- text-decoration:none !important;
- color:#3788e8 !important;
- font-style:none !important;
- }
- #multiochhelper ul li,#multiochhelper_status {
- margin:1px 1px;
- padding:1px 5px;
- font-size:13px;
- text-shadow:0 -1px 0 #333333;
- color:White;
- border:1px solid #8B3D92;
- background-color:#B555C5;
- background:radial-gradient(ellipse at center, #B555C5, #8B3D92);
- list-style:none outside;
- }
- #multiochhelper div#multiochhelper_status_loader {
- float:left;
- }
- #multiochhelper div#multiochhelper_status_text {
- float:left;
- }
- #multiochhelper div#multiochhelper_status_clear {
- clear:left;
- }
- #multiochhelper ul li {
- cursor:pointer;
- }
- #multiochhelper ul li:hover {
- background-color:#CC6BDD;
- background:radial-gradient(ellipse at center, #CC6BDD, #8B3D92);
- }
- #multiochhelper select,#multiochhelper input {
- border-radius:0;
- box-shadow:none;
- text-shadow:none;
- border:none;
- background:white;
- color:black;
- }
- ${SPINNERCSS}
- `)
- // div container
- const zi = getNextZIndex()
- const $div = $('<div>').appendTo(document.body)
- $div.attr('id', 'multiochhelper')
- $div.attr('style', 'z-index:' + zi + '; position:fixed; background:#E6E6E6; color:Black; border:#B555C5 2px solid;border-radius:5px; padding:3px;')
- if (settings.position[0] === 'top') {
- $div.css('top', '0%')
- } else {
- $div.css('bottom', '0%')
- }
- if (settings.position[1] === 'left') {
- $div.css('left', '0%')
- } else {
- $div.css('right', '0%')
- }
- // Status
- const $status = $('<div>').appendTo($div).hide()
- $status.attr('id', 'multiochhelper_status')
- const $loader = $('<div>').appendTo($status)
- $loader.attr('id', 'multiochhelper_status_loader')
- const $statustext = $('<div>').appendTo($status)
- $statustext.attr('id', 'multiochhelper_status_text')
- const $statusclear = $('<div>').appendTo($status)
- $statusclear.attr('id', 'multiochhelper_status_clear')
- const $ul = $('<ul>').appendTo($div)
- // Button
- const $entry = menuentry(label || (multi[currentdebrid].name.charAt(0).toUpperCase() + multi[currentdebrid].name.slice(1)))
- $ul.append($entry)
- return $entry
- }
- const isSetup = await GM.getValue('setup', false)
- // Update hoster status
- let updatinghosters = false
- if (isSetup) {
- for (const key in multi) {
- if (multi[key].updateStatusURLpattern.test(document.location.href)) { // usually in this is true in the iframe which is defined below
- multi[key].updateStatus()
- updatinghosters = true
- break
- }
- }
- }
- // Create iframes to check hoster status:
- if (!updatinghosters && isSetup) {
- const now = new Date()
- for (const key in multi) {
- if ('updateStatusURL' in multi[key] && (now - multi[key].lastUpdate) > (settings.updateHosterStatusInterval * 60 * 60 * 1000)) {
- const $iframe = $('<embed>').appendTo(document.body)
- $iframe.bind('load', function () {
- const frame = this
- window.setTimeout(function () { $(frame).remove() }, 3000)
- })
- $iframe.attr('src', multi[key].updateStatusURL)
- }
- }
- }
- // Setup
- if (!updatinghosters) {
- if (!isSetup) {
- await aboutMe()
- if (!confirm(scriptName + ' Setup\n\nPlease take some time to configure ' + scriptName + ' and then save the settings!\n\nPress cancel to continue with the default configuration!')) {
- await GM.setValue('setup', true)
- alert(scriptName + '\n\nDefault settings will be used.')
- document.location.reload()
- }
- }
- }
- if (document.location.href.indexOf('nopremium.pl') !== -1) {
- // nopremium.pl Website
- if (document.location.search.substring(0, 6) === '?link:') {
- // Insert link on nopremium.pl
- $('#filesList').val(decodeURIComponent(document.location.search.substring(6)))
- }
- } else if (document.location.href.indexOf('www.premiumize.me') !== -1) {
- // premiumize.me Website
- if (document.location.search.substring(0, 6) === '?link:') {
- // Insert link on nopremium.pl
- $('textarea').val(decodeURIComponent(document.location.search.substring(6)))
- }
- } else if (document.location.href.indexOf('download.serienjunkies.org') !== -1) {
- // Serienjunkies
- if (!document.querySelector('.g-recaptcha')) { // if not on captcha page
- const $b = button('Decrypt links')
- $b.click(function (ev) {
- const removeImg = loader()
- getSerienjunkiesLinks(removeImg)
- })
- }
- } else if (document.location.href === 'http://filecloud.io/download.html') {
- // filecloud.io
- if (unsafeWindow.__currentUrl) {
- showOneclickButton = true
- showOneclickLink = decodeURIComponent(unsafeWindow.__currentUrl)
- }
- } else if (document.location.href.indexOf('filecrypt.cc') !== -1) {
- // filecrypt.cc folder
- if (document.location.href.indexOf('helper.html') !== -1) { // if not on captcha page
- window.addEventListener('message', function filecryptmessage (event) {
- if (event.data && typeof (event.data) === 'object') {
- window.opener.postMessage({ filecryptData: JSON.stringify(event.data) }, '*') // Send message back to the opening window
- window.removeEventListener('message', filecryptmessage) // Prevent further messages from creating several buttons
- }
- }, false)
- } else if (document.location.href.indexOf('Container') !== -1) { // if not on captcha page
- const $b = button("Please open the Click'n'Load Popup (several times)")
- $b.click(function () {
- $('#cnl_btn').click()
- })
- window.addEventListener('message', function filecryptmessage2 (event) { // Receive messages from the popup
- if (event.data && typeof (event.data) === 'object' && 'filecryptData' in event.data) {
- window.removeEventListener('message', filecryptmessage2) // Prevent further messages from creating several buttons
- setStatus('Decrypting', -1)
- const removeImg = loader()
- getFilecryptcc(JSON.parse(event.data.filecryptData), removeImg)
- }
- }, false)
- }
- } else if (document.location.href.substring(7, 22) === 'protected.to/f-') {
- // http://protected.to folder
- if (document.querySelectorAll('.links a').length > 0) { // If not on captcha page
- showOneclickButton = true
- showOneclickLink = ''
- $('.links a').each(function () {
- showOneclickLink += decodeURIComponent(this.href) + '\n'
- })
- }
- } else if (document.location.href.substring(8, 23) === 'safelinking.net') {
- // safelinking.net folder
- if (!document.getElementById('captcha-wrapper')) {
- const $b = button('Decrypt links')
- $b.click(function (ev) {
- const removeImg = loader()
- getSafeLinkingNetLinks(removeImg)
- })
- }
- } else if (document.location.href.indexOf('.firedrive.com/share/') !== -1) {
- // firedrive.com folder
- showOneclickButton = true
- showOneclickLink = ''
- $('a.pf_item_link:visible').each(function () {
- showOneclickLink += decodeURIComponent(this.href) + '\n'
- })
- } else if (document.location.href.indexOf('rapidgator.net/folder/') !== -1) {
- // Rapidgator folder
- showOneclickButton = true
- showOneclickLink = ''
- $('#grid tbody a').each(function () {
- showOneclickLink += decodeURIComponent(this.href) + '\n'
- })
- } else if (document.location.hostname === "dailyuploads.net" && currentdebrid === 'premiumize.me') {
- // Dailyuploads.net: submit direct download link (after captcha was solved) to premiumize.me instead of link
- if (document.querySelector('div.banner div.inner a>img[src*="redbutton.png"]')) {
- showOneclickButton = true
- showOneclickLink = document.querySelector('div.banner div.inner a>img[src*="redbutton.png"]').parentNode.href
- } else {
- showOneclickButton = false
- button("Please solve the captcha first")
- }
- } else if (document.location.hostname === 'multiup.org') {
- // Multiup.org mirrors
- showOneclickButton = document.querySelectorAll('button[link]').length > 0
- showOneclickLink = Array.from(document.querySelectorAll('button[link]')).map(b => b.getAttribute('link')).join('\n')
- } else if (document.location.href.substring(0, 55) === 'https://cvzi.github.io/Userscripts/index.html?link=sync') {
- // Window opened from Helper script to sync hoster status (see postMessage events below)
- showOneclickButton = false
- const message = 'Updating hoster status...'
- const h1 = document.body.appendChild(document.createElement('h1'))
- h1.appendChild(document.createTextNode(scriptHightligherName + ': ' + message))
- setTitle('')
- window.setTimeout(function () {
- const h2 = document.body.appendChild(document.createElement('h2'))
- h2.appendChild(document.createTextNode('You may close this tab now'))
- }, 4000)
- } else if (document.location.href.substring(0, 51) === 'https://cvzi.github.io/Userscripts/index.html?link=') {
- // Iframe for a X-Frame-Options website
- showOneclickButton = true
- showOneclickLink = decodeURIComponent(document.location.search.match(/link=(.+)/)[1])
- } else {
- // One click hoster website
- showOneclickButton = true
- showOneclickLink = decodeURIComponent(document.location.href)
- }
- if (showOneclickButton) {
- let mouseOverAvailable = true
- // Split links into array
- const splitted = showOneclickLink.split('\n')
- showOneclickLink = []
- for (let i = 0; i < splitted.length; i++) {
- if ($.trim(splitted[i])) {
- showOneclickLink.push($.trim(splitted[i]))
- }
- }
- const $b = button()
- $b.bind('mousedown',
- function (ev) {
- mouseOverAvailable = false
- if (ev.which === 3) { // Right click
- mouse(settings.rightClick, showOneclickLink)
- } else if (ev.which === 2) { // Middle click
- mouse(settings.middleClick, showOneclickLink)
- } else if (ev.which === 1) { // Left click {
- mouse(settings.leftClick, showOneclickLink)
- }
- })
- if (settings.mouseOver !== 'none') {
- let ti = false
- $b.on({
- mouseover: function () {
- if (!mouseOverAvailable) { return }
- ti = setTimeout(function () {
- if (!mouseOverAvailable) { return }
- mouseOverAvailable = false
- mouse(settings.mouseOver, showOneclickLink)
- }, settings.mouseOverDelay)
- },
- mouseout: function () {
- if (ti !== false) clearTimeout(ti)
- }
- })
- }
- // Prevent context menu on right click
- if (settings.rightClick !== 'none') {
- $b[0].addEventListener('contextmenu', e => e.preventDefault(), false)
- }
- }
- // Handle messages from the highlight script
- window.addEventListener('message', function (e) {
- if (typeof e.data !== 'object' || !('iAm' in e.data) || e.data.iAm !== 'Unrestrict.li') {
- return
- }
- switch (e.data.type) {
- case 'alllinks':
- if (showOneclickFromHighlighScriptAllLinks) {
- return
- }
- showOneclickFromHighlighScriptAllLinks = true
- showOneclickFromHighlighScriptAllLinksLoc = e.data.loc
- showOneclickFromHighlighScriptAllLinksLinks = e.data.links.join('\n')
- if ($('#multiochhelper ul li').length > 1) { // Menu already opened
- menu(showOneclickLink)
- }
- break
- case 'selectedlinks':
- if (showOneclickFromHighlighScriptSelectedLinks) {
- return
- }
- showOneclickFromHighlighScriptSelectedLinks = true
- showOneclickFromHighlighScriptSelectedLinksLoc = e.data.loc
- showOneclickFromHighlighScriptSelectedLinksLinks = e.data.links.join('\n')
- if ($('#multiochhelper ul li').length > 1) { // Menu already opened
- menu(showOneclickLink)
- }
- break
- case 'requesthosterstatus': {
- window.setTimeout(function () {
- const h3 = document.body.appendChild(document.createElement('h3'))
- h3.appendChild(document.createTextNode('This will only take a few seconds'))
- }, 0)
- const o = {}
- for (const key in multi) {
- o[key] = multi[key].status
- }
- e.source.postMessage({ iAm: 'Unrestrict.li', type: 'hosterstatus', str: JSON.stringify(o) }, '*')
- break
- }
- }
- }, true)
- })()