diff of fe56de1e3c7ff17ebc1fe573d733ecb8414eeb29
fe56de1e3c7ff17ebc1fe573d733ecb8414eeb29
diff --git a/aggressive-murja.asd b/aggressive-murja.asd
index ff2c8a0..256c397 100644
--- a/aggressive-murja.asd
+++ b/aggressive-murja.asd
@@ -94,7 +94,7 @@
(:file "media-admin")
(:file "new-post")))
(:file "blog-root")
- ))
+ (:file "rss")))
(:file "main"))))
:in-order-to ((test-op (test-op "aggressive-murja/tests"))))
diff --git a/resources/css/murja.css b/resources/css/murja.css
index 5f0c3ad..19146f9 100644
--- a/resources/css/murja.css
+++ b/resources/css/murja.css
@@ -1,5 +1,6 @@
html, body {
- height: 100%
+ height: 100%;
+ font-size: 1.1em;
}
#editor-post-title {
@@ -220,7 +221,7 @@ a:hover {
}
header {
- font-size: 3em;
+ /*font-size: 3em;*/
color: #FFF;
display: table;
margin: 0 auto;
@@ -510,6 +511,20 @@ input:required {
justify-content: space-between;
}
+/* TODO: replace all .images references with this class */
+.flowy-list {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+}
+
+.flowy-list-item {
+ margin: 20px;
+ border-width: 3px;
+ list-style: none;
+ border-style: inset;
+}
+
@media only screen and (max-device-width:480px)
{
body {
diff --git a/resources/sql/reader-fns.sql b/resources/sql/reader-fns.sql
index a3847d1..1e8864e 100644
--- a/resources/sql/reader-fns.sql
+++ b/resources/sql/reader-fns.sql
@@ -15,6 +15,14 @@ WHERE owner = $1
GROUP BY fs.id, u.username, u.nickname, u.img_location
ORDER BY fs.name;
+-- name: get-user-feeds2
+-- this is used in the new, ssr'ed feed reader
+SELECT fs.id, fs.name, fs.url, count(fi.*) as amount_of_items, fs.last_modified
+FROM blog.feed_subscription fs
+LEFT JOIN blog.feed_item fi ON (fs.id = fi.feed AND (read_at is null OR $2) AND fi.pubdate <= now())
+WHERE owner = $1
+GROUP BY fs.id, fs.name, fs.url, fs.last_modified;
+
-- name: delete-feed
DELETE FROM blog.feed_subscription
WHERE id = $1 AND owner = $2;
diff --git a/src/model/post.lisp b/src/model/post.lisp
index 615f544..4aa10f6 100644
--- a/src/model/post.lisp
+++ b/src/model/post.lisp
@@ -1,6 +1,6 @@
(defpackage murja.model.post
(:use :cl)
- (:export :Post :get-page :get-post :post-id :post-title :article :creator :tags :created-at :post-hidden? :post-unlisted? :next-post-id :previous-post-id :previouslies
+ (:export :RSS-Post :rss-link :Post :get-page :get-post :post-id :post-title :article :creator :tags :created-at :post-hidden? :post-unlisted? :next-post-id :previous-post-id :previouslies
:id :title :creator :created-at :content :admin-get-all-titles
:title :month :year :id :tags :hidden :unlisted)
(:import-from :com.inuoe.jzon :parse))
@@ -28,6 +28,14 @@
(:documentation "A blogpost")
(:table-name "blog.Post"))
+(defclass RSS-Post (Post)
+ ((rss-link :initarg :rss-link :accessor rss-link))
+ ;; there's no direct rss-post table, but this is required due to inheriting Post...
+ (:metaclass postmodern:dao-class))
+
+(defmethod rss-link ((p t))
+ nil)
+
(defclass Title ()
((title :initarg :title :accessor post-title :initform (error "Title required"))
diff --git a/src/rss/reader-db.lisp b/src/rss/reader-db.lisp
index c85a141..80ae51e 100644
--- a/src/rss/reader-db.lisp
+++ b/src/rss/reader-db.lisp
@@ -3,7 +3,7 @@
(:import-from :halisql :defqueries)
(:import-from :lisp-fixup :partial :compose)
(:import-from :cl-date-time-parser :parse-date-time)
- (:export :*last-updated* :get-feed-name-and-url :*updates* :get-user-feeds :subscribe-to-feed :mark-as-read :delete-feed :download))
+ (:export :*last-updated* :get-user-feeds2 :get-feed-name-and-url :*updates* :get-user-feeds :subscribe-to-feed :mark-as-read :delete-feed :download))
(in-package :murja.rss.reader-db)
diff --git a/src/view/components/blogpost.lisp b/src/view/components/blogpost.lisp
index d2eff3f..31f2a4d 100644
--- a/src/view/components/blogpost.lisp
+++ b/src/view/components/blogpost.lisp
@@ -25,14 +25,18 @@
(assert img-location)
(with-html
(:div.post
- (:a :href (format nil "/blog/post/~d" id) title)
+ (:a :href (if (rss-link post)
+ (rss-link post)
+ (format nil "/blog/post/~d" id))
+ title)
(:div.meta
(:img.user_avatar :src img-location)
(:p ("By ~a" nickname))
(:p ("Written at ~a" (let ((lisp-fixup:*rfc822* t))
(lisp-fixup:fix-timestamp created-at)))))
- (when *user*
+ (when (and *user*
+ (not (rss-link post)))
;; the old editor is in "/blog/post/edit/~d"
(:a :href (format nil "/blog/post/editor/~d" id) "Edit this post"))
(:article.content
diff --git a/src/view/components/tabs.lisp b/src/view/components/tabs.lisp
index 36266f1..2103e72 100644
--- a/src/view/components/tabs.lisp
+++ b/src/view/components/tabs.lisp
@@ -33,7 +33,8 @@
(defmacro deftab (sym (&key
url
(title "")
- subtab
+ subtab
+ params
require-login
needed-abilities
captured-url-params
@@ -58,7 +59,8 @@
(@ssr-authenticated :require-authentication ,require-login )
;;@check-if-initial
(@dispatcher ,inject-to-head)
- )) ()
+ ))
+ ,params
(values (quote ,sym) (list ,@captured-url-params)))))
(defun tab-container (selected-tab tablist tab-parameters)
diff --git a/src/view/rss.lisp b/src/view/rss.lisp
new file mode 100644
index 0000000..daf469d
--- /dev/null
+++ b/src/view/rss.lisp
@@ -0,0 +1,71 @@
+(defpackage murja.view.rss
+ (:use :cl :binding-arrows :spinneret :murja.rss.reader-db)
+ (:import-from :murja.view.components.tabs :deftab)
+ (:import-from :murja.middleware.auth :*user*)
+ (:import-from :murja.model.user :user-id))
+
+(in-package :murja.view.rss)
+
+(deftab rss-single-item (:url "/blog/feeds/:feed-id/item/:item-id"
+ :subtab rss
+ :require-login t
+ :captured-url-params (feed-id item-id))
+ (let* ((post-row (postmodern:query "UPDATE blog.feed_item
+SET read_at = now()
+WHERE id = $1 AND feed = $2
+RETURNING id, title, description, link, author, pubdate" item-id feed-id :list)))
+ (destructuring-bind (id title description link author pubdate) post-row
+ (let ((p (make-instance 'murja.model.post:RSS-Post
+ :created-at pubdate
+ :id nil
+ :tags nil
+ :creator (make-instance 'murja.model.user:user
+ :nickname author)
+ :content description
+ :title title
+ :rss-link link)))
+ (murja.view.components.blogpost:blogpost p)))))
+
+(deftab rss-single-feed (:url "/blog/feeds/:feed-id"
+ :subtab rss
+ :params (&get archived)
+ :require-login t
+ :captured-url-params (feed-id archived))
+ (let ((items (postmodern:query
+ "SELECT id, fetched, title, link, author, pubdate
+FROM blog.feed_item
+WHERE feed = $1 AND (read_at is null OR $2) AND pubdate <= now()
+ORDER BY pubdate DESC" feed-id (not (not archived))))
+ (feed-name (caar (postmodern:query "SELECT name FROM blog.feed_subscription WHERE id = $1" feed-id)))
+ (lisp-fixup:*rfc822* t))
+ (:h* ("~a (~d)" feed-name (length items)))
+
+ (:div
+ (:a :href (str:replace-all "?archived=NIL" ""
+ (easy-routes:genurl 'rss-single-feed :feed-id feed-id :archived (not archived)))
+ (if archived
+ "Show only unread"
+ "Show all")))
+
+ (:ul
+ (dolist (item items)
+ (destructuring-bind (id fetched title link author pubdate) item
+ (:li (:a :href (easy-routes:genurl 'rss-single-item :feed-id feed-id :item-id id) title)
+ (:section ("Published ~a" (lisp-fixup:fix-timestamp pubdate)))))))))
+
+
+
+(deftab rss (:url "/blog/feeds/"
+ :title "RSS Feeds"
+ :require-login t)
+ (let ((feeds (get-user-feeds2 (user-id *user*) nil))
+ (lisp-fixup:*rfc822* t))
+ (:ul.flowy-list
+ (dolist (feed feeds)
+ (destructuring-bind (id name url count last-modified) feed
+ (:li.flowy-list-item
+ (:h*
+ (:a :href (easy-routes:genurl 'rss-single-feed :feed-id id) (format nil "~a (~d)" name count)))
+ (:div "Feed is located in " (:a :href url url))
+ (:div ("Last updated ~a" (unless (equalp last-modified :NULL)
+ (lisp-fixup:fix-timestamp last-modified))))))))))