From 49094293904bcca5f636ea58646465bf5fda5d0c Mon Sep 17 00:00:00 2001 From: deranjer Date: Wed, 18 Apr 2018 22:41:32 -0400 Subject: [PATCH] starting to redo the core to do queuing and better downloading --- .gitignore | 3 +- Dockerfile | 3 ++ config.toml | 8 ++-- engine/cronJobs.go | 8 ++-- engine/engine.go | 85 +++++++++++++++++++++++++++++++---------- engine/engineHelpers.go | 15 +++++++- main.go | 27 ++++++------- settings/settings.go | 54 ++++++++++++++------------ storage/storage.go | 1 + 9 files changed, 136 insertions(+), 68 deletions(-) create mode 100644 Dockerfile diff --git a/.gitignore b/.gitignore index f576cbe0..47fa7c6d 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ config.toml.old /public/static/js/kickwebsocket.js.backup /public/static/js/kickwebsocket-generated.js clientAuth.txt -dist \ No newline at end of file +dist +debScripts/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..83b943e4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM scratch +COPY goTorrent / +ENTRYPOINT [ "/goTorrent" ] \ No newline at end of file diff --git a/config.toml b/config.toml index 0936c523..071a3753 100644 --- a/config.toml +++ b/config.toml @@ -1,7 +1,7 @@ [serverConfig] ServerPort = ":8000" #leave format as is it expects a string with colon - ServerAddr = "192.168.1.100" #Put in the IP address you want to bind to + ServerAddr = "192.168.1.8" #Put in the IP address you want to bind to LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic LogOutput = "stdout" #Options = file, stdout #file will print it to logs/server.log @@ -13,8 +13,10 @@ #Limits your upload and download speed globally, all are averages and not burst protected (usually burst on start). #Low = ~.05MB/s, Medium = ~.5MB/s, High = ~1.5MB/s - UploadRateLimit = "Unlimited" #Options are "Low", "Medium", "High", "Unlimited" #Unlimited is default - DownloadRateLimit = "Unlimited" + UploadRateLimit = "Medium" #Options are "Low", "Medium", "High", "Unlimited" #Unlimited is default + DownloadRateLimit = "Medium" + #Maximum number of allowed active torrents, the rest will be queued + MaxActiveTorrents = 1 [goTorrentWebUI] #Basic goTorrentWebUI authentication (not terribly secure, implemented in JS, password is hashed to SHA256, not salted, basically don't depend on this if you require very good security) diff --git a/engine/cronJobs.go b/engine/cronJobs.go index b37c5f16..ca725992 100644 --- a/engine/cronJobs.go +++ b/engine/cronJobs.go @@ -22,7 +22,7 @@ func InitializeCronEngine() *cron.Cron { } //CheckTorrentWatchFolder adds torrents from a watch folder //TODO see if you can use filepath.Abs instead of changing directory -func CheckTorrentWatchFolder(c *cron.Cron, db *storm.DB, tclient *torrent.Client, torrentLocalStorage Storage.TorrentLocal, config Settings.FullClientSettings) { +func CheckTorrentWatchFolder(c *cron.Cron, db *storm.DB, tclient *torrent.Client, torrentLocalStorage Storage.TorrentLocal, config Settings.FullClientSettings, activeTorrents []string, queuedTorrents []string) { c.AddFunc("@every 5m", func() { Logger.WithFields(logrus.Fields{"Watch Folder": config.TorrentWatchFolder}).Info("Running the watch folder cron job") torrentFiles, err := ioutil.ReadDir(config.TorrentWatchFolder) @@ -50,7 +50,7 @@ func CheckTorrentWatchFolder(c *cron.Cron, db *storm.DB, tclient *torrent.Client os.Remove(fullFilePathAbs) //delete the torrent after adding it and copying it over Logger.WithFields(logrus.Fields{"Source Folder": fullFilePathAbs, "Destination Folder": fullNewFilePathAbs, "Torrent": file.Name()}).Info("Added torrent from watch folder, and moved torrent file") - StartTorrent(clientTorrent, torrentLocalStorage, db, "file", fullNewFilePathAbs, config.DefaultMoveFolder, "default", config) + AddTorrent(clientTorrent, torrentLocalStorage, db, "file", fullNewFilePathAbs, config.DefaultMoveFolder, "default", config, activeTorrents, queuedTorrents) } } @@ -58,7 +58,7 @@ func CheckTorrentWatchFolder(c *cron.Cron, db *storm.DB, tclient *torrent.Client } //RefreshRSSCron refreshes all of the RSS feeds on an hourly basis -func RefreshRSSCron(c *cron.Cron, db *storm.DB, tclient *torrent.Client, torrentLocalStorage Storage.TorrentLocal, config Settings.FullClientSettings) { +func RefreshRSSCron(c *cron.Cron, db *storm.DB, tclient *torrent.Client, torrentLocalStorage Storage.TorrentLocal, config Settings.FullClientSettings, activeTorrents []string, queuedTorrents []string) { c.AddFunc("@hourly", func() { torrentHashHistory := Storage.FetchHashHistory(db) RSSFeedStore := Storage.FetchRSSFeeds(db) @@ -86,7 +86,7 @@ func RefreshRSSCron(c *cron.Cron, db *storm.DB, tclient *torrent.Client, torrent Logger.WithFields(logrus.Fields{"err": err, "Torrent": RSSTorrent.Title}).Warn("Unable to add torrent to torrent client!") break //break out of the loop entirely for this message since we hit an error } - StartTorrent(clientTorrent, torrentLocalStorage, db, "magnet", "", config.DefaultMoveFolder, "RSS", config) //TODO let user specify torrent default storage location and let change on fly + AddTorrent(clientTorrent, torrentLocalStorage, db, "magnet", "", config.DefaultMoveFolder, "RSS", config, activeTorrents, queuedTorrents) //TODO let user specify torrent default storage location and let change on fly singleFeed.Torrents = append(singleFeed.Torrents, singleRSSTorrent) } diff --git a/engine/engine.go b/engine/engine.go index 608cccb3..417f3448 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -129,8 +129,13 @@ func readTorrentFileFromDB(element *Storage.TorrentLocal, tclient *torrent.Clien return singleTorrent, nil } -//StartTorrent creates the storage.db entry and starts A NEW TORRENT and adds to the running torrent array -func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.TorrentLocal, torrentDbStorage *storm.DB, torrentType, torrentFilePathAbs, torrentStoragePath, labelValue string, config Settings.FullClientSettings) { +//StartTorrents attempts to start torrents by adding them to the active torrents, then the queue, and by increasing their connections (if they were stopped) +func StartTorrents(clientTorrent *torrent.Client, torrentHashes []string, activeTorrents []string, queuedTorrents []string) { + +} + +//AddTorrent creates the storage.db entry and starts A NEW TORRENT and adds to the running torrent array +func AddTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.TorrentLocal, torrentDbStorage *storm.DB, torrentType, torrentFilePathAbs, torrentStoragePath, labelValue string, config Settings.FullClientSettings, activeTorrents []string, queuedTorrents []string) { timedOut := timeOutInfo(clientTorrent, 45) //seeing if adding the torrent times out (giving 45 seconds) if timedOut { //if we fail to add the torrent return return @@ -177,18 +182,24 @@ func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.To } torrentLocalStorage.TorrentFilePriority = TorrentFilePriorityArray - Storage.AddTorrentLocalStorage(torrentDbStorage, torrentLocalStorage) //writing all of the data to the database - clientTorrent.DownloadAll() //set all pieces to download - NumPieces := clientTorrent.NumPieces() //find the number of pieces - clientTorrent.CancelPieces(1, NumPieces) //cancel all of the pieces to use file priority - for _, singleFile := range clientTorrent.Files() { //setting all of the file priorities to normal - singleFile.SetPriority(torrent.PiecePriorityNormal) + + if len(activeTorrents) < config.MaxActiveTorrents { + if len(queuedTorrents) > 0 { + queuedTorrents = append(queuedTorrents, clientTorrent.InfoHash().String()) + CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "success", Payload: "Torrent queued!"}, Conn) + torrentLocalStorage.QueuedStatus = "Queued" + } else { + clientTorrent.NewReader() + activeTorrents = append(activeTorrents, clientTorrent.InfoHash().String()) + CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "success", Payload: "Torrent added!"}, Conn) + torrentLocalStorage.QueuedStatus = "Active" + } } - CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "success", Payload: "Torrent added!"}, Conn) + Storage.AddTorrentLocalStorage(torrentDbStorage, torrentLocalStorage) //writing all of the data to the database } //CreateInitialTorrentArray adds all the torrents on program start from the database -func CreateInitialTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Storage.TorrentLocal, db *storm.DB) { +func CreateInitialTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Storage.TorrentLocal, db *storm.DB, config Settings.FullClientSettings, activeTorrents []string, queuedTorrents []string) { for _, singleTorrentFromStorage := range TorrentLocalArray { var singleTorrent *torrent.Torrent var err error @@ -218,20 +229,44 @@ func CreateInitialTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto if err != nil { Logger.WithFields(logrus.Fields{"torrentFile": singleTorrent.Name(), "error": err}).Error("Unable to add infobytes to the torrent!") } + if singleTorrentFromStorage.QueuedStatus == "Active" { + singleTorrent.NewReader() + activeTorrents = append(activeTorrents, singleTorrent.InfoHash().String()) + } else if singleTorrentFromStorage.QueuedStatus == "Queued" { + queuedTorrents = append(queuedTorrents, singleTorrent.InfoHash().String()) + } + if singleTorrentFromStorage.TorrentStatus != "Completed" && singleTorrentFromStorage.TorrentStatus != "Stopped" { - singleTorrent.DownloadAll() //set all of the pieces to download (piece prio is NE to file prio) - NumPieces := singleTorrent.NumPieces() //find the number of pieces - singleTorrent.CancelPieces(1, NumPieces) //cancel all of the pieces to use file priority - for _, singleFile := range singleTorrent.Files() { //setting all of the file priorities to normal - singleFile.SetPriority(torrent.PiecePriorityNormal) + fmt.Println("checking about queueing torrent") + if len(activeTorrents) < config.MaxActiveTorrents { + fmt.Println("ActiveTOrrents", activeTorrents) + singleTorrent.NewReader() + singleTorrentFromStorage.QueuedStatus = "Active" + activeTorrents = append(activeTorrents, singleTorrent.InfoHash().String()) //adding the torrent hash to the queue + } else { + queuedTorrents = append(queuedTorrents, singleTorrent.InfoHash().String()) + fmt.Println("Queuing torrent") + singleTorrentFromStorage.QueuedStatus = "Queued" } } + Storage.UpdateStorageTick(db, *singleTorrentFromStorage) } + if len(activeTorrents) < config.MaxActiveTorrents && len(queuedTorrents) > 0 { //after all the torrents are added, see if out active torrent list isn't full, then add from the queue + fmt.Println("adding torrents from queue (if any in there)") + maxCanSend := config.MaxActiveTorrents - len(activeTorrents) + torrentsToStart := make([]string, maxCanSend) + for i, torrentHash := range queuedTorrents { + torrentsToStart[i] = torrentHash + } + StartTorrents(tclient, torrentsToStart, activeTorrents, queuedTorrents) + + } + SetFilePriority(tclient, db) //Setting the desired file priority from storage } //CreateRunningTorrentArray creates the entire torrent list to pass to client -func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Storage.TorrentLocal, PreviousTorrentArray []ClientDB, config Settings.FullClientSettings, db *storm.DB) (RunningTorrentArray []ClientDB) { +func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Storage.TorrentLocal, PreviousTorrentArray []ClientDB, config Settings.FullClientSettings, db *storm.DB, activeTorrents []string, queuedTorrents []string) (RunningTorrentArray []ClientDB) { for _, singleTorrentFromStorage := range TorrentLocalArray { var singleTorrent *torrent.Torrent @@ -241,11 +276,8 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto singleTorrent = liveTorrent } } - tickUpdateStruct := Storage.TorrentLocal{} //we are shoving the tick updates into a torrentlocal struct to pass to storage happens at the end of the routine - fullClientDB := new(ClientDB) - //singleTorrentStorageInfo := Storage.FetchTorrentFromStorage(db, TempHash.String()) //pulling the single torrent info from storage () if singleTorrentFromStorage.TorrentStatus == "Dropped" { Logger.WithFields(logrus.Fields{"selection": singleTorrentFromStorage.TorrentName}).Info("Deleting just the torrent") @@ -253,7 +285,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto Storage.DelTorrentLocalStorage(db, singleTorrentFromStorage.Hash) } if singleTorrentFromStorage.TorrentStatus == "DroppedData" { - Logger.WithFields(logrus.Fields{"selection": singleTorrentFromStorage.TorrentName}).Info("Deleting just the torrent") + Logger.WithFields(logrus.Fields{"selection": singleTorrentFromStorage.TorrentName}).Info("Deleting torrent and data") singleTorrent.Drop() Storage.DelTorrentLocalStorageAndFiles(db, singleTorrentFromStorage.Hash, Config.TorrentConfig.DataDir) @@ -319,10 +351,21 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto } CalculateTorrentETA(singleTorrentFromStorage.TorrentSize, calculatedCompletedSize, fullClientDB) //needs to be here since we need the speed calculated before we can estimate the eta. + if (len(activeTorrents) < config.MaxActiveTorrents) && (len(queuedTorrents) > 0) { //If there is room for another torrent in active torrents, add it. + newTorrentHash := queuedTorrents[0] + fmt.Println("Moving Torrent to active queue") + for _, torrent := range tclient.Torrents() { + if newTorrentHash == torrent.InfoHash().String() { + torrent.NewReader() + activeTorrents = append(activeTorrents, newTorrentHash) + singleTorrentFromStorage.QueuedStatus = "Active" + } + } + } fullClientDB.TotalUploadedSize = HumanizeBytes(float32(fullClientDB.TotalUploadedBytes)) fullClientDB.UploadRatio = CalculateUploadRatio(singleTorrent, fullClientDB) //calculate the upload ratio - CalculateTorrentStatus(singleTorrent, fullClientDB, config, singleTorrentFromStorage, calculatedCompletedSize, calculatedTotalSize) + CalculateTorrentStatus(singleTorrent, fullClientDB, config, singleTorrentFromStorage, calculatedCompletedSize, calculatedTotalSize, activeTorrents, queuedTorrents) //add torrents to the queue, remove from queue, etc tickUpdateStruct.UploadRatio = fullClientDB.UploadRatio tickUpdateStruct.TorrentSize = calculatedTotalSize diff --git a/engine/engineHelpers.go b/engine/engineHelpers.go index c03eae0d..e70f9515 100644 --- a/engine/engineHelpers.go +++ b/engine/engineHelpers.go @@ -185,17 +185,28 @@ func CalculateUploadRatio(t *torrent.Torrent, c *ClientDB) string { } //CalculateTorrentStatus is used to determine what the STATUS column of the frontend will display ll2 -func CalculateTorrentStatus(t *torrent.Torrent, c *ClientDB, config Settings.FullClientSettings, tFromStorage *storage.TorrentLocal, bytesCompleted int64, totalSize int64) { +func CalculateTorrentStatus(t *torrent.Torrent, c *ClientDB, config Settings.FullClientSettings, tFromStorage *storage.TorrentLocal, bytesCompleted int64, totalSize int64, activeTorrents []string, queuedTorrents []string) { if (tFromStorage.TorrentStatus == "Stopped") || (float64(c.TotalUploadedBytes)/float64(bytesCompleted) >= config.SeedRatioStop && tFromStorage.TorrentUploadLimit == true) { //If storage shows torrent stopped or if it is over the seeding ratio AND is under the global limit c.Status = "Stopped" c.MaxConnections = 0 t.SetMaxEstablishedConns(0) + for i, hash := range activeTorrents { //If the torrent is stopped, pull it from the active torrent array + if tFromStorage.Hash == hash { + activeTorrents = append(activeTorrents[:i], activeTorrents[i+1:]...) + } + } } else { //Only has 2 states in storage, stopped or running, so we know it should be running, and the websocket request handled updating the database with connections and status + for _, torrentHash := range queuedTorrents { + if tFromStorage.Hash == torrentHash { + fmt.Println("Setting torrent to queued") + c.Status = "Queued" + return + } + } bytesMissing := totalSize - bytesCompleted c.MaxConnections = 80 t.SetMaxEstablishedConns(80) - //t.DownloadAll() //ensure that we are setting the torrent to download if t.Seeding() && t.Stats().ActivePeers > 0 && bytesMissing == 0 { c.Status = "Seeding" } else if t.Stats().ActivePeers > 0 && bytesMissing > 0 { diff --git a/main.go b/main.go index c4cc9b2c..e51e406c 100644 --- a/main.go +++ b/main.go @@ -94,6 +94,8 @@ func main() { Engine.Logger = Logger //Injecting the logger into all the packages Storage.Logger = Logger Settings.Logger = Logger + var activeTorrents []string + var queuedTorrents []string Config := Settings.FullClientSettingsNew() //grabbing from settings.go Engine.Config = Config if Config.LoggingOutput == "file" { @@ -123,7 +125,7 @@ func main() { httpAddr := Config.HTTPAddr os.MkdirAll(Config.TFileUploadFolder, 0755) //creating a directory to store uploaded torrent files os.MkdirAll(Config.TorrentWatchFolder, 0755) //creating a directory to watch for added .torrent files - //Logger.WithFields(logrus.Fields{"Config": Config}).Info("Torrent Client Config has been generated...") + Logger.WithFields(logrus.Fields{"Config": Config}).Info("Torrent Client Config has been generated...") tclient, err := torrent.NewClient(&Config.TorrentConfig) //pulling out the torrent specific config to use if err != nil { @@ -189,12 +191,12 @@ func main() { TorrentLocalArray := Storage.FetchAllStoredTorrents(db) //pulling in all the already added torrents - this is an array of ALL of the local storage torrents, they will be added back in via hash if TorrentLocalArray != nil { //the first creation of the running torrent array //since we are adding all of them in we use a coroutine... just allows the web ui to load then it will load in the torrents - go Engine.CreateInitialTorrentArray(tclient, TorrentLocalArray, db) //adding all of the stored torrents into the torrent client + go Engine.CreateInitialTorrentArray(tclient, TorrentLocalArray, db, Config, activeTorrents, queuedTorrents) //adding all of the stored torrents into the torrent client } else { Logger.Info("Database is empty, no torrents loaded") } - Engine.CheckTorrentWatchFolder(cronEngine, db, tclient, torrentLocalStorage, Config) //Every 5 minutes the engine will check the specified folder for new .torrent files - Engine.RefreshRSSCron(cronEngine, db, tclient, torrentLocalStorage, Config) // Refresing the RSS feeds on an hourly basis to add torrents that show up in the RSS feed + Engine.CheckTorrentWatchFolder(cronEngine, db, tclient, torrentLocalStorage, Config, activeTorrents, queuedTorrents) //Every 5 minutes the engine will check the specified folder for new .torrent files + Engine.RefreshRSSCron(cronEngine, db, tclient, torrentLocalStorage, Config, activeTorrents, queuedTorrents) // Refresing the RSS feeds on an hourly basis to add torrents that show up in the RSS feed router := mux.NewRouter() //setting up the handler for the web backend router.HandleFunc("/", serveHome) //Serving the main page for our SPA @@ -202,7 +204,7 @@ func main() { http.Handle("/", router) router.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) { //TODO, remove this TorrentLocalArray = Storage.FetchAllStoredTorrents(db) - RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db) //Updates the RunningTorrentArray with the current client data as well + RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db, activeTorrents, queuedTorrents) //Updates the RunningTorrentArray with the current client data as well var torrentlistArray = new(Engine.TorrentList) torrentlistArray.MessageType = "torrentList" //setting the type of message torrentlistArray.ClientDBstruct = RunningTorrentArray //the full JSON that includes the number of torrents as the root @@ -275,8 +277,8 @@ func main() { Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested TorrentList Update") go func() { //running updates in separate thread so can still accept commands - TorrentLocalArray = Storage.FetchAllStoredTorrents(db) //Required to re-read th database since we write to the DB and this will pull the changes from it - RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db) //Updates the RunningTorrentArray with the current client data as well + TorrentLocalArray = Storage.FetchAllStoredTorrents(db) //Required to re-read th database since we write to the DB and this will pull the changes from it + RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db, activeTorrents, queuedTorrents) //Updates the RunningTorrentArray with the current client data as well PreviousTorrentArray = RunningTorrentArray torrentlistArray := Engine.TorrentList{MessageType: "torrentList", ClientDBstruct: RunningTorrentArray, Totaltorrents: len(RunningTorrentArray)} Logger.WithFields(logrus.Fields{"torrentList": torrentlistArray, "previousTorrentList": PreviousTorrentArray}).Debug("Previous and Current Torrent Lists for sending to client") @@ -299,7 +301,7 @@ func main() { Logger.WithFields(logrus.Fields{"message": msg}).Info("Client Requested Torrents by Label") label := payloadData["Label"].(string) torrentsByLabel := Storage.FetchTorrentsByLabel(db, label) - RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db) + RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db, activeTorrents, queuedTorrents) labelRunningArray := []Engine.ClientDB{} for _, torrent := range RunningTorrentArray { //Ranging over the running torrents and if the hashes match we have torrents by label for _, label := range torrentsByLabel { @@ -422,7 +424,7 @@ func main() { } Logger.WithFields(logrus.Fields{"clientTorrent": clientTorrent, "magnetLink": magnetLink}).Info("Adding torrent to client!") Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received MagnetLink"}, conn) - go Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "magnet", "", storageValue, labelValue, Config) //starting the torrent and creating local DB entry + go Engine.AddTorrent(clientTorrent, torrentLocalStorage, db, "magnet", "", storageValue, labelValue, Config, activeTorrents, queuedTorrents) //starting the torrent and creating local DB entry } @@ -469,7 +471,7 @@ func main() { Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to add Torrent to torrent server"}, conn) } Logger.WithFields(logrus.Fields{"clienttorrent": clientTorrent.Name(), "filename": filePathAbs}).Info("Added torrent") - go Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "file", filePathAbs, storageValue, labelValue, Config) + go Engine.AddTorrent(clientTorrent, torrentLocalStorage, db, "file", filePathAbs, storageValue, labelValue, Config, activeTorrents, queuedTorrents) case "stopTorrents": torrentHashes := payloadData["TorrentHashes"].([]interface{}) @@ -517,9 +519,8 @@ func main() { oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String()) oldTorrentInfo.TorrentStatus = "Running" oldTorrentInfo.MaxConnections = 80 - singleTorrent.DownloadAll() //set all of the pieces to download (piece prio is NE to file prio) - NumPieces := singleTorrent.NumPieces() //find the number of pieces - singleTorrent.CancelPieces(1, NumPieces) //cancel all of the pieces to use file priority + singleTorrent.NewReader() //set all of the pieces to download (piece prio is NE to file prio) + oldTorrentInfo.QueuedStatus = "Active" for _, file := range singleTorrent.Files() { for _, sentFile := range oldTorrentInfo.TorrentFilePriority { if file.DisplayPath() == sentFile.TorrentFilePath { diff --git a/settings/settings.go b/settings/settings.go index fc6e4a9f..9a0bae92 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -40,6 +40,7 @@ type FullClientSettings struct { DefaultMoveFolder string TorrentWatchFolder string ClientConnectSettings + MaxActiveTorrents int } //default is called if there is a parsing error @@ -70,6 +71,8 @@ func dhtServerSettings(dhtConfig dht.ServerConfig) dht.ServerConfig { func calculateRateLimiters(uploadRate, downloadRate string) (*rate.Limiter, *rate.Limiter) { //TODO reorg var uploadRateLimiterSize int var downloadRateLimiterSize int + var downloadRateLimiter *rate.Limiter + var uploadRateLimiter *rate.Limiter switch uploadRate { case "Low": @@ -79,8 +82,8 @@ func calculateRateLimiters(uploadRate, downloadRate string) (*rate.Limiter, *rat case "High": uploadRateLimiterSize = 1500000 default: - downloadRateLimiter := rate.NewLimiter(rate.Inf, 0) - uploadRateLimiter := rate.NewLimiter(rate.Inf, 0) + downloadRateLimiter = rate.NewLimiter(rate.Inf, 0) + uploadRateLimiter = rate.NewLimiter(rate.Inf, 0) return downloadRateLimiter, uploadRateLimiter } @@ -89,17 +92,18 @@ func calculateRateLimiters(uploadRate, downloadRate string) (*rate.Limiter, *rat downloadRateLimiterSize = 50000 case "Medium": downloadRateLimiterSize = 500000 + fmt.Println("Medium Rate Limit...") case "High": downloadRateLimiterSize = 1500000 default: - downloadRateLimiter := rate.NewLimiter(rate.Inf, 0) - uploadRateLimiter := rate.NewLimiter(rate.Inf, 0) + downloadRateLimiter = rate.NewLimiter(rate.Inf, 0) + uploadRateLimiter = rate.NewLimiter(rate.Inf, 0) return downloadRateLimiter, uploadRateLimiter } var limitPerSecondUl = rate.Limit(uploadRateLimiterSize) - uploadRateLimiter := rate.NewLimiter(limitPerSecondUl, uploadRateLimiterSize) + uploadRateLimiter = rate.NewLimiter(limitPerSecondUl, uploadRateLimiterSize) var limitPerSecondDl = rate.Limit(uploadRateLimiterSize) - downloadRateLimiter := rate.NewLimiter(limitPerSecondDl, downloadRateLimiterSize) + downloadRateLimiter = rate.NewLimiter(limitPerSecondDl, downloadRateLimiterSize) return downloadRateLimiter, uploadRateLimiter } @@ -177,9 +181,9 @@ func FullClientSettingsNew() FullClientSettings { //Rate Limiters //var uploadRateLimiter *rate.Limiter //var downloadRateLimiter *rate.Limiter - //uploadRate := viper.GetString("serverConfig.UploadRateLimit") - //downloadRate := viper.GetString("serverConfig.DownloadRateLimit") - //downloadRateLimiter, uploadRateLimiter = calculateRateLimiters(uploadRate, downloadRate) + uploadRate := viper.GetString("serverConfig.UploadRateLimit") + downloadRate := viper.GetString("serverConfig.DownloadRateLimit") + downloadRateLimiter, uploadRateLimiter := calculateRateLimiters(uploadRate, downloadRate) //Internals dataDir := filepath.ToSlash(viper.GetString("torrentClientConfig.DownloadDir")) //Converting the string literal into a filepath dataDirAbs, err := filepath.Abs(dataDir) //Converting to an absolute file path @@ -191,6 +195,7 @@ func FullClientSettingsNew() FullClientSettings { noDHT := viper.GetBool("torrentClientConfig.NoDHT") noUpload := viper.GetBool("torrentClientConfig.NoUpload") seed := viper.GetBool("torrentClientConfig.Seed") + maxActiveTorrents := viper.GetInt("serverConfig.MaxActiveTorrents") peerID := viper.GetString("torrentClientConfig.PeerID") disableUTP := viper.GetBool("torrentClientConfig.DisableUTP") @@ -213,21 +218,21 @@ func FullClientSettingsNew() FullClientSettings { } tConfig := torrent.Config{ - DataDir: dataDirAbs, - ListenAddr: listenAddr, - DisablePEX: disablePex, - NoDHT: noDHT, - DHTConfig: dhtServerConfig, - NoUpload: noUpload, - Seed: seed, - //UploadRateLimiter: uploadRateLimiter, - //DownloadRateLimiter: downloadRateLimiter, - PeerID: peerID, - DisableUTP: disableUTP, - DisableTCP: disableTCP, - DisableIPv6: disableIPv6, - Debug: debug, - EncryptionPolicy: encryptionPolicy, + DataDir: dataDirAbs, + ListenAddr: listenAddr, + DisablePEX: disablePex, + NoDHT: noDHT, + DHTConfig: dhtServerConfig, + NoUpload: noUpload, + Seed: seed, + UploadRateLimiter: uploadRateLimiter, + DownloadRateLimiter: downloadRateLimiter, + PeerID: peerID, + DisableUTP: disableUTP, + DisableTCP: disableTCP, + DisableIPv6: disableIPv6, + Debug: debug, + EncryptionPolicy: encryptionPolicy, } Config := FullClientSettings{ @@ -248,6 +253,7 @@ func FullClientSettingsNew() FullClientSettings { TorrentConfig: tConfig, DefaultMoveFolder: defaultMoveFolderAbs, TorrentWatchFolder: torrentWatchFolderAbs, + MaxActiveTorrents: maxActiveTorrents, } return Config diff --git a/storage/storage.go b/storage/storage.go index 74fd38fc..97eef499 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -83,6 +83,7 @@ type TorrentLocal struct { TorrentSize int64 //If we cancel a file change the download size since we won't be downloading that file UploadRatio string TorrentFilePriority []TorrentFilePriority + QueuedStatus string //Either "Queued", "Active", or "None" } //SaveConfig saves the config to the database to compare for changes to settings.toml on restart