/* * Copyright (c) Henrik Niehaus * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of the project (Lazy Bones) nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package lazybones.programmanager; import java.awt.event.MouseEvent; import java.util.Calendar; import java.util.ConcurrentModificationException; import java.util.List; import javax.swing.JPopupMenu; import lazybones.ChannelManager; import lazybones.ChannelManager.ChannelNotFoundException; import lazybones.LazyBones; import lazybones.LazyBonesTimer; import lazybones.TimerManager; import lazybones.VDRConnection; import lazybones.programmanager.evaluation.DoppelpackDetector; import lazybones.programmanager.evaluation.Evaluator; import lazybones.programmanager.evaluation.Result; import org.hampelratte.svdrp.Response; import org.hampelratte.svdrp.commands.LSTE; import org.hampelratte.svdrp.parsers.EPGParser; import org.hampelratte.svdrp.responses.highlevel.Channel; import org.hampelratte.svdrp.responses.highlevel.EPGEntry; import org.hampelratte.svdrp.responses.highlevel.Timer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import util.programmouseevent.ProgramMouseEventHandler; import devplugin.Program; public class ProgramManager { private static transient Logger logger = LoggerFactory.getLogger(ProgramManager.class); private static ProgramManager instance; private final Evaluator evaluator = new Evaluator(); private ProgramManager() { } public static ProgramManager getInstance() { if (instance == null) { instance = new ProgramManager(); } return instance; } public LazyBonesTimer getTimerForTime(Calendar cal, devplugin.Channel chan) { long time_t = cal.getTimeInMillis() / 1000; Object o = ChannelManager.getChannelMapping().get(chan.getId()); int channelNumber = ((Channel) o).getChannelNumber(); LSTE cmd = new LSTE(channelNumber, time_t); Response res = VDRConnection.send(cmd); if (res != null && res.getCode() == 215) { List<EPGEntry> epg = new EPGParser().parse(res.getMessage()); if (epg.size() > 0) { EPGEntry entry = epg.get(0); // we can use the first element, because there will be only one item in the list Timer timer = new Timer(); timer.setChannelNumber(channelNumber); timer.setTitle(entry.getTitle()); timer.setStartTime(entry.getStartTime()); timer.setEndTime(entry.getEndTime()); timer.setDescription(entry.getDescription()); int prio = Integer.parseInt(LazyBones.getProperties().getProperty("timer.prio")); int lifetime = Integer.parseInt(LazyBones.getProperties().getProperty("timer.lifetime")); timer.setLifetime(lifetime); timer.setPriority(prio); return new LazyBonesTimer(timer); } } return null; } public JPopupMenu getContextMenuForTimer(LazyBonesTimer timer) { List<String> tvBrowserProgIds = timer.getTvBrowserProgIDs(); JPopupMenu popup; if (tvBrowserProgIds.size() > 0) { Program prog = ProgramDatabase.getProgram(tvBrowserProgIds.get(0)); popup = LazyBones.getPluginManager().createPluginContextMenu(prog, null); } else { popup = LazyBones.getInstance().getSimpleContextMenu(timer); } return popup; } /** * Called to mark all Programs */ public void markPrograms(TimerManager timerManager) { List<LazyBonesTimer> timers = timerManager.getTimers(); // for every timer try { for (LazyBonesTimer timer : timers) { markSingularTimer(timer, timerManager); } } catch (ConcurrentModificationException e) { // the timers list has changed while we were marking programs, let's start over logger.debug("Timers list has changed while marking programs. Beginning from scratch."); // first remove all previously set marks unmarkPrograms(); // now mark all timers markPrograms(timerManager); } } /** * Unmarks all programs, which are marked by LazyBones */ public void unmarkPrograms() { Program[] markedPrograms = LazyBones.getPluginManager().getMarkedPrograms(); for (Program marked : markedPrograms) { marked.unmark(LazyBones.getInstance()); } } /** * * @param timer * @param chan */ private void markSingularTimer(LazyBonesTimer timer, TimerManager timerManager) { // get the day program of the day, the previous day and the next day List<Program> threeDayProgram; try { threeDayProgram = ProgramDatabase.getProgramAroundTimer(timer); } catch (ChannelNotFoundException e) { timer.setReason(LazyBonesTimer.NO_CHANNEL); return; } // Mark doppelpack timers. If we found a doppelpack, we can stop at this point boolean doppelpackFound = new DoppelpackDetector(threeDayProgram).markDoppelpackTimer(timer); if (doppelpackFound) { return; } // no doppelpacks, we can now evaluate the programs with // several criteria Result bestMatching = evaluator.evaluate(threeDayProgram, timer); if (bestMatching == null) { logger.warn("Couldn't assign timer: ", timer); timer.setReason(LazyBonesTimer.NOT_FOUND); return; } logger.debug("Best matching program for timer \"{}\" is \"{}\" with a percentage of {}", new Object[] { timer.getTitle(), bestMatching.getProgram().getTitle(), bestMatching.getPercentage() }); int threshold = Integer.parseInt(LazyBones.getProperties().getProperty("percentageThreshold")); // if the percentage of equality is higher than the config value // percentageThreshold, mark this program if (bestMatching.getPercentage() >= threshold) { assignTimerToProgram(bestMatching.getProgram(), timer); } else { // no candidate and no doppelpack found // look for the timer in stored timers boolean found = timerManager.lookUpTimer(timer, bestMatching.getProgram()); if (!found) { // we have no mapping logger.warn("Couldn't find a program with that title: ", timer.getTitle()); logger.warn("Couldn't assign timer: ", timer); timer.setReason(LazyBonesTimer.NOT_FOUND); } } } public void assignTimerToProgram(Program prog, LazyBonesTimer timer) { timer.addTvBrowserProgID(prog.getUniqueID()); prog.mark(LazyBones.getInstance()); prog.validateMarking(); // if (timer.isRepeating()) { // Date d = prog.getDate(); // timer.getStartTime().set(Calendar.DAY_OF_MONTH, d.getDayOfMonth()); // timer.getStartTime().set(Calendar.MONTH, d.getMonth()-1); // timer.getStartTime().set(Calendar.YEAR, d.getYear()); // } } public void handleTimerDoubleClick(LazyBonesTimer timer, MouseEvent e) { List<String> progIDs = timer.getTvBrowserProgIDs(); if (progIDs.size() > 0) { String firstProgID = progIDs.get(0); Program prog = ProgramDatabase.getProgram(firstProgID); if (prog != null) { ProgramMouseEventHandler.handleProgramClick(prog, LazyBones.getInstance(), false, e); } } } }