00001 #!/usr/bin/perl -w
00002 #
00003 # Provides notification of upcoming recordings.
00004 #
00005 # Automatically detects database settings.
00006 #
00007
00008 # Includes
00009 use DBI;
00010 use Getopt::Long;
00011 use MythTV;
00012
00013 # Some variables we'll use here
00014 our ($num_recordings, $heading, $plain_text, $text_format, $usage);
00015 our ($hours, $minutes, $seconds, $no_conflicts_message);
00016 our ($scheduled, $duplicates, $deactivated, $conflicts);
00017 our ($dnum_recordings, $dheading, $dtext_format);
00018 our ($dhours, $dminutes, $dseconds, $dno_conflicts_message);
00019 our ($dscheduled, $dduplicates, $ddeactivated, $dconflicts);
00020 our ($status_text_format, $status_value_format);
00021 our ($dstatus_text_format, $dstatus_value_format);
00022
00023 # Default number of upcoming recordings to show
00024 $dnum_recordings = 5;
00025 # Default period in which to show recordings
00026 $dhours = -1;
00027 $dminutes = -1;
00028 $dseconds = -1;
00029 # Default recording status types to show
00030 $dscheduled = 1;
00031 $dduplicates = 0;
00032 $ddeactivated = 0;
00033 $dconflicts = 1;
00034 # Default status output heading
00035 $dheading='Upcoming Recordings:\n';
00036 # Default format of plain-text output
00037 $dtext_format='%rs\n%n/%j, %g:%i %A - %cc\n%T - %S\n%R\n\n';
00038 # Default "no conflicts" message
00039 $dno_conflicts_message='No conflicts.\n';
00040 # Default format of status output display text
00041 $dstatus_text_format= '<a href="#">%rs - %n/%j, %g:%i %A - %cc - '.
00042 '%T - %S<br />'.
00043 '<span><strong>%T</strong> %n/%j, %g:%i %A<br />'.
00044 '<em>%S</em><br /><br />%R<br /></span></a><hr />';
00045 # Default format of status output value
00046 $dstatus_value_format = '%n/%j, %g:%i %A - %T - %S';
00047
00048 # Provide default values for GetOptions
00049 $num_recordings = $dnum_recordings;
00050 $hours = $dhours;
00051 $minutes = $dminutes;
00052 $seconds = $dseconds;
00053 $scheduled = $dscheduled;
00054 $duplicates = $dduplicates;
00055 $deactivated = $ddeactivated;
00056 $conflicts = $dconflicts;
00057 $heading = $dheading;
00058 $text_format = $dtext_format;
00059 $no_conflicts_message = $dno_conflicts_message;
00060 $status_text_format = $dstatus_text_format;
00061 $status_value_format = $dstatus_value_format;
00062
00063 # Load the cli options
00064 GetOptions('num_recordings|recordings=s' => \$num_recordings,
00065 'hours|o=i' => \$hours,
00066 'minutes=i' => \$minutes,
00067 'seconds|s=i' => \$seconds,
00068 'show_scheduled|_show_scheduled|scheduled|_scheduled|e!'
00069 => \$scheduled,
00070 'show_duplicates|_show_duplicates|duplicates|_duplicates|p!'
00071 => \$duplicates,
00072 'show_deactivated|_show_deactivated|deactivated|_deactivated|v!'
00073 => \$deactivated,
00074 'show_conflicts|_show_conflicts|conflicts|_conflicts!'
00075 => \$conflicts,
00076 'heading=s' => \$heading,
00077 'plain_text' => \$plain_text,
00078 'text_format=s' => \$text_format,
00079 'no_conflicts_message=s' => \$no_conflicts_message,
00080 'status_text_format=s' => \$status_text_format,
00081 'status_value_format=s' => \$status_value_format,
00082 'usage|help' => \$usage
00083 );
00084
00085 # Print usage
00086 if ($usage) {
00087 # Make default "--show_*" options readable
00088 $dscheduled = ($dscheduled ? '--show_scheduled' :
00089 '--no_show_scheduled');
00090 $dduplicates = ($dduplicates ? '--show_duplicates' :
00091 '--no_show_duplicates');
00092 $ddeactivated = ($ddeactivated ? '--show_deactivated' :
00093 '--no_show_deactivated');
00094 $dconflicts = ($dconflicts ? '--show_conflicts' :
00095 '--no_show_conflicts');
00096 print <<EOF;
00097 $0 usage:
00098
00099 options:
00100
00101 --recordings [number of recordings]
00102
00103 Outputs information on the next [number of recordings] shows to be recorded
00104 by MythTV and that match the criteria specified for --scheduled,
00105 --duplicates, --deactivated, and --conflicts. To output information on all
00106 matching recordings, specify -1.
00107
00108 default: $dnum_recordings
00109
00110 --hours [number of hours]
00111
00112 Outputs information on recordings starting in the next [number of hours]
00113 and that match the criteria specified for --scheduled, --duplicates,
00114 --deactivated, and --conflicts. This option may be specified in
00115 conjunction with --minutes and --seconds. To output information on all
00116 matching recordings regardless of start time, specify -1 for --hours,
00117 --minutes, and --seconds.
00118
00119 default: $dhours
00120
00121 --minutes [number of minutes]
00122
00123 Outputs information on recordings starting in the next [number of minutes]
00124 and that match the criteria specified for --scheduled, --duplicates,
00125 --deactivated, and --conflicts. This option may be specified in
00126 conjunction with --hours and --seconds. To output information on all
00127 matching recordings regardless of start time, specify -1 for --hours,
00128 --minutes, and --seconds.
00129
00130 default: $dminutes
00131
00132 --seconds [number of seconds]
00133
00134 Outputs information on recordings starting in the next [number of seconds]
00135 and that match the criteria specified for --scheduled, --duplicates,
00136 --deactivated, and --conflicts. This option may be specified in
00137 conjunction with --hours and --minutes. To output information on all
00138 matching recordings regardless of start time, specify -1 for --hours,
00139 --minutes, and --seconds.
00140
00141 default: $dseconds
00142
00143 --show_scheduled|--no_show_scheduled
00144
00145 Outputs information about scheduled recordings. Scheduled recordings are
00146 those that MythTV plans to actually record.
00147
00148 default: $dscheduled
00149
00150 --show_duplicates|--no_show_duplicates
00151
00152 Outputs information about duplicate recordings. Duplicate recordings are
00153 those that will not be recorded because of the specified duplicate matching
00154 policy for the rule.
00155
00156 default: $dduplicates
00157
00158 --show_deactivated|--no_show_deactivated
00159
00160 Outputs information about deactivated recordings. Deactivated recordings
00161 are those that MythTV will not record because the schedule is inactive,
00162 because the showing was set to never record, because the show is being
00163 recorded in an earlier or later showing, because there are too many
00164 recordings or not enough disk space to allow the recording, or because
00165 the show you\'ve specified for recording is not listed in the timeslot
00166 specified.
00167
00168 default: $ddeactivated
00169
00170 --show_conflicts|--no_show_conflicts
00171
00172 Outputs information about conflicts (those shows that MythTV cannot record
00173 because of other higher-priority scheduled recordings).
00174
00175 default: $dconflicts
00176
00177 --heading [heading]
00178 Output the [heading] before printing information about recordings.
00179
00180 default: \'$dheading\'
00181
00182 --plain_text
00183 Output information in plain text format (i.e. for inclusion in an e-mail
00184 notification).
00185
00186 --text_format [format]
00187 Use the provided [format] to display information on the recordings. The
00188 format should use the same format specifiers used by mythrename.pl, but
00189 may also use \\r and/or \\n for line breaks and %rs for recording status.
00190 This option is ignored if --plain_text is not used.
00191
00192 default: \'$dtext_format\'
00193
00194 --no_conflicts_message [message]
00195 Use the provided [message] to specify there are no conflicts. This option
00196 is used when only information about conflicts is requested and there are
00197 no conflicts. I.e. it is only used with the combination of show_*
00198 options --show_conflicts, --no_show_scheduled, --no_show_deactivated,
00199 and --no_show_duplicates .
00200
00201 default: \'$dno_conflicts_message\'
00202
00203 --help
00204
00205 Show this help text.
00206
00207 EOF
00208 exit;
00209 }
00210
00211 # Determine the period of interest
00212 my $now = time();
00213 my $start_before = $now;
00214 $start_before = $start_before + ($hours * 3600) if ($hours > 0);
00215 $start_before = $start_before + ($minutes * 60) if ($minutes > 0);
00216 $start_before = $start_before + $seconds if ($seconds > 0);
00217 $start_before = 0 if (!($start_before > $now));
00218
00219 # Fix the heading.
00220 if (defined($plain_text)) {
00221 $heading =~ s/\\r/\r/g;
00222 $heading =~ s/\\n/\n/g;
00223 }
00224 else {
00225 # Remove line break format specifiers from heading for status output
00226 $heading =~ s/(\\r|\\n)//g;
00227 }
00228
00229 # Connect to mythbackend
00230 my $Myth = new MythTV();
00231
00232 # Get the list of recordings
00233 my $count = 0;
00234 my %rows = $Myth->backend_rows('QUERY_GETALLPENDING', 2);
00235 my $has_conflicts = $rows{'offset'}[0];
00236 if ((!$has_conflicts) &&
00237 (($conflicts) &&
00238 (!(($scheduled) || ($duplicates) || ($deactivated))))) {
00239 $no_conflicts_message =~ s/\\r/\r/g;
00240 $no_conflicts_message =~ s/\\n/\n/g;
00241 print "$no_conflicts_message";
00242 exit 0;
00243 }
00244 my $num_scheduled = $rows{'offset'}[1];
00245 our $show;
00246 foreach my $row (@{$rows{'rows'}}) {
00247 last unless (($count < $num_recordings) || ($num_recordings < 0));
00248 $show = new MythTV::Program(@$row);
00249 last if (($start_before) && ($show->{'recstartts'} > $start_before));
00250 next if ((!$scheduled) && (is_scheduled($show->{'recstatus'})));
00251 next if ((!$duplicates) && (is_duplicate($show->{'recstatus'})));
00252 next if ((!$deactivated) && (is_deactivated($show->{'recstatus'})));
00253 next if ((!$conflicts) && (is_conflict($show->{'recstatus'})));
00254
00255 # Print the recording information in the desired format
00256 if (defined($plain_text)) {
00257 text_print($count);
00258 }
00259 else {
00260 status_print($count);
00261 }
00262 $count++;
00263 }
00264
00265 # Returns true if the show is scheduled to record
00266 sub is_scheduled {
00267 my $recstatus = (shift() or 0);
00268 return (($MythTV::recstatus_willrecord == $recstatus) ||
00269 ($MythTV::recstatus_recorded == $recstatus) ||
00270 ($MythTV::recstatus_recording == $recstatus));
00271 }
00272
00273 # Returns true if the show is a duplicate
00274 sub is_duplicate {
00275 my $recstatus = (shift() or 0);
00276 return (($MythTV::recstatus_repeat == $recstatus) ||
00277 ($MythTV::recstatus_previousrecording == $recstatus) ||
00278 ($MythTV::recstatus_currentrecording == $recstatus));
00279 }
00280
00281 # Returns true if the recording is deactivated
00282 sub is_deactivated {
00283 my $recstatus = (shift() or 0);
00284 return (($MythTV::recstatus_inactive == $recstatus) ||
00285 ($MythTV::recstatus_toomanyrecordings == $recstatus) ||
00286 ($MythTV::recstatus_cancelled == $recstatus) ||
00287 ($MythTV::recstatus_deleted == $recstatus) ||
00288 ($MythTV::recstatus_aborted == $recstatus) ||
00289 ($MythTV::recstatus_notlisted == $recstatus) ||
00290 ($MythTV::recstatus_dontrecord == $recstatus) ||
00291 ($MythTV::recstatus_lowdiskspace == $recstatus) ||
00292 ($MythTV::recstatus_tunerbusy == $recstatus) ||
00293 ($MythTV::recstatus_neverrecord == $recstatus) ||
00294 ($MythTV::recstatus_earliershowing == $recstatus) ||
00295 ($MythTV::recstatus_latershowing == $recstatus));
00296 }
00297
00298 # Returns true if the show cannot be recorded due to a conflict
00299 sub is_conflict {
00300 my $recstatus = (shift() or 0);
00301 return ($MythTV::recstatus_conflict == $recstatus);
00302 }
00303
00304 # Print the output for use in the backend status page.
00305 sub status_print {
00306 my $count = shift;
00307 my $text = $show->format_name($status_text_format, ' ', ' ', 1, 0 ,1);
00308 $text =~ s/%rs/$MythTV::RecStatus_Types{$show->{'recstatus'}}/g;
00309 my $value = $show->format_name($status_value_format, ' ', ' ',
00310 1, 0 ,1);
00311 $value =~ s/%rs/$MythTV::RecStatus_Types{$show->{'recstatus'}}/g;
00312 print("$heading<div class=\"schedule\">") if ($count == 0);
00313 print("$text");
00314 print("</div>") if ($count == ($num_recordings - 1));
00315 print("[]:[]recording$count");
00316 print("[]:[]$value\n");
00317 }
00318
00319 # Print the output in plain text format
00320 sub text_print {
00321 my $count = shift;
00322 my $text = $show->format_name($text_format, ' ', ' ', 1, 0 ,1);
00323 $text =~ s/%rs/$MythTV::RecStatus_Types{$show->{'recstatus'}}/g;
00324 $text =~ s/\\r/\r/g;
00325 $text =~ s/\\n/\n/g;
00326 print("$heading") if ($count == 0);
00327 print("$text");
00328 }
00329