Compare commits

...

34 Commits

Author SHA1 Message Date
hummypkg
ca6129abef update version
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@258 2a923420-c742-0410-a762-8d5b09965624
2011-07-08 20:53:46 +00:00
hummypkg
42b5805c45 finish restart
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@253 2a923420-c742-0410-a762-8d5b09965624
2011-07-08 20:39:57 +00:00
hummypkg
88ada938d1 commit initial backup/restore framework and restart
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@252 2a923420-c742-0410-a762-8d5b09965624
2011-07-07 22:33:19 +00:00
hummypkg
15040206ab work on restore
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@245 2a923420-c742-0410-a762-8d5b09965624
2011-07-06 23:16:20 +00:00
hummypkg
4861459aec checkpoint backup/restore
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@236 2a923420-c742-0410-a762-8d5b09965624
2011-07-05 22:59:34 +00:00
hummypkg
5523ec6a43 initial backup function
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@235 2a923420-c742-0410-a762-8d5b09965624
2011-07-05 18:38:42 +00:00
hummypkg
5f6c7a843c new reservations screen
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@234 2a923420-c742-0410-a762-8d5b09965624
2011-07-05 00:19:02 +00:00
hummypkg
e712f38bb1 fix plugin error
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@233 2a923420-c742-0410-a762-8d5b09965624
2011-07-04 22:41:24 +00:00
hummypkg
61d879e90a update to 0.5.9
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@225 2a923420-c742-0410-a762-8d5b09965624
2011-07-04 20:02:59 +00:00
hummypkg
638d2dedb3 no caching, add draghandle, less flushing
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@224 2a923420-c742-0410-a762-8d5b09965624
2011-07-04 20:01:14 +00:00
hummypkg
d1cfff8899 restructure requires, add initial plugin class and hook into settings
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@220 2a923420-c742-0410-a762-8d5b09965624
2011-07-01 22:56:53 +00:00
hummypkg
9116c6e8a9 improve new folder icon, allow [S]CRID searches from the term box
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@216 2a923420-c742-0410-a762-8d5b09965624
2011-06-30 22:10:22 +00:00
hummypkg
6efcb5bde0 group search terms together
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@215 2a923420-c742-0410-a762-8d5b09965624
2011-06-30 00:16:10 +00:00
hummypkg
444ca7370b update to 0.5.8. Add jim.pack requirement
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@213 2a923420-c742-0410-a762-8d5b09965624
2011-06-29 23:59:00 +00:00
hummypkg
a44be5f1ae better solution to cleaning keywords
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@212 2a923420-c742-0410-a762-8d5b09965624
2011-06-29 23:57:01 +00:00
hummypkg
4e42dcf655 show new folders
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@211 2a923420-c742-0410-a762-8d5b09965624
2011-06-29 23:53:16 +00:00
hummypkg
43db44d742 improve EPG search using drop-down options. Implement package management
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@210 2a923420-c742-0410-a762-8d5b09965624
2011-06-29 22:53:15 +00:00
hummypkg
050cb611bf working on package system
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@209 2a923420-c742-0410-a762-8d5b09965624
2011-06-28 00:20:31 +00:00
hummypkg
d068d93073 improve directory size display
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@207 2a923420-c742-0410-a762-8d5b09965624
2011-06-27 21:59:07 +00:00
hummypkg
7025cf09f5 fix lock, add guidance icons, add new icon
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@205 2a923420-c742-0410-a762-8d5b09965624
2011-06-27 19:57:32 +00:00
hummypkg
32db0c900b depend on hmt 1.0.5
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@204 2a923420-c742-0410-a762-8d5b09965624
2011-06-26 23:13:01 +00:00
hummypkg
d7dcb79dad update to version 0.5.5
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@200 2a923420-c742-0410-a762-8d5b09965624
2011-06-26 23:07:06 +00:00
hummypkg
04453c1815 finish rename function
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@199 2a923420-c742-0410-a762-8d5b09965624
2011-06-26 23:05:38 +00:00
hummypkg
3bc9f5217b add sync script
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@198 2a923420-c742-0410-a762-8d5b09965624
2011-06-25 21:02:26 +00:00
hummypkg
8d67bb82bb more work on rename
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@197 2a923420-c742-0410-a762-8d5b09965624
2011-06-25 20:59:50 +00:00
hummypkg
9faac3c8fe support HD model for EPG
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@196 2a923420-c742-0410-a762-8d5b09965624
2011-06-23 11:14:57 +00:00
hummypkg
0c858b3410 restructure browser
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@194 2a923420-c742-0410-a762-8d5b09965624
2011-06-22 23:36:30 +00:00
hummypkg
1cd0f96bf4 add missing return
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@193 2a923420-c742-0410-a762-8d5b09965624
2011-06-22 10:41:41 +00:00
hummypkg
8e839121de tweak popup
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@192 2a923420-c742-0410-a762-8d5b09965624
2011-06-22 00:32:13 +00:00
hummypkg
7400437a1f add iphone checkboxes and improve services screen
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@191 2a923420-c742-0410-a762-8d5b09965624
2011-06-22 00:21:48 +00:00
hummypkg
26e90143bf add files
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@189 2a923420-c742-0410-a762-8d5b09965624
2011-06-21 22:38:43 +00:00
hummypkg
884e17b3a7 add download option, require busybox 1.18.3-1
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@188 2a923420-c742-0410-a762-8d5b09965624
2011-06-21 22:38:20 +00:00
hummypkg
7202b7e4f8 mv
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@183 2a923420-c742-0410-a762-8d5b09965624
2011-06-17 09:30:09 +00:00
hummypkg
087532136c mv
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif~@181 2a923420-c742-0410-a762-8d5b09965624
2011-06-17 09:29:33 +00:00
84 changed files with 2659 additions and 729 deletions

1
CONTROL/conffiles Normal file
View File

@@ -0,0 +1 @@
etc/webif.db

View File

@@ -1,10 +1,11 @@
Package: webif
Priority: optional
Section: web
Version: 0.5.1
Version: 0.6.0
Architecture: mipsel
Maintainer: af123@hummypkg.org.uk
Depends: mongoose(>=2.11-4),jim-sqlite3,jim-cgi,service-control,busybox,lsof,jim-oo,epg(>=1.0.2)
Depends: mongoose(>=2.11-6),jim(>=0.71-1),jim-sqlite3(>=0.71-1),jim-cgi(>=0.3),jim-oo,jim-pack,service-control,busybox(>=1.18.3-1),lsof,epg(>=1.0.2),hmt(>=1.0.6),ssmtp
Replaces: af123-webif
Conflicts: af123-webif
Description: A web interface for the Humax. In development.
Suggests: ffmpeg
Description: An evolving web interface for the Humax.

BIN
etc/webif.db Normal file

Binary file not shown.

View File

@@ -0,0 +1,75 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/setup
require rsv.class
set dir /mod/var/backup
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
if {![dict exists $_cgi file]} {
puts "No filename supplied."
exit
}
set file [file tail [dict get $_cgi file]]
set ffile "/$dir/$file.rbk"
if {[file exists $ffile]} {
puts "Backup file <i>$file</i> already exists."
exit
}
if {[catch { set fd [open $ffile w] } msg]} {
puts "Error creating backup file. - $msg"
exit
}
puts "Backing up scheduled recordings and events..."
set events [rsv list]
set fields [lsort [[rsv] vars]]
#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"
}
puts $fd ""
}
puts "Done."
puts "Backing up channel favourites..."
set grp 0
foreach res [$rsvdb query {
select eFavGroup,
TBL_FAV.eSvcType,
substr(szSvcName, 2) as szSvcName
from TBL_FAV join TBL_SVC using (hSvc)
order by eFavGroup
}] {
if {$res(eFavGroup) != $grp} {
set grp $res(eFavGroup)
puts " Group $grp"
}
puts " $res(szSvcName)"
puts $fd "fav\t$res(eFavGroup)\t$res(eSvcType)\t$res(szSvcName)"
}
puts "Done."
close $fd
rsv cleanup

View File

@@ -0,0 +1,59 @@
function refresh_files()
{
$('#backup_files').load('/cgi-bin/backup/files.jim', function() {
$('input.restore').change(function() {
$('#restore_button').removeAttr('disabled')
.button('option', 'disabled', false);
$('#delete_button').removeAttr('disabled')
.button('option', 'disabled', false);
});
});
}
$(document).ready(function() {
$('button').button();
refresh_files();
$('#backup_button').click(function() {
$('#backup_working').slideDown();
$('#results').load('/cgi-bin/backup/backup.jim?' +
$('#backup_name').serialize(), function() {
$('#results').slideDown(function() {
$('#backup_working').slideUp();
refresh_files();
});
});
});
$('#delete_button').click(function() {
var backup = $('input.restore').val();
if (confirm('Confirm deletion of ' + backup))
{
$('#results').load('/cgi-bin/backup/delete.jim?' +
$('input.restore').serialize(), function() {
$('#results').slideDown(function() {
refresh_files();
});
});
}
});
$('#restore_button').click(function() {
var backup = $('input.restore').val();
if (confirm('!!!!!!!!!!!!!!!!!!!!!!!!! PLEASE CONFIRM !!!!!!!!!!!!!!!!!!!!!!!!!\n\nAre you sure you wish to erase all scheduled recordings and favourite channels and then restore them from\n' + backup + '?'))
{
$('#restore_working').slideDown();
$('#results').load('/cgi-bin/backup/restore.jim?' +
$('input.restore').serialize(), function() {
$('#results').slideDown(function() {
$('#restore_working').slideUp();
refresh_files();
$('#restore_warning').slideDown();
$('#restart_block').load(
'/cgi-bin/restartblock.jim');
});
});
}
});
});

View File

@@ -0,0 +1,31 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/setup
set dir /mod/var/backup
puts "Content-Type: text/html"
puts "Pragma: nocache"
puts "Expires: Thu, 01 Jan 1970 00:00:00 GMT"
puts ""
cgi_input
#cgi_dump
if {![dict exists $_cgi restore_file]} {
puts "No filename supplied."
exit
}
set file [file tail [dict get $_cgi restore_file]]
set ffile "/$dir/$file.rbk"
if {![file exists $ffile]} {
puts "Backup file <i>$file</i> does not exist."
} elseif {[catch { file delete $ffile } msg]} {
puts "Deletion failed: $msg"
} else {
puts "Successfully deleted <i>$file</i>"
}

View File

@@ -0,0 +1,39 @@
#!/mod/bin/jimsh
package require cgi
puts "Content-Type: text/html"
puts "Pragma: nocache"
puts "Expires: Thu, 01 Jan 1970 00:00:00 GMT"
puts ""
set dir "/mod/var/backup"
proc empty {} {
puts "<font style=\"color: grey\">
<i>No current backup files.</i>
</font>"
}
if {![file isdirectory $dir]} {
empty
exit
}
set backups [glob -nocomplain "$dir/*.rbk"]
if {![llength $backups]} {
empty
exit
}
foreach backup $backups {
set b [file rootname [file tail $backup]]
puts "<input name=restore_file class=restore
type=radio value=\"$b\">$b <font class=footnote>(
[clock format [file mtime $backup] -format {%c %Z}]
)</font></input>
<br>
"
}

View File

@@ -0,0 +1,136 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/setup
require rsv.class
set dir /mod/var/backup
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
#set _cgi(restore_file) "backup-2011-Jul-05-19:22"
if {![dict exists $_cgi restore_file]} {
puts "No filename supplied."
exit
}
set file [file tail [dict get $_cgi restore_file]]
set ffile "/$dir/$file.rbk"
if {![file exists $ffile]} {
puts "Backup file <i>$file</i> does not exist."
exit
}
if {[catch { set fd [open $ffile r] } msg]} {
puts "Error opening backup file. - $msg"
exit
}
proc findhsvc {channel} {
global rsvdb
set hsvc [$rsvdb query "
select hSvc
from channel.TBL_SVC
where szSvcName = '$channel'
or szSvcname = '\025$channel'
limit 1
"]
if {[llength $hsvc] == 1} {
return [lindex [lindex $hsvc 0] 1]
} else {
return 0
}
}
puts "Restoring scheduled events..."
$rsvdb query {delete from TBL_RESERVATION}
set fields [lsort [[rsv] vars]]
set data [split [read $fd] "\n"]
foreach line $data {
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 }
incr i
lappend vars $f [lindex $vals $i]
}
set rsv [rsv new $vars]
# Need to fix up channel and CRID mappings in case something has
# changed during a channel scan.
puts " Restoring [$rsv name]"
set bad 0
# First, the service number
set ohsvc [$rsv get hsvc]
if {$ohsvc > 0} {
set hsvc [$rsv fix_hsvc]
if {$hsvc == 0} {
puts " Cannot find channel, restore failed."
set bad 1
} elseif {$hsvc != $ohsvc} {
puts -nonewline " Service number has "
puts "changed $ohsvc -> $hsvc, fixing."
} else {
puts " No change in channel service."
}
}
if {!$bad} { $rsv insert }
}
puts "Restoring favourite channels..."
$rsvdb query {delete from channel.TBL_FAV}
set grp 0
foreach line $data {
set vals [split $line "\t"]
if {[lindex $vals 0] ne "fav"} { continue }
set group [lindex $vals 1]
set type [lindex $vals 2]
set chan [lindex $vals 3]
set hsvc [findhsvc $chan]
if {$grp != $group} {
set grp $group
puts " Group $grp"
}
puts " $chan"
if {!$hsvc} {
puts " Cannot map channel name to service."
continue
}
set query "
insert into channel.TBL_FAV(hSvc, eFavGroup, eSvcType)
values($hsvc, $group, $type);
"
$rsvdb query $query
}
close [open /tmp/.restartpending w]
close $fd
rsv cleanup

View File

@@ -1,74 +1,33 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/ts.class
source /mod/var/mongoose/lib/setup
require ts.class pretty_size
puts "Content-Type: text/html"
puts ""
set ignore {.nts .thm .hmt .hmi}
set standard {.avi .mpg .wmv .mkv}
set include {.ts .avi .mpg .mpeg .wmv .mkv .mp3 .mp4 .mov}
cgi_input
#cgi_dump
#set _cgi(tsfile) "/media/My Video/Family Guy/2.19._Excellence_in_Broadcasting.ts"
#set _cgi(action) "delete"
#set env(REQUEST_URI) ''
proc tsfile {file bfile {ajax 0}} {{i 0}} {
set ts [ts fetch $file]
if {$ajax == 0} { puts "<div class=\"va tsfile\" id=[incr i]>" }
puts "
<a class=ts file=\"$file\" href=#>
<img class=va border=0 width=45
src=/images/741_1_10_Video_Title.png>
$bfile
</a>
"
if {[$ts get definition] eq "HD"} {
puts "<img class=va src=/images/172_1_00_HD.png height=21>"
} else {
puts "<img class=va src=/images/172_1_26_SD.png height=21>"
}
set locked 0
if {[$ts flag "Locked"] > 0} {
set locked 1
puts "<img class=va src=/images/178_1_00_Icon_Lock.png
height=21>"
}
puts "
<a class=tsopt file=\"$file\" href=#>
<img class=\"opt va\" border=0 width=45 did=$i locked=$locked
src=/images/181_1_00_Help5_OPT_Plus.png>
</a>
<div class=\"results blood\" style=\"margin: 0 0 0 5em\"></div>
"
if {$ajax == 0} { puts "</div>" }
}
proc genfile {file bfile} {
puts "
<div class=va>
<a href=#>
<img class=va border=0 width=45 style=\"padding: 0.3em 0\"
src=/images/743_4_10_Video_Xvid_File.png>
$bfile
</a>
</div>
"
}
#set _cgi(dir) "/media/My Video/Chuggington"
proc directory {file bfile} {
regsub -all " +" $bfile "" tbfile
puts "<div class=va>"
puts "<a href=$::env(REQUEST_URI)?dir=[cgi_quote_url $file]>"
puts "<img border=0 class=va src=/images/711_1_09_Media_Folder.png>"
puts "$bfile</a></div>"
puts "<img border=0 class=va id=\"img$tbfile\"
src=/images/711_1_09_Media_Folder.png>"
puts "$bfile</a><span class=filesize id=\"$tbfile\">
</span></div>"
}
proc entry {file {ajax 0}} {
set bfile [lindex [split $file /] end]
proc entry {file} {{i 0}} {
set bfile [file tail $file]
if {[string index $bfile 0] == "\025"} {
set bfile [string range $bfile 1 end]
}
@@ -77,94 +36,97 @@ proc entry {file {ajax 0}} {
continue
}
set ext [file extension $file]
if {$ext eq ".ts"} {
tsfile $file $bfile $ajax
continue
}
if {$ext in $::ignore} { continue }
if {$ext in $::standard} {
genfile $file $bfile
continue
}
}
if {$ext in $::ignore || $ext ni $::include} { continue }
if {[dict exists $_cgi tsfile]} {
set file [dict get $_cgi tsfile]
set ts [ts fetch $file]
file stat $file st
set sz [pretty_size $st(size)]
if {[dict exists $_cgi action]} {
switch [dict get $_cgi action] {
entry {
entry $file 1
}
delete {
if {[$ts delete]} {
puts "Successfully deleted $file."
} else {
puts "Problem deleting $file, [$ts get error]"
}
}
lock {
set action lock
if {[$ts flag "Locked"]} { set action unlock }
if {[$ts $action]} {
puts "Successfully [set action]ed $file."
} else {
puts "Problem [set action]ing $file,
[$ts get error]"
}
}
}
exit
set base [file rootname $file]
if {$ext eq ".ts" && [file exists "${base}.nts"]} {
set type ts
set ts [ts fetch $file 1]
set img Video_TS
} else {
set type gen
set ts 0
set img Video_Other
}
source /mod/var/mongoose/lib/epg.class
puts "
<table class=keyval>
<tr>
<th>Title</th>
<td>[$ts get title]</td>
</tr><tr>
<th>Synopsis</th>
<td>[$ts get synopsis]</td>
</tr><tr>
<th>Definition</th>
<td>
<div class=\"va bf\" id=[incr i]>
<a class=bf file=\"$file\" type=$type href=#>
"
if {[$ts get definition] eq "HD"} {
puts "<img class=va src=/images/172_1_00_HD.png height=21>"
set new 0
if {$type eq "ts"} {
if {[$ts flag "New"] > 0} { set new 1 }
} else {
puts "<img class=va src=/images/172_1_26_SD.png height=21>"
if {![file exists "[file rootname $file].hmi"]} { set new 1 }
}
puts "</td>
</tr><tr>
<th>Channel</th>
<td>[epg channelicon [$ts get channel_name] 50 "vertical-align: middle"]
[$ts get channel_num] - [$ts get channel_name]</td>
</tr><tr>
<th>Start Time</th>
<td>"
puts [clock format [$ts get start] -format "%c %Z"]
puts "</td>
</tr><tr>
<th>End Time</th>
<td>"
puts [clock format [$ts get end] -format "%c %Z"]
puts "</td>
</tr><tr>
<th>Duration</th>
<td>[$ts duration] minute(s).</td>
</tr><tr>
<th>Size</th>
<td>[$ts size] MiB</td>
</tr><tr>
<th>Flags</th>
<td>[$ts get flags]</td>
</tr>
</table>
if {$new} { append img _New }
puts "<img class=va border=0 src=/img/$img.png>"
puts "
$bfile
</a>
"
exit
# Size
puts "<span class=filesize> ($sz) </span>"
# Icons
set locked 0
set encd 0
set def unknown
if {$type eq "ts"} {
# HD / SD
if {[$ts get definition] eq "HD"} {
set def HD
set img "172_1_00_HD"
} else {
set def SD
set img "172_1_26_SD"
}
puts "<img class=va src=/images/$img.png height=21>"
# Locked
if {[$ts flag "Locked"] > 0} {
set locked 1
puts "<img class=va src=/images/178_1_00_Icon_Lock.png
height=21>"
}
# Encrypted
if {[$ts flag "Encrypted"] > 0} {
set encd 1
puts "<img class=va
src=/images/749_1_26_Video_Encryption.png
height=21>"
}
# Guidance
if {[$ts flag "Guidance"] > 0} {
puts "<img class=va
src=/images/174_1_26_GuidancePolicy.png
height=21>"
}
}
# Opt+ button
puts "
<a href=#>
<img class=\"opt va\" border=0 width=45 type=$type did=$i
locked=$locked encd=$encd def=$def new=$new
src=/images/181_1_00_Help5_OPT_Plus.png>
</a>
<div class=\"results blood\" style=\"margin: 0 0 0 5em\"></div>
"
puts "</div>"
}
if {[dict exists $_cgi dir]} {
@@ -173,179 +135,102 @@ if {[dict exists $_cgi dir]} {
set dir "/media/My Video"
}
source /mod/var/mongoose/html/lib/header.jim
######################################################################
# Render web page
puts {
header
<link href=/css/jquery.contextMenu.css rel=stylesheet type=text/css />
<script type="text/javascript" src="/js/jquery.contextMenu.js"></script>
puts {
<link href=/css/jquery.contextMenu.css rel=stylesheet type=text/css />
<script type="text/javascript" src="/js/jquery.contextMenu.js"></script>
<ul id=optmenu class=contextMenu>
<li><a href=#delete>Delete</a></li>
<li><a href=#lock>Toggle Lock</a></li>
<li><a href=#rename>Rename</a></li>
<li><a href=#title>Change Title</a></li>
</ul>
<ul id=optmenu class=contextMenu>
<li><a href=#delete>Delete</a></li>
<li><a href=#lock>Toggle Lock</a></li>
<li><a href=#enc>Toggle Enc</a></li>
<li><a href=#new>Toggle New</a></li>
<li><a href=#rename>Rename</a></li>
<li><a href=#download>Download</a></li>
</ul>
<div id=dialogue></div>
<div id=confirm title="Confirmation Required"></div>
<div id=renameform title="Rename media file" style="display: none">
<form id=renameform_form>
<input type=hidden name="renameorig" id="renameorig" value="">
<input type=hidden name="titleorig" id="titleorig" value="">
<table border=0>
<tr>
<th>
<label for="rename">
<b>New Filename</b>
</label>
</th>
<td>
<input type=text name="rename" id="rename"
value="" size=70 maxlength=255
class="text ui-widget-content ui-corner-all">
</td>
</tr>
<tr style="display: none" class=tstype>
<th>
<label for="renametitle" style="padding-top: 0.5em">
<b>New EPG Title</b>
</label>
</th>
<td>
<input type=text name="renametitle" id="renametitle"
value="" size=70 maxlength=48
class="text ui-widget-content ui-corner-all">
</td>
</tr>
<tr style="display: none" class=tstype>
<td colspan=2 id=synopsis style="font-style: italic"></td>
</tr>
</table>
</form>
</div>
<script type=text/javascript>
function bindmenu(selector)
{
$(selector).contextMenu(
{
menu: 'optmenu',
leftButton: true,
beforeShow:
function(el, menu)
{
if (el.attr('locked') == 1)
{
$(menu).changeContextMenuItem('#lock', 'Unlock');
$('#optmenu').disableContextMenuItems('#delete');
}
else
{
$(menu).changeContextMenuItem('#lock', 'Lock');
$('#optmenu').enableContextMenuItems('#delete');
}
}
},
function (action, el, pos)
{
var ts = $(el).parent().prevAll('a.ts').last().attr('file');
var did = $(el).attr('did');
switch (action)
{
case 'delete':
confirm_action('delete', delete_callback, ts, did);
break;
<div id=dialogue></div>
<div id=confirm title="Confirmation Required"></div>
case 'lock':
confirm_action('change the lock on', lock_callback, ts, did);
break;
default:
alert('Unhandled action: ' + action);
break;
}
}
);
}
var $confirm = $('#confirm').dialog({
modal: true, autoOpen: false,
height: 160, width: 500,
show: 'fade', hide: 'fade',
draggable: false, resizable: false
});
var confirm_action = function(action, callback, ts, id) {
var bts = ts.replace(/.*\/|\.[^.]*$/g, '');
$confirm.dialog('option', 'buttons', {
'Yes': function() { $(this).dialog('close');
callback(ts, id); },
'No': function() {$(this).dialog('close');}
});
$('#confirm').empty().html(
'Are you sure you wish to ' + action + '<br>' +
'<i>' + bts + '</i> ?'
);
$confirm.dialog('open');
}
var delete_callback = function(ts, id) {
var el = 'div.tsfile#' + id;
var results = el + ' .results';
var url = window.location.pathname + '?tsfile=' +
encodeURIComponent(ts) + '&action=delete';
$(results).load(url, function() {
$(el).delay(3000).slideUp(300, function() {
$(el).remove();
});
});
}
var lock_callback = function(ts, id) {
var el = 'div.tsfile#' + id;
var results = el + ' .results';
var url = window.location.pathname + '?tsfile=' +
encodeURIComponent(ts) + '&action=';
$(results).load(url + 'lock', function() {
$(results).delay(3000).slideUp(150,
function() {
$(el).load(url + 'entry', function() {
bindmenu(el + ' img.opt');
});;
}
);
});
}
// Dialogue init
var $dialog = $('#dialogue').dialog({
title: "Recording Details",
modal: false, autoOpen: false,
height: 600, width: 700,
show: 'scale', hide: 'fade',
draggable: true, resizable: true,
buttons: { "Close":
function() {$(this).dialog('close');}},
close: function(e,u) { $('#dialogue').empty().html(
'<img src="/img/loading.gif" alt="loading">'); }
});
$(document).ready(function() {
$('#optmenu').disableContextMenuItems('#rename,#title');
bindmenu('img.opt');
$('a.ts').click(function(e) {
e.preventDefault();
var file = $(this).attr('file');
var url = window.location.pathname + '?tsfile=' +
encodeURIComponent(file);
$('#dialogue').load(url);
$dialog.dialog('open');
});
});
</script>
<script type=text/javascript src=/cgi-bin/browse/browse.js></script>
}
puts { <div style="border: 1px solid grey; padding: 1em"> }
puts "<span style=\"display:none\" id=dir>$dir</span>"
# Breadcrumb path
puts "<h1>"
puts "
<fieldset style=\"margin: 1em\">
<legend style=\"font-size: 1.5em; padding: 0 0.5em 0.5em 0.5em;\">
"
set stub ""
foreach part [split $dir /] {
if {$stub eq "/"} { set name $part } else { set name "/$part" }
append stub $name
puts "<a href=$env(REQUEST_URI)?dir=[cgi_quote_url $stub]>$name</a>
}
puts "</h1>"
puts "<span class=filesize id=dirsize></span>"
puts "</legend>"
# Parent directory
set parent [join [lrange [split $dir /] 0 end-1] /]
if {$parent ne ""} {
puts "
<div class=va>
<a href=$env(REQUEST_URI)?dir=[cgi_quote_url $parent]>
<img src=/images/711_3_09_Media_Folder_UP.png class=va>
<img border=0 src=/images/711_3_09_Media_Folder_UP.png class=va>
\[parent directory\]</a>
</div>
"
}
# Strip double slashes
regsub -all -- {\/+} "$dir/*" "/" dir
foreach file [lsort [glob -nocomplain "$dir"]] {
entry $file
}
puts "</div>"
puts "</fieldset>"
source /mod/var/mongoose/html/lib/footer.jim
footer

View File

@@ -0,0 +1,286 @@
function epginfo_callback(data, status, xhr)
{
var width = 85;
if (status != 'success')
return;
//console.log(status);
//console.dir(data);
$('#titleorig').val(data.title);
$('#renametitle').val(data.title);
if (data.synopsis.length > width)
data.synopsis = data.synopsis.substring(0, width) + '...';
$('#synopsis').html(data.synopsis);
$('tr.tstype').show('slow');
}
function insert_folder_size(folder, size)
{
folder = folder.replace(/ /g, '');
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
//console.log("Folder: (%s) = (%s)", folder, size);
if (folder == "")
$('#dirsize').text(' (' + size + 'iB)');
else
$('#' + folder).text(' (' + size + 'iB)');
}
function folder_size_callback(data, status, xhr)
{
//console.log("Status: %s", status);
//console.dir(data);
$.each(data, insert_folder_size);
}
function set_folder_new(folder, cnt)
{
folder = folder.replace(/ /g, '');
folder = folder.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
//console.log("Folder: (%s) = (%s)", folder, cnt);
$('#img' + folder).attr('src', '/img/Folder_New.png');
}
function new_folder_callback(data, status, xhr)
{
//console.log("Status: %s", status);
//console.dir(data);
$.each(data, set_folder_new);
}
function delete_callback(file, type, id)
{
var el = 'div.bf#' + id;
var results = el + ' .results';
var url = '/cgi-bin/browse/delete.jim?file=' +
encodeURIComponent(file) + '&type=' + type;
$(results).load(url, function() {
$(el).delay(3000).slideUp(300, function() {
$(el).remove();
});
});
}
function lock_callback(file, type, id)
{
var url = '/cgi-bin/browse/lock.jim?file=' + encodeURIComponent(file);
$.get(url, function() { window.location.reload(true); });
}
function enc_callback(file, type, id)
{
var url = '/cgi-bin/browse/enc.jim?file=' + encodeURIComponent(file);
$.get(url, function() { window.location.reload(true); });
}
function new_callback(file, type, id)
{
var url = '/cgi-bin/browse/new.jim?file=' + encodeURIComponent(file);
$.get(url, function() { window.location.reload(true); });
}
function rename_submit()
{
var s = $('#renameform_form').serialize();
$.get('/cgi-bin/browse/rename.jim?' + s,
function() { window.location.reload(true); });
}
var $confirm; // Populated after DOM is loaded.
function confirm_action(action, callback, file, type, id)
{
var bfile = file.replace(/.*\/|\.[^.]*$/g, '');
$confirm.dialog('option', 'buttons', {
'Yes': function() { $(this).dialog('close');
callback(file, type, id); },
'No': function() {$(this).dialog('close');}
});
$('#confirm').empty().html(
'Are you sure you wish to ' + action + '<br>' +
'<i>' + bfile + '</i> ?'
);
$confirm.dialog('open');
}
function preparemenu(el, menu)
{
if (el.attr('type') == 'ts')
{
if (el.attr('def') == 'HD')
{
$('#optmenu').enableContextMenuItems('#enc');
if (el.attr('encd') == 1)
$(menu).changeContextMenuItem('#enc',
'Remove ENC');
else
$(menu).changeContextMenuItem('#enc',
'Set ENC');
}
else
$('#optmenu').disableContextMenuItems('#enc');
$('#optmenu').enableContextMenuItems('#new');
if (el.attr('new') == 1)
$(menu).changeContextMenuItem('#new', 'Mark watched');
else
$(menu).changeContextMenuItem('#new', 'Mark new');
$('#optmenu').enableContextMenuItems('#lock');
if (el.attr('locked') == 1)
{
$(menu).changeContextMenuItem('#lock', 'Unlock');
$('#optmenu').disableContextMenuItems('#delete');
}
else
{
$(menu).changeContextMenuItem('#lock', 'Lock');
$('#optmenu').enableContextMenuItems('#delete');
}
}
else
{
$('#optmenu').enableContextMenuItems('#delete');
$('#optmenu').disableContextMenuItems('#lock');
$('#optmenu').disableContextMenuItems('#enc');
$('#optmenu').disableContextMenuItems('#new');
}
}
$(document).ready(function() {
var menuclick = function(action, el, pos)
{
var file = $(el).parent().prevAll('a.bf').last().attr('file');
var bfile = file.replace(/.*\/|\.[^.]*$/g, '');
bfile = bfile.replace(/[\x00-\x1f]+/g, '');
var type = $(el).attr('type');
var id = $(el).attr('did');
switch (action)
{
case 'delete':
confirm_action('delete', delete_callback, file,
type, id);
break;
case 'lock':
confirm_action('change the lock on', lock_callback,
file, type, id);
break;
case 'enc':
confirm_action('change the ENC flag on', enc_callback,
file, type, id);
break;
case 'new':
confirm_action('change the New flag on', new_callback,
file, type, id);
break;
case 'rename':
$('#rename').val(bfile);
$('#renameorig').val(file);
$('#titleorig').val('');
$('#renametitle').val('');
$('#synopsis').val('');
$('tr.tstype').css('display', 'none');
if (type == 'ts')
{
$.getJSON('/cgi-bin/browse/epgtitle.jim?file=' +
encodeURIComponent(file), epginfo_callback);
}
$('#renameform').dialog('open');
break;
case 'download':
window.location.href = file;
break;
default:
alert('Unhandled action: ' + action);
break;
}
};
// Bind context menu to opt+ image
$('img.opt').contextMenu(
{
menu: 'optmenu',
leftButton: true,
beforeShow: preparemenu
},
menuclick
);
// Disable items which are not yet implemented.
$('#optmenu').disableContextMenuItems('#title');
// Create reusable dialogue.
var $dialog = $('#dialogue').dialog({
title: "Media Details",
modal: false, autoOpen: false,
height: 600, width: 700,
show: 'scale', hide: 'fade',
draggable: true, resizable: true,
buttons: {
"Close": function() {
$(this).dialog('close');
}
},
close: function(e,u) { $('#dialogue').empty().html(
'<img src="/img/loading.gif" alt="loading">'); }
});
// Bind dialogue open to filenames.
$('a.bf').click(function(e) {
e.preventDefault();
var file = $(this).attr('file');
var type = $(this).attr('type');
var url = '/cgi-bin/browse/file.jim?file=' +
encodeURIComponent(file) + '&type=' + type;
$('#dialogue').load(url);
$dialog.dialog('open');
});
$('#renameform').dialog({
autoOpen: false,
height: 'auto', width: 'auto',
modal: true,
buttons: {
"Update": rename_submit,
"Close": function() {
$(this).dialog('close');
}
},
close: function() { $('#rename').val(''); }
});
// Create re-usable confirmation dialogue.
$confirm = $('#confirm').dialog({
modal: true, autoOpen: false,
height: 160, width: 500,
show: 'fade', hide: 'fade',
draggable: false, resizable: false
});
var dir = $('#dir').text();
// Load folder sizes
$.getJSON('/cgi-bin/browse/sizes.jim?dir=' + encodeURIComponent(dir),
folder_size_callback);
// Flag folders with unwatched items
$.getJSON('/cgi-bin/browse/newdir.jim?dir=' + encodeURIComponent(dir),
new_folder_callback);
});

View File

@@ -0,0 +1,27 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/ts.class
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
set file [dict get $_cgi file]
set type [dict get $_cgi type]
if {$type eq "ts"} {
set ts [ts fetch $file]
if {[$ts delete]} {
puts "Successfully deleted $file."
} else {
puts "Problem deleting $file, [$ts get error]"
}
exit
}
file delete $file
puts "Successfully deleted $file."

View File

@@ -0,0 +1,27 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/ts.class
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
#set _cgi(file) "/media/My Video/The Walking Dead/The Walking Dead S01E06.ts"
set file [dict get $_cgi file]
set ts [ts fetch $file]
if {[set ts [ts fetch $file]] != 0} {
set action enc
if {[$ts flag "Encrypted"]} { set action unenc }
if {[$ts $action]} {
puts "Successfully [set action]ed $file."
} else {
puts "Problem [set action]ing $file,
[$ts get error]"
}
}

View File

@@ -0,0 +1,22 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/ts.class
puts "Content-Type: application/json"
puts ""
cgi_input
#cgi_dump
#set _cgi(file) "/media/My Video/Doctor Who/6.13._The_Almost_People.ts"
if {![dict exists $_cgi file]} { exit }
set file [dict get $_cgi file]
set ts [ts fetch $file]
puts "{"
puts "\"title\" : \"[$ts get title]\","
puts "\"synopsis\" : \"[$ts get synopsis]\""
puts "}"

View File

@@ -0,0 +1,17 @@
#!/mod/bin/jimsh
package require cgi
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
if [file exists /mod/bin/ffmpeg] {
set file [dict get $_cgi file]
puts [exec /mod/var/mongoose/lib/ffmpeg -i $file]
} else {
puts "Install ffmpeg package for more information..."
}

View File

@@ -0,0 +1,115 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/pretty_size
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
#set _cgi(file) "/media/My Video/Dangermouse/Series 1/01_rogue_robots.avi"
if {![dict exists $_cgi file]} { exit }
set file [dict get $_cgi file]
set type [dict get $_cgi type]
file stat $file st
set sz [pretty_size $st(size)]
if {$type eq "ts"} {
source /mod/var/mongoose/lib/epg.class
source /mod/var/mongoose/lib/ts.class
set ts [ts fetch $file]
puts "
<table class=keyval>
<tr>
<th>Title</th>
<td>[$ts get title]</td>
</tr><tr>
<th>Synopsis</th>
<td>[$ts get synopsis]</td>
</tr><tr>
"
if {[$ts flag "Guidance"] > 0} {
puts "
<th>Guidance</th>
<td><img class=va
src=/images/174_1_26_GuidancePolicy.png height=21>
[$ts get guidance]
</td>
</tr><tr>
"
}
puts "
<th>Definition</th>
<td>
"
if {[$ts get definition] eq "HD"} {
puts "<img class=va src=/images/172_1_00_HD.png height=21>"
} else {
puts "<img class=va src=/images/172_1_26_SD.png height=21>"
}
puts "</td>
</tr><tr>
<th>Channel</th>
<td>[epg channelicon [$ts get channel_name] 50 "vertical-align: middle"]
[$ts get channel_num] - [$ts get channel_name]</td>
</tr><tr>
<th>Start Time</th>
<td>"
puts [clock format [$ts get start] -format "%c %Z"]
puts "</td>
</tr><tr>
<th>End Time</th>
<td>"
puts [clock format [$ts get end] -format "%c %Z"]
puts "</td>
</tr><tr>
<th>Duration</th>
<td>[$ts duration] minute(s).</td>
</tr><tr>
<th>Size</th>
<td>$sz</td>
</tr><tr>
<th>Flags</th>
<td>[$ts get flags]</td>
</tr>
</table>
"
exit
}
# Otherwise, for a general file.
puts "
<table class=keyval>
<tr>
<th>File</th>
<td>$file</td>
</tr><tr>
<th>Size</th>
<td>$sz</td>
</tr><tr>
<th>Info</th>
<td class=pre id=ffmpeg>
<img src=/img/loading.gif><i>Loading...</i>
</td>
</tr>
</table>
"
set url "/cgi-bin/browse/ffmpeg.jim?file=[cgi_quote_url $file]"
puts { <script type="text/javascript"> }
puts "var url = \"$url\";"
puts {
$('#ffmpeg').load(url);
</script>
}

View File

@@ -0,0 +1,27 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/ts.class
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
#set _cgi(file) "/media/My Video/The Walking Dead/The Walking Dead S01E06.ts"
set file [dict get $_cgi file]
set ts [ts fetch $file]
if {[set ts [ts fetch $file]] != 0} {
set action lock
if {[$ts flag "Locked"]} { set action unlock }
if {[$ts $action]} {
puts "Successfully [set action]ed $file."
} else {
puts "Problem [set action]ing $file,
[$ts get error]"
}
}

View File

@@ -0,0 +1,27 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/ts.class
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
#set _cgi(file) "/media/My Video/The Walking Dead/The Walking Dead S01E06.ts"
set file [dict get $_cgi file]
set ts [ts fetch $file]
if {[set ts [ts fetch $file]] != 0} {
set action new
if {[$ts flag "New"]} { set action watched }
if {[$ts set_$action]} {
puts "Successfully marked $file as $action."
} else {
puts "Problem marking $file as $action,
[$ts get error]"
}
}

View File

@@ -0,0 +1,34 @@
#!/mod/bin/jimsh
package require cgi
package require pack
puts "Content-Type: application/json"
puts ""
cgi_input
#cgi_dump
#set _cgi(dir) "/media/My Video"
set root [dict get $_cgi dir]
# Strip double slashes
regsub -all -- {\/+} "$root/*" "/" root
puts "{"
foreach dir [glob -nocomplain "$root"] {
if {[file exists "$dir/.series"]} {
set fd [open "$dir/.series"]
set bytes [read $fd 8]
set recs [unpack $bytes -uintle 0 32]
set plays [unpack $bytes -uintle 32 32]
set diff $($recs - $plays)
if {$diff != 0} {
set node [lindex [split $dir /] end]
puts "\"$node\": $diff,"
}
}
}
puts "\"dummy\" : 0"
puts "}"

View File

@@ -0,0 +1,53 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/ts.class
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
#renameorig
#titleorig
#rename
#renametitle
#set _cgi(renameorig) "/media/My Video/The Walking Dead/The Walking Dead_20110521_2201.ts"
#set _cgi(rename) "Last Episode"
if {![dict exists $_cgi renameorig]} { exit }
set file [dict get $_cgi renameorig]
set newfile [dict get $_cgi rename]
if {[string length [string trim $newfile]] == 0 || $file eq $newfile} {
set newfile ""
}
if {[file isdirectory $file]} {
#puts "Directory."
if {$newfile ne ""} {
set dir [file dirname $file]
set newfile "${dir}/${newfile}"
file rename $file $newfile
}
} elseif {[set ts [ts fetch $file]] != 0} {
#puts "TS file."
catch {
set title [dict get $_cgi renametitle]
set titleorig [dict get $_cgi titleorig]
if {[string length [string trim $title]] > 0 &&
$title ne $titleorig} {
$ts settitle $title
}
}
if {$newfile ne ""} { ts renamegroup $file $newfile }
} else {
#puts "Normal file."
if {$newfile ne ""} { ts renamegroup $file $newfile }
}

View File

@@ -0,0 +1,26 @@
#!/mod/bin/jimsh
package require cgi
puts "Content-Type: application/json"
puts ""
cgi_input
#cgi_dump
#set _cgi(dir) "/media/My Video"
set dir [dict get $_cgi dir]
#9.4G /media/My Video/Archive
#1.4G /media/My Video/CSI_ Crime Scene Investigation
puts "{"
foreach line [split [exec /mod/bin/busybox/du -h "$dir/"] "\n"] {
set fields [split $line "\t"]
set size [lindex $fields 0]
set node [lindex [split [lindex $fields 1] /] end]
puts "\"$node\" : \"$size\","
}
puts "\"dummy\" : \"\""
puts "}"

View File

@@ -1,12 +1,13 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/epg.class
source /mod/var/mongoose/lib/setup
require epg.class
puts "Content-Type: text/html"
puts ""
source /mod/var/mongoose/html/lib/header.jim
header
cgi_input
#cgi_dump
@@ -31,5 +32,6 @@ if { $raw == 0 } {
puts "</pre>"
epg cleanup
source /mod/var/mongoose/html/lib/footer.jim
footer

View File

@@ -1,7 +1,8 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/epg.class
source /mod/var/mongoose/lib/setup
require epg.class
puts "Content-Type: text/html"
puts ""
@@ -13,9 +14,7 @@ set service 0
catch { set service [dict get $_cgi service] }
set event 0
catch { set event [dict get $_cgi event] }
if {! [dict exists $_cgi bare]} {
source /mod/var/mongoose/html/lib/header.jim
}
if {! [dict exists $_cgi bare]} { header }
#set service 8384
#set event 25293
@@ -105,7 +104,5 @@ puts "
"
epg cleanup
if {! [dict exists $_cgi bare]} {
source /mod/var/mongoose/html/lib/footer.jim
}
if {! [dict exists $_cgi bare]} { footer }

View File

@@ -1,28 +1,19 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/epg.class
source /mod/var/mongoose/lib/altrow
source /mod/var/mongoose/lib/cat
source /mod/var/mongoose/lib/setup
require epg.class spinner.class altrow
puts "Content-Type: text/html"
puts ""
source /mod/var/mongoose/html/lib/header.jim
header
puts "<script type=text/javascript src=/js/highlight.js></script>"
source /mod/var/mongoose/lib/epg_popup
puts "<script type=text/javascript src=/js/jquery.highlight.js></script>"
cgi_input
#cgi_dump
#set _cgi [dict create term "doctor who"]
#set env(REQUEST_URI) "test"
set term ""
catch { set term [dict get $_cgi term] }
set cmd "search"
if {[dict exists $_cgi full]} { set cmd "searchall" }
set ct 0
catch { set ct [dict get $_cgi ct] }
set crid ""
@@ -30,72 +21,35 @@ catch { set crid [dict get $_cgi crid] }
set scrid ""
catch { set scrid [dict get $_cgi scrid] }
puts "
<form method=get action=/cgi-bin/epg_search.jim>
Search EPG: <input name=term size=20 maxlength=255 value=\"$term\">
<input type=checkbox name=full"
if {[dict exists $_cgi full]} { puts " checked" }
puts ">Search descriptions as well as titles.
<input type=submit value=Search>
"
if {[dict exists $_cgi term]} {
set lterm [dict get $_cgi term]
set db [sqlite3.open /var/lib/humaxtv/setup.db]
set res [$db query {
select itemBlob from TBL_USERCONFIG
where itemName like 'EPG\_KEYWORD\_%%' ESCAPE '\'
}]
proc cts {type img text} {
puts "<a href=$::env(REQUEST_URI)?ct=$type>
<img height=18 border=0 src=/images/173_3_00_G3_$img.png>&nbsp;$text</a>";
}
puts {
<br>
<table>
<tr><td rowspan=2>Content Type Searches</td>
<td>
}
cts 1 "Movie" "Film/Drama"
puts "</td><td>"
cts 2 "News" "News/Current affairs"
puts "</td><td>"
cts 4 "Sports" "Sport"
puts "</td><td>"
cts 9 "Education" "Education/Science/Factual"
puts "</td><td>"
cts 10 "Leisure" "Leisure"
puts "</td></tr><tr><td>"
cts 7 "Art" "Arts/Culture"
puts "</td><td>"
cts 3 "Show" "Show/Game show"
puts "</td><td>"
cts 5 "Children" "Children"
puts "</td><td>"
cts 8 "Society" "Social/Political/Economic"
puts "</td><td>"
cts 6 "Music" "Music/Ballet/Dance"
puts "</tr></table>"
puts "<table cellpadding=5>"
if {[llength $res] > 0} {
puts "<tr><td>Keyword Searches</td>"
foreach keyword $res {
set kw [string range [lindex $keyword 1] 1 end]
puts "<td><a href=$env(REQUEST_URI)?term=[cgi_quote_url $kw]>$kw
</a></td>"
if {[string match {CRID:*} $lterm]} {
set crid [string range $lterm 5 end]
} elseif {[string match {SCRID:*} $lterm]} {
set scrid [string range $lterm 6 end]
}
puts "</tr>"
} elseif {$crid ne ""} {
set _cgi(term) "CRID:$crid"
} elseif {$scrid ne ""} {
set _cgi(term) "SCRID:$scrid"
}
puts "</table>"
$db close
require epg_search
puts "</form>"
[spinner new {
text "Searching EPG..."
size "1.2em"
style "margin: 1em;"
}] start
require epg_popup
#set _cgi [dict create term "doctor who"]
#set env(REQUEST_URI) "test"
set cmd "search"
if {$searchfull} { set cmd "searchall" }
if {$ct > 0 } {
set records [epg fetch dump -type $ct]
@@ -103,13 +57,16 @@ if {$ct > 0 } {
set records [epg fetch dump -crid $crid]
} elseif {$scrid ne ""} {
set records [epg fetch dump -scrid $scrid]
} elseif {$term ne ""} {
set records [epg fetch $cmd -extra $term]
} elseif {$searchterm ne ""} {
set records [epg fetch $cmd -extra $searchterm]
} else {
set records {}
}
set favlist [epg favlist]
puts {
if {[llength $records] > 0} {
puts {
<table class=borders id=results style="clear: both;margin: 0.5em 0 0 0">
<tr>
<th>Date</th>
@@ -117,6 +74,9 @@ puts {
<th>Programme</th>
<th>Synopsis</th>
</tr>
}
} else {
puts "No results found."
}
proc rsort {v1 v2} {
@@ -147,18 +107,17 @@ foreach record [lsort -command rsort $records] {
puts [$record cell]
puts "<td>[$record get text]</td><td>[$record get warning]</td>"
puts "</tr>"
flush stdout
}
puts "</table>"
if {$term != ""} {
if {$searchterm != ""} {
puts "
<script type=text/javascript>
highlight(document.getElementById(\"results\"), \"$term\");
\$('#results').highlight('$searchterm');
</script>
"
}
epg cleanup
source /mod/var/mongoose/html/lib/footer.jim
footer

View File

@@ -1,15 +1,13 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/epg.class
source /mod/var/mongoose/lib/spinner.class
source /mod/var/mongoose/lib/altrow
source /mod/var/mongoose/lib/cat
source /mod/var/mongoose/lib/setup
require epg.class spinner.class altrow
puts "Content-Type: text/html"
puts ""
source /mod/var/mongoose/html/lib/header.jim
header
[spinner new {
text "Loading EPG Data..."
@@ -20,7 +18,7 @@ source /mod/var/mongoose/html/lib/header.jim
cgi_input
#cgi_dump
source /mod/var/mongoose/lib/epg_popup
require epg_popup
set service 0
set service 4351
@@ -67,10 +65,9 @@ foreach record $records {
puts "<td>[$record get text]</td>"
puts "<td>[$record get warning]</td>"
puts "</tr>"
flush stdout
}
puts "</table>"
epg cleanup
source /mod/var/mongoose/html/lib/footer.jim
footer

18
var/mongoose/cgi-bin/opkg.jim Executable file
View File

@@ -0,0 +1,18 @@
#!/mod/bin/jimsh
package require cgi
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
#set _cgi(cmd) {remove binutils}
if {![dict exists $_cgi cmd]} { set _cgi(cmd) status }
set cmd [dict get $_cgi cmd]
puts [exec /mod/var/mongoose/lib/opkg {*}$cmd]

View File

@@ -0,0 +1,8 @@
#!/mod/bin/jimsh
puts "Content-Type: text/html"
puts ""
puts [exec /etc/init.d/S90settop restart]
file delete /tmp/.restartpending

View File

@@ -0,0 +1,7 @@
#!/mod/bin/jimsh
puts "Content-Type: text/html"
puts ""
source /mod/var/mongoose/include/restart.jim

View File

@@ -1,7 +1,9 @@
#!/mod/bin/jimsh
source /mod/var/mongoose/lib/settings.class
package require cgi
source /mod/var/mongoose/lib/setup
require settings.class
require plugin
puts "Content-Type: text/html"
puts ""
@@ -17,8 +19,7 @@ set channel_group [$settings channel_group]
# Handle updates
#set _cgi(smtp_server) "fred.bob"
#set env(REQUEST_URI) ''
if {![dict exists $env REQUEST_URI]} { set env(REQUEST_URI) "" }
proc _handle_update {class var old text} {
global _cgi
@@ -50,15 +51,15 @@ handle_str_update hostname $hostname Hostname
_handle_update ascii smtp_server $smtp_server "SMTP Server"
handle_int_update channel_group $channel_group "Channel Group"
source /mod/var/mongoose/html/lib/header.jim
header
puts {<script type="text/javascript" src="/js/jquery.form.js"></script>}
puts {
<script type=text/javascript>
$(document).ready(function () {
//$(":submit").button();
//$(":submit").height(20);
$('form').each(function(i, el) {
$(":submit").button();
$('form.auto').each(function(i, el) {
var id = $(this).attr('id');
var output = '#' + id + '_output'
$(this).ajaxForm({
@@ -75,14 +76,23 @@ puts {
}
puts "
<h1>Settings</h1>
<table class=keyval>
<fieldset style=\"display: inline\">
<legend>
General Settings
</legend>
<table>
"
puts "
<tr>
<form id=hostname method=get action=$env(REQUEST_URI)>
<th>Hostname</th>
<form class=auto id=hostname method=get action=$env(REQUEST_URI)>
<th class=key>Hostname</th>
<td><input name=hostname value=\"$hostname\"
class=\"text ui-widget-content ui-corner-all\"
length=20 maxlength=50>
<small>
<input id=hostname_submit value=\"change\" type=submit>
</small>
<div id=hostname_output></div>
</td>
</form>
@@ -91,22 +101,10 @@ puts "
puts "
<tr>
<form id=smtp_server method=get action=$env(REQUEST_URI)>
<th>SMTP Server for outbound email</th>
<td><input name=smtp_server value=\"$smtp_server\"
length=20 maxlength=50>
<input id=smtp_server_submit value=\"change\" type=submit>
<div id=smtp_server_output></div>
</td>
</form>
</tr>
"
puts "
<tr>
<form id=channel_group method=get action=$env(REQUEST_URI)>
<th>Channel Group for EPG</th>
<form class=auto id=channel_group method=get action=$env(REQUEST_URI)>
<th class=key>Channel Group for EPG</th>
<td><select id=channel_group name=channel_group
class=\"text ui-widget-content ui-corner-all\"
value=[$settings channel_group]>
"
@@ -123,7 +121,9 @@ foreach grp [$settings channel_groups] {
puts "
</select>
<input name=channel_group value=\"change\" type=submit>
<small>
<input name=channel_group value=\"set\" type=submit>
</small>
<div id=channel_group_output></div>
</td>
</form>
@@ -132,11 +132,35 @@ puts "
puts "
</table>
</form>
<br>
More coming soon...
<br>
<br>
</fieldset>
<br><br>
<fieldset style=\"display: inline\">
<legend> Email Settings </legend>
<table>
"
source /mod/var/mongoose/html/lib/footer.jim
puts "
<tr>
<form class=auto id=smtp_server method=get action=$env(REQUEST_URI)>
<th class=key>SMTP Server for outbound email</th>
<td><input name=smtp_server value=\"$smtp_server\"
class=\"text ui-widget-content ui-corner-all\"
length=20 maxlength=50>
<small>
<input id=smtp_server_submit value=\"change\" type=submit>
</small>
<div id=smtp_server_output></div>
</td>
</form>
</tr>
"
puts "
</table>
</fieldset>
"
eval_plugins settings
footer

View File

@@ -3,10 +3,6 @@
puts "Content-Type: text/html"
puts ""
#puts "<img style=\"vertical-align: middle\" src=/images/745_1_11_Video_1REC.png><span style=\"vertical-align: middle\">Recording one thing</span>"
#puts "<img style=\"vertical-align: middle\" src=/images/745_1_11_Video_1REC.png><span style=\"vertical-align: middle\">Recording another thing</span>"
#puts "<img style=\"vertical-align: middle\" src=/images/745_1_10_Video_2Live.png><span style=\"vertical-align: middle\">Watching something else</span>"
if {[catch {set pid [exec pgrep humaxtv]}]} { exit }
if {[catch {set data [exec lsof -p $pid | grep Video | fgrep .ts]} ]} {
@@ -43,9 +39,8 @@ foreach line $lines {
incr seen($name)
lappend output "<img style=\"vertical-align: middle\"
src=/images/$icon><span
style=\"vertical-align: middle\">$mode&nbsp;$name</span>"
lappend output "<img class=va src=/images/$icon><span class=va>
$mode&nbsp;$name</span><br>"
}
if {[llength $output]} {

View File

@@ -0,0 +1,4 @@
<!--#include virtual="/lib/header.shtml" -->
<!--#exec cmd="/mod/var/mongoose/include/backup.jim" -->
<!--#include virtual="/lib/footer.shtml" -->

View File

@@ -0,0 +1,75 @@
.iPhoneCheckContainer {
position: relative;
height: 27px;
cursor: pointer;
overflow: hidden; }
.iPhoneCheckContainer input {
position: absolute;
top: 5px;
left: 30px;
opacity: 0;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
filter: progid:DXImageTransform.Microsoft.Alpha(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;
position: absolute;
width: auto;
top: 0;
padding-top: 5px;
overflow: hidden; }
.iPhoneCheckContainer, .iPhoneCheckContainer label {
user-select: none;
-moz-user-select: none;
-khtml-user-select: none; }
.iPhoneCheckDisabled {
opacity: 0.5;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50); }
label.iPhoneCheckLabelOn {
color: white;
background: url('/img/iphone-style-checkboxes/on.png?1282083753') no-repeat;
text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.6);
left: 0;
padding-top: 5px; }
label.iPhoneCheckLabelOn span {
padding-left: 8px; }
label.iPhoneCheckLabelOff {
color: #8b8b8b;
background: url('/img/iphone-style-checkboxes/off.png?1282083753') no-repeat right 0;
text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.6);
text-align: right;
right: 0; }
label.iPhoneCheckLabelOff span {
padding-right: 8px; }
.iPhoneCheckHandle {
display: block;
height: 27px;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
width: 0;
background: url('/img/iphone-style-checkboxes/slider_left.png?1282083753') 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; }
.iPhoneCheckHandleCenter {
height: 100%;
width: 100%;
background: url('/img/iphone-style-checkboxes/slider_center.png?1282083753'); }

View File

@@ -1,62 +1,62 @@
/* Generic context menu styles */
.contextMenu {
position: absolute;
width: 120px;
z-index: 99999;
border: solid 1px #CCC;
background: #EEE;
padding: 0px;
margin: 0px;
display: none;
}
.contextMenu LI {
list-style: none;
padding: 0px;
margin: 0px;
}
.contextMenu A {
color: #333;
text-decoration: none;
display: block;
line-height: 20px;
height: 20px;
background-position: 6px center;
background-repeat: no-repeat;
outline: none;
padding: 1px 5px;
padding-left: 28px;
}
.contextMenu LI.hover A {
color: #FFF;
background-color: #3399FF;
}
.contextMenu LI.disabled A {
color: #AAA;
cursor: default;
}
.contextMenu LI.hover.disabled A {
background-color: transparent;
}
.contextMenu LI.separator {
border-top: solid 1px #CCC;
}
/*
Adding Icons
You can add icons to the context menu by adding
classes to the respective LI element(s)
*/
.contextMenu LI.edit A { background-image: url(images/page_white_edit.png); }
.contextMenu LI.cut A { background-image: url(images/cut.png); }
.contextMenu LI.copy A { background-image: url(images/page_white_copy.png); }
.contextMenu LI.paste A { background-image: url(images/page_white_paste.png); }
.contextMenu LI.delete A { background-image: url(images/page_white_delete.png); }
.contextMenu LI.quit A { background-image: url(images/door.png); }
/* Generic context menu styles */
.contextMenu {
position: absolute;
width: 140px;
z-index: 99999;
border: solid 1px #CCC;
background: #EEE;
padding: 0px;
margin: 0px;
display: none;
}
.contextMenu LI {
list-style: none;
padding: 0px;
margin: 0px;
}
.contextMenu A {
color: #333;
text-decoration: none;
display: block;
line-height: 20px;
height: 20px;
background-position: 6px center;
background-repeat: no-repeat;
outline: none;
padding: 1px 5px;
padding-left: 28px;
}
.contextMenu LI.hover A {
color: #FFF;
background-color: #3399FF;
}
.contextMenu LI.disabled A {
color: #AAA;
cursor: default;
}
.contextMenu LI.hover.disabled A {
background-color: transparent;
}
.contextMenu LI.separator {
border-top: solid 1px #CCC;
}
/*
Adding Icons
You can add icons to the context menu by adding
classes to the respective LI element(s)
*/
.contextMenu LI.edit A { background-image: url(images/page_white_edit.png); }
.contextMenu LI.cut A { background-image: url(images/cut.png); }
.contextMenu LI.copy A { background-image: url(images/page_white_copy.png); }
.contextMenu LI.paste A { background-image: url(images/page_white_paste.png); }
.contextMenu LI.delete A { background-image: url(images/page_white_delete.png); }
.contextMenu LI.quit A { background-image: url(images/door.png); }

View File

@@ -52,6 +52,13 @@ div.footer
padding-top: 2em;
}
div.warningbox
{
background: url('/img/redshade.png') repeat-x;
padding: 0.5em;
margin: 1em;
}
table
{
empty-cells: show;
@@ -63,13 +70,13 @@ table.borders, table.borders td, table.borders th
empty-cells: show;
}
table tr.odd
table tr.odd, table td.odd, table th.odd
{
background: #ccff99;
color: black;
}
table tr.even
table tr.even, table td.even, table th.even
{
background: #ffffcc;
color: black;
@@ -86,7 +93,7 @@ table th
text-align: left;
}
table.keyval th
table.keyval th, th.key
{
background: #ccff99;
font-weight: bold;
@@ -101,7 +108,7 @@ table.keyval td
color: black;
}
pre
pre, .pre
{
font-family: Consolas, 'Courier New', Courier, monospace;
color: black;
@@ -174,6 +181,12 @@ pre
background: transparent;
}
.filesize
{
color: #6a6aff;
background: transparent;
}
.footnote
{
color: #ff4000;
@@ -225,3 +238,23 @@ img.progress
vertical-align: middle;
}
.block
{
display: block;
}
.hidden
{
display: none;
}
input.text
{
padding: .4em;
}
.highlight
{
background-color: yellow;
}

View File

@@ -1,9 +1,4 @@
<!--#include virtual="/lib/header.shtml" -->
<form method=get action=/cgi-bin/epg_search.jim>
Search EPG: <input name=term size=20 maxlength=255>
<input type=checkbox name=full>Search descriptions as well as titles.
<input type=submit value=Search>
</form>
<!--#exec cmd="/mod/var/mongoose/include/epg.jim" -->
<!--#include virtual="/lib/footer.shtml" -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -1 +0,0 @@
ADULT PARTY.png -

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 B

View File

@@ -19,6 +19,8 @@ $(document).ready(function() {
});
</script>
<div style="clear: both">
<div style="float: left">
<center>
<a href=/cgi-bin/browse.jim>
@@ -56,8 +58,11 @@ $(document).ready(function() {
<br>
</center>
</div>
</div>
<div style="float: left; clear: left">
<div style="clear: both">
<div style="float: left">
<center>
<a href=/services.shtml>
<img src=/img/spanner.jpg border=0 width=217 height=228>
@@ -97,12 +102,14 @@ $(document).ready(function() {
</center>
</div>
</div>
<div style="clear: both">
<!--#exec cmd="/mod/var/mongoose/include/mediatomb.jim" -->
</div>
<div class=footer>
<ul>
<li>
<!--#exec cmd="/mod/var/mongoose/include/mediatomb.jim" -->
MediaTomb Web Interface</a>
</li><li>
<a href=/db.shtml target=_blank>SQLite3 Database Dump</a>
</li><li>
<a href=/jim/ref.html target=_blank>Jim Reference Manual</a> |

View File

@@ -0,0 +1,229 @@
/*!
// iPhone-style Checkboxes jQuery plugin
// Copyright Thomas Reynolds, licensed GPL & MIT
*/
;(function($, iphoneStyle) {
// Constructor
$[iphoneStyle] = function(elem, options) {
this.$elem = $(elem);
// Import options into instance variables
var obj = this;
$.each(options, function(key, value) {
obj[key] = value;
});
// Initialize the control
this.wrapCheckboxWithDivs();
this.attachEvents();
this.disableTextSelection();
if (this.resizeHandle) { this.optionallyResize('handle'); }
if (this.resizeContainer) { this.optionallyResize('container'); }
this.initialPosition();
};
$.extend($[iphoneStyle].prototype, {
// Wrap the existing input[type=checkbox] with divs for styling and grab DOM references to the created nodes
wrapCheckboxWithDivs: function() {
this.$elem.wrap('<div class="' + this.containerClass + '" />');
this.container = this.$elem.parent();
this.offLabel = $('<label class="'+ this.labelOffClass +'">' +
'<span>'+ this.uncheckedLabel +'</span>' +
'</label>').appendTo(this.container);
this.offSpan = this.offLabel.children('span');
this.onLabel = $('<label class="'+ this.labelOnClass +'">' +
'<span>'+ this.checkedLabel +'</span>' +
'</label>').appendTo(this.container);
this.onSpan = this.onLabel.children('span');
this.handle = $('<div class="' + this.handleClass + '">' +
'<div class="' + this.handleRightClass + '">' +
'<div class="' + this.handleCenterClass + '" />' +
'</div>' +
'</div>').appendTo(this.container);
},
// Disable IE text selection, other browsers are handled in CSS
disableTextSelection: function() {
if (!$.browser.msie) { return; }
// Elements containing text should be unselectable
$.each([this.handle, this.offLabel, this.onLabel, this.container], function() {
$(this).attr("unselectable", "on");
});
},
// Automatically resize the handle or container
optionallyResize: function(mode) {
var onLabelWidth = this.onLabel.width(),
offLabelWidth = this.offLabel.width();
if (mode == 'container') {
var newWidth = (onLabelWidth > offLabelWidth) ? onLabelWidth : offLabelWidth;
newWidth += this.handle.width() + 15;
} else {
var newWidth = (onLabelWidth < offLabelWidth) ? onLabelWidth : offLabelWidth;
}
this[mode].css({ width: newWidth });
},
attachEvents: function() {
var obj = this;
// A mousedown anywhere in the control will start tracking for dragging
this.container
.bind('mousedown touchstart', function(event) {
event.preventDefault();
if (obj.$elem.is(':disabled')) { return; }
var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
$[iphoneStyle].currentlyClicking = obj.handle;
$[iphoneStyle].dragStartPosition = x;
$[iphoneStyle].handleLeftOffset = parseInt(obj.handle.css('left'), 10) || 0;
$[iphoneStyle].dragStartedOn = obj.$elem;
})
// Utilize event bubbling to handle drag on any element beneath the container
.bind('iPhoneDrag', function(event, x) {
event.preventDefault();
if (obj.$elem.is(':disabled')) { return; }
if (obj.$elem != $[iphoneStyle].dragStartedOn) { return; }
var p = (x + $[iphoneStyle].handleLeftOffset - $[iphoneStyle].dragStartPosition) / obj.rightSide;
if (p < 0) { p = 0; }
if (p > 1) { p = 1; }
obj.handle.css({ left: p * obj.rightSide });
obj.onLabel.css({ width: p * obj.rightSide + 4 });
obj.offSpan.css({ marginRight: -p * obj.rightSide });
obj.onSpan.css({ marginLeft: -(1 - p) * obj.rightSide });
})
// Utilize event bubbling to handle drag end on any element beneath the container
.bind('iPhoneDragEnd', function(event, x) {
if (obj.$elem.is(':disabled')) { return; }
var checked;
if ($[iphoneStyle].dragging) {
var p = (x - $[iphoneStyle].dragStartPosition) / obj.rightSide;
checked = (p < 0) ? Math.abs(p) < 0.5 : p >= 0.5;
} else {
checked = !obj.$elem.attr('checked');
}
obj.$elem.attr('checked', checked);
$[iphoneStyle].currentlyClicking = null;
$[iphoneStyle].dragging = null;
obj.$elem.change();
});
// Animate when we get a change event
this.$elem.change(function() {
if (obj.$elem.is(':disabled')) {
obj.container.addClass(obj.disabledClass);
return false;
} else {
obj.container.removeClass(obj.disabledClass);
}
var new_left = obj.$elem.attr('checked') ? obj.rightSide : 0;
obj.handle.animate({ left: new_left }, obj.duration);
obj.onLabel.animate({ width: new_left + 4 }, obj.duration);
obj.offSpan.animate({ marginRight: -new_left }, obj.duration);
obj.onSpan.animate({ marginLeft: new_left - obj.rightSide }, obj.duration);
});
},
// Setup the control's inital position
initialPosition: function() {
this.offLabel.css({ width: this.container.width() - 5 });
var offset = ($.browser.msie && $.browser.version < 7) ? 3 : 6;
this.rightSide = this.container.width() - this.handle.width() - offset;
if (this.$elem.is(':checked')) {
this.handle.css({ left: this.rightSide });
this.onLabel.css({ width: this.rightSide + 4 });
this.offSpan.css({ marginRight: -this.rightSide });
} else {
this.onLabel.css({ width: 0 });
this.onSpan.css({ marginLeft: -this.rightSide });
}
if (this.$elem.is(':disabled')) {
this.container.addClass(this.disabledClass);
}
}
});
// jQuery-specific code
$.fn[iphoneStyle] = function(options) {
var checkboxes = this.filter(':checkbox');
// Fail early if we don't have any checkboxes passed in
if (!checkboxes.length) { return this; }
// Merge options passed in with global defaults
var opt = $.extend({}, $[iphoneStyle].defaults, options);
checkboxes.each(function() {
$(this).data(iphoneStyle, new $[iphoneStyle](this, opt));
});
if (!$[iphoneStyle].initComplete) {
// As the mouse moves on the page, animate if we are in a drag state
$(document)
.bind('mousemove touchmove', function(event) {
if (!$[iphoneStyle].currentlyClicking) { return; }
event.preventDefault();
var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
if (!$[iphoneStyle].dragging &&
(Math.abs($[iphoneStyle].dragStartPosition - x) > opt.dragThreshold)) {
$[iphoneStyle].dragging = true;
}
$(event.target).trigger('iPhoneDrag', [x]);
})
// When the mouse comes up, leave drag state
.bind('mouseup touchend', function(event) {
if (!$[iphoneStyle].currentlyClicking) { return; }
event.preventDefault();
var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
$($[iphoneStyle].currentlyClicking).trigger('iPhoneDragEnd', [x]);
});
$[iphoneStyle].initComplete = true;
}
return this;
}; // End of $.fn[iphoneStyle]
$[iphoneStyle].defaults = {
duration: 200, // Time spent during slide animation
checkedLabel: 'ON', // Text content of "on" state
uncheckedLabel: 'OFF', // Text content of "off" state
resizeHandle: true, // Automatically resize the handle to cover either label
resizeContainer: true, // Automatically resize the widget to contain the labels
disabledClass: 'iPhoneCheckDisabled',
containerClass: 'iPhoneCheckContainer',
labelOnClass: 'iPhoneCheckLabelOn',
labelOffClass: 'iPhoneCheckLabelOff',
handleClass: 'iPhoneCheckHandle',
handleCenterClass: 'iPhoneCheckHandleCenter',
handleRightClass: 'iPhoneCheckHandleRight',
dragThreshold: 5 // Pixels that must be dragged for a click to be ignored
};
})(jQuery, 'iphoneStyle');

View File

@@ -0,0 +1,53 @@
/*
highlight v3
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>
*/
jQuery.fn.highlight = function(pat) {
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos = node.data.toUpperCase().indexOf(pat);
if (pos >= 0) {
var spannode = document.createElement('span');
spannode.className = 'highlight';
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(pat.length);
var middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
}
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < node.childNodes.length; ++i) {
i += innerHighlight(node.childNodes[i], pat);
}
}
return skip;
}
return this.each(function() {
innerHighlight(this, pat.toUpperCase());
});
};
jQuery.fn.removeHighlight = function() {
return this.find("span.highlight").each(function() {
this.parentNode.firstChild.nodeName;
with (this.parentNode) {
replaceChild(this.firstChild, this);
normalize();
}
}).end();
};

View File

@@ -0,0 +1,33 @@
$(document).ready(function() {
$('button').button();
var $dialog = $('#dialogue').dialog({
title: "Package Management Results",
modal: false, autoOpen: false,
height: 500, width: 700,
show: 'scale', hide: 'fade',
draggable: true, resizable: true,
buttons: { "Close":
function() {$(this).dialog('close');}},
close: function(e,u) { window.location.reload(true); }
});
var opkg = '/cgi-bin/opkg.jim?cmd=';
$('#opkgupdate').click(function() {
$('#result_txt').load(opkg + 'update');
$('#results').show('slow');
});
$('button.remove, button.install, button.upgrade').click(function() {
$('#dspinner').show();
$('#dresults').load(
opkg + encodeURIComponent(
$(this).attr('action') + ' ' + $(this).attr('id')
),
function() { $('#dspinner').hide('slow') });
$dialog.dialog('open');
});
});

View File

@@ -6,6 +6,8 @@ puts {
source /mod/var/mongoose/include/model.jim
puts {
</title>
<meta http-equiv="expires" value="Thu, 01 Jan 1970 00:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
<link rel="shortcut icon" href=/img/favicon.ico />
<link href=/css/style.css rel=stylesheet type=text/css />
<link type="text/css" href="/css/jquery-ui.css" rel="Stylesheet" />
@@ -16,6 +18,7 @@ puts {
}
source /mod/var/mongoose/html/lib/topbar.jim
source /mod/var/mongoose/include/restart.jim
puts {
<div style="clear: both">

View File

@@ -1,6 +1,8 @@
<html>
<head>
<title><!--#exec cmd="/mod/var/mongoose/include/model.jim" --></title>
<meta http-equiv="expires" value="Thu, 01 Jan 1970 00:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
<link rel="shortcut icon" href=/img/favicon.ico />
<link href=/css/style.css rel=stylesheet type=text/css />
<link type="text/css" href="/css/jquery-ui.css" rel="Stylesheet" />
@@ -10,6 +12,7 @@
<body>
<!--#include virtual="/lib/topbar.shtml" -->
<!--#exec cmd="/mod/var/mongoose/include/restart.jim" -->
<div style="clear: both">

View File

@@ -4,17 +4,18 @@ puts {
<div class=container onclick="location.href='/'; return false;">
<div class=left><img src=/images/154_1_00_WIN_MD116_1L.png></div>
<div class=middle>
<img border=0 src=/images/516_1_26_Freeview_Logo.png>
<span style="font-size: 150%; padding: 0 0 0 2em;">
}
source /mod/var/mongoose/include/model.jim
puts {
</span>
<!-- Start include diskspace -->
<!-- Start include diskspace - above other items to work around IE feature.. -->
}
source /mod/var/mongoose/include/diskspace.jim
puts {
<!-- End include diskspace -->
<img border=0 src=/images/516_1_26_Freeview_Logo.png>
<span style="display: inline; font-size: 150%;
padding: 0 0 0 2em;">
}
source /mod/var/mongoose/include/model.jim
puts {
</span>
</div>
<div class=right><img src=/images/154_1_00_WIN_MD116_3R.png></div>
</div>

View File

@@ -3,13 +3,13 @@
<div class=container onclick="location.href='/'; return false;">
<div class=left><img src=/images/154_1_00_WIN_MD116_1L.png></div>
<div class=middle>
<img border=0 src=/images/516_1_26_Freeview_Logo.png>
<span style="font-size: 150%; padding: 0 0 0 2em;">
<!--#exec cmd="/mod/var/mongoose/include/model.jim" -->
</span>
<!-- Start include diskspace -->
<!-- Start include diskspace - above other items to work around IE feature.. -->
<!--#exec cmd="/mod/var/mongoose/include/diskspace.jim" -->
<!-- End include diskspace -->
<img border=0 src=/images/516_1_26_Freeview_Logo.png>
<span style="font-size: 1.5em; padding: 0 0 0 2em;">
<!--#exec cmd="/mod/var/mongoose/include/model.jim" -->
</span>
</div>
<div class=right><img src=/images/154_1_00_WIN_MD116_3R.png></div>
</div>

View File

@@ -1,6 +1,8 @@
<!--#include virtual="/lib/header.shtml" -->
<h1>Package Management</h1>
<h1 class=vam>Package Management
<button class=vam id=opkgupdate>Update package list from Internet</button>
</h1>
<div id=results class=shadowbox style="width: 90%; display: none; margin: 1 0 1em 0">
<div>
<pre id=result_txt>
@@ -9,6 +11,11 @@ Results...
</div>
</div>
<div id=dialogue style="display: none; align: center">
<pre id=dresults></pre>
<div id=dspinner><img src=/img/loading.gif>Processing...</div>
</div>
<!--#exec cmd="/mod/var/mongoose/include/packages.jim" -->
<!--#include virtual="/lib/footer.shtml" -->

View File

@@ -1,40 +1,27 @@
<!--#include virtual="/lib/header.shtml" -->
<link href=/css/iphone-style-checkboxes.css rel=stylesheet type=text/css />
<script type="text/javascript" src="/js/iphone-style-checkboxes.js"></script>
<script type="text/javascript">
<script type=text/javascript src=/js/ajax.js></script>
$(document).ready(function() {
$('input:checkbox').iphoneStyle();
// Don't allow turning off the web server from within the web server..
$('input:checkbox[name=mongoose][class=toggle]').attr('disabled', true);
<script type=text/javascript>
function updateResults()
{
var r = document.getElementById('results');
if (r && request.readyState == 4 && request.status == 200)
{
r.style.display = 'block';
var t = document.getElementById('result_txt');
t.innerHTML = request.responseText;
}
}
function go(service, action)
{
if (service == null || service == "" ||
action == null || action == "")
return;
var url = "/cgi-bin/service.jim?service=" + escape(service) +
"&action=" + escape(action);
request.open("GET", url, true);
request.onreadystatechange = updateResults;
request.send(null);
}
function toggle(obj)
{
if (obj.src.search("on") > -1)
obj.src = '/img/off.png';
else
obj.src = '/img/on.png';
}
$(':checkbox').change(function() {
var url = '/cgi-bin/service.jim?action=' +
escape($(this).attr('class')) +
'&service=' +
escape($(this).attr('name'));
$('#result_txt').load(url, function() {
if ($('#results').is(":visible") == false)
{
$('#results').show('slow');
$('#results').delay(3000).hide('slow');
}
});
});
});
</script>

67
var/mongoose/include/backup.jim Executable file
View File

@@ -0,0 +1,67 @@
#!/mod/bin/jimsh
source /mod/var/mongoose/lib/setup
require altrow rsv.class
puts {
<script type=text/javascript src=/cgi-bin/backup/backup.js></script>
<h2>Backup/Restore</h2>
<div id=restart_block></div>
<div id=restore_warning class="hidden warningbox">
<center>
<b>!!!!!!!!!!!!!! PLEASE NOTE !!!!!!!!!!!!!!
<br><br>
After restoring the scheduled recordings you <b>MUST</b> restart the box using
the link at the top of the screen or via the remote control and then add
at least one scheduled entry using the remote control
(which you can then delete).
</div>
<div style="clear: both; float: left; width: 40%; border: 1px solid grey;
padding: 1em">
To create a backup of your current favourite channel configuration and
scheduled recordings, enter a name in the box below and click the button.
A suggested name has been entered for you.
<p>
}
puts "<input type=text size=30 maxlength=50 id=backup_name name=file
class=\"text ui-widget-content ui-corner-all\"
value=\"[clock format [clock seconds] -format "backup-%Y-%b-%d-%H:%M"]\">"
puts "<button id=backup_button>Create Backup</button>"
puts {
<br>
<div id=backup_working class=va style="display: none;">
<img class=va src=/img/loading.gif>&nbsp;
<font class=footnote>Backing up...</font>
</div>
</div>
<div id=backup_files_outer
style="float: left; width: 40%; border: 1px solid grey; margin-left: 1em;
padding: 0 1em 1em 1em">
<h3>Available Backups</h3>
<div id=backup_files style="padding: 0 0 0 2em">
<img src=/img/loading.gif>Retrieving list of backups...
</div>
<br>
<button id=restore_button disabled>Restore Backup</button>
<button id=delete_button disabled>Delete Backup</button>
<br>
<div id=restore_working class=va style="display: none;">
<img class=va src=/img/loading.gif>&nbsp;
<font class=footnote>Restoring...</font>
</div>
</div>
<div id=results class=pre
style="display: none; clear: both; float: left; padding: 1em;
margin-top: 1em; border: 1px solid grey; width: 70%">
</div>
}

View File

@@ -1,10 +1,11 @@
#!/mod/bin/jimsh
package require sqlite3
source /mod/var/mongoose/lib/altrow
source /mod/var/mongoose/lib/setup
require altrow
proc db_info {db_file} {
if {![file exists $db_file]} { return }
set db [sqlite3.open $db_file]
set tables [$db query {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}]
@@ -40,4 +41,5 @@ puts {<style type="text/css">table, td, th {border-collapse:collapse; border:1px
db_info /var/lib/humaxtv/rsv.db
db_info /var/lib/humaxtv/setup.db
db_info /var/lib/humaxtv/channel.db
#db_info /mnt/hd2/dms_cds.db

View File

@@ -5,7 +5,7 @@ if {[os.gethostname] eq "hosting"} {
set used "100GB"
set perc "10"
} else {
foreach df [split [exec df -h] "\n\r"] {
foreach df [split [exec df -h 2>>/dev/null] "\n\r"] {
if [string match *sd*2* $df] {
regsub -all -- {[[:space:]]+} $df " " df
set fields [split $df]
@@ -18,13 +18,26 @@ if {[os.gethostname] eq "hosting"} {
set file [format "%02d" [expr {$perc * 25 / 100 + 1}]]
puts "<div style=\"float: right; background:url('/images/345_1_27_ST_USB_BG.png')\">"
puts "<img src=/images/345_2_14_ST_HDD_$file.png>"
puts "</div>"
puts "<span style=\"float: right\">"
puts "<br>"
puts "Total space: $size<br>"
puts "Used: $used ($perc%)"
puts "</span>"
# The HD model only has the USB images which are blue. I prefer the green
# one so use those if available.
if {[file exists /opt/share/images/blue/345_2_14_ST_HDD_01.png]} {
set prefix 345_2_14_ST_HDD
} else {
set prefix 345_1_27_ST_USB
}
puts "
<span style=\"float: right;
background:url('/images/345_1_27_ST_USB_BG.png')
no-repeat\">
<img src=/images/${prefix}_$file.png>
</span>
<span style=\"float: right\">
<br>
Total space: $size<br>
Used: $used ($perc%)
</span>
"

View File

@@ -1,18 +1,16 @@
#!/mod/bin/jimsh
source /mod/var/mongoose/lib/epg.class
source /mod/var/mongoose/lib/spinner.class
source /mod/var/mongoose/lib/altrow
source /mod/var/mongoose/lib/cat
package require cgi
source /mod/var/mongoose/lib/setup
require epg.class spinner.class altrow epg_search
[spinner new {
text "Loading EPG Data..."
text "Loading Now/Next Information..."
size "1.2em"
style "margin: 1em;"
}] start
#cat /mod/var/mongoose/lib/epg_popup
source /mod/var/mongoose/lib/epg_popup
require epg_popup
set start [clock milliseconds]
set records [epg fetch dump -time [clock seconds]]

View File

@@ -8,5 +8,18 @@ close $fd
regexp {URL=([^"]*)} $data match
set url [string range $match 4 [string length $match]]
puts "<a href=$url>";
puts "
<div style=\"float: left; padding-top: 5em\">
<center>
<a href=$url>
<img src=/img/mediatomb.png width=180>
</a>
<br>
<a href=$url>
<b>MediaTomb</b>
</a>
<br>
</center>
</div>
"

View File

@@ -1,52 +1,57 @@
#!/mod/bin/jimsh
# Build a list of available packages
source /mod/var/mongoose/lib/setup
require pkg.class
puts {
<style type=text/css>
.ui-button, .ui-button-text { padding: 0; font-size: 12px; }
</style>
<script type=text/javascript src=/js/packages.js></script>
<table class=borders>
<tr>
<th>Package</th>
<th>Installed</th>
<th>Avail</th>
<th>Description</th>
</tr>
set avail_pkgs {}
foreach pkg [split [exec /bin/opkg list] "\n"] {
if [regexp {^ } $pkg] {
append descr $pkg
} else {
if {[regexp {^([^ ]+) - ([^ ]+) - (.*)$} \
$pkg full name ver descr] == 0} { continue }
}
set avail_pkgs($name) [concat $ver "$descr"]
#puts "Set: $name = ($ver, $descr)<br>"
}
# Build a list of installed packages - just the names
set inst_pkgs {}
foreach pkg [split [exec /bin/opkg list-installed] "\n"] {
if {[regexp {^([^ ]+)} $pkg name] == 0} { continue }
lappend inst_pkgs $name
#puts "Inst: $name<br>"
}
set avail [pkg avail]
foreach name [lsort [array names avail]] {
set pkg [pkg load $name $avail($name)]
puts "<table class=borders>"
puts "<tr>"
puts "<th>Installed</th>"
puts "<th>Name</th>"
puts "<th>Version</th>"
puts "<th>Description</th>"
puts "</tr>"
foreach name [lsort [array names avail_pkgs]] {
set value $avail_pkgs($name)
set ver [lindex $value 0]
set descr [lrange $value 1 [llength $value]]
puts "<tr>"
puts "<td>"
if {[lsearch $inst_pkgs $name] > -1} {
puts "<img src=/img/on.png>"
if {![$pkg is installed]} {
puts "<tr>"
} elseif {[$pkg is upgradable]} {
puts "<tr class=yellowshade>"
} else {
puts "<img src=/img/off.png>"
puts "<tr class=greenshade>"
}
puts "</td>"
puts "<td>$name</td>"
puts "<td>$ver</td>"
puts "<td>$descr</td>"
puts "
<td>$name</td>
<td>[$pkg get installed]</td>
<td>[$pkg get latest]</td>
<td>[$pkg get descr]</td>
"
if {![$pkg is installed]} {
set type Install
} elseif {[$pkg is upgradable]} {
set type Upgrade
} else {
set type Remove
}
puts "<td align=center><button id=\"$name\"
action=[string tolower $type]
class=[string tolower $type]>$type</button></td>"
puts "</tr>"
}

View File

@@ -0,0 +1,52 @@
#!/mod/bin/jimsh
if {[file exists /tmp/.restartpending]} {
puts {
<center>
<div style="width: 60%; height: 0.7em;
background: url(/img/stripes.gif) repeat-x;"></div>
<div style="font-size: 1.2em; width: 60%; text-align: center; padding: 0.5em">
A warm restart is required in order to complete a scheduling operation.
<br>
<font class=blood>
}
# Is humaxtv doing anything?
set pid [exec pgrep humaxtv]
set c 0
catch { set c [exec /mod/bin/lsof -p $pid | grep Video | fgrep .ts | wc -l] }
if {$c > 0} {
puts "Cannot restart whilst box is busy."
} else {
puts {
Restart via the remote control or
<small><button id=restart_humaxtv>Restart now</button></small>
}
}
puts {
</font>
</div>
<div style="width: 60%; height: 0.7em; margin-bottom: 2em;
background: url(/img/stripes.gif) repeat-x;"></div>
</center>
<script type=text/javascript>
$('#restart_humaxtv').button();
$('#restart_humaxtv').click(function() {
if (confirm('Are you sure you wish to perform a warm restart now?'))
{
$.ajax({
url: '/cgi-bin/restart.jim',
success: function() {
window.location.reload(true);
}
});
}
});
</script>
}
}

View File

@@ -1,62 +1,45 @@
#!/mod/bin/jimsh
package require sqlite3
source /mod/var/mongoose/lib/setup
require altrow rsv.class progressbar
source /mod/var/mongoose/lib/altrow
set events [rsv list]
set db [sqlite3.open /var/lib/humaxtv/rsv.db]
$db query {attach database '/var/lib/humaxtv/channel.db' as channel}
puts {
<table class=borders>
<tr>
<th></th>
<th colspan=2>Channel</th>
<th>Programme</th>
<th>Start Time</th>
<th>Duration</th>
<th>Mode</th>
<th>Event/Series ID</th>
<th>Events</th>
</tr>
}
set res [$db query {
select *, channel.TBL_SVC.szSvcName, channel.TBL_SVC.usLcn,
case when ersvtype > 3 then 1 else 0 end as sort
from tbl_reservation
left join channel.TBL_SVC
on main.TBL_RESERVATION.hSvc = channel.TBL_SVC.hSvc
order by sort, nsttime
}]
puts "<table class=borders>"
puts "<tr>"
#puts "<th>Slot</th>"
puts "<th colspan=2>Programme</th>"
puts "<th>Duration</th>"
puts "<th colspan=2>Channel</th>"
puts "<th>Date/Time</th>"
puts "<th>Mode</th>"
puts "<th>Event/Series ID</th>"
puts "</tr>"
foreach r $res {
set name [string range $r(szevtname) 1 end]
if {[string first "i7" $name] == 0} {
set name [string range $name 2 end]
set b "*"
} else {
set b ""
}
foreach event $events {
set name [$event name]
altrow
set rsvicon ""
set alta ""
switch $r(ersvtype) {
switch [$event get ersvtype] {
1 { set rsvicon "175_1_00_Reservation_Watch.png" }
2 { set rsvicon "175_1_00_Reservation_Watch.png" }
3 { set rsvicon "175_1_11_Reservation_Record.png" }
5 { set rsvicon "745_1_10_Video_2Live.png"; set alta "Wake-up" }
6 { set rsvicon "745_1_11_Video_1REC.png"; set alta "Sleep" }
7 { set rsvicon "345_6_08_ST_Ad_Hoc.png"
set alta "Auto Update" }
default { set alta "Unknown type $r(ersvtype)" }
5 { set rsvicon "745_1_10_Video_2Live.png" }
6 { set rsvicon "745_1_11_Video_1REC.png" }
7 { set rsvicon "345_6_08_ST_Ad_Hoc.png" }
}
if {$name == ""} { set name "-- $alta --" }
set series 0
if {$r(ucRecKind) == 4} {
if {[$event get ucRecKind] == 4} {
set RKIcon "175_1_11_Series_Record.png"
set series 1
} else {
switch $r(erepeat) {
switch [$event get erepeat] {
1 {set RKIcon "521_1_00_RP_Daily_C.png"}
2 {set RKIcon "521_1_00_RP_Weekly_C.png"}
3 {set RKIcon "521_1_00_RP_Weekdays_C.png"}
@@ -66,38 +49,90 @@ foreach r $res {
}
if {$rsvicon ne ""} {
set rsvicon "<img src='images/$rsvicon' height=15>
set rsvicon "<img src='images/$rsvicon' height=20>
}
if {$RKIcon ne ""} {
set RKIcon "<img src='images/$RKIcon' height=15>
set RKIcon "<img src='images/$RKIcon' height=20>
}
# puts "<td>{$r(ulslot)}</td>"
puts "<td>$b</td><td>$name</td>"
puts "<td>[clock format $r(nduration) -format %T]</td>"
puts "<td>$r(usLcn)</td>"
puts "<td>[string range $r(szSvcName) 1 end]</td>"
if { $r(nsttime) < [clock seconds] } {
puts "<td class=blood>"
puts "<td>[$event get ulslot]</td>"
if {[$event get usLcn] ne ""} {
puts "
<td>
<img src=\"/img/channels/[$event channel_name].png\"
width=50>
</td>
<td nowrap>[$event get usLcn]<br>
[$event channel_name]</td>
"
} else {
puts "<td>"
puts "<td colspan=2>&nbsp;<br><br></td>"
}
puts "[clock format $r(nsttime) -format {%c %Z}]</td>"
puts "<td>$rsvicon $RKIcon</td>"
puts "<td>"
set crid [join [lrange [split $r(szCRID) "/"] 1 end]]
puts "<td nowrap>$name</td>"
set s [$event get nsttime]
set d [$event get nduration]
set e $($s + $d)
set n [clock seconds]
if { $n > $e } {
puts "<td class=blood nowrap class=va>"
} else {
puts "<td nowrap class=va>"
}
puts "[clock format $s -format "%a %d %b %Y"]<br>
[clock format $s -format "%H:%M %Z"]"
if {$d > 0 && $n > $s && $n < $e} {
puts "<br>"
set perc [expr [expr $n - $s] * 100 / $d]
puts "<img class=va src=/images/745_1_11_Video_1REC.png>"
puts [progressbar $perc]
}
puts "</td>"
puts "<td>[clock format [$event get nduration] -format %T]</td>"
puts "<td nowrap>$rsvicon $RKIcon</td>"
puts "<td nowrap>"
set crid [join [lrange [split [$event get szCRID] /] 1 end]]
if {$crid != ""} {
puts -nonewline "<a href=/cgi-bin/epg_search.jim?"
if $series { puts -nonewline "s" }
puts "crid=/$crid>
<img border=0 src=/images/421_1_00_CH_Title_2R_Arrow.png
height=14>
$r(szCRID)"
[$event get szCRID]"
puts "</a>"
}
puts "</td>"
puts "<td nowrap>"
set flag 0
foreach ev [split [$event get szEventToRecord] "|"] {
if {$ev eq ""} { continue }
set ev [string range $ev 1 end]
if {$flag} { puts "<br>" }
incr flag
set crid [join [lrange [split $ev /] 1 end]]
puts -nonewline "<a href=/cgi-bin/epg_search.jim?"
puts "crid=/$crid>
<img border=0 src=/images/421_1_00_CH_Title_2R_Arrow.png
height=14>
$ev"
puts "</a>"
}
puts "</td>"
puts "</tr>"
}
puts "</table>"
puts "<font class=footnote>Click on the CRID to view episodes.</font>"
$db close
puts {
<button onclick="window.location='/backup.shtml';">
Backup/Restore Scheduled Recordings/Events.
</button>
}

View File

@@ -2,18 +2,6 @@
set services [split [exec /mod/bin/service mlist]]
proc button {state service action} {
puts -nonewline "<a href=#>"
puts -nonewline "<img border=0 src=/img/$state.png"
puts -nonewline " onClick=\"go('$service', '$action'); "
puts -nonewline "toggle(this); return false\">"
puts "</a>"
}
proc control {s a} {
return "<a href=/cgi-bin/service.jim?action=$a&service=$s>"
}
foreach service $services {
set data [split $service ":"]
set name [lindex $data 0]
@@ -21,20 +9,19 @@ foreach service $services {
set auto [lindex $data 2]
set running [lindex $data 3]
puts "<tr class=even><td>$name</td>"
puts "<tr><td class=even>$name</td>"
if (!$installed) {
puts "<td colspan=3><i>Not installed</i></td></tr>"
continue
}
puts "<td>"
if ($auto) { button on $name auto } else { button off $name auto }
puts "</td>"
puts -nonewline "<td><input type=checkbox class=auto name=\"$name\""
if ($auto) { puts -nonewline " checked" }
puts "></td>"
puts "<td>"
if ($running) { button on $name toggle } else {
button off $name toggle }
puts "</td>"
puts -nonewline "<td><input type=checkbox class=toggle name=\"$name\"""
if ($running) { puts -nonewline " checked" }
puts "></td>"
puts "</tr>"
}

View File

@@ -1,35 +0,0 @@
#!/mod/bin/jimsh
set ::env(PATH) "/mod/bin/busybox:/mod/bin:/bin"
set pid [exec pgrep humaxtv]
if {[catch {set line [exec lsof -p $pid | grep Video | fgrep .ts]} ]} {
exit
}
regsub -all -- {[[:space:]]+} $line " " line
set fields [split $line " "]
set size [lindex $fields 6]
sleep 2
set line [exec lsof -p $pid | grep Video | fgrep .ts]
regsub -all -- {[[:space:]]+} $line " " line
set fields [split $line " "]
set size2 [lindex $fields 6]
if { $size2 > $size } {
set mode "Recording"
set icon "745_1_11_Video_1REC.png"
} else {
set mode "Watching"
set icon "745_1_10_Video_2Live.png"
}
set name [lindex [split $line "/"] end]
puts "<div class=shadowbox><div>"
puts "<img src=/images/$icon>$mode $name"
puts "</div></div>"

View File

@@ -1,15 +1,20 @@
source /mod/var/mongoose/lib/setup
if {[expr ! [exists -proc class ]]} { package require oo }
if {[expr ! [exists -proc sqlite3.open ]]} { package require sqlite3 }
if {[expr ! [exists -proc settings ]]} {
source /mod/var/mongoose/lib/settings.class
if {![exists -proc class ]} { package require oo }
if {![exists -proc sqlite3.open ]} { package require sqlite3 }
if {![exists -proc settings ]} { require settings.class }
require progressbar
set ::channeldb 0
catch { set ::channeldb [sqlite3.open /var/lib/humaxtv/channel.db] }
set ::epgpath /mnt/hd1/dvbepg/epg.dat
set ::hdepgpath /media/drive1/epgsavedata
if {![file exists $::epgpath] && [file exists $::hdepgpath]} {
set ::epgpath $::hdepgpath
}
source /mod/var/mongoose/lib/progressbar
set channeldb 0
catch { set channeldb [sqlite3.open /var/lib/humaxtv/channel.db] }
# * service_id, event_id, start, duration, encrypted, name, text
# * warning, content code, content type,
# * event CRID, series CRID, rec CRID
@@ -210,7 +215,7 @@ proc {epg cleanup} {} {
proc {epg exec} {mode args} {
set raw 0
set cmd [list /mod/bin/epg]
set cmd [list /mod/bin/epg -f $::epgpath]
set extra ""
foreach arg $args {
if {[string first "-" $arg] == 0} {
@@ -259,3 +264,15 @@ proc {epg favlist} {} {
"] { lindex $i end }]
}
proc {epg channellist} {} {
global channeldb
set channels {}
lmap i [$channeldb query "
select usSvcid, szSvcName
from TBL_SVC
"] { set channels([string range [lindex $i 3] 1 end]) [lindex $i 1] }
return $channels
}

122
var/mongoose/lib/epg_search Executable file
View File

@@ -0,0 +1,122 @@
puts {
<style type=text/css>
.ui-button, .ui-button-text { padding: 0; font-size: 12px; }
#moresearch { display: none; }
#morebutton { position: relative; top: -12px; }
</style>
}
set searchterm ""
catch { set searchterm [dict get $_cgi term] }
set searchfull 0
catch { if {[dict exists $_cgi full]} { set searchfull 1 } }
puts "
<form method=get action=/cgi-bin/epg_search.jim>
<fieldset>
<legend>EPG Search</legend>
<label for=term>Query</label>
<input type=text name=term id=term size=20 maxlength=255 value=\"$searchterm\"
class=\"text ui-widget-content ui-corner-all\">
<input type=submit value=Search>
<input type=checkbox name=full id=full"
if {$searchfull == 1} { puts -nonewline " checked" }
puts ">
<label for=full>Search descriptions as well as titles.</label>
<font class=footnote style=\"margin-left: 5em\">
Click down arrow below for more options.
</font>
<div id=moresearch class=hidden>
"
proc cts {type img text} {
puts "<a href=/cgi-bin/epg_search.jim?ct=$type>
<img height=18 border=0 src=/images/173_3_00_G3_$img.png>
&nbsp;$text</a>";
}
puts {
<br>
<fieldset>
<legend>Content Type Searches</legend>
<table>
<tr>
<td>
}
cts 1 "Movie" "Film/Drama"
puts "</td><td>"
cts 2 "News" "News/Current affairs"
puts "</td><td>"
cts 4 "Sports" "Sport"
puts "</td><td>"
cts 9 "Education" "Education/Science/Factual"
puts "</td><td>"
cts 10 "Leisure" "Leisure"
puts "</td></tr><tr><td>"
cts 7 "Art" "Arts/Culture"
puts "</td><td>"
cts 3 "Show" "Show/Game show"
puts "</td><td>"
cts 5 "Children" "Children"
puts "</td><td>"
cts 8 "Society" "Social/Political/Economic"
puts "</td><td>"
cts 6 "Music" "Music/Ballet/Dance"
puts "</tr></table></fieldset>"
set db [sqlite3.open /var/lib/humaxtv/setup.db]
set res [$db query {
select itemBlob from TBL_USERCONFIG
where itemName like 'EPG\_KEYWORD\_%%' ESCAPE '\'
}]
$db close
if {[llength $res] > 0} {
puts "
<fieldset>
<legend>Keyword Searches</legend>
<table cellpadding=5>
<tr>
"
foreach keyword $res {
set kw [string range [lindex $keyword 1] 1 end]
# Clean the keyword string.
regexp -nocase {^(\w+)} $kw kw
puts "<td><a href=/cgi-bin/epg_search.jim?term=[cgi_quote_url $kw]>$kw
</a></td>"
}
puts "
</tr>
</table>
</fieldset>
"
}
puts "
</div>
"
puts "</fieldset>"
puts "<center><img id=morebutton src=/img/more_show.png></center>"
puts "</form>"
puts {
<script type=text/javascript>
$('input:submit').button();
$('#morebutton').click(function(e) {
e.preventDefault();
$('#moresearch').slideToggle('slow');
if ($('#morebutton').attr('src') == '/img/more_show.png')
$('#morebutton').attr('src', '/img/more_hide.png');
else
$('#morebutton').attr('src', '/img/more_show.png');
});
</script>
}

8
var/mongoose/lib/ffmpeg Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
/mod/bin/ffmpeg "$@" 2>&1 | sed '
1,8d
$d
'
exit 0

6
var/mongoose/lib/opkg Executable file
View File

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

84
var/mongoose/lib/pkg.class Executable file
View File

@@ -0,0 +1,84 @@
if {[expr ! [exists -proc class ]]} { package require oo }
class pkg {
name ""
descr ""
installed ""
latest ""
install_time 0
}
pkg method _load {nm info} {
set name $nm
set latest [lindex $info 0]
set descr [lrange $info 1 end]
foreach line [split [exec /bin/opkg status $name] "\n"] {
if {[string match {Version: *} $line]} {
set installed [string range $line 9 end]
}
if {[string match {Installed-Time: } $line]} {
set install_time [string range $line 16 end]
}
}
}
pkg method is {what} {
switch $what {
installed {
if {$installed eq ""} { return 0 }
return 1
}
upgradable {
if {$installed eq $latest} { return 0 }
return 1
}
}
return 0
}
proc {pkg load} {nm info} {
set e [pkg]
$e _load $nm $info
return $e
}
proc {pkg avail} {} {
set avail_pkgs {}
foreach pkg [split [exec /bin/opkg list] "\n"] {
if [regexp {^ } $pkg] {
append descr $pkg
} else {
if {[regexp {^([^ ]+) - ([^ ]+) - (.*)$} \
$pkg full name ver descr] == 0} { continue }
}
set avail_pkgs($name) [concat $ver "$descr"]
#puts "Set: $name = ($ver, $descr)<br>"
}
return $avail_pkgs
}
proc {pkg installed} {} {
# Build a list of installed packages - just the names
set inst_pkgs {}
foreach pkg [split [exec /bin/opkg list-installed] "\n"] {
if {[regexp {^([^ ]+)} $pkg name] == 0} { continue }
lappend inst_pkgs $name
#puts "Inst: $name<br>"
}
return $inst_pkgs
}
proc {pkg upgradable} {} {
#webif - 0.5.3 - 0.5.7
set upgr_pkgs {}
foreach pkg [split [exec /bin/opkg list-upgradable] "\n"] {
if {[regexp {^([^ ]+) - ([^ ]+) - (.*)$} $pkg \
dummy name oldver newver] == 0} { continue }
set upgr_pkgs($name) [concat $oldver $newver]
#puts "Set: $name = ($oldver, $newver)<br>"
}
return $upgr_pkgs
}

9
var/mongoose/lib/plugin Normal file
View File

@@ -0,0 +1,9 @@
proc eval_plugins {hook} {
foreach plugin [glob /mod/var/mongoose/plugin/*] {
if {[file isfile "$plugin/$hook.hook"]} {
uplevel source "$plugin/$hook.hook"
}
}
}

View File

@@ -0,0 +1,15 @@
if {[expr ! [exists -proc pretty_size ]]} {
proc pretty_size {size} {
set units {bytes KiB MiB GiB TiB}
for {set i 0} {$size > 1023} {incr i} {
set size $($size / 1024.0)
}
set size [format "%.2f" $size]
return "$size [lindex $units $i]"
}
}

136
var/mongoose/lib/rsv.class Executable file
View File

@@ -0,0 +1,136 @@
source /mod/var/mongoose/lib/setup
if {![exists -proc class ]} { package require oo }
if {![exists -proc sqlite3.open ]} { package require sqlite3 }
if {![exists -proc settings ]} { require settings.class }
set rsvdb [sqlite3.open /var/lib/humaxtv/rsv.db]
$rsvdb query {attach database '/var/lib/humaxtv/channel.db' as channel}
class rsv {
ulslot 0
ersvtype 0
hsvc 0
nsttime 0
szsttime 0
nduration 0
erepeat 0
usevtid 0
szevtname {}
ulPreOffset 0
ulPostOffset 0
ulProgramId 0
ulSeriesId 0
ucVolume 0
ucInputMode 0
usChNum 0
ucRecKind 0
ucCRIDType 0
szCRID {}
szFPBRecPath {}
szRecordedProgCrid {}
szEventToRecord {}
aulEventToRecordInfo {}
bRecomRsv 0
usLastRecordedEvtId 0
eReady 0
szSvcName {}
usLcn 0
sort 0
}
rsv method name {} {
set name [string range $szevtname 1 end]
if {[string first "i7" $name] == 0} {
set name [string range $name 2 end]
}
if {$name == ""} {
switch $ersvtype {
5 { set name "--- Wake-up ---" }
6 { set name "--- Sleep ---" }
7 { set name "--- Auto Update ---" }
default { set name "--- Unknown event type $ersvtype ---" }
}
}
return $name
}
rsv method channel_name {} {
return [string range $szSvcName 1 end]
}
rsv method fix_hsvc {} {
global rsvdb
set _hsvc [$rsvdb query "
select hSvc
from channel.TBL_SVC
where szSvcName = '$szSvcName'
or szSvcname = '\025$szSvcName'
limit 1
"]
if {[llength $_hsvc] == 1} {
set hsvc [lindex [lindex $_hsvc 0] 1]
} else {
set hsvc 0
}
return $hsvc
}
rsv method insert {} {
global rsvdb
if {!$ulslot} {
set slot [
$rsvdb query {select max(ulslot) FROM TBL_RESERVATION}]
set slot [expr 1 + [lindex [lindex $slot 0] 1]]
set ulslot $slot
}
set fields [lsort [$self vars]]
foreach field {aulEventToRecordInfo szSvcName usLcn sort} {
set df [lsearch $fields $field]
set fields [lreplace $fields $df $df]
}
set vals {}
foreach field $fields {
lappend vals "'[$self get $field]'"
}
set query "insert into TBL_RESERVATION("
append query [join $fields ","]
append query ") values("
append query [join $vals ","]
append query ");"
$rsvdb query $query
}
proc {rsv list} {} {
catch { $::rsvdb query {.mode tcl} }
set res [$::rsvdb query {
select tbl_reservation.*,
channel.TBL_SVC.szSvcName, channel.TBL_SVC.usLcn,
case when ersvtype > 3 then 1 else 0 end as sort
from tbl_reservation
left join channel.TBL_SVC
on main.TBL_RESERVATION.hSvc = channel.TBL_SVC.hSvc
order by sort, nsttime
}]
set records {}
foreach rec $res {
lappend records [rsv new $rec]
}
return $records
}
proc {rsv cleanup} {} {
catch {$::rsvdb close}
}

View File

@@ -1,6 +1,6 @@
if {[expr ! [exists -proc class ]]} { package require oo }
if {[expr ! [exists -proc sqlite3.open ]]} { package require sqlite3 }
if {![exists -proc class ]} { package require oo }
if {![exists -proc sqlite3.open ]} { package require sqlite3 }
set settingsdb [sqlite3.open /mod/etc/webif.db]

20
var/mongoose/lib/setup Normal file
View File

@@ -0,0 +1,20 @@
if {![exists -proc require]} {
proc require {args} {{done {}}} {
foreach file $args {
if {$file ni $done} {
uplevel source "/mod/var/mongoose/lib/$file"
lappend $done $file
}
}
}
proc header {} {
uplevel source /mod/var/mongoose/html/lib/header.jim
}
proc footer {} {
uplevel source /mod/var/mongoose/html/lib/footer.jim
}
}

View File

@@ -1,5 +1,5 @@
if {[expr ! [exists -proc class ]]} { package require oo }
if {![exists -proc class ]} { package require oo }
class ts {
file ""
@@ -13,6 +13,7 @@ class ts {
end 0
flags ""
error ""
guidance ""
}
ts method duration {} {
@@ -20,11 +21,8 @@ ts method duration {} {
}
ts method size {} {
set sz "??"
catch {
file stat $file st
set sz [expr $st(size) / 1048576]
}
file stat $file st
return $st(size)
}
ts method _parse {line} {
@@ -38,6 +36,7 @@ ts method _parse {line} {
set start [lindex $vars 5]
set end [lindex $vars 6]
set flags [split [string range [lindex $vars 7] 0 end-1] ,]
set guidance [lindex $vars 8]
}
ts method flag {f} {
@@ -46,14 +45,36 @@ ts method flag {f} {
ts method unlock {} {
set cmd [list /mod/bin/hmt -lock $file]
#puts "CMD: $cmd"
exec {*}$cmd
return 1
}
ts method lock {} {
set cmd [list /mod/bin/hmt +lock $file]
#puts "CMD: $cmd"
exec {*}$cmd
return 1
}
ts method unenc {} {
set cmd [list /mod/bin/hmt -protect $file]
exec {*}$cmd
return 1
}
ts method enc {} {
set cmd [list /mod/bin/hmt +protect $file]
exec {*}$cmd
return 1
}
ts method set_new {} {
set cmd [list /mod/bin/hmt +new $file]
exec {*}$cmd
return 1
}
ts method set_watched {} {
set cmd [list /mod/bin/hmt -new $file]
exec {*}$cmd
return 1
}
@@ -78,7 +99,14 @@ proc {ts exec} {file} {
return [exec {*}$cmd]
}
proc {ts fetch} {file} {
proc {ts fetch} {file {checked 0}} {
# Check that this is a .ts file which has at least one sidecar
# file (.nts)
if {!$checked} {
if {[file extension $file] ne ".ts"} { return 0 }
if {![file exists "[file rootname $file].nts"]} { return 0 }
}
return [ts parse $file [ts exec $file]]
}
@@ -91,3 +119,27 @@ ts method delete {} {
return 1
}
ts method settitle {newtitle} {
if {[string length newtitle] > 48} { return }
exec /mod/bin/hmt "+settitle=${newtitle}" $file
}
proc {ts renamegroup} {from to} {
set dir [file dirname $from]
set root [file rootname $from]
# Catch from string without a . character in it
if {$root eq $from} { return }
# Protect special characters in root. In particular [] characters
# which are used a lot for torrent names.
regsub -all {([\\["$])} $root {\\\1} root
foreach f [glob -nocomplain "${root}.*"] {
set ext [file extension $f]
#puts "rename $f \"${dir}/${to}${ext}\""
file rename $f "${dir}/${to}${ext}"
}
}