Don’t have much time to code it and maintain but thought i would give pointers. the code above should allow for a quick hack of existing music scanners easilly
Here is an untested attempt at a scanner. i will not maintain it nor test
import os, sys, Media
import logging # Python - logging.basicConfig
from mutagen import File as MFile
Virtual = True
### setup logging https://docs.python.org/2/library/logging.html ### #logging.debug/info/warning/error/critical('some critical message: %s', 'highest category')
try: platform = sys.platform.lower() # sys.platform: win32 | darwin | linux2,
except: platform="other"
# try: platform = Platform.OS.lower() # Platform.OS: Windows, MacOSX, or Linux
# except: p5latform = ""
if (platform == 'win32' or platform == 'windows'): LOG_PATH = os.path.expandvars( '%LOCALAPPDATA%\\Plex Media Server\Logs' )
elif (platform == 'darwin' or platform == 'macosx'): LOG_PATH = os.path.expandvars( '$HOME/Library/Application Support/Plex Media Server\Logs' )
elif 'linux' in platform: LOG_PATH = os.path.expandvars( '$PLEX_HOME/Library/Application Support/Plex Media Server\Logs' )
if not os.path.isdir(LOG_PATH): LOG_PATH = os.path.expanduser('~')
logging.basicConfig(filename=os.path.join(LOG_PATH, LOG_FILE), format=LOG_FORMAT, level=logging.DEBUG)
### Log function ########################################################################################
def Log(entry, filename='Plex Media Scanner Custom.log'): #need relative path
logging.info(entry + "\r\n") # allow to use windows notepad with correct line feeds
print entry # when ran from console
### Add files into Plex database ########################################################################
def explore_path(subdir, file_tree):
files=[]
for item in os.listdir(subdir):
fullpath = os.path.join(subdir, item)
if os.path.isdir (fullpath):
for rx in ignore_dirs_re_findall: ### Skip unwanted folders ###
result = re.findall(rx, item)
if len(result): break
else: explore_path(fullpath, file_tree)
elif os.path.isfile(fullpath):
fileName, fileExtension = os.path.splitext(item)
if fileExtension[1:] in video_exts:
for rx in ignore_files_re_findall: ### Filter trailers and sample files ###
result = re.findall(rx, item)
if len(result):
Log("'%s' ignore_files_findall: match" % item)
break
else: files.append(fullpath) ### Retain wanted file extensions ###
if not files == []: file_tree[subdir] = files
def Scan(path, files, mediaList, subdirs, language=None, root=None):
#if not path == "": return # Exit every other iteration than the root scan
if not root: return
TYPES = {'mp3': 'MP3', 'aac': 'AAC', 'alac': 'ALAC', 'ogg': 'OGG', 'opus': 'Opus', 'flac': 'FLAC',
'ape': 'APE', 'wv': 'WavPack', 'mpc': 'Musepack', 'asf': 'Windows Media', 'aiff': 'AIFF', }
Log("=== Scan ================================================================================================================")
Log("Platform: '%s', Test location: '%s'" % (platform, LOG_PATH))
Log("Scan: (root: '%s', path='%s', subdirs: '%s', Files: '%s', language: '%s')" % (root if root is not None else "", path, str(subdirs), str(files), language))
Log("=========================================================================================================================")
file_tree = {} # initialize file_tree
explore_path(root, file_tree) # initialize file_tree with files on root
for path, files in file_tree.iteritems(): # Loop to add all series while on the root folder Scan call, which allows subfolders to work
subdirs=[] # Recreate normal scanner coding: subfolders empty
path = path.replace(root, "") # Recreate normal scanner coding: path is relative to root
if path.startswith("/"): path = path[1:] # Recreate normal scanner coding: path doesn't start with "/"
relative_path = path.replace(root, " ") # Foe exemple /group/serie/season/ep folder
reverse_path = Utils.SplitPath(relative_path) # Take top two as show/season, but require at least the top one.
reverse_path.reverse() # Reverse the order of the folders
for filename in files:
file, fileExtension = os.path.splitext(filename) # read file extensions
if fileExtension[1:] not in TYPES: continue # clean out files that are not audio files. if it's not an audio file, we don't want it
elif type(MFile(filename, None, True)).__name__ is 'OggOpus': # Extract metadata
plex_track = Media.Track(
artist = str(MFile(filename, None, True)['ARTIST' ]).encode("utf-8"), # might need [3:-2] to clean up tags??
album = str(MFile(filename, None, True)['ALBUM' ]).encode("utf-8"),
title = str(MFile(filename, None, True)['TITLE' ]).encode("utf-8"),
album_artist = str(MFile(filename, None, True)['ALBUMARTIST']).encode("utf-8"),
index = str(MFile(filename, None, True)['TRACKNUMBER']).encode("utf-8"),
disc = str(MFile(filename, None, True)['DISCNUMBER' ]).encode("utf-8"),
)
plex_track.parts.append(filename)
mediaList.append(plex_track)
Best would be to take the original scanner init.py and AudioFiles.py and edit relevant parts
It already accepts opus files, just the supprot for the internal meta has to be added