mirror of
https://github.com/ThaUnknown/miru.git
synced 2026-04-20 08:52:06 +00:00
fix: improve season parsing, better feedback on rate limit, search looking for null, multiple torrent event listeners, unneeded elevated install prompt
This commit is contained in:
parent
712abc89bb
commit
2e91889559
5 changed files with 157 additions and 56 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Miru",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.3",
|
||||
"author": "ThaUnknown_ <ThaUnknown@users.noreply.github.com>",
|
||||
"main": "src/index.js",
|
||||
"homepage": "https://github.com/ThaUnknown/miru#readme",
|
||||
|
|
@ -79,7 +79,6 @@
|
|||
]
|
||||
},
|
||||
"nsis": {
|
||||
"perMachine": true,
|
||||
"allowToChangeInstallationDirectory": true,
|
||||
"oneClick": false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,33 +151,35 @@ ipcMain.on('current', (event, data) => {
|
|||
})
|
||||
|
||||
ipcMain.on('settings', (event, data) => {
|
||||
settings = data
|
||||
client = new WebTorrent({
|
||||
dht: !settings.torrentDHT,
|
||||
downloadLimit: settings.torrentSpeed * 1048576 || 0,
|
||||
uploadLimit: settings.torrentSpeed * 1572864 || 0 // :trolled:
|
||||
})
|
||||
setInterval(() => {
|
||||
window?.webContents?.send('stats', {
|
||||
numPeers: (client?.torrents.length && client?.torrents[0].numPeers) || 0,
|
||||
uploadSpeed: (client?.torrents.length && client?.torrents[0].uploadSpeed) || 0,
|
||||
downloadSpeed: (client?.torrents.length && client?.torrents[0].downloadSpeed) || 0
|
||||
if (!client) {
|
||||
settings = data
|
||||
client = new WebTorrent({
|
||||
dht: !settings.torrentDHT,
|
||||
downloadLimit: settings.torrentSpeed * 1048576 || 0,
|
||||
uploadLimit: settings.torrentSpeed * 1572864 || 0 // :trolled:
|
||||
})
|
||||
}, 200)
|
||||
client.on('torrent', torrent => {
|
||||
const files = torrent.files.map(file => {
|
||||
return {
|
||||
infoHash: torrent.infoHash,
|
||||
name: file.name,
|
||||
type: file._getMimeType(),
|
||||
size: file.size,
|
||||
path: file.path,
|
||||
url: encodeURI('http://localhost:41785/webtorrent/' + torrent.infoHash + '/' + file.path)
|
||||
}
|
||||
setInterval(() => {
|
||||
window?.webContents?.send('stats', {
|
||||
numPeers: (client?.torrents.length && client?.torrents[0].numPeers) || 0,
|
||||
uploadSpeed: (client?.torrents.length && client?.torrents[0].uploadSpeed) || 0,
|
||||
downloadSpeed: (client?.torrents.length && client?.torrents[0].downloadSpeed) || 0
|
||||
})
|
||||
}, 200)
|
||||
client.on('torrent', torrent => {
|
||||
const files = torrent.files.map(file => {
|
||||
return {
|
||||
infoHash: torrent.infoHash,
|
||||
name: file.name,
|
||||
type: file._getMimeType(),
|
||||
size: file.size,
|
||||
path: file.path,
|
||||
url: encodeURI('http://localhost:41785/webtorrent/' + torrent.infoHash + '/' + file.path)
|
||||
}
|
||||
})
|
||||
window?.webContents.send('files', files)
|
||||
window?.webContents.send('torrent', Array.from(torrent.torrentFile))
|
||||
})
|
||||
window?.webContents.send('files', files)
|
||||
window?.webContents.send('torrent', Array.from(torrent.torrentFile))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('torrent', (event, data) => {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
searchTimeout = setTimeout(() => {
|
||||
current = null
|
||||
current = 'search'
|
||||
if (Object.values(search).filter(v => v).length) current = 'search'
|
||||
searchTimeout = null
|
||||
}, 500)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,98 @@
|
|||
import { alToken } from '@/lib/pages/Settings.svelte'
|
||||
import { addToast } from '@/lib/Toasts.svelte'
|
||||
|
||||
const codes = {
|
||||
100: 'Continue',
|
||||
101: 'Switching Protocols',
|
||||
102: 'Processing',
|
||||
200: 'OK',
|
||||
201: 'Created',
|
||||
202: 'Accepted',
|
||||
203: 'Non-Authoritative Information',
|
||||
204: 'No Content',
|
||||
205: 'Reset Content',
|
||||
206: 'Partial Content',
|
||||
207: 'Multi-Status',
|
||||
300: 'Multiple Choices',
|
||||
301: 'Moved Permanently',
|
||||
302: 'Moved Temporarily',
|
||||
303: 'See Other',
|
||||
304: 'Not Modified',
|
||||
305: 'Use Proxy',
|
||||
307: 'Temporary Redirect',
|
||||
400: 'Bad Request',
|
||||
401: 'Unauthorized',
|
||||
402: 'Payment Required',
|
||||
403: 'Forbidden',
|
||||
404: 'Not Found',
|
||||
405: 'Method Not Allowed',
|
||||
406: 'Not Acceptable',
|
||||
407: 'Proxy Authentication Required',
|
||||
408: 'Request Time-out',
|
||||
409: 'Conflict',
|
||||
410: 'Gone',
|
||||
411: 'Length Required',
|
||||
412: 'Precondition Failed',
|
||||
413: 'Request Entity Too Large',
|
||||
414: 'Request-URI Too Large',
|
||||
415: 'Unsupported Media Type',
|
||||
416: 'Requested Range Not Satisfiable',
|
||||
417: 'Expectation Failed',
|
||||
418: 'I\'m a teapot',
|
||||
422: 'Unprocessable Entity',
|
||||
423: 'Locked',
|
||||
424: 'Failed Dependency',
|
||||
425: 'Unordered Collection',
|
||||
426: 'Upgrade Required',
|
||||
428: 'Precondition Required',
|
||||
429: 'Too Many Requests',
|
||||
431: 'Request Header Fields Too Large',
|
||||
500: 'Internal Server Error',
|
||||
501: 'Not Implemented',
|
||||
502: 'Bad Gateway',
|
||||
503: 'Service Unavailable',
|
||||
504: 'Gateway Time-out',
|
||||
505: 'HTTP Version Not Supported',
|
||||
506: 'Variant Also Negotiates',
|
||||
507: 'Insufficient Storage',
|
||||
509: 'Bandwidth Limit Exceeded',
|
||||
510: 'Not Extended',
|
||||
511: 'Network Authentication Required'
|
||||
}
|
||||
|
||||
export const alID =
|
||||
!!alToken &&
|
||||
alRequest({ method: 'Viewer', token: alToken })
|
||||
|
||||
async function handleRequest (opts) {
|
||||
return await fetch('https://graphql.anilist.co', opts).then(async res => {
|
||||
const json = await res.json()
|
||||
if (!res.ok) {
|
||||
for (const error of json.errors) {
|
||||
addToast({
|
||||
text: `Failed making request to anilist!<br>Try again in a minute.<br>${error.status} - ${error.message}`,
|
||||
title: 'Search Failed',
|
||||
type: 'danger'
|
||||
})
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
return json
|
||||
function printError (error) {
|
||||
console.warn(error)
|
||||
addToast({
|
||||
text: `Failed making request to anilist!<br>Try again in a minute.<br>${error.status} - ${error.message || codes[error.status]}`,
|
||||
title: 'Search Failed',
|
||||
type: 'danger'
|
||||
})
|
||||
}
|
||||
|
||||
async function handleRequest (opts) {
|
||||
const res = await fetch('https://graphql.anilist.co', opts)
|
||||
let json = null
|
||||
try {
|
||||
json = await res.json()
|
||||
} catch (error) {
|
||||
if (!res.ok) {
|
||||
printError({ status: res.status, message: res.statusText })
|
||||
} else {
|
||||
printError(error)
|
||||
}
|
||||
}
|
||||
if (!res.ok && json) {
|
||||
for (const error of json.errors) {
|
||||
printError(error)
|
||||
}
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
export function alEntry (filemedia) {
|
||||
if (filemedia.media && alToken && (filemedia.media.nextAiringEpisode?.episode || filemedia.media.episodes) >= filemedia.episodeNumber) {
|
||||
if (!filemedia.media.mediaListEntry || filemedia.media.mediaListEntry?.progress <= filemedia.episodeNumber || filemedia.media.episodes === 1) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const imageRx = /\.(jpeg|jpg|gif|png|webp)/i
|
|||
|
||||
fetch('https://nyaa.si').catch(() => {
|
||||
addToast({
|
||||
text: 'Failed connecting to Nyaa!<br>Visit https://wiki.piracy.moe/en/tutorials/unblock<br>for a guide on how to bypass ISP blocks.',
|
||||
text: 'Failed connecting to Nyaa! Visit<br>wiki.piracy.moe/en/tutorials/unblock<br>for a guide on how to bypass ISP blocks.',
|
||||
title: 'Nyaa Blocked',
|
||||
type: 'danger'
|
||||
})
|
||||
|
|
@ -84,22 +84,51 @@ function traceAnime (image, type) { // WAIT lookup logic
|
|||
export const episodeRx = /Episode (\d+) - (.*)/
|
||||
|
||||
// resolve anime name based on file name and store it
|
||||
const postfix = {
|
||||
1: 'st',
|
||||
2: 'nd',
|
||||
3: 'rd'
|
||||
}
|
||||
|
||||
async function resolveTitle (title) {
|
||||
if (!(title in relations)) {
|
||||
// resolve name and shit
|
||||
const method = { name: title, method: 'SearchName', perPage: 1, status: ['RELEASING', 'FINISHED'], sort: 'SEARCH_MATCH' }
|
||||
let res = await alRequest(method)
|
||||
if (!res.data.Page.media[0]) {
|
||||
const index = method.name.search(/S\d/)
|
||||
method.name = ((index !== -1 && method.name.slice(0, index) + method.name.slice(index + 1, method.name.length)) || method.name).replace('(TV)', '').replace(/ (19[5-9]\d|20[0-6]\d)/, '').replace('-', '')
|
||||
res = await alRequest(method)
|
||||
}
|
||||
if (res.data.Page.media[0]) {
|
||||
relations[title] = res.data.Page.media[0].id
|
||||
async function resolveTitle (name) {
|
||||
if (!(name in relations)) {
|
||||
const method = { name, method: 'SearchName', perPage: 1, status: ['RELEASING', 'FINISHED'], sort: 'SEARCH_MATCH' }
|
||||
|
||||
// inefficient but readable
|
||||
|
||||
let media = null
|
||||
// change S2 into Season 2 or 2nd Season
|
||||
const match = method.name.match(/ S(\d)$/)
|
||||
const oldname = method.name
|
||||
if (match) {
|
||||
method.name = method.name.replace(/ S(\d)$/, ` ${match[1]}${postfix[match[1]] || 'th'} Season`)
|
||||
media = (await alRequest(method)).data.Page.media[0]
|
||||
if (!media) {
|
||||
method.name = oldname.replace(/ S(\d)$/, ` Season ${match[1]}`)
|
||||
media = (await alRequest(method)).data.Page.media[0]
|
||||
}
|
||||
} else {
|
||||
relations[title] = null
|
||||
media = (await alRequest(method)).data.Page.media[0]
|
||||
}
|
||||
|
||||
// remove (TV)
|
||||
if (!media) {
|
||||
const match = method.name.match(/\(TV\)/)
|
||||
if (match) {
|
||||
method.name = name.replace('(TV)', '').replace('-', '')
|
||||
media = (await alRequest(method)).data.Page.media[0]
|
||||
}
|
||||
}
|
||||
// remove 2020
|
||||
if (!media) {
|
||||
const match = method.name.match(/ (19[5-9]\d|20\d{2})/)
|
||||
if (match) {
|
||||
method.name = method.name.replace(/ (19[5-9]\d|20\d{2})/, '')
|
||||
media = (await alRequest(method)).data.Page.media[0]
|
||||
}
|
||||
}
|
||||
|
||||
relations[name] = media?.id || null
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue