diff --git a/CONTROL/control b/CONTROL/control index a253e3b..afc6f48 100644 --- a/CONTROL/control +++ b/CONTROL/control @@ -1,10 +1,10 @@ Package: webif Priority: optional Section: web -Version: 1.2.5-6 +Version: 1.2.5-7 Architecture: mipsel Maintainer: af123@hummypkg.org.uk -Depends: webif-channelicons(>=1.1.18),lighttpd(>=1.4.35-2),jim(>=0.76),jim-oo,jim-sqlite3(>=0.76),jim-cgi(>=0.7),jim-binary(>=0.76),service-control(>=2.1),busybox(>=1.20.2-1),lsof(>=4.87),epg(>=1.2.0),hmt(>=2.0.7),ssmtp,anacron,trm(>=1.1),openssl-command,nicesplice,id3v2,file,rsvsync(>=1.0.2),webif-charts(>=1.2-1),stripts(>=1.2.5-3),smartmontools,tmenu(>=1.08),ffmpeg,id3v2,multienv(>=1.6),tcpping(>=1.1),e2fsprogs,wireless-tools(>=29-1),dbupdate,recmon(>=2.0.7) +Depends: webif-channelicons(>=1.1.18),lighttpd(>=1.4.37-2),jim(>=0.76),jim-oo,jim-sqlite3(>=0.76),jim-cgi(>=0.7),jim-binary(>=0.76),service-control(>=2.1),busybox(>=1.20.2-1),lsof(>=4.87),epg(>=1.2.0),hmt(>=2.0.8),ssmtp,anacron,trm(>=1.1),openssl-command,nicesplice,id3v2,file,rsvsync(>=1.0.2),webif-charts(>=1.2-1),stripts(>=1.2.5-3),smartmontools,tmenu(>=1.08),ffmpeg,id3v2,multienv(>=1.6),tcpping(>=1.1),e2fsprogs,wireless-tools(>=29-1),dbupdate,recmon(>=2.0.7) Suggests: Description: An evolving web interface for the Humax. Tags: http://hummy.tv/forum/threads/6484/ diff --git a/webif/cgi-bin/tvdbimg.jim b/webif/cgi-bin/tvdbimg.jim new file mode 100755 index 0000000..af24815 --- /dev/null +++ b/webif/cgi-bin/tvdbimg.jim @@ -0,0 +1,15 @@ +#!/mod/bin/jimsh + +package require cgi +source /mod/webif/lib/setup +require tvdb.class + +set file [cgi_get file "-"] +if {$file eq "-"} { exit } + +if {![file exists "$::tvdb::icache/$file"]} { + tvdb cachebanner $file +} + +httpredirect "/cache/tvdb/img/$file" + diff --git a/webif/html/browse/file.jim b/webif/html/browse/file.jim index 3c8e0da..590158c 100755 --- a/webif/html/browse/file.jim +++ b/webif/html/browse/file.jim @@ -21,7 +21,7 @@ if {$type eq "ts"} { # Causes other series information to be automatically populated set epname [$ts episode_name] set series [$ts series_name] - set sdata [$ts get tvdb_series] + set tvdb [$ts get tvdb_series] set idata [$ts get tvdb_data] puts " @@ -48,19 +48,26 @@ if {$type eq "ts"} { Episode " - if {[llength $sdata]} { - set sid [$sdata get seriesid] - if {$sid} { - append series " / " - append series " / DB:$sid" - } + puts "[$ts epstr] - $epname ($series)" + if {[llength $tvdb]} { + puts "" } - puts "[$ts epstr] - $epname ($series) + puts " " - if {[llength $sdata] && [llength $idata]} { - puts "TheTVDB + if {[llength $tvdb] && [llength $idata]} { + puts "TheTVDB" + set sid [$tvdb get seriesid] + puts "View on + " + if {[[settings] tvdb_debug]} { + puts " | " + puts " + View database($sid)" + } + puts " +
Found episode using [$ts get tvdb_method] @@ -72,10 +79,10 @@ if {$type eq "ts"} { if {[[settings] tvdb_debug]} { puts "
- [$sdata get _phrases] + [$tvdb get _phrases]
- [lrange [$sdata get _smatches] 0 8] + [lrange [$tvdb get _smatches] 0 8]
" } @@ -199,8 +206,16 @@ if {[$ts get bookmarks]} { puts " " -puts { +puts " +" +jscss episode.js + +set search [cgi_get search ""] + +if {[catch {set ts [ts fetch $file]}] || $ts eq "0"} { + puts "Unable to load recording data." + exit +} + +# Causes other series information to be automatically populated +$ts clearepdata +set epname [$ts episode_name] +set series [$ts series_name] +set tvdb [$ts get tvdb_series] +set idata [$ts get tvdb_data] + +browse breadcrumb [file dirname $file] +puts " +
+Episode Search + Search for: + + +
+ +
+ + + + + + + + + + + + + + + + + +
Title[$ts get title]
File[$ts get file]
Detected Episode[$ts epstr] - $epname ($series)
Found Using[$ts get tvdb_method]
Synopsis[$ts get synopsis]
+
+" + +if {$search ne ""} { + set matches [lmap i [$tvdb episodesearch $search] { + lassign $i x id + list $id 0 + }] +} else { + set matches [$tvdb get _smatches] +} + +if {![llength $matches]} { + exit +} + + +puts " +
+ + + + + + + + + + + +" + +foreach match $matches { + lassign $match episode_id score + set ep [$tvdb episodebyid $episode_id] + + if {![llength $ep]} continue + + puts " + + + + + + " +} + +puts " + +
ScoreEp.NameSynopsis
" + + if {[dict exists $ep thumb]} { + puts "" + } + puts "$scores$ep(series)e$ep(episode) $ep(name) +
+ +
$ep(overview)
+
+" + diff --git a/webif/html/browse/tvdb/episode.js b/webif/html/browse/tvdb/episode.js new file mode 100644 index 0000000..3123682 --- /dev/null +++ b/webif/html/browse/tvdb/episode.js @@ -0,0 +1,42 @@ + +$(function() { + +var synopsis = $('.synopsis').text(); +var words = synopsis.split(" "); +for (var i = 0;i < words.length - 1; i++) +{ + var word = words[i]; + if (word.length > 4) + $('table.results').highlight(words[i]); +} + +$('button.select').button().on('click', function() { + $tr = $(this).closest('tr'); + $.get('select.jim', { + file: file, + episode: $tr.attr('sid'), + s: $tr.attr('s'), + e: $tr.attr('e') + }, function() { + window.location.href = '/browse/?dir=' + + encodeURIComponent(dir); + }); +}); + +$('#tvdbepsearch').button({icons:{primary:"ui-icon-search"}}) + .on('click', function() { + window.location.href = 'episode.jim?file=' + + encodeURIComponent(file) + '&search=' + + encodeURIComponent($('#searchterm').val()); +}); + +$('table.results') + .tablesorter({ + theme: 'webif', + widthFixed: false, + sortList: [[1,1]], + widgets: ['zebra', 'stickyHeaders'] + }); + +}); + diff --git a/webif/html/browse/tvdb/search.jim b/webif/html/browse/tvdb/search.jim index b4d60d5..ec54332 100755 --- a/webif/html/browse/tvdb/search.jim +++ b/webif/html/browse/tvdb/search.jim @@ -16,7 +16,15 @@ if {[llength $slist]} {
+ " + if {[dict exists $series banner]} { + puts " + " + } else { + puts "View on TheTVDB" + } + puts " $series(seriesname) diff --git a/webif/html/browse/tvdb/select.jim b/webif/html/browse/tvdb/select.jim new file mode 100755 index 0000000..8a7cd38 --- /dev/null +++ b/webif/html/browse/tvdb/select.jim @@ -0,0 +1,22 @@ +#!/mod/bin/jimsh + +package require cgi +source /mod/webif/lib/setup +require tvdb.class ts.class + +set file [cgi_get file -] +set episode [cgi_get episode -] +set s [cgi_get s -] +set e [cgi_get e -] + +httpheader + +if {$file eq "-" || $episode eq "-"} exit + +if {[catch {set ts [ts fetch $file]}] || $ts eq "0"} { + puts "Unable to load recording data." + exit +} + +$ts storeepisode [list $s $e 0] + diff --git a/webif/lib/browse.class b/webif/lib/browse.class index d8e9c3b..107c039 100644 --- a/webif/lib/browse.class +++ b/webif/lib/browse.class @@ -3,6 +3,7 @@ require system.class plugin if {![exists -proc class]} { package require oo } class dir {} +class browse {} proc _addicon {img {hover ""} {class va}} { set icon "$name" + } +} + diff --git a/webif/lib/setup b/webif/lib/setup index 0a5f1f5..0e5571f 100644 --- a/webif/lib/setup +++ b/webif/lib/setup @@ -9,6 +9,13 @@ if {![exists -proc require]} { } } + proc httpredirect {url} { + puts -nonewline "Location: $url\r\n" + puts -nonewline "\r\n" + puts "Redirecting to $url" + exit + } + proc httpheader {{type "text/html"} {cache 0} {extra ""}} {{done 0}} { if {$done} return if {!$cache} { diff --git a/webif/lib/system.class b/webif/lib/system.class index 3b5ecd6..f3d4ee0 100644 --- a/webif/lib/system.class +++ b/webif/lib/system.class @@ -128,6 +128,7 @@ proc {system kernelver} {} {{ver ""}} { "Feb 7 14:15:02 KST 2014" { format "HDR_1.03.12" } "May 19 22:39:27 BST 2014" { format "HDR_CFW_3.00" } "Feb 19 20:58:57 GMT 2015" { format "HDR_CFW_3.03" } + "Nov 18 19:16:42 GMT 2015" { format "HDR_CFW_3.10" } # HD "Oct 11 21:14:31 KST 2010" { format "HD_1.01.12" } diff --git a/webif/lib/ts.class b/webif/lib/ts.class index 873e4ca..1e28b8e 100644 --- a/webif/lib/ts.class +++ b/webif/lib/ts.class @@ -27,6 +27,7 @@ class ts { status "" series "" + seriescached 1 seriesnum 0 episodenum 0 episodetot 0 @@ -60,7 +61,7 @@ ts method _parse {line} { lassign [split $line "\t"] \ title synopsis definition channel_num channel_name \ start end flags_list guidance bookmarks schedstart scheddur \ - genre resume status + genre resume status seriesnum episodenum episodetot set flags [split [string range $flags_list 0 end-1] ,] } @@ -83,6 +84,21 @@ ts method setbookmarks {marks} { exec /mod/bin/hmt +setbookmarks=[join $marks :] $file } +ts method storeepisode {{data {}}} { + if {[llength $data]} { + set d [join $data ","] + } else { + set d "$seriesnum,$episodenum,$episodetot" + } + exec /mod/bin/hmt +setseries=$d $file +} + +ts method clearepdata {} { + set seriesnum 0 + set episodenum 0 + set episodetot 0 +} + ts method flag {f} { if {$f in $flags} {return 1} else {return 0} } @@ -520,14 +536,18 @@ ts method _tvdb_resolve {seriesid} { set dir [file dirname $file] - set tvdb_series [set v [tvdb series [$self series_name] $seriesid]] + set tvdb_series [set v [tvdb series "" $seriesid]] if {[$v get seriesid] == 0} { return } # Got one. # Easiest case - we can explicitly request the episode. if {$seriesnum && $episodenum} { - set tvdb_method "series and episode number" + if {$seriescached} { + set tvdb_method "cached values" + } else { + set tvdb_method "series and episode number" + } return [$v episodebynum $seriesnum $episodenum] } @@ -557,34 +577,15 @@ ts method _tvdb_resolve {seriesid} { return [$v episodebysynopsis $synopsis] } -ts method episode_name {} { - set s $synopsis +proc {ts serieslist} {dir} { + set idfile "$dir/.tvdbseriesid" + if {![file exists $idfile]} { return {} } + return [lmap i [split [file read $idfile] "\n"] { + string trim $i + }] +} - ###################################################################### - # Attempt to determine the episode name from the synopsis - - # Strip common prefixes - foreach prefix $::ts::episode_prefixes { - regsub -nocase -all -- $prefix $s "" s - } - - # Strip anything following a colon. - regsub -all -- { *[:].*$} $s "" s - - # If the resulting string is longer than 40 characters then - # split around . and take the left hand side if appropriate. - if {[string length $s] > 40} { - lassign [split $s "."] v w - set s $v - if {[string length $s] < 6 && [string length $w] < 6} { - append s "_$w" - } - } - - # Shorten if too long. - if {[string length $s] > 40} { set s [string range $s 0 39] } - - set episodename $s +ts method extract_numbers {} { ###################################################################### # Check for embedded Series/Episode number. @@ -625,6 +626,42 @@ ts method episode_name {} { } } +} + +ts method episode_name {} { + set s $synopsis + + ###################################################################### + # Attempt to determine the episode name from the synopsis + + # Strip common prefixes + foreach prefix $::ts::episode_prefixes { + regsub -nocase -all -- $prefix $s "" s + } + + # Strip anything following a colon. + regsub -all -- { *[:].*$} $s "" s + + # If the resulting string is longer than 40 characters then + # split around . and take the left hand side if appropriate. + if {[string length $s] > 40} { + lassign [split $s "."] v w + set s $v + if {[string length $s] < 6 && [string length $w] < 6} { + append s "_$w" + } + } + + # Shorten if too long. + if {[string length $s] > 40} { set s [string range $s 0 39] } + + set episodename $s + + if {$episodenum == 0} { + $self extract_numbers + set seriescached 0 + } + # Now see if TVDB has anything to add set fbase "[file dirname $file]/.tvdb" @@ -636,12 +673,20 @@ ts method episode_name {} { if {!$seriesnum && [file exists "${fbase}series"]} { set seriesnum [string trim [file read "${fbase}series"]] } - foreach seriesid [\ - string trim [split [file read "${fbase}seriesid"] "\n"]] { + foreach seriesid [ts serieslist [$self dir]] { set tvdb_data [$self _tvdb_resolve $seriesid] if {![dict exists $tvdb_data name]} continue - if {!$seriesnum} { set seriesnum $tvdb_data(series) } - if {!$episodenum} { set episodenum $tvdb_data(episode) } + set flag 0 + if {!$seriesnum} { + set seriesnum $tvdb_data(series) + incr flag + } + if {!$episodenum} { + set episodenum $tvdb_data(episode) + incr flag + } + if {$flag} { $self storeepisode } + return $tvdb_data(name) } diff --git a/webif/lib/tvdb.class b/webif/lib/tvdb.class index dff433e..2a98e3d 100644 --- a/webif/lib/tvdb.class +++ b/webif/lib/tvdb.class @@ -3,11 +3,12 @@ source /mod/webif/lib/setup package require cgi if {![exists -proc class]} { package require oo } if {![exists -proc sqlite3.open]} { package require sqlite3 } -require xml.class +require system.class xml.class set ::tvdb::apikey 1764335F804A5A91 set ::tvdb::mirror "thetvdb.com" set ::tvdb::cache "/mod/var/tvdb" +set ::tvdb::icache "/mod/webif/cache/tvdb/img" set ::tvdb::cacheage 86400 set ::tvdb::debug 0 @@ -15,7 +16,12 @@ if {![file isdirectory $::tvdb::cache]} { file mkdir $::tvdb::cache } +if {![file isdirectory $::tvdb::icache]} { + system mkdir_p $::tvdb::icache +} + set ::tvdb::indexdb [sqlite3.open "$::tvdb::cache/series.db"] + $::tvdb::indexdb query { create table if not exists nseries( [name] text primary key @@ -46,8 +52,8 @@ tvdb method setseries {sid} { } tvdb method _fetch {url} { - set f [socket stream $::tvdb::mirror:80] - $f puts -nonewline "GET /api/$url HTTP/1.0\r\n" + set f [socket stream "${::tvdb::mirror}:80"] + $f puts -nonewline "GET $url HTTP/1.0\r\n" $f puts -nonewline "Host: $::tvdb::mirror\r\n" $f puts -nonewline "Connection: close\r\n" $f puts -nonewline "\r\n" @@ -149,7 +155,7 @@ tvdb method fetchseries {} { # Download the series info set f [open "$base.zip" w] puts $f [$self _fetch \ - "$::tvdb::apikey/series/$seriesid/all/en.zip"] + "/api/$::tvdb::apikey/series/$seriesid/all/en.zip"] $f close catch {exec unzip -o -q "$base.zip" en.xml -d $::tvdb::cache} if {[file exists "$::tvdb::cache/en.xml"]} { @@ -174,7 +180,7 @@ tvdb method loadseries {} { tvdb method searchseries {series} { ::tvdb::dlog "Searching TVDB for $series" set seriesxml [$self _fetch \ - "/GetSeries.php?seriesname=[cgi_quote_url $series]"] + "/api/GetSeries.php?seriesname=[cgi_quote_url $series]"] return [$self _extract $seriesxml Series \ {seriesid SeriesName banner Overview}] } @@ -195,7 +201,7 @@ tvdb method findseries {series} { ::tvdb::dlog "Trying to find series in TVDB" set seriesxml [$self _fetch \ - "/GetSeries.php?seriesname=[cgi_quote_url $series]"] + "/api/GetSeries.php?seriesname=[cgi_quote_url $series]"] $self _parse $seriesxml {seriesid} Series } @@ -260,17 +266,28 @@ tvdb method wordcount {db words extra} { #puts "Phrase: $w
" set ret [$db query { - select episode_id from episode + select episode_id, + case + when name like '%%%s%%' then 1 + else 0 + end as inname + from episode where overview like '%%%s%%' or name like '%%%s%%' %s - } $w $w $extra] + } $w $w $w $extra] foreach row $ret { #puts "  > FOUND: ($w)
" ladd _phrases $w - lassign $row x id - # Score is twice phrase length - incr _matches($id) $($i * 2) + lassign $row x id x inname + if {$inname eq "1"} { + # If found in name then score is 10x + # phrase length + incr _matches($id) $($i * 10) + } else { + # Score is twice phrase length + incr _matches($id) $($i * 2) + } } } } @@ -304,6 +321,15 @@ tvdb method seek {synopsis {extra ""}} { return {} } +tvdb method episodebyid {episode_id} { + if {![llength [set db [$self dbhandle]]]} return {} + set ret [$db query { + select * from episode where episode_id = %s + } $episode_id] + if {[llength $ret]} { return [lindex $ret 0] } + return {} +} + tvdb method episodebyepnum {episode synopsis} { return [$self seek $synopsis "and episode = $episode"] } @@ -316,6 +342,21 @@ tvdb method episodebysynopsis {synopsis} { return [$self seek $synopsis] } +tvdb method episodesearch {search} { + if {![llength [set db [$self dbhandle]]]} return {} + set ret [$db query { + select episode_id, + case + when name like '%%%s%%' then 1 + else 0 + end as inname + from episode + where overview like '%%%s%%' + or name like '%%%s%%' + } $search $search $search] + return $ret +} + tvdb method series_count {} { if {![llength [set db [$self dbhandle]]]} { return 0 } @@ -347,8 +388,39 @@ proc {tvdb series} {series {sid 0}} { return $t } +proc {tvdb fetchfile} {url} { + set f [socket stream "${::tvdb::mirror}:80"] + $f puts -nonewline "GET $url HTTP/1.0\r\n" + $f puts -nonewline "Host: $::tvdb::mirror\r\n" + $f puts -nonewline "Connection: close\r\n" + $f puts -nonewline "\r\n" + + # Skip headers in the response. + set line [string trim [$f gets]] + while {[string length $line]} { + #puts "Web Header: $line" + set line [string trim [$f gets]] + } + + # Save the body + set ret [$f read] + $f close + return $ret +} + +proc {tvdb cachebanner} {banner} { + if {![file exists "$::tvdb::icache/$banner"]} { + set ret [tvdb fetchfile \ + "http://$::tvdb::mirror/banners/$banner"] + if {[string length $ret] > 50} { + system mkdir_p "$::tvdb::icache/[file dirname $banner]" + file write "$::tvdb::icache/$banner" $ret + } + } +} + proc {tvdb bannerurl} {banner} { - return "http://$::tvdb::mirror/banners/$banner" + return "/cgi-bin/tvdbimg.jim?file=[cgi_quote_url $banner]" } proc {tvdb seriesurl} {seriesid} {