Skip to content

Commit

Permalink
Add metaLanguage config #22
Browse files Browse the repository at this point in the history
  • Loading branch information
arvida42 committed Sep 4, 2024
1 parent c63ca71 commit 3a4919a
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 39 deletions.
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {readFileSync} from "fs";
import config from './lib/config.js';
import cache, {vacuum as vacuumCache, clean as cleanCache} from './lib/cache.js';
import path from 'path';
import * as meta from './lib/meta.js';
import * as icon from './lib/icon.js';
import * as debrid from './lib/debrid.js';
import {getIndexers} from './lib/jackett.js';
Expand Down Expand Up @@ -92,6 +93,7 @@ app.get('/:userConfig?/configure', async(req, res) => {
defaultUserConfig: config.defaultUserConfig,
qualities: config.qualities,
languages: config.languages.map(l => ({value: l.value, label: l.label})).filter(v => v.value != 'multi'),
metaLanguages: await meta.getLanguages(),
sorts: config.sorts,
indexers,
passkey: {enabled: false},
Expand Down
35 changes: 19 additions & 16 deletions src/lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ export default {
sortUncached: sortCommaListToArray(process.env.DEFAULT_SORT_UNCACHED || 'seeders:true'),
indexers: commaListToArray(process.env.DEFAULT_INDEXERS || 'all'),
indexerTimeoutSec: parseInt(process.env.DEFAULT_INDEXER_TIMEOUT_SEC || '60'),
passkey: ''
passkey: '',
// If not defined, the original title is used for search. If defined, the title in the given language is used for search
// format: ISO 639-1, example: en
metaLanguage: process.env.DEFAULT_META_LANGUAGE || ''
},

qualities: [
Expand All @@ -71,21 +74,21 @@ export default {
{value: [['size', true]], label: 'By size'}
],
languages: [
{value: 'multi', emoji: '🌎', pattern: 'multi'},
{value: 'arabic', emoji: '🇦🇪', pattern: 'arabic'},
{value: 'chinese', emoji: '🇨🇳', pattern: 'chinese'},
{value: 'german', emoji: '🇩🇪', pattern: 'german'},
{value: 'english', emoji: '🇺🇸', pattern: '(eng(lish)?)'},
{value: 'spanish', emoji: '🇪🇸', pattern: 'spa(nish)?'},
{value: 'french', emoji: '🇫🇷', pattern: 'fre(nch)?'},
{value: 'dutch', emoji: '🇳🇱', pattern: 'dutch'},
{value: 'italian', emoji: '🇮🇹', pattern: 'ita(lian)?'},
{value: 'korean', emoji: '🇰🇷', pattern: 'korean'},
{value: 'portuguese', emoji: '🇵🇹', pattern: 'portuguese'},
{value: 'russian', emoji: '🇷🇺', pattern: 'rus(sian)?'},
{value: 'swedish', emoji: '🇸🇪', pattern: 'swedish'},
{value: 'tamil', emoji: '🇮🇳', pattern: 'tamil'},
{value: 'turkish', emoji: '🇹🇷', pattern: 'turkish'}
{value: 'multi', emoji: '🌎', iso639: '', pattern: 'multi'},
{value: 'arabic', emoji: '🇦🇪', iso639: 'ar', pattern: 'arabic'},
{value: 'chinese', emoji: '🇨🇳', iso639: 'zh', pattern: 'chinese'},
{value: 'german', emoji: '🇩🇪', iso639: 'de', pattern: 'german'},
{value: 'english', emoji: '🇺🇸', iso639: 'en', pattern: '(eng(lish)?)'},
{value: 'spanish', emoji: '🇪🇸', iso639: 'es', pattern: 'spa(nish)?'},
{value: 'french', emoji: '🇫🇷', iso639: 'fr', pattern: 'fre(nch)?'},
{value: 'dutch', emoji: '🇳🇱', iso639: 'nl', pattern: 'dutch'},
{value: 'italian', emoji: '🇮🇹', iso639: 'it', pattern: 'ita(lian)?'},
{value: 'korean', emoji: '🇰🇷', iso639: 'ko', pattern: 'korean'},
{value: 'portuguese', emoji: '🇵🇹', iso639: 'pt', pattern: 'portuguese'},
{value: 'russian', emoji: '🇷🇺', iso639: 'ru', pattern: 'rus(sian)?'},
{value: 'swedish', emoji: '🇸🇪', iso639: 'sv', pattern: 'swedish'},
{value: 'tamil', emoji: '🇮🇳', iso639: 'ta', pattern: 'tamil'},
{value: 'turkish', emoji: '🇹🇷', iso639: 'tr', pattern: 'turkish'}
].map(lang => {
lang.label = `${lang.emoji} ${lang.value.charAt(0).toUpperCase() + lang.value.slice(1)}`;
lang.pattern = new RegExp(` ${lang.pattern} `, 'i');
Expand Down
12 changes: 6 additions & 6 deletions src/lib/jackettio.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ function parseStremioId(stremioId){
return {id, season: parseInt(season || 0), episode: parseInt(episode || 0)};
}

async function getMetaInfos(type, stremioId){
async function getMetaInfos(type, stremioId, language){
const {id, season, episode} = parseStremioId(stremioId);
if(type == 'movie'){
return meta.getMovieById(id);
return meta.getMovieById(id, language);
}else if(type == 'series'){
return meta.getEpisodeById(id, season, episode);
return meta.getEpisodeById(id, season, episode, language);
}else{
throw new Error(`Unsuported type ${type}`);
}
Expand Down Expand Up @@ -247,7 +247,7 @@ async function prepareNextEpisode(userConfig, metaInfos, debridInstance){

if(nextEpisode){

metaInfos = await meta.getEpisodeById(metaInfos.id, nextEpisode.season, nextEpisode.episode);
metaInfos = await meta.getEpisodeById(metaInfos.id, nextEpisode.season, nextEpisode.episode, userConfig.metaLanguage);
const torrents = await getTorrents(userConfig, metaInfos, debridInstance);

// Cache next episode on debrid when not cached
Expand Down Expand Up @@ -312,7 +312,7 @@ export async function getStreams(userConfig, type, stremioId, publicUrl){
const {id, season, episode} = parseStremioId(stremioId);
const debridInstance = debrid.instance(userConfig);

let metaInfos = await getMetaInfos(type, stremioId);
let metaInfos = await getMetaInfos(type, stremioId, userConfig.metaLanguage);

const torrents = await getTorrents(userConfig, metaInfos, debridInstance);

Expand Down Expand Up @@ -360,7 +360,7 @@ export async function getDownload(userConfig, type, stremioId, torrentId){

// Prepare next expisode debrid cache
if(type == 'series' && userConfig.forceCacheNextEpisode){
getMetaInfos(type, stremioId).then(metaInfos => prepareNextEpisode(userConfig, metaInfos, debridInstance));
getMetaInfos(type, stremioId, userConfig.metaLanguage).then(metaInfos => prepareNextEpisode(userConfig, metaInfos, debridInstance));
}

download = await cache.get(cacheKey);
Expand Down
12 changes: 8 additions & 4 deletions src/lib/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import Tmdb from './meta/tmdb.js';

const client = config.tmdbAccessToken ? new Tmdb() : new Cinemeta();

export async function getMovieById(id){
return client.getMovieById(id);
export async function getMovieById(id, language){
return client.getMovieById(id, language);
}

export async function getEpisodeById(id, season, episode){
return client.getEpisodeById(id, season, episode);
export async function getEpisodeById(id, season, episode, language){
return client.getEpisodeById(id, season, episode, language);
}

export async function getLanguages(){
return client.getLanguages();
}
4 changes: 4 additions & 0 deletions src/lib/meta/cinemeta.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export default class Cinemeta {

}

async getLanguages(){
return [];
}

async #request(method, path, opts, cacheOpts){

cacheOpts = Object.assign({key: '', ttl: 0}, cacheOpts || {});
Expand Down
18 changes: 11 additions & 7 deletions src/lib/meta/tmdb.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ export default class Tmdb {
static id = 'tmdb';
static name = 'The Movie Database';

async getMovieById(id){
async getMovieById(id, language){

const searchId = await this.#request('GET', `/3/find/${id}`, {query: {external_source: 'imdb_id'}}, {key: `searchId:${id}`, ttl: 3600*3});
const searchId = await this.#request('GET', `/3/find/${id}`, {query: {external_source: 'imdb_id', language: language || 'en-US'}}, {key: `searchId:${id}:${language || '-'}`, ttl: 3600*3});
const meta = searchId.movie_results[0];

return {
name: meta.original_title || meta.title,
name: language ? meta.title || meta.original_title : meta.original_title || meta.title,
year: parseInt(`${meta.release_date}`.split('-').shift()),
imdb_id: id,
type: 'movie',
Expand All @@ -22,10 +22,10 @@ export default class Tmdb {

}

async getEpisodeById(id, season, episode){
async getEpisodeById(id, season, episode, language){

const searchId = await this.#request('GET', `/3/find/${id}`, {query: {external_source: 'imdb_id'}}, {key: `searchId:${id}`, ttl: 3600*3});
const meta = await this.#request('GET', `/3/tv/${searchId.tv_results[0].id}`, {query: {language: 'en-US'}}, {key: id, ttl: 3600*3});
const searchId = await this.#request('GET', `/3/find/${id}`, {query: {external_source: 'imdb_id'}}, {key: `searchId:${id}:${language || '-'}`, ttl: 3600*3});
const meta = await this.#request('GET', `/3/tv/${searchId.tv_results[0].id}`, {query: {language: language || 'en-US'}}, {key: id, ttl: 3600*3});

const episodes = [];
meta.seasons.forEach(s => {
Expand All @@ -39,7 +39,7 @@ export default class Tmdb {
});

return {
name: meta.original_name || meta.name,
name: language ? meta.name || meta.original_name : meta.original_name || meta.name,
year: parseInt(`${meta.first_air_date}`.split('-').shift()),
imdb_id: id,
type: 'series',
Expand All @@ -52,6 +52,10 @@ export default class Tmdb {

}

async getLanguages(){
return [{value: '', label: '🌎Original (Recommended)'}].concat(...config.languages.map(language => ({value: language.iso639, label: language.label})).filter(language => language.value));
}

async #request(method, path, opts, cacheOpts){

if(!config.tmdbAccessToken){
Expand Down
21 changes: 15 additions & 6 deletions src/template/configure.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ <h5>Indexers</h5>
</div>
<div class="mb-3" v-if="indexers.length >= 1 && !immulatableUserConfigKeys.includes('indexers')">
<label>Indexers enabled:</label>
<div class="d-flex">
<div class="d-flex flex-wrap">
<div v-for="indexer in indexers" class="me-3" :title="indexer.types.join(', ')">
<input class="form-check-input me-1" type="checkbox" v-model="indexer.checked" :id="indexer.label">
<label class="form-check-label" :for="indexer.label">{{indexer.label}}</label>
Expand All @@ -48,7 +48,7 @@ <h5>Filters & Sorts</h5>
<div class="ps-2 border-start border-secondary-subtle">
<div class="mb-3" v-if="!immulatableUserConfigKeys.includes('qualities')">
<label>Qualities:</label>
<div class="d-flex">
<div class="d-flex flex-wrap">
<div v-for="quality in qualities" class="me-3">
<input class="form-check-input me-1" type="checkbox" v-model="quality.checked" :id="quality.label">
<label class="form-check-label" :for="quality.label">{{quality.label}}</label>
Expand Down Expand Up @@ -83,11 +83,18 @@ <h5>Filters & Sorts</h5>
<small class="text-muted">This could increase the chance of cached torrents. 2 is a good number</small>
</div>
<div class="mb-3" v-if="!immulatableUserConfigKeys.includes('priotizeLanguages')">
<label>Priotize languages</label>
<label>Priotize audio languages</label>
<select v-model="form.priotizeLanguages" class="form-select" multiple>
<option v-for="language in languages" :value="language.value">{{language.label}}</option>
</select>
</div>
<div class="mb-3" v-if="!immulatableUserConfigKeys.includes('metaLanguage') && metaLanguages.length > 0">
<label>Search languages</label>
<select v-model="form.metaLanguage" class="form-select">
<option v-for="metaLanguage in metaLanguages" :value="metaLanguage.value">{{metaLanguage.label}}</option>
</select>
<small class="text-muted">By default, the search uses the original title and works in most cases, but you can force the search to use a specific language.</small>
</div>
</div>
<h5>Debrid</h5>
<div class="ps-2 border-start border-secondary-subtle">
Expand Down Expand Up @@ -127,7 +134,7 @@ <h5>Debrid</h5>
createApp({
setup() {

const {addon, debrids, defaultUserConfig, qualities, languages, sorts, indexers, passkey, immulatableUserConfigKeys} = config;
const {addon, debrids, defaultUserConfig, qualities, languages, sorts, indexers, passkey, immulatableUserConfigKeys, metaLanguages} = config;

const debrid = ref({});
const error = ref('');
Expand All @@ -153,7 +160,8 @@ <h5>Debrid</h5>
sortUncached: defaultUserConfig.sortUncached,
forceCacheNextEpisode: defaultUserConfig.forceCacheNextEpisode,
priotizeLanguages: defaultUserConfig.priotizeLanguages,
indexerTimeoutSec: defaultUserConfig.indexerTimeoutSec
indexerTimeoutSec: defaultUserConfig.indexerTimeoutSec,
metaLanguage: defaultUserConfig.metaLanguage
};
qualities.forEach(quality => quality.checked = defaultUserConfig.qualities.includes(quality.value));
indexers.forEach(indexer => indexer.checked = defaultUserConfig.indexers.includes(indexer.value) || defaultUserConfig.indexers.includes('all'));
Expand Down Expand Up @@ -209,7 +217,8 @@ <h5>Debrid</h5>
passkey,
immulatableUserConfigKeys,
languages,
isUpdate
isUpdate,
metaLanguages
}
}
}).mount('#app')
Expand Down

0 comments on commit 3a4919a

Please sign in to comment.