move all viewer scripts to javascript
This commit is contained in:
@@ -8,9 +8,12 @@ type Recaptcha struct {
|
|||||||
// GetRecaptcha gets the reCaptcha site key from the pixelapi server. If
|
// GetRecaptcha gets the reCaptcha site key from the pixelapi server. If
|
||||||
// reCaptcha is disabled the key will be empty
|
// reCaptcha is disabled the key will be empty
|
||||||
func (p *PixelAPI) GetRecaptcha() (resp Recaptcha, err error) {
|
func (p *PixelAPI) GetRecaptcha() (resp Recaptcha, err error) {
|
||||||
err = p.jsonRequest("GET", p.apiEndpoint+"/misc/recaptcha", &resp)
|
return resp, p.jsonRequest("GET", p.apiEndpoint+"/misc/recaptcha", &resp)
|
||||||
if err != nil {
|
}
|
||||||
return resp, err
|
|
||||||
}
|
// GetMiscViewToken requests a viewtoken from the server. The viewtoken is valid
|
||||||
return resp, nil
|
// for a limited amount of time and can be used to add views to a file.
|
||||||
|
// Viewtokens can only be requested from localhost
|
||||||
|
func (p *PixelAPI) GetMiscViewToken() (resp string, err error) {
|
||||||
|
return resp, p.jsonRequest("GET", p.apiEndpoint+"/misc/viewtoken", &resp)
|
||||||
}
|
}
|
||||||
|
@@ -83,7 +83,7 @@ class ListNavigator {
|
|||||||
do {
|
do {
|
||||||
rand = Math.round(Math.random() * ln.length);
|
rand = Math.round(Math.random() * ln.length);
|
||||||
console.log("rand is " + rand);
|
console.log("rand is " + rand);
|
||||||
} while(ln.history.indexOf(index) > -1);
|
} while(ln.history.indexOf(rand) > -1);
|
||||||
|
|
||||||
ln.setItem(rand);
|
ln.setItem(rand);
|
||||||
}
|
}
|
||||||
|
@@ -9,15 +9,17 @@ class Viewer {
|
|||||||
currentFile = "";
|
currentFile = "";
|
||||||
title = ""; // Contains either the file name or list title
|
title = ""; // Contains either the file name or list title
|
||||||
listId = "";
|
listId = "";
|
||||||
|
viewToken = "";
|
||||||
isList = false;
|
isList = false;
|
||||||
isFile = false;
|
isFile = false;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
|
|
||||||
constructor(type, data) {let v = this;
|
constructor(type, viewToken, data) {let v = this;
|
||||||
if(v.initialized){
|
if(v.initialized){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v.viewToken = viewToken;
|
||||||
v.toolbar = new Toolbar(v);
|
v.toolbar = new Toolbar(v);
|
||||||
v.detailsWindow = new DetailsWindow(v);
|
v.detailsWindow = new DetailsWindow(v);
|
||||||
|
|
||||||
@@ -72,32 +74,52 @@ class Viewer {
|
|||||||
// Update the file details
|
// Update the file details
|
||||||
v.detailsWindow.setDetails(file);
|
v.detailsWindow.setDetails(file);
|
||||||
|
|
||||||
|
// Register a new view. We don't care what this returns becasue we can't
|
||||||
|
// do anything about it anyway
|
||||||
|
fetch(apiEndpoint+"/file/"+file.id+"/view",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {"Content-Type": "application/x-www-form-urlencoded"},
|
||||||
|
body: "token="+v.viewToken
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Clear the canvas
|
// Clear the canvas
|
||||||
v.divFilepreview.innerHTML = "";
|
v.divFilepreview.innerHTML = "";
|
||||||
|
|
||||||
if (file.mime_type.startsWith("image")) {
|
let nextItem = () => {
|
||||||
|
if (v.listNavigator !== null) {
|
||||||
|
v.listNavigator.nextItem();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (
|
||||||
|
file.mime_type.startsWith("image")
|
||||||
|
) {
|
||||||
new ImageViewer(v, file).render(v.divFilepreview);
|
new ImageViewer(v, file).render(v.divFilepreview);
|
||||||
} else if (file.mime_type.startsWith("video")) {
|
} else if (
|
||||||
new VideoViewer(v, file, () => {
|
file.mime_type.startsWith("video") ||
|
||||||
if (v.listNavigator !== null) {
|
file.mime_type === "application/matroska" ||
|
||||||
v.listNavigator.nextItem();
|
file.mime_type === "application/x-matroska"
|
||||||
}
|
) {
|
||||||
}).render(v.divFilepreview);
|
new VideoViewer(v, file, nextItem).render(v.divFilepreview);
|
||||||
} else if (file.mime_type.startsWith("audio") || file.mime_type === "application/ogg") {
|
} else if (
|
||||||
new AudioViewer(v, file, () => {
|
file.mime_type.startsWith("audio") ||
|
||||||
if (v.listNavigator !== null) {
|
file.mime_type === "application/ogg"
|
||||||
v.listNavigator.nextItem();
|
) {
|
||||||
}
|
new AudioViewer(v, file, nextItem).render(v.divFilepreview);
|
||||||
}).render(v.divFilepreview);
|
} else if (
|
||||||
|
file.mime_type === "application/pdf" ||
|
||||||
|
file.mime_type === "application/x-pdf"
|
||||||
|
) {
|
||||||
|
new PDFViewer(v, file).render(v.divFilepreview);
|
||||||
|
} else if (
|
||||||
|
file.mime_type.startsWith("text") ||
|
||||||
|
file.id === "demo"
|
||||||
|
) {
|
||||||
|
new TextViewer(v, file).render(v.divFilepreview);
|
||||||
} else {
|
} else {
|
||||||
fetch("/u/"+file.id+"/preview").then(resp => {
|
new FileViewer(v, file).render(v.divFilepreview);
|
||||||
if (!resp.ok) { return Promise.reject(resp.status); }
|
|
||||||
return resp.text();
|
|
||||||
}).then(resp => {
|
|
||||||
v.divFilepreview.innerHTML = resp;
|
|
||||||
}).catch(err => {
|
|
||||||
v.divFilepreview.innerText = "Error loading file: "+err;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,37 +8,37 @@ class AudioViewer {
|
|||||||
element = null;
|
element = null;
|
||||||
source = null;
|
source = null;
|
||||||
|
|
||||||
constructor(viewer, file, next) {let av = this;
|
constructor(viewer, file, next) {let v = this;
|
||||||
av.viewer = viewer;
|
v.viewer = viewer;
|
||||||
av.file = file;
|
v.file = file;
|
||||||
av.next = next;
|
v.next = next;
|
||||||
|
|
||||||
av.container = document.createElement("div");
|
v.container = document.createElement("div");
|
||||||
av.container.classList = "image-container";
|
v.container.classList = "image-container";
|
||||||
av.container.appendChild(document.createElement("br"));
|
v.container.appendChild(document.createElement("br"));
|
||||||
|
|
||||||
av.icon = document.createElement("img");
|
v.icon = document.createElement("img");
|
||||||
av.icon.src = "/res/img/mime/audio.png";
|
v.icon.src = "/res/img/mime/audio.png";
|
||||||
av.container.appendChild(av.icon);
|
v.container.appendChild(v.icon);
|
||||||
|
|
||||||
av.container.appendChild(document.createElement("br"));
|
v.container.appendChild(document.createElement("br"));
|
||||||
av.container.appendChild(document.createTextNode(file.name));
|
v.container.appendChild(document.createTextNode(file.name));
|
||||||
av.container.appendChild(document.createElement("br"));
|
v.container.appendChild(document.createElement("br"));
|
||||||
av.container.appendChild(document.createElement("br"));
|
v.container.appendChild(document.createElement("br"));
|
||||||
|
|
||||||
av.element = document.createElement("audio");
|
v.element = document.createElement("audio");
|
||||||
av.element.autoplay = "autoplay";
|
v.element.autoplay = "autoplay";
|
||||||
av.element.controls = "controls";
|
v.element.controls = "controls";
|
||||||
av.element.style.width = "90%";
|
v.element.style.width = "90%";
|
||||||
av.element.addEventListener("ended", () => { av.next(); }, false);
|
v.element.addEventListener("ended", () => { v.next(); }, false);
|
||||||
|
|
||||||
av.source = document.createElement("source");
|
v.source = document.createElement("source");
|
||||||
av.source.src = apiEndpoint+"/file/"+av.file.id;
|
v.source.src = apiEndpoint+"/file/"+v.file.id;
|
||||||
av.element.appendChild(av.source);
|
v.element.appendChild(v.source);
|
||||||
av.container.appendChild(av.element);
|
v.container.appendChild(v.element);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(parent) {let av = this;
|
render(parent) {let v = this;
|
||||||
parent.appendChild(av.container);
|
parent.appendChild(v.container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
res/include/script/file_viewer/viewer_scripts/FileViewer.js
Normal file
35
res/include/script/file_viewer/viewer_scripts/FileViewer.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
class FileViewer {
|
||||||
|
viewer = null;
|
||||||
|
file = null;
|
||||||
|
|
||||||
|
container = null;
|
||||||
|
icon = null;
|
||||||
|
|
||||||
|
constructor(viewer, file, next) {let v = this;
|
||||||
|
v.viewer = viewer;
|
||||||
|
v.file = file;
|
||||||
|
v.next = next;
|
||||||
|
|
||||||
|
v.container = document.createElement("div");
|
||||||
|
v.container.classList = "image-container";
|
||||||
|
v.container.appendChild(document.createElement("br"));
|
||||||
|
|
||||||
|
v.icon = document.createElement("img");
|
||||||
|
v.icon.src = apiEndpoint+"/"+file.thumbnail_href;
|
||||||
|
v.container.appendChild(v.icon);
|
||||||
|
|
||||||
|
v.container.appendChild(document.createElement("br"));
|
||||||
|
v.container.appendChild(document.createTextNode(file.name));
|
||||||
|
v.container.appendChild(document.createElement("br"));
|
||||||
|
v.container.appendChild(document.createTextNode("Type: "+file.mime_type));
|
||||||
|
v.container.appendChild(document.createElement("br"));
|
||||||
|
v.container.appendChild(document.createElement("br"));
|
||||||
|
v.container.appendChild(document.createTextNode(
|
||||||
|
"Press the 'Download' button in the menu to download this file"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
render(parent) {let v = this;
|
||||||
|
parent.appendChild(v.container);
|
||||||
|
}
|
||||||
|
}
|
@@ -2,54 +2,55 @@ class ImageViewer {
|
|||||||
viewer = null;
|
viewer = null;
|
||||||
file = null;
|
file = null;
|
||||||
|
|
||||||
imgContainer = null;
|
container = null;
|
||||||
imgElement = null;
|
element = null;
|
||||||
|
|
||||||
zoomed = false;
|
zoomed = false;
|
||||||
x = 0;
|
x = 0;
|
||||||
y = 0;
|
y = 0;
|
||||||
dragging = false;
|
dragging = false;
|
||||||
|
|
||||||
constructor(viewer, file) {let iv = this;
|
constructor(viewer, file) {let v = this;
|
||||||
iv.viewer = viewer;
|
v.viewer = viewer;
|
||||||
iv.file = file;
|
v.file = file;
|
||||||
|
|
||||||
iv.imgContainer = document.createElement("div");
|
v.container = document.createElement("dv");
|
||||||
iv.imgContainer.classList = "image-container";
|
v.container.classList = "image-container";
|
||||||
|
// v.container.style.lineHeight = "0";
|
||||||
|
|
||||||
iv.imgElement = document.createElement("img");
|
v.element = document.createElement("img");
|
||||||
iv.imgElement.classList = "pannable drop-shadow";
|
v.element.classList = "pannable center drop-shadow";
|
||||||
iv.imgElement.src = apiEndpoint+"/file/"+iv.file.id;
|
v.element.src = apiEndpoint+"/file/"+v.file.id;
|
||||||
iv.imgElement.addEventListener("mousedown", (e) => { return iv.mousedown(e); });
|
v.element.addEventListener("dblclick", (e) => { return v.doubleclick(e); });
|
||||||
iv.imgElement.addEventListener("dblclick", (e) => { return iv.doubleclick(e); });
|
v.element.addEventListener("doubletap", (e) => { return v.doubleclick(e); });
|
||||||
iv.imgElement.addEventListener("doubletap", (e) => { return iv.doubleclick(e); });
|
v.element.addEventListener("mousedown", (e) => { return v.mousedown(e); });
|
||||||
document.addEventListener("mousemove", (e) => { return iv.mousemove(e); });
|
document.addEventListener("mousemove", (e) => { return v.mousemove(e); });
|
||||||
document.addEventListener("mouseup", (e) => { return iv.mouseup(e); });
|
document.addEventListener("mouseup", (e) => { return v.mouseup(e); });
|
||||||
|
|
||||||
iv.imgContainer.appendChild(iv.imgElement);
|
v.container.appendChild(v.element);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(parent) {let iv = this;
|
render(parent) {let v = this;
|
||||||
parent.appendChild(iv.imgContainer);
|
parent.appendChild(v.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
doubleclick(e) {let iv = this;
|
doubleclick(e) {let v = this;
|
||||||
if (iv.zoomed) {
|
if (v.zoomed) {
|
||||||
iv.imgElement.style.maxWidth = "100%";
|
v.element.style.maxWidth = "100%";
|
||||||
iv.imgElement.style.maxHeight = "100%";
|
v.element.style.maxHeight = "100%";
|
||||||
iv.imgElement.style.top = "50%";
|
v.element.style.top = "50%";
|
||||||
iv.imgElement.style.left = "auto";
|
v.element.style.left = "auto";
|
||||||
iv.imgElement.style.transform = "translateY(-50%)";
|
v.element.style.transform = "translateY(-50%)";
|
||||||
iv.imgContainer.style.overflow = "hidden";
|
v.container.style.overflow = "hidden";
|
||||||
iv.zoomed = false;
|
v.zoomed = false;
|
||||||
} else {
|
} else {
|
||||||
iv.imgElement.style.maxWidth = "none";
|
v.element.style.maxWidth = "none";
|
||||||
iv.imgElement.style.maxHeight = "none";
|
v.element.style.maxHeight = "none";
|
||||||
iv.imgElement.style.top = "0";
|
v.element.style.top = "0";
|
||||||
iv.imgElement.style.left = "";
|
v.element.style.left = "";
|
||||||
iv.imgElement.style.transform = "none";
|
v.element.style.transform = "none";
|
||||||
iv.imgContainer.style.overflow = "scroll";
|
v.container.style.overflow = "scroll";
|
||||||
iv.zoomed = true;
|
v.zoomed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -57,11 +58,11 @@ class ImageViewer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mousedown(e) {let iv = this;
|
mousedown(e) {let v = this;
|
||||||
if (!iv.dragging && e.which === 1 && iv.zoomed) {
|
if (!v.dragging && e.which === 1 && v.zoomed) {
|
||||||
iv.x = e.pageX;
|
v.x = e.pageX;
|
||||||
iv.y = e.pageY;
|
v.y = e.pageY;
|
||||||
iv.dragging = true;
|
v.dragging = true;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -69,13 +70,13 @@ class ImageViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mousemove(e) {let iv = this;
|
mousemove(e) {let v = this;
|
||||||
if (iv.dragging) {
|
if (v.dragging) {
|
||||||
iv.imgContainer.scrollLeft = iv.imgContainer.scrollLeft - (e.pageX - iv.x);
|
v.container.scrollLeft = v.container.scrollLeft - (e.pageX - v.x);
|
||||||
iv.imgContainer.scrollTop = iv.imgContainer.scrollTop - (e.pageY - iv.y);
|
v.container.scrollTop = v.container.scrollTop - (e.pageY - v.y);
|
||||||
|
|
||||||
iv.x = e.pageX;
|
v.x = e.pageX;
|
||||||
iv.y = e.pageY;
|
v.y = e.pageY;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -84,9 +85,9 @@ class ImageViewer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseup(e) {let iv = this;
|
mouseup(e) {let v = this;
|
||||||
if (iv.dragging) {
|
if (v.dragging) {
|
||||||
iv.dragging = false;
|
v.dragging = false;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -94,63 +95,3 @@ class ImageViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// var zoomed = false;
|
|
||||||
// // When a user clicks the image
|
|
||||||
// $("#displayImg").on("dblclick doubletap", function (event) {
|
|
||||||
// if (zoomed) {
|
|
||||||
// $("#displayImg").css("max-width", "100%");
|
|
||||||
// $("#displayImg").css("max-height", "100%");
|
|
||||||
// $("#displayImg").css("top", "50%");
|
|
||||||
// $("#displayImg").css("left", "auto");
|
|
||||||
// $("#displayImg").css("transform", "translateY(-50%)");
|
|
||||||
// $(".image-container").css("overflow", "hidden");
|
|
||||||
// zoomed = false;
|
|
||||||
// } else {
|
|
||||||
// $("#displayImg").css("max-width", "none");
|
|
||||||
// $("#displayImg").css("max-height", "none");
|
|
||||||
// $("#displayImg").css("transform", "none");
|
|
||||||
// $(".pannable").css("top", "0");
|
|
||||||
// $(".image-container").css("overflow", "scroll");
|
|
||||||
// zoomed = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// return false;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// Image dragging around the screen
|
|
||||||
|
|
||||||
// var drag = {
|
|
||||||
// x: 0,
|
|
||||||
// y: 0,
|
|
||||||
// state: false
|
|
||||||
// };
|
|
||||||
|
|
||||||
// $(".pannable").on("mousedown", function (e) {
|
|
||||||
// if (!drag.state && e.which === 1 && zoomed) {
|
|
||||||
// drag.x = e.pageX;
|
|
||||||
// drag.y = e.pageY;
|
|
||||||
// drag.state = true;
|
|
||||||
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// var img = $(".image-container");
|
|
||||||
|
|
||||||
// $(document).on("mousemove", function (e) {
|
|
||||||
// if (drag.state) {
|
|
||||||
// img.scrollLeft(img.scrollLeft() - (e.pageX - drag.x));
|
|
||||||
// img.scrollTop(img.scrollTop() - (e.pageY - drag.y));
|
|
||||||
|
|
||||||
// drag.x = e.pageX;
|
|
||||||
// drag.y = e.pageY;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// $(document).on("mouseup", function () {
|
|
||||||
// if (drag.state) {
|
|
||||||
// drag.state = false;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
19
res/include/script/file_viewer/viewer_scripts/PDFViewer.js
Normal file
19
res/include/script/file_viewer/viewer_scripts/PDFViewer.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
class PDFViewer {
|
||||||
|
viewer = null;
|
||||||
|
file = null;
|
||||||
|
container = null;
|
||||||
|
|
||||||
|
constructor(viewer, file) {let v = this;
|
||||||
|
v.viewer = viewer;
|
||||||
|
v.file = file;
|
||||||
|
|
||||||
|
v.container = document.createElement("iframe");
|
||||||
|
v.container.classList = "image-container";
|
||||||
|
v.container.style.border = "none";
|
||||||
|
v.container.src = "/res/misc/pdf-viewer/web/viewer.html?file="+apiEndpoint+"/file/"+file.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(parent) {let v = this;
|
||||||
|
parent.appendChild(v.container);
|
||||||
|
}
|
||||||
|
}
|
63
res/include/script/file_viewer/viewer_scripts/TextViewer.js
Normal file
63
res/include/script/file_viewer/viewer_scripts/TextViewer.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
class TextViewer {
|
||||||
|
viewer = null;
|
||||||
|
file = null;
|
||||||
|
|
||||||
|
container = null;
|
||||||
|
pre = null;
|
||||||
|
prettyprint = null;
|
||||||
|
|
||||||
|
constructor(viewer, file) {let v = this;
|
||||||
|
v.viewer = viewer;
|
||||||
|
v.file = file;
|
||||||
|
|
||||||
|
v.container = document.createElement("div");
|
||||||
|
v.container.classList = "text-container";
|
||||||
|
|
||||||
|
if (file.name.endsWith(".md") || file.name.endsWith(".markdown") || file.id === "demo") {
|
||||||
|
v.getMarkdown();
|
||||||
|
} else {
|
||||||
|
v.getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getText() {let v = this;
|
||||||
|
v.pre = document.createElement("pre");
|
||||||
|
v.pre.classList = "pre-container prettyprint linenums";
|
||||||
|
v.pre.innerText = "Loading...";
|
||||||
|
v.container.appendChild(v.pre);
|
||||||
|
|
||||||
|
if (v.file.size > 1<<22) { // File larger than 4 MiB
|
||||||
|
v.pre.innerText = "File is too large to view online.\nPlease download and view it locally.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(apiEndpoint+"/file/"+v.file.id).then(resp => {
|
||||||
|
if (!resp.ok) { return Promise.reject(resp.status); }
|
||||||
|
return resp.text();
|
||||||
|
}).then(resp => {
|
||||||
|
v.pre.innerText = resp;
|
||||||
|
|
||||||
|
// Load prettyprint script
|
||||||
|
v.prettyprint = document.createElement("script");
|
||||||
|
v.prettyprint.src = "https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert";
|
||||||
|
v.container.appendChild(v.prettyprint);
|
||||||
|
}).catch(err => {
|
||||||
|
v.pre.innerText = "Error loading file: "+err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getMarkdown() {let v = this;
|
||||||
|
fetch("/u/"+v.file.id+"/preview").then(resp => {
|
||||||
|
if (!resp.ok) { return Promise.reject(resp.status); }
|
||||||
|
return resp.text();
|
||||||
|
}).then(resp => {
|
||||||
|
v.container.innerHTML = resp;
|
||||||
|
}).catch(err => {
|
||||||
|
v.container.innerText = "Error loading file: "+err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render(parent) {let v = this;
|
||||||
|
parent.appendChild(v.container);
|
||||||
|
}
|
||||||
|
}
|
@@ -7,28 +7,28 @@ class VideoViewer {
|
|||||||
vidElement = null;
|
vidElement = null;
|
||||||
videoSource = null;
|
videoSource = null;
|
||||||
|
|
||||||
constructor(viewer, file, next) {let vv = this;
|
constructor(viewer, file, next) {let v = this;
|
||||||
vv.viewer = viewer;
|
v.viewer = viewer;
|
||||||
vv.file = file;
|
v.file = file;
|
||||||
vv.next = next;
|
v.next = next;
|
||||||
|
|
||||||
vv.vidContainer = document.createElement("div");
|
v.vidContainer = document.createElement("div");
|
||||||
vv.vidContainer.classList = "image-container";
|
v.vidContainer.classList = "image-container";
|
||||||
|
|
||||||
vv.vidElement = document.createElement("video");
|
v.vidElement = document.createElement("video");
|
||||||
vv.vidElement.autoplay = "autoplay";
|
v.vidElement.autoplay = "autoplay";
|
||||||
vv.vidElement.controls = "controls";
|
v.vidElement.controls = "controls";
|
||||||
vv.vidElement.classList = "center drop-shadow";
|
v.vidElement.classList = "center drop-shadow";
|
||||||
vv.vidElement.addEventListener("ended", () => { vv.next(); }, false);
|
v.vidElement.addEventListener("ended", () => { v.next(); }, false);
|
||||||
|
|
||||||
vv.videoSource = document.createElement("source");
|
v.videoSource = document.createElement("source");
|
||||||
vv.videoSource.src = apiEndpoint+"/file/"+vv.file.id;
|
v.videoSource.src = apiEndpoint+"/file/"+v.file.id;
|
||||||
|
|
||||||
vv.vidElement.appendChild(vv.videoSource);
|
v.vidElement.appendChild(v.videoSource);
|
||||||
vv.vidContainer.appendChild(vv.vidElement);
|
v.vidContainer.appendChild(v.vidElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(parent) {let vv = this;
|
render(parent) {let v = this;
|
||||||
parent.appendChild(vv.vidContainer);
|
parent.appendChild(v.vidContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -154,20 +154,13 @@
|
|||||||
=====================*/
|
=====================*/
|
||||||
.image-container{
|
.image-container{
|
||||||
position: relative;
|
position: relative;
|
||||||
|
display: block;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image{
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
margin: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-container{
|
.text-container{
|
||||||
background: #333 none;
|
background: #333 none;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -184,17 +177,6 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pannable{
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
margin: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
cursor: move;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.center{
|
.center{
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -205,9 +187,8 @@
|
|||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.drop-shadow{
|
.pannable{ cursor: move; }
|
||||||
box-shadow: var(--shadow_color) 10px 10px 50px;
|
.drop-shadow{ box-shadow: var(--shadow_color) 10px 10px 50px; }
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================
|
/* ========================
|
||||||
|| TOOLBAR COMPONENTS ||
|
|| TOOLBAR COMPONENTS ||
|
||||||
|
@@ -92,7 +92,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="filepreview" class="file_viewer_file_preview">
|
<div id="filepreview" class="file_viewer_file_preview">
|
||||||
<div class="image" style="margin-top: 20%; width: 100px; height: 100px;">{{template "spinner.svg" .}}</div>
|
<div class="center" style="width: 100px; height: 100px;">{{template "spinner.svg" .}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="sponsors" class="sponsors">
|
<div id="sponsors" class="sponsors">
|
||||||
@@ -163,11 +163,14 @@
|
|||||||
{{template `ImageViewer.js`}}
|
{{template `ImageViewer.js`}}
|
||||||
{{template `VideoViewer.js`}}
|
{{template `VideoViewer.js`}}
|
||||||
{{template `AudioViewer.js`}}
|
{{template `AudioViewer.js`}}
|
||||||
|
{{template `PDFViewer.js`}}
|
||||||
|
{{template `TextViewer.js`}}
|
||||||
|
{{template `FileViewer.js`}}
|
||||||
|
|
||||||
// This info gets filled in on the server side to prevent having to make an API call right after the page loads.
|
// This info gets filled in on the server side to prevent having to make an API call right after the page loads.
|
||||||
// Just to slice another few milliseconds from the load time :)
|
// Just to slice another few milliseconds from the load time :)
|
||||||
window.addEventListener("load", function(){
|
window.addEventListener("load", function(){
|
||||||
new Viewer('{{.Other.Type}}', {{.Other.APIResponse}});
|
new Viewer('{{.Other.Type}}', '{{.Other.ViewToken}}', {{.Other.APIResponse}});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -1,13 +1,9 @@
|
|||||||
package webcontroller
|
package webcontroller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"html"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"fornaxian.com/pixeldrain-api/util"
|
"fornaxian.com/pixeldrain-api/util"
|
||||||
@@ -16,7 +12,6 @@ import (
|
|||||||
"github.com/microcosm-cc/bluemonday"
|
"github.com/microcosm-cc/bluemonday"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"github.com/timakin/gonvert"
|
|
||||||
|
|
||||||
"gopkg.in/russross/blackfriday.v2"
|
"gopkg.in/russross/blackfriday.v2"
|
||||||
)
|
)
|
||||||
@@ -57,176 +52,34 @@ func (f filePreview) run(inf *pixelapi.FileInfo) string {
|
|||||||
f.FileURL = f.APIURL + "/file/" + f.FileInfo.ID
|
f.FileURL = f.APIURL + "/file/" + f.FileInfo.ID
|
||||||
f.DownloadURL = f.APIURL + "/file/" + f.FileInfo.ID + "?download"
|
f.DownloadURL = f.APIURL + "/file/" + f.FileInfo.ID + "?download"
|
||||||
|
|
||||||
if strings.HasPrefix(f.FileInfo.MimeType, "image") {
|
if strings.HasPrefix(f.FileInfo.MimeType, "text") &&
|
||||||
return f.image()
|
(strings.HasSuffix(f.FileInfo.Name, ".md") || strings.HasSuffix(f.FileInfo.Name, ".markdown")) {
|
||||||
} else if strings.HasPrefix(f.FileInfo.MimeType, "video") {
|
return f.markdown()
|
||||||
return f.video()
|
|
||||||
} else if strings.HasPrefix(f.FileInfo.MimeType, "audio") {
|
|
||||||
return f.audio()
|
|
||||||
} else if strings.HasPrefix(f.FileInfo.MimeType, "text") {
|
|
||||||
if strings.HasSuffix(f.FileInfo.Name, ".md") || strings.HasSuffix(f.FileInfo.Name, ".markdown") {
|
|
||||||
return f.markdown()
|
|
||||||
}
|
|
||||||
return f.text()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch f.FileInfo.MimeType {
|
|
||||||
case
|
|
||||||
"application/ogg":
|
|
||||||
return f.audio()
|
|
||||||
case
|
|
||||||
"application/matroska",
|
|
||||||
"application/x-matroska":
|
|
||||||
return f.video()
|
|
||||||
case
|
|
||||||
"application/pdf",
|
|
||||||
"application/x-pdf":
|
|
||||||
return f.pdf()
|
|
||||||
case
|
|
||||||
"application/octet-stream": // Fallback for when mime type not recognized
|
|
||||||
switch filepath.Ext(f.FileInfo.Name) {
|
|
||||||
case
|
|
||||||
".mp3":
|
|
||||||
return f.audio()
|
|
||||||
case
|
|
||||||
".mp4":
|
|
||||||
return f.video()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// none of the mime type checks triggered, so we return the default page
|
// none of the mime type checks triggered, so we return the default page
|
||||||
return f.def()
|
return ""
|
||||||
}
|
|
||||||
|
|
||||||
func (f filePreview) image() string {
|
|
||||||
return fmt.Sprintf(`<div class="image-container">
|
|
||||||
<img id="displayImg" src="%s" class="pannable drop-shadow"/>
|
|
||||||
</div>
|
|
||||||
<script src="/res/viewer-scripts/image.js"></script>`,
|
|
||||||
f.FileURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f filePreview) audio() string {
|
|
||||||
return fmt.Sprintf(`<div class="image-container">
|
|
||||||
<br/>
|
|
||||||
<img src="/res/img/mime/audio.png" alt="Audio"/>
|
|
||||||
<br/>%s<br/>
|
|
||||||
<audio id="audioPlayer" controls="controls" autoplay="autoplay" style="width:90%%;">
|
|
||||||
<source src="%s" />
|
|
||||||
</audio>
|
|
||||||
</div>
|
|
||||||
<script src="/res/viewer-scripts/audio.js"></script>`,
|
|
||||||
f.FileInfo.Name,
|
|
||||||
f.FileURL,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f filePreview) video() string {
|
|
||||||
return fmt.Sprintf(`<div class="image-container">
|
|
||||||
<video id="videoPlayer" autoplay="autoplay" controls="controls" class="center drop-shadow">
|
|
||||||
<source src="%s"/>
|
|
||||||
Your web browser does not support the HTML video tag.
|
|
||||||
</video>
|
|
||||||
</div>
|
|
||||||
<script src="/res/viewer-scripts/video.js"></script>`,
|
|
||||||
f.FileURL,
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f filePreview) pdf() string {
|
|
||||||
u, _ := url.Parse(f.FileURL)
|
|
||||||
return f.frame("/res/misc/pdf-viewer/web/viewer.html?file=" + u.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f filePreview) text() string {
|
|
||||||
htmlOut := `<div class="text-container">
|
|
||||||
<pre class="pre-container %s" style="width: 100%%;">%s</pre>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
if f.FileInfo.Size > 1<<22 { // 4 MiB limit to prevent out of memory errors
|
|
||||||
return fmt.Sprintf(htmlOut, "",
|
|
||||||
"File is too large to view online.\nPlease download and view it locally.",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := f.PixelAPI.GetFile(f.FileInfo.ID)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Can't download text file for preview: %s", err)
|
|
||||||
return fmt.Sprintf(htmlOut, "",
|
|
||||||
"An error occurred while downloading this file.",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
defer body.Close()
|
|
||||||
|
|
||||||
bodyBytes, err := ioutil.ReadAll(body)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Can't read text file for preview: %s", err)
|
|
||||||
return fmt.Sprintf(htmlOut, "",
|
|
||||||
"An error occurred while reading this file.",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
converter := gonvert.New(string(bodyBytes), gonvert.UTF8)
|
|
||||||
result, err := converter.Convert()
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("Unable to decode text file: %s", err)
|
|
||||||
return fmt.Sprintf(htmlOut, "",
|
|
||||||
"This file is using an unknown character encoding.\nPlease download it and view it locally.",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
htmlOut += `<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"></script>`
|
|
||||||
|
|
||||||
return fmt.Sprintf(htmlOut, "prettyprint linenums", html.EscapeString(result))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f filePreview) markdown() string {
|
func (f filePreview) markdown() string {
|
||||||
htmlOut := `<div class="text-container">%s</div>`
|
|
||||||
|
|
||||||
if f.FileInfo.Size > 1e6 { // Prevent out of memory errors
|
if f.FileInfo.Size > 1e6 { // Prevent out of memory errors
|
||||||
return fmt.Sprintf(htmlOut, "",
|
return "File is too large to view online.\nPlease download and view it locally."
|
||||||
"File is too large to view online.\nPlease download and view it locally.",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := f.PixelAPI.GetFile(f.FileInfo.ID)
|
body, err := f.PixelAPI.GetFile(f.FileInfo.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Can't download text file for preview: %s", err)
|
log.Error("Can't download text file for preview: %s", err)
|
||||||
return fmt.Sprintf(htmlOut, "",
|
return "An error occurred while downloading this file."
|
||||||
"An error occurred while downloading this file.",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
defer body.Close()
|
defer body.Close()
|
||||||
|
|
||||||
bodyBytes, err := ioutil.ReadAll(body)
|
bodyBytes, err := ioutil.ReadAll(body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Can't read text file for preview: %s", err)
|
log.Error("Can't read text file for preview: %s", err)
|
||||||
return fmt.Sprintf(htmlOut, "",
|
return "An error occurred while reading this file."
|
||||||
"An error occurred while reading this file.",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
md := bluemonday.UGCPolicy().SanitizeBytes(blackfriday.Run(bodyBytes))
|
return string(bluemonday.UGCPolicy().SanitizeBytes(blackfriday.Run(bodyBytes)))
|
||||||
|
|
||||||
return fmt.Sprintf(htmlOut, md)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f filePreview) frame(url string) string {
|
|
||||||
return fmt.Sprintf(`<iframe src="%s" class="image-container"
|
|
||||||
seamless="seamless" frameborder="0" allowtransparency="true"
|
|
||||||
</iframe>`,
|
|
||||||
url,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f filePreview) def() string {
|
|
||||||
return fmt.Sprintf(
|
|
||||||
`<br/><img src="%s" class="image"><br/>%s<br/>Type: '%s'`,
|
|
||||||
f.APIURL+f.FileInfo.ThumbnailHREF,
|
|
||||||
f.FileInfo.Name,
|
|
||||||
f.FileInfo.MimeType,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeFilePreviewDemo serves the content of the demo file. It contains a nice
|
// ServeFilePreviewDemo serves the content of the demo file. It contains a nice
|
||||||
@@ -234,8 +87,7 @@ func (f filePreview) def() string {
|
|||||||
// categorize the website.
|
// categorize the website.
|
||||||
func serveFilePreviewDemo(w http.ResponseWriter) {
|
func serveFilePreviewDemo(w http.ResponseWriter) {
|
||||||
io.WriteString(w,
|
io.WriteString(w,
|
||||||
`<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"></script>
|
`<pre style="line-height: 1em;">
|
||||||
<div class="text-container"><pre class="pre-container linenums" style="width: 100%">
|
|
||||||
, __ _
|
, __ _
|
||||||
/|/ \o | | | o
|
/|/ \o | | | o
|
||||||
|___/ _ | | __| ,_ __, _ _
|
|___/ _ | | __| ,_ __, _ _
|
||||||
@@ -249,5 +101,5 @@ The website automatically detects what kind of file you requested and prepares a
|
|||||||
Pixeldrain is a free service for sharing files with large or small groups of people. For more information visit the home page by pressing the home button on the toolbar at the left side of the screen.
|
Pixeldrain is a free service for sharing files with large or small groups of people. For more information visit the home page by pressing the home button on the toolbar at the left side of the screen.
|
||||||
|
|
||||||
Press the Details button or "i" for more info about pixeldrain's file viewer.
|
Press the Details button or "i" for more info about pixeldrain's file viewer.
|
||||||
</pre></div>`)
|
</pre>`)
|
||||||
}
|
}
|
||||||
|
@@ -1,46 +0,0 @@
|
|||||||
package webcontroller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"fornaxian.com/pixeldrain-web/pixelapi"
|
|
||||||
|
|
||||||
"github.com/Fornaxian/log"
|
|
||||||
"github.com/julienschmidt/httprouter"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ServeListViewer controller for GET /l/:id
|
|
||||||
func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|
||||||
var api = pixelapi.New(wc.apiURLInternal, "")
|
|
||||||
var list, err = api.GetList(p.ByName("id"))
|
|
||||||
var templateData = wc.newTemplateData(w, r)
|
|
||||||
if err != nil {
|
|
||||||
if err, ok := err.(pixelapi.Error); ok && err.ReqError {
|
|
||||||
log.Error("API request error occurred: %s", err.Value)
|
|
||||||
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
wc.templates.Get().ExecuteTemplate(w, "list_not_found", templateData)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
templateData.Title = fmt.Sprintf("%s ~ pixeldrain", list.Title)
|
|
||||||
templateData.OGData = metadataFromList(*list)
|
|
||||||
templateData.Other = viewerData{
|
|
||||||
Type: "list",
|
|
||||||
CaptchaKey: wc.captchaSiteKey,
|
|
||||||
APIResponse: map[string]interface{}{
|
|
||||||
"id": list.ID,
|
|
||||||
"data": list.Files,
|
|
||||||
"date_created": list.DateCreated,
|
|
||||||
"title": list.Title,
|
|
||||||
"views": 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err = wc.templates.Get().ExecuteTemplate(w, "file_viewer", templateData)
|
|
||||||
if err != nil && !strings.Contains(err.Error(), "broken pipe") {
|
|
||||||
log.Error("Error executing template file_viewer: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -10,14 +10,24 @@ import (
|
|||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func viewTokenOrBust(api *pixelapi.PixelAPI) (t string) {
|
||||||
|
var err error
|
||||||
|
if t, err = api.GetMiscViewToken(); err != nil {
|
||||||
|
log.Error("Could not get viewtoken: %s", err)
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
type viewerData struct {
|
type viewerData struct {
|
||||||
Type string // file or list
|
Type string // file or list
|
||||||
CaptchaKey string
|
CaptchaKey string
|
||||||
|
ViewToken string
|
||||||
APIResponse interface{}
|
APIResponse interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeFileViewer controller for GET /u/:id
|
// ServeFileViewer controller for GET /u/:id
|
||||||
func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
|
var err error
|
||||||
if p.ByName("id") == "demo" {
|
if p.ByName("id") == "demo" {
|
||||||
wc.serveFileViewerDemo(w, r) // Required for a-ads.com quality check
|
wc.serveFileViewerDemo(w, r) // Required for a-ads.com quality check
|
||||||
return
|
return
|
||||||
@@ -32,18 +42,17 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
|||||||
ids = append(ids, p.ByName("id"))
|
ids = append(ids, p.ByName("id"))
|
||||||
}
|
}
|
||||||
|
|
||||||
var api = pixelapi.New(wc.apiURLInternal, "")
|
templateData := wc.newTemplateData(w, r)
|
||||||
|
|
||||||
var finfo []*pixelapi.FileInfo
|
var finfo []*pixelapi.FileInfo
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
inf, err := api.GetFileInfo(id, "")
|
inf, err := templateData.PixelAPI.GetFileInfo(id, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
finfo = append(finfo, inf)
|
finfo = append(finfo, inf)
|
||||||
}
|
}
|
||||||
|
|
||||||
templateData := wc.newTemplateData(w, r)
|
|
||||||
|
|
||||||
if len(finfo) == 0 {
|
if len(finfo) == 0 {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
wc.templates.Get().ExecuteTemplate(w, "file_not_found", templateData)
|
wc.templates.Get().ExecuteTemplate(w, "file_not_found", templateData)
|
||||||
@@ -51,12 +60,12 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
|||||||
}
|
}
|
||||||
|
|
||||||
templateData.OGData = metadataFromFile(*finfo[0])
|
templateData.OGData = metadataFromFile(*finfo[0])
|
||||||
var err error
|
|
||||||
if list {
|
if list {
|
||||||
templateData.Title = fmt.Sprintf("%d files on pixeldrain", len(finfo))
|
templateData.Title = fmt.Sprintf("%d files on pixeldrain", len(finfo))
|
||||||
templateData.Other = viewerData{
|
templateData.Other = viewerData{
|
||||||
Type: "list",
|
Type: "list",
|
||||||
CaptchaKey: wc.captchaKey(),
|
CaptchaKey: wc.captchaKey(),
|
||||||
|
ViewToken: viewTokenOrBust(templateData.PixelAPI),
|
||||||
APIResponse: map[string]interface{}{
|
APIResponse: map[string]interface{}{
|
||||||
"data": finfo,
|
"data": finfo,
|
||||||
"date_created": "now",
|
"date_created": "now",
|
||||||
@@ -70,6 +79,7 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
|||||||
templateData.Other = viewerData{
|
templateData.Other = viewerData{
|
||||||
Type: "file",
|
Type: "file",
|
||||||
CaptchaKey: wc.captchaKey(),
|
CaptchaKey: wc.captchaKey(),
|
||||||
|
ViewToken: viewTokenOrBust(templateData.PixelAPI),
|
||||||
APIResponse: finfo[0],
|
APIResponse: finfo[0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,3 +116,38 @@ func (wc *WebController) serveFileViewerDemo(w http.ResponseWriter, r *http.Requ
|
|||||||
log.Error("Error rendering demo file: %s", err)
|
log.Error("Error rendering demo file: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServeListViewer controller for GET /l/:id
|
||||||
|
func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
|
var api = pixelapi.New(wc.apiURLInternal, "")
|
||||||
|
var list, err = api.GetList(p.ByName("id"))
|
||||||
|
var templateData = wc.newTemplateData(w, r)
|
||||||
|
if err != nil {
|
||||||
|
if err, ok := err.(pixelapi.Error); ok && err.ReqError {
|
||||||
|
log.Error("API request error occurred: %s", err.Value)
|
||||||
|
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
wc.templates.Get().ExecuteTemplate(w, "list_not_found", templateData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
templateData.Title = fmt.Sprintf("%s ~ pixeldrain", list.Title)
|
||||||
|
templateData.OGData = metadataFromList(*list)
|
||||||
|
templateData.Other = viewerData{
|
||||||
|
Type: "list",
|
||||||
|
CaptchaKey: wc.captchaSiteKey,
|
||||||
|
ViewToken: viewTokenOrBust(templateData.PixelAPI),
|
||||||
|
APIResponse: map[string]interface{}{
|
||||||
|
"id": list.ID,
|
||||||
|
"data": list.Files,
|
||||||
|
"date_created": list.DateCreated,
|
||||||
|
"title": list.Title,
|
||||||
|
"views": 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = wc.templates.Get().ExecuteTemplate(w, "file_viewer", templateData)
|
||||||
|
if err != nil && !strings.Contains(err.Error(), "broken pipe") {
|
||||||
|
log.Error("Error executing template file_viewer: %s", err)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user