fixing notification issue, parallelizing startTorrent, verifying torrent after move

This commit is contained in:
2018-03-25 09:34:32 -04:00
parent 10399cc6e5
commit 0a0f0cd577
6 changed files with 162 additions and 13 deletions

View File

@@ -1,14 +1,14 @@
[serverConfig] [serverConfig]
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 = "192.168.1.100" #Put in the IP address you want to bind to ServerAddr = "192.168.1.6" #Put in the IP address you want to bind to
LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic
LogOutput = "stdout" #Options = file, stdout #file will print it to logs/server.log LogOutput = "stdout" #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
#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 = 'downloads' #default path that a finished torrent is symlinked to after completion. Torrents added via RSS will default here DefaultMoveFolder = 'Z:\downloads' #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). #Limits your upload and download speed globally, all are averages and not burst protected (usually burst on start).
@@ -25,24 +25,24 @@
[notifications] [notifications]
PushBulletToken = "" #add your pushbullet api token here to notify of torrent completion to pushbullet PushBulletToken = "o.8sUHemPkTCaty3u7KnyvEBN19EkeT63g" #add your pushbullet api token here to notify of torrent completion to pushbullet
[reverseProxy] [reverseProxy]
#This is for setting up goTorrent behind a reverse Proxy (with SSL, reverse proxy with no SSL will require editing the WSS connection to a WS connection manually) #This is for setting up goTorrent behind a reverse Proxy (with SSL, reverse proxy with no SSL will require editing the WSS connection to a WS connection manually)
ProxyEnabled = false #bool, either false or true ProxyEnabled = true #bool, either false or true
#URL is CASE SENSITIVE #URL is CASE SENSITIVE
BaseURL = "domain.com/subroute/" # MUST be in the format (if you have a subdomain, and must have trailing slash) "yoursubdomain.domain.org/subroute/" BaseURL = "derajnet.duckdns.org/gopher/" # MUST be in the format (if you have a subdomain, and must have trailing slash) "yoursubdomain.domain.org/subroute/"
[EncryptionPolicy] [EncryptionPolicy]
DisableEncryption = false DisableEncryption = false
ForceEncryption = false ForceEncryption = false
PreferNoEncryption = true PreferNoEncryption = false
[torrentClientConfig] [torrentClientConfig]
DownloadDir = 'downloading' #the full OR relative path where the torrent server stores in-progress torrents DownloadDir = 'downloading' #the full OR relative path where the torrent server stores in-progress torrents
Seed = true #boolean #seed after download Seed = false #boolean #seed after download
# Never send chunks to peers. # Never send chunks to peers.
NoUpload = false #boolean NoUpload = false #boolean

122
config.toml.bk Normal file
View File

@@ -0,0 +1,122 @@
[serverConfig]
ServerPort = ":8000" #leave format as is it expects a string with colon
ServerAddr = "192.168.1.100" #Put in the IP address you want to bind to
LogLevel = "Info" # Options = Debug, Info, Warn, Error, Fatal, Panic
LogOutput = "stdout" #Options = file, stdout #file will print it to logs/server.log
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.
DefaultMoveFolder = 'downloads' #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"
[goTorrentWebUI]
#Basic goTorrentWebUI authentication (not terribly secure, implemented in JS, password is hashed to SHA256, not salted, basically don't depend on this if you require very good security)
WebUIAuth = false # bool, if false no authentication is required for the webUI
WebUIUser = "admin"
WebUIPassword = "Password1"
[notifications]
PushBulletToken = "" #add your pushbullet api token here to notify of torrent completion to pushbullet
[reverseProxy]
#This is for setting up goTorrent behind a reverse Proxy (with SSL, reverse proxy with no SSL will require editing the WSS connection to a WS connection manually)
ProxyEnabled = false #bool, either false or true
#URL is CASE SENSITIVE
BaseURL = "domain.com/subroute/" # MUST be in the format (if you have a subdomain, and must have trailing slash) "yoursubdomain.domain.org/subroute/"
[EncryptionPolicy]
DisableEncryption = false
ForceEncryption = false
PreferNoEncryption = true
[torrentClientConfig]
DownloadDir = 'downloading' #the full OR relative path where the torrent server stores in-progress torrents
Seed = true #boolean #seed after download
# Never send chunks to peers.
NoUpload = false #boolean
#User-provided Client peer ID. If not present, one is generated automatically.
PeerID = "" #string
#The address to listen for new uTP and TCP bittorrent protocol connections. DHT shares a UDP socket with uTP unless configured otherwise.
ListenAddr = "" #Leave Blank for default, syntax "HOST:PORT"
#Don't announce to trackers. This only leaves DHT to discover peers.
DisableTrackers = false #boolean
DisablePEX = false # boolean
# Don't create a DHT.
NoDHT = false #boolean
#For the bittorrent protocol.
DisableUTP = false #bool
#For the bittorrent protocol.
DisableTCP = false #bool
#Called to instantiate storage for each added torrent. Builtin backends
# are in the storage package. If not set, the "file" implementation is used.
DefaultStorage = "storage.ClientImpl"
#encryption policy
IPBlocklist = "" #of type iplist.Ranger
DisableIPv6 = false #boolean
Debug = false #boolean
#HTTP *http.Client
HTTPUserAgent = "" # HTTPUserAgent changes default UserAgent for HTTP requests
ExtendedHandshakeClientVersion = ""
Bep20 = ""
# Overrides the default DHT configuration, see dhtServerConfig #advanced.. so be careful
DHTConfig = "" # default is "dht.ServerConfig"
[dhtServerConfig]
# Set NodeId Manually. Caller must ensure that if NodeId does not conform to DHT Security Extensions, that NoSecurity is also set.
NodeId = "" #[20]byte
Conn = "" # https:#godoc.org/net#PacketConn #not implemented
# Don't respond to queries from other nodes.
Passive = false # boolean
# the default addresses are "router.utorrent.com:6881","router.bittorrent.com:6881","dht.transmissionbt.com:6881","dht.aelitis.com:6881",
#https:#github.com/anacrolix/dht/blob/master/dht.go
StartingNodes = "dht.GlobalBootstrapAddrs"
#Disable the DHT security extension: http:#www.libtorrent.org/dht_sec.html.
NoSecurity = false
#Initial IP blocklist to use. Applied before serving and bootstrapping begins.
IPBlocklist = "" #of type iplist.Ranger
#Used to secure the server's ID. Defaults to the Conn's LocalAddr(). Set to the IP that remote nodes will see,
#as that IP is what they'll use to validate our ID.
PublicIP = "" #net.IP
#Hook received queries. Return true if you don't want to propagate to the default handlers.
OnQuery = "func(query *krpc.Msg, source net.Addr) (propagate bool)"
#Called when a peer successfully announces to us.
OnAnnouncePeer = "func(infoHash metainfo.Hash, peer Peer)"
#How long to wait before re-sending queries that haven't received a response. Defaults to a random value between 4.5 and 5.5s.
QueryResendDelay = "func() time.Duration"

View File

@@ -15,7 +15,7 @@ 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 Settings.FullClientSettings, tHash string, db *storm.DB, moveDone bool, oldPath string) { //moveDone and oldPath are for moving a completed torrent func MoveAndLeaveSymlink(config Settings.FullClientSettings, tHash string, db *storm.DB, moveDone bool, oldPath string) error { //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.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
@@ -25,6 +25,8 @@ func MoveAndLeaveSymlink(config Settings.FullClientSettings, tHash string, db *s
oldFilePath, err = filepath.Abs(oldFilePathTemp) 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!")
moveDone = false
return err
} }
} else { } else {
oldFilePathTemp := filepath.Join(config.TorrentConfig.DataDir, tStorage.TorrentName) oldFilePathTemp := filepath.Join(config.TorrentConfig.DataDir, tStorage.TorrentName)
@@ -32,24 +34,31 @@ func MoveAndLeaveSymlink(config Settings.FullClientSettings, tHash string, db *s
oldFilePath, err = filepath.Abs(oldFilePathTemp) 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!")
moveDone = false
return err
} }
} }
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 {
Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": newFilePath}).Error("Cannot create absolute file path for new file path!") Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": newFilePath}).Error("Cannot create absolute file path for new file path!")
moveDone = false
return err
} }
_, err = os.Stat(tStorage.StoragePath) _, 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 {
Logger.WithFields(logrus.Fields{"New File Path": newFilePath, "error": err}).Error("Cannot create new directory") Logger.WithFields(logrus.Fields{"New File Path": newFilePath, "error": err}).Error("Cannot create new directory")
moveDone = false
return err
} }
} }
oldFileInfo, err := os.Stat(oldFilePath) oldFileInfo, err := os.Stat(oldFilePath)
if err != nil { if err != nil {
Logger.WithFields(logrus.Fields{"Old File info": oldFileInfo, "Old File Path": oldFilePath, "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 moveDone = false
return err
} }
if oldFilePath != newFilePath { if oldFilePath != newFilePath {
@@ -58,6 +67,8 @@ func MoveAndLeaveSymlink(config Settings.FullClientSettings, tHash string, db *s
err := folderCopy.Copy(oldFilePath, newFilePath) //copy the folder to the new location err := folderCopy.Copy(oldFilePath, newFilePath) //copy the folder to the new location
if err != nil { if err != nil {
Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error Copying Folder!") Logger.WithFields(logrus.Fields{"Old File Path": oldFilePath, "New File Path": newFilePath, "error": err}).Error("Error Copying Folder!")
moveDone = false
return err
} }
os.Chmod(newFilePath, 0777) 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 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
@@ -65,6 +76,8 @@ func MoveAndLeaveSymlink(config Settings.FullClientSettings, tHash string, db *s
err = os.Symlink(newFilePath, oldFilePath) err = os.Symlink(newFilePath, oldFilePath)
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")
moveDone = false
return err
} }
} }
if moveDone == false { if moveDone == false {
@@ -75,7 +88,7 @@ func MoveAndLeaveSymlink(config Settings.FullClientSettings, tHash string, db *s
tStorage.StoragePath = filepath.Dir(newFilePath) tStorage.StoragePath = filepath.Dir(newFilePath)
Storage.UpdateStorageTick(db, tStorage) Storage.UpdateStorageTick(db, tStorage)
} }
return nil
} }
func notifyUser(tStorage Storage.TorrentLocal, config Settings.FullClientSettings, db *storm.DB) { func notifyUser(tStorage Storage.TorrentLocal, config Settings.FullClientSettings, db *storm.DB) {

View File

@@ -275,7 +275,16 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
TempHash = singleTorrent.InfoHash() TempHash = singleTorrent.InfoHash()
if (calculatedCompletedSize == singleTorrentFromStorage.TorrentSize) && (singleTorrentFromStorage.TorrentMoved == false) { //if we are done downloading and haven't moved torrent yet if (calculatedCompletedSize == singleTorrentFromStorage.TorrentSize) && (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...") Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Torrent Completed, moving...")
go 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 tStorage := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String()) //Todo... find a better way to do this in the go-routine currently just to make sure it doesn't trigger multiple times
tStorage.TorrentMoved = true
Storage.UpdateStorageTick(db, tStorage)
go func() { //moving torrent in separate go-routine then verifying that the data is still there and correct
err := 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
if err != nil {
VerifyData(singleTorrent)
}
}()
} }
fullStruct := singleTorrent.Stats() fullStruct := singleTorrent.Stats()

View File

@@ -23,6 +23,11 @@ func secondsToMinutes(inSeconds int64) string {
return str return str
} }
//VerifyData just verifies the data of a torrent by hash
func VerifyData(singleTorrent *torrent.Torrent) {
singleTorrent.VerifyData()
}
//MakeRange creates a range of pieces to set their priority based on a file //MakeRange creates a range of pieces to set their priority based on a file
func MakeRange(min, max int) []int { func MakeRange(min, max int) []int {
a := make([]int, max-min+1) a := make([]int, max-min+1)

View File

@@ -418,7 +418,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, "magnet", "", storageValue, labelValue, Config) //starting the torrent and creating local DB entry go Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "magnet", "", storageValue, labelValue, Config) //starting the torrent and creating local DB entry
} }
@@ -465,7 +465,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": filePathAbs}).Info("Added torrent") Logger.WithFields(logrus.Fields{"clienttorrent": clientTorrent.Name(), "filename": filePathAbs}).Info("Added torrent")
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "file", filePathAbs, storageValue, labelValue, Config) go Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "file", filePathAbs, storageValue, labelValue, Config)
case "stopTorrents": case "stopTorrents":
torrentHashes := payloadData["TorrentHashes"].([]interface{}) torrentHashes := payloadData["TorrentHashes"].([]interface{})