Skip to content

Commit 4b118d0

Browse files
rootroot
authored andcommitted
version 0.2.0 - In Nextcloud the successive versions will be stored
1 parent b8303c1 commit 4b118d0

File tree

4 files changed

+152
-41
lines changed

4 files changed

+152
-41
lines changed

opt - Acceso directo.lnk

100644100755
File mode changed.

pibiapp/hooks.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@
8989

9090
doc_events = {
9191
"File": {
92+
"before_insert": "pibiapp.nextcloud.nextcloud_link.nextcloud_before_insert",
9293
"after_insert": "pibiapp.nextcloud.nextcloud_link.nextcloud_insert",
94+
"on_trash": "pibiapp.nextcloud.nextcloud_link.nextcloud_before_delete",
9395
"after_delete": "pibiapp.nextcloud.nextcloud_link.nextcloud_delete"
9496
}
9597
}

pibiapp/nextcloud/nextcloud_apis.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, Dolores Juliana Fdez Martin
1+
# Copyright (c) 2018-2019, Dolores Juliana Fdez Martin
22
# License: GNU General Public License v3. See license.txt
33
#
44
# This file is part of Pibiapp_Nextcloud.
@@ -110,7 +110,7 @@ def mkdirs(self, nc_path):
110110
self.cd(old_cwd)
111111

112112
def delete(self, path):
113-
self.command('DELETE', path, 204)
113+
self.command('DELETE', path, (204, 404))
114114

115115
def upload(self, local_fileobj, remote_fileobj, nc_path="." ):
116116
if nc_path != ".":
@@ -155,7 +155,36 @@ def gettag(self, idtag):
155155
return root[0][1][0][0].text
156156
else:
157157
return ''
158-
158+
159+
def deletetags(self, idfile, nodelete):
160+
method='PROPFIND'
161+
url = self.baseurl.replace("webdav","dav") + "/systemtags-relations/files/" + str(idfile)
162+
headers = {"Content-Type": "text/xml" }
163+
fullpath = os.path.realpath(__file__).replace("nextcloud_apis.py","tagpropfind.xml")
164+
fullpath = fullpath.replace('xmlc','xml')
165+
xmlfile = open(fullpath,"r")
166+
data = xmlfile.read()
167+
xmlfile.close()
168+
response = self.session.request(method, url, headers=headers, data=data, allow_redirects=False)
169+
if response.status_code >= 400: return ''
170+
root = ET.fromstring(response.content)
171+
i = 1
172+
while i < len(root):
173+
tag = root[i][1][0][0].text
174+
if not tag in nodelete:
175+
idtag = root[i][1][0][3].text
176+
status_code = self.deletetag(idfile, idtag)
177+
if status_code >= 400: break
178+
i += 1
179+
return
180+
181+
def deletetag(self, idfile, idtag):
182+
method='DELETE'
183+
url = self.baseurl.replace("webdav","dav") + "/systemtags-relations/files/" + str(idfile) + "/" + str(idtag)
184+
headers = {"Content-Type": "text/xml" }
185+
response = self.session.request(method, url, headers=headers)
186+
return response.status_code
187+
159188
class OCS():
160189
def __init__(self, ncurl, user, passwd, js=False):
161190
self.tojs = "?format=json" if js else ""
@@ -213,7 +242,7 @@ def addGroup(self,gid):
213242
return self.post(url,msg)
214243

215244
def createShare(self,path,shareType,shareWith=None,publicUpload=None,password=None,permissions=None):
216-
url = self.Share_url + "/shares"+self.tojs
245+
url = self.Share_url + "/shares" + self.tojs
217246
if publicUpload == True: publicUpload = "true"
218247
if (path == None or isinstance(shareType, int) != True) or (shareType in [0,1] and shareWith == None): return False
219248
msg = {"path":path,"shareType":shareType}

pibiapp/nextcloud/nextcloud_link.py

Lines changed: 117 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, Dolores Juliana Fdez Martin
1+
# Copyright (c) 2018-2019, Dolores Juliana Fdez Martin
22
# License: GNU General Public License v3. See license.txt
33
#
44
# This file is part of Pibiapp_Nextcloud.
@@ -23,10 +23,12 @@
2323
import requests
2424
from json import dumps
2525
from frappe.modules.utils import get_doctype_module, get_module_app
26+
from frappe.desk.tags import DocTags
2627
from pibiapp.nextcloud import nextcloud_apis
2728
import json
2829
import os
2930
import time
31+
import sys
3032

3133
class nextcloud_link():
3234
def __init__(self):
@@ -56,13 +58,9 @@ def __init__(self):
5658

5759
def tagging(self, doc, idfile, relational):
5860
self.actualizetags()
59-
doctype = doc.attached_to_doctype
60-
module = get_doctype_module(doctype)
61-
name = doc.attached_to_name
62-
self.puttag( doctype, idfile)
63-
self.puttag( module, idfile)
64-
self.puttag( name, idfile)
65-
if relational: self.relationaltags(doctype, name, idfile)
61+
lista = self.listtags(doc, idfile, relational)
62+
for display_name in lista:
63+
self.puttag( display_name, idfile)
6664

6765
def puttag(self, display_name, idfile):
6866
idtag = self.searchtag( display_name)
@@ -107,68 +105,150 @@ def inserttag(self, idtag, display_name):
107105
def relationaltags(self, doctype, name, idfile):
108106
docntrans = frappe.get_doc(doctype, name)
109107
meta = frappe.get_meta(doctype)
108+
lista = ""
110109
for lf in meta.get_link_fields():
111-
name = docntrans.get(lf.fieldname)
112-
if name != "" and name != None:
113-
self.puttag( name, idfile)
110+
tag = docntrans.get(lf.fieldname)
111+
if tag != "" and tag != None:
112+
lista = lista + " # " + tag
113+
lista = lista + DocTags(doctype).get_tags(name).replace("," , " # ")
114+
return lista
115+
116+
def deletetags(self, doc, idfile, relational=True):
117+
lista = self.listtags(doc, idfile, relational)
118+
status_code = self.webdav.deletetags(idfile, nodelete=lista)
119+
120+
def listtags(self, doc, idfile, relational):
121+
doctype = doc.attached_to_doctype
122+
module = get_doctype_module(doctype)
123+
name = doc.attached_to_name
124+
lista = doctype + " # " + module + " # " + name
125+
if relational: lista = lista + self.relationaltags(doctype, name, idfile)
126+
return lista.split(" # ")
127+
128+
def shareModule(self, doc):
129+
# add group for module
130+
data_json = doc.nc.ocs.getGroup(doc.nc.module)
131+
data_string = json.dumps(data_json)
132+
decoded = json.loads(data_string)
133+
isgroup = str(decoded["ocs"]["meta"]["statuscode"])
134+
if isgroup == '404':
135+
data_json = doc.nc.ocs.addGroup(doc.nc.module)
136+
# add Share group in Nextcloud
137+
shareType = 1
138+
permit = 1
139+
data_json = doc.nc.ocs.createShare(doc.nc.pathglobal,shareType,shareWith=doc.nc.module,publicUpload=True,password=None,permissions=permit)
140+
return data_json
141+
114142

115143
@frappe.whitelist()
116-
def nextcloud_insert(doc, method=None):
144+
def nextcloud_before_insert(doc, method=None):
145+
doc.flags.ignore_nc = True
117146
nc = nextcloud_link()
118147
if not nc.isconnect: return
148+
doc.flags.ignore_file_validate = True
119149
doctype = doc.attached_to_doctype
120150
module = get_doctype_module(doctype)
121151
# Excluded module
122152
if module in nc.excludedmodules: return
153+
# File previously attached to another transaction
154+
if not doc.file_name or doc.file_name == None: return
155+
if " NC/f/" in doc.file_name: return
156+
doc.flags.ignore_nc = False
123157
site = frappe.local.site
124158
if doc.is_private: local_fileobj = "./" + site + doc.file_url
125159
else: local_fileobj = "./" + site + "/public" + doc.file_url
126160
fileobj = local_fileobj.split('/')
127161
uu = len(fileobj) - 1
128-
# get path
129-
app = get_module_app(module)
130-
path = nc.initialpath + "/" + app + "/" + module + "/" + doctype
131-
pathglobal = path + "/" + fileobj[uu]
162+
doc.nc = nc
163+
doc.nc.module = module
164+
doc.nc.app = get_module_app(module)
165+
doc.nc.path = nc.initialpath + "/" + doc.nc.app + "/" + module + "/" + doctype
166+
doc.nc.pathglobal = doc.nc.path + "/" + fileobj[uu]
167+
doc.nc.local_fileobj = local_fileobj
168+
doc.nc.remote_fileobj=fileobj[uu]
169+
170+
171+
@frappe.whitelist()
172+
def nextcloud_insert(doc, method=None):
173+
if doc.flags.ignore_nc: return
132174
# upload to nextcloud
133-
nc.webdav.upload(local_fileobj, remote_fileobj=fileobj[uu], nc_path=path)
134-
# add group for module
135-
data_json = nc.ocs.getGroup(module)
136-
data_string = json.dumps(data_json)
137-
decoded = json.loads(data_string)
138-
isgroup = str(decoded["ocs"]["meta"]["statuscode"])
139-
if isgroup == '404':
140-
data_json = nc.ocs.addGroup(module)
141-
# add Share group in Nextcloud
142-
shareType = 1
143-
permit = 1
144-
data_json = nc.ocs.createShare(pathglobal,shareType,shareWith=module,publicUpload=True,password=None,permissions=permit)
175+
if not "http" in doc.nc.local_fileobj:
176+
doc.nc.webdav.upload(local_fileobj=doc.nc.local_fileobj, remote_fileobj=doc.nc.remote_fileobj, nc_path=doc.nc.path)
177+
else:
178+
data = frappe.db.get_value("File", {"file_url": doc.file_url , "file_name": ["like", "%NC/f/%"]}, ["attached_to_doctype", "name", "file_name"], as_dict=True)
179+
if data:
180+
if doc.attached_to_doctype != data.attached_to_doctype:
181+
doctype = data.attached_to_doctype
182+
module = get_doctype_module(doctype)
183+
app = get_module_app(module)
184+
doc.nc.pathglobal = doc.nc.initialpath + "/" + app + "/" + module + "/" + doctype + "/" + doc.file_name
185+
data_json = doc.nc.shareModule(doc)
186+
fname = data.file_name.replace(" NC/f/","#")
187+
doc.file_name = fname.split("#")[0] + " NC(" + data.name + ")/f/" + fname.split("#")[1]
188+
doc.save()
189+
return
190+
data_json = doc.nc.shareModule(doc)
145191
# add public Share in Nextcloud
146-
if nc.sharepublic or doc.is_private == False:
192+
if doc.nc.sharepublic or doc.is_private == False:
147193
shareType = 3
148-
data_json = nc.ocs.createShare(pathglobal,shareType)
194+
data_json = doc.nc.ocs.createShare(doc.nc.pathglobal,shareType)
149195
if data_json == "":
150196
time.sleep(2)
151-
data_json = nc.ocs.createShare(pathglobal,shareType)
197+
data_json = doc.nc.ocs.createShare(doc.nc.pathglobal,shareType)
152198
data_string = json.dumps(data_json)
153199
decoded = json.loads(data_string)
154-
fileid = str(decoded["ocs"]["data"]["file_source"])
155-
if nc.sharepublic or doc.is_private == False:
200+
try:
201+
fileid = str(decoded["ocs"]["data"]["file_source"])
202+
except TypeError:
203+
fname = frappe.db.get_value("File", {"file_name": ["like", doc.file_name + " NC/f/%"]}, "name")
204+
docorigin = frappe.get_doc('File', str(fname))
205+
if docorigin:
206+
docorigin.content_hash = doc.content_hash
207+
docorigin.flags.ignore_file_validate = True
208+
docorigin.save()
209+
if doc.nc.enabletagging:
210+
fileid = str(docorigin.file_name.replace(" NC/f/","#").split("#")[1])
211+
doc.nc.deletetags(docorigin, fileid, relational=doc.nc.relationaltagging)
212+
doc.nc.tagging(docorigin, fileid, relational=doc.nc.relationaltagging)
213+
os.remove(doc.nc.local_fileobj)
214+
doc.delete()
215+
frappe.db.commit()
216+
sys.exit()
217+
if doc.nc.sharepublic or doc.is_private == False:
156218
urllink = str(decoded["ocs"]["data"]["url"])
157219
else:
158-
urllink = nc.url + "/f/" + fileid
220+
urllink = doc.nc.url + "/f/" + fileid
159221
# update doctype file
160222
if urllink != None and urllink != "":
161223
doc.file_url = urllink
162224
doc.file_name = doc.file_name + " NC/f/" + fileid
163225
doc.save()
164-
# delete local file
165-
os.remove(local_fileobj)
226+
# delete local file
227+
os.remove(doc.nc.local_fileobj)
166228
# tagging
167-
if nc.enabletagging: nc.tagging(doc, fileid, relational=nc.relationaltagging)
229+
if doc.nc.enabletagging: doc.nc.tagging(doc, fileid, relational=doc.nc.relationaltagging)
168230

231+
@frappe.whitelist()
232+
def nextcloud_before_delete(doc, method=None):
233+
doc.flags.ignore_nc = True
234+
nc = nextcloud_link()
235+
if not nc.isconnect: return
236+
doc.flags.ignore_file_validate = True
237+
doctype = doc.attached_to_doctype
238+
module = get_doctype_module(doctype)
239+
# Excluded module
240+
if module in nc.excludedmodules: return
241+
# File previously attached to another transaction
242+
if not doc.file_name or doc.file_name == None: return
243+
if not " NC/f/" in doc.file_name: return
244+
doc.flags.ignore_nc = False
245+
data = frappe.db.get_value("File", {"file_url": doc.file_url , "file_name": ["like", "%NC(%"]}, ["attached_to_doctype", "attached_to_name"], as_dict=True)
246+
if data:
247+
frappe.throw(_("The file can not be deleted while it is related to this transaction: {0} {1}").format(data.attached_to_doctype, data.attached_to_name))
169248

170249
@frappe.whitelist()
171250
def nextcloud_delete(doc, method=None):
251+
if doc.flags.ignore_nc: return
172252
nc = nextcloud_link()
173253
if not nc.isconnect: return
174254
doctype = doc.attached_to_doctype

0 commit comments

Comments
 (0)