From d7ece81776c34dd926c1b072b7427705e73e56c0 Mon Sep 17 00:00:00 2001 From: Jaime Pillora Date: Tue, 15 Sep 2015 00:51:54 +1000 Subject: [PATCH] improved ui, fixed js crash, rebuild go1.5.1 --- engine/torrent.go | 8 +-- server/server.go | 14 ++-- server/server_files.go | 15 +++-- server/server_search.go | 2 +- static/files/css/sections/torrents.css | 31 +++++++-- static/files/js/downloads-controller.js | 12 ++-- static/files/js/omni-controller.js | 12 ++-- static/files/template/downloads.html | 60 ----------------- static/files/template/torrents.html | 86 ++++++++++++------------- 9 files changed, 111 insertions(+), 129 deletions(-) diff --git a/engine/torrent.go b/engine/torrent.go index ff865b7ce..92e33ea84 100644 --- a/engine/torrent.go +++ b/engine/torrent.go @@ -66,17 +66,17 @@ func (torrent *Torrent) Update(t torrent.Torrent) { } } file.Completed = completed - file.Percent = percent(file.Completed, file.Chunks) + file.Percent = percent(int64(file.Completed), int64(file.Chunks)) file.f = f totalChunks += file.Chunks totalCompleted += file.Completed } - torrent.Percent = percent(totalChunks, totalCompleted) //cacluate rate now := time.Now() bytes := t.BytesCompleted() + torrent.Percent = percent(bytes, torrent.Size) if !torrent.updatedAt.IsZero() { dt := float32(now.Sub(torrent.updatedAt)) db := float32(bytes - torrent.Downloaded) @@ -87,9 +87,9 @@ func (torrent *Torrent) Update(t torrent.Torrent) { torrent.t = t } -func percent(n, total int) float32 { +func percent(n, total int64) float32 { if total == 0 { return float32(0) } - return float32(int(float32(10000)*(float32(n)/float32(total)))) / 100 + return float32(int(float64(10000)*(float64(n)/float64(total)))) / 100 } diff --git a/server/server.go b/server/server.go index 82c907ecf..6f07b0023 100644 --- a/server/server.go +++ b/server/server.go @@ -16,7 +16,8 @@ import ( "github.com/jpillora/cloud-torrent/engine" "github.com/jpillora/cloud-torrent/static" "github.com/jpillora/go-realtime" - "github.com/jpillora/scraper/lib" + "github.com/jpillora/requestlog" + "github.com/jpillora/scraper/scraper" ) //Server is the "State" portion of the diagram @@ -26,6 +27,7 @@ type Server struct { Host string `help:"Listening interface (default all)"` Auth string `help:"Optional basic auth (in form user:password)"` ConfigPath string `help:"Configuration file path"` + Log bool `help:"Enable request logging"` //http handlers files, static http.Handler scraper *scraper.Handler @@ -51,7 +53,7 @@ func (s *Server) init() error { //will use a the local embed/ dir if it exists, otherwise will use the hardcoded embedded binaries s.files = http.HandlerFunc(s.serveFiles) s.static = ctstatic.FileSystemHandler() - s.scraper = &scraper.Handler{Log: true} + s.scraper = &scraper.Handler{Log: false} if err := s.scraper.LoadConfig(defaultSearchConfig); err != nil { log.Fatal(err) } @@ -104,7 +106,7 @@ func (s *Server) init() error { // log.Printf("torrents #%d files #%d", len(s.state.Torrents), len(s.state.Downloads.Children)) s.state.Unlock() s.state.Update() - time.Sleep(1 * time.Second) + time.Sleep(2 * time.Second) } }() @@ -135,8 +137,12 @@ func (s *Server) Run() error { // TODO if Open { // cross platform open - https://github.com/skratchdot/open-golang // } + h := http.Handler(http.HandlerFunc(s.handle)) + if s.Log { + h = requestlog.Wrap(h) + } log.Printf("Listening on %d...", s.Port) - return http.ListenAndServe(s.Host+":"+strconv.Itoa(s.Port), http.HandlerFunc(s.handle)) + return http.ListenAndServe(s.Host+":"+strconv.Itoa(s.Port), h) } func (s *Server) handle(w http.ResponseWriter, r *http.Request) { diff --git a/server/server_files.go b/server/server_files.go index 031c49917..f4d354dcc 100644 --- a/server/server_files.go +++ b/server/server_files.go @@ -1,6 +1,7 @@ package server import ( + "errors" "fmt" "io/ioutil" "log" @@ -11,6 +12,8 @@ import ( "time" ) +const fileNumberLimit = 1000 + type fsNode struct { Name string Size int64 @@ -22,7 +25,7 @@ func (s *Server) listFiles() *fsNode { rootDir := s.state.Config.DownloadDirectory root := &fsNode{} if info, err := os.Stat(rootDir); err == nil { - if err := list(rootDir, info, root); err != nil { + if err := list(rootDir, info, root, new(int)); err != nil { log.Printf("File listing failed: %s", err) } } @@ -56,9 +59,13 @@ func (s *Server) serveFiles(w http.ResponseWriter, r *http.Request) { //custom directory walk -func list(path string, info os.FileInfo, node *fsNode) error { +func list(path string, info os.FileInfo, node *fsNode, n *int) error { if (!info.IsDir() && !info.Mode().IsRegular()) || strings.HasPrefix(info.Name(), ".") { - return fmt.Errorf("Non-regular file") + return errors.New("Non-regular file") + } + (*n)++ + if (*n) > fileNumberLimit { + return errors.New("Over file limit") //limit number of files walked } node.Name = info.Name() node.Size = info.Size() @@ -74,7 +81,7 @@ func list(path string, info os.FileInfo, node *fsNode) error { for _, i := range children { c := &fsNode{} p := filepath.Join(path, i.Name()) - if err := list(p, i, c); err != nil { + if err := list(p, i, c, n); err != nil { continue } node.Size += c.Size diff --git a/server/server_search.go b/server/server_search.go index 6bff532d8..d8dd4c02b 100644 --- a/server/server_search.go +++ b/server/server_search.go @@ -45,7 +45,7 @@ var defaultSearchConfig = []byte(`{ "url": "http://audiobookbay.co{{path}}", "result": { "infohash": "/td>([a-f0-9]+) td:nth-child(2)" + "tracker": "table tr td:nth-child(2)" } } }`) diff --git a/static/files/css/sections/torrents.css b/static/files/css/sections/torrents.css index ee250872c..d6a41ab1b 100644 --- a/static/files/css/sections/torrents.css +++ b/static/files/css/sections/torrents.css @@ -26,9 +26,16 @@ section.torrents { font-size: 0.75rem; } +.torrent .info .progress { + margin: 0; +} +.torrent .info .progress .bar { + height: 10px; +} + .torrent .status { - padding-top: 10px; - display: inline; + padding: 5px; + display: inline-block; } .torrent .status .muted { @@ -46,18 +53,31 @@ section.torrents { font-size: 0.75rem; } + + +.torrent .download.file .name span { + position: relative; + z-index: 1; +} + +.torrent .download.file .name .percent { + display: inline-block; + width: 60px; +} + + .torrent .download.file .name, .torrent .download.file .percent { position: relative; overflow: hidden; } -.torrent .download.file .progress { +.torrent .downloads .progress { position: absolute; top: 0; left: 0; width: 100%; - opacity: 0.75; + opacity: 0.55; z-index: 0; padding: 4px; margin: 0; @@ -68,6 +88,9 @@ section.torrents { height: 100%; } +.torrent .downloads thead tr th.size { + width: 110px; +} .torrent .downloads tfoot tr th { font-weight: bold; font-size: 0.85rem; diff --git a/static/files/js/downloads-controller.js b/static/files/js/downloads-controller.js index 3cad64354..6201e7fe8 100644 --- a/static/files/js/downloads-controller.js +++ b/static/files/js/downloads-controller.js @@ -31,11 +31,13 @@ app.controller("NodeController", function($scope, $rootScope, $http, $timeout) { if($scope.isfile() && torrents) { for(var ih in torrents) { var files = torrents[ih].Files; - for (var i = 0; i < files.length; i++) { - var f = files[i]; - if(f.Path === path) { - n.$file = f; - break; + if(files) { + for (var i = 0; i < files.length; i++) { + var f = files[i]; + if(f.Path === path) { + n.$file = f; + break; + } } } if(n.$file) diff --git a/static/files/js/omni-controller.js b/static/files/js/omni-controller.js index 12b33a802..c0b6d44fd 100644 --- a/static/files/js/omni-controller.js +++ b/static/files/js/omni-controller.js @@ -155,9 +155,9 @@ app.controller("OmniController", function($scope, $rootScope, storage, api, sear } for (var i = 0; i < results.length; i++) { var r = results[i]; - //add origin to absolute urls - if(r.url && /^\//.test(r.url)) { - r.url = origin + r.url; + //add origin to path to create urls + if(r.path && /^\//.test(r.path)) { + r.url = origin + r.path; } $scope.results.push(r); } @@ -184,7 +184,11 @@ app.controller("OmniController", function($scope, $rootScope, storage, api, sear if (data.magnet) { magnet = data.magnet; } else if (data.infohash) { - magnet = magnetURI(result.name, data.infohash, [{v: data.tracker }]); + //get urls from the comma separated list + var trackers = (data.tracker || "").split(",").filter(function(s){ + return /^(http|udp):\/\//.test(s); + }).map(function(v) { return {v:v}; }); + magnet = magnetURI(result.name, data.infohash, trackers); } else { $scope.omnierr = "No magnet or infohash found"; return; diff --git a/static/files/template/downloads.html b/static/files/template/downloads.html index 2caba9dec..c0cd269ba 100644 --- a/static/files/template/downloads.html +++ b/static/files/template/downloads.html @@ -11,63 +11,3 @@

Downloads

ng-include src="'template/download-tree.html'"> - - diff --git a/static/files/template/torrents.html b/static/files/template/torrents.html index fc42bb16c..3d9968cb9 100644 --- a/static/files/template/torrents.html +++ b/static/files/template/torrents.html @@ -33,26 +33,40 @@
#{{ t.InfoHash }}
+
+
+
+
+
- +
+ +
+ +
{{t.Downloaded | bytes}} - ({{t.DownloadRate | bytes}}/s) - - - - - Start - - - Stop - - - Remove - + / {{t.Size | bytes}} + - {{t.Percent }}% + - {{t.DownloadRate | bytes}}/s +
-
+
- - + @@ -120,9 +123,6 @@
-
File SizeProgress
No filesNo files
- - {{ f.Path | filename }} - -
{{ t.Size | bytes }} Total -   -