Skip to content
This repository has been archived by the owner on Jan 21, 2022. It is now read-only.

Commit

Permalink
[magneticow] fully client-side rendering + better file tree + API fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
boramalper committed May 21, 2019
1 parent 75abc0e commit 2cc4c49
Show file tree
Hide file tree
Showing 12 changed files with 444 additions and 180 deletions.
64 changes: 23 additions & 41 deletions cmd/magneticow/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"go.uber.org/zap"
)

func apiTorrentsHandler(w http.ResponseWriter, r *http.Request) {
func apiTorrents(w http.ResponseWriter, r *http.Request) {
// @lastOrderedValue AND @lastID are either both supplied or neither of them should be supplied
// at all; and if that is NOT the case, then return an error.
if q := r.URL.Query(); !((q.Get("lastOrderedValue") != "" && q.Get("lastID") != "") ||
Expand All @@ -29,6 +29,7 @@ func apiTorrentsHandler(w http.ResponseWriter, r *http.Request) {
Ascending *bool `schema:"ascending"`
LastOrderedValue *float64 `schema:"lastOrderedValue"`
LastID *uint64 `schema:"lastID"`
Limit *uint `schema:"limit"`
}
if err := decoder.Decode(&tq, r.URL.Query()); err != nil {
respondError(w, 400, "error while parsing the URL: %s", err.Error())
Expand Down Expand Up @@ -69,27 +70,26 @@ func apiTorrentsHandler(w http.ResponseWriter, r *http.Request) {
}
}

if tq.Limit == nil {
tq.Limit = new(uint)
*tq.Limit = 20
}

torrents, err := database.QueryTorrents(
*tq.Query, *tq.Epoch, orderBy,
*tq.Ascending, N_TORRENTS, tq.LastOrderedValue, tq.LastID)
*tq.Ascending, *tq.Limit, tq.LastOrderedValue, tq.LastID)
if err != nil {
respondError(w, 400, "query error: %s", err.Error())
return
}

// TODO: use plain Marshal
jm, err := json.MarshalIndent(torrents, "", " ")
if err != nil {
respondError(w, 500, "json marshalling error: %s", err.Error())
return
}

if _, err = w.Write(jm); err != nil {
zap.L().Warn("couldn't write http.ResponseWriter", zap.Error(err))
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if err = json.NewEncoder(w).Encode(torrents); err != nil {
zap.L().Warn("JSON encode error", zap.Error(err))
}
}

func apiTorrentsInfohashHandler(w http.ResponseWriter, r *http.Request) {
func apiTorrent(w http.ResponseWriter, r *http.Request) {
infohashHex := mux.Vars(r)["infohash"]

infohash, err := hex.DecodeString(infohashHex)
Expand All @@ -107,19 +107,13 @@ func apiTorrentsInfohashHandler(w http.ResponseWriter, r *http.Request) {
return
}

// TODO: use plain Marshal
jm, err := json.MarshalIndent(torrent, "", " ")
if err != nil {
respondError(w, 500, "json marshalling error: %s", err.Error())
return
}

if _, err = w.Write(jm); err != nil {
zap.L().Warn("couldn't write http.ResponseWriter", zap.Error(err))
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if err = json.NewEncoder(w).Encode(torrent); err != nil {
zap.L().Warn("JSON encode error", zap.Error(err))
}
}

func apiFilesInfohashHandler(w http.ResponseWriter, r *http.Request) {
func apiFilelist(w http.ResponseWriter, r *http.Request) {
infohashHex := mux.Vars(r)["infohash"]

infohash, err := hex.DecodeString(infohashHex)
Expand All @@ -137,19 +131,13 @@ func apiFilesInfohashHandler(w http.ResponseWriter, r *http.Request) {
return
}

// TODO: use plain Marshal
jm, err := json.MarshalIndent(files, "", " ")
if err != nil {
respondError(w, 500, "json marshalling error: %s", err.Error())
return
}

if _, err = w.Write(jm); err != nil {
zap.L().Warn("couldn't write http.ResponseWriter", zap.Error(err))
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if err = json.NewEncoder(w).Encode(files); err != nil {
zap.L().Warn("JSON encode error", zap.Error(err))
}
}

func apiStatisticsHandler(w http.ResponseWriter, r *http.Request) {
func apiStatistics(w http.ResponseWriter, r *http.Request) {
from := r.URL.Query().Get("from")

// TODO: use gorilla?
Expand All @@ -175,15 +163,9 @@ func apiStatisticsHandler(w http.ResponseWriter, r *http.Request) {
return
}

// TODO: use plain Marshal
jm, err := json.MarshalIndent(stats, "", " ")
if err != nil {
respondError(w, 500, "json marshalling error: %s", err.Error())
return
}

if _, err = w.Write(jm); err != nil {
zap.L().Warn("couldn't write http.ResponseWriter", zap.Error(err))
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if err = json.NewEncoder(w).Encode(stats); err != nil {
zap.L().Warn("JSON encode error", zap.Error(err))
}
}

Expand Down
8 changes: 8 additions & 0 deletions cmd/magneticow/data/static/scripts/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ function fileSize(fileSizeInBytes) {
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
}

function humaniseDate(unixTime) {
return (new Date(unixTime * 1000)).toLocaleDateString("en-GB", {
day: "2-digit",
month: "2-digit",
year: "numeric"
});
}

/**
* Returns the ISO 8601 week number for this date.
*
Expand Down
77 changes: 31 additions & 46 deletions cmd/magneticow/data/static/scripts/torrent.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,37 @@


window.onload = function() {
var pre_element = document.getElementsByTagName("pre")[0];
var paths = pre_element.textContent.replace(/\s+$/, "").split("\n");
paths.sort(naturalSort);
paths = paths.map(function(path) { return path.split('/'); });
pre_element.textContent = stringify(structurise(paths)).join("\n");
};
let infoHash = window.location.pathname.split("/")[2];

fetch("/api/v0.1/torrents/" + infoHash).then(x => x.json()).then(x => {
document.querySelector("title").innerText = x.name + " - magneticow";

const template = document.getElementById("main-template").innerHTML;
document.querySelector("main").innerHTML = Mustache.render(template, {
name: x.name,
infoHash: x.infoHash,
sizeHumanised: fileSize(x.size),
discoveredOnHumanised: humaniseDate(x.discoveredOn),
nFiles: x.nFiles,
});

fetch("/api/v0.1/torrents/" + infoHash + "/filelist").then(x => x.json()).then(x => {
const tree = new VanillaTree('#fileTree', {
placeholder: 'Loading...',
});

function structurise(paths) {
var items = [];
for(var i = 0, l = paths.length; i < l; i++) {
var path = paths[i];
var name = path[0];
var rest = path.slice(1);
var item = null;
for(var j = 0, m = items.length; j < m; j++) {
if(items[j].name === name) {
item = items[j];
break;
for (let e of x) {
let pathElems = e.path.split("/");

for (let i = 0; i < pathElems.length; i++) {
tree.add({
id: pathElems.slice(0, i + 1).join("/"),
parent: i >= 1 ? pathElems.slice(0, i).join("/") : undefined,
label: pathElems[i] + ( i === pathElems.length - 1 ? "&emsp;<tt>" + fileSize(e.size) + "</tt>" : ""),
opened: true,
});
}
}
}
if(item === null) {
item = {name: name, children: []};
items.push(item);
}
if(rest.length > 0) {
item.children.push(rest);
}
}
for(i = 0, l = items.length; i < l; i++) {
item = items[i];
item.children = structurise(item.children);
}
return items;
}


function stringify(items) {
var lines = [];
for(var i = 0, l = items.length; i < l; i++) {
var item = items[i];
lines.push(item.name);
var subLines = stringify(item.children);
for(var j = 0, m = subLines.length; j < m; j++) {
lines.push(" " + subLines[j]);
}
}
return lines;
}
});
});
};
6 changes: 1 addition & 5 deletions cmd/magneticow/data/static/scripts/torrents.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,7 @@ function load() {

for (let t of torrents) {
t.size = fileSize(t.size);
t.discoveredOn = (new Date(t.discoveredOn * 1000)).toLocaleDateString("en-GB", {
day: "2-digit",
month: "2-digit",
year: "numeric"
});
t.discoveredOn = humaniseDate(t.discoveredOn);

ul.innerHTML += Mustache.render(template, t);
}
Expand Down
Loading

0 comments on commit 2cc4c49

Please sign in to comment.