From 6af49b317dddd3a11ceee20c84974f37eab3a04e Mon Sep 17 00:00:00 2001 From: deranjer Date: Thu, 25 Jan 2018 23:08:10 -0500 Subject: [PATCH] Adding logic to change torrent storage path --- .vscode/settings.json | 11 +- engine/clientStructs.go | 16 +-- engine/cronJobs.go | 4 +- engine/doneTorrentActions.go | 29 +++-- engine/doneTorrentActions_test.go | 46 +++++++ engine/engine.go | 32 +++-- .../src/BackendComm/backendWebsocket.js | 1 + .../src/BottomMenu/Tabs/generalTab.js | 4 +- .../TopMenu/Modals/RSSModal/addRSSModal.js | 1 - .../src/TopMenu/Modals/addTorrentFileModal.js | 11 +- .../src/TopMenu/Modals/addTorrentLinkModal.js | 14 ++- .../src/TopMenu/Modals/changeStorageModal.js | 116 ++++++++++++++++++ main.go | 22 +++- public/static/js/bundle.js | 26 ++-- storage/storage.go | 6 +- 15 files changed, 279 insertions(+), 60 deletions(-) create mode 100644 engine/doneTorrentActions_test.go create mode 100644 goTorrentWebUI/src/TopMenu/Modals/changeStorageModal.js diff --git a/.vscode/settings.json b/.vscode/settings.json index 3b664107..b4b79a21 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,12 @@ { - "git.ignoreLimitWarning": true + "git.ignoreLimitWarning": true, + "cSpell.words": [ + "anacrolix", + "asdine", + "btih", + "gofeed", + "logrus", + "mmcdole", + "otiai" + ] } \ No newline at end of file diff --git a/engine/clientStructs.go b/engine/clientStructs.go index 8e2b4865..e21c68ed 100644 --- a/engine/clientStructs.go +++ b/engine/clientStructs.go @@ -9,15 +9,17 @@ import ( //All the message types are first, first the server handling messages from the client -//Message contains the JSON messages from the client, we first unmarshal to get the messagetype, then each module unmarshalls the actual message once we know the type +//Message contains the JSON messages from the client, we first unmarshal to get the messagetype, then each module un-marshalls the actual message once we know the type type Message struct { - MessageType string - MessageDetail string `json:",omitempty"` - MessageDetailTwo string `json:",omitempty"` - Payload []string + MessageType string + MessageDetail string `json:",omitempty"` + MessageDetailTwo string `json:",omitempty"` + MessageDetailThree string `json:",omitempty"` + Payload []string } //Next are the messages the server sends to the client + //ServerPushMessage is information (usually logs and status messages) that the server pushes to the client type ServerPushMessage struct { MessageType string @@ -70,7 +72,7 @@ type TorrentFile struct { } //ClientDB struct contains the struct that is used to compose the torrentlist -type ClientDB struct { //TODO maybe seperate out the internal bits into another client struct +type ClientDB struct { //TODO maybe separate out the internal bits into another client struct TorrentHashString string `json:"TorrentHashString"` //Passed to client for displaying hash and is used to uniquly identify all torrents TorrentName string `json:"TorrentName"` DownloadedSize string `json:"DownloadedSize"` //how much the client has downloaded total @@ -83,7 +85,7 @@ type ClientDB struct { //TODO maybe seperate out the internal bits into another StoragePath string `json:"StoragePath"` //Passed to client (and stored in stormdb) DateAdded string //Passed to client (and stored in stormdb) ETA string `json:"ETA"` //Passed to client - Label string //Passed to client and stored in stormdb + TorrentLabel string //Passed to client and stored in stormdb SourceType string `json:"SourceType"` //Stores whether the torrent came from a torrent file or a magnet link KnownSwarm []torrent.Peer //Passed to client for Peer Tab UploadRatio string //Passed to client, stores the string for uploadratio stored in stormdb diff --git a/engine/cronJobs.go b/engine/cronJobs.go index 18ed9226..87b59ebb 100644 --- a/engine/cronJobs.go +++ b/engine/cronJobs.go @@ -40,7 +40,7 @@ func CheckTorrentWatchFolder(c *cron.Cron, db *storm.DB, tclient *torrent.Client break //break out of the loop entirely for this message since we hit an error } fullNewFilePath := filepath.Join(config.TFileUploadFolder, file.Name()) - StartTorrent(clientTorrent, torrentLocalStorage, db, config.TorrentConfig.DataDir, "file", file.Name(), config.DefaultMoveFolder) + StartTorrent(clientTorrent, torrentLocalStorage, db, config.TorrentConfig.DataDir, "file", file.Name(), config.DefaultMoveFolder, "default") CopyFile(fullFilePath, fullNewFilePath) os.Remove(fullFilePath) //delete the torrent after adding it and copying it over Logger.WithFields(logrus.Fields{"Source Folder": config.TorrentWatchFolder, "Destination Folder": config.TFileUploadFolder, "Torrent": file.Name()}).Info("Added torrent from watch folder, and moved torrent file") @@ -78,7 +78,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, config.TorrentConfig.DataDir, "magnet", "", config.DefaultMoveFolder) //TODO let user specify torrent default storage location and let change on fly + StartTorrent(clientTorrent, torrentLocalStorage, db, config.TorrentConfig.DataDir, "magnet", "", config.DefaultMoveFolder, "RSS") //TODO let user specify torrent default storage location and let change on fly singleFeed.Torrents = append(singleFeed.Torrents, singleRSSTorrent) } diff --git a/engine/doneTorrentActions.go b/engine/doneTorrentActions.go index 6da57ff6..e62b63cb 100644 --- a/engine/doneTorrentActions.go +++ b/engine/doneTorrentActions.go @@ -6,7 +6,6 @@ import ( "path/filepath" "runtime" - "github.com/anacrolix/torrent" "github.com/asdine/storm" Storage "github.com/deranjer/goTorrent/storage" pushbullet "github.com/mitsuse/pushbullet-go" @@ -16,11 +15,11 @@ import ( ) //MoveAndLeaveSymlink takes the file from the default download dir and moves it to the user specified directory and then leaves a symlink behind. -func MoveAndLeaveSymlink(config FullClientSettings, singleTorrent *torrent.Torrent, db *storm.DB) { - Logger.WithFields(logrus.Fields{"Torrent Name": singleTorrent.Name()}).Info("Move and Create symlink started for torrent") - tStorage := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String()) - oldFilePath := filepath.Join(config.TorrentConfig.DataDir, singleTorrent.Name()) - newFilePath := filepath.Join(tStorage.StoragePath, singleTorrent.Name()) +func MoveAndLeaveSymlink(config FullClientSettings, tHash string, db *storm.DB) { + tStorage := Storage.FetchTorrentFromStorage(db, tHash) + Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentFileName}).Info("Move and Create symlink started for torrent") + oldFilePath := filepath.Join(config.TorrentConfig.DataDir, tStorage.TorrentFileName) + newFilePath := filepath.Join(tStorage.StoragePath, tStorage.TorrentFileName) _, err := os.Stat(tStorage.StoragePath) if os.IsNotExist(err) { err := os.MkdirAll(tStorage.StoragePath, 0755) @@ -40,7 +39,7 @@ func MoveAndLeaveSymlink(config FullClientSettings, singleTorrent *torrent.Torre os.Mkdir(newFilePath, 0755) folderCopy.Copy(oldFilePath, newFilePath) //copy the folder to the new location os.Chmod(newFilePath, 0777) - notifyUser(tStorage, config, singleTorrent, db) + notifyUser(tStorage, config, db) return } srcFile, err := os.Open(oldFilePath) @@ -66,7 +65,7 @@ func MoveAndLeaveSymlink(config FullClientSettings, singleTorrent *torrent.Torre Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Windows: Error syncing new file to disk") } Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "bytesWritten": bytesWritten}).Info("Windows Torrent Copy Completed") - notifyUser(tStorage, config, singleTorrent, db) + notifyUser(tStorage, config, db) } else { folderCopy.Copy(oldFilePath, newFilePath) os.Chmod(newFilePath, 0777) //changing permissions on the new file to be permissive @@ -76,28 +75,28 @@ func MoveAndLeaveSymlink(config FullClientSettings, singleTorrent *torrent.Torre Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error creating symlink") return } - notifyUser(tStorage, config, singleTorrent, db) + notifyUser(tStorage, config, db) Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath}).Info("Moving completed torrent") } } } -func notifyUser(tStorage Storage.TorrentLocal, config FullClientSettings, singleTorrent *torrent.Torrent, db *storm.DB) { - Logger.WithFields(logrus.Fields{"New File Path": tStorage.StoragePath, "Torrent Name": singleTorrent.Name()}).Info("Attempting to notify user..") +func notifyUser(tStorage Storage.TorrentLocal, config FullClientSettings, db *storm.DB) { + Logger.WithFields(logrus.Fields{"New File Path": tStorage.StoragePath, "Torrent Name": tStorage.TorrentFileName}).Info("Attempting to notify user..") tStorage.TorrentMoved = true Storage.AddTorrentLocalStorage(db, tStorage) //Updating the fact that we moved the torrent if config.PushBulletToken != "" { pb := pushbullet.New(config.PushBulletToken) n := requests.NewNote() - n.Title = singleTorrent.Name() + n.Title = tStorage.TorrentFileName n.Body = "Completed and moved to " + tStorage.StoragePath if _, err := pb.PostPushesNote(n); err != nil { - Logger.WithFields(logrus.Fields{"Torrent": singleTorrent.Name(), "New File Path": tStorage.StoragePath, "error": err}).Error("Error pushing PushBullet Note") + Logger.WithFields(logrus.Fields{"Torrent": tStorage.TorrentFileName, "New File Path": tStorage.StoragePath, "error": err}).Error("Error pushing PushBullet Note") return } - Logger.WithFields(logrus.Fields{"Torrent": singleTorrent.Name(), "New File Path": tStorage.StoragePath}).Info("Pushbullet note sent") + Logger.WithFields(logrus.Fields{"Torrent": tStorage.TorrentFileName, "New File Path": tStorage.StoragePath}).Info("Pushbullet note sent") } else { - Logger.WithFields(logrus.Fields{"New File Path": tStorage.StoragePath, "Torrent Name": singleTorrent.Name()}).Info("No pushbullet API key set, not notifying") + Logger.WithFields(logrus.Fields{"New File Path": tStorage.StoragePath, "Torrent Name": tStorage.TorrentFileName}).Info("No pushbullet API key set, not notifying") } } diff --git a/engine/doneTorrentActions_test.go b/engine/doneTorrentActions_test.go new file mode 100644 index 00000000..87efb7b7 --- /dev/null +++ b/engine/doneTorrentActions_test.go @@ -0,0 +1,46 @@ +package engine + +import ( + "testing" + + "github.com/asdine/storm" + Storage "github.com/deranjer/goTorrent/storage" +) + +func TestMoveAndLeaveSymlink(t *testing.T) { + type args struct { + config FullClientSettings + tStorage Storage.TorrentLocal + db *storm.DB + } + tests := []struct { + name string + args args + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + MoveAndLeaveSymlink(tt.args.config, tt.args.tStorage, tt.args.db) + }) + } +} + +func Test_notifyUser(t *testing.T) { + type args struct { + tStorage Storage.TorrentLocal + config FullClientSettings + db *storm.DB + } + tests := []struct { + name string + args args + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + notifyUser(tt.args.tStorage, tt.args.config, tt.args.db) + }) + } +} diff --git a/engine/engine.go b/engine/engine.go index bfd74689..f9cef0dc 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -84,7 +84,7 @@ func timeOutInfo(clientTorrent *torrent.Torrent, seconds time.Duration) (deleted }() select { case <-clientTorrent.GotInfo(): //attempting to retrieve info for torrent - Logger.WithFields(logrus.Fields{"clientTorrentName": clientTorrent.Name()}).Debug("Recieved torrent info for torrent") + Logger.WithFields(logrus.Fields{"clientTorrentName": clientTorrent.Name()}).Debug("Received torrent info for torrent") clientTorrent.DownloadAll() return false case <-timeout: // getting info for torrent has timed out so purging the torrent @@ -123,8 +123,8 @@ func readTorrentFileFromDB(element *Storage.TorrentLocal, tclient *torrent.Clien } //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, dataDir string, torrentType string, torrentFileName string, torrentStoragePath string) { - timedOut := timeOutInfo(clientTorrent, 45) //seeing if adding the torrrent times out (giving 45 seconds) +func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.TorrentLocal, torrentDbStorage *storm.DB, dataDir string, torrentType string, torrentFileName string, torrentStoragePath string, labelValue 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 } @@ -139,6 +139,7 @@ func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.To } torrentLocalStorage.Hash = TempHash.String() // we will store the infohash to add it back later on client restart (if needed) torrentLocalStorage.InfoBytes = clientTorrent.Metainfo().InfoBytes + torrentLocalStorage.Label = labelValue torrentLocalStorage.DateAdded = time.Now().Format("Jan _2 2006") torrentLocalStorage.StoragePath = torrentStoragePath torrentLocalStorage.TorrentName = clientTorrent.Name() @@ -190,7 +191,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto } if len(singleTorrentFromStorage.InfoBytes) == 0 { //TODO.. kind of a fringe scenario.. not sure if needed since the db should always have the infobytes timeOut := timeOutInfo(singleTorrent, 45) - if timeOut == true { // if we did timeout then drop the torrent from the boltdb database + if timeOut == true { // if we did timeout then drop the torrent from the bolt.db database Storage.DelTorrentLocalStorage(db, singleTorrentFromStorage.Hash) //purging torrent from the local database continue } @@ -204,8 +205,8 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto //Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Generating infohash") TempHash = singleTorrent.InfoHash() - if (singleTorrent.BytesCompleted() == singleTorrent.Length()) && (singleTorrentFromStorage.TorrentMoved == false) { //if we are done downloading and havent moved torrent yet - MoveAndLeaveSymlink(config, singleTorrent, db) //can take some time to move file so running this in another thread TODO make this a goroutine and skip this block if the routine is still running + if (singleTorrent.BytesCompleted() == singleTorrent.Length()) && (singleTorrentFromStorage.TorrentMoved == false) { //if we are done downloading and haven't moved torrent yet + MoveAndLeaveSymlink(config, singleTorrent.InfoHash().String(), db) //can take some time to move file so running this in another thread TODO make this a goroutine and skip this block if the routine is still running } fullStruct := singleTorrent.Stats() @@ -232,6 +233,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto fullClientDB.StoragePath = singleTorrentFromStorage.StoragePath fullClientDB.TorrentName = singleTorrentFromStorage.TorrentName fullClientDB.DateAdded = singleTorrentFromStorage.DateAdded + fullClientDB.TorrentLabel = singleTorrentFromStorage.Label fullClientDB.BytesCompleted = singleTorrent.BytesCompleted() fullClientDB.NumberofFiles = len(singleTorrent.Files()) @@ -245,7 +247,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto } } } - CalculateTorrentETA(singleTorrent, fullClientDB) //needs to be here since we need the speed calcuated before we can estimate the eta. + CalculateTorrentETA(singleTorrent, fullClientDB) //needs to be here since we need the speed calculated before we can estimate the eta. fullClientDB.TotalUploadedSize = HumanizeBytes(float32(fullClientDB.TotalUploadedBytes)) fullClientDB.UploadRatio = CalculateUploadRatio(singleTorrent, fullClientDB) //calculate the upload ratio @@ -343,3 +345,19 @@ func CreateTorrentDetailJSON(tclient *torrent.Client, selectedHash string, torre } return TorrentDetailStruct } + +func ChangeStorageLocation(newStorageLocation string, torrentHashes []string, db *storm.DB) { + + for _, torrentHash := range torrentHashes { + var selectedTorrent Storage.TorrentLocal + err := db.Find("TorrentLocal", torrentHash, &selectedTorrent) + if err != nil { + Logger.WithFields(logrus.Fields{"torrentHash": torrentHash}).Error("Unable to find torrent in db to update!") + CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Failed to change Storage Location"}, Conn) + } + fmt.Printf("%+v\n", selectedTorrent) + db.UpdateField(&selectedTorrent{Hash: torrentHash}, "StoragePath", newStorageLocation) + + } + +} diff --git a/goTorrentWebUI/src/BackendComm/backendWebsocket.js b/goTorrentWebUI/src/BackendComm/backendWebsocket.js index 252f78c5..228fe506 100644 --- a/goTorrentWebUI/src/BackendComm/backendWebsocket.js +++ b/goTorrentWebUI/src/BackendComm/backendWebsocket.js @@ -61,6 +61,7 @@ ws.onmessage = function (evt) { //When we recieve a message from the websocket FileNumber: serverMessage.data[i].NumberofFiles, PieceNumber: serverMessage.data[i].NumberofPieces, MaxConnections: serverMessage.data[i].MaxConnections, + Label: serverMessage.data[i].TorrentLabel, }) } var newTitle = '(' + serverMessage.total + ')' + title; //updating the title diff --git a/goTorrentWebUI/src/BottomMenu/Tabs/generalTab.js b/goTorrentWebUI/src/BottomMenu/Tabs/generalTab.js index 4f6cd853..813aec3d 100644 --- a/goTorrentWebUI/src/BottomMenu/Tabs/generalTab.js +++ b/goTorrentWebUI/src/BottomMenu/Tabs/generalTab.js @@ -64,7 +64,7 @@ class GeneralTab extends React.Component { Storage Path: {this.state.selectedTorrent["StoragePath"]} Date Added: {this.state.selectedTorrent["DateAdded"]} Source Type: {this.state.selectedTorrent["SourceType"]} - Label: None + Label: {this.state.selectedTorrent["TorrentLabel"]} Torrent Hash: {this.state.selectedTorrent["TorrentHashString"]} @@ -82,8 +82,6 @@ class GeneralTab extends React.Component { Number of Files: {this.state.selectedTorrent["FileNumber"]} Number of Pieces: {this.state.selectedTorrent["PieceNumber"]} - - diff --git a/goTorrentWebUI/src/TopMenu/Modals/RSSModal/addRSSModal.js b/goTorrentWebUI/src/TopMenu/Modals/RSSModal/addRSSModal.js index dac30ed0..e61f5ee2 100644 --- a/goTorrentWebUI/src/TopMenu/Modals/RSSModal/addRSSModal.js +++ b/goTorrentWebUI/src/TopMenu/Modals/RSSModal/addRSSModal.js @@ -74,7 +74,6 @@ const inlineStyle = { ); } - }; diff --git a/goTorrentWebUI/src/TopMenu/Modals/addTorrentFileModal.js b/goTorrentWebUI/src/TopMenu/Modals/addTorrentFileModal.js index 8b50145a..8de049b4 100644 --- a/goTorrentWebUI/src/TopMenu/Modals/addTorrentFileModal.js +++ b/goTorrentWebUI/src/TopMenu/Modals/addTorrentFileModal.js @@ -46,6 +46,7 @@ export default class addTorrentFilePopup extends React.Component { torrentFileValue: [], storageValue: ``, //raw string for possible windows filepath showDrop: true, + torrentLabel: "", }; handleClickOpen = () => { @@ -68,8 +69,9 @@ export default class addTorrentFilePopup extends React.Component { let torrentFileMessage = { messageType: "torrentFileSubmit", - messageDetail: this.state.torrentFileName, - messageDetailTwo: this.state.storageValue, + torrentFileName: this.state.torrentFileName, + torrentStorageValue : this.state.storageValue, + torrentLabelValue: this.state.torrentLabel, Payload: [base64data], } console.log("Sending magnet link: ", torrentFileMessage); @@ -85,7 +87,9 @@ export default class addTorrentFilePopup extends React.Component { console.log("File Name", file[0].name) } - + setLabelValue = (event) => { + this.setState({torrentLabel: event.target.value}) + } setStorageValue = (event) => { this.setState({storageValue: event.target.value}) @@ -114,6 +118,7 @@ export default class addTorrentFilePopup extends React.Component { this.state.torrentFileName } + + + + + + ); + } +}; + + +const mapStateToProps = state => { + return { + selectionHashes: state.selectionHashes, + selection: state.selection, + }; + } + + + + +export default connect(mapStateToProps)(BackendSocket); \ No newline at end of file diff --git a/main.go b/main.go index 2f073cbd..0bc12eff 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,7 @@ type SingleRSSFeedMessage struct { //TODO had issues with getting this to work w URL string //the URL of the individual RSS feed Name string TotalTorrents int - Torrents []Storage.SingleRSSTorrent //name of the torrentss + Torrents []Storage.SingleRSSTorrent //name of the torrents } var ( @@ -168,7 +168,6 @@ func main() { case "torrentDetailedInfo": Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested TorrentListDetail Update") - torrentDetailArray := Engine.CreateTorrentDetailJSON(tclient, msg.Payload[0], db) conn.WriteJSON(torrentDetailArray) @@ -177,6 +176,19 @@ func main() { torrentPeerList := Engine.CreatePeerListArray(tclient, msg.Payload[0]) conn.WriteJSON(torrentPeerList) + case "changeStorageValue": + Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested Storage Location Update") + newStorageLocation := msg.MessageDetail + hashes := msg.Payload + for _, singleHash := range hashes { + singleTorrent := Storage.FetchTorrentFromStorage(db, singleHash) + singleTorrent.StoragePath = newStorageLocation + Storage.UpdateStorageTick(db, singleTorrent) //push torrent to storage + if singleTorrent.TorrentMoved == true { //If torrent has already been moved and I change path then move it again... TODO, does this work with symlinks? + Engine.MoveAndLeaveSymlink(Config, singleHash, db) + } + } + case "settingsFileRequest": Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested Settings File") clientSettingsFile, err := json.Marshal(Config) @@ -246,6 +258,7 @@ func main() { case "magnetLinkSubmit": //if we detect a magnet link we will be adding a magnet torrent storageValue := msg.MessageDetail + labelValue := msg.MessageDetailTwo if storageValue == "" { storageValue, err = filepath.Abs(filepath.ToSlash(Config.DefaultMoveFolder)) if err != nil { @@ -268,7 +281,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) - Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "magnet", "", storageValue) //starting the torrent and creating local DB entry + Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "magnet", "", storageValue, labelValue) //starting the torrent and creating local DB entry } @@ -282,6 +295,7 @@ func main() { } FileName := msg.MessageDetail storageValue := msg.MessageDetailTwo + labelValue := msg.MessageDetailThree if storageValue == "" { storageValue, err = filepath.Abs(filepath.ToSlash(Config.DefaultMoveFolder)) if err != nil { @@ -310,7 +324,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": filePath}).Info("Added torrent") - Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "file", filePath, storageValue) + Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "file", filePath, storageValue, labelValue) case "stopTorrents": TorrentListCommands := msg.Payload diff --git a/public/static/js/bundle.js b/public/static/js/bundle.js index 59fc3ca8..9e81b798 100644 --- a/public/static/js/bundle.js +++ b/public/static/js/bundle.js @@ -87004,7 +87004,8 @@ var addTorrentPopup = function (_React$Component) { return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = addTorrentPopup.__proto__ || Object.getPrototypeOf(addTorrentPopup)).call.apply(_ref, [this].concat(args))), _this), _this.state = { open: false, magnetLinkValue: "", - storageValue: '' + storageValue: '', + torrentLabel: "" }, _this.handleClickOpen = function () { _this.setState({ open: true }); @@ -87015,7 +87016,8 @@ var addTorrentPopup = function (_React$Component) { //let magnetLinkSubmit = this.state.textValue; var magnetLinkMessage = { messageType: "magnetLinkSubmit", - messageDetail: _this.state.storageValue, + storageValue: _this.state.storageValue, + torrentLabel: _this.state.torrentLabel, Payload: [_this.state.magnetLinkValue] }; console.log("Sending magnet link: ", magnetLinkMessage); @@ -87027,6 +87029,8 @@ var addTorrentPopup = function (_React$Component) { _this.setState({ magnetLinkValue: event.target.value }); }, _this.setStorageValue = function (event) { _this.setState({ storageValue: event.target.value }); + }, _this.setLabelValue = function (event) { + _this.setState({ torrentLabel: event.target.value }); }, _temp), _possibleConstructorReturn(_this, _ret); } @@ -87074,7 +87078,8 @@ var addTorrentPopup = function (_React$Component) { fullWidth: true, onChange: this.setMagnetLinkValue }), - _react2.default.createElement(_TextField2.default, { id: 'storagePath', type: 'text', label: 'Storage Path', placeholder: 'Empty will be default torrent storage path', fullWidth: true, onChange: this.setStorageValue }) + _react2.default.createElement(_TextField2.default, { id: 'storagePath', type: 'text', label: 'Storage Path', placeholder: 'Empty will be default torrent storage path', fullWidth: true, onChange: this.setStorageValue }), + _react2.default.createElement(_TextField2.default, { id: 'labelValue', type: 'text', label: 'Label Value', placeholder: 'Empty will be no label', fullWidth: true, onChange: this.setLabelValue }) ), _react2.default.createElement( _Dialog.DialogActions, @@ -95273,7 +95278,8 @@ var addTorrentFilePopup = function (_React$Component) { torrentFileName: "", torrentFileValue: [], storageValue: '', //raw string for possible windows filepath - showDrop: true + showDrop: true, + torrentLabel: "" }, _this.handleClickOpen = function () { _this.setState({ open: true }); }, _this.handleRequestClose = function () { @@ -95290,8 +95296,9 @@ var addTorrentFilePopup = function (_React$Component) { var torrentFileMessage = { messageType: "torrentFileSubmit", - messageDetail: _this.state.torrentFileName, - messageDetailTwo: _this.state.storageValue, + torrentFileName: _this.state.torrentFileName, + torrentStorageValue: _this.state.storageValue, + torrentLabelValue: _this.state.torrentLabel, Payload: [base64data] }; console.log("Sending magnet link: ", torrentFileMessage); @@ -95303,6 +95310,8 @@ var addTorrentFilePopup = function (_React$Component) { _this.setState({ showDrop: false }); _this.setState({ torrentFileValue: file }); console.log("File Name", file[0].name); + }, _this.setLabelValue = function (event) { + _this.setState({ torrentLabel: event.target.value }); }, _this.setStorageValue = function (event) { _this.setState({ storageValue: event.target.value }); }, _temp), _possibleConstructorReturn(_this, _ret); @@ -95344,7 +95353,8 @@ var addTorrentFilePopup = function (_React$Component) { 'Upload Torrent Here and Add Storage Path' ), this.state.torrentFileName != "" && this.state.torrentFileName, - _react2.default.createElement(_TextField2.default, { id: 'storagePath', type: 'text', label: 'Storage Path', placeholder: 'Empty will be default torrent storage path', fullWidth: true, onChange: this.setStorageValue }) + _react2.default.createElement(_TextField2.default, { id: 'storagePath', type: 'text', label: 'Storage Path', placeholder: 'Empty will be default torrent storage path', fullWidth: true, onChange: this.setStorageValue }), + _react2.default.createElement(_TextField2.default, { id: 'labelValue', type: 'text', label: 'Label Value', placeholder: 'Empty will be no label', fullWidth: true, onChange: this.setLabelValue }) ), _react2.default.createElement( _Dialog.DialogActions, @@ -129840,13 +129850,11 @@ var mapStateToProps = function mapStateToProps(state) { return { selectionHashes: state.selectionHashes, fileList: state.fileList - //fileSelectionNames: state.fileSelectionNames, }; }; var mapDispatchToProps = function mapDispatchToProps(dispatch) { return { - //changeFileSelection: (fileSelection) => dispatch({type: actionTypes.CHANGE_FILE_SELECTION, fileSelection}), sendSelectionHashes: function sendSelectionHashes(selectionHashes) { return dispatch({ type: actionTypes.SELECTION_HASHES, selectionHashes: selectionHashes }); } diff --git a/storage/storage.go b/storage/storage.go index 9556db32..24074a69 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -53,10 +53,10 @@ type TorrentLocal struct { MaxConnections int TorrentType string //magnet or .torrent file TorrentFileName string - TorrentFile []byte //TODO store and reteive torrent file from here - Label string //for labeling torrent files + TorrentFile []byte + Label string UploadedBytes int64 - DownloadedBytes int64 //TODO not sure if needed since we should have the file which contains the bytes + DownloadedBytes int64 UploadRatio string TorrentFilePriority []TorrentFilePriority }