closes #9, closes #8, closes #3, closes #4, added new notification features, search torrents, change directory, force seed torrent, updated Readme
This commit is contained in:
20
README.md
20
README.md
@@ -26,11 +26,19 @@ Image of the frontend UI
|
|||||||
- Automatic stop after seeding ratio reached
|
- Automatic stop after seeding ratio reached
|
||||||
- Pushbullet notification on torrent complete
|
- Pushbullet notification on torrent complete
|
||||||
- Automatic move of completed torrent to new directory (leave symlink behind for seeding)
|
- Automatic move of completed torrent to new directory (leave symlink behind for seeding)
|
||||||
- Doesn't work on Windows yet, have to copy file for now
|
- Symlinks don't work on Windows yet, have to copy file for now
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
- Early-Mid 2018
|
- Early-Mid 2018
|
||||||
|
|
||||||
|
- [X] Ability to modify storage path of torrent after it has been added
|
||||||
|
|
||||||
|
- [X] Backend to frontend notification messages
|
||||||
|
|
||||||
|
- [X] Global Rate Limiting for Upload/Download Speed
|
||||||
|
|
||||||
|
- [X] Add torrents from watch folder (cron job every 5 minutes)
|
||||||
|
|
||||||
- [ ] Unit testing completed for a large portion of the package
|
- [ ] Unit testing completed for a large portion of the package
|
||||||
|
|
||||||
- [ ] Stability/bug fixing/Optimization rewrite of some of the core structures of the WebUI and base server
|
- [ ] Stability/bug fixing/Optimization rewrite of some of the core structures of the WebUI and base server
|
||||||
@@ -40,8 +48,8 @@ Image of the frontend UI
|
|||||||
- [ ] Ability to set priority for individual files (just added to anacrolix/torrent so coming soon, already added to my UI)
|
- [ ] Ability to set priority for individual files (just added to anacrolix/torrent so coming soon, already added to my UI)
|
||||||
|
|
||||||
- [ ] Ability to view TOML settings from WebUI (and perhaps change a few as well)
|
- [ ] Ability to view TOML settings from WebUI (and perhaps change a few as well)
|
||||||
|
|
||||||
- [ ] Ability to modify storage path of torrent after it has been added
|
- [ ] Authentication from client to server
|
||||||
|
|
||||||
- Late 2018
|
- Late 2018
|
||||||
|
|
||||||
@@ -96,6 +104,12 @@ The `config.toml` file contains all of the settings for the server part of the a
|
|||||||
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
|
||||||
#Relative or absolute path accepted, the server will convert any relative path to an absolute path.
|
#Relative or absolute path accepted, the server will convert any relative path to an absolute path.
|
||||||
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
|
||||||
|
|
||||||
|
#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]
|
||||||
|
@@ -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 = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic
|
LogLevel = "Warn" # 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
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
[notifications]
|
[notifications]
|
||||||
|
|
||||||
PushBulletToken = "o.QW6G7F6FUOKXCUKmw948fBceCUn0msFi" #add your pushbullet api token here to notify of torrent completion to pushbullet
|
PushBulletToken = "" #add your pushbullet api token here to notify of torrent completion to pushbullet
|
||||||
|
|
||||||
|
|
||||||
[EncryptionPolicy]
|
[EncryptionPolicy]
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 63 KiB |
@@ -2,6 +2,7 @@ package engine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/anacrolix/torrent"
|
"github.com/anacrolix/torrent"
|
||||||
@@ -46,9 +47,9 @@ func CheckTorrentWatchFolder(c *cron.Cron, db *storm.DB, tclient *torrent.Client
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
//os.Remove(fullFilePathAbs) //delete the torrent after adding it and copying it over
|
os.Remove(fullFilePathAbs) //delete the torrent after adding it and copying it over
|
||||||
Logger.WithFields(logrus.Fields{"Source Folder": fullFilePathAbs, "Destination Folder": fullNewFilePathAbs, "Torrent": file.Name()}).Info("Added torrent from watch folder, and moved torrent file")
|
Logger.WithFields(logrus.Fields{"Source Folder": fullFilePathAbs, "Destination Folder": fullNewFilePathAbs, "Torrent": file.Name()}).Info("Added torrent from watch folder, and moved torrent file")
|
||||||
StartTorrent(clientTorrent, torrentLocalStorage, db, config.TorrentConfig.DataDir, "file", file.Name(), config.DefaultMoveFolder, "default", config.TFileUploadFolder)
|
StartTorrent(clientTorrent, torrentLocalStorage, db, "file", fullNewFilePathAbs, config.DefaultMoveFolder, "default", config)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,7 +85,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", config.TFileUploadFolder) //TODO let user specify torrent default storage location and let change on fly
|
StartTorrent(clientTorrent, torrentLocalStorage, db, "magnet", "", config.DefaultMoveFolder, "RSS", config) //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,8 +1,6 @@
|
|||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -20,22 +18,21 @@ func MoveAndLeaveSymlink(config FullClientSettings, tHash string, db *storm.DB,
|
|||||||
tStorage := Storage.FetchTorrentFromStorage(db, tHash)
|
tStorage := Storage.FetchTorrentFromStorage(db, tHash)
|
||||||
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName}).Info("Move and Create symlink started for torrent")
|
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName}).Info("Move and Create symlink started for torrent")
|
||||||
var oldFilePath string
|
var oldFilePath string
|
||||||
if moveDone {
|
if moveDone { //only occurs on manual move
|
||||||
oldFilePathTemp := filepath.Join(oldPath, tStorage.TorrentName)
|
oldFilePathTemp := filepath.Join(oldPath, tStorage.TorrentName)
|
||||||
oldFilePath, err := filepath.Abs(oldFilePathTemp)
|
var err error
|
||||||
|
oldFilePath, err = filepath.Abs(oldFilePathTemp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": oldFilePath}).Error("Cannot create absolute file path!")
|
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": oldFilePath}).Error("Cannot create absolute file path!")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("oldfilepath", oldFilePath)
|
|
||||||
} else {
|
} else {
|
||||||
oldFilePathTemp := filepath.Join(config.TorrentConfig.DataDir, tStorage.TorrentName)
|
oldFilePathTemp := filepath.Join(config.TorrentConfig.DataDir, tStorage.TorrentName)
|
||||||
oldFilePath, err := filepath.Abs(oldFilePathTemp)
|
var err error
|
||||||
|
oldFilePath, err = filepath.Abs(oldFilePathTemp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": oldFilePath}).Error("Cannot create absolute file path!")
|
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": oldFilePath}).Error("Cannot create absolute file path!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newFilePathTemp := filepath.Join(tStorage.StoragePath, tStorage.TorrentName)
|
newFilePathTemp := filepath.Join(tStorage.StoragePath, tStorage.TorrentName)
|
||||||
newFilePath, err := filepath.Abs(newFilePathTemp)
|
newFilePath, err := filepath.Abs(newFilePathTemp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -55,70 +52,27 @@ func MoveAndLeaveSymlink(config FullClientSettings, tHash string, db *storm.DB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if oldFilePath != newFilePath {
|
if oldFilePath != newFilePath {
|
||||||
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
|
newFilePathDir := filepath.Dir(newFilePath)
|
||||||
if oldFileInfo.IsDir() {
|
os.Mkdir(newFilePathDir, 0755)
|
||||||
os.Mkdir(newFilePath, 0755)
|
err := folderCopy.Copy(oldFilePath, newFilePath) //copy the folder to the new location
|
||||||
if moveDone {
|
if err != nil {
|
||||||
err := folderCopy.Copy(config.TorrentConfig.DataDir, newFilePath)
|
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error Copying Folder!")
|
||||||
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)
|
|
||||||
notifyUser(tStorage, config, db)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
srcFile, err := os.Open(oldFilePath)
|
|
||||||
defer srcFile.Close()
|
|
||||||
if err != nil {
|
|
||||||
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "error": err}).Error("Windows: Cannot open old file for copy")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
destFile, err := os.Create(newFilePath)
|
|
||||||
defer destFile.Close()
|
|
||||||
if err != nil {
|
|
||||||
Logger.WithFields(logrus.Fields{"New File Path": newFilePath, "error": err}).Error("Windows: Cannot open new file for copying into")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bytesWritten, err := io.Copy(destFile, srcFile)
|
|
||||||
if err != nil {
|
|
||||||
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Windows: Cannot copy old file into new")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = destFile.Sync()
|
|
||||||
if err != nil {
|
|
||||||
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, db)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
folderCopy.Copy(oldFilePath, newFilePath)
|
|
||||||
os.Chmod(newFilePath, 0777) //changing permissions on the new file to be permissive
|
|
||||||
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
|
|
||||||
if err != nil {
|
|
||||||
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error creating symlink")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notifyUser(tStorage, config, db)
|
|
||||||
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath}).Info("Moving completed torrent")
|
|
||||||
}
|
}
|
||||||
|
os.Chmod(newFilePath, 0777)
|
||||||
|
if runtime.GOOS != "windows" { //TODO the windows symlink is broken on windows 10 creator edition, so on the other platforms create symlink (windows will copy) until Go1.11
|
||||||
|
os.RemoveAll(oldFilePath)
|
||||||
|
err = os.Symlink(newFilePath, oldFilePath)
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error creating symlink")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if moveDone == false {
|
||||||
|
tStorage.TorrentMoved = true //TODO error handling instead of just saying torrent was moved when it was not
|
||||||
|
notifyUser(tStorage, config, db) //Only notify if we haven't moved yet, don't want to push notify user every time user uses change storage button
|
||||||
|
}
|
||||||
|
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath}).Info("Moving completed torrent")
|
||||||
|
tStorage.StoragePath = filepath.Dir(newFilePath)
|
||||||
|
Storage.UpdateStorageTick(db, tStorage)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -128,7 +127,7 @@ 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
|
//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, torrentType, torrentFileName, torrentStoragePath, labelValue, tFileUploadFolder string) {
|
func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.TorrentLocal, torrentDbStorage *storm.DB, torrentType, torrentFilePathAbs, torrentStoragePath, labelValue string, config FullClientSettings) {
|
||||||
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
|
||||||
@@ -147,6 +146,7 @@ func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.To
|
|||||||
torrentLocalStorage.Label = labelValue
|
torrentLocalStorage.Label = labelValue
|
||||||
torrentLocalStorage.DateAdded = time.Now().Format("Jan _2 2006")
|
torrentLocalStorage.DateAdded = time.Now().Format("Jan _2 2006")
|
||||||
torrentLocalStorage.StoragePath = torrentStoragePath
|
torrentLocalStorage.StoragePath = torrentStoragePath
|
||||||
|
torrentLocalStorage.TempStoragePath = config.TorrentConfig.DataDir
|
||||||
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.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.TorrentMoved = false //by default the torrent has no been moved.
|
||||||
@@ -154,8 +154,6 @@ func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.To
|
|||||||
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
|
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
|
||||||
torrentFilePath := filepath.Join(tFileUploadFolder, torrentFileName)
|
|
||||||
torrentFilePathAbs, err := filepath.Abs(torrentFilePath)
|
|
||||||
torrentfile, err := ioutil.ReadFile(torrentFilePathAbs)
|
torrentfile, err := ioutil.ReadFile(torrentFilePathAbs)
|
||||||
torrentLocalStorage.TorrentFileName = torrentFilePathAbs
|
torrentLocalStorage.TorrentFileName = torrentFilePathAbs
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -236,11 +234,10 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
|||||||
PercentDone := fmt.Sprintf("%.2f", float32(singleTorrent.BytesCompleted())/float32(singleTorrentFromStorage.TorrentSize))
|
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.BytesReadData //used for calculations not passed to client calculating up/down speed
|
||||||
fullClientDB.DataBytesWritten = fullStruct.ConnStats.DataBytesWritten //used for calculations not passed to client calculating up/down speed
|
fullClientDB.DataBytesWritten = fullStruct.ConnStats.BytesWrittenData //used for calculations not passed to client calculating up/down speed
|
||||||
fullClientDB.ActivePeers = activePeersString + " / (" + totalPeersString + ")"
|
fullClientDB.ActivePeers = activePeersString + " / (" + totalPeersString + ")"
|
||||||
fullClientDB.TorrentHashString = TempHash.String()
|
fullClientDB.TorrentHashString = TempHash.String()
|
||||||
fullClientDB.StoragePath = singleTorrentFromStorage.StoragePath
|
|
||||||
fullClientDB.TorrentName = singleTorrentFromStorage.TorrentName
|
fullClientDB.TorrentName = singleTorrentFromStorage.TorrentName
|
||||||
fullClientDB.DateAdded = singleTorrentFromStorage.DateAdded
|
fullClientDB.DateAdded = singleTorrentFromStorage.DateAdded
|
||||||
fullClientDB.TorrentLabel = singleTorrentFromStorage.Label
|
fullClientDB.TorrentLabel = singleTorrentFromStorage.Label
|
||||||
@@ -252,7 +249,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
|||||||
TempHash := singleTorrent.InfoHash()
|
TempHash := singleTorrent.InfoHash()
|
||||||
if previousElement.TorrentHashString == TempHash.String() { //matching previous to new
|
if previousElement.TorrentHashString == TempHash.String() { //matching previous to new
|
||||||
CalculateTorrentSpeed(singleTorrent, fullClientDB, previousElement)
|
CalculateTorrentSpeed(singleTorrent, fullClientDB, previousElement)
|
||||||
fullClientDB.TotalUploadedBytes = singleTorrentFromStorage.UploadedBytes + (fullStruct.ConnStats.DataBytesWritten - previousElement.DataBytesWritten)
|
fullClientDB.TotalUploadedBytes = singleTorrentFromStorage.UploadedBytes + (fullStruct.ConnStats.BytesWrittenData - previousElement.DataBytesWritten)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -276,7 +273,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
|||||||
}
|
}
|
||||||
|
|
||||||
//CreateFileListArray creates a file list for a single torrent that is selected and sent to the server
|
//CreateFileListArray creates a file list for a single torrent that is selected and sent to the server
|
||||||
func CreateFileListArray(tclient *torrent.Client, selectedHash string, db *storm.DB) TorrentFileList {
|
func CreateFileListArray(tclient *torrent.Client, selectedHash string, db *storm.DB, config FullClientSettings) TorrentFileList {
|
||||||
runningTorrents := tclient.Torrents() //don't need running torrent array since we aren't adding or deleting from storage
|
runningTorrents := tclient.Torrents() //don't need running torrent array since we aren't adding or deleting from storage
|
||||||
torrentFileListStorage := Storage.FetchTorrentFromStorage(db, selectedHash)
|
torrentFileListStorage := Storage.FetchTorrentFromStorage(db, selectedHash)
|
||||||
TorrentFileListSelected := TorrentFileList{}
|
TorrentFileListSelected := TorrentFileList{}
|
||||||
@@ -289,11 +286,7 @@ func CreateFileListArray(tclient *torrent.Client, selectedHash string, db *storm
|
|||||||
for _, singleFile := range torrentFilesRaw {
|
for _, singleFile := range torrentFilesRaw {
|
||||||
TorrentFileStruct.TorrentHashString = tempHash
|
TorrentFileStruct.TorrentHashString = tempHash
|
||||||
TorrentFileStruct.FileName = singleFile.DisplayPath()
|
TorrentFileStruct.FileName = singleFile.DisplayPath()
|
||||||
absFilePath, err := filepath.Abs(singleFile.Path())
|
TorrentFileStruct.FilePath = singleFile.Path()
|
||||||
if err != nil {
|
|
||||||
Logger.WithFields(logrus.Fields{"file": singleFile.Path()}).Debug("Unable to create absolute path")
|
|
||||||
}
|
|
||||||
TorrentFileStruct.FilePath = absFilePath
|
|
||||||
PieceState := singleFile.State()
|
PieceState := singleFile.State()
|
||||||
var downloadedBytes int64
|
var downloadedBytes int64
|
||||||
for _, piece := range PieceState {
|
for _, piece := range PieceState {
|
||||||
|
@@ -62,7 +62,7 @@ func CopyFile(srcFile string, destFile string) {
|
|||||||
func CalculateTorrentSpeed(t *torrent.Torrent, c *ClientDB, oc ClientDB) {
|
func CalculateTorrentSpeed(t *torrent.Torrent, c *ClientDB, oc ClientDB) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
bytes := t.BytesCompleted()
|
bytes := t.BytesCompleted()
|
||||||
bytesUpload := t.Stats().DataBytesWritten
|
bytesUpload := t.Stats().BytesWrittenData
|
||||||
dt := float32(now.Sub(oc.UpdatedAt)) // get the delta time length between now and last updated
|
dt := float32(now.Sub(oc.UpdatedAt)) // get the delta time length between now and last updated
|
||||||
db := float32(bytes - oc.BytesCompleted) //getting the delta bytes
|
db := float32(bytes - oc.BytesCompleted) //getting the delta bytes
|
||||||
rate := db * (float32(time.Second) / dt) // converting into seconds
|
rate := db * (float32(time.Second) / dt) // converting into seconds
|
||||||
|
@@ -89,7 +89,10 @@ const inlineStyle = {
|
|||||||
{i: 'b', x: 0, y: 1, w: 1, h: 5, static: true},
|
{i: 'b', x: 0, y: 1, w: 1, h: 5, static: true},
|
||||||
{i: 'c', x: 1, y: 1, w: 5, h: 5, minW: 5, minH: 3, static: true},
|
{i: 'c', x: 1, y: 1, w: 5, h: 5, minW: 5, minH: 3, static: true},
|
||||||
];
|
];
|
||||||
this.state = { layout };
|
this.state = {
|
||||||
|
layout ,
|
||||||
|
textValue: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -103,7 +106,6 @@ const inlineStyle = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleAddRSSFeed = () => {
|
handleAddRSSFeed = () => {
|
||||||
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]
|
||||||
@@ -113,20 +115,13 @@ const inlineStyle = {
|
|||||||
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
|
||||||
|
this.setState({textValue: ""})
|
||||||
}
|
}
|
||||||
|
|
||||||
setTextValue = (event) => {
|
setTextValue = (event) => {
|
||||||
this.setState({ textValue: event.target.value });
|
this.setState({ textValue: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
|
||||||
console.log("nextprops", nextProps, "Modal", nextProps.RSSModalOpen)
|
|
||||||
}
|
|
||||||
componentWillMount () {
|
|
||||||
console.log("Mounting grid")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={inlineStyle}>
|
<div style={inlineStyle}>
|
||||||
|
@@ -41,7 +41,7 @@ class DeleteTorrentModal extends React.Component {
|
|||||||
let selection = []
|
let selection = []
|
||||||
let deleteTorrentHashes = {
|
let deleteTorrentHashes = {
|
||||||
MessageType: "deleteTorrents",
|
MessageType: "deleteTorrents",
|
||||||
MessageDetail: "true",
|
MessageDetail: "false", //delete with data
|
||||||
Payload: this.props.selectionHashes
|
Payload: this.props.selectionHashes
|
||||||
}
|
}
|
||||||
console.log("Deleting Torrents", deleteTorrentHashes)
|
console.log("Deleting Torrents", deleteTorrentHashes)
|
||||||
@@ -56,7 +56,7 @@ class DeleteTorrentModal extends React.Component {
|
|||||||
|
|
||||||
let deleteTorrentHashes = {
|
let deleteTorrentHashes = {
|
||||||
MessageType: "deleteTorrents",
|
MessageType: "deleteTorrents",
|
||||||
MessageDetail: "true",
|
MessageDetail: "true", //delete with data
|
||||||
Payload: this.props.selectionHashes,
|
Payload: this.props.selectionHashes,
|
||||||
}
|
}
|
||||||
console.log("Deleting Torrents and Data", deleteTorrentHashes)
|
console.log("Deleting Torrents and Data", deleteTorrentHashes)
|
||||||
|
46
main.go
46
main.go
@@ -163,7 +163,7 @@ func main() {
|
|||||||
|
|
||||||
case "torrentFileListRequest": //client requested a filelist update
|
case "torrentFileListRequest": //client requested a filelist update
|
||||||
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested FileList Update")
|
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested FileList Update")
|
||||||
FileListArray := Engine.CreateFileListArray(tclient, msg.Payload[0], db)
|
FileListArray := Engine.CreateFileListArray(tclient, msg.Payload[0], db, Config)
|
||||||
conn.WriteJSON(FileListArray) //writing the JSON to the client
|
conn.WriteJSON(FileListArray) //writing the JSON to the client
|
||||||
|
|
||||||
case "torrentDetailedInfo":
|
case "torrentDetailedInfo":
|
||||||
@@ -176,6 +176,21 @@ func main() {
|
|||||||
torrentPeerList := Engine.CreatePeerListArray(tclient, msg.Payload[0])
|
torrentPeerList := Engine.CreatePeerListArray(tclient, msg.Payload[0])
|
||||||
conn.WriteJSON(torrentPeerList)
|
conn.WriteJSON(torrentPeerList)
|
||||||
|
|
||||||
|
case "fetchTorrentsByLabel": //TODO test this to make sure it works
|
||||||
|
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested Torrents by Label")
|
||||||
|
label := msg.MessageDetail
|
||||||
|
torrentsByLabel := Storage.FetchTorrentsByLabel(db, label)
|
||||||
|
RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db)
|
||||||
|
labelRunningArray := []Engine.ClientDB{}
|
||||||
|
for _, torrent := range RunningTorrentArray { //Ranging over the running torrents and if the hashes match we have torrents by label
|
||||||
|
for _, label := range torrentsByLabel {
|
||||||
|
if torrent.TorrentHashString == label.Hash {
|
||||||
|
labelRunningArray = append(labelRunningArray, torrent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn.WriteJSON(labelRunningArray)
|
||||||
|
|
||||||
case "changeStorageValue":
|
case "changeStorageValue":
|
||||||
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested Storage Location Update")
|
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested Storage Location Update")
|
||||||
newStorageLocation := msg.MessageDetail
|
newStorageLocation := msg.MessageDetail
|
||||||
@@ -183,10 +198,16 @@ func main() {
|
|||||||
for _, singleHash := range hashes {
|
for _, singleHash := range hashes {
|
||||||
singleTorrent := Storage.FetchTorrentFromStorage(db, singleHash)
|
singleTorrent := Storage.FetchTorrentFromStorage(db, singleHash)
|
||||||
oldPath := singleTorrent.StoragePath
|
oldPath := singleTorrent.StoragePath
|
||||||
singleTorrent.StoragePath = newStorageLocation
|
newStorageLocationAbs, err := filepath.Abs(filepath.ToSlash(newStorageLocation))
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"patherr": err, "path": newStorageLocation}).Warn("Unable to create absolute path for storage location, using default")
|
||||||
|
singleTorrent.StoragePath = Config.TorrentConfig.DataDir
|
||||||
|
} else {
|
||||||
|
singleTorrent.StoragePath = newStorageLocationAbs
|
||||||
|
}
|
||||||
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?
|
||||||
Logger.WithFields(logrus.Fields{"message": msg}).Info("Torrent completed so moving to new location")
|
Logger.WithFields(logrus.Fields{"message": msg}).Info("Change Storage Value called")
|
||||||
Engine.MoveAndLeaveSymlink(Config, singleHash, db, true, oldPath)
|
Engine.MoveAndLeaveSymlink(Config, singleHash, db, true, oldPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,7 +304,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, Config.TFileUploadFolder) //starting the torrent and creating local DB entry
|
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "magnet", "", storageValue, labelValue, Config) //starting the torrent and creating local DB entry
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,8 +317,6 @@ 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,21 +333,22 @@ func main() {
|
|||||||
storageValue, _ = filepath.Abs(filepath.ToSlash(Config.DefaultMoveFolder))
|
storageValue, _ = filepath.Abs(filepath.ToSlash(Config.DefaultMoveFolder))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filePath := filepath.Join(Config.TFileUploadFolder, FileName) //creating a full filepath to store the .torrent files
|
filePath := filepath.Join(Config.TFileUploadFolder, FileName)
|
||||||
|
filePathAbs, err := filepath.Abs(filePath) //creating a full filepath to store the .torrent files
|
||||||
|
|
||||||
err = ioutil.WriteFile(filePath, file, 0755) //Dumping our received file into the filename
|
err = ioutil.WriteFile(filePathAbs, file, 0755) //Dumping our received file into the filename
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"filepath": filePath, "file Name": FileName, "Error": err}).Error("Unable to write torrent data to file")
|
Logger.WithFields(logrus.Fields{"filepath": filePathAbs, "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)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientTorrent, err := tclient.AddTorrentFromFile(filePath)
|
clientTorrent, err := tclient.AddTorrentFromFile(filePathAbs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.WithFields(logrus.Fields{"filepath": filePath, "Error": err}).Error("Unable to add Torrent to torrent server")
|
Logger.WithFields(logrus.Fields{"filepath": filePathAbs, "Error": err}).Error("Unable to add Torrent to torrent server")
|
||||||
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": filePathAbs}).Info("Added torrent")
|
||||||
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, Config.TorrentConfig.DataDir, "file", filePath, storageValue, labelValue, Config.TFileUploadFolder)
|
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "file", filePathAbs, storageValue, labelValue, Config)
|
||||||
|
|
||||||
case "stopTorrents":
|
case "stopTorrents":
|
||||||
TorrentListCommands := msg.Payload
|
TorrentListCommands := msg.Payload
|
||||||
|
@@ -97281,7 +97281,6 @@ var RSSModalLayout = function (_React$Component) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_this.handleAddRSSFeed = function () {
|
_this.handleAddRSSFeed = function () {
|
||||||
_this.setState({ textValue: "Clear" }); //clearing out the text submitted
|
|
||||||
var RSSURLSubmit = {
|
var RSSURLSubmit = {
|
||||||
MessageType: "addRSSFeed",
|
MessageType: "addRSSFeed",
|
||||||
Payload: [_this.state.textValue]
|
Payload: [_this.state.textValue]
|
||||||
@@ -97291,6 +97290,7 @@ var RSSModalLayout = function (_React$Component) {
|
|||||||
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
|
||||||
|
_this.setState({ textValue: "" });
|
||||||
};
|
};
|
||||||
|
|
||||||
_this.setTextValue = function (event) {
|
_this.setTextValue = function (event) {
|
||||||
@@ -97298,7 +97298,10 @@ var RSSModalLayout = function (_React$Component) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var layout = [{ i: 'a', x: 0, y: 0, w: 6, h: 1, static: true }, { i: 'b', x: 0, y: 1, w: 1, h: 5, static: true }, { i: 'c', x: 1, y: 1, w: 5, h: 5, minW: 5, minH: 3, static: true }];
|
var layout = [{ i: 'a', x: 0, y: 0, w: 6, h: 1, static: true }, { i: 'b', x: 0, y: 1, w: 1, h: 5, static: true }, { i: 'c', x: 1, y: 1, w: 5, h: 5, minW: 5, minH: 3, static: true }];
|
||||||
_this.state = { layout: layout };
|
_this.state = {
|
||||||
|
layout: layout,
|
||||||
|
textValue: ""
|
||||||
|
};
|
||||||
|
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
@@ -97308,16 +97311,6 @@ var RSSModalLayout = function (_React$Component) {
|
|||||||
value: function onLayoutChange(layout) {
|
value: function onLayoutChange(layout) {
|
||||||
this.props.onLayoutChange(layout);
|
this.props.onLayoutChange(layout);
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
key: 'componentWillReceiveProps',
|
|
||||||
value: function componentWillReceiveProps(nextProps) {
|
|
||||||
console.log("nextprops", nextProps, "Modal", nextProps.RSSModalOpen);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'componentWillMount',
|
|
||||||
value: function componentWillMount() {
|
|
||||||
console.log("Mounting grid");
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
key: 'render',
|
key: 'render',
|
||||||
value: function render() {
|
value: function render() {
|
||||||
@@ -116880,7 +116873,7 @@ var DeleteTorrentModal = function (_React$Component) {
|
|||||||
var selection = [];
|
var selection = [];
|
||||||
var deleteTorrentHashes = {
|
var deleteTorrentHashes = {
|
||||||
MessageType: "deleteTorrents",
|
MessageType: "deleteTorrents",
|
||||||
MessageDetail: "true",
|
MessageDetail: "false", //delete with data
|
||||||
Payload: _this.props.selectionHashes
|
Payload: _this.props.selectionHashes
|
||||||
};
|
};
|
||||||
console.log("Deleting Torrents", deleteTorrentHashes);
|
console.log("Deleting Torrents", deleteTorrentHashes);
|
||||||
@@ -116893,7 +116886,7 @@ var DeleteTorrentModal = function (_React$Component) {
|
|||||||
|
|
||||||
var deleteTorrentHashes = {
|
var deleteTorrentHashes = {
|
||||||
MessageType: "deleteTorrents",
|
MessageType: "deleteTorrents",
|
||||||
MessageDetail: "true",
|
MessageDetail: "true", //delete with data
|
||||||
Payload: _this.props.selectionHashes
|
Payload: _this.props.selectionHashes
|
||||||
};
|
};
|
||||||
console.log("Deleting Torrents and Data", deleteTorrentHashes);
|
console.log("Deleting Torrents and Data", deleteTorrentHashes);
|
||||||
|
@@ -46,14 +46,15 @@ type TorrentLocal struct {
|
|||||||
Hash string `storm:"id,unique"` //Hash should be unique for every torrent... if not we are re-adding an already added torrent
|
Hash string `storm:"id,unique"` //Hash should be unique for every torrent... if not we are re-adding an already added torrent
|
||||||
InfoBytes []byte
|
InfoBytes []byte
|
||||||
DateAdded string
|
DateAdded string
|
||||||
StoragePath string
|
StoragePath string //The absolute value of the path where the torrent will be moved when completed
|
||||||
|
TempStoragePath string //The absolute path of where the torrent is temporarily stored as it is downloaded
|
||||||
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)
|
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 //Should be absolute path
|
TorrentFileName string //Should be just the name of the torrent
|
||||||
TorrentFile []byte
|
TorrentFile []byte
|
||||||
Label string
|
Label string
|
||||||
UploadedBytes int64
|
UploadedBytes int64
|
||||||
@@ -144,6 +145,22 @@ func FetchTorrentFromStorage(torrentStorage *storm.DB, selectedHash string) Torr
|
|||||||
return singleTorrentInfo
|
return singleTorrentInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FetchTorrentsByLabel fetches a list of torrents that have a specific label
|
||||||
|
func FetchTorrentsByLabel(torrentStorage *storm.DB, label string) []TorrentLocal {
|
||||||
|
allTorrents := []*TorrentLocal{}
|
||||||
|
torrentsByLabel := []TorrentLocal{}
|
||||||
|
err := torrentStorage.All(&allTorrents)
|
||||||
|
if err != nil {
|
||||||
|
Logger.WithFields(logrus.Fields{"database": torrentStorage, "error": err}).Error("Unable to read Database into torrentLocalArray!")
|
||||||
|
}
|
||||||
|
for _, torrent := range allTorrents {
|
||||||
|
if torrent.Label == label {
|
||||||
|
torrentsByLabel = append(torrentsByLabel, *torrent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return torrentsByLabel
|
||||||
|
}
|
||||||
|
|
||||||
//FetchHashHistory fetches the infohash of all torrents added into the client. The cron job checks this so as not to add torrents from RSS that were already added before
|
//FetchHashHistory fetches the infohash of all torrents added into the client. The cron job checks this so as not to add torrents from RSS that were already added before
|
||||||
func FetchHashHistory(db *storm.DB) TorrentHistoryList {
|
func FetchHashHistory(db *storm.DB) TorrentHistoryList {
|
||||||
torrentHistory := TorrentHistoryList{}
|
torrentHistory := TorrentHistoryList{}
|
||||||
|
3
torrentUpload/desktop.ini
Normal file
3
torrentUpload/desktop.ini
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[LocalizedFileNames]
|
||||||
|
Plan_9_from_Outer_Space_1959_archive.torrent=@Plan_9_from_Outer_Space_1959_archive.torrent,0
|
||||||
|
Return_of_the_Street_Fighter.avi.torrent=@Return_of_the_Street_Fighter.avi.torrent,0
|
Reference in New Issue
Block a user