Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for opening the anilist page for a manga #3

Open
valconius opened this issue Sep 12, 2020 · 0 comments
Open

Add support for opening the anilist page for a manga #3

valconius opened this issue Sep 12, 2020 · 0 comments
Labels
enhancement New feature or request

Comments

@valconius
Copy link

valconius commented Sep 12, 2020

Anilist's GraphiQL database contains a separate sub-database for "MANGA". Actually using it in mpv is, however, finnicky. Apologies for the long explanation below, whose purpose is to explain what I mean by guessit and anilist are finnicky.

Below, I describe how to use mpv to open manga files and use that database. I don't know lua or python very well, but it works for a random sampling of comic archives, and where it doesn't work, anilist is either incomplete or its GraphiQL search engine incorrectly returns the wrong entry.

open-anilist-page.lua is altered significantly (mainly because I don't know how to use lua very well). As a consequence, all the logic is here in the lua file. The python file is modified to now take two arguments, where the second is the string matching anilist's database, which is either ANIME or MANGA. This seems simple enough, but wait a bit. Note that I have also moved the python file to the subdirectory called scripts/open-anilist-page.d/, because sometimes mpv complains that it "cannot load a python script file" (this occurs randomly with various mpv.conf files I have, who knows why).

global_path = "" -- gio/kio path to image file currently open in mpv
                 -- Example:
                 --   archive://Blood Soul (Complete).cbr|/Blood Soul V01 Ch01-06 (Complete)/Blood_Soul_v01_ch01_[Easy_Going]/1_Credits_Blood_Soul.jpg
global_name = "" -- No longer extracted from mpv's properties alone
global_type = ""

function callback(success, result, error)
   if result.status == 0 then
      mp.osd_message("Found "..global_type.." for: \n    "..global_name.."\nLaunched browser\n", 5)
   else
      mp.osd_message("Unable to find Anilist URL.", 5)
   end
end

function launch_anilist()
   mp.osd_message("Finding Anilist URL...", 30)

   -- GLOBAL_PATH := mp.get_property("path")
   -- If GLOBAL_PATH contains "cbr" or "cbz"
   --   GLOBAL_NAME := GLOBAL_PATH or GLOBAL_NAME := MORE_ACCURATE_NAME
   --   GLOBAL_TYPE := "MANGA"
   -- Else
   --   GLOBAL_NAME := mp.get_property("filename")
   --   GLOBAL_TYPE := "ANIME"

   global_path = mp.get_property("path")
   if string.match(global_path, "%.cb[rz7t]") or string.match(global_path, "%.zip") or string.match(global_path, "%.rar")
   then
      -- This is too inaccurate:
      --   global_name = global_path

      -- This is more accurate:
      _, _, firstpart, secondpart = string.find(global_path, "(%w*://)(.*)%..*|.*")
      if firstpart == nil then     -- path did not contain something like "archive://"
         global_name = global_path -- so pick a name for guessit that is probably close enough
      else
         global_name = secondpart
      end
      
      global_type = "MANGA"
   else
      global_name = mp.get_property("filename")
      global_type = "ANIME"
   end

   mp.msg.info("global_path: "..global_path)
   mp.msg.info("global_name: "..global_name)
   mp.msg.info("global_type: "..global_type)
   
   local script_dir = debug.getinfo(1).source:match("@?(.*/)")
   local table = {}
   table.name = "subprocess"
   table.args = {"python", script_dir.."open-anilist-page.d/open-anilist-page.py", global_name, global_type}
   local cmd = mp.command_native_async(table, callback)
end

-- change key binding as desired 
mp.add_key_binding('ctrl+a', 'launch_anilist', launch_anilist)

open-anilist-page.py is basically the same. I'm unfamiliar with python's lambdas and such, so I just clobbered this together by brute force. I show only the parts I changed. _makeAnilistQuery takes a second argument, which is either "ANIME" or "MANGA", and the main routine is likewise modified.

...

def _makeAnilistQuery(name, anilist_type):
	response = requests.post(
		'https://graphql.anilist.co',
		json=
		{
			'query': '''
			 	query($searchStr:String) {
			 		Media (search: $searchStr, type: ''' + anilist_type + ''') {
			 			siteUrl
			 		}
			 	}
			 ''',
			'variables': { 'searchStr': name }
		})
	if response.status_code == 200:
		return response.json()["data"]["Media"]["siteUrl"]
	else:
		raise Exception("Query failed!")

	return None

def get_anilist_url(filename, anilist_type:
	...

	return _makeAnilistQuery(name, anilist_type)

if __name__ == "__main__":
	...
		url = get_anilist_url(sys.argv[1], sys.argv[2])
	...

Next, consider this example anilist GraphiQL query (opens an interactive page on anilist.co/grapihql). Consider the following mangas opened and passed as data. In the lua file, if global_name = global_path were used, guessit might fail to match some of these mangas.

  • Some file called "Eight.cbz"
    • Without the silly pseudo-code logic I have in the lua file, guessit will for some strange reason redirect you to a manga title "| . /", which yes does really exist. Obviously, the fix was to capture only the archive's name.
  • Some file called "Senpai's Afterschool Touching Lecture.cbz"
    • Yes, this is an embarassing file name, but the point is guessit sees archive://blahblahblah.cbz but for some reason requests the manga page for "blahblahblah cbz" instead of "blahblahblah", which causes the script to fail. Obviously, the fix was to capture only the archive's name minus its file extension.
  • Some file called "Does not exist in anilist's database.cbz"
    • anilist returns an error, which is supposed to happen.
  • Some file called "Blood Soul.cbz".
    • guessit says is called "Blood Soul", which GraphiQL says is a yaoi manga, when it isn't. anilist should return an error because Blood Soul doesn't exist in its database, but it doesn't! This is where I am stuck.

In short, everything works, except for cases where anilist is completely retarded.

I did this just because I was bored, so I don't expect to revisit this, but in case anyone is trying to extend this mpv script, this was my effort that actually kinda works (when anilist works, that is). Please note at the bottom, where I say I am stuck, so if anyone wants to advance this issue, please fix the whole part where I am stuck and please make something like my code look better than this. You, the reader, can see that the fixes are pretty obvious, but they are painful to implement in python and lua (for me), but simple in something like Scheme. For example, that mess above where a giant json thing is just copy-pasted is because python's string.Format() uses curly brackets that cause errors, but in Scheme, it is (probably) pretty easy to specify a different Format String Syntax (link is what it is in python's manual. In other words, good luck! I give up.

@ehoneyse ehoneyse added the enhancement New feature or request label Sep 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants