Is there a way to use folders names and path and use them for metadatas ?

Hi,
To be frank I’ve a somewhat big library, with no homogenous names. This is like custom videos and there is no way to fetch datas from the internet about theses videos.
Whatever, my library is quite good organised physicaly since I use folders, but once I put it in Plex is a big mess since there is no structure (the folder view is not really a solution, only a last resort workaround).

If’ve found that using collections like tags could be nice for me, even it’s a hided feature. I can batch assign them when going into folder view, select all file in the folder and then assign them the desired tags. It will take some time but it’s ok. The problem is that is not dynamic, bad assignements can be done, or miss some files, well far from perfect and hard to manage if you have a lot of videos.

Here is an example how I’m structured (please don’t judge… it’s porn… but whatever the problem will be the same with custom videos)
X\Straight\Asian
X\Straight\Teen
X\■■■■\Milf
X\Fetish\Latex\Asian
X\Jobs\Handjob\Black
etc…

It seem evident to me, but is there a custom scanner or something so, that just scan files, take folders names and put them in tags/collections ? For “X\Fetish\Latex\Asian” it will be “Fetish” + “Latex” + “Asian”. I don’t care about file names since most of them are no revelant and doens’t have any usefull informations in it.
Like I see it will be wonderfull, since if I can do it work in that way then I can mix tags in any way. Plus it doesn’t seem a very complicated solution and I’m suprised there is nothing related to that. It could be also a nice solution for your holidays videos :wink:

Thanks for your response :wink:

@DavidL Hi. i am a scanner and agent writer (scanner ASS link in my signature, ah coincidences, and HAMA agent)…
The scanner can get the title for movie or series or series episode titles and the year at most
The collection attribute exist for the agent, not scanner.

Empty agent template: https://github.com/ZeroQI/Hama.bundle/releases/download/v1.0/Empty_Agent_template.bundle.7z
get folder path to file in dir variable:

  • The agent need to assign from the title a unique id (could be the movie filename) in Search()
  • from that unique id in Update() section, you can set collections

that gives you the folder path but the path depth is variable, so we nee to have the name of the folder at which stopping. root maybe but no access from the agent? will consider you are under windows and folders start at the drive letter
Here is the gist of it:

dir = os.path.dirname(media.items[0].parts[0].file) #movie library:
### series library
#for s in media.seasons:
#  for e in media.seasons[s].episodes:
#    dir = os.path.dirname( media.seasons[s].episodes[e].items[0].parts[0].file); break
#  break
metadata.collections.clear() #clear all collection tags
reverse_folder_list = list(reversed(Utils.SplitPath(path))) #create 
for folder in reverse_folder_list:
  if len (folder) <= 3: break
  metadata.collections.add(folder)

Hi and thanks for your well detailed response :slight_smile:
I’m somewhat initiated with coding in various language, not python btw… but was just to make it clear I still a noob and I probably some dumb mistakes :wink:

I’m modded your template, then got some errors at launch and debugged them. Now it load fine, I can create a gallery and assign the agent. But when scanning the gallery nothing is showing up. It say scan finished but no files seems to be detected, or at least no notifications for that and the gallery still empty.

Here is the scanner log :
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - Performing a scan with ‘Plex Series Scanner’ (language: en virtual: 0).
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - * Scanning /volume1/video/Test
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - * Scanning directory /volume1/video/Test (parent: no)
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - Adding file for scanner: /volume1/video/Test/Test.zip
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - Adding file for scanner: /volume1/video/Test/test3.mp4
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - Adding subdirectory for scanner: /volume1/video/Test/folder1
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - Directory had 1 files, database had 0 files, can’t skip.
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - * Scanning directory /volume1/video/Test/folder1 (parent: yes)
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - Adding file for scanner: /volume1/video/Test/folder1/test1.mp4
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - Adding subdirectory for scanner: /volume1/video/Test/folder1/folder2
Jan 19, 2017 00:24:18 [0x43e1c040] DEBUG - Directory had 1 files, database had 0 files, can’t skip.
Jan 19, 2017 00:24:19 [0x43e1c040] DEBUG - * Scanning directory /volume1/video/Test/folder1/folder2 (parent: yes)
Jan 19, 2017 00:24:19 [0x43e1c040] DEBUG - Adding file for scanner: /volume1/video/Test/folder1/folder2/test2.mp4
Jan 19, 2017 00:24:19 [0x43e1c040] DEBUG - Directory had 1 files, database had 0 files, can’t skip.
Jan 19, 2017 00:24:19 [0x43e1c040] DEBUG - Removing 0 media items that were left.
Jan 19, 2017 00:24:19 [0x43e1c040] DEBUG - Removing 0 directories that were left.
Jan 19, 2017 00:24:19 [0x43e1c040] DEBUG - Downloading document http://127.0.0.1:32400/library/changestamp
Jan 19, 2017 00:24:19 [0x43e1c040] DEBUG - HTTP requesting GET http://127.0.0.1:32400/library/changestamp
Jan 19, 2017 00:24:19 [0x43e1c040] DEBUG - Refreshing section 13 of type: 2

And there is the full plugin code : http://pastebin.com/Ags30WCs

There is two parts in update() for testing purposes. Also I’ve putted some Log() but I don’t see any outputs in the log files ? Where is the output ? I used this tip a lot for debugging and here I’m a little lost since I don’t see what happen and how it is processing.

You talked about the path lengths, I’m using Plex on a Synology, so under Linux. The physical gallery path is “/volume1/video/X/”.
I didn’t get what you mean about that, do I need to put an offset to bypass the “/volume1/video/X” part ? Why do I need to tell where it must stop ? It must just scan the entire folder, no ?

Any idea of what I’m missing to have the files showing in the gallery ? Even without collections for now ?

The scanner decide which files show in plex.
The agent just choose the metadata for what is showing.
That is a tv show agent you need for a movie library


Download PlexPlug-inFramework.pdf 765.6K page 33

you might want to use in code “Agent.Movies”.
“Folders2Collections.bundle” is the foldername

Logs are located in \NAS\Plex\Library\Application Support\Plex Media Server\Logs\PMS Plugin Logs

  • com.plexapp.system.log
  • com.plexapp.FoldersToCollections.log

Here is a corrected agent showing up in the list movie library agent
Didn’t had time to test further. beware of indentation, i use 2 spaces for level and the agent will crash with one space more/less

Do you have posters/nfo files together with some videos or not at all ?

Ok, meanwhile I finally got them into the library, it’s showing up and generating thumbnails. I also changed to Movies.
I figured out that I need to use the results function and put the ID in it. I’ll compare to your corrected agent later.

Now I’m getting and error about Utils.SplitPath(path), it isn’t recognized.
I tryed to import Utils, utils and shutils but it say “ImportError: No module named utils”. Is it a custom function ?

Nvm, I found that is a call to another bundle : https://github.com/plexinc-plugins/Scanners.bundle/blob/master/Contents/Resources/Common/Utils.py
Will include it, doing some tests and let you know how it’s going.

“import Utils” works in the scanner, not agent apparently… My bad…
It is unusual for the agent to actually manipulate paths, as it is meant for metadata. you could also use tags .
You get the agent errors in the logs so it makes it easier to troubleshoot now. Nearly there !

I find it empty with no metadata to gather… Do you have posters/nfo files together with the videos or not at all ?

import os, re  #import time def Log(dbgline): Log("

" + time.strftime("%H:%M:%S - ") + dbgline + "


")

def Start():
  HTTP.CacheTime             = CACHE_1DAY
  HTTP.Headers['User-Agent'] = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)'

class Folders2CollectionsMovieAgent(Agent.Movies):
  name, primary_provider, fallback_agent, contributes_to, languages, accepts_from = ('Folders2CollectionsMovie', True, False, None, [Locale.Language.English,], [] )  #, 'com.plexapp.agents.opensubtitles'
  
  def search(self, results, media, lang, manual=False):
    Log("".ljust(157, '-'))
    Log("search() - Title: '%s'  -> '%s'" % (media.title, media.episode))
    Log(os.path.splitext(os.path.basename(path))[0])
    results.Append( MetadataSearchResult(id=str(media.title), name=media.title, year=None, lang=lang, score=100))#results.Sort('score', descending=True)

  def update(self, metadata, media, lang):
    Log("".ljust(157, '='))
    Log("update() - metadata.id: '%s', metadata.title: '%s'" % (metadata.id, metadata.title))
    filename  = media.items[0].parts[0].file.decode('utf-8')
    dirname   = os.path.dirname(filename)
    cleanname = os.path.splitext(os.path.basename(filename))[0]
    Log("filename: '%s', cleanname: '%s', dirname: '%s'" %(cleanname, filename, dirname))
    metadata.title                   = "title updated"
    metadata.summary                 = 'Summary updated'
    metadata.studio                  = 'Studio updated'
    metadata.originally_available_at = Datetime.ParseDate('1981-12-03').date()
    
    metadata.collections.clear() #clear all collection tags
    while dirname and not dirname.endswith(os.sep):
      folder = os.path.dirname(dir)
      Log(folder)
      if len(folder) <= 3: break
      metadata.collections.add(folder) 
    Log('update() ended')

that should fix the error

No there is no posters or nfo, only various videos, most are webrip or amateur and so are not on any databases. That’s why I want to build movies informations from the folders names, so it will be structured and it can be filtered.

That said I’m at a point where I don’t have any errors into the logs, the plugins is parsed fine. But nothing appear into collections, names, date, or anything else. Only the title of the video file.

Also my Log() still doesn’t work, they are not into logs files, It seem search() and update() are not triggered, but the plugins is as I see some basic informations into logs. That could explain why I don’t see my Log() and why no informations is present on the video.
But I don’t get what’s the problem. I readed the code so much time that my eyes are burning xD

import re, os, urllib

def Start():
  HTTP.CacheTime             = CACHE_1DAY
  HTTP.Headers['User-Agent'] = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)'

class Folders2CollectionsAgent(Agent.Movies):
  name, primary_provider, fallback_agent, contributes_to, languages, accepts_from = ('Folders2Collections', True, False, None, [Locale.Language.English,], [] )  #, 'com.plexapp.agents.opensubtitles'

  def search(self, results, media, lang, manual=False):
    Log('SEARRRCCCCCCCCCCCCCCCCCCCCCCHHHHHHHHHHHHHHHHHH')
    path = media.filename
    Log(media.filename)
    Log(path)
    path = urllib.unquote(path)
    Log(path)
    filename = os.path.splitext(os.path.basename(path))[0]
    Log(filename)
    Log("".ljust(157, '-'))
    Log("search() - Title: '%s'  -> '%s'" % (media.title, media.episode))
    Log(os.path.splitext(os.path.basename(path))[0])
    results.Append( MetadataSearchResult(id=str(media.title), name=media.title, year=None, lang=lang, score=100))#results.Sort('score', descending=True)

  def update(self, metadata, media, lang):
    Log('UPPPDDDAAAAAAAAAAAAATTTTTTTTTTTTTTTTTTTEEEEEEEEEEEEEEEEEEEEEE')
    filename  = media.items[0].parts[0].file.decode('utf-8')
    dirname   = os.path.dirname(filename)
    cleanname = os.path.splitext(os.path.basename(filename))[0]
    Log("filename: '%s', cleanname: '%s', dirname: '%s'" %(cleanname, filename, dirname))
    metadata.title                   = "title updated"
    Log(metadata.title)
    metadata.summary                 = 'Summary updated'
    metadata.studio                  = 'Studio updated'
    metadata.originally_available_at = Datetime.ParseDate('1981-12-03').date()
 
    metadata.collections.clear() #clear all collection tags
    while dirname and not dirname.endswith(os.sep):
      folder = os.path.dirname(dir)
      Log(folder)
      if len(folder) <= 3: break
      metadata.collections.add(folder) 
    Log('update() ended')

I’m interested in this same feature, but I see that as my files are idented in separate foledrs with name of the movie (Kodi style), I have to skip the first foleder.
Any update since 2017?

Here is the edited code above made into a running agent. Need somebody to continue coding…

One technique you can use is to make the videos into a TV Show:
TV/Videos (2018)
TV/Videos/S01 White/
TV/Videos/S02 Black/
where “what” and “black” are your metatags.
Then within each folder, use SxxEyy description:
TV/Videos/S01 White/S01E01 Giraffe.mp4
TV/Videos/S01 White/S01E02 Elephant.mp4
TV/Videos/S02 Black/S02E01 Rhino.mp4

In this case, Plex ignores the season folders and uses the SxxEyy info instead.
This technique makes it easier to organize your files on the computer but the folder names do not affect how Plex displays the season information in Media Player.

As a feature request, I agree that the ability to add tags to TV Seasons, Movie folders, and filenames would be great.