Compare commits

...

55 Commits

Author SHA1 Message Date
hummypkg
3559a430ab add epg -day and rsv commit when necessary
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@305 2a923420-c742-0410-a762-8d5b09965624
2011-08-25 20:30:13 +00:00
hummypkg
945c6d1b4b use pending table for scheduling
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@296 2a923420-c742-0410-a762-8d5b09965624
2011-08-22 20:55:06 +00:00
hummypkg
81c3ef4f73 support same directory symlinks
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@294 2a923420-c742-0410-a762-8d5b09965624
2011-08-20 21:30:43 +00:00
hummypkg
2c61281b09 skip non-directory links
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@292 2a923420-c742-0410-a762-8d5b09965624
2011-08-20 20:50:40 +00:00
hummypkg
d5b27acd46 fix minor file browser bugs
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@291 2a923420-c742-0410-a762-8d5b09965624
2011-08-20 20:45:23 +00:00
hummypkg
767021557f download decrypted fiels
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@285 2a923420-c742-0410-a762-8d5b09965624
2011-08-13 00:18:42 +00:00
hummypkg
4f900f47b4 download decrypted versions of files
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@284 2a923420-c742-0410-a762-8d5b09965624
2011-08-13 00:18:12 +00:00
hummypkg
8383651367 minor bugfixes, support ffmpeg 0.8
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@282 2a923420-c742-0410-a762-8d5b09965624
2011-07-19 23:10:32 +00:00
hummypkg
d764969b8f update to 0.6.3, show alternate showings
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@280 2a923420-c742-0410-a762-8d5b09965624
2011-07-18 19:26:58 +00:00
hummypkg
301336b778 updae to 0.6.2
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@277 2a923420-c742-0410-a762-8d5b09965624
2011-07-17 21:01:27 +00:00
hummypkg
1b8761b8f3 fix diskspace bug, add sortable schedule list, fix plugin bug
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@276 2a923420-c742-0410-a762-8d5b09965624
2011-07-17 20:52:33 +00:00
hummypkg
b2f5f2c48a more attempts at chunked opkg
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@274 2a923420-c742-0410-a762-8d5b09965624
2011-07-15 23:20:57 +00:00
hummypkg
64b73ee14b create chunked module and add iajax. Update pkg to handled chunked responses
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@273 2a923420-c742-0410-a762-8d5b09965624
2011-07-14 22:22:54 +00:00
hummypkg
dbc3d21807 fix diskspace problem on HD
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@272 2a923420-c742-0410-a762-8d5b09965624
2011-07-14 19:28:00 +00:00
hummypkg
d1267cbd1e update version number
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@268 2a923420-c742-0410-a762-8d5b09965624
2011-07-12 18:57:48 +00:00
hummypkg
7643a92550 scheduling updates
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@267 2a923420-c742-0410-a762-8d5b09965624
2011-07-12 18:57:30 +00:00
hummypkg
b1176d9f64 remove etc directory
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@266 2a923420-c742-0410-a762-8d5b09965624
2011-07-11 23:30:42 +00:00
hummypkg
ded9495595 re-implemented package management. Initial suppor for remote scheduling
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@265 2a923420-c742-0410-a762-8d5b09965624
2011-07-11 23:29:21 +00:00
hummypkg
2a224c1055 bug fixes, to 0.6.0-2
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@262 2a923420-c742-0410-a762-8d5b09965624
2011-07-09 20:12:33 +00:00
hummypkg
33a72aa43f include var/backup
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif/trunk@261 2a923420-c742-0410-a762-8d5b09965624
2011-07-08 22:51:33 +00:00
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
hummypkg
700306b3a8 implement delete action + menu item greying out and correct lock/unlock labels. Also add SMTP server settings
git-svn-id: file:///root/webif/svn/humax/pkg/src/webif@180 2a923420-c742-0410-a762-8d5b09965624
2011-06-16 23:49:48 +00:00
102 changed files with 3883 additions and 844 deletions

View File

@@ -1,10 +1,11 @@
Package: webif
Priority: optional
Section: web
Version: 0.5.1
Version: 0.6.4-1
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(>=3.0-2),jim(>=0.71-1),jim-sqlite3(>=0.71-1),jim-cgi(>=0.4),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.

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: no-cache"
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: no-cache"
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,142 @@
#!/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-09-20:37"
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 {begin transaction;}
$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 }
}
$rsvdb query {commit transaction;}
puts "Restoring favourite channels..."
$rsvdb query {begin transaction;}
$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
}
$rsvdb query {commit transaction;}
close [open /tmp/.restartpending w]
close $fd
rsv cleanup

View File

@@ -1,73 +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 ignore {.nts .thm .hmt .hmi}
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) "lock"
#set env(REQUEST_URI) ''
proc tsfile {file bfile} {{i 0}} {
set ts [ts fetch $file]
puts "
<div class=\"va tsfile\" id=[incr i]>
<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>"
}
if {[$ts flag "Locked"] > 0} {
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
src=/images/181_1_00_Help5_OPT_Plus.png>
</a>
<div class=\"results blood\" style=\"margin: 0 0 0 5em\"></div>
</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} {
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]
}
@@ -75,95 +35,98 @@ proc entry {file} {
directory $file $bfile
continue
}
regexp -- {\.([^.]+)$} "$file" allmatch ext
if {$ext eq "ts"} {
tsfile $file $bfile
continue
}
if {$ext in $::ignore} { continue }
if {$ext in $::standard} {
genfile $file $bfile
continue
}
}
set ext [file extension $file]
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
}
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]} {
@@ -172,157 +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>
<div id=dialogue></div>
<div id=confirm title="Confirmation Required"></div>
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');
}
);
});
}
// 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() {
$('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');
});
$('img.opt').contextMenu(
{
menu: 'optmenu',
leftButton: true,
},
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;
case 'lock':
confirm_action('change the lock on', lock_callback, ts, did);
break;
default:
alert('Unhandled action: ' + action);
break;
}
}
);
});
</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,287 @@
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 = '/cgi-bin/browse/download.jim?file=' +
encodeURIComponent(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,49 @@
#!/mod/bin/jimsh
package require cgi
package require sqlite3
source /mod/var/mongoose/lib/setup
require ts.class
#puts "Content-Type: text/plain\r\n\r\n"
cgi_input
#cgi_dump
set file [dict get $_cgi file]
set rfile [file normalize $file]
set ts [ts fetch $file]
set dmsfile /mnt/hd2/dms_cds.db
set url $file
set mime "video/ts"
if {[file exists $dmsfile]} {
set db [sqlite3.open /mnt/hd2/dms_cds.db]
set muri [$db query "
select tblresource.mimetype, contenturi
from tblresource join tblmedia using (mediaid)
where localurl = '%s'" $rfile]
if {$muri != ""} {
set rec [lindex $muri 0]
set xuri [lindex $rec 3]
set mime [lindex $rec 1]
set url "http://$env(HTTP_HOST):9000/web/$xuri"
}
}
puts "Content-Type: text/plain"
puts "Refresh: 0; url=$url"
puts "Content-length: 0"
puts ""
#puts "Pragma: public"
#puts "Expires: 0"
#puts "Cache-Control: must-revalidate, post-check=0, pre-check=0"
#puts "Content-Type: application/force-download"
#puts "Content-Type: application/download"
#puts "Content-Type: $mime"
#puts "Content-Disposition: attachment; filename=\"[file tail $file]\""
#puts "Content-Transfer-Encoding: binary"
#puts "Content-Length: [file size $rfile]"

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,46 @@
#!/mod/bin/jimsh
package require cgi
#puts "Content-Type: text/plain"
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 [file tail [lindex $fields 1]]
# set node [lindex [split [lindex $fields 1] /] end]
puts "\"$node\" : \"$size\","
}
# Handle symbolic links.
foreach file [glob -nocomplain "$dir/*"] {
if {[catch {set lk [file readlink $file]}]} continue
if {![string match "/*" $lk]} { set lk "$dir/$lk" }
if {![file isdirectory $lk]} continue
foreach line [split [exec /mod/bin/busybox/du -h "$lk"] "\n"] {
set fields [split $line "\t"]
if {[lindex $fields 1] eq $lk} {
set node [file tail $file]
set size [lindex $fields 0]
puts "\"$node\" : \"@$size\","
}
}
}
puts "\"dummy\" : \"\""
puts "}"

72
var/mongoose/cgi-bin/db.jim Executable file
View File

@@ -0,0 +1,72 @@
#!/mod/bin/jimsh
package require cgi
package require sqlite3
source /mod/var/mongoose/lib/setup
require altrow
puts "Content-Type: text/html"
puts ""
header
cgi_input
#cgi_dump
set ftab [cgi_get tab]
set fdb [cgi_get db]
if {$fdb != 0} {
puts "<h1><a href=/cgi-bin/db.jim>Remove filters</a></h1>"
}
proc db_info {db_file} {
global _cgi fdb ftab
if {$fdb != 0 && [file tail $db_file] ne $fdb} { return }
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
}]
puts "<h1><a href=/cgi-bin/db.jim?db=[file tail $db_file]>
$db_file</a></h1>"
foreach table $tables {
set table [lindex $table 1]
if {$ftab != 0 && $ftab ne $table} { continue }
set columns [$db query "pragma table_info($table)"]
set datas [$db query "SELECT * FROM $table order by 1"]
puts "<h2><a href=/cgi-bin/db.jim?db=[file tail $db_file]&tab=$table>$table</a></h2>"
puts "<table class=borders>"
puts " <tr>"
foreach column $columns {
puts " <th>[lindex $column 3]</th>"
}
puts " </tr>"
foreach data $datas {
altrow
for {set i 1} {$i < [llength $data]} {incr i 2} {
puts " <td>[lindex $data $i]</td>"
}
puts " </tr>"
}
puts "</table>"
}
$db close
}
db_info /var/lib/humaxtv/rsvp.db
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
footer

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,15 +14,26 @@ 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
#set service 8448
#set event 30843
set record [lindex [epg fetch dump -service $service -event $event] 0]
$record get_channel_info
set others [$record othertimes]
puts {
<style type=text/css>
font.also
{
font-size: 0.9em;
font-style: italic;
color: #333;
background: transparent;
}
</style>
}
puts "
<table class=keyval>
@@ -33,10 +45,38 @@ puts "
<td>[$record get text]</td>
</tr><tr>
<th>Start</th>
<td>[clock format [$record get start] -format {%c %Z}]</td>
<td>[clock format [$record get start] -format {%c %Z}]
"
foreach o $others {
if {[$o ended]} { continue }
$o get_channel_info
$o process_sched
if {[$o get series_crid] eq ""} { set ro 1 } else { set ro 2 }
puts -nonewline "<br><font class=also>&nbsp;&nbsp;&nbsp;&nbsp;"
puts -nonewline "Also: "
puts -nonewline "<a class=event href=# xs=[$o get service_id] "
puts -nonewline "xe=[$o get event_id] "
puts -nonewline "sch=[$o get sched_type] rec=$ro>"
puts -nonewline "[clock format [$o get start] -format {%c %Z}]"
puts -nonewline " on "
puts -nonewline [$o channel_icon 16]
puts -nonewline "[$o get channel_name] "
puts "</a>"
puts "</font>"
}
puts "
</td>
</tr><tr>
<th>Duration</th>
<td>[clock format [$record get duration] -format %T]</td>
<td>[clock format [$record get duration] -format %T]
"
if {[$record showing]} {
puts [progressbar [$record percent]]
}
puts "
</td>
</tr><tr>
<th>Type</th>
<td>[$record get content_type] ([$record get content_code])</td>
@@ -55,8 +95,13 @@ if {[$record get warning] != ""} {
if {[$record get event_crid] != ""} {
puts "
<tr>
<th>CRID</th>
<td>[$record get channel_crid][$record get event_crid]</td>
<th>CRID</th><td>
<a href=/cgi-bin/epg_search.jim?crid=[$record get event_crid]>
<img border=0 height=14
src=/images/421_1_00_CH_Title_2R_Arrow.png>
[$record get channel_crid][$record get event_crid]
</a>
</td>
</tr>
"
}
@@ -104,8 +149,8 @@ puts "
</a>
"
epg cleanup
if {! [dict exists $_cgi bare]} {
source /mod/var/mongoose/html/lib/footer.jim
}
puts "<div id=epginfo_extra class=footnote></div>"
epg cleanup
if {! [dict exists $_cgi bare]} { footer }

View File

@@ -0,0 +1,83 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/setup
require epg.class
puts "Content-Type: text/html"
puts ""
cgi_input
#cgi_dump
#set _cgi(service) 4170
#set _cgi(event) 38584
#set _cgi(type) 2
if {![dict exists $_cgi service] || ![dict exists $_cgi event]} {
puts "Error, insufficient parameters passed."
exit
}
set service $_cgi(service)
set event $_cgi(event)
set type 1
if {[dict exists $_cgi type]} { set type $_cgi(type) }
set event [lindex [epg fetch dump -service $service -event $event] 0]
if {$event eq ""} {
puts "Error, cannot find event to schedule."
exit
}
if {[$event percent] > 0} {
puts "Error, cannot record programme which has already started showing"
puts "or occurred in the past."
exit
}
$event get_channel_info
set args {}
set args(ersvtype) 3
set args(hsvc) [$event get channel_hsvc]
set args(nsttime) [$event get start]
set args(nduration) [$event get duration]
set args(usevtid) [$event get event_id]
set args(szevtname) "\025[$event get name]"
set args(eReady) 30
set ccrid [$event get channel_crid]
if {$type == 1} {
# Event
set args(ucCRIDType) 49
set args(ucRecKind) 1
set args(szCRID) "$ccrid[$event get event_crid]"
set args(szEventToRecord) "1$args(szCRID)|"
} else {
# Series
set args(ucCRIDType) 50
set args(ucRecKind) 4
set args(szCRID) "$ccrid[$event get series_crid]"
set args(szFPBRecPath) "$args(szevtname)"
set progs [lmap i [epg fetch dump -scrid [$event get series_crid]] {
if {[set ecrid [$i get event_crid]] eq ""} { continue }
list "1$::ccrid$ecrid"
}]
set args(szEventToRecord) "[join $progs "|"]|"
}
#puts $args
set msg ""
if {![file exists /mod/.schedule.testing]} { set msg "Disabled during testing" }
if {$msg ne "" || [catch {[rsv new $args] insert} msg]} {
puts "Error encountered while scheduling the recording: <i>$msg</i>"
} else {
puts "Successfully scheduled recording of <i>[$event get name]</i>"
close [open /tmp/.restartpending w]
}
epg cleanup

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} {
@@ -135,9 +95,14 @@ foreach record [lsort -command rsort $records] {
}
altrow
$record get_channel_info
puts "<td nowrap>
set ended [$record ended]
if $ended { puts "<td nowrap class=blood>" } else { puts "<td nowrap>"}
puts "
[clock format [$record get start] -format "%a %d %b %Y"]<br>
[clock format [$record get start] -format "%H:%M %Z"]</td>"
[clock format [$record get start] -format "%H:%M %Z"]"
puts "</td>"
puts "<td>[$record get channel_num]</td>"
puts "<td>[$record channel_icon 50]</td>"
puts "<td nowrap>
@@ -147,18 +112,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,12 +18,9 @@ source /mod/var/mongoose/html/lib/header.jim
cgi_input
#cgi_dump
source /mod/var/mongoose/lib/epg_popup
set service 0
set service 4351
catch { set service [dict get $_cgi service] }
require epg_popup
set service [cgi_get service 4351]
set records [epg fetch dump -service $service]
set tr [lindex $records 0]
@@ -56,21 +51,22 @@ puts {
set i 0
foreach record $records {
altrow
$record get_channel_info
set ended [$record ended]
if {[$record showing]} {
puts "<td><img src=/images/111_1_00_Cursor_2R_Arrow.png></td>"
} else { puts "<td></td>" }
puts "<td nowrap>
[clock format [$record get start] -format "%a %d %b %Y"]</td>"
puts "<td nowrap>
[clock format [$record get start] -format "%H:%M"]</td>"
if $ended { puts "<td nowrap class=blood>" } else { puts "<td nowrap>" }
puts "[clock format [$record get start] -format "%a %d %b %Y"]</td>"
if $ended { puts "<td nowrap class=blood>" } else { puts "<td nowrap>" }
puts "[clock format [$record get start] -format "%H:%M"]</td>"
puts [$record cell]
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

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

@@ -0,0 +1,29 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/setup
require pkg.class chunked
cgi_input
#cgi_dump
set cmd [cgi_get cmd update]
start_chunked
set bcmd "|/mod/var/mongoose/lib/opkg $cmd"
set fd [open $bcmd r]
while {[gets $fd line] >= 0} {
chunk "$line\r\n"
#chunk_pad
}
close $fd
if {$cmd eq "update"} {
chunk "Updating package meta information\r\n"
pkg fetchmeta
chunk "Done.\r\n"
}
end_chunked

98
var/mongoose/cgi-bin/pkg.jim Executable file
View File

@@ -0,0 +1,98 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/setup
require settings.class pkg.class altrow
if {[[settings] pkgdev]} { set filter 0 } else { set filter 1 }
puts "Content-Type: text/html"
puts "Pragma: no-cache"
puts "Expires: Thu, 01 Jan 1970 00:00:00 GMT"
puts ""
cgi_input
#cgi_dump
if {![dict exists $_cgi type]} { set _cgi(type) avail }
proc pkgrow {pkg} {
set name [$pkg get name]
altrow
puts "
<td nowrap>$name</td>
"
if {$::type eq "avail"} {
puts "<td nowrap>[$pkg get latest]</td>"
} else {
puts "<td nowrap>[$pkg get installed]</td>"
}
if {$::type eq "upgr"} {
puts "<td nowrap>[$pkg get latest]</td>"
}
if {[dict exists $::pkgmeta $name]} {
puts "<td>$::pkgmeta($name)</td>"
} else {
puts "<td>[$pkg get descr]</td>"
}
if {![$pkg is installed]} {
set type Install
} elseif {$::type eq "upgr" && [$pkg is upgradable]} {
set type Upgrade
} else {
set type Remove
}
puts "<td align=center><small><button id=\"[$pkg get name]\"
action=[string tolower $type]
class=[string tolower $type]>$type</button></small></td>"
puts "</tr>"
}
pkg loadmeta
set type $_cgi(type)
set pkgs [pkg $type]
if {[llength $pkgs] > 0} {
puts "<table><tr><th>Package</th>"
if {$type eq "avail"} {
puts "<th>Available</th>"
} else {
puts "<th>Installed</th>"
}
if {$type eq "upgr"} {
puts "<th>Avail</th>"
}
puts "
<th>Description</th>
<th>&nbsp;&nbsp;Action&nbsp;&nbsp;</th>
</tr>
"
foreach pkg $pkgs {
if {$filter && ![dict exists $::pkgmeta $pkg]} { continue }
pkgrow [pkg load $pkg]
}
puts "</table>"
if {$filter} {
puts "<font class=footnote>This is a filtered package list. To show all packages, enable the <i>Show development and advanced packages</i> in the settings screen.</font>"
}
} else {
puts "<i>No packages "
switch $type {
inst { puts "are installed." }
upgr { puts "are available for upgrade." }
avail { puts "are available for installation." }
}
puts "</i>"
}

View File

@@ -0,0 +1,57 @@
#!/mod/bin/jimsh
package require cgi
source /mod/var/mongoose/lib/setup
require rsv.class
puts "Content-Type: text/html"
puts ""
cgi_input
if {[cgi_get now] eq "yes"} {
# - Busybox reboot does sync the disk but may still not be clean enough.
puts "Restarting."
exec /etc/init.d/S90settop shut
exec /sbin/reboot
exit
}
file delete /tmp/.restartpending
header
# Commit pending reservations on older mod versions.
if {![file exists /sbin/rsvsync] && ![file exists /mod/boot/rsvsync]} {
rsv commit
}
puts {
<link href=/css/jquery.progressbar.css rel=stylesheet type=text/css />
<script type="text/javascript" src="/js/jquery.progressbar.js"></script>
<script type=text/javascript>
var handle = 0;
var pct = 0;
function update()
{
$('#progressbar').reportprogress(++pct);
if (pct == 100)
{
clearInterval(handle);
pct = 0;
window.location = '/';
}
}
$(document).ready(function() {
$('#progressbar').reportprogress(0);
handle = setInterval("update()", 300);
$.get('/cgi-bin/restart.jim?now=yes');
});
</script>
Please wait while the Humax restarts...<br>
<div id=progressbar></div>
}
footer

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 ""
@@ -12,10 +14,14 @@ cgi_input
set settings [settings new]
set hostname [$settings hostname]
set smtp_server [$settings smtp_server]
set channel_group [$settings channel_group]
set pkgdev [$settings pkgdev]
# Handle updates
if {![dict exists $env REQUEST_URI]} { set env(REQUEST_URI) "" }
proc _handle_update {class var old text} {
global _cgi
global settings
@@ -43,16 +49,22 @@ proc handle_str_update {var old {text "Value"}} {
}
handle_str_update hostname $hostname Hostname
_handle_update ascii smtp_server $smtp_server "SMTP Server"
handle_int_update channel_group $channel_group "Channel Group"
if {[dict exists $_cgi pkgdevoff] && ![dict exists $_cgi pkgdev]} {
set _cgi(pkgdev) 0
}
handle_int_update pkgdev $pkgdev "Development Package Display"
header
source /mod/var/mongoose/html/lib/header.jim
puts {<script type="text/javascript" src="/js/jquery.form.js"></script>}
puts {
<script type=text/javascript>
$(document).ready(function () {
$(":submit").button();
$('form').each(function(i, el) {
$('form.auto').each(function(i, el) {
var id = $(this).attr('id');
var output = '#' + id + '_output'
$(this).ajaxForm({
@@ -69,14 +81,26 @@ puts {
}
puts "
<h1>Settings</h1>
<table class=keyval>
<link href=/css/iphone-style-checkboxes.css rel=stylesheet type=text/css />
<script type=\"text/javascript\" src=\"/js/iphone-style-checkboxes.js\">
</script>
<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>
@@ -85,9 +109,10 @@ puts "
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]>
"
@@ -104,7 +129,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>
@@ -113,11 +140,63 @@ 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>
<br><br>
<fieldset style=\"display: inline\">
<legend> Advanced Settings </legend>
<table>
"
puts "
<tr>
<form class=auto id=pkgdev method=get action=$env(REQUEST_URI)>
<th class=key>Show development and advanced packages?</th>
<td><input name=pkgdevoff value=0 type=hidden>
<input name=pkgdev id=pkgdev value=1 type=checkbox
"
if {$pkgdev} { puts " checked" }
puts {
>
<small>
<input id=pkgdev_submit value="save" type=submit>
</small>
<div id=pkgdev_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,13 @@
#!/mod/bin/jimsh
set url "http://$env(HTTP_HOST):9091/"
puts "Content-Type: text/html
Location: $url
<meta http-equiv=refresh content=\"0; url=$url\">
Transmission is available <a href=$url>here</a>
"

View File

@@ -1,4 +1,4 @@
<!--#include virtual="/lib/header.shtml" -->
<!--#exec cmd="/mod/var/mongoose/include/db.jim" -->
<!--#include virtual="/lib/footer.shtml" -->
<!--#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: 150px;
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

@@ -0,0 +1,31 @@
/* progress bar container */
#progressbar{
border:1px solid black;
width:200px;
height:20px;
position:relative;
color:black;
}
/* color bar */
#progressbar div.progress{
position:absolute;
width:0;
height:100%;
overflow:hidden;
background-color:#369;
}
/* text on bar */
#progressbar div.progress .text{
position:absolute;
text-align:center;
color:white;
}
/* text off bar */
#progressbar div.text{
position:absolute;
width:100%;
height:100%;
text-align:center;
}

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

@@ -0,0 +1,21 @@
table.tablesorter .header {
background-image: url(/img/tsort/bg.png);
background-repeat: no-repeat;
border-left: 1px solid #FFF;
border-right: 1px solid #000;
border-top: 1px solid #FFF;
padding-left: 30px;
padding-top: 8px;
height: auto;
}
table.tablesorter .headerSortUp {
background-image: url(/img/tsort/asc.png);
background-repeat: no-repeat;
}
table.tablesorter .headerSortDown {
background-image: url(/img/tsort/desc.png);
background-repeat: no-repeat;
}

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

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>
@@ -39,7 +41,7 @@ $(document).ready(function() {
</a>
<br>
<a href=/sched.shtml>
<b>Scheduled Recordings</b>
<b>Scheduled Events</b>
</a>
<br>
</center>
@@ -56,8 +58,11 @@ $(document).ready(function() {
<br>
</center>
</div>
</div>
<div style="float: left; clear: left">
<div style="clear: both; padding-top: 1em">
<div style="float: left">
<center>
<a href=/services.shtml>
<img src=/img/spanner.jpg border=0 width=217 height=228>
@@ -72,11 +77,11 @@ $(document).ready(function() {
<div style="float: left">
<center>
<a href=/packages.shtml>
<a href=/pkg.shtml>
<img src=/img/packages.jpg border=0 width=217 height=228>
</a>
<br>
<a href=/packages.shtml>
<a href=/pkg.shtml>
<b>Package Management</b>
</a>
<br>
@@ -97,13 +102,16 @@ $(document).ready(function() {
</center>
</div>
</div>
<div style="clear: both">
<!--#exec cmd="/mod/var/mongoose/include/mediatomb.jim" -->
<!--#exec cmd="/mod/var/mongoose/include/transmission.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>
<a href=/cgi-bin/db.jim target=_blank>SQLite3 Database Dump</a>
</li><li>
<a href=/jim/ref.html target=_blank>Jim Reference Manual</a> |
<a href=/jim/oo.html target=_blank>OO</a> |

View File

@@ -0,0 +1,50 @@
jQuery.ajaxPrefilter(function(options, _, jqXHR) {
if (jQuery.isFunction(options.progress)) {
var xhrFactory = options.xhr,
interval;
options.xhr = function() {
var xhr = xhrFactory.apply(this, arguments),
partial = "",
prevcount = 1;
interval = setInterval(function() {
var responseText,
jQueryPartial;
try {
responseText = xhr.responseText;
if (responseText && (responseText.length > partial.length))
{
partial = responseText;
jQueryPartial = $(partial).filter("*")
if (jQueryPartial.length > prevcount) {
prevcount = jQueryPartial.length;
options.progress(jQueryPartial.filter("*:not(:last)"));
}
}
} catch(e) {
alert(e);
}
}, options.progressInterval);
return xhr;
};
function stop()
{
if (interval)
clearInterval(interval);
}
jqXHR.then(stop, stop);
}
});

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

@@ -13,8 +13,9 @@
// (C)2008 by Cory S.N. LaViska.
//
// For details, visit http://creativecommons.org/licenses/by/3.0/us/
//
// Modified 11NOV08 By Bill Beckelman to include option to use left mouse button instead.
// Modified by Andy Fiddaman to support left click and
// support modification of menu items.
if (jQuery) (function() {
$.extend($.fn, {
@@ -25,6 +26,7 @@ if (jQuery) (function() {
if (o.inSpeed == undefined) o.inSpeed = 150;
if (o.outSpeed == undefined) o.outSpeed = 75;
if (o.leftButton == undefined) o.leftButton = false;
if (o.beforeShow == undefined) o.beforeShow = false;
// 0 needs to be -1 for expected results (no fade)
if (o.inSpeed == 0) o.inSpeed = -1;
if (o.outSpeed == 0) o.outSpeed = -1;
@@ -34,8 +36,8 @@ if (jQuery) (function() {
var offset = $(el).offset();
// Add contextMenu class
$('#' + o.menu).addClass('contextMenu');
if (o.leftButton) $(this).bind('click', false);
// Simulate a true right click
$(this).bind('click', false);
$(this).mousedown(function(e) {
var evt = e;
$(this).mouseup(function(e) {
@@ -49,6 +51,8 @@ if (jQuery) (function() {
if ($(el).hasClass('disabled')) return false;
if (o.beforeShow) o.beforeShow(el, menu);
// Detect mouse position
var d = {}, x, y;
if (self.innerHeight) {
@@ -185,6 +189,15 @@ if (jQuery) (function() {
return ($(this));
},
// Change context menu text on the fly
changeContextMenuItem: function(d, t) {
if (d == undefined) return;
$(this).each(function() {
$(this).find('A[href="' + d + '"]').text(t);
});
return ($(this));
},
// Disable context menu(s)
disableContextMenu: function() {
$(this).each(function() {

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,54 @@
/*
* Copyright (c) 2007 Josh Bush (digitalbush.com)
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* Progress Bar Plugin for jQuery
* Version: Alpha 2
* Release: 2007-02-26
*/
(function($) {
//Main Method
$.fn.reportprogress = function(val,maxVal) {
var max=100;
if(maxVal)
max=maxVal;
return this.each(
function(){
var div=$(this);
var innerdiv=div.find(".progress");
if(innerdiv.length!=1){
innerdiv=$("<div class='progress'></div>");
div.append("<div class='text'>&nbsp;</div>");
$("<span class='text'>&nbsp;</span>").css("width",div.width()).appendTo(innerdiv);
div.append(innerdiv);
}
var width=Math.round(val/max*100);
innerdiv.css("width",width+"%");
div.find(".text").html(width+" %");
}
);
};
})(jQuery);

File diff suppressed because one or more lines are too long

View File

@@ -16,6 +16,9 @@ puts {
}
source /mod/var/mongoose/html/lib/topbar.jim
puts "<div id=restart_block>"
source /mod/var/mongoose/include/restart.jim
puts "</div>"
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,9 @@
<body>
<!--#include virtual="/lib/topbar.shtml" -->
<div id=restart_block>
<!--#exec cmd="/mod/var/mongoose/include/restart.jim" -->
</div>
<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,14 +0,0 @@
<!--#include virtual="/lib/header.shtml" -->
<h1>Package Management</h1>
<div id=results class=shadowbox style="width: 90%; display: none; margin: 1 0 1em 0">
<div>
<pre id=result_txt>
Results...
</pre>
</div>
</div>
<!--#exec cmd="/mod/var/mongoose/include/packages.jim" -->
<!--#include virtual="/lib/footer.shtml" -->

141
var/mongoose/html/pkg.shtml Normal file
View File

@@ -0,0 +1,141 @@
<!--#include virtual="/lib/header.shtml" -->
<style type=text/css>
button.install
{
display: none;
background-image: none;
background: #ccff99;
}
button.remove
{
display: none;
background-image: none;
background: #ff6666;
}
button.upgrade
{
display: none;
}
</style>
<div class=va style="padding: 0 0 1em 0">
<h1 style="display: inline" class=va>Package Management</h1>
<small>
<button class=va id=opkgupdate style="display: none">
Update package list from Internet
</button>
</small>
</div>
<div id=results class=shadowbox
style="width: 90%; display: none; margin: 1 0 1em 0">
<div>
<pre id=result_txt>
Updating package list...
</pre>
</div>
</div>
<div id=dialogue style="display: none; align: center">
<pre id=dresults></pre>
<div id=dspinner><img border=0 src=/img/loading.gif>Processing request...</div>
</div>
<script type=text/javascript src=/js/iajax.js></script>
<script type=text/javascript>
var opkg = '/cgi-bin/opkg.jim?cmd=';
$(document).ready(function() {
$('#opkgupdate')
.button()
.click(function() { execopkg('update'); })
.fadeIn('slow');
$('#pkgtabs').tabs({
load: setup_buttons,
spinner: '<img border=0 src=/img/loading.gif> ' +
'<em>Loading...</em>'
});
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); }
});
jQuery.ajaxSetup({progressInterval: 1});
function loaddata(data, isfinal)
{
console.log('loaddata called, final=' + isfinal);
console.log('Data: ' + data);
$('#dresults').append(data);
if (isfinal)
$('#dspinner').hide('slow');
}
function execopkg(arg)
{
$('#dspinner').show();
$dialog.dialog('open');
$('#dresults').empty();
$.ajax({
type: "GET",
url: opkg + arg,
progress: loaddata,
success: function(data) {
console.log("ajax success");
loaddata(data, true);
},
error: function(_, _, e) {
console.log("ajax error");
alert(e);
}
});
}
function setup_buttons()
{
$('button.remove, button.install, button.upgrade')
.button()
.click(function() {
if ($(this).attr('action') == 'remove' &&
!confirm('Please confirm removal of the ' +
$(this).attr('id') + ' package.'))
return;
execopkg(encodeURIComponent($(this).attr('action') +
' ' + $(this).attr('id')));
}).fadeIn('slow');
}
});
</script>
<div id=pkgtabs>
<ul>
<li>
<a href=/cgi-bin/pkg.jim?type=inst>
<span>Installed</span>
</a>
</li><li>
<a href=/cgi-bin/pkg.jim?type=upgr>
<span>Upgrades</span>
</a>
</li><li>
<a href=/cgi-bin/pkg.jim?type=avail>
<span>Available</span>
</a>
</li>
</ul>
</div>
<!--#include virtual="/lib/footer.shtml" -->

View File

@@ -1,4 +1,6 @@
<!--#include virtual="/lib/header.shtml" -->
<script type="text/javascript" src="/js/jquery.tablesorter.js"></script>
<link type=text/css href=/css/tsort.css rel=Stylesheet />
<!--#exec cmd="/mod/var/mongoose/include/sched.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>

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

@@ -0,0 +1,66 @@
#!/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=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,43 +0,0 @@
#!/mod/bin/jimsh
package require sqlite3
source /mod/var/mongoose/lib/altrow
proc db_info {db_file} {
set db [sqlite3.open $db_file]
set tables [$db query {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}]
puts "<h1>$db_file</h1>"
foreach table $tables {
set table_name [lindex $table 1]
set columns [$db query "pragma table_info($table_name)"]
set datas [$db query "SELECT * FROM $table_name"]
puts "<h2>$table_name</h2>"
puts "<table>"
puts " <tr>"
foreach column $columns {
puts " <th>[lindex $column 3]</th>"
}
puts " </tr>"
foreach data $datas {
altrow
for {set i 1} {$i < [llength $data]} {incr i 2} {
puts " <td>[lindex $data $i]</td>"
}
puts " </tr>"
}
puts "</table>"
}
$db close
}
puts {<style type="text/css">table, td, th {border-collapse:collapse; border:1px solid black;}</style>}
db_info /var/lib/humaxtv/rsv.db
db_info /var/lib/humaxtv/setup.db
db_info /var/lib/humaxtv/channel.db

View File

@@ -1,30 +1,49 @@
#!/mod/bin/jimsh
if {[os.gethostname] eq "hosting"} {
set size "1TB"
set used "100GB"
set perc "10"
} else {
foreach df [split [exec df -h] "\n\r"] {
if [string match *sd*2* $df] {
regsub -all -- {[[:space:]]+} $df " " df
set fields [split $df]
set size [lindex $fields 1]
set used [lindex $fields 2]
set perc [string trimright [lindex $fields 4] "%"]
}
proc extract {line} {
regsub -all -- {[[:space:]]+} $line " " line
set fields [split $line]
set ::size [lindex $fields 1]
set ::used [lindex $fields 2]
set ::perc [string trimright [lindex $fields 4] "%"]
}
set used 0
set size 0
set perc 0
foreach df [split [exec df -h 2>>/dev/null] "\n\r"] {
if {[string match *sd?2* $df]} {
extract $df
break;
}
if {[string match *media/drive? $df]} {
extract $df
}
}
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 border=0 src=/img/mediatomb.png width=180>
</a>
<br>
<a href=$url>
<b>MediaTomb</b>
</a>
<br>
</center>
</div>
"

View File

@@ -1,54 +0,0 @@
#!/mod/bin/jimsh
# Build a list of available packages
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>"
}
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>"
} else {
puts "<img src=/img/off.png>"
}
puts "</td>"
puts "<td>$name</td>"
puts "<td>$ver</td>"
puts "<td>$descr</td>"
puts "</tr>"
}
puts "</table>"

46
var/mongoose/include/pkg.jim Executable file
View File

@@ -0,0 +1,46 @@
#!/mod/bin/jimsh
source /mod/var/mongoose/lib/setup
puts {
<script type=text/javascript src=/js/packages.js></script>
<style type=text/css>
button.install
{
display: none;
background-image: none;
background: #ccff99;
}
button.remove
{
display: none;
background-image: none;
background: #ff6666;
}
button.upgrade
{
display: none;
}
</style>
<div id=pkgtabs>
<ul>
<li>
<a href=/cgi-bin/pkg.jim?type=inst>
<span>Installed</span>
</a>
</li><li>
<a href=/cgi-bin/pkg.jim?type=upgr>
<span>Upgrades</span>
</a>
</li><li>
<a href=/cgi-bin/pkg.jim?type=avail>
<span>Available</span>
</a>
</li>
</ul>
</div>
}

View File

@@ -0,0 +1,45 @@
#!/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 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?'))
window.location = '/cgi-bin/restart.jim';
});
</script>
}
}

View File

@@ -1,62 +1,86 @@
#!/mod/bin/jimsh
package require sqlite3
source /mod/var/mongoose/lib/setup
require altrow rsv.class progressbar
source /mod/var/mongoose/lib/altrow
puts {
<script type=text/javascript>
set db [sqlite3.open /var/lib/humaxtv/rsv.db]
$db query {attach database '/var/lib/humaxtv/channel.db' as channel}
$.tablesorter.addParser({
id: 'programme',
is: function () { return false; },
format: function(s) {
return s.toLowerCase().replace(/---/, 'zzz');
},
type: 'text'
});
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
}]
$.tablesorter.addParser({
id: 'date',
is: function () { return false; },
format: function(s) {
var d = new Date(s.substring(0, s.length - 4));
return d.getTime();
},
type: 'numeric'
});
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 ""
$(document).ready(function() {
$('table.tablesorter').tablesorter({
headers: {
1: { sorter: false },
3: { sorter: 'programme' },
4: { sorter: 'date' },
5: { sorter: 'date' },
5: { sorter: false },
6: { sorter: false },
7: { sorter: false }
}
});
});
</script>
}
proc eventheader {} {
puts {
<table class="borders tablesorter">
<thead>
<tr>
<th></th>
<th>&nbsp;</th><th>Channel</th>
<th>Programme</th>
<th>Start Time</th>
<th>Duration</th>
<th>Mode</th>
<th>Event/Series ID</th>
<th>Events</th>
</tr>
</thead>
<tbody>
}
}
proc eventrow {event} {
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 +90,123 @@ 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>&nbsp;<br><br></td><td>&nbsp;</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>"
if {[$event get aulEventToRecordInfo] != ""} {
puts "<td>*</td>"
}
puts "</tr>"
}
puts "</table>"
puts "<font class=footnote>Click on the CRID to view episodes.</font>"
$db close
proc eventfooter {} {
puts "</tbody></table>"
}
set events [rsv list pending]
if {[llength $events] > 0} {
puts "<h2>Pending Scheduled Events</h2>"
eventheader
foreach event $events {eventrow $event}
eventfooter
puts {
<small>
<button onclick="window.location='/cgi-bin/db.jim?db=rsvp.db&tab=pending';">
Raw database view
</button>
</small>
}
}
puts "<h2>Scheduled Events</h2>"
set events [rsv list]
eventheader
foreach event $events {eventrow $event}
eventfooter
puts {
<small>
<button onclick="window.location='/backup.shtml';">
Backup/Restore Scheduled Recordings/Events
</button>
<button onclick="window.location='/cgi-bin/db.jim?db=rsv.db&tab=TBL_RESERVATION';">
Raw database view
</button>
<script type=text/javascript>
$('button').button();
</script>
}

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

@@ -0,0 +1,21 @@
#!/mod/bin/jimsh
if {![file exists /mod/sbin/transmission-daemon]} { exit 0 }
set url "/cgi-bin/transmission.jim"
puts "
<div style=\"float: left; padding-top: 5em\">
<center>
<a href=$url>
<img border=0 src=/img/transmission.png>
</a>
<br>
<a href=$url>
<b>Transmission</b>
</a>
<br>
</center>
</div>
"

21
var/mongoose/lib/chunked Executable file
View File

@@ -0,0 +1,21 @@
proc chunk {chk} {
puts -nonewline [format "%x\r\n" [string length $chk]]
puts -nonewline "$chk\r\n"
flush stdout
}
proc chunk_pad {{len 256}} {
incr len
chunk [string range [format "%${len}d" 0] 1 end-1]
}
proc start_chunked {{type "text/html"}} {
puts -nonewline "Content-Type: $type\r\n"
puts -nonewline "Transfer-Encoding: chunked\r\n\r\n"
}
proc end_chunked {} {
puts -nonewline "0\r\n\r\n\r\n"
}

View File

@@ -1,14 +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 }
require settings.class progressbar rsv.class
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] }
set ::rsvlookup [rsv lookuptab]
# * service_id, event_id, start, duration, encrypted, name, text
# * warning, content code, content type,
@@ -32,6 +38,10 @@ class epg {
channel_num 0
channel_name ""
channel_crid ""
channel_hsvc 0
sched_type 0
rsv 0
}
epg method _parse {line} {
@@ -60,8 +70,15 @@ epg method percent {} {
}
epg method showing {} {
set percent [$self percent]
if {$percent > 0 && $percent < 100} { return 1 } else { return 0 }
set now [clock seconds]
if {$start > $now} { return 0 }
if {$start + $duration < $now} { return 0 }
return 1
}
epg method ended {} {
if {$start + $duration < [clock seconds]} { return 1 }
return 0
}
epg method elapsed {} {
@@ -77,7 +94,7 @@ epg method remaining {} {
epg method type_icon {} {
set img ""
switch -- [$self get content_code] {
switch -- $content_code {
1 { set img "Movie" }
2 { set img "News" }
3 { set img "Show" }
@@ -105,7 +122,7 @@ proc {epg channelicon} {name {width 0} {style ""}} {
}
epg method channel_icon {{width 0} {style ""}} {
set str "<img src=\"/img/channels/[$self get channel_name].png\"";
set str "<img src=\"/img/channels/$channel_name.png\"";
if {$width > 0} { append str " width=$width" }
if {$style ne ""} { append str " style=\"$style\" }
append str " alt=\"\">"
@@ -117,13 +134,38 @@ epg method get_channel_info {} {
if {!$channel_num && $channeldb != ""} {
set chan [lindex [$channeldb query {
select szSvcName, usLcn, aucDefaultAuthority
select szSvcName, usLcn, aucDefaultAuthority, hsvc
from TBL_SVC
where usSvcId = %s} "[$self get service_id]"
where usSvcId = %s} $service_id
] 0]
set channel_num $chan(usLcn)
set channel_name [string range $chan(szSvcName) 1 end]
set channel_crid [string toupper $chan(aucDefaultAuthority)]
if {[dict exists $chan usLcn]} {
set channel_num $chan(usLcn)
set channel_name [string range $chan(szSvcName) 1 end]
set channel_crid [string toupper $chan(aucDefaultAuthority)]
set channel_hsvc $chan(hSvc)
}
}
}
epg method get_rsv {} {
if {$hsvc == 0} { $self get_channel_info }
if {$hsvc == 0} { return }
if {$rsv == 0 && $event_crid ne ""} {
set rsv [rsv entry $event_crid $hsvc]
}
if {$rsv == 0 && $series_crid ne ""} {
set rsv [rsv entry $series_crid $hsvc]
}
}
epg method process_sched {} {
set sched_type 0
if {$event_crid ne "" && "$channel_hsvc$event_crid" in $::rsvlookup} {
set sched_type 1
} elseif {$series_crid ne "" &&
"$channel_hsvc$series_crid" in $::rsvlookup} {
set sched_type 2
}
}
@@ -133,40 +175,55 @@ epg method icon_set {{height 0}} {
set set ""
if {$icon != ""} {
lappend set "<img src=$icon $height
alt=\"[$self get content_type]\"
title=\"[$self get content_type]\">"
alt=\"$content_type\" title=\"$content_type\">"
}
if {[$self get rec_crid] != ""} {
$self process_sched
if {$sched_type == 1} {
lappend set \
"<img src=/images/178_1_26_Icon_Recommend.png $height>"
"<img src=/images/175_1_11_Reservation_Record.png $height>"
}
if {[$self get series_crid] != ""} {
if {$sched_type == 2} {
lappend set \
"<img src=/images/175_1_11_Series_Record.png $height>"
} elseif {$series_crid ne ""} {
lappend set \
"<img src=/images/178_1_00_Icon_Serise.png $height>"
}
if {$rec_crid ne ""} {
lappend set \
"<img src=/images/178_1_26_Icon_Recommend.png $height>"
}
return $set
}
epg method cell {} {
set name [$self get name]
set text [$self get text]
set percent [$self percent]
puts "<td nowrap valign=top title=\"$text\">"
puts [join [$self icon_set 14] ""]
if {$series_crid ne ""} {
set recopts 2
} else {
set recopts 1
}
puts "
<a class=event href=# xs=[$self get service_id]
xe=[$self get event_id]>
$name</a>"
<a class=event href=# xs=$service_id xe=$event_id
sch=$sched_type rec=$recopts>
$name</a>
"
puts "<br>"
puts "<font class=footnote>"
puts "[clock format [$self get start] -format %H:%M]"
puts " ([clock format [$self get duration] -format %T])"
puts "[clock format $start -format %H:%M]"
puts " ([clock format $duration -format %T])"
if {$percent > 0 && $percent < 100} {
puts "<br>[progressbar $percent]"
puts "$percent% [clock format [$self elapsed] -format %T] /
@@ -177,8 +234,8 @@ epg method cell {} {
}
epg method next {} {
set tm [expr [$self get start] + [$self get duration] + 60]
set nextlist [epg fetch dump -service [$self get service_id] -time $tm]
set tm $($start + $duration + 60)
set nextlist [epg fetch dump -service $service_id -time $tm]
if {[llength nextlist] > 0} {
return [lindex $nextlist 0]
@@ -189,13 +246,25 @@ epg method next {} {
epg method recommended {} {
set rec ""
if {[$self get rec_crid] != ""} {
if {$rec_crid ne ""} {
catch { set rec [lindex [
epg fetch dump -crid [$self get rec_crid]] 0] }
epg fetch dump -crid $rec_crid] 0] }
}
return $rec
}
epg method othertimes {} {
if {$event_crid eq ""} { return "" }
set others ""
foreach other [epg fetch dump -crid $event_crid] {
if {[$other get service_id] == $service_id &&
[$other get event_id] == $event_id} { continue }
lappend others $other
}
return $others
}
proc {epg parse} {line} {
set e [epg new]
$e _parse $line
@@ -210,7 +279,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} {
@@ -222,6 +291,7 @@ proc {epg exec} {mode args} {
-service { lappend cmd -S $args($arg) }
-event { lappend cmd -E $args($arg) }
-time { lappend cmd -@ $args($arg) }
-day { lappend cmd -/ $args($arg) }
-extra { set extra $args($arg) }
default { error "Invalid option, $arg" }
}
@@ -259,3 +329,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
}

View File

@@ -1,27 +1,70 @@
puts {
<div id=dialogue></div>
<script type=text/javascript>
$(document).ready(function() {
var $dialog = $('#dialogue').dialog({
title: "Programme Details",
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) { $('#dialogue').empty().html(
'<img src="/img/loading.gif" alt="loading">'); }
});
$('a.event').click(function(e) {
e.preventDefault();
var url = '/cgi-bin/epg_info.jim?service=' +
$(this).attr('xs') + '&event=' +
$(this).attr('xe') + '&bare=1';
$('#dialogue').load(url);
$dialog.dialog('open');
$(document).ready(function() {
function doschedule(type)
{
$('#epginfo_extra').load('/cgi-bin/epg_schedule.jim?' +
'service=' +
encodeURIComponent($('#dialogue').attr('xs')) +
'&event=' +
encodeURIComponent($('#dialogue').attr('xe')) +
'&type=' + type, function() {
$('#restart_block')
.load('/cgi-bin/restartblock.jim');
});
$(":button:contains('Record')").fadeOut('slow');
}
var $buttons1 = {
"Close" : function() {$(this).dialog('close');}
};
var $buttons2 = $.extend(
{"Record Programme": function() { doschedule(1) }},
$buttons1);
var $buttons3 = $.extend(
{"Record Series": function() { doschedule(2) }},
$buttons2);
var $dialog = $('#dialogue').dialog({
title: "Programme Details",
modal: false, autoOpen: false,
height: 500, width: 700,
show: 'scale', hide: 'fade',
draggable: true, resizable: true,
buttons: $buttons1,
close: function(e,u) { $('#dialogue').empty().html(
'<img src="/img/loading.gif" alt="loading">'); }
});
function epgpopup(e, o)
{
e.preventDefault();
var sch = o.attr('sch');
var rec = o.attr('rec');
if (sch != 0)
$dialog.dialog("option", "buttons", $buttons1);
else if (rec == 2)
$dialog.dialog("option", "buttons", $buttons3);
else if (rec == 1)
$dialog.dialog("option", "buttons", $buttons2);
else
$dialog.dialog("option", "buttons", $buttons1);
var url = '/cgi-bin/epg_info.jim?service=' +
o.attr('xs') + '&event=' +
o.attr('xe') + '&bare=1';
$('#dialogue').load(url, function() {
$('#dialogue a.event').click(function(e) {
epgpopup(e, $(this));
});
});
$('#dialogue')
.attr('xs', o.attr('xs'))
.attr('xe', o.attr('xe'));
$dialog.dialog('open');
}
$('a.event').click(function(e) { epgpopup(e, $(this)) });
});
</script>
}

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

@@ -0,0 +1,124 @@
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><td><a href=/epg.shtml>Now/Next</a>"
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>
}

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

@@ -0,0 +1,14 @@
#!/bin/sh
if [ -x /mod/bin/ffprobe ]; then
/mod/bin/ffprobe "$@" 2>&1 | sed '
1,10d
'
else
/mod/bin/ffmpeg "$@" 2>&1 | sed '
1,8d
$d
'
fi
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 "$@" 2>&1
exit 0

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

@@ -0,0 +1,103 @@
if {[expr ! [exists -proc class ]]} { package require oo }
class pkg {
name ""
latest ""
descr ""
installed ""
}
set ::pkgmeta {}
pkg method _load {nm} {
set name $nm
set info [join [split [exec /bin/opkg list $nm] "\n"] " "]
regexp {^([^ ]+) - ([^ ]+) - (.*)$} $info full xname latest descr
set info [exec /bin/opkg list-installed $nm]
regexp {^([^ ]+) - ([^ ]+)$} $info full xname installed
return $self
}
proc {pkg load} {nm} {
return [[pkg] _load $nm]
}
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 avail} {} {
set inst_pkgs [pkg inst]
set avail_pkgs {}
foreach pkg [split [exec /bin/opkg list] "\n"] {
if [regexp {^ } $pkg] { continue }
if {[regexp {^([^ ]+)} $pkg name] == 0} { continue }
if {$name ni $inst_pkgs} { lappend avail_pkgs $name }
#puts "New: $name<br>"
}
return $avail_pkgs
}
proc {pkg inst} {} {
# 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 upgr} {} {
#webif - 0.5.3 - 0.5.7
set upgr_pkgs {}
foreach pkg [split [exec /bin/opkg list-upgradable] "\n"] {
if {[regexp {^([^ ]+)} $pkg name] == 0} { continue }
lappend upgr_pkgs $name
#puts "Upgr: $name<br>"
}
return $upgr_pkgs
}
proc {pkg loadmeta} {} {
if {[llength $::pkgmeta]} { return }
if {![file exists "/mod/var/pkg.meta"]} {
pkg fetchmeta
} else {
set meta [open "/mod/var/pkg.meta" r]
set ::pkgmeta [read $meta]
$meta close
}
}
proc {pkg fetchmeta} {} {
set f [socket stream hummypkg.org.uk:80]
$f puts -nonewline "GET /pkg.meta HTTP/1.1\r\n"
$f puts -nonewline "Host: hummypkg.org.uk\r\n"
$f puts -nonewline "\r\n"
set line [string trim [$f gets]]
while {[string length $line]} {
set line [string trim [$f gets]]
}
set ::pkgmeta [$f read]
$f close
set ff [open "/mod/var/pkg.meta" w]
puts $ff $::pkgmeta
$ff close
}

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

@@ -0,0 +1,9 @@
proc eval_plugins {hook} {
foreach plugin [glob -nocomplain /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]"
}
}

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

@@ -0,0 +1,210 @@
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}
if {![file exists /var/lib/humaxtv/rsvp.db]} {
file copy /var/lib/humaxtv/rsv.db /var/lib/humaxtv/rsvp.db
set tdb [sqlite3.open /var/lib/humaxtv/rsvp.db]
$tdb query {drop table TBL_VERSION}
$tdb query {alter table TBL_RESERVATION rename to pending}
$tdb query {delete from pending}
$tdb close
}
$rsvdb query {attach database '/var/lib/humaxtv/rsvp.db' as pending}
class rsv {
ulslot -1
ersvtype 0
hsvc 0
nsttime 0
szsttime "00000000000000"
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 clear_ulslot {} {
set ulslot -1
}
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 ---" }
11 { set name "--- DSO Event? ---" }
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 {{table pending}} {
global rsvdb
# Find a spare slot.
if {$ulslot < 0} {
set slotlist [$rsvdb query "
select ulslot FROM $table
order by ulslot;
"]
if {[llength $slotlist] > 0} {
set slots [lmap i $slotlist {lindex $i 1}]
set max [lindex $i end]
for {set i 0} {$i < $max} {incr i} {
if {$i ni $slots} {
set ulslot $i
break
}
}
if {$ulslot < 0} { set ulslot $($max + 1) }
}
if {$ulslot < 0} { set ulslot 0 }
}
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 {
# Escape any quotes embedded in the data.
regsub -all {'} [$self get $field] {''} f
lappend vals "'$f'"
#lappend vals "'[$self get $field]'"
}
set query "insert into ${table}("
append query [join $fields ","]
append query ") values("
append query [join $vals ","]
append query ");"
$rsvdb query $query
}
proc {rsv list} {{table tbl_reservation}} {
set res [$::rsvdb query "
select $table.*,
channel.TBL_SVC.szSvcName, channel.TBL_SVC.usLcn,
case when ersvtype > 3 then 1 else 0 end as sort
from $table
left join channel.TBL_SVC
on $table.hSvc = channel.TBL_SVC.hSvc
order by sort, nsttime
"]
set records {}
foreach rec $res {
lappend records [rsv new $rec]
}
return $records
}
proc {rsv lookuptab} {} {
set records {}
foreach tab {tbl_reservation pending} {
set res [$::rsvdb query "
select $tab.szCRID, channel.TBL_SVC.hSvc
from $tab left join channel.TBL_SVC
on $tab.hSvc = channel.TBL_SVC.hSvc
where ersvtype <= 3
"]
foreach rec $res {
lappend records "$rec(hSvc)/[file tail $rec(szCRID)]"
}
}
return $records
}
proc {rsv entry} {{table TBL_RESERVATION} crid svc} {
set res [$::rsvdb query "
select $table.*,
channel.TBL_SVC.szSvcName, channel.TBL_SVC.usLcn
from $table
left join channel.TBL_SVC
on $table.hSvc = channel.TBL_SVC.hSvc
where szCRID like '%%%s' and $table.hsvc = '%s'
" $crid $svc]
if {[llength $res] > 0} {
return [rsv new [lindex $res 0]]
}
return 0
}
proc {rsv cleanup} {} {
catch {$::rsvdb close}
}
proc {rsv commit} {} {
$::rsvdb query {begin transaction}
foreach rec [rsv list pending] {
$rec clear_ulslot
$rec insert TBL_RESERVATION
}
$::rsvdb query {delete from pending}
$::rsvdb query {commit transaction}
}

View File

@@ -1,12 +1,26 @@
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]
if {![file exists /mod/etc/webif.db]} {
set settingsdb [sqlite3.open /mod/etc/webif.db]
catch {
$settingsdb query {
CREATE TABLE settings(name text, nval int, tval text);
}
$settingsdb query {
CREATE UNIQUE INDEX key on settings(name);
}
}
} else {
set settingsdb [sqlite3.open /mod/etc/webif.db]
}
class settings {
hostname ""
channel_group 0
smtp_server ""
pkgdev 0
}
settings method hostname {{name ""}} {
@@ -30,6 +44,34 @@ settings method hostname {{name ""}} {
}
}
settings method smtp_server {{server ""}} {
if {$server == ""} {
# Get
if {[catch {set fd [open "/mod/etc/ssmtp/ssmtp.conf" r]}]} {
set server "mail"
} else {
foreach line [split [read $fd] "\n"] {
set a [string first "mailhub=" $line]
if {$a == 0} {
set server [string range $line 8 end]
set server [string trim $server]
}
}
close $fd
}
return $server
} else {
# Set
if {[string is ascii -strict $server]} {
set fd [open "/mod/etc/ssmtp/ssmtp.conf" w]
puts $fd "mailhub=$server"
puts $fd "rewriteDomain=hummypkg.org.uk"
puts $fd "hostname=[$self hostname].hummypkg.org.uk"
close $fd
}
}
}
settings method _nval_setting {name {val -1}} {
global settingsdb;
@@ -57,6 +99,10 @@ settings method channel_group {{group -1}} {
return [$self _nval_setting channel_group $group]
}
settings method pkgdev {{val -1}} {
return [$self _nval_setting pkgdev $val]
}
settings method channel_groups {} {
set ret ""
set db [sqlite3.open /var/lib/humaxtv/setup.db]

Some files were not shown because too many files have changed in this diff Show More