106b253385e0190527f12799f4c3f889da7f782f
[ndcode_site.git] / page.jst
1 let XDate = require('xdate')
2 let cookie = require('cookie')
3 let crypto = require('crypto')
4
5 return async (env, head, body, scripts) => {
6   let favicons = await env.site.get_min_html('/_favicon/favicons.html')
7   let globals = await env.site.get_json('/_config/globals.json')
8
9   let transaction = env.site.database.Transaction()
10   let root = await transaction.get(transaction.LazyObject())
11   let sessions = await root.get('sessions', transaction.LazyObject())
12   let pageviews = await root.get('pageviews', transaction.LazyObject())
13
14   let cookies = cookie.parse(env.request.headers.cookie || '')
15   let session_key =
16     Object.prototype.hasOwnProperty.call(cookies, 'session_key') ?
17       cookies.session_key :
18       crypto.randomBytes(16).toString('hex')
19   let session = await sessions.get(session_key, transaction.LazyObject())
20     
21   let expires = new XDate()
22   expires.addMonths(1)
23   session.set('expires', expires.toUTCString())
24   env.response.setHeader(
25     'Set-Cookie',
26     'session_key=' +
27     session_key +
28     '; expires=' +
29     session.expires +
30     '; path=/;'
31   )
32
33   let pageview = await pageviews.get(
34     env.parsed_url.pathname,
35     transaction.LazyObject()
36   )
37   pageview.set(
38     'visits',
39     (await pageview.get('visits') || 0) + 1
40   )
41
42   let session_pageviews = await session.get(
43     'pageviews',
44     transaction.LazyObject()
45   )
46   let i = await session_pageviews.get(env.parsed_url.pathname)
47   if (i === undefined) {
48     pageview.set(
49       'unique_visits',
50       (await pageview.get('unique_visits') || 0) + 1
51     )
52     i = 0
53   }
54   session_pageviews.set(env.parsed_url.pathname, i + 1)
55
56   await transaction.commit()
57
58   let _out = []
59   _out.push('<!DOCTYPE html>')
60   html(lang="en") {
61     head {
62       meta(charset="utf-8") {}
63       meta(http-equiv="X-UA-Compatible" content="IE=edge") {}
64       meta(name="viewport" content="width=device-width,initial-scale=1") {}
65       // The above 3 meta tags *must* come first in the head;
66       // any other head content must come *after* these tags
67   
68       link(rel="stylesheet" href="/css/bootstrap.css") {}
69       link(rel="stylesheet" href="//fonts.googleapis.com/css?family=Frank+Ruhl+Libre:regular,regularitalic,semibold,semibolditalic,bold,bolditalic,black,blackitalic") {}
70       link(rel="stylesheet" href="//fonts.googleapis.com/css?family=Nunito+Sans:regular,regularitalic,semibold,semibolditalic,bold,bolditalic,black,blackitalic") {}
71   
72       await head(_out)
73
74       // HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries
75       // WARNING: Respond.js doesn't work if you view the page via file://
76       _out.push('<!--[if lt IE 9]>')
77       script(src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js") {}
78       script(src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js") {}
79       _out.push('<![endif]-->')
80
81       // use favicon generator website to get favicons.zip and favicons.html
82       _out.push(favicons)
83     }
84     body {
85       await body(_out)
86   
87       // jQuery (necessary for Bootstrap's JavaScript plugins)
88       script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js") {}
89       // Include all compiled plugins (below), or include individual files as needed
90       //script(src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous") {}
91       script(src="/js/bootstrap.js") {}
92
93       await scripts(_out)
94     }
95   }
96   env.site.serve(env, 200, Buffer.from(_out.join('')), 'page.jst')
97 }