File prio code added, API rewrite completed, some core features rewritten for clarity
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
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
|
||||
LogLevel = "Debug" # 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
|
||||
|
||||
SeedRatioStop = 1.50 #automatically stops the torrent after it reaches this seeding ratio
|
||||
@@ -20,7 +20,7 @@
|
||||
#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 = true # bool, if false no authentication is required for the webUI
|
||||
WebUIUser = "admin"
|
||||
WebUIPassword = "Password"
|
||||
WebUIPassword = "Password1"
|
||||
|
||||
|
||||
[notifications]
|
||||
|
@@ -9,7 +9,7 @@ var (
|
||||
baseFile = `
|
||||
var authMessage = {
|
||||
MessageType: "authRequest",
|
||||
Payload: [ClientAuthString]
|
||||
Payload: {"ClientAuthString": ClientAuthString}
|
||||
}
|
||||
|
||||
var kickStart = {
|
||||
|
@@ -11,11 +11,8 @@ import (
|
||||
|
||||
//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 {
|
||||
MessageType string
|
||||
MessageDetail string `json:",omitempty"`
|
||||
MessageDetailTwo string `json:",omitempty"`
|
||||
MessageDetailThree string `json:",omitempty"`
|
||||
Payload []string
|
||||
MessageType string
|
||||
Payload interface{}
|
||||
}
|
||||
|
||||
//Next are the messages the server sends to the client
|
||||
@@ -56,48 +53,48 @@ type TorrentFileList struct {
|
||||
|
||||
//PeerFileList returns a slice of peers
|
||||
type PeerFileList struct {
|
||||
MessageType string `json:"MessageType"`
|
||||
TotalPeers int `json:"TotalPeers"`
|
||||
PeerList []torrent.Peer `json:"PeerList"`
|
||||
MessageType string
|
||||
TotalPeers int
|
||||
PeerList []torrent.Peer
|
||||
}
|
||||
|
||||
//TorrentFile describes a single file that a torrent client is downloading for a single torrent
|
||||
type TorrentFile struct {
|
||||
TorrentHashString string //Used to tie the file to a torrent //TODO not sure if neededs
|
||||
FileName string
|
||||
FilePath string
|
||||
FileSize string
|
||||
FilePercent string
|
||||
FilePriority string
|
||||
TorrentHashString string //Used to tie the file to a torrent //TODO not sure if needed
|
||||
FileName string //The name of the file
|
||||
FilePath string //The relative filepath to the file
|
||||
FileSize string //Humanized file size display
|
||||
FilePercent string //String value of percent of individual file percent done
|
||||
FilePriority string //Currently "High", "Normal", or "Cancel"
|
||||
}
|
||||
|
||||
//ClientDB struct contains the struct that is used to compose the torrentlist
|
||||
type ClientDB struct { //TODO maybe separate out the internal bits into another client struct
|
||||
TorrentHashString string `json:"TorrentHashString"` //Passed to client for displaying hash and is used to uniquly identify all torrents
|
||||
TorrentName string `json:"TorrentName"`
|
||||
DownloadedSize string `json:"DownloadedSize"` //how much the client has downloaded total
|
||||
Size string `json:"Size"` //total size of the torrent
|
||||
DownloadSpeed string `json:"DownloadSpeed"` //the dl speed of the torrent
|
||||
Status string `json:"Status"` //Passed to client for display
|
||||
PercentDone string `json:"PercentDone"` //Passed to client to show percent done
|
||||
ActivePeers string `json:"ActivePeers"` //passed to client
|
||||
UploadSpeed string `json:"UploadSpeed"` //passed to client to show Uploadspeed
|
||||
StoragePath string `json:"StoragePath"` //Passed to client (and stored in stormdb)
|
||||
TorrentHashString string //Passed to client for displaying hash and is used to uniquely identify all torrents
|
||||
TorrentName string //String of the name of the torrent
|
||||
DownloadedSize string //how much the client has downloaded total
|
||||
Size string //total size of the torrent
|
||||
DownloadSpeed string //the dl speed of the torrent
|
||||
Status string //Passed to client for display
|
||||
PercentDone string //Passed to client to show percent done
|
||||
ActivePeers string //passed to client
|
||||
UploadSpeed string //passed to client to show Uploadspeed
|
||||
StoragePath string //Passed to client (and stored in stormdb)
|
||||
DateAdded string //Passed to client (and stored in stormdb)
|
||||
ETA string `json:"ETA"` //Passed to client
|
||||
ETA string //Passed to client
|
||||
TorrentLabel string //Passed to client and stored in stormdb
|
||||
SourceType string `json:"SourceType"` //Stores whether the torrent came from a torrent file or a magnet link
|
||||
SourceType string //Stores whether the torrent came from a torrent file or a magnet link
|
||||
KnownSwarm []torrent.Peer //Passed to client for Peer Tab
|
||||
UploadRatio string //Passed to client, stores the string for uploadratio stored in stormdb
|
||||
TotalUploadedSize string //Humanized version of TotalUploadedBytes to pass to the client
|
||||
TotalUploadedBytes int64 //includes bytes that happened before reboot (from stormdb)
|
||||
TotalUploadedBytes int64 `json:"-"` //includes bytes that happened before reboot (from stormdb)
|
||||
downloadSpeedInt int64 //Internal used for calculating dl speed
|
||||
BytesCompleted int64 //Internal used for calculating the dl speed
|
||||
DataBytesWritten int64 //Internal used for calculating dl speed
|
||||
DataBytesRead int64 //Internal used for calculating dl speed
|
||||
UpdatedAt time.Time //Internal used for calculating speeds of upload and download
|
||||
TorrentHash metainfo.Hash //Used to create string for TorrentHashString... not sure why I have it... make that a TODO I guess
|
||||
NumberofFiles int
|
||||
NumberofPieces int
|
||||
MaxConnections int //Used to stop the torrent by limiting the max allowed connections
|
||||
BytesCompleted int64 `json:"-"` //Internal used for calculating the dl speed
|
||||
DataBytesWritten int64 `json:"-"` //Internal used for calculating dl speed
|
||||
DataBytesRead int64 `json:"-"` //Internal used for calculating dl speed
|
||||
UpdatedAt time.Time `json:"-"` //Internal used for calculating speeds of upload and download
|
||||
TorrentHash metainfo.Hash `json:"-"` //Used to create string for TorrentHashString... not sure why I have it... make that a TODO I guess
|
||||
NumberofFiles int //Number of files in the torrent
|
||||
NumberofPieces int //Total number of pieces in the torrent (Not currently used)
|
||||
MaxConnections int //Used to stop the torrent by limiting the max allowed connections
|
||||
}
|
||||
|
@@ -173,6 +173,7 @@ func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.To
|
||||
|
||||
}
|
||||
torrentLocalStorage.TorrentFilePriority = TorrentFilePriorityArray
|
||||
fmt.Println("TorrentUPloadLimit", torrentLocalStorage.TorrentUploadLimit)
|
||||
Storage.AddTorrentLocalStorage(torrentDbStorage, torrentLocalStorage) //writing all of the data to the database
|
||||
clientTorrent.DownloadAll() //starting the download
|
||||
CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "success", Payload: "Torrent added!"}, Conn)
|
||||
@@ -214,11 +215,10 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
||||
if err != nil {
|
||||
Logger.WithFields(logrus.Fields{"torrentFile": singleTorrent.Name(), "error": err}).Error("Unable to add infobytes to the torrent!")
|
||||
}
|
||||
//Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Generating infohash")
|
||||
calculatedTotalSize := CalculateDownloadSize(singleTorrentFromStorage, singleTorrent)
|
||||
calculatedCompleteSize := CalculateCompleteSize(singleTorrentFromStorage, singleTorrent)
|
||||
calculatedCompletedSize := CalculateCompletedSize(singleTorrentFromStorage, singleTorrent)
|
||||
TempHash = singleTorrent.InfoHash()
|
||||
if (calculatedCompleteSize == 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...")
|
||||
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
|
||||
}
|
||||
@@ -229,12 +229,12 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
||||
totalPeersString := fmt.Sprintf("%v", fullStruct.TotalPeers)
|
||||
fullClientDB.StoragePath = singleTorrentFromStorage.StoragePath
|
||||
|
||||
downloadedSizeHumanized := HumanizeBytes(float32(calculatedCompleteSize)) //convert size to GB if needed
|
||||
downloadedSizeHumanized := HumanizeBytes(float32(calculatedCompletedSize)) //convert size to GB if needed
|
||||
totalSizeHumanized := HumanizeBytes(float32(calculatedTotalSize))
|
||||
|
||||
fullClientDB.DownloadedSize = downloadedSizeHumanized
|
||||
fullClientDB.Size = totalSizeHumanized
|
||||
PercentDone := fmt.Sprintf("%.2f", float32(calculatedCompleteSize)/float32(calculatedTotalSize))
|
||||
PercentDone := fmt.Sprintf("%.2f", float32(calculatedCompletedSize)/float32(calculatedTotalSize))
|
||||
fullClientDB.TorrentHash = TempHash
|
||||
fullClientDB.PercentDone = PercentDone
|
||||
fullClientDB.DataBytesRead = fullStruct.ConnStats.BytesReadData //used for calculations not passed to client calculating up/down speed
|
||||
@@ -244,7 +244,7 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
||||
fullClientDB.TorrentName = singleTorrentFromStorage.TorrentName
|
||||
fullClientDB.DateAdded = singleTorrentFromStorage.DateAdded
|
||||
fullClientDB.TorrentLabel = singleTorrentFromStorage.Label
|
||||
fullClientDB.BytesCompleted = calculatedCompleteSize
|
||||
fullClientDB.BytesCompleted = calculatedCompletedSize
|
||||
fullClientDB.NumberofFiles = len(singleTorrent.Files())
|
||||
|
||||
if len(PreviousTorrentArray) > 0 { //if we actually have a previous array //ranging over the previous torrent array to calculate the speed for each torrent
|
||||
@@ -256,18 +256,18 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
|
||||
}
|
||||
}
|
||||
}
|
||||
CalculateTorrentETA(singleTorrentFromStorage.TorrentSize, calculatedCompleteSize, fullClientDB) //needs to be here since we need the speed calculated before we can estimate the eta.
|
||||
CalculateTorrentETA(singleTorrentFromStorage.TorrentSize, calculatedCompletedSize, fullClientDB) //needs to be here since we need the speed calculated before we can estimate the eta.
|
||||
|
||||
fullClientDB.TotalUploadedSize = HumanizeBytes(float32(fullClientDB.TotalUploadedBytes))
|
||||
fullClientDB.UploadRatio = CalculateUploadRatio(singleTorrent, fullClientDB) //calculate the upload ratio
|
||||
|
||||
CalculateTorrentStatus(singleTorrent, fullClientDB, config, singleTorrentFromStorage)
|
||||
CalculateTorrentStatus(singleTorrent, fullClientDB, config, singleTorrentFromStorage, calculatedCompletedSize, calculatedTotalSize)
|
||||
|
||||
tickUpdateStruct.UploadRatio = fullClientDB.UploadRatio
|
||||
tickUpdateStruct.UploadedBytes = fullClientDB.TotalUploadedBytes
|
||||
tickUpdateStruct.TorrentStatus = fullClientDB.Status
|
||||
tickUpdateStruct.Hash = fullClientDB.TorrentHashString //needed for index
|
||||
|
||||
fmt.Println("Status", tickUpdateStruct.TorrentStatus)
|
||||
Storage.UpdateStorageTick(db, tickUpdateStruct)
|
||||
RunningTorrentArray = append(RunningTorrentArray, *fullClientDB)
|
||||
|
||||
|
@@ -94,12 +94,11 @@ func CalculateDownloadSize(tFromStorage *Storage.TorrentLocal, activeTorrent *to
|
||||
return totalLength
|
||||
}
|
||||
|
||||
//CalculateCompleteSize will be used to calculate how much of the actual torrent we have completed minus the canceled files (even if they have been partially downloaded)
|
||||
func CalculateCompleteSize(tFromStorage *Storage.TorrentLocal, activeTorrent *torrent.Torrent) int64 {
|
||||
var downloadedLength int64
|
||||
//CalculateCompletedSize will be used to calculate how much of the actual torrent we have completed minus the canceled files (even if they have been partially downloaded)
|
||||
func CalculateCompletedSize(tFromStorage *Storage.TorrentLocal, activeTorrent *torrent.Torrent) int64 {
|
||||
var discardByteLength int64
|
||||
for _, storageFile := range tFromStorage.TorrentFilePriority {
|
||||
if storageFile.TorrentFilePriority != "Cancel" { //If the file is canceled
|
||||
if storageFile.TorrentFilePriority == "Cancel" { //If the file is canceled don't count it as downloaded
|
||||
for _, activeFile := range activeTorrent.Files() {
|
||||
if activeFile.DisplayPath() == storageFile.TorrentFilePath { //match the file from storage to active
|
||||
for _, piece := range activeFile.State() {
|
||||
@@ -111,7 +110,7 @@ func CalculateCompleteSize(tFromStorage *Storage.TorrentLocal, activeTorrent *to
|
||||
}
|
||||
}
|
||||
}
|
||||
downloadedLength = downloadedLength - discardByteLength
|
||||
downloadedLength := activeTorrent.BytesCompleted() - discardByteLength
|
||||
return downloadedLength
|
||||
}
|
||||
|
||||
@@ -141,22 +140,23 @@ func CalculateUploadRatio(t *torrent.Torrent, c *ClientDB) string {
|
||||
}
|
||||
|
||||
//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) {
|
||||
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
|
||||
func CalculateTorrentStatus(t *torrent.Torrent, c *ClientDB, config FullClientSettings, tFromStorage *storage.TorrentLocal, bytesCompleted int64, totalSize int64) {
|
||||
if (tFromStorage.TorrentStatus == "Stopped") || (float64(c.TotalUploadedBytes)/float64(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.MaxConnections = 0
|
||||
t.SetMaxEstablishedConns(0)
|
||||
} else { //Only has 2 states in storage, stopped or running, so we know it should be running, and the websocket request handled updating the database with connections and status
|
||||
bytesMissing := totalSize - bytesCompleted
|
||||
c.MaxConnections = 80
|
||||
t.SetMaxEstablishedConns(80) //TODO this should not be needed but apparently is needed
|
||||
t.DownloadAll() //ensure that we are setting the torrent to download
|
||||
if t.Seeding() && t.Stats().ActivePeers > 0 && t.BytesMissing() == 0 {
|
||||
if t.Seeding() && t.Stats().ActivePeers > 0 && bytesMissing == 0 {
|
||||
c.Status = "Seeding"
|
||||
} else if t.Stats().ActivePeers > 0 && t.BytesMissing() > 0 {
|
||||
} else if t.Stats().ActivePeers > 0 && bytesMissing > 0 {
|
||||
c.Status = "Downloading"
|
||||
} else if t.Stats().ActivePeers == 0 && t.BytesMissing() == 0 {
|
||||
} else if t.Stats().ActivePeers == 0 && bytesMissing == 0 {
|
||||
c.Status = "Completed"
|
||||
} else if t.Stats().ActivePeers == 0 && t.BytesMissing() > 0 {
|
||||
} else if t.Stats().ActivePeers == 0 && bytesMissing > 0 {
|
||||
c.Status = "Awaiting Peers"
|
||||
} else {
|
||||
c.Status = "Unknown"
|
||||
|
@@ -128,7 +128,7 @@ var torrentListRequest = {
|
||||
console.log("Logger data requested");
|
||||
break;
|
||||
|
||||
case "rssListRequest":
|
||||
case "rssList":
|
||||
console.log("RSSListRequest recieved", evt.data);
|
||||
RSSList = [];
|
||||
for (var i = 0; i < serverMessage.TotalRSSFeeds; i++) {
|
||||
@@ -191,7 +191,7 @@ var BackendSocket = function (_React$Component) {
|
||||
case 1:
|
||||
var peerListHashes = {
|
||||
MessageType: "torrentPeerListRequest",
|
||||
Payload: selectionHashes
|
||||
Payload: {"PeerListHash": selectionHashes}
|
||||
};
|
||||
console.log("Peers tab information requested", peerListHashes);
|
||||
ws.send(JSON.stringify(peerListHashes));
|
||||
@@ -199,7 +199,7 @@ var BackendSocket = function (_React$Component) {
|
||||
case 2:
|
||||
var fileListHashes = {
|
||||
MessageType: "torrentFileListRequest",
|
||||
Payload: selectionHashes
|
||||
Payload: {"FileListHash": selectionHashes[0]}
|
||||
};
|
||||
console.log("Files tab information requested", fileListHashes);
|
||||
ws.send(JSON.stringify(fileListHashes));
|
||||
@@ -256,7 +256,7 @@ var BackendSocket = function (_React$Component) {
|
||||
case 1:
|
||||
var peerListHashes = {
|
||||
MessageType: "torrentPeerListRequest",
|
||||
Payload: this.props.selectionHashes
|
||||
Payload: {"PeerListHash": this.props.selectionHashes}
|
||||
};
|
||||
ws.send(JSON.stringify(peerListHashes));
|
||||
this.props.newPeerList(peerList);
|
||||
@@ -264,7 +264,7 @@ var BackendSocket = function (_React$Component) {
|
||||
case 2:
|
||||
var fileListHashes = {
|
||||
MessageType: "torrentFileListRequest",
|
||||
Payload: this.props.selectionHashes
|
||||
Payload: {"FileListHash": this.props.selectionHashes[0]}
|
||||
};
|
||||
ws.send(JSON.stringify(fileListHashes));
|
||||
this.props.newFileList(fileList);
|
||||
|
@@ -104,7 +104,7 @@ ws.onmessage = function (evt) { //When we recieve a message from the websocket
|
||||
console.log("Logger data requested")
|
||||
break;
|
||||
|
||||
case "rssListRequest":
|
||||
case "rssList":
|
||||
console.log("RSSListRequest recieved", evt.data)
|
||||
RSSList = [];
|
||||
for (var i = 0; i < serverMessage.TotalRSSFeeds; i++){
|
||||
@@ -163,7 +163,7 @@ class BackendSocket extends React.Component {
|
||||
case 1:
|
||||
let peerListHashes = {
|
||||
MessageType: "torrentPeerListRequest",
|
||||
Payload: selectionHashes,
|
||||
Payload: {"PeerListHash": selectionHashes[0]}
|
||||
}
|
||||
console.log("Peers tab information requested", peerListHashes)
|
||||
ws.send(JSON.stringify(peerListHashes))
|
||||
@@ -171,7 +171,7 @@ class BackendSocket extends React.Component {
|
||||
case 2:
|
||||
let fileListHashes = {
|
||||
MessageType: "torrentFileListRequest",
|
||||
Payload: selectionHashes,
|
||||
Payload: {"FileListHash": selectionHashes[0]}
|
||||
}
|
||||
console.log("Files tab information requested", fileListHashes)
|
||||
ws.send(JSON.stringify(fileListHashes))
|
||||
@@ -222,7 +222,6 @@ class BackendSocket extends React.Component {
|
||||
this.props.newServerMessage(serverPushMessage)
|
||||
}
|
||||
|
||||
|
||||
ws.send(JSON.stringify(torrentListRequest))//talking to the server to get the torrent list
|
||||
if (ws.readyState === ws.CLOSED){ //if our websocket gets closed inform the user
|
||||
webSocketState = false
|
||||
@@ -236,7 +235,7 @@ class BackendSocket extends React.Component {
|
||||
case 1:
|
||||
let peerListHashes = {
|
||||
MessageType: "torrentPeerListRequest",
|
||||
Payload: this.props.selectionHashes,
|
||||
Payload: {"PeerListHash": this.props.selectionHashes[0]}
|
||||
}
|
||||
ws.send(JSON.stringify(peerListHashes))
|
||||
this.props.newPeerList(peerList)
|
||||
@@ -244,7 +243,7 @@ class BackendSocket extends React.Component {
|
||||
case 2:
|
||||
let fileListHashes = {
|
||||
MessageType: "torrentFileListRequest",
|
||||
Payload: this.props.selectionHashes,
|
||||
Payload: {"FileListHash": this.props.selectionHashes[0]}
|
||||
}
|
||||
ws.send(JSON.stringify(fileListHashes))
|
||||
this.props.newFileList(fileList)
|
||||
@@ -256,7 +255,6 @@ class BackendSocket extends React.Component {
|
||||
}
|
||||
|
||||
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
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
|
||||
@@ -287,9 +285,6 @@ const mapStateToProps = state => {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
newTorrentList: (torrentList) => dispatch({type: actionTypes.TORRENT_LIST, torrentList }),
|
||||
@@ -305,6 +300,4 @@ const mapDispatchToProps = dispatch => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(BackendSocket);
|
@@ -66,10 +66,9 @@ class FileTab extends React.Component {
|
||||
})
|
||||
let setFilePriority = {
|
||||
MessageType: "setFilePriority",
|
||||
MessageDetail: priority,
|
||||
MessageDetailTwo: selectionHash,
|
||||
Payload: filePaths,
|
||||
Payload: {"TorrentHash": selectionHashes, "FilePriority": priority, "FilePaths": filePaths}
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(setFilePriority))
|
||||
ws.send(JSON.stringify(setFilePriority))
|
||||
}
|
||||
|
@@ -63,7 +63,7 @@ const inlineStyle = {
|
||||
showRSSFiles = (key) => {
|
||||
let RSSTorrentsRequest = {
|
||||
MessageType: "rssTorrentsRequest",
|
||||
Payload: [this.props.RSSList[key].RSSURL]
|
||||
Payload: {"RSSURL": this.props.RSSList[key].RSSURL}
|
||||
}
|
||||
ws.send(JSON.stringify(RSSTorrentsRequest))
|
||||
|
||||
|
@@ -108,7 +108,7 @@ const inlineStyle = {
|
||||
handleAddRSSFeed = () => {
|
||||
let RSSURLSubmit = {
|
||||
MessageType: "addRSSFeed",
|
||||
Payload: [this.state.textValue]
|
||||
Payload: {"RSSURL": this.state.textValue}
|
||||
}
|
||||
ws.send(JSON.stringify(RSSURLSubmit));
|
||||
let RSSRequest = {
|
||||
|
@@ -65,12 +65,12 @@ class RSSTorrentList extends React.Component {
|
||||
console.log("element", element)
|
||||
sendMagnetLinks.push(element.TorrentLink)
|
||||
})
|
||||
let magnetLinkSubmit = {
|
||||
let magnetLinkMessage = {
|
||||
MessageType: "magnetLinkSubmit",
|
||||
Payload: sendMagnetLinks,
|
||||
}
|
||||
console.log(JSON.stringify(magnetLinkSubmit))
|
||||
ws.send(JSON.stringify(magnetLinkSubmit))
|
||||
Payload: {"MagnetLinks": [sendMagnetLinks], "Label": "RSS"}
|
||||
}
|
||||
console.log(JSON.stringify(magnetLinkMessage))
|
||||
ws.send(JSON.stringify(magnetLinkMessage))
|
||||
}
|
||||
|
||||
componentWillReceiveProps () {
|
||||
|
@@ -69,10 +69,7 @@ export default class addTorrentFilePopup extends React.Component {
|
||||
|
||||
let torrentFileMessage = {
|
||||
MessageType: "torrentFileSubmit",
|
||||
MessageDetail: this.state.torrentFileName, //filename
|
||||
MessageDetailTwo: this.state.storageValue, //storage path
|
||||
MessageDetailThree: this.state.torrentLabel, //torrent label
|
||||
Payload: [base64data],
|
||||
Payload: {"FileData": base64data, "FileName": this.state.torrentFileName, "StorageValue": this.state.storageValue, "Label": this.state.torrentLabel}
|
||||
}
|
||||
console.log("Sending Torrent File: ", torrentFileMessage);
|
||||
ws.send(JSON.stringify(torrentFileMessage));
|
||||
|
@@ -54,9 +54,7 @@ export default class addTorrentPopup extends React.Component {
|
||||
console.log("MagnetLink", this.state.magnetLinkValue)
|
||||
let magnetLinkMessage = {
|
||||
MessageType: "magnetLinkSubmit",
|
||||
MessageDetail: this.state.storageValue, //storage location
|
||||
MessageDetailTwo: this.state.torrentLabel, //label
|
||||
Payload: [this.state.magnetLinkValue]
|
||||
Payload: {"MagnetLinks": [this.state.magnetLinkValue], "StorageValue": this.state.storageValue, "Label": this.state.torrentLabel}
|
||||
}
|
||||
console.log("Sending magnet link: ", magnetLinkMessage);
|
||||
ws.send(JSON.stringify(magnetLinkMessage));
|
||||
|
@@ -48,12 +48,11 @@ class ChangeStorageModal extends React.Component {
|
||||
|
||||
handleSubmit = () => {
|
||||
this.setState({ open: false });
|
||||
//let magnetLinkSubmit = this.state.textValue;
|
||||
let changeStorageMessage = {
|
||||
MessageType: "changeStorageValue",
|
||||
MessageDetail: this.state.storageValue, //new storage value
|
||||
Payload: this.props.selectionHashes, //the selection hashes
|
||||
Payload: {"ChangeStorageHashes": this.props.selectionHashes, "StorageValue": this.state.storageValue} //the selection hashes and new store value
|
||||
}
|
||||
|
||||
console.log("Sending new Storage Location: ", changeStorageMessage);
|
||||
ws.send(JSON.stringify(changeStorageMessage));
|
||||
this.setState({storageValue: ``})
|
||||
|
@@ -41,8 +41,7 @@ class DeleteTorrentModal extends React.Component {
|
||||
let selection = []
|
||||
let deleteTorrentHashes = {
|
||||
MessageType: "deleteTorrents",
|
||||
MessageDetail: "false", //delete with data
|
||||
Payload: this.props.selectionHashes
|
||||
Payload: {"TorrentHashes": this.props.selectionHashes, "WithData": false}
|
||||
}
|
||||
console.log("Deleting Torrents", deleteTorrentHashes)
|
||||
ws.send(JSON.stringify(deleteTorrentHashes))
|
||||
@@ -56,8 +55,7 @@ class DeleteTorrentModal extends React.Component {
|
||||
|
||||
let deleteTorrentHashes = {
|
||||
MessageType: "deleteTorrents",
|
||||
MessageDetail: "true", //delete with data
|
||||
Payload: this.props.selectionHashes,
|
||||
Payload: {"TorrentHashes": this.props.selectionHashes, "WithData": true}
|
||||
}
|
||||
console.log("Deleting Torrents and Data", deleteTorrentHashes)
|
||||
ws.send(JSON.stringify(deleteTorrentHashes))
|
||||
|
@@ -82,7 +82,7 @@ class IconButtons extends React.Component {
|
||||
console.log("Force starting Torrents", this.props.selectionHashes)
|
||||
let forceUploadTorrents = {
|
||||
MessageType: "forceUploadTorrents",
|
||||
Payload: this.props.selectionHashes,
|
||||
Payload: {"TorrentHashes": this.props.selectionHashes}
|
||||
}
|
||||
ws.send(JSON.stringify(forceUploadTorrents))
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class IconButtons extends React.Component {
|
||||
console.log("Starting Torrents", this.props.selectionHashes)
|
||||
let startTorrentHashes = {
|
||||
MessageType: "startTorrents",
|
||||
Payload: this.props.selectionHashes,
|
||||
Payload: {"TorrentHashes": this.props.selectionHashes}
|
||||
}
|
||||
//console.log("Peers tab information requested", peerListHashes)
|
||||
ws.send(JSON.stringify(startTorrentHashes))
|
||||
@@ -101,7 +101,7 @@ class IconButtons extends React.Component {
|
||||
stopTorrent = () => {
|
||||
let stopTorrentHashes = {
|
||||
MessageType: "stopTorrents",
|
||||
Payload: this.props.selectionHashes,
|
||||
Payload: {"TorrentHashes": this.props.selectionHashes}
|
||||
}
|
||||
console.log("Stopping Torrents", stopTorrentHashes)
|
||||
ws.send(JSON.stringify(stopTorrentHashes))
|
||||
|
@@ -70,6 +70,11 @@ class BasicLayout extends React.PureComponent {
|
||||
this.props.onLayoutChange(layout);
|
||||
}
|
||||
|
||||
componentWillMount() { //if login not required log in automatically
|
||||
if (LoginRequired == false){
|
||||
this.setState({loggedin: true})
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return [
|
||||
|
@@ -69,7 +69,7 @@ export default class Login extends React.Component {
|
||||
this.setState({ open: false, username: "", password: "" });
|
||||
this.props.changeLoggedin(true)
|
||||
} else {
|
||||
this.setState({wrongPasswordMessage: "Wrong Username/Password!", username: "", password: "" })
|
||||
this.setState({wrongPasswordMessage: "Wrong Username/Password!"})
|
||||
}
|
||||
}
|
||||
|
||||
|
171
main.go
171
main.go
@@ -36,8 +36,9 @@ type SingleRSSFeedMessage struct { //TODO had issues with getting this to work w
|
||||
|
||||
var (
|
||||
//Logger does logging for the entire project
|
||||
Logger = logrus.New()
|
||||
Authenticated = false //to verify if user is authenticated, this is stored here
|
||||
Logger = logrus.New()
|
||||
//Authenticated stores the value of the result of the client that connects to the server
|
||||
Authenticated = false
|
||||
APP_ID = os.Getenv("APP_ID")
|
||||
)
|
||||
|
||||
@@ -54,14 +55,15 @@ func serveHome(w http.ResponseWriter, r *http.Request) {
|
||||
func handleAuthentication(conn *websocket.Conn, db *storm.DB) {
|
||||
msg := Engine.Message{}
|
||||
err := conn.ReadJSON(&msg)
|
||||
payloadData := msg.Payload.(map[string]interface{})
|
||||
clientAuthToken := payloadData["ClientAuthString"].(string)
|
||||
if err != nil {
|
||||
Logger.WithFields(logrus.Fields{"error": err, "SuppliedToken": msg.Payload[0]}).Error("Unable to read authentication message")
|
||||
Logger.WithFields(logrus.Fields{"error": err, "SuppliedToken": clientAuthToken}).Error("Unable to read authentication message")
|
||||
}
|
||||
authString := msg.Payload[0] //First element will be the auth request
|
||||
fmt.Println("Authstring", authString)
|
||||
fmt.Println("Authstring", clientAuthToken)
|
||||
signingKeyStruct := Storage.FetchJWTTokens(db)
|
||||
singingKey := signingKeyStruct.SigningKey
|
||||
token, err := jwt.Parse(authString, func(token *jwt.Token) (interface{}, error) {
|
||||
token, err := jwt.Parse(clientAuthToken, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
@@ -198,10 +200,11 @@ func main() {
|
||||
if Authenticated != true {
|
||||
handleAuthentication(conn, db)
|
||||
} else { //If we are authenticated inject the connection into the other packages
|
||||
fmt.Println("Authenticated... continue")
|
||||
Engine.Conn = conn
|
||||
Storage.Conn = conn
|
||||
Logger.WithFields(logrus.Fields{"Conn": conn}).Info("Authenticated, websocket connection available!")
|
||||
}
|
||||
Engine.Conn = conn
|
||||
Storage.Conn = conn
|
||||
|
||||
MessageLoop: //Tagging this so we can continue out of it with any errors we encounter that are failing
|
||||
for {
|
||||
runningTorrents := tclient.Torrents() //getting running torrents here since multiple cases ask for the running torrents
|
||||
@@ -212,6 +215,10 @@ func main() {
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Malformed JSON request made to server.. ignoring"}, conn)
|
||||
break MessageLoop
|
||||
}
|
||||
var payloadData map[string]interface{}
|
||||
if msg.Payload != nil {
|
||||
payloadData = msg.Payload.(map[string]interface{})
|
||||
}
|
||||
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Message From Client")
|
||||
switch msg.MessageType { //first handling data requests
|
||||
case "authRequest":
|
||||
@@ -236,22 +243,25 @@ func main() {
|
||||
|
||||
case "torrentFileListRequest": //client requested a filelist update
|
||||
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested FileList Update")
|
||||
FileListArray := Engine.CreateFileListArray(tclient, msg.Payload[0], db, Config)
|
||||
fileListArrayRequest := payloadData["FileListHash"].(string)
|
||||
FileListArray := Engine.CreateFileListArray(tclient, fileListArrayRequest, db, Config)
|
||||
conn.WriteJSON(FileListArray) //writing the JSON to the client
|
||||
|
||||
case "torrentDetailedInfo":
|
||||
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested TorrentListDetail Update")
|
||||
torrentDetailArray := Engine.CreateTorrentDetailJSON(tclient, msg.Payload[0], db)
|
||||
conn.WriteJSON(torrentDetailArray)
|
||||
//case "torrentDetailedInfo":
|
||||
// Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested TorrentListDetail Update")
|
||||
// fileListArrayRequest := payloadData["FileListArray"].(string)
|
||||
// torrentDetailArray := Engine.CreateTorrentDetailJSON(tclient, msg.Payload[0], db)
|
||||
// conn.WriteJSON(torrentDetailArray)
|
||||
|
||||
case "torrentPeerListRequest":
|
||||
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested PeerList Update")
|
||||
torrentPeerList := Engine.CreatePeerListArray(tclient, msg.Payload[0])
|
||||
peerListArrayRequest := payloadData["PeerListHash"].(string)
|
||||
torrentPeerList := Engine.CreatePeerListArray(tclient, peerListArrayRequest)
|
||||
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
|
||||
label := payloadData["Label"].(string)
|
||||
torrentsByLabel := Storage.FetchTorrentsByLabel(db, label)
|
||||
RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db)
|
||||
labelRunningArray := []Engine.ClientDB{}
|
||||
@@ -266,8 +276,8 @@ func main() {
|
||||
|
||||
case "changeStorageValue":
|
||||
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested Storage Location Update")
|
||||
newStorageLocation := msg.MessageDetail
|
||||
hashes := msg.Payload
|
||||
newStorageLocation := payloadData["StorageValue"].(string)
|
||||
hashes := payloadData["ChangeStorageHashes"].([]string)
|
||||
for _, singleHash := range hashes {
|
||||
singleTorrent := Storage.FetchTorrentFromStorage(db, singleHash)
|
||||
oldPath := singleTorrent.StoragePath
|
||||
@@ -296,9 +306,8 @@ func main() {
|
||||
|
||||
case "rssFeedRequest":
|
||||
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested RSS Update")
|
||||
|
||||
RSSList := Storage.FetchRSSFeeds(db)
|
||||
RSSJSONFeed := Engine.RSSJSONList{MessageType: "rssListRequest", TotalRSSFeeds: len(RSSList.RSSFeeds)}
|
||||
RSSJSONFeed := Engine.RSSJSONList{MessageType: "rssList", TotalRSSFeeds: len(RSSList.RSSFeeds)}
|
||||
RSSsingleFeed := Engine.RSSFeedsNames{}
|
||||
for _, singleFeed := range RSSList.RSSFeeds {
|
||||
RSSsingleFeed.RSSName = singleFeed.Name
|
||||
@@ -308,8 +317,8 @@ func main() {
|
||||
conn.WriteJSON(RSSJSONFeed)
|
||||
|
||||
case "addRSSFeed":
|
||||
Logger.WithFields(logrus.Fields{"message": msg.Payload[0]}).Debug("Client Added RSS Feed")
|
||||
newRSSFeed := msg.Payload[0] //there will only be one RSS feed (hopefully)
|
||||
newRSSFeed := payloadData["RSSURL"].(string)
|
||||
Logger.WithFields(logrus.Fields{"message": newRSSFeed}).Debug("Client Added RSS Feed")
|
||||
fullRSSFeeds := Storage.FetchRSSFeeds(db)
|
||||
Logger.WithFields(logrus.Fields{"RSSFeeds": fullRSSFeeds}).Debug("Pulled Full RSS Feeds")
|
||||
for _, singleFeed := range fullRSSFeeds.RSSFeeds {
|
||||
@@ -330,31 +339,31 @@ func main() {
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "success", Payload: "Added RSS Feed"}, conn)
|
||||
newRSSFeedFull := Storage.SingleRSSFeed{}
|
||||
newRSSFeedFull.Name = feed.Title
|
||||
newRSSFeedFull.URL = msg.Payload[0]
|
||||
newRSSFeedFull.URL = newRSSFeed
|
||||
fullRSSFeeds.RSSFeeds = append(fullRSSFeeds.RSSFeeds, newRSSFeedFull) // add the new RSS feed to the stack
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Adding RSS feed..."}, conn)
|
||||
Engine.ForceRSSRefresh(db, fullRSSFeeds)
|
||||
//forcing an RSS refresh to fully populate all rss feeds TODO maybe just push the update of the new RSS feed and leave cron to update? But user would most likely expect and immediate update
|
||||
|
||||
case "deleteRSSFeed":
|
||||
Logger.WithFields(logrus.Fields{"message": msg.Payload[0]}).Debug("Deleting RSS Feed")
|
||||
removingRSSFeed := msg.Payload[0]
|
||||
Storage.DeleteRSSFeed(db, removingRSSFeed)
|
||||
deleteRSSFeed := payloadData["RSSURL"].(string)
|
||||
Logger.WithFields(logrus.Fields{"message": deleteRSSFeed}).Debug("Deleting RSS Feed")
|
||||
Storage.DeleteRSSFeed(db, deleteRSSFeed)
|
||||
fullRSSFeeds := Storage.FetchRSSFeeds(db)
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Deleting RSS feed..."}, conn)
|
||||
Engine.ForceRSSRefresh(db, fullRSSFeeds)
|
||||
|
||||
case "rssTorrentsRequest":
|
||||
RSSFeedURL := msg.Payload[0]
|
||||
Logger.WithFields(logrus.Fields{"RSSFeed": msg.Payload[0]}).Info("Requesting torrentList for feed..")
|
||||
RSSFeedURL := payloadData["RSSURL"].(string)
|
||||
Logger.WithFields(logrus.Fields{"RSSFeed": RSSFeedURL}).Info("Requesting torrentList for feed..")
|
||||
UpdatedRSSFeed := Engine.RefreshSingleRSSFeed(db, Storage.FetchSpecificRSSFeed(db, RSSFeedURL))
|
||||
TorrentRSSList := SingleRSSFeedMessage{MessageType: "rssTorrentList", URL: RSSFeedURL, Name: UpdatedRSSFeed.Name, TotalTorrents: len(UpdatedRSSFeed.Torrents), Torrents: UpdatedRSSFeed.Torrents}
|
||||
Logger.WithFields(logrus.Fields{"TorrentRSSList": TorrentRSSList}).Debug("Returning Torrent list from RSSFeed to client")
|
||||
conn.WriteJSON(TorrentRSSList)
|
||||
|
||||
case "magnetLinkSubmit": //if we detect a magnet link we will be adding a magnet torrent
|
||||
storageValue := msg.MessageDetail
|
||||
labelValue := msg.MessageDetailTwo
|
||||
storageValue := payloadData["StorageValue"].(string)
|
||||
labelValue := payloadData["Label"].(string)
|
||||
if storageValue == "" {
|
||||
storageValue, err = filepath.Abs(filepath.ToSlash(Config.DefaultMoveFolder))
|
||||
if err != nil {
|
||||
@@ -368,7 +377,8 @@ func main() {
|
||||
storageValue, _ = filepath.Abs(filepath.ToSlash(Config.DefaultMoveFolder))
|
||||
}
|
||||
}
|
||||
for _, magnetLink := range msg.Payload {
|
||||
magnetLinks := payloadData["MagnetLinks"].([]string)
|
||||
for _, magnetLink := range magnetLinks {
|
||||
clientTorrent, err := tclient.AddMagnet(magnetLink) //reading the payload into the torrent client
|
||||
if err != nil {
|
||||
Logger.WithFields(logrus.Fields{"err": err, "MagnetLink": magnetLink}).Error("Unable to add magnetlink to client!")
|
||||
@@ -382,16 +392,17 @@ func main() {
|
||||
}
|
||||
|
||||
case "torrentFileSubmit":
|
||||
//base64file := strings.TrimPrefix(msg.Payload[0], "data:;base64,") //trimming off the unneeded bits from the front of the json //TODO maybe do this in client?
|
||||
base64file := strings.Split(msg.Payload[0], ",") //Mozilla and Chrome have different payloads, but both start the file after the comma
|
||||
base64encoded := payloadData["FileData"].(string)
|
||||
fileName := payloadData["FileName"].(string)
|
||||
storageValue := payloadData["StorageValue"].(string)
|
||||
labelValue := payloadData["Label"].(string)
|
||||
base64file := strings.Split(base64encoded, ",") //Mozilla and Chrome have different payloads, but both start the file after the comma
|
||||
file, err := base64.StdEncoding.DecodeString(base64file[1]) //grabbing the second half of the string after the split
|
||||
if err != nil {
|
||||
Logger.WithFields(logrus.Fields{"Error": err, "file": file}).Info("Unable to decode base64 string to file")
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "error", Payload: "Unable to decode base64 string to file"}, conn)
|
||||
}
|
||||
FileName := msg.MessageDetail
|
||||
storageValue := msg.MessageDetailTwo
|
||||
labelValue := msg.MessageDetailThree
|
||||
|
||||
if storageValue == "" {
|
||||
storageValue, err = filepath.Abs(filepath.ToSlash(Config.DefaultMoveFolder))
|
||||
if err != nil {
|
||||
@@ -406,12 +417,12 @@ func main() {
|
||||
storageValue, _ = filepath.Abs(filepath.ToSlash(Config.DefaultMoveFolder))
|
||||
}
|
||||
}
|
||||
filePath := filepath.Join(Config.TFileUploadFolder, FileName)
|
||||
filePath := filepath.Join(Config.TFileUploadFolder, fileName)
|
||||
filePathAbs, err := filepath.Abs(filePath) //creating a full filepath to store the .torrent files
|
||||
|
||||
err = ioutil.WriteFile(filePathAbs, file, 0755) //Dumping our received file into the filename
|
||||
if err != nil {
|
||||
Logger.WithFields(logrus.Fields{"filepath": filePathAbs, "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)
|
||||
}
|
||||
|
||||
@@ -424,11 +435,11 @@ func main() {
|
||||
Engine.StartTorrent(clientTorrent, torrentLocalStorage, db, "file", filePathAbs, storageValue, labelValue, Config)
|
||||
|
||||
case "stopTorrents":
|
||||
TorrentListCommands := msg.Payload
|
||||
torrentHashes := payloadData["TorrentHashes"].([]interface{})
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Stop Request"}, conn)
|
||||
for _, singleTorrent := range runningTorrents {
|
||||
|
||||
for _, singleSelection := range TorrentListCommands {
|
||||
for _, singleSelection := range torrentHashes {
|
||||
if singleTorrent.InfoHash().String() == singleSelection {
|
||||
Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Matched for stopping torrents")
|
||||
oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String())
|
||||
@@ -442,15 +453,16 @@ func main() {
|
||||
}
|
||||
|
||||
case "deleteTorrents":
|
||||
withData := msg.MessageDetail //Checking if torrents should be deleted with data
|
||||
torrentHashes := payloadData["TorrentHashes"].([]interface{})
|
||||
withData := payloadData["WithData"].(bool) //Checking if torrents should be deleted with data
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Delete Request"}, conn)
|
||||
Logger.WithFields(logrus.Fields{"deleteTorrentsPayload": msg.Payload, "torrentlist": msg.Payload, "deleteWithData?": withData}).Info("message for deleting torrents")
|
||||
for _, singleTorrent := range runningTorrents {
|
||||
for _, singleSelection := range msg.Payload {
|
||||
for _, singleSelection := range torrentHashes {
|
||||
if singleTorrent.InfoHash().String() == singleSelection {
|
||||
singleTorrent.Drop()
|
||||
Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Matched for deleting torrents")
|
||||
if withData == "true" {
|
||||
if withData {
|
||||
Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Deleting torrent and data")
|
||||
Storage.DelTorrentLocalStorageAndFiles(db, singleTorrent.InfoHash().String(), Config.TorrentConfig.DataDir)
|
||||
} else {
|
||||
@@ -462,10 +474,11 @@ func main() {
|
||||
}
|
||||
|
||||
case "startTorrents":
|
||||
torrentHashes := payloadData["TorrentHashes"].([]interface{})
|
||||
Logger.WithFields(logrus.Fields{"selection": msg.Payload}).Info("Matched for starting torrents")
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Start Request"}, conn)
|
||||
for _, singleTorrent := range runningTorrents {
|
||||
for _, singleSelection := range msg.Payload {
|
||||
for _, singleSelection := range torrentHashes {
|
||||
if singleTorrent.InfoHash().String() == singleSelection {
|
||||
Logger.WithFields(logrus.Fields{"infoHash": singleTorrent.InfoHash().String()}).Debug("Found matching torrent to start")
|
||||
oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String())
|
||||
@@ -480,74 +493,62 @@ func main() {
|
||||
}
|
||||
|
||||
case "forceUploadTorrents":
|
||||
torrentHashes := payloadData["TorrentHashes"].([]interface{})
|
||||
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 {
|
||||
for _, singleSelection := range torrentHashes {
|
||||
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
|
||||
fmt.Println("OldtorrentinfoName", oldTorrentInfo.TorrentName)
|
||||
oldMax := singleTorrent.SetMaxEstablishedConns(80)
|
||||
singleTorrent.DownloadAll()
|
||||
Logger.WithFields(logrus.Fields{"Previous Max Connections": oldMax, "Torrent": oldTorrentInfo.TorrentName}).Info("Setting max connection from zero to")
|
||||
Logger.WithFields(logrus.Fields{"Previous Max Connections": oldMax, "NewMax": oldTorrentInfo.MaxConnections, "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%?
|
||||
Logger.WithFields(logrus.Fields{"selection": msg.Payload}).Info("Matched for setting file priority")
|
||||
priorityRequested := payloadData["FilePriority"].(string)
|
||||
torrentHash := payloadData["TorrentHash"].(string)
|
||||
fileList := payloadData["FilePaths"].([]string)
|
||||
Logger.WithFields(logrus.Fields{"selection": torrentHash}).Info("Matched for setting file priority")
|
||||
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Set Priority Request"}, conn)
|
||||
priorityRequested := msg.MessageDetail //storing the priority requested
|
||||
infoHash := msg.MessageDetailTwo //storing our infohash
|
||||
fileList := msg.Payload //filelist contains the ABSOLUTE paths to all of the files
|
||||
Logger.WithFields(logrus.Fields{"filelist": fileList}).Debug("Full filelist for setting file priority")
|
||||
for _, singleTorrent := range runningTorrents {
|
||||
if singleTorrent.InfoHash().String() == infoHash {
|
||||
activeTorrentStruct := Storage.FetchTorrentFromStorage(db, infoHash) //fetching all the data from the db to update certain fields then write it all back
|
||||
if singleTorrent.InfoHash().String() == torrentHash {
|
||||
activeTorrentStruct := Storage.FetchTorrentFromStorage(db, torrentHash) //fetching all the data from the db to update certain fields then write it all back
|
||||
Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrent}).Debug("Matched for changing file prio torrents")
|
||||
for _, file := range singleTorrent.Files() {
|
||||
for _, sentFile := range fileList {
|
||||
absFilePath, err := filepath.Abs(file.Path())
|
||||
if err != nil {
|
||||
Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrent}).Error("Cannot create absolute file path for file")
|
||||
}
|
||||
if absFilePath == sentFile {
|
||||
if priorityRequested == "High" {
|
||||
var priorityString string
|
||||
if file.Path() == sentFile {
|
||||
switch priorityRequested {
|
||||
case "High":
|
||||
priorityString = "High"
|
||||
file.SetPriority(torrent.PiecePriorityHigh)
|
||||
Logger.WithFields(logrus.Fields{"singleTorrent": file.DisplayPath()}).Debug("Setting priority for HIGH")
|
||||
for i, specificFile := range activeTorrentStruct.TorrentFilePriority { //searching for that specific file
|
||||
if specificFile.TorrentFilePath == file.DisplayPath() {
|
||||
activeTorrentStruct.TorrentFilePriority[i].TorrentFilePriority = "High" //writing just that field to the current struct
|
||||
}
|
||||
}
|
||||
Storage.UpdateStorageTick(db, activeTorrentStruct) //re-writting essentially that entire struct right back into the database
|
||||
}
|
||||
if priorityRequested == "Normal" {
|
||||
case "Normal":
|
||||
priorityString = "Normal"
|
||||
file.SetPriority(torrent.PiecePriorityNormal)
|
||||
Logger.WithFields(logrus.Fields{"singleTorrent": file.DisplayPath()}).Debug("Setting priority for Normal")
|
||||
for i, specificFile := range activeTorrentStruct.TorrentFilePriority { //searching for that specific file
|
||||
if specificFile.TorrentFilePath == file.DisplayPath() {
|
||||
activeTorrentStruct.TorrentFilePriority[i].TorrentFilePriority = "Normal" //writing just that field to the current struct
|
||||
}
|
||||
}
|
||||
Storage.UpdateStorageTick(db, activeTorrentStruct) //re-writting essentially that entire struct right back into the database
|
||||
}
|
||||
if priorityRequested == "Cancel" {
|
||||
case "Cancel":
|
||||
priorityString = "Cancel"
|
||||
file.SetPriority(torrent.PiecePriorityNone)
|
||||
Logger.WithFields(logrus.Fields{"singleTorrent": file.DisplayPath()}).Debug("Canceling file")
|
||||
for i, specificFile := range activeTorrentStruct.TorrentFilePriority { //searching for that specific file
|
||||
if specificFile.TorrentFilePath == file.DisplayPath() {
|
||||
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
|
||||
default:
|
||||
priorityString = "Normal"
|
||||
file.SetPriority(torrent.PiecePriorityNormal)
|
||||
}
|
||||
|
||||
for i, specificFile := range activeTorrentStruct.TorrentFilePriority { //searching for that specific file
|
||||
if specificFile.TorrentFilePath == file.DisplayPath() {
|
||||
activeTorrentStruct.TorrentFilePriority[i].TorrentFilePriority = priorityString //writing just that field to the current struct
|
||||
}
|
||||
}
|
||||
Logger.WithFields(logrus.Fields{"singleTorrent": file.DisplayPath()}).Debug("Setting priority for ", priorityString)
|
||||
Storage.UpdateStorageTick(db, activeTorrentStruct) //re-writting essentially that entire struct right back into the database
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -60330,6 +60330,14 @@ var BasicLayout = function (_React$PureComponent) {
|
||||
value: function onLayoutChange(layout) {
|
||||
this.props.onLayoutChange(layout);
|
||||
}
|
||||
}, {
|
||||
key: 'componentWillMount',
|
||||
value: function componentWillMount() {
|
||||
//if login not required log in automatically
|
||||
if (LoginRequired == false) {
|
||||
this.setState({ loggedin: true });
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
@@ -84243,7 +84251,7 @@ var IconButtons = function (_React$Component) {
|
||||
console.log("Force starting Torrents", _this.props.selectionHashes);
|
||||
var forceUploadTorrents = {
|
||||
MessageType: "forceUploadTorrents",
|
||||
Payload: _this.props.selectionHashes
|
||||
Payload: { "TorrentHashes": _this.props.selectionHashes }
|
||||
};
|
||||
ws.send(JSON.stringify(forceUploadTorrents));
|
||||
};
|
||||
@@ -84252,7 +84260,7 @@ var IconButtons = function (_React$Component) {
|
||||
console.log("Starting Torrents", _this.props.selectionHashes);
|
||||
var startTorrentHashes = {
|
||||
MessageType: "startTorrents",
|
||||
Payload: _this.props.selectionHashes
|
||||
Payload: { "TorrentHashes": _this.props.selectionHashes }
|
||||
//console.log("Peers tab information requested", peerListHashes)
|
||||
};ws.send(JSON.stringify(startTorrentHashes));
|
||||
_this.props.setButtonState(_this.props.selection); //TODO this currently just forces a button refresh, should be a better way to do this
|
||||
@@ -84261,7 +84269,7 @@ var IconButtons = function (_React$Component) {
|
||||
_this.stopTorrent = function () {
|
||||
var stopTorrentHashes = {
|
||||
MessageType: "stopTorrents",
|
||||
Payload: _this.props.selectionHashes
|
||||
Payload: { "TorrentHashes": _this.props.selectionHashes }
|
||||
};
|
||||
console.log("Stopping Torrents", stopTorrentHashes);
|
||||
ws.send(JSON.stringify(stopTorrentHashes));
|
||||
@@ -91979,9 +91987,7 @@ var addTorrentPopup = function (_React$Component) {
|
||||
console.log("MagnetLink", _this.state.magnetLinkValue);
|
||||
var magnetLinkMessage = {
|
||||
MessageType: "magnetLinkSubmit",
|
||||
MessageDetail: _this.state.storageValue, //storage location
|
||||
MessageDetailTwo: _this.state.torrentLabel, //label
|
||||
Payload: [_this.state.magnetLinkValue]
|
||||
Payload: { "MagnetLinks": [_this.state.magnetLinkValue], "StorageValue": _this.state.storageValue, "Label": _this.state.torrentLabel }
|
||||
};
|
||||
console.log("Sending magnet link: ", magnetLinkMessage);
|
||||
ws.send(JSON.stringify(magnetLinkMessage));
|
||||
@@ -100257,10 +100263,7 @@ var addTorrentFilePopup = function (_React$Component) {
|
||||
|
||||
var torrentFileMessage = {
|
||||
MessageType: "torrentFileSubmit",
|
||||
MessageDetail: _this.state.torrentFileName, //filename
|
||||
MessageDetailTwo: _this.state.storageValue, //storage path
|
||||
MessageDetailThree: _this.state.torrentLabel, //torrent label
|
||||
Payload: [base64data]
|
||||
Payload: { "FileData": base64data, "FileName": _this.state.torrentFileName, "StorageValue": _this.state.storageValue, "Label": _this.state.torrentLabel }
|
||||
};
|
||||
console.log("Sending Torrent File: ", torrentFileMessage);
|
||||
ws.send(JSON.stringify(torrentFileMessage));
|
||||
@@ -102006,11 +102009,6 @@ var AddRSSModal = function (_React$Component) {
|
||||
}
|
||||
|
||||
_createClass(AddRSSModal, [{
|
||||
key: 'componentDidMount',
|
||||
value: function componentDidMount() {//Immediatly request an update of the feed when loading app
|
||||
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var _props = this.props,
|
||||
@@ -102212,7 +102210,7 @@ var RSSModalLayout = function (_React$Component) {
|
||||
_this.handleAddRSSFeed = function () {
|
||||
var RSSURLSubmit = {
|
||||
MessageType: "addRSSFeed",
|
||||
Payload: [_this.state.textValue]
|
||||
Payload: { "RSSURL": _this.state.textValue }
|
||||
};
|
||||
ws.send(JSON.stringify(RSSURLSubmit));
|
||||
var RSSRequest = {
|
||||
@@ -102467,7 +102465,7 @@ var RSSFeedList = function (_React$Component) {
|
||||
}, _this.showRSSFiles = function (key) {
|
||||
var RSSTorrentsRequest = {
|
||||
MessageType: "rssTorrentsRequest",
|
||||
Payload: [_this.props.RSSList[key].RSSURL]
|
||||
Payload: { "RSSURL": _this.props.RSSList[key].RSSURL }
|
||||
};
|
||||
ws.send(JSON.stringify(RSSTorrentsRequest));
|
||||
|
||||
@@ -102631,12 +102629,12 @@ var RSSTorrentList = function (_React$Component) {
|
||||
console.log("element", element);
|
||||
sendMagnetLinks.push(element.TorrentLink);
|
||||
});
|
||||
var magnetLinkSubmit = {
|
||||
var magnetLinkMessage = {
|
||||
MessageType: "magnetLinkSubmit",
|
||||
Payload: sendMagnetLinks
|
||||
Payload: { "MagnetLinks": [sendMagnetLinks], "Label": "RSS" }
|
||||
};
|
||||
console.log(JSON.stringify(magnetLinkSubmit));
|
||||
ws.send(JSON.stringify(magnetLinkSubmit));
|
||||
console.log(JSON.stringify(magnetLinkMessage));
|
||||
ws.send(JSON.stringify(magnetLinkMessage));
|
||||
};
|
||||
|
||||
_this.state = { //rows are stored in redux they are sent over from the server
|
||||
@@ -121802,8 +121800,7 @@ var DeleteTorrentModal = function (_React$Component) {
|
||||
var selection = [];
|
||||
var deleteTorrentHashes = {
|
||||
MessageType: "deleteTorrents",
|
||||
MessageDetail: "false", //delete with data
|
||||
Payload: _this.props.selectionHashes
|
||||
Payload: { "TorrentHashes": _this.props.selectionHashes, "WithData": false }
|
||||
};
|
||||
console.log("Deleting Torrents", deleteTorrentHashes);
|
||||
ws.send(JSON.stringify(deleteTorrentHashes));
|
||||
@@ -121815,8 +121812,7 @@ var DeleteTorrentModal = function (_React$Component) {
|
||||
|
||||
var deleteTorrentHashes = {
|
||||
MessageType: "deleteTorrents",
|
||||
MessageDetail: "true", //delete with data
|
||||
Payload: _this.props.selectionHashes
|
||||
Payload: { "TorrentHashes": _this.props.selectionHashes, "WithData": true }
|
||||
};
|
||||
console.log("Deleting Torrents and Data", deleteTorrentHashes);
|
||||
ws.send(JSON.stringify(deleteTorrentHashes));
|
||||
@@ -122023,12 +122019,11 @@ var ChangeStorageModal = function (_React$Component) {
|
||||
_this.setState({ open: false });
|
||||
}, _this.handleSubmit = function () {
|
||||
_this.setState({ open: false });
|
||||
//let magnetLinkSubmit = this.state.textValue;
|
||||
var changeStorageMessage = {
|
||||
MessageType: "changeStorageValue",
|
||||
MessageDetail: _this.state.storageValue, //new storage value
|
||||
Payload: _this.props.selectionHashes //the selection hashes
|
||||
};
|
||||
Payload: { "ChangeStorageHashes": _this.props.selectionHashes, "StorageValue": _this.state.storageValue //the selection hashes and new store value
|
||||
} };
|
||||
|
||||
console.log("Sending new Storage Location: ", changeStorageMessage);
|
||||
ws.send(JSON.stringify(changeStorageMessage));
|
||||
_this.setState({ storageValue: '' });
|
||||
@@ -122633,7 +122628,7 @@ var torrentListRequest = {
|
||||
console.log("Logger data requested");
|
||||
break;
|
||||
|
||||
case "rssListRequest":
|
||||
case "rssList":
|
||||
console.log("RSSListRequest recieved", evt.data);
|
||||
RSSList = [];
|
||||
for (var i = 0; i < serverMessage.TotalRSSFeeds; i++) {
|
||||
@@ -122701,7 +122696,7 @@ var BackendSocket = function (_React$Component) {
|
||||
case 1:
|
||||
var peerListHashes = {
|
||||
MessageType: "torrentPeerListRequest",
|
||||
Payload: selectionHashes
|
||||
Payload: { "PeerListHash": selectionHashes[0] }
|
||||
};
|
||||
console.log("Peers tab information requested", peerListHashes);
|
||||
ws.send(JSON.stringify(peerListHashes));
|
||||
@@ -122709,7 +122704,7 @@ var BackendSocket = function (_React$Component) {
|
||||
case 2:
|
||||
var fileListHashes = {
|
||||
MessageType: "torrentFileListRequest",
|
||||
Payload: selectionHashes
|
||||
Payload: { "FileListHash": selectionHashes[0] }
|
||||
};
|
||||
console.log("Files tab information requested", fileListHashes);
|
||||
ws.send(JSON.stringify(fileListHashes));
|
||||
@@ -122780,7 +122775,7 @@ var BackendSocket = function (_React$Component) {
|
||||
case 1:
|
||||
var peerListHashes = {
|
||||
MessageType: "torrentPeerListRequest",
|
||||
Payload: this.props.selectionHashes
|
||||
Payload: { "PeerListHash": this.props.selectionHashes[0] }
|
||||
};
|
||||
ws.send(JSON.stringify(peerListHashes));
|
||||
this.props.newPeerList(peerList);
|
||||
@@ -122788,7 +122783,7 @@ var BackendSocket = function (_React$Component) {
|
||||
case 2:
|
||||
var fileListHashes = {
|
||||
MessageType: "torrentFileListRequest",
|
||||
Payload: this.props.selectionHashes
|
||||
Payload: { "FileListHash": this.props.selectionHashes[0] }
|
||||
};
|
||||
ws.send(JSON.stringify(fileListHashes));
|
||||
this.props.newFileList(fileList);
|
||||
@@ -135094,10 +135089,9 @@ var FileTab = function (_React$Component) {
|
||||
});
|
||||
var setFilePriority = {
|
||||
MessageType: "setFilePriority",
|
||||
MessageDetail: priority,
|
||||
MessageDetailTwo: selectionHash,
|
||||
Payload: filePaths
|
||||
Payload: { "TorrentHash": selectionHashes, "FilePriority": priority, "FilePaths": filePaths }
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(setFilePriority));
|
||||
ws.send(JSON.stringify(setFilePriority));
|
||||
};
|
||||
@@ -140525,15 +140519,12 @@ var Login = function (_React$Component) {
|
||||
_this.handleSubmit();
|
||||
}
|
||||
}, _this.handleSubmit = function () {
|
||||
console.log("Attempting authentication");
|
||||
var hashedPass = sha256(_this.state.password);
|
||||
console.log("Hashed Password", hashedPass, "Password", _this.state.password);
|
||||
var hashedPass = sha256(_this.state.password); //hash the password to match it with the hashed one in the kickwebsocket
|
||||
if (_this.state.username == ClientUsername && hashedPass == ClientPassword) {
|
||||
_this.setState({ open: false, username: "", password: "" });
|
||||
_this.props.changeLoggedin(true);
|
||||
} else {
|
||||
console.log("Wrong Username/Password", ClientUsername, ClientPassword, _this.state.username, _this.state.password);
|
||||
_this.setState({ wrongPasswordMessage: "Wrong Username/Password!", username: "", password: "" });
|
||||
_this.setState({ wrongPasswordMessage: "Wrong Username/Password!" });
|
||||
}
|
||||
}, _this.handleRequestClose = function () {
|
||||
ws.close();
|
||||
|
@@ -3,6 +3,9 @@
|
||||
IP = "192.168.1.100"
|
||||
Port = "8000"
|
||||
ClientAuthString = "" //String generated on first start and stored in the root as "clientAuth.txt"
|
||||
const LoginRequired = true
|
||||
const ClientUsername = "admin"
|
||||
const ClientPassword = "" //create a sha256 hash of your password and enter it here
|
||||
|
||||
//var ws = new WebSocket(`ws://${IP}:${Port}/websocket`); //for websockets not over an SSL reverse proxy
|
||||
|
||||
|
@@ -50,7 +50,7 @@ type SingleRSSFeed struct {
|
||||
type SingleRSSTorrent struct {
|
||||
Link string `storm:"id,unique"`
|
||||
Title string
|
||||
PubDate string //TODO, change this to a date of some kind
|
||||
PubDate string
|
||||
}
|
||||
|
||||
//TorrentFilePriority stores the priority for each file in a torrent
|
||||
@@ -266,7 +266,7 @@ func DeleteRSSFeed(db *storm.DB, RSSFeedURL string) {
|
||||
newRSSFeedStore := RSSFeedStore{ID: RSSFeedStoreOld.ID} //creating new store
|
||||
for _, RSSFeed := range RSSFeedStoreOld.RSSFeeds { //recreating entire store and excluding that one RSS feed we don't want
|
||||
if RSSFeed.URL != RSSFeedURL {
|
||||
Logger.WithFields(logrus.Fields{"RSSFeedURL": RSSFeedURL}).Debug("Adding new RSS feed to list..")
|
||||
Logger.WithFields(logrus.Fields{"RSSFeedURL": RSSFeedURL}).Debug("Deleting RSS Feed...")
|
||||
newRSSFeedStore.RSSFeeds = append(newRSSFeedStore.RSSFeeds, RSSFeed)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user