easyVDR Kopie des easyVDR-Forums zum Nachschlagen
Script zur Erstellung DLNA-freundlicher Aufnahmeverzeichnisse

easyVDR - >VARforumsname - >Script zur Erstellung DLNA-freundlicher Aufnahmeverzeichnisse

brkai  19.Sep.2018 16:59:47
Hallo zusammen,

da ich mit meinen verschiedenen easyVDR-Versionen immer wieder von eurem KowHow partizipiert habe,
möchte ich der Community auch mal was zur Verfügung stellen. (... hoffe, hier ist der richtige Platz dafür)

Da wir mittlerweile mehrere Smart-TV's im Haus verteilt haben, wollte ich die Aufnahmen für den WaF gut lesbar mit dem minidlna servieren.
Bei der Lösung, die mir Herr G. ausgespuckt hat, war mir die Einarbeitungszeit zu lange, daher habe ich mir letztes Wochenende quick & dirty ein Python (2) Script gebastelt.
- Geht bestimmt auch eleganter -

Voraussetzung:
Es darf nur eine *.TS Datei im Aufnahmeverzeichnis vorhanden sein. Also muss die max. Größe für die Aufnahmen im VDR entsprechend hoch eingestellt sein.


Das Script sollte bei einem Standard-easyVDR 3.x Setup OOTB laufen und macht folgendes:
- Verzeichnis für den minidlna-Server anlegen
- Durchlaufen der Aufnahme-Pfades
- Auslesen des Titel und Untertitel aus der VDR info Datei

- Im Zielverzeichnis für den minidlna-Server Unterverzeichnisse und Symlinks (zu 0001.ts) mit "schönen", langen Namen aus Titel und Untertitel anlegen


Mittels Cron-Job lasse ich es alle 10 Min. laufen.

Was nicht sauber geht:
Wenn z.B. die Symlinks im Verzeichnis /xxx/aufnahmen liegen und der minidlna auf dieses Verzeichnis schaut, kommt er anscheinend etwas durcheinenader und zeigt nach einem "Refresh" in den Cilents nur noch "Ordner Durchsuchen" an (Wo dann auch alles wieder zu finden ist).
Das liegt wahrscheinlich daran, dass das Script die Verzeichnis-Struktur bei jedem Durchlauf komplett neu erstellt und ist bei mir bisher nicht mehr aufgetreten, seit ich den minidlna auf das übergeordnete Verzeichnis schauen lasse, also: /xxx

Wenn der minidlna-Server erstmal dem Symlink gefolgt ist, macht es offensichtlich nichts aus, wenn man ihm den Symlink während des Streamens unter dem Hintern weg zieht, zumindest sind die Streams beim Testen nicht zusammengebrochen.


#! /usr/bin/python

import sys
import os
import errno
import string
import shutil

strAppDir = os.path.dirname(os.path.realpath(__file__)) + "/"

strBaseDirRecordings = "/media/easyvdr01/video0"
strBaseDirDLNA = "/media/easyvdr01/dlnarecordings/aufnahmen"

strExtensionStream = "TS"
strExtensionRecFolder = "rec"

strArrFoldersExExclude = ["/media/easyvdr01/video0/ausgelagerteaufnahmen"]
strArrFoldersExExcludeTemp =

strArrSubtitleNoSwap = ["Fernsehserie", "Fernsehfilm", "Moderation:"]

strReplaceTuples4UserFriendlyOut = [("_", " "),
("~", "-"),
("#2E", "."),
("#3A", ":"),
("#3F", "?"),
("/", "-"),
("\xc3\x9f", "ss")]

#\xc3\x9f   = sZ



def check_dirsexist(strPath2Check):
   if not os.path.exists(strPath2Check):
       os.makedirs(strPath2Check)
   return True

def cleanup_storage(strPath2Clean, boolWithSubdirs = False):
   for dir_name, subdir_list, file_list in os.walk(strPath2Clean):
       if boolWithSubdirs == False:
           for filename in file_list:
               os.remove(os.path.join(strPath2Clean, filename))
       else:
           for filename in file_list:
               os.remove(os.path.join(dir_name, filename))
       if dir_name <> strPath2Clean:
           shutil.rmtree(dir_name)
   return True

def walklevel(some_dir, level=1):
   some_dir = some_dir.rstrip(os.path.sep)
   assert os.path.isdir(some_dir)
   num_sep = some_dir.count(os.path.sep)
   for root, dirs, files in os.walk(some_dir):
       yield root, dirs, files
       num_sep_this = root.count(os.path.sep)
       if num_sep + level <= num_sep_this:
           del dirs[:]

def string_included(stringToSearchIn, ArrayWithSubStrings):
 returnVal = False
 for curStr in ArrayWithSubStrings:
   if curStr in stringToSearchIn:
     returnVal = True
     break
 return returnVal

def make_userfriend(dirnameInput, IsArray=False):
 if IsArray == True:
   dirnameOutput =
   for modThis in dirnameInput:
     for stringTuples in strReplaceTuples4UserFriendlyOut:
       replaceThis = stringTuples
       replaceWith = stringTuples
       modThis = modThis.replace(replaceThis, replaceWith)
     dirnameOutput.append(modThis.replace(replaceThis, replaceWith))
 else:
   dirnameOutput = dirnameInput
   for stringTuples in strReplaceTuples4UserFriendlyOut:
     replaceThis = stringTuples
     replaceWith = stringTuples
     dirnameOutput = dirnameOutput.replace(replaceThis, replaceWith)
 return dirnameOutput

def read_vdrinfo(strFileFullPath):
   arrTemp =
   lnCount = 0
   if os.path.exists(strFileFullPath) == True:
       inputFile = open(strFileFullPath,'r')
       strLines = [line.rstrip('\n') for line in inputFile]
       inputFile.close()
       for line in strLines:
         lnCount = lnCount + 1
         if line <> "":
           if lnCount == 3:
             strSplitLine = [lineA.rstrip(' ') for lineA in line]
             if strSplitLine == "T":
               arrTemp.append(line.replace("T ", "", 1))
           if lnCount == 4:
             strSplitLine = [lineA.rstrip(' ') for lineA in line]
             if strSplitLine == "S":
               arrTemp.append(line.replace("S ", "", 1))
   return arrTemp

def create_symlink(strRecDir, strTargetDir, IsSerie=False, MultiRecs=False):
   symlinkName = ""
   for dir_name_src, subdir_list_src, file_list_src in walklevel(strRecDir):
       file_list_src.sort()
       if dir_name_src <> strRecDir:
           if MultiRecs == True:
               machNix = 1
           symlinkName = ""
           if os.path.splitext(dir_name_src)[1:] == strExtensionRecFolder:
               arrInfo = make_userfriend(read_vdrinfo(os.path.join(dir_name_src, "info")), True)
               # an letzter stelle des Namens kommt das aufnahmeverzeichnis (zur sicherheit, um eindeutigkeit zu behalten)
               strDateOfRecording = os.path.splitext(os.path.basename(dir_name_src).replace(".rec", ""))
               if len(arrInfo) == 1:
                   symlinkName = arrInfo + " " + strDateOfRecording
               if len(arrInfo) == 2:
                   NoSwap = string_included(arrInfo, strArrSubtitleNoSwap)
                   if IsSerie == False:
                       symlinkName = arrInfo + " (" + arrInfo + ") " + strDateOfRecording
                   else:
                       if NoSwap == False:
                           symlinkName = arrInfo + " (" + arrInfo + ") " + strDateOfRecording
                       else:
                           symlinkName = arrInfo + " (" + arrInfo + ") " + strDateOfRecording
               if len(symlinkName) >0:
                   symlinkName = symlinkName + ".ts"
                   try:
                       os.unlink(os.path.join(strTargetDir, symlinkName))
                   except OSError, e:
                       machNix = 1
                   try:
                       os.symlink(os.path.join(dir_name_src, "00001.ts"), os.path.join(strTargetDir, symlinkName))
                   except OSError, e:
                       print "LINK Error ", e.errno
                       machNix = 1

def GetRecDirs(strFindInDir):
   NumOfDirs = 0
   ArrRecDirs =
   SubDirString = ""
   for PathNameRecordings, SubDirListRecordings, FileListRecordings in walklevel(strFindInDir):
       SubDirListRecordings.sort()
       for SubDir in SubDirListRecordings:
           if os.path.splitext(SubDir)[1:] == strExtensionRecFolder:
               NumOfDirs = NumOfDirs + 1
               SubDirString = os.path.join(SubDirString, SubDir)
           else:
               SubDirString = os.path.join(SubDirString, SubDir)
               NumOfDirs = NumOfDirs + 1
               ArrRecDirs.append(SubDirString)
   return ArrRecDirs

def GetRecDirs2(strFindInDir):
   NumOfDirs = 0
   ArrRecDirs =
   SubDirString = ""
   for PathNameRecordings, SubDirListRecordings, FileListRecordings in walklevel(strFindInDir):
       SubDirListRecordings.sort()
       for SubDir in SubDirListRecordings:
           if os.path.splitext(SubDir)[1:] == strExtensionRecFolder:
               NumOfDirs = NumOfDirs + 1
           else:
               NumOfDirs = NumOfDirs + 1
               ArrRecDirs.append(SubDir)
   return ArrRecDirs


def CountSubDirs(strCountInDir):
   NumSubDirs = 0
   NumRecDirs = 0
   for PathNameRecordings, SubDirListRecordings, FileListRecordings in walklevel(strCountInDir):
       for SubDir in SubDirListRecordings:
           if os.path.splitext(SubDirListRecordings)[1:] == strExtensionRecFolder:
               NumRecDirs = NumRecDirs + 1
           else:
               NumSubDirs = NumSubDirs + 1
   return NumSubDirs, NumRecDirs, len(FileListRecordings)


def WalkRecordDirs(strSourceDir, strTargetDir, IsSeriesDir=False, SpecialTreatment=False):
   for PathNameRecordings, SubDirListRecordings, FileListRecordings in walklevel(strSourceDir):
       SubDirListRecordings.sort()
       if PathNameRecordings <> strSourceDir:
           if not string_included(PathNameRecordings,strArrFoldersExExclude):
               if not string_included(PathNameRecordings,strArrFoldersExExcludeTemp):
                   strDirTarg = os.path.join(strTargetDir, make_userfriend(os.path.basename(PathNameRecordings)))
                   NumSubDirs, NumRecDirs, NumFiles = CountSubDirs(PathNameRecordings)
                   if NumSubDirs == 0 and NumRecDirs == 1 and NumFiles > 1:
                       #aufnahme!, symlink erzeugen
                       create_symlink(PathNameRecordings, strTargetDir, IsSeriesDir)
                   elif NumSubDirs == NumRecDirs and NumFiles == 0:
                       #serien-verzeichnis!, weiter suchen
                       if SpecialTreatment == True:
                           if NumSubDirs == 1 and NumRecDirs == 1 and NumFiles == 0:
                               #aufnahme!, symlink erzeugen
                               RecDirs = GetRecDirs(PathNameRecordings)
                               #print "RecDirs      ", IsSeriesDir, strTargetDir
                               if len(RecDirs) == 1:
                                   create_symlink(os.path.join(PathNameRecordings, RecDirs), strTargetDir, IsSeriesDir)
                           if NumSubDirs == 1 and NumRecDirs > 1 and NumFiles == 0:
                               #mehrere aufnahmen!, symlink erzeugen
                               print "         ", PathNameRecordings
                               RecDirs = GetRecDirs(PathNameRecordings)
                               print "RecDirs      ", IsSeriesDir, strTargetDir
                               if len(RecDirs) == 1:
                                   create_symlink(os.path.join(PathNameRecordings, RecDirs), strTargetDir, IsSeriesDir, True)
                           if NumSubDirs > 1 and NumRecDirs > 1 and NumFiles == 0:
                               #mehrere aufnahmen, mehrere Unterverzeichnisse!, symlinks erzeugen
                               RecDirs = GetRecDirs2(PathNameRecordings)
                               for RecSubDir in RecDirs:
                                   create_symlink(os.path.join(PathNameRecordings, RecSubDir), strTargetDir, IsSeriesDir, True)
                       else:
                           check_dirsexist(strDirTarg)
                           WalkRecordDirs(PathNameRecordings, strDirTarg, True)
                   elif NumSubDirs == 1 and NumRecDirs > 1 and NumFiles == 0:
                       #mehrere aufnahmen!, symlink erzeugen
                       #print "spezial-behandlung!!!"
                       if SpecialTreatment == True:
                           if NumSubDirs == 1 and NumRecDirs > 1 and NumFiles == 0:
                               #mehrere aufnahmen!, symlink erzeugen
                               RecDirs = GetRecDirs(PathNameRecordings)
                               if len(RecDirs) == 1:
                                   create_symlink(os.path.join(PathNameRecordings, RecDirs), strTargetDir)
                   elif NumSubDirs > 0 and NumRecDirs == 0 and NumFiles == 0:
                       #serien-verzeichnis spezielle behandlung!, weiter suchen
                       check_dirsexist(strDirTarg)
                       WalkRecordDirs(PathNameRecordings, strDirTarg, True, True)


check_dirsexist(strBaseDirDLNA)
cleanup_storage(strBaseDirDLNA, True)
WalkRecordDirs(strBaseDirRecordings, strBaseDirDLNA)