Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F87895530
api.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Oct 15, 14:58
Size
6 KB
Mime Type
text/x-python
Expires
Thu, Oct 17, 14:58 (2 d)
Engine
blob
Format
Raw Data
Handle
21675363
Attached To
R3600 invenio-infoscience
api.py
View Options
# -*- coding: utf-8 -*-
##
## This file is part of Invenio.
## Copyright (C) 2013, 2014 CERN.
##
## Invenio is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## Invenio is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
invenio.modules.documents.api
-----------------------------
Documents API
Following example shows how to handle documents metadata::
>>> from flask import g
>>> from invenio.base.factory import create_app
>>> app = create_app()
>>> ctx = app.test_request_context()
>>> ctx.push()
>>> from invenio.modules.documents import api
>>> from invenio.modules.jsonalchemy.jsonext.engines import memory
>>> app.config['DOCUMENTS_ENGINE'] = \
"invenio.modules.jsonalchemy.jsonext.engines.memory:MemoryStorage"
>>> d = api.Document.create({'title': 'Title 1'})
>>> d['title']
'Title 1'
>>> d['creator']
0
>>> d['title'] = 'New Title 1'
>>> d = d.update()
>>> api.Document.get_document(d['_id'])['title']
'New Title 1'
>>> ctx.pop()
"""
import
fs
import
six
from
datetime
import
datetime
from
flask
import
g
from
fs.opener
import
opener
from
werkzeug.utils
import
import_string
from
werkzeug.local
import
LocalProxy
from
invenio.base.globals
import
cfg
from
invenio.modules.jsonalchemy.wrappers
import
SmartJson
from
invenio.modules.jsonalchemy.reader
import
Reader
from
.
import
signals
,
errors
def
get_storage_engine
():
if
not
hasattr
(
g
,
"documents_storage_engine"
):
engine
=
cfg
[
'DOCUMENTS_ENGINE'
]
if
isinstance
(
engine
,
six
.
string_types
):
engine
=
import_string
(
engine
)
key
=
engine
.
__name__
.
upper
()
kwargs
=
cfg
.
get
(
'DOCUMENTS_{0}'
.
format
(
key
),
{})
g
.
documents_storage_engine
=
engine
(
**
kwargs
)
return
g
.
documents_storage_engine
class
Document
(
SmartJson
):
"""Document"""
storage_engine
=
LocalProxy
(
get_storage_engine
)
@classmethod
def
create
(
cls
,
data
,
model
=
'document_base'
,
master_format
=
'json'
,
**
kwargs
):
document
=
Reader
.
translate
(
data
,
cls
,
master_format
=
master_format
,
model
=
model
,
namespace
=
'documentext'
,
**
kwargs
)
cls
.
storage_engine
.
save_one
(
document
.
dumps
())
signals
.
document_created
.
send
(
document
)
return
document
@classmethod
def
get_document
(
cls
,
uuid
,
include_deleted
=
False
):
"""Returns document instance identified by UUID.
Find existing document::
>>> from flask import g
>>> from invenio.base.factory import create_app
>>> app = create_app()
>>> ctx = app.test_request_context()
>>> ctx.push()
>>> from invenio.modules.documents import api
>>> from invenio.modules.jsonalchemy.jsonext.engines import memory
>>> app.config['DOCUMENTS_ENGINE'] = \
"invenio.modules.jsonalchemy.jsonext.engines.memory:MemoryStorage"
>>> d = api.Document.create({'title': 'Title 1'})
>>> e = api.Document.get_document(d['_id'])
If you try to find deleted document you will get an exception::
>>> e.delete()
>>> api.Document.get_document(d['_id'])
Traceback (most recent call last):
...
DeletedDocument
and also if you try to find not existing document::
>>> import uuid
>>> api.Document.get_document(str(uuid.uuid4()))
Traceback (most recent call last):
...
DocumentNotFound
>>> ctx.pop()
:returns: a :class:`Document` instance.
:raises: :class:`~.invenio.modules.documents.errors.DocumentNotFound`
or :class:`~invenio.modules.documents.errors.DeletedDocument`
"""
try
:
document
=
cls
(
cls
.
storage_engine
.
get_one
(
uuid
))
except
:
raise
errors
.
DocumentNotFound
if
not
include_deleted
and
document
[
'deleted'
]:
raise
errors
.
DeletedDocument
return
document
def
_save
(
self
):
try
:
return
self
.
storage_engine
.
update_one
(
self
.
dumps
(),
id
=
self
[
'_id'
])
except
:
return
self
.
storage_engine
.
save_one
(
self
.
dumps
(),
id
=
self
[
'_id'
])
def
update
(
self
):
"""Update document object."""
#FIXME This should be probably done in model dump.
self
[
'modification_date'
]
=
datetime
.
now
()
return
self
.
_save
()
def
setcontents
(
self
,
source
,
name
,
chunk_size
=
65536
):
"""A convenience method to create a new file from a string or file-like
object.
:note: All paths has to be absolute or specified in full URI format.
:param data: .
:param name: File URI or filename generator taking `self` as argument.
"""
if
isinstance
(
source
,
six
.
string_types
):
self
[
'source'
]
=
source
f
=
opener
.
open
(
source
,
'rb'
)
else
:
f
=
source
if
callable
(
name
):
name
=
name
(
self
)
else
:
name
=
fs
.
path
.
abspath
(
name
)
signals
.
document_before_content_set
.
send
(
self
,
name
=
name
)
data
=
f
.
read
()
_fs
,
filename
=
opener
.
parse
(
name
)
_fs
.
setcontents
(
filename
,
data
,
chunk_size
)
_fs
.
close
()
signals
.
document_after_content_set
.
send
(
self
,
name
=
name
)
if
hasattr
(
f
,
'close'
):
f
.
close
()
self
[
'uri'
]
=
name
self
.
_save
()
def
open
(
self
,
mode
=
'r'
,
**
kwargs
):
"""Open a the 'uri' as a file-like object."""
_fs
,
filename
=
opener
.
parse
(
self
[
'uri'
])
return
_fs
.
open
(
filename
,
mode
=
mode
,
**
kwargs
)
def
delete
(
self
,
force
=
False
):
"""Deletes the instance of document.
:param force: If it is True then the document is deleted including
attached files and metadata.
"""
self
[
'deleted'
]
=
True
if
force
and
self
.
get
(
'uri'
)
is
not
None
:
signals
.
document_before_file_delete
.
send
(
self
)
fs
,
filename
=
opener
.
parse
(
self
[
'uri'
])
fs
.
remove
(
filename
)
self
[
'uri'
]
=
None
self
.
_save
()
Event Timeline
Log In to Comment