forked from BruceWangNo1/remote-torrent
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fec11bc
commit 556d27a
Showing
6 changed files
with
338 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
media |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package remote_torrent | ||
|
||
import ( | ||
"os/exec" | ||
"log" | ||
"bytes" | ||
"fmt" | ||
) | ||
|
||
var out bytes.Buffer | ||
|
||
func download(magnet string) error { | ||
_, err := exec.LookPath("torrent") | ||
if err != nil { | ||
log.Fatal("Please install anacrolix/torrent first.\n") | ||
return err | ||
} | ||
|
||
go func() { | ||
cmd := exec.Command("torrent", magnet) | ||
cmd.Dir = "/root/media/" | ||
cmd.Stdout = &out | ||
err := cmd.Start() | ||
if err != nil { | ||
log.Fatal(err) | ||
return | ||
} | ||
//downloadFinished = make(chan string) | ||
//downloadFinished <- "finished" | ||
fmt.Println("Torrent Download Finished Successfully.") | ||
}() | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"log" | ||
rt "github.com/brucewangno1/remote-torrent" | ||
) | ||
|
||
// 1) Client Mode (e.g. go run main.go client userName:password ip:port torrentFile/magnetLink) | ||
// 2) Server Mode (e.g. go run main.go server portToListen userName:Password) | ||
func main() { | ||
mode := os.Args[1] | ||
if mode == "client" { | ||
rt.RTClient(os.Args[2:]) | ||
} else if mode == "server" { | ||
rt.RTServer(os.Args[2:]) | ||
} else { | ||
log.Fatal("Args input is wrong. Please check usage\n") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package remote_torrent | ||
|
||
import ( | ||
"net/http" | ||
"net/url" | ||
"strings" | ||
"fmt" | ||
"io/ioutil" | ||
"time" | ||
"os/exec" | ||
"log" | ||
"os" | ||
) | ||
|
||
func RTClient(args []string) { | ||
username := strings.Split(args[0], ":")[0] | ||
password := strings.Split(args[0], ":")[1] | ||
ipAndPort := args[1] | ||
magnet := args[2] | ||
|
||
//finished := make(chan error, 2) | ||
// | ||
//c := make(chan os.Signal, 2) | ||
//signal.Notify(c, os.Interrupt, syscall.SIGTERM) | ||
// | ||
//go func() { | ||
// select { | ||
// case <-c: | ||
// if err := cmd.Process.Kill(); err != nil { | ||
// log.Fatal("failed to kill: ", err) | ||
// } | ||
// os.Exit(1) | ||
// return | ||
// case err := <-finished: | ||
// if err != nil { | ||
// fmt.Println(err) | ||
// return | ||
// } | ||
// } | ||
//}() | ||
|
||
// schedule torrent download | ||
for { | ||
schedulingResp, err := http.PostForm("http://" + ipAndPort + "/magnet", url.Values{"username": {username}, "password": {password}, "magnet": {magnet}}) | ||
if err != nil { | ||
fmt.Println(err) | ||
fmt.Println("retrying...") | ||
continue | ||
} else { | ||
fmt.Println("Torrent download scheduling over http succeeds.") | ||
} | ||
|
||
if schedulingResp.StatusCode == http.StatusUnauthorized { | ||
log.Fatal("Authentication failed.") | ||
return | ||
} | ||
|
||
body, err := ioutil.ReadAll(schedulingResp.Body) | ||
schedulingResp.Body.Close() | ||
|
||
if err != nil { | ||
fmt.Println(err) | ||
fmt.Println("retrying...") | ||
continue | ||
} | ||
|
||
fmt.Println(string(body)) | ||
break | ||
} | ||
|
||
// status check | ||
ticker := time.NewTicker(time.Second * 3) | ||
|
||
for range ticker.C { | ||
statusCheckResp, statusCheckErr := http.PostForm("http://" + ipAndPort + "/status", url.Values{"username": {username}, "password": {password}}) | ||
if statusCheckErr != nil { | ||
fmt.Println(statusCheckErr) | ||
} | ||
|
||
if statusCheckResp.StatusCode == http.StatusUnauthorized { | ||
log.Fatal("Authentication failed.") | ||
return | ||
} | ||
|
||
body, err := ioutil.ReadAll(statusCheckResp.Body) | ||
if err != nil { | ||
fmt.Println(err) | ||
} | ||
|
||
fmt.Printf("\rStatus check: %s.", string(body)) | ||
|
||
statusCheckResp.Body.Close() | ||
|
||
if strings.Contains(string(body), "Torrent Download Finished.") { | ||
fmt.Println("\nTorrent download completed 100% on server side.") | ||
break | ||
} | ||
} | ||
ticker.Stop() | ||
close(ticker) | ||
|
||
// download files from server's directory | ||
for { | ||
_, err := exec.LookPath("wget") | ||
if err != nil { | ||
log.Fatal("Please install wget on your local machine first.\n") | ||
return | ||
} | ||
cmd := exec.Command("wget", "-r", "--post-data", "username=" + username + "&password=" + password, "http://" + ipAndPort + "/") | ||
cmd.Stderr = os.Stdout | ||
err = cmd.Run() | ||
if err != nil { | ||
log.Fatal("Error starting wget: %v", err) | ||
} | ||
|
||
//go func() { | ||
// finished <- cmd.Wait() | ||
//}() | ||
|
||
|
||
fmt.Println("Torrent successfully retrieved to client.") | ||
break | ||
} | ||
|
||
// remove torrent on server remotely | ||
for { | ||
removeTorrentResponse, removeTorrentErr := http.PostForm("http://" + ipAndPort + "/remove", url.Values{"username": {username}, "password": {password}}) | ||
if removeTorrentErr != nil { | ||
fmt.Println(removeTorrentErr) | ||
fmt.Println("retrying...") | ||
continue | ||
} | ||
|
||
if removeTorrentResponse.StatusCode == http.StatusUnauthorized { | ||
log.Fatal("Authentication failed.") | ||
return | ||
} | ||
|
||
body, err := ioutil.ReadAll(removeTorrentResponse.Body) | ||
removeTorrentResponse.Body.Close() | ||
|
||
if err != nil { | ||
fmt.Println(err) | ||
continue | ||
} | ||
fmt.Println(string(body)) | ||
break | ||
} | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package remote_torrent | ||
|
||
import ( | ||
"net/http" | ||
"fmt" | ||
"strings" | ||
"os/exec" | ||
"os" | ||
) | ||
var ( | ||
port string | ||
username string | ||
password string | ||
//downloadFinished chan string | ||
) | ||
|
||
func RTServer(args []string) { | ||
port = args[0] | ||
username = strings.Split(args[1], ":")[0] | ||
password = strings.Split(args[1], ":")[1] | ||
|
||
// Simple static webserver | ||
mux := http.NewServeMux() | ||
mux.HandleFunc("/", simpleAuthentication(http.FileServer(http.Dir("/root/media/")))) | ||
mux.HandleFunc("/magnet", torrentDownloadAssignment) | ||
mux.HandleFunc("/status", statusCheck) | ||
mux.HandleFunc("/remove", removeTorrent) | ||
http.ListenAndServe(":"+port, mux) | ||
} | ||
|
||
|
||
func simpleAuthentication(fn http.Handler) http.HandlerFunc { | ||
return func(w http.ResponseWriter, r *http.Request) { | ||
//user, pass, _ := r.BasicAuth() | ||
err := r.ParseForm() | ||
if err != nil { | ||
http.Error(w, "Unauthorized.", 401) | ||
return | ||
} | ||
username := r.PostFormValue("username") | ||
password := r.PostFormValue("password") | ||
|
||
if !check(username, password) { | ||
http.Error(w, "Unauthorized.", 401) | ||
return | ||
} | ||
fn.ServeHTTP(w, r) | ||
} | ||
} | ||
|
||
func check(u, p string) bool { | ||
if u == username && p == password { | ||
return true | ||
} else { | ||
return false | ||
} | ||
} | ||
|
||
func torrentDownloadAssignment(w http.ResponseWriter, r *http.Request) { | ||
if check(r.PostFormValue("username"), r.PostFormValue("password")) { | ||
magnet := r.PostFormValue("magnet") | ||
go download(magnet) | ||
fmt.Fprintf(w, "Torrent Download Scheduled.") | ||
} else { | ||
w.WriteHeader(http.StatusUnauthorized) | ||
fmt.Fprintf(w, "Authentication Failed.") | ||
} | ||
} | ||
|
||
func statusCheck(w http.ResponseWriter, r *http.Request) { | ||
if check(r.PostFormValue("username"), r.PostFormValue("password")) { | ||
downloadLog := out.String() | ||
if strings.Contains(downloadLog, "utpSocketUtpPacketsReceived") { | ||
fmt.Println("Torrent Download Finished.") | ||
fmt.Fprintf(w, "Torrent Download Finished.") | ||
return | ||
} | ||
info := strings.Split(downloadLog, "% downloading") | ||
infoLength := len(info) | ||
if infoLength < 2 { | ||
fmt.Fprintf(w, "not started yet") | ||
} else { | ||
mostUpToDateStatus := info[infoLength - 2] | ||
mostUpToDateStatusDownloaded := strings.Split(strings.Split(info[infoLength - 1], "(")[1], "/")[0] | ||
mostUpToDateStatusOverallData := strings.Split(strings.Split(info[infoLength - 1], "/")[1], ")")[0] | ||
length := len(mostUpToDateStatus) | ||
statusPercentage := mostUpToDateStatus[length-3:] | ||
|
||
fmt.Println(mostUpToDateStatusDownloaded) | ||
fmt.Fprintf(w, statusPercentage + "%% " + mostUpToDateStatusDownloaded + "/"+ mostUpToDateStatusOverallData) | ||
} | ||
} else { | ||
w.WriteHeader(http.StatusUnauthorized) | ||
fmt.Fprintf(w, "Authentication Failed.") | ||
} | ||
} | ||
|
||
func removeTorrent(w http.ResponseWriter, r *http.Request) { | ||
if check(r.PostFormValue("username"), r.PostFormValue("password")) { | ||
//cmd := exec.Command("bash") | ||
cmd := exec.Command("bash", "-c", "rm -rf /root/media/*") | ||
//cmd.Stdin = strings.NewReader("rm -rf /root/media/*") | ||
cmd.Stdout = os.Stdout | ||
cmd.Stderr = os.Stdout | ||
err := cmd.Run() | ||
if err != nil { | ||
fmt.Println(err) | ||
fmt.Fprintf(w, "'rm' command failed.") | ||
} | ||
|
||
fmt.Fprintf(w, "Torrent removed on server side.") | ||
} else { | ||
w.WriteHeader(http.StatusUnauthorized) | ||
fmt.Fprintf(w, "Authentication Failed.") | ||
} | ||
} |