move all viewer scripts to javascript
This commit is contained in:
@@ -1,13 +1,9 @@
|
||||
package webcontroller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"fornaxian.com/pixeldrain-api/util"
|
||||
@@ -16,7 +12,6 @@ import (
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/timakin/gonvert"
|
||||
|
||||
"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.DownloadURL = f.APIURL + "/file/" + f.FileInfo.ID + "?download"
|
||||
|
||||
if strings.HasPrefix(f.FileInfo.MimeType, "image") {
|
||||
return f.image()
|
||||
} else if strings.HasPrefix(f.FileInfo.MimeType, "video") {
|
||||
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()
|
||||
}
|
||||
if strings.HasPrefix(f.FileInfo.MimeType, "text") &&
|
||||
(strings.HasSuffix(f.FileInfo.Name, ".md") || strings.HasSuffix(f.FileInfo.Name, ".markdown")) {
|
||||
return f.markdown()
|
||||
}
|
||||
|
||||
// none of the mime type checks triggered, so we return the default page
|
||||
return f.def()
|
||||
}
|
||||
|
||||
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))
|
||||
return ""
|
||||
}
|
||||
|
||||
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.",
|
||||
)
|
||||
return "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.",
|
||||
)
|
||||
return "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.",
|
||||
)
|
||||
return "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 {
|
||||
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,
|
||||
)
|
||||
return string(bluemonday.UGCPolicy().SanitizeBytes(blackfriday.Run(bodyBytes)))
|
||||
}
|
||||
|
||||
// ServeFilePreviewDemo serves the content of the demo file. It contains a nice
|
||||
@@ -234,8 +87,7 @@ func (f filePreview) def() string {
|
||||
// categorize the website.
|
||||
func serveFilePreviewDemo(w http.ResponseWriter) {
|
||||
io.WriteString(w,
|
||||
`<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"></script>
|
||||
<div class="text-container"><pre class="pre-container linenums" style="width: 100%">
|
||||
`<pre style="line-height: 1em;">
|
||||
, __ _
|
||||
/|/ \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.
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
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 string // file or list
|
||||
CaptchaKey string
|
||||
ViewToken string
|
||||
APIResponse interface{}
|
||||
}
|
||||
|
||||
// ServeFileViewer controller for GET /u/:id
|
||||
func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
var err error
|
||||
if p.ByName("id") == "demo" {
|
||||
wc.serveFileViewerDemo(w, r) // Required for a-ads.com quality check
|
||||
return
|
||||
@@ -32,18 +42,17 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
ids = append(ids, p.ByName("id"))
|
||||
}
|
||||
|
||||
var api = pixelapi.New(wc.apiURLInternal, "")
|
||||
templateData := wc.newTemplateData(w, r)
|
||||
|
||||
var finfo []*pixelapi.FileInfo
|
||||
for _, id := range ids {
|
||||
inf, err := api.GetFileInfo(id, "")
|
||||
inf, err := templateData.PixelAPI.GetFileInfo(id, "")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
finfo = append(finfo, inf)
|
||||
}
|
||||
|
||||
templateData := wc.newTemplateData(w, r)
|
||||
|
||||
if len(finfo) == 0 {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
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])
|
||||
var err error
|
||||
if list {
|
||||
templateData.Title = fmt.Sprintf("%d files on pixeldrain", len(finfo))
|
||||
templateData.Other = viewerData{
|
||||
Type: "list",
|
||||
CaptchaKey: wc.captchaKey(),
|
||||
ViewToken: viewTokenOrBust(templateData.PixelAPI),
|
||||
APIResponse: map[string]interface{}{
|
||||
"data": finfo,
|
||||
"date_created": "now",
|
||||
@@ -70,6 +79,7 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
templateData.Other = viewerData{
|
||||
Type: "file",
|
||||
CaptchaKey: wc.captchaKey(),
|
||||
ViewToken: viewTokenOrBust(templateData.PixelAPI),
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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