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

Commit 2cc4c49

Browse files
committed
[magneticow] fully client-side rendering + better file tree + API fixes
1 parent 75abc0e commit 2cc4c49

File tree

12 files changed

+444
-180
lines changed

12 files changed

+444
-180
lines changed

cmd/magneticow/api.go

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"go.uber.org/zap"
1414
)
1515

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

73+
if tq.Limit == nil {
74+
tq.Limit = new(uint)
75+
*tq.Limit = 20
76+
}
77+
7278
torrents, err := database.QueryTorrents(
7379
*tq.Query, *tq.Epoch, orderBy,
74-
*tq.Ascending, N_TORRENTS, tq.LastOrderedValue, tq.LastID)
80+
*tq.Ascending, *tq.Limit, tq.LastOrderedValue, tq.LastID)
7581
if err != nil {
7682
respondError(w, 400, "query error: %s", err.Error())
7783
return
7884
}
7985

80-
// TODO: use plain Marshal
81-
jm, err := json.MarshalIndent(torrents, "", " ")
82-
if err != nil {
83-
respondError(w, 500, "json marshalling error: %s", err.Error())
84-
return
85-
}
86-
87-
if _, err = w.Write(jm); err != nil {
88-
zap.L().Warn("couldn't write http.ResponseWriter", zap.Error(err))
86+
w.Header().Set("Content-Type", "application/json; charset=utf-8")
87+
if err = json.NewEncoder(w).Encode(torrents); err != nil {
88+
zap.L().Warn("JSON encode error", zap.Error(err))
8989
}
9090
}
9191

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

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

110-
// TODO: use plain Marshal
111-
jm, err := json.MarshalIndent(torrent, "", " ")
112-
if err != nil {
113-
respondError(w, 500, "json marshalling error: %s", err.Error())
114-
return
115-
}
116-
117-
if _, err = w.Write(jm); err != nil {
118-
zap.L().Warn("couldn't write http.ResponseWriter", zap.Error(err))
110+
w.Header().Set("Content-Type", "application/json; charset=utf-8")
111+
if err = json.NewEncoder(w).Encode(torrent); err != nil {
112+
zap.L().Warn("JSON encode error", zap.Error(err))
119113
}
120114
}
121115

122-
func apiFilesInfohashHandler(w http.ResponseWriter, r *http.Request) {
116+
func apiFilelist(w http.ResponseWriter, r *http.Request) {
123117
infohashHex := mux.Vars(r)["infohash"]
124118

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

140-
// TODO: use plain Marshal
141-
jm, err := json.MarshalIndent(files, "", " ")
142-
if err != nil {
143-
respondError(w, 500, "json marshalling error: %s", err.Error())
144-
return
145-
}
146-
147-
if _, err = w.Write(jm); err != nil {
148-
zap.L().Warn("couldn't write http.ResponseWriter", zap.Error(err))
134+
w.Header().Set("Content-Type", "application/json; charset=utf-8")
135+
if err = json.NewEncoder(w).Encode(files); err != nil {
136+
zap.L().Warn("JSON encode error", zap.Error(err))
149137
}
150138
}
151139

152-
func apiStatisticsHandler(w http.ResponseWriter, r *http.Request) {
140+
func apiStatistics(w http.ResponseWriter, r *http.Request) {
153141
from := r.URL.Query().Get("from")
154142

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

178-
// TODO: use plain Marshal
179-
jm, err := json.MarshalIndent(stats, "", " ")
180-
if err != nil {
181-
respondError(w, 500, "json marshalling error: %s", err.Error())
182-
return
183-
}
184-
185-
if _, err = w.Write(jm); err != nil {
186-
zap.L().Warn("couldn't write http.ResponseWriter", zap.Error(err))
166+
w.Header().Set("Content-Type", "application/json; charset=utf-8")
167+
if err = json.NewEncoder(w).Encode(stats); err != nil {
168+
zap.L().Warn("JSON encode error", zap.Error(err))
187169
}
188170
}
189171

cmd/magneticow/data/static/scripts/common.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ function fileSize(fileSizeInBytes) {
2424
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
2525
}
2626

27+
function humaniseDate(unixTime) {
28+
return (new Date(unixTime * 1000)).toLocaleDateString("en-GB", {
29+
day: "2-digit",
30+
month: "2-digit",
31+
year: "numeric"
32+
});
33+
}
34+
2735
/**
2836
* Returns the ISO 8601 week number for this date.
2937
*

cmd/magneticow/data/static/scripts/torrent.js

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,52 +9,37 @@
99

1010

1111
window.onload = function() {
12-
var pre_element = document.getElementsByTagName("pre")[0];
13-
var paths = pre_element.textContent.replace(/\s+$/, "").split("\n");
14-
paths.sort(naturalSort);
15-
paths = paths.map(function(path) { return path.split('/'); });
16-
pre_element.textContent = stringify(structurise(paths)).join("\n");
17-
};
12+
let infoHash = window.location.pathname.split("/")[2];
13+
14+
fetch("/api/v0.1/torrents/" + infoHash).then(x => x.json()).then(x => {
15+
document.querySelector("title").innerText = x.name + " - magneticow";
16+
17+
const template = document.getElementById("main-template").innerHTML;
18+
document.querySelector("main").innerHTML = Mustache.render(template, {
19+
name: x.name,
20+
infoHash: x.infoHash,
21+
sizeHumanised: fileSize(x.size),
22+
discoveredOnHumanised: humaniseDate(x.discoveredOn),
23+
nFiles: x.nFiles,
24+
});
1825

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

20-
function structurise(paths) {
21-
var items = [];
22-
for(var i = 0, l = paths.length; i < l; i++) {
23-
var path = paths[i];
24-
var name = path[0];
25-
var rest = path.slice(1);
26-
var item = null;
27-
for(var j = 0, m = items.length; j < m; j++) {
28-
if(items[j].name === name) {
29-
item = items[j];
30-
break;
31+
for (let e of x) {
32+
let pathElems = e.path.split("/");
33+
34+
for (let i = 0; i < pathElems.length; i++) {
35+
tree.add({
36+
id: pathElems.slice(0, i + 1).join("/"),
37+
parent: i >= 1 ? pathElems.slice(0, i).join("/") : undefined,
38+
label: pathElems[i] + ( i === pathElems.length - 1 ? "&emsp;<tt>" + fileSize(e.size) + "</tt>" : ""),
39+
opened: true,
40+
});
41+
}
3142
}
32-
}
33-
if(item === null) {
34-
item = {name: name, children: []};
35-
items.push(item);
36-
}
37-
if(rest.length > 0) {
38-
item.children.push(rest);
39-
}
40-
}
41-
for(i = 0, l = items.length; i < l; i++) {
42-
item = items[i];
43-
item.children = structurise(item.children);
44-
}
45-
return items;
46-
}
47-
48-
49-
function stringify(items) {
50-
var lines = [];
51-
for(var i = 0, l = items.length; i < l; i++) {
52-
var item = items[i];
53-
lines.push(item.name);
54-
var subLines = stringify(item.children);
55-
for(var j = 0, m = subLines.length; j < m; j++) {
56-
lines.push(" " + subLines[j]);
57-
}
58-
}
59-
return lines;
60-
}
43+
});
44+
});
45+
};

cmd/magneticow/data/static/scripts/torrents.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,7 @@ function load() {
104104

105105
for (let t of torrents) {
106106
t.size = fileSize(t.size);
107-
t.discoveredOn = (new Date(t.discoveredOn * 1000)).toLocaleDateString("en-GB", {
108-
day: "2-digit",
109-
month: "2-digit",
110-
year: "numeric"
111-
});
107+
t.discoveredOn = humaniseDate(t.discoveredOn);
112108

113109
ul.innerHTML += Mustache.render(template, t);
114110
}

0 commit comments

Comments
 (0)