File prio code added, API rewrite completed, some core features rewritten for clarity

This commit is contained in:
2018-02-15 22:49:11 -05:00
parent b843cfc11b
commit c5b86597cb
22 changed files with 215 additions and 234 deletions

View File

@@ -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]

View File

@@ -9,7 +9,7 @@ var (
baseFile = `
var authMessage = {
MessageType: "authRequest",
Payload: [ClientAuthString]
Payload: {"ClientAuthString": ClientAuthString}
}
var kickStart = {

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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"

View File

@@ -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);

View File

@@ -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);

View File

@@ -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))
}

View File

@@ -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))

View File

@@ -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 = {

View File

@@ -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 () {

View File

@@ -66,13 +66,10 @@ export default class addTorrentFilePopup extends React.Component {
reader.onloadend = () => {
let base64data = reader.result;
console.log("Base64", base64data)
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));

View File

@@ -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));

View File

@@ -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: ``})

View File

@@ -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))

View File

@@ -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))

View File

@@ -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 [

View File

@@ -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
View File

@@ -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
}
}
}

View File

@@ -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();

View File

@@ -2,7 +2,10 @@
IP = "192.168.1.100"
Port = "8000"
ClientAuthString = "" //String generated on first start and stored in the root as "clientAuth.txt"
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

View File

@@ -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)
}
}