Compare commits

...

41 Commits

Author SHA1 Message Date
hummypkg
c886f6afd2 versioned backups + change folder for pending
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2044 2a923420-c742-0410-a762-8d5b09965624
2014-10-07 21:23:15 +00:00
hummypkg
e6d7af1fc4 1.0.17 RC
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2041 2a923420-c742-0410-a762-8d5b09965624
2014-10-07 00:49:22 +00:00
hummypkg
0691577b96 fix mkdir
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2035 2a923420-c742-0410-a762-8d5b09965624
2014-09-13 09:00:17 +00:00
hummypkg
876d5b5e8a add force dedup process
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2033 2a923420-c742-0410-a762-8d5b09965624
2014-09-04 22:34:30 +00:00
hummypkg
4d895e464d check connectivity
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2030 2a923420-c742-0410-a762-8d5b09965624
2014-08-28 18:44:42 +00:00
hummypkg
252d6bf7f6 revert iphone-style-checkboxes and re-patch for actual width calculations
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2023 2a923420-c742-0410-a762-8d5b09965624
2014-07-23 19:16:58 +00:00
hummypkg
ea03a67b4a adding
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2021 2a923420-c742-0410-a762-8d5b09965624
2014-07-21 22:01:10 +00:00
hummypkg
3adbeb987a 1.0.16
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2020 2a923420-c742-0410-a762-8d5b09965624
2014-07-21 21:55:28 +00:00
hummypkg
23fdc62b81 fix icon paths with spaces
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2018 2a923420-c742-0410-a762-8d5b09965624
2014-07-09 21:34:50 +00:00
hummypkg
b88691c9e5 add channelicons, fix status, show more actions
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2017 2a923420-c742-0410-a762-8d5b09965624
2014-07-08 18:30:02 +00:00
hummypkg
3c4b907091 pass processed file list to plugins
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2016 2a923420-c742-0410-a762-8d5b09965624
2014-07-07 22:06:57 +00:00
hummypkg
1c00e63f48 fix bookmarks, add serial number
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@2012 2a923420-c742-0410-a762-8d5b09965624
2014-07-06 20:11:59 +00:00
hummypkg
59006ff474 ladd
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1986 2a923420-c742-0410-a762-8d5b09965624
2014-06-25 19:51:30 +00:00
hummypkg
616c0afff1 updates
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1983 2a923420-c742-0410-a762-8d5b09965624
2014-06-23 20:14:23 +00:00
hummypkg
84899871e1 1.0.15-3
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1981 2a923420-c742-0410-a762-8d5b09965624
2014-06-19 21:34:48 +00:00
hummypkg
ed042ee230 bug fixes
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1979 2a923420-c742-0410-a762-8d5b09965624
2014-06-19 18:50:53 +00:00
hummypkg
3c44ec33f9 fix dedup inuse problem
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1975 2a923420-c742-0410-a762-8d5b09965624
2014-06-17 08:49:04 +00:00
hummypkg
02d7bc3f33 bookmark management
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1974 2a923420-c742-0410-a762-8d5b09965624
2014-06-16 21:14:37 +00:00
hummypkg
492b37be41 1.0.15 & improved status
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1968 2a923420-c742-0410-a762-8d5b09965624
2014-06-14 09:21:09 +00:00
hummypkg
c237f228a8 restructure tdelete
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1954 2a923420-c742-0410-a762-8d5b09965624
2014-06-12 17:43:19 +00:00
hummypkg
7a523a9ddb fix TSR bug
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1953 2a923420-c742-0410-a762-8d5b09965624
2014-06-11 21:18:19 +00:00
hummypkg
972366de14 update status
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1950 2a923420-c742-0410-a762-8d5b09965624
2014-06-10 22:01:42 +00:00
hummypkg
aeb96c2c8a update to new lsof and fix things
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1949 2a923420-c742-0410-a762-8d5b09965624
2014-06-10 17:12:06 +00:00
hummypkg
68f98c8a65 add inuse
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1947 2a923420-c742-0410-a762-8d5b09965624
2014-06-09 22:22:33 +00:00
hummypkg
61b09db04b updates
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1946 2a923420-c742-0410-a762-8d5b09965624
2014-06-09 20:54:52 +00:00
hummypkg
de2035e1e0 fix bugs
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1944 2a923420-c742-0410-a762-8d5b09965624
2014-06-06 23:24:32 +00:00
hummypkg
b4bd45566e fix jconfirmaction
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1938 2a923420-c742-0410-a762-8d5b09965624
2014-06-05 21:10:01 +00:00
hummypkg
692488a11f tweak diskspace check again
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1935 2a923420-c742-0410-a762-8d5b09965624
2014-06-04 20:35:38 +00:00
hummypkg
bd27200ba8 add resume
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1932 2a923420-c742-0410-a762-8d5b09965624
2014-06-03 22:33:24 +00:00
hummypkg
7e30a4272e webif 1.0.14
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1928 2a923420-c742-0410-a762-8d5b09965624
2014-06-03 22:03:36 +00:00
hummypkg
945007f73d add nav buttons + browse hooks
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1927 2a923420-c742-0410-a762-8d5b09965624
2014-06-03 22:03:23 +00:00
hummypkg
fc9c912f99 improve disk space calculation
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1924 2a923420-c742-0410-a762-8d5b09965624
2014-05-31 14:50:12 +00:00
hummypkg
bf67161898 various
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1922 2a923420-c742-0410-a762-8d5b09965624
2014-05-28 21:29:10 +00:00
hummypkg
f029ab1ce6 improve diskspace check
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1920 2a923420-c742-0410-a762-8d5b09965624
2014-05-28 18:10:58 +00:00
hummypkg
bfd099a82e update auto-expiry with new options
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1919 2a923420-c742-0410-a762-8d5b09965624
2014-05-21 22:10:22 +00:00
hummypkg
d9a284994e reintroduce mongoose dependency
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1899 2a923420-c742-0410-a762-8d5b09965624
2014-05-11 16:42:42 +00:00
hummypkg
e6df0ae3af update for 1.0.13 - switch web server software
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1894 2a923420-c742-0410-a762-8d5b09965624
2014-05-11 14:05:00 +00:00
hummypkg
e14ccce2cc update dependencies
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1883 2a923420-c742-0410-a762-8d5b09965624
2014-05-03 22:26:19 +00:00
hummypkg
60111cd8b1 update conffiles for new layout
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1873 2a923420-c742-0410-a762-8d5b09965624
2014-05-02 22:18:44 +00:00
hummypkg
fb81a7e954 defer shrink until after decryption if both are pending
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1872 2a923420-c742-0410-a762-8d5b09965624
2014-05-02 11:25:25 +00:00
hummypkg
218221c069 1.0.12 update
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@1870 2a923420-c742-0410-a762-8d5b09965624
2014-04-30 21:57:44 +00:00
96 changed files with 1501 additions and 503 deletions

View File

@@ -1,6 +1,6 @@
var/mongoose/html/css/EXTRA.css
var/mongoose/html/favicon.ico
var/mongoose/html/img/fav/57.png
var/mongoose/html/img/fav/72.png
var/mongoose/html/img/fav/114.png
var/mongoose/html/img/fav/144.png
webif/html/css/EXTRA.css
webif/html/favicon.ico
webif/html/img/fav/57.png
webif/html/img/fav/72.png
webif/html/img/fav/114.png
webif/html/img/fav/144.png

View File

@@ -1,11 +1,10 @@
Package: webif
Priority: optional
Section: web
Version: 1.0.11-5
Version: 1.0.17
Architecture: mipsel
Maintainer: af123@hummypkg.org.uk
Depends: webif-channelicons(>=1.1.10),mongoose(>=3.0.11),jim(>=0.75-1),jim-oo,jim-sqlite3(>=0.75),jim-cgi(>=0.7),jim-binary(>=0.75),service-control(>=1.2),busybox(>=1.20.2-1),lsof,epg(>=1.0.13),hmt(>=1.1.14),ssmtp,anacron,trm(>=1.1),openssl-command,nicesplice,id3v2,file,rsvsync(>=1.0.2),webif-charts(>=1.2),stripts(>=1.2.5-3),smartmontools,tmenu(>=1.08),ffmpeg,id3v2,multienv(>=1.6)
Conflicts: tvdiary(<0.0.2-6)
Depends: webif-channelicons(>=1.1.13),lighttpd(>=1.4.35-2),jim(>=0.75-1),jim-oo,jim-sqlite3(>=0.75),jim-cgi(>=0.7),jim-binary(>=0.75),service-control(>=1.2),busybox(>=1.20.2-1),lsof(>=4.87),epg(>=1.0.13),hmt(>=1.1.21),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),mongoose
Suggests:
Description: An evolving web interface for the Humax.
Tags: http://hummy.tv/forum/threads/4723/
Tags: http://hummy.tv/forum/threads/5031/

View File

@@ -1,6 +1,16 @@
#!/bin/sh
echo "Postinstall $*"
# Relocate any stray files in /mod/var/mongoose
if [ -d /mod/var/mongoose -a ! -h /mod/var/mongoose ]; then
(
cd /mod/var/mongoose
find . | cpio -pmud /mod/webif
cd /mod/var
rm -rf mongoose
ln -s ../webif mongoose
)
fi
export tmpf=/tmp/cronf.$$

View File

@@ -2,7 +2,7 @@
# Handle moving the legacy /var/mongoose directory to /webif..
if [ -h /mod/webif -a -d /var/mongoose ]; then
if [ -h /mod/webif -a -d /mod/var/mongoose -a ! -h /mod/var/mongoose ]; then
echo "Relocating web interface files..."
cd /mod

View File

@@ -3,7 +3,7 @@
package require cgi
package require sqlite3
source /mod/webif/lib/setup
require altrow progressbar epg.class
require altrow progressbar epg.class system.class
header
@@ -51,7 +51,7 @@ foreach tw [$db query {
"
puts "<td>[progressbar $ucLevel]</td>"
puts "<td>[progressbar $ucQuality]</td>"
puts "<td>[string range $netName 3 end]</td>"
puts "<td>[system strip $netName]</td>"
set channels [$db query {
select usLcn, szSvcName, szPrvName, aucDefaultAuthority
@@ -91,10 +91,10 @@ foreach tw [$db query {
src=/images/421_1_00_CH_Title_2R_Arrow.png>
view
</a></td>"
puts "<td>$ehs</th>"
puts "<td>$ehs</td>"
puts "</tr>"
puts "<tr id=mchan_$tsIdx class=mchan style=\"display: none\">
<td colspan=5>"
<td colspan=9>"
puts "<table style=\"margin-left: 5em\">"
puts "<tr>
<th colspan=3>Channel</th>
@@ -107,15 +107,13 @@ foreach tw [$db query {
set name [string range $name 1 end]
set prv [string range $prv 3 end]
altrow
puts "<td class=va>"
puts "[epg channelicon $name 50]</td>
<td>$lcn</td><td>$name</td>"
puts "</td><td>"
puts $prv
puts "</td><td>"
puts $auth
puts "</td>"
puts "</tr>"
puts "
<td class=va>[epg channelicon $name 50]</td>
<td>$lcn</td><td>$name</td>
<td>$prv</td>
<td>$auth</td>
</tr>
"
}
puts "</table>"
puts "</td></tr>"
@@ -142,3 +140,5 @@ $(document).ready(function() {
</script>
}
footer

View File

@@ -70,6 +70,7 @@ if {[llength $records] > 0} {
<th colspan=3>Channel</th>
<th>Programme</th>
<th>Synopsis</th>
<th></th>
</tr>
}
} else {

15
webif/cgi-bin/hximages.jim Executable file
View File

@@ -0,0 +1,15 @@
#!/mod/bin/jimsh
source /mod/webif/lib/setup
header
puts "<ul>"
foreach f [readdir "/opt/share/images/blue"] {
if {![string match {*.png} $f]} continue
puts "<li><img src=\"/images/$f\">$f</li>"
}
puts "</ul>"

View File

@@ -2,7 +2,7 @@
package require cgi
source /mod/webif/lib/setup
require pkg.class
require pkg.class system.class
cgi_input
#cgi_dump
@@ -10,27 +10,36 @@ cgi_input
set cmd [cgi_get cmd update]
proc opkg {cmd} {
puts ">>> opkg $cmd\r\n"
puts ">>> opkg $cmd"
set bcmd "|/mod/webif/lib/bin/opkg $cmd"
set fd [open $bcmd r]
while {[gets $fd line] >= 0} {
puts "$line\r\n"
puts "$line"
}
close $fd
puts "\r\n"
puts ""
}
httpheader "text/plain"
if {![system connectivity]} {
puts ""
puts "!! ERROR - No network connectivity to package repository !!"
puts ""
puts "Check your Internet connection and DNS service and then try again."
exit
}
if {$cmd eq "upgrade"} { opkg update }
opkg $cmd
if {$cmd eq "update" || $cmd eq "upgrade"} {
puts "Updating package meta information\r\n"
puts "Updating package meta information"
pkg fetchmeta
puts "Done.\r\n"
puts "Updating diagnostic meta information\r\n"
puts "Done."
puts ""
puts "Updating diagnostic meta information"
pkg fetchdiagmeta
puts "Done.\r\n"
puts "Done."
}

View File

@@ -45,7 +45,7 @@ puts {
$(document).ready(function() {
$('#progressbar').reportprogress(0);
handle = setInterval("update()", 350);
handle = setInterval("update()", 400);
$.get('/cgi-bin/restart.jim?now=yes');
});
</script>

View File

@@ -19,74 +19,185 @@ switch $runmode {
}
}
if {"-d" in $argv} {
proc debug {arg} { puts $arg }
} else {
proc debug {arg} {}
}
if {[catch {set pid [exec pgrep -n humaxtv]}]} {
puts "Cannot find humaxtv process."
exit
}
set exts {.ts .mkv .avi .mpg .mpeg .wmv .mp3 .mp4 .mov}
proc get_data {} {
global pid
global pid exts opfile
set ret {}
if {[catch {set data \
[exec /mod/bin/lsof -p $pid | grep Video | fgrep .ts]} ]} {
[exec /mod/webif/lib/bin/lsof -X -Fns -p $pid]} msg]} {
set ret {}
} else {
set size 0
foreach line [split $data "\n"] {
regsub -all -- {[[:space:]]+} $line " " line
set name [file rootname [file tail $line]]
if {[dict exists $ret $name]} {
set ret($name) -1
} else {
set size [lindex [split $line " "] 6]
set ret($name) $size
set typ [string index $line 0]
switch $typ {
s {
set size [string range $line 1 end]
}
n {
if {[string first Video/ $line] == -1 && \
[string first /media/ $line] == -1} {
continue
}
regsub -- { \([^\)]+\)$} $line "" line
set ext [file extension $line]
if {$ext ni $exts} continue
set file [string range $line 1 end]
# Handle chase play (same file open twice
# and recently written)
if {[dict exists $ret $file] && \
$ext eq ".ts"} {
set age [expr [clock seconds] - \
[file mtime $file]]
if {$age < 60} {
set ret($file) -1
}
} else {
set ret($file) $size
}
}
}
}
if {$opfile ne "" && $opfile ni $ret} {
set ret($opfile) [file size $opfile]
}
}
return $ret
}
set play 0
set rec 0
set seen {}
set output {}
if {$type eq "full"} {
set data [get_data]
} else {
set data {}
set opfile ""
if {[file exists "/mod/tmp/webif_auto/.op"} {
set fp [open "/mod/tmp/webif_auto/.op"]
lassign [split [string trim [$fp read]] ":"] op opfile
$fp close
debug "OP: $op - $opfile"
}
set data {}
if {$type eq "full"} {
set data [get_data]
}
if {[llength $data]} {
sleep 3
set ndata [get_data]
foreach name [array names ndata] {
if {![dict exists $seen $name]} { set seen($name) 0 }
if {![dict exists $data $name]} { set data($name) 0 }
if {[file exists "/mod/tmp/webif_auto/decrypting.$name.ts"]} {
set mode "Decrypting"
set icon "178_1_00_Icon_Lock.png style=\"padding: 0 0.2em 0 0.5em\""
} elseif {$ndata($name) == -1} {
incr rec
incr play
set mode "Chase Playing"
set icon "745_1_11_Video_3REC_Live.png"
} elseif {$ndata($name) > $data($name) && $seen($name) < 1} {
incr rec
set mode "Recording"
set icon "745_1_11_Video_1REC.png"
} else {
incr play
set mode "Playing"
set icon "745_1_10_Video_2Live.png"
debug " DATA: ($data)"
if {![file exists /tmp/.rractive]} {
sleep 3
set ndata [get_data]
debug " NDATA: ($ndata)"
set rr 0
} else {
sleep 1
set ndata [get_data]
debug " NDATA: ($ndata)"
foreach k [array names data] {
if {![dict exists $ndata $k]} {
dict unset data $k
}
}
incr seen($name)
set rr 1
set recs {}
loop i 0 2 {
catch {
set fd [open "/tmp/.rec$i" r]
lappend recs "[$fd read -nonewline].ts"
$fd close
}
}
debug " RECS: $recs"
}
foreach file [array names data] {
set bname [file rootname [file tail $file]]
if {$file eq $opfile} {
set mode $op
} elseif {$data($file) == -1} {
set mode chase
} elseif {$rr} {
if {$file in $recs} {
set mode rec
} else {
set mode play
}
} else {
if {![dict exists $ndata $file]} continue
if {$ndata($file) > $data($file)} {
set mode rec
} else {
set mode play
}
}
switch $mode {
chase {
incr rec
incr play
set mode "Chase Playing"
set icon "745_1_11_Video_3REC_Live.png"
}
rec {
incr rec
set mode "Recording"
set icon "745_1_11_Video_1REC.png"
}
play {
incr play
set mode "Playing"
set icon "745_1_10_Video_2Live.png"
}
dec {
set mode "Decrypting"
set icon "/img/decrypt.png "
append icon "style=\"padding: 0 0.2em 0 0.5em\""
}
mpg {
set mode "Extracting MPG"
set icon "/img/mpg.png "
append icon "style=\"padding: 0 0.2em 0 0.5em\""
}
mp3 {
set mode "Extracting MP3"
set icon "/img/mp3.png "
append icon "style=\"padding: 0 0.2em 0 0.5em\""
}
shrink {
set mode "Shrinking"
set icon "/img/compress.png "
append icon "style=\"padding: 0 0.2em 0 0.5em\""
}
}
if {[string first "/" $icon] == -1} {
set icon "/images/$icon"
}
set name [string map {
"/mnt/hd2/My Video/" ""
"/media/drive1/Video/" ""
"/media/" ""
".ts" ""
} $file]
if {$runmode eq "cgi"} {
lappend output [concat \
"<span class=\"va stitem\">\n" \
" <img class=va src=/images/$icon>\n" \
" <img class=va src=$icon>\n" \
" <span>$mode&nbsp;<i>$name</i></span>\n" \
"</span>\n" \
]
@@ -96,6 +207,9 @@ if {[llength $data]} {
}
}
######################################################################
# Live viewing information
if {![system instandby] && $play < 1} {
set hsvc [system param CUR_SVC Value USERCONFIG]
@@ -136,6 +250,9 @@ if {![system instandby] && $play < 1} {
}
}
######################################################################
# In standby
if {[system instandby]} {
if {$runmode eq "cgi"} {
lappend output [concat \
@@ -150,6 +267,9 @@ if {[system instandby]} {
}
}
######################################################################
# Upcoming recordings
set events [rsv list tbl_reservation \
" where ersvtype = 3 and nsttime - [clock seconds] < $schedtime
and nsttime > [clock seconds] "]
@@ -173,6 +293,9 @@ foreach event $events {
}
}
######################################################################
# Output
if {[llength $output]} {
if {$runmode eq "cgi"} {
puts [join $output "\n<br>\n"]

View File

@@ -249,7 +249,7 @@ $('#xepgnow')
}
puts "
<a href=/cgi-bin/settings.jim>
<a href=/settings/settings.jim>
<img border=0 height=14 src=/images/421_1_00_CH_Title_2R_Arrow.png>
Visit settings to change EPG options.
</a><br>

View File

@@ -39,7 +39,6 @@ foreach line $data {
set vars {}
set i 0
foreach f $fields {
if {$f eq "aulEventToRecordInfo"} { continue }
incr i
lappend vars $f [lindex $vals $i]
}

View File

@@ -2,23 +2,48 @@
package require cgi
source /mod/webif/lib/setup
httpheader
require browse.class
# dir=%2Fmedia%2FMy+Video%2FWeatherview
# aexpiry_days=13
set dir [cgi_get dir "-"]
set days [cgi_get aexpiry_days 7]
if {$dir eq "-"} exit
set act [cgi_get act "update"]
if {$act eq "fetch"} {
httpheader "application/json"
set data [{dir expiry} $dir]
puts "{"
puts " \"days\": \"$data(days)\","
puts " \"keep\": \"$data(keep)\","
puts " \"type\": \"$data(type)\","
puts " \"keepnew\": \"$data(keepnew)\""
puts "}"
exit
}
if {$act eq "remove"} {
httpheader
if {[file exists "$dir/.autoexpire"]} {
file delete "$dir/.autoexpire"
}
exit
}
httpheader
set data(days) [cgi_get aexpiry_days 0]
set data(keep) [cgi_get aexpiry_min 0]
set data(type) [cgi_get aexpiry_timetype recorded]
set data(keepnew) [cgi_get aexpiry_unwatched 0]
if {![file isdirectory $dir]} {
puts "Not a directory."
exit
}
set fd [open "$dir/.autoexpire" w]
puts $fd $days
$fd close
{dir expiry} $dir $data
puts "Ok."

View File

@@ -29,6 +29,8 @@ if {[system pkginst ffmpeg]} {
puts { <li><a href=#vthm>View Thumbnail</a></li> }
puts { <li class=bookmark><a href=#bmarks>Bookmarks</a></li> }
if $nicesplice {
puts {
<li class="cut"><a href=#crop>Crop</a></li>
@@ -38,6 +40,16 @@ if $nicesplice {
puts {
<li class=separator><a href=#lock>Toggle Lock</a></li>
<li><a href=#new>Toggle New</a></li>
}
if {[llength $plugins(menu)]} {
foreach plugin $plugins(menu) {
lassign $plugin tag options
puts "<li class=$tag><a href=#$tag>$options(desc)</a></li>"
}
}
puts {
</ul>
<ul id=ooptmenu class=contextMenu style="width: 160px">
@@ -80,7 +92,7 @@ if $flatten {
}
puts {
<li class=clock><a href=#expire>Auto-Expire</a></li>
<li class=clock><a href=#expire>Auto-Expire Options</a></li>
}
if {[system pkginst ffmpeg]} {
@@ -90,6 +102,13 @@ if {[system pkginst ffmpeg]} {
}
}
if {[llength $plugins(dmenu)]} {
foreach plugin $plugins(dmenu) {
lassign $plugin tag options
puts "<li class=$tag><a href=#$tag>$options(desc)</a></li>"
}
}
puts {
</ul>
@@ -259,28 +278,76 @@ puts {
</form>
</div>
<div id=aexpiry title="Auto-Expiry" style="display: none">
<div id=aexpiry title="Auto-Expiry Settings"
style="display: none; line-height: 1em;">
<form id=aexpiry_form>
<input type=hidden name="dir" id="aexpiry_ldir" value="">
}
puts {
<table border=0>
<tr>
<th>
<tr><th align=right>
<label for="aexpiry_days">
<b>Expire after</b>
<span class=blood>(in days)</span>
<b>Remove recordings after</b> (in days)
<br><span class=footnote>
(Leave blank to skip age check)
</span>
</label>
</th>
<td>
</th><td>
<input name="aexpiry_days" id="aexpiry_days"
type=number value=0 size=5 maxlength=3
class="text ui-widget-content ui-corner-all">
</td>
</tr>
</td></tr>
<tr><th>
<label for="aexpiry_min">
<b>Keep at least</b>
(number of recordings)
<br>
<span class=footnote>(Oldest will be deleted first)
</span>
</label>
</th><td>
<input name="aexpiry_min" id="aexpiry_min"
type=number value=0 size=5 maxlength=3
class="text ui-widget-content ui-corner-all">
</td></tr>
<tr><th>
<label for="aexpiry_timetype">
<b>For date of recording, use</b>
</label>
</th><td>
<input name="aexpiry_timetype" id="aexpiry_timetype0"
type=radio value=0 checked
class="text ui-widget-content ui-corner-all">
Recording end time
<br>
<input name="aexpiry_timetype" id="aexpiry_timetype1"
type=radio value=1
class="text ui-widget-content ui-corner-all">
<span>
When last watched
<span class=bfootnote>(or end time if unwatched)</span>
</span>
</td></tr>
<tr><th>
<label for="aexpiry_unwatched">
<b>Never delete unwatched recordings</b>
</label>
</th><td>
<input name="aexpiry_unwatched" id="aexpiry_unwatched"
type=checkbox value=1
class="ui-widget-content ui-corner-all">
</td></tr>
</table>
<div id=aexpiry_working class=hidden>
<img src=/img/loading.gif> Applying auto-expiry...
<img src=/img/loading.gif> Applying changes...
</div>
<div id=aexpiry_loading class=hidden>
<img src=/img/loading.gif> Retrieving data...
</div>
</form>
</div>

View File

@@ -0,0 +1,49 @@
#!/mod/bin/jimsh
package require cgi
source /mod/webif/lib/setup
require ts.class pretty_size
jscss script.js style.css
jqplugin touchpunch
header
set rfile [cgi_get file]
set ts [ts fetch $rfile]
set dir [string map {' \\'} [file dirname $rfile]]
set erfile [string map {' \\'} $rfile]
set len [$ts duration 1]
puts "
<script type=text/javascript>
var initbookmarks = '[$ts bookmarks]';
var len = [$ts duration 1];
var file = '$erfile';
var dir = '$dir';
</script>
<fieldset class=cleft>
<legend>Manage Bookmarks</legend>
<table class=keyval cellpadding=5>
<tr><th>File:</th><td>$rfile</td></tr>
<tr><th>Length:</th><td>[clock format $len -format %T]</td></tr>
<tr><th>Size:</th><td>[pretty_size [$ts size]] ([$ts get definition])</td></tr>
<tr><th>Bookmarks<br><span class=footnote>(enter in seconds)</span></th><td>
<input id=bookmarks size=80 maxlength=255 init=\"[$ts bookmarks]\"
value=\"\" />
<button id=update>Update</button>
<br>
<span id=bookmarkstime></span>
</td></tr><tr><td align=right>
<button class=left id=addbmark>Add Bookmark</button>
<button class=left id=delbmark>Remove Bookmark</button>
</td><td><div id=slider></div></td></tr>
</table>
<div id=buttons>
<button id=save>Save Bookmarks</button>
<button id=back>Back to Media Browser</button>
</div>
<div id=results class=\"hidden blood\"></div>
"

View File

@@ -0,0 +1,20 @@
#!/mod/bin/jimsh
package require cgi
source /mod/webif/lib/setup
require ts.class
httpheader
set file [cgi_get file]
set bookmarks [cgi_get bookmarks ""]
if {[system inuse $file]} {
puts "This file is in use. Cannot process at the moment."
exit
}
set ts [ts fetch $file]
$ts setbookmarks [split [string trim $bookmarks]]
puts "Bookmarks saved successfully."

View File

@@ -0,0 +1,132 @@
var curval = 0;
var $slider;
function
setvals()
{
values = $.trim($('#bookmarks').val()).split(/ +/);
if (!values.length || values[0] == '')
{
refreshtimes();
return;
}
nvalues = [];
$.each(values, function(k, v) {
if (v > len)
v = len;
if (v < 0)
v = 0;
nvalues.push(v);
});
values = nvalues;
$('#bookmarks').val(values.join(' '));
sortmarks();
refreshtimes();
}
function
draw_slider()
{
if ($slider)
$slider.slider('destroy');
else
$slider = $('#slider');
setvals();
values = $.trim($('#bookmarks').val()).split(/ +/);
if (!values.length || values[0] == '')
{
$slider = null;
return;
}
$slider.slider({
min: 0,
max: len,
step: 1,
values: values,
start: function(event, ui) {
curval = ui.value;
},
stop: function(event, ui) {
curval = ui.value;
sortmarks();
refreshtimes();
},
slide: function(event, ui) {
var marks = '';
for (var i = 0; i < ui.values.length; ++i)
marks += ui.values[i] + ' ';
$('#bookmarks').val($.trim(marks));
setvals();
}
});
};
function
refreshtimes()
{
var t = '';
values = $.trim($('#bookmarks').val()).split(/ +/);
if (!values.length || values[0] == '')
{
$('#bookmarkstime').text(t);
return;
}
$.each(values, function(k, v) {
t += new Date(null, null, null, null, null, v)
.toTimeString().match(/\d{2}:\d{2}:\d{2}/)[0] + ' ';
});
$('#bookmarkstime').text(t);
}
function
sortmarks()
{
var a = $.trim($('#bookmarks').val()).split(/ +/);
a.sort(function(a, b){return a-b});
$('#bookmarks').val(a.join(" "));
}
$(function() {
$('#bookmarks').val($('#bookmarks').attr('init'));
draw_slider();
$('#addbmark').button({icons: {primary: "ui-icon-plus"}, text: false})
.on('click', function() {
$('#bookmarks').val('0 ' + $('#bookmarks').val());
draw_slider();
});
$('#delbmark').button({icons: {primary: "ui-icon-minus"}, text: false})
.on('click', function() {
var cur = $('#bookmarks').val();
cur = $.trim(cur.replace(
new RegExp('(^| )' + curval + '( |$)', ''), ' '));
$('#bookmarks').val(cur);
draw_slider();
});
$('#save').button({icons: {primary: "ui-icon-disk"}})
.on('click', function() {
$.post('save.jim', {
file: file,
bookmarks: $('#bookmarks').val()
}, function(data) {
$('#results').html(data)
.slideDown('slow').delay(5000).slideUp('slow');
});
});
$('#back').button({icons: {primary: "ui-icon-arrowreturnthick-1-w"}})
.on('click', function() {
window.location = '../index.jim?dir=' + dir;
});
$('#update').button()
.on('click', function() {
draw_slider();
});
});

View File

@@ -0,0 +1,16 @@
#slider
{
margin-top: 5px;
}
#buttons
{
margin-top: 5px;
}
#buttons2
{
margin-top: 5px;
}

View File

@@ -9,13 +9,14 @@ jscss crop.js
header
set rfile [cgi_get file]
set invert [cgi_get invert 0]
set ts [ts fetch $rfile]
set dir [file dirname $rfile]
set len [$ts duration 1]
puts "
<fieldset class=cleft>
<fieldset>
<legend>Crop recording</legend>
<table class=keyval cellpadding=5>
@@ -24,12 +25,9 @@ puts "
<tr><th>Size:</th><td>[pretty_size [$ts size]] ([$ts get definition])</td></tr>
<tr><th>Bookmarks:</th><td>[$ts get bookmarks] @ "
set flag 0
foreach b [$ts bookmarks] {
if $flag { puts -nonewline ", " }
incr flag
puts -nonewline [clock format $b -format "%T"]
}
puts [join [lmap i [$ts bookmarks 1] {
clock format $i -format "%T"
}] ", "]
puts "</td></tr><tr><th>File</th><td>"
@@ -41,10 +39,16 @@ proc div {type left right} {
$type</div>"
}
set bookmarks {}
if {$invert} {
append bookmarks "0 "
}
append bookmarks [$ts bookmarks]
set keeping 0
set last 0
set start -1
foreach b [$ts bookmarks] {
foreach b $bookmarks {
if {$start < 0} {
set start $b
continue
@@ -94,6 +98,7 @@ puts "
></span>
<div id=cropdiv style=\"padding: 1em\">
<button id=invert invert=$invert>Invert selection</button>
<button id=cropit>Perform crop operation</button>
</div>
@@ -101,9 +106,9 @@ puts "
Cropping: <div id=progressbar></div>
</div>
<button id=back class=hidden>Back to media list</button>
<button id=back>Back to media list</button>
<div id=output class=pre style=\"margin-top: 10px\"></div>
<div id=output class=\"hidden pre\" style=\"margin-top: 10px\"></div>
</fieldset>
"

View File

@@ -24,8 +24,9 @@ $('#cropit').button().click(function() {
$('#cropdiv').hide('slow');
$('#progressdiv').show('slow');
handle = setInterval("update()", 1000);
$('#output').text('Please do not interrupt...')
.load('execute.jim?file=' + $('#params').attr('file'),
$('#output').show().text('Please do not interrupt...')
.load('execute.jim?file=' + $('#params').attr('file') +
'&invert=' + $('#invert').attr('invert'),
function() {
clearInterval(handle);
handle = 0;
@@ -34,5 +35,10 @@ $('#cropit').button().click(function() {
});
});
$('#invert').button().on('click', function() {
window.location = 'crop.jim?file=' + $('#params').attr('file') +
'&invert=' + ($(this).attr('invert') == '1' ? '0' : '1');
});
});

View File

@@ -7,6 +7,7 @@ require ts.class pretty_size system.class
httpheader
set rfile [cgi_get file]
set invert [cgi_get invert]
if {[system inuse $rfile]} {
puts "This file is in use. Cannot process at the moment."
@@ -25,7 +26,7 @@ set origdir "$dir/_original"
if {![file exists $origdir]} { file mkdir $origdir }
set shname [file tail $base]
puts "Processing $shname"
puts "Processing $shname (inverted: $invert)"
if {[file exists "$origdir/$shname.ts"]} {
puts "This recording already exists within _original"
@@ -33,6 +34,8 @@ if {[file exists "$origdir/$shname.ts"]} {
exit
}
set bookmarks [$ts bookmarks]
puts "Moving recording to $origdir"
set tail [file tail $base]
@@ -42,17 +45,36 @@ foreach ext $tsgroup {
file rename "$base.$ext" "${origdir}/$tail.$ext"
}
puts [exec /mod/bin/nicesplice \
-in "$origdir/$shname" \
-out "$dir/$shname" \
-cutBookMarks]
set cmd [list /mod/bin/nicesplice \
-in "$origdir/$shname" \
-out "$dir/$shname"]
if {$invert} {
if {[expr [llength $bookmarks] % 2] != 0} {
lappend bookmarks [$ts duration 1]
}
foreach k [array names bookmarks] {
lappend cmd -cut $($k * 10) $($bookmarks($k) * 10)
}
} else {
lappend cmd "-cutBookMarks"
}
puts "CMD: $cmd"
puts [exec {*}$cmd]
#puts [exec /mod/bin/nicesplice \
# -in "$origdir/$shname" \
# -out "$dir/$shname" \
# -cutBookMarks]
set newname "$shname-[clock seconds]"
puts "Renaming file group to $newname"
ts renamegroup "$dir/$shname.ts" $newname
exec /mod/bin/hmt "+setfilename=$newname" "$dir/$newname.hmt"
# New nicesplice shrinks whilst cropping.
exec /mod/bin/hmt "+shrunk" "$dir/$newname.hmt"
# No longer required - nicesplice now sets this flag.
#exec /mod/bin/hmt "+shrunk" "$dir/$newname.hmt"
set croptime [expr [expr [clock milliseconds] - $cropstart] / 1000.0]
puts "Time taken: $croptime"

View File

@@ -2,7 +2,7 @@
package require cgi
source /mod/webif/lib/setup
require pretty_size
require pretty_size progressbar
httpheader
@@ -79,6 +79,11 @@ if {$type eq "ts"} {
<td>[$ts duration] minute(s).
<font class=also>(Scheduled: [expr [$ts get scheddur] / 60])
</font></td>
</tr><tr>
<th>Resumes</th>
<td>[expr [$ts get resume] / 60] minutes into recording.
[progressbar $([$ts get resume] * 100 / [$ts duration 1])]
</td>
</tr><tr>
<th>Size</th>
<td>$sz</td>
@@ -111,7 +116,10 @@ puts "</td>
<td>[$ts get flags]
"
if {[$ts get bookmarks]} {
puts " \[Bookmarks: [$ts get bookmarks]\]"
puts " \[Bookmarks: [$ts get bookmarks] @ [join \
[lmap i [$ts bookmarks 1] {
clock format $i -format "%T"
}] ", "]"
}
puts "</tr>"

View File

@@ -2,10 +2,15 @@
package require cgi
source /mod/webif/lib/setup
require ts.class pretty_size system.class settings.class escape browse.class
require ts.class pretty_size system.class settings.class escape browse.class \
plugin epg.class
jqplugin contextMenu bar enadis
jscss script.js style.css
set plugins { dmenu {} menu {} }
eval_plugins browse
header
set nicesplice [system pkginst nicesplice]
@@ -37,7 +42,7 @@ set model [system model]
set dustbin [system dustbin 1]
proc icon {img {hover ""} {extra ""} {class "va"}} {
puts -nonewline "<img src=$img class=\"$class\" height=21 $extra"
puts -nonewline "<img src=\"$img\" class=\"$class\" height=21 $extra"
if {$hover ne ""} {
puts -nonewline " alt=\"$hover\" title=\"$hover\""
}
@@ -88,7 +93,7 @@ set dircount 0
set filecount 0
proc entry {file} {{i 0}} {
global dircount filecount
global dircount filecount dinuse
set bfile [file tail $file]
regsub -all " +" $bfile "" tbfile
@@ -169,6 +174,11 @@ proc entry {file} {{i 0}} {
set dlna 0
set shrunk 0
if {$type eq "ts"} {
if {$bfile in $dinuse} {
icon "/img/inuse.png"
}
icon [epg channeliconpath [$ts get channel_name]] \
[$ts get channel_name] "" "va browsechannel"
set genre [$ts get genre]
set glist [ts genrelist]
if {[dict exists $glist $genre]} {
@@ -314,6 +324,7 @@ switch $order {
default { set files [lsort -nocase $files] }
}
set dinuse [system dirinuse $dir]
foreach file $files { entry "$dir/$file" }
puts "

View File

@@ -4,7 +4,7 @@ package require cgi
source /mod/webif/lib/setup
require ts.class pretty_size
jqplugin progressbar touchbridge
jqplugin progressbar touchpunch
jscss join.js join.css
header

View File

@@ -1,4 +1,9 @@
var plugins = {
menu: {},
dmenu: {}
};
var dir;
function disableall()
@@ -131,24 +136,6 @@ function new_folder_callback(data, status, xhr)
$.each(data, set_folder_new);
}
//function insert_shrunk(file, perc)
//{
// if (perc == 0)
// {
// file = file.replace(/[ ]/g, '');
// file = file.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
// //console.log("File: (%s) = (%s)", file, perc);
// $('#sp_' + file).show();
// }
//}
//function shrunk_callback(data, status, xhr)
//{
// //console.log("Status: %s", status);
// //console.dir(data);
// $.each(data, insert_shrunk);
//}
function delete_callback(file, dir, id)
{
var el = 'div.bf#' + id;
@@ -220,6 +207,14 @@ function aexpiry_submit()
function() { window.location.reload(true); });
}
function aexpiry_remove()
{
$('#aexpiry_working').slideDown('slow');
var s = $('#aexpiry_form').serialize();
$.get('/browse/aexpiry.jim?act=remove&' + s,
function() { window.location.reload(true); });
}
function newdir_submit()
{
var s = $('#newdirform_form').serialize();
@@ -283,13 +278,16 @@ function preparemenu(el, menu)
else
$(menu).disableContextMenuItems('#thm');
if (el.attr('shrunk') == 0)
$(menu).enableContextMenuItems('#strip');
else
$(menu).disableContextMenuItems('#strip');
if (el.attr('thmok') == 1)
$(menu).enableContextMenuItems('#vthm');
else
$(menu).disableContextMenuItems('#vthm');
$(menu).enableContextMenuItems('#strip');
if (el.attr('rsize') > 4294967296)
$(menu).enableContextMenuItems('#chunk');
else
@@ -301,7 +299,6 @@ function preparemenu(el, menu)
else
$(menu).changeContextMenuItem('#new', 'Mark new');
$(menu).enableContextMenuItems('#lock');
if (el.attr('locked') == 1)
{
@@ -390,10 +387,27 @@ function preparedmenu(el, menu)
fixdmenu(el, menu, 'autodecrypt', '#decrypt', 'Auto-decrypt', 1);
fixdmenu(el, menu, 'autompg', '#mpg', 'Auto-mpg', 0);
fixdmenu(el, menu, 'automp3', '#mp3', 'Auto-audio', 0);
fixdmenu(el, menu, 'autoexpire', '#expire', 'Auto-expire', 0);
//fixdmenu(el, menu, 'autoexpire', '#expire', 'Auto-expire', 0);
}
$(document).ready(function() {
function flagdir(file, flag, iconset, output, options)
{
var url = '/browse/flagdir.jim?dir=' + file +
'&flag=' + flag;
$(output).slideDown().load(url, function() {
$(iconset)
.empty()
.html('<img src=/img/loading.gif> Updating...')
.load('/browse/iconset.jim?file=' + file);
if ($(options).attr(flag) == '1')
$(options).attr(flag, 0);
else
$(options).attr(flag, 1);
}).delay(3000).slideUp();
}
$(function() {
dir = $('#dir').text();
@@ -461,13 +475,15 @@ var menuclick = function(action, el, pos)
break;
case 'vthm':
// window.open('/browse/bmpw.jim?file=' + file, 'hxwebifbmp',
// 'height=156,width=280,toolbar=no,' +
// 'scrollbars=no,menubar=no,location=no,titlebar=no');
$('#thmbmp').attr('src', 'bmp.jim?file=' + file);
$('#bmpdialogue').dialog('open');
break;
case 'bmarks':
window.location.href = '/browse/bookmarks/?file=' +
file;
break;
case 'download':
window.location.href = '/browse/download.jim?file=' +
file + '&base=' +
@@ -505,28 +521,14 @@ var menuclick = function(action, el, pos)
break;
default:
alert('Unhandled action: ' + action);
if (plugins.menu[action])
plugins.menu[action](file);
else
alert('Unhandled action: ' + action);
break;
}
};
function flagdir(file, flag, iconset, output, options)
{
var url = '/browse/flagdir.jim?dir=' + file +
'&flag=' + flag;
$(output).load(url, function() {
$(iconset)
.empty()
.html('<img src=/img/loading.gif> Updating...')
.load('/browse/iconset.jim?file=' + file);
if ($(options).attr(flag) == '1')
$(options).attr(flag, 0);
else
$(options).attr(flag, 1);
}).delay(3000).slideUp();
}
var dmenuclick = function(action, el, pos)
{
var direl = $(el).parent().parent();
@@ -587,19 +589,37 @@ var dmenuclick = function(action, el, pos)
break;
case 'expire':
if ($(el).attr('autoexpire') == 1)
flagdir(file, 'autoexpire', iconset, results, el);
else
{
$('#aexpiry_ldir').val(decodeURIComponent(file));
if ($(el).attr('autoexpiredays') > 0)
$('#aexpiry_days')
.val($(el).attr('autoexpiredays'));
else
$('#aexpiry_days').val(7);
$('#aexpiry_working').hide('fast');
$('#aexpiry').dialog('open');
}
$('#aexpiry_ldir').val(decodeURIComponent(file));
// Initialise form with default values
$('#aexpiry_days').val("");
$('#aexpiry_timetype0').prop('checked', true);
$('#aexpiry_min').val("");
$('#aexpiry_unwatched').prop('checked', false);
$('#aexpiry_form input').disable();
$('#aexpiry_working').hide('fast');
$('#aexpiry_loading').show('fast');
$.getJSON('aexpiry.jim?act=fetch&dir=' + file, function(data) {
$.each(data, function(key, val) {
if (key == 'days')
$('#aexpiry_days').val(val);
else if (key == 'keep')
$('#aexpiry_min').val(val);
else if (key == 'keepnew')
$('#aexpiry_unwatched')
.prop('checked',
val == "1" ? true : false);
else if (key == 'type')
$('#aexpiry_timetype' + val)
.prop('checked', true);
});
$('#aexpiry_loading').hide('slow');
$('#aexpiry_form input').enable();
});
$('#aexpiry').dialog('open');
break;
case 'flat':
@@ -640,7 +660,10 @@ var dmenuclick = function(action, el, pos)
break;
default:
alert('Unhandled action: ' + action);
if (plugins.dmenu[action])
plugins.dmenu[action](file, iconset, results, el);
else
alert('Unhandled action: ' + action);
break;
}
};
@@ -772,6 +795,7 @@ var dmenuclick = function(action, el, pos)
modal: true,
buttons: {
"Update": aexpiry_submit,
"Remove Settings": aexpiry_remove,
"Close": function() {
$(this).dialog('close');
}
@@ -821,10 +845,6 @@ var dmenuclick = function(action, el, pos)
$.getJSON('/browse/sizes.jim?dir=' + encodeURIComponent(dir),
folder_size_callback);
// Flag shrunk recordings
// $.getJSON('/browse/shrunk.jim?dir=' + encodeURIComponent(dir),
// shrunk_callback);
// Flag folders with unwatched items
$.getJSON('/browse/newdir.jim?dir=' + encodeURIComponent(dir),
new_folder_callback);

View File

@@ -21,6 +21,15 @@ html>body
{
clear: left;
}
.right, .cright
{
float: right;
}
.cright
{
clear: right;
}
fieldset.left, fieldset.cleft
{
display: inline;
@@ -229,14 +238,18 @@ pre, .pre
background: transparent;
}
.footnote
.footnote, .bfootnote
{
color: #ff4000;
background: transparent;
font-size: 70%;
font-weight: bold;
}
.footnote
{
color: #ff4000;
}
.blueshade
{
background: #b9daff;

View File

@@ -72,8 +72,8 @@ foreach dir $dirs {
if {$doit} {
# Dooooo, it.
$ts settitle $syn
ts renamegroup $file $fn
$ts set_deduped
ts renamegroup $file $fn
}
}
}

View File

@@ -11,6 +11,7 @@ source process.jim
set dir [cgi_get dir "/media/My Video"]
set doit [cgi_get doit 0]
set reset [cgi_get reset 0]
jscss script.js
@@ -31,6 +32,11 @@ foreach file [readdir $dir] {
set file "$dir/$file"
if {[file extension $file] ne ".hmt"} { continue }
if {$reset} {
set ts [ts fetch $file 1]
$ts unset_deduped
}
set base [file tail [file rootname $file]]
lassign [dedupprocess $file] stat ts syn fn
@@ -69,8 +75,8 @@ foreach file [readdir $dir] {
if {$doit} {
# Dooooo, it.
$ts settitle $syn
ts renamegroup $file $fn
$ts set_deduped
ts renamegroup $file $fn
puts -nonewline "Done"
}
}
@@ -90,7 +96,11 @@ puts {
<button id=browse>Back to media browser</button>
}
if {!$doit} { puts "<button id=dedup>Process folder</button>" }
if {!$doit} {
puts "<button id=dedup>Process folder</button>"
} else {
puts "<button id=reset>Force re-processing of folder.</button>"
}
puts {
</small>

View File

@@ -17,8 +17,7 @@ proc dedupprocess {file} {{seen {}}} {
set base [file tail [file rootname $file]]
set syn [dedupnormalise [$ts get synopsis] [$ts get title]]
# Escape special characters to create the filename.
regsub -all -- {[\/ &]} $syn "_" fn
regsub -all -- {[?]} $fn "" fn
set fn [system filename $syn]
set stat ok
if {[$ts inuse]} {

View File

@@ -10,5 +10,9 @@ $('#dedup').button().click(function() {
window.location = window.location + '&doit=1';
});
$('#reset').button().click(function() {
window.location = window.location + '&reset=1';
});
});

View File

@@ -25,8 +25,10 @@ puts {
<option value=0>-- Select diag or type name in box below --
}
foreach diag [array names ::diagmeta] {
puts "<option value=\"$diag\">$diag\n"
catch {
foreach diag [array names ::diagmeta] {
puts "<option value=\"$diag\">$diag\n"
}
}
puts {

View File

@@ -8,7 +8,12 @@ jqplugin enadis tabsupport filetree
jscss script.js style.css
header
set file [cgi_get file "/tmp/hosts"]
set file [cgi_get file -]
set backdesc [cgi_get backdesc "Back to diagnostics"]
set backlink [cgi_get backlink "/diag/diag.jim"]
if {$file ne "-"} {
puts "<script type=text/javascript>forcefile = '$file';</script>"
}
puts {
@@ -33,10 +38,12 @@ class="ui-widget ui-corner-all"></textarea>
</fieldset>
<div class=cleft>
<button id=back>Back to diagnostics</button>
}
puts "<button id=back dst=\"$backlink\">$backdesc</button>"
puts {
</div>
<div class=cleft style="margin-top: 1em">
<div id=qedit class=cleft style="margin-top: 1em">
<fieldset>
<legend> Commonly edited files </legend>
<ul>

View File

@@ -1,4 +1,6 @@
var forcefile = false;
$(function() {
var file = null;
@@ -100,8 +102,8 @@ $('#revert').click(function() {
});
$('#back').click(function() {
window.location = '/diag/diag.jim';
});
window.location = $(this).attr('dst');
});
function createf_submit()
{
@@ -148,4 +150,10 @@ $('a.qfile').on('click', function() {
loadfile($(this).text());
});
if (forcefile)
{
loadfile(forcefile);
$('#open,#create,#qedit').remove();
}
});

View File

@@ -98,7 +98,7 @@ if {$lcn > 0} { puts "</tr>" }
puts "</table>"
puts "
<a href=/cgi-bin/settings.jim>
<a href=/settings/settings.jim>
<img border=0 height=14 src=/images/421_1_00_CH_Title_2R_Arrow.png>
Visit settings to change EPG options.
</a><br>

BIN
webif/html/img/blank.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

BIN
webif/html/img/inuse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
webif/html/img/inuse2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

BIN
webif/html/img/nav/down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

BIN
webif/html/img/nav/last.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

BIN
webif/html/img/nav/left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

BIN
webif/html/img/nav/top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

BIN
webif/html/img/nav/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

View File

@@ -0,0 +1,14 @@
/*! Copyright 2012, Ben Lin (http://dreamerslab.com/)
* Licensed under the MIT License (LICENSE.txt).
*
* Version: 1.0.16
*
* Requires: jQuery >= 1.2.3
*/
(function(a){a.fn.addBack=a.fn.addBack||a.fn.andSelf;
a.fn.extend({actual:function(b,l){if(!this[b]){throw'$.actual => The jQuery method "'+b+'" you called does not exist';}var f={absolute:false,clone:false,includeMargin:false};
var i=a.extend(f,l);var e=this.eq(0);var h,j;if(i.clone===true){h=function(){var m="position: absolute !important; top: -1000 !important; ";e=e.clone().attr("style",m).appendTo("body");
};j=function(){e.remove();};}else{var g=[];var d="";var c;h=function(){c=e.parents().addBack().filter(":hidden");d+="visibility: hidden !important; display: block !important; ";
if(i.absolute===true){d+="position: absolute !important; ";}c.each(function(){var m=a(this);var n=m.attr("style");g.push(n);m.attr("style",n?n+";"+d:d);
});};j=function(){c.each(function(m){var o=a(this);var n=g[m];if(n===undefined){o.removeAttr("style");}else{o.attr("style",n);}});};}h();var k=/(outer)/.test(b)?e[b](i.includeMargin):e[b]();
j();return k;}});})(jQuery);

View File

@@ -7,11 +7,12 @@
height: 78px;
font-size: 13px;
line-height: 1.5em;
background: url('/img/bubble.png') left top no-repeat;
background: url(/img/bubble.png) left top no-repeat;
padding: 10px 0 0 0;
text-shadow: 0px 1px 0px #fff;
margin-left: -7em;
margin-top: -6em;
z-index: 1000;
opacity: 0;
}
@@ -24,7 +25,7 @@
height: 21px;
color: #fff;
text-shadow: 0px 1px 0px #000;
background: url('/img/button.png') left top no-repeat;
background: url(/img/button.png) left top no-repeat;
}
.jcatitle {

View File

@@ -1,50 +1,49 @@
/*
* jQuery Plugin : jConfirmAction
*
* by Hidayat Sagita
* Original by Hidayat Sagita
* http://www.webstuffshare.com
* Licensed Under GPL version 2 license.
*
* Modified by af123
*/
(function($){
jQuery.fn.jConfirmAction = function (options, callback) {
// Some jConfirmAction options (limited to customize language) :
// question : a text for your question.
// yesAnswer : a text for Yes answer.
// cancelAnswer : a text for Cancel/No answer.
var theOptions = jQuery.extend ({
jQuery.fn.dojConfirmAction = function(options, callback) {
var options = jQuery.extend ({
question: "Are You Sure?",
yesAnswer: "Yes",
cancelAnswer: "Cancel"
}, options);
return this.each (function () {
$(this).click(function(e) {
e.preventDefault();
var obj = $(this);
var p = $(this);
if($(this).next('.question').length <= 0)
$(this).after('<div class="jcaquestion">'+theOptions.question+'<br/> <span class="jcayes">'+theOptions.yesAnswer+'</span><span class="jcacancel">'+theOptions.cancelAnswer+'</span></div>');
$(this).next('.jcaquestion').animate({opacity: 1}, 300);
$('.jcayes').bind('click', function() {
callback(p);
});
$('.jcacancel').bind('click', function(){
$(this).parents('.jcaquestion').fadeOut(300, function() {
$(this).remove();
});
});
});
if (obj.next('.jcaquestion').length <= 0)
obj.after('<div class=jcaquestion>' +
options.question + '<br/>' +
'<span class=jcayes>' + options.yesAnswer +
'</span>' +
'<span class=jcacancel>' + options.cancelAnswer +
'</span></div>');
o = obj.next('.jcaquestion');
o.animate({opacity: 1}, 300);
o.find('.jcayes').on('click', function() {
o.fadeOut(300, function() { $(this).remove(); });
callback(obj);
});
o.find('.jcacancel').on('click', function() {
o.fadeOut(300, function() { $(this).remove(); });
});
}
jQuery.fn.jConfirmAction = function(options, callback) {
return this.each(function () {
$(this).on('click', function(e) {
e.preventDefault();
$(this).dojConfirmAction(options, callback);
});
});
};
})(jQuery);

View File

@@ -18,4 +18,5 @@
.context-menu-item.icon-mp3 { background-image: url(/img/context/mp3.png); }
.context-menu-item.icon-clock { background-image: url(/img/context/clock.png); }
.context-menu-item.icon-thm { background-image: url(/img/context/thumb.png); }
.context-menu-item.icon-bookmark { background-image: url(/img/context/bookmark.png); }

View File

@@ -73,5 +73,6 @@
.contextMenu LI.mp3 A { background-image: url(/img/context/mp3.png); }
.contextMenu LI.clock A { background-image: url(/img/context/clock.png); }
.contextMenu LI.thm A { background-image: url(/img/context/thumb.png); }
.contextMenu LI.bookmark A { background-image: url(/img/context/bookmark.png); }

View File

@@ -6,7 +6,8 @@
$(this)
.removeClass('ui-state-disabled')
.removeClass('ui-button-disabled')
.removeProp('disabled');
.prop('disabled', false)
.removeAttr('aria-disabled');
});
};

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
ios-style-checkboxes

View File

@@ -1,4 +1,5 @@
.iPhoneCheckContainer {
-webkit-transform:translate3d(0,0,0);
position: relative;
height: 27px;
cursor: pointer;
@@ -7,16 +8,14 @@
position: absolute;
top: 5px;
left: 30px;
opacity: 0;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); }
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0; }
.iPhoneCheckContainer label {
white-space: nowrap;
font-size: 17px;
line-height: 17px;
font-weight: bold;
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
text-transform: uppercase;
cursor: pointer;
display: block;
height: 27px;
@@ -31,13 +30,12 @@
-khtml-user-select: none; }
.iPhoneCheckDisabled {
opacity: 0.5;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50); }
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
opacity: 0.5; }
label.iPhoneCheckLabelOn {
color: white;
background: url('/img/iphone-style-checkboxes/on.png?1282083753') no-repeat;
background: url('images/iphone-style-checkboxes/on.png?1284697268') no-repeat;
text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.6);
left: 0;
padding-top: 5px; }
@@ -45,7 +43,7 @@ label.iPhoneCheckLabelOn {
padding-left: 8px; }
label.iPhoneCheckLabelOff {
color: #8b8b8b;
background: url('/img/iphone-style-checkboxes/off.png?1282083753') no-repeat right 0;
background: url('images/iphone-style-checkboxes/off.png?1284697268') no-repeat right 0;
text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.6);
text-align: right;
right: 0; }
@@ -60,16 +58,89 @@ label.iPhoneCheckLabelOff {
top: 0;
left: 0;
width: 0;
background: url('/img/iphone-style-checkboxes/slider_left.png?1282083753') no-repeat;
background: url('images/iphone-style-checkboxes/slider_left.png?1284697268') no-repeat;
padding-left: 3px; }
.iPhoneCheckHandleRight {
height: 100%;
width: 100%;
padding-right: 3px;
background: url('/img/iphone-style-checkboxes/slider_right.png?1282083753') no-repeat right 0; }
background: url('images/iphone-style-checkboxes/slider_right.png?1284697268') no-repeat right 0; }
.iPhoneCheckHandleCenter {
height: 100%;
width: 100%;
background: url('/img/iphone-style-checkboxes/slider_center.png?1282083753'); }
background: url('images/iphone-style-checkboxes/slider_center.png?1284697268'); }
.iOSCheckContainer {
position: relative;
height: 27px;
cursor: pointer;
overflow: hidden; }
.iOSCheckContainer input {
position: absolute;
top: 5px;
left: 30px;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0; }
.iOSCheckContainer label {
white-space: nowrap;
font-size: 17px;
line-height: 17px;
font-weight: bold;
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
cursor: pointer;
display: block;
height: 27px;
position: absolute;
width: auto;
top: 0;
padding-top: 5px;
overflow: hidden; }
.iOSCheckContainer, .iOSCheckContainer label {
user-select: none;
-moz-user-select: none;
-khtml-user-select: none; }
.iOSCheckDisabled {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
opacity: 0.5; }
label.iOSCheckLabelOn {
color: white;
background: url('images/ios-style-checkboxes/on.png?1284697268') no-repeat;
text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.6);
left: 0;
padding-top: 5px; }
label.iOSCheckLabelOn span {
padding-left: 8px; }
label.iOSCheckLabelOff {
color: #8b8b8b;
background: url('images/ios-style-checkboxes/off.png?1284697268') no-repeat right 0;
text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.6);
text-align: right;
right: 0; }
label.iOSCheckLabelOff span {
padding-right: 8px; }
.iOSCheckHandle {
display: block;
height: 27px;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
width: 0;
background: url('images/ios-style-checkboxes/slider_left.png?1284697268') no-repeat;
padding-left: 3px; }
.iOSCheckHandleRight {
height: 100%;
width: 100%;
padding-right: 3px;
background: url('images/ios-style-checkboxes/slider_right.png?1284697268') no-repeat right 0; }
.iOSCheckHandleCenter {
height: 100%;
width: 100%;
background: url('images/ios-style-checkboxes/slider_center.png?1284697268'); }

View File

@@ -4,6 +4,13 @@
*/
;(function($, iphoneStyle) {
$.fn._width = function()
{
if ($.fn.actual != null)
return $(this).actual('width');
return $(this).width();
};
// Constructor
$[iphoneStyle] = function(elem, options) {
this.$elem = $(elem);
@@ -61,12 +68,12 @@ $.extend($[iphoneStyle].prototype, {
// Automatically resize the handle or container
optionallyResize: function(mode) {
var onLabelWidth = this.onLabel.width(),
offLabelWidth = this.offLabel.width();
var onLabelWidth = this.onLabel._width();
offLabelWidth = this.offLabel._width();
if (mode == 'container') {
var newWidth = (onLabelWidth > offLabelWidth) ? onLabelWidth : offLabelWidth;
newWidth += this.handle.width() + 15;
newWidth += this.handle._width() + 15;
} else {
var newWidth = (onLabelWidth < offLabelWidth) ? onLabelWidth : offLabelWidth;
}
@@ -146,11 +153,11 @@ $.extend($[iphoneStyle].prototype, {
// Setup the control's inital position
initialPosition: function() {
this.offLabel.css({ width: this.container.width() - 5 });
this.offLabel.css({ width: this.container._width() - 5 });
// var offset = ($.browser.msie && $.browser.version < 7) ? 3 : 6;
var offset = 6;
this.rightSide = this.container.width() - this.handle.width() - offset;
this.rightSide = this.container._width() - this.handle._width() - offset;
if (this.$elem.is(':checked')) {
this.handle.css({ left: this.rightSide });

View File

@@ -0,0 +1,11 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);

View File

@@ -2,6 +2,7 @@
function s(query) {return $("div.ui-page-active " + query);}
$(document).on('pageshow', '#indexpage', function() {
console.log('pageshow - indexpage');
$('div.status').last().empty()
.load('/cgi-bin/status.jim', function() {
$(this).slideDown('slow');
@@ -9,6 +10,7 @@ $(document).on('pageshow', '#indexpage', function() {
});
$(document).on('pagecreate', '#indexpage', function() {
console.log('pagecreate - indexpage');
$('a.refresh').on('click', function(e) {
e.preventDefault();
$.mobile.loading('show');
@@ -16,7 +18,6 @@ $(document).on('pagecreate', '#indexpage', function() {
});
$('#xepgsearch').hide('fast');
$('#epgsearch').on('click', function(e) {
e.preventDefault();
$('#xepgsearch').toggle('slow');

View File

@@ -4,7 +4,12 @@ $(document).ready(function() {
var busy = false;
var tswitch = false;
var stick = false;
var stick = true;
// Retrieve the stored selected tab from the hash portion of the URL.
var curtab = ~~(window.location.hash.slice(1));
if (curtab < 0 || curtab > 2)
curtab = 0;
$('#opkgupdate')
.button()
@@ -17,6 +22,7 @@ $(document).ready(function() {
.fadeIn('slow');
$('#pkgtabs').tabs({
active: curtab,
create: function(event, ui) {
$(ui.panel).html("<img src=/img/loading.gif>" +
"Loading data... Please wait...");
@@ -24,6 +30,7 @@ $(document).ready(function() {
$('#pkgtabs').tabs('disable');
},
activate: function(event, ui) {
window.location.hash = ui.newTab.index();
if (busy)
{
alert('Please wait until the current ' +
@@ -81,8 +88,6 @@ $(document).ready(function() {
}
});
jQuery.ajaxSetup({progressInterval: 1});
function loaddata(data, status)
{
if (window.console)
@@ -97,7 +102,7 @@ $(document).ready(function() {
$('#complete').show('slow');
if (status == 'success' && !stick)
$('#dialogue').dialog('close');
stick = false;
//stick = false;
}
else
$('#dresults').append(data);
@@ -123,6 +128,7 @@ $(document).ready(function() {
type: "GET",
url: opkg + arg,
progress: loaddata,
progressInterval: 500,
success: function(data, status) {
loaddata(data, status);
},

View File

@@ -58,6 +58,7 @@ puts {
<div id=fchange title="Change folder" style="display: none">
<form id=fchangeform>
<input type=hidden name=sid id=fchangeslot value=0>
<input type=hidden name=table id=fchangetable value=TBL_RESERVATION>
<table border=0>
<tr>
<th>

View File

@@ -14,9 +14,7 @@ set event [rsv slot $table $slot]
# Humax TV replaces these characters.
# "%*./:<>?\|
set dir "[system mediaroot]/[\
regsub -all {["%*\./:<>?\\|]} [$event folder] "_"]"
set dir "[system mediaroot]/[system filename [$event folder]]"
if {[file exists $dir]} {
puts "Folder $dir already exists."

View File

@@ -143,7 +143,16 @@ proc eventrow {event {table TBL_RESERVATION} {pending 0}} {
puts "<a class=event href=#
xs=$svcmap($service_id) xe=$event_id>
[clock format $start \
-format {%a %d %b %Y %H:%M}]</a><br>"
-format {%a %d %b %Y %H:%M}]</a>"
if {$service_id != [$event get hsvc]} {
set ch [system strip [\
get_channel_attr_byhsvc \
$service_id szSvcName]]
puts "<img width=15 src=\"[\
epg channeliconpath $ch]\""
puts "title=\"$ch\" alt=\"$ch\">"
}
puts "<br>"
} else {
puts "[clock format $start \
-format {%a %d %b %Y %H:%M}]

View File

@@ -152,7 +152,8 @@ function preparemenu(el, menu)
else
$('#optmenu').disableContextMenuItems('#mkfolder');
if ($(el).attr('table') != 'pending' && $(el).attr('reckind') == 4)
// if ($(el).attr('table') != 'pending' && $(el).attr('reckind') == 4)
if ($(el).attr('reckind') == 4)
$('#optmenu').enableContextMenuItems('#folder');
else
$('#optmenu').disableContextMenuItems('#folder');
@@ -194,6 +195,7 @@ function menuclick(action, el, pos)
case 'folder':
$('#fchangeslot').val(sid);
$('#fchangename').val($(el).find('a.schedule').text());
$('#fchangetable').val($(el).attr('table'));
$('#fchange').dialog('open');
break;

View File

@@ -62,7 +62,7 @@ foreach service $services {
puts "<tr><td class=even>$name</td>"
if (!$installed) {
puts "<td colspan=3><i>Not installed</i></td></tr>"
puts "<td colspan=2><i>Not installed</i></td></tr>"
continue
}

View File

@@ -2,7 +2,7 @@
package require cgi
source /mod/webif/lib/setup
require settings.class plugin system.class
require settings.class plugin system.class spinner.class
httpheader
@@ -126,12 +126,18 @@ if {$aclact ne "-" && $acluser ne "-"} {
exit
}
jqplugin form iphone-style-checkboxes
jqplugin form actual iphone-style-checkboxes touchpunch
jscss settings.js
header
[spinner new {
text "Loading Settings..."
size "1.2em"
style "margin: 1em;"
}] start
puts {
<div id=accordion>
<div id=accordion class=hidden>
}
proc setting_toggle {name attr checked {invert 0} {val 0}} {
@@ -248,7 +254,7 @@ puts "
<table>
"
setting_toggle "HTTPS web server?" "https" \
[file exists /mod/etc/mongoose.cert] 0 1
[file exists /mod/etc/webif.pem] 0 1
puts "
</table>
</legend></fieldset>

View File

@@ -21,11 +21,6 @@
$(document).ready(function () {
$(":submit").button();
//$('[type="checkbox"] :not(.yesno)').iphoneStyle();
$('[type="checkbox"]').iphoneStyle({
checkedLabel: 'YES',
uncheckedLabel: 'NO'
});
$('form.auto').each(function(i, el) {
var id = $(this).attr('id');
var output = '#' + id + '_output';
@@ -41,7 +36,7 @@ $(document).ready(function () {
});
});
$('.setting_toggle').change(function() {
$('.setting_toggle').on('change', function() {
var arg = '0';
var urlargs;
if ($(this).prop('checked'))
@@ -59,7 +54,7 @@ $(document).ready(function () {
else
urlargs = attr + '=' + arg;
$(this).disable();
// $(this).disable();
$(output)
.empty()
@@ -67,18 +62,31 @@ $(document).ready(function () {
.html('<img src=/img/loading.gif> Please wait...')
.load('/settings/settings.jim?' + urlargs,
function() {
$(el).enable();
// $(el).enable();
$(output)
.css('font-style', 'italic')
.delay(2000).fadeOut('slow');
});
});
// Use window.name to remember the active accordion index
if (window.name == "")
window.name = "0";
accordionindex = ~~window.name;
$('#accordion').accordion({
active: accordionindex,
header: 'h4',
collapsible: true,
active: 0,
heightStyle: 'content'
heightStyle: 'content',
activate: function(event, ui) {
window.name = $('#accordion').accordion('option', 'active');
}
}).show();
$('[type="checkbox"]').iphoneStyle({
checkedLabel: 'YES',
uncheckedLabel: 'NO'
});
// For now - until plugins are updated.

View File

@@ -1,9 +1,18 @@
#!/mod/bin/jimsh
source /mod/webif/lib/setup
require system.class
require system.class pretty_size
lassign [system diskspace 1] size used perc free fperc tsrbuf tsrused
# Calculate the TSR reserve
set tsrreserve $($tsrbuf - $tsrused)
# Adjust values to account for the TSR reserve
set free $($free - $tsrreserve)
set used $($size - $free)
set fperc $($free * 100 / $size)
set perc $(100 - $fperc)
lassign [system diskspace] size used perc free fperc
set dsindex $($perc * 25 / 100 + 1)
if {$dsindex > 25} { set dsindex 25 }
set dsfile [format "%02d" $dsindex]
@@ -27,9 +36,9 @@ puts "
<span style=\"float: right\">
<br>
Total space: $size<br>
Used: $used ($perc%)<br>
Free: $free ($fperc%)
Total space: [pretty_size $size]<br>
Used: [pretty_size $used] ($perc%)<br>
Free: [pretty_size $free] ($fperc%)
</span>
"

View File

@@ -9,18 +9,13 @@ if {$modbuild > 0} {
append modver " (build $modbuild)"
}
if {[dict exists $env SERVER_SOFTWARE]} {
set wstype "Lighttpd"
} else {
set wstype "Mongoose"
}
puts "<span class=blood style=\"font-size: 0.9em; float: right; clear: right\">
Web interface version: [system pkgver webif] ($wstype)<br>
Web interface version: [system pkgver webif]<br>
Custom firmware version: $modver
"
catch {set fhtcpversion [system fhtcpversion]}
catch {set kernelver [system kernelver]}
puts "<br>Humax Version: $fhtcpversion (kernel $kernelver)"
puts "<br>Serial Number: [system serialno]"
puts "</span>"

View File

@@ -1,13 +1,15 @@
#!/mod/bin/jimsh
source /mod/webif/lib/setup
require lock system.class ts.class tdelete pretty_size browse.class \
require lock system.class ts.class pretty_size browse.class \
safe_delete settings.class plugin
set settings [settings]
set loglevel [$settings autolog]
set audiomp3 [$settings audiomp3]
set modules {decrypt dedup shrink mpg mp3 expire}
if {![acquire_lock webif_auto]} {
puts "Cannot acquire exclusive lock, terminating."
exit
@@ -27,6 +29,7 @@ if {[lindex $argv 0] eq "-d"} {
} else {
set logfd [open "/mod/tmp/auto.log" "a+"]
}
proc log {msg {level 1}} {
if {$level > $::loglevel} return
puts $::logfd "[\
@@ -49,8 +52,6 @@ proc endclock {size} {
return "[pretty_size $size] in $el seconds - [pretty_size $rate]/s"
}
set modules {decrypt dedup shrink mpg mp3 expire}
foreach mod $modules {
set "hook_pre${mod}scan" {}
set "hook_pre$mod" {}
@@ -58,11 +59,11 @@ foreach mod $modules {
set "hook_post${mod}scan" {}
}
proc register {type fn} {
proc register {type fn {priority 50}} {
global "hook_$type"
if {[info exists "hook_$type"]} {
lappend "hook_$type" $fn
log "Registered $fn for $type hook." 1
lappend "hook_$type" [list $fn $priority]
log "Registered $fn for $type hook with priority $priority." 1
} else {
log "Unknown hook hook_$type" 0
}
@@ -71,8 +72,10 @@ proc register {type fn} {
proc runplugin {name {ts 0}} {
set var "hook_$name"
global $var
foreach p [subst $$var] {
if {[catch {$p $ts} msg]} {
foreach p [lsort -index end -decreasing -integer [subst $$var]] {
lassign $p fn priority
log "Running $name plugin $fn (priority $priority)" 2
if {[catch {uplevel 1 $fn $ts} msg]} {
log "Plugin error: $msg" 0
}
}
@@ -125,7 +128,7 @@ if {![file exists $tmp]} {
}
# Clean-up the temporary directory
foreach file [readdir -nocomplain $tmp] { tdelete "$tmp/$file" }
foreach file [readdir -nocomplain $tmp] { file tdelete "$tmp/$file" }
if {[system pkginst undelete]} {
set dustbin "[system dustbin]"
@@ -140,10 +143,23 @@ set recalc 0
proc dorecalc {dir} {
global recalc
if {!$recalc} return
log "Running unwatched recalculation for $dir" 2
ts resetnew $dir
set recalc 0
}
proc startop {op file} {
global tmp
set fp [open "$tmp/.op" "w"]
puts $fp "$op:$file"
$fp close
}
proc endop {} {
global tmp
file delete "$tmp/.op"
}
proc dedup {dir} {
log "DEDUP: \[$dir]" 2
loop i 0 1 {
@@ -154,32 +170,8 @@ proc dedup {dir} {
}
}
proc do_expire {ts} {
global ax_days
set file [$ts get file]
# Calculate the age of the file in days.
set age $(([clock seconds] - [$ts get start]) / 86400.0)
log " EXPIRE: $file (age = $age)" 2
if {$age > $ax_days} {
if {[$ts inuse]} {
log " EXPIRE: $file ($age > $ax_days)"
log " In use."
return
}
runplugin preexpire $ts
if {[safe_delete $file]} {
log " EXPIRE: $file ($age > $ax_days)" 0
log " Deleted." 0
runplugin postexpire $ts
incr ::recalc
}
}
}
proc do_shrink {ts} {
global tmp dustbin tsgroup
global tmp dustbin tsgroup processed_files
set file [$ts get file]
if {[$ts flag "Shrunk"]} {
@@ -187,6 +179,18 @@ proc do_shrink {ts} {
return
}
# If the directory is flagged for decryption as well as shrink
# then check to see if decryption has already occured. If not,
# defer the shrink for now.
set dir [file dirname $file]
if {[file exists "$dir/.autodecrypt"] || [scanup $dir decrypt] == 1} {
log " $dir is also set for decryption." 2
if {[$ts flag "ODEncrypted"]} {
log " $file - deferring shrink until decrypted." 1
return
}
}
set file [file rootname [$ts get file]]
if {[$ts inuse]} {
@@ -213,6 +217,7 @@ proc do_shrink {ts} {
}
set size [$ts size]
dsc $size
startop shrink [$ts get file]
runplugin preshrink $ts
startclock
log " SHRINK: $file" 0
@@ -227,6 +232,7 @@ proc do_shrink {ts} {
} msg]} {
log "Error during shrink: $msg" 0
system notify "$file - auto-shrink - error $msg."
endop
return
}
@@ -255,11 +261,13 @@ proc do_shrink {ts} {
}
$ts set_shrunk
log "Done... [endclock $size]" 0
lappend processed_files [$ts get file]
runplugin postshrink $ts
endop
}
proc do_decrypt {ts} {
global tmp dustbin
global tmp dustbin processed_files
set file [$ts get file]
set rfile [file rootname $file]
@@ -270,6 +278,11 @@ proc do_decrypt {ts} {
return
}
if {[$ts flag "Encrypted"]} {
log " $file - Protected (Enc flag)." 2
return
}
lassign [$ts dlnaloc "127.0.0.1"] url
if {$url eq ""} {
log " $file - Not yet indexed."
@@ -291,7 +304,7 @@ proc do_decrypt {ts} {
set anencd [exec /mod/bin/stripts -qE $rfile]
if {$anencd != "1"} {
log " $file - already decrypted but the HMT flag is wrong." 0
system notify "$file - auto-decrypt - file is already decrypted but the HMT flag is wrong."
system notify "$file - auto-decrypt - file is already decrypted but the HMT flag is wrong. Run the 'fixencflags' diagnostic."
return
}
@@ -299,8 +312,7 @@ proc do_decrypt {ts} {
set size [$ts size]
dsc $size
runplugin predecrypt $ts
set flagfile "$tmp/decrypting.$bfile"
file touch $flagfile
startop dec $file
startclock
log " DECRYPT: $rfile" 0
log " DLNA: $url" 0
@@ -309,7 +321,7 @@ proc do_decrypt {ts} {
if {[file size $file] != [file size "$tmp/$bfile"]} {
log " $file - File size mismatch." 0
file delete "$tmp/$bfile"
file delete $flagfile
endop
return
}
@@ -318,7 +330,7 @@ proc do_decrypt {ts} {
if {[$ts inuse]} {
log " $file - In use."
file delete "$tmp/$bfile"
file delete $flagfile
endop
return
}
@@ -333,7 +345,7 @@ proc do_decrypt {ts} {
log " $file - File did not decrypt properly." 0
system notify "$file - auto-decrypt failed."
file delete "$tmp/$bfile"
file delete $flagfile
endop
return
}
@@ -363,15 +375,16 @@ proc do_decrypt {ts} {
}
}
} else {
tdelete "$rfile.encrypted"
file tdelete "$rfile.encrypted"
}
log "Done... [endclock $size]" 0
file delete $flagfile
lappend processed_files [$ts get file]
runplugin postdecrypt $ts
endop
}
proc do_mpg {ts} {
global tmp tsgroup
global tmp tsgroup processed_files
set file [file rootname [$ts get file]]
@@ -394,6 +407,7 @@ proc do_mpg {ts} {
log " $file - In use."
return
}
startop mpg [$ts get file]
runplugin prempg $ts
dsc [$ts size]
@@ -410,16 +424,19 @@ proc do_mpg {ts} {
} msg]} {
log "Error during mpg extract: $msg" 0
system notify "$file - auto-mpg - error $msg."
endop
return
}
# Move the MPG into the local directory
file rename $tmp/mpg.mpg $file.mpg
lappend processed_files [$ts get file]
runplugin postmpg $ts
endop
}
proc do_mp3 {ts} {
global tmp tsgroup
global tmp tsgroup processed_files
set file [file rootname [$ts get file]]
@@ -443,6 +460,7 @@ proc do_mp3 {ts} {
log " $file - In use."
return
}
startop mp3 [$ts get file]
runplugin premp3 $ts
dsc [$ts size]
@@ -460,6 +478,7 @@ proc do_mp3 {ts} {
} msg]} {
log "Error during mp3 extract: $msg" 0
system notify "$file - auto-mp3 - error $msg."
endop
return
}
@@ -474,7 +493,9 @@ proc do_mp3 {ts} {
# Move the MP3 into the local directory
file rename $tmp/mp3.mp3 $file.mp3
lappend processed_files [$ts get file]
runplugin postmp3 $ts
endop
}
proc entries {dir callback} {
@@ -507,11 +528,93 @@ proc mp3 {dir} {
}
proc expire {dir} {
global ax_days
log "EXPIRE: \[$dir]" 2
set ax_days [{dir expiry} $dir]
entries $dir do_expire
# type 0 keep {} days 2 keepnew 0
set ax [{dir expiry} $dir]
log " $ax" 2
if {![string is integer -strict $ax(keep)]} { set ax(keep) 0 }
if {![string is integer -strict $ax(days)]} { set ax(days) 0 }
if {!$ax(keep) && !$ax(days)} {
log "Expire error ($dir): neither keep nor days set ($ax)" 0
return
}
if {$ax(type) eq "0"} {
set getter [lambda {ts} { list [$ts get end] }]
} else {
set getter [lambda {ts} { list [$ts lastmod] }]
}
set entries [lsort \
-command [lambda {a b} {upvar getter g; expr [$g $a] - [$g $b]}]\
[lmap i [readdir -nocomplain $dir] {
if {![string match {*.ts} $i]} continue
if {[catch {set ts [ts fetch "$dir/$i"]}]} continue
if {$ts == 0} continue
list $ts
}]]
# Entries are now sorted with oldest first, according to the selected
# criterion.
set num [llength $entries]
log " Entries: $num" 2
foreach e $entries { log " [file tail [$e get file]]" 2 }
set now [clock seconds]
foreach ts $entries {
set file [$ts get file]
if {$num <= $ax(keep)} {
log " Remaining ($num) <= keep ($ax(keep))" 2
break
}
log " [file tail $file]"
if {[$ts inuse]} {
log " In use, skipping."
continue
}
if {$ax(keepnew) ne "0" && [$ts flag New]} {
log " Unwatched, skipping."
continue
}
if {$ax(days) > 0} {
# Calculate age in days
set age $(($now - [$getter $ts]) / 86400.0)
log " $age days (cf. $ax(days))"
if {$age < $ax(days)} {
log " Too new, skipping."
continue
}
}
log " Removing."
runplugin preexpire $ts
if {![safe_delete $file]} {
log "Unknown error in safe_delete, aborting." 0
break
}
log " EXPIRE: removed $file" 0
runplugin postexpire $ts
incr ::recalc
incr num -1
}
}
proc scan_run {dir flag callback} {
global dustbin
if {$dir eq $dustbin} return
if {[string match {\[*} [file tail $dir]]} return
if {[file exists "$dir/.$flag"]} { $callback $dir }
foreach entry [readdir -nocomplain $dir] {
if {[file isdirectory "$dir/$entry"]} {
scan_run "$dir/$entry" $flag $callback
}
}
}
proc scan {dir attr {force 0} {recurse 1}} {{indent 0}} {
@@ -607,13 +710,23 @@ if {[lindex $argv 0] eq "-single"} {
scansingle [lrange $argv 1 end]
} elseif {[llength $argv] > 0} {
set loglevel 2
foreach arg $argv { scan $root $arg }
foreach arg $argv {
set st [clock milliseconds]
log "$arg scan starting."
set processed_files {}
runplugin "pre${arg}scan"
scan $root $arg
runplugin "post${arg}scan" processed_files
log "$arg scan completed in [elapsed $st] seconds."
}
} else {
foreach arg $modules {
set st [clock milliseconds]
log "$arg scan starting."
set processed_files {}
runplugin "pre${arg}scan"
scan $root $arg
runplugin "post${arg}scan"
runplugin "post${arg}scan" processed_files
log "$arg scan completed in [elapsed $st] seconds."
}
}

6
webif/lib/bin/lsof Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
# stderr is always unbuffered so use that...
/mod/bin/lsof "$@" 2>&1
exit 0

View File

@@ -1,5 +1,5 @@
require system.class
require system.class plugin
#if {![exists -proc class]} { package require oo }
#class browse {}
@@ -15,14 +15,21 @@ proc _addicon {img {hover ""} {class va}} {
return $icon
}
proc {dir expiry} {dir} {
if {[catch {
set fd [open "$dir/.autoexpire"]
set days $([read $fd] + 0)
proc {dir expiry} {dir {data {}}} {
if {[llength $data] > 1} {
set fd [open "$dir/.autoexpire" w]
puts $fd "$data(days):$data(type):$data(keep):$data(keepnew):"
$fd close
}]} { set days 0 }
if {!$days} { set days 7 }
return $days
return
}
set ret { days "" type 0 keep "" keepnew 0 }
catch {
set fd [open "$dir/.autoexpire"]
lassign [split [string trim [read $fd]] ":"] \
ret(days) ret(type) ret(keep) ret(keepnew)
$fd close
} msg
return $ret
}
proc {dir iconset} {dir} {
@@ -34,7 +41,7 @@ proc {dir iconset} {dir} {
if {[string match {\[*\]} [file tail $dir]]} { set noflat 1 }
if {[file exists "$dir/.noflatten"]} { set noflat 1 }
if $noflat { lappend icons \
[_addicon "/img/flat-tyre.png" "No-flatten" }
[_addicon "/img/flat-tyre.png" "No-flatten"] }
lappend attrs "noflat=$noflat"
}
@@ -92,13 +99,13 @@ proc {dir iconset} {dir} {
set autoexpire 0
if {[file exists "$dir/.autoexpire"]} {
set days [{dir expiry} $dir]
set autoexpire 1
lappend icons [_addicon "/img/clock.png" \
"Auto-Expire ($days day$($days == 1 ? "" : "s"))"]
lappend attrs "autoexpire=1" "autoexpiredays=$days"
lappend icons [_addicon "/img/clock.png" "Auto-Expire"]
lappend attrs "autoexpire=1"
}
eval_plugins diriconset
return [list $icons $attrs]
}

View File

@@ -110,6 +110,10 @@ epg method type_icon {} {
}
}
proc {epg channeliconpath} {name} {
return "/img/channels/out/$name.png"
}
proc {epg channelicon} {name {width 0} {style ""}} {
set str "<img src=\"/img/channels/out/$name.png\"";
if {$width > 0} { append str " width=$width" }

View File

@@ -55,11 +55,23 @@ proc {file touch} {target {ref ""}} {
}
}
proc {file tdelete} {target} {
if {[file isdirectory $target]} {
foreach f [readdir -nocomplain $target] {
file tdelete "$target/$f"
}
exec /mod/bin/busybox/rm -rf $target
} else {
exec /mod/bin/trm $target
}
}
local proc file {cmd args} {
switch $cmd {
"rename" { tailcall {file rename} {*}$args }
"copy" { tailcall {file copy} {*}$args }
"touch" { tailcall {file touch} {*}$args }
"tdelete" { tailcall {file tdelete} {*}$args }
default { tailcall upcall file $cmd {*}$args }
}
}

View File

@@ -7,7 +7,7 @@ proc hexdump data {
set bytes [string byterange $data $n $($n+15)]
binary scan $bytes H* hex
set hex [regexp -all -inline .. $hex]
regsub -all -- {[^a-z]} $bytes . ascii
regsub -all -- {[^a-z0-9]} $bytes . ascii
append dump [format "%04X: %-48s %-16s\n" $n $hex $ascii]
incr n 16
}

View File

@@ -1,10 +1 @@
#proc {dict merge} {dict args} {
# foreach d $args {
# foreach k [dict keys $d] {
# dict set dict $k [dict get $d $k]
# }
# }
# return $dict
#}

View File

@@ -131,19 +131,28 @@ proc {pkg loaddiagmeta} {} {
}
}
proc {pkg fetchmeta} {} {
set f [socket stream hummypkg.org.uk:80]
$f puts -nonewline "GET /hdrfoxt2/pkg.meta HTTP/1.1\r\n"
$f puts -nonewline "Host: hummypkg.org.uk\r\n"
proc {pkg fetchfile} {url} {
set f [socket stream hpkg.tv:80]
$f puts -nonewline "GET /hdrfoxt2/$url HTTP/1.1\r\n"
$f puts -nonewline "Host: hpkg.tv\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]]
}
set ::pkgmeta [$f read]
# Save the body
set ret [$f read]
$f close
return $ret
}
proc {pkg fetchmeta} {} {
set ::pkgmeta [pkg fetchfile pkg.meta]
set ff [open "/mod/var/pkg.meta" w]
puts $ff $::pkgmeta
@@ -151,18 +160,7 @@ proc {pkg fetchmeta} {} {
}
proc {pkg fetchdiagmeta} {} {
set f [socket stream hummypkg.org.uk:80]
$f puts -nonewline "GET /diag/diag.meta HTTP/1.1\r\n"
$f puts -nonewline "Host: hummypkg.org.uk\r\n"
$f puts -nonewline "Connection: close\r\n"
$f puts -nonewline "\r\n"
set line [string trim [$f gets]]
while {[string length $line]} {
set line [string trim [$f gets]]
}
set ::diagmeta [$f read]
$f close
set ::diagmeta [pkg fetchfile diag.meta]
set ff [open "/mod/var/diag.meta" w]
puts $ff $::diagmeta

View File

@@ -21,6 +21,8 @@ $rsvdb query {attach database '/var/lib/humaxtv/rsvp.db' as pending}
# version.
catch { $rsvdb query {alter table pending add column action int} }
set binaryfields {aulEventToRecordInfo}
class rsv {
ulslot -1
ersvtype 0
@@ -55,9 +57,9 @@ class rsv {
}
require findhsvc
if {![exists -proc binary]} { package require binary }
rsv method aul {} {
if {![exists -proc binary]} { package require binary }
set aul {}
for {set i 0} {$i < [string length $aulEventToRecordInfo]} {incr i 16} {
binary scan [string range $aulEventToRecordInfo $i $($i + 15)] \
@@ -67,6 +69,16 @@ rsv method aul {} {
return $aul
}
proc {rsv mkaul} {e} {
$e get_channel_info
return [binary format iiii \
[$e get channel_hsvc] \
[$e get start] \
[$e end] \
[$e get event_id] \
]
}
rsv method clear_ulslot {} {
set ulslot -1
}
@@ -255,7 +267,7 @@ rsv method insert {{table pending} {force 0}} {
set fields [lsort [$self vars]]
foreach field {aulEventToRecordInfo szSvcName usLcn sort} {
foreach field {szSvcName usLcn sort} {
set df [lsearch $fields $field]
set fields [lreplace $fields $df $df]
}
@@ -267,10 +279,17 @@ rsv method insert {{table pending} {force 0}} {
set vals {}
foreach field $fields {
# Escape any quotes embedded in the data.
regsub -all {'} [$self get $field] {''} f
lappend vals "'$f'"
#lappend vals "'[$self get $field]'"
set f [$self get $field]
if {$field in $::binaryfields && [string bytelength $f] > 1} {
if {![regexp -nocase {^[0-9a-f]+$} $f} {
binary scan $f H* f
}
lappend vals "X'$f'"
} else {
# Escape any quotes and percents embedded in the data.
regsub -all {['%]} $f {&&} f
lappend vals "'$f'"
}
}
set query "insert into ${table}("
@@ -486,11 +505,17 @@ proc {rsv construct} {event type} {
set args(ucRecKind) 4
set args(szCRID) "$ccrid[$event get series_crid]"
set args(szFPBRecPath) "$args(szevtname)"
set progs [lmap i [epg fetch dump -scrid [$event get series_crid]] {
set events {}
set progs [lmap i [\
epg dbfetch dump -scrid [$event get series_crid] \
-sort start] {
if {[set ecrid [$i get event_crid]] eq ""} { continue }
binary scan [rsv mkaul $i] H* ret
lappend events $ret
list "1$::ccrid$ecrid"
}]
set args(szEventToRecord) "[join $progs "|"]|"
set args(aulEventToRecordInfo) [join $events ""]
}
return [rsv new $args]
@@ -509,15 +534,19 @@ proc {rsv backup} {file} {
set fields [lsort [[rsv] vars]]
#puts $fd "# [join $fields "\t"]"
puts $fd "# version 2"
puts $fd "# [join $fields "\t"]"
foreach event $events {
puts " Backing up scheduled event '[$event name]'"
puts -nonewline $fd "event\t"
foreach f $fields {
if {$f eq "aulEventToRecordInfo"} { continue }
puts -nonewline $fd "[$event get $f]\t"
set ret [$event get $f]
if {$f in $::binaryfields} {
binary scan $ret H* ret
}
puts -nonewline $fd "$ret\t"
}
puts $fd ""
}
@@ -566,13 +595,21 @@ proc {rsv restore} {file} {
set data [split [read $fd] "\n"]
set ver 1
foreach line $data {
if {[string match "# version *" $line]} {
set ver [lindex [split $line " "] 2]
puts "Backup version $ver"
}
set vals [split $line "\t"]
if {[lindex $vals 0] ne "event"} { continue }
set vars {}
set i 0
foreach f $fields {
if {$f eq "aulEventToRecordInfo"} { continue }
if {$ver < 2 && $f eq "aulEventToRecordInfo"} {
continue
}
incr i
lappend vars $f [lindex $vals $i]
}

View File

@@ -2,7 +2,7 @@
if {![exists -proc _del_bindir]} {
source /mod/webif/lib/setup
require ts.class system.class tdelete
require ts.class system.class
if {[system pkginst undelete]} {
set _del_dustbin [system dustbin]
@@ -48,7 +48,7 @@ if {![exists -proc _del_bindir]} {
file rename $file $ndir
_del_touch $ndir
} else {
tdelete $file
file tdelete $file
}
return 1
}
@@ -78,7 +78,7 @@ if {![exists -proc _del_bindir]} {
file rename $file $nfile
_del_touch $nfile
} else {
tdelete $file
file tdelete $file
}
catch {file delete "[file rootname $file].hmi"}
return 1

View File

@@ -96,7 +96,7 @@ if {![exists -proc require]} {
foreach c $css { _css $c }
}
require fileops overrides
require fileops overrides utils
# Jim 0.75 removes legacy 'case'
alias case switch

View File

@@ -66,6 +66,18 @@ proc {system fhtcpversion} {} {
return $ver
}
# 822272+6 - MAC address
# 833536 - Serial number
proc {system serialno} {} {
set fd [open /dev/mtd3 r]
$fd seek 833536
set bytes [$fd read 14]
$fd close
return "[string range $bytes 0 1] [string range $bytes 2 8] [
string range $bytes 9 end]"
}
proc {system kernelver} {} {
#1 SMP Sun Mar 25 18:30:38 KST 2012
set ver [string range [exec uname -v] 11 end]
@@ -83,6 +95,7 @@ proc {system kernelver} {} {
"May 8 14:32:30 KST 2013" { format "HDR_1.03.06(b)" }
"Dec 10 14:36:54 KST 2013" { format "HDR_1.03.11" }
"Feb 7 14:15:02 KST 2014" { format "HDR_1.03.12" }
"May 19 22:39:27 BST 2014" { format "HDR_CFW_3.00" }
# HD
"Oct 11 21:14:31 KST 2010" { format "HD_1.01.12" }
@@ -101,30 +114,34 @@ proc {system pkgver} {{pkg webif}} {
return [lrange [split [exec opkg list-installed $pkg] " "] 2 end]
}
proc {system pkginst} {pkg} {{cache {}} {ncache {}}} {
if {$pkg in $cache} { return 1 }
if {$pkg in $ncache} { return 0 }
# It may not be possible to get an opkg lock immediately so
# try several times and throw an error if not.
set status unknown
loop i 0 5 {
if {[catch {set status [exec opkg list-installed $pkg]}]} {
sleep 1
} else break
}
if {$status eq "unknown"} {
error "Could not get opkg lock after 5 seconds."
}
if {$status ne ""} {
lappend $cache $pkg
return 1
}
lappend $ncache $pkg
return 0
proc {system pkginst} {pkg} {
return [file exists "/mod/var/opkg/info/$pkg.control"]
}
#proc {system pkginst} {pkg} {{cache {}} {ncache {}}} {
# if {$pkg in $cache} { return 1 }
# if {$pkg in $ncache} { return 0 }
#
# # It may not be possible to get an opkg lock immediately so
# # try several times and throw an error if not.
# set status unknown
# loop i 0 5 {
# if {[catch {set status [exec opkg list-installed $pkg]}]} {
# sleep 1
# } else break
# }
# if {$status eq "unknown"} {
# error "Could not get opkg lock after 5 seconds."
# }
#
# if {$status ne ""} {
# lappend cache $pkg
# return 1
# }
# lappend ncache $pkg
# return 0
#}
proc {system mediaroot} {} {
switch [system model] {
HDR { return "/media/My Video" }
@@ -143,56 +160,72 @@ proc {system dustbin} {{short 0}} {
return "[system mediaroot]/$dustbin"
}
proc {system diskspace} {} {
proc {system diskpart} {} {
switch [system model] {
HDR { set part /mnt/hd2 }
HD { set part /media/drive1 }
HDR { return "/mnt/hd2" }
HD { return "/media/drive1" }
}
}
set size 0
set used 0
set free 0
set perc 0
set dev 0
foreach line [split [exec /mod/bin/busybox/df -h $part 2>>/dev/null] "\n\r"] {
proc {system diskdev} {} {
set part [system diskpart]
foreach line [split [\
exec /mod/bin/busybox/df $part 2>>/dev/null] "\n\r"] {
if {[string match "/*" $line]} {
regsub -all -- {[[:space:]]+} $line " " line
set fields [split $line]
set dev [lindex $fields 0]
set size [lindex $fields 1]
set used [lindex $fields 2]
set free [lindex $fields 3]
set perc [string trimright [lindex $fields 4] "%"]
set fperc $(100 - $perc)
lassign [split $line] dev
break
}
}
return [list $size $used $perc $free $fperc $dev]
return $dev
}
proc {system disk} {} {
return [string range [lindex [system diskspace] 5] 0 end-1]
return [string range [system diskdev] 0 end-1]
}
require pretty_size
proc {system diskspace} {{raw 0}} {
set part [system diskpart]
lassign [exec /mod/bin/busybox/stat -f -c {%S %b %f} $part] \
bsize blocks fblocks
set size $($bsize * $blocks)
set free $($bsize * $fblocks)
set used $($size - $free)
set perc $($used * 100 / $size)
set fperc $(100 - $perc)
switch [system model] {
HDR { set tsrdir "/mnt/hd2/Tsr" }
HD { set tsrdir "/media/drive1/.tsr" }
}
if {[file isdirectory $tsrdir]} {
set tsrbuf 21474836480
lassign [exec du -ks $tsrdir] tsrused
set tsrused $($tsrused * 1024)
} else {
set tsrbuf 0
set tsrused 0
}
if {!$raw} {
set size [pretty_size $size]
set free [pretty_size $free]
set used [pretty_size $used]
set tsrbuf [pretty_size $tsrbuf]
set tsrused [pretty_size $tsrused]
}
return [list $size $used $perc $free $fperc $tsrbuf $tsrused]
}
proc {system diskfree} {} {
switch [system model] {
HDR { set part /mnt/hd2 }
HD { set part /media/drive1 }
}
set free 0
foreach line [split [exec /mod/bin/busybox/df -k $part 2>>/dev/null] "\n\r"] {
if {[string match "/*" $line]} {
regsub -all -- {[[:space:]]+} $line " " line
set fields [split $line]
set free [lindex $fields 3]
set free $($free * 1024)
break
}
}
return $free
lassign [exec /mod/bin/busybox/stat -f -c {%S %f} [system diskpart]] \
bsize fblocks
return $($bsize * $fblocks)
}
proc {system busy} {} {
@@ -201,7 +234,8 @@ proc {system busy} {} {
return 0
}
set c 0
foreach line [split [exec /mod/bin/lsof -p $pid] "\n"] {
foreach line [split [\
exec /mod/webif/lib/bin/lsof -X -Fn -p $pid] "\n"] {
if {[string match {*Video*.ts} $line]} { incr c }
}
if {$c > 0} { return 1 }
@@ -209,23 +243,22 @@ proc {system busy} {} {
}
proc {system inuse} {file} {
# Is anything using the file?
set file [file rootname [file tail $file]]
# Escape any unicode characters to match lsof output.
foreach range [lreverse [\
regexp -inline -indices -all -- {[\x80-\xff]} $file]] {
set i [lindex $range 0]
binary scan [string index $file $i] H2 hex
set file [string replace $file $i $i "\\x$hex"]
set op [exec /mod/webif/lib/bin/lsof -X -Fn $file]
if {$op eq ""} {
return 0
} else {
return 1
}
}
set c 0
foreach line [split [exec /mod/bin/lsof] "\n"] {
if {[string first $file $line] >= 0} { incr c }
proc {system dirinuse} {dir} {
set files {}
foreach line [split [\
exec /mod/webif/lib/bin/lsof -X -Fn +d $dir] "\n"] {
if {[string index $line 0] ne "n"} continue
lappend files [file tail $line]
}
if {$c > 0} { return 1 }
return 0
return $files
}
proc {system reboot} {} {
@@ -328,3 +361,34 @@ proc {system display} {hdr hd} {
}
}
proc {system uptime} {} {
set fd [open /proc/uptime r]
set uptime [lindex [split [read $fd]] 0]
$fd close
return $uptime
}
proc {system filename} {str {extra ""}} {
# Humax TV replaces these characters.
# "%*./:<>?\|
set chars "\"%*\./:<>?\\\\|$extra"
return [regsub -all "\[$chars]" $str "_"]
}
proc {system connectivity} {{site "hpkg.tv"}} {
if {[catch {exec /bin/ping -4 -c 2 -W 3 -w 3 -q $site >/dev/null}]} {
return 0
}
return 1
}
proc {system strip} {str} {
if {[string range $str 1 2] eq "i7"} {
set str [string range $str 3 end]
}
if {[string first "\025" $str] == 0} {
set str [string range $str 1 end]
}
return $str
}

View File

@@ -1,19 +1,7 @@
if {![exists -proc tdelete]} {
proc tdelete {path} {
if {[file isdirectory $path]} {
regsub -all {([\\["$])} $path {\\\1} cpath
foreach file [glob -nocomplain "${cpath}/*"] {
if {[file isdirectory $file]} {
tdelete $file
} else {
exec /mod/bin/trm $file
}
}
exec /mod/bin/busybox/rm -rf $path
} else {
exec /mod/bin/trm $path
}
}
# Deprecated - just use {file tdelete}
if {![exists -alias tdelete]} {
alias tdelete {file tdelete}
}

View File

@@ -2,7 +2,7 @@
if {![exists -proc class]} { package require oo }
if {![exists -proc pack]} { package require pack }
source /mod/webif/lib/setup
require tdelete system.class
require system.class
set dmsfile /mnt/hd2/dms_cds.db
@@ -25,6 +25,15 @@ class ts {
schedstart 0
scheddur 0
genre 0
resume 0
}
ts method bfile {} {
return [file tail [file rootname $file]]
}
ts method dir {} {
return [file dirname $file]
}
ts method duration {{raw 0}} {
@@ -43,18 +52,27 @@ ts method _parse {line} {
lassign [split $line "\t"] \
title synopsis definition channel_num channel_name \
start end flags_list guidance bookmarks schedstart scheddur \
genre
genre resume
set flags [split [string range $flags_list 0 end-1] ,]
}
ts method inuse {} {
if {[system inuse [file rootname $file]]} { return 1 }
return 0
ts method lastmod {} {
return [file mtime "[file rootname $file].hmt"]
}
ts method bookmarks {} {
return [exec /mod/bin/hmt -bookmarks $file]
ts method inuse {} {
return [system inuse $file]
}
ts method bookmarks {{aslist 0}} {
set marks [split [string trim [exec /mod/bin/hmt -bookmarks $file]]]
if {$aslist} { return $marks }
return [join $marks " "]
}
ts method setbookmarks {marks} {
exec /mod/bin/hmt +setbookmarks=[join $marks :] $file
}
ts method flag {f} {
@@ -64,49 +82,63 @@ ts method flag {f} {
ts method unlock {} {
set cmd [list /mod/bin/hmt -lock $file]
exec {*}$cmd
lremove flags "Locked"
return 1
}
ts method lock {} {
set cmd [list /mod/bin/hmt +lock $file]
exec {*}$cmd
ladd flags "Locked"
return 1
}
ts method set_shrunk {} {
set cmd [list /mod/bin/hmt +shrunk $file]
exec {*}$cmd
lappend flags "Shrunk"
ladd flags "Shrunk"
return 1
}
ts method set_deduped {} {
set cmd [list /mod/bin/hmt +dedup $file]
exec {*}$cmd
ladd flags "Deduped"
return 1
}
ts method unset_deduped {} {
set cmd [list /mod/bin/hmt -dedup $file]
exec {*}$cmd
lremove flags "Deduped"
return 1
}
ts method unenc {} {
set cmd [list /mod/bin/hmt -protect $file]
exec {*}$cmd
lremove flags "Encrypted"
return 1
}
ts method enc {} {
set cmd [list /mod/bin/hmt +protect $file]
exec {*}$cmd
ladd flags "Encrypted"
return 1
}
ts method set_new {} {
set cmd [list /mod/bin/hmt +new $file]
exec {*}$cmd
ladd flags "New"
return 1
}
ts method set_watched {} {
set cmd [list /mod/bin/hmt -new $file]
exec {*}$cmd
lremove flags "New"
return 1
}
@@ -151,12 +183,16 @@ proc {ts fetch} {file {checked 0}} {
if {![file exists "[file rootname $file].nts"]} { return 0 }
}
if {[file extension $file] ne ".ts"} {
set file "[file rootname $file].ts"
}
return [ts parse $file [ts exec $file]]
}
ts method delete {} {
foreach f [$self fileset] {
tdelete $f
file tdelete $f
puts "Removed $f<br>"
}
return 1
@@ -187,12 +223,14 @@ ts method settitle {newtitle} {
if {[string length newtitle] > 48} { return }
exec /mod/bin/hmt "+settitle=${newtitle}" $file
set title $newtitle
}
ts method setsynopsis {newsynopsis} {
if {[string length newsynopsis] > 252} { return }
exec /mod/bin/hmt "+setsynopsis=${newsynopsis}" $file
set synopsis $newsynopsis
}
ts method setguidance {newguidance} {
@@ -203,10 +241,12 @@ ts method setguidance {newguidance} {
} else {
exec /mod/bin/hmt "+setguidance=${newguidance}" $file
}
set guidance $newguidance
}
ts method setgenre {newgenre} {
exec /mod/bin/hmt "+setgenre=-${newgenre}" $file
set genre $newgenre
}
ts method dlnaloc {{urlbase 0}} {
@@ -279,7 +319,7 @@ ts method mkthm {{offset 0}} {
}
exec /bin/echo -n " " >> $bfile.thm~
file rename -force $bfile.thm~ $bfile.thm
tdelete $bfile.bmp
file tdelete $bfile.bmp
return 1
}
@@ -300,22 +340,22 @@ proc {ts renamegroup} {from to} {
exec /mod/bin/hmt "+setfilename=$to" "${dir}/${to}.hmt"
set ndir [file normalize $dir]
if {![catch {set db [sqlite3.open $::dmsfile]}]} {
catch {
set x [lindex [$db query {select mediaid from tblMedia
where localUrl = '%s'} [file normalize $from]] 0]
lassign $x key mediaid
if {$mediaid ne ""} {
$db query {update tblMedia set localUrl = '%s'
where mediaid = %s} "${ndir}/{$to}.ts" $mediaid
$db query {update tblMedia set title = '%s'
where mediaid = %s} "{$to}.ts" $mediaid
}
}
$db close
}
# set ndir [file normalize $dir]
#
# if {![catch {set db [sqlite3.open $::dmsfile]}]} {
# catch {
# set x [lindex [$db query {select mediaid from tblMedia
# where localUrl = '%s'} [file normalize $from]] 0]
# lassign $x key mediaid
# if {$mediaid ne ""} {
# $db query {update tblMedia set localUrl = '%s'
# where mediaid = %s} "${ndir}/{$to}.ts" $mediaid
# $db query {update tblMedia set title = '%s'
# where mediaid = %s} "{$to}.ts" $mediaid
# }
# }
# $db close
# }
}
proc {ts touchgroup} {target ref} {
@@ -402,8 +442,10 @@ proc {ts iterate} {callback {verbose 0} {dir ""}} {{rootdev 0}} {
if {$verbose} { puts "Scanning directory ($dir)" }
file stat "$dir/" st
if {$st(dev) != $rootdev} return
if {$rootdev != 0} {
file stat "$dir/" st
if {$st(dev) != $rootdev} return
}
foreach entry [readdir -nocomplain $dir] {
if {[file isdirectory "$dir/$entry"]} {

14
webif/lib/utils Normal file
View File

@@ -0,0 +1,14 @@
proc ladd {var args} {
upvar $var v
foreach val $args {
if {$val ni $v} { lappend v $val }
}
}
proc lremove {var val} {
upvar $var v
if {$val ni $v} return
set v [lsearch -all -inline -not -exact $v $val]
}