now torrent pages work too!
- Changed the URL structure of torrent pages: Before: /torrents/{{infoHash}}/{{name}} After: /torrents/{{infoHash}}
This commit is contained in:
parent
0501fc3e3c
commit
3a45f17647
@ -56,6 +56,7 @@ func apiTorrentsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: use plain Marshal
|
||||
jm, err := json.MarshalIndent(torrents, "", " ")
|
||||
if err != nil {
|
||||
respondError(w, 500, "json marshalling error: %s", err.Error())
|
||||
|
73
cmd/magneticow/data/static/scripts/naturalSort-v0.8.1.js
Normal file
73
cmd/magneticow/data/static/scripts/naturalSort-v0.8.1.js
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Natural Sort algorithm for Javascript - Version 0.8.1 - Released under MIT license
|
||||
* Author: Jim Palmer (based on chunking idea from Dave Koelle)
|
||||
*
|
||||
* https://github.com/overset/javascript-natural-sort
|
||||
*
|
||||
* Modified by Mert Bora ALPER <bora@boramalper.org> for magnetico.
|
||||
*/
|
||||
function naturalSort (a, b) {
|
||||
/* The following modification makes sure that paths with less levels (i.e. less directories) are
|
||||
* smaller than (or, "comes before") the directories with more levels (i.e. more directories).
|
||||
*
|
||||
* Without Bora's Modification:
|
||||
* >>> ["/aaaa/aaa/aa.html", "/aaaa/bbb.txt"].sort(naturalSort)
|
||||
* ["/aaaa/aaa/aa.html", "/aaaa/bbb.txt"]
|
||||
*
|
||||
* With Bora's Modification:
|
||||
* >>> ["/aaaa/aaa/aa.html", "/aaaa/bbb.txt"].sort(naturalSort)
|
||||
* ["/aaaa/bbb.txt", "/aaaa/aaa/aa.html"]
|
||||
*
|
||||
* <Bora's Modification>
|
||||
*/
|
||||
let aSlashes = a.split("/").length,
|
||||
bSlashes = b.split("/").length;
|
||||
if (aSlashes !== bSlashes)
|
||||
return aSlashes - bSlashes;
|
||||
// </Bora's Modification>
|
||||
|
||||
var re = /(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g,
|
||||
sre = /^\s+|\s+$/g, // trim pre-post whitespace
|
||||
snre = /\s+/g, // normalize all whitespace to single ' ' character
|
||||
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
|
||||
hre = /^0x[0-9a-f]+$/i,
|
||||
ore = /^0/,
|
||||
i = function(s) {
|
||||
return (naturalSort.insensitive && ('' + s).toLowerCase() || '' + s).replace(sre, '');
|
||||
},
|
||||
// convert all to strings strip whitespace
|
||||
x = i(a),
|
||||
y = i(b),
|
||||
// chunk/tokenize
|
||||
xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
|
||||
yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
|
||||
// numeric, hex or date detection
|
||||
xD = parseInt(x.match(hre), 16) || (xN.length !== 1 && Date.parse(x)),
|
||||
yD = parseInt(y.match(hre), 16) || xD && y.match(dre) && Date.parse(y) || null,
|
||||
normChunk = function(s, l) {
|
||||
// normalize spaces; find floats not starting with '0', string or 0 if not defined (Clint Priest)
|
||||
return (!s.match(ore) || l == 1) && parseFloat(s) || s.replace(snre, ' ').replace(sre, '') || 0;
|
||||
},
|
||||
oFxNcL, oFyNcL;
|
||||
// first try and sort Hex codes or Dates
|
||||
if (yD) {
|
||||
if (xD < yD) { return -1; }
|
||||
else if (xD > yD) { return 1; }
|
||||
}
|
||||
// natural sorting through split numeric strings and default strings
|
||||
for(var cLoc = 0, xNl = xN.length, yNl = yN.length, numS = Math.max(xNl, yNl); cLoc < numS; cLoc++) {
|
||||
oFxNcL = normChunk(xN[cLoc] || '', xNl);
|
||||
oFyNcL = normChunk(yN[cLoc] || '', yNl);
|
||||
// handle numeric vs string comparison - number < string - (Kyle Adams)
|
||||
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
|
||||
return isNaN(oFxNcL) ? 1 : -1;
|
||||
}
|
||||
// if unicode use locale comparison
|
||||
if (/[^\x00-\x80]/.test(oFxNcL + oFyNcL) && oFxNcL.localeCompare) {
|
||||
var comp = oFxNcL.localeCompare(oFyNcL);
|
||||
return comp / Math.abs(comp);
|
||||
}
|
||||
if (oFxNcL < oFyNcL) { return -1; }
|
||||
else if (oFxNcL > oFyNcL) { return 1; }
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
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");
|
||||
};
|
||||
|
@ -122,7 +122,7 @@ function encodeQueryData(data) {
|
||||
// https://stackoverflow.com/q/10420352/4466589
|
||||
function fileSize(fileSizeInBytes) {
|
||||
let i = -1;
|
||||
let byteUnits = [' kB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'];
|
||||
let byteUnits = [' KiB', ' MiB', ' GiB', ' TiB', ' PiB', ' EiB', ' ZiB', ' YiB'];
|
||||
do {
|
||||
fileSizeInBytes = fileSizeInBytes / 1024;
|
||||
i++;
|
||||
|
@ -2,11 +2,12 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{ torrent.name }} - magnetico</title>
|
||||
<link rel="stylesheet" href="static/styles/reset.css">
|
||||
<link rel="stylesheet" href="static/styles/essential.css">
|
||||
<link rel="stylesheet" href="static/styles/torrent.css">
|
||||
<script defer src="static/scripts/torrent.js"></script>
|
||||
<title>{{ .T.Name }} - magnetico</title>
|
||||
<link rel="stylesheet" href="/static/styles/reset.css">
|
||||
<link rel="stylesheet" href="/static/styles/essential.css">
|
||||
<link rel="stylesheet" href="/static/styles/torrent.css">
|
||||
<script defer src="/static/scripts/naturalSort-v0.8.1.js"></script>
|
||||
<script defer src="/static/scripts/torrent.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
@ -17,39 +18,32 @@
|
||||
</header>
|
||||
<main>
|
||||
<div id="title">
|
||||
<h2>{{ torrent.name }}</h2>
|
||||
<a href="magnet:?xt=urn:btih:{{ torrent.info_hash }}&dn={{ torrent.name }}">
|
||||
<img src="static/assets/magnet.gif" alt="Magnet link"
|
||||
<h2>{{ .T.Name }}</h2>
|
||||
<a href="magnet:?xt=urn:btih:{{ bytesToHex .T.InfoHash }}&dn={{ .T.Name }}">
|
||||
<img src="/static/assets/magnet.gif" alt="Magnet link"
|
||||
title="Download this torrent using magnet" />
|
||||
<small>{{ torrent.info_hash }}</small>
|
||||
<small>{{ bytesToHex .T.InfoHash }}</small>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th scope="row">Size</th>
|
||||
<td>{{ torrent.size }}</td>
|
||||
<td>{{ humanizeSize .T.Size }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Discovered on</th>
|
||||
<td>{{ torrent.discovered_on }}</td>
|
||||
<td>{{ unixTimeToYearMonthDay .T.DiscoveredOn }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Files</th>
|
||||
<td>{{ torrent.files|length }}</td>
|
||||
<td>{{ .T.NFiles }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Contents</h3>
|
||||
<noscript>
|
||||
<pre>
|
||||
{% for file in torrent.files -%}
|
||||
{{ file.path }}{{ "\n" }}
|
||||
{%- endfor %}
|
||||
</pre>
|
||||
</noscript>
|
||||
<!-- Content of this element will be overwritten by the script -->
|
||||
<pre>{% for file in torrent.files -%}{{ file.path }}{{ "\t" + file.size }}{{ "\n" }}{%- endfor %}</pre>
|
||||
<pre>{{ range .F }}{{ .Path }}{{ "\t" }}{{ humanizeSizeF .Size }}{{ "\n" }}{{ end }}</pre>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
@ -16,7 +16,7 @@
|
||||
<td><a href="magnet:?xt=urn:btih:{{infoHash}}&dn={{name}}">
|
||||
<img src="static/assets/magnet.gif" alt="Magnet link"
|
||||
title="Download this torrent using magnet" /></a></td>
|
||||
<td><a href="/torrents/{{infoHash}}/{{name}}">{{name}}</a></td>
|
||||
<td><a href="/torrents/{{infoHash}}">{{name}}</a></td>
|
||||
<td>{{size}}</td>
|
||||
<td>{{discoveredOn}}</td>
|
||||
</tr>
|
||||
|
@ -126,6 +126,13 @@ func main() {
|
||||
return humanize.IBytes(s)
|
||||
},
|
||||
|
||||
"humanizeSizeF": func(s int64) string {
|
||||
if s < 0 {
|
||||
return ""
|
||||
}
|
||||
return humanize.IBytes(uint64(s))
|
||||
},
|
||||
|
||||
"comma": func(s uint) string {
|
||||
return humanize.Comma(int64(s))
|
||||
},
|
||||
@ -135,7 +142,7 @@ func main() {
|
||||
// templates["feed"] = template.Must(template.New("feed").Parse(string(mustAsset("templates/feed.xml"))))
|
||||
templates["homepage"] = template.Must(template.New("homepage").Funcs(templateFunctions).Parse(string(mustAsset("templates/homepage.html"))))
|
||||
// templates["statistics"] = template.Must(template.New("statistics").Parse(string(mustAsset("templates/statistics.html"))))
|
||||
// templates["torrent"] = template.Must(template.New("torrent").Funcs(templateFunctions).Parse(string(mustAsset("templates/torrent.html"))))
|
||||
templates["torrent"] = template.Must(template.New("torrent").Funcs(templateFunctions).Parse(string(mustAsset("templates/torrent.html"))))
|
||||
// templates["torrents"] = template.Must(template.New("torrents").Funcs(templateFunctions).Parse(string(mustAsset("templates/torrents.html"))))
|
||||
|
||||
var err error
|
||||
@ -182,6 +189,7 @@ func torrentsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
// TODO: we might as well move torrent.html into static...
|
||||
func torrentsInfohashHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// show torrents/{infohash}
|
||||
infoHash, err := hex.DecodeString(mux.Vars(r)["infohash"])
|
||||
@ -193,8 +201,32 @@ func torrentsInfohashHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
if torrent == nil {
|
||||
w.WriteHeader(404)
|
||||
w.Write([]byte("torrent not found!"))
|
||||
return
|
||||
}
|
||||
|
||||
templates["torrent"].Execute(w, torrent)
|
||||
files, err := database.GetFiles(infoHash)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
if files == nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte("files not found what!!!"))
|
||||
return
|
||||
}
|
||||
|
||||
err = templates["torrent"].Execute(w, struct {
|
||||
T *persistence.TorrentMetadata
|
||||
F []persistence.File
|
||||
}{
|
||||
T: torrent,
|
||||
F: files,
|
||||
})
|
||||
if err != nil {
|
||||
panic("error while executing template!")
|
||||
}
|
||||
}
|
||||
|
||||
func statisticsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -330,7 +330,9 @@ func (db *sqlite3Database) GetTorrent(infoHash []byte) (*TorrentMetadata, error)
|
||||
}
|
||||
|
||||
func (db *sqlite3Database) GetFiles(infoHash []byte) ([]File, error) {
|
||||
rows, err := db.conn.Query("SELECT size, path FROM files WHERE torrent_id = ?;", infoHash)
|
||||
rows, err := db.conn.Query(
|
||||
"SELECT size, path FROM files, torrents WHERE files.torrent_id = torrents.id AND torrents.info_hash = ?;",
|
||||
infoHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user