|
@@ -6,7 +6,7 @@ import transaction
|
6
|
6
|
from os.path import normpath, dirname, basename
|
7
|
7
|
from tracim.lib.content import ContentApi
|
8
|
8
|
from tracim.lib.webdav import HistoryType
|
9
|
|
-from tracim.lib.webdav import MyFileStream, MyFileStream2
|
|
9
|
+from tracim.lib.webdav import FileStream
|
10
|
10
|
from tracim.lib.user import UserApi
|
11
|
11
|
from tracim.lib.workspace import WorkspaceApi
|
12
|
12
|
from wsgidav import compat
|
|
@@ -26,28 +26,6 @@ _CONTENTS = {
|
26
|
26
|
ContentType.Thread: OtherFile
|
27
|
27
|
}
|
28
|
28
|
|
29
|
|
-def create_readable_date(some_date):
|
30
|
|
- aff = ''
|
31
|
|
-
|
32
|
|
- delta = datetime.now() - some_date
|
33
|
|
-
|
34
|
|
- if delta.days > 0:
|
35
|
|
- if delta.days >= 365:
|
36
|
|
- aff = '%d year%s ago' % (delta.days/365, 's' if delta.days/365>=2 else '')
|
37
|
|
- elif delta.days >= 30:
|
38
|
|
- aff = '%d month%s ago' % (delta.days/30, 's' if delta.days/30>=2 else '')
|
39
|
|
- else:
|
40
|
|
- aff = '%d day%s ago' % (delta.days, 's' if delta.days>=2 else '')
|
41
|
|
- else:
|
42
|
|
- if delta.seconds < 60:
|
43
|
|
- aff = '%d second%s ago' % (delta.seconds, 's' if delta.seconds>1 else '')
|
44
|
|
- elif delta.seconds/60 < 60:
|
45
|
|
- aff = '%d minute%s ago' % (delta.seconds/60, 's' if delta.seconds/60>=2 else '')
|
46
|
|
- else:
|
47
|
|
- aff = '%d hour%s ago' % (delta.seconds/3600, 's' if delta.seconds/3600>=2 else '')
|
48
|
|
-
|
49
|
|
- return aff
|
50
|
|
-
|
51
|
29
|
class Encapsuler(object):
|
52
|
30
|
def __init__(self, type: str, api: ContentApi, content: Content):
|
53
|
31
|
self._api = api
|
|
@@ -69,31 +47,6 @@ class Encapsuler(object):
|
69
|
47
|
|
70
|
48
|
transaction.commit()
|
71
|
49
|
|
72
|
|
-class DummyResource(object):
|
73
|
|
- def __init__(self, file_name: str, content: Content, content_api: ContentApi):
|
74
|
|
- self._file_name = file_name
|
75
|
|
- self._content = content
|
76
|
|
- self._api = content_api
|
77
|
|
-
|
78
|
|
- def beginWrite(self, contentType) -> MyFileStream2:
|
79
|
|
- return MyFileStream2(file_name=self._file_name, content=self._content, content_api=self._api)
|
80
|
|
-
|
81
|
|
- def endWrite(self, withErrors):
|
82
|
|
- pass
|
83
|
|
-
|
84
|
|
-
|
85
|
|
-class DummyResource2(object):
|
86
|
|
- def __init__(self, content: Content, content_api: ContentApi, file_name: str=''):
|
87
|
|
- self._content = content
|
88
|
|
- self._api = content_api
|
89
|
|
- self._file_name = file_name
|
90
|
|
-
|
91
|
|
- def beginWrite(self, contentType) -> MyFileStream:
|
92
|
|
- return MyFileStream(content=self._content, content_api=self._api, file_name=self._file_name)
|
93
|
|
-
|
94
|
|
- def endWrite(self, withErrors: bool):
|
95
|
|
- pass
|
96
|
|
-
|
97
|
50
|
|
98
|
51
|
class Root(DAVCollection):
|
99
|
52
|
def __init__(self, path: str, environ: dict):
|
|
@@ -304,8 +257,13 @@ class Folder(DAVCollection):
|
304
|
257
|
environ=self.environ
|
305
|
258
|
)
|
306
|
259
|
|
307
|
|
- def createEmptyResource(self, file_name: str) -> DummyResource:
|
308
|
|
- return DummyResource(file_name=file_name, content=self._content, content_api=self._api)
|
|
260
|
+ def createEmptyResource(self, file_name: str) -> FileStream:
|
|
261
|
+ return FileStream(
|
|
262
|
+ file_name=file_name,
|
|
263
|
+ content=self._content,
|
|
264
|
+ content_api=self._api,
|
|
265
|
+ new_file=True
|
|
266
|
+ )
|
309
|
267
|
|
310
|
268
|
def createCollection(self, label: str) -> Folder:
|
311
|
269
|
|
|
@@ -687,11 +645,17 @@ class HistoryFileFolder(HistoryFolder):
|
687
|
645
|
def createCollection(self, name):
|
688
|
646
|
raise DAVError(HTTP_FORBIDDEN)
|
689
|
647
|
|
690
|
|
- def createEmptyResource(self, name) -> DummyResource2:
|
691
|
|
- return DummyResource2(content=self._content, content_api=self._api, file_name=name)
|
|
648
|
+ def createEmptyResource(self, name) -> FileStream:
|
|
649
|
+ return FileStream(
|
|
650
|
+ content=self._content,
|
|
651
|
+ content_api=self._api,
|
|
652
|
+ file_name=name,
|
|
653
|
+ new_file=False
|
|
654
|
+ )
|
692
|
655
|
|
693
|
656
|
def getMemberNames(self) -> [str]:
|
694
|
|
- return [content.revision_id for content in self._content.revisions]
|
|
657
|
+ return [content.revision_id for content in self._content.revisions \
|
|
658
|
+ if content.revision_type in [ActionDescription.CREATION, ActionDescription.EDITION, ActionDescription.REVISION]]
|
695
|
659
|
|
696
|
660
|
def getMember(self, item_id) -> DAVCollection:
|
697
|
661
|
|
|
@@ -883,7 +847,7 @@ class OtherFile(File):
|
883
|
847
|
histHTML = '<table class="table table-striped table-hover">'
|
884
|
848
|
for event in hist:
|
885
|
849
|
if isinstance(event, VirtualEvent):
|
886
|
|
- date = create_readable_date(event.created)
|
|
850
|
+ date = event.create_readable_date()
|
887
|
851
|
_LABELS = {
|
888
|
852
|
'archiving': 'Item archived',
|
889
|
853
|
'content-comment': 'Item commented',
|
|
@@ -995,7 +959,7 @@ class OtherFile(File):
|
995
|
959
|
%s
|
996
|
960
|
</div>
|
997
|
961
|
</div>
|
998
|
|
- ''' % (t.owner.display_name, create_readable_date(t.created), t.description)
|
|
962
|
+ ''' % (t.owner.display_name, t.create_readable_date(), t.description)
|
999
|
963
|
|
1000
|
964
|
if t.owner.display_name not in participants:
|
1001
|
965
|
participants[t.owner.display_name] = [1, t.created]
|
|
@@ -1032,19 +996,10 @@ class OtherFile(File):
|
1032
|
996
|
</div>
|
1033
|
997
|
''' % (t.type.icon,
|
1034
|
998
|
t.owner.display_name,
|
1035
|
|
- create_readable_date(t.created),
|
|
999
|
+ t.create_readable_date(),
|
1036
|
1000
|
label,
|
1037
|
1001
|
'''<span><a href="#">(View revision)</a></span>''' if t.type.id == 'revision' else '')
|
1038
|
1002
|
|
1039
|
|
- descP = ''
|
1040
|
|
- for name, infos in participants.items():
|
1041
|
|
- descP = '''
|
1042
|
|
- <div><b>%s</b> - %d message%s - last %s</div>
|
1043
|
|
- ''' % (name,
|
1044
|
|
- infos[0],
|
1045
|
|
- 's' if infos[0]>1 else '',
|
1046
|
|
- create_readable_date(infos[1]))
|
1047
|
|
-
|
1048
|
1003
|
page = '''
|
1049
|
1004
|
<html>
|
1050
|
1005
|
<head>
|
|
@@ -1055,7 +1010,7 @@ class OtherFile(File):
|
1055
|
1010
|
<script type="text/javascript" src="/home/arnaud/Documents/css/script.js"></script>
|
1056
|
1011
|
</head>
|
1057
|
1012
|
<body>
|
1058
|
|
- <div id="left" class="col-lg-8 col-md-12 col-sm-12 col-xs-12">
|
|
1013
|
+ <div id="left" class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
1059
|
1014
|
<div class="title thread">
|
1060
|
1015
|
<div class="title-text">
|
1061
|
1016
|
<i class="fa fa-comments-o title-icon thread"></i>
|
|
@@ -1080,10 +1035,6 @@ class OtherFile(File):
|
1080
|
1035
|
%s
|
1081
|
1036
|
</div>
|
1082
|
1037
|
</div>
|
1083
|
|
- <div id="right" class="col-lg-4 col-md-12 col-sm-12 col-xs-12">
|
1084
|
|
- <h4>Participants</h4>
|
1085
|
|
- %s
|
1086
|
|
- </div>
|
1087
|
1038
|
</body>
|
1088
|
1039
|
</html>
|
1089
|
1040
|
''' % (content.label,
|
|
@@ -1091,8 +1042,7 @@ class OtherFile(File):
|
1091
|
1042
|
self._content.created.strftime("%B %d, %Y at %H:%m"),
|
1092
|
1043
|
self._content.owner.display_name,
|
1093
|
1044
|
content.description,
|
1094
|
|
- disc,
|
1095
|
|
- descP)
|
|
1045
|
+ disc)
|
1096
|
1046
|
|
1097
|
1047
|
return page
|
1098
|
1048
|
|