As of SageTV 1.2.8 there's 2 interfaces defined in Sage.jar that are relevant, sage.EPGImportPlugin and sage.EPDBPublic, here's their .java definitions: NOTE: This was updated as of V6.0.13 to add the EPGDBPublic.addAiringDetailedPublic method and the Judge/Narrator roles /* * Copyright 2001-2008 SageTV, LLC. All rights reserved. */ package sage; // The plugin class must implement this interface public interface EPGImportPlugin { /* * NOTE: In SageTV V1.2.8 this call is not implemented yet, it will retrieve this list from the SageTV server instead, * but the EPG data will be retrieved using the plugin. It is implemented in V1.3 and higher. * Returns a String[][2] for a given zip code. Each element pair represents a provider GUID & a provider name. * These names will be displayed in the Setup Wizard for SageTV. The provider GUIDs must be valid arguments * for Long.parseLong(providerID), represent positive numbers, and be consistent and unique for given provider. * An example of the return value is: * { { "1", "Test Lineup1"} {"2", "Test Lineup2"} } */ public String[][] getProviders(String zipCode); /* * NOTE: In SageTV V1.2.8 this call is not implemented yet, it will retrieve this list from the SageTV server instead, * but the EPG data will be retrieved using the plugin. It is implemented in V1.3 and higher. * Returns a String[][2]. Each element pair represents a provider ID & a provider name. * These names will be displayed in the Setup Wizard for SageTV if Local Markets are selected * for the provider. The provider GUIDs must be valid arguments * for Long.parseLong(providerID), represent positive numbers, and be consistent and unique for given provider. * An example of the return value is: * { { "3", "Test Local Lineup1"} {"4", "Test Local Lineup2"} } */ public String[][] getLocalMarkets(); /* * This is called daily (or more often if other events occur) to update the EPG database. * It should return true if successful, and false if not. The providerID argument * references the provider selected from the functions above. The EPGDBPublic object * is what is used to make calls to the database to provide it with the new EPG information. * See the documentation on EPGDBPublic for more information */ public boolean updateGuide(String providerID, EPGDBPublic dbInterface); } /* * Copyright 2001-2008 SageTV, LLC. All rights reserved. */ package sage; // This is the callback interface the plugin uses to update the database public interface EPGDBPublic { /* * Call this to add a Channel to the database. This will update if the stationID is already * used. name should be the call sign, like KABC. longName can be a full descriptive name like * "Channel 4 Los Angeles NBC". network represents the parent network, i.e. ABC, HBO, MTV and is * optional. stationID is the GUID referring to this Channel. * * Returns true if the Channel was successfully updated/added to the database. */ public boolean addChannelPublic(String name, String longName, String network, int stationID); /* * Call this with the current providerID, and a map of stationIDs to channel numbers. The keys in the map * should be Integer objects wrapping stationIDs as used in the addChannelPublic method. The values in the map * should be String[] that represent the channel numbers for that station. An example is if ESPN w/ stationdID=34 * is on channel numbers 3 and 94, the map would contain a: Integer(34)->{"3", "94"} */ public void setLineup(long providerID, java.util.Map lineupMap); // The ROLE constants are used in addShowPublic below static final byte ACTOR_ROLE = 1; static final byte LEAD_ACTOR_ROLE = 2; static final byte SUPPORTING_ACTOR_ROLE = 3; static final byte ACTRESS_ROLE = 4; static final byte LEAD_ACTRESS_ROLE = 5; static final byte SUPPORTING_ACTRESS_ROLE = 6; static final byte GUEST_ROLE = 7; static final byte GUEST_STAR_ROLE = 8; static final byte DIRECTOR_ROLE = 9; static final byte PRODUCER_ROLE = 10; static final byte WRITER_ROLE = 11; static final byte CHOREOGRAPHER_ROLE = 12; static final byte SPORTS_FIGURE_ROLE = 13; static final byte COACH_ROLE = 14; static final byte HOST_ROLE = 15; static final byte EXECUTIVE_PRODUCER_ROLE = 16; static final byte JUDGE_ROLE = 20; static final byte NARRATOR_ROLE = 21; /* * Call this to add a Show to the database. If a show with this extID is already present, it will be updated * to this information. You can use null or String[0] for any fields you don't want to specify. * title - the title of the show (use for reruns) * primeTitle - the title of the show (use for first runs) * episodeName - the name of the episode * desc - a description of this show * duration - not used, set to 0 * category - name of a category for this show * subCategory - name of a subCategory for this show * people - names of people/actors in this show * roles - must be same length as people array, uses the X_ROLE constants in this file to specify what each is * rated - rating of a show, i.e. PG, G, R, etc. * expandedRatings - additional rating information, i.e. Violence, Nudity, Adult Content * year - the year it was produced, for movies * parentalRating - not used, set to null * bonus - additional information about the show * extID - GUID representing this show * language - the language the show is in * originalAirDate - the original airing date of this show, it's a long value from java.util.Date * * Returns true if the Show was successfully updated/added to the database. */ public boolean addShowPublic(String title, String primeTitle, String episodeName, String desc, long duration, String category, String subCategory, String[] people, byte[] roles, String rated, String[] expandedRatings, String year, String parentalRating, String[] bonus, String extID, String language, long originalAirDate); /* * Call this to add an Airing to the database. An Airing is time-channel-show correlation. * extID - refers to the GUID of a Show previously added with addShowPublic * stationID - referes to the stationID GUID of a Channel previously added with addChannelPublic * startTime - the time this airing starts, a long from java.util.Date * duration - the length of this airing in milliseconds * * Returns true if this Airing was successfully updated/added to the database. The database will * automatically ensure that there are no inconsistencies in the Airings, if you add one that * overlaps with the station-time-duration of another. The one(s) that were in the database before * the call will be removed and the new one added. It will also fill in any gaps with "No Data" sections * for you automatically. */ public boolean addAiringPublic(String extID, int stationID, long startTime, long duration); /* * Call this to add an Airing to the database. An Airing is time-channel-show correlation. * extID - refers to the GUID of a Show previously added with addShowPublic * stationID - referes to the stationID GUID of a Channel previously added with addChannelPublic * startTime - the time this airing starts, a long from java.util.Date * duration - the length of this airing in milliseconds * partNumber - if it is a multipart show this is the part number, otherwise this should be 0 * totalParts - for multipart TV shows, this is the total number of parts otherwise this should be zero * parentalRating - the parental rating for the show, should be a localized value from "TVY", "TVY7", "TVG", "TVPG", "TV14", "TVM" or the empty string * hdtv - true if it's an HDTV airing, false otherwise * stereo - true if it's a stereo recording, false otherwise * closedCaptioning - true if the airing has closed captioning, false otherwise * sap - true if the Airing has a Secondary Audio Program (SAP), false otherwise * subtitled - true if the Airing is subtitled, false otherwise * premierFinale - should be the empty string or a localized value from the list "Premier", "Channel Premier", "Season Premier", "Series Premier", "Season Finale", "Series Finale" * * Returns true if this Airing was successfully updated/added to the database. The database will * automatically ensure that there are no inconsistencies in the Airings, if you add one that * overlaps with the station-time-duration of another. The one(s) that were in the database before * the call will be removed and the new one added. It will also fill in any gaps with "No Data" sections * for you automatically. */ public boolean addAiringDetailedPublic(String extID, int stationID, long startTime, long duration, int partNumber, int totalParts, String parentalRating, boolean hdtv, boolean stereo, boolean closedCaptioning, boolean sap, boolean subtitled, String premierFinale); } There's also a setting in the properties file called: epg/epg_import_plugin you'll need to set that to be the name of the class file to load for the EPG plugin. The SageTV directory is part of the classpath. The default constructor is used to create the plugin object. The plugin object must implement the sage.EPGImportPlugin interface.