|
@@ -9,6 +9,7 @@ from hashlib import sha256
|
9
|
9
|
import bs4
|
10
|
10
|
from sqlalchemy import Table, ForeignKey, Column, Sequence
|
11
|
11
|
from sqlalchemy.types import Unicode, Integer, DateTime, Text, LargeBinary
|
|
12
|
+import sqlalchemy.types as sqlat
|
12
|
13
|
from sqlalchemy.orm import relation, synonym, relationship
|
13
|
14
|
from sqlalchemy.orm import backref
|
14
|
15
|
import sqlalchemy.orm as sqlao
|
|
@@ -18,40 +19,7 @@ from tg.i18n import ugettext as _, lazy_ugettext as l_
|
18
|
19
|
|
19
|
20
|
import tg
|
20
|
21
|
from pboard.model import DeclarativeBase, metadata, DBSession
|
21
|
|
-
|
22
|
|
-# This is the association table for the many-to-many relationship between
|
23
|
|
-# groups and permissions.
|
24
|
|
-"""pod_node_table = Table('pod_nodes', metadata,
|
25
|
|
- Column('node_id', Integer, Sequence('pod_nodes__node_id__sequence'), primary_key=True),
|
26
|
|
- Column('parent_id', Integer, ForeignKey('pod_nodes.node_id'), nullable=True, default=None),
|
27
|
|
- Column('node_order', Integer, nullable=True, default=1),
|
28
|
|
- Column('node_type', Unicode(16), unique=False, nullable=False, default='data'),
|
29
|
|
- Column('node_status', Unicode(16), unique=False, nullable=False, default='new'),
|
30
|
|
-
|
31
|
|
- Column('created_at', DateTime, unique=False, nullable=False),
|
32
|
|
- Column('updated_at', DateTime, unique=False, nullable=False),
|
33
|
|
-
|
34
|
|
- Column('data_label', Unicode(1024), unique=False, nullable=False, default=''),
|
35
|
|
- Column('data_content', Text(), unique=False, nullable=False, default=''),
|
36
|
|
- Column('data_datetime', DateTime, unique=False, nullable=False),
|
37
|
|
- Column('data_reminder_datetime', DateTime, unique=False, nullable=True),
|
38
|
|
-
|
39
|
|
- Column('data_file_name', Unicode(255), unique=False, nullable=False, default=''),
|
40
|
|
- Column('data_file_mime_type', Unicode(255), unique=False, nullable=False, default=''),
|
41
|
|
- Column('data_file_content', LargeBinary(), unique=False, nullable=False, default=None),
|
42
|
|
-)
|
43
|
|
-"""
|
44
|
|
-"""
|
45
|
|
-- node_type
|
46
|
|
-
|
47
|
|
-- node_created_at
|
48
|
|
-- node_updated_at
|
49
|
|
-
|
50
|
|
-- data_label
|
51
|
|
-- data_content
|
52
|
|
-- data_source_url
|
53
|
|
-- data_status_id
|
54
|
|
-"""
|
|
22
|
+from pboard.model import auth as pma
|
55
|
23
|
|
56
|
24
|
class PBNodeStatusItem(object):
|
57
|
25
|
def __init__(self, psStatusId, psStatusLabel, psStatusFamily, psIconId, psCssClass): #, psBackgroundColor):
|
|
@@ -143,8 +111,7 @@ class PBNodeStatus(object):
|
143
|
111
|
PBNodeStatus.StatusList['closed'],
|
144
|
112
|
PBNodeStatus.StatusList['deleted']
|
145
|
113
|
]
|
146
|
|
-
|
147
|
|
- PBNodeStatus.StatusList.values()
|
|
114
|
+
|
148
|
115
|
|
149
|
116
|
@classmethod
|
150
|
117
|
def getStatusItem(cls, psStatusId):
|
|
@@ -182,6 +149,7 @@ class PBNode(DeclarativeBase):
|
182
|
149
|
return len(self._lStaticChildList)
|
183
|
150
|
|
184
|
151
|
__tablename__ = 'pod_nodes'
|
|
152
|
+
|
185
|
153
|
node_id = Column(Integer, Sequence('pod_nodes__node_id__sequence'), primary_key=True)
|
186
|
154
|
parent_id = Column(Integer, ForeignKey('pod_nodes.node_id'), nullable=True, default=None)
|
187
|
155
|
node_depth = Column(Integer, unique=False, nullable=False, default=0)
|
|
@@ -195,6 +163,21 @@ class PBNode(DeclarativeBase):
|
195
|
163
|
created_at = Column(DateTime, unique=False, nullable=False)
|
196
|
164
|
updated_at = Column(DateTime, unique=False, nullable=False)
|
197
|
165
|
|
|
166
|
+ """
|
|
167
|
+ if 1, the document is available for other users logged into pod.
|
|
168
|
+ default is 0 (private document)
|
|
169
|
+ """
|
|
170
|
+ is_shared = Column(sqlat.Boolean, unique=False, nullable=False, default=False)
|
|
171
|
+ """
|
|
172
|
+ if 1, the document is available through a public - but obfuscated, url
|
|
173
|
+ default is 0 (document not publicly available)
|
|
174
|
+ """
|
|
175
|
+ is_public = Column(sqlat.Boolean, unique=False, nullable=False, default=False)
|
|
176
|
+ """
|
|
177
|
+ here is the hash allowing to get the document publicly
|
|
178
|
+ """
|
|
179
|
+ public_url_key = Column(Unicode(1024), unique=False, nullable=False, default='')
|
|
180
|
+
|
198
|
181
|
data_label = Column(Unicode(1024), unique=False, nullable=False, default='')
|
199
|
182
|
data_content = Column(Text(), unique=False, nullable=False, default='')
|
200
|
183
|
|
|
@@ -207,6 +190,7 @@ class PBNode(DeclarativeBase):
|
207
|
190
|
|
208
|
191
|
|
209
|
192
|
_oParent = relationship('PBNode', remote_side=[node_id], backref='_lAllChildren')
|
|
193
|
+ _oOwner = relationship('User', remote_side=[pma.User.user_id], backref='_lAllNodes')
|
210
|
194
|
|
211
|
195
|
def getChildrenOfType(self, plNodeTypeList, poKeySortingMethod=None, pbDoReverseSorting=False):
|
212
|
196
|
"""return all children nodes of type 'data' or 'node' or 'folder'"""
|
|
@@ -230,9 +214,15 @@ class PBNode(DeclarativeBase):
|
230
|
214
|
def getChildNb(self):
|
231
|
215
|
return self.getChildNbOfType([PBNodeType.Data])
|
232
|
216
|
|
233
|
|
- def getChildren(self):
|
|
217
|
+ def getChildren(self, pbIncludeDeleted=False):
|
234
|
218
|
"""return all children nodes of type 'data' or 'node' or 'folder'"""
|
235
|
|
- return self.getChildrenOfType([PBNodeType.Node, PBNodeType.Folder, PBNodeType.Data])
|
|
219
|
+ # return self.getChildrenOfType([PBNodeType.Node, PBNodeType.Folder, PBNodeType.Data])
|
|
220
|
+ items = self.getChildrenOfType([PBNodeType.Node, PBNodeType.Folder, PBNodeType.Data])
|
|
221
|
+ items2 = list()
|
|
222
|
+ for item in items:
|
|
223
|
+ if pbIncludeDeleted==True or item.node_status!='deleted':
|
|
224
|
+ items2.append(item)
|
|
225
|
+ return items2
|
236
|
226
|
|
237
|
227
|
def getContacts(self):
|
238
|
228
|
"""return all children nodes of type 'data' or 'node' or 'folder'"""
|
|
@@ -343,13 +333,23 @@ class PBNode(DeclarativeBase):
|
343
|
333
|
break
|
344
|
334
|
return PBNodeStatus.getStatusItem(lsRealStatusId)
|
345
|
335
|
|
346
|
|
- def getTruncatedLabel(self, piCharNb):
|
347
|
|
- lsTruncatedLabel = ''
|
|
336
|
+ def getTruncatedLabel(self: PBNode, piCharNb: int):
|
|
337
|
+ """
|
|
338
|
+ return a truncated version of the data_label property.
|
|
339
|
+ if piCharNb is not > 0, then the full data_label is returned
|
|
340
|
+ note: if the node is a file and the data_label is empty, the file name is returned
|
|
341
|
+ """
|
|
342
|
+ lsTruncatedLabel = self.data_label
|
|
343
|
+
|
|
344
|
+ # 2014-05-06 - D.A. - HACK
|
|
345
|
+ # if the node is a file and label empty, then use the filename as data_label
|
|
346
|
+ if self.node_type==PBNodeType.File and lsTruncatedLabel=='':
|
|
347
|
+ lsTruncatedLabel = self.data_file_name
|
|
348
|
+
|
348
|
349
|
liMaxLength = int(piCharNb)
|
349
|
|
- if len(self.data_label)>liMaxLength:
|
350
|
|
- lsTruncatedLabel = self.data_label[0:liMaxLength-1]+'…'
|
351
|
|
- else:
|
352
|
|
- lsTruncatedLabel = self.data_label
|
|
350
|
+ if liMaxLength>0 and len(lsTruncatedLabel)>liMaxLength:
|
|
351
|
+ lsTruncatedLabel = lsTruncatedLabel[0:liMaxLength-1]+'…'
|
|
352
|
+
|
353
|
353
|
return lsTruncatedLabel
|
354
|
354
|
|
355
|
355
|
def getTruncatedContentAsText(self, piCharNb):
|
|
@@ -387,29 +387,3 @@ class PBNode(DeclarativeBase):
|
387
|
387
|
# Does not match @@ at end of content.
|
388
|
388
|
|
389
|
389
|
|
390
|
|
-
|
391
|
|
-"""from sqlalchemy.orm import mapper
|
392
|
|
-mapper(
|
393
|
|
- PBNode,
|
394
|
|
- pod_node_table,
|
395
|
|
- properties = {'_lAllChildren' : relationship(PBNode, backref=backref('_oParent', remote_side=PBNode.parent_id)) }
|
396
|
|
-)"""
|
397
|
|
-
|
398
|
|
-
|
399
|
|
-
|
400
|
|
-""" children = relationship('TreeNode',
|
401
|
|
-
|
402
|
|
- # cascade deletions
|
403
|
|
- cascade="all",
|
404
|
|
-
|
405
|
|
- # many to one + adjacency list - remote_side
|
406
|
|
- # is required to reference the 'remote'
|
407
|
|
- # column in the join condition.
|
408
|
|
- backref=backref("parent", remote_side='TreeNode.id'),
|
409
|
|
-
|
410
|
|
- # children will be represented as a dictionary
|
411
|
|
- # on the "name" attribute.
|
412
|
|
- collection_class=attribute_mapped_collection('name'),
|
413
|
|
- )
|
414
|
|
-"""
|
415
|
|
-
|