package org.wamblee.crawler.kiss;
+import java.util.Comparator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.DocumentFactory;
+import org.dom4j.Element;
import org.wamblee.crawler.Action;
import org.wamblee.crawler.Page;
import org.wamblee.crawler.PageException;
/**
- * Represents a television program.
+ * Represents a television program.
*/
public class Program {
+
+ /**
+ * Lexicographical comparison of programs based on (time, title, channel).
+ *
+ */
+ public static class TimeSorter implements Comparator<Program> {
+
+ /* (non-Javadoc)
+ * @see java.util.Comparator#compare(T, T)
+ */
+ public int compare(Program o1, Program o2) {
+ int value = o1.getInterval().getBegin().compareTo(o2.getInterval().getBegin());
+ if ( value != 0 ) {
+ return value;
+ }
+ value = o1.getName().compareTo(o2.getName());
+ if (value != 0 ) {
+ return value;
+ }
+ return o1.getChannel().compareTo(o2.getChannel());
+ }
+ }
+
+ private static final Log LOG = LogFactory.getLog(Program.class);
/**
- * Name of the record action on the program details page.
+ * Name of the record action on the program details page.
*/
private static final String RECORD_ACTION = "record";
-
+
private static final String RESULT_ELEM = "result";
-
+
public enum RecordingResult {
- OK("Successfully recorded programs"),
- DUPLICATE("Already recorded programs"),
- CONFLICT("Programs in conflict with another recorded program"),
- OLDSHOW("Programs that occured in the past"),
- ERROR("Programs that could not be recorded for technical reasons");
-
- private String _description;
-
- private RecordingResult(String aDescription) {
- _description = aDescription;
- }
-
- public String getDescription() {
- return _description;
- }
+ OK("Successfully recorded programs"), DUPLICATE(
+ "Already recorded programs"), CONFLICT(
+ "Programs in conflict with another recorded program"), OLDSHOW(
+ "Programs that occurred in the past"), ERROR(
+ "Programs that could not be recorded for technical reasons");
+
+ private String _description;
+
+ private RecordingResult(String aDescription) {
+ _description = aDescription;
+ }
+
+ public String getDescription() {
+ return _description;
+ }
};
/**
- * Indent string to use for pretty printing.
+ * Indent string to use for pretty printing.
*/
private static final String INDENT = " ";
/**
- * Channel the program is on.
+ * Channel the program is on.
*/
private String _channel;
/**
- * Program name.
+ * Program name.
*/
private String _name;
/**
- * Program description.
+ * Program description.
*/
private String _description;
/**
- * Keywords or classification of the program.
+ * Keywords or classification of the program.
*/
private String _keywords;
private TimeInterval _interval;
/**
- * Action to execute to obtain program information and/or record the program.
+ * Action to execute to obtain program information and/or record the
+ * program.
*/
private Action _programInfo;
/**
- * Constructs the program.
- * @param aChannel Channel name.
- * @param aName Program name.
- * @param aDescription Description.
- * @param aKeywords Keywords/classification.
- * @param aInterval Time interval.
- * @param aProgramInfo Action to execute for detailed program information or
- * for recording the page.
+ * Constructs the program.
+ *
+ * @param aChannel
+ * Channel name.
+ * @param aName
+ * Program name.
+ * @param aDescription
+ * Description.
+ * @param aKeywords
+ * Keywords/classification.
+ * @param aInterval
+ * Time interval.
+ * @param aProgramInfo
+ * Action to execute for detailed program information or for
+ * recording the page.
*/
public Program(String aChannel, String aName, String aDescription,
String aKeywords, TimeInterval aInterval, Action aProgramInfo) {
/**
* Gets the channel.
+ *
* @return Channel.
*/
public String getChannel() {
/**
* Gets the program name.
- * @return Name.
+ *
+ * @return Name.
*/
public String getName() {
return _name;
/**
* Gets the description.
- * @return Description.
+ *
+ * @return Description.
*/
public String getDescription() {
return _description;
}
/**
- * Gets the keywords/classification.
+ * Gets the keywords/classification.
+ *
* @return Keywords/classification
*/
public String getKeywords() {
}
/**
- * Gets the time interval.
- * @return Time interval.
+ * Gets the time interval.
+ *
+ * @return Time interval.
*/
public TimeInterval getInterval() {
return _interval;
}
+
+ /**
+ * Checks if recording is possible.
+ * @return True iff recording is possible.
+ */
+ public boolean isRecordingPossible() {
+ try {
+ Action record = _programInfo.execute().getAction(RECORD_ACTION);
+ if (record == null) {
+ return false;
+ }
+ return true;
+ } catch (PageException e) {
+ return false;
+ }
+ }
/**
* Records the show.
- * @return True iff an attempt could be made to record the page.
- * @throws PageException In case of problems recording the page.
+ *
+ * @return Status describing the result of recording.
*/
- public RecordingResult record() throws PageException {
- Action record = _programInfo.execute().getAction(RECORD_ACTION);
- if (record == null) {
- return RecordingResult.OLDSHOW;
+ public RecordingResult record() {
+ LOG.info("Recording " + this);
+ if ( SystemProperties.isRecordDisabled() ) {
+ return RecordingResult.OK;
+ }
+ try {
+ Action record = _programInfo.execute().getAction(RECORD_ACTION);
+ if (record == null) {
+ LOG.info(" result: " + RecordingResult.OLDSHOW);
+ return RecordingResult.OLDSHOW;
+ }
+ Page result = record.execute();
+ RecordingResult recordingResult = RecordingResult.valueOf(result.getContent().getText());
+ LOG.info(" result: " + recordingResult);
+ return recordingResult;
+ } catch (PageException e) {
+ LOG.warn("Technical problem recording program: '" + this + "'", e);
+ LOG.info(" result: " + RecordingResult.ERROR);
+ return RecordingResult.ERROR;
}
- Page result = record.execute();
- return RecordingResult.valueOf(result.getContent().getText());
}
/**
- * Accepts the visitor.
- * @param aVisitor Visitor.
+ * Accepts the visitor.
+ *
+ * @param aVisitor
+ * Visitor.
*/
public void accept(Visitor aVisitor) {
aVisitor.visitProgram(this);
+ ")" + "\n"
+ (INDENT + _description).replaceAll("\n", "\n" + INDENT);
}
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof Program)) {
+ return false;
+ }
+ Program program = (Program)obj;
+ return getName().equals(program.getName()) &&
+ _programInfo.equals(program._programInfo);
+ }
+
+ /**
+ * Converts program information to XML.
+ * @return XML representation of program information.
+ */
+ public Element asXml() {
+ DocumentFactory factory = DocumentFactory.getInstance();
+ Element program = factory.createElement("program");
+ program.addElement("name").setText(getName());
+ program.addElement("description").setText(getDescription());
+ program.addElement("keywords").setText(getKeywords());
+ program.addElement("channel").setText(getChannel());
+ Element interval = program.addElement("interval");
+ interval.addElement("begin").setText(getInterval().getBegin().toString());
+ interval.addElement("end").setText(getInterval().getEnd().toString());
+ return program;
+ }
}