From a1c029345bdea286a4de7f2cbcf00a1356b2998d Mon Sep 17 00:00:00 2001 From: Las Zenow Date: Mon, 3 Jun 2013 10:21:28 +0200 Subject: [PATCH 01/13] Ignore ctags --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 865ec4a..9281d52 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,9 @@ books/ new/ cover/ trantor -.*.swp tools/adduser/adduser tools/update/update tools/togridfs/togridfs tools/getISBNnDesc/getISBNnDesc +tags +.*.swp From d51b7f935c06bcb661ec900879602cf825c5601f Mon Sep 17 00:00:00 2001 From: Las Zenow Date: Tue, 4 Jun 2013 21:30:37 +0200 Subject: [PATCH 02/13] Use the new API of epubgo --- cover.go | 2 +- reader.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cover.go b/cover.go index 626f65f..1e8c68f 100644 --- a/cover.go +++ b/cover.go @@ -86,7 +86,7 @@ func GetCover(e *epubgo.Epub, title string) (bson.ObjectId, bson.ObjectId) { res := exp.FindSubmatch(txt) if res != nil { href := string(res[1]) - urlPart := strings.Split(it.Url(), "/") + urlPart := strings.Split(it.URL(), "/") url := strings.Join(urlPart[:len(urlPart)-1], "/") if href[:3] == "../" { href = href[3:] diff --git a/reader.go b/reader.go index 8b11a2b..4ab738d 100644 --- a/reader.go +++ b/reader.go @@ -65,10 +65,10 @@ func getNextPrev(e *epubgo.Epub, file string, id string, base string) (string, s prev := "" next := "" for err == nil { - if cleanLink(spine.Url()) == file { + if cleanLink(spine.URL()) == file { break } - prev = spine.Url() + prev = spine.URL() err = spine.Next() } if err != nil { @@ -79,7 +79,7 @@ func getNextPrev(e *epubgo.Epub, file string, id string, base string) (string, s prev = genLink(id, base, prev) } if spine.Next() == nil { - next = genLink(id, base, spine.Url()) + next = genLink(id, base, spine.URL()) } return next, prev } @@ -106,7 +106,7 @@ func listChapters(nav *epubgo.NavigationIterator, depth int) []chapter { for err == nil { var c chapter c.Label = nav.Title() - c.Link = nav.Url() + c.Link = nav.URL() c.Depth = depth for c.Depth < depth { c.Out = append(c.Out, true) @@ -143,7 +143,7 @@ func readStartHandler(w http.ResponseWriter, r *http.Request, sess *Session) { notFound(w, r) return } - http.Redirect(w, r, "/read/"+id+"/"+it.Url(), http.StatusTemporaryRedirect) + http.Redirect(w, r, "/read/"+id+"/"+it.URL(), http.StatusTemporaryRedirect) } func readHandler(w http.ResponseWriter, r *http.Request, sess *Session) { From 61764d51b329a67aafd86edc7a6dc7d0c0dc72cc Mon Sep 17 00:00:00 2001 From: Las Zenow Date: Tue, 16 Jul 2013 01:24:39 +0200 Subject: [PATCH 03/13] Update about page with status, bitcoin and pgp --- templates/about.html | 69 ++++++++++++++++++++++++++++++++++++++++++++ templates/index.html | 5 ++++ 2 files changed, 74 insertions(+) diff --git a/templates/about.html b/templates/about.html index ecf1bf9..5475660 100644 --- a/templates/about.html +++ b/templates/about.html @@ -6,4 +6,73 @@

We like to pay the authors, but not the corporations that make profit from them. We won't listen to any content remove request from corporations, editorials, right management organizations or any other blood-suckers.

+

Status

+ +

The Imperial Library of Trantor it's in beta-status. We are working to provide a good user experience, but it's still in early development.

+ +

Any help is welcome. You can write us comments to our email address (zenow@tormail.org), upload your epubs, download our source code hack it and send us patches, ...

+ +

Donations

+ +

If you feel like donate some bitcoins we'll gladly accept them. You can request one bitcoin key for you or use our public bitcoin key:

+

1JioYbSYDH4JQYbhF7tX2kGUVZc2vzvugx

+ +

PGP

+ +

You can use pgp to write me emails, use my key:

+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+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
+IXsSLZzM+UxPlUZpEqSH0qllMrtZAR4Xvvk=
+=KPVB
+-----END PGP PUBLIC KEY BLOCK-----
+
+ {{template "footer.html"}} diff --git a/templates/index.html b/templates/index.html index e2fb587..ca8d66e 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,5 +1,10 @@ {{template "header.html" .S}} +
+ + News! The about has being updated with pgp key and bitcoin address for donations. +
+

Last books added:

From bf0480868dcfc0840a7cb5bf327e40965dbce7f3 Mon Sep 17 00:00:00 2001 From: Las Zenow Date: Tue, 16 Jul 2013 22:56:48 +0200 Subject: [PATCH 04/13] Fix upload problems --- upload.go | 79 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/upload.go b/upload.go index 2b90d76..74a6f43 100644 --- a/upload.go +++ b/upload.go @@ -18,51 +18,62 @@ func InitUpload() { var uploadChannel chan uploadRequest type uploadRequest struct { - epubs []*multipart.FileHeader + file multipart.File + filename string } func uploadWorker() { for req := range uploadChannel { - for _, f := range req.epubs { - file, err := f.Open() - if err != nil { - log.Println("Can not open uploaded file", f.Filename, ":", err) - continue - } - defer file.Close() - - epub, err := openMultipartEpub(file) - if err != nil { - log.Println("Not valid epub uploaded file", f.Filename, ":", err) - continue - } - defer epub.Close() - - book := parseFile(epub) - title, _ := book["title"].(string) - file.Seek(0, 0) - id, err := StoreNewFile(title+".epub", file) - if err != nil { - log.Println("Error storing book (", title, "):", err) - continue - } - - book["file"] = id - db.InsertBook(book) - log.Println("File uploaded:", f.Filename) - } + processFile(req) } } +func processFile(req uploadRequest) { + defer req.file.Close() + + epub, err := openMultipartEpub(req.file) + if err != nil { + log.Println("Not valid epub uploaded req.file", req.filename, ":", err) + return + } + defer epub.Close() + + book := parseFile(epub) + title, _ := book["title"].(string) + req.file.Seek(0, 0) + id, err := StoreNewFile(title+".epub", req.file) + if err != nil { + log.Println("Error storing book (", title, "):", err) + return + } + + book["req.file"] = id + db.InsertBook(book) + log.Println("File uploaded:", req.filename) +} + func uploadPostHandler(w http.ResponseWriter, r *http.Request, sess *Session) { + problem := false + r.ParseMultipartForm(20000000) filesForm := r.MultipartForm.File["epub"] - uploadChannel <- uploadRequest{filesForm} + for _, f := range filesForm { + file, err := f.Open() + if err != nil { + log.Println("Can not open uploaded file", f.Filename, ":", err) + sess.Notify("Upload problem!", "There was a problem with book "+f.Filename, "error") + problem = true + continue + } + uploadChannel <- uploadRequest{file, f.Filename} + } - if len(filesForm) > 0 { - sess.Notify("Upload successful!", "Thank you for your contribution", "success") - } else { - sess.Notify("Upload problem!", "No books where uploaded.", "error") + if !problem { + if len(filesForm) > 0 { + sess.Notify("Upload successful!", "Thank you for your contribution", "success") + } else { + sess.Notify("Upload problem!", "No books where uploaded.", "error") + } } uploadHandler(w, r, sess) } From 5f612a36adca598eb76c77e869aa5cd9f3b7d804 Mon Sep 17 00:00:00 2001 From: Las Zenow Date: Wed, 17 Jul 2013 01:08:44 +0200 Subject: [PATCH 05/13] Simple news implementation Is missing some proper design and to show up the news on the front page. --- config.go | 2 ++ database.go | 19 +++++++++++++++ news.go | 51 ++++++++++++++++++++++++++++++++++++++++ template.go | 3 +++ templates/edit_news.html | 9 +++++++ templates/header.html | 5 +++- templates/news.html | 10 ++++++++ trantor.go | 3 +++ 8 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 news.go create mode 100644 templates/edit_news.html create mode 100644 templates/news.html diff --git a/config.go b/config.go index b8f5f71..21f0612 100644 --- a/config.go +++ b/config.go @@ -14,6 +14,7 @@ const ( DAILY_VISITS_COLL = "visits.daily" MONTHLY_VISITS_COLL = "visits.monthly" USERS_COLL = "users" + NEWS_COLL = "news" STATS_COLL = "statistics" FS_BOOKS = "fs_books" FS_IMGS = "fs_imgs" @@ -28,6 +29,7 @@ const ( TAGS_DISPLAY = 50 SEARCH_ITEMS_PAGE = 20 NEW_ITEMS_PAGE = 50 + NUM_NEWS = 10 TEMPLATE_PATH = "templates/" CSS_PATH = "css/" diff --git a/database.go b/database.go index ebf6fb0..9f96fd2 100644 --- a/database.go +++ b/database.go @@ -34,10 +34,16 @@ type Book struct { Keywords []string } +type News struct { + Date time.Time + Text string +} + type DB struct { session *mgo.Session books *mgo.Collection user *mgo.Collection + news *mgo.Collection stats *mgo.Collection mr *MR } @@ -53,6 +59,7 @@ func initDB() *DB { database := d.session.DB(DB_NAME) d.books = database.C(BOOKS_COLL) d.user = database.C(USERS_COLL) + d.news = database.C(NEWS_COLL) d.stats = database.C(STATS_COLL) d.mr = NewMR(database) return d @@ -82,6 +89,18 @@ func (d *DB) UserValid(user string, pass string) bool { return n != 0 } +func (d *DB) AddNews(text string) error { + var news News + news.Text = text + news.Date = time.Now() + return d.news.Insert(news) +} + +func (d *DB) GetNews(num int) (news []News, err error) { + err = d.news.Find(bson.M{}).Sort("-date").Limit(num).All(&news) + return +} + func (d *DB) InsertStats(stats interface{}) error { return d.stats.Insert(stats) } diff --git a/news.go b/news.go new file mode 100644 index 0000000..640c46d --- /dev/null +++ b/news.go @@ -0,0 +1,51 @@ +package main + +import ( + "net/http" +) + +type newsData struct { + S Status + News []news +} + +type news struct { + Date string + Text string +} + +func newsHandler(w http.ResponseWriter, r *http.Request, sess *Session) { + var data newsData + data.S = GetStatus(w, r) + data.S.News = true + newsEntries, _ := db.GetNews(NUM_NEWS) + data.News = make([]news, len(newsEntries)) + for i, n := range newsEntries { + data.News[i].Text = n.Text + data.News[i].Date = n.Date.Format("Jan 31, 2006") + } + loadTemplate(w, "news", data) +} + +func editNewsHandler(w http.ResponseWriter, r *http.Request, sess *Session) { + if sess.User == "" { + notFound(w, r) + return + } + + var data statusData + data.S = GetStatus(w, r) + data.S.News = true + loadTemplate(w, "edit_news", data) +} + +func postNewsHandler(w http.ResponseWriter, r *http.Request, sess *Session) { + if sess.User == "" { + notFound(w, r) + return + } + + text := r.FormValue("text") + db.AddNews(text) + http.Redirect(w, r, "/news/", http.StatusFound) +} diff --git a/template.go b/template.go index 6d5da0e..4d1ecaa 100644 --- a/template.go +++ b/template.go @@ -11,6 +11,7 @@ type Status struct { Notif []Notification Home bool About bool + News bool Upload bool Stats bool Help bool @@ -30,6 +31,8 @@ var templates = template.Must(template.ParseFiles(TEMPLATE_PATH+"header.html", TEMPLATE_PATH+"404.html", TEMPLATE_PATH+"index.html", TEMPLATE_PATH+"about.html", + TEMPLATE_PATH+"news.html", + TEMPLATE_PATH+"edit_news.html", TEMPLATE_PATH+"book.html", TEMPLATE_PATH+"search.html", TEMPLATE_PATH+"upload.html", diff --git a/templates/edit_news.html b/templates/edit_news.html new file mode 100644 index 0000000..d07c763 --- /dev/null +++ b/templates/edit_news.html @@ -0,0 +1,9 @@ +{{template "header.html" .S}} + +

Add News:

+
+ + +
+ +{{template "footer.html"}} diff --git a/templates/header.html b/templates/header.html index d46e17e..25d97c3 100644 --- a/templates/header.html +++ b/templates/header.html @@ -52,7 +52,8 @@ @@ -65,6 +66,8 @@