Last active
September 11, 2020 21:12
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'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> · <a href="/contact" target="_blank">Contact</a> · <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