1
0
mirror of https://github.com/moparisthebest/rcrdit synced 2024-12-22 07:18:56 -05:00

Add ability to import multiple xmltv.xml files

This commit is contained in:
Travis Burtrum 2017-02-28 23:53:06 -05:00
parent c454eb713f
commit 783cc6bc70
3 changed files with 56 additions and 35 deletions

View File

@ -22,8 +22,11 @@
<databaseUrl>jdbc:mysql://localhost:3306/rcrdit?user=rcrdit&amp;password=rcrdit</databaseUrl> <databaseUrl>jdbc:mysql://localhost:3306/rcrdit?user=rcrdit&amp;password=rcrdit</databaseUrl>
<!-- server uri (context path and port) for web application --> <!-- server uri (context path and port) for web application -->
<serverUri>http://localhost:8080/rcrdit/</serverUri> <serverUri>http://localhost:8080/rcrdit/</serverUri>
<!-- path to xmltv.xml file normally generated by xmltv scripts from schedulesdirect or http://zap2xml.awardspace.info/ --> <!-- paths to xmltv.xml files normally generated by xmltv scripts from schedulesdirect or http://zap2xml.awardspace.info/ -->
<xmltvPath>/etc/xmltv.xml</xmltvPath> <xmltvPaths>
<xmltvPath>/etc/xmltv.xml</xmltvPath>
<xmltvPath>/etc/xmltv-other.xml</xmltvPath>
</xmltvPaths>
<!-- all channels you recieve, one of the names from each channel from xmltv.xml above --> <!-- all channels you recieve, one of the names from each channel from xmltv.xml above -->
<channels> <channels>
<channel>2.1</channel> <channel>2.1</channel>

View File

@ -79,7 +79,8 @@ public class RcrdIt extends ResourceConfig implements AutoCloseable {
// config items // config items
private final Tuners tuners; private final Tuners tuners;
private final Set<String> allChannels; private final Set<String> allChannels;
private final String databaseUrl, xmltvPath; private final List<String> xmltvPaths;
private final String databaseUrl;
private final TimerTask scheduleTask = new ScheduleTask(); private final TimerTask scheduleTask = new ScheduleTask();
private final Timer timer = new Timer(); private final Timer timer = new Timer();
@ -102,7 +103,7 @@ public class RcrdIt extends ResourceConfig implements AutoCloseable {
serverUri += "/"; serverUri += "/";
this.serverUri = serverUri; this.serverUri = serverUri;
this.xmltvPath = rcrdit.getChild("xmltvPath").getValue(); this.xmltvPaths = Arrays.stream(rcrdit.getChild("xmltvPaths").getChildren("xmltvPath")).map(XmlElement::getValue).collect(Collectors.toList());
this.allChannels = Arrays.stream(rcrdit.getChild("channels").getChildren("channel")).map(XmlElement::getValue).collect(Collectors.toSet()); this.allChannels = Arrays.stream(rcrdit.getChild("channels").getChildren("channel")).map(XmlElement::getValue).collect(Collectors.toSet());
final List<Tuner> tuners = new ArrayList<>(); final List<Tuner> tuners = new ArrayList<>();
@ -370,7 +371,7 @@ public class RcrdIt extends ResourceConfig implements AutoCloseable {
@Override @Override
public void run() { public void run() {
try { try {
schedule = Tv.readSchedule(xmltvPath, allChannels); schedule = Tv.readSchedule(xmltvPaths, allChannels);
//System.out.println(schedule); //System.out.println(schedule);
// todo: only re-calcuate if schedule changed // todo: only re-calcuate if schedule changed
reCalculateSchedule(); reCalculateSchedule();
@ -412,7 +413,7 @@ public class RcrdIt extends ResourceConfig implements AutoCloseable {
"tuners=" + tuners + "tuners=" + tuners +
", allChannels=" + allChannels + ", allChannels=" + allChannels +
", databaseUrl='" + databaseUrl + '\'' + ", databaseUrl='" + databaseUrl + '\'' +
", xmltvPath='" + xmltvPath + '\'' + ", xmltvPaths='" + xmltvPaths + '\'' +
'}'; '}';
} }

View File

@ -76,7 +76,7 @@ public class Tv {
'}'; '}';
} }
public static Tv readSchedule(final String resource, final Set<String> allChannels) throws Exception { public static Tv readSchedule(final List<String> resources, final Set<String> allChannels) throws Exception {
//try /*(InputStream is = new FileInputStream(resource))*/ { //try /*(InputStream is = new FileInputStream(resource))*/ {
/* /*
ObjectMapper mapper = new XmlMapper(new XmlFactory()); // create once, reuse ObjectMapper mapper = new XmlMapper(new XmlFactory()); // create once, reuse
@ -107,39 +107,56 @@ public class Tv {
.withZone(ZoneId.systemDefault()) .withZone(ZoneId.systemDefault())
.withResolverStyle(ResolverStyle.STRICT); .withResolverStyle(ResolverStyle.STRICT);
final XmlElement tv = AbstractXmlElement.getFactory().readFromFile(resource);
//System.out.print(tv);
final List<Channel> channels = new ArrayList<>(); final List<Channel> channels = new ArrayList<>();
final Map<String, String> chanIdToChanName = new HashMap<>();
for (final XmlElement chan : tv.getChildren("channel")) {
final Channel channel = new Channel(chan.getAttribute("id"), Arrays.stream(chan.getChildren("display-name")).map(XmlElement::getValue).collect(Collectors.toSet()));
for (final String displayName : channel.getDisplayNames())
if (allChannels == null || allChannels.isEmpty() || allChannels.contains(displayName)) {
chanIdToChanName.put(channel.getId(), displayName);
channels.add(channel);
break;
}
}
final List<Program> programs = new ArrayList<>(); final List<Program> programs = new ArrayList<>();
final Instant now = Instant.now().truncatedTo(ChronoUnit.MINUTES); Instant lastEndTime = Instant.now();
Instant lastEndTime = now;
for (final XmlElement prog : tv.getChildren("programme")) { for(final String resource : resources) {
final String chanId = prog.getAttribute("channel"); final XmlElement tv = AbstractXmlElement.getFactory().readFromFile(resource);
final String chanName = chanIdToChanName.get(chanId); //System.out.print(tv);
if (chanName != null) {
final Instant stop = INSTANT.parse(prog.getAttribute("stop"), Instant::from); final Map<String, String> chanIdToChanName = new HashMap<>();
if (stop.isAfter(now)) { for (final XmlElement chan : tv.getChildren("channel")) {
programs.add(new Program(INSTANT.parse(prog.getAttribute("start"), Instant::from), stop, chanId, chanName, final Channel channel = new Channel(chan.getAttribute("id"), Arrays.stream(chan.getChildren("display-name")).map(XmlElement::getValue).collect(Collectors.toSet()));
val(prog.getChild("title")), val(prog.getChild("sub-title")), val(prog.getChild("desc")), val(prog.getChild("episode-num")), for (final String displayName : channel.getDisplayNames())
val(prog.getChild("date")), val(prog.getChild("category")), prog.getChild("previously-shown") != null if (allChannels == null || allChannels.isEmpty() || allChannels.contains(displayName)) {
)); chanIdToChanName.put(channel.getId(), displayName);
if (stop.isAfter(lastEndTime)) channels.add(channel);
lastEndTime = stop; break;
}
}
final Instant now = Instant.now().truncatedTo(ChronoUnit.MINUTES);
for (final XmlElement prog : tv.getChildren("programme")) {
final String chanId = prog.getAttribute("channel");
final String chanName = chanIdToChanName.get(chanId);
if (chanName != null) {
final Instant stop = INSTANT.parse(prog.getAttribute("stop"), Instant::from);
if (stop.isAfter(now)) {
programs.add(new Program(INSTANT.parse(prog.getAttribute("start"), Instant::from), stop, chanId, chanName,
val(prog.getChild("title")), val(prog.getChild("sub-title")), val(prog.getChild("desc")), val(prog.getChild("episode-num")),
val(prog.getChild("date")), val(prog.getChild("category")), prog.getChild("previously-shown") != null
));
if (stop.isAfter(lastEndTime))
lastEndTime = stop;
}
} }
} }
} }
// de-duplicate, keep channels in order, programs don't matter since we will sort anyway...
// in theory we should only have to do this if resources.size() > 1, but who knows what kind of crazy xml will appear...
{
final Set<Channel> dedup = new LinkedHashSet<>(channels);
channels.clear();
channels.addAll(dedup);
}
{
final Set<Program> dedup = new HashSet<>(programs);
programs.clear();
programs.addAll(dedup);
}
programs.sort(ProgramTimeComparator.instance); programs.sort(ProgramTimeComparator.instance);
return new Tv(channels, programs, lastEndTime); return new Tv(channels, programs, lastEndTime);
/* /*