|
SageTV v7 Customizations This forums is for discussing and sharing user-created modifications for the SageTV version 7 application created by using the SageTV Studio or through the use of external plugins. Use this forum to discuss plugins for SageTV version 7 and newer. |
|
Thread Tools | Search this Thread | Display Modes |
#681
|
|||
|
|||
Output isn't dumped until the process ends. All output is captured within the task client then sent to the server for logging after the process completes. There will be no logs available until the task is completed/failed. Metadata, however, should be showing up. Though this may be a bug with the UI because if the file is renaming, etc. then the metadata must be available in the script otherwise it'd just fail.
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#682
|
||||
|
||||
Quote:
|
#683
|
|||
|
|||
Quote:
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#684
|
|||
|
|||
Having a bit of an issue. Here is my job process
After recording: add comskip job which runs after recording is complete add transcode job that waits for the .edl to be created before it proceeds The problem is occasionally the comskip job doesn't complete, so the transcode job just goes around and around and never starts. It seems to hold up the queue so that nothing else transcodes either. What is the best solution to this? Thanks |
#685
|
|||
|
|||
Quote:
I'm assuming all of these tasks are for a specific media file object you've identified? If so, just add a counter to the metadata of that media file and once the counter exceeds a max, just return SKIPPED for the task. So each time the check for an edl is done and it fails, before returning 1 in the test script check a metadata value of that media file. If it's greater than the max then return 2 instead of 1 (meaning to skip the task) else increment the counter. You could also generate a system message to notify you that the transcode task never started because an edl wasn't found after x number of tries. Hopefully that makes sense?
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#686
|
||||
|
||||
Can someone save me from myself?
I have over 1000 tasks in the Active queue and I cannot clear them using the kill all tasks. Is there a quick way to do it? I fixed the cause of all of the jobs queuing up (i think), but I need to clear out what is there. I even tried uninstalling the SJQ plugin, but that did not work. |
#687
|
||||
|
||||
Today it seems to be working, though I changed nothing. I did restart sagetv, so maybe something was 'confused' after all the testing and resolved with the all healing gesture.... the UI behavior is normal as well so... Elvis has left the building.... Will let you know if it 'happens' again. Thx.
|
#688
|
|||
|
|||
Quote:
Code:
DELETE FROM queue WHERE state NOT IN ('STARTED', 'RUNNING') Code:
DELETE FROM queue WHERE state IN ('WAITING')
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#689
|
||||
|
||||
That worked, thanks!
|
#690
|
||||
|
||||
I'm lost... a bit and could some guidance out of the woods.
There's what looks to me like an error in my script, it works, but I think that's coincidence. I'm trying to make changes to the routine to check that type does not = "Movie" and move things around a bit, such as remove the special characters from the filename earlier on in the script so I can use the same variable later without having to do it again, etc. , in doing so I 'fixed' what looks to me like an open "{" in this block: Code:
if (type == "Movie") { def newPrefix = title + " /(/" + year + "/)/" } else { def newPrefix = "${title} - " if(seNum != null) newPrefix += seNum else if(subtitle != "") newPrefix += subtitle else if(origAirDate != null) newPrefix += origAirDate else newPrefix += "UNKNOWN" def file = new File(newPrefix + ".ts") def dir = file.getParent() def base = FilenameUtils.getBaseName(file.getName()) def ext = FilenameUtils.getExtension(file.getName()) def i = 1 while(file.exists()) file = new File(dir, "$base-${i++}.$ext") println "New file is: $file" newPrefix = FilenameUtils.getBaseName(file.getName()) The whole original script: Code:
// def SJQ4_METADATA = ["SJQ4_ID":"4548571", "SJQ4_TYPE":"MediaFile"] // And then do whatever you were doing as normal; just remember to // remove the above line before using the scirpt in SJQv4. import org.apache.commons.io.FilenameUtils import org.apache.commons.io.FileUtils private class Settings { static public final boolean TEST_MODE = false } def mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) if(mf == null) { //make sure it's a valid file id println "Invalid media file id! [${SJQ4_METADATA['SJQ4_ID']}]" return 1 } AiringAPI.SetWatched(mf); // Lets set the show as watched before we go further // def cats = ShowAPI.GetShowCatagoriesList(mf) // show catagogries used to decide if its a move or tv series def type = MediaFileAPI.GetMediaFileMetadata(mf, "MediaType") def title = ShowAPI.GetShowTitle(mf) def sNum = ShowAPI.GetShowSeasonNumber(mf) def eNum = ShowAPI.GetShowEpisodeNumber(mf) def seNum = sNum > 0 && eNum > 0 ? String.format("S%02dE%02d", sNum, eNum) : null def subtitle = ShowAPI.GetShowEpisode(mf) def origAirDate = ShowAPI.GetOriginalAiringDate(mf) > 0 ? new Date(ShowAPI.GetOriginalAiringDate(mf)).format("yyyy-MM-dd") : null def year = ShowAPI.GetShowYear(mf) // if (cats.contains("Movie") || cats.contains("Film")) { if (type == "Movie") { def newPrefix = title + " /(/" + year + "/)/" } else { def newPrefix = "${title} - " if(seNum != null) newPrefix += seNum else if(subtitle != "") newPrefix += subtitle else if(origAirDate != null) newPrefix += origAirDate else newPrefix += "UNKNOWN" def file = new File(newPrefix + ".ts") def dir = file.getParent() def base = FilenameUtils.getBaseName(file.getName()) def ext = FilenameUtils.getExtension(file.getName()) def i = 1 while(file.exists()) file = new File(dir, "$base-${i++}.$ext") println "New file is: $file" newPrefix = FilenameUtils.getBaseName(file.getName()) def numSegments = MediaFileAPI.GetNumberOfSegments(mf) if(numSegments == 1) { def prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath()) println "Renaming files that look like '${prefix}.*' to '${newPrefix}.*'..." renameMatches(MediaFileAPI.GetParentDirectory(mf), prefix, null, newPrefix) } else if(numSegments > 1) { for(def i2 = 0; i < numSegments; ++i2) { def prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, i2).getAbsolutePath()) def segPrefix = "$newPrefix-$i2" println "Renaming files that look like '${prefix}.*' to '${segPrefix}.*'..." renameMatches(MediaFileAPI.GetParentDirecotry(mf), prefix, null, segPrefix) } } else { println "No file segments for given media file!" return 1 } return 0 } // Pass null for newDir to keep renamed file in same directory def renameMatches(def oldDir, def prefix, def newDir, def newPrefix) { if(newDir == null) newDir = oldDir Utility.DirectoryListing(oldDir).each { if(FilenameUtils.wildcardMatchOnSystem(it.getName(), "${prefix}.*")) { def newName = (newPrefix + it.getName().substring(it.getName().indexOf('.')) =~ /[\/\\:*?<>]/).replaceAll("") if(!Settings.TEST_MODE) { try { FileUtils.moveFile(it, new File(newDir, newName)) } catch(IOException e) { e.printStackTrace() println("Failed to move file to destination!") FileUtils.copyFile(it, new File(newDir, newName)) } } else { println "Would rename '$it' to '$newName' if test mode were disabled!" } } } // comskip attempt def newName2 = (newPrefix =~ /[\/\\:*?<>]/).replaceAll("") // remove special characthers from newPrefix def fullpathfile = newDir.toString() + "/" + newName2 + ".ts" // Convert newDir from file type to string variable and add .ts to filename, combine. def command = ["c:/program files/comskip/comskip.exe", fullpathfile] //define command as an array println "full command will be '$command'" def proc = command.execute() if(!Settings.TEST_MODE) { // Are we running test mode, if not do this def initialSize = 4096 def outStream = new ByteArrayOutputStream(initialSize) def errStream = new ByteArrayOutputStream(initialSize) proc.consumeProcessOutput(outStream, errStream) proc.waitFor() println 'out:\n' + outStream println 'err:\n' + errStream } else { // if we are in test mode do this println "Would run '$command' if test mode were disabled!" } } return 0; Code:
def SJQ4_METADATA = ["SJQ4_ID":"4586791", "SJQ4_TYPE":"MediaFile"] // And then do whatever you were doing as normal; just remember to // remove the above line before using the scirpt in SJQv4. import org.apache.commons.io.FilenameUtils import org.apache.commons.io.FileUtils private class Settings { static public final boolean TEST_MODE = false } def mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) if(mf == null) { //make sure it's a valid file id println "Invalid media file id! [${SJQ4_METADATA['SJQ4_ID']}]" return 1 } AiringAPI.SetWatched(mf); // Lets set the show as watched before we go further def type = MediaFileAPI.GetMediaFileMetadata(mf, "MediaType") def title = ShowAPI.GetShowTitle(mf) def sNum = ShowAPI.GetShowSeasonNumber(mf) def eNum = ShowAPI.GetShowEpisodeNumber(mf) def seNum = sNum > 0 && eNum > 0 ? String.format("S%02dE%02d", sNum, eNum) : null def subtitle = ShowAPI.GetShowEpisode(mf) def origAirDate = ShowAPI.GetOriginalAiringDate(mf) > 0 ? new Date(ShowAPI.GetOriginalAiringDate(mf)).format("yyyy-MM-dd") : null def year = ShowAPI.GetShowYear(mf) def newPrefix = "${title}" if (type != "Movie") { newPrefix += " - " if(seNum != null) newPrefix += seNum else if(subtitle != "") newPrefix += subtitle else if(origAirDate != null) newPrefix += origAirDate else newPrefix += "UNKNOWN" } else { println "we've got us a movie!" if(year != null) newPrefix += "/(/ ${year})" else if(origAirDate != null) newPrefix += origAirDate } newPrefix = (newPrefix =~ /[\/\\:*?<>]/).replaceAll("") def file = new File(newPrefix + ".ts") def dir = file.getParent() def base = FilenameUtils.getBaseName(file.getName()) def ext = FilenameUtils.getExtension(file.getName()) def i = 1 while(file.exists()) file = new File(dir, "$base-${i++}.$ext") println "New file is: $file" newPrefix = FilenameUtils.getBaseName(file.getName()) def fullfilename = file.toString() println "fullfilename is: $fullfilename" def numSegments = MediaFileAPI.GetNumberOfSegments(mf) if(numSegments == 1) { def prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath()) println "Renaming files that look like '${prefix}.*' to '${newPrefix}.*'..." renameMatches(MediaFileAPI.GetParentDirectory(mf), prefix, null, newPrefix) } else if(numSegments > 1) { for(def i2 = 0; i < numSegments; ++i2) { def prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, i2).getAbsolutePath()) def segPrefix = "$newPrefix-$i2" println "Renaming files that look like '${prefix}.*' to '${segPrefix}.*'..." renameMatches(MediaFileAPI.GetParentDirecotry(mf), prefix, null, segPrefix) } } else { println "No file segments for given media file!" return 1 } return 0 } // Pass null for newDir to keep renamed file in same directory def renameMatches(def oldDir, def prefix, def newDir, def newPrefix) { if(newDir == null) newDir = oldDir Utility.DirectoryListing(oldDir).each { if(FilenameUtils.wildcardMatchOnSystem(it.getName(), "${prefix}.*")) { def newName = (newPrefix + it.getName().substring(it.getName().indexOf('.'))) // =~ /[\/\\:*?<>]/).replaceAll("") if(!Settings.TEST_MODE) { try { FileUtils.moveFile(it, new File(newDir, newName)) } catch(IOException e) { e.printStackTrace() println("Failed to move file to destination!") FileUtils.copyFile(it, new File(newDir, newName)) } } else { println "Would rename '$it' to '$newName' if test mode were disabled!" } } } // comskip attempt //def newName2 = (newPrefix =~ /[\/\\:*?<>]/).replaceAll("") // remove special characthers from newPrefix // def fullpathfile = "${newDir}.toString()/${newfilename}.toString)" // Convert newDir from file type to string variable and add .ts to filename, combine. def fullpathfile = newDir.toString() + "\\$fullfilename" println "fullpathfile is=$fullpathfile" // fullpathfile += fullfilename.toString() // def fullpathfile = "${newDir}.toString()/${newfilename}.toString()" def command = ["c:/program files/comskip/comskip.exe", fullpathfile] //define command as an array println "full command will be '$command'" def proc = command.execute() if(!Settings.TEST_MODE) { // Are we running test mode, if not do this def initialSize = 4096 def outStream = new ByteArrayOutputStream(initialSize) def errStream = new ByteArrayOutputStream(initialSize) proc.consumeProcessOutput(outStream, errStream) proc.waitFor() println 'out:\n' + outStream println 'err:\n' + errStream } else { // if we are in test mode do this println "Would run '$command' if test mode were disabled!" } return 0 } |
#691
|
|||
|
|||
@bikesquid - so i have no idea if this is your problem or not... but i loaded up your two original scripts into notepad++ and did a difference on them so i could easily see what changed and the one thing i notice is in the original script the final "return 0" is outside the last } and in the modified one its inside...
like i said i havent examined the code in depth to see if that is really the problem but it was one difference i noticed... if you havent already you may want to fire up the scripts in a difference editor (notepad++ works great for this) and then it makes it very easy to see the differences.
__________________
Server 2003 r2 32bit, SageTV9 (finally!) 2x Dual HDHR (OTA), 1x HD-PVR (Comcast), 1x HDHR-3CC via SageDCT (Comcast) 2x HD300, 1x SageClient (Win10 Test/Development) Check out TVExplorer |
#692
|
||||
|
||||
Can someone tell me if this should work? It is the media_file_scanner script with lines added to only process .mpg and .ts files. I tried it and I am getting EOF Exception errors. I highlighted my changes in red.
Code:
/* Media File Scanner/Task Queuer Last Modified: 15 Feb 2011 Author: Derek Battams <derek AT battams DOT ca> Use this script to periodically scan your media objects and check to see if any need to have tasks queued on them. Basically, set up your media mask and then modify the needsProcessing() function to do the checks you want against each object. If needsProcessing() returns true for an object then it will queue up each task listed in the taskIds list for that object. Typically, you would run this script periodically via the SJQv4 crontab. PLEASE RUN THIS SCRIPT WITH testMode = true BEFORE ALLOWING IT TO ACTUALLY QUEUE UP TASKS!! */ /***** CONFIGURE BELOW *****/ def testMode = false // If true, only print out which media files would be queued up, don't actually add the tasks to the queue def mediaMask = "T" // What types of media should be scanned? (T = TV, M = Music, V = Imported Video, D = DVD, B = BluRay, P = Pictures; TMV = TV + Music + Imports, etc.) def taskIds = ["COMSKIP","COMSKIPSD"] // Multiple tasks can be listed, separated by commas /* Returns true if the argument needs to be queued or false if it should be skipped Modify this function to determine which media files get queued up and which don't */ def needsProcessing(Object mediaFile) { // This function could be written in a much more condensed manner, but I'm breaking it up for the sake of readability // So let's skip queuing this media file if it's live tv or an IR recording if(AiringAPI.IsNotManualOrFavorite(mediaFile)) return false // Personally, I don't comskip until the recording is done, so don't queue up recordings in progress if(MediaFileAPI.IsFileCurrentlyRecording(mediaFile)) return false // Let's also skip it if it's from a channel known not to have commercials (adjust the regex accordingly) if(AiringAPI.GetAiringChannelName(mediaFile) =~ /HBO.*|M(?:HD){0,1}|WPBS|.*PPV.*/) return false // Let's also skip it if there is already an edl file for the media file; adjust the extensions, if necessary if(hasArtifacts(mediaFile, ["edl"])) // This function is defined at the bottom of the file return false // Let's skip it if the file is not a supported media file type if(isSupportedExt(mediaFile, ["mpg","ts"])) // This function is defined at the bottom of the file return true // I don't like comskipping hockey and football games, I just have the skip ahead set properly on my remote so don't bother if(MediaFileAPI.GetMediaTitle(mediaFile) =~ /NFL Football|MLB Baseball|NHL Hockey|College Football|College Basketball/) return false // All our tests have passed so return true return true } /***** END CONFIG BLOCK *****/ /***** DO NOT MODIFY BELOW THIS LINE *****/ import com.google.code.sagetvaddons.sjq.network.ServerClient import com.google.code.sagetvaddons.metadata.Factory import org.apache.commons.io.FilenameUtils def sc = !testMode ? new ServerClient() : null MediaFileAPI.GetMediaFiles(mediaMask).each { mf -> if(needsProcessing(mf)) { if(!testMode) taskIds.each { id -> sc.addTask(id, Factory.getMap(mf)) } else println "Would queue up '${MediaFileAPI.GetMediaTitle(mf)}' (${MediaFileAPI.GetMediaFileID(mf)}); skipped because test mode is TRUE" } } if(sc != null) sc.close() return 0 // Returns true if any segment of the given media file has at least one artifact of any of the given artifact extensions; false otherwise def hasArtifacts(Object mf, List exts) { for(def it : MediaFileAPI.GetSegmentFiles(mf)) { def absPath = it.getAbsolutePath() def dir = FilenameUtils.getFullPath(absPath) def base = FilenameUtils.getBaseName(absPath) for(def ext : exts) { def artifact = "${dir}${base}.$ext" if(Utility.IsFilePath(artifact)) {return true} } } return false } // Returns false if the extension is mpg or ts def isSupportedExt(Object mf, List exts2) { for(def it : MediaFileAPI.GetSegmentFiles(mf)) { def absPath2 = it.getAbsolutePath() def extension = FilenameUtils.getExtension(absPath2) for(def ext2 : exts2) { if(extension==ext2) {return true} } } return false } |
#693
|
||||
|
||||
Quote:
The errors I'm getting are (using xxx for the script file name): MissingPropertyException: No such property:fullfilename for class: xxx @ xxx$renamaneMatches(xxx:116) -this is the line # @ xxx$renameMatches.callCurrent(Unknown Source) @ xxx.run(xxx:74) - again the line # Problem is that though I've seen MissingPropertyException errors before and slugger has explained it to me, I don't see how this is the same issue and don't know how to interpret it. |
#694
|
|||
|
|||
Quote:
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#695
|
||||
|
||||
I'm using sagegroovy for testing is there a way to output the full stack trace, it's a heck of a lot of typing otherwise...? Normal cut/paste from the output window doesn't seem to be doing anything
|
#696
|
||||
|
||||
Quote:
thx. script: Code:
def SJQ4_METADATA = ["SJQ4_ID":"4581185", "SJQ4_TYPE":"MediaFile"] // And then do whatever you were doing as normal; just remember to // remove the above line before using the scirpt in SJQv4. import org.apache.commons.io.FilenameUtils import org.apache.commons.io.FileUtils private class Settings { static public final boolean TEST_MODE = false } def mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) if(mf == null) { //make sure it's a valid file id println "Invalid media file id! [${SJQ4_METADATA['SJQ4_ID']}]" return 1 } AiringAPI.SetWatched(mf); // Lets set the show as watched before we go further def type = MediaFileAPI.GetMediaFileMetadata(mf, "MediaType") def title = ShowAPI.GetShowTitle(mf) def sNum = ShowAPI.GetShowSeasonNumber(mf) def eNum = ShowAPI.GetShowEpisodeNumber(mf) def seNum = sNum > 0 && eNum > 0 ? String.format("S%02dE%02d", sNum, eNum) : null def subtitle = ShowAPI.GetShowEpisode(mf) def origAirDate = ShowAPI.GetOriginalAiringDate(mf) > 0 ? new Date(ShowAPI.GetOriginalAiringDate(mf)).format("yyyy-MM-dd") : null def year = ShowAPI.GetShowYear(mf) def newPrefix = "${title}" if (type != "Movie") { newPrefix += " - " if(seNum != null) newPrefix += seNum else if(subtitle != "") newPrefix += subtitle else if(origAirDate != null) newPrefix += origAirDate else newPrefix += "UNKNOWN" } else { println "we've got us a movie!" if(year != null) newPrefix += "/(/ ${year})" else if(origAirDate != null) newPrefix += origAirDate } newPrefix = (newPrefix =~ /[\/\\:*?<>]/).replaceAll("") def file = new File(newPrefix + ".ts") def dir = file.getParent() def base = FilenameUtils.getBaseName(file.getName()) def ext = FilenameUtils.getExtension(file.getName()) def i = 1 while(file.exists()) file = new File(dir, "$base-${i++}.$ext") println "New file is: $file" newPrefix = FilenameUtils.getBaseName(file.getName()) def fullfilename = file.toString() println "fullfilename is: $fullfilename" def numSegments = MediaFileAPI.GetNumberOfSegments(mf) if(numSegments == 1) { def prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath()) println "Renaming files that look like '${prefix}.*' to '${newPrefix}.*'..." renameMatches(MediaFileAPI.GetParentDirectory(mf), prefix, null, newPrefix) } else if(numSegments > 1) { for(def i2 = 0; i < numSegments; ++i2) { def prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, i2).getAbsolutePath()) def segPrefix = "$newPrefix-$i2" println "Renaming files that look like '${prefix}.*' to '${segPrefix}.*'..." renameMatches(MediaFileAPI.GetParentDirecotry(mf), prefix, null, segPrefix) } } else { println "No file segments for given media file!" return 1 } return 0 // Pass null for newDir to keep renamed file in same directory def renameMatches(def oldDir, def prefix, def newDir, def newPrefix) { if(newDir == null) newDir = oldDir Utility.DirectoryListing(oldDir).each { if(FilenameUtils.wildcardMatchOnSystem(it.getName(), "${prefix}.*")) { def newName = (newPrefix + it.getName().substring(it.getName().indexOf('.'))) // =~ /[\/\\:*?<>]/).replaceAll("") if(!Settings.TEST_MODE) { try { FileUtils.moveFile(it, new File(newDir, newName)) } catch(IOException e) { e.printStackTrace() println("Failed to move file to destination!") FileUtils.copyFile(it, new File(newDir, newName)) } } else { println "Would rename '$it' to '$newName' if test mode were disabled!" } } } // comskip attempt //def newName2 = (newPrefix =~ /[\/\\:*?<>]/).replaceAll("") // remove special characthers from newPrefix // def fullpathfile = "${newDir}.toString()/${newfilename}.toString)" // Convert newDir from file type to string variable and add .ts to filename, combine. def fullpathfile = newDir.toString() + "\\$fullfilename" println "fullpathfile is=$fullpathfile" // fullpathfile += fullfilename.toString() // def fullpathfile = "${newDir}.toString()/${newfilename}.toString()" def command = ["c:/program files/comskip/comskip.exe", fullpathfile] //define command as an array println "full command will be '$command'" def proc = command.execute() if(!Settings.TEST_MODE) { // Are we running test mode, if not do this def initialSize = 4096 def outStream = new ByteArrayOutputStream(initialSize) def errStream = new ByteArrayOutputStream(initialSize) proc.consumeProcessOutput(outStream, errStream) proc.waitFor() println 'out:\n' + outStream println 'err:\n' + errStream } else { // if we are in test mode do this println "Would run '$command' if test mode were disabled!" } return 0 } Code:
New file is: Nikita - S01E17.ts fullfilename is: Nikita - S01E17.ts Renaming files that look like 'Nikita-Covenant-4500262-0.*' to 'Nikita - S01E17.*'... Exception thrown groovy.lang.MissingPropertyException: No such property: fullfilename for class: file_rename_experiment at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:49) at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:239) at file_rename_experiment.renameMatches(file_rename_experiment.groovy:116) at file_rename_experiment$renameMatches.callCurrent(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:161) at file_rename_experiment.run(file_rename_experiment.groovy:74) at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:264) at groovy.lang.GroovyShell.run(GroovyShell.java:513) at groovy.lang.GroovyShell.run(GroovyShell.java:170) at groovy.lang.GroovyShell$run$6.call(Unknown Source) at groovy.ui.Console$_runScriptImpl_closure16.doCall(Console.groovy:890) at sun.reflect.GeneratedMethodAccessor875.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:273) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149) at groovy.ui.Console$_runScriptImpl_closure16.doCall(Console.groovy) at sun.reflect.GeneratedMethodAccessor874.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:273) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886) at groovy.lang.Closure.call(Closure.java:276) at groovy.lang.Closure.call(Closure.java:271) at groovy.lang.Closure.run(Closure.java:354) at java.lang.Thread.run(Unknown Source) |
#697
|
|||
|
|||
@rsagetv99 I copied/pasted the script as you have it here into SageGroovy and it ran fine for me with no edits at all. Did you edit it on Windows and try to run it in Linux or vice versa? That may cause problems with the Groovy interpreter, not sure.
However, it doesn't quite do what you want it to so I made a few tweaks... Code:
/* Media File Scanner/Task Queuer Last Modified: 15 Feb 2011 Author: Derek Battams <derek AT battams DOT ca> Use this script to periodically scan your media objects and check to see if any need to have tasks queued on them. Basically, set up your media mask and then modify the needsProcessing() function to do the checks you want against each object. If needsProcessing() returns true for an object then it will queue up each task listed in the taskIds list for that object. Typically, you would run this script periodically via the SJQv4 crontab. PLEASE RUN THIS SCRIPT WITH testMode = true BEFORE ALLOWING IT TO ACTUALLY QUEUE UP TASKS!! */ /***** CONFIGURE BELOW *****/ def testMode = false // If true, only print out which media files would be queued up, don't actually add the tasks to the queue def mediaMask = "T" // What types of media should be scanned? (T = TV, M = Music, V = Imported Video, D = DVD, B = BluRay, P = Pictures; TMV = TV + Music + Imports, etc.) def taskIds = ["COMSKIP","COMSKIPSD"] // Multiple tasks can be listed, separated by commas /* Returns true if the argument needs to be queued or false if it should be skipped Modify this function to determine which media files get queued up and which don't */ def needsProcessing(Object mediaFile) { // This function could be written in a much more condensed manner, but I'm breaking it up for the sake of readability // So let's skip queuing this media file if it's live tv or an IR recording if(AiringAPI.IsNotManualOrFavorite(mediaFile)) return false // Personally, I don't comskip until the recording is done, so don't queue up recordings in progress if(MediaFileAPI.IsFileCurrentlyRecording(mediaFile)) return false // Let's also skip it if it's from a channel known not to have commercials (adjust the regex accordingly) if(AiringAPI.GetAiringChannelName(mediaFile) =~ /HBO.*|M(?:HD){0,1}|WPBS|.*PPV.*/) return false // Let's also skip it if there is already an edl file for the media file; adjust the extensions, if necessary if(hasArtifacts(mediaFile, ["edl"])) // This function is defined at the bottom of the file return false // Let's skip it if the file is not a supported media file type if(!isSupportedExt(mediaFile, ["mpg","ts"])) // This function is defined at the bottom of the file return false // I don't like comskipping hockey and football games, I just have the skip ahead set properly on my remote so don't bother if(MediaFileAPI.GetMediaTitle(mediaFile) =~ /NFL Football|MLB Baseball|NHL Hockey|College Football|College Basketball/) return false // All our tests have passed so return true return true } /***** END CONFIG BLOCK *****/ /***** DO NOT MODIFY BELOW THIS LINE *****/ import com.google.code.sagetvaddons.sjq.network.ServerClient import com.google.code.sagetvaddons.metadata.Factory import org.apache.commons.io.FilenameUtils def sc = !testMode ? new ServerClient() : null MediaFileAPI.GetMediaFiles(mediaMask).each { mf -> if(needsProcessing(mf)) { if(!testMode) taskIds.each { id -> sc.addTask(id, Factory.getMap(mf)) } else println "Would queue up '${MediaFileAPI.GetMediaTitle(mf)}' (${MediaFileAPI.GetMediaFileID(mf)}); skipped because test mode is TRUE" } } if(sc != null) sc.close() return 0 // Returns true if any segment of the given media file has at least one artifact of any of the given artifact extensions; false otherwise def hasArtifacts(Object mf, List exts) { for(def it : MediaFileAPI.GetSegmentFiles(mf)) { def absPath = it.getAbsolutePath() def dir = FilenameUtils.getFullPath(absPath) def base = FilenameUtils.getBaseName(absPath) for(def ext : exts) { def artifact = "${dir}${base}.$ext" if(Utility.IsFilePath(artifact)) {return true} } } return false } // Returns false if the extension is mpg or ts def isSupportedExt(Object mf, List supported) { def mfExts = [] MediaFileAPI.GetSegmentFiles(mf).each { mfExts += FilenameUtils.getExtension(it.getName()) } if(mfExts.size() == 0) return false for(def ext : supported) if(mfExts.contains(ext)) return true return false } I also rewrote your isSupportedExt() function because it was hard for me to follow your logic, but it turns out that may not have been necessary since the real problem was in needsProcessing()
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#698
|
|||
|
|||
@bikesquid Time for some code reorg.
You've got a function defined in the middle of your main execution path. It seems you've gotten the bottom half of main stuck inside the function, which is why the fullfilename var isn't accessible on line 116... That } you thought was random really wasn't. Here's my edits... you didn't have newDir reassigned to anything - look for my big BLOCK letter comment for where you need to reassign that var if you want to move the renamed files to a different dir. Some notes:
Code:
def SJQ4_METADATA = ["SJQ4_ID":"6346252", "SJQ4_TYPE":"MediaFile"] // And then do whatever you were doing as normal; just remember to // remove the above line before using the scirpt in SJQv4. import org.apache.commons.io.FilenameUtils import org.apache.commons.io.FileUtils private class Settings { static public final boolean TEST_MODE = true } def mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) if(mf == null) { //make sure it's a valid file id println "Invalid media file id! [${SJQ4_METADATA['SJQ4_ID']}]" return 1 } AiringAPI.SetWatched(mf); // Lets set the show as watched before we go further def type = MediaFileAPI.GetMediaFileMetadata(mf, "MediaType") def title = ShowAPI.GetShowTitle(mf) def sNum = ShowAPI.GetShowSeasonNumber(mf) def eNum = ShowAPI.GetShowEpisodeNumber(mf) def seNum = sNum > 0 && eNum > 0 ? String.format("S%02dE%02d", sNum, eNum) : null def subtitle = ShowAPI.GetShowEpisode(mf) def origAirDate = ShowAPI.GetOriginalAiringDate(mf) > 0 ? new Date(ShowAPI.GetOriginalAiringDate(mf)).format("yyyy-MM-dd") : null def year = ShowAPI.GetShowYear(mf) def newPrefix = "${title}" if (type != "Movie") { newPrefix += " - " if(seNum != null) newPrefix += seNum else if(subtitle != "") newPrefix += subtitle else if(origAirDate != null) newPrefix += origAirDate else newPrefix += "UNKNOWN" } else { println "we've got us a movie!" if(year != null) newPrefix += "/(/ ${year})" else if(origAirDate != null) newPrefix += origAirDate } newPrefix = (newPrefix =~ /[\/\\:*?<>]/).replaceAll("") def file = new File(newPrefix + ".ts") def dir = file.getParent() def base = FilenameUtils.getBaseName(file.getName()) def ext = FilenameUtils.getExtension(file.getName()) def i = 1 while(file.exists()) file = new File(dir, "$base-${i++}.$ext") println "New file is: $file" newPrefix = FilenameUtils.getBaseName(file.getName()) def fullfilename = file.toString() println "fullfilename is: $fullfilename" def numSegments = MediaFileAPI.GetNumberOfSegments(mf) if(numSegments == 1) { def prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath()) println "Renaming files that look like '${prefix}.*' to '${newPrefix}.*'..." renameMatches(MediaFileAPI.GetParentDirectory(mf), prefix, null, newPrefix) } else if(numSegments > 1) { for(def i2 = 0; i < numSegments; ++i2) { def prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, i2).getAbsolutePath()) def segPrefix = "$newPrefix-$i2" println "Renaming files that look like '${prefix}.*' to '${segPrefix}.*'..." renameMatches(MediaFileAPI.GetParentDirecotry(mf), prefix, null, segPrefix) } } else { println "No file segments for given media file!" return 1 } // comskip attempt //def newName2 = (newPrefix =~ /[\/\\:*?<>]/).replaceAll("") // remove special characthers from newPrefix // def fullpathfile = "${newDir}.toString()/${newfilename}.toString)" // Convert newDir from file type to string variable and add .ts to filename, combine. // YOU WILL PROBABLY WANT TO REASSIGN newDir HERE!! def newDir = MediaFileAPI.GetParentDirectory(mf) def fullpathfile = newDir.toString() + "\\$fullfilename" println "fullpathfile is=$fullpathfile" // fullpathfile += fullfilename.toString() // def fullpathfile = "${newDir}.toString()/${newfilename}.toString()" def command = ["c:/program files/comskip/comskip.exe", fullpathfile] //define command as an array println "full command will be '$command'" if(!Settings.TEST_MODE) { // Are we running test mode, if not do this def proc = command.execute() def initialSize = 4096 def outStream = new ByteArrayOutputStream(initialSize) def errStream = new ByteArrayOutputStream(initialSize) proc.consumeProcessOutput(outStream, errStream) proc.waitFor() println 'out:\n' + outStream println 'err:\n' + errStream } else { // if we are in test mode do this println "Would run '$command' if test mode were disabled!" } return 0 // Pass null for newDir to keep renamed file in same directory def renameMatches(def oldDir, def prefix, def newDir, def newPrefix) { if(newDir == null) newDir = oldDir Utility.DirectoryListing(oldDir).each { if(FilenameUtils.wildcardMatchOnSystem(it.getName(), "${prefix}.*")) { def newName = (newPrefix + it.getName().substring(it.getName().indexOf('.'))) // =~ /[\/\\:*?<>]/).replaceAll("") if(!Settings.TEST_MODE) { try { FileUtils.moveFile(it, new File(newDir, newName)) } catch(IOException e) { e.printStackTrace() println("Failed to move file to destination!") FileUtils.copyFile(it, new File(newDir, newName)) } } else { println "Would rename '$it' to '$newName' if test mode were disabled!" } } } }
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#699
|
||||
|
||||
Quote:
I tried your script and it looks like it is working perfectly. Thanks alot. |
#700
|
||||
|
||||
Quote:
Quote:
Damn! I thought I had.... Quote:
Quote:
I do have a follow-up "under the hood" SJQ question though. Is there a way to inject a job into the queue from outside sage? I.E. once comskip is done I'd like to review the edits and then put the job back in to run a few more steps, such as cutting the comskip output from the file, handbrake etc. But as another process(s) and as the object file isn't a sagetv recording any longer it's difficult to find from within sagetv. |
Currently Active Users Viewing This Thread: 4 (0 members and 4 guests) | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Plugin: MizookLCD (Alternate SageTV LCDSmartie Plugin) | cslatt | SageTV Customizations | 48 | 06-11-2012 10:44 AM |
SJQv4: Technology Preview | Slugger | SageTV v7 Customizations | 39 | 12-17-2010 01:17 PM |
SageTV Plugin Developers: Any way to see stats for your plugin? | mkanet | SageTV Software | 4 | 12-12-2010 10:33 PM |
MediaPlayer Plugin/STV Import: Winamp Media Player Plugin | deria | SageTV Customizations | 447 | 12-11-2010 07:38 PM |
SJQv4: Design Discussion | Slugger | SageTV v7 Customizations | 26 | 10-18-2010 08:22 AM |