diff options
-rw-r--r-- | http.go | 117 | ||||
-rw-r--r-- | templates/base.html | 8 | ||||
-rw-r--r-- | templates/paper-list.html | 80 |
3 files changed, 161 insertions, 44 deletions
@@ -1,9 +1,13 @@ package main import ( + "encoding/xml" "fmt" "html/template" + "io" + "io/ioutil" "log" + "mime/multipart" "net/http" "os" "path/filepath" @@ -141,21 +145,42 @@ func (papers *Papers) AddHandler(w http.ResponseWriter, r *http.Request) { } if r.Method == http.MethodPost { - if err := r.ParseForm(); err != nil { - res.Status = fmt.Sprintf("Error parsing form: %v", err) - baseTemplate.Execute(w, &res) - return + // Check Content-Type to determine which parser to use + contentType := r.Header.Get("Content-Type") + if strings.HasPrefix(contentType, "multipart/form-data") { + if err := r.ParseMultipartForm(MAX_SIZE); err != nil { + res.Status = fmt.Sprintf("Error parsing form: %v", err) + baseTemplate.Execute(w, &res) + return + } + } else { + if err := r.ParseForm(); err != nil { + res.Status = fmt.Sprintf("Error parsing form: %v", err) + baseTemplate.Execute(w, &res) + return + } } paperURL := strings.TrimSpace(r.FormValue("dl-paper")) category := strings.TrimSpace(r.FormValue("dl-category")) newCategory := strings.TrimSpace(r.FormValue("new-category")) + paperDOI := strings.TrimSpace(r.FormValue("paper-doi")) switch { - case paperURL != "" && category != "": - res.Status, res.LastPaperDL, res.LastUsedCategory = handlePaperDownload(papers, paperURL, category) case newCategory != "": res.Status, res.LastUsedCategory = handleNewCategory(papers, newCategory) + case category != "": + // Handle file upload + file, header, err := r.FormFile("upload-file") + if err == nil { + defer file.Close() + res.Status, res.LastPaperDL, res.LastUsedCategory = handleFileUpload(papers, file, header, category, paperDOI) + } else if paperURL != "" { + // Handle URL download with optional DOI + res.Status, res.LastPaperDL, res.LastUsedCategory = handlePaperDownload(papers, paperURL, category, paperDOI) + } else { + res.Status = "No paper URL or file provided" + } } } @@ -198,6 +223,74 @@ func (papers *Papers) DownloadHandler(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, paperPath) } +func handleFileUpload(papers *Papers, file io.Reader, header *multipart.FileHeader, category, doi string) (status, lastPaperDL, lastUsedCategory string) { + // Create temporary file + tmpFile, err := os.CreateTemp("", "upload-*.pdf") + if err != nil { + return fmt.Sprintf("Error creating temporary file: %v", err), "", category + } + defer os.Remove(tmpFile.Name()) + + // Copy uploaded file to temporary file + if _, err := io.Copy(tmpFile, file); err != nil { + return fmt.Sprintf("Error saving uploaded file: %v", err), "", category + } + tmpFile.Close() + + var meta *Meta + if doi != "" { + // If DOI provided, get metadata + meta, err = getMetaFromDOI(client, []byte(doi)) + if err != nil { + return fmt.Sprintf("Error getting metadata: %v", err), "", category + } + } else { + meta = &Meta{} + } + + paper, err := papers.NewPaperFromDirectLink(&http.Response{ + Header: http.Header{ + "Content-Type": []string{"application/pdf"}, + }, + Body: ioutil.NopCloser(strings.NewReader("")), + }, meta, category) + if err != nil { + return fmt.Sprintf("Error processing paper: %v", err), "", category + } + + // Move temporary file to final location + if err := renameFile(tmpFile.Name(), paper.PaperPath); err != nil { + return fmt.Sprintf("Error moving file: %v", err), "", category + } + + if doi != "" { + paper.Meta = *meta + tmpXML, err := os.CreateTemp("", "tmp-*.meta.xml") + if err != nil { + return fmt.Sprintf("Error creating metadata file: %v", err), "", category + } + defer os.Remove(tmpXML.Name()) + + if err := xml.NewEncoder(tmpXML).Encode(meta); err != nil { + return fmt.Sprintf("Error encoding metadata: %v", err), "", category + } + tmpXML.Close() + + paper.MetaPath = filepath.Join(filepath.Join(papers.Path, category), paper.PaperName+".meta.xml") + if err := renameFile(tmpXML.Name(), paper.MetaPath); err != nil { + return fmt.Sprintf("Error saving metadata: %v", err), "", category + } + } + + if paper.Meta.Title != "" { + status = fmt.Sprintf("%q uploaded successfully", paper.Meta.Title) + } else { + status = fmt.Sprintf("%q uploaded successfully", paper.PaperName) + } + + return status, strings.TrimPrefix(paper.PaperPath, papers.Path+"/"), category +} + // Handler helper functions func handleDelete(papers *Papers, r *http.Request) string { for _, paper := range r.Form["paper"] { @@ -237,8 +330,16 @@ func handleRename(papers *Papers, r *http.Request) string { return "Rename successful" } -func handlePaperDownload(papers *Papers, paperURL, category string) (status, lastPaperDL, lastUsedCategory string) { - paper, err := papers.ProcessAddPaperInput(category, paperURL) +func handlePaperDownload(papers *Papers, paperURL, category, doi string) (status, lastPaperDL, lastUsedCategory string) { + var paper *Paper + var err error + + if doi != "" { + paper, err = papers.NewPaperFromDOI([]byte(doi), category) + } else { + paper, err = papers.ProcessAddPaperInput(category, paperURL) + } + if err != nil { return err.Error(), "", category } diff --git a/templates/base.html b/templates/base.html index 8118c62..8d3f27d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -50,8 +50,10 @@ {{ else }} <tr> <td> - <form method="post" action="/admin/add/"> - <input type="text" name="dl-paper" placeholder="URL or DOI" value=""/> + <form method="post" action="/admin/add/" enctype="multipart/form-data"> + <input type="text" name="dl-paper" placeholder="URL or DOI" /> + <input type="text" name="paper-doi" placeholder="Optional DOI for URL/file" /> + <input type="file" name="upload-file" accept="application/pdf" /> <select name="dl-category" id="category"> {{ $lastUsedCategory := .LastUsedCategory }} {{ if $lastUsedCategory }} @@ -63,7 +65,7 @@ {{ end }} {{ end }} </select> - <input type="submit" value="Download"/> + <input type="submit" value="Add Paper"/> </form> </td> </tr> diff --git a/templates/paper-list.html b/templates/paper-list.html index 6ed1db8..d23f2c8 100644 --- a/templates/paper-list.html +++ b/templates/paper-list.html @@ -1,24 +1,30 @@ -{{ define "paper-list" }} {{ range $category, $papers := .Papers.List }} {{ -$paperCount := len $papers }} {{ if ge $paperCount 1 }} {{ if $.Edit }} -<input - type="checkbox" - id="{{ $category }}" - name="category" - value="{{ $category }}" -/> -<label for="{{ $category }}"> +{{ define "paper-list" }} +{{ range $category, $papers := .Papers.List }} +{{ $paperCount := len $papers }} +{{ if ge $paperCount 1 }} +<div style="display: flex; align-items: center;"> + {{ if $.Edit }} + <input + type="checkbox" + id="{{ $category }}" + name="category" + value="{{ $category }}" + style="margin-right: 10px;" + /> {{ end }} <h2 id="{{ $category }}"> - <a class="category-title" href="#{{ $category }}">{{ $category }}</a> + <label for="{{ $category }}"> + <a class="category-title" href="#{{ $category }}">{{ $category }}</a> + </label> </h2> - {{ if $.Edit }} -</label> -<br /> -{{ end }} {{ range $path, $paper := $papers }} +</div> + +{{ range $path, $paper := $papers }} <div class="paper"> {{ if $.Edit }} <input type="checkbox" id="{{ $path }}" name="paper" value="{{ $path }}" /> - {{ end }} {{ if $paper.Meta.Title }} + {{ end }} + {{ if $paper.Meta.Title }} <a class="paper-title" href="/download/{{ $path }}" @@ -36,26 +42,34 @@ $paperCount := len $papers }} {{ if ge $paperCount 1 }} {{ if $.Edit }} <br /> <div class="{{ if not $.Edit }}paper-meta{{ end }}"> - {{ $contCount := len $paper.Meta.Contributors }} {{ if ge $contCount 1 - }} {{- range $index, $contributor := $paper.Meta.Contributors -}} {{- if - $index }}, {{ end }} {{- $contributor.FirstName }} {{ - $contributor.LastName -}} {{- end -}} + {{ $contCount := len $paper.Meta.Contributors }} + {{ if ge $contCount 1 }} + {{- range $index, $contributor := $paper.Meta.Contributors -}} + {{- if $index }}, {{ end }} + {{- $contributor.FirstName }} {{ $contributor.LastName -}} + {{- end -}} <br /> - {{ end }} {{ $hasVal := false }} {{ if $paper.Meta.PubYear }}{{ $hasVal - = true }} + {{ end }} + {{ $hasVal := false }} + {{ if $paper.Meta.PubYear }}{{ $hasVal = true }} <span class="paper-year">{{ $paper.Meta.PubYear }}</span> - {{ end }} {{ if $paper.Meta.DOI }}{{ if $hasVal }}- {{end}} - <a href="https://doi.org/{{ $paper.Meta.DOI }}" - >{{ $paper.Meta.DOI }}</a - > - {{ else if $paper.Meta.ArxivID }} {{ if $hasVal }}- {{ end }} - <a href="https://arxiv.org/abs/{{ $paper.Meta.ArxivID }}" - >{{ $paper.Meta.ArxivID }}</a - > - {{ else if $paper.Meta.Resource }} {{ if $hasVal }}- {{ end }} + {{ end }} + {{ if $paper.Meta.DOI }}{{ if $hasVal }}- {{end}} + <a href="https://doi.org/{{ $paper.Meta.DOI }}">{{ $paper.Meta.DOI }}</a> + {{ else if $paper.Meta.ArxivID }} + {{ if $hasVal }}- {{ end }} + <a href="https://arxiv.org/abs/{{ $paper.Meta.ArxivID }}">{{ $paper.Meta.ArxivID }}</a> + {{ else if $paper.Meta.Resource }} + {{ if $hasVal }}- {{ end }} <a href="{{ $paper.Meta.Resource }}">{{ $paper.Meta.Resource }}</a> - {{ end }} {{ if $paper.Meta.Journal }} {{ if $hasVal }}- {{ end }} {{ - $paper.Meta.Journal }} {{ end }} + {{ end }} + {{ if $paper.Meta.Journal }} + {{ if $hasVal }}- {{ end }} + {{ $paper.Meta.Journal }} + {{ end }} </div> </div> -{{ end }} {{ end }} {{ end }} {{ end }} +{{ end }} +{{ end }} +{{ end }} +{{ end }} |