Files
tryton/trytond/webdav/webdav.py
T

399 lines
16 KiB
Python
Raw Normal View History

2008-06-23 20:18:54 +02:00
#This file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms.
2008-02-14 01:43:39 +01:00
"WebDAV"
import os
import base64
import time
2008-02-14 01:43:39 +01:00
from trytond.osv import fields, OSV
2008-02-14 15:19:08 +01:00
from trytond.version import PACKAGE, VERSION, WEBSITE
2008-06-03 20:22:48 +02:00
from trytond import pooler
from trytond.pooler import get_pool_report
from trytond.report import Report
2008-02-14 01:43:39 +01:00
2008-05-28 20:40:53 +02:00
class Collection(OSV):
"Collection"
_name = "webdav.collection"
2008-02-14 01:43:39 +01:00
_description = __doc__
name = fields.Char('Name', size=128, required=True, select=1)
2008-05-28 20:40:53 +02:00
parent = fields.Many2One('webdav.collection', 'Parent',
2008-07-19 22:56:32 +02:00
ondelete='restrict', domain=[('model', '=', False)])
2008-05-28 20:40:53 +02:00
childs = fields.One2Many('webdav.collection', 'parent', 'Childs')
model = fields.Many2One('ir.model', 'Model')
domain = fields.Char('Domain', size=250)
def __init__(self):
2008-05-28 20:40:53 +02:00
super(Collection, self).__init__()
self._sql_constraints += [
('name_parent_uniq', 'UNIQUE (name, parent)',
2008-05-28 20:40:53 +02:00
'The collection name must be unique inside a collection!'),
]
self._constraints += [
2008-08-05 11:34:45 +02:00
('check_recursion', 'recursive_collections'),
('check_attachment', 'collection_file_name'),
]
2008-08-05 11:34:45 +02:00
self._error_messages.update({
'recursive_collections': 'You can not create recursive ' \
'collections!',
'collection_file_name': 'You can not create a collection\n' \
'with the same name of an existing file\n'
'inside the same collection!',
})
self.ext2mime = {
'.png': 'image/png',
2008-07-23 23:30:50 +02:00
'.odt': 'application/vnd.oasis.opendocument.text',
'.pdf': 'application/pdf',
}
2008-02-14 01:43:39 +01:00
def default_domain(self, cursor, user, context=None):
return '[]'
def check_attachment(self, cursor, user, ids):
attachment_obj = self.pool.get('ir.attachment')
2008-05-28 20:40:53 +02:00
for collection in self.browse(cursor, user, ids):
if collection.parent:
attachment_ids = attachment_obj.search(cursor, user, [
('res_model', '=', self._name),
2008-05-28 20:40:53 +02:00
('res_id', '=', collection.parent.id),
])
for attachment in attachment_obj.browse(cursor, user,
attachment_ids):
2008-05-28 20:40:53 +02:00
if attachment.name == collection.name:
return False
return True
2008-02-14 01:43:39 +01:00
def _uri2object(self, cursor, user, uri, object_name=_name, object_id=False,
context=None):
attachment_obj = self.pool.get('ir.attachment')
2008-06-03 20:22:48 +02:00
report_obj = self.pool.get('ir.action.report')
if not uri:
return self._name, False
2008-02-14 01:43:39 +01:00
name, uri = (uri.split('/', 1) + [None])[0:2]
if object_name == self._name:
2008-05-28 20:40:53 +02:00
collection_ids = self.search(cursor, user, [
2008-02-14 01:43:39 +01:00
('name', '=', name),
('parent', '=', object_id),
], limit=1, context=context)
2008-05-28 20:40:53 +02:00
if collection_ids:
object_id = collection_ids[0]
collection = self.browse(cursor, user, object_id,
2008-02-14 01:43:39 +01:00
context=context)
2008-05-28 20:40:53 +02:00
if collection.model and uri:
object_name = collection.model.model
2008-02-14 01:43:39 +01:00
else:
if uri:
return None, 0
attachment_ids = attachment_obj.search(cursor, user, [
('res_model', '=', object_name),
('res_id', '=', object_id),
('name', '=', name),
], limit=1, context=context)
if attachment_ids:
object_name = 'ir.attachment'
object_id = attachment_ids[0]
else:
object_name = None
object_id = False
2008-02-14 01:43:39 +01:00
else:
splitted_name = name.rsplit('-', 1)
if len(splitted_name) != 2:
return object_name, 0
object_id = int(splitted_name[1].strip())
2008-02-14 01:43:39 +01:00
if uri:
if '/' in uri:
return None, 0
2008-06-03 20:22:48 +02:00
report_ids = report_obj.search(cursor, user, [
('model', '=', object_name),
2008-06-03 20:22:48 +02:00
], context=context)
reports = report_obj.browse(cursor, user, report_ids,
context=context)
for report in reports:
report_name = report.name + '-' + str(report.id) \
+ '.' + report.output_format.format
if uri == report_name:
return 'ir.action.report', object_id
name = uri
attachment_ids = attachment_obj.search(cursor, user, [
('res_model', '=', object_name),
('res_id', '=', object_id),
('name', '=', name),
], limit=1, context=context)
if attachment_ids:
object_name = 'ir.attachment'
object_id = attachment_ids[0]
else:
object_name = None
object_id = False
return object_name, object_id
2008-02-14 01:43:39 +01:00
if uri:
return self._uri2object(cursor, user, uri, object_name,
object_id, context)
return object_name, object_id
def get_childs(self, cursor, user, uri, context=None):
2008-06-03 20:22:48 +02:00
report_obj = self.pool.get('ir.action.report')
2008-02-14 01:43:39 +01:00
res = []
if not uri:
2008-05-28 20:40:53 +02:00
collection_ids = self.search(cursor, user, [
2008-02-14 01:43:39 +01:00
('parent', '=', False),
], context=context)
2008-05-28 20:40:53 +02:00
for collection in self.browse(cursor, user, collection_ids,
2008-02-14 01:43:39 +01:00
context=context):
2008-05-28 20:40:53 +02:00
if '/' in collection.name:
continue
2008-05-28 20:40:53 +02:00
res.append(collection.name)
2008-02-14 01:43:39 +01:00
return res
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
if object_name == self._name and object_id:
2008-05-28 20:40:53 +02:00
collection = self.browse(cursor, user, object_id, context=context)
if collection.model:
model_obj = self.pool.get(collection.model.model)
2008-05-27 11:04:17 +02:00
if not model_obj:
return res
2008-02-14 01:43:39 +01:00
model_ids = model_obj.search(cursor, user,
2008-05-28 20:40:53 +02:00
eval(collection.domain or "[]"), context=context)
2008-02-14 01:43:39 +01:00
for child_id, child_name in model_obj.name_get(cursor, user,
model_ids, context=context):
if '/' in child_name:
continue
2008-02-14 01:43:39 +01:00
res.append(child_name + '-' + str(child_id))
return res
else:
2008-05-28 20:40:53 +02:00
for child in collection.childs:
if '/' in child.name:
continue
2008-02-14 01:43:39 +01:00
res.append(child.name)
if object_name not in ('ir.attachment', 'ir.action.report'):
2008-06-03 20:22:48 +02:00
report_ids = report_obj.search(cursor, user, [
('model', '=', object_name),
2008-06-03 20:22:48 +02:00
], context=context)
reports = report_obj.browse(cursor, user, report_ids,
context=context)
for report in reports:
report_name = report.name + '-' + str(report.id) \
+ '.' + report.output_format.format
if '/' in report_name:
continue
res.append(report_name)
2008-02-14 01:43:39 +01:00
attachment_obj = self.pool.get('ir.attachment')
attachment_ids = attachment_obj.search(cursor, user, [
('res_model', '=', object_name),
('res_id', '=', object_id),
], context=context)
for attachment in attachment_obj.browse(cursor, user, attachment_ids,
context=context):
if attachment.name and not attachment.link:
if '/' in attachment.name:
continue
res.append(attachment.name)
2008-02-14 01:43:39 +01:00
return res
def get_resourcetype(self, cursor, user, uri, context=None):
from DAV.constants import COLLECTION, OBJECT
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
if object_name in ('ir.attachment', 'ir.action.report'):
return OBJECT
return COLLECTION
def get_contentlength(self, cursor, user, uri, context=None):
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
if object_name == 'ir.attachment':
attachment_obj = self.pool.get('ir.attachment')
attachment = attachment_obj.browse(cursor, user, object_id,
context=context)
try:
if attachment.datas_size:
return str(attachment.datas_size)
except:
return '0'
2008-02-14 01:43:39 +01:00
return '0'
2008-02-14 15:19:08 +01:00
def get_contenttype(self, cursor, user, uri, context=None):
2008-02-14 01:43:39 +01:00
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
2008-06-03 20:22:48 +02:00
if object_name in ('ir.attachment', 'ir.action.report'):
2008-02-14 15:19:08 +01:00
ext = os.path.splitext(uri)[1]
if not ext:
return "application/octet-stream"
return self.ext2mime.get(ext, 'application/octet-stream')
return "application/octet-stream"
def get_creationdate(self, cursor, user, uri, context=None):
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
2008-07-23 23:18:50 +02:00
if object_name:
model_obj = self.pool.get(object_name)
2008-09-05 12:18:20 +02:00
if object_id:
2008-07-23 23:18:50 +02:00
cursor.execute('SELECT EXTRACT(epoch FROM create_date) ' \
'FROM "' + model_obj._table +'" ' \
'WHERE id = %s', (object_id,))
if cursor.rowcount:
return cursor.fetchone()[0]
return time.time()
def get_lastmodified(self, cursor, user, uri, context=None):
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
2008-07-23 23:18:50 +02:00
if object_name:
model_obj = self.pool.get(object_name)
2008-09-05 12:18:20 +02:00
if object_id:
2008-07-23 23:18:50 +02:00
cursor.execute('SELECT EXTRACT(epoch FROM write_date) ' \
'FROM "' + model_obj._table +'" ' \
'WHERE id = %s', (object_id,))
if cursor.rowcount:
return cursor.fetchone()[0]
return time.time()
2008-02-14 15:19:08 +01:00
def get_data(self, cursor, user, uri, context=None):
from DAV.errors import DAV_NotFound
if uri:
object_name, object_id = self._uri2object(cursor, user, uri,
2008-02-14 01:43:39 +01:00
context=context)
if object_name == 'ir.attachment' and object_id:
2008-02-14 15:19:08 +01:00
attachment_obj = self.pool.get('ir.attachment')
attachment = attachment_obj.browse(cursor, user, object_id,
context=context)
try:
if attachment.datas:
return base64.decodestring(attachment.datas)
except:
raise DAV_NotFound
2008-06-03 20:22:48 +02:00
if object_name == 'ir.action.report' and object_id:
report_obj = self.pool.get('ir.action.report')
report_id = int(uri.rsplit('/', 1)[-1].rsplit('-',
1)[-1].rsplit('.', 1)[0])
report = report_obj.browse(cursor, user, report_id,
context=context)
if report.report_name:
reportsvc = get_pool_report(cursor.dbname)
report_svc = reportsvc.get(report.report_name)
if not report_svc:
report_svc = Report.create_instance(reportsvc,
'report', pooler.get_pool(cursor.dbname))
report_svc._name = report.report_name
val = report_svc.execute(cursor, user, [object_id],
{'id': object_id, 'ids': [object_id]},
context=context)
return base64.decodestring(val[1])
raise DAV_NotFound
2008-02-14 01:43:39 +01:00
def put(self, cursor, user, uri, data, content_type, context=None):
from DAV.errors import DAV_Forbidden
from DAV.utils import get_uriparentpath, get_urifilename
object_name, object_id = self._uri2object(cursor, user,
get_uriparentpath(uri), context=context)
if not object_name \
or object_name in ('ir.attachment') \
or not object_id:
raise DAV_Forbidden
attachment_obj = self.pool.get('ir.attachment')
object_name2, object_id2 = self._uri2object(cursor, user, uri,
context=context)
if not object_id2:
name = get_urifilename(uri)
try:
attachment_obj.create(cursor, user, {
'name': name,
'datas': base64.encodestring(data),
'name': name,
'res_model': object_name,
'res_id': object_id,
}, context=context)
except:
raise DAV_Forbidden
else:
try:
attachment_obj.write(cursor, user, object_id2, {
'datas': base64.encodestring(data),
}, context=context)
except:
raise DAV_Forbidden
return 201
def mkcol(self, cursor, user, uri, context=None):
from DAV.errors import DAV_Forbidden
from DAV.utils import get_uriparentpath, get_urifilename
if uri[-1:] == '/':
uri = uri[:-1]
object_name, object_id = self._uri2object(cursor, user,
get_uriparentpath(uri), context=context)
2008-05-28 20:40:53 +02:00
if object_name != 'webdav.collection':
raise DAV_Forbidden
name = get_urifilename(uri)
try:
self.create(cursor, user, {
'name': name,
'parent': object_id,
}, context=context)
except:
raise DAV_Forbidden
return 201
def rmcol(self, cursor, user, uri, context=None):
from DAV.errors import DAV_Forbidden
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
2008-05-28 20:40:53 +02:00
if object_name != 'webdav.collection' \
or not object_id:
raise DAV_Forbidden
try:
2008-07-25 12:49:00 +02:00
self.delete(cursor, user, object_id, context=context)
except:
raise DAV_Forbidden
return 200
def rm(self, cursor, user, uri, context=None):
from DAV.errors import DAV_Forbidden
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
2008-07-23 23:18:50 +02:00
if not object_name:
raise DAV_Forbidden
if object_name != 'ir.attachment' \
or not object_id:
raise DAV_Forbidden
model_obj = self.pool.get(object_name)
try:
2008-07-25 12:49:00 +02:00
model_obj.delete(cursor, user, object_id, context=context)
except:
raise DAV_Forbidden
return 200
2008-02-14 01:43:39 +01:00
def exists(self, cursor, user, uri, context=None):
object_name, object_id = self._uri2object(cursor, user, uri,
context=context)
if object_name and object_id:
2008-02-14 01:43:39 +01:00
return 1
return None
2008-05-28 20:40:53 +02:00
Collection()
class Attachment(OSV):
_name = 'ir.attachment'
2008-03-03 18:30:39 +01:00
def __init__(self):
super(Attachment, self).__init__()
self._constraints += [
2008-08-05 11:34:45 +02:00
('check_collection', 'collection_attachment_name'),
2008-03-03 18:30:39 +01:00
]
2008-08-05 11:34:45 +02:00
self._error_messages.update({
'collection_attachment_name': 'You can not create a attachment\n' \
'on a collection that have the same name\n' \
'than a child collection!',
})
2008-05-28 20:40:53 +02:00
def check_collection(self, cursor, user, ids):
collection_obj = self.pool.get('webdav.collection')
for attachment in self.browse(cursor, user, ids):
2008-05-28 20:40:53 +02:00
if attachment.res_model == 'webdav.collection':
collection = collection_obj.browse(cursor, user,
attachment.res_id)
2008-05-28 20:40:53 +02:00
for child in collection.childs:
if child.name == attachment.name:
return False
return True
Attachment()