testing rate limiting, making API changes
This commit is contained in:
16
config.toml
16
config.toml
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
ServerPort = ":8000" #leave format as is it expects a string with colon
|
ServerPort = ":8000" #leave format as is it expects a string with colon
|
||||||
ServerAddr = "" #blank will bind to default IP address, usually fine to leave be
|
ServerAddr = "" #blank will bind to default IP address, usually fine to leave be
|
||||||
LogLevel = "Warn" # Options = Debug, Info, Warn, Error, Fatal, Panic
|
LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic
|
||||||
LogOutput = "file" #Options = file, stdout #file will print it to logs/server.log
|
LogOutput = "file" #Options = file, stdout #file will print it to logs/server.log
|
||||||
|
|
||||||
SeedRatioStop = 1.50 #automatically stops the torrent after it reaches this seeding ratio
|
SeedRatioStop = 1.50 #automatically stops the torrent after it reaches this seeding ratio
|
||||||
@@ -11,10 +11,15 @@
|
|||||||
DefaultMoveFolder = 'downloaded' #default path that a finished torrent is symlinked to after completion. Torrents added via RSS will default here
|
DefaultMoveFolder = 'downloaded' #default path that a finished torrent is symlinked to after completion. Torrents added via RSS will default here
|
||||||
TorrentWatchFolder = 'torrentUpload' #folder path that is watched for .torrent files and adds them automatically every 5 minutes
|
TorrentWatchFolder = 'torrentUpload' #folder path that is watched for .torrent files and adds them automatically every 5 minutes
|
||||||
|
|
||||||
|
#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"
|
||||||
|
|
||||||
|
|
||||||
[notifications]
|
[notifications]
|
||||||
|
|
||||||
PushBulletToken = "" #add your pushbullet api token here to notify of torrent completion to pushbullet
|
PushBulletToken = "o.QW6G7F6FUOKXCUKmw948fBceCUn0msFi" #add your pushbullet api token here to notify of torrent completion to pushbullet
|
||||||
|
|
||||||
|
|
||||||
[EncryptionPolicy]
|
[EncryptionPolicy]
|
||||||
@@ -43,13 +48,6 @@
|
|||||||
# Don't create a DHT.
|
# Don't create a DHT.
|
||||||
NoDHT = false #boolean
|
NoDHT = false #boolean
|
||||||
|
|
||||||
# Events are data bytes sent in pieces. The burst must be large enough to fit a whole chunk.
|
|
||||||
UploadRateLimiter = "" #*rate.Limiter
|
|
||||||
|
|
||||||
#The events are bytes read from connections. The burst must be biggerthan the largest Read performed on a Conn minus one. This is likely to
|
|
||||||
#be the larger of the main read loop buffer (~4096), and the requested chunk size (~16KiB).
|
|
||||||
DownloadRateLimiter = "" #*rate.Limiter
|
|
||||||
|
|
||||||
#User-provided Client peer ID. If not present, one is generated automatically.
|
#User-provided Client peer ID. If not present, one is generated automatically.
|
||||||
PeerID = "" #string
|
PeerID = "" #string
|
||||||
|
|
||||||
|
Binary file not shown.
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
//All the message types are first, first the server handling messages from the client
|
//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 un-marshalls the actual message once we know the type
|
//Message contains the JSON messages from the client, we first unmarshal to get the messagetype, then pass it on to each module
|
||||||
type Message struct {
|
type Message struct {
|
||||||
MessageType string
|
MessageType string
|
||||||
MessageDetail string `json:",omitempty"`
|
MessageDetail string `json:",omitempty"`
|
||||||
|
@@ -2,7 +2,6 @@ package engine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/anacrolix/torrent"
|
"github.com/anacrolix/torrent"
|
||||||
@@ -32,18 +31,25 @@ func CheckTorrentWatchFolder(c *cron.Cron, db *storm.DB, tclient *torrent.Client
|
|||||||
for _, file := range torrentFiles {
|
for _, file := range torrentFiles {
|
||||||
if filepath.Ext(file.Name()) != ".torrent" {
|
if filepath.Ext(file.Name()) != ".torrent" {
|
||||||
Logger.WithFields(logrus.Fields{"File": file.Name(), "error": err}).Error("Not a torrent file..")
|
Logger.WithFields(logrus.Fields{"File": file.Name(), "error": err}).Error("Not a torrent file..")
|
||||||
|
continue
|
||||||
} else {
|
} else {
|
||||||
fullFilePath := filepath.Join(config.TorrentWatchFolder, file.Name())
|
fullFilePath := filepath.Join(config.TorrentWatchFolder, file.Name())
|
||||||
clientTorrent, err := tclient.AddTorrentFromFile(fullFilePath)
|
fullFilePathAbs, err := filepath.Abs(fullFilePath)
|
||||||
|
|
||||||
|
fullNewFilePath := filepath.Join(config.TFileUploadFolder, file.Name())
|
||||||
|
fullNewFilePathAbs, err := filepath.Abs(fullNewFilePath)
|
||||||
|
Logger.WithFields(logrus.Fields{"Name": file.Name(), "FullFilePath": fullFilePathAbs, "newFullFilePath": fullNewFilePathAbs}).Info("Attempting to add the following file... and copy to")
|
||||||
|
CopyFile(fullFilePathAbs, fullNewFilePathAbs)
|
||||||
|
clientTorrent, err := tclient.AddTorrentFromFile(fullNewFilePathAbs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"err": err, "Torrent": file.Name()}).Warn("Unable to add torrent to torrent client!")
|
Logger.WithFields(logrus.Fields{"err": err, "Torrent": file.Name()}).Warn("Unable to add torrent to torrent client!")
|
||||||
break //break out of the loop entirely for this message since we hit an error
|
continue
|
||||||
}
|
}
|
||||||
fullNewFilePath := filepath.Join(config.TFileUploadFolder, file.Name())
|
|
||||||
StartTorrent(clientTorrent, torrentLocalStorage, db, config.TorrentConfig.DataDir, "file", file.Name(), config.DefaultMoveFolder, "default")
|
//os.Remove(fullFilePathAbs) //delete the torrent after adding it and copying it over
|
||||||
CopyFile(fullFilePath, fullNewFilePath)
|
Logger.WithFields(logrus.Fields{"Source Folder": fullFilePathAbs, "Destination Folder": fullNewFilePathAbs, "Torrent": file.Name()}).Info("Added torrent from watch folder, and moved torrent file")
|
||||||
os.Remove(fullFilePath) //delete the torrent after adding it and copying it over
|
StartTorrent(clientTorrent, torrentLocalStorage, db, config.TorrentConfig.DataDir, "file", file.Name(), config.DefaultMoveFolder, "default", config.TFileUploadFolder)
|
||||||
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 +84,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!")
|
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
|
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, "RSS") //TODO let user specify torrent default storage location and let change on fly
|
StartTorrent(clientTorrent, torrentLocalStorage, db, config.TorrentConfig.DataDir, "magnet", "", config.DefaultMoveFolder, "RSS", config.TFileUploadFolder) //TODO let user specify torrent default storage location and let change on fly
|
||||||
singleFeed.Torrents = append(singleFeed.Torrents, singleRSSTorrent)
|
singleFeed.Torrents = append(singleFeed.Torrents, singleRSSTorrent)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -15,12 +16,32 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//MoveAndLeaveSymlink takes the file from the default download dir and moves it to the user specified directory and then leaves a symlink behind.
|
//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, tHash string, db *storm.DB) {
|
func MoveAndLeaveSymlink(config FullClientSettings, tHash string, db *storm.DB, moveDone bool, oldPath string) { //moveDone and oldPath are for moving a completed torrent
|
||||||
tStorage := Storage.FetchTorrentFromStorage(db, tHash)
|
tStorage := Storage.FetchTorrentFromStorage(db, tHash)
|
||||||
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentFileName}).Info("Move and Create symlink started for torrent")
|
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName}).Info("Move and Create symlink started for torrent")
|
||||||
oldFilePath := filepath.Join(config.TorrentConfig.DataDir, tStorage.TorrentFileName)
|
var oldFilePath string
|
||||||
newFilePath := filepath.Join(tStorage.StoragePath, tStorage.TorrentFileName)
|
if moveDone {
|
||||||
_, err := os.Stat(tStorage.StoragePath)
|
oldFilePathTemp := filepath.Join(oldPath, tStorage.TorrentName)
|
||||||
|
oldFilePath, err := filepath.Abs(oldFilePathTemp)
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": oldFilePath}).Error("Cannot create absolute file path!")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("oldfilepath", oldFilePath)
|
||||||
|
} else {
|
||||||
|
oldFilePathTemp := filepath.Join(config.TorrentConfig.DataDir, tStorage.TorrentName)
|
||||||
|
oldFilePath, err := filepath.Abs(oldFilePathTemp)
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": oldFilePath}).Error("Cannot create absolute file path!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newFilePathTemp := filepath.Join(tStorage.StoragePath, tStorage.TorrentName)
|
||||||
|
newFilePath, err := filepath.Abs(newFilePathTemp)
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": newFilePath}).Error("Cannot create absolute file path for new file path!")
|
||||||
|
}
|
||||||
|
_, err = os.Stat(tStorage.StoragePath)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err := os.MkdirAll(tStorage.StoragePath, 0755)
|
err := os.MkdirAll(tStorage.StoragePath, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -29,7 +50,7 @@ func MoveAndLeaveSymlink(config FullClientSettings, tHash string, db *storm.DB)
|
|||||||
}
|
}
|
||||||
oldFileInfo, err := os.Stat(oldFilePath)
|
oldFileInfo, err := os.Stat(oldFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"Old File info": oldFileInfo, "error": err}).Error("Cannot find the old file to copy/symlink!")
|
Logger.WithFields(logrus.Fields{"Old File info": oldFileInfo, "Old File Path": oldFilePath, "error": err}).Error("Cannot find the old file to copy/symlink!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +58,18 @@ func MoveAndLeaveSymlink(config FullClientSettings, tHash string, db *storm.DB)
|
|||||||
if runtime.GOOS == "windows" { //TODO the windows symlink is broken on windows 10 creator edition, so doing a copy for now until Go 1.11
|
if runtime.GOOS == "windows" { //TODO the windows symlink is broken on windows 10 creator edition, so doing a copy for now until Go 1.11
|
||||||
if oldFileInfo.IsDir() {
|
if oldFileInfo.IsDir() {
|
||||||
os.Mkdir(newFilePath, 0755)
|
os.Mkdir(newFilePath, 0755)
|
||||||
folderCopy.Copy(oldFilePath, newFilePath) //copy the folder to the new location
|
if moveDone {
|
||||||
|
err := folderCopy.Copy(config.TorrentConfig.DataDir, newFilePath)
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"Old File Path": config.TorrentConfig.DataDir, "New File Path": newFilePath, "error": err}).Error("Error Copying Folder!")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := folderCopy.Copy(oldFilePath, newFilePath) //copy the folder to the new location
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error Copying Folder!")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
os.Chmod(newFilePath, 0777)
|
os.Chmod(newFilePath, 0777)
|
||||||
notifyUser(tStorage, config, db)
|
notifyUser(tStorage, config, db)
|
||||||
return
|
return
|
||||||
@@ -67,14 +99,23 @@ func MoveAndLeaveSymlink(config FullClientSettings, tHash string, db *storm.DB)
|
|||||||
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "bytesWritten": bytesWritten}).Info("Windows Torrent Copy Completed")
|
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "bytesWritten": bytesWritten}).Info("Windows Torrent Copy Completed")
|
||||||
notifyUser(tStorage, config, db)
|
notifyUser(tStorage, config, db)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
folderCopy.Copy(oldFilePath, newFilePath)
|
folderCopy.Copy(oldFilePath, newFilePath)
|
||||||
os.Chmod(newFilePath, 0777) //changing permissions on the new file to be permissive
|
os.Chmod(newFilePath, 0777) //changing permissions on the new file to be permissive
|
||||||
os.RemoveAll(oldFilePath)
|
os.RemoveAll(oldFilePath)
|
||||||
|
if moveDone {
|
||||||
|
err := os.Symlink(newFilePath, config.TorrentConfig.DataDir)
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"Old File Path": config.TorrentConfig.DataDir, "New File Path": newFilePath, "error": err}).Error("Error creating symlink")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
err := os.Symlink(newFilePath, oldFilePath) //For all other OS's create a symlink
|
err := os.Symlink(newFilePath, oldFilePath) //For all other OS's create a symlink
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error creating symlink")
|
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error creating symlink")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
notifyUser(tStorage, config, db)
|
notifyUser(tStorage, config, db)
|
||||||
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath}).Info("Moving completed torrent")
|
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath}).Info("Moving completed torrent")
|
||||||
}
|
}
|
||||||
@@ -83,20 +124,21 @@ func MoveAndLeaveSymlink(config FullClientSettings, tHash string, db *storm.DB)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func notifyUser(tStorage Storage.TorrentLocal, config FullClientSettings, db *storm.DB) {
|
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..")
|
Logger.WithFields(logrus.Fields{"New File Path": tStorage.StoragePath, "Torrent Name": tStorage.TorrentName}).Info("Attempting to notify user..")
|
||||||
tStorage.TorrentMoved = true
|
tStorage.TorrentMoved = true
|
||||||
Storage.AddTorrentLocalStorage(db, tStorage) //Updating the fact that we moved the torrent
|
//Storage.AddTorrentLocalStorage(db, tStorage) //Updating the fact that we moved the torrent
|
||||||
|
Storage.UpdateStorageTick(db, tStorage)
|
||||||
if config.PushBulletToken != "" {
|
if config.PushBulletToken != "" {
|
||||||
pb := pushbullet.New(config.PushBulletToken)
|
pb := pushbullet.New(config.PushBulletToken)
|
||||||
n := requests.NewNote()
|
n := requests.NewNote()
|
||||||
n.Title = tStorage.TorrentFileName
|
n.Title = tStorage.TorrentName
|
||||||
n.Body = "Completed and moved to " + tStorage.StoragePath
|
n.Body = "Completed and moved to " + tStorage.StoragePath
|
||||||
if _, err := pb.PostPushesNote(n); err != nil {
|
if _, err := pb.PostPushesNote(n); err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"Torrent": tStorage.TorrentFileName, "New File Path": tStorage.StoragePath, "error": err}).Error("Error pushing PushBullet Note")
|
Logger.WithFields(logrus.Fields{"Torrent": tStorage.TorrentName, "New File Path": tStorage.StoragePath, "error": err}).Error("Error pushing PushBullet Note")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Logger.WithFields(logrus.Fields{"Torrent": tStorage.TorrentFileName, "New File Path": tStorage.StoragePath}).Info("Pushbullet note sent")
|
Logger.WithFields(logrus.Fields{"Torrent": tStorage.TorrentName, "New File Path": tStorage.StoragePath}).Info("Pushbullet note sent")
|
||||||
} else {
|
} else {
|
||||||
Logger.WithFields(logrus.Fields{"New File Path": tStorage.StoragePath, "Torrent Name": tStorage.TorrentFileName}).Info("No pushbullet API key set, not notifying")
|
Logger.WithFields(logrus.Fields{"New File Path": tStorage.StoragePath, "Torrent Name": tStorage.TorrentName}).Info("No pushbullet API key set, not notifying")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -96,15 +96,17 @@ func timeOutInfo(clientTorrent *torrent.Torrent, seconds time.Duration) (deleted
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func readTorrentFileFromDB(element *Storage.TorrentLocal, tclient *torrent.Client, db *storm.DB) (singleTorrent *torrent.Torrent) {
|
func readTorrentFileFromDB(element *Storage.TorrentLocal, tclient *torrent.Client, db *storm.DB) (singleTorrent *torrent.Torrent, err error) {
|
||||||
tempFile, err := ioutil.TempFile("", "TorrentFileTemp")
|
tempFile, err := ioutil.TempFile("", "TorrentFileTemp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"tempfile": tempFile, "err": err}).Error("Unable to create tempfile")
|
Logger.WithFields(logrus.Fields{"tempfile": tempFile, "err": err}).Error("Unable to create tempfile")
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
//defer tempFile.Close() //Todo.. if we remove this do we need to close it?
|
//defer tempFile.Close() //Todo.. if we remove this do we need to close it?
|
||||||
defer os.Remove(tempFile.Name())
|
defer os.Remove(tempFile.Name())
|
||||||
if _, err := tempFile.Write(element.TorrentFile); err != nil { //writing out out the entire file back into the temp dir from boltdb
|
if _, err := tempFile.Write(element.TorrentFile); err != nil { //writing out out the entire file back into the temp dir from boltdb
|
||||||
Logger.WithFields(logrus.Fields{"tempfile": tempFile, "err": err}).Error("Unable to write to tempfile")
|
Logger.WithFields(logrus.Fields{"tempfile": tempFile, "err": err}).Error("Unable to write to tempfile")
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := tempFile.Close(); err != nil { //close the tempfile so that we can add it back into the torrent client
|
if err := tempFile.Close(); err != nil { //close the tempfile so that we can add it back into the torrent client
|
||||||
Logger.WithFields(logrus.Fields{"tempfile": tempFile, "err": err}).Error("Unable to close tempfile")
|
Logger.WithFields(logrus.Fields{"tempfile": tempFile, "err": err}).Error("Unable to close tempfile")
|
||||||
@@ -112,18 +114,21 @@ func readTorrentFileFromDB(element *Storage.TorrentLocal, tclient *torrent.Clien
|
|||||||
_, err = os.Stat(element.TorrentFileName) //if we CAN find the torrent, add it
|
_, err = os.Stat(element.TorrentFileName) //if we CAN find the torrent, add it
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"tempfile": tempFile, "err": err}).Error("Unable to find file")
|
Logger.WithFields(logrus.Fields{"tempfile": tempFile, "err": err}).Error("Unable to find file")
|
||||||
|
Storage.DelTorrentLocalStorage(db, element.Hash) //purge the torrent
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
singleTorrent, err = tclient.AddTorrentFromFile(element.TorrentFileName)
|
singleTorrent, err = tclient.AddTorrentFromFile(element.TorrentFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"tempfile": element.TorrentFileName, "err": err}).Error("Unable to add Torrent from file!")
|
Logger.WithFields(logrus.Fields{"tempfile": element.TorrentFileName, "err": err}).Error("Unable to add Torrent from file!")
|
||||||
CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to add Torrent from file!"}, Conn)
|
CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to add Torrent from file!"}, Conn)
|
||||||
|
Storage.DelTorrentLocalStorage(db, element.Hash) //purge the torrent
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return singleTorrent
|
return singleTorrent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//StartTorrent creates the storage.db entry and starts A NEW TORRENT and adds to the running torrent array
|
//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, labelValue string) {
|
func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.TorrentLocal, torrentDbStorage *storm.DB, dataDir, torrentType, torrentFileName, torrentStoragePath, labelValue, tFileUploadFolder string) {
|
||||||
timedOut := timeOutInfo(clientTorrent, 45) //seeing if adding the torrent times out (giving 45 seconds)
|
timedOut := timeOutInfo(clientTorrent, 45) //seeing if adding the torrent times out (giving 45 seconds)
|
||||||
if timedOut { //if we fail to add the torrent return
|
if timedOut { //if we fail to add the torrent return
|
||||||
return
|
return
|
||||||
@@ -143,11 +148,16 @@ func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.To
|
|||||||
torrentLocalStorage.DateAdded = time.Now().Format("Jan _2 2006")
|
torrentLocalStorage.DateAdded = time.Now().Format("Jan _2 2006")
|
||||||
torrentLocalStorage.StoragePath = torrentStoragePath
|
torrentLocalStorage.StoragePath = torrentStoragePath
|
||||||
torrentLocalStorage.TorrentName = clientTorrent.Name()
|
torrentLocalStorage.TorrentName = clientTorrent.Name()
|
||||||
|
torrentLocalStorage.TorrentUploadLimit = true //by default all of the torrents will stop uploading after the global rate is set.
|
||||||
|
torrentLocalStorage.TorrentMoved = false //by default the torrent has no been moved.
|
||||||
torrentLocalStorage.TorrentStatus = "Running" //by default start all the torrents as downloading.
|
torrentLocalStorage.TorrentStatus = "Running" //by default start all the torrents as downloading.
|
||||||
torrentLocalStorage.TorrentType = torrentType //either "file" or "magnet" maybe more in the future
|
torrentLocalStorage.TorrentType = torrentType //either "file" or "magnet" maybe more in the future
|
||||||
|
torrentLocalStorage.TorrentSize = clientTorrent.Length() //Length will change as we cancel files so store it in DB
|
||||||
if torrentType == "file" { //if it is a file read the entire file into the database for us to spit out later
|
if torrentType == "file" { //if it is a file read the entire file into the database for us to spit out later
|
||||||
torrentLocalStorage.TorrentFileName = torrentFileName
|
torrentFilePath := filepath.Join(tFileUploadFolder, torrentFileName)
|
||||||
torrentfile, err := ioutil.ReadFile(torrentFileName)
|
torrentFilePathAbs, err := filepath.Abs(torrentFilePath)
|
||||||
|
torrentfile, err := ioutil.ReadFile(torrentFilePathAbs)
|
||||||
|
torrentLocalStorage.TorrentFileName = torrentFilePathAbs
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"torrentFile": torrentfile, "error": err}).Error("Unable to read the torrent file")
|
Logger.WithFields(logrus.Fields{"torrentFile": torrentfile, "error": err}).Error("Unable to read the torrent file")
|
||||||
}
|
}
|
||||||
@@ -182,7 +192,11 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
|||||||
//singleTorrentStorageInfo := Storage.FetchTorrentFromStorage(db, TempHash.String()) //pulling the single torrent info from storage ()
|
//singleTorrentStorageInfo := Storage.FetchTorrentFromStorage(db, TempHash.String()) //pulling the single torrent info from storage ()
|
||||||
|
|
||||||
if singleTorrentFromStorage.TorrentType == "file" { //if it is a file pull it from the uploaded torrent folder
|
if singleTorrentFromStorage.TorrentType == "file" { //if it is a file pull it from the uploaded torrent folder
|
||||||
singleTorrent = readTorrentFileFromDB(singleTorrentFromStorage, tclient, db)
|
var err error
|
||||||
|
singleTorrent, err = readTorrentFileFromDB(singleTorrentFromStorage, tclient, db)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
fullClientDB.SourceType = "Torrent File"
|
fullClientDB.SourceType = "Torrent File"
|
||||||
} else {
|
} else {
|
||||||
singleTorrentFromStorageMagnet := "magnet:?xt=urn:btih:" + singleTorrentFromStorage.Hash //For magnet links just need to prepend the magnet part to the hash to readd
|
singleTorrentFromStorageMagnet := "magnet:?xt=urn:btih:" + singleTorrentFromStorage.Hash //For magnet links just need to prepend the magnet part to the hash to readd
|
||||||
@@ -204,26 +218,22 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
|||||||
}
|
}
|
||||||
//Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Generating infohash")
|
//Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Generating infohash")
|
||||||
TempHash = singleTorrent.InfoHash()
|
TempHash = singleTorrent.InfoHash()
|
||||||
|
if (singleTorrent.BytesCompleted() == singleTorrentFromStorage.TorrentSize) && (singleTorrentFromStorage.TorrentMoved == false) { //if we are done downloading and haven't moved torrent yet
|
||||||
if (singleTorrent.BytesCompleted() == singleTorrent.Length()) && (singleTorrentFromStorage.TorrentMoved == false) { //if we are done downloading and haven't moved torrent yet
|
Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Torrent Completed, moving...")
|
||||||
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
|
MoveAndLeaveSymlink(config, singleTorrent.InfoHash().String(), db, false, "") //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()
|
fullStruct := singleTorrent.Stats()
|
||||||
|
|
||||||
activePeersString := strconv.Itoa(fullStruct.ActivePeers) //converting to strings
|
activePeersString := strconv.Itoa(fullStruct.ActivePeers) //converting to strings
|
||||||
totalPeersString := fmt.Sprintf("%v", fullStruct.TotalPeers)
|
totalPeersString := fmt.Sprintf("%v", fullStruct.TotalPeers)
|
||||||
//fetching all the info from the database
|
fullClientDB.StoragePath = singleTorrentFromStorage.StoragePath
|
||||||
|
|
||||||
fullClientDB.StoragePath = singleTorrentFromStorage.StoragePath //grabbed from database
|
|
||||||
|
|
||||||
downloadedSizeHumanized := HumanizeBytes(float32(singleTorrent.BytesCompleted())) //convert size to GB if needed
|
downloadedSizeHumanized := HumanizeBytes(float32(singleTorrent.BytesCompleted())) //convert size to GB if needed
|
||||||
totalSizeHumanized := HumanizeBytes(float32(singleTorrent.Length()))
|
|
||||||
//Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Generated infohash")
|
totalSizeHumanized := HumanizeBytes(float32(singleTorrentFromStorage.TorrentSize))
|
||||||
//grabbed from torrent client
|
|
||||||
fullClientDB.DownloadedSize = downloadedSizeHumanized
|
fullClientDB.DownloadedSize = downloadedSizeHumanized
|
||||||
fullClientDB.Size = totalSizeHumanized
|
fullClientDB.Size = totalSizeHumanized
|
||||||
PercentDone := fmt.Sprintf("%.2f", float32(singleTorrent.BytesCompleted())/float32(singleTorrent.Length()))
|
PercentDone := fmt.Sprintf("%.2f", float32(singleTorrent.BytesCompleted())/float32(singleTorrentFromStorage.TorrentSize))
|
||||||
fullClientDB.TorrentHash = TempHash
|
fullClientDB.TorrentHash = TempHash
|
||||||
fullClientDB.PercentDone = PercentDone
|
fullClientDB.PercentDone = PercentDone
|
||||||
fullClientDB.DataBytesRead = fullStruct.ConnStats.DataBytesRead //used for calculations not passed to client calculating up/down speed
|
fullClientDB.DataBytesRead = fullStruct.ConnStats.DataBytesRead //used for calculations not passed to client calculating up/down speed
|
||||||
@@ -237,8 +247,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
|||||||
fullClientDB.BytesCompleted = singleTorrent.BytesCompleted()
|
fullClientDB.BytesCompleted = singleTorrent.BytesCompleted()
|
||||||
fullClientDB.NumberofFiles = len(singleTorrent.Files())
|
fullClientDB.NumberofFiles = len(singleTorrent.Files())
|
||||||
|
|
||||||
//ranging over the previous torrent array to calculate the speed for each torrent
|
if len(PreviousTorrentArray) > 0 { //if we actually have a previous array //ranging over the previous torrent array to calculate the speed for each torrent
|
||||||
if len(PreviousTorrentArray) > 0 { //if we actually have a previous array
|
|
||||||
for _, previousElement := range PreviousTorrentArray {
|
for _, previousElement := range PreviousTorrentArray {
|
||||||
TempHash := singleTorrent.InfoHash()
|
TempHash := singleTorrent.InfoHash()
|
||||||
if previousElement.TorrentHashString == TempHash.String() { //matching previous to new
|
if previousElement.TorrentHashString == TempHash.String() { //matching previous to new
|
||||||
@@ -247,7 +256,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CalculateTorrentETA(singleTorrent, fullClientDB) //needs to be here since we need the speed calculated before we can estimate the eta.
|
CalculateTorrentETA(singleTorrentFromStorage.TorrentSize, singleTorrent.BytesCompleted(), fullClientDB) //needs to be here since we need the speed calculated before we can estimate the eta.
|
||||||
|
|
||||||
fullClientDB.TotalUploadedSize = HumanizeBytes(float32(fullClientDB.TotalUploadedBytes))
|
fullClientDB.TotalUploadedSize = HumanizeBytes(float32(fullClientDB.TotalUploadedBytes))
|
||||||
fullClientDB.UploadRatio = CalculateUploadRatio(singleTorrent, fullClientDB) //calculate the upload ratio
|
fullClientDB.UploadRatio = CalculateUploadRatio(singleTorrent, fullClientDB) //calculate the upload ratio
|
||||||
@@ -345,19 +354,3 @@ func CreateTorrentDetailJSON(tclient *torrent.Client, selectedHash string, torre
|
|||||||
}
|
}
|
||||||
return TorrentDetailStruct
|
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)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/anacrolix/torrent"
|
"github.com/anacrolix/torrent"
|
||||||
"github.com/deranjer/goTorrent/storage"
|
"github.com/deranjer/goTorrent/storage"
|
||||||
|
Storage "github.com/deranjer/goTorrent/storage"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ func CopyFile(srcFile string, destFile string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"File": srcFile, "Error": err}).Error("Cannot open source file")
|
Logger.WithFields(logrus.Fields{"File": srcFile, "Error": err}).Error("Cannot open source file")
|
||||||
}
|
}
|
||||||
outfileContents, err := os.Open(destFile)
|
outfileContents, err := os.Create(destFile)
|
||||||
defer outfileContents.Close()
|
defer outfileContents.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"File": destFile, "Error": err}).Error("Cannot open destination file")
|
Logger.WithFields(logrus.Fields{"File": destFile, "Error": err}).Error("Cannot open destination file")
|
||||||
@@ -82,9 +83,14 @@ func CalculateTorrentSpeed(t *torrent.Torrent, c *ClientDB, oc ClientDB) {
|
|||||||
c.UpdatedAt = now
|
c.UpdatedAt = now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//CalculateDownloadSize will calculate the download size once file priorities are sorted out
|
||||||
|
func CalculateDownloadSize(tFromStorage *Storage.TorrentLocal) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//CalculateTorrentETA is used to estimate the remaining dl time of the torrent based on the speed that the MB are being downloaded
|
//CalculateTorrentETA is used to estimate the remaining dl time of the torrent based on the speed that the MB are being downloaded
|
||||||
func CalculateTorrentETA(t *torrent.Torrent, c *ClientDB) {
|
func CalculateTorrentETA(tSize int64, tBytesCompleted int64, c *ClientDB) {
|
||||||
missingBytes := t.Length() - t.BytesCompleted()
|
missingBytes := tSize - tBytesCompleted
|
||||||
missingMB := missingBytes / 1024 / 1024
|
missingMB := missingBytes / 1024 / 1024
|
||||||
if missingMB == 0 {
|
if missingMB == 0 {
|
||||||
c.ETA = "Done"
|
c.ETA = "Done"
|
||||||
@@ -108,8 +114,8 @@ func CalculateUploadRatio(t *torrent.Torrent, c *ClientDB) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//CalculateTorrentStatus is used to determine what the STATUS column of the frontend will display ll2
|
//CalculateTorrentStatus is used to determine what the STATUS column of the frontend will display ll2
|
||||||
func CalculateTorrentStatus(t *torrent.Torrent, c *ClientDB, config FullClientSettings, tFromStorage *storage.TorrentLocal) { //TODO redo all of this to allow for stopped torrents
|
func CalculateTorrentStatus(t *torrent.Torrent, c *ClientDB, config FullClientSettings, tFromStorage *storage.TorrentLocal) {
|
||||||
if (tFromStorage.TorrentStatus == "Stopped") || (float64(c.TotalUploadedBytes)/float64(t.BytesCompleted()) >= config.SeedRatioStop) {
|
if (tFromStorage.TorrentStatus == "Stopped") || (float64(c.TotalUploadedBytes)/float64(t.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.Status = "Stopped"
|
||||||
c.MaxConnections = 0
|
c.MaxConnections = 0
|
||||||
t.SetMaxEstablishedConns(0)
|
t.SetMaxEstablishedConns(0)
|
||||||
|
@@ -4,11 +4,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"golang.org/x/time/rate"
|
||||||
|
|
||||||
"github.com/anacrolix/dht"
|
"github.com/anacrolix/dht"
|
||||||
"github.com/anacrolix/torrent"
|
"github.com/anacrolix/torrent"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"golang.org/x/time/rate"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//FullClientSettings contains all of the settings for our entire application
|
//FullClientSettings contains all of the settings for our entire application
|
||||||
@@ -49,6 +50,42 @@ func dhtServerSettings(dhtConfig dht.ServerConfig) dht.ServerConfig {
|
|||||||
return dhtConfig
|
return dhtConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func calculateRateLimiters(uploadRate, downloadRate string) (*rate.Limiter, *rate.Limiter) { //TODO reorg
|
||||||
|
var uploadRateLimiterSize int
|
||||||
|
var downloadRateLimiterSize int
|
||||||
|
|
||||||
|
switch uploadRate {
|
||||||
|
case "Low":
|
||||||
|
uploadRateLimiterSize = 50000
|
||||||
|
case "Medium":
|
||||||
|
uploadRateLimiterSize = 500000
|
||||||
|
case "High":
|
||||||
|
uploadRateLimiterSize = 1500000
|
||||||
|
default:
|
||||||
|
downloadRateLimiter := rate.NewLimiter(rate.Inf, 0)
|
||||||
|
uploadRateLimiter := rate.NewLimiter(rate.Inf, 0)
|
||||||
|
return downloadRateLimiter, uploadRateLimiter
|
||||||
|
}
|
||||||
|
|
||||||
|
switch downloadRate {
|
||||||
|
case "Low":
|
||||||
|
downloadRateLimiterSize = 50000
|
||||||
|
case "Medium":
|
||||||
|
downloadRateLimiterSize = 500000
|
||||||
|
case "High":
|
||||||
|
downloadRateLimiterSize = 1500000
|
||||||
|
default:
|
||||||
|
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)
|
||||||
|
var limitPerSecondDl = rate.Limit(uploadRateLimiterSize)
|
||||||
|
downloadRateLimiter := rate.NewLimiter(limitPerSecondDl, downloadRateLimiterSize)
|
||||||
|
return downloadRateLimiter, uploadRateLimiter
|
||||||
|
}
|
||||||
|
|
||||||
//FullClientSettingsNew creates a new set of setting from config.toml
|
//FullClientSettingsNew creates a new set of setting from config.toml
|
||||||
func FullClientSettingsNew() FullClientSettings {
|
func FullClientSettingsNew() FullClientSettings {
|
||||||
viper.SetConfigName("config")
|
viper.SetConfigName("config")
|
||||||
@@ -84,6 +121,12 @@ func FullClientSettingsNew() FullClientSettings {
|
|||||||
fmt.Println("Failed creating absolute path for dataDir", err)
|
fmt.Println("Failed creating absolute path for dataDir", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var uploadRateLimiter *rate.Limiter
|
||||||
|
var downloadRateLimiter *rate.Limiter
|
||||||
|
uploadRate := viper.GetString("serverConfig.UploadRateLimit")
|
||||||
|
downloadRate := viper.GetString("serverConfig.DownloadRateLimit")
|
||||||
|
downloadRateLimiter, uploadRateLimiter = calculateRateLimiters(uploadRate, downloadRate)
|
||||||
|
|
||||||
listenAddr := viper.GetString("torrentClientConfig.ListenAddr")
|
listenAddr := viper.GetString("torrentClientConfig.ListenAddr")
|
||||||
disablePex := viper.GetBool("torrentClientConfig.DisablePEX")
|
disablePex := viper.GetBool("torrentClientConfig.DisablePEX")
|
||||||
noDHT := viper.GetBool("torrentClientConfig.NoDHT")
|
noDHT := viper.GetBool("torrentClientConfig.NoDHT")
|
||||||
@@ -124,12 +167,6 @@ func FullClientSettingsNew() FullClientSettings {
|
|||||||
dhtServerConfig = dhtServerSettings(dhtServerConfig)
|
dhtServerConfig = dhtServerSettings(dhtServerConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadRateLimiter := new(rate.Limiter)
|
|
||||||
viper.UnmarshalKey("UploadRateLimiter", &uploadRateLimiter)
|
|
||||||
|
|
||||||
downloadRateLimiter := new(rate.Limiter)
|
|
||||||
viper.UnmarshalKey("DownloadRateLimiter", &downloadRateLimiter)
|
|
||||||
|
|
||||||
encryptionPolicy := torrent.EncryptionPolicy{
|
encryptionPolicy := torrent.EncryptionPolicy{
|
||||||
DisableEncryption: viper.GetBool("EncryptionPolicy.DisableEncryption"),
|
DisableEncryption: viper.GetBool("EncryptionPolicy.DisableEncryption"),
|
||||||
ForceEncryption: viper.GetBool("EncryptionPolicy.ForceEncryption"),
|
ForceEncryption: viper.GetBool("EncryptionPolicy.ForceEncryption"),
|
||||||
@@ -144,8 +181,8 @@ func FullClientSettingsNew() FullClientSettings {
|
|||||||
DHTConfig: dhtServerConfig,
|
DHTConfig: dhtServerConfig,
|
||||||
NoUpload: noUpload,
|
NoUpload: noUpload,
|
||||||
Seed: seed,
|
Seed: seed,
|
||||||
//UploadRateLimiter: uploadRateLimiter,
|
UploadRateLimiter: uploadRateLimiter,
|
||||||
//DownloadRateLimiter: downloadRateLimiter,
|
DownloadRateLimiter: downloadRateLimiter,
|
||||||
PeerID: peerID,
|
PeerID: peerID,
|
||||||
DisableUTP: disableUTP,
|
DisableUTP: disableUTP,
|
||||||
DisableTCP: disableTCP,
|
DisableTCP: disableTCP,
|
||||||
|
@@ -52,7 +52,7 @@ var RSSList = [];
|
|||||||
var RSSTorrentList = [];
|
var RSSTorrentList = [];
|
||||||
|
|
||||||
var torrentListRequest = {
|
var torrentListRequest = {
|
||||||
messageType: "torrentListRequest"
|
MessageType: "torrentListRequest"
|
||||||
|
|
||||||
//websocket is started in kickwebsocket.js and is picked up here so "ws" is already defined 22
|
//websocket is started in kickwebsocket.js and is picked up here so "ws" is already defined 22
|
||||||
};ws.onmessage = function (evt) {
|
};ws.onmessage = function (evt) {
|
||||||
|
@@ -116,9 +116,9 @@ var addTorrentFilePopup = function (_React$Component) {
|
|||||||
console.log("Base64", base64data);
|
console.log("Base64", base64data);
|
||||||
|
|
||||||
var torrentFileMessage = {
|
var torrentFileMessage = {
|
||||||
messageType: "torrentFileSubmit",
|
MessageType: "torrentFileSubmit",
|
||||||
messageDetail: _this.state.torrentFileName,
|
MessageDetail: this.state.torrentFileName,
|
||||||
messageDetailTwo: _this.state.storageValue,
|
MessageDetailTwo: this.state.storageValue,
|
||||||
Payload: [base64data]
|
Payload: [base64data]
|
||||||
};
|
};
|
||||||
console.log("Sending magnet link: ", torrentFileMessage);
|
console.log("Sending magnet link: ", torrentFileMessage);
|
||||||
|
@@ -22,7 +22,7 @@ let serverPushMessage = [];
|
|||||||
let webSocketState = false;
|
let webSocketState = false;
|
||||||
|
|
||||||
var torrentListRequest = {
|
var torrentListRequest = {
|
||||||
messageType: "torrentListRequest"
|
MessageType: "torrentListRequest"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ ws.onmessage = function (evt) { //When we recieve a message from the websocket
|
|||||||
FileNumber: serverMessage.data[i].NumberofFiles,
|
FileNumber: serverMessage.data[i].NumberofFiles,
|
||||||
PieceNumber: serverMessage.data[i].NumberofPieces,
|
PieceNumber: serverMessage.data[i].NumberofPieces,
|
||||||
MaxConnections: serverMessage.data[i].MaxConnections,
|
MaxConnections: serverMessage.data[i].MaxConnections,
|
||||||
Label: serverMessage.data[i].TorrentLabel,
|
TorrentLabel: serverMessage.data[i].TorrentLabel,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
var newTitle = '(' + serverMessage.total + ')' + title; //updating the title
|
var newTitle = '(' + serverMessage.total + ')' + title; //updating the title
|
||||||
@@ -143,20 +143,18 @@ ws.onclose = function() {
|
|||||||
console.log('Closing connection')
|
console.log('Closing connection')
|
||||||
};
|
};
|
||||||
|
|
||||||
var divStyle = {
|
|
||||||
display: 'inline-block',
|
|
||||||
paddingTop: '10px',
|
|
||||||
paddingLeft: '10px',
|
|
||||||
}
|
|
||||||
|
|
||||||
var buttonStyle ={
|
var buttonStyle ={
|
||||||
fontSize: '60px',
|
fontSize: '60px',
|
||||||
|
marginLeft: '20px',
|
||||||
|
}
|
||||||
|
|
||||||
|
const inlineStyle = {
|
||||||
|
display: 'inline-block',
|
||||||
|
backdrop: 'static',
|
||||||
}
|
}
|
||||||
|
|
||||||
class BackendSocket extends React.Component {
|
class BackendSocket extends React.Component {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
selectionHandler = (selectionHashes, selectedTab) => {
|
selectionHandler = (selectionHashes, selectedTab) => {
|
||||||
switch (selectedTab) {
|
switch (selectedTab) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -258,6 +256,7 @@ class BackendSocket extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
console.log("Length", nextProps.selectionHashes.length, "value", nextProps.selectionHashes)
|
console.log("Length", nextProps.selectionHashes.length, "value", nextProps.selectionHashes)
|
||||||
if (nextProps.selectionHashes.length === 1){ //if we have a selection pass it on for the tabs to verify
|
if (nextProps.selectionHashes.length === 1){ //if we have a selection pass it on for the tabs to verify
|
||||||
@@ -268,12 +267,9 @@ class BackendSocket extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={divStyle}>
|
<div style={inlineStyle}>
|
||||||
<BackendIcon styles={buttonStyle} color="primary" data-tip="BackendStatus: Green=Good" aria-label="Settings" />
|
<BackendIcon style={buttonStyle} color="primary" data-tip="BackendStatus: Green=Good" aria-label="Settings" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -35,7 +35,6 @@ class GeneralTab extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps = () => {
|
componentWillReceiveProps = () => {
|
||||||
//console.log("recieving props in generaltab", "TYPE", this.props.selectionHashes[Object.keys(this.props.selectionHashes)[0]])
|
|
||||||
if (this.props.selectionHashes.length === 1) { //if one torrent is selected
|
if (this.props.selectionHashes.length === 1) { //if one torrent is selected
|
||||||
let selectionHashTemp = this.props.selectionHashes[Object.keys(this.props.selectionHashes)[0]]// extract out the hash of the single selection
|
let selectionHashTemp = this.props.selectionHashes[Object.keys(this.props.selectionHashes)[0]]// extract out the hash of the single selection
|
||||||
let selectedTorrentTemp = []
|
let selectedTorrentTemp = []
|
||||||
@@ -44,7 +43,6 @@ class GeneralTab extends React.Component {
|
|||||||
selectedTorrentTemp = singleTorrent
|
selectedTorrentTemp = singleTorrent
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
//selectedTorrentTemp = this.props.torrentList.filter(torrent => torrent.TorrentHashString === this.props.selectionHashes)
|
|
||||||
//console.log("SelectedTorrentTemp", selectedTorrentTemp)
|
//console.log("SelectedTorrentTemp", selectedTorrentTemp)
|
||||||
this.setState({ selectedTorrent: selectedTorrentTemp });
|
this.setState({ selectedTorrent: selectedTorrentTemp });
|
||||||
} else {
|
} else {
|
||||||
@@ -52,7 +50,6 @@ class GeneralTab extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes } = this.props;
|
const { classes } = this.props;
|
||||||
return (
|
return (
|
||||||
@@ -90,9 +87,6 @@ class GeneralTab extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
return {
|
return {
|
||||||
selectionHashes: state.selectionHashes,
|
selectionHashes: state.selectionHashes,
|
||||||
|
@@ -62,7 +62,7 @@ const inlineStyle = {
|
|||||||
|
|
||||||
showRSSFiles = (key) => {
|
showRSSFiles = (key) => {
|
||||||
let RSSTorrentsRequest = {
|
let RSSTorrentsRequest = {
|
||||||
messageType: "rssTorrentsRequest",
|
MessageType: "rssTorrentsRequest",
|
||||||
Payload: [this.props.RSSList[key].RSSURL]
|
Payload: [this.props.RSSList[key].RSSURL]
|
||||||
}
|
}
|
||||||
ws.send(JSON.stringify(RSSTorrentsRequest))
|
ws.send(JSON.stringify(RSSTorrentsRequest))
|
||||||
@@ -85,7 +85,7 @@ const inlineStyle = {
|
|||||||
|
|
||||||
deleteRSSFeed = (key) => {
|
deleteRSSFeed = (key) => {
|
||||||
let RSSURLDelete = {
|
let RSSURLDelete = {
|
||||||
messageType: "deleteRSSFeed",
|
MessageType: "deleteRSSFeed",
|
||||||
Payload: [this.props.RSSList[key]]
|
Payload: [this.props.RSSList[key]]
|
||||||
}
|
}
|
||||||
console.log("Deleting THIS", this.props.RSSList[key])
|
console.log("Deleting THIS", this.props.RSSList[key])
|
||||||
|
@@ -105,12 +105,12 @@ const inlineStyle = {
|
|||||||
handleAddRSSFeed = () => {
|
handleAddRSSFeed = () => {
|
||||||
this.setState({ textValue: "Clear"}) //clearing out the text submitted
|
this.setState({ textValue: "Clear"}) //clearing out the text submitted
|
||||||
let RSSURLSubmit = {
|
let RSSURLSubmit = {
|
||||||
messageType: "addRSSFeed",
|
MessageType: "addRSSFeed",
|
||||||
Payload: [this.state.textValue]
|
Payload: [this.state.textValue]
|
||||||
}
|
}
|
||||||
ws.send(JSON.stringify(RSSURLSubmit));
|
ws.send(JSON.stringify(RSSURLSubmit));
|
||||||
let RSSRequest = {
|
let RSSRequest = {
|
||||||
messageType: "rssFeedRequest",
|
MessageType: "rssFeedRequest",
|
||||||
}
|
}
|
||||||
ws.send(JSON.stringify(RSSRequest)) //Immediatly request an update of the feed when you add a new URL
|
ws.send(JSON.stringify(RSSRequest)) //Immediatly request an update of the feed when you add a new URL
|
||||||
}
|
}
|
||||||
|
@@ -31,11 +31,9 @@ import * as actionTypes from '../../../store/actions';
|
|||||||
|
|
||||||
const button = {
|
const button = {
|
||||||
fontSize: '60px',
|
fontSize: '60px',
|
||||||
paddingRight: '20px',
|
marginLeft: '20px',
|
||||||
paddingLeft: '20px',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const inlineStyle = {
|
const inlineStyle = {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
backdrop: 'static',
|
backdrop: 'static',
|
||||||
@@ -46,7 +44,7 @@ const inlineStyle = {
|
|||||||
|
|
||||||
componentDidMount () { //Immediatly request an update of the feed when loading app
|
componentDidMount () { //Immediatly request an update of the feed when loading app
|
||||||
let RSSRequest = {
|
let RSSRequest = {
|
||||||
messageType: "rssFeedRequest",
|
MessageType: "rssFeedRequest",
|
||||||
}
|
}
|
||||||
ws.send(JSON.stringify(RSSRequest))
|
ws.send(JSON.stringify(RSSRequest))
|
||||||
|
|
||||||
|
@@ -20,8 +20,8 @@ import Dropzone from 'react-dropzone';
|
|||||||
|
|
||||||
const button = {
|
const button = {
|
||||||
fontSize: '60px',
|
fontSize: '60px',
|
||||||
paddingRight: '20px',
|
marginLeft: '20px',
|
||||||
paddingLeft: '20px',
|
marginRight: '20px',
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadButton = {
|
const uploadButton = {
|
||||||
@@ -68,13 +68,13 @@ export default class addTorrentFilePopup extends React.Component {
|
|||||||
console.log("Base64", base64data)
|
console.log("Base64", base64data)
|
||||||
|
|
||||||
let torrentFileMessage = {
|
let torrentFileMessage = {
|
||||||
messageType: "torrentFileSubmit",
|
MessageType: "torrentFileSubmit",
|
||||||
torrentFileName: this.state.torrentFileName,
|
MessageDetail: this.state.torrentFileName, //filename
|
||||||
torrentStorageValue : this.state.storageValue,
|
MessageDetailTwo: this.state.storageValue, //storage path
|
||||||
torrentLabelValue: this.state.torrentLabel,
|
MessageDetailThree: this.state.torrentLabel, //torrent label
|
||||||
Payload: [base64data],
|
Payload: [base64data],
|
||||||
}
|
}
|
||||||
console.log("Sending magnet link: ", torrentFileMessage);
|
console.log("Sending Torrent File: ", torrentFileMessage);
|
||||||
ws.send(JSON.stringify(torrentFileMessage));
|
ws.send(JSON.stringify(torrentFileMessage));
|
||||||
this.setState({torrentFileName: "", storageValue: ``, torrentFileValue: [], showDrop: true})
|
this.setState({torrentFileName: "", storageValue: ``, torrentFileValue: [], showDrop: true})
|
||||||
}
|
}
|
||||||
|
@@ -20,8 +20,7 @@ import IconButton from 'material-ui/IconButton';
|
|||||||
|
|
||||||
const button = {
|
const button = {
|
||||||
fontSize: '60px',
|
fontSize: '60px',
|
||||||
paddingRight: '20px',
|
marginRight: '20px',
|
||||||
paddingLeft: '20px',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const inlineStyle = {
|
const inlineStyle = {
|
||||||
@@ -52,15 +51,16 @@ export default class addTorrentPopup extends React.Component {
|
|||||||
handleSubmit = () => {
|
handleSubmit = () => {
|
||||||
this.setState({ open: false });
|
this.setState({ open: false });
|
||||||
//let magnetLinkSubmit = this.state.textValue;
|
//let magnetLinkSubmit = this.state.textValue;
|
||||||
|
console.log("MagnetLink", this.state.magnetLinkValue)
|
||||||
let magnetLinkMessage = {
|
let magnetLinkMessage = {
|
||||||
messageType: "magnetLinkSubmit",
|
MessageType: "magnetLinkSubmit",
|
||||||
storageValue: this.state.storageValue,
|
MessageDetail: this.state.storageValue, //storage location
|
||||||
torrentLabel: this.state.torrentLabel,
|
MessageDetailTwo: this.state.torrentLabel, //label
|
||||||
Payload: [this.state.magnetLinkValue]
|
Payload: [this.state.magnetLinkValue]
|
||||||
}
|
}
|
||||||
console.log("Sending magnet link: ", magnetLinkMessage);
|
console.log("Sending magnet link: ", magnetLinkMessage);
|
||||||
ws.send(JSON.stringify(magnetLinkMessage));
|
ws.send(JSON.stringify(magnetLinkMessage));
|
||||||
this.setState({magnetLinkValue: ""}, {torrentLabel: ""}, {storageValue: ``})
|
//this.setState({magnetLinkValue: ""}, {torrentLabel: ""}, {storageValue: ``})
|
||||||
}
|
}
|
||||||
|
|
||||||
setMagnetLinkValue = (event) => {
|
setMagnetLinkValue = (event) => {
|
||||||
|
@@ -16,14 +16,14 @@ import Icon from 'material-ui/Icon';
|
|||||||
import IconButton from 'material-ui/IconButton';
|
import IconButton from 'material-ui/IconButton';
|
||||||
//Importing Redux
|
//Importing Redux
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import * as actionTypes from '../store/actions';
|
import * as actionTypes from '../../store/actions';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const button = {
|
const button = {
|
||||||
fontSize: '60px',
|
fontSize: '60px',
|
||||||
paddingRight: '20px',
|
marginLeft: '20px',
|
||||||
paddingLeft: '20px',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const inlineStyle = {
|
const inlineStyle = {
|
||||||
@@ -31,7 +31,7 @@ const inlineStyle = {
|
|||||||
backdrop: 'static',
|
backdrop: 'static',
|
||||||
}
|
}
|
||||||
|
|
||||||
class addTorrentPopup extends React.Component {
|
class ChangeStorageModal extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
open: false,
|
open: false,
|
||||||
@@ -50,9 +50,9 @@ class addTorrentPopup extends React.Component {
|
|||||||
this.setState({ open: false });
|
this.setState({ open: false });
|
||||||
//let magnetLinkSubmit = this.state.textValue;
|
//let magnetLinkSubmit = this.state.textValue;
|
||||||
let changeStorageMessage = {
|
let changeStorageMessage = {
|
||||||
messageType: "changeStorageValue",
|
MessageType: "changeStorageValue",
|
||||||
newStorageValue: this.state.storageValue,
|
MessageDetail: this.state.storageValue, //new storage value
|
||||||
Payload: [this.props.selectionHashes]
|
Payload: this.props.selectionHashes, //the selection hashes
|
||||||
}
|
}
|
||||||
console.log("Sending new Storage Location: ", changeStorageMessage);
|
console.log("Sending new Storage Location: ", changeStorageMessage);
|
||||||
ws.send(JSON.stringify(changeStorageMessage));
|
ws.send(JSON.stringify(changeStorageMessage));
|
||||||
@@ -113,4 +113,4 @@ const mapStateToProps = state => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(BackendSocket);
|
export default connect(mapStateToProps)(ChangeStorageModal);
|
@@ -22,8 +22,7 @@ import * as actionTypes from '../../store/actions';
|
|||||||
|
|
||||||
const button = {
|
const button = {
|
||||||
fontSize: '60px',
|
fontSize: '60px',
|
||||||
paddingRight: '20px',
|
marginRight: '20px',
|
||||||
paddingLeft: '20px',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const inlineStyle = {
|
const inlineStyle = {
|
||||||
|
@@ -9,12 +9,15 @@ import AddTorrentLinkPopup from './Modals/addTorrentLinkModal';
|
|||||||
import AddTorrentFilePopup from './Modals/addTorrentFileModal';
|
import AddTorrentFilePopup from './Modals/addTorrentFileModal';
|
||||||
import AddRSSModal from './Modals/RSSModal/addRSSModal';
|
import AddRSSModal from './Modals/RSSModal/addRSSModal';
|
||||||
import DeleteTorrentModal from './Modals/deleteTorrentModal';
|
import DeleteTorrentModal from './Modals/deleteTorrentModal';
|
||||||
|
import ChangeStorageModal from './Modals/changeStorageModal';
|
||||||
|
import TorrentSearch from './torrentSearch';
|
||||||
|
|
||||||
import StartTorrentIcon from 'material-ui-icons/PlayArrow';
|
import StartTorrentIcon from 'material-ui-icons/PlayArrow';
|
||||||
//import PauseTorrentIcon from 'material-ui-icons/Pause';
|
//import PauseTorrentIcon from 'material-ui-icons/Pause';
|
||||||
import StopTorrentIcon from 'material-ui-icons/Stop';
|
import StopTorrentIcon from 'material-ui-icons/Stop';
|
||||||
import RSSTorrentIcon from 'material-ui-icons/RssFeed';
|
import RSSTorrentIcon from 'material-ui-icons/RssFeed';
|
||||||
import SettingsIcon from 'material-ui-icons/Settings';
|
import SettingsIcon from 'material-ui-icons/Settings';
|
||||||
|
import ForceUploadIcon from 'material-ui-icons/KeyboardArrowUp';
|
||||||
|
|
||||||
|
|
||||||
import ReactTooltip from 'react-tooltip'
|
import ReactTooltip from 'react-tooltip'
|
||||||
@@ -38,9 +41,6 @@ const styles = theme => ({
|
|||||||
input: {
|
input: {
|
||||||
display: 'none',
|
display: 'none',
|
||||||
},
|
},
|
||||||
paddingTest: {
|
|
||||||
display: 'inline-block'
|
|
||||||
},
|
|
||||||
padding: {
|
padding: {
|
||||||
paddingTop: '10px',
|
paddingTop: '10px',
|
||||||
paddingLeft: '10px',
|
paddingLeft: '10px',
|
||||||
@@ -61,13 +61,30 @@ const styles = theme => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class IconButtons extends React.Component {
|
class IconButtons extends React.Component {
|
||||||
constructor(props){
|
constructor(props){
|
||||||
super(props);
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
forceStartButton: "default"
|
||||||
|
}
|
||||||
|
|
||||||
this.state = { serverMessage: ["info", "A props message"]}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps = (nextprops) => {
|
||||||
|
if (nextprops.selectionHashes.length > 0){
|
||||||
|
this.setState({forceStartButton: "primary"})
|
||||||
|
} else {
|
||||||
|
this.setState({forceStartButton: "default"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forceStartTorrent = () => {
|
||||||
|
console.log("Force starting Torrents", this.props.selectionHashes)
|
||||||
|
let forceUploadTorrents = {
|
||||||
|
MessageType: "forceUploadTorrents",
|
||||||
|
Payload: this.props.selectionHashes,
|
||||||
|
}
|
||||||
|
ws.send(JSON.stringify(forceUploadTorrents))
|
||||||
}
|
}
|
||||||
|
|
||||||
startTorrent = () => {
|
startTorrent = () => {
|
||||||
@@ -99,6 +116,10 @@ class IconButtons extends React.Component {
|
|||||||
<AddTorrentFilePopup />
|
<AddTorrentFilePopup />
|
||||||
<AddTorrentLinkPopup />
|
<AddTorrentLinkPopup />
|
||||||
<div className={classes.verticalDivider}></div>
|
<div className={classes.verticalDivider}></div>
|
||||||
|
<IconButton color={this.state.forceStartButton} data-tip="Force Upload Torrent (override upload limit)" className={classes.button} aria-label="Force Start Torrent" onClick={this.forceStartTorrent}>
|
||||||
|
<ReactTooltip place="top" type="light" effect="float" />
|
||||||
|
<ForceUploadIcon />
|
||||||
|
</IconButton>
|
||||||
<IconButton color={this.props.buttonState[0].startButton} data-tip="Start Torrent" className={classes.button} aria-label="Start Torrent" onClick={this.startTorrent}>
|
<IconButton color={this.props.buttonState[0].startButton} data-tip="Start Torrent" className={classes.button} aria-label="Start Torrent" onClick={this.startTorrent}>
|
||||||
<ReactTooltip place="top" type="light" effect="float" />
|
<ReactTooltip place="top" type="light" effect="float" />
|
||||||
<StartTorrentIcon />
|
<StartTorrentIcon />
|
||||||
@@ -113,13 +134,17 @@ class IconButtons extends React.Component {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
<DeleteTorrentModal />
|
<DeleteTorrentModal />
|
||||||
<div className={classes.verticalDivider}></div>
|
<div className={classes.verticalDivider}></div>
|
||||||
|
<ChangeStorageModal />
|
||||||
<AddRSSModal />
|
<AddRSSModal />
|
||||||
<IconButton color="primary" data-tip="Settings" className={classes.button} aria-label="Settings">
|
<IconButton color="primary" data-tip="Settings" className={classes.button} aria-label="Settings">
|
||||||
<ReactTooltip place="top" type="light" effect="float" />
|
<ReactTooltip place="top" type="light" effect="float" />
|
||||||
<SettingsIcon />
|
<SettingsIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<div className={classes.verticalDivider}></div>
|
<div className={classes.verticalDivider}></div>
|
||||||
|
<TorrentSearch />
|
||||||
|
<div className={classes.verticalDivider}></div>
|
||||||
<BackendSocket />
|
<BackendSocket />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -141,7 +166,6 @@ const mapStateToProps = state => {
|
|||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => {
|
||||||
return {
|
return {
|
||||||
setButtonState: (buttonState) => dispatch({type: actionTypes.SET_BUTTON_STATE, buttonState}),
|
setButtonState: (buttonState) => dispatch({type: actionTypes.SET_BUTTON_STATE, buttonState}),
|
||||||
changeSelection: (selection) => dispatch({type: actionTypes.CHANGE_SELECTION, selection}), //used to force a selection empty after deleting torrent
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
77
goTorrentWebUI/src/TopMenu/torrentSearch.js
Normal file
77
goTorrentWebUI/src/TopMenu/torrentSearch.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import TextField from 'material-ui/TextField';
|
||||||
|
import { withStyles } from 'material-ui/styles';
|
||||||
|
|
||||||
|
//Redux
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import * as actionTypes from '../store/actions'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const styles = theme => ({
|
||||||
|
textField: {
|
||||||
|
marginLeft: theme.spacing.unit,
|
||||||
|
marginRight: theme.spacing.unit,
|
||||||
|
marginBottom: '20px',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
class TorrentSearch extends React.Component {
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
searchValue: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
componentWillReceiveProps = (nextprops) => {
|
||||||
|
|
||||||
|
if (nextprops.filter[0].columnName == "Status"){ //If we are using the left menu filter clear the searchbox
|
||||||
|
this.setState({searchValue: ""})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange = (event) => {
|
||||||
|
this.setState({searchValue: event.target.value})
|
||||||
|
let filterState = [{columnName: 'TorrentName', value: event.target.value}]
|
||||||
|
this.props.changeFilter(filterState)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { classes } = this.props;
|
||||||
|
return(
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
id="search"
|
||||||
|
label="Search Torrents"
|
||||||
|
type="search"
|
||||||
|
className={classes.textField}
|
||||||
|
onChange={this.onChange}
|
||||||
|
value={this.state.searchValue}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const mapStateToProps = state => {
|
||||||
|
return {
|
||||||
|
filter: state.filter,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
changeFilter: (filter) => dispatch({type: actionTypes.CHANGE_FILTER, filter: filter}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default withStyles(styles)(connect(mapStateToProps, mapDispatchToProps)(TorrentSearch))
|
@@ -55,10 +55,19 @@ class SimpleList extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setActiveElement = (listItem) => {
|
componentWillReceiveProps = (nextprops) => {
|
||||||
|
const { classes } = this.props;
|
||||||
|
if (nextprops.filter[0].columnName == "TorrentName"){ //If we are using the top searchbox move back to all torrents
|
||||||
|
this.setState({
|
||||||
|
allTorrentsClass: classes.active,
|
||||||
|
downloadingClass: '',
|
||||||
|
seedingClass: '',
|
||||||
|
activeTorrentsClass: '',
|
||||||
|
completedTorrentsClass: '',
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setFilter = (filterState, id) => {
|
setFilter = (filterState, id) => {
|
||||||
|
@@ -19,7 +19,8 @@ const initialState = {
|
|||||||
RSSTorrentList: [],
|
RSSTorrentList: [],
|
||||||
RSSModalOpen: false,
|
RSSModalOpen: false,
|
||||||
serverPushMessage: [],
|
serverPushMessage: [],
|
||||||
webSocketState: false
|
webSocketState: false,
|
||||||
|
searchFilterTerm: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -116,9 +116,7 @@ class TorrentListTable extends React.Component {
|
|||||||
|
|
||||||
filterHandler = (filter) => { //TODO, figure out how to do multiple filter
|
filterHandler = (filter) => { //TODO, figure out how to do multiple filter
|
||||||
//console.log("Changing FIlter", filter)
|
//console.log("Changing FIlter", filter)
|
||||||
if (filter.value ==="Active"){
|
|
||||||
console.log("This filter doesn't fucking work")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -149,13 +147,6 @@ class TorrentListTable extends React.Component {
|
|||||||
<TableColumnReordering order={this.state.columnOrder} onOrderChange={this.changeColumnOrder} />
|
<TableColumnReordering order={this.state.columnOrder} onOrderChange={this.changeColumnOrder} />
|
||||||
<TableSelection selectByRowClick highlightSelected />
|
<TableSelection selectByRowClick highlightSelected />
|
||||||
<TableHeaderRow allowSorting allowResizing allowDragging />
|
<TableHeaderRow allowSorting allowResizing allowDragging />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
|
32
main.go
32
main.go
@@ -182,10 +182,12 @@ func main() {
|
|||||||
hashes := msg.Payload
|
hashes := msg.Payload
|
||||||
for _, singleHash := range hashes {
|
for _, singleHash := range hashes {
|
||||||
singleTorrent := Storage.FetchTorrentFromStorage(db, singleHash)
|
singleTorrent := Storage.FetchTorrentFromStorage(db, singleHash)
|
||||||
|
oldPath := singleTorrent.StoragePath
|
||||||
singleTorrent.StoragePath = newStorageLocation
|
singleTorrent.StoragePath = newStorageLocation
|
||||||
Storage.UpdateStorageTick(db, singleTorrent) //push torrent to storage
|
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?
|
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)
|
Logger.WithFields(logrus.Fields{"message": msg}).Info("Torrent completed so moving to new location")
|
||||||
|
Engine.MoveAndLeaveSymlink(Config, singleHash, db, true, oldPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +283,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
Logger.WithFields(logrus.Fields{"clientTorrent": clientTorrent, "magnetLink": magnetLink}).Info("Adding torrent to client!")
|
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.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received MagnetLink"}, conn)
|
||||||
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "magnet", "", storageValue, labelValue) //starting the torrent and creating local DB entry
|
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "magnet", "", storageValue, labelValue, Config.TFileUploadFolder) //starting the torrent and creating local DB entry
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,6 +296,8 @@ func main() {
|
|||||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to decode base64 string to file"}, conn)
|
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to decode base64 string to file"}, conn)
|
||||||
}
|
}
|
||||||
FileName := msg.MessageDetail
|
FileName := msg.MessageDetail
|
||||||
|
fmt.Println("Full Message", msg.MessageType, msg.MessageDetail, msg.MessageDetailTwo, msg.MessageDetailThree)
|
||||||
|
fmt.Println("FileName", msg.MessageDetail)
|
||||||
storageValue := msg.MessageDetailTwo
|
storageValue := msg.MessageDetailTwo
|
||||||
labelValue := msg.MessageDetailThree
|
labelValue := msg.MessageDetailThree
|
||||||
if storageValue == "" {
|
if storageValue == "" {
|
||||||
@@ -314,7 +318,7 @@ func main() {
|
|||||||
|
|
||||||
err = ioutil.WriteFile(filePath, file, 0755) //Dumping our received file into the filename
|
err = ioutil.WriteFile(filePath, file, 0755) //Dumping our received file into the filename
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"filepath": filePath, "Error": err}).Error("Unable to write torrent data to file")
|
Logger.WithFields(logrus.Fields{"filepath": filePath, "file Name": FileName, "Error": err}).Error("Unable to write torrent data to file")
|
||||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to write torrent data to file"}, conn)
|
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to write torrent data to file"}, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,7 +328,7 @@ func main() {
|
|||||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to add Torrent to torrent server"}, conn)
|
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")
|
Logger.WithFields(logrus.Fields{"clienttorrent": clientTorrent.Name(), "filename": filePath}).Info("Added torrent")
|
||||||
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "file", filePath, storageValue, labelValue)
|
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "file", filePath, storageValue, labelValue, Config.TFileUploadFolder)
|
||||||
|
|
||||||
case "stopTorrents":
|
case "stopTorrents":
|
||||||
TorrentListCommands := msg.Payload
|
TorrentListCommands := msg.Payload
|
||||||
@@ -382,6 +386,25 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "forceUploadTorrents":
|
||||||
|
Logger.WithFields(logrus.Fields{"selection": msg.Payload}).Info("Matched for force Uploading Torrents")
|
||||||
|
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Force Start Request"}, conn)
|
||||||
|
for _, singleTorrent := range runningTorrents {
|
||||||
|
for _, singleSelection := range msg.Payload {
|
||||||
|
if singleTorrent.InfoHash().String() == singleSelection {
|
||||||
|
Logger.WithFields(logrus.Fields{"infoHash": singleTorrent.InfoHash().String()}).Debug("Found matching torrent to force start")
|
||||||
|
oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String())
|
||||||
|
oldTorrentInfo.TorrentUploadLimit = false // no upload limit for this torrent
|
||||||
|
oldTorrentInfo.TorrentStatus = "Running"
|
||||||
|
oldTorrentInfo.MaxConnections = 80
|
||||||
|
oldMax := singleTorrent.SetMaxEstablishedConns(80)
|
||||||
|
singleTorrent.DownloadAll()
|
||||||
|
Logger.WithFields(logrus.Fields{"Previous Max Connections": oldMax, "Torrent": oldTorrentInfo.TorrentName}).Info("Setting max connection from zero to")
|
||||||
|
Storage.UpdateStorageTick(db, oldTorrentInfo) //Updating the torrent status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case "setFilePriority": //TODO disable if the file is already at 100%?
|
case "setFilePriority": //TODO disable if the file is already at 100%?
|
||||||
Logger.WithFields(logrus.Fields{"selection": msg.Payload}).Info("Matched for setting file priority")
|
Logger.WithFields(logrus.Fields{"selection": msg.Payload}).Info("Matched for setting file priority")
|
||||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Set Priority Request"}, conn)
|
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Set Priority Request"}, conn)
|
||||||
@@ -428,6 +451,7 @@ func main() {
|
|||||||
for i, specificFile := range activeTorrentStruct.TorrentFilePriority { //searching for that specific file
|
for i, specificFile := range activeTorrentStruct.TorrentFilePriority { //searching for that specific file
|
||||||
if specificFile.TorrentFilePath == file.DisplayPath() {
|
if specificFile.TorrentFilePath == file.DisplayPath() {
|
||||||
activeTorrentStruct.TorrentFilePriority[i].TorrentFilePriority = "Canceled" //writing just that field to the current struct
|
activeTorrentStruct.TorrentFilePriority[i].TorrentFilePriority = "Canceled" //writing just that field to the current struct
|
||||||
|
activeTorrentStruct.TorrentSize = activeTorrentStruct.TorrentSize - file.Length() //changing the length of the download since the file was canceled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Storage.UpdateStorageTick(db, activeTorrentStruct) //re-writting essentially that entire struct right back into the database
|
Storage.UpdateStorageTick(db, activeTorrentStruct) //re-writting essentially that entire struct right back into the database
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
var ws = new WebSocket("ws://192.168.1.141:8000/websocket"); //creating websocket
|
var ws = new WebSocket("ws://192.168.1.141:8000/websocket"); //creating websocket
|
||||||
|
|
||||||
var kickStart = {
|
var kickStart = {
|
||||||
messageType: "torrentListRequest"
|
MessageType: "torrentListRequest"
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.onopen = function()
|
ws.onopen = function()
|
||||||
|
BIN
storage.db.old
Normal file
BIN
storage.db.old
Normal file
Binary file not shown.
@@ -50,13 +50,15 @@ type TorrentLocal struct {
|
|||||||
TorrentMoved bool
|
TorrentMoved bool
|
||||||
TorrentName string
|
TorrentName string
|
||||||
TorrentStatus string
|
TorrentStatus string
|
||||||
|
TorrentUploadLimit bool //if true this torrent will bypass the upload storage limit (effectively unlimited)
|
||||||
MaxConnections int
|
MaxConnections int
|
||||||
TorrentType string //magnet or .torrent file
|
TorrentType string //magnet or .torrent file
|
||||||
TorrentFileName string
|
TorrentFileName string //Should be absolute path
|
||||||
TorrentFile []byte
|
TorrentFile []byte
|
||||||
Label string
|
Label string
|
||||||
UploadedBytes int64
|
UploadedBytes int64
|
||||||
DownloadedBytes int64
|
DownloadedBytes int64
|
||||||
|
TorrentSize int64 //If we cancel a file change the download size since we won't be downloading that file
|
||||||
UploadRatio string
|
UploadRatio string
|
||||||
TorrentFilePriority []TorrentFilePriority
|
TorrentFilePriority []TorrentFilePriority
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user