summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndreas Brachold <vdr07@deltab.de>2007-11-27 15:22:33 +0000
committerAndreas Brachold <vdr07@deltab.de>2007-11-27 15:22:33 +0000
commit73ffd898650f6cb75d323cc438845a3aead1b110 (patch)
treee92d68f9802fd2ae1e7479d0e02935ac350bb1bf /lib
parentaacaa350f7da7c154264897da26d15ff38df46bb (diff)
downloadxxv-73ffd898650f6cb75d323cc438845a3aead1b110.tar.gz
xxv-73ffd898650f6cb75d323cc438845a3aead1b110.tar.bz2
* Database: Change method of version control, use comment from table, instead use table 'VERSION'
* RECORDS: Use MD5 for mapping preview images * RECORDS: Don't use 2nd try to generate preview images * Handle field names from table now with special character, remove prior workaround * TIMER: Search lookup also for description * buildsearch: redesign avoid SQL-Injection * AUTOTIMER: Speed up background scan, compare now only changed und added epg-events
Diffstat (limited to 'lib')
-rw-r--r--lib/Tools.pm110
-rw-r--r--lib/XXV/MODULES/AUTOTIMER.pm153
-rw-r--r--lib/XXV/MODULES/CHANNELS.pm17
-rw-r--r--lib/XXV/MODULES/CHRONICLE.pm65
-rw-r--r--lib/XXV/MODULES/CONFIG.pm11
-rw-r--r--lib/XXV/MODULES/EPG.pm134
-rw-r--r--lib/XXV/MODULES/MEDIALIB.pm16
-rw-r--r--lib/XXV/MODULES/MUSIC.pm121
-rw-r--r--lib/XXV/MODULES/RECORDS.pm124
-rw-r--r--lib/XXV/MODULES/TIMERS.pm102
-rw-r--r--lib/XXV/MODULES/USER.pm32
11 files changed, 516 insertions, 369 deletions
diff --git a/lib/Tools.pm b/lib/Tools.pm
index d73c920..b8d65f0 100644
--- a/lib/Tools.pm
+++ b/lib/Tools.pm
@@ -22,8 +22,8 @@ our $LOGCALLB = sub{ };
our $DBH = {};
@EXPORT = qw(&datum &stackTrace &lg &event &debug &error &panic &rep2str &dumper &getFromSocket &fields
- &load_file &save_file &tableExists &tableUpdated &buildsearch &deleteDir &getip &convert &int &entities &reentities &bench
- &fmttime &getDataByTable &getDataById &getDataBySearch &getDataByFields &umlaute &touch);
+ &load_file &save_file &tableUpdated &buildsearch &deleteDir &getip &convert &int &entities &reentities &bench
+ &fmttime &getDataByTable &getDataById &getDataBySearch &getDataByFields &touch);
# ------------------
@@ -229,7 +229,7 @@ sub tableExists {
my $dbh = shift || return error('No database handle defined!');
my $name = shift || return error('No table defined!');
- my $erg = $dbh->selectall_arrayref('show tables');
+ my $erg = $dbh->selectall_arrayref("show tables LIKE '$name'");
for(@$erg) {
return 1 if($name eq $_->[0]);
}
@@ -237,17 +237,31 @@ sub tableExists {
}
# ------------------
+sub tableStatus {
+# ------------------
+ my $dbh = shift || return error('No database handle defined!');
+ my $table = shift || return error('No table defined!');
+ my $row = shift || return error('No row defined!');
+
+ my $erg = $dbh->selectrow_hashref("SHOW TABLE STATUS LIKE '$table'");
+ if($erg and exists $erg->{$row}) {
+ return $erg->{$row};
+ }
+ return 0;
+}
+
+# ------------------
sub tableUpdated {
# ------------------
my $dbh = shift || return error('No database handle defined!');
my $table = shift || return error('No table defined!');
- my $rows = shift || return error('No rows defined!');
+ my $dbversion = shift || return error('No version of database defined!');
my $drop = shift || 0;
# remove old Version, if updated
if(tableExists($dbh, $table)) {
- my $fields = fields($dbh, 'select * from '.$table);
- if(!$fields || scalar @$fields != $rows) {
+ my $tableversion = tableStatus($dbh, $table,'Comment');
+ if(!$tableversion || $tableversion ne $dbversion) {
if($drop) {
lg sprintf('Remove old version from database table %s',$table);
$dbh->do(sprintf('drop table %s',$table))
@@ -256,13 +270,13 @@ sub tableUpdated {
panic sprintf(
q|------- !PROBLEM! ----------
Upps, you have a incompatible or corrupted database.
-Table %s has %d. It's expected %d rows.
+Table %s has version '%s'. It's expected version '%s'.
Please check database e.g. with mysqlcheck --all-databases --fast --silent
or use the script contrib/upgrade-xxv.sh to upgrade the database!
----------------------------|#'
,$table
- ,$fields ? scalar @$fields : 0
- ,$rows);
+ ,$tableversion ? $tableversion : 0
+ ,$dbversion);
return 0;
}
}
@@ -316,26 +330,33 @@ sub _buildsearchcomma {
#--------------------------------------------------------
my ($queryField, $Search) = @_;
+ my $term;
my $out;
foreach my $su (split(/\s*,\s*/, $Search)) {
-# $su =~ s/\./\\\\\./sg;
- $su =~ s/\'/\\\\\'/sg;
- $su =~ s/\"/\./sg;
- $su =~ s/\+/\\\\\+/sg;
- $su =~ s/\?/\\\\\?/sg;
- $su =~ s/\(/\\\\\(/sg;
- $su =~ s/\)/\\\\\)/sg;
+ $su =~ s/\./\\\./sg;
+# $su =~ s/\'/\\\'/sg;
+# $su =~ s/\"/\./sg;
+ $su =~ s/\*/\\\*/sg;
+ $su =~ s/\+/\\\+/sg;
+ $su =~ s/\?/\\\?/sg;
+ $su =~ s/\(/\\\(/sg;
+ $su =~ s/\)/\\\)/sg;
$out .= ' AND ' if($out);
if($su =~ s/^\-+//) {
- $out .= qq| ($queryField NOT RLIKE "$su")|;
+ $out .= qq| ($queryField NOT RLIKE ?)|;
+ push(@$term,$su);
} else {
$su =~ s/^\&+//; #remove for backward compatibility
- $out .= qq| ($queryField RLIKE "$su")|;
+ $out .= qq| ($queryField RLIKE ?)|;
+ push(@$term,$su);
}
}
# dumper($out);
- return $out;
+ return {
+ query => $out,
+ term => $term
+ };
}
#--------------------------------------------------------
@@ -344,6 +365,7 @@ sub _buildsearchlogical {
my ($queryField, $Search) = @_;
my $out;
+ my $term;
my $op = 1;
$out = " (";
foreach my $su (split(/( AND NOT | OR | AND )/, $Search)) {
@@ -360,22 +382,26 @@ sub _buildsearchlogical {
} else {
$out .= " AND" unless($op);
-# $su =~ s/\./\\\\\./sg;
- $su =~ s/\'/\\\\\'/sg;
- $su =~ s/\"/\./sg;
- $su =~ s/\+/\\\\\+/sg;
- $su =~ s/\?/\\\\\?/sg;
- $su =~ s/\(/\\\\\(/sg;
- $su =~ s/\)/\\\\\)/sg;
-
- $out .= qq| ($queryField RLIKE "$su")|;
-
+ $su =~ s/\./\\\./sg;
+# $su =~ s/\'/\\\'/sg;
+# $su =~ s/\"/\./sg;
+ $su =~ s/\*/\\\*/sg;
+ $su =~ s/\+/\\\+/sg;
+ $su =~ s/\?/\\\?/sg;
+ $su =~ s/\(/\\\(/sg;
+ $su =~ s/\)/\\\)/sg;
+
+ $out .= qq| ($queryField RLIKE ?)|;
+ push(@$term,$su);
$op = 0;
}
}
$out .= " )";
# dumper($out);
- return $out;
+ return {
+ query => $out,
+ term => $term
+ };
}
@@ -384,7 +410,7 @@ sub buildsearch {
#--------------------------------------------------------
my ($InFields, $Search) = @_;
my @fields = split(/\s*,\s*/, $InFields);
- my $queryField = scalar(@fields) > 1 ? qq|CONCAT_WS("~",$InFields)| : qq|$InFields|;
+ my $queryField = scalar(@fields) > 1 ? qq|CONCAT_WS(" ",$InFields)| : qq|$InFields|;
if( grep(/ AND /, $Search)
or grep(/ OR /, $Search)
@@ -569,28 +595,6 @@ sub bench {
}
# ------------------
-sub umlaute {
-# ------------------
- my $s = shift || return "";
-
- my %uml = (
- 'Ä' => 'Ae',
- 'Ö' => 'Oe',
- 'Ü' => 'Ue',
- 'ä' => 'ae',
- 'ö' => 'oe',
- 'ü' => 'ue',
- 'ß' => 'sz'
- );
-
- my @uml = join("|", keys(%uml));
-
- $s =~ s/(@uml)/$uml{$1}/eg;
-
- return $s;
-}
-
-# ------------------
sub touch {
# ------------------
my $file = shift;
diff --git a/lib/XXV/MODULES/AUTOTIMER.pm b/lib/XXV/MODULES/AUTOTIMER.pm
index f22c60a..04eafbb 100644
--- a/lib/XXV/MODULES/AUTOTIMER.pm
+++ b/lib/XXV/MODULES/AUTOTIMER.pm
@@ -250,14 +250,18 @@ sub _init {
# ------------------
my $obj = shift || return error('No object defined!');
- return 0, panic("Session to database is'nt connected")
- unless($obj->{dbh});
+ unless($obj->{dbh}) {
+ panic("Session to database is'nt connected");
+ return 0;
+ }
+ my $version = main::getDBVersion();
# don't remove old table, if updated rows => warn only
- tableUpdated($obj->{dbh},'AUTOTIMER',19,0);
+ if(!tableUpdated($obj->{dbh},'AUTOTIMER',$version,0)) {
+ return 0;
+ }
# Look for table or create this table
- my $version = main::getVersion;
$obj->{dbh}->do(qq|
CREATE TABLE IF NOT EXISTS AUTOTIMER (
Id int(11) unsigned auto_increment NOT NULL,
@@ -337,6 +341,33 @@ sub autotimer {
my $vdrVersion = main::getVdrVersion();
+ # Search only for event there added since last runtime.
+ # and search not with TEMPEPG at manual running
+ my $addtime = ((not ref $console) && ($obj->{addtime})) ? $obj->{addtime} : 0;
+ $obj->{addtime} = time unless($autotimerid);
+
+ &bench('AUTOTIMER');
+ if($addtime) {
+
+ # Remove old data
+ $obj->{dbh}->do('DELETE FROM TEMPEPG');
+
+ # Copy only new events from EPG to TEMPEPG, to speed up search
+ my $sql = qq|INSERT INTO TEMPEPG SELECT e.* FROM EPG as e, CHANNELS as c
+ WHERE e.addtime >= FROM_UNIXTIME(?)|;
+
+ # Exclude unwanted channels
+ if($obj->{exclude}) {
+ $sql .= sprintf(' AND ( e.channel_id = c.Id ) AND NOT (c.%s)',
+ $obj->{exclude});
+ }
+
+ my $sth = $obj->{dbh}->prepare($sql)
+ or return error sprintf("Couldn't prepare query: %s.",$sql);
+ $sth->execute($addtime)
+ or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
+ }
+
# Get Timersmodule
my $timermod = main::getModule('TIMERS');
foreach my $id (sort keys %$att) {
@@ -351,7 +382,7 @@ sub autotimer {
}
# Build SQL Command and run it ....
- my $events = $obj->_eventsearch($a, $timermod) || next;
+ my $events = $obj->_eventsearch($a, $timermod, $addtime ) || next;
# Only search for one at?
if(ref $console && $autotimerid) {
@@ -474,6 +505,11 @@ sub autotimer {
}
}
+ &bench('AUTOTIMER');
+ my $seconds = &bench()->{'AUTOTIMER'};
+ lg sprintf("Runtime %s seconds", $seconds);
+
+
$waiter->next(undef,undef,gettext('Read new timers into database.'))
if(ref $waiter);
@@ -986,39 +1022,43 @@ sub list {
my $text = shift || '';
my $params = shift;
- my $where = '';
- if($text =~ /^.*?/) {
- if($text =~ /^[0-9]+?/) {
- $where = "WHERE Id = '$text'";
- } elsif($text) {
- $where = 'WHERE '.buildsearch("Search,Dir",$text);
- }
- }
+ my $term;
+ my $search = '';
+ if($text and $text =~ /^[0-9,_ ]+$/ ) {
+ my @timers = split(/[^0-9]/, $text);
+ $search = sprintf(" WHERE Id in (%s)",join(',' => ('?') x @timers));
+ foreach(@timers) { push(@{$term},$_); }
+
+ } elsif($text) {
+ my $query = buildsearch("Search,Dir",$text);
+ $search = sprintf('WHERE %s', $query->{query});
+ foreach(@{$query->{term}}) { push(@{$term},$_); }
+ }
my %f = (
- 'Id' => umlaute(gettext('Service')),
- 'Act' => umlaute(gettext('Act')),
- 'Search' => umlaute(gettext('Search')),
- 'Channels' => umlaute(gettext('Channels')),
- 'Start' => umlaute(gettext('Start')),
- 'Stop' => umlaute(gettext('Stop')),
- 'Dir' => umlaute(gettext('Dir')),
- 'Min' => umlaute(gettext('Min')),
+ 'Id' => gettext('Service'),
+ 'Activ' => gettext('Activ'),
+ 'Search' => gettext('Search'),
+ 'Channels' => gettext('Channels'),
+ 'Start' => gettext('Start'),
+ 'Stop' => gettext('Stop'),
+ 'Dir' => gettext('Directory'),
+ 'Min' => gettext('Minimum length'),
);
my $sql = qq|
SELECT SQL_CACHE
- Id as $f{'Id'},
- Activ as $f{'Act'},
- Search as $f{'Search'},
- Channels as $f{'Channels'},
- Dir as $f{'Dir'},
- Start as $f{'Start'},
- Stop as $f{'Stop'},
- MinLength as $f{'Min'}
+ Id as \'$f{'Id'}\',
+ Activ as \'$f{'Activ'}\',
+ Search as \'$f{'Search'}\',
+ Channels as \'$f{'Channels'}\',
+ Dir as \'$f{'Dir'}\',
+ Start as \'$f{'Start'}\',
+ Stop as \'$f{'Stop'}\',
+ MinLength as \'$f{'Min'}\'
FROM
AUTOTIMER
- $where
+ $search
|;
my $fields = fields($obj->{dbh}, $sql);
@@ -1032,7 +1072,10 @@ sub list {
else {
$sql .= " asc"; }
- my $erg = $obj->{dbh}->selectall_arrayref($sql);
+ my $sth = $obj->{dbh}->prepare($sql);
+ $sth->execute(@{$term})
+ or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
+ my $erg = $sth->fetchall_arrayref();
unshift(@$erg, $fields);
my $channels = main::getModule('CHANNELS')->ChannelHash('Id');
@@ -1054,51 +1097,61 @@ sub _eventsearch {
my $obj = shift || return error('No object defined!');
my $a = shift || return error('No data defined!');
my $timermod = shift || main::getModule('TIMERS') || return error ("Couldn't access modul TIMERS!");
+ my $addtime = shift;
# Searchstrings to Paragraphs Changed
$a->{Search} =~ s/\:/\:\.\*/
if($a->{InFields} =~ /description/);
- my $search = buildsearch($a->{InFields}, $a->{Search});
+ my $query = buildsearch($a->{InFields}, $a->{Search});
+ my $search = $query->{query};
+ my $term = $query->{term};
# Start and Stop
if($a->{Start} and $a->{Stop}) {
if($a->{Start} > $a->{Stop}) {
- $search .= "\n AND ((DATE_FORMAT(e.starttime, '%H%i') > $a->{Start} AND DATE_FORMAT(e.starttime, '%H%i') < 2359) OR (DATE_FORMAT(e.starttime, '%H%i') >= 0 and DATE_FORMAT(e.starttime, '%H%i') < $a->{Stop}))";
+ $search .= "\n AND ((DATE_FORMAT(e.starttime, '%H%i') > ? AND DATE_FORMAT(e.starttime, '%H%i') < 2359) OR (DATE_FORMAT(e.starttime, '%H%i') >= 0 and DATE_FORMAT(e.starttime, '%H%i') < ?))";
} else {
- $search .= "\n AND (DATE_FORMAT(e.starttime, '%H%i') > $a->{Start} AND DATE_FORMAT(e.starttime, '%H%i') < $a->{Stop})";
+ $search .= "\n AND (DATE_FORMAT(e.starttime, '%H%i') > ? AND DATE_FORMAT(e.starttime, '%H%i') < ?)";
}
+ push(@{$term},$a->{Start});
+ push(@{$term},$a->{Stop});
}
# Min Length
if(exists $a->{MinLength} and $a->{MinLength}) {
- $search .= sprintf(" AND e.duration >= %d ", $a->{MinLength} * 60);
+ $search .= " AND e.duration >= ?";
+ push(@{$term},$a->{MinLength} * 60);
}
# Channels
if($a->{Channels} and my @channelids = split(',', $a->{Channels})) {
- @channelids = map {$_ = "'$_'"} @channelids;
- $search = sprintf(' %s AND channel_id in (%s)', $search, join(',', @channelids));
+ $search .= sprintf(" AND channel_id in (%s)",join(',' => ('?') x @channelids));
+ foreach(@channelids) {
+ push(@{$term},$_);
+ }
}
# Weekdays
if($a->{Weekdays} and my @weekdays = split(',', $a->{Weekdays})) {
if(scalar @weekdays != 7 and scalar @weekdays != 0) {
- @weekdays = map {$_ = "'$_'"} @weekdays;
- $search = sprintf(' %s AND DATE_FORMAT(e.starttime, \'%%a\') in (%s)', $search, join(',', @weekdays));
+ $search .= sprintf(" AND DATE_FORMAT(e.starttime, \'%%a\') in (%s)",join(',' => ('?') x @weekdays));
+ foreach(@weekdays) {
+ push(@{$term},$_);
+ }
}
}
# Exclude channels, ifn't already lookup for channels
- if($obj->{exclude} && not $a->{Channels}) {
- $search = sprintf(' %s AND NOT (c.%s)', $search, $obj->{exclude});
+ if($obj->{exclude} && not $a->{Channels} && not $addtime) {
+ $search .= sprintf(' AND NOT (c.%s)', $obj->{exclude});
}
# Custom time range
my $after = 0;
my $prev = 0;
# if($a->{VPS} ne 'y') {
- if(defined $a->{prevminutes}) {
+ if(defined $a->{prevminutes}) {
$prev = $a->{prevminutes} * 60;
} else {
$prev = $timermod->{prevminutes} * 60;
@@ -1110,6 +1163,8 @@ sub _eventsearch {
}
# }
+ my $table = $addtime ? 'TEMPEPG' : 'EPG';
+
# Search for events
my $sql = qq|
SELECT SQL_CACHE
@@ -1120,23 +1175,25 @@ SELECT SQL_CACHE
e.title as Title,
e.subtitle as Subtitle,
e.description as Summary,
- DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) - $prev ), '%d') as Day,
- DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) - $prev ), '%H%i') as Start,
- DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) + e.duration + $after ), '%H%i') as Stop,
+ DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) - ? ), '%d') as Day,
+ DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) - ? ), '%H%i') as Start,
+ DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.starttime) + e.duration + ? ), '%H%i') as Stop,
DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.vpstime)), '%d') as VpsDay,
DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.vpstime)), '%H%i') as VpsStart,
DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(e.vpstime) + e.duration), '%H%i') as VpsStop
FROM
- EPG as e,
+ $table as e,
CHANNELS as c
WHERE
( $search )
AND ( e.channel_id = c.Id )|;
#dumper $sql;
- my $data = $obj->{dbh}->selectall_hashref($sql, 'eventid');
- return $data;
+ my $sth = $obj->{dbh}->prepare($sql);
+ $sth->execute($prev,$prev,$after,@{$term})
+ or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
+ return $sth->fetchall_hashref('eventid');
}
# ------------------
diff --git a/lib/XXV/MODULES/CHANNELS.pm b/lib/XXV/MODULES/CHANNELS.pm
index 1bab6a5..d2f7fe0 100644
--- a/lib/XXV/MODULES/CHANNELS.pm
+++ b/lib/XXV/MODULES/CHANNELS.pm
@@ -190,15 +190,20 @@ sub _init {
# ------------------
my $obj = shift || return error('No object defined!');
- return 0, panic("Session to database is'nt connected")
- unless($obj->{dbh});
+ unless($obj->{dbh}) {
+ panic("Session to database is'nt connected");
+ return 0;
+ }
- # remove old table, if updated rows
- tableUpdated($obj->{dbh},'CHANNELS',16,1);
- tableUpdated($obj->{dbh},'CHANNELGROUPS',3,1);
+ my $version = 26; # Must be increment if rows of table changed
+ # this tables hasen't handmade user data,
+ # therefore old table could dropped if updated rows
+ if(!tableUpdated($obj->{dbh},'CHANNELS',$version,1)
+ || !tableUpdated($obj->{dbh},'CHANNELGROUPS',$version,1)) {
+ return 0;
+ }
# Look for table or create this table
- my $version = main::getVersion;
$obj->{dbh}->do(qq|
CREATE TABLE IF NOT EXISTS CHANNELS (
Id varchar(100) NOT NULL,
diff --git a/lib/XXV/MODULES/CHRONICLE.pm b/lib/XXV/MODULES/CHRONICLE.pm
index 8cfc1ae..a3c177d 100644
--- a/lib/XXV/MODULES/CHRONICLE.pm
+++ b/lib/XXV/MODULES/CHRONICLE.pm
@@ -92,14 +92,19 @@ sub _init {
my $self = shift || return error('No object defined!');
if($self->{active} eq 'y') {
- return 0, panic("Session to database is'nt connected")
- unless($self->{dbh});
+ unless($self->{dbh}) {
+ panic("Session to database is'nt connected");
+ return 0;
+ }
+
+ my $version = main::getDBVersion();
# don't remove old table, if updated rows => warn only
- tableUpdated($self->{dbh},'CHRONICLE',6,0);
+ if(!tableUpdated($self->{dbh},'CHRONICLE',$version,0)) {
+ return 0;
+ }
# Look for table or create this table
- my $version = main::getVersion;
$self->{dbh}->do(qq|
CREATE TABLE IF NOT EXISTS CHRONICLE (
id int unsigned auto_increment not NULL,
@@ -157,23 +162,23 @@ sub list {
my $console = shift || return error('No console defined!');
my %f = (
- 'id' => umlaute(gettext('Service')),
- 'title' => umlaute(gettext('Title')),
- 'subtitle' => umlaute(gettext('Subtitle')),
- 'channel' => umlaute(gettext('Channel')),
- 'day' => umlaute(gettext('Day')),
- 'start' => umlaute(gettext('Start')),
- 'stop' => umlaute(gettext('Stop'))
+ 'id' => gettext('Service'),
+ 'title' => gettext('Title'),
+ 'subtitle' => gettext('Subtitle'),
+ 'channel' => gettext('Channel'),
+ 'day' => gettext('Day'),
+ 'start' => gettext('Start'),
+ 'stop' => gettext('Stop')
);
my $sql = qq|
SELECT SQL_CACHE
- CHRONICLE.id as $f{'id'},
- CHRONICLE.title as $f{'title'},
- CHRONICLE.channel_id as $f{'channel'},
- DATE_FORMAT(CHRONICLE.starttime, '%d.%m.%Y') as $f{'day'},
- DATE_FORMAT(CHRONICLE.starttime, '%H:%i') as $f{'start'},
- DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(CHRONICLE.starttime) + CHRONICLE.duration), '%H:%i') as $f{'stop'}
+ CHRONICLE.id as \'$f{'id'}\',
+ CHRONICLE.title as \'$f{'title'}\',
+ CHRONICLE.channel_id as \'$f{'channel'}\',
+ DATE_FORMAT(CHRONICLE.starttime, '%d.%m.%Y') as \'$f{'day'}\',
+ DATE_FORMAT(CHRONICLE.starttime, '%H:%i') as \'$f{'start'}\',
+ DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(CHRONICLE.starttime) + CHRONICLE.duration), '%H:%i') as \'$f{'stop'}\'
FROM CHRONICLE
ORDER BY CHRONICLE.starttime
|;
@@ -197,23 +202,23 @@ sub search {
$quest =~ s/\+/\\\\\+/sg;
my %f = (
- 'id' => umlaute(gettext('Service')),
- 'title' => umlaute(gettext('Title')),
- 'subtitle' => umlaute(gettext('Subtitle')),
- 'channel' => umlaute(gettext('Channel')),
- 'day' => umlaute(gettext('Day')),
- 'start' => umlaute(gettext('Start')),
- 'stop' => umlaute(gettext('Stop'))
+ 'id' => gettext('Service'),
+ 'title' => gettext('Title'),
+ 'subtitle' => gettext('Subtitle'),
+ 'channel' => gettext('Channel'),
+ 'day' => gettext('Day'),
+ 'start' => gettext('Start'),
+ 'stop' => gettext('Stop')
);
my $sql = qq|
SELECT SQL_CACHE
- CHRONICLE.id as $f{'id'},
- CHRONICLE.title as $f{'title'},
- CHRONICLE.channel_id as $f{'channel'},
- DATE_FORMAT(CHRONICLE.starttime, '%d.%m.%Y') as $f{'day'},
- DATE_FORMAT(CHRONICLE.starttime, '%H:%i') as $f{'start'},
- DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(CHRONICLE.starttime) + CHRONICLE.duration), '%H:%i') as $f{'stop'}
+ CHRONICLE.id as \'$f{'id'}\',
+ CHRONICLE.title as \'$f{'title'}\',
+ CHRONICLE.channel_id as \'$f{'channel'}\',
+ DATE_FORMAT(CHRONICLE.starttime, '%d.%m.%Y') as \'$f{'day'}\',
+ DATE_FORMAT(CHRONICLE.starttime, '%H:%i') as \'$f{'start'}\',
+ DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(CHRONICLE.starttime) + CHRONICLE.duration), '%H:%i') as \'$f{'stop'}\'
FROM CHRONICLE
WHERE CHRONICLE.title RLIKE ?
ORDER BY CHRONICLE.starttime
diff --git a/lib/XXV/MODULES/CONFIG.pm b/lib/XXV/MODULES/CONFIG.pm
index 213cd6d..993abeb 100644
--- a/lib/XXV/MODULES/CONFIG.pm
+++ b/lib/XXV/MODULES/CONFIG.pm
@@ -108,7 +108,8 @@ sub menu {
my $mods = main::getModules;
foreach my $module (sort keys %{$mods}) {
my $name = $mods->{$module}->{MOD}->{Name};
- next unless(exists $obj->{config}->{$name});
+ error(sprintf("Missing real modul name %s",$module)) unless($name);
+ next unless($name && exists $obj->{config}->{$name});
$ret->{links}->{$name} = {
text => $name,
@@ -331,8 +332,12 @@ sub usage {
# Search for command and display the Description
foreach my $modName (sort keys %{$mods}) {
my $modCfg = $mods->{$modName}->{MOD};
- push(@realModName, $mods->{$modName}->{MOD}->{Name});
- next if($modulename and uc($modulename) ne $modCfg->{Name});
+
+ my $name = $modCfg->{Name};
+ error(sprintf("Missing real modul name %s",$modName)) unless($name);
+ push(@realModName, $name) if($name);
+
+ next if($modulename and uc($modulename) ne $name);
foreach my $cmdName (sort keys %{$modCfg->{Commands}}) {
push(@$ret,
[
diff --git a/lib/XXV/MODULES/EPG.pm b/lib/XXV/MODULES/EPG.pm
index 440c629..ed0319c 100644
--- a/lib/XXV/MODULES/EPG.pm
+++ b/lib/XXV/MODULES/EPG.pm
@@ -197,18 +197,29 @@ sub _init {
# ------------------
my $obj = shift || return error('No object defined!');
- return 0, panic("Session to database is'nt connected")
- unless($obj->{dbh});
+ unless($obj->{dbh}) {
+ panic("Session to database is'nt connected");
+ return 0;
+ }
+
+ my $version = 26; # Must be increment if rows of table changed
+ # this tables hasen't handmade user data,
+ # therefore old table could dropped if updated rows
# Look for table or create this table
- foreach my $table (qw/EPG OLDEPG/) {
+ foreach my $table (qw/EPG OLDEPG TEMPEPG/) {
- # remove old table, if updated rows
- tableUpdated($obj->{dbh},$table,14,1);
+ # remove old table, if updated version
+ if(!tableUpdated($obj->{dbh},$table,$version,1)) {
+ return 0;
+ }
+
+ # Create TEMPEPG as temporary table,
+ # which only used inside AUTOTIMER and dropped at shutdown
+ my $temp = $table eq 'TEMPEPG' ? 'TEMPORARY' : '';
- my $version = main::getVersion;
$obj->{dbh}->do(qq|
- CREATE TABLE IF NOT EXISTS $table (
+ CREATE $temp TABLE IF NOT EXISTS $table (
eventid bigint unsigned NOT NULL default '0',
title text NOT NULL default '',
subtitle text default '',
@@ -592,40 +603,35 @@ sub search {
}
}
+ my $erg = [];
+ if($search) {
+
# Channelsearch
if($params->{channel}) {
- $search .= ' AND '
- if($search);
- $search .= sprintf('c.POS = %lu ', $params->{channel});
+ $search->{query} .= ' AND c.POS = ?';
+ push(@{$search->{term}},$params->{channel});
}
# Videoformat search
if($params->{Videoformat} && $params->{Videoformat} eq 'widescreen') {
- $search .= ' AND '
- if($search);
- $search .= 'e.video like "%%16:9%%" ';
+ $search->{query} .= ' AND e.video like "%%16:9%%"';
}
# Audioformat search
# XXX: Leider kann man an den Audioeintrag nicht richtig erkennnen
# hab erst zu spät erkannt das diese Info aus dem tvm2vdr kommen ;(
# if($params->{Audioformat} eq 'dts') {
-# $search .= ' AND '
-# if($search);
-# $search .= 'e.audio like "%%Digital%%" ';
+# $search->{query} .= ' AND e.audio like "%%Digital%%"';
# }
# MinLength search
if($params->{MinLength}) {
- $search .= ' AND '
- if($search);
- $search .= sprintf('e.duration >= %d ', ($params->{MinLength}*60));
+ $search->{query} .= ' AND e.duration >= ?';
+ push(@{$search->{term}},($params->{MinLength}*60));
}
- my $erg = [];
- if($search) {
- my $sql = qq|
+ my $sql = qq|
SELECT SQL_CACHE
e.eventid as Service,
e.title as Title,
@@ -642,14 +648,16 @@ sub search {
CHANNELS as c
where
e.channel_id = c.Id
- AND ( $search )
+ AND ( $search->{query} )
order by
starttime
|;
- #dumper($sql);
my $fields = fields($obj->{dbh}, $sql);
+ my $sth = $obj->{dbh}->prepare($sql);
+ $sth->execute(@{$search->{term}})
+ or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
+ $erg = $sth->fetchall_arrayref();
- $erg = $obj->{dbh}->selectall_arrayref($sql);
unshift(@$erg, $fields);
}
$console->table($erg, {
@@ -730,14 +738,14 @@ sub display {
}
my %f = (
- 'Id' => umlaute(gettext('Service')),
- 'Title' => umlaute(gettext('Title')),
- 'Subtitle' => umlaute(gettext('Subtitle')),
- 'Channel' => umlaute(gettext('Channel')),
- 'Start' => umlaute(gettext('Start')),
- 'Stop' => umlaute(gettext('Stop')),
- 'Description' => umlaute(gettext('Description')),
- 'Percent' => umlaute(gettext('Percent')),
+ 'Id' => gettext('Service'),
+ 'Title' => gettext('Title'),
+ 'Subtitle' => gettext('Subtitle'),
+ 'Channel' => gettext('Channel'),
+ 'Start' => gettext('Start'),
+ 'Stop' => gettext('Stop'),
+ 'Description' => gettext('Description'),
+ 'Percent' => gettext('Percent')
);
my $fields;
@@ -754,15 +762,15 @@ sub display {
foreach my $table (qw/EPG OLDEPG/) {
my $sql = qq|
SELECT SQL_CACHE
- e.eventid as $f{'Id'},
- e.title as $f{'Title'},
- e.subtitle as $f{'Subtitle'},
- $start as $f{'Start'},
- $stopp as $f{'Stop'},
- c.Name as $f{'Channel'},
- e.description as $f{'Description'},
+ e.eventid as \'$f{'Id'}\',
+ e.title as \'$f{'Title'}\',
+ e.subtitle as \'$f{'Subtitle'}\',
+ $start as \'$f{'Start'}\',
+ $stopp as \'$f{'Stop'}\',
+ c.Name as \'$f{'Channel'}\',
+ e.description as \'$f{'Description'}\',
e.image as __Image,
- (unix_timestamp(e.starttime) + e.duration - unix_timestamp())/duration*100 as $f{'Percent'},
+ (unix_timestamp(e.starttime) + e.duration - unix_timestamp())/duration*100 as \'$f{'Percent'}\',
e.video as __Video,
e.audio as __Audio,
IF(e.vpstime!=0,$vps,'') as __VPS
@@ -832,23 +840,23 @@ GROUP BY c.Id
or return error sprintf("Couldn't execute query: %s.",$sthtemp->errstr);
my %f = (
- 'Service' => umlaute(gettext('Service')),
- 'Title' => umlaute(gettext('Title')),
- 'Channel' => umlaute(gettext('Channel')),
- 'Start' => umlaute(gettext('Start')),
- 'Stop' => umlaute(gettext('Stop'))
+ 'Service' => gettext('Service'),
+ 'Title' => gettext('Title'),
+ 'Channel' => gettext('Channel'),
+ 'Start' => gettext('Start'),
+ 'Stop' => gettext('Stop')
);
my $sql =
qq|
SELECT SQL_CACHE
- e.eventid as $f{'Service'},
- e.title as $f{'Title'},
+ e.eventid as \'$f{'Service'}\',
+ e.title as \'$f{'Title'}\',
e.subtitle as __Subtitle,
- c.Name as $f{'Channel'},
+ c.Name as \'$f{'Channel'}\',
c.POS as __POS,
g.Name as __Channelgroup,
- DATE_FORMAT(e.starttime, "%H:%i") as $f{'Start'},
- DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(starttime) + e.duration), "%H:%i") as $f{'Stop'},
+ DATE_FORMAT(e.starttime, "%H:%i") as \'$f{'Start'}\',
+ DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(starttime) + e.duration), "%H:%i") as \'$f{'Stop'}\',
e.description as __Description,
999 as __Percent,
IF(e.vpstime!=0,DATE_FORMAT(e.vpstime, '%H:%i'),'') as __VPS
@@ -906,26 +914,26 @@ sub runningNow {
$zeit++;
my %f = (
- 'Service' => umlaute(gettext('Service')),
- 'Title' => umlaute(gettext('Title')),
- 'Channel' => umlaute(gettext('Channel')),
- 'Start' => umlaute(gettext('Start')),
- 'Stop' => umlaute(gettext('Stop')),
- 'Percent' => umlaute(gettext('Percent')),
+ 'Service' => gettext('Service'),
+ 'Title' => gettext('Title'),
+ 'Channel' => gettext('Channel'),
+ 'Start' => gettext('Start'),
+ 'Stop' => gettext('Stop'),
+ 'Percent' => gettext('Percent')
);
my $sql =
qq|
SELECT SQL_CACHE
- e.eventid as $f{'Service'},
- e.title as $f{'Title'},
+ e.eventid as \'$f{'Service'}\',
+ e.title as \'$f{'Title'}\',
e.subtitle as __Subtitle,
- c.Name as $f{'Channel'},
+ c.Name as \'$f{'Channel'}\',
c.POS as __POS,
g.Name as __Channelgroup,
- DATE_FORMAT(e.starttime, "%H:%i") as $f{'Start'},
- DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(starttime) + e.duration), "%H:%i") as $f{'Stop'},
+ DATE_FORMAT(e.starttime, "%H:%i") as \'$f{'Start'}\',
+ DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP(starttime) + e.duration), "%H:%i") as \'$f{'Stop'}\',
e.description as __Description,
- (unix_timestamp(e.starttime) + e.duration - unix_timestamp())/e.duration*100 as $f{'Percent'},
+ (unix_timestamp(e.starttime) + e.duration - unix_timestamp())/e.duration*100 as \'$f{'Percent'}\',
IF(e.vpstime!=0,DATE_FORMAT(e.vpstime, '%H:%i'),'') as __VPS
FROM
EPG as e, CHANNELS as c, CHANNELGROUPS as g
diff --git a/lib/XXV/MODULES/MEDIALIB.pm b/lib/XXV/MODULES/MEDIALIB.pm
index b0f78f6..83d5593 100644
--- a/lib/XXV/MODULES/MEDIALIB.pm
+++ b/lib/XXV/MODULES/MEDIALIB.pm
@@ -193,16 +193,20 @@ sub _init {
# ------------------
my $obj = shift || return error('No object defined!');
- return 0, panic("Session to database is'nt connected")
- unless($obj->{dbh});
+ unless($obj->{dbh}) {
+ panic("Session to database is'nt connected");
+ return 0;
+ }
+ my $version = main::getDBVersion();
# don't remove old table, if updated rows => warn only
- tableUpdated($obj->{dbh},'MEDIALIB_ACTORS',4,0);
- tableUpdated($obj->{dbh},'MEDIALIB_VIDEODATA',33,0);
- tableUpdated($obj->{dbh},'MEDIALIB_VIDEOGENRE',2,0);
+ if(!tableUpdated($obj->{dbh},'MEDIALIB_ACTORS',$version,0)
+ ||!tableUpdated($obj->{dbh},'MEDIALIB_VIDEODATA',$version,0)
+ ||!tableUpdated($obj->{dbh},'MEDIALIB_VIDEOGENRE',$version,0)) {
+ return 0;
+ }
# Look for tables or create this tables
- my $version = main::getVersion;
$obj->{dbh}->do(qq|
CREATE TABLE IF NOT EXISTS MEDIALIB_ACTORS (
name varchar(255) NOT NULL default '',
diff --git a/lib/XXV/MODULES/MUSIC.pm b/lib/XXV/MODULES/MUSIC.pm
index 3bfc3e9..424f27e 100644
--- a/lib/XXV/MODULES/MUSIC.pm
+++ b/lib/XXV/MODULES/MUSIC.pm
@@ -280,11 +280,18 @@ sub _init {
);
unless($obj->{mdbh}) {
- # Look for table or create this table
- my $version = main::getVersion;
- # don't remove old table, if updated rows => warn only
- tableUpdated($obj->{dbh},'MUSIC',12,0);
+ unless($obj->{dbh}) {
+ panic("Session to database is'nt connected");
+ return 0;
+ }
+
+ my $version = 26; # Must be increment if rows of table changed
+ # this tables hasen't handmade user data,
+ # therefore old table could dropped if updated rows
+ if(!tableUpdated($obj->{dbh},'MUSIC',$version,1)) {
+ return 0;
+ }
$obj->{dbh}->do(qq|
CREATE TABLE IF NOT EXISTS MUSIC (
@@ -527,7 +534,7 @@ sub list {
my $obj = shift || return error('No object defined!');
my $watcher = shift || return error('No watcher defined!');
my $console = shift || return error('No console defined!');
- my $search = shift;
+ my $param = shift;
my $dbh = ($obj->{mdbh} ? $obj->{mdbh} : $obj->{dbh});
return 0
@@ -537,17 +544,17 @@ sub list {
$obj->{GENRES} = $dbh->selectall_hashref('SELECT SQL_CACHE * from genre', 'id')
if($obj->{mdbh} && !$obj->{GENRES});
- if($obj->{mdbh} && ! $search) {
+ if($obj->{mdbh} && ! $param) {
my $eg = $dbh->selectrow_arrayref('SELECT SQL_CACHE title from album limit 1')
|| return $console->err($obj->{mdbh}->errstr);
- $search = sprintf('album:%s', $eg->[0]);
- } elsif(! $search) {
+ $param = sprintf('album:%s', $eg->[0]);
+ } elsif(! $param) {
my $eg = $dbh->selectrow_arrayref('SELECT SQL_CACHE ALBUM from MUSIC limit 1')
|| return $console->err($dbh->errstr);
- $search = sprintf('album:%s', $eg->[0]);
+ $param = sprintf('album:%s', $eg->[0]);
}
- my @field = split(':',$search);
+ my @field = split(':',$param);
my $typ = $field[0];
# Muggleübersetzer ;)
@@ -574,29 +581,36 @@ sub list {
$t = ($obj->{mdbh} ? 'tracks.'.$translate->{$typ} : uc($typ));
}
- my $where;
+ my $search = '';
+ my $term;
if($typ eq 'search') {
if($obj->{mdbh}) {
- $where = buildsearch("album.artist,tracks.artist,album.title,tracks.title,album.covertxt",$text);
+ my $query = buildsearch("album.artist,tracks.artist,album.title,tracks.title,album.covertxt",$text);
+ $search = $query->{query};
+ foreach(@{$query->{term}}) { push(@{$term},$_); }
+ foreach(@{$query->{term}}) { push(@{$term},$_); } #double for UNION
} else {
- $where = buildsearch("ALBUM,ARTIST,TITLE,COMMENT",$text);
+ my $query = buildsearch("ALBUM,ARTIST,TITLE,COMMENT",$text);
+ $search = $query->{query};
+ foreach(@{$query->{term}}) { push(@{$term},$_); }
}
} elsif($typ eq 'genre' && $obj->{mdbh}) {
- $text =~ s/\'/\\'/sg;#'
- $where = sprintf("%s LIKE '%s%%'", $t, $text);
+ $search = sprintf("%s LIKE ?", $t); #?%
+ push(@{$term},$text.'%');
} else {
- $text =~ s/\'/\\'/sg;#'
- $where = sprintf("%s LIKE '%%%s%%'", $t, $text);
+ $search = sprintf("%s RLIKE ?", $t); #%?%
+ push(@{$term},$text);
+ push(@{$term},$text) if($obj->{mdbh});
}
my %f = (
- 'Id' => umlaute(gettext('Sv')),
- 'Artist' => umlaute(gettext('Artist')),
- 'Album' => umlaute(gettext('Album')),
- 'Title' => umlaute(gettext('Title')),
- 'Tracknum' => umlaute(gettext('Tracknum')),
- 'Year' => umlaute(gettext('Year')),
- 'Length' => umlaute(gettext('Length')),
+ 'Id' => gettext('Service'),
+ 'Artist' => gettext('Artist'),
+ 'Album' => gettext('Album'),
+ 'Title' => gettext('Title'),
+ 'Tracknum' => gettext('Number of track'),
+ 'Year' => gettext('Year'),
+ 'Length' => gettext('Length')
);
my $sql;
@@ -604,13 +618,13 @@ sub list {
$sql = qq|
SELECT SQL_CACHE
- tracks.id as $f{'Id'},
- tracks.artist as $f{'Artist'},
- album.title as $f{'Album'},
- tracks.title as $f{'Title'},
- tracks.tracknb as $f{'Tracknum'},
- tracks.year as $f{'Year'},
- IF(tracks.length >= 3600,SEC_TO_TIME(tracks.length),DATE_FORMAT(FROM_UNIXTIME(tracks.length), '%i:%s')) as $f{'Length'},
+ tracks.id as \'$f{'Id'}\',
+ tracks.artist as \'$f{'Artist'}\',
+ album.title as \'$f{'Album'}\',
+ tracks.title as \'$f{'Title'}\',
+ tracks.tracknb as \'$f{'Tracknum'}\',
+ tracks.year as \'$f{'Year'}\',
+ IF(tracks.length >= 3600,SEC_TO_TIME(tracks.length),DATE_FORMAT(FROM_UNIXTIME(tracks.length), '%i:%s')) as \'$f{'Length'}\',
genre.genre as __GENRE,
album.covertxt as __COMMENT
FROM
@@ -618,20 +632,20 @@ sub list {
WHERE
tracks.sourceid = album.cddbid and
tracks.genre1 = genre.id and
- ( $where )
+ $search
|;
$sql .= qq|
UNION
SELECT SQL_CACHE
- tracks.id as $f{'Id'},
- tracks.artist as $f{'Artist'},
- album.title as $f{'Album'},
- tracks.title as $f{'Title'},
- tracks.tracknb as $f{'Tracknum'},
- tracks.year as $f{'Year'},
- IF(tracks.length >= 3600,SEC_TO_TIME(tracks.length),DATE_FORMAT(FROM_UNIXTIME(tracks.length), '%i:%s')) as $f{'Length'},
+ tracks.id as \'$f{'Id'}\',
+ tracks.artist as \'$f{'Artist'}\',
+ album.title as \'$f{'Album'}\',
+ tracks.title as \'$f{'Title'}\',
+ tracks.tracknb as \'$f{'Tracknum'}\',
+ tracks.year as \'$f{'Year'}\',
+ IF(tracks.length >= 3600,SEC_TO_TIME(tracks.length),DATE_FORMAT(FROM_UNIXTIME(tracks.length), '%i:%s')) as \'$f{'Length'}\',
"" as __GENRE,
album.covertxt as __COMMENT
FROM
@@ -639,41 +653,46 @@ sub list {
WHERE
tracks.sourceid = album.cddbid and
tracks.genre1 = 'NULL' and
- ( $where )
+ $search
+
| if($typ ne 'genre');
$sql .= qq|
ORDER BY
- $f{'Album'},
- $f{'Tracknum'}
+ \'$f{'Album'}\',
+ \'$f{'Tracknum'}\'
|;
} else {
$sql = qq|
SELECT SQL_CACHE
- ID as $f{'Id'},
- ARTIST as $f{'Artist'},
- ALBUM as $f{'Album'},
- TITLE as $f{'Title'},
- TRACKNUM as $f{'Tracknum'},
- YEAR as $f{'Year'},
- IF(SECS >= 3600,SEC_TO_TIME(SECS),DATE_FORMAT(FROM_UNIXTIME(SECS), '%i:%s')) as $f{'Length'},
+ ID as \'$f{'Id'}\',
+ ARTIST as \'$f{'Artist'}\',
+ ALBUM as \'$f{'Album'}\',
+ TITLE as \'$f{'Title'}\',
+ TRACKNUM as \'$f{'Tracknum'}\',
+ YEAR as \'$f{'Year'}\',
+ IF(SECS >= 3600,SEC_TO_TIME(SECS),DATE_FORMAT(FROM_UNIXTIME(SECS), '%i:%s')) as \'$f{'Length'}\',
GENRE as __GENRE,
COMMENT as __COMMENT
FROM
MUSIC
WHERE
- ( $where )
+ 1 AND
+ $search
ORDER BY
FILE
|;
}
my $fields = fields($dbh, $sql);
- my $erg = $dbh->selectall_arrayref($sql);
+ my $sth = $dbh->prepare($sql);
+ $sth->execute(@{$term})
+ or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
+ my $erg = $sth->fetchall_arrayref();
unshift(@$erg, $fields);
my $params = {
diff --git a/lib/XXV/MODULES/RECORDS.pm b/lib/XXV/MODULES/RECORDS.pm
index 27c7893..792f832 100644
--- a/lib/XXV/MODULES/RECORDS.pm
+++ b/lib/XXV/MODULES/RECORDS.pm
@@ -22,6 +22,7 @@ sub module {
Name => 'RECORDS',
Prereq => {
'Time::Local' => 'efficiently compute time from local and GMT time ',
+ 'Digest::MD5 qw(md5_hex)' => 'Perl interface to the MD5 Algorithm'
},
Description => gettext('This module manages recordings.'),
Version => (split(/ /, '$Revision$'))[1],
@@ -256,11 +257,14 @@ sub _init {
return 0;
}
- # remove old table, if updated rows
- tableUpdated($obj->{dbh},'RECORDS',11,1);
+ my $version = 26; # Must be increment if rows of table changed
+ # this tables hasen't handmade user data,
+ # therefore old table could dropped if updated rows
+ if(!tableUpdated($obj->{dbh},'RECORDS',$version,1)) {
+ return 0;
+ }
# Look for table or create this table
- my $version = main::getVersion;
$obj->{dbh}->do(qq|
CREATE TABLE IF NOT EXISTS RECORDS (
eventid bigint unsigned NOT NULL,
@@ -387,7 +391,8 @@ sub readData {
my $watcher = shift;
my $console = shift;
my $waiter = shift;
- my $forceUpdate = shift;
+ # Read manual or Once at day, make full scan
+ my $forceUpdate = shift || ($obj->{countReading} % ( $obj->{fullreading} * 3600 / $obj->{interval} ) == 0);
# Read recording over SVDRP
my $lstr = $obj->{svdrp}->command('lstr');
@@ -424,7 +429,7 @@ sub readData {
}
- my @merkIds;
+ my @merkMD5;
my $insertedData = 0;
my $updatedState = 0;
my $l = 0;
@@ -439,8 +444,7 @@ sub readData {
$obj->{FILES} = undef;
my $db_data;
- if($forceUpdate || $obj->{countReading} % ( $obj->{fullreading} * 3600 / $obj->{interval} ) == 0) {
- # Once at day, make full scan
+ if($forceUpdate) {
$obj->{dbh}->do('DELETE FROM RECORDS');
} else {
# read database for compare with vdr data
@@ -497,7 +501,7 @@ sub readData {
$db_data->{$h}->{addtime} = time;
# Make Preview and remove older Preview images
- my $command = $obj->videoPreview( $db_data->{$h}->{eventid}, $db_data->{$h}, 1);
+ my $command = $obj->videoPreview( $db_data->{$h}, 1);
push(@{$obj->{JOBS}}, $command)
if($command && not grep(/\Q$command/g,@{$obj->{JOBS}}));
}
@@ -514,7 +518,7 @@ sub readData {
$totalDuration += $db_data->{$h}->{duration};
$totalSpace += $db_data->{$h}->{FileSize};
- push(@merkIds,$db_data->{$h}->{eventid});
+ push(@merkMD5,$db_data->{$h}->{RecordMD5});
# delete updated rows from hash
delete $db_data->{$h};
@@ -536,7 +540,7 @@ sub readData {
$totalSpace += $anahash->{FileSize};
if($obj->insert($anahash)) {
- push(@merkIds,$anahash->{eventid});
+ push(@merkMD5,$anahash->{RecordMD5});
$insertedData++;
} else {
push(@{$err},$anahash->{title});
@@ -558,9 +562,10 @@ sub readData {
$sth->execute(@todel)
or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
}
-
+
+ my $removedData = $db_data ? scalar keys %$db_data : 0;
debug sprintf 'Finish .. %d recordings inserted, %d recordings updated, %d recordings removed',
- $insertedData, $updatedState, $db_data ? scalar keys %$db_data : 0;
+ $insertedData, $updatedState, $removedData;
error sprintf("Unsupported unit '%s' to calc free capacity",$freeUnit) unless($freeUnit eq 'MB');
@@ -595,19 +600,25 @@ sub readData {
# alte PreviewDirs loeschen
foreach my $dir (glob(sprintf('%s/*_shot', $obj->{previewimages}))) {
- my $oldEventNumber = (split('/', $dir))[-1];
- unless(grep(sprintf('%lu_shot',$_) eq $oldEventNumber, @merkIds)) {
+ my $basedir = basename($dir);
+ unless(grep(sprintf('%s_shot',$_) eq $basedir, @merkMD5)) {
+ lg sprintf("Remove old preview files : '%s'",$dir);
deleteDir($dir);
}
}
- # Delete all old EPG entrys without the RecordIds which old as one day.
- if(scalar @merkIds) {
- my $sql = sprintf('DELETE FROM OLDEPG where (UNIX_TIMESTAMP(starttime) + duration) < (UNIX_TIMESTAMP() - 86400) and eventid not in (%s)', join(',' => ('?') x @merkIds));
- my $sth = $obj->{dbh}->prepare($sql);
- $sth->execute(@merkIds)
- or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
- }
+ # Delete all old EPG entrys
+ if($forceUpdate || $removedData) {
+ my $sqldeleteEvents = qq|
+DELETE FROM OLDEPG
+ WHERE
+ (UNIX_TIMESTAMP(starttime) + duration) < (UNIX_TIMESTAMP() - 86400)
+ and eventid not in
+ ( SELECT eventid FROM RECORDS )
+|;
+ $obj->{dbh}->do($sqldeleteEvents)
+ or error sprintf("Couldn't execute query: %s, %s.",$sqldeleteEvents, $DBI::errstr);
+ }
$obj->updated() if($insertedData);
@@ -617,9 +628,9 @@ sub readData {
if(ref $console) {
$console->start() if(ref $waiter);
if(scalar @{$err} == 0) {
- $console->message(sprintf(gettext("Write %d recordings to the database."), scalar @merkIds));
+ $console->message(sprintf(gettext("Write %d recordings to the database."), scalar @merkMD5));
} else {
- unshift(@{$err}, sprintf(gettext("Write %d recordings to the database. Couldn't assign %d recordings."), scalar @merkIds , scalar @{$err}));
+ unshift(@{$err}, sprintf(gettext("Write %d recordings to the database. Couldn't assign %d recordings."), scalar @merkMD5 , scalar @{$err}));
lg join("\n", @$err);
$console->err($err);
}
@@ -681,7 +692,7 @@ sub insert {
qq|
REPLACE INTO RECORDS
(eventid, RecordId, RecordMD5, Path, Prio, Lifetime, State, FileSize, Marks, Type )
- VALUES (?,?,md5(?),?,?,?,?,?,?,?)
+ VALUES (?,?,?,?,?,?,?,?,?,?)
|);
$attr->{Marks} = ""
@@ -690,7 +701,7 @@ sub insert {
return $sth->execute(
$attr->{eventid},
$attr->{RecordId},
- $attr->{Path},
+ $attr->{RecordMD5},
$attr->{Path},
$attr->{Prio},
$attr->{Lifetime},
@@ -785,11 +796,12 @@ sub analyze {
}
# Make Preview
- my $command = $obj->videoPreview( $event->{eventid}, $info );
+ my $command = $obj->videoPreview( $info );
push(@{$obj->{JOBS}}, $command)
if($command && not grep(/\Q$command/g,@{$obj->{JOBS}}));
my $ret = {
+ RecordMD5 => $info->{RecordMD5},
title => $recattr->{title},
RecordId => $recattr->{id},
Duration => $info->{duration},
@@ -918,6 +930,7 @@ sub videoInfo {
}
$status->{path} = $path;
+ $status->{RecordMD5} = md5_hex($path);
}
return $status;
@@ -938,9 +951,8 @@ sub qquote {
sub videoPreview {
# ------------------
my $obj = shift || return error('No object defined!');
- my $eventid = shift || return error('No eventid defined!');
my $info = shift || return error ('No information defined!');
- my $rebuild = shift || 0;
+ my $rebuild = shift || 0;
if ($obj->{previewcommand} eq 'Nothing') {
return 0;
@@ -958,7 +970,7 @@ sub videoPreview {
# Save dir
my $count = $obj->{previewcount};
- my $outdir = sprintf('%s/%lu_shot', $obj->{previewimages}, $eventid);
+ my $outdir = sprintf('%s/%s_shot', $obj->{previewimages}, $info->{RecordMD5});
# Stop here if enough files present
my @images = glob("$outdir/*.jpg");
@@ -967,13 +979,10 @@ sub videoPreview {
deleteDir($outdir) if(scalar @images && $rebuild);
- # or stop if two log's present, use two logs avoid to early run on current live recording
- my $log = sprintf('%s/preview_1st.log', $outdir);
+ # or stop if log's present
+ my $log = sprintf('%s/preview.log', $outdir);
if(-e $log) {
- $log = sprintf('%s/preview_2nd.log', $outdir);
- if(-e $log) {
return 0;
- }
}
# Mplayer
@@ -1218,7 +1227,7 @@ where
$obj->_loadreccmds;
my $param = {
- previews => $obj->getPreviewFiles($rec->{eventid}),
+ previews => $obj->getPreviewFiles($rec->{RecordId}),
reccmds => [@{$obj->{reccmds}}],
};
@@ -1301,10 +1310,10 @@ AND (
}
my %f = (
- 'Id' => umlaute(gettext('Service')),
- 'Title' => umlaute(gettext('Title')),
- 'Subtitle' => umlaute(gettext('Subtitle')),
- 'Duration' => umlaute(gettext('Duration')),
+ 'Id' => gettext('Service'),
+ 'Title' => gettext('Title'),
+ 'Subtitle' => gettext('Subtitle'),
+ 'Duration' => gettext('Duration')
);
my $start = "e.starttime";
@@ -1312,11 +1321,11 @@ AND (
my $sql = qq|
SELECT SQL_CACHE
- r.RecordMD5 as $f{'Id'},
+ r.RecordMD5 as \'$f{'Id'}\',
r.eventid as __EventId,
- e.title as $f{'Title'},
- e.subtitle as $f{'Subtitle'},
- SUM(e.duration) as $f{'Duration'},
+ e.title as \'$f{'Title'}\',
+ e.subtitle as \'$f{'Subtitle'}\',
+ SUM(e.duration) as \'$f{'Duration'}\',
$start as __RecordStart,
SUM(State) as __New,
r.Type as __Type,
@@ -1371,13 +1380,15 @@ sub search {
my $text = shift || return $obj->list($watcher,$console);
my $params = shift;
- my $search = buildsearch("e.title,e.subtitle,e.description",$text);
+ my $query = buildsearch("e.title,e.subtitle,e.description",$text);
+ my $search = $query->{query};
+ my $term = $query->{term};
my %f = (
- 'Id' => umlaute(gettext('Service')),
- 'Title' => umlaute(gettext('Title')),
- 'Subtitle' => umlaute(gettext('Subtitle')),
- 'Duration' => umlaute(gettext('Duration')),
+ 'Id' => gettext('Service'),
+ 'Title' => gettext('Title'),
+ 'Subtitle' => gettext('Subtitle'),
+ 'Duration' => gettext('Duration')
);
my $start = "e.starttime";
@@ -1385,11 +1396,11 @@ sub search {
my $sql = qq|
SELECT SQL_CACHE
- r.RecordMD5 as $f{'Id'},
+ r.RecordMD5 as \'$f{'Id'}\',
r.eventid as __EventId,
- e.title as $f{'Title'},
- e.subtitle as $f{'Subtitle'},
- e.duration as $f{'Duration'},
+ e.title as \'$f{'Title'}\',
+ e.subtitle as \'$f{'Subtitle'}\',
+ e.duration as \'$f{'Duration'}\',
$start as __RecordStart ,
r.State as __New,
r.Type as __Type,
@@ -1416,7 +1427,10 @@ WHERE
else {
$sql .= " asc"; }
- my $erg = $obj->{dbh}->selectall_arrayref($sql);
+ my $sth = $obj->{dbh}->prepare($sql);
+ $sth->execute(@{$term})
+ or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
+ my $erg = $sth->fetchall_arrayref();
unshift(@$erg, $fields);
my $param = {
@@ -2002,10 +2016,10 @@ sub IdToPath {
sub getPreviewFiles {
# ------------------
my $obj = shift || return error('No object defined!');
- my $id = shift || return error('No eventid defined!');
+ my $md5 = shift || return error('No eventid defined!');
# look for pictures
- my $outdir = sprintf('%s/%lu_shot', $obj->{previewimages}, $id);
+ my $outdir = sprintf('%s/%s_shot', $obj->{previewimages}, $md5);
if(my @previews = glob("$outdir/[0-9]*.jpg")) {
splice(@previews,$obj->{previewcount},scalar(@previews))
if(scalar(@previews) > $obj->{previewcount});
diff --git a/lib/XXV/MODULES/TIMERS.pm b/lib/XXV/MODULES/TIMERS.pm
index 91e1f09..0db6457 100644
--- a/lib/XXV/MODULES/TIMERS.pm
+++ b/lib/XXV/MODULES/TIMERS.pm
@@ -360,14 +360,19 @@ sub _init {
# ------------------
my $obj = shift || return error('No object defined!');
- return 0, panic("Session to database is'nt connected")
- unless($obj->{dbh});
+ unless($obj->{dbh}) {
+ panic("Session to database is'nt connected");
+ return 0;
+ }
- # remove old table, if updated rows
- tableUpdated($obj->{dbh},'TIMERS',19,1);
+ my $version = 26; # Must be increment if rows of table changed
+ # this tables hasen't handmade user data,
+ # therefore old table could dropped if updated rows
+ if(!tableUpdated($obj->{dbh},'TIMERS',$version,1)) {
+ return 0;
+ }
# Look for table or create this table
- my $version = main::getVersion;
$obj->{dbh}->do(qq|
CREATE TABLE IF NOT EXISTS TIMERS (
Id int(11) unsigned NOT NULL,
@@ -465,7 +470,7 @@ sub saveTimer {
], $pos);
}
- event sprintf('Save timer "%s" with id: "%d"', $data->{File}, $pos);
+ event sprintf('Save timer "%s" with id: "%d"', $data->{File}, $pos || 0);
return $erg;
}
@@ -1064,35 +1069,48 @@ sub list {
my $console = shift || return error('No console defined!');
my $text = shift || '';
- my $in = '';
- if($text and $text =~ /^[0-9,_ ]+$/ ) {
- my @timers = split(/[^0-9]/, $text);
- $in = sprintf("and t.Id in ( %s )",join(',',@timers));
- } elsif($text) {
- $in = sprintf('and ( %s )', buildsearch("t.File,t.Summary",$text));
- }
+ my $term;
+ my $search1 = '';
+ my $search2 = '';
+ if($text and $text =~ /^[0-9,_ ]+$/ ) {
+ my @timers = split(/[^0-9]/, $text);
+ $search1 = sprintf(" AND t.Id in (%s)",join(',' => ('?') x @timers));
+ foreach(@timers) { push(@{$term},$_); }
+ $search2 = sprintf(" AND t.Id in (%s)",join(',' => ('?') x @timers));
+ foreach(@timers) { push(@{$term},$_); }
+
+ } elsif($text) {
+ my $query1 = buildsearch("t.File,e.description",$text);
+ $search1 = sprintf('AND ( %s )', $query1->{query});
+ foreach(@{$query1->{term}}) { push(@{$term},$_); }
+
+ my $query2 = buildsearch("t.File",$text);
+ $search2 = sprintf('AND ( %s )', $query2->{query});
+ foreach(@{$query2->{term}}) { push(@{$term},$_); }
+ }
+
my %f = (
- 'Id' => umlaute(gettext('Sv')),
- 'Status' => umlaute(gettext('Status')),
- 'Day' => umlaute(gettext('Day')),
- 'Channel' => umlaute(gettext('Channel')),
- 'Start' => umlaute(gettext('Start')),
- 'Stop' => umlaute(gettext('Stop')),
- 'Title' => umlaute(gettext('Title')),
- 'Priority' => umlaute(gettext('Priority')),
+ 'Id' => gettext('Service'),
+ 'Status' => gettext('Status'),
+ 'Day' => gettext('Day'),
+ 'Channel' => gettext('Channel'),
+ 'Start' => gettext('Start'),
+ 'Stop' => gettext('Stop'),
+ 'Title' => gettext('Title'),
+ 'Priority' => gettext('Priority')
);
my $sql = qq|
SELECT SQL_CACHE
- t.Id as $f{'Id'},
- t.Status as $f{'Status'},
- c.Name as $f{'Channel'},
+ t.Id as \'$f{'Id'}\',
+ t.Status as \'$f{'Status'}\',
+ c.Name as \'$f{'Channel'}\',
c.Pos as __Pos,
- t.Day as $f{'Day'},
- DATE_FORMAT(t.NextStartTime, '%H:%i') as $f{'Start'},
- DATE_FORMAT(t.NextStopTime, '%H:%i') as $f{'Stop'},
- t.File as $f{'Title'},
- t.Priority as $f{'Priority'},
+ t.Day as \'$f{'Day'}\',
+ DATE_FORMAT(t.NextStartTime, '%H:%i') as \'$f{'Start'}\',
+ DATE_FORMAT(t.NextStopTime, '%H:%i') as \'$f{'Stop'}\',
+ t.File as \'$f{'Title'}\',
+ t.Priority as \'$f{'Priority'}\',
UNIX_TIMESTAMP(t.NextStartTime) as __Day,
t.Collision as __Collision,
t.eventid as __eventid,
@@ -1106,20 +1124,20 @@ FROM
WHERE
t.ChannelID = c.Id
and (t.eventid = e.eventid)
- $in
+ $search1
UNION
SELECT SQL_CACHE
- t.Id as $f{'Id'},
- t.Status as $f{'Status'},
- c.Name as $f{'Channel'},
+ t.Id as \'$f{'Id'}\',
+ t.Status as \'$f{'Status'}\',
+ c.Name as \'$f{'Channel'}\',
c.Pos as __Pos,
- t.Day as $f{'Day'},
- DATE_FORMAT(t.NextStartTime, '%H:%i') as $f{'Start'},
- DATE_FORMAT(t.NextStopTime, '%H:%i') as $f{'Stop'},
- t.File as $f{'Title'},
- t.Priority as $f{'Priority'},
+ t.Day as \'$f{'Day'}\',
+ DATE_FORMAT(t.NextStartTime, '%H:%i') as \'$f{'Start'}\',
+ DATE_FORMAT(t.NextStopTime, '%H:%i') as \'$f{'Stop'}\',
+ t.File as \'$f{'Title'}\',
+ t.Priority as \'$f{'Priority'}\',
UNIX_TIMESTAMP(t.NextStartTime) as __Day,
t.Collision as __Collision,
t.eventid as __eventid,
@@ -1132,7 +1150,7 @@ FROM
WHERE
t.ChannelID = c.Id
and (t.eventid = 0)
- $in
+ $search2
ORDER BY
__Day
@@ -1140,8 +1158,12 @@ ORDER BY
my $fields = fields($obj->{dbh}, $sql);
- my $erg = $obj->{dbh}->selectall_arrayref($sql);
+ my $sth = $obj->{dbh}->prepare($sql);
+ $sth->execute(@{$term})
+ or return error sprintf("Couldn't execute query: %s.",$sth->errstr);
+ my $erg = $sth->fetchall_arrayref();
unshift(@$erg, $fields);
+
$console->table($erg, {
runningTimer => $obj->getRunningTimer,
cards => $obj->{DVBCards},
diff --git a/lib/XXV/MODULES/USER.pm b/lib/XXV/MODULES/USER.pm
index 5043828..52ebdf6 100644
--- a/lib/XXV/MODULES/USER.pm
+++ b/lib/XXV/MODULES/USER.pm
@@ -186,14 +186,18 @@ sub _init {
# ------------------
my $obj = shift || return error('No object defined!');
- return 0, panic("Session to database is'nt connected")
- unless($obj->{dbh});
+ unless($obj->{dbh}) {
+ panic("Session to database is'nt connected");
+ return 0;
+ }
+ my $version = main::getDBVersion();
# don't remove old table, if updated rows => warn only
- tableUpdated($obj->{dbh},'USER',9,0);
+ if(!tableUpdated($obj->{dbh},'USER',$version,0)) {
+ return 0;
+ }
# Look for table or create this table
- my $version = main::getVersion;
my $erg = $obj->{dbh}->do(qq|
CREATE TABLE IF NOT EXISTS USER (
Id int(11) unsigned auto_increment NOT NULL,
@@ -518,20 +522,20 @@ sub list {
my $console = shift || return error('No console defined!');
my %f = (
- 'Id' => umlaute(gettext('Service')),
- 'Name' => umlaute(gettext('Name')),
- 'Level' => umlaute(gettext('Level')),
- 'Prefs' => umlaute(gettext('Preferences')),
- 'UserPrefs' => umlaute(gettext('UserPreferences')),
+ 'Id' => gettext('Service'),
+ 'Name' => gettext('Name'),
+ 'Level' => gettext('Level'),
+ 'Prefs' => gettext('Preferences'),
+ 'UserPrefs' => gettext('User preferences')
);
my $sql = qq|
SELECT SQL_CACHE
- Id as $f{Id},
- Name as $f{Name},
- Level as $f{Level},
- Prefs as $f{Prefs},
- UserPrefs as $f{UserPrefs}
+ Id as \'$f{Id}\',
+ Name as \'$f{Name}\',
+ Level as \'$f{Level}\',
+ Prefs as \'$f{Prefs}\',
+ UserPrefs as \'$f{UserPrefs}\'
from
USER
|;