Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F10384400
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Subscribers
None
View Options
diff --git a/account_import.go b/account_import.go
index c8fe8a2..3fd434e 100644
--- a/account_import.go
+++ b/account_import.go
@@ -1,134 +1,155 @@
package writefreely
import (
"fmt"
"html/template"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
+ "strings"
"github.com/hashicorp/go-multierror"
"github.com/writeas/impart"
wfimport "github.com/writeas/import"
"github.com/writeas/web-core/log"
)
func viewImport(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
// Fetch extra user data
p := NewUserPage(app, r, u, "Import", nil)
c, err := app.db.GetCollections(u)
if err != nil {
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("unable to fetch collections: %v", err)}
}
d := struct {
*UserPage
Collections *[]Collection
Flashes []template.HTML
+ Message string
+ InfoMsg bool
}{
UserPage: p,
Collections: c,
Flashes: []template.HTML{},
}
flashes, _ := getSessionFlashes(app, w, r, nil)
for _, flash := range flashes {
- d.Flashes = append(d.Flashes, template.HTML(flash))
+ if strings.HasPrefix(flash, "SUCCESS: ") {
+ d.Message = strings.TrimPrefix(flash, "SUCCESS: ")
+ } else if strings.HasPrefix(flash, "INFO: ") {
+ d.Message = strings.TrimPrefix(flash, "INFO: ")
+ d.InfoMsg = true
+ } else {
+ d.Flashes = append(d.Flashes, template.HTML(flash))
+ }
}
showUserPage(w, "import", d)
return nil
}
func handleImport(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
// limit 10MB per submission
r.ParseMultipartForm(10 << 20)
files := r.MultipartForm.File["files"]
var fileErrs []error
+ filesSubmitted := len(files)
+ var filesImported int
for _, formFile := range files {
- // TODO: count uploaded files that succeed and report back with message
file, err := formFile.Open()
if err != nil {
fileErrs = append(fileErrs, fmt.Errorf("failed to open form file: %s", formFile.Filename))
log.Error("import textfile: open from form: %v", err)
continue
}
defer file.Close()
tempFile, err := ioutil.TempFile("", "post-upload-*.txt")
if err != nil {
fileErrs = append(fileErrs, fmt.Errorf("failed to create temporary file for: %s", formFile.Filename))
log.Error("import textfile: create temp file: %v", err)
continue
}
defer tempFile.Close()
_, err = io.Copy(tempFile, file)
if err != nil {
fileErrs = append(fileErrs, fmt.Errorf("failed to copy file into temporary location: %s", formFile.Filename))
log.Error("import textfile: copy to temp: %v", err)
continue
}
info, err := tempFile.Stat()
if err != nil {
fileErrs = append(fileErrs, fmt.Errorf("failed to get file info of: %s", formFile.Filename))
log.Error("import textfile: stat temp file: %v", err)
continue
}
post, err := wfimport.FromFile(filepath.Join(os.TempDir(), info.Name()))
if err == wfimport.ErrEmptyFile {
// not a real error so don't log
_ = addSessionFlash(app, w, r, fmt.Sprintf("%s was empty, import skipped", formFile.Filename), nil)
continue
} else if err != nil {
fileErrs = append(fileErrs, fmt.Errorf("failed to read copy of %s", formFile.Filename))
log.Error("import textfile: file to post: %v", err)
continue
}
post.Collection = r.PostFormValue("collection")
coll, _ := app.db.GetCollection(post.Collection)
if coll == nil {
coll = &Collection{
ID: 0,
}
}
submittedPost := SubmittedPost{
Title: &post.Title,
Content: &post.Content,
Font: "norm",
}
if coll.ID != 0 && app.cfg.App.Federation {
token, err := app.db.GetAccessToken(u.ID)
if err != nil {
fileErrs = append(fileErrs, fmt.Errorf("failed to authenticate uploading: %s", formFile.Filename))
log.Error("import textfile: get accesstoken: %+v", err)
continue
}
ownedPost, err := app.db.CreateOwnedPost(&submittedPost, token, coll.Alias, app.cfg.App.Host)
if err != nil {
fileErrs = append(fileErrs, fmt.Errorf("failed to create owned post for %s", formFile.Filename))
log.Error("import textfile: create owned post: %v", err)
continue
}
go federatePost(app, ownedPost, coll.ID, false)
} else {
_, err = app.db.CreatePost(u.ID, coll.ID, &submittedPost)
if err != nil {
fileErrs = append(fileErrs, fmt.Errorf("failed to create post from %s", formFile.Filename))
log.Error("import textfile: create db post: %v", err)
continue
}
}
+ filesImported++
}
if len(fileErrs) != 0 {
_ = addSessionFlash(app, w, r, multierror.ListFormatFunc(fileErrs), nil)
}
+ if filesImported == filesSubmitted {
+ verb := "posts"
+ if filesSubmitted == 1 {
+ verb = "post"
+ }
+ _ = addSessionFlash(app, w, r, fmt.Sprintf("SUCCESS: Import complete, %d %s imported.", filesImported, verb), nil)
+ } else if filesImported > 0 {
+ _ = addSessionFlash(app, w, r, fmt.Sprintf("INFO: %d of %d posts imported, see details below.", filesImported, filesSubmitted), nil)
+ }
return impart.HTTPError{http.StatusFound, "/me/import"}
}
diff --git a/templates/user/import.tmpl b/templates/user/import.tmpl
index c258783..3833095 100644
--- a/templates/user/import.tmpl
+++ b/templates/user/import.tmpl
@@ -1,33 +1,38 @@
{{define "import"}}
{{template "header" .}}
<div class="snug content-container">
+ {{if .Message}}
+ <div class="alert {{if .InfoMsg}}info{{else}}success{{end}}">
+ <p>{{.Message}}</p>
+ </div>
+ {{end}}
<h2 id="posts-header">Import</h2>
<p>Upload text or markdown files to import as posts.</p>
<div class="formContainer">
<form id="importPosts" class="import" enctype="multipart/form-data" action="/me/import" method="POST">
<label for="file" hidden>Browse files to upload</label>
<input class="fileInput" name="files" type="file" multiple accept=".txt,.md"/>
<br />
<label for="collection">Select a blog to import the posts under.</label>
<select name="collection">
{{range $i, $el := .Collections}}
<option value={{.Alias}}>
{{if .Title}}{{.Title}}{{else}}{{.Alias}}{{end}}
</option>
{{end}}
<option value="" selected>drafts</option>
</select>
<br />
<input type="submit" value="Import" />
</form>
</div>
{{if .Flashes}}
<ul class="errors">
{{range .Flashes}}<li class="urgent">{{.}}</li>{{end}}
</ul>
{{end}}
</div>
{{template "footer" .}}
{{end}}
\ No newline at end of file
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 3:43 PM (1 d, 4 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3104596
Attached To
rWF WriteFreely
Event Timeline
Log In to Comment