PaferaPy Async 0.1
ASGI framework focused on simplicity and efficiency
Loading...
Searching...
No Matches
session.py
Go to the documentation of this file.
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4import time
5import datetime
6
7from pafera.types import *
8from pafera.validators import *
9
11
12# Flags for the session object
13SESSION_EXPIRED = 0x01
14
15# *********************************************************************
16# Bootstrap class for the database.
18 """Tracker for the various types of programs that visit the site.
19 Note that this will not track every single visitor since sessions
20 depend on JavaScript being enabled to load sessionvars.js, but can
21 be a good approximation of human visits.
22 """
23
24 _dbfields = {
25 'id': ('INTEGER PRIMARY KEY AUTOINCREMENT', 'NOT NULL',),
26 'header': ('TEXT', 'NOT NULL', BlankValidator()),
27 'platform': ('TEXT', "NOT NULL DEFAULT ''", ),
28 'browser': ('TEXT', "NOT NULL DEFAULT ''", ),
29 'version': ('TEXT', "NOT NULL DEFAULT ''", ),
30 'flags': ('INT', 'NOT NULL DEFAULT 0',),
31 }
32 _dbindexes = (
33 )
34 _dblinks = []
35 _dbdisplay = ['platform', 'browser', 'version']
36 _dbflags = 0
37
38 # -------------------------------------------------------------------
39 def __init__(self):
40 super().__init__()
41
42# *********************************************************************
44 """Keeps track of user sessions, language selection, and application
45 data.
46
47 This class also has the ability to record every URL that the user
48 visited and how long they stayed on that page if
49 g.siteconfig['urltracking'] is enabled. It makes the system a bit
50 slower, but gives you much better analysis of what the user did and
51 what they were interested in.
52 """
53
54 _dbfields = {
55 'rbid': ('BIGINT PRIMARY KEY', 'NOT NULL',),
56 'userid': ('INT', 'NOT NULL DEFAULT 0',),
57 'useragentid': ('INT', 'NOT NULL',),
58 'length': ('INT', 'NOT NULL DEFAULT 0',),
59 'flags': ('INT', 'NOT NULL DEFAULT 0',),
60 'ip': ('TEXT', 'NOT NULL', BlankValidator()),
61 'lang': ('TEXT', 'NOT NULL', BlankValidator()),
62 'langcodes': ('LIST', 'NOT NULL', BlankValidator()),
63 'data': ('DICT', "NOT NULL DEFAULT ''",),
64 'starttime': ('DATETIME', 'NOT NULL',),
65 'endtime': ('DATETIME', 'NOT NULL DEFAULT 0',),
66 'urls': ('LIST', "NOT NULL DEFAULT ''",),
67 }
68 _dbindexes = (
69 )
70 _dblinks = []
71 _dbdisplay = ['userid', 'length', 'lang', 'starttime']
72 _dbflags = 0
73
74 # -------------------------------------------------------------------
75 def __init__(self):
76 super().__init__()
77
78 self.data = {}
79 self.urls = []
80 self.needupdate = 0
81
82 # -------------------------------------------------------------------
83 def CheckExpired(self, g):
84 """See if the current session has expired and creates a new one if
85 necessary.
86 """
87 currenttime = time.time()
88
89 if currenttime > self.endtime.timestamp() + IntV(g.siteconfig, 'sessiontimeout', 600, 2678400, 604800):
90 self.New(g)
91 '''with open('expired.log', 'a+') as f:
92 f.write(f""">>> Session {self.rbid} expired:
93 User ID:\t{g.session.userid}
94 Current Time:\t{currenttime}
95 End Time:\t{self.endtime.timestamp()}
96 Length:\t{currenttime - self.starttime.timestamp()}
97 Session Timeout:\t{IntV(g.siteconfig, 'sessiontimeout', 600, 2678400, 604800)}\n""")
98 '''
99
100 # -------------------------------------------------------------------
101 def New(self, g):
102 """Creates a new session, closing the old session.
103
104 This also setups the useragent, languages, and other default settings.
105 """
106 currenttime = time.time()
107
108 if self.rbid:
109 self.Set(
110 endtime = currenttime,
111 length = currenttime - self.starttime.timestamp(),
112 flags = SESSION_EXPIRED,
113 )
114 g.db.Update(self)
115 g.db.Commit()
116
117 self.Set(
118 rbid = 0,
119 userid = 0,
120 )
121
122 req = g.request
123 ua = g.request.user_agent
124
125 useragent = g.db.Find(system_useragent, 'WHERE header = ?', ua.string)
126
127 # Some testing tools don't provide platform, browser, and such.
128 # Therefore, we use blank values instead.
129 if not useragent:
130 useragent = system_useragent()
131 useragent.Set(
132 header = ua.string,
133 platform = ua.platform if ua.platform else '',
134 browser = ua.browser if ua.browser else '',
135 version = ua.version if ua.version else '',
136 flags = 0,
137 )
138 g.db.Insert(useragent)
139 g.db.Commit()
140 else:
141 useragent = useragent[0]
142
143 lang = req.accept_languages.best_match(g.siteconfig['languages'])
144
145 if not lang:
146 lang = 'en'
147
148 langcodes = list(g.request.accept_languages.values())
149
150 if not langcodes:
151 langcodes = ['en']
152
153 self.Set(
154 userid = 0,
155 useragentid = useragent.id,
156 ip = req.environ['HTTP_X_FORWARDED_FOR'] if req.environ.get('HTTP_X_FORWARDED_FOR') else req.environ['REMOTE_ADDR'],
157 lang = lang,
158 langcodes = langcodes,
159 length = 0,
160 starttime = currenttime,
161 endtime = currenttime,
162 flags = 0,
163 urls = [],
164 data = {
165 'texttheme': 'default',
166 'wallpaper': 'blue',
167 'usericon': '',
168 'groups': [],
169 },
170 )
171
172 g.db.Insert(self)
173 g.db.Commit()
174
175 # -------------------------------------------------------------------
176 def __getitem__(self, key):
177 """Convenience functions to allow the session object to be used as
178 a dict that saves settings at the end of the script.
179 """
180
181 if key in self.data:
182 return self.data[key]
183
184 return None
185
186 # -------------------------------------------------------------------
187 def __setitem__(self, key, value):
188 """Convenience functions to allow the session object to be used as
189 a dict that saves settings at the end of the script.
190 """
191 if key in self.data:
192 if self.data[key] == value:
193 return
194
195 self.data[key] = value
196 self._datachanged = 1
197
198 # -------------------------------------------------------------------
199 def __delitem__(self, key):
200 """Convenience functions to allow the session object to be used as
201 a dict that saves settings at the end of the script.
202 """
203 if key in self.data:
204 del self.data[key]
205
206 # -------------------------------------------------------------------
207 def get(self, key, defaultvalue = None):
208 """Convenience functions to allow the session object to be used as
209 a dict that saves settings at the end of the script.
210 """
211 return self.data.get(key, defaultvalue)
Base class for all database models.
Definition: modelbase.py:20
def Set(self, **kwargs)
We use this method instead of direct attribute access in order to keep track of what values have been...
Definition: modelbase.py:115
Throws an exception on blank values.
Definition: validators.py:43
Keeps track of user sessions, language selection, and application data.
Definition: session.py:43
def CheckExpired(self, g)
See if the current session has expired and creates a new one if necessary.
Definition: session.py:83
def __delitem__(self, key)
Convenience functions to allow the session object to be used as a dict that saves settings at the end...
Definition: session.py:199
def New(self, g)
Creates a new session, closing the old session.
Definition: session.py:101
def __init__(self)
Initialize all fields at creation like a good programmer should.
Definition: session.py:75
def __getitem__(self, key)
Convenience functions to allow the session object to be used as a dict that saves settings at the end...
Definition: session.py:176
def get(self, key, defaultvalue=None)
Convenience functions to allow the session object to be used as a dict that saves settings at the end...
Definition: session.py:207
def __setitem__(self, key, value)
Convenience functions to allow the session object to be used as a dict that saves settings at the end...
Definition: session.py:187
Tracker for the various types of programs that visit the site.
Definition: session.py:17
def __init__(self)
Initialize all fields at creation like a good programmer should.
Definition: session.py:39
def IntV(d, k, min=None, max=None, default=0)
Utility function to get an int from a dict or object given its name.
Definition: types.py:169