1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
# PyLint doesn't grok Zope interfaces.
# pylint: disable-msg=E0213
__metaclass__ = type
__all__ = [
'DownloadFailed',
'IFileUploadClient',
'ILibrarianClient',
'IRestrictedLibrarianClient',
'LibrarianServerError',
'LIBRARIAN_SERVER_DEFAULT_TIMEOUT',
'UploadFailed',
]
import signal
from zope.interface import Interface
SIGDUMPMEM = signal.SIGRTMIN + 10
DUMP_FILE = '/tmp/librarian-memory.dump'
class LibrarianFailure(Exception):
"""Base class for failures trying to use the libararian."""
class UploadFailed(LibrarianFailure):
pass
class DownloadFailed(LibrarianFailure):
pass
class LibrarianServerError(Exception):
"""An error indicating that the Librarian server is not responding."""
# the default time in seconds FileUploadClient.getByFileAlias() will
# retry to open a connection to the Librarain server before raising
# LibrarianServerError.
LIBRARIAN_SERVER_DEFAULT_TIMEOUT = 5
class IFileUploadClient(Interface):
"""Upload API for the Librarian client."""
def addFile(name, size, file, contentType, expires=None):
"""Add a file to the librarian.
:param name: Name to store the file as.
:param size: Size of the file.
:param file: File-like object with the content in it.
:param expires: Expiry time of file, or None to keep until
unreferenced.
:raises UploadFailed: If the server rejects the upload for some reason
Database insertions are done by the client, so access to the
LibraryFileAlias and LibraryFileContent objects is available
immediately. However, the newly uploaded file cannot be retrieved
from the Librarian until the client transaction has been committed.
Returns the id of the newly added LibraryFileAlias
"""
def remoteAddFile(name, size, file, contentType, expires=None):
"""Add a file to the librarian using the remote protocol.
As per addFile, except that the database insertions are done by the
librarian. This means that the corresponding rows in the
LibraryFileAlias and LibraryFileContent tables will not be available
until the client transaction has been committed. However, the data
is retrievable from the Librarian even if the client transaction rolls
back.
This method is used to ensure files get placed into the Librarian even
when the current transaction may be rolled back (eg. for storing
exception information in the Librarian), or when the client does not
have a database connection (eg. untrusted code).
Returns the URL of the newly added file.
"""
class IFileDownloadClient(Interface):
"""Download API for the Librarian client."""
def getURLForAlias(aliasID, secure=False):
"""Returns the URL to the given file.
:param aliasID: The LibraryFileAlias for the file to get. A DB lookup
will be done for this - if many are to be calculated, eagar loading
is recommended.
:param secure: If False, generate an http url on the main librarian
domain.
If True, generate an https url on a subdomain
i$aliasID.restricted.$main_librarian_domain.
Note that when a secure URL is generated, a TimeLimitedToken must
separately be obtained and combined with the URL to use it.
"""
def getURLForAliasObject(alias):
"""Returns the URL to a given `LibraryFileAlias` object.
Use this with care. Do not pass the `LibraryFileAlias` object
across process or thread boundaries. If you need to pass a
`LibraryFileAlias` across a boundary, pass alias.id and use
`getURLForAlias` instead.
"""
def getFileByAlias(aliasID, timeout=LIBRARIAN_SERVER_DEFAULT_TIMEOUT):
"""Returns a file-like object to read the file contents from.
:param aliasID: The alias ID identifying the file.
:param timeout: The number of seconds the method retries to open
a connection to the Librarian server. If the connection
cannot be established in the given time, a
LibrarianServerError is raised.
:return: A file-like object to read the file contents from.
:raises DownloadFailed: If the alias is not found.
:raises LibrarianServerError: If the librarian server is
unreachable or returns an 5xx HTTPError.
"""
class ILibrarianClient(IFileUploadClient, IFileDownloadClient):
"""Interface for the librarian client."""
class IRestrictedLibrarianClient(ILibrarianClient):
"""A version of the client that connects to a restricted librarian."""
|