Compare commits
41 Commits
1.0.12@187
...
1.0.17@214
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c886f6afd2 | ||
|
|
e6d7af1fc4 | ||
|
|
0691577b96 | ||
|
|
876d5b5e8a | ||
|
|
4d895e464d | ||
|
|
252d6bf7f6 | ||
|
|
ea03a67b4a | ||
|
|
3adbeb987a | ||
|
|
23fdc62b81 | ||
|
|
b88691c9e5 | ||
|
|
3c4b907091 | ||
|
|
1c00e63f48 | ||
|
|
59006ff474 | ||
|
|
616c0afff1 | ||
|
|
84899871e1 | ||
|
|
ed042ee230 | ||
|
|
3c44ec33f9 | ||
|
|
02d7bc3f33 | ||
|
|
492b37be41 | ||
|
|
c237f228a8 | ||
|
|
7a523a9ddb | ||
|
|
972366de14 | ||
|
|
aeb96c2c8a | ||
|
|
68f98c8a65 | ||
|
|
61b09db04b | ||
|
|
de2035e1e0 | ||
|
|
b4bd45566e | ||
|
|
692488a11f | ||
|
|
bd27200ba8 | ||
|
|
7e30a4272e | ||
|
|
945007f73d | ||
|
|
fc9c912f99 | ||
|
|
bf67161898 | ||
|
|
f029ab1ce6 | ||
|
|
bfd099a82e | ||
|
|
d9a284994e | ||
|
|
e6df0ae3af | ||
|
|
e14ccce2cc | ||
|
|
60111cd8b1 | ||
|
|
fb81a7e954 | ||
|
|
218221c069 |
@@ -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
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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.$$
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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>"
|
||||
|
||||
@@ -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."
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 <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"]
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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."
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
49
webif/html/browse/bookmarks/index.jim
Executable 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>
|
||||
"
|
||||
|
||||
20
webif/html/browse/bookmarks/save.jim
Executable 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."
|
||||
|
||||
132
webif/html/browse/bookmarks/script.js
Normal 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();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
16
webif/html/browse/bookmarks/style.css
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
#slider
|
||||
{
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#buttons
|
||||
{
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#buttons2
|
||||
{
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
"
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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]} {
|
||||
|
||||
@@ -10,5 +10,9 @@ $('#dedup').button().click(function() {
|
||||
window.location = window.location + '&doit=1';
|
||||
});
|
||||
|
||||
$('#reset').button().click(function() {
|
||||
window.location = window.location + '&reset=1';
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -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
|
After Width: | Height: | Size: 42 B |
BIN
webif/html/img/context/bookmark.png
Normal file
|
After Width: | Height: | Size: 642 B |
BIN
webif/html/img/inuse.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
webif/html/img/inuse2.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
webif/html/img/nav/bottom-grey.png
Normal file
|
After Width: | Height: | Size: 315 B |
BIN
webif/html/img/nav/bottom.png
Normal file
|
After Width: | Height: | Size: 319 B |
BIN
webif/html/img/nav/down-grey.png
Normal file
|
After Width: | Height: | Size: 296 B |
BIN
webif/html/img/nav/down.png
Normal file
|
After Width: | Height: | Size: 300 B |
BIN
webif/html/img/nav/first-grey.png
Normal file
|
After Width: | Height: | Size: 309 B |
BIN
webif/html/img/nav/first.png
Normal file
|
After Width: | Height: | Size: 326 B |
BIN
webif/html/img/nav/last-grey.png
Normal file
|
After Width: | Height: | Size: 323 B |
BIN
webif/html/img/nav/last.png
Normal file
|
After Width: | Height: | Size: 325 B |
BIN
webif/html/img/nav/left-grey.png
Normal file
|
After Width: | Height: | Size: 290 B |
BIN
webif/html/img/nav/left.png
Normal file
|
After Width: | Height: | Size: 300 B |
BIN
webif/html/img/nav/right-grey.png
Normal file
|
After Width: | Height: | Size: 295 B |
BIN
webif/html/img/nav/right.png
Normal file
|
After Width: | Height: | Size: 299 B |
BIN
webif/html/img/nav/top-grey.png
Normal file
|
After Width: | Height: | Size: 299 B |
BIN
webif/html/img/nav/top.png
Normal file
|
After Width: | Height: | Size: 316 B |
BIN
webif/html/img/nav/up-grey.png
Normal file
|
After Width: | Height: | Size: 289 B |
BIN
webif/html/img/nav/up.png
Normal file
|
After Width: | Height: | Size: 300 B |
14
webif/html/lib/jquery.plugin/actual/jquery.actual.min.js
vendored
Normal 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);
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
$(this)
|
||||
.removeClass('ui-state-disabled')
|
||||
.removeClass('ui-button-disabled')
|
||||
.removeProp('disabled');
|
||||
.prop('disabled', false)
|
||||
.removeAttr('aria-disabled');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 260 B |
|
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 324 B |
|
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 321 B |
@@ -0,0 +1 @@
|
||||
ios-style-checkboxes
|
||||
@@ -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'); }
|
||||
|
||||
@@ -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 });
|
||||
|
||||
11
webif/html/lib/jquery.plugin/touchpunch/jquery.ui.touch-punch.min.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/*!
|
||||
* jQuery UI Touch Punch 0.2.3
|
||||
*
|
||||
* Copyright 2011–2014, 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);
|
||||
@@ -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');
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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}]
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
"
|
||||
|
||||
|
||||
@@ -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>"
|
||||
|
||||
|
||||
@@ -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
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# stderr is always unbuffered so use that...
|
||||
/mod/bin/lsof "$@" 2>&1
|
||||
exit 0
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
#}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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]
|
||||
}
|
||||
|
||||