Jump to content

"Better" identify library


jeffersoncg

Recommended Posts

jeffersoncg

Hi, I'm new here.
I added several movies to my library, but the names weren't 100% accurate, for example: "expendables.mkv", which was recognized as "expendables 4"
I don't know if Emby would need the information there like "expendables 1.mkv", but there are several of these movies that were added that ended up like this, having only the name of the movie, without informing the "order" (like the movie "Scream .mkv" which emby recognized as "Scream 5").
In a "Manga" reader that i did, i make this code to "find" the most probably correct match. I'm not a developer,  i just tryed make the code until it give-me a good result.

Code running with 2473 movies in db, and it find the match easily (I used it a lot with all 1.378 manga that i have, and it update each correctly, without a problem), so...
Is there a way to implement something like this on emby?

I know that the code is way to not optimized, but, for now is what i can do. 😢 

image.png.5969e622d33c77026ef351e84972b7e8.png

Code:

function GetAllMangaMatches(Lista, Nome){
	let NovaLista = Clone(Lista);
	let Retorno = {Vazio: ''};
	let Mangas = [];
	let Counter = 0;
	while (!Empty(Retorno)) {
		if(Counter > Lista.length)
			break;
		Retorno = FiltrarManga(NovaLista, Nome);
		if(!Empty(Retorno)) {
			Mangas.push(Retorno);
			delete(NovaLista[NovaLista.indexOf(Retorno)]);
			NovaLista = CleanArray(NovaLista);
		}
		Counter++;
	}
	return Mangas;
}
function Clone(Objeto) {
	let Copia = null;
    if(!Array.isArray(Objeto))
	    Copia = Object.assign({}, Objeto)
    else
        Copia = Object.keys(Objeto).map((key) => Objeto[key]);
	return Copia;
}

function Empty(Object) {
	return $.isEmptyObject(Object);
}
function FiltrarManga(Lista, Nome){
	if (Lista.length == 0) return '';
	let Manga = [];
	let CountMax = 0;
	let Count = 0;
	let ListaNomes = arrayColumn(Lista, "Name");
	ListaNomes = ChangeCase(ListaNomes, toLowerCase);
	Nome = RemoverCaracteresEspeciais(Nome.toLowerCase());
	let NomeArray = Nome.split(' ');
	NomeArray = CleanArray(NomeArray);
	let isOrigemDoujinshi = NomeArray.includes('doujinshi');
	let SelectedValue = [];
	let isMatchDoujinshi = false;
	x = 0;
	let foundExact = false;
	ListaNomes.map(function(value){ 
		if(foundExact)
			return; 
		value = RemoverCaracteresEspeciais(value);
		if (value == Nome) {
			Manga = Lista[x];
			foundExact = true;
			return Manga;
		}
		Count = GetOcorrencias(value, Nome); 	
		if (Count > CountMax) {
			CountMax = Count;
			Manga = Lista[x];
			SelectedValue = value.split(' ');
			SelectedValue = CleanArray(SelectedValue);
			isMatchDoujinshi = SelectedValue.includes('doujinshi');
		}
		x++;
	})
	let NomeArraySize = NomeArray.length;
	if (((CountMax > NomeArraySize*0.9) && (NomeArraySize + 3 > SelectedValue.length) || (foundExact)) && (isMatchDoujinshi == isOrigemDoujinshi)) {
		if(Manga != undefined) {
			if(Manga.length == 0) {
				Manga = Lista[0];
			}
		} else {
			Manga = Lista[0];
		}
	} else {
		return [];
	}
	return Manga;
}
function arrayColumn(array, columnName) {
    return array.map(value => value[columnName])
}
 function ChangeCase(Elemento, CaseFunction, Parameters) {
	switch (typeof(Elemento)) {
		case 'string':
			return CaseFunction(Elemento, Parameters);
		break;
		case 'object':
			if(Array.isArray(Elemento)) {
				return Elemento.map(x => ChangeCase(x, CaseFunction, Parameters));
			} else {
                if(Elemento != null) {
                    let ElementTemp = {};
                    Object.keys(Elemento).map(function(key){
                        ElementTemp[key] = ChangeCase(Elemento[key], CaseFunction, Parameters);
                    })
                    return ElementTemp;
                } else 
                    return null;
			}
		break;
		default:
			return Elemento;
		break;
	}
}
function RemoverCaracteresEspeciais(texto, subst = ' ') {
	let pattern = /[^a-z1-9]/gi;
	return texto.replaceAll(pattern, subst);
}
function CleanArray(Array) {
	return Array.filter(x => !$.isEmptyObject(x));
}
function GetOcorrencias(Fonte, Busca) {
	let ArBusca = RemoverCaracteresEspeciais(Busca).toLowerCase().split(' ');
	ArBusca = CleanArray(ArBusca);
	Fonte = RemoverCaracteresEspeciais(Fonte).toLowerCase();
	let Contagem = 0;
	ArBusca.map(function(value){
		if(Fonte.indexOf(value) != -1)
			Contagem += 1;
	})	
	return Contagem;
}
function GetAllMangaMatches(Lista, Nome){
	let NovaLista = Clone(Lista);
	let Retorno = {Vazio: ''};
	let Mangas = [];
	let Counter = 0;
	while (!Empty(Retorno)) {
		if(Counter > Lista.length)
			break;
		Retorno = FiltrarManga(NovaLista, Nome);
		if(!Empty(Retorno)) {
			Mangas.push(Retorno);
			delete(NovaLista[NovaLista.indexOf(Retorno)]);
			NovaLista = CleanArray(NovaLista);
		}
		Counter++;
	}
	return Mangas;
}

function toLowerCase(Texto) {
	return Texto.toLowerCase();
}

function AddScriptByJavascript(src){
	script = document.createElement('script');
	script.src = src;
	document.body.appendChild(script);
}

AddScriptByJavascript("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js");

Ps: I Also add there a code "Importer" to add jquery, because the function from jquery "$.isEmptyObject(Object)" is needed.

If wanna me to translate the function/parameters to english, i can do too.

Edited by jeffersoncg
typo
Link to comment
Share on other sites

Hi, Emby doesn't recognized expendables as expendables 4, rather, your highest priority movie metadata provider on your movie library does that.

So which is it, MovieDb?

Link to comment
Share on other sites

jeffersoncg
2 minutes ago, Luke said:

Hi, Emby doesn't recognized expendables as expendables 4, rather, your highest priority movie metadata provider on your movie library does that.

So which is it, MovieDb?

Here did, i was confused by it too. (the names was in portueguese-br, "Expendables => Mercenarios", "Scream => Panico")
The metadata order is:

1º TheMovieDb
2º The Open Movie Database

Link to comment
Share on other sites

Happy2Play

Might need to see the server log to see the actual query sent to provider.

  • Like 1
Link to comment
Share on other sites

jeffersoncg
9 minutes ago, Happy2Play said:

Might need to see the server log to see the actual query sent to provider.

How do i get the server logs? Theres a log file? or inside the admin panel i can get?

Link to comment
Share on other sites

Happy2Play
2 minutes ago, jeffersoncg said:

How do i get the server logs? Theres a log file? or inside the admin panel i can get?

If you cannot get to the log location, you can download them via Settings-Logs.

Path can be found in Paths box on Dashboard on stable release and the three-dot menu button on beta release.

  • Like 1
Link to comment
Share on other sites

jeffersoncg
6 minutes ago, Happy2Play said:

If you cannot get to the log location, you can download them via Settings-Logs.

Path can be found in Paths box on Dashboard on stable release and the three-dot menu button on beta release.

it take a while, i had to remove and add again the file, to indentify.

The "log.txt" is just after add the file "Mercenarios.mp4", and the other is the "all day" log 

log.txt embyserver.txt

Link to comment
Share on other sites

Happy2Play
8 minutes ago, jeffersoncg said:

it take a while, i had to remove and add again the file, to indentify.

The "log.txt" is just after add the file "Mercenarios.mp4", and the other is the "all day" log 

log.txt 154.53 kB · 0 downloads embyserver.txt 13.32 MB · 0 downloads

From the embyserver log

2022-04-11 23:41:20.327 Info App: MovieDbProvider: Finding id for item: Mercenarios
2022-04-11 23:41:20.327 Info HttpClient: GET https://api.themoviedb.org/3/search/movie?api_key=f6bd687ffa63cd282b6ff2c6877f2669&query=Mercenarios&language=pt-br
2022-04-11 23:41:20.521 Debug App: Throttling Tmdb by 106 ms
2022-04-11 23:41:20.627 Info HttpClient: GET https://api.themoviedb.org/3/movie/678751?api_key=f6bd687ffa63cd282b6ff2c6877f2669&append_to_response=casts,releases,images,keywords,trailers&language=pt-BR&include_image_language=pt-BR,pt,null,en

If you open the query to TMDB you can see the item you actually want is actually the 6th item returned.  Part of it is not using proper name "Os Mercenários" and language query.

But using "Os Mercenários" returns "Os Mercenários 4" first.

https://api.themoviedb.org/3/search/movie?api_key=f6bd687ffa63cd282b6ff2c6877f2669&query=Os%20Mercen%C3%A1rios&language=pt-br

So in this example it would be impossible to know what you want returned with just "Mercenarios" in the flat structure you are using and potentially missing year.

But yes some of this is specific to language.  As "Expendables" get better result from provider.

https://api.themoviedb.org/3/search/movie?api_key=f6bd687ffa63cd282b6ff2c6877f2669&query=expendables&language=en

So there are many quirks with it comes to TMDB queries unfortunately.

  • Like 1
Link to comment
Share on other sites

jeffersoncg
5 minutes ago, Happy2Play said:

From the embyserver log

2022-04-11 23:41:20.327 Info App: MovieDbProvider: Finding id for item: Mercenarios
2022-04-11 23:41:20.327 Info HttpClient: GET https://api.themoviedb.org/3/search/movie?api_key=f6bd687ffa63cd282b6ff2c6877f2669&query=Mercenarios&language=pt-br
2022-04-11 23:41:20.521 Debug App: Throttling Tmdb by 106 ms
2022-04-11 23:41:20.627 Info HttpClient: GET https://api.themoviedb.org/3/movie/678751?api_key=f6bd687ffa63cd282b6ff2c6877f2669&append_to_response=casts,releases,images,keywords,trailers&language=pt-BR&include_image_language=pt-BR,pt,null,en

If you open the query to TMDB you can see the item you actually want is actually the 6th item returned.  Part of it is not using proper name "Os Mercenários" and language query.

But using "Os Mercenários" returns "Os Mercenários 4" first.

https://api.themoviedb.org/3/search/movie?api_key=f6bd687ffa63cd282b6ff2c6877f2669&query=Os%20Mercen%C3%A1rios&language=pt-br

So in this example it would be impossible to know what you want returned with just "Mercenarios" in the flat structure you are using and potentially missing year.

But yes some of this is specific to language.  As "Expendables" get better result from provider.

https://api.themoviedb.org/3/search/movie?api_key=f6bd687ffa63cd282b6ff2c6877f2669&query=expendables&language=en

So there are many quirks with it comes to TMDB queries unfortunately.

Oh, i finnally got it, so, it's better if i identify manually, and after all my data is correct, if i change the names of files(i made a simple script, to change the name based on "nfo" info), to something like "Meteor (2021)  [tmdbid=870404]" it will always identify correctly? I had to remake the server a few times before, and always had to indentify again, so now, i rename all files, including (nfo, -fanart, -cover, bif and all).

So, is it better if the files that i add is in english?

Link to comment
Share on other sites

Happy2Play
1 minute ago, jeffersoncg said:

to something like "Meteor (2021)  [tmdbid=870404]" it will always identify correctly?

Yes that method would be perfect as you are providing the exact id for the file in question.

2 minutes ago, jeffersoncg said:

So, is it better if the files that i add is in english?

With providerid provided naming will not matter as the providerid will be used.

  • Like 1
Link to comment
Share on other sites

jeffersoncg
12 minutes ago, Happy2Play said:

Yes that method would be perfect as you are providing the exact id for the file in question.

With providerid provided naming will not matter as the providerid will be used.

Perfect, Thanks @Happy2Play, theres a way, a program, i don'k know that check the file and identify wich movie is? Theres a lot of movies that was identified wrong (and i run the script to change the name by the nfo, so some(several) files are identified wrong. If theres a program to make this, gonna really save-me.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...