Download and view graphs
This commit is contained in:
7
res/static/misc/chartjs/Chart.bundle.min.js
vendored
Normal file
7
res/static/misc/chartjs/Chart.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
res/static/misc/chartjs/Chart.min.js
vendored
Normal file
7
res/static/misc/chartjs/Chart.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -173,6 +173,7 @@ function loadCaptcha(){
|
|||||||
|
|
||||||
var DetailsWindow = {
|
var DetailsWindow = {
|
||||||
visible: false,
|
visible: false,
|
||||||
|
fileID: "",
|
||||||
popupDiv: document.getElementById("details_popup"),
|
popupDiv: document.getElementById("details_popup"),
|
||||||
detailsButton: document.getElementById("btnDetails"),
|
detailsButton: document.getElementById("btnDetails"),
|
||||||
toggle: function () {
|
toggle: function () {
|
||||||
@@ -186,6 +187,7 @@ var DetailsWindow = {
|
|||||||
this.popupDiv.style.visibility = "visible"
|
this.popupDiv.style.visibility = "visible"
|
||||||
this.detailsButton.classList.add("button_highlight")
|
this.detailsButton.classList.add("button_highlight")
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
|
this.renderGraph(this.fileID);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setDetails: function (file) {
|
setDetails: function (file) {
|
||||||
@@ -197,6 +199,7 @@ var DetailsWindow = {
|
|||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: apiEndpoint + "/file/" + file.id + "/info",
|
url: apiEndpoint + "/file/" + file.id + "/info",
|
||||||
success: function(data){
|
success: function(data){
|
||||||
|
this.fileID = data.id;
|
||||||
$("#info_file_details").html(
|
$("#info_file_details").html(
|
||||||
"<table>"
|
"<table>"
|
||||||
+ "<tr><td>Name<td><td>" + escapeHTML(data.name) + "</td></tr>"
|
+ "<tr><td>Name<td><td>" + escapeHTML(data.name) + "</td></tr>"
|
||||||
@@ -210,9 +213,13 @@ var DetailsWindow = {
|
|||||||
+ "</table>"
|
+ "</table>"
|
||||||
);
|
);
|
||||||
Toolbar.setStats(data.views, data.bandwidth_used/data.size);
|
Toolbar.setStats(data.views, data.bandwidth_used/data.size);
|
||||||
|
if(this.visible) {
|
||||||
|
this.renderGraph(data.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
this.fileID = file.id;
|
||||||
$("#info_file_details").html(
|
$("#info_file_details").html(
|
||||||
"<table>"
|
"<table>"
|
||||||
+ "<tr><td>Name<td><td>" + escapeHTML(file.name) + "</td></tr>"
|
+ "<tr><td>Name<td><td>" + escapeHTML(file.name) + "</td></tr>"
|
||||||
@@ -224,6 +231,65 @@ var DetailsWindow = {
|
|||||||
+ "</table>"
|
+ "</table>"
|
||||||
);
|
);
|
||||||
Toolbar.setStats(file.views, file.bandwidth_used/file.size);
|
Toolbar.setStats(file.views, file.bandwidth_used/file.size);
|
||||||
|
if(this.visible) {
|
||||||
|
this.renderGraph(file.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
renderGraph: function(fileID) {
|
||||||
|
console.log("rendering graph "+fileID);
|
||||||
|
$.get(apiEndpoint+"/file/" + fileID + "/timeseries", function(response){
|
||||||
|
console.log(response);
|
||||||
|
if (response.success) {
|
||||||
|
var ctx = document.getElementById('bandwidth_chart');
|
||||||
|
Chart.defaults.global.defaultFontColor = "#b3b3b3";
|
||||||
|
Chart.defaults.global.defaultFontSize = 16;
|
||||||
|
Chart.defaults.global.defaultFontFamily = "Ubuntu";
|
||||||
|
new Chart(
|
||||||
|
document.getElementById('bandwidth_chart'),
|
||||||
|
{
|
||||||
|
type: 'line',
|
||||||
|
data: response,
|
||||||
|
options: {
|
||||||
|
stacked: false,
|
||||||
|
aspectRatio: 2.5,
|
||||||
|
tooltips: {
|
||||||
|
mode: "index",
|
||||||
|
intersect: false,
|
||||||
|
axis: "x"
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
yAxes: [
|
||||||
|
{
|
||||||
|
type: "linear",
|
||||||
|
display: true,
|
||||||
|
position: "left",
|
||||||
|
id: "y_bandwidth",
|
||||||
|
scaleLabel: {
|
||||||
|
display: true,
|
||||||
|
labelString: "Downloads"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
type: "linear",
|
||||||
|
display: true,
|
||||||
|
position: "right",
|
||||||
|
id: "y_views",
|
||||||
|
scaleLabel: {
|
||||||
|
display: true,
|
||||||
|
labelString: "Views"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
point: {
|
||||||
|
radius: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -214,7 +214,7 @@ body{
|
|||||||
|
|
||||||
.details_popup{
|
.details_popup{
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
width: 1200px;
|
width: 1500px;
|
||||||
height: 800px;
|
height: 800px;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
@@ -131,6 +131,11 @@
|
|||||||
<tr><td>SHIFT + s</td><td> = Download all the files in the list as a zip archive</td></tr>
|
<tr><td>SHIFT + s</td><td> = Download all the files in the list as a zip archive</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<h3>Bandwidth and views</h3>
|
||||||
|
<div id="chart_container" class="chart-container" style="position: relative; width: 100%; height: auto;">
|
||||||
|
<canvas id="bandwidth_chart"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3>Credits</h3>
|
<h3>Credits</h3>
|
||||||
All server side code written by
|
All server side code written by
|
||||||
<a target="_blank" href="https://fornaxian.com/">Fornax (me)</a>.
|
<a target="_blank" href="https://fornaxian.com/">Fornax (me)</a>.
|
||||||
@@ -156,6 +161,7 @@
|
|||||||
<img src="/res/img/misc/loadthink.gif" style="margin-top: 20%; width: 200px; height: 200px;" />
|
<img src="/res/img/misc/loadthink.gif" style="margin-top: 20%; width: 200px; height: 200px;" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="/res/misc/chartjs/Chart.min.js"></script>
|
||||||
<script src="/res/script/jquery.js"></script>
|
<script src="/res/script/jquery.js"></script>
|
||||||
<script src="/res/script/Keyboard.js"></script>
|
<script src="/res/script/Keyboard.js"></script>
|
||||||
<script src="/res/script/Toolbar.js?v1"></script>
|
<script src="/res/script/Toolbar.js?v1"></script>
|
||||||
|
@@ -13,9 +13,12 @@ import (
|
|||||||
"fornaxian.com/pixeldrain-api/util"
|
"fornaxian.com/pixeldrain-api/util"
|
||||||
"fornaxian.com/pixeldrain-web/pixelapi"
|
"fornaxian.com/pixeldrain-web/pixelapi"
|
||||||
"github.com/Fornaxian/log"
|
"github.com/Fornaxian/log"
|
||||||
|
"github.com/microcosm-cc/bluemonday"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"github.com/timakin/gonvert"
|
"github.com/timakin/gonvert"
|
||||||
|
|
||||||
|
"gopkg.in/russross/blackfriday.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServeFilePreview controller for GET /u/:id/preview
|
// ServeFilePreview controller for GET /u/:id/preview
|
||||||
@@ -61,6 +64,9 @@ func (f filePreview) run(inf *pixelapi.FileInfo) string {
|
|||||||
} else if strings.HasPrefix(f.FileInfo.MimeType, "audio") {
|
} else if strings.HasPrefix(f.FileInfo.MimeType, "audio") {
|
||||||
return f.audio()
|
return f.audio()
|
||||||
} else if strings.HasPrefix(f.FileInfo.MimeType, "text") {
|
} 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()
|
return f.text()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,6 +186,37 @@ func (f filePreview) text() string {
|
|||||||
return fmt.Sprintf(htmlOut, prettyPrint, result)
|
return fmt.Sprintf(htmlOut, prettyPrint, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f filePreview) markdown() string {
|
||||||
|
htmlOut := `<div class="text-container">%s</div>`
|
||||||
|
|
||||||
|
if f.FileInfo.Size > 1e6 { // 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.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
md := bluemonday.UGCPolicy().SanitizeBytes(blackfriday.Run(bodyBytes))
|
||||||
|
|
||||||
|
return fmt.Sprintf(htmlOut, md)
|
||||||
|
}
|
||||||
|
|
||||||
func (f filePreview) frame(url string) string {
|
func (f filePreview) frame(url string) string {
|
||||||
return fmt.Sprintf(`<iframe src="%s" class="image-container"
|
return fmt.Sprintf(`<iframe src="%s" class="image-container"
|
||||||
seamless="seamless" frameborder="0" allowtransparency="true"
|
seamless="seamless" frameborder="0" allowtransparency="true"
|
||||||
|
Reference in New Issue
Block a user