EPG | Version 4

EPG Developing Guide

Find out more about developing with the add-on Electronic Program Guide.

Java Tag Library

We provide a Tag Library to simplify JSP development. It provides support for the concept of programs, which may have multiple broadcast dates (see above).

In the following, we give an overview over the provided tags using examples. A detailed documentation of all the tags is available in the Tag Library Descriptor (TLD) and as TLDDoc.

epg:broadcastSearch

This tag allows searching for broadcast dates (using Solr). Results may be restricted using optional criteria, e.g., a minimal date or the station.

The result is a EpgResultPage. Each entry in the result page represents a single broadcast date and also contains all data of the broadcast itself.

In the following example, we search for all broadcasts in a given time range and within a specific station:

<%@ page pageEncoding="utf-8" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://www.subshell.com/sophora/epg" prefix="epg"%>
 
<fmt:parseDate var="minDate" pattern="dd.MM.yyyy HH:mm" type="both" value="12.05.2014 22:00"/>
<fmt:parseDate var="maxDate" pattern="dd.MM.yyyy HH:mm" type="both" value="12.05.2014 22:45"/>
<epg:broadcastSearch
 stationExternalIds="station-externalId"
 var="result" minDate="${minDate}" maxDate="${maxDate}" />
 
total: ${result.totalCount} <br />
size: ${result.entries.size()} <br />
hasNextPage: ${result.hasNextPage} <br />
hasPreviousPage: ${result.hasPreviousPage} <br />
pageSize: ${result.pageSize} <br />
pageNumber: ${result.pageNumber} <br />
<hr />
 
<c:forEach var="entry" items="${result.entries}">
 ${entry.broadcast.startTime['yyyy-MM-dd HH:mm']} - ${entry.broadcast.endTime['yyyy-MM-dd HH:mm']} - ${entry.program.title} - ${entry.broadcast.station.title}
 <hr />
</c:forEach>

Additional search criteria not directly supported by the tag can be given using Solr query fragments. In the following example, we search for a broadcast containing "Hamburg" in its title:

<%@ page pageEncoding="utf-8" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.subshell.com/sophora/epg" prefix="epg"%>
<%@ taglib tagdir="/WEB-INF/tags/sophora-commons" prefix="sc"%>
 
<sc:getCurrentDate var="now" />
 
<c:set var="programQuery">+example_title_s:*Hamburg*</c:set>
<epg:broadcastSearch var="result" minDate="${now}" minDateMode="excludeRunning" pageSize="10" programQuery="${programQuery}" />
 
<h1>Title contains "Hamburg"</h1>
<p>
<c:forEach var="entry" items="${result.entries}">
 <hr />
 ${entry.broadcast.startTime['yyyy-MM-dd HH:mm']} - ${entry.broadcast.endTime['yyyy-MM-dd HH:mm']} - ${entry.program.title} - ${entry.broadcast.station.title}
</c:forEach>
</p>

epg:currentBroadcast

This tag is used to determine the broadcast that is currently running on a station.

<%@ taglib uri="http://www.subshell.com/sophora/epg" prefix="epg"%>
 
<epg:currentBroadcast var="result" stationExternalIds="station-externalId"/>
<h1>Current Broadcast:</h1>
<p>
<c:choose>
 <c:when test="${empty result}">
 Currently no broadcast.
 </c:when>
 <c:otherwise>
 ${result.broadcast.startTime['yyyy-MM-dd HH:mm']} - ${result.broadcast.endTime['yyyy-MM-dd HH:mm']} - ${result.program.title} - ${result.broadcast.station.title}
 </c:otherwise>
</c:choose>
</p>

epg:isDaylightSavingTimeTransition

This tag returns whether there is a clock change on a given date.

<%@ page pageEncoding="utf-8" contentType="text/html; charset=UTF-8" import="java.util.*"%>
<%@ taglib uri="http://www.subshell.com/sophora/epg" prefix="epg"%>
 
<%
 Calendar cal = Calendar.getInstance();
 cal.set(cal.get(Calendar.YEAR), Calendar.MARCH, 29);
 Date testDate = cal.getTime();
%>
 
<epg:isDaylightSavingTimeTransition var="result" date="<%=testDate%>" />
<h1><%=testDate%></h1>
<h2>Daylight saving time transition on the given date: ${result}</h2>

epg:getNextDaylightSavingTimeTransition

Returns the next day on which a clock change will happen.

<%@ page pageEncoding="utf-8" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://www.subshell.com/sophora/epg" prefix="epg"%>
 
<epg:getNextDaylightSavingTimeTransition var="nextTransition"/>
 
<h1>Next daylight saving time transition: ${nextTransition}</h1>

epg:flushCacheAtNextBroadcastStart

This tag sets the flush date according to the next future broadcast. No flush date is set if no future broadcast can found.
The following arguments can be provided to the tag:

  • broadcasts: A list of broadcasts (as list of EpgResultEntrys). The flush date will be set to the nearest start or end date of a broadcast in the list.
  • stations: Comma-separated list of externalIds of stations. The flush date will be set to the nearest start date of a broadcast on any of those stations.
  • programUuid: Uuid of a program document. The flush date will be set to the next broadcast start or end of this program.
Exactly one of the arguments must be set.

<%@ page pageEncoding="utf-8" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://www.subshell.com/sophora/epg" prefix="epg"%>
 
<fmt:parseDate var="minDate" pattern="dd.MM.yyyy HH:mm" type="both" value="10.02.2015 09:00" parseLocale="GERMAN"/>
<fmt:parseDate var="maxDate" pattern="dd.MM.yyyy HH:mm" type="both" value="11.02.2015 12:45" parseLocale="GERMAN"/>
 
<epg:broadcastSearch stationExternalIds="station1-externalId" var="broadcasts" minDate="${minDate}" maxDate="${maxDate}" />
<epg:flushCacheAtNextBroadcastStart broadcasts="${broadcasts.entries}"/>
<epg:flushCacheAtNextBroadcastStart stations="station1-externalId,station2-externalId"/>
<epg:flushCacheAtNextBroadcastStart programUuid="${current.uuid}"/>

epg:solrSearch

This tag provides generic EPG Solr search capability.
The Solr query for broadcasts (e.g., to search for broadcast dates that are reruns) can be supplied via the broadcastQuery attribute. In addition, the (optional) programQuery attribute can be set to query for programs (e.g., to do full-text search within the program title).
Furthermore, the tag provides support for all Solr attributes (e.g., fields, pageNumber, pageSize, ...).
The return value is a EpgResultPage.

Configuration

Enable block joins in the configuration document

Blockjoins offer better performance than regular joins. Using blockjoins is only possible with a Sophora Server that has at least version 2.5.35. After your epg-core is reindexed, you can enable blockjoins setting blockjoin.enabled.<epg-core> to true in the configuration document. For further information see the solr documentation.

Configuration options in sophora.properties

The following properties can be configured using sophora.properties.

PropertyDescription
com.subshell.sophora.delivery.epg.taglib.programNodeTypeThe node type that represents program objects.
com.subshell.sophora.delivery.epg.taglib.defaultSolrCoreThe non-epg-specific Solr core to be used for searching. "default" if not configured.
com.subshell.sophora.delivery.epg.taglib.epgSolrCoreThe epg-specific Solr core. "epgProgram" if not configured.
com.subshell.sophora.delivery.epg.taglib.programModelThe name of the content map model used for program search results.

Java Library

We provide some projects that help working with EPG documents. Foremost is the epg-model. It contains model classes for the concepts stored in the documents. Based on that there is epg-export-commons for exporting EPG to different formats. Classes to aid in searching broadcasts in the specific Solr core used by Sophora EPG can be found in epg-serach-commons. For testing the epg-testutils are helpful especially in the context of Teletext.

epg-model

The EPG model contains model classes and logic for electronic program guides. Most functionality of the EPG view in the DeskClient comes from this project.

The most important models are the following:

  • One broadcast is represented by an IEpgScheduleEntry.
  • All broadcasts of a station (EpgStation) for one day is contained in an EpgSchedule.

Here is an example how to print the schedule of the current day:

ISophoraClient sophoraClient = [...]; 
DateTime date = DateTime.now();

// station
StationDao stations = new StationDao(sophoraClient, new TemplateDao(sophoraClient));
EpgStation exampleStation = stations.getStationByExternalId("example-station");
// schedule
IEpgDocumentsProvider liveProgramsProvider = new LiveWorkspaceProgramsProvider(sophoraClient);
EpgSchedule scheduleOfDay = new EpgSchedule(sophoraClient, date, exampleStation, liveProgramsProvider);
// output
System.out.println("schedule of '" + exampleStation.getName() + "' at " + date.toLocalDate());
for (IEpgScheduleEntry entry: scheduleOfDay.getEntries()) {
	System.out.println(entry.getStartDate().toLocalTime() + " " + entry.getTitle());
}

If you are reusing the IEpgDocumentsProvider consider wapping it in a CachingProgramsProvider for better performance. You can also use the EpgScheduleFactory from the epg-export-commons project for simple creation of common schedules in a Spring environment.

Regional programs

A station can have regional sub stations. The schedule of the main station can have gaps which are filled differently in each regional station. The schedule merges these broadcasts.

To check if a station is a regional station or not use EpgStation.isMainStation(). For schedule entries IEpgScheduleEntry.hasRegionalCoverage() denotes that the actual broadcast depends on the regional station.

Public Holidays

The model project also contains logic for holidays and daylight saving times in the corresponding packages. To check if a given day is a holiday:

// field
private static final Holidays holidays = new Holidays(new EpgHolidaysFilter()); 
// method
public void doSomethingWith(DateTime date) {
		CalendarDay holiday = holidays.getHoliday(date);
		if (holiday != null) {
			System.out.println("It is " + holiday.getName() + "!");
		} else {
			System.out.println("It is an ordinary day");
 		}
}

epg-export-commons

This project is used to export EPG data to other formats. It is the core of EPGExporters created by subshell. Here you find helpers for creating files and putting them to places like FTP servers. It also provides web server logic for monitoring those exports.

Most components are provided as Spring beans. Some entry points:

  • EpgScheduleFactory for accessing all broadcasts of a given day.
  • EpgExporterConfig lists possibilities of EPG exporters which are not all implemented in this project. Especially the TeletextExportConfig is only a data class.
  • AbstractPocDayExporter creates POC-XML (ARD-Sendungsdaten)
  • The package com.subshell.sophora.epg.transport handles network transfers.

Contact us for further information to your use case.

epg-search-commons

This project is used by the Java Tag Library mentioned above. It contains the low level queries for accessing broadcasts in the Solr.

The class BroadcastSearchQuery creates Solr queries which can be used to find specific broadcasts. Most fields of a broadcast can be filtered. Two queries can be created: A broadcast query that filters the child nodes of program documents and additionally a program query for custom searches. So additionally you need to provide a join for these Solr documents, if you use both queries.

In the following example, we search for all broadcasts in a given time range and within a specific station containing "Hamburg" in its title:

Date now = new Date();
Date inOver3Hours = new Date(now.getTime() + 12_345_678L);
BroadcastSearchQuery query = new BroadcastSearchQuery();
// configure query
query.setMinDate(now);
query.setMaxDate(inOver3Hours);
query.setStationExternalIds(Collections.singleton("example-tv-station"));
query.setProgramQuery("+example_title_s:*Hamburg*");
// create the queries for sending them to Solr
String solrQuery = query.createFullProgramQuery();
String solrFilterQuery = query.createBroadcastQuery(sophoraClient);
String solrSortQuery = query.createSortQuery();
int solrPageSize = query.getPageSize();

Last modified on 11/6/20

The content of this page is licensed under the CC BY 4.0 License. Code samples are licensed under the MIT License.

Icon