proc torrent:init {} {global torrent_control torrent_array; array set torrent_array ""; array set torrent_control ""; set torrent_control(active) ""} proc torrent:set {id args} {global torrent_array; foreach {var val} $args {set torrent_array($id,$var) $val} } proc torrent:get {id var} {global torrent_array;if [info exists torrent_array($id,$var)] {return $torrent_array($id,$var)} {return "-1"}} proc torrent:wget {id} { global conf cd $conf(torrentdir) set url [torrent:get $id url] catch "exec $conf(wgetbin) -nc -q $url" torrent:set $id filename [string range $url [expr [string last / $url]+1] end] set in [open "| $conf(ctorrentbin) -x [torrent:get $id filename]" r] set data [read $in] set announce ""; set creation ""; set piecelength "" regexp {Announce:.([^\n]+)} $data fullmatch announce regexp {Created.On:.([^\n]+)} $data fullmatch creation regexp {Piece.length:.([^\n]+)} $data fullmatch piecelength set files "" set sizeall 0 foreach line [split $data \n] { puts stderr $line set name "ERROR"; set size 0 set name [lrange $line 1 end-1] if [regexp {([0-9]+)} [lindex $line 0] fullmatch nr]&&[regexp {([0-9]+)} [lindex $line end] fullmatch size] { if ![is_int $nr] {continue} if ![is_int $size] {continue} puts stderr "$nr : $name : $size" lappend files [list $name $size] set sizeall [expr $sizeall+$size] } } torrent:set $id announce $announce torrent:set $id creation $creation torrent:set $id piecelength $piecelength torrent:set $id files $files torrent:set $id size [expr ($sizeall/1024)/1024] } proc torrent:start {id} { global torrent_control conf set command "$conf(ctorrentbin) -e [torrent:get $id seedlimit] -E [torrent:get $id ratio] -M [torrent:get $id maxpeers] -m [torrent:get $id minpeers] -D [torrent:get $id dlimit] -U [torrent:get $id ulimit] -a $conf(torrentdir)/[torrent:get $id filename]" set in [open "| $command" r+] fconfigure $in -blocking 0 torrent:set $id channel $in torrent:set $id active 1 torrent:set $id laststats 0 lappend torrent_control(active) $id } proc torrent:stats {id} { set in [torrent:get $id channel] # Lets not update stats too often, since ctorrent delievers stats only once a second set seconds [clock seconds] if [expr $seconds-[torrent:get $id laststats]]<2 {return 1} {torrent:set $id laststats $seconds} set matchchar 0 set matchlist [list 92 124 45 47] flush $in set buffer [read $in] set line [string range $buffer end-120 end] set line [string range $line [expr [string first [format %c 10] $line]+1] end] scan [string index $line 0] %c matchchar # if ![lsearch $matchlist $matchchar]>=0 {return 0} set string $line # Parses the ctorrent Status Line for information # Returns a list containing the status information in the original Order # For more Information check http://www.rahul.net/dholmes/ctorrent/userguide.html set seed 0; set leech 0; set swarm 0; set pcompl 0; set ptotal 0; set pavail 0; set down 0; set up 0; set drate 0; set urate 0; set ratio 0 regexp {([0-9]+)/([0-9]+)/([0-9]+) \[([0-9]+)/([0-9]+)/([0-9]+)\] ([0-9]+)MB,([0-9]+)MB \| ([^K]+)K/s \| ([^K]+)K E:([0-9,]+)} $string match seed leech swarm pcompl ptotal pavail down up drate urate ratio regsub , $drate . drate regsub , $urate . urate regsub , $ratio . ratio torrent:set $id seed $seed leech $leech swarm $swarm pcompl $pcompl ptotal $ptotal pavail $pavail down $down up $up drate $drate urate $urate ratio $ratio return 1 } torrent:init