Skip to content

Commit

Permalink
refactor!: reorganize code
Browse files Browse the repository at this point in the history
- The api key comes from the enviroment variable `FOREM_API_KEY`
  - API calls don't get the api key as a parameter anymore
- All the get calls are asynchronous
  • Loading branch information
Massolari committed Mar 5, 2024
1 parent fbeb4cb commit e94cfd3
Show file tree
Hide file tree
Showing 11 changed files with 510 additions and 400 deletions.
84 changes: 62 additions & 22 deletions fnl/forem-nvim/api.fnl
Original file line number Diff line number Diff line change
@@ -1,58 +1,98 @@
(local curl (require :plenary.curl))
(local notify (require :forem-nvim.notify))
(local job (require :plenary.job))
(local M {})
(local base-url "https://dev.to/api")

(λ key []
vim.env.FOREM_API_KEY)

(λ handle-async-error [response]
(notify.error (.. "Error: " response.body.error)))

(λ get-article-template [title]
(string.format "---
title: %s
published: false
description:
description:
tags:
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
---
" title))

(λ request [request-fun api-key endpoint options]
(λ request [request-fun endpoint options]
(let [parameters (vim.tbl_extend :force
{:url (.. base-url endpoint)
:headers {: api-key
:content_type :application/json}}
:headers {:api-key (key)
:content_type :application/json
:accept :application/vnd.forem.api-v1+json}}
options)
response (request-fun parameters)]
(if response.body
(vim.tbl_extend :force response
{:body (vim.fn.json_decode response.body)})
response)))

(λ get [api-key endpoint]
(request curl.get api-key endpoint {}))
(λ request-async [method endpoint options on-success ?on-error]
(: (job:new {:command :curl
:args [:-X
method
:-H
"Content-Type: application/json"
:-H
"Accept: application/vnd.forem.api-v1+json"
:-H
(.. "api-key: " (key))
:-d
(vim.fn.json_encode options)
(.. base-url endpoint)]
:on_exit (fn [this code]
(vim.schedule #(let [results (this:result)
result (vim.fn.join results "\n")
response (vim.fn.json_decode result)]
(if (= code 0)
(on-success response)
(do
(handle-async-error response)
(when ?on-error
(?on-error response)))))))})
:start))

(λ put [api-key endpoint body]
(request curl.put api-key endpoint {: body}))
(λ get [endpoint on-sucess ?on-error]
(request-async :GET endpoint {} on-sucess ?on-error))

(λ post [api-key endpoint body]
(request curl.post api-key endpoint {: body}))
(λ put [endpoint body]
(request curl.put endpoint {: body}))

(λ M.my-articles [api-key]
(get api-key :/articles/me/all))
(λ post [endpoint body]
(request curl.post endpoint {: body}))

(λ M.save-article [api-key id content]
(put api-key (.. :/articles/ id)
(λ M.my-articles [on-success ?on-error]
(get :/articles/me/all on-success ?on-error))

(λ M.save-article [id content]
(put (.. :/articles/ id)
(vim.fn.json_encode {:article {:body_markdown content}})))

(λ M.new-article [api-key title]
(post api-key :/articles
(λ M.new-article [title]
(post :/articles
(vim.fn.json_encode {:article {:body_markdown (get-article-template title)}})))

(λ M.feed [api-key]
(get api-key :/articles))
(λ M.feed [on-success ?on-error]
(get :/articles on-success ?on-error))

(λ M.get-article [id on-success ?on-error]
(get (.. :/articles/ id) on-success ?on-error))

(λ M.get-article [api-key id]
(get api-key (.. :/articles/ id)))
(λ M.get-article-by-path [path on-success ?on-error]
(get (.. :/articles/ path) on-success ?on-error))

(λ M.get-article-by-path [api-key path]
(get api-key (.. :/articles/ path)))
(λ M.handle-api-error [response on-success]
(let [start-status (-> response.status (tostring) (string.sub 1 2))]
(if (not= start-status :20)
(notify.error (.. "Error: " response.body.error))
(on-success response))))

M
94 changes: 69 additions & 25 deletions fnl/forem-nvim/buffer.fnl
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
(local api (require :forem-nvim.api))
(local Article (require :forem-nvim.article))
(local notify (require :forem-nvim.notify))
(local util (require :forem-nvim.util))
(local {: fold : set-locals : set-local} (require :forem-nvim.util))
(local M {})

Expand All @@ -16,8 +19,10 @@
[:swapfile false]]))

(λ M.write [bufnr text ?init]
(set-local :modifiable true)
(vim.api.nvim_buf_set_lines bufnr (or ?init 0) -1 false text))
(let [modifiable (vim.opt_local.modifiable:get)]
(set-local :modifiable true)
(vim.api.nvim_buf_set_lines bufnr (or ?init 0) -1 false text)
(set-local :modifiable modifiable)))

(λ M.get-content []
(let [bufnr (vim.api.nvim_get_current_buf)]
Expand All @@ -31,29 +36,68 @@
(M.write bufnr article-body))
(set-basic-options-and [[:buftype :acwrite] [:swapfile false]]))

(λ M.open-feed [articles]
(vim.cmd ":edit forem://articles/feed")
(let [bufnr (vim.api.nvim_get_current_buf)
max-columns (fold (fn [article total]
(vim.fn.max [(length article.title)
(length article.description)
total])) 0
articles)
feed (->> articles
(vim.tbl_map (fn [article]
(Article.format-to-feed article max-columns)))
(vim.tbl_flatten))]
(set _G.forem-feed-articles {})
(each [_ article (pairs articles)]
(tset _G.forem-feed-articles article.title
{:id article.id :url article.url}))
(M.write bufnr ["# Your Feed"
""
"Press <Enter> in a card to open the article in a new buffer"
"and <C-b> to open it in the browser."
""])
(M.write bufnr feed 5)
(set-feed-basic-options)))
(λ seek-feed-title [line-number get-next-line-number count]
(let [line-content (vim.fn.getline line-number)
?title (string.match line-content " ## (.+)" 1)]
(if ?title
?title
(> count 1000)
(notify.error "Could not find title")
(seek-feed-title (get-next-line-number line-number)
get-next-line-number (+ count 1)))))

(λ get-card-title [line-number]
(let [line-content (vim.fn.getline line-number)
is-card-upper-border? (string.match line-content "🭽" 1)
is-out-of-card? (not (string.match line-content "^[ |🭽|▏|🭼]" 1))]
(if is-out-of-card?
nil
(seek-feed-title line-number
(if is-card-upper-border?
(fn [n]
(+ n 1))
(fn [n]
(- n 1))) 0))))

(λ open-feed-article [location]
(let [title (get-card-title (vim.fn.line "."))
?article-data (. _G.forem-feed-articles title)]
(when title
(if ?article-data
(if (= location :browser)
(util.open-browser-url ?article-data.url)
(api.get-article ?article-data.id M.open-article))
(notify.error "Could not find article data. Please reopen the feed.")))))

(λ M.load-feed []
(set-feed-basic-options)
(local bufnr (vim.api.nvim_get_current_buf))
(M.write bufnr ["Loading feed..."])
(api.feed (fn [articles]
(vim.keymap.set :n :<CR> #(open-feed-article :buffer)
{:buffer true :silent true})
(vim.keymap.set :n :<C-b> #(open-feed-article :browser)
{:buffer true :silent true})
(let [max-columns (fold (fn [article total]
(vim.fn.max [(length article.title)
(length article.description)
total]))
0 articles)
feed (->> articles
(vim.tbl_map (fn [article]
(Article.format-to-feed article
max-columns)))
(vim.tbl_flatten))]
(set _G.forem-feed-articles {})
(each [_ article (pairs articles)]
(tset _G.forem-feed-articles article.title
{:id article.id :url article.url}))
(M.write bufnr ["# Your Feed"
""
"Press <Enter> in a card to open the article in a new buffer"
"and <C-b> to open it in the browser."
""])
(M.write bufnr feed 5)))))

(λ M.open-article [article]
(vim.cmd (string.format ":edit forem://article/%s" article.title))
Expand Down
Loading

0 comments on commit e94cfd3

Please sign in to comment.