Mercurial > p > roundup > code
annotate roundup/rest.py @ 5674:6dc4dba1c225
REST: Use If-Match header for incoming requests
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Mon, 25 Mar 2019 21:23:52 +0100 |
| parents | 1e8f17090a33 |
| children | 1fa59181ce58 |
| rev | line source |
|---|---|
|
5557
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
1 """ |
|
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
2 Restful API for Roundup |
|
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
3 |
|
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
4 This module is free software, you may redistribute it |
|
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
5 and/or modify under the same terms as Python. |
|
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
6 """ |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
7 |
| 5602 | 8 from __future__ import print_function |
| 9 | |
| 10 try: | |
| 11 from urllib.parse import urlparse | |
| 12 except ImportError: | |
| 13 from urlparse import urlparse | |
| 5574 | 14 import os |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
15 import json |
|
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
16 import pprint |
|
5567
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
17 import sys |
|
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
18 import time |
|
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
19 import traceback |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
20 import re |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
21 |
|
5631
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
22 try: |
|
5653
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
23 # if dicttoxml installed in roundup directory, use it |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
24 from .dicttoxml import dicttoxml |
|
5631
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
25 except ImportError: |
|
5653
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
26 try: |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
27 # else look in sys.path |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
28 from dicttoxml import dicttoxml |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
29 except ImportError: |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
30 # else not supported |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
31 dicttoxml = None |
|
5631
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
32 |
|
5557
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
33 from roundup import hyperdb |
| 5596 | 34 from roundup import date |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
35 from roundup import actions |
|
5655
207e0f5d551c
Merge in non-conflicting changes from ba67e397f063
John Rouillard <rouilj@ieee.org>
diff
changeset
|
36 from roundup.anypy.strings import bs2b, b2s |
|
5562
70df783c4c0b
Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5561
diff
changeset
|
37 from roundup.exceptions import * |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
38 from roundup.cgi.exceptions import * |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
39 |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
40 from hashlib import md5 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
41 |
| 5602 | 42 # Py3 compatible basestring |
| 43 try: | |
| 44 basestring | |
| 45 except NameError: | |
| 46 basestring = str | |
| 47 unicode = str | |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
48 |
|
5620
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
49 import logging |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
50 logger = logging.getLogger('roundup.rest') |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
51 |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
52 def _data_decorator(func): |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
53 """Wrap the returned data into an object.""" |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
54 def format_object(self, *args, **kwargs): |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
55 # get the data / error from function |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
56 try: |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
57 code, data = func(self, *args, **kwargs) |
| 5602 | 58 except NotFound as msg: |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
59 code = 404 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
60 data = msg |
| 5602 | 61 except IndexError as msg: |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
62 code = 404 |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
63 data = msg |
| 5602 | 64 except Unauthorised as msg: |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
65 code = 403 |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
66 data = msg |
| 5602 | 67 except UsageError as msg: |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
68 code = 400 |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
69 data = msg |
| 5602 | 70 except (AttributeError, Reject) as msg: |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
71 code = 405 |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
72 data = msg |
| 5602 | 73 except ValueError as msg: |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
74 code = 409 |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
75 data = msg |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
76 except PreconditionFailed as msg: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
77 code = 412 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
78 data = msg |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
79 except NotImplementedError: |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
80 code = 402 # nothing to pay, just a mark for debugging purpose |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
81 data = 'Method under development' |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
82 except: |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
83 exc, val, tb = sys.exc_info() |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
84 code = 400 |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
85 ts = time.ctime() |
| 5602 | 86 if getattr (self.client.request, 'DEBUG_MODE', None): |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
87 data = val |
|
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
88 else: |
|
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
89 data = '%s: An error occurred. Please check the server log' \ |
|
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
90 ' for more information.' % ts |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
91 # out to the logfile |
| 5602 | 92 print ('EXCEPTION AT', ts) |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
93 traceback.print_exc() |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
94 |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
95 # decorate it |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
96 self.client.response_code = code |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
97 if code >= 400: # any error require error format |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
98 result = { |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
99 'error': { |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
100 'status': code, |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
101 'msg': data |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
102 } |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
103 } |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
104 else: |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
105 result = { |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
106 'data': data |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
107 } |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
108 return result |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
109 return format_object |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
110 |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
111 def calculate_etag (node, classname="Missing", id="0"): |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
112 '''given a hyperdb node generate a hashed representation of it to be |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
113 used as an etag. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
114 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
115 This code needs a __repr__ function in the Password class. This |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
116 replaces the repr(items) which would be: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
117 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
118 <roundup.password.Password instance at 0x7f3442406170> |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
119 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
120 with the string representation: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
121 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
122 {PBKDF2}10000$k4d74EDgxlbH...A |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
123 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
124 This makes the representation repeatable as the location of the |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
125 password instance is not static and we need a constant value to |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
126 calculate the etag. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
127 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
128 Note that repr() is chosen for the node rather than str() since |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
129 repr is meant to be an unambiguous representation. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
130 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
131 classname and id are used for logging only. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
132 ''' |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
133 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
134 items = node.items(protected=True) # include every item |
|
5668
a4bb88a1a643
A fix for https://issues.roundup-tracker.org/issue2551034
John Rouillard <rouilj@ieee.org>
parents:
5662
diff
changeset
|
135 etag = md5(bs2b(repr(sorted(items)))).hexdigest() |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
136 logger.debug("object=%s%s; tag=%s; repr=%s", classname, id, |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
137 etag, repr(node.items(protected=True))) |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
138 # Quotes are part of ETag spec, normal headers don't have quotes |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
139 return '"%s"' % etag |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
140 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
141 def check_etag (node, etags, classname="Missing", id="0"): |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
142 '''Take a list of etags and compare to the etag for the given node. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
143 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
144 Iterate over all supplied etags, |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
145 If a tag fails to match, return False. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
146 If at least one etag matches, return True. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
147 If all etags are None, return False. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
148 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
149 ''' |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
150 have_etag_match=False |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
151 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
152 node_etag = calculate_etag(node, classname, id) |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
153 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
154 for etag in etags: |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
155 if etag is not None: |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
156 if etag != node_etag: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
157 return False |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
158 have_etag_match=True |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
159 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
160 if have_etag_match: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
161 return True |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
162 else: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
163 return False |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
164 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
165 def obtain_etags(headers,input): |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
166 '''Get ETags value from headers or payload data''' |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
167 etags = [] |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
168 if '@etag' in input: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
169 etags.append(input['@etag'].value); |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
170 etags.append(headers.get("If-Match", None)) |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
171 return etags |
| 5596 | 172 |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
173 def parse_accept_header(accept): |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
174 """ |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
175 Parse the Accept header *accept*, returning a list with 3-tuples of |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
176 [(str(media_type), dict(params), float(q_value)),] ordered by q values. |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
177 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
178 If the accept header includes vendor-specific types like:: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
179 application/vnd.yourcompany.yourproduct-v1.1+json |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
180 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
181 It will actually convert the vendor and version into parameters and |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
182 convert the content type into `application/json` so appropriate content |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
183 negotiation decisions can be made. |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
184 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
185 Default `q` for values that are not specified is 1.0 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
186 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
187 # Based on https://gist.github.com/samuraisam/2714195 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
188 # Also, based on a snipped found in this project: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
189 # https://github.com/martinblech/mimerender |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
190 """ |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
191 result = [] |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
192 for media_range in accept.split(","): |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
193 parts = media_range.split(";") |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
194 media_type = parts.pop(0).strip() |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
195 media_params = [] |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
196 # convert vendor-specific content types into something useful (see |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
197 # docstring) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
198 typ, subtyp = media_type.split('/') |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
199 # check for a + in the sub-type |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
200 if '+' in subtyp: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
201 # if it exists, determine if the subtype is a vendor-specific type |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
202 vnd, sep, extra = subtyp.partition('+') |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
203 if vnd.startswith('vnd'): |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
204 # and then... if it ends in something like "-v1.1" parse the |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
205 # version out |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
206 if '-v' in vnd: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
207 vnd, sep, rest = vnd.rpartition('-v') |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
208 if len(rest): |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
209 # add the version as a media param |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
210 try: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
211 version = media_params.append(('version', |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
212 float(rest))) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
213 except ValueError: |
| 5596 | 214 version = 1.0 # could not be parsed |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
215 # add the vendor code as a media param |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
216 media_params.append(('vendor', vnd)) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
217 # and re-write media_type to something like application/json so |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
218 # it can be used usefully when looking up emitters |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
219 media_type = '{}/{}'.format(typ, extra) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
220 q = 1.0 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
221 for part in parts: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
222 (key, value) = part.lstrip().split("=", 1) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
223 key = key.strip() |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
224 value = value.strip() |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
225 if key == "q": |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
226 q = float(value) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
227 else: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
228 media_params.append((key, value)) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
229 result.append((media_type, dict(media_params), q)) |
|
5653
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
230 result.sort(key=lambda x: x[2], reverse=True) |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
231 return result |
|
5567
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
232 |
| 5596 | 233 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
234 class Routing(object): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
235 __route_map = {} |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
236 __var_to_regex = re.compile(r"<:(\w+)>") |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
237 url_to_regex = r"([\w.\-~!$&'()*+,;=:@\%%]+)" |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
238 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
239 @classmethod |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
240 def route(cls, rule, methods='GET'): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
241 """A decorator that is used to register a view function for a |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
242 given URL rule: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
243 @self.route('/') |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
244 def index(): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
245 return 'Hello World' |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
246 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
247 rest/ will be added to the beginning of the url string |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
248 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
249 Args: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
250 rule (string): the URL rule |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
251 methods (string or tuple or list): the http method |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
252 """ |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
253 # strip the '/' character from rule string |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
254 rule = rule.strip('/') |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
255 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
256 # add 'rest/' to the rule string |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
257 if not rule.startswith('rest/'): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
258 rule = '^rest/' + rule + '$' |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
259 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
260 if isinstance(methods, basestring): # convert string to tuple |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
261 methods = (methods,) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
262 methods = set(item.upper() for item in methods) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
263 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
264 # convert a rule to a compiled regex object |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
265 # so /data/<:class>/<:id> will become |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
266 # /data/([charset]+)/([charset]+) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
267 # and extract the variable names to a list [(class), (id)] |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
268 func_vars = cls.__var_to_regex.findall(rule) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
269 rule = re.compile(cls.__var_to_regex.sub(cls.url_to_regex, rule)) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
270 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
271 # then we decorate it: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
272 # route_map[regex][method] = func |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
273 def decorator(func): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
274 rule_route = cls.__route_map.get(rule, {}) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
275 func_obj = { |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
276 'func': func, |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
277 'vars': func_vars |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
278 } |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
279 for method in methods: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
280 rule_route[method] = func_obj |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
281 cls.__route_map[rule] = rule_route |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
282 return func |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
283 return decorator |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
284 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
285 @classmethod |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
286 def execute(cls, instance, path, method, input): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
287 # format the input |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
288 path = path.strip('/').lower() |
|
5622
2a7d23a098ca
Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents:
5621
diff
changeset
|
289 if path == 'rest': |
|
2a7d23a098ca
Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents:
5621
diff
changeset
|
290 # allow handler to be called for /rest/ |
|
2a7d23a098ca
Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents:
5621
diff
changeset
|
291 path = 'rest/' |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
292 method = method.upper() |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
293 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
294 # find the rule match the path |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
295 # then get handler match the method |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
296 for path_regex in cls.__route_map: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
297 match_obj = path_regex.match(path) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
298 if match_obj: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
299 try: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
300 func_obj = cls.__route_map[path_regex][method] |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
301 except KeyError: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
302 raise Reject('Method %s not allowed' % method) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
303 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
304 # retrieve the vars list and the function caller |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
305 list_vars = func_obj['vars'] |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
306 func = func_obj['func'] |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
307 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
308 # zip the varlist into a dictionary, and pass it to the caller |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
309 args = dict(zip(list_vars, match_obj.groups())) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
310 args['input'] = input |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
311 return func(instance, **args) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
312 raise NotFound('Nothing matches the given URI') |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
313 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
314 |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
315 class RestfulInstance(object): |
| 5582 | 316 """The RestfulInstance performs REST request from the client""" |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
317 |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
318 __default_patch_op = "replace" # default operator for PATCH method |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
319 __accepted_content_type = { |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
320 "application/json": "json", |
|
5631
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
321 "*/*": "json", |
|
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
322 "application/xml": "xml" |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
323 } |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
324 __default_accept_type = "json" |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
325 |
|
5568
edab9daa8015
Make objects returned by REST follow the standard
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5567
diff
changeset
|
326 def __init__(self, client, db): |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
327 self.client = client |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
328 self.db = db |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
329 self.translator = client.translator |
| 5604 | 330 # This used to be initialized from client.instance.actions which |
| 331 # would include too many actions that do not make sense in the | |
| 332 # REST-API context, so for now we only permit the retire and | |
| 333 # restore actions. | |
| 334 self.actions = dict (retire = actions.Retire, restore = actions.Restore) | |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
335 |
|
5616
aa4c271514ae
Original code generated url's using a harcoded protocol and took the
John Rouillard <rouilj@ieee.org>
parents:
5604
diff
changeset
|
336 # note TRACKER_WEB ends in a / |
|
aa4c271514ae
Original code generated url's using a harcoded protocol and took the
John Rouillard <rouilj@ieee.org>
parents:
5604
diff
changeset
|
337 self.base_path = '%srest' % (self.db.config.TRACKER_WEB) |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
338 self.data_path = self.base_path + '/data' |
|
5569
2718aeb55ffa
Add base_path to generate uri
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5568
diff
changeset
|
339 |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
340 def props_from_args(self, cl, args, itemid=None): |
| 5582 | 341 """Construct a list of properties from the given arguments, |
| 342 and return them after validation. | |
| 343 | |
| 344 Args: | |
| 345 cl (string): class object of the resource | |
| 346 args (list): the submitted form of the user | |
| 347 itemid (string, optional): itemid of the object | |
| 348 | |
| 349 Returns: | |
| 350 dict: dictionary of validated properties | |
| 351 | |
| 352 """ | |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
353 class_props = cl.properties.keys() |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
354 props = {} |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
355 # props = dict.fromkeys(class_props, None) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
356 |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
357 for arg in args: |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
358 key = arg.name |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
359 value = arg.value |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
360 if key not in class_props: |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
361 continue |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
362 props[key] = self.prop_from_arg(cl, key, value, itemid) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
363 |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
364 return props |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
365 |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
366 def prop_from_arg(self, cl, key, value, itemid=None): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
367 """Construct a property from the given argument, |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
368 and return them after validation. |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
369 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
370 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
371 cl (string): class object of the resource |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
372 key (string): attribute key |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
373 value (string): attribute value |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
374 itemid (string, optional): itemid of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
375 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
376 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
377 value: value of validated properties |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
378 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
379 """ |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
380 prop = None |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
381 if isinstance(key, unicode): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
382 try: |
| 5602 | 383 x = key.encode('ascii') |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
384 except UnicodeEncodeError: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
385 raise UsageError( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
386 'argument %r is no valid ascii keyword' % key |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
387 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
388 if value: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
389 try: |
| 5602 | 390 prop = hyperdb.rawToHyperdb(self.db, cl, itemid, key, value) |
| 391 except hyperdb.HyperdbValueError as msg: | |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
392 raise UsageError(msg) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
393 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
394 return prop |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
395 |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
396 def error_obj(self, status, msg, source=None): |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
397 """Return an error object""" |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
398 self.client.response_code = status |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
399 result = { |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
400 'error': { |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
401 'status': status, |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
402 'msg': msg |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
403 } |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
404 } |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
405 if source is not None: |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
406 result['error']['source'] = source |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
407 |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
408 return result |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
409 |
|
5595
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
410 def patch_data(self, op, old_val, new_val): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
411 """Perform patch operation based on old_val and new_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
412 |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
413 Args: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
414 op (string): PATCH operation: add, replace, remove |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
415 old_val: old value of the property |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
416 new_val: new value of the property |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
417 |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
418 Returns: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
419 result (string): value after performed the operation |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
420 """ |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
421 # add operation: If neither of the value is None, use the other one |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
422 # Otherwise, concat those 2 value |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
423 if op == 'add': |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
424 if old_val is None: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
425 result = new_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
426 elif new_val is None: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
427 result = old_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
428 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
429 result = old_val + new_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
430 # Replace operation: new value is returned |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
431 elif op == 'replace': |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
432 result = new_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
433 # Remove operation: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
434 # if old_val is not a list/dict, change it to None |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
435 # if old_val is a list/dict, but the parameter is empty, |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
436 # change it to none |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
437 # if old_val is a list/dict, and parameter is not empty |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
438 # proceed to remove the values from parameter from the list/dict |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
439 elif op == 'remove': |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
440 if isinstance(old_val, list): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
441 if new_val is None: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
442 result = [] |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
443 elif isinstance(new_val, list): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
444 result = [x for x in old_val if x not in new_val] |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
445 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
446 if new_val in old_val: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
447 old_val.remove(new_val) |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
448 elif isinstance(old_val, dict): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
449 if new_val is None: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
450 result = {} |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
451 elif isinstance(new_val, dict): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
452 for x in new_val: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
453 old_val.pop(x, None) |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
454 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
455 old_val.pop(new_val, None) |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
456 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
457 result = None |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
458 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
459 raise UsageError('PATCH Operation %s is not allowed' % op) |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
460 |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
461 return result |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
462 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
463 def raise_if_no_etag(self, class_name, item_id, input): |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
464 class_obj = self.db.getclass(class_name) |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
465 if not check_etag(class_obj.getnode(item_id), |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
466 obtain_etags(self.client.request.headers, input), |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
467 class_name, |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
468 item_id): |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
469 raise PreconditionFailed( |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
470 "If-Match is missing or does not match." |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
471 " Retrieve asset and retry modification if valid.") |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
472 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
473 @Routing.route("/data/<:class_name>", 'GET') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
474 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
475 def get_collection(self, class_name, input): |
| 5582 | 476 """GET resource from class URI. |
| 477 | |
| 478 This function returns only items have View permission | |
| 479 class_name should be valid already | |
| 480 | |
| 481 Args: | |
| 482 class_name (string): class name of the resource (Ex: issue, msg) | |
| 483 input (list): the submitted form of the user | |
| 484 | |
| 485 Returns: | |
| 486 int: http status code 200 (OK) | |
| 487 list: list of reference item in the class | |
| 488 id: id of the object | |
| 489 link: path to the object | |
| 490 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
491 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
492 raise NotFound('Class %s not found' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
493 if not self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
494 'View', self.db.getuid(), class_name |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
495 ): |
|
5562
70df783c4c0b
Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5561
diff
changeset
|
496 raise Unauthorised('Permission to view %s denied' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
497 |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
498 class_obj = self.db.getclass(class_name) |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
499 class_path = '%s/%s/' % (self.data_path, class_name) |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
500 |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
501 # Handle filtering and pagination |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
502 filter_props = {} |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
503 page = { |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
504 'size': None, |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
505 'index': 1 # setting just size starts at page 1 |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
506 } |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
507 uid = self.db.getuid() |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
508 for form_field in input.value: |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
509 key = form_field.name |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
510 value = form_field.value |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
511 if key.startswith("@page_"): # serve the paging purpose |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
512 key = key[6:] |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
513 value = int(value) |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
514 page[key] = value |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
515 else: # serve the filter purpose |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
516 prop = class_obj.getprops()[key] |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
517 # We drop properties without search permission silently |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
518 # This reflects the current behavior of other roundup |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
519 # interfaces |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
520 if not self.db.security.hasSearchPermission( |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
521 uid, class_name, key |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
522 ): |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
523 continue |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
524 if isinstance (prop, (hyperdb.Link, hyperdb.Multilink)): |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
525 vals = [] |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
526 linkcls = self.db.getclass (prop.classname) |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
527 for p in value.split(","): |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
528 if prop.try_id_parsing and p.isdigit(): |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
529 vals.append(p) |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
530 else: |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
531 vals.append(linkcls.lookup(p)) |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
532 filter_props[key] = vals |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
533 else: |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
534 filter_props[key] = value |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
535 if not filter_props: |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
536 obj_list = class_obj.list() |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
537 else: |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
538 obj_list = class_obj.filter(None, filter_props) |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
539 |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
540 # extract result from data |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
541 result={} |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
542 result['collection'] = [ |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
543 {'id': item_id, 'link': class_path + item_id} |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
544 for item_id in obj_list |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
545 if self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
546 'View', self.db.getuid(), class_name, itemid=item_id |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
547 ) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
548 ] |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
549 result_len = len(result['collection']) |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
550 |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
551 # pagination - page_index from 1...N |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
552 if page['size'] is not None: |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
553 page_start = max((page['index']-1) * page['size'], 0) |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
554 page_end = min(page_start + page['size'], result_len) |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
555 result['collection'] = result['collection'][page_start:page_end] |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
556 result['@links'] = {} |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
557 for rel in ('next', 'prev', 'self'): |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
558 if rel == 'next': |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
559 # if current index includes all data, continue |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
560 if page['index']*page['size'] > result_len: continue |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
561 index=page['index']+1 |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
562 if rel == 'prev': |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
563 if page['index'] <= 1: continue |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
564 index=page['index']-1 |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
565 if rel == 'self': index=page['index'] |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
566 |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
567 result['@links'][rel] = [] |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
568 result['@links'][rel].append({ |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
569 'rel': rel, |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
570 'uri': "%s/%s?@page_index=%s&"%(self.data_path, |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
571 class_name,index) \ |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
572 + '&'.join([ "%s=%s"%(field.name,field.value) \ |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
573 for field in input.value \ |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
574 if field.name != "@page_index"]) }) |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
575 |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
576 result['@total_size'] = result_len |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
577 self.client.setHeader("X-Count-Total", str(result_len)) |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
578 return 200, result |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
579 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
580 @Routing.route("/data/<:class_name>/<:item_id>", 'GET') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
581 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
582 def get_element(self, class_name, item_id, input): |
| 5582 | 583 """GET resource from object URI. |
| 584 | |
| 585 This function returns only properties have View permission | |
| 586 class_name and item_id should be valid already | |
| 587 | |
| 588 Args: | |
| 589 class_name (string): class name of the resource (Ex: issue, msg) | |
| 590 item_id (string): id of the resource (Ex: 12, 15) | |
| 591 input (list): the submitted form of the user | |
| 592 | |
| 593 Returns: | |
| 594 int: http status code 200 (OK) | |
| 595 dict: a dictionary represents the object | |
| 596 id: id of the object | |
| 597 type: class name of the object | |
| 598 link: link to the object | |
| 599 attributes: a dictionary represent the attributes of the object | |
| 600 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
601 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
602 raise NotFound('Class %s not found' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
603 if not self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
604 'View', self.db.getuid(), class_name, itemid=item_id |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
605 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
606 raise Unauthorised( |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
607 'Permission to view %s%s denied' % (class_name, item_id) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
608 ) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
609 |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
610 class_obj = self.db.getclass(class_name) |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
611 node = class_obj.getnode(item_id) |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
612 etag = calculate_etag(node, class_name, item_id) |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
613 props = None |
|
5638
7e3cceec3f4f
Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents:
5636
diff
changeset
|
614 protected=False |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
615 verbose=1 |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
616 for form_field in input.value: |
|
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
617 key = form_field.name |
|
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
618 value = form_field.value |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
619 if key == "@fields": |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
620 props = value.split(",") |
|
5638
7e3cceec3f4f
Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents:
5636
diff
changeset
|
621 if key == "@protected": |
|
7e3cceec3f4f
Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents:
5636
diff
changeset
|
622 # allow client to request read only |
|
7e3cceec3f4f
Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents:
5636
diff
changeset
|
623 # properties like creator, activity etc. |
|
7e3cceec3f4f
Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents:
5636
diff
changeset
|
624 protected = value.lower() == "true" |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
625 if key == "@verbose": |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
626 verbose = int (value) |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
627 |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
628 result = {} |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
629 uid = self.db.getuid() |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
630 if props is None: |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
631 props = class_obj.getprops(protected=protected) |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
632 |
|
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
633 try: |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
634 for pn in sorted(props): |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
635 prop = props[pn] |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
636 if not self.db.security.hasPermission( |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
637 'View', uid, class_name, pn, item_id |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
638 ): |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
639 continue |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
640 v = getattr(node, pn) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
641 if isinstance (prop, (hyperdb.Link, hyperdb.Multilink)): |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
642 linkcls = self.db.getclass (prop.classname) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
643 cp = '%s/%s/' % (self.data_path, prop.classname) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
644 if verbose and v: |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
645 if isinstance(v, type([])): |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
646 r = [] |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
647 for id in v: |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
648 d = dict(id = id, link = cp + id) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
649 if verbose > 1: |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
650 label = linkcls.labelprop() |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
651 d [label] = linkcls.get(id, label) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
652 r.append(d) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
653 result[pn] = r |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
654 else: |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
655 result[pn] = dict(id = v, link = cp + v) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
656 if verbose > 1: |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
657 label = linkcls.labelprop() |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
658 result[pn][label] = linkcls.get(v, label) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
659 else: |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
660 result[pn] = v |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
661 elif isinstance (prop, hyperdb.String) and pn == 'content': |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
662 # Do not show the (possibly HUGE) content prop |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
663 # unless very verbose, we display the standard |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
664 # download link instead |
|
5662
5ceed592706e
Display content property starting with verbose=3
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5661
diff
changeset
|
665 if verbose < 3: |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
666 u = self.db.config.TRACKER_WEB |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
667 p = u + '%s%s/' % (class_name, node.id) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
668 result[pn] = dict(link = p) |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
669 else: |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
670 result[pn] = v |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
671 else: |
|
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
672 result[pn] = v |
| 5602 | 673 except KeyError as msg: |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
674 raise UsageError("%s field not valid" % msg) |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
675 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
676 'id': item_id, |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
677 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
678 'link': '%s/%s/%s' % (self.data_path, class_name, item_id), |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
679 'attributes': dict(result), |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
680 '@etag': etag |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
681 } |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
682 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
683 self.client.setHeader("ETag", etag) |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
684 return 200, result |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
685 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
686 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'GET') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
687 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
688 def get_attribute(self, class_name, item_id, attr_name, input): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
689 """GET resource from attribute URI. |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
690 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
691 This function returns only attribute has View permission |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
692 class_name should be valid already |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
693 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
694 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
695 class_name (string): class name of the resource (Ex: issue, msg) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
696 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
697 attr_name (string): attribute of the resource (Ex: title, nosy) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
698 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
699 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
700 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
701 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
702 list: a dictionary represents the attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
703 id: id of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
704 type: class name of the attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
705 link: link to the attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
706 data: data of the requested attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
707 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
708 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
709 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
710 if not self.db.security.hasPermission( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
711 'View', self.db.getuid(), class_name, attr_name, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
712 ): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
713 raise Unauthorised( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
714 'Permission to view %s%s %s denied' % |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
715 (class_name, item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
716 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
717 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
718 class_obj = self.db.getclass(class_name) |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
719 node = class_obj.getnode(item_id) |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
720 etag = calculate_etag(node, class_name, item_id) |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
721 data = node.__getattr__(attr_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
722 result = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
723 'id': item_id, |
|
5631
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
724 'type': str(type(data)), |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
725 'link': "%s/%s/%s/%s" % |
|
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
726 (self.data_path, class_name, item_id, attr_name), |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
727 'data': data, |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
728 '@etag': etag |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
729 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
730 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
731 self.client.setHeader("ETag", etag) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
732 return 200, result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
733 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
734 @Routing.route("/data/<:class_name>", 'POST') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
735 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
736 def post_collection(self, class_name, input): |
| 5582 | 737 """POST a new object to a class |
| 738 | |
| 739 If the item is successfully created, the "Location" header will also | |
| 740 contain the link to the created object | |
| 741 | |
| 742 Args: | |
| 743 class_name (string): class name of the resource (Ex: issue, msg) | |
| 744 input (list): the submitted form of the user | |
| 745 | |
| 746 Returns: | |
| 747 int: http status code 201 (Created) | |
| 748 dict: a reference item to the created object | |
| 749 id: id of the object | |
| 750 link: path to the object | |
| 751 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
752 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
753 raise NotFound('Class %s not found' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
754 if not self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
755 'Create', self.db.getuid(), class_name |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
756 ): |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
757 raise Unauthorised('Permission to create %s denied' % class_name) |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
758 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
759 class_obj = self.db.getclass(class_name) |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
760 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
761 # convert types |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
762 props = self.props_from_args(class_obj, input.value) |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
763 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
764 # check for the key property |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
765 key = class_obj.getkey() |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
766 if key and key not in props: |
| 5576 | 767 raise UsageError("Must provide the '%s' property." % key) |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
768 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
769 for key in props: |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
770 if not self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
771 'Create', self.db.getuid(), class_name, property=key |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
772 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
773 raise Unauthorised( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
774 'Permission to create %s.%s denied' % (class_name, key) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
775 ) |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
776 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
777 # do the actual create |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
778 try: |
|
5562
70df783c4c0b
Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5561
diff
changeset
|
779 item_id = class_obj.create(**props) |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
780 self.db.commit() |
| 5602 | 781 except (TypeError, IndexError, ValueError) as message: |
| 5576 | 782 raise ValueError(message) |
| 5602 | 783 except KeyError as msg: |
| 5576 | 784 raise UsageError("Must provide the %s property." % msg) |
|
5562
70df783c4c0b
Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5561
diff
changeset
|
785 |
|
5573
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
786 # set the header Location |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
787 link = '%s/%s/%s' % (self.data_path, class_name, item_id) |
|
5573
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
788 self.client.setHeader("Location", link) |
|
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
789 |
|
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
790 # set the response body |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
791 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
792 'id': item_id, |
|
5573
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
793 'link': link |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
794 } |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
795 return 201, result |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
796 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
797 @Routing.route("/data/<:class_name>/<:item_id>", 'PUT') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
798 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
799 def put_element(self, class_name, item_id, input): |
| 5582 | 800 """PUT a new content to an object |
| 801 | |
| 802 Replace the content of the existing object | |
| 803 | |
| 804 Args: | |
| 805 class_name (string): class name of the resource (Ex: issue, msg) | |
| 806 item_id (string): id of the resource (Ex: 12, 15) | |
| 807 input (list): the submitted form of the user | |
| 808 | |
| 809 Returns: | |
| 810 int: http status code 200 (OK) | |
| 811 dict: a dictionary represents the modified object | |
| 812 id: id of the object | |
| 813 type: class name of the object | |
| 814 link: link to the object | |
| 815 attributes: a dictionary represent only changed attributes of | |
| 816 the object | |
| 817 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
818 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
819 raise NotFound('Class %s not found' % class_name) |
| 5564 | 820 class_obj = self.db.getclass(class_name) |
| 821 | |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
822 props = self.props_from_args(class_obj, input.value, item_id) |
| 5602 | 823 for p in props: |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
824 if not self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
825 'Edit', self.db.getuid(), class_name, p, item_id |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
826 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
827 raise Unauthorised( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
828 'Permission to edit %s of %s%s denied' % |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
829 (p, class_name, item_id) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
830 ) |
| 5564 | 831 try: |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
832 self.raise_if_no_etag(class_name, item_id, input) |
| 5564 | 833 result = class_obj.set(item_id, **props) |
| 834 self.db.commit() | |
| 5602 | 835 except (TypeError, IndexError, ValueError) as message: |
| 5576 | 836 raise ValueError(message) |
| 5564 | 837 |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
838 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
839 'id': item_id, |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
840 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
841 'link': '%s/%s/%s' % (self.data_path, class_name, item_id), |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
842 'attribute': result |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
843 } |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
844 return 200, result |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
845 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
846 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'PUT') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
847 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
848 def put_attribute(self, class_name, item_id, attr_name, input): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
849 """PUT an attribute to an object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
850 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
851 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
852 class_name (string): class name of the resource (Ex: issue, msg) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
853 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
854 attr_name (string): attribute of the resource (Ex: title, nosy) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
855 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
856 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
857 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
858 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
859 dict:a dictionary represents the modified object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
860 id: id of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
861 type: class name of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
862 link: link to the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
863 attributes: a dictionary represent only changed attributes of |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
864 the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
865 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
866 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
867 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
868 if not self.db.security.hasPermission( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
869 'Edit', self.db.getuid(), class_name, attr_name, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
870 ): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
871 raise Unauthorised( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
872 'Permission to edit %s%s %s denied' % |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
873 (class_name, item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
874 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
875 class_obj = self.db.getclass(class_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
876 props = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
877 attr_name: self.prop_from_arg( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
878 class_obj, attr_name, input['data'].value, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
879 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
880 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
881 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
882 try: |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
883 self.raise_if_no_etag(class_name, item_id, input) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
884 result = class_obj.set(item_id, **props) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
885 self.db.commit() |
| 5602 | 886 except (TypeError, IndexError, ValueError) as message: |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
887 raise ValueError(message) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
888 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
889 result = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
890 'id': item_id, |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
891 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
892 'link': '%s/%s/%s' % (self.data_path, class_name, item_id), |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
893 'attribute': result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
894 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
895 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
896 return 200, result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
897 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
898 @Routing.route("/data/<:class_name>", 'DELETE') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
899 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
900 def delete_collection(self, class_name, input): |
| 5604 | 901 """DELETE (retire) all objects in a class |
| 902 There is currently no use-case, so this is disabled and | |
| 903 always returns Unauthorised. | |
| 5582 | 904 |
| 905 Args: | |
| 906 class_name (string): class name of the resource (Ex: issue, msg) | |
| 907 input (list): the submitted form of the user | |
| 908 | |
| 909 Returns: | |
| 910 int: http status code 200 (OK) | |
| 911 dict: | |
| 912 status (string): 'ok' | |
| 913 count (int): number of deleted objects | |
| 914 """ | |
| 5604 | 915 raise Unauthorised('Deletion of a whole class disabled') |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
916 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
917 raise NotFound('Class %s not found' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
918 if not self.db.security.hasPermission( |
| 5604 | 919 'Retire', self.db.getuid(), class_name |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
920 ): |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
921 raise Unauthorised('Permission to delete %s denied' % class_name) |
|
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
922 |
|
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
923 class_obj = self.db.getclass(class_name) |
|
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
924 for item_id in class_obj.list(): |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
925 if not self.db.security.hasPermission( |
| 5604 | 926 'Retire', self.db.getuid(), class_name, itemid=item_id |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
927 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
928 raise Unauthorised( |
| 5604 | 929 'Permission to retire %s %s denied' % (class_name, item_id) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
930 ) |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
931 |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
932 count = len(class_obj.list()) |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
933 for item_id in class_obj.list(): |
| 5604 | 934 class_obj.retire (item_id) |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
935 |
|
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
936 self.db.commit() |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
937 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
938 'status': 'ok', |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
939 'count': count |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
940 } |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
941 |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
942 return 200, result |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
943 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
944 @Routing.route("/data/<:class_name>/<:item_id>", 'DELETE') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
945 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
946 def delete_element(self, class_name, item_id, input): |
| 5604 | 947 """DELETE (retire) an object in a class |
| 5582 | 948 |
| 949 Args: | |
| 950 class_name (string): class name of the resource (Ex: issue, msg) | |
| 951 item_id (string): id of the resource (Ex: 12, 15) | |
| 952 input (list): the submitted form of the user | |
| 953 | |
| 954 Returns: | |
| 955 int: http status code 200 (OK) | |
| 956 dict: | |
| 957 status (string): 'ok' | |
| 958 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
959 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
960 raise NotFound('Class %s not found' % class_name) |
| 5604 | 961 class_obj = self.db.classes [class_name] |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
962 if not self.db.security.hasPermission( |
| 5604 | 963 'Retire', self.db.getuid(), class_name, itemid=item_id |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
964 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
965 raise Unauthorised( |
| 5604 | 966 'Permission to retire %s %s denied' % (class_name, item_id) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
967 ) |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
968 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
969 self.raise_if_no_etag(class_name, item_id, input) |
| 5604 | 970 class_obj.retire (item_id) |
|
5562
70df783c4c0b
Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5561
diff
changeset
|
971 self.db.commit() |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
972 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
973 'status': 'ok' |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
974 } |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
975 |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
976 return 200, result |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
977 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
978 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'DELETE') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
979 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
980 def delete_attribute(self, class_name, item_id, attr_name, input): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
981 """DELETE an attribute in a object by setting it to None or empty |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
982 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
983 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
984 class_name (string): class name of the resource (Ex: issue, msg) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
985 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
986 attr_name (string): attribute of the resource (Ex: title, nosy) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
987 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
988 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
989 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
990 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
991 dict: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
992 status (string): 'ok' |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
993 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
994 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
995 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
996 if not self.db.security.hasPermission( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
997 'Edit', self.db.getuid(), class_name, attr_name, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
998 ): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
999 raise Unauthorised( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1000 'Permission to delete %s%s %s denied' % |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1001 (class_name, item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1002 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1003 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1004 class_obj = self.db.getclass(class_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1005 props = {} |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1006 prop_obj = class_obj.get(item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1007 if isinstance(prop_obj, list): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1008 props[attr_name] = [] |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1009 else: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1010 props[attr_name] = None |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1011 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1012 try: |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1013 self.raise_if_no_etag(class_name, item_id, input) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1014 class_obj.set(item_id, **props) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1015 self.db.commit() |
| 5602 | 1016 except (TypeError, IndexError, ValueError) as message: |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1017 raise ValueError(message) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1018 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1019 result = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1020 'status': 'ok' |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1021 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1022 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1023 return 200, result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1024 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1025 @Routing.route("/data/<:class_name>/<:item_id>", 'PATCH') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
1026 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
1027 def patch_element(self, class_name, item_id, input): |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1028 """PATCH an object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1029 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1030 Patch an element using 3 operators |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1031 ADD : Append new value to the object's attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1032 REPLACE: Replace object's attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1033 REMOVE: Clear object's attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1034 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1035 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1036 class_name (string): class name of the resource (Ex: issue, msg) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1037 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1038 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1039 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1040 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1041 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1042 dict: a dictionary represents the modified object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1043 id: id of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1044 type: class name of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1045 link: link to the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1046 attributes: a dictionary represent only changed attributes of |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1047 the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1048 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1049 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1050 raise NotFound('Class %s not found' % class_name) |
|
5580
d5a54b1851aa
Add default op action for Patch
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5579
diff
changeset
|
1051 try: |
|
5660
d8d2b7724292
First attempt at REST-API documentation
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5659
diff
changeset
|
1052 op = input['@op'].value.lower() |
|
5580
d5a54b1851aa
Add default op action for Patch
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5579
diff
changeset
|
1053 except KeyError: |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
1054 op = self.__default_patch_op |
|
5578
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1055 class_obj = self.db.getclass(class_name) |
|
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1056 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1057 self.raise_if_no_etag(class_name, item_id, input) |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
1058 |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1059 # if patch operation is action, call the action handler |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1060 action_args = [class_name + item_id] |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1061 if op == 'action': |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1062 # extract action_name and action_args from form fields |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1063 for form_field in input.value: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1064 key = form_field.name |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1065 value = form_field.value |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
1066 if key == "@action_name": |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1067 name = value |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
1068 elif key.startswith('@action_args'): |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1069 action_args.append(value) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1070 |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1071 if name in self.actions: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1072 action_type = self.actions[name] |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1073 else: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1074 raise UsageError( |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1075 'action "%s" is not supported %s' % |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1076 (name, ','.join(self.actions.keys())) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1077 ) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1078 action = action_type(self.db, self.translator) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1079 result = action.execute(*action_args) |
|
5578
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1080 |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1081 result = { |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1082 'id': item_id, |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1083 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1084 'link': '%s/%s/%s' % (self.data_path, class_name, item_id), |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1085 'result': result |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1086 } |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1087 else: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1088 # else patch operation is processing data |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1089 props = self.props_from_args(class_obj, input.value, item_id) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1090 |
| 5602 | 1091 for prop in props: |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1092 if not self.db.security.hasPermission( |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1093 'Edit', self.db.getuid(), class_name, prop, item_id |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1094 ): |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1095 raise Unauthorised( |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1096 'Permission to edit %s of %s%s denied' % |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1097 (prop, class_name, item_id) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1098 ) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1099 |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1100 props[prop] = self.patch_data( |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1101 op, class_obj.get(item_id, prop), props[prop] |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1102 ) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1103 |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1104 try: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1105 result = class_obj.set(item_id, **props) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1106 self.db.commit() |
| 5602 | 1107 except (TypeError, IndexError, ValueError) as message: |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1108 raise ValueError(message) |
|
5578
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1109 |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1110 result = { |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1111 'id': item_id, |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1112 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1113 'link': '%s/%s/%s' % (self.data_path, class_name, item_id), |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1114 'attribute': result |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1115 } |
|
5578
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1116 return 200, result |
|
5557
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
1117 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1118 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'PATCH') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
1119 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1120 def patch_attribute(self, class_name, item_id, attr_name, input): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1121 """PATCH an attribute of an object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1122 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1123 Patch an element using 3 operators |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1124 ADD : Append new value to the attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1125 REPLACE: Replace attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1126 REMOVE: Clear attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1127 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1128 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1129 class_name (string): class name of the resource (Ex: issue, msg) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1130 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1131 attr_name (string): attribute of the resource (Ex: title, nosy) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1132 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1133 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1134 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1135 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1136 dict: a dictionary represents the modified object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1137 id: id of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1138 type: class name of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1139 link: link to the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1140 attributes: a dictionary represent only changed attributes of |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1141 the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1142 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1143 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1144 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1145 try: |
|
5660
d8d2b7724292
First attempt at REST-API documentation
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5659
diff
changeset
|
1146 op = input['@op'].value.lower() |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1147 except KeyError: |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
1148 op = self.__default_patch_op |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1149 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1150 if not self.db.security.hasPermission( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1151 'Edit', self.db.getuid(), class_name, attr_name, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1152 ): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1153 raise Unauthorised( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1154 'Permission to edit %s%s %s denied' % |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1155 (class_name, item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1156 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1157 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1158 prop = attr_name |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1159 class_obj = self.db.getclass(class_name) |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
1160 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1161 self.raise_if_no_etag(class_name, item_id, input) |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
1162 |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1163 props = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1164 prop: self.prop_from_arg( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1165 class_obj, prop, input['data'].value, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1166 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1167 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1168 |
|
5595
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
1169 props[prop] = self.patch_data( |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
1170 op, class_obj.get(item_id, prop), props[prop] |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
1171 ) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1172 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1173 try: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1174 result = class_obj.set(item_id, **props) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1175 self.db.commit() |
| 5602 | 1176 except (TypeError, IndexError, ValueError) as message: |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1177 raise ValueError(message) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1178 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1179 result = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1180 'id': item_id, |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1181 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1182 'link': '%s/%s/%s' % (self.data_path, class_name, item_id), |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1183 'attribute': result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1184 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1185 return 200, result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1186 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1187 @Routing.route("/data/<:class_name>", 'OPTIONS') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
1188 @_data_decorator |
| 5575 | 1189 def options_collection(self, class_name, input): |
| 5582 | 1190 """OPTION return the HTTP Header for the class uri |
| 1191 | |
| 1192 Returns: | |
| 1193 int: http status code 204 (No content) | |
| 1194 body (string): an empty string | |
| 1195 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1196 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1197 raise NotFound('Class %s not found' % class_name) |
| 5575 | 1198 return 204, "" |
| 1199 | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1200 @Routing.route("/data/<:class_name>/<:item_id>", 'OPTIONS') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
1201 @_data_decorator |
| 5575 | 1202 def options_element(self, class_name, item_id, input): |
| 5582 | 1203 """OPTION return the HTTP Header for the object uri |
| 1204 | |
| 1205 Returns: | |
| 1206 int: http status code 204 (No content) | |
| 1207 body (string): an empty string | |
| 1208 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1209 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1210 raise NotFound('Class %s not found' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1211 self.client.setHeader( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1212 "Accept-Patch", |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1213 "application/x-www-form-urlencoded, multipart/form-data" |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1214 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1215 return 204, "" |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1216 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1217 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'OPTIONS') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
1218 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1219 def option_attribute(self, class_name, item_id, attr_name, input): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1220 """OPTION return the HTTP Header for the attribute uri |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1221 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1222 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1223 int: http status code 204 (No content) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1224 body (string): an empty string |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1225 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1226 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1227 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1228 self.client.setHeader( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1229 "Accept-Patch", |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1230 "application/x-www-form-urlencoded, multipart/form-data" |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1231 ) |
| 5575 | 1232 return 204, "" |
| 1233 | |
|
5632
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1234 @Routing.route("/") |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1235 @_data_decorator |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1236 def describe(self, input): |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1237 """Describe the rest endpoint""" |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1238 result = { |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1239 "default_version": "1", |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1240 "supported_versions": [ "1" ], |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1241 "links": [ { "uri": self.base_path +"/summary", |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1242 "rel": "summary"}, |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1243 { "uri": self.base_path, |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1244 "rel": "self"}, |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1245 { "uri": self.base_path + "/data", |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1246 "rel": "data"} |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1247 ] |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1248 } |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1249 |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1250 return 200, result |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1251 |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1252 @Routing.route("/data") |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1253 @_data_decorator |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1254 def data(self, input): |
| 5658 | 1255 """Describe the subelements of data |
|
5632
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1256 |
| 5658 | 1257 One entry for each class the user may view |
|
5632
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1258 """ |
| 5658 | 1259 result = {} |
| 1260 uid = self.db.getuid () | |
| 1261 for cls in sorted (self.db.classes) : | |
| 1262 if self.db.security.hasPermission('View', uid, cls) : | |
| 1263 result [cls] = dict(link = self.base_path + '/data/' + cls) | |
|
5632
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1264 return 200, result |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1265 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1266 @Routing.route("/summary") |
| 5596 | 1267 @_data_decorator |
| 1268 def summary(self, input): | |
| 1269 """Get a summary of resource from class URI. | |
| 1270 | |
| 1271 This function returns only items have View permission | |
| 1272 class_name should be valid already | |
| 1273 | |
| 1274 Args: | |
| 1275 class_name (string): class name of the resource (Ex: issue, msg) | |
| 1276 input (list): the submitted form of the user | |
| 1277 | |
| 1278 Returns: | |
| 1279 int: http status code 200 (OK) | |
| 1280 list: | |
| 1281 """ | |
| 1282 if not self.db.security.hasPermission( | |
| 1283 'View', self.db.getuid(), 'issue' | |
| 1284 ) and not self.db.security.hasPermission( | |
| 1285 'View', self.db.getuid(), 'status' | |
| 1286 ) and not self.db.security.hasPermission( | |
| 1287 'View', self.db.getuid(), 'issue' | |
| 1288 ): | |
| 1289 raise Unauthorised('Permission to view summary denied') | |
| 1290 | |
| 1291 old = date.Date('-1w') | |
| 1292 | |
| 1293 created = [] | |
| 1294 summary = {} | |
| 1295 messages = [] | |
| 1296 | |
| 1297 # loop through all the recently-active issues | |
| 1298 for issue_id in self.db.issue.filter(None, {'activity': '-1w;'}): | |
| 1299 num = 0 | |
| 1300 status_name = self.db.status.get( | |
| 1301 self.db.issue.get(issue_id, 'status'), | |
| 1302 'name' | |
| 1303 ) | |
| 1304 issue_object = { | |
| 1305 'id': issue_id, | |
|
5621
39dbe83643c0
Fix path of links in /rest/summary.
John Rouillard <rouilj@ieee.org>
parents:
5620
diff
changeset
|
1306 'link': self.base_path + '/data/issue/' + issue_id, |
| 5596 | 1307 'title': self.db.issue.get(issue_id, 'title') |
| 1308 } | |
| 1309 for x, ts, uid, action, data in self.db.issue.history(issue_id): | |
| 1310 if ts < old: | |
| 1311 continue | |
| 1312 if action == 'create': | |
| 1313 created.append(issue_object) | |
| 1314 elif action == 'set' and 'messages' in data: | |
| 1315 num += 1 | |
| 1316 summary.setdefault(status_name, []).append(issue_object) | |
| 1317 messages.append((num, issue_object)) | |
| 1318 | |
|
5668
a4bb88a1a643
A fix for https://issues.roundup-tracker.org/issue2551034
John Rouillard <rouilj@ieee.org>
parents:
5662
diff
changeset
|
1319 sorted(messages, key=lambda tup: tup[0], reverse=True) |
| 5596 | 1320 |
| 1321 result = { | |
| 1322 'created': created, | |
| 1323 'summary': summary, | |
| 1324 'most_discussed': messages[:10] | |
| 1325 } | |
| 1326 | |
| 1327 return 200, result | |
| 1328 | |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
1329 def dispatch(self, method, uri, input): |
| 5582 | 1330 """format and process the request""" |
| 5574 | 1331 # if X-HTTP-Method-Override is set, follow the override method |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1332 headers = self.client.request.headers |
|
5620
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1333 # Never allow GET to be an unsafe operation (i.e. data changing). |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1334 # User must use POST to "tunnel" DELETE, PUT, OPTIONS etc. |
|
5650
e8ca7072c629
Fix Python 3 issues in REST code.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5646
diff
changeset
|
1335 override = headers.get('X-HTTP-Method-Override') |
|
5620
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1336 output = None |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1337 if override: |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1338 if method.upper() != 'GET': |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1339 logger.debug( |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1340 'Method overridden from %s to %s', method, override) |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1341 method = override |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1342 else: |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1343 output = self.error_obj(400, |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1344 "X-HTTP-Method-Override: %s can not be used with GET method. Use Post instead." % override) |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1345 logger.info( |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1346 'Ignoring X-HTTP-Method-Override for GET request on %s', |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1347 uri) |
| 5574 | 1348 |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1349 # parse Accept header and get the content type |
|
5650
e8ca7072c629
Fix Python 3 issues in REST code.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5646
diff
changeset
|
1350 accept_header = parse_accept_header(headers.get('Accept')) |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1351 accept_type = "invalid" |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1352 for part in accept_header: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1353 if part[0] in self.__accepted_content_type: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1354 accept_type = self.__accepted_content_type[part[0]] |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1355 |
| 5574 | 1356 # get the request format for response |
| 1357 # priority : extension from uri (/rest/issue.json), | |
| 1358 # header (Accept: application/json, application/xml) | |
| 1359 # default (application/json) | |
| 5602 | 1360 ext_type = os.path.splitext(urlparse(uri).path)[1][1:] |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1361 data_type = ext_type or accept_type or self.__default_accept_type |
| 5574 | 1362 |
|
5617
38b7c4693d9a
Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents:
5616
diff
changeset
|
1363 if ( ext_type ): |
|
38b7c4693d9a
Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents:
5616
diff
changeset
|
1364 # strip extension so uri make sense |
|
5619
1c9208fa9127
Make sure a commentis a comment.
John Rouillard <rouilj@ieee.org>
parents:
5618
diff
changeset
|
1365 # .../issue.json -> .../issue |
|
5617
38b7c4693d9a
Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents:
5616
diff
changeset
|
1366 uri = uri[:-( len(ext_type) + 1 )] |
|
38b7c4693d9a
Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents:
5616
diff
changeset
|
1367 |
| 5582 | 1368 # add access-control-allow-* to support CORS |
| 5574 | 1369 self.client.setHeader("Access-Control-Allow-Origin", "*") |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1370 self.client.setHeader( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1371 "Access-Control-Allow-Headers", |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1372 "Content-Type, Authorization, X-HTTP-Method-Override" |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1373 ) |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1374 self.client.setHeader( |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1375 "Allow", |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1376 "HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH" |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1377 ) |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1378 self.client.setHeader( |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1379 "Access-Control-Allow-Methods", |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1380 "HEAD, OPTIONS, GET, PUT, DELETE, PATCH" |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1381 ) |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1382 # Is there an input.value with format json data? |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1383 # If so turn it into an object that emulates enough |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1384 # of the FieldStorge methods/props to allow a response. |
|
5650
e8ca7072c629
Fix Python 3 issues in REST code.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5646
diff
changeset
|
1385 content_type_header = headers.get('Content-Type', None) |
|
5655
207e0f5d551c
Merge in non-conflicting changes from ba67e397f063
John Rouillard <rouilj@ieee.org>
diff
changeset
|
1386 # python2 is str type, python3 is bytes |
|
207e0f5d551c
Merge in non-conflicting changes from ba67e397f063
John Rouillard <rouilj@ieee.org>
diff
changeset
|
1387 if type(input.value) in ( str, bytes ) and content_type_header: |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1388 parsed_content_type_header = content_type_header |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1389 # the structure of a content-type header |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1390 # is complex: mime-type; options(charset ...) |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1391 # for now we just accept application/json. |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1392 # FIXME there should be a function: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1393 # parse_content_type_header(content_type_header) |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1394 # that returns a tuple like the Accept header parser. |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1395 # Then the test below could use: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1396 # parsed_content_type_header[0].lower() == 'json' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1397 # That way we could handle stuff like: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1398 # application/vnd.roundup-foo+json; charset=UTF8 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1399 # for example. |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1400 if content_type_header.lower() == "application/json": |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1401 try: |
|
5655
207e0f5d551c
Merge in non-conflicting changes from ba67e397f063
John Rouillard <rouilj@ieee.org>
diff
changeset
|
1402 input = SimulateFieldStorageFromJson(b2s(input.value)) |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1403 except ValueError as msg: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1404 output = self.error_obj(400, msg) |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1405 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1406 # check for pretty print |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1407 try: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1408 pretty_output = not input['pretty'].value.lower() == "false" |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1409 except KeyError: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1410 pretty_output = True |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1411 |
| 5582 | 1412 # Call the appropriate method |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1413 try: |
|
5620
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1414 # If output was defined by a prior error |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1415 # condition skip call |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1416 if not output: |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1417 output = Routing.execute(self, uri, method, input) |
| 5602 | 1418 except NotFound as msg: |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1419 output = self.error_obj(404, msg) |
| 5602 | 1420 except Reject as msg: |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1421 output = self.error_obj(405, msg) |
|
5567
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
1422 |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1423 # Format the content type |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
1424 if data_type.lower() == "json": |
|
5589
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1425 self.client.setHeader("Content-Type", "application/json") |
|
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1426 if pretty_output: |
|
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1427 indent = 4 |
| 5574 | 1428 else: |
|
5589
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1429 indent = None |
|
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1430 output = RoundupJSONEncoder(indent=indent).encode(output) |
|
5631
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
1431 elif data_type.lower() == "xml" and dicttoxml: |
|
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
1432 self.client.setHeader("Content-Type", "application/xml") |
|
5669
1e8f17090a33
Try to fix mysql crash on close by rolling back mysqlclient.
John Rouillard <rouilj@ieee.org>
parents:
5668
diff
changeset
|
1433 output = b2s(dicttoxml(output, root=False)) |
|
5589
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1434 else: |
|
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1435 self.client.response_code = 406 |
|
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1436 output = "Content type is not accepted by client" |
|
5557
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
1437 |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
1438 # Make output json end in a newline to |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
1439 # separate from following text in logs etc.. |
|
5653
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
1440 return bs2b(output + "\n") |
|
5566
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1441 |
|
5567
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
1442 |
|
5566
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1443 class RoundupJSONEncoder(json.JSONEncoder): |
| 5582 | 1444 """RoundupJSONEncoder overrides the default JSONEncoder to handle all |
| 1445 types of the object without returning any error""" | |
|
5566
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1446 def default(self, obj): |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1447 try: |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1448 result = json.JSONEncoder.default(self, obj) |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1449 except TypeError: |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1450 result = str(obj) |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1451 return result |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1452 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1453 class SimulateFieldStorageFromJson(): |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1454 ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1455 The internals of the rest interface assume the data was sent as |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1456 application/x-www-form-urlencoded. So we should have a |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1457 FieldStorage and MiniFieldStorage structure. |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1458 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1459 However if we want to handle json data, we need to: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1460 1) create the Fieldstorage/MiniFieldStorage structure |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1461 or |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1462 2) simultate the interface parts of FieldStorage structure |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1463 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1464 To do 2, create a object that emulates the: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1465 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1466 object['prop'].value |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1467 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1468 references used when accessing a FieldStorage structure. |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1469 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1470 That's what this class does. |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1471 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1472 ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1473 def __init__(self, json_string): |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1474 ''' Parse the json string into an internal dict. ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1475 def raise_error_on_constant(x): |
|
5644
b4d7588c74a4
Make exception raising work on python 3.
John Rouillard <rouilj@ieee.org>
parents:
5643
diff
changeset
|
1476 raise ValueError("Unacceptable number: %s"%x) |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1477 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1478 self.json_dict = json.loads(json_string, |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1479 parse_constant = raise_error_on_constant) |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1480 self.value = [ self.FsValue(index, self.json_dict[index]) for index in self.json_dict.keys() ] |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1481 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1482 class FsValue: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1483 '''Class that does nothing but response to a .value property ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1484 def __init__(self, name, val): |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1485 self.name=name |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1486 self.value=val |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1487 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1488 def __getitem__(self, index): |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1489 '''Return an FsValue created from the value of self.json_dict[index] |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1490 ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1491 return self.FsValue(index, self.json_dict[index]) |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1492 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1493 def __contains__(self, index): |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1494 ''' implement: 'foo' in DICT ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1495 return index in self.json_dict |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1496 |
