Implement pageviews and unique pageviews counters
authorNick Downing <downing.nick@gmail.com>
Mon, 8 Oct 2018 02:46:35 +0000 (13:46 +1100)
committerNick Downing <downing.nick@gmail.com>
Mon, 8 Oct 2018 02:46:35 +0000 (13:46 +1100)
ndserver.js

index 7914b5e..590287f 100755 (executable)
@@ -31,6 +31,7 @@ catch (err) {
   if (err.code !== 'EEXIST') // should check error type
     throw err
 }
+
 let sessions
 {
   let text 
@@ -44,10 +45,16 @@ let sessions
   }
   sessions = JSON.parse(text)
 }
-let sessions_dirty = false;
+let sessions_is_dirty = false
+let sessions_dirty = () => {
+  if (!sessions_is_dirty) {
+    sessions_is_dirty = true
+    setTimeout(sessions_write, 5000)
+  }
+}
 let sessions_write = async () => {
   try {
-    sessions_dirty = false;
+    sessions_is_dirty = false;
     console.log('writing analytics/sessions.json')
     await fs_writeFile(
       'analytics/sessions.json',
@@ -60,6 +67,41 @@ let sessions_write = async () => {
   }
 }
 
+let pageviews
+{
+  let text 
+  try {
+    text = fs.readFileSync('analytics/pageviews.json', {encoding: 'utf-8'})
+  }
+  catch (err) {
+    if (err.code !== 'ENOENT') // should check error type
+      throw err
+    text = '{}'
+  }
+  pageviews = JSON.parse(text)
+}
+let pageviews_is_dirty = false
+let pageviews_dirty = () => {
+  if (!pageviews_is_dirty) {
+    pageviews_is_dirty = true
+    setTimeout(pageviews_write, 5000)
+  }
+}
+let pageviews_write = async () => {
+  try {
+    pageviews_is_dirty = false;
+    console.log('writing analytics/pageviews.json')
+    await fs_writeFile(
+      'analytics/pageviews.json',
+      JSON.stringify(pageviews),
+      {encoding: 'utf-8'}
+    )
+  }
+  catch (err) {
+    console.error(err.stack || err.message)
+  }
+}
+
 let build_cache_js = new BuildCache()
 let req_js = async path => {
   let result = await build_cache_js.get(path)
@@ -327,30 +369,7 @@ let app = async (req, res, protocol) => {
     redirect(res, path + (parsed_url.search || ''))
     return
   }
-
-  let cookies = cookie.parse(req.headers.cookie || ''), session
-  if (
-    !cookies.hasOwnProperty('session') ||
-    !sessions.hasOwnProperty(site) ||
-    !sessions[site].hasOwnProperty(session = cookies.session)
-  )
-    session = crypto.randomBytes(16).toString('hex')
-  let expires = new XDate()
-  expires.addMonths(1)
-  expires = expires.toUTCString()
-  res.setHeader(
-    'Set-Cookie',
-    'session=' + session + '; expires=' + expires + '; path=/;'
-  )
-  if (!sessions.hasOwnProperty(site))
-    sessions[site] = {}
-  if (!sessions[site].hasOwnProperty(session))
-    sessions[site][session] = {}
-  sessions[site][session].expires = expires
-  if (!sessions_dirty) {
-    sessions_dirty = true
-    setTimeout(sessions_write, 5000)
-  }
+  let page = path.slice(1).join('/')
 
   temp = file_name.lastIndexOf('.')
   let file_type = temp === -1 ? '' : file_name.substring(temp + 1)
@@ -359,7 +378,52 @@ let app = async (req, res, protocol) => {
     mime_types[file_type] :
     mime_type_default
 
-  let page = dir_name + '/' + file_name, data
+  if (file_type == 'html') {
+    if (!sessions.hasOwnProperty(site))
+      sessions[site] = {}
+    let site_sessions = sessions[site]
+    let cookies = cookie.parse(req.headers.cookie || ''), session_key
+    if (
+      !cookies.hasOwnProperty('session_key') ||
+      !site_sessions.hasOwnProperty(session_key = cookies.session_key)
+    ) {
+      session_key = crypto.randomBytes(16).toString('hex')
+      site_sessions[session_key] = {}
+    }
+    let session = site_sessions[session_key]
+  
+    let expires = new XDate()
+    expires.addMonths(1)
+    expires = expires.toUTCString()
+    res.setHeader(
+      'Set-Cookie',
+      'session_key=' + session_key + '; expires=' + expires + '; path=/;'
+    )
+    session.expires = expires
+
+    if (!pageviews.hasOwnProperty(site))
+      pageviews[site] = {}
+    let site_pageviews = pageviews[site]
+    if (!site_pageviews.hasOwnProperty(page))
+      site_pageviews[page] = {visits: 0, unique_visits: 0}
+    let pageview = site_pageviews[page]
+    ++pageview.visits;
+
+  
+    if (!session.hasOwnProperty('pageviews'))
+      session.pageviews = {}
+    let session_pageviews = session.pageviews
+    if (!session_pageviews.hasOwnProperty(page)) {
+      session_pageviews[page] = 0
+      ++pageview.unique_visits
+    }
+    ++session_pageviews[page]
+
+    sessions_dirty()
+    pageviews_dirty()
+  }
+
+  /*let*/ page = dir_name + '/' + file_name; let data
   if (dir_name_is_pub) {
     try {
       let data = await fs_readFile(site_root + page)