|
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 |
#1481
|
||||
|
||||
Quote:
(...and I might steal your script ) |
#1482
|
|||
|
|||
Cannot delete file using SageAPI
I have occasionally received an error when I try to use the command: "MediaFileAPI.DeleteFile(mf)". What I am doing is using Handbrake to transcode s SageTV recording file from MPEG-2 (or h.264 TS) to h.264 mp4 using handbrake. After using Handbrake I try to delete the file and I get an error.
Here is the error that I get: Code:
Got an Error from the remote side: 404; Command Failed: DeleteFile ========== Remote Stack Dump =========== java.lang.RuntimeException: Invalid Object Reference: 2231765; It may be that the reference has been cleaned up. at sagex.remote.AbstractRPCHandler.getReference(AbstractRPCHandler.java:180) at sagex.remote.AbstractRPCHandler.handleRPCCall(AbstractRPCHandler.java:77) at sagex.remote.rmi.SageRemoteCommandImpl.executeCommand(SageRemoteCommandImpl.java:36) at sun.reflect.GeneratedMethodAccessor177.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Unknown Source) at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.RuntimeException: No object reference for 2231765 at sagex.remote.AbstractRPCHandler.getReference(AbstractRPCHandler.java:175) ... 16 more Result: [RemoteObjectRef[2231765:198];] It is possible that for some reason the Mediafile object number is changing as when I ran this procedure again on the same file it referred to an object number of 4946671 rather than 2231765.
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#1483
|
|||
|
|||
Quote:
All you need to do is call MediaFileAPI.GetMediaFileForID() again (or which ever call you used to create the obj reference) in order to get a new reference to the object then the call to DeleteFile() should succeed.
__________________
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... |
#1484
|
||||
|
||||
Quote:
I use the following which relinks, then cleans up the original file and then clears any cling-ons from various processes associated with the original: Code:
//relink ExternalID to new file // the three minute rule applies, so reinit this variable. mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) // Delete the CUT file MediaFileAPI.DeleteFile(mf) // Delete any flac associated with the CUT file Utility.DirectoryListing(new File(CutDir)).each { if(FilenameUtils.wildcardMatchOnSystem(it.getName(), "${Prefix}.*")) { def fileName = new File(CutDir, Prefix + (it.getName().substring(it.getName().indexOf('.')))) try { fileName.delete() } catch(IOException e) { e.printStackTrace() } } } |
#1485
|
|||
|
|||
Quote:
In one of the routines where I am having this issue I am using an each loop to iterate through a list. So the mediafile variable mf is not defined by an SJQ variable like bikesquid's example but by setting mf=it. So can I just make this call once again before the delete command, put another mf=it? Or will the Remote Object References in the list no longer be valid? I would think that somehow the References are still valid since I am currently looping through about 20 files. Each file takes about 2 minutes to transcode and I am not getting any issues, unless the file is larger and I hit the three minute threshold. Here is how I create my list (this creates a list of all Mediafiles that are from Children's shows that have "Einsteins" in the title that are in a folder with TV in the name): Code:
FileList =MediaFileAPI.GetMediaFiles('T') ShowList2=FileList.findAll{ShowAPI.GetShowTitle(it).contains("Einsteins")} ShowList1=ShowList2.findAll{ShowAPI.GetShowCategoriesList(it).toString().contains("Children")} ShowList3=ShowList1.findAll{MediaFileAPI.GetFileForSegment(it,0).toString().contains("tv")} ShowList.each { mf = it ... }
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#1486
|
|||
|
|||
Yeah just call the same init code again to reinit the objects and then you should be fine.
__________________
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... |
#1487
|
|||
|
|||
OK, I am having more issues with this tonight. When I make a list of TV shows matching certain criteria the list contains objectIDs, and looks like this: [RemoteObjectRef[16199930:1888];, RemoteObjectRef[16199930:1928];, RemoteObjectRef[16199930:1932];, RemoteObjectRef[16199930:1939];, RemoteObjectRef[16199930:1951];, RemoteObjectRef[16199930:1955];]
There must be an easy, Groovy way of creating a second list that is the mediafile IDs of that list. So if the original list is List1 how do I make List2 that is a list of all of the Mediafile IDs of List1 or something like this List2=MediaFileAPI.GetMediaFileID(List1). I can't even figure out how to do this the brute force way by looping through List1 and appending each element onto List2.
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#1488
|
|||
|
|||
OK, so I think this is the brute force way of doing this:
def List2=[] List1.each {List2 << MediaFileAPI.GetMediaFileID(it) } Is that the best way of doing this? And will the identifiers in List2 be permanent or do they expire in 3 mins as well.
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#1489
|
|||
|
|||
Off the top of my head (and untested)...
Code:
def mediaIds = MediaFileAPI.GetMediaFiles('T').findAll { ShowAPI.GetShowTitle(it) == 'Family Guy' }.collect { MediaFileAPI.GetMediaFileID(it) } println mediaIds
__________________
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... Last edited by Slugger; 03-05-2014 at 10:53 PM. Reason: Poor variable name choice originally |
#1490
|
|||
|
|||
Your way would work just fine, I think mine would be considered the "more groovy" way to do it. Either should end in the same result though.
Edit: Yes the list of media file id numbers is "permanent" (well they don't expire like RemoteObjectRefs do). If something else deletes those media files in Sage in the meantime then the id number is no longer valid, but they don't "timeout" so to speak.
__________________
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... Last edited by Slugger; 03-05-2014 at 10:54 PM. Reason: Gee, I really need to go to bed. ;) |
#1491
|
|||
|
|||
Yes, they both work but yours is Groovier! And the IDs in this list will be permanent, and not expire in 3 mins?
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#1492
|
|||
|
|||
Correct. See my edits above.
__________________
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... |
#1493
|
|||
|
|||
I don't know if anyone has posted about this but here is another way to get your Groovy fix - there is an online Groovy Web Console at http://groovyconsole.appspot.com/
You can test out your code here - even on mobile devices. Although I don't imagine that Sage specific APIs will work.
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#1494
|
||||
|
||||
Noticed that my e-mails from the Groovy Scripts have stopped coming.
How would I go about debugging it? Wondering if TWC/RR made some change so it is rejecting the e-mails now. I use similar script for other e-mails. Last e-mail I got was on 3/5/2014 I get in the log the following [mail] Failed to send email: 500 5.5.2 unrecognized command premires.groovy Code:
/* Receive email alerts for premieres found in the EPG Last Modified: 19 Sep 2011 Author: Derek Battams <derek AT battams DOT ca> This script will scan the EPG and send you an email with all premieres for the current day. I suggest running this once a day from the SJQv4 crontab to get an email alert for the day's premieres. YOU MUST CHANGE THE EMAIL SETTINGS BELOW OR YOU WON'T RECEIVE THE EMAIL ALERTS! */ import static java.util.Calendar.* private class EmailSettings { static def sendMail = true // Set this to false to just dump the alert msg to stdout instead of emailing it static def host = 'smtp-server.carolina.rr.com' static def user = 'made up e-mail for my mailbox rules to use' static def pwd = '' static def port = '25' static def subj = 'SAGETV - Today\'s PrimeTime Premieres' static def from = user // Gmail will reject mail via SMTP if the from addr != user id so no point in changing this static def to = 'to@my.email' // Sometimes Gmail won't send an email addressed to yourself, try a plus address at the end; YMMV static def ssl = 'false' // Gmail requires SSL, other SMTP servers may or may not; this is a STRING setting! } def shows = new HashSet<String>() def midnight = new Date() midnight.set(hourOfDay: 0, minute: 0, second: 0, millisecond: 0) midnight[MILLISECOND] = 0 midnight = midnight.getTime() def msg = new StringBuilder() Database.SearchSelectedFields('Premiere', false, false, false, false, false, false, false, false, false, true, 'T').each { def id = ShowAPI.GetShowExternalID(it) def start = AiringAPI.GetAiringStartTime(it) if(shows.add(id) && id.startsWith('EP') && start >= midnight + 71900000 && start < midnight + 94500000) { msg.append("${ShowAPI.GetShowTitle(it)}") def ep = ShowAPI.GetShowEpisode(it) if(ep) msg.append(": $ep") msg.append(" (${AiringAPI.GetAiringChannelName(it)}/${AiringAPI.GetAiringChannelNumber(it)} ${ShowAPI.GetShowExternalID(it)})\n") def desc = ShowAPI.GetShowDescription(it) if(desc) msg.append("${ShowAPI.GetShowDescription(it)}\n") msg.append('\n') } } if(msg.toString()) { if(EmailSettings.sendMail) sendMail(msg.toString()) else println msg.toString() } return 0 def sendMail(def msg) { def ant = new AntBuilder() ant.mail(mailhost: EmailSettings.host, mailport: EmailSettings.port, subject: EmailSettings.subj, user: EmailSettings.user, password: EmailSettings.pwd, ssl: EmailSettings.ssl) { from(address: EmailSettings.from) to(address: EmailSettings.to) message(msg) } } |
#1495
|
|||
|
|||
Quote:
You can try this to get a little more output as to the error (maybe): In the script right after the line: Code:
def ant = new AntBuilder() Code:
ant.project.getBuildListeners().firstElement().setMessageOutputLevel(4)
__________________
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... |
#1496
|
||||
|
||||
Got it working again. Had to add authentication to the groovy scripts.
Strange that Outlook isn't needing it and my non-TWC e-mails are still sending fine. Oh well, something to remember and change in my other scripts |
#1497
|
|||
|
|||
My Daily Report
Here is some code for folks to play with, if they like. This is my Daily Report which I run via a SJQv4 cron job at 12:01am every day that emails the output to my gmail account (so the email stuff is set up for gmail). The report sends out a list of all shows to be recorded that day and it also reports on the free space on all media hard drives, place your Sage system drive.
The report provide hyperlinks to your Sage Web pages to facilitate making changes to recordings so you need to set up the proper URLs for your system - I have replaced my URL with mickeymouse in this example. The report looks like this: Quote:
Code:
/* Daily Email for Sage Recordings Last Modified: 14 Jan 2012 Author: Wayner although I steal most of the code from... Derek Battams <derek AT battams DOT ca> Run this script daily to produce a report of the day's upcoming recordings. Each show includes a link to the web interface, which will allow you to record the airing, if so desired. This script requires SRE as it notes if SRE is monitoring the recording. If running from the SageGroovy environment make sure to copy all SRE JAR files to the Sagegroovy/lib folder. I set this to email at 12:01 every morning. You MUST change the settings below, especially the email settings if you want this script to email the output. The script is written for the SJQv4 environment and expects it is running in that environment. */ import com.google.code.sagetvaddons.sre.engine.DataStore import org.apache.commons.io.FileUtils import sagex.api.* def BASE_URL = 'http://mickeymouse.dyndns.org:8080/sage' // Base URL to your web interface, with NO trailing slash def sageweburl = BASE_URL+'/Home' // This is where the Sage Web home page resides def sagemobweburl= 'http://mickeymouse.dyndns.org:8080/sagem/m/menu.js' // Same for the Sage mobile web page class EmailSettings { static def sendMail = true // Set this to false to just dump the alert msg to stdout instead of emailing it static def host = 'smtp.gmail.com' static def user = 'mickey.mouse@gmail.com' static def pwd = 'iluvminnie' static def port = '465' static def subj = 'Sage Recordings for Today' static def from = user // Gmail will reject mail via SMTP if the from addr != user id so no point in changing this static def to = 'mickey.mouse@gmail.com' // Sometimes Gmail won't send an email addressed to yourself, try a plus address at the end; YMMV static def ssl = 'true' // Gmail requires SSL, other SMTP servers may or may not; this is a STRING setting! } def sendMail(def msg) { def ant = new AntBuilder() ant.mail(mailhost: EmailSettings.host, mailport: EmailSettings.port, subject: EmailSettings.subj, user: EmailSettings.user, password: EmailSettings.pwd, ssl: "true") { from(address: EmailSettings.from) to(address: EmailSettings.to) message(msg) } } def start = new Date() start[Calendar.HOUR_OF_DAY] = 0 start[Calendar.MINUTE] = 0 start[Calendar.SECOND] = 0 def end = new Date(start.getTime() + 1L*1000L *3600L * 24L) // 1 day * 1000ms/s * 3600s/hr * 24hr/day def shows = new HashSet() def airings = [] airings=Global.GetScheduledRecordingsForTime(start.getTime(), end.getTime()) def datastore = DataStore.getInstance() def msg = new StringBuilder() StartTime=start.format('EEEE MMM d hh:mm a') EndTime=end.format('EEEE MMM d hh:mm a') msg <<"TV Recording Schedule for: $StartTime to $EndTime\n" msg <<"---------------------------------------------------------------------------------------------------\n" airings.each { msg << "${new Date(AiringAPI.GetAiringStartTime(it)).format('hh:mma')} to ${new Date(AiringAPI.GetAiringEndTime(it)).format('hh:mma')}\n" msg << "${ShowAPI.GetShowTitle(it)} - " SRE1 = datastore.getMonitorStatusByObj(it) SRE = SRE1.toString() if (SRE == "NO_MONITOR") { msg << "${ShowAPI.GetShowEpisode(it)}\n"} else { msg << "${ShowAPI.GetShowEpisode(it)} - SRE is monitoring\n"} msg << "The show is airing on ${AiringAPI.GetAiringChannelName(it)}\n" msg << "${BASE_URL}/DetailedInfo?AiringId=${AiringAPI.GetAiringID(it)}\n\n" } msg <<"---------------------------------------------------------------------------------------------------\n" lobsdbThreshold=50 //this number is in MB to trigger a warning SageTVPath=Utility.GetWorkingDirectory() FreeSpace=(Utility.GetDiskFreeSpace(SageTVPath)/1e9).toFloat().round(1) msg << "SageTV is located at: $SageTVPath\n\n" msg << "Free Space on System drive is: $FreeSpace GB\n\n" msg << "Free space for TV Drives is:\n\n" Configuration.GetVideoDirectories().each { PathString=it.toString() FreeSpace=(Utility.GetDiskFreeSpace(PathString)/1e9).toFloat().round(1) msg << "$PathString Freee space is $FreeSpace GB\n\n" } msg << "Free space for Video Library Drives is:\n\n" Configuration.GetVideoLibraryImportPaths().each { PathString=it.toString() FreeSpace=(Utility.GetDiskFreeSpace(PathString)/1e9).toFloat().round(1) msg << "$PathString Freee space is $FreeSpace GB\n\n" } lobsDir=new File (SageTVPath+"\\.lobs.db") if (lobsDir.exists()) { lobsDirSize= (FileUtils.sizeOfDirectory(lobsDir)/1000000).toFloat().round(1) if( lobsDirSize > lobsdbThreshold) { msg << "Error******************************\r\nlobs.db folder is getting too big!\n\n" } msg << ".lobs.db folder is located at $lobsDir and size is $lobsDirSize MB\n\n" } msg << "To edit go to: $sageweburl\n" msg << "or for mobile: $sagemobweburl\n" if(EmailSettings.sendMail && msg.toString()) sendMail(msg.toString()) else if(msg.toString()) println msg return 0
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#1498
|
||||
|
||||
I have been searching for a better way to comskip on my setup. I came across this file in my searches that looks like exactly what I want to to do with comskip. My problem is that I am not a programmer and nor do I understand the programming language,( I am a school maintenance director by trade ). I tried to make changes to this file and run this file as a bat file thru SJQ4. I do have SJQ4 back installed as I had uninstalled it because of lack of knowledge about the program. I have been trying to make the postprocessing.bat file in comskip work and fire it off with SJQ4 and it does work. But I cannot make the individual ini's for different channels work. So here is another file that I have come across that is exactly what I want to do.
So can anyone point me in the direction of whether this will work in sjq4 or whether this could work as a batch file? I just don't know what kind of file this is and where I would put it. I have modified it to my channels. Thanks to any one that can help Wayne
__________________
New setup 1-22 GIGABYTE B560 HD3 MB | Intel I5 6 core CPU | 500 GB WD SSD system drive | (2) 2TB Western Digital SSD drives pooled | 16 GB DDR ram | UHD 630 on board graphics| Win 10 64 bit | SageTV 9 | (5) Sage HD TV extenders | (1) HDHomeRun quad tuner HD OTA | (1) HDHomeRun Dual tuner HD OTA | (2) 1512 HD-PVR2s recording from 2 Dish Network VIP 211K's with Uirt ir control | MX-700 Home theater remote | 60" LED TV | (4) 32" Lcd TV's Last edited by Doubledose; 04-06-2014 at 06:56 AM. |
#1499
|
|||
|
|||
That attached file won't just work as a batch file, it's groovy code. You could convert that groovy script to a Windows batch file, but given the groovy/java constructs that the script uses, a conversion to batch would not be trivial.
My guess about the inis not working is that it's trying to match the channel names using lowercase letters but I'm pretty sure the channel name is going to be all caps so that script will always run the 'OTHER' ini file or not run comskip at all. Try changing the line towards the top: String channel = AiringAPI.GetAiringChannelName(mediaFile) to String channel = AiringAPI.GetAiringChannelName(mediaFile).toLowerCase() That change should allow the channel names to match.
__________________
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... |
#1500
|
|||
|
|||
Actually, changing the channel name to lower case makes the last else case invalid. If you add the toLowerCase() as suggested, then change this:
} else if(channel !=~ /WANEDT|WPTADT|WISEDT|FOXDT|HBO.*|ACMAXHD|5MAXHD|HDNETMV|MAX.*|MOMAX|STZ.*|ENC.*|SHO.*|TMC.*|PPV.*/) { So that all the letters there are lower case.
__________________
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... |
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 |