aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-07-15 08:35:10 -0400
committerClyne Sullivan <clyne@bitgloo.com>2023-07-15 08:35:10 -0400
commit4822a5f4c0c9b230863b5a68f4aa890136e11c7b (patch)
treed3b5edb124c1d7ce2c4cd5483471d1c27ef2fd5b
parentb9c39fdc582116086befde372684a1901115728f (diff)
code documentation and refactoring
-rw-r--r--src/lemmold/core.clj168
1 files changed, 129 insertions, 39 deletions
diff --git a/src/lemmold/core.clj b/src/lemmold/core.clj
index c08d30f..ab366d4 100644
--- a/src/lemmold/core.clj
+++ b/src/lemmold/core.clj
@@ -2,19 +2,42 @@
(:require [clj-http.client :as client])
(:require [clojure.data.json :as json]))
-(def POST-LIST "/post/list")
-(def COMMENTS "/comment/list")
-
-(defn make-api-url [inst endpoint]
- (str "https://" inst "/api/v3" endpoint))
-
-(defn api-call [api-url query-params]
+(def DEFAULT-INSTANCE
+ "The default instance to access."
+ "lemmy.ml")
+(def POST-PAGESIZE
+ "Number of posts to show per 'page'. Set by the API."
+ 5)
+(def COMMENT-PAGESIZE
+ "Number of comments to show per 'page'. Kept low for smaller screens."
+ 1)
+(def COMMENT-LIMIT
+ "Maximum number of comments to retrieve for a post."
+ 50)
+
+(def POST-LIST
+ "API endpoint for post list."
+ "/post/list")
+(def COMMENTS
+ "API endpoint for comment list (of a given post)."
+ "/comment/list")
+
+(defn make-api-url
+ "Builds URL for API request given the instance and endpoint."
+ [inst endpoint]
+ (str "https://" inst "/api/v3" endpoint))
+
+(defn api-call
+ "Completes an API request, returning the processed JSON."
+ [api-url query-params]
(-> api-url
(client/get {:accept :json :query-params query-params})
(get :body)
(json/read-str)))
-(defn post-list [instance community page]
+(defn post-list
+ "Fetches a post list from the given instance and endpoint."
+ [instance community page]
(let [query-params (cond-> {:sort "Hot" :page (str page)}
(not (empty? community))
(assoc :community_name community))]
@@ -22,12 +45,17 @@
(api-call query-params)
(get "posts"))))
-(defn comments-list [instance post]
+(defn comments-list
+ "Fetches the comment list for a given post."
+ [instance post]
(-> (make-api-url instance COMMENTS)
- (api-call {:limit "50" :post_id (str (get-in post ["post" "id"]))})
+ (api-call {:limit (str COMMENT-LIMIT)
+ :post_id (str (get-in post ["post" "id"]))})
(get "comments")))
-(defn show-post-item [index post]
+(defn show-post-item
+ "Renders a listing of the given post. Index is for user selection."
+ [index post]
(let [items [["creator" "name"]
["community" "name"]
["post" "name"]
@@ -36,26 +64,35 @@
data (cons (inc index) (mapv (partial get-in post) items))]
(apply (partial printf "%d. %s on %s\n %s\n at %s (%d comments)\n\n") data)))
-(defn show-comment-item [commnt]
+(defn show-comment-item
+ "Renders the given comment (from a post)."
+ [commnt]
(println (get-in commnt ["creator" "name"]) "says:")
(println (get-in commnt ["comment" "content"]))
- (println)
- )
+ (println))
-(defn show-posts [posts]
- (doseq [index (range 0 5)]
+(defn show-posts
+ "Displays a page's worth of post listings."
+ [posts]
+ (doseq [index (range 0 POST-PAGESIZE)]
(show-post-item index (nth posts index))))
-(defn show-comments [comments]
- (doseq [commnt (take 1 comments)]
+(defn show-comments
+ "Displays a page's worth of comments."
+ [comments]
+ (doseq [commnt (take COMMENT-PAGESIZE comments)]
(show-comment-item commnt)))
-(defn show-posts-prompt []
- (print "#NPQ> ")
+(defn show-posts-prompt
+ "Collects user input at post listing menu."
+ []
+ (print "#NPCIQ> ")
(flush)
(first (read-line)))
-(defn show-comments-prompt []
+(defn show-comments-prompt
+ "Collects user input at comment listing menu."
+ []
(print "BNP> ")
(flush)
(first (read-line)))
@@ -66,37 +103,90 @@
(read-line))
(defn show-instance-prompt []
- (print "Enter instance name [lemmy.ml]: ")
+ (printf "Enter instance name [%s]: " DEFAULT-INSTANCE)
(flush)
- (let [inst (read-line)] (if (empty? inst) "lemmy.ml" inst)))
+ (let [inst (read-line)] (if (empty? inst) DEFAULT-INSTANCE inst)))
-(defn view-post [instance post]
+(defn view-post
+ "Main loop for viewing a post and its comments."
+ [instance post]
(loop [offset 0 comments (comments-list instance post)]
(println)
- (show-comments (if (pos? offset) (drop (* 1 offset) comments) comments))
+ (show-comments (drop (* COMMENT-PAGESIZE offset) comments))
(case (show-comments-prompt)
\B (println)
\N (recur (inc offset) comments)
\P (recur (dec offset) comments)
(do (println "Unknown command.") (recur offset comments)))))
-(defn view-page [instance init-community]
- (loop [top true community init-community page 1 posts (post-list instance community page)]
+(defn view-nth-post
+ "Views the index-th post from the current post list."
+ [state posts index]
+ (view-post
+ (:instance state)
+ (nth posts (cond-> (+ 5 index) (:top state) (- 5))))
+ state)
+
+(defn get-post-list
+ "Fetches a new list of posts given the current (view-page) state."
+ [state]
+ (post-list (:instance state) (:community state) (:page state)))
+
+(defn next-page
+ "Updates state for viewing the next page of posts."
+ [state]
+ (if (:top state)
+ (assoc state :top false)
+ (-> state (assoc :top true) (update :page inc))))
+
+(defn prev-page
+ "Updates state for viewing the previous page of posts."
+ [state]
+ (if-not (:top state)
+ (assoc state :top true)
+ (-> state (assoc :top false) (update :page dec))))
+
+(defn change-community
+ "Updates state for viewing a different community."
+ [state]
+ (-> state
+ (assoc :top true)
+ (assoc :page 1)
+ (assoc :community (show-community-prompt))))
+
+(defn change-instance
+ "Updates state for viewing a different instance."
+ [state]
+ (-> state
+ (assoc :instance (show-instance-prompt))
+ (change-community)))
+
+(defn view-page
+ "Main loop for viewing posts listings."
+ [init-instance init-community]
+ (loop [state {:top true
+ :instance init-instance
+ :community init-community
+ :page 1}
+ posts (get-post-list state)]
(println)
- (show-posts (if top posts (drop 5 posts)))
+ (show-posts (if (:top state) posts (drop POST-PAGESIZE posts)))
(case (show-posts-prompt)
- \N (if top (recur false community page posts)
- (recur true community (inc page) (post-list instance community (inc page))))
- \P (if top (recur false community (dec page) (post-list instance community (dec page)))
- (recur true community page posts))
+ \N (let [new-state (next-page state)]
+ (recur new-state (if (:top new-state) (get-post-list new-state) posts)))
+ \P (let [new-state (prev-page state)]
+ (recur new-state (if (:top new-state) posts (get-post-list new-state))))
\Q (println)
- \1 (do (view-post instance (nth posts (cond-> 5 top (- 5)))) (recur top community page posts))
- \2 (do (view-post instance (nth posts (cond-> 6 top (- 5)))) (recur top community page posts))
- \3 (do (view-post instance (nth posts (cond-> 7 top (- 5)))) (recur top community page posts))
- \4 (do (view-post instance (nth posts (cond-> 8 top (- 5)))) (recur top community page posts))
- \5 (do (view-post instance (nth posts (cond-> 9 top (- 5)))) (recur top community page posts))
- \C (let [comm (show-community-prompt)] (recur true comm 1 (post-list instance comm page)))
- (do (println "Unknown command.") (recur top community page posts)))))
+ \1 (recur (view-nth-post state posts 0) posts)
+ \2 (recur (view-nth-post state posts 1) posts)
+ \3 (recur (view-nth-post state posts 2) posts)
+ \4 (recur (view-nth-post state posts 3) posts)
+ \5 (recur (view-nth-post state posts 4) posts)
+ \C (let [new-state (change-community state)]
+ (recur new-state (get-post-list new-state)))
+ \I (let [new-state (change-instance state)]
+ (recur new-state (get-post-list new-state)))
+ (do (println "Unknown command.") (recur state posts)))))
(defn -main [& args]
(println "Welcome to lemmold, your old-school Lemmy browser!")