Skip to content

Commit 348143d

Browse files
authored
Merge pull request #4 from neo451/dev
Dev
2 parents 779f4f5 + 4c2e526 commit 348143d

File tree

15 files changed

+2276
-330
lines changed

15 files changed

+2276
-330
lines changed

.github/workflows/luarocks.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Push to Luarocks
22

33
on:
4-
merge:
4+
push:
55
tags: # Will upload to luarocks.org when a tag is pushed
66
- "*"
77
pull_request: # Will test a local install without uploading to luarocks.org
@@ -30,3 +30,5 @@ jobs:
3030
tree-sitter-xml
3131
tree-sitter-markdown
3232
tree-sitter-html
33+
plenary.nvim
34+
conform.nvim

lua/feed/commands.lua

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ function cmds.list_feeds()
159159
end
160160

161161
function cmds.update()
162+
config.opml_t = require("feed.opml").import(config.opml)
162163
local ok, progress = pcall(require, "fidget.progress")
163164
local handle
164165
if not ok then
@@ -170,10 +171,16 @@ function cmds.update()
170171
percentage = 0,
171172
}
172173
end
174+
175+
if config.opml_t then
176+
config.feeds = vim.list_extend(config.feeds, config.opml_t.outline) -- TODO: remove duplicates ...
177+
end
178+
173179
for _, link in ipairs(config.feeds) do
174180
fetch.update_feed(link, #config.feeds, handle)
175181
end
176-
db:sort() -- TODO:
182+
183+
-- db:sort() -- TODO:
177184
db:save()
178185
end
179186

@@ -202,6 +209,7 @@ end
202209

203210
---@param args string[]
204211
local function load_command(args)
212+
Pr(args)
205213
local cmd = table.remove(args, 1)
206214
return cmds[cmd](unpack(args))
207215
end

lua/feed/config.lua

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,20 @@ local default = {
5555
---@type string
5656
split = "13split",
5757
---@type string
58-
colorscheme = "kanagawa-lotus",
58+
colorscheme = "morning",
5959

6060
---@type feed.feed[]
6161
feeds = {},
62+
63+
---@type string
64+
opml = "~/.local/share/nvim/feed/feeds.opml",
6265
}
6366

64-
--- TODO:
6567
---@class feed.config
6668
---@field feed? feed.feed[]
67-
68-
local user_config = type(vim.g.feed_config) == "function" and vim.g.feed_config() or vim.g.feed_config or {}
69+
---@field opml? string
6970

7071
---@type feed.config
71-
local config = vim.tbl_deep_extend("force", default, user_config or {})
72+
local config = vim.tbl_deep_extend("force", default, vim.g.feed_config or {})
7273

7374
return config

lua/feed/db.lua

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,6 @@ local Path = require "plenary.path"
22
local db_mt = { __class = "feed.db" }
33
db_mt.__index = db_mt
44

5-
local function isFile(path)
6-
local f = io.open(path, "r")
7-
if f then
8-
f:close()
9-
return true
10-
end
11-
return false
12-
end
13-
145
---@param path string
156
---@param content string
167
local function save_file(path, content)
@@ -64,12 +55,20 @@ end
6455
---sort index by time, descending
6556
function db_mt:sort()
6657
table.sort(self.index, function(a, b)
67-
return a.time > b.time
58+
if a.time and b.time then
59+
return a.time > b.time
60+
end
61+
return true -- HACK:
6862
end)
6963
end
7064

7165
function db_mt:update_index()
72-
self.index = loadfile(self.dir .. "/index")()
66+
local ok, res = pcall(loadfile, self.dir .. "/index")
67+
if ok then
68+
self.index = res()
69+
else
70+
print "failed to update index?"
71+
end
7372
end
7473

7574
---@param entry feed.entry
@@ -87,6 +86,10 @@ function db_mt:blowup()
8786
end
8887

8988
local index_header = { version = "0.1" }
89+
local opml_template = [[<?xml version="1.0" encoding="UTF-8"?>
90+
<opml version="1.0"><head><title>feed_nvim_export</title></head><body>
91+
<outline text="neovim.io" title="neovim.io" type="rss" xmlUrl="https://neovim.io/news.xml" htmlUrl="https://neovim.io/news"/>
92+
</body></opml>]]
9093

9194
-- TODO: support windows, but planery.path does not.. make pull request..
9295

@@ -106,6 +109,11 @@ local function prepare_db(dir)
106109
index_path:touch()
107110
index_path:write("return " .. vim.inspect(index_header), "w")
108111
end
112+
local opml_path = Path:new(dir .. "/feeds.opml")
113+
if not opml_path:is_file() then
114+
opml_path:touch()
115+
opml_path:write(opml_template, "w")
116+
end
109117
end
110118

111119
---@param dir string

lua/feed/feedparser.lua

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,23 @@ local function is_json(str)
1111
return ok
1212
end
1313

14+
local function handle_atom_link(entry)
15+
if not vim.islist(entry.link) then
16+
return entry.link.href
17+
end
18+
-- TODO: read spec for the different link types
19+
return entry.link[1].href
20+
end
21+
22+
local function handle_atom_content(content)
23+
if content.type == "html" then
24+
return content[1]
25+
else
26+
-- TODO: treedoc power!
27+
return "xhtml not supported now"
28+
end
29+
end
30+
1431
---@param entry table
1532
---@param feedtype string
1633
---@param title string
@@ -22,18 +39,30 @@ local function reify_entry(entry, feedtype, title)
2239
res.id = sha1(entry.link)
2340
res.feed = title
2441
res.title = entry.title
25-
res.time = date.new_from.rss(entry.pubDate):absolute()
26-
res.content = entry["content:encoded"] or entry.description
42+
local ok, time = pcall(function()
43+
return date.new_from.rss(entry.pubDate):absolute()
44+
end)
45+
if ok then
46+
res.time = time
47+
end
48+
res.content = entry["content:encoded"] or entry.description or ""
2749
res.author = entry.author or title
2850
elseif feedtype == "json" then
2951
res.link = entry.url
3052
res.id = sha1(entry.url)
3153
res.feed = title
3254
res.title = entry.title
33-
res.time = date.new_from.json(entry.date_published)
55+
res.time = date.new_from.json(entry.date_published):absolute()
3456
res.author = title
3557
res.content = entry.content_html
3658
elseif feedtype == "atom" then -- TODO: read spec!!!
59+
res.link = handle_atom_link(entry)
60+
res.id = sha1(res.link)
61+
res.title = entry.title[1]
62+
res.feed = title
63+
res.time = date.new_from.atom(entry.published):absolute()
64+
res.author = title
65+
res.content = handle_atom_content(entry.content)
3766
end
3867
res.tags = { unread = true }
3968
return res
@@ -66,7 +95,8 @@ local function reify(ast, feedtype)
6695
res.entries[i] = reify_entry(v, "json", res.title)
6796
end
6897
elseif feedtype == "atom" then
69-
res.title = ast.title
98+
res.title = ast.title[1]
99+
res.entries = {}
70100
for _, v in ipairs(ast.link) do
71101
if v.type and ut.looks_like_url(v.href) then -- HACK: check spec
72102
res.link = v.href
@@ -89,7 +119,7 @@ end
89119
---@return feed.feedtype
90120
local function parse(src, opts)
91121
local ast, feedtype
92-
opts = opts or {}
122+
opts = opts or { reify = true }
93123
if opts.type == "json" or is_json(src) then
94124
ast, feedtype = vim.json.decode(src), "json"
95125
else

lua/feed/fetch.lua

Lines changed: 14 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,11 @@
11
local curl = require "plenary.curl"
22
local config = require "feed.config"
33
local feedparser = require "feed.feedparser"
4-
local date = require "feed.date"
54
local db = require("feed.db").db(config.db_dir)
6-
local sha1 = require "feed.sha1"
75

86
local M = {}
97

10-
---@param ast table
11-
---@param feed_type feed.feedtype
12-
---@return feed.entry[]
13-
---@return string
14-
local function get_root(ast, feed_type)
15-
if feed_type == "json" then
16-
return ast.items, ast.title
17-
elseif feed_type == "rss" then
18-
return ast.channel.item, ast.channel.title
19-
else
20-
return {}, "nulllll" --- TODO: test atom feeds!!!
21-
end
22-
end
23-
24-
local date_tag = {
25-
rss = "pubDate",
26-
json = "date_published",
27-
}
28-
29-
---@param entry table
30-
---@param feedtype feed.feedtype
31-
---@param feedname string
32-
---@return feed.entry
33-
---@return string # content to store on disk
34-
local function unify(entry, feedtype, feedname)
35-
local content
36-
local _date = entry[date_tag[feedtype]]
37-
entry[date_tag[feedtype]] = nil
38-
entry.time = date.new_from[feedtype](_date):absolute()
39-
entry.feed = feedname
40-
if feedtype == "json" then
41-
entry.link = entry.url
42-
entry.id = sha1(entry.link)
43-
entry.url = nil
44-
content = entry.content_html
45-
entry.content_html = nil
46-
elseif feedtype == "rss" then
47-
entry.link = entry.link
48-
entry.id = sha1(entry.link)
49-
content = entry["content:encoded"] or entry.description
50-
entry["content:encoded"] = nil
51-
entry.description = nil
52-
end
53-
entry.tags = { unread = true } -- HACK:
54-
return entry, content
55-
end
56-
57-
function M.fetch(url, timeout, callback)
8+
local function fetch(url, timeout, callback)
589
curl.get {
5910
url = url,
6011
timeout = timeout,
@@ -70,7 +21,11 @@ function M.update_feed(feed, total, handle)
7021
local src
7122
local url
7223
if type(feed) == "table" then
73-
url = feed[1]
24+
if feed.xmlUrl then
25+
url = feed.xmlUrl
26+
else
27+
url = feed[1]
28+
end
7429
else
7530
url = feed
7631
end
@@ -79,16 +34,19 @@ function M.update_feed(feed, total, handle)
7934
return
8035
end
8136
src = res.body
82-
-- src = (res.body):gsub("\n", "")
83-
local ok, ast, feed_type = pcall(feedparser.parse, src)
37+
local ok, ast = pcall(feedparser.parse, src)
8438
if not ok then -- FOR DEBUG
8539
print(("[feed.nvim] failed to parse %s"):format(feed.name or url))
8640
print(ast)
8741
return
8842
end
89-
local entries, feed_name = get_root(ast, feed_type)
43+
---@type feed.opml
44+
config.opml_t:append(ast.title, nil, ast.link, url)
45+
local entries = ast.entries
9046
for _, entry in ipairs(entries) do
91-
db:add(unify(entry, feed_type, feed_name))
47+
local content = entry.content
48+
entry.content = nil
49+
db:add(entry, content)
9250
end
9351
db:save()
9452
if handle then
@@ -98,7 +56,7 @@ function M.update_feed(feed, total, handle)
9856
end
9957
end
10058
end
101-
M.fetch(url, 30000, callback)
59+
fetch(url, 30000, callback)
10260
end
10361

10462
-- TODO: maybe use a process bar like fidget.nvim

lua/feed/format.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ local strings = require "plenary.strings"
33
local date = require "feed.date"
44
local config = require "feed.config"
55
local treedoc = require "treedoc"
6-
local conv = require "treedoc.conv.markdown"
6+
local conv = require "treedoc.writers.markdown"
77

88
---porperly align, justify and trucate the title
99
---@param str string

0 commit comments

Comments
 (0)