#!/mod/bin/jimsh source /mod/webif/lib/setup require lock system.class ts.class tdelete set testing 0 proc dsc {} { lassign [system diskspace] x x perc if {$perc > 90} { puts "Insufficient disk space ($perc%), terminating." exit } } dsc if {![acquire_lock webif_auto]} { puts "Cannot acquire exclusive lock, terminating." exit } set tmp "/mod/tmp/webif_auto" if {![file exists $tmp]} { if {[catch {file mkdir $tmp} msg]} { puts "Cannot create temporary directory - $tmp ($msg)" exit } } elseif {![file isdirectory $tmp]} { puts "Cannot create temporary directory - $tmp (file exists)" exit } # Clean-up the temporary directory foreach file [readdir -nocomplain $tmp] { tdelete "$tmp/$file" } if {[system pkginst undelete]} { set dustbin "[system dustbin]" } else { set dustbin "" } proc bindir {file binroot} { set dir [file dirname $file] regsub "^[system mediaroot]" $dir $binroot ndir if {$dir eq $ndir} { set ndir $binroot } system mkdir_p $ndir return $ndir } proc dedup {dir} { if {$::testing} { puts "DEDUP: \[$dir]" } else { puts [exec /mod/webif/html/dedup/dedup -yes $dir] exec /mod/webif/html/dedup/dedup -yes $dir } } proc do_shrink {ts} { global tmp dustbin tsgroup set file [file rootname [$ts get file]] if {[catch { set perc [exec /mod/bin/stripts -aq $file] } msg]} { puts " Error: $msg" return } if {[string match {*%} $perc]} { set perc [string range $perc 0 end-1] } else { set perc 0 } if {$perc == 0} { #puts " Already shrunk." return } puts " SHRINK: $file" puts " Estimate $perc% saving." puts " Shrinking..." if {[catch { puts [exec nice -n 19 /mod/bin/stripts -q $file $tmp/shrunk] } msg]} { puts "Error during shrink: $msg" return } # The following steps are structured to minimise the risk of # things being left in an inconsistent state if the system goes # into standby. Renames within the same filesystem are very # quick so the risk is small, but even so... # Move the shrunken version back to the local directory. foreach f [glob "$tmp/shrunk.*"] { set ext [file extension $f] file rename $f "${file}_shrunk${ext}" } # Move the old recording to the bin if undelete is installed. if {$dustbin ne ""} { $ts move [bindir $file "$dustbin/webif_autoshrink"] 1 1 } else { # Delete otherwise. if {[$ts delete]} { puts "Successfully deleted $file." } else { puts "Problem deleting $file, [$ts get error]" return } } # Finally, rename the shrunken recording again. foreach ext $tsgroup { set f "${file}_shrunk.$ext" if {[file exists $f]} { file rename $f "${file}.$ext" } } } proc do_decrypt {ts} { global tmp dustbin set file [$ts get file] set rfile [file rootname $file] set bfile [file tail $file] if {![$ts flag "ODEncrypted"]} { #puts " Already decrypted." return } lassign [$ts dlnaloc] url if {$url eq ""} { #puts " Not yet indexed." return } puts " DECRYPT: $rfile" puts " DLNA: $url" exec wget -O "$tmp/$bfile" $url if {[file size $file] != [file size "$tmp/$bfile"]} { puts " File size mismatch." return } # Move the encrypted file out of the way. file rename $file "$rfile.encrypted" # Move the decrypted copy into place. file rename "$tmp/$bfile" $file # Patch the HMT - quickest way to get back to a playable file. exec /mod/bin/hmt -encrypted "$rfile.hmt" puts " Removing/binning old copy." # Move the old recording to the bin if undelete is installed. if {$dustbin ne ""} { set bin [bindir $file "$dustbin/webif_autodecrypt"] set tail [file tail $rfile] file rename "$rfile.encrypted" "$bin/$tail.ts" foreach ext {nts hmt thm} { if {[file exists "$rfile.$ext"]} { file copy $rfile.$ext "$bin/$tail.$ext" if {$ext eq "hmt"} { # Patch the binned HMT back exec /mod/bin/hmt +encrypted \ "$bin/$tail.hmt" } } } } else { tdelete "$rfile.encrypted" } puts " Done." } proc do_mpg {ts} { global tmp tsgroup set file [file rootname [$ts get file]] if {[file exists $file.mpg]} { # Already done. return } if {[$ts flag "ODEncrypted"]} { #puts " Not decrypted." return } if {[$ts get definition] eq "HD"} { # Cannot extract a useful MP3 from a HD recording. return } puts " MPG: $file" puts " Converting..." if {[catch { puts [exec nice -n 19 /mod/bin/ffmpeg -y -benchmark -v 0 \ -i $file.ts \ -map 0:0 -map 0:1 \ -vcodec copy -acodec copy $tmp/mpg.mpg] } msg]} { puts "Error during mpg extract: $msg" return } # Move the MPG into the local directory file rename $tmp/mpg.mpg $file.mpg } proc entries {dir callback} { foreach entry [readdir -nocomplain $dir] { dsc if {![string match {*.ts} $entry} continue if {[catch {set ts [ts fetch "$dir/$entry"]}]} continue if {$ts == 0} continue if {[system inuse [file rootname "$dir/$entry"]]} { puts "$entry - in use\n" continue } $callback $ts } } proc shrink {dir} { puts "SHRINK: \[$dir]" if {!$::testing} { entries $dir do_shrink } } proc decrypt {dir} { puts "DECRYPT: \[$dir]" if {!$::testing} { entries $dir do_decrypt } } proc mpg {dir} { puts "MPG: \[$dir]" if {!$::testing} { entries $dir do_mpg } } proc scan {dir attr {force 0}} {{indent 0}} { global dustbin incr indent 2 if {$::testing} { puts "[string repeat " " $indent]\[$dir]" } #if {[string match {\[*} $dir]} continue if {$dir eq $dustbin} { puts "Dustbin, skipping." return } dsc # Recursion if {[file exists "$dir/.auto${attr}r"]} { if {$::testing} { puts "[string repeat " " $indent] (R)" } set force 1 } if {$force || [file exists "$dir/.auto$attr"]} { $attr $dir } foreach entry [readdir -nocomplain $dir] { if {[file isdirectory "$dir/$entry"]} { scan "$dir/$entry" $attr $force } } incr indent -2 } set root [system mediaroot] if {[llength $argv] > 0} { if {[lindex $argv 0] eq "test"} { set testing 1 } foreach arg $argv { scan $root $arg } } else { foreach arg {dedup decrypt shrink mpg} { scan $root $arg } } release_lock webif_auto