rewriting how file prio works, adding token generation to backend, minor fixes

This commit is contained in:
2018-03-19 21:22:57 -04:00
parent a56a507ca2
commit fa46ba6025
10 changed files with 194 additions and 84 deletions

View File

@@ -21,6 +21,9 @@ import (
//Logger is the injected variable for global logger //Logger is the injected variable for global logger
var Logger *logrus.Logger var Logger *logrus.Logger
//Config is the injected variable for the torrent config
var Config Settings.FullClientSettings
//Conn is the injected variable for the websocket connection //Conn is the injected variable for the websocket connection
var Conn *websocket.Conn var Conn *websocket.Conn
@@ -85,7 +88,6 @@ func timeOutInfo(clientTorrent *torrent.Torrent, seconds time.Duration) (deleted
select { select {
case <-clientTorrent.GotInfo(): //attempting to retrieve info for torrent case <-clientTorrent.GotInfo(): //attempting to retrieve info for torrent
Logger.WithFields(logrus.Fields{"clientTorrentName": clientTorrent.Name()}).Debug("Received torrent info for torrent") Logger.WithFields(logrus.Fields{"clientTorrentName": clientTorrent.Name()}).Debug("Received torrent info for torrent")
clientTorrent.DownloadAll()
return false return false
case <-timeout: // getting info for torrent has timed out so purging the torrent case <-timeout: // getting info for torrent has timed out so purging the torrent
Logger.WithFields(logrus.Fields{"clientTorrentName": clientTorrent.Name()}).Error("Forced to drop torrent from timeout waiting for info") Logger.WithFields(logrus.Fields{"clientTorrentName": clientTorrent.Name()}).Error("Forced to drop torrent from timeout waiting for info")
@@ -173,34 +175,37 @@ func StartTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage Storage.To
TorrentFilePriorityArray = append(TorrentFilePriorityArray, torrentFilePriority) TorrentFilePriorityArray = append(TorrentFilePriorityArray, torrentFilePriority)
} }
torrentLocalStorage.TorrentFilePriority = TorrentFilePriorityArray torrentLocalStorage.TorrentFilePriority = TorrentFilePriorityArray
Storage.AddTorrentLocalStorage(torrentDbStorage, torrentLocalStorage) //writing all of the data to the database Storage.AddTorrentLocalStorage(torrentDbStorage, torrentLocalStorage) //writing all of the data to the database
clientTorrent.DownloadAll() //starting the download clientTorrent.DownloadAll() //set all pieces to download
NumPieces := clientTorrent.NumPieces() //find the number of pieces
clientTorrent.CancelPieces(1, NumPieces) //cancel all of the pieces to use file priority
for _, singleFile := range clientTorrent.Files() { //setting all of the file priorities to normal
singleFile.SetPriority(torrent.PiecePriorityNormal)
}
fmt.Println("Downloading ALL") //starting the download
CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "success", Payload: "Torrent added!"}, Conn) CreateServerPushMessage(ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "success", Payload: "Torrent added!"}, Conn)
} }
//CreateRunningTorrentArray creates the entire torrent list to pass to client //CreateInitialTorrentArray adds all the torrents on program start from the database
func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Storage.TorrentLocal, PreviousTorrentArray []ClientDB, config Settings.FullClientSettings, db *storm.DB) (RunningTorrentArray []ClientDB) { func CreateInitialTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Storage.TorrentLocal, db *storm.DB) {
for _, singleTorrentFromStorage := range TorrentLocalArray { for _, singleTorrentFromStorage := range TorrentLocalArray {
var singleTorrent *torrent.Torrent var singleTorrent *torrent.Torrent
var TempHash metainfo.Hash var err error
tickUpdateStruct := Storage.TorrentLocal{} //we are shoving the tick updates into a torrentlocal struct to pass to storage happens at the end of the routine
fullClientDB := new(ClientDB)
//singleTorrentStorageInfo := Storage.FetchTorrentFromStorage(db, TempHash.String()) //pulling the single torrent info from storage ()
if singleTorrentFromStorage.TorrentType == "file" { //if it is a file pull it from the uploaded torrent folder if singleTorrentFromStorage.TorrentType == "file" { //if it is a file pull it from the uploaded torrent folder
var err error
singleTorrent, err = readTorrentFileFromDB(singleTorrentFromStorage, tclient, db) singleTorrent, err = readTorrentFileFromDB(singleTorrentFromStorage, tclient, db)
if err != nil { if err != nil {
continue continue
} }
fullClientDB.SourceType = "Torrent File"
} else { } else {
singleTorrentFromStorageMagnet := "magnet:?xt=urn:btih:" + singleTorrentFromStorage.Hash //For magnet links just need to prepend the magnet part to the hash to readd singleTorrentFromStorageMagnet := "magnet:?xt=urn:btih:" + singleTorrentFromStorage.Hash //For magnet links just need to prepend the magnet part to the hash to readd
singleTorrent, _ = tclient.AddMagnet(singleTorrentFromStorageMagnet) singleTorrent, err = tclient.AddMagnet(singleTorrentFromStorageMagnet)
fullClientDB.SourceType = "Magnet Link" if err != nil {
continue
}
} }
if len(singleTorrentFromStorage.InfoBytes) == 0 { //TODO.. kind of a fringe scenario.. not sure if needed since the db should always have the infobytes if len(singleTorrentFromStorage.InfoBytes) == 0 { //TODO.. kind of a fringe scenario.. not sure if needed since the db should always have the infobytes
timeOut := timeOutInfo(singleTorrent, 45) timeOut := timeOutInfo(singleTorrent, 45)
@@ -211,16 +216,66 @@ func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Sto
singleTorrentFromStorage.InfoBytes = singleTorrent.Metainfo().InfoBytes singleTorrentFromStorage.InfoBytes = singleTorrent.Metainfo().InfoBytes
} }
err := singleTorrent.SetInfoBytes(singleTorrentFromStorage.InfoBytes) //setting the infobytes back into the torrent err = singleTorrent.SetInfoBytes(singleTorrentFromStorage.InfoBytes) //setting the infobytes back into the torrent
if err != nil { if err != nil {
Logger.WithFields(logrus.Fields{"torrentFile": singleTorrent.Name(), "error": err}).Error("Unable to add infobytes to the torrent!") Logger.WithFields(logrus.Fields{"torrentFile": singleTorrent.Name(), "error": err}).Error("Unable to add infobytes to the torrent!")
} }
if singleTorrentFromStorage.TorrentStatus != "Completed" && singleTorrentFromStorage.TorrentStatus != "Stopped" {
fmt.Println("Starting torrent as download", singleTorrent.Name())
singleTorrent.DownloadAll() //set all of the pieces to download (piece prio is NE to file prio)
NumPieces := singleTorrent.NumPieces() //find the number of pieces
singleTorrent.CancelPieces(1, NumPieces) //cancel all of the pieces to use file priority
for _, singleFile := range singleTorrent.Files() { //setting all of the file priorities to normal
singleFile.SetPriority(torrent.PiecePriorityNormal)
}
} else {
fmt.Println("Torrent status is....", singleTorrentFromStorage.TorrentStatus)
}
}
SetFilePriority(tclient, db) //Setting the desired file priority from storage
}
//CreateRunningTorrentArray creates the entire torrent list to pass to client
func CreateRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*Storage.TorrentLocal, PreviousTorrentArray []ClientDB, config Settings.FullClientSettings, db *storm.DB) (RunningTorrentArray []ClientDB) {
for _, singleTorrentFromStorage := range TorrentLocalArray {
var singleTorrent *torrent.Torrent
var TempHash metainfo.Hash
for _, liveTorrent := range tclient.Torrents() { //matching the torrent from storage to the live torrent
if singleTorrentFromStorage.Hash == liveTorrent.InfoHash().String() {
singleTorrent = liveTorrent
}
}
tickUpdateStruct := Storage.TorrentLocal{} //we are shoving the tick updates into a torrentlocal struct to pass to storage happens at the end of the routine
fullClientDB := new(ClientDB)
//singleTorrentStorageInfo := Storage.FetchTorrentFromStorage(db, TempHash.String()) //pulling the single torrent info from storage ()
if singleTorrentFromStorage.TorrentStatus == "Dropped" {
Logger.WithFields(logrus.Fields{"selection": singleTorrentFromStorage.TorrentName}).Info("Deleting just the torrent")
singleTorrent.Drop()
Storage.DelTorrentLocalStorage(db, singleTorrentFromStorage.Hash)
}
if singleTorrentFromStorage.TorrentStatus == "DroppedData" {
Logger.WithFields(logrus.Fields{"selection": singleTorrentFromStorage.TorrentName}).Info("Deleting just the torrent")
singleTorrent.Drop()
Storage.DelTorrentLocalStorageAndFiles(db, singleTorrentFromStorage.Hash, Config.TorrentConfig.DataDir)
}
if singleTorrentFromStorage.TorrentType == "file" { //if it is a file pull it from the uploaded torrent folder
fullClientDB.SourceType = "Torrent File"
} else {
fullClientDB.SourceType = "Magnet Link"
}
calculatedTotalSize := CalculateDownloadSize(singleTorrentFromStorage, singleTorrent) calculatedTotalSize := CalculateDownloadSize(singleTorrentFromStorage, singleTorrent)
calculatedCompletedSize := CalculateCompletedSize(singleTorrentFromStorage, singleTorrent) calculatedCompletedSize := CalculateCompletedSize(singleTorrentFromStorage, singleTorrent)
TempHash = singleTorrent.InfoHash() TempHash = singleTorrent.InfoHash()
if (calculatedCompletedSize == singleTorrentFromStorage.TorrentSize) && (singleTorrentFromStorage.TorrentMoved == false) { //if we are done downloading and haven't moved torrent yet if (calculatedCompletedSize == singleTorrentFromStorage.TorrentSize) && (singleTorrentFromStorage.TorrentMoved == false) { //if we are done downloading and haven't moved torrent yet
Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Torrent Completed, moving...") Logger.WithFields(logrus.Fields{"singleTorrent": singleTorrentFromStorage.TorrentName}).Info("Torrent Completed, moving...")
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 go MoveAndLeaveSymlink(config, singleTorrent.InfoHash().String(), db, false, "") //can take some time to move file so running this in another thread TODO make this a goroutine and skip this block if the routine is still running
} }
fullStruct := singleTorrent.Stats() fullStruct := singleTorrent.Stats()

View File

@@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/anacrolix/torrent" "github.com/anacrolix/torrent"
"github.com/asdine/storm"
Settings "github.com/deranjer/goTorrent/settings" Settings "github.com/deranjer/goTorrent/settings"
"github.com/deranjer/goTorrent/storage" "github.com/deranjer/goTorrent/storage"
Storage "github.com/deranjer/goTorrent/storage" Storage "github.com/deranjer/goTorrent/storage"
@@ -22,6 +23,15 @@ func secondsToMinutes(inSeconds int64) string {
return str return str
} }
//MakeRange creates a range of pieces to set their priority based on a file
func MakeRange(min, max int) []int {
a := make([]int, max-min+1)
for i := range a {
a[i] = min + i
}
return a
}
//HumanizeBytes returns a nice humanized version of bytes in either GB or MB //HumanizeBytes returns a nice humanized version of bytes in either GB or MB
func HumanizeBytes(bytes float32) string { func HumanizeBytes(bytes float32) string {
if bytes < 1000000 { //if we have less than 1MB in bytes convert to KB if bytes < 1000000 { //if we have less than 1MB in bytes convert to KB
@@ -59,10 +69,36 @@ func CopyFile(srcFile string, destFile string) { //TODO move this to our importe
} }
//SetFilePriority sets the priorities for all of the files in a torrent
func SetFilePriority(t *torrent.Client, db *storm.DB) {
storedTorrents := Storage.FetchAllStoredTorrents(db)
for _, singleTorrent := range t.Torrents() {
for _, storedTorrent := range storedTorrents {
if storedTorrent.Hash == singleTorrent.InfoHash().String() {
for _, file := range singleTorrent.Files() {
for _, storedFile := range storedTorrent.TorrentFilePriority {
if storedFile.TorrentFilePath == file.DisplayPath() {
switch storedFile.TorrentFilePriority {
case "High":
file.SetPriority(torrent.PiecePriorityHigh)
case "Normal":
file.SetPriority(torrent.PiecePriorityNormal)
case "Cancel":
file.SetPriority(torrent.PiecePriorityNone)
default:
file.SetPriority(torrent.PiecePriorityNormal)
}
}
}
}
}
}
}
}
//CalculateTorrentSpeed is used to calculate the torrent upload and download speed over time c is current clientdb, oc is last client db to calculate speed over time //CalculateTorrentSpeed is used to calculate the torrent upload and download speed over time c is current clientdb, oc is last client db to calculate speed over time
func CalculateTorrentSpeed(t *torrent.Torrent, c *ClientDB, oc ClientDB, completedSize int64) { func CalculateTorrentSpeed(t *torrent.Torrent, c *ClientDB, oc ClientDB, completedSize int64) {
now := time.Now() now := time.Now()
//bytes := t.BytesCompleted()
bytes := completedSize bytes := completedSize
bytesUpload := t.Stats().BytesWrittenData bytesUpload := t.Stats().BytesWrittenData
dt := float32(now.Sub(oc.UpdatedAt)) // get the delta time length between now and last updated dt := float32(now.Sub(oc.UpdatedAt)) // get the delta time length between now and last updated
@@ -113,6 +149,9 @@ func CalculateCompletedSize(tFromStorage *Storage.TorrentLocal, activeTorrent *t
} }
} }
downloadedLength := activeTorrent.BytesCompleted() - discardByteLength downloadedLength := activeTorrent.BytesCompleted() - discardByteLength
if downloadedLength < 0 {
downloadedLength = 0
}
return downloadedLength return downloadedLength
} }
@@ -146,11 +185,12 @@ func CalculateTorrentStatus(t *torrent.Torrent, c *ClientDB, config Settings.Ful
c.Status = "Stopped" c.Status = "Stopped"
c.MaxConnections = 0 c.MaxConnections = 0
t.SetMaxEstablishedConns(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 } 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 bytesMissing := totalSize - bytesCompleted
c.MaxConnections = 80 c.MaxConnections = 80
t.SetMaxEstablishedConns(80) //TODO this should not be needed but apparently is needed t.SetMaxEstablishedConns(80)
t.DownloadAll() //ensure that we are setting the torrent to download //t.DownloadAll() //ensure that we are setting the torrent to download
if t.Seeding() && t.Stats().ActivePeers > 0 && bytesMissing == 0 { if t.Seeding() && t.Stats().ActivePeers > 0 && bytesMissing == 0 {
c.Status = "Seeding" c.Status = "Seeding"
} else if t.Stats().ActivePeers > 0 && bytesMissing > 0 { } else if t.Stats().ActivePeers > 0 && bytesMissing > 0 {

View File

@@ -7,7 +7,7 @@ import { ProgressBarCell } from '../../CustomCells/progressBarCell';
import { import {
SortingState, IntegratedSorting, VirtualTableLayout, SelectionState, SortingState, IntegratedSorting, IntegratedSelection, VirtualTableLayout, SelectionState,
} from '@devexpress/dx-react-grid'; } from '@devexpress/dx-react-grid';
import { import {
@@ -131,7 +131,8 @@ class FileTab extends React.Component {
<TableColumnResizing columnWidths={this.state.columnWidths} onColumnWidthsChange={this.changeColumnWidths}/> <TableColumnResizing columnWidths={this.state.columnWidths} onColumnWidthsChange={this.changeColumnWidths}/>
<TableColumnReordering order={this.state.columnOrder} onOrderChange={this.changeColumnOrder} /> <TableColumnReordering order={this.state.columnOrder} onOrderChange={this.changeColumnOrder} />
<TableSelection selectByRowClick highlightSelected /> <IntegratedSelection />
<TableSelection selectByRowClick highlightSelected showSelectAll />
<TableHeaderRow allowSorting allowResizing allowDragging /> <TableHeaderRow allowSorting allowResizing allowDragging />
</Grid> </Grid>
</Paper> </Paper>

View File

@@ -4,7 +4,7 @@ import Button from 'material-ui/Button';
import Paper from 'material-ui/Paper'; import Paper from 'material-ui/Paper';
import { import {
SortingState, IntegratedSorting, VirtualTableLayout, SelectionState, SortingState, IntegratedSorting, IntegratedSelection, VirtualTableLayout, SelectionState,
} from '@devexpress/dx-react-grid'; } from '@devexpress/dx-react-grid';
import { import {
@@ -98,7 +98,8 @@ class RSSTorrentList extends React.Component {
<TableColumnResizing columnWidths={this.state.columnWidths} onColumnWidthsChange={this.changeColumnWidths}/> <TableColumnResizing columnWidths={this.state.columnWidths} onColumnWidthsChange={this.changeColumnWidths}/>
<TableColumnReordering order={this.state.columnOrder} onOrderChange={this.changeColumnOrder} /> <TableColumnReordering order={this.state.columnOrder} onOrderChange={this.changeColumnOrder} />
<TableSelection selectByRowClick highlightSelected /> <IntegratedSelection />
<TableSelection selectByRowClick highlightSelected showSelectAll />
<TableHeaderRow allowSorting allowResizing allowDragging /> <TableHeaderRow allowSorting allowResizing allowDragging />
</Grid> </Grid>
</Paper> </Paper>

View File

@@ -88,7 +88,7 @@ export default class Login extends React.Component {
render() { render() {
const { classes, onClose, handleRequestClose, handleSubmit } = this.props; const { classes, onClose, handleRequestClose, handleSubmit } = this.props;
return ( return (
<Dialog open={this.state.open} onClose={this.handleRequestClose} ignoreBackdropClick={true} disableBackdrop={true}> <Dialog open={this.state.open} onClose={this.handleRequestClose} disableBackdropClick disableEscapeKeyDown>
<DialogTitle>Login Here</DialogTitle> <DialogTitle>Login Here</DialogTitle>
<DialogContent> <DialogContent>
<DialogContentText> <DialogContentText>
@@ -106,9 +106,10 @@ export default class Login extends React.Component {
type="text" type="text"
placeholder="Username" placeholder="Username"
fullWidth fullWidth
required
onChange={this.setUserNameValue} onChange={this.setUserNameValue}
/> />
<TextField id="password" type="password" label="Password" placeholder="Password" fullWidth onChange={this.setPasswordValue} /> <TextField id="password" type="password" label="Password" placeholder="Password" required fullWidth onChange={this.setPasswordValue} />
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button onClick={this.handleRequestClose} color="primary"> <Button onClick={this.handleRequestClose} color="primary">

View File

@@ -157,6 +157,7 @@ const reducer = (state = initialState, action) => {
if (buttonStateTest.length > 0 && buttonStateTest2.length === 0){ if (buttonStateTest.length > 0 && buttonStateTest2.length === 0){
let buttonStateFinal = [{startButton: "default", stopButton: "primary", deleteButton: "secondary", fSeedButton: "default", fRecheckButton: "primary"}] let buttonStateFinal = [{startButton: "default", stopButton: "primary", deleteButton: "secondary", fSeedButton: "default", fRecheckButton: "primary"}]
console.log("ButtonStateFil")
return { return {
...state, ...state,
buttonState: buttonStateFinal buttonState: buttonStateFinal
@@ -179,14 +180,13 @@ const reducer = (state = initialState, action) => {
}; };
} }
let buttonStateFinal = state.buttonStateDefault //If we can't match, just make it default
return {
...state,
buttonState: buttonStateFinal
};
} }
return {
...state,
buttonState: buttonStateFinal
};
default:
return state;
}; };
console.log("no actiontypes found", action) console.log("no actiontypes found", action)

View File

@@ -5,7 +5,7 @@ import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table';
import Paper from 'material-ui/Paper'; import Paper from 'material-ui/Paper';
import { import {
SortingState, IntegratedSorting, VirtualTableLayout, SelectionState, FilteringState, IntegratedFiltering, SortingState, IntegratedSorting, IntegratedSelection, VirtualTableLayout, SelectionState, FilteringState, IntegratedFiltering,
} from '@devexpress/dx-react-grid'; } from '@devexpress/dx-react-grid';
import { import {
@@ -134,7 +134,8 @@ class TorrentListTable extends React.Component {
<DragDropProvider/> <DragDropProvider/>
<TableColumnResizing columnWidths={this.state.columnWidths} onColumnWidthsChange={this.changeColumnWidths}/> <TableColumnResizing columnWidths={this.state.columnWidths} onColumnWidthsChange={this.changeColumnWidths}/>
<TableColumnReordering order={this.state.columnOrder} onOrderChange={this.changeColumnOrder} /> <TableColumnReordering order={this.state.columnOrder} onOrderChange={this.changeColumnOrder} />
<TableSelection selectByRowClick highlightSelected /> <IntegratedSelection />
<TableSelection selectByRowClick highlightSelected showSelectAll />
<TableHeaderRow allowSorting allowResizing allowDragging /> <TableHeaderRow allowSorting allowResizing allowDragging />
</Grid> </Grid>
</Paper> </Paper>

70
main.go
View File

@@ -95,6 +95,7 @@ func main() {
Storage.Logger = Logger Storage.Logger = Logger
Settings.Logger = Logger Settings.Logger = Logger
Config := Settings.FullClientSettingsNew() //grabbing from settings.go Config := Settings.FullClientSettingsNew() //grabbing from settings.go
Engine.Config = Config
if Config.LoggingOutput == "file" { if Config.LoggingOutput == "file" {
_, err := os.Stat("logs") _, err := os.Stat("logs")
if os.IsNotExist(err) { if os.IsNotExist(err) {
@@ -135,6 +136,7 @@ func main() {
defer db.Close() //defering closing the database until the program closes defer db.Close() //defering closing the database until the program closes
tokens := Storage.IssuedTokensList{} //if first run setting up the authentication tokens tokens := Storage.IssuedTokensList{} //if first run setting up the authentication tokens
var signingKey []byte
err = db.One("ID", 3, &tokens) err = db.One("ID", 3, &tokens)
if err != nil { if err != nil {
Logger.WithFields(logrus.Fields{"RSSFeedStore": tokens, "error": err}).Info("No Tokens database found, assuming first run, generating token...") Logger.WithFields(logrus.Fields{"RSSFeedStore": tokens, "error": err}).Info("No Tokens database found, assuming first run, generating token...")
@@ -147,11 +149,9 @@ func main() {
Issuer: "goTorrentServer", Issuer: "goTorrentServer",
}, },
} }
signingkey := Settings.GenerateSigningKey() //Running this will invalidate any certs you already issued!! signingKey = Settings.GenerateSigningKey() //Running this will invalidate any certs you already issued!!
fmt.Println("SigningKey", signingkey) authString := Settings.GenerateToken(claims, signingKey)
authString := Settings.GenerateToken(claims, signingkey) tokens.SigningKey = signingKey
tokens.SigningKey = signingkey
fmt.Println("ClientToken: ", authString)
tokens.FirstToken = authString tokens.FirstToken = authString
tokens.TokenNames = append(tokens.TokenNames, Storage.SingleToken{"firstClient"}) tokens.TokenNames = append(tokens.TokenNames, Storage.SingleToken{"firstClient"})
err := ioutil.WriteFile("clientAuth.txt", []byte(authString), 0755) err := ioutil.WriteFile("clientAuth.txt", []byte(authString), 0755)
@@ -159,6 +159,9 @@ func main() {
Logger.WithFields(logrus.Fields{"error": err}).Warn("Unable to write client auth to file..") Logger.WithFields(logrus.Fields{"error": err}).Warn("Unable to write client auth to file..")
} }
db.Save(&tokens) //Writing all of that to the database db.Save(&tokens) //Writing all of that to the database
} else { //Already have a signing key so pulling that signing key out of the database to sign any key requests
tokens := Storage.FetchJWTTokens(db)
signingKey = tokens.SigningKey
} }
oldConfig, err := Storage.FetchConfig(db) oldConfig, err := Storage.FetchConfig(db)
@@ -178,17 +181,14 @@ func main() {
cronEngine := Engine.InitializeCronEngine() //Starting the cron engine for tasks cronEngine := Engine.InitializeCronEngine() //Starting the cron engine for tasks
Logger.Debug("Cron Engine Initialized...") Logger.Debug("Cron Engine Initialized...")
torrentLocalStorage := Storage.TorrentLocal{} //creating a new struct that stores all of our local storage info torrentLocalStorage := Storage.TorrentLocal{} //creating a new struct that stores all of our local storage info
var TorrentLocalArray = []*Storage.TorrentLocal{} //this is an array of ALL of the local storage torrents, they will be added back in via hash var RunningTorrentArray = []Engine.ClientDB{} //this stores ALL of the torrents that are running, used for client update pushes combines Local Storage and Running tclient info
var RunningTorrentArray = []Engine.ClientDB{} //this stores ALL of the torrents that are running, used for client update pushes combines Local Storage and Running tclient info
var PreviousTorrentArray = []Engine.ClientDB{} var PreviousTorrentArray = []Engine.ClientDB{}
TorrentLocalArray = Storage.FetchAllStoredTorrents(db) //pulling in all the already added torrents TorrentLocalArray := Storage.FetchAllStoredTorrents(db) //pulling in all the already added torrents - this is an array of ALL of the local storage torrents, they will be added back in via hash
if TorrentLocalArray != nil { //the first creation of the running torrent array //since we are adding all of them in we use a coroutine... just allows the web ui to load then it will load in the torrents if TorrentLocalArray != nil { //the first creation of the running torrent array //since we are adding all of them in we use a coroutine... just allows the web ui to load then it will load in the torrents
go func() { //TODO instead of running all torrent fetches in coroutine see if possible to run each single one in a routine so we don't wait for ALL of them to be verified go Engine.CreateInitialTorrentArray(tclient, TorrentLocalArray, db) //adding all of the stored torrents into the torrent client
RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db)
}()
} else { } else {
Logger.Info("Database is empty, no torrents loaded") Logger.Info("Database is empty, no torrents loaded")
} }
@@ -254,16 +254,28 @@ func main() {
handleAuthentication(conn, db) handleAuthentication(conn, db)
} }
case "newAuthToken":
claims := Settings.GoTorrentClaims{
payloadData["ClientName"].(string),
jwt.StandardClaims{
Issuer: "goTorrentServer",
},
}
Logger.WithFields(logrus.Fields{"clientName": payloadData["ClientName"].(string)}).Info("New Auth Token creation request")
fmt.Println("Signing Key", signingKey)
token := Settings.GenerateToken(claims, signingKey)
tokenReturn := Settings.TokenReturn{TokenReturn: token}
tokensDB := Storage.FetchJWTTokens(db)
tokensDB.TokenNames = append(tokens.TokenNames, Storage.SingleToken{payloadData["ClientName"].(string)})
db.Update(&tokensDB) //adding the new token client name to the database
conn.WriteJSON(tokenReturn)
case "torrentListRequest": case "torrentListRequest":
Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested TorrentList Update") Logger.WithFields(logrus.Fields{"message": msg}).Debug("Client Requested TorrentList Update")
TorrentLocalArray = Storage.FetchAllStoredTorrents(db) //Required to re-read th database since we write to the DB and this will pull the changes from it TorrentLocalArray = Storage.FetchAllStoredTorrents(db) //Required to re-read th database since we write to the DB and this will pull the changes from it
RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db) //Updates the RunningTorrentArray with the current client data as well RunningTorrentArray = Engine.CreateRunningTorrentArray(tclient, TorrentLocalArray, PreviousTorrentArray, Config, db) //Updates the RunningTorrentArray with the current client data as well
PreviousTorrentArray = RunningTorrentArray PreviousTorrentArray = RunningTorrentArray
//Logger.WithFields(logrus.Fields{"message": msg}).Infof("%+v\n", RunningTorrentArray) torrentlistArray := Engine.TorrentList{MessageType: "torrentList", ClientDBstruct: RunningTorrentArray, Totaltorrents: len(RunningTorrentArray)}
var torrentlistArray = new(Engine.TorrentList)
torrentlistArray.MessageType = "torrentList"
torrentlistArray.ClientDBstruct = RunningTorrentArray
torrentlistArray.Totaltorrents = len(RunningTorrentArray)
Logger.WithFields(logrus.Fields{"torrentList": torrentlistArray, "previousTorrentList": PreviousTorrentArray}).Debug("Previous and Current Torrent Lists for sending to client") Logger.WithFields(logrus.Fields{"torrentList": torrentlistArray, "previousTorrentList": PreviousTorrentArray}).Debug("Previous and Current Torrent Lists for sending to client")
conn.WriteJSON(torrentlistArray) conn.WriteJSON(torrentlistArray)
@@ -359,7 +371,7 @@ func main() {
fullRSSFeeds.RSSFeeds = append(fullRSSFeeds.RSSFeeds, newRSSFeedFull) // add the new RSS feed to the stack 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.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Adding RSS feed..."}, conn)
Engine.ForceRSSRefresh(db, fullRSSFeeds) 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 //forcing an RSS refresh to fully populate all rss feeds
case "deleteRSSFeed": case "deleteRSSFeed":
deleteRSSFeed := payloadData["RSSURL"].(string) deleteRSSFeed := payloadData["RSSURL"].(string)
@@ -458,16 +470,13 @@ func main() {
case "stopTorrents": case "stopTorrents":
torrentHashes := payloadData["TorrentHashes"].([]interface{}) torrentHashes := payloadData["TorrentHashes"].([]interface{})
Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Stop Request"}, conn) Engine.CreateServerPushMessage(Engine.ServerPushMessage{MessageType: "serverPushMessage", MessageLevel: "info", Payload: "Received Stop Request"}, conn)
for _, singleTorrent := range runningTorrents { for _, singleTorrent := range tclient.Torrents() {
for _, singleSelection := range torrentHashes { for _, singleSelection := range torrentHashes {
if singleTorrent.InfoHash().String() == singleSelection { if singleTorrent.InfoHash().String() == singleSelection {
Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Matched for stopping torrents") Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Matched for stopping torrents")
oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String()) oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String())
oldTorrentInfo.TorrentStatus = "Stopped" oldTorrentInfo.TorrentStatus = "Stopped"
oldTorrentInfo.MaxConnections = 0 oldTorrentInfo.MaxConnections = 0
oldMax := singleTorrent.SetMaxEstablishedConns(0) //Forcing the max amount of connections allowed to zero effectively stopping it
Logger.WithFields(logrus.Fields{"oldMaxConnections": oldMax, "torrent": singleTorrent}).Info("Forcing connections to zero for torrent")
Storage.UpdateStorageTick(db, oldTorrentInfo) //Updating the torrent status Storage.UpdateStorageTick(db, oldTorrentInfo) //Updating the torrent status
} }
} }
@@ -481,15 +490,14 @@ func main() {
for _, singleTorrent := range runningTorrents { for _, singleTorrent := range runningTorrents {
for _, singleSelection := range torrentHashes { for _, singleSelection := range torrentHashes {
if singleTorrent.InfoHash().String() == singleSelection { if singleTorrent.InfoHash().String() == singleSelection {
singleTorrent.Drop() oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String())
Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Matched for deleting torrents") Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Matched for deleting torrents")
if withData { if withData {
Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Deleting torrent and data") oldTorrentInfo.TorrentStatus = "DroppedData" //Will be cleaned up the next engine loop since deleting a torrent mid loop can cause issues
Storage.DelTorrentLocalStorageAndFiles(db, singleTorrent.InfoHash().String(), Config.TorrentConfig.DataDir)
} else { } else {
Logger.WithFields(logrus.Fields{"selection": singleSelection}).Info("Deleting just the torrent") oldTorrentInfo.TorrentStatus = "Dropped"
Storage.DelTorrentLocalStorage(db, singleTorrent.InfoHash().String())
} }
Storage.UpdateStorageTick(db, oldTorrentInfo)
} }
} }
} }
@@ -505,9 +513,7 @@ func main() {
oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String()) oldTorrentInfo := Storage.FetchTorrentFromStorage(db, singleTorrent.InfoHash().String())
oldTorrentInfo.TorrentStatus = "Running" oldTorrentInfo.TorrentStatus = "Running"
oldTorrentInfo.MaxConnections = 80 oldTorrentInfo.MaxConnections = 80
oldMax := singleTorrent.SetMaxEstablishedConns(80) Logger.WithFields(logrus.Fields{"Torrent": oldTorrentInfo.TorrentName}).Info("Changing database to torrent running with 80 max connections")
Logger.WithFields(logrus.Fields{"Previous Max Connections": oldMax, "Torrent": oldTorrentInfo.TorrentName}).Info("Setting max connection from zero to")
singleTorrent.DownloadAll() //forcing a download all just in case TODO.. might reset priorities of file dl
Storage.UpdateStorageTick(db, oldTorrentInfo) //Updating the torrent status Storage.UpdateStorageTick(db, oldTorrentInfo) //Updating the torrent status
} }
} }
@@ -526,9 +532,7 @@ func main() {
oldTorrentInfo.TorrentStatus = "Running" oldTorrentInfo.TorrentStatus = "Running"
oldTorrentInfo.MaxConnections = 80 oldTorrentInfo.MaxConnections = 80
fmt.Println("OldtorrentinfoName", oldTorrentInfo.TorrentName) fmt.Println("OldtorrentinfoName", oldTorrentInfo.TorrentName)
oldMax := singleTorrent.SetMaxEstablishedConns(80) Logger.WithFields(logrus.Fields{"NewMax": oldTorrentInfo.MaxConnections, "Torrent": oldTorrentInfo.TorrentName}).Info("Setting max connection from zero to 80")
singleTorrent.DownloadAll()
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 Storage.UpdateStorageTick(db, oldTorrentInfo) //Updating the torrent status
} }
} }

View File

@@ -80033,9 +80033,9 @@ var reducer = function reducer() {
case actionTypes.SET_BUTTON_STATE: case actionTypes.SET_BUTTON_STATE:
if (action.buttonState.length === 0) { if (action.buttonState.length === 0) {
//if selection is empty buttons will be default and selectionHashes will be blanked out and pushed to redux //if selection is empty buttons will be default and selectionHashes will be blanked out and pushed to redux
var _buttonStateFinal = state.buttonStateDefault; //if no selection dispatch that to redux var buttonStateFinal = state.buttonStateDefault; //if no selection dispatch that to redux
return _extends({}, state, { return _extends({}, state, {
buttonState: _buttonStateFinal buttonState: buttonStateFinal
}); });
} else { } else {
// if we have selection continue on with logic to determine button state // if we have selection continue on with logic to determine button state
@@ -80059,6 +80059,7 @@ var reducer = function reducer() {
if (buttonStateTest.length > 0 && buttonStateTest2.length === 0) { if (buttonStateTest.length > 0 && buttonStateTest2.length === 0) {
var _buttonStateFinal2 = [{ startButton: "default", stopButton: "primary", deleteButton: "secondary", fSeedButton: "default", fRecheckButton: "primary" }]; var _buttonStateFinal2 = [{ startButton: "default", stopButton: "primary", deleteButton: "secondary", fSeedButton: "default", fRecheckButton: "primary" }];
console.log("ButtonStateFil");
return _extends({}, state, { return _extends({}, state, {
buttonState: _buttonStateFinal2 buttonState: _buttonStateFinal2
}); });
@@ -80075,13 +80076,12 @@ var reducer = function reducer() {
buttonState: _buttonStateFinal4 buttonState: _buttonStateFinal4
}); });
} }
var _buttonStateFinal = state.buttonStateDefault; //If we can't match, just make it default
return _extends({}, state, {
buttonState: _buttonStateFinal
});
} }
return _extends({}, state, {
buttonState: buttonStateFinal
});
default:
return state;
}; };
console.log("no actiontypes found", action); console.log("no actiontypes found", action);
@@ -88319,7 +88319,7 @@ var addTorrentPopup = function (_React$Component) {
value: function render() { value: function render() {
var _props = this.props, var _props = this.props,
classes = _props.classes, classes = _props.classes,
onRequestClose = _props.onRequestClose, onClose = _props.onClose,
handleRequestClose = _props.handleRequestClose, handleRequestClose = _props.handleRequestClose,
handleSubmit = _props.handleSubmit; handleSubmit = _props.handleSubmit;
@@ -97937,7 +97937,6 @@ var RSSFeedList = function (_React$Component) {
value: function render() { value: function render() {
var _this2 = this; var _this2 = this;
//const { classes, onRequestClose, handleRequestClose, handleSubmit } = this.props;
if (this.props.RSSList.length > 0 && this.state.showList == false) { if (this.props.RSSList.length > 0 && this.state.showList == false) {
console.log("Setting list to show...."); console.log("Setting list to show....");
this.setState({ showList: true }); this.setState({ showList: true });
@@ -98136,7 +98135,8 @@ var RSSTorrentList = function (_React$Component) {
_react2.default.createElement(_dxReactGridMaterialUi.VirtualTable, { height: 500 }), _react2.default.createElement(_dxReactGridMaterialUi.VirtualTable, { height: 500 }),
_react2.default.createElement(_dxReactGridMaterialUi.TableColumnResizing, { columnWidths: this.state.columnWidths, onColumnWidthsChange: this.changeColumnWidths }), _react2.default.createElement(_dxReactGridMaterialUi.TableColumnResizing, { columnWidths: this.state.columnWidths, onColumnWidthsChange: this.changeColumnWidths }),
_react2.default.createElement(_dxReactGridMaterialUi.TableColumnReordering, { order: this.state.columnOrder, onOrderChange: this.changeColumnOrder }), _react2.default.createElement(_dxReactGridMaterialUi.TableColumnReordering, { order: this.state.columnOrder, onOrderChange: this.changeColumnOrder }),
_react2.default.createElement(_dxReactGridMaterialUi.TableSelection, { selectByRowClick: true, highlightSelected: true }), _react2.default.createElement(_dxReactGrid.IntegratedSelection, null),
_react2.default.createElement(_dxReactGridMaterialUi.TableSelection, { selectByRowClick: true, highlightSelected: true, showSelectAll: true }),
_react2.default.createElement(_dxReactGridMaterialUi.TableHeaderRow, { allowSorting: true, allowResizing: true, allowDragging: true }) _react2.default.createElement(_dxReactGridMaterialUi.TableHeaderRow, { allowSorting: true, allowResizing: true, allowDragging: true })
) )
) )
@@ -124980,7 +124980,8 @@ var FileTab = function (_React$Component) {
_react2.default.createElement(_dxReactGridMaterialUi.VirtualTable, { height: 300, cellComponent: this.progressBar }), _react2.default.createElement(_dxReactGridMaterialUi.VirtualTable, { height: 300, cellComponent: this.progressBar }),
_react2.default.createElement(_dxReactGridMaterialUi.TableColumnResizing, { columnWidths: this.state.columnWidths, onColumnWidthsChange: this.changeColumnWidths }), _react2.default.createElement(_dxReactGridMaterialUi.TableColumnResizing, { columnWidths: this.state.columnWidths, onColumnWidthsChange: this.changeColumnWidths }),
_react2.default.createElement(_dxReactGridMaterialUi.TableColumnReordering, { order: this.state.columnOrder, onOrderChange: this.changeColumnOrder }), _react2.default.createElement(_dxReactGridMaterialUi.TableColumnReordering, { order: this.state.columnOrder, onOrderChange: this.changeColumnOrder }),
_react2.default.createElement(_dxReactGridMaterialUi.TableSelection, { selectByRowClick: true, highlightSelected: true }), _react2.default.createElement(_dxReactGrid.IntegratedSelection, null),
_react2.default.createElement(_dxReactGridMaterialUi.TableSelection, { selectByRowClick: true, highlightSelected: true, showSelectAll: true }),
_react2.default.createElement(_dxReactGridMaterialUi.TableHeaderRow, { allowSorting: true, allowResizing: true, allowDragging: true }) _react2.default.createElement(_dxReactGridMaterialUi.TableHeaderRow, { allowSorting: true, allowResizing: true, allowDragging: true })
) )
) )
@@ -132715,7 +132716,8 @@ var TorrentListTable = function (_React$Component) {
_react2.default.createElement(_dxReactGridMaterialUi.DragDropProvider, null), _react2.default.createElement(_dxReactGridMaterialUi.DragDropProvider, null),
_react2.default.createElement(_dxReactGridMaterialUi.TableColumnResizing, { columnWidths: this.state.columnWidths, onColumnWidthsChange: this.changeColumnWidths }), _react2.default.createElement(_dxReactGridMaterialUi.TableColumnResizing, { columnWidths: this.state.columnWidths, onColumnWidthsChange: this.changeColumnWidths }),
_react2.default.createElement(_dxReactGridMaterialUi.TableColumnReordering, { order: this.state.columnOrder, onOrderChange: this.changeColumnOrder }), _react2.default.createElement(_dxReactGridMaterialUi.TableColumnReordering, { order: this.state.columnOrder, onOrderChange: this.changeColumnOrder }),
_react2.default.createElement(_dxReactGridMaterialUi.TableSelection, { selectByRowClick: true, highlightSelected: true }), _react2.default.createElement(_dxReactGrid.IntegratedSelection, null),
_react2.default.createElement(_dxReactGridMaterialUi.TableSelection, { selectByRowClick: true, highlightSelected: true, showSelectAll: true }),
_react2.default.createElement(_dxReactGridMaterialUi.TableHeaderRow, { allowSorting: true, allowResizing: true, allowDragging: true }) _react2.default.createElement(_dxReactGridMaterialUi.TableHeaderRow, { allowSorting: true, allowResizing: true, allowDragging: true })
) )
); );
@@ -136872,13 +136874,13 @@ var Login = function (_React$Component) {
value: function render() { value: function render() {
var _props = this.props, var _props = this.props,
classes = _props.classes, classes = _props.classes,
onRequestClose = _props.onRequestClose, onClose = _props.onClose,
handleRequestClose = _props.handleRequestClose, handleRequestClose = _props.handleRequestClose,
handleSubmit = _props.handleSubmit; handleSubmit = _props.handleSubmit;
return _react2.default.createElement( return _react2.default.createElement(
_Dialog2.default, _Dialog2.default,
{ open: this.state.open, onClose: this.handleRequestClose, ignoreBackdropClick: true, disableBackdrop: true }, { open: this.state.open, onClose: this.handleRequestClose, disableBackdropClick: true, disableEscapeKeyDown: true },
_react2.default.createElement( _react2.default.createElement(
_Dialog.DialogTitle, _Dialog.DialogTitle,
null, null,
@@ -136906,9 +136908,10 @@ var Login = function (_React$Component) {
type: 'text', type: 'text',
placeholder: 'Username', placeholder: 'Username',
fullWidth: true, fullWidth: true,
required: true,
onChange: this.setUserNameValue onChange: this.setUserNameValue
}), }),
_react2.default.createElement(_TextField2.default, { id: 'password', type: 'password', label: 'Password', placeholder: 'Password', fullWidth: true, onChange: this.setPasswordValue }) _react2.default.createElement(_TextField2.default, { id: 'password', type: 'password', label: 'Password', placeholder: 'Password', required: true, fullWidth: true, onChange: this.setPasswordValue })
), ),
_react2.default.createElement( _react2.default.createElement(
_Dialog.DialogActions, _Dialog.DialogActions,

View File

@@ -13,6 +13,10 @@ type AuthRequest struct {
AuthString string `json:"AuthString"` AuthString string `json:"AuthString"`
} }
type TokenReturn struct {
TokenReturn string `json:"TokenReturn"`
}
//GoTorrentClaims stores the name of the client (usually user entered) and any standard jwt claims we want to define //GoTorrentClaims stores the name of the client (usually user entered) and any standard jwt claims we want to define
type GoTorrentClaims struct { type GoTorrentClaims struct {
ClientName string `json:"clientName"` ClientName string `json:"clientName"`