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))))))))))