Skip to content

Instantly share code, notes, and snippets.

@ariankordi
Last active September 11, 2020 21:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ariankordi/952bf916959e0219e5f6cbd4e5c0edc3 to your computer and use it in GitHub Desktop.
Save ariankordi/952bf916959e0219e5f6cbd4e5c0edc3 to your computer and use it in GitHub Desktop.
insanele stupid hack that i spent hours on that lets you watch crunchyroll on cytube, worked on calzoneman/sync commit 88365612dab2351b297c895952fa98b105894b4d
diff --git a/index.js b/index.js
old mode 100755
new mode 100644
diff --git a/package.json b/package.json
index a003e77..caee25a 100644
--- a/package.json
+++ b/package.json
@@ -13,17 +13,19 @@
"bcrypt": "^3.0.6",
"bluebird": "^3.5.1",
"body-parser": "^1.18.2",
"cheerio": "^1.0.0-rc.2",
"clone": "^2.1.1",
"compression": "^1.5.2",
"cookie-parser": "^1.4.0",
"create-error": "^0.3.1",
"csrf": "^3.0.0",
- "cytube-mediaquery": "git://github.com/CyTube/mediaquery",
+ "cytube-mediaquery": "git://github.com/CyTube/mediaquery.git",
"cytubefilters": "git://github.com/calzoneman/cytubefilters.git#c6df180eeb226eaffc7909cf047d3667dc58ef67",
"express": "^4.16.2",
"express-minify": "^1.0.0",
"graceful-fs": "^4.1.2",
+ "html-entities": "^1.3.1",
"json-typecheck": "^0.1.3",
"knex": "^0.20.3",
"lodash": "^4.17.5",
diff --git a/servcmd.sh.js b/servcmd.sh.js
old mode 100755
new mode 100644
diff --git a/src/ffmpeg.js b/src/ffmpeg.js
index 377d3cb..e946cf8 100644
--- a/src/ffmpeg.js
+++ b/src/ffmpeg.js
@@ -138,6 +138,9 @@ function getCookie(res) {
function testUrl(url, cb, params = { redirCount: 0, cookie: '' }) {
const { redirCount, cookie } = params;
var data = urlparse.parse(url);
+
+if(url.startsWith('https://dl.v.vrv.co/')) return cb();
+
if (!/https:/.test(data.protocol)) {
if (redirCount > 0) {
// If the original URL redirected, the user is probably not aware
@@ -188,7 +191,12 @@ function testUrl(url, cb, params = { redirCount: 0, cookie: '' }) {
return cb(translateStatusCode(res.statusCode));
}
- if (!/^audio|^video/.test(res.headers["content-type"])) {
+const hlsContentTypes = [
+ "application/vnd.apple.mpegurl",
+ "application/x-mpegURL"
+];
+ //if (!/^audio|^video/.test(res.headers["content-type"])) {
+ if (!/^audio|^video/.test(res.headers["content-type"]) && !hlsContentTypes.includes(res.headers["content-type"])) {
cb("Could not detect a supported audio/video type. See " +
"https://git.io/fjtOK for a list of supported providers. " +
"(Content-Type was: '" + res.headers["content-type"] + "')");
@@ -508,8 +516,9 @@ exports.query = function (filename, cb) {
cb(null, data);
} else {
- return cb("File did not contain an acceptable codec. See " +
+ /*return cb("File did not contain an acceptable codec. See " +
"https://git.io/vrE75 for details.");
+ */cb(null, data);
}
});
}));
diff --git a/src/get-info.js b/src/get-info.js
index 25bca7c..1a68445 100644
--- a/src/get-info.js
+++ b/src/get-info.js
@@ -13,6 +13,14 @@ const Mixer = require("cytube-mediaquery/lib/provider/mixer");
import { Counter } from 'prom-client';
import { lookup as lookupCustomMetadata } from './custom-media';
+const fs = require('fs');
+const url = require('url');
+const http = require('http');
+const zlib = require('zlib');
+// yes we need this so that the crunchyroll titles aren't messed upup
+// i know. i hate this as much as you do too
+const AllHtmlEntities = require('html-entities').AllHtmlEntities;
+
const LOGGER = require('@calzoneman/jsli')('get-info');
const lookupCounter = new Counter({
name: 'cytube_media_lookups_total',
@@ -20,21 +28,67 @@ const lookupCounter = new Counter({
labelNames: ['shortCode']
});
-var urlRetrieve = function (transport, options, callback) {
- var req = transport.request(options, function (res) {
- res.on("error", function (err) {
+function fixRedirectIfNeeded(urldata, redirect) {
+ var parsedRedirect = url.parse(redirect);
+
+ //console.log('from ' + urldata.host + ' to ' + parsedRedirect.hostname);
+ if(parsedRedirect.host !== null) {
+ // Relative path,
+ // uh oops looks like url.parse's host has a port name and hostname doesn't, uhh this probably ruins some continuity idk just help me
+ urldata.host = parsedRedirect.hostname;
+ urldata.hostname = parsedRedirect.hostname;
+ }
+
+ urldata.path = parsedRedirect.path;
+
+ return urldata;
+}
+
+var urlRetrieve = function (transport, options, callback, params = { redirCount: 0}) {
+ const { redirCount, cookie } = params;
+
+ //console.log(options.host + options.path);
+
+ var req = transport.request(options, function (res) {
+ res.on("error", function (err) {
+
LOGGER.error("HTTP response " + options.host + options.path + " failed: "+
err);
callback(503, "");
});
- var buffer = "";
- res.setEncoding("utf-8");
+ var chunks = [];
+ //res.setEncoding("utf-8");
+ res.setEncoding('binary');
res.on("data", function (chunk) {
- buffer += chunk;
+ //console.log(typeof chunk);
+ chunks.push(Buffer.from(chunk, 'binary'));
});
res.on("end", function () {
- callback(res.statusCode, buffer);
+ if (res.statusCode === 301 || res.statusCode === 302) {
+ //console.log('... and handling! redirect!')
+ if (redirCount > 2) {
+ return callback(503, "The request for the audio/video file has been redirected " +
+ "more than twice. This could indicate a misconfiguration " +
+ "on the website hosting the link. For best results, use " +
+ "a direct link. See https://git.io/vrE75 for details.");
+ }
+ const nextParams = {
+ redirCount: redirCount + 1
+ };
+ return urlRetrieve(transport, fixRedirectIfNeeded(options, res.headers["location"]), callback, nextParams);
+ }
+ // now gzip uncompress !!!!
+ //console.log(res.headers);
+ var buffer = Buffer.concat(chunks);
+ if(res.headers['content-encoding'] && res.headers['content-encoding'] === 'gzip') {
+ zlib.gunzip(buffer, function(err, decoded) {
+ //console.log(err);
+ callback(res.statusCode, decoded && decoded.toString());
+ });
+ } else {
+ callback(res.statusCode, buffer.toString());
+ }
});
});
@@ -423,9 +477,23 @@ var Getters = {
);
return;
}
- var title = "Livestream";
+ /*var title = "Livestream";
var media = new Media(id, title, "--:--", "hl");
callback(false, media);
+ var title = "not a Livestream";
+ */
+ //var media = new Media(id, title, "--:--", "hl");
+ ffmpeg.query(id, function (err, data) {
+ if (err) {
+ return callback(err);
+ }
+
+ var m = new Media(id, title, data.duration, "hl", {
+ codec: data.codec
+ });
+ callback(null, m);
+ });
+ //callback(false, media);
},
/* imgur.com albums */
@@ -481,8 +549,201 @@ var Getters = {
});
},
- /* ffmpeg for raw files */
- fi: function (id, cb) {
+ /* ffmpeg for raw files */
+ fi: function (id, cb) {
+ //var _this = this;
+ // see if url happens to be a crunchyroll url
+ if(id.startsWith('https://www.crunchyroll.com/')) {
+ LOGGER.info('entering cronchyroll handler');
+ // wWAIT. first check if string ends with !no, if so then NO HARDSUBS!
+ // edit now the no hardsubs function chooses the opposite default hardsub option lol ok who cares i am the only one who will be using this anyway because it is extraordinarily bad
+ var noHardsubs = false;
+ if(id.endsWith('!no')) {
+ noHardsubs = true;
+ // strip last three characters, "!no" from the id
+ id = id.substring(0, id.length - 3);
+ }
+ urlRetrieve(https, {
+ //host: 'www.crunchyroll.com',
+ host: 'status.tehw00t.net',
+ port: 443,
+ path: '/miniProxy.php?' + id,
+ //path: id.split('.com')[1],
+ method: 'GET',
+ headers: {
+ // this header is necessary in some cases or else the website may redirect and return 302
+ 'Accept-Language': 'en-US'
+ }
+ }, function(status, data) {
+ switch (status) {
+ case 200:
+ break; /* Request is OK, skip to handling data */
+ default:
+ return cb("HTTP " + status, null);
+ }
+ //var $ = cheerio.load(data);
+ /*fs.writeFile('helloworld.txt', data, function (err) {
+ if (err) return console.log(err);
+ console.log('Hello World > helloworld.txt');
+ });*/
+ //console.log(data);
+ // if video has trailer notice
+ if(data.includes('<div class="showmedia-trailer-notice">')) {
+ cb('crunchyroll is only responding to us with a trailer for this video. strange. it\'s not going to work, did you provide a premium-only video? because that will not work here', null);
+ return;
+ }
+
+ var splitFinalUrl;
+ //var splitTitle;
+ var fixedTitle;
+ try {
+ var splitPart1;
+ /*if(noHardsubs) {
+ splitPart1 = data.split('hls","audio_lang":"jaJP","hardsub_lang":null,"url":"');
+ } else {
+ splitPart1 = data.split('hls","audio_lang":"jaJP","hardsub_lang":"enUS","url":"');
+ }*/
+ // determine audio lang first.
+ //console.log('hellO!')
+ var splitAudioLangPart1 = data.split('hls","audio_lang":"')
+ splitAudioLangPart1 = [splitAudioLangPart1.shift(), splitAudioLangPart1.join('hls","audio_lang":"')]
+ var splitAudioLangPart2 = splitAudioLangPart1[1].split('"')[0];
+ //console.log('audio lang is ' + splitAudioLangPart2)
+ // if audio lang is english, then don't use hardsubs by default.
+ var useHardsubs = true;
+ // if language is NOT japanese, use subs
+ if(splitAudioLangPart2 !== 'jaJP') {
+ useHardsubs = false;
+ //console.log('so i will NOt have hardsubs')
+ //splitPart1 = splitAudioLangPart1[1].split('hardsub_lang":null,"url":"');
+ }/* else {
+ console.log('i am including hardsubs')
+ // for other languages, get the hardsub version
+ splitPart1 = splitAudioLangPart1[1].split('hardsub_lang":"enUS","url":"');
+ }*/
+ // in this context, this noHardsubs name means to just invert the current value of whether we are using hardsubs or not.
+ if(noHardsubs) {
+ useHardsubs = !useHardsubs;
+ }
+ if(useHardsubs) {
+ //console.log('so we are using hardsubs apparently')
+ splitPart1 = splitAudioLangPart1[1].split('hardsub_lang":"enUS","url":"');
+ } else {
+ //console.log('not using hardsubs.')
+ splitPart1 = splitAudioLangPart1[1].split('hardsub_lang":null,"url":"');
+ }
+ // splitpart1 has the url with a quote and content at the end
+ // splitpart2 will have the actual url content
+ var splitPart2 = splitPart1[1].split('"')[0];
+ //console.log('got url. pray that this works')
+ splitFinalUrl = splitPart2.replace(/\\/g, '');
+ //LOGGER.info(splitFinalUrl);
+ //console.log(splitPart2);
+ //console.log(splitFinalUrl);
+
+ // extract title from meta name element
+ var splitTitlePart1 = data.split('tle>');
+ // split title by the ending tag too just in case,,
+ var splitTitlePart2 = splitTitlePart1[1].split('</');
+ var splitTitle = splitTitlePart2[0].split(', - Watch on Crunchyroll')[0];
+ var fixedTitle = new AllHtmlEntities().decode(splitTitle);
+ LOGGER.info('crunchyroll title: ' + fixedTitle);
+ } catch(e) {
+ LOGGER.error(e.stack);
+ cb('crunchyroll parsing error. you probably entered an incorrect url; this feature is very dumb and only reads episode watch urls correctly. can you visit it yourself? ' + e, null);
+ return;
+ }
+ //cb(splitFinalUrl, null);
+ /*_this.hl(splitFinalUrl, function(one, two) {
+ cb(one, two);
+ });*/
+ /*ffmpeg.query(splitFinalUrl, function (err, data) {
+ if (err) {
+ return cb(err);
+ }
+
+ //console.log('DURATION! DURATION! ' + typeof data.duration + '::: ' + data.duration);
+
+ var m = new Media(splitFinalUrl, splitTitle, data.duration, "hl", {
+ codec: data.codec
+ });
+ return cb(null, m);
+ });*/
+ // mANually gwt duration
+ // NVM I JUST WROTE ALL OF THIS AND REALIZED IT'SNOT EVEN NECESSARY AAAA
+ var mediaLength = 0.0;
+
+ var requestData = url.parse(splitFinalUrl);
+ //console.log('entering hls parse with ' + splitFinalUrl);
+ urlRetrieve(https, requestData, function(s, data) {
+ if(s !== 200) {
+ LOGGER.error('OH NO STATUS IS NOT 200!!!!! it is ' + s);
+ }
+ var initialHlsLines = data.split('\n');
+ var foundFirstUrl;
+ initialHlsLines.forEach(function(line) {
+ //console.log('line!');
+ // if first url was already found, then DIE. ok?
+ if(foundFirstUrl === true) {
+ //console.log('skipping this');
+ return;
+ }
+ // if line is empty??? then skip
+ if(line.length < 1) {
+ return;
+ }
+ if(line[0] === '#') {
+ return;
+ }
+ foundFirstUrl = true;
+ // ok so this line may be a url now so i guess get it
+ //console.log('ok now i am going to get ' + line);
+ requestData = url.parse(line);
+ urlRetrieve(https, requestData, function(s, data) {
+ if(s !== 200) {
+ LOGGER.error('OH NO STATUS IS NOT 200!!!!! it is ' + s);
+ }
+ var hlsLines = data.split('\n');
+ hlsLines.forEach(function(line) {
+ // eof. done???
+ if(line.length < 1) {
+ var duration = Math.ceil(mediaLength);
+ LOGGER.info('hls video duration: ' + String(duration));
+ // FIX pl.crunchyroll.com!!!!
+ // replace to use proxy
+ if(splitFinalUrl.startsWith('https://pl.crunchyroll.com')) {
+ splitFinalUrl = splitFinalUrl.replace('https://pl.crunchyroll.com', '/pl-proxy');
+ }
+ var m = new Media(splitFinalUrl, fixedTitle, duration, "hl", {
+ codec: 'h264'
+ });
+ return cb(null, m);
+ }
+ if(!line.startsWith('#EXTINF:')) {
+ return;
+ }
+ // this line is an extinf line at this point
+ var thisHlsNumber = line.split('#EXTINF:')[1].split(',')[0];
+ //console.log(Number(thisHlsNumber));
+ mediaLength += Number(thisHlsNumber);
+ //console.log(mediaLength);
+ });
+ });
+ // first one is the only one necessary ok ok ok ok
+ return;
+ });
+ });
+ /*var m = new Media(splitFinalUrl, splitTitle, 0, "hl", {
+ codec: 'h264'
+ });
+ return cb(null, m);
+ */
+ });
+ return;
+ }
+ LOGGER.info('ooops! reaching standard fi handler');
ffmpeg.query(id, function (err, data) {
if (err) {
return cb(err);
diff --git a/src/media.js b/src/media.js
index 6829f7c..7ff01a9 100644
--- a/src/media.js
+++ b/src/media.js
@@ -19,8 +19,8 @@ function Media(id, title, seconds, type, meta) {
Media.prototype = {
setTitle: function (title) {
this.title = title;
- if (this.title.length > 100) {
- this.title = this.title.substring(0, 97) + "...";
+ if (this.title.length > 200) {
+ this.title = this.title.substring(0, 197) + "...";
}
},
diff --git a/src/tor.js b/src/tor.js
index bd64194..0343a0f 100644
--- a/src/tor.js
+++ b/src/tor.js
@@ -12,6 +12,7 @@ const ONE_DAY = 24 * 3600 * 1000;
const TOR_EXIT_IPS = new Set();
function loadTorList() {
+ LOGGER.info('loadTorList()');
return fs.statAsync(TOR_EXIT_LIST_FILE).then(stats => {
if (new Date() - stats.mtime > ONE_DAY) {
LOGGER.info('Tor exit node list is older than 24h, re-downloading from %s',
@@ -66,10 +67,12 @@ function loadTorListFromWebsite() {
}
function loadTorListFromFile() {
- LOGGER.info('Loading Tor exit list from %s', TOR_EXIT_LIST_FILE);
- return fs.readFileAsync(TOR_EXIT_LIST_FILE).then(contents => {
+ LOGGER.info('Loading Tor exit list from %s lmao jk NOT', TOR_EXIT_LIST_FILE);
+ return [];
+ /*return fs.readFileAsync(TOR_EXIT_LIST_FILE).then(contents => {
return JSON.parse(String(contents));
});
+ */
}
loadTorList().then(exits => {
diff --git a/src/utilities.js b/src/utilities.js
index 485ae23..0ff7524 100644
--- a/src/utilities.js
+++ b/src/utilities.js
@@ -231,7 +231,7 @@
case "cu":
case "im":
case "hb":
- case "hl":
+ //case "hl":
case "mx":
return true;
default:
diff --git a/src/web/csrf.js b/src/web/csrf.js
index 2fd6fa6..55994c3 100644
--- a/src/web/csrf.js
+++ b/src/web/csrf.js
@@ -16,7 +16,9 @@ exports.init = function csrfInit (domain) {
res.cookie("_csrf", secret, {
domain: domain,
signed: true,
- httpOnly: true
+ httpOnly: true,
+ sameSite: 'None',
+ secure: true,
});
}
diff --git a/src/web/routes/index.js b/src/web/routes/index.js
index dc10313..402b55e 100644
--- a/src/web/routes/index.js
+++ b/src/web/routes/index.js
@@ -1,5 +1,8 @@
import { sendPug } from '../pug';
+const https = require('https');
+
export default function initialize(app, channelIndex, maxEntries) {
app.get('/', (req, res) => {
channelIndex.listPublicChannels().then((channels) => {
@@ -18,4 +21,41 @@ export default function initialize(app, channelIndex, maxEntries) {
});
});
});
+
+ // fix for pl.crunchyroll.com, just like how nani.ninja and umi.party had to
+ // fun fact i had the exact same idea for implementation as umi o_o...............
+ app.get('/pl-proxy/:url(*)', function(req, response) {
+ var headers = {};
+ // pass through compression why am i doing this to myself
+ if(req.headers['accept-encoding']) {
+ headers['accept-encoding'] = req.headers['accept-encoding'];
+ }
+ //console.log(req);
+ // idk if parsedUrl will always be accessible but ok
+ https.get('https://pl.crunchyroll.com/' + req.params.url + req._parsedUrl.search, {headers: headers}, function(res) {
+ let chunks = [];
+ res.setEncoding('binary');
+ res.on('data', function(chunk) {
+ chunks.push(Buffer.from(chunk, 'binary'));
+ });
+ res.on('end', function() {
+ // pass content type
+ response.setHeader('Content-Type', res.headers['content-type']);
+ response.setHeader('Content-Length', res.headers['content-length']);
+ //console.log(res.headers)
+ // pass through compression i guess
+ if(res.headers['content-encoding']) {
+ response.setHeader('Content-Encoding', res.headers['content-encoding']);
+ }
+ response.send(Buffer.concat(chunks));
+ //response.send(responseData);
+ });
+ });
+ // that should do it
+ });
}
diff --git a/src/web/webserver.js b/src/web/webserver.js
index cb9ef61..560f435 100644
--- a/src/web/webserver.js
+++ b/src/web/webserver.js
@@ -243,13 +243,15 @@ module.exports = {
domain: Config.get("http.root-domain-dotted"),
expires: expiration,
httpOnly: true,
- signed: true
+ signed: true,
+ secure: true,
});
} else {
res.cookie("auth", auth, {
expires: expiration,
httpOnly: true,
- signed: true
+ signed: true,
+ secure: true,
});
}
}
diff --git a/templates/contact.pug b/templates/contact.pug
index 67f2cd3..add47d4 100644
--- a/templates/contact.pug
+++ b/templates/contact.pug
@@ -6,16 +6,17 @@ mixin email(e, k)
block content
.col-md-8.col-md-offset-2
h1 Contact
- h3 Email
- if contacts.length == 0
- p No contacts listed.
- else
- each contact in contacts
- strong= contact.name
- p.text-muted= contact.title
- +email(contact.email, contact.emkey)
- br
- hr
+ p don&apos;t
+ //h3 Email
+ //if contacts.length == 0
+ // p No contacts listed.
+ //else
+ // each contact in contacts
+ // strong= contact.name
+ // p.text-muted= contact.title
+ // +email(contact.email, contact.emkey)
+ // br
+ // hr
append footer
script(type="text/javascript").
diff --git a/templates/footer.pug b/templates/footer.pug
index 210e45a..43dfd7b 100644
--- a/templates/footer.pug
+++ b/templates/footer.pug
@@ -3,6 +3,7 @@ mixin footer
.container
p.text-muted.credit.
Powered by CyTube, available on <a href="https://github.com/calzoneman/sync" target="_blank" rel="noreferrer noopener">GitHub</a>&nbsp;&middot; <a href="/contact" target="_blank">Contact</a>&nbsp;&middot; <a href="https://github.com/calzoneman/sync/wiki" target="_blank" rel="noopener noreferrer">Wiki</a>
+ <br>Modified source code available on <a href="https://gist.github.com/ariankordi/952bf916959e0219e5f6cbd4e5c0edc3" target="_blank" rel="noreferrer noopener">my GitHub Gist</a>, also <a href="/cronch.patch" target="_blank" rel="noreferrer noopener">here (download)</a>
script(src="/js/jquery-1.11.0.min.js")
// Must be included before jQuery-UI since jQuery-UI overrides jQuery.fn.button
// I should really abandon this crap one day
diff --git a/templates/head.pug b/templates/head.pug
index 597e977..8659ef7 100644
--- a/templates/head.pug
+++ b/templates/head.pug
@@ -5,6 +5,11 @@ mixin head()
meta(name="viewport", content="width=device-width, initial-scale=1.0")
meta(name="description", content=siteDescription)
+ link(rel="icon", type="image/png", href="/img/favicon.png")
+ meta(name="og:image", content="/img/a.jpg")
+ meta(name="twitter:card", content="summary_large_image")
+
+
title= siteTitle
link(href="/css/sticky-footer-navbar.css", rel="stylesheet")
link(href="/css/cytube.css", rel="stylesheet")
diff --git a/www/css/sticky-footer-navbar.css b/www/css/sticky-footer-navbar.css
index 923c7de..713014d 100644
--- a/www/css/sticky-footer-navbar.css
+++ b/www/css/sticky-footer-navbar.css
@@ -21,7 +21,7 @@ body {
}
.container .credit {
- margin: 20px 0;
+ margin: 10px 0;
text-align: center;
}
diff --git a/www/js/ui.js b/www/js/ui.js
index 2db2ea3..03e5c53 100644
--- a/www/js/ui.js
+++ b/www/js/ui.js
@@ -360,6 +360,7 @@ function queue(pos, src) {
if (pos === "next" && $("#queue li").length === 0) links.unshift(links.pop());
var emitQueue = [];
var addTemp = $(".add-temp").prop("checked");
+ var disableHardsubs = $('#subtitle-toggle-val').prop('checked');
var notification = document.getElementById("addfromurl-queue");
if (!notification) {
notification = document.createElement("div");
@@ -420,6 +421,10 @@ function queue(pos, src) {
"alert-danger", true)
.insertAfter($("#addfromurl"));
} else {
+ // if you are reading this, please help me
+ if(disableHardsubs) {
+ data.id += '!no';
+ }
emitQueue.push({
id: data.id,
type: data.type,
@@ -438,6 +443,7 @@ function queue(pos, src) {
if (!data) {
$("#mediaurl").val("");
$("#addfromurl-title").remove();
+ $("#fucking-subtitle-toggle").remove();
return;
}
@@ -469,13 +475,38 @@ $("#mediaurl").keyup(function(ev) {
queue("end", "url");
} else {
var editTitle = false;
+ var cronchSubtitleToggle = false;
try {
- if (parseMediaLink($("#mediaurl").val()).type === "fi") {
+ if($("#mediaurl").val().startsWith('https://www.crunchyroll.com/')) {
+ //console.log('hewwo owo');
+ cronchSubtitleToggle = true;
+ } else if (parseMediaLink($("#mediaurl").val()).type === "fi") {
editTitle = true;
}
} catch (error) {
}
+ if (cronchSubtitleToggle) {
+ var subtitleToggle = $("#fucking-subtitle-toggle");
+ if (subtitleToggle.length === 0) {
+ subtitleToggle = $("<div class=\"checkbox\" id=\"fucking-subtitle-toggle\"><label><input id=\"subtitle-toggle-val\" type=\"checkbox\">use opposite default hardsub option</label></div>")
+ .appendTo($("#addfromurl"));
+ /*$("<span/>").text("Title (optional; for raw files only)")
+ .appendTo(title);
+ $("<input/>").addClass("form-control")
+ .attr("type", "text")
+ .attr("id", "addfromurl-title-val")
+ .keydown(function (ev) {
+ if (ev.keyCode === 13) {
+ queue("end", "url");
+ }
+ })
+ .appendTo($("#addfromurl-title"));*/
+ }
+ } else {
+ $("#fucking-subtitle-toggle").remove();
+ }
+
if (editTitle) {
var title = $("#addfromurl-title");
if (title.length === 0) {
diff --git a/www/js/util.js b/www/js/util.js
index 6765be5..970ba20 100644
--- a/www/js/util.js
+++ b/www/js/util.js
@@ -3295,6 +3295,15 @@ function stopQueueSpinner(data) {
data = { id: data.meta.mixer.channelToken };
}
+ // me too, BR)O0o0 also you r app sucks but actually no i would not blame it because it has been through a lot ok ok ok oko okk o
+ //console.log(data);
+ //console.log('i knowy');
+ if(data && data.id.startsWith('https://dl.v.vrv.co/')) {
+ //console.log('REMOVING!!!!');
+ $("#queueprogress").remove();
+ return;
+ }
+
var shouldRemove = (data !== null &&
typeof data === 'object' &&
$("#queueprogress").data("queue-id") === data.id);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment