diff --git a/config.toml b/config.toml index 0936c523..418b12ca 100644 --- a/config.toml +++ b/config.toml @@ -1,14 +1,14 @@ [serverConfig] ServerPort = ":8000" #leave format as is it expects a string with colon - ServerAddr = "192.168.1.100" #Put in the IP address you want to bind to + ServerAddr = "192.168.1.6" #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 + 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 #Limits your upload and download speed globally, all are averages and not burst protected (usually burst on start). @@ -25,24 +25,24 @@ [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] #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 - 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] DisableEncryption = false ForceEncryption = false - PreferNoEncryption = true + PreferNoEncryption = false [torrentClientConfig] 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. NoUpload = false #boolean diff --git a/config.toml.bk b/config.toml.bk new file mode 100644 index 00000000..0936c523 --- /dev/null +++ b/config.toml.bk @@ -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" \ No newline at end of file diff --git a/engine/doneTorrentActions.go b/engine/doneTorrentActions.go index 50572095..1f81115c 100644 --- a/engine/doneTorrentActions.go +++ b/engine/doneTorrentActions.go @@ -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. -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) Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName}).Info("Move and Create symlink started for torrent") var oldFilePath string @@ -25,6 +25,8 @@ func MoveAndLeaveSymlink(config Settings.FullClientSettings, tHash string, db *s oldFilePath, err = filepath.Abs(oldFilePathTemp) if err != nil { Logger.WithFields(logrus.Fields{"Torrent Name": tStorage.TorrentName, "Filepath": oldFilePath}).Error("Cannot create absolute file path!") + moveDone = false + return err } } else { 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) if err != nil { 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) 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!") + moveDone = false + return err } _, err = os.Stat(tStorage.StoragePath) if os.IsNotExist(err) { err := os.MkdirAll(tStorage.StoragePath, 0755) if err != nil { Logger.WithFields(logrus.Fields{"New File Path": newFilePath, "error": err}).Error("Cannot create new directory") + moveDone = false + return err } } oldFileInfo, err := os.Stat(oldFilePath) 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!") - return + moveDone = false + return err } 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 if err != nil { 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) 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) if err != nil { 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 { @@ -75,7 +88,7 @@ func MoveAndLeaveSymlink(config Settings.FullClientSettings, tHash string, db *s tStorage.StoragePath = filepath.Dir(newFilePath) Storage.UpdateStorageTick(db, tStorage) } - + return nil } func notifyUser(tStorage Storage.TorrentLocal, config Settings.FullClientSettings, db *storm.DB) { diff --git a/engine/engine.go b/engine/engine.go index 30c0003f..243705a5 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -275,7 +275,16 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto TempHash = singleTorrent.InfoHash() 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...") - 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() diff --git a/engine/engineHelpers.go b/engine/engineHelpers.go index 39c560d7..f033465f 100644 --- a/engine/engineHelpers.go +++ b/engine/engineHelpers.go @@ -23,6 +23,11 @@ func secondsToMinutes(inSeconds int64) string { 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 func MakeRange(min, max int) []int { a := make([]int, max-min+1) diff --git a/main.go b/main.go index 64bd0fdb..d14dad18 100644 --- a/main.go +++ b/main.go @@ -418,7 +418,7 @@ func main() { } Logger.WithFields(logrus.Fields{"clientTorrent": clientTorrent, "magnetLink": magnetLink}).Info("Adding torrent to client!") Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received MagnetLink"}, conn) - Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "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) } 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": torrentHashes := payloadData["TorrentHashes"].([]interface{})