File: blog_utils.lua

package info (click to toggle)
ntopng 5.2.1%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 121,832 kB
  • sloc: javascript: 143,431; cpp: 71,175; ansic: 11,108; sh: 4,687; makefile: 911; python: 587; sql: 512; pascal: 234; perl: 118; ruby: 52; exp: 4
file content (206 lines) | stat: -rw-r--r-- 5,407 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
--
-- (C) 2020-22 - ntop.org
--

local json = require("dkjson")

local MAX_POSTS = 3
local blog_utils = {}

local BLOG_FEED_KEY         = "ntopng.cache.blog_feed"
local BLOG_NEXT_FEED_UPDATE = "ntopng.prefs.next_feed_update"
local JSON_FEED             = "https://feed.ntop.org/blog.json"

-- Parse the date string, following this pattern: yyyy-mm-ddTH:M:S+00:00
-- Return 0 if the date string is empty, otherwise it returns the right epoch
function blog_utils.parseDate(date)

   if (isEmptyString(date)) then return 0 end

   local pattern = "(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)+(%d+):(%d+)"
   local year, month, day, hour, minutes = date:match(pattern)

   local epoch = os.time({year=year, month=month, day=day, hour=hour, min=minutes})
   return epoch
end

function blog_utils.intersectPosts(s1, s2)

   -- if there aren't any old post then return the new ones
   if (s1[1] == nil) then return s2 end
   -- do integrity check on old set
   if (s1[1].epoch == nil) then return s2 end
   -- if there aren't any new post then return the old ones
   if (s2[1] == nil) then return s1 end

   local intersected = {}
   local j = 1

   -- insert the new posts
   for i = 1, MAX_POSTS do
      if (s2[i].epoch > s1[1].epoch) then
	 intersected[i] = s2[i]
	 j = j + 1
      end
   end

   -- insert the olds posts if the array is not full
   local k = 1
   for i = j, MAX_POSTS do
      intersected[i] = s1[k]
      k = k + 1
   end

   return (intersected)

end

function blog_utils.updatePostState(blogNotificationId, username)

   if (blogNotificationId == nil) then return false end
   if (isEmptyString(username)) then return false end

   local postsJSON = ntop.getPref(BLOG_FEED_KEY)
   local posts = {}

   if (not isEmptyString(postsJSON)) then
      posts = json.decode(postsJSON)
   end

   local success = false

   for _, p in pairs(posts) do
      if (p.id == blogNotificationId) then
         if (p.users_read == nil) then p.users_read = {} end
         p.users_read[username] = true
         success = true
      end
   end

   ntop.setPref(BLOG_FEED_KEY, json.encode(posts))

   return (success)
end

function blog_utils.updateRedis(newPosts)

   -- decode older posts from updateRedis
   local oldPostsJSON = ntop.getPref(BLOG_FEED_KEY)
   local oldPosts = {}
   if (not isEmptyString(oldPostsJSON)) then
      oldPosts = json.decode(oldPostsJSON)
   end

   -- intersect two notifications sets and marks the new
   local intersected = blog_utils.intersectPosts(oldPosts, newPosts)

   -- save the posts inside redis
   ntop.setPref(BLOG_FEED_KEY, json.encode(intersected))
   
end

function blog_utils.fetchLatestPosts()  

   if ntop.isOffline() then
      return
   end

   local response
   local now = os.time()
   local next_fetch = ntop.getPref(BLOG_NEXT_FEED_UPDATE)
   local debug = false
   
   if(debug) then traceError(TRACE_NORMAL, TRACE_CONSOLE, "blog_utils.fetchLatestPosts()") end
   
   if((next_fetch ~= nil) and (next_fetch ~= "")) then
      next_fetch = tonumber(next_fetch)

      if(next_fetch > now) then
	 if(debug) then tprint("Not yet time to refresh blog [".. (now-next_fetch) .." src]") end
	 return
      end
   end

   if(debug) then traceError(TRACE_NORMAL, TRACE_CONSOLE, "Refreshing ntop blog feed...") end
   response = ntop.httpGet(JSON_FEED)

   if(debug) then tprint(response["CONTENT"]) end
   
   if ((response == nil) or (response["CONTENT"] == nil)) then
      ntop.setPref(BLOG_NEXT_FEED_UPDATE, now+300) -- Try again not less than 5 mins
      return (false)
   end
   
   local jsonFeed = json.decode(response["CONTENT"])

   if ((jsonFeed == nil) or table.empty(jsonFeed["items"])) then
      ntop.setPref(BLOG_NEXT_FEED_UPDATE, now+300) -- Try again not less than 5 mins
      return (false)
   end

   if(debug) then tprint("Update next feed time (in 12 hours)") end
   ntop.setPref(BLOG_NEXT_FEED_UPDATE, now+43200) -- Try again not less than 12 hours
   
   local posts = jsonFeed["items"]

   local latest3Posts = {posts[1], posts[2], posts[3]}
   local formattedPosts = {}

   for i, post in ipairs(latest3Posts) do
      if (post ~= nil) then

	 local splittedLink = split(post.id, "?p=")
	 local postId = tonumber(splittedLink[2])
	 local postTitle = post.title
	 local postURL = post.url
	 local postShortDesc = string.sub(post.content_text, 1, 48) .. '...'
	 local postEpoch = blog_utils.parseDate(post.date_published)

	 local post = {
	    id = postId,
	    title = postTitle,
	    link = postURL,
	    shortDesc = postShortDesc,
	    epoch = postEpoch
	 }

	 formattedPosts[#formattedPosts + 1] = post
      end
   end

   -- updates redis
   blog_utils.updateRedis(formattedPosts)

   return (true)
end

function blog_utils.readPostsFromRedis(username)
   if (username == nil) then return {} end
   if (isEmptyString(username)) then return {} end

   local postsJSON = ntop.getPref(BLOG_FEED_KEY)
   local posts = {}

   if (not isEmptyString(postsJSON)) then
      posts = json.decode(postsJSON)
   end

   local newPostCounter = 0

   -- post.users_read is an array which contains
   -- the users who read the notification
   for _, post in pairs(posts) do
      if (post.users_read == nil) then
	 post.users_read = {}
	 newPostCounter = newPostCounter + 1
      else
	 if (not post.users_read[username]) then
	    newPostCounter = newPostCounter + 1
	 end
      end
   end

   return posts, newPostCounter
end

return blog_utils