comparison libervia/server/session_iface.py @ 1124:28e3eb3bb217

files reorganisation and installation rework: - files have been reorganised to follow other SàT projects and usual Python organisation (no more "/src" directory) - VERSION file is now used, as for other SàT projects - replace the overcomplicated setup.py be a more sane one. Pyjamas part is not compiled anymore by setup.py, it must be done separatly - removed check for data_dir if it's empty - installation tested working in virtual env - libervia launching script is now in bin/libervia
author Goffi <goffi@goffi.org>
date Sat, 25 Aug 2018 17:59:48 +0200
parents src/server/session_iface.py@cdd389ef97bc
children 2af117bfe6cc
comparison
equal deleted inserted replaced
1123:63a4b8fe9782 1124:28e3eb3bb217
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # Libervia: a SAT frontend
5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org)
6
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 from zope.interface import Interface, Attribute, implements
20 from sat.tools.common import data_objects
21 from libervia.server.constants import Const as C
22 from collections import OrderedDict
23 import os.path
24 import shortuuid
25 import time
26
27 FLAGS_KEY = "_flags"
28 MAX_CACHE_AFFILIATIONS = 100 # number of nodes to keep in cache
29
30
31 class ISATSession(Interface):
32 profile = Attribute("Sat profile")
33 jid = Attribute("JID associated with the profile")
34 uuid = Attribute("uuid associated with the profile session")
35 identities = Attribute("Identities of XMPP entities")
36
37
38 class SATSession(object):
39 implements(ISATSession)
40
41 def __init__(self, session):
42 self.profile = None
43 self.jid = None
44 self.started = time.time()
45 # time when the backend session was started
46 self.backend_started = None
47 self.uuid = unicode(shortuuid.uuid())
48 self.identities = data_objects.Identities()
49 self.csrf_token = unicode(shortuuid.uuid())
50 self.pages_data = {} # used to keep data accross reloads (key is page instance)
51 self.affiliations = OrderedDict() # cache for node affiliations
52
53 @property
54 def cache_dir(self):
55 if self.profile is None:
56 return self.service_cache_url + u"/"
57 return os.path.join(u"/", C.CACHE_DIR, self.uuid) + u"/"
58
59 @property
60 def connected(self):
61 return self.profile is not None
62
63 @property
64 def guest(self):
65 """True if this is a guest session"""
66 if self.profile is None:
67 return False
68 else:
69 return self.profile.startswith("guest@@")
70
71 def getPageData(self, page, key):
72 """get session data for a page
73
74 @param page(LiberviaPage): instance of the page
75 @param key(object): data key
76 return (None, object): value of the key
77 None if not found or page_data doesn't exist
78 """
79 return self.pages_data.get(page, {}).get(key)
80
81 def popPageData(self, page, key, default=None):
82 """like getPageData, but remove key once value is gotten
83
84 @param page(LiberviaPage): instance of the page
85 @param key(object): data key
86 @param default(object): value to return if key is not found
87 @return (object): found value or default
88 """
89 page_data = self.pages_data.get(page)
90 if page_data is None:
91 return default
92 value = page_data.pop(key, default)
93 if not page_data:
94 # no need to keep unused page_data
95 del self.pages_data[page]
96 return value
97
98 def setPageData(self, page, key, value):
99 """set data to persist on reload
100
101 @param page(LiberviaPage): instance of the page
102 @param key(object): data key
103 @param value(object): value to set
104 @return (object): set value
105 """
106 page_data = self.pages_data.setdefault(page, {})
107 page_data[key] = value
108 return value
109
110 def setPageFlag(self, page, flag):
111 """set a flag for this page
112
113 @param page(LiberviaPage): instance of the page
114 @param flag(unicode): flag to set
115 """
116 flags = self.getPageData(page, FLAGS_KEY)
117 if flags is None:
118 flags = self.setPageData(page, FLAGS_KEY, set())
119 flags.add(flag)
120
121 def popPageFlag(self, page, flag):
122 """return True if flag is set
123
124 flag is removed if it was set
125 @param page(LiberviaPage): instance of the page
126 @param flag(unicode): flag to set
127 @return (bool): True if flaag was set
128 """
129 page_data = self.pages_data.get(page, {})
130 flags = page_data.get(FLAGS_KEY)
131 if flags is None:
132 return False
133 if flag in flags:
134 flags.remove(flag)
135 # we remove data if they are not used anymore
136 if not flags:
137 del page_data[FLAGS_KEY]
138 if not page_data:
139 del self.pages_data[page]
140 return True
141 else:
142 return False
143
144 def getAffiliation(self, service, node):
145 """retrieve affiliation for a pubsub node
146
147 @param service(jid.JID): pubsub service
148 @param node(unicode): pubsub node
149 @return (unicode, None): affiliation, or None if it is not in cache
150 """
151 if service.resource:
152 raise ValueError(u"Service must not have a resource")
153 if not node:
154 raise ValueError(u"node must be set")
155 try:
156 affiliation = self.affiliations.pop((service, node))
157 except KeyError:
158 return None
159 else:
160 # we replace at the top to get the most recently used on top
161 # so less recently used will be removed if cache is full
162 self.affiliations[(service, node)] = affiliation
163 return affiliation
164
165 def setAffiliation(self, service, node, affiliation):
166 """cache affiliation for a node
167
168 will empty cache when it become too big
169 @param service(jid.JID): pubsub service
170 @param node(unicode): pubsub node
171 @param affiliation(unicode): affiliation to this node
172 """
173 if service.resource:
174 raise ValueError(u"Service must not have a resource")
175 if not node:
176 raise ValueError(u"node must be set")
177 self.affiliations[(service, node)] = affiliation
178 while len(self.affiliations) > MAX_CACHE_AFFILIATIONS:
179 self.affiliations.popitem(last=False)
180
181
182 class ISATGuestSession(Interface):
183 id = Attribute("UUID of the guest")
184 data = Attribute("data associated with the guest")
185
186
187 class SATGuestSession(object):
188 implements(ISATGuestSession)
189
190 def __init__(self, session):
191 self.id = None
192 self.data = None