SageTV Community  

Go Back   SageTV Community > SageTV Development and Customizations > SageTV v7 Customizations
Forum Rules FAQs Community Downloads Today's Posts Search

Notices

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.

Reply
 
Thread Tools Search this Thread Display Modes
  #721  
Old 04-17-2011, 09:16 AM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
Quote:
Originally Posted by tmiranda View Post
Slugger,

I want to change the backup scripts so that if it is not run by a certain time of day it will not be run at all on that day. Right now I have the script set to do a backup at 4:00 AM and I want to make sure that if it's not run by 8:00 AM it's not run at all.

Do you suggest I do this by making the agent only available between 4 AM and 8 AM, or do you suggest I check the time in the test script and return 2 if it's past 8 AM?

Tom
I think either way works, if you're asking what I'd do then I'd probably set the task to only be available on the agent from 4-8am. You don't need to disable the entire agent, you can define schedules at the task level. Remember, for 4am-8am use:

* 4-7 * * *

Which actually matches 4:00 - 7:59. Where 4-8 would match 4:00 - 8:59.

By doing it that way, if it can't do it on the morning it's added to the queue then the task will stay in the queue and try again the next morning between 4-8 until it finally succeeds. If you want to just skip altogether and try again next week then check in the test script for the time and return 2 if it's beyond 8am, which will mark the task as skipped.
__________________
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...
Reply With Quote
  #722  
Old 04-17-2011, 03:09 PM
Korny Korny is offline
Sage Advanced User
 
Join Date: Nov 2010
Location: Minnesota
Posts: 87
Quick question about passing arguments

I'm trying to pass multiple arguments to a bash script file and the first argument is working fine "$SJQ4_PATH/$SJQ4_LAST_SEGMENT" but if I add $SJQ4_TITLE and $SJQ4_EPISODE they are passed as exactly that so the output reads like this

/media/Array1/sagetv/house12345.ts $SJQ4_TITLE $SJQ4_EPISODE

Which isn't really helpful for me at this time.
currently I have
"$SJQ4_PATH/SJQ4_LAST_SEGMENT $SJQ4_TITLE $SJQ4_EPISODE"
so in the bash script
$1 is /media/Array1/sagetv/house12345.ts
$2 is outputting $SJQ4_TITLE
$3 is outputting $SJQ4_EPISODE

I've tried putting quotations around both $SJQ4_TITLE and $SJQ4_EPISODE and without and having the whole argument within the same quotations. Am I just missing something really stupid here :/

Code:
#!/bin/bash
filename=$1
showtitle=$2
episode=$3
cp $filename "/media/Array1/needsprocess/$showtitle $episode.mkv"
The results are
$SJQ4_TITLE $SJQ4_EPISODE.mkv
Any help would be appreciated
__________________
Intel I7 4790k @ stock speeds, 32 GB of ram. 8TB of recording space.
Reply With Quote
  #723  
Old 04-17-2011, 08:19 PM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
When you queue up a task based on a media file object, SJQ only sets environment variables for the media file and nothing else.

See this document:

http://code.google.com/p/sagetv-addo...i/Sjq4Metadata

Have a look at the section for "Media File". Those are the only vars provide when a media file is queued. So this is why the $SJQ4_PATH and $SJQ4_LAST_SEGMENT expand, but the others do not.

You have a few choices to address this:

1) Instead of calling a bash script and trying to pass command line arguments, write a groovy script to do your task. With a groovy script, you can simply load the MediaFile object and then grab any and all metadata about it within your script.

Code:
import org.apache.commons.io.FileUtils

def mediaFile = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA['SJQ4_ID'].toInteger())

def fileName = "${SJQ4_METADATA['SJQ4_PATH']}/${SJQ4_METADATA['SJQ4_LAST_SEGMENT']}"
def showTitle = MediaFileAPI.GetMediaTitle(mediaFile)
def episode = ShowAPI.GetShowEpisode(mediaFile)

try {
   FileUtils.copyFile(new File(fileName), new File("/media/Array1/needsprocess/$showTitle $episode.mkv")
} catch(IOException e) {
   e.printStackTrace()
   return 1 // Copy failed
}

return 0
Really, you should be doing some error checking and some other things like stripping invalid characters from the file name, etc., but I'll assume you're doing that and just simplified your code for the sake of brevity on the forums (as I have done with my example groovy script).

2) Call a test groovy script and use it to modify the command line args to the bash script. You'd basically do the same thing as above, but instead of actually doing the file copy, just modify the exe's arguments by using Tools.setExeArgs()

3) Access the values you desire in bash via wget calls to the Sage HTTP remote APIs. Those vars I linked to above are env vars in your bash scripts so you could make an API call via wget to access the additional data you want.

The point here is that if you want to access values other than those provided, you have to somehow do it via a Sage API call. I prefer #1, but any of the methods discussed are valid.

Happy scripting!
__________________
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...
Reply With Quote
  #724  
Old 04-19-2011, 04:40 PM
bikesquid's Avatar
bikesquid bikesquid is offline
Sage Aficionado
 
Join Date: Jan 2010
Location: California's North Coast
Posts: 392
Any idea why I'm getting the attached error? I don't think I'm getting it all the time, but the last couple for sure.. The error goes on for about a half mile, but this is the jist.... In the end the script completes down to setting the metadata which seems to fail. If more of the error stream is needed would love to know a way to copy from a log file rather than the UI....
THX!


Script is:
Code:
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
}
// Let's set TASK_Status to 'running'.

MediaFileAPI.SetMediaFileMetadata(mf, 'TASK_Status', 'CUT_RUNNING')

def Prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath())
def Origfile = new File(Prefix + ".ts")
def VideoReDoFile = new File(Prefix + ".VPrj")
def Origdir = ((MediaFileAPI.GetParentDirectory(mf).toString()) + "\\")
def Origdir2 = (MediaFileAPI.GetParentDirectory(mf))
def base = FilenameUtils.getBaseName(Origfile.getName())
def CutExt = ".ts"
def CutDir = "\\\\Sage-pc\\Mirror_Set\\Process_TV\\com_free\\"
def FullInputFile = Origdir + VideoReDoFile
def FullCutFile = CutDir + Origfile
    println FullCutFile

def src = (FullCutFile.toString())
   println "fullpathfile is=$src"

def sid = ShowAPI.GetShowExternalID(mf)
   println "ExternalID is ${sid}"



// Cutting file using VideoRedo
def i = 1
def file = new File(FullCutFile)
while(file.exists())
    file = new File(CutDir, "$base-${i++}$CutExt")
println "New file is: $file"
FullCutFile = file

println "Cutting files that look like '${FullInputFile}' to '${FullCutFile}'."
def command = ('cscript.exe //nologo "C:\\Program Files (x86)\\VideoReDoTVSuite4\\vp.vbs " "' + FullInputFile + '" "' + FullCutFile + '" "/p:H.264 Transport Stream" /q /e')
println "full cut 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!"
}

//relink ExternalID to new file

if(!Settings.TEST_MODE) { // Are we running test mode, if not do this
     if(!Utility.IsFilePath(src)) {
       println "${src} does not exist!"
       return 1
    }

    if(MediaFileAPI.GetMediaFileForFilePath(new File(src)) != null) {
       println "${src} is already a registered SageTV media file!"
       return 1
    }

    def show = ShowAPI.GetShowForExternalID(sid)
    if(show == null) {
       println "ShowEID ${sid} is invalid!"
       return 1
    }

    def mfadd = MediaFileAPI.AddMediaFile(new File(src), null)
    if(mfadd == null) {
       println "Failed to add media file!"
       return 1
    }
    
    if(!MediaFileAPI.SetMediaFileShow(mfadd, show)) {
       println "Failed to link show metadata to media file!"
       return 1
    }

    MediaFileAPI.SetMediaFileMetadata(mf, 'TASK_Status', 'CUT_DONE')
    println "TASK_Status set to '(MediaFileAPI.GetMediaFileMetadata(mf, 'TASK_Status')'"

    MediaFileAPI.MoveTVFileOutOfLibrary(mfadd)
    println "Imported '${src}' and linked it to ShowEID '${sid}'!"
    // Let's set TASK_Status.

} else {  // if we are in test mode do this
 //      println "Would have relinked the showID '${sid}' to the new file '${src}' if test mode were disabled!"
}
    
// Let's delete the original files since that was successful

if(!Settings.TEST_MODE) { // Are we running test mode, if not do this
    Utility.DirectoryListing(Origdir2).each {
        if(FilenameUtils.wildcardMatchOnSystem(it.getName(), "${Prefix}.*")) {
            def fileName = new File(Origdir2, base + (it.getName().substring(it.getName().indexOf('.'))))
                try {
                    fileName.delete()
                }  catch(IOException e) {
                   e.printStackTrace()
                }
        }
    }
} else {  // if we are in test mode do this
    println "Would delete ${Prefix}.* if test mode were disabled!"
}
return 0
Attached Images
File Type: png latest error.png (232.4 KB, 155 views)
Reply With Quote
  #725  
Old 04-19-2011, 05:28 PM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
Remote objects, which are any Sage API objects when running Groovy scripts in SJQ, only live for 3 minutes by default.

The exe you're running (VideoRedo) presumably runs longer than that so when it's done, the object references you have are no longer valid.

The best fix is to reinitialize all your Sage objects after any long process completes. So reinitialize your mf var (and any other vars that were grabbed before the exe was started) after VideoRedo is done. Make 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...
Reply With Quote
  #726  
Old 04-19-2011, 05:49 PM
bikesquid's Avatar
bikesquid bikesquid is offline
Sage Aficionado
 
Join Date: Jan 2010
Location: California's North Coast
Posts: 392
Quote:
Originally Posted by Slugger View Post
Make sense?
Yup, sure do. Question: is this as simple as doing a copy/paste below the exec of any "def = " needed beyond the 3min mark or will I be getting a lot of variable already exists?...
I ask because at the moment I have nothing to test with...
cheers.
Reply With Quote
  #727  
Old 04-19-2011, 06:41 PM
Korny Korny is offline
Sage Advanced User
 
Join Date: Nov 2010
Location: Minnesota
Posts: 87
Uggg I hate being a noob, and I REALLY hate nested quotations marks
I'm using option #2 because my bash script is basically complete.
I've tried various places for quotations my latest
if(!Tools.setExeArgs(" $fileName '$showTitle' '$episode' " ))
so lets say I feed it American Dad show title
and Frannie 911 as an episode, because there are spaces I need quotations marks in the arguement. The problem I'm having is the quotation marks are not disappearing so the file is called "American Dad".Frannie 911".mkv, so the spacing is correct but its like there is a second set of quotation marks. If I take the single quotes then I get American.Dad.mkv which is a result of the script using American is arguement 2 and Dad as arguement 3

I'm learning slowly but blah, I miss TI 85 programing




Quote:
Originally Posted by Slugger View Post
When you queue up a task based on a media file object, SJQ only sets environment variables for the media file and nothing else.

See this document:

http://code.google.com/p/sagetv-addo...i/Sjq4Metadata

Have a look at the section for "Media File". Those are the only vars provide when a media file is queued. So this is why the $SJQ4_PATH and $SJQ4_LAST_SEGMENT expand, but the others do not.

You have a few choices to address this:

1) Instead of calling a bash script and trying to pass command line arguments, write a groovy script to do your task. With a groovy script, you can simply load the MediaFile object and then grab any and all metadata about it within your script.

Code:
import org.apache.commons.io.FileUtils

def mediaFile = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA['SJQ4_ID'].toInteger())

def fileName = "${SJQ4_METADATA['SJQ4_PATH']}/${SJQ4_METADATA['SJQ4_LAST_SEGMENT']}"
def showTitle = MediaFileAPI.GetMediaTitle(mediaFile)
def episode = ShowAPI.GetShowEpisode(mediaFile)

try {
   FileUtils.copyFile(new File(fileName), new File("/media/Array1/needsprocess/$showTitle $episode.mkv")
} catch(IOException e) {
   e.printStackTrace()
   return 1 // Copy failed
}

return 0
Really, you should be doing some error checking and some other things like stripping invalid characters from the file name, etc., but I'll assume you're doing that and just simplified your code for the sake of brevity on the forums (as I have done with my example groovy script).

2) Call a test groovy script and use it to modify the command line args to the bash script. You'd basically do the same thing as above, but instead of actually doing the file copy, just modify the exe's arguments by using Tools.setExeArgs()

3) Access the values you desire in bash via wget calls to the Sage HTTP remote APIs. Those vars I linked to above are env vars in your bash scripts so you could make an API call via wget to access the additional data you want.

The point here is that if you want to access values other than those provided, you have to somehow do it via a Sage API call. I prefer #1, but any of the methods discussed are valid.

Happy scripting!
__________________
Intel I7 4790k @ stock speeds, 32 GB of ram. 8TB of recording space.
Reply With Quote
  #728  
Old 04-19-2011, 07:07 PM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
Quote:
Originally Posted by bikesquid View Post
Yup, sure do. Question: is this as simple as doing a copy/paste below the exec of any "def = " needed beyond the 3min mark or will I be getting a lot of variable already exists?...
I ask because at the moment I have nothing to test with...
cheers.
Yes, and you can do ones that already exist, it doesn't matter. But you only need to do it for Sage objects (typically MediaFileAPI.GetMediaFileForID()).
__________________
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...
Reply With Quote
  #729  
Old 04-19-2011, 07:22 PM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
Quote:
Originally Posted by Korny View Post
Uggg I hate being a noob, and I REALLY hate nested quotations marks
I'm using option #2 because my bash script is basically complete.
I've tried various places for quotations my latest
if(!Tools.setExeArgs(" $fileName '$showTitle' '$episode' " ))
so lets say I feed it American Dad show title
and Frannie 911 as an episode, because there are spaces I need quotations marks in the arguement. The problem I'm having is the quotation marks are not disappearing so the file is called "American Dad".Frannie 911".mkv, so the spacing is correct but its like there is a second set of quotation marks. If I take the single quotes then I get American.Dad.mkv which is a result of the script using American is arguement 2 and Dad as arguement 3

I'm learning slowly but blah, I miss TI 85 programing
Double quote everything... that's the safest way.

if(!Tools.setExeArgs("\"$fileName\" \"$showTitle\" \"$episode\""))

If that's not working then open a ticket and I'll have to do some testing on Linux to try and reproduce you're results and then fix it.
__________________
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...
Reply With Quote
  #730  
Old 04-20-2011, 07:19 AM
gdippel gdippel is offline
Sage Aficionado
 
Join Date: Oct 2003
Location: Bayside, New York
Posts: 301
Quote:
Originally Posted by Slugger View Post
This week's Groovy addition is my implementation of full SageTV backups.

Follow this wiki doc for details on how to set it all up. This is an advanced configuration for advanced SJQv4 users. The task must run on a standalone task client (or outside of SJQv4 altogether). You cannot run this task from the SageTV plugin version of the task client (because part of the process is to shutdown SageTV, more details in wiki).

Basically, when you set it all up, you get the following:

An SJQv4 task capable of determining when it's "safe" to stop SageTV and perform a full backup of the SageTV application folder then restart SageTV. See the wiki doc and the scripts for more details.

Happy scripting!
When I run the backup script (in test mode) via Sagegroovy, I get the following error messages:


unable to resolve class org.apache.commons.io.FilenameUtils
at line: 77, column: 1

unable to resolve class org.apache.commons.io.FileUtils
at line: 76, column: 1

I'm running Sagegroovy on the same server as SageTV. Is there something I need to install?
Reply With Quote
  #731  
Old 04-20-2011, 11:19 AM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
Quote:
Originally Posted by gdippel View Post
When I run the backup script (in test mode) via Sagegroovy, I get the following error messages:


unable to resolve class org.apache.commons.io.FilenameUtils
at line: 77, column: 1

unable to resolve class org.apache.commons.io.FileUtils
at line: 76, column: 1

I'm running Sagegroovy on the same server as SageTV. Is there something I need to install?
Are you running the latest SageGroovy build (4.0.0.1482.0)? If not, upgrade or install the commons-io jar file into the lib dir of your SageGroovy install (and restart SageGroovy).
__________________
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...
Reply With Quote
  #732  
Old 04-20-2011, 11:31 AM
bikesquid's Avatar
bikesquid bikesquid is offline
Sage Aficionado
 
Join Date: Jan 2010
Location: California's North Coast
Posts: 392
ok, so I've relinked mf to the MediaFileAPI, and in one script that corrects the problem, but in another (running handbrake) when I try to relink the metadata to the 'new' file I'm having a little problem with the ShowAPI.GetShowExternalID(mf) returning null.... Any suggestions on how to address? The script is as follows:
Code:
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
}

// Let's set TASK_Status to 'running'.
MediaFileAPI.SetMediaFileMetadata(mf, 'TASK_Status', 'HandBrake_RUNNING')


def title = ShowAPI.GetShowTitle(mf)
def Prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath())
def Origfile = new File(Prefix + ".ts")
def Outputfile = new File(Prefix + ".mkv")
def Origdir = ((MediaFileAPI.GetParentDirectory(mf).toString()) + "\\")
def Origdir2 = (MediaFileAPI.GetParentDirectory(mf))
def base = FilenameUtils.getBaseName(Origfile.getName())
def OrigExt = ("." + FilenameUtils.getExtension(Origfile.getName()))
def CutExt = ".ts"
def OutputExt = ".mkv"
def OutputDir = "D:\\Process_TV\\com_free\\handbrake\\"
def FullInputFile = "D:\\Process_TV\\com_free\\" + Origfile
// def FullInputFile = Origdir + Origfile
def FullOutputFile = OutputDir + Outputfile
println FullOutputFile

   
// Let's also skip it if it's from a channel known not to have commercials (adjust the regex accordingly)
if(AiringAPI.GetAiringChannelName(mf) =~ /HBO.*|SPEED.*/){
    FileUtils.copyFile(FullInputFile, new File(OutputDir, Origfile))
    return 1
}


// Shrink-i-dink with HandBrake
def i = 1
def file = new File(FullOutputFile)
while(file.exists())
    file = new File(OutputDir, "$base-${i++}$CutExt")
println "New file is: $file"
FullOutputFile = file

println "Shrinking '${FullInputFile}' to '${FullOutputFile}'."
def command = """C:\\Program Files (x86)\\Handbrake\\HandBrakeCLI.exe""" + """ -i "${FullInputFile}" -o "${FullOutputFile}" -f mkv -q 0.86 -x ref=3:mixed-refs=2:bframes=3:b-pyramid=1:b-rdo=1:bime=1:weightb=1:subme=6:trellis=1:analyse=all:8x8dct=1:vbv-maxrate=25000 -5 -E ac3 -6 none"""
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!"
}

//relink ExternalID to new file

if(!Settings.TEST_MODE) { // Are we running test mode, if not do this

    mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger())

    def src = (FullOutputFile.toString())
    println "fullpathfile is=$src"

    def sid = ShowAPI.GetShowExternalID(mf)
    println "ExternalID is ${sid}"


    if(!Utility.IsFilePath(src)) {
       println "${src} does not exist!"
       return 1
    }

    if(MediaFileAPI.GetMediaFileForFilePath(new File(src)) != null) {
       println "${src} is already a registered SageTV media file!"
       return 1
    }

    def show = ShowAPI.GetShowForExternalID(sid)
    if(show == null) {
       println "ShowEID ${sid} is invalid!"
       return 1
    }

    def mfadd = MediaFileAPI.AddMediaFile(new File(src), null)
    if(mfadd == null) {
       println "Failed to add media file!"
       return 1
    }
    
    if(!MediaFileAPI.SetMediaFileShow(mfadd, show)) {
       println "Failed to link show metadata to media file!"
       return 1
    }

    MediaFileAPI.MoveTVFileOutOfLibrary(mfadd)
    println "Imported '${src}' and linked it to ShowEID '${sid}'!"

    def fileName = new File(Origdir2, base + ".ts")
    fileName.delete()

    MediaFileAPI.SetMediaFileMetadata(mf, 'TASK_Status', 'HandBrake_DONE')
    return 0
Reply With Quote
  #733  
Old 04-20-2011, 12:39 PM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
Are you replacing the recorded file with the new mkv? If so, the Sage API is probably returning null because the underlying video file no longer exists when you try to reinit the variable. If that's the case, then instead of reinitializing the Sage object after the process completes, grab whatever metadata you need from it ahead of time and then just use those vars as needed.
__________________
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...
Reply With Quote
  #734  
Old 04-20-2011, 01:04 PM
bikesquid's Avatar
bikesquid bikesquid is offline
Sage Aficionado
 
Join Date: Jan 2010
Location: California's North Coast
Posts: 392
Quote:
Originally Posted by Slugger View Post
Are you replacing the recorded file with the new mkv? If so, the Sage API is probably returning null because the underlying video file no longer exists when you try to reinit the variable. If that's the case, then instead of reinitializing the Sage object after the process completes, grab whatever metadata you need from it ahead of time and then just use those vars as needed.
I'm not 'replacing' exactly... I'm creating the .mkv while the .ts still exists, then I'm relinking the externalID (in theory) before deleting the input file.... So, the input file still exists until the last couple lines, well below the null return. I suppose in the end I'm 'done' when the handbrake process is complete so I could just delete the input file rather than relink the external ID.

I'll try bypassing the error by just doing the delete instead but I'm really trying to understand why the externalID would be invalid given the original file exists and mf has been redefined....

For me the 'why' is always helpful.
Thanks again!
Reply With Quote
  #735  
Old 04-20-2011, 01:11 PM
gdippel gdippel is offline
Sage Aficionado
 
Join Date: Oct 2003
Location: Bayside, New York
Posts: 301
Quote:
Originally Posted by Slugger View Post
Are you running the latest SageGroovy build (4.0.0.1482.0)? If not, upgrade or install the commons-io jar file into the lib dir of your SageGroovy install (and restart SageGroovy).
I upgraded Sagegroovy, now it works, thanks.
Reply With Quote
  #736  
Old 04-20-2011, 03:05 PM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
Quote:
Originally Posted by bikesquid View Post
I'm not 'replacing' exactly... I'm creating the .mkv while the .ts still exists, then I'm relinking the externalID (in theory) before deleting the input file.... So, the input file still exists until the last couple lines, well below the null return. I suppose in the end I'm 'done' when the handbrake process is complete so I could just delete the input file rather than relink the external ID.

I'll try bypassing the error by just doing the delete instead but I'm really trying to understand why the externalID would be invalid given the original file exists and mf has been redefined....

For me the 'why' is always helpful.
Thanks again!
If it's always returning null then something's wrong. Is the mf null when you try to reinitialize it? You're going to have to println a lot of debug statements to try and track down exactly which line is failing. I can't see anything wrong with the script so you'll have to start debugging.

I agree, the 'why' is always nice to figure out. If nothing else, it provides peace of mind.
__________________
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...
Reply With Quote
  #737  
Old 04-21-2011, 05:37 PM
bikesquid's Avatar
bikesquid bikesquid is offline
Sage Aficionado
 
Join Date: Jan 2010
Location: California's North Coast
Posts: 392
Quote:
Originally Posted by Slugger View Post
If it's always returning null then something's wrong. Is the mf null when you try to reinitialize it? You're going to have to println a lot of debug statements to try and track down exactly which line is failing. I can't see anything wrong with the script so you'll have to start debugging.

I agree, the 'why' is always nice to figure out. If nothing else, it provides peace of mind.
mf is in fact returning null on reinit. But not in sagegroovy....

Output from Sagegroovy:
Code:
Rip done!
HandBrake has exited.

mf is RemoteObjectRef[29364672];
fullpathfile is=D:\Process_TV\com_free\handbrake\MythBusters - S08E03.mkv
ExternalID is EP5576780291
Imported 'D:\Process_TV\com_free\handbrake\MythBusters - S08E03.mkv' and linked it to ShowEID 'EP5576780291'!
\\Sage-pc\Mirror_Set\Process_TV\com_free\MythBusters - S08E03.ts
Output from Sage UI:
Code:
Log for Test Script and Executable:
HandBrake has exited.
mf is null
fullpath is=D:\Process _TV\com_free\handbrake\Motorcycle Racing - FIM World Supersport Europe.mkv
ExternalID is
ShowEID is invalid!
Reply With Quote
  #738  
Old 04-21-2011, 08:09 PM
Slugger Slugger is offline
SageTVaholic
 
Join Date: Mar 2007
Location: Kingston, ON
Posts: 4,008
Look in the sagex-api.log file and see if there's any errors when the script runs from SJQ vs. SageGroovy. I definitely have no answer as to why it returns null from SJQ and not in SageGroovy. Hopefully the sagex-api logs provide an answer.
__________________
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...
Reply With Quote
  #739  
Old 04-22-2011, 12:57 PM
bikesquid's Avatar
bikesquid bikesquid is offline
Sage Aficionado
 
Join Date: Jan 2010
Location: California's North Coast
Posts: 392
Quote:
Originally Posted by Slugger View Post
Look in the sagex-api.log file
The log only seems to show the latest minute or so... looking in 'sagetv/logs' I assume that's the right place?
As a part of testing, I just did println statements for all the def commands at the top of the script and they all print the 'correct' data, but when mf is reassigned on the next line it's coming back null....

Interesting info in sjq.log however - excerpt of offending time attached along with the screen capture of the ui log info showing the println of mf and reassignment as null....
just to be complete, here's the code again:
Code:
// def SJQ4_METADATA = ["SJQ4_ID":"4677970", "SJQ4_TYPE":"MediaFile"]

// 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
}

// Let's set TASK_Status to 'running'.
MediaFileAPI.SetMediaFileMetadata(mf, 'TASK_Status', 'HandBrake_RUNNING')


def title = ShowAPI.GetShowTitle(mf)
def Prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath())
def Origfile = new File(Prefix + ".ts")
def Outputfile = new File(Prefix + ".mkv")
def Origdir = ((MediaFileAPI.GetParentDirectory(mf).toString()) + "\\")
def Origdir2 = (MediaFileAPI.GetParentDirectory(mf))
def base = FilenameUtils.getBaseName(Origfile.getName())
def OrigExt = ("." + FilenameUtils.getExtension(Origfile.getName()))
def CutExt = ".ts"
def OutputExt = ".mkv"
def OutputDir = "D:\\Process_TV\\com_free\\handbrake\\"
def FullInputFile = "D:\\Process_TV\\com_free\\" + Origfile
def FullOutputFile = OutputDir + Outputfile
   
// Let's also skip it if it's from a channel known not to have commercials (adjust the regex accordingly)
if(AiringAPI.GetAiringChannelName(mf) =~ /HBO.*|SPEED.*/){
    FileUtils.copyFile(FullInputFile, new File(OutputDir, Origfile))
    return 1
}


// Shrink-i-dink with HandBrake
def i = 1
def file = new File(FullOutputFile)
while(file.exists())
    file = new File(OutputDir, "$base-${i++}$CutExt")
    FullOutputFile = file

def command = """C:\\Program Files (x86)\\Handbrake\\HandBrakeCLI.exe""" + """ -i "${FullInputFile}" -o "${FullOutputFile}" -f mkv -q 0.86 -x ref=3:mixed-refs=2:bframes=3:b-pyramid=1:b-rdo=1:bime=1:weightb=1:subme=6:trellis=1:analyse=all:8x8dct=1:vbv-maxrate=25000 -5 -E ac3 -6 none"""
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!"
}

//relink ExternalID to new file

if(!Settings.TEST_MODE) { // Are we running test mode, if not do this


println "title '${title}'"
println "Prefix '${Prefix}'" //= FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath())
println "Origfile '${Origfile}'" //= new File(Prefix + ".ts")
println "Outputfile '${Outputfile}'"  //= new File(Prefix + ".mkv")
println "Origdir '${Origdir}'"//= ((MediaFileAPI.GetParentDirectory(mf).toString()) + "\\")
println "Origdir2 '${Origdir2}'" //= (MediaFileAPI.GetParentDirectory(mf))
println "base '${base}'"//= FilenameUtils.getBaseName(Origfile.getName())
println "OrigExt '${OrigExt}'"//= ("." + FilenameUtils.getExtension(Origfile.getName()))
println "CutExt '${CutExt}'"//= ".ts"
println "OutputExt '${OutputExt}'"//= ".mkv"
println "OutputDir '${OutputDir}'"//= "D:\\Process_TV\\com_free\\handbrake\\"
println "FullInputFile '${FullInputFile}'"//= "D:\\Process_TV\\com_free\\" + Origfile
println "FullOutputFile '${FullOutputFile}'"// = OutputDir + Outputfile
println "mf '${mf}'"
    mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger())
    println "mf is ${mf}"

    MediaFileAPI.SetMediaFileMetadata(mf, 'TASK_Status', 'HandBrake_DONE')

    def src = (FullOutputFile.toString())
    println "fullpathfile is=$src"

    def sid = ShowAPI.GetShowExternalID(mf)
    println "ExternalID is ${sid}"


    if(!Utility.IsFilePath(src)) {
       println "${src} does not exist!"
       return 1
    }

    if(MediaFileAPI.GetMediaFileForFilePath(new File(src)) != null) {
       println "${src} is already a registered SageTV media file!"
       return 1
    }

    def show = ShowAPI.GetShowForExternalID(sid)
    if(show == null) {
       println "ShowEID ${sid} is invalid!"
       return 1
    }

    def mfadd = MediaFileAPI.AddMediaFile(new File(src), null)
    if(mfadd == null) {
       println "Failed to add media file!"
       return 1
    }
    
    if(!MediaFileAPI.SetMediaFileShow(mfadd, show)) {
       println "Failed to link show metadata to media file!"
       return 1
    }

    MediaFileAPI.MoveTVFileOutOfLibrary(mfadd)
    println "Imported '${src}' and linked it to ShowEID '${sid}'!"

    Prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath())
    Origfile = new File(Prefix + ".ts")
    Origdir2 = (MediaFileAPI.GetParentDirectory(mf))
    base = FilenameUtils.getBaseName(Origfile.getName())

    def fileName = new File(Origdir2, base + ".ts")
    println fileName
    fileName.delete()

    return 0

} else {  // if we are in test mode do this
       println "Would do a bunch of shit if test mode were disabled!"
}
Attached Images
File Type: png mfnull_log.png (323.9 KB, 149 views)
Attached Files
File Type: txt sjq.log.txt (118.4 KB, 131 views)
Reply With Quote
  #740  
Old 04-22-2011, 01:00 PM
bikesquid's Avatar
bikesquid bikesquid is offline
Sage Aficionado
 
Join Date: Jan 2010
Location: California's North Coast
Posts: 392
Forgot to mention, when run as a direct assignment of job it seems to complete fine, when assigned via mediascan script and waiting for the cut script to complete, that's when it seems to die. Here are the media scan and cut scripts for the sake of completeness....
Attached Files
File Type: txt cut.groovy.txt (4.4 KB, 118 views)
File Type: txt media_file_scanner.groovy.txt (3.7 KB, 116 views)
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

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


All times are GMT -6. The time now is 10:36 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.
Copyright 2003-2005 SageTV, LLC. All rights reserved.