webif/webif/html/browse/index.jim

473 lines
11 KiB
Tcl
Executable File

#!/mod/bin/jimsh
package require cgi
source /mod/webif/lib/setup
require ts.class pretty_size system.class settings.class browse.class \
plugin epg.class classdump queue.class
set mroot [system mediaroot]
set dir [cgi_get dir $mroot]
jqplugin contextMenu bar enadis blockui dialogue
jscss script.js style.css
if {[system has tvdb]} { jscss tvdb/script.js tvdb/style.css }
set plugins { dmenu {} menu {} omenu {} buttons {} }
eval_plugins browse
header
set nicesplice [system pkginst nicesplice]
set ignore {.nts .thm .hmi}
set include {.ts .avi .mpg .mpeg .wmv .mkv .mp3 .mp4 .mov .hmt .m4v .m4a .webm}
if {![dict exists $env SCRIPT_NAME]} {
set env(SCRIPT_NAME) ""
cgi_input
set _cgi(dir) "/media/My Video/"
}
if {![dict exists $env QUERY_STRING]} { set env(QUERY_STRING) "root" }
set dir [string map [list "\{root\}" $mroot] $dir]
set config [settings new]
set order [cgi_get order -]
if {$order eq "-"} {
set order [$config sortorder]
} else {
$config sortorder $order
}
set nofcount [$config nounwatchedcount]
set nounderscore [$config nounderscore]
set model [system model]
set dustbin [system dustbin 1]
set dlnaok [system dlnastatus]
proc icon {img {hover ""} {extra ""} {class "va"}} {
puts -nonewline "<img src=\"$img\" class=\"$class\" height=21 $extra"
if {$hover ne ""} {
puts -nonewline " alt=\"$hover\" title=\"$hover\""
}
puts ">"
}
proc directory {file bfile tbfile} {
puts "<div class=\"va relative\">"
set img "/images/711_1_09_Media_Folder.png"
if {$bfile eq $::dustbin} { set img "/img/Dustbin_Folder.png" }
puts "<img border=0 class=va id=\"img$tbfile\" src=$img>"
if {!$::nofcount} { puts "<span class=foldernum></span>" }
if {!$::nounderscore} { puts "<span class=folderu>_</span>" }
puts "<input class=\"fs fsdir\" type=checkbox>"
puts "<a class=dbf
href=\"$::env(SCRIPT_NAME)?dir=[cgi_quote_url $file]\"
file=\"[cgi_quote_html $file]\">"
puts "$bfile</a><span class=filesize id=\"$tbfile\">
</span>"
lassign [dir iconset $file] icons attrs
puts "<span class=iconset>"
puts [join $icons ""]
puts "</span>"
if {[string first $::mroot $file] >= 0} {
set class dopt
} else {
set class doopt
}
puts -nonewline "
<a href=#>
<img class=\"$class va\" border=0 width=45 "
puts -nonewline [join $attrs " "]
puts "
src=/images/181_1_00_Help5_OPT_Plus.png>
</a>
"
puts "
<div class=\"results blood\" style=\"margin: 0 0 0 5em\"></div>
"
puts "</div>"
}
set dircount 0
set filecount 0
proc entry {file} {{i 0}} {
global dircount filecount dinuse
set bfile [file tail $file]
regsub -all " +" $bfile "" tbfile
if {[string index $bfile 0] == "\025"} {
set bfile [string range $bfile 1 end]
}
if {[file isdirectory "$file"]} {
incr dircount
directory $file $bfile $tbfile
return
}
set ext [string tolower [file extension $file]]
if {$ext in $::ignore || $ext ni $::include} { return }
set rsz [file size $file]
set sz [pretty_size $rsz]
set base [file rootname $file]
set thmok 0
if {$ext eq ".ts" && [file exists "${base}.hmt"]} {
set type ts
set ts [ts fetch $file 1]
set rstat [$ts get status]
if {$rstat eq "Valid/OK"} {
set img Video_TS
} elseif {$rstat eq "Loss of power/OK" && $bfile in $dinuse} {
set img Video_Rec
} else {
set img Video_Failed
}
set omenu opt
if {[$ts get definition] eq ""} {
set type gen
set ts 0
set img Video_Other
set omenu oopt
} else {
set omenu opt
}
if {[file exists "${base}.thm"]} { set thmok 1 }
} elseif {$ext eq ".hmt"} {
if {[file exists "${base}.ts"]} { return }
# Sole hmt file indicates failure to track.
set type bad
set ts 0
set img Video_Failed
set omenu oopt
} else {
set type gen
set ts 0
set img Video_Other
set omenu oopt
}
incr filecount
set new 0
if {$type eq "ts"} {
if {[$ts flag "New"] > 0} { set new 1 }
} elseif {$type eq "gen"} {
if {![file exists "${base}.hmi"]} { set new 1 }
}
if {$new} { append img _New }
set fscl "fs"
set synopsis ""
if {$type eq "ts"} {
set fscl "fs fsts"
set synopsis [cgi_quote_html [$ts get synopsis]]
}
puts "
<div class=\"va bf\" id=[incr i]>
<img class=va border=0 src=/img/$img.png>
<input class=\"$fscl\" type=checkbox>
<a class=bf title=\"$synopsis\"
file=\"[cgi_quote_html $file]\" type=$type href=#>
$bfile
</a>
"
# Size
puts "<span class=filesize> ($sz) </span>"
# Icons
set attrs {}
if {$type eq "ts"} {
if {$bfile in $dinuse} {
icon "/img/inuse.png"
}
icon [epg channeliconpath [$ts get channel_name]] \
[$ts get channel_name] "" "va browsechannel"
lassign [$ts genre_info] txt img
icon "$img" $txt "" "va genre"
lassign [ts iconset $ts] icons attrs
puts [join $icons ""]
} elseif {$ext eq ".mp3"} {
# Will be completed using an ajax call.
icon "/img/blank.gif" "" "" "va mp3icon"
}
# Indexed
set dlna 0
if {$::dlnaok && $::model eq "HDR" &&
[llength [system dlnaurl $file]]} {
icon "/img/dlna.png" "Indexed by DLNA Server"
set dlna 1
}
# Queued
if {$type eq "ts"} {
set queued [queue status $ts]
if {$queued ne ""} {
icon "/img/queueps.png" "Queued for $queued"
}
}
# Opt+ button
puts "
<a href=#>
<img class=\"$omenu va\" border=0 width=45 type=$type did=$i
[join $attrs " "]
new=$new rsize=$rsz dlna=$dlna thmok=$thmok
src=/images/181_1_00_Help5_OPT_Plus.png>
</a>
<div class=\"results blood\" style=\"margin: 0 0 0 5em\"></div>
"
puts "</div>"
}
######################################################################
# Render web page
source assets.jim
if {[system has tvdb]} { source tvdb/assets.jim }
if {[system model] eq "HDR" && ![system param DMS_START_ON]} {
puts {
<span class="blood dlnawarning cleft">
Note: Content Sharing is disabled on this system.
</span>
}
}
# elseif {!$dlnaok && ![system instandby]} {
# puts {
# <span class="blood dlnawarning cleft">
# Note: Content Sharing not yet active on this system.
# </span>
# }
#}
puts "
<script type=text/javascript>
var dir = '[string map {' {\'}} $dir]';
var mediaroot = '$mroot';
</script>
<fieldset class=cleft style=\"margin: 0 1em 1em 1em\">
<legend style=\"font-size: 1.5em; padding: 0 0.5em 0.5em 0.5em;\">
"
browse breadcrumb $dir
lassign [dir iconset $dir] icons attrs
puts "
<span class=filesize id=dirsize></span>
<span id=diriconset>[join $icons ""]</span>
<a href=#>
<img class=\"dopt self va\" border=0 width=45 [join $attrs " "]
src=/images/181_1_00_Help5_OPT_Plus.png>
</a>
<div class=\"results blood\" style=\"margin: 0 0 0 5em\"></div>
"
puts "</legend>"
if {[system has tvdb] && [string length $dir] > [string length $mroot]} {
source tvdb/banner.jim
}
# Parent directory
set parent [join [lrange [split $dir /] 0 end-1] /]
if {$parent ne ""} {
puts "
<div class=va>
<a href=\"$env(SCRIPT_NAME)?dir=[cgi_quote_url $parent]\">
<img border=0 src=/images/711_3_09_Media_Folder_UP.png class=va>
\[parent directory\]</a>
</div>
"
}
proc s_file_stat {a b attr} {
global dir
set a "$dir/$a"
set b "$dir/$b"
set ad [file isdirectory $a]
set bd [file isdirectory $b]
if {$ad && !$bd} { return -1 }
if {$bd && !$ad} { return 1 }
if {$ad && $bd} {
if {$a < $b} { return -1 }
if {$a > $b} { return 1 }
return 0
}
if {[catch {file stat $a l}]} { return 0}
set at $l($attr)
if {[catch {file stat $b l}]} { return 0}
set bt $l($attr)
if {$at < $bt} { return -1 }
if {$at > $bt} { return 1 }
return 0
}
proc s_time {a b} {
tailcall s_file_stat $a $b mtime
}
proc s_size {a b} {
tailcall s_file_stat $a $b size
}
set files [readdir -nocomplain $dir]
switch $order {
1 { set files [lsort -command s_time $files] }
2 { set files [lreverse [lsort -command s_time $files]] }
3 { set files [lsort -command s_size $files] }
4 { set files [lreverse [lsort -command s_size $files]] }
default { set files [lsort -nocase $files] }
}
set dinuse [system dirinuse $dir]
foreach file $files { entry "$dir/$file" }
puts "
<a href=# id=selectall>Select all</a> | <a href=# id=deselectall>none</a>
&nbsp;&nbsp;
Directories: $dircount, Files: $filecount
"
# Sort icons
puts "<div id=sortdiv>"
set sortlist {
{0 sort_name name {Alphabetical order A->Z}}
{1 sort_date date {Oldest first}}
{2 sort_date reverse-date {Newest first}}
{3 sort_size size {Smallest first}}
{4 sort_size reverse-size {Largest first}}}
puts "
Sort by: "
foreach sl $sortlist {
lassign $sl index img descr tt
if {$index} { puts " | " }
set tag " (current)"
if {$order != $index} {
set qs [regsub -all {&order=[[[:digit:]]+} $env(QUERY_STRING) ""]
puts "<a href=\"$env(SCRIPT_NAME)?$qs&order=$index\" title=\"$tt\">"
set tag ""
set ket "a"
} else {
puts "<span title=\"$tt\">"
set ket "span"
}
puts "<img class=va border=0 src=/img/$img.gif> $descr$tag</$ket>"
}
puts "</div>"
puts "</fieldset>"
puts {
<fieldset class=left style="margin: 0 1em 1em 1em">
<legend style="font-size: 1.5em; padding: 0 0.5em 0.5em 0.5em; color: #1e5bbd;">
File Clipboard
</legend>
<div id=clipboard>
<img src=/img/spin.gif> <i>Loading...</i>
</div>
</fieldset>
}
# Always-active buttons.
puts {
<div class=buttonrow>
<button id=newdir>New Folder</button>
<button id=dedup><img src=/img/dedup.png width=16>
De-duplicate/tidy this folder</button>
<button id=queue><img src=/img/queueps.png class=qb> View Queue</button>
}
# Streamer file
if {[file exists /mnt/hd3/Streamer_down_file]} {
puts {
<button id=save_stream file=/mnt/hd3/Streamer_down_file>
Save last streamed content
<span id=streamstatus></span>
</button>
}
}
puts "</div>"
# Buttons dependent on selection
puts {
<div class=buttonrow>
<button id=copy class=onesel>Copy</button>
<button id=cut class=onesel>Cut</button>
<button id=delete class=onesel>Delete</button>
}
# Join
if {$nicesplice} {
puts { <button id=join class=tstwosel>Join</button> }
}
# Queue
set queueactions(decrypt) "Decryption"
if {$model ne "HD"} {
# For HDR, give slower option too.
dict set queueactions "decrypt -direct" "Decryption (direct, slower)"
}
set queueactions(shrink) "Shrink"
dict set queueactions "mp3 -mp2" "Audio-Extraction (mp2, fast)"
dict set queueactions "mp3 -mp3" "Audio-Extraction (mp3, slow)"
set queueactions(mpg) "Conversion to MPG"
eval_plugins queueactions
puts {
<button id=so_queue class=tsonesel><img src=/img/queueps.png class=qb>
Queue for</button>
<select id=so_queueactions
class="tsonesel text ui-widget-content ui-corner-all">
}
set rqueueactions [lreverse $queueactions]
foreach v [lsort [dict keys $rqueueactions]] {
set k $rqueueactions($v)
puts "<option value=\"$k\">$v</option>"
}
puts {
</select>
}
# Plugin buttons
if {[llength $plugins(buttons)]} {
puts "</div><div class=buttonrow>"
foreach plugin $plugins(buttons) {
lassign $plugin tag options
puts "
<button class=plugin act=\"$options(link)\">$options(desc)</button>
"
}
}
puts "</div>"
footer