annotate roundup/rest.py @ 5630:07abc8d36940

Add etag support to rest interface to prevent multiple users from overwriting other users changes. All GET requests for an object (issue, user, keyword etc.) or a property of an object (e.g the title of an issue) return the etag for the object in the ETag header as well as the @etag field in the returned object. All requests that change existing objects (DELETE, PUT or PATCH) require: 1 A request include an ETag header with the etag value retrieved for the object. 2 A submits a form that includes the field @etag that must have the value retrieved for the object. If an etag is not supplied by one of these methods, or any supplied etag does not match the etag calculated at the time the DELETE, PUT or PATCH request is made, HTTP error 412 (Precondition Failed) is returned and no change is made. At that time the client code should retrieve the object again, reconcile the changes and can try to send a new update. The etag is the md5 hash of the representation (repr()) of the object retrieved from the database.
author John Rouillard <rouilj@ieee.org>
date Fri, 01 Mar 2019 22:57:07 -0500
parents 2a7d23a098ca
children a5c890d308c3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
8 from __future__ import print_function
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
9
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
10 try:
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
11 from urllib.parse import urlparse
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
12 except ImportError:
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
13 from urlparse import urlparse
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
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
5557
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
22 from roundup import hyperdb
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
23 from roundup import date
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
24 from roundup import actions
5562
70df783c4c0b Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5561
diff changeset
25 from roundup.exceptions import *
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
26 from roundup.cgi.exceptions import *
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
27
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
28 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
29
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
30 # Py3 compatible basestring
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
31 try:
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
32 basestring
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
33 except NameError:
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
34 basestring = str
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
35 unicode = str
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
36
5620
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
37 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
38 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
39
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
40 def _data_decorator(func):
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
41 """Wrap the returned data into an object."""
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
42 def format_object(self, *args, **kwargs):
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
43 # get the data / error from function
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
44 try:
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
45 code, data = func(self, *args, **kwargs)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
46 except NotFound as msg:
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
47 code = 404
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
48 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
49 except IndexError as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
50 code = 404
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
51 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
52 except Unauthorised as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
53 code = 403
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
54 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
55 except UsageError as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
56 code = 400
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
57 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
58 except (AttributeError, Reject) as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
59 code = 405
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
60 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
61 except ValueError as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
62 code = 409
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
63 data = msg
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
64 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
65 code = 412
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
66 data = msg
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
67 except NotImplementedError:
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
68 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
69 data = 'Method under development'
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
70 except:
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
71 exc, val, tb = sys.exc_info()
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
72 code = 400
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
73 ts = time.ctime()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
74 if getattr (self.client.request, 'DEBUG_MODE', None):
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
75 data = val
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
76 else:
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
77 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
78 ' for more information.' % ts
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
79 # out to the logfile
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
80 print ('EXCEPTION AT', ts)
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
81 traceback.print_exc()
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
82
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
83 # decorate it
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
84 self.client.response_code = code
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
85 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
86 result = {
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
87 'error': {
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
88 'status': code,
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
89 'msg': data
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
90 }
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
91 }
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
92 else:
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
93 result = {
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
94 'data': data
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
95 }
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
96 return result
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
97 return format_object
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
98
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
99 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
100 '''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
101 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
102
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
103 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
104 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
105
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
106 <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
107
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
108 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
109
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
110 {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
111
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
112 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
113 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
114 calculate the etag.
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
115
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
116 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
117 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
118
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
119 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
120 '''
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 items = node.items(protected=True) # include every item
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
123 etag = md5(repr(items)).hexdigest()
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
124 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
125 etag, repr(node.items(protected=True)))
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
126 return 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 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
129 '''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
130
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
131 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
132 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
133 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
134 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
135
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
136 '''
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
137 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
138
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
139 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
140
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
141 for etag in etags:
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
142 if etag != None:
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
143 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
144 return False
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
145 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
146
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
147 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
148 return True
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
149 else:
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
150 return 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 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
153 '''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
154 etags = []
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
155 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
156 etags.append(input['@etag'].value);
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
157 etags.append(headers.getheader("ETag", None))
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
158 return etags
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
159
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
160 def parse_accept_header(accept):
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
161 """
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
162 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
163 [(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
164
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
165 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
166 application/vnd.yourcompany.yourproduct-v1.1+json
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
167
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
168 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
169 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
170 negotiation decisions can be made.
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
171
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
172 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
173
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
174 # 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
175 # 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
176 # https://github.com/martinblech/mimerender
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 result = []
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
179 for media_range in accept.split(","):
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
180 parts = media_range.split(";")
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
181 media_type = parts.pop(0).strip()
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
182 media_params = []
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
183 # 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
184 # docstring)
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
185 typ, subtyp = media_type.split('/')
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
186 # check for a + in the sub-type
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
187 if '+' in subtyp:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
188 # 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
189 vnd, sep, extra = subtyp.partition('+')
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
190 if vnd.startswith('vnd'):
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
191 # 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
192 # version out
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
193 if '-v' in vnd:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
194 vnd, sep, rest = vnd.rpartition('-v')
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
195 if len(rest):
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
196 # add the version as a media param
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
197 try:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
198 version = media_params.append(('version',
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
199 float(rest)))
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
200 except ValueError:
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
201 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
202 # 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
203 media_params.append(('vendor', vnd))
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
204 # 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
205 # 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
206 media_type = '{}/{}'.format(typ, extra)
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
207 q = 1.0
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
208 for part in parts:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
209 (key, value) = part.lstrip().split("=", 1)
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
210 key = key.strip()
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
211 value = value.strip()
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
212 if key == "q":
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
213 q = float(value)
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
214 else:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
215 media_params.append((key, value))
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
216 result.append((media_type, dict(media_params), q))
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
217 result.sort(lambda x, y: -cmp(x[2], y[2]))
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
218 return result
5567
1af57f9d5bf7 Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5566
diff changeset
219
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
220
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
221 class Routing(object):
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
222 __route_map = {}
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
223 __var_to_regex = re.compile(r"<:(\w+)>")
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
224 url_to_regex = r"([\w.\-~!$&'()*+,;=:@\%%]+)"
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
225
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
226 @classmethod
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
227 def route(cls, rule, methods='GET'):
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
228 """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
229 given URL rule:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
230 @self.route('/')
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
231 def index():
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
232 return 'Hello World'
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
233
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
234 rest/ will be added to the beginning of the url string
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
235
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
236 Args:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
237 rule (string): the URL rule
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
238 methods (string or tuple or list): the http method
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
239 """
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
240 # strip the '/' character from rule string
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
241 rule = rule.strip('/')
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
242
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
243 # add 'rest/' to the rule string
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
244 if not rule.startswith('rest/'):
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
245 rule = '^rest/' + rule + '$'
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 if isinstance(methods, basestring): # convert string to tuple
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
248 methods = (methods,)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
249 methods = set(item.upper() for item in methods)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
250
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
251 # convert a rule to a compiled regex object
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
252 # so /data/<:class>/<:id> will become
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
253 # /data/([charset]+)/([charset]+)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
254 # and extract the variable names to a list [(class), (id)]
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
255 func_vars = cls.__var_to_regex.findall(rule)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
256 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
257
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
258 # then we decorate it:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
259 # route_map[regex][method] = func
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
260 def decorator(func):
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
261 rule_route = cls.__route_map.get(rule, {})
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
262 func_obj = {
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
263 'func': func,
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
264 'vars': func_vars
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
265 }
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
266 for method in methods:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
267 rule_route[method] = func_obj
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
268 cls.__route_map[rule] = rule_route
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
269 return func
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
270 return decorator
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
271
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
272 @classmethod
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
273 def execute(cls, instance, path, method, input):
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
274 # format the input
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
275 path = path.strip('/').lower()
5622
2a7d23a098ca Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents: 5621
diff changeset
276 if path == 'rest':
2a7d23a098ca Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents: 5621
diff changeset
277 # 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
278 path = 'rest/'
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
279 method = method.upper()
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
280
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
281 # find the rule match the path
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
282 # then get handler match the method
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
283 for path_regex in cls.__route_map:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
284 match_obj = path_regex.match(path)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
285 if match_obj:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
286 try:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
287 func_obj = cls.__route_map[path_regex][method]
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
288 except KeyError:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
289 raise Reject('Method %s not allowed' % method)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
290
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
291 # retrieve the vars list and the function caller
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
292 list_vars = func_obj['vars']
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
293 func = func_obj['func']
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
294
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
295 # 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
296 args = dict(zip(list_vars, match_obj.groups()))
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
297 args['input'] = input
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
298 return func(instance, **args)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
299 raise NotFound('Nothing matches the given URI')
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
300
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
301
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
302 class RestfulInstance(object):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
303 """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
304
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
305 __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
306 __accepted_content_type = {
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
307 "application/json": "json",
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
308 "*/*": "json"
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
309 # "application/xml": "xml"
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
310 }
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
311 __default_accept_type = "json"
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
312
5568
edab9daa8015 Make objects returned by REST follow the standard
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5567
diff changeset
313 def __init__(self, client, db):
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
314 self.client = client
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
315 self.db = db
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
316 self.translator = client.translator
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
317 # This used to be initialized from client.instance.actions which
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
318 # would include too many actions that do not make sense in the
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
319 # REST-API context, so for now we only permit the retire and
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
320 # restore actions.
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
321 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
322
5616
aa4c271514ae Original code generated url's using a harcoded protocol and took the
John Rouillard <rouilj@ieee.org>
parents: 5604
diff changeset
323 # 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
324 self.base_path = '%srest' % (self.db.config.TRACKER_WEB)
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
325 self.data_path = self.base_path + '/data'
5569
2718aeb55ffa Add base_path to generate uri
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5568
diff changeset
326
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
327 def props_from_args(self, cl, args, itemid=None):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
328 """Construct a list of properties from the given arguments,
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
329 and return them after validation.
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
330
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
331 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
332 cl (string): class object of the resource
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
333 args (list): the submitted form of the user
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
334 itemid (string, optional): itemid of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
335
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
336 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
337 dict: dictionary of validated properties
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
338
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
339 """
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
340 class_props = cl.properties.keys()
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
341 props = {}
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
342 # props = dict.fromkeys(class_props, None)
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
343
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
344 for arg in args:
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
345 key = arg.name
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
346 value = arg.value
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
347 if key not in class_props:
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
348 continue
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
349 props[key] = self.prop_from_arg(cl, key, value, itemid)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
350
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
351 return props
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
352
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
353 def prop_from_arg(self, cl, key, value, itemid=None):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
354 """Construct a property from the given argument,
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
355 and return them after validation.
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
356
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
357 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
358 cl (string): class object of the resource
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
359 key (string): attribute key
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
360 value (string): attribute value
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
361 itemid (string, optional): itemid of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
362
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
363 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
364 value: value of validated properties
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
365
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
366 """
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
367 prop = None
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
368 if isinstance(key, unicode):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
369 try:
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
370 x = key.encode('ascii')
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
371 except UnicodeEncodeError:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
372 raise UsageError(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
373 'argument %r is no valid ascii keyword' % key
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
374 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
375 if value:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
376 try:
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
377 prop = hyperdb.rawToHyperdb(self.db, cl, itemid, key, value)
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
378 except hyperdb.HyperdbValueError as msg:
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
379 raise UsageError(msg)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
380
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
381 return prop
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
382
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
383 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
384 """Return an error object"""
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
385 self.client.response_code = status
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
386 result = {
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
387 'error': {
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
388 'status': status,
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
389 'msg': msg
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
390 }
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
391 }
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
392 if source is not None:
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
393 result['error']['source'] = source
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
394
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
395 return result
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
396
5595
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
397 def patch_data(self, op, old_val, new_val):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
398 """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
399
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
400 Args:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
401 op (string): PATCH operation: add, replace, remove
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
402 old_val: old value of the property
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
403 new_val: new value of the property
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
404
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
405 Returns:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
406 result (string): value after performed the operation
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
407 """
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
408 # 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
409 # Otherwise, concat those 2 value
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
410 if op == 'add':
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
411 if old_val is None:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
412 result = new_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
413 elif new_val is None:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
414 result = old_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
415 else:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
416 result = old_val + new_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
417 # Replace operation: new value is returned
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
418 elif op == 'replace':
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
419 result = new_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
420 # Remove operation:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
421 # 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
422 # 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
423 # change it to none
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
424 # 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
425 # 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
426 elif op == 'remove':
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
427 if isinstance(old_val, list):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
428 if new_val is None:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
429 result = []
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
430 elif isinstance(new_val, list):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
431 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
432 else:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
433 if new_val in old_val:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
434 old_val.remove(new_val)
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
435 elif isinstance(old_val, dict):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
436 if new_val is None:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
437 result = {}
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
438 elif isinstance(new_val, dict):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
439 for x in new_val:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
440 old_val.pop(x, None)
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
441 else:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
442 old_val.pop(new_val, None)
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
443 else:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
444 result = None
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 raise UsageError('PATCH Operation %s is not allowed' % op)
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
447
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
448 return result
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
449
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
450 @Routing.route("/data/<:class_name>", 'GET')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
451 @_data_decorator
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
452 def get_collection(self, class_name, input):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
453 """GET resource from class URI.
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
454
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
455 This function returns only items have View permission
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
456 class_name should be valid already
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
457
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
458 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
459 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
460 input (list): the submitted form of the user
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
461
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
462 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
463 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
464 list: list of reference item in the class
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
465 id: id of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
466 link: path to the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
467 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
468 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
469 raise NotFound('Class %s not found' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
470 if not self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
471 'View', self.db.getuid(), class_name
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
472 ):
5562
70df783c4c0b Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5561
diff changeset
473 raise Unauthorised('Permission to view %s denied' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
474
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
475 class_obj = self.db.getclass(class_name)
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
476 class_path = '%s/%s/' % (self.data_path, class_name)
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
477
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
478 # Handle filtering and pagination
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
479 filter_props = {}
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
480 page = {
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
481 'size': None,
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
482 'index': None
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
483 }
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
484 for form_field in input.value:
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
485 key = form_field.name
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
486 value = form_field.value
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
487 if key.startswith("where_"): # serve the filter purpose
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
488 key = key[6:]
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
489 filter_props[key] = [
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
490 getattr(self.db, key).lookup(p)
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
491 for p in value.split(",")
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
492 ]
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
493 elif key.startswith("page_"): # serve the paging purpose
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
494 key = key[5:]
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
495 value = int(value)
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
496 page[key] = value
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
497
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
498 if not filter_props:
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
499 obj_list = class_obj.list()
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
500 else:
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
501 obj_list = class_obj.filter(None, filter_props)
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
502
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
503 # extract result from data
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
504 result = [
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
505 {'id': item_id, 'link': class_path + item_id}
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
506 for item_id in obj_list
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
507 if self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
508 'View', self.db.getuid(), class_name, itemid=item_id
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
509 )
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
510 ]
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
511
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
512 # pagination
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
513 if page['size'] is not None and page['index'] is not None:
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
514 page_start = max(page['index'] * page['size'], 0)
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
515 page_end = min(page_start + page['size'], len(result))
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
516 result = result[page_start:page_end]
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
517
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
518 self.client.setHeader("X-Count-Total", str(len(result)))
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
519 return 200, result
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
520
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
521 @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
522 @_data_decorator
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
523 def get_element(self, class_name, item_id, input):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
524 """GET resource from object URI.
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
525
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
526 This function returns only properties have View permission
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
527 class_name and item_id should be valid already
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
528
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
529 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
530 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
531 item_id (string): id of the resource (Ex: 12, 15)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
532 input (list): the submitted form of the user
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
533
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
534 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
535 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
536 dict: a dictionary represents the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
537 id: id of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
538 type: class name of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
539 link: link to the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
540 attributes: a dictionary represent the attributes of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
541 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
542 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
543 raise NotFound('Class %s not found' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
544 if not self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
545 'View', self.db.getuid(), class_name, itemid=item_id
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
546 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
547 raise Unauthorised(
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
548 'Permission to view %s%s denied' % (class_name, item_id)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
549 )
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
550
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
551 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
552 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
553 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
554 props = None
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
555 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
556 key = form_field.name
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
557 value = form_field.value
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
558 if key == "fields":
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
559 props = value.split(",")
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
560
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
561 if props is None:
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
562 props = list(sorted(class_obj.properties.keys()))
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
563
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
564 try:
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
565 result = [
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
566 (prop_name, node.__getattr__(prop_name))
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
567 for prop_name in props
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
568 if self.db.security.hasPermission(
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
569 'View', self.db.getuid(), class_name, prop_name,
5618
1ad3881fc683 The access check on properties for an instance of a class
John Rouillard <rouilj@ieee.org>
parents: 5617
diff changeset
570 item_id )
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
571 ]
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
572 except KeyError as msg:
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
573 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
574 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
575 'id': item_id,
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
576 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
577 '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
578 'attributes': dict(result),
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
579 '@etag': etag
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
580 }
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
581
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
582 self.client.setHeader("ETag", '"%s"'%etag)
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
583 return 200, result
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
584
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
585 @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
586 @_data_decorator
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
587 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
588 """GET resource from attribute URI.
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
589
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
590 This function returns only attribute has View permission
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
591 class_name should be valid already
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
592
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
593 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
594 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
595 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
596 attr_name (string): attribute of the resource (Ex: title, nosy)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
597 input (list): the submitted form of the user
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
598
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
599 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
600 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
601 list: a dictionary represents the attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
602 id: id of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
603 type: class name of the attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
604 link: link to the attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
605 data: data of the requested attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
606 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
607 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
608 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
609 if not self.db.security.hasPermission(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
610 'View', self.db.getuid(), class_name, attr_name, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
611 ):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
612 raise Unauthorised(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
613 'Permission to view %s%s %s denied' %
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
614 (class_name, item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
615 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
616
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
617 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
618 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
619 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
620 data = node.__getattr__(attr_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
621 result = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
622 'id': item_id,
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
623 'type': type(data),
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
624 'link': "%s/%s/%s/%s" %
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
625 (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
626 'data': data,
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
627 '@etag': etag
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
628 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
629
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
630 self.client.setHeader("ETag", '"%s"'%etag )
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
631 return 200, result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
632
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
633 @Routing.route("/data/<:class_name>", 'POST')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
634 @_data_decorator
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
635 def post_collection(self, class_name, input):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
636 """POST a new object to a class
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
637
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
638 If the item is successfully created, the "Location" header will also
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
639 contain the link to the created object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
640
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
641 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
642 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
643 input (list): the submitted form of the user
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
644
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
645 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
646 int: http status code 201 (Created)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
647 dict: a reference item to the created object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
648 id: id of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
649 link: path to the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
650 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
651 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
652 raise NotFound('Class %s not found' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
653 if not self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
654 'Create', self.db.getuid(), class_name
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
655 ):
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
656 raise Unauthorised('Permission to create %s denied' % class_name)
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
657
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
658 class_obj = self.db.getclass(class_name)
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
659
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
660 # convert types
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
661 props = self.props_from_args(class_obj, input.value)
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
662
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
663 # check for the key property
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
664 key = class_obj.getkey()
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
665 if key and key not in props:
5576
77d11a24f718 Exceptions
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5575
diff changeset
666 raise UsageError("Must provide the '%s' property." % key)
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
667
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
668 for key in props:
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
669 if not self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
670 'Create', self.db.getuid(), class_name, property=key
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
671 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
672 raise Unauthorised(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
673 'Permission to create %s.%s denied' % (class_name, key)
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
674 )
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
675
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
676 # do the actual create
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
677 try:
5562
70df783c4c0b Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5561
diff changeset
678 item_id = class_obj.create(**props)
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
679 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
680 except (TypeError, IndexError, ValueError) as message:
5576
77d11a24f718 Exceptions
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5575
diff changeset
681 raise ValueError(message)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
682 except KeyError as msg:
5576
77d11a24f718 Exceptions
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5575
diff changeset
683 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
684
5573
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
685 # set the header Location
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
686 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
687 self.client.setHeader("Location", link)
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
688
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
689 # set the response body
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
690 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
691 'id': item_id,
5573
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
692 'link': link
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
693 }
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
694 return 201, result
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
695
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
696 @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
697 @_data_decorator
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
698 def put_element(self, class_name, item_id, input):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
699 """PUT a new content to an object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
700
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
701 Replace the content of the existing object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
702
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
703 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
704 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
705 item_id (string): id of the resource (Ex: 12, 15)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
706 input (list): the submitted form of the user
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
707
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
708 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
709 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
710 dict: a dictionary represents the modified object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
711 id: id of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
712 type: class name of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
713 link: link to the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
714 attributes: a dictionary represent only changed attributes of
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
715 the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
716 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
717 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
718 raise NotFound('Class %s not found' % class_name)
5564
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
719 class_obj = self.db.getclass(class_name)
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
720
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
721 props = self.props_from_args(class_obj, input.value, item_id)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
722 for p in props:
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
723 if not self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
724 'Edit', self.db.getuid(), class_name, p, item_id
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
725 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
726 raise Unauthorised(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
727 'Permission to edit %s of %s%s denied' %
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
728 (p, class_name, item_id)
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
729 )
5564
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
730 try:
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
731 if not check_etag(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
732 obtain_etags(self.client.request.headers, input),
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
733 class_name,
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
734 item_id):
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
735 raise PreconditionFailed("Etag is missing or does not match."
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
736 "Retreive asset and retry modification if valid.")
5564
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
737 result = class_obj.set(item_id, **props)
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
738 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
739 except (TypeError, IndexError, ValueError) as message:
5576
77d11a24f718 Exceptions
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5575
diff changeset
740 raise ValueError(message)
5564
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
741
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
742 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
743 'id': item_id,
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
744 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
745 '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
746 'attribute': result
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
747 }
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
748 return 200, result
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
749
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
750 @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
751 @_data_decorator
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
752 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
753 """PUT an attribute to an object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
754
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
755 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
756 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
757 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
758 attr_name (string): attribute of the resource (Ex: title, nosy)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
759 input (list): the submitted form of the user
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
760
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
761 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
762 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
763 dict:a dictionary represents the modified object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
764 id: id of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
765 type: class name of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
766 link: link to the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
767 attributes: a dictionary represent only changed attributes of
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
768 the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
769 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
770 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
771 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
772 if not self.db.security.hasPermission(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
773 'Edit', self.db.getuid(), class_name, attr_name, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
774 ):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
775 raise Unauthorised(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
776 'Permission to edit %s%s %s denied' %
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
777 (class_name, item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
778 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
779 class_obj = self.db.getclass(class_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
780 props = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
781 attr_name: self.prop_from_arg(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
782 class_obj, attr_name, input['data'].value, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
783 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
784 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
785
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
786 try:
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
787 if not check_etag(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
788 obtain_etags(self.client.request.headers, input),
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
789 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
790 raise PreconditionFailed("Etag is missing or does not match."
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
791 "Retreive asset and retry modification if valid.")
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
792 result = class_obj.set(item_id, **props)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
793 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
794 except (TypeError, IndexError, ValueError) as message:
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
795 raise ValueError(message)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
796
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
797 result = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
798 'id': item_id,
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
799 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
800 '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
801 'attribute': result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
802 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
803
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
804 return 200, result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
805
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
806 @Routing.route("/data/<:class_name>", 'DELETE')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
807 @_data_decorator
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
808 def delete_collection(self, class_name, input):
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
809 """DELETE (retire) all objects in a class
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
810 There is currently no use-case, so this is disabled and
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
811 always returns Unauthorised.
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
812
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
813 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
814 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
815 input (list): the submitted form of the user
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
816
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
817 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
818 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
819 dict:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
820 status (string): 'ok'
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
821 count (int): number of deleted objects
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
822 """
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
823 raise Unauthorised('Deletion of a whole class disabled')
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
824 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
825 raise NotFound('Class %s not found' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
826 if not self.db.security.hasPermission(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
827 'Retire', self.db.getuid(), class_name
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
828 ):
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
829 raise Unauthorised('Permission to delete %s denied' % class_name)
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
830
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
831 class_obj = self.db.getclass(class_name)
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
832 for item_id in class_obj.list():
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
833 if not self.db.security.hasPermission(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
834 'Retire', self.db.getuid(), class_name, itemid=item_id
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
835 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
836 raise Unauthorised(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
837 'Permission to retire %s %s denied' % (class_name, item_id)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
838 )
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
839
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
840 count = len(class_obj.list())
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
841 for item_id in class_obj.list():
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
842 class_obj.retire (item_id)
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
843
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
844 self.db.commit()
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
845 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
846 'status': 'ok',
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
847 'count': count
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
848 }
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
849
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
850 return 200, result
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
851
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
852 @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
853 @_data_decorator
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
854 def delete_element(self, class_name, item_id, input):
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
855 """DELETE (retire) an object in a class
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
856
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
857 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
858 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
859 item_id (string): id of the resource (Ex: 12, 15)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
860 input (list): the submitted form of the user
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
861
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
862 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
863 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
864 dict:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
865 status (string): 'ok'
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
866 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
867 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
868 raise NotFound('Class %s not found' % class_name)
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
869 class_obj = self.db.classes [class_name]
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
870 if not self.db.security.hasPermission(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
871 'Retire', self.db.getuid(), class_name, itemid=item_id
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
872 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
873 raise Unauthorised(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
874 'Permission to retire %s %s denied' % (class_name, item_id)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
875 )
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
876
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
877 if not check_etag(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
878 obtain_etags(self.client.request.headers, input),
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
879 class_name,
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
880 item_id):
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
881 raise PreconditionFailed("Etag is missing or does not match."
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
882 "Retreive asset and retry modification if valid.")
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
883
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
884 class_obj.retire (item_id)
5562
70df783c4c0b Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5561
diff changeset
885 self.db.commit()
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
886 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
887 'status': 'ok'
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
888 }
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
889
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
890 return 200, result
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
891
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
892 @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
893 @_data_decorator
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
894 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
895 """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
896
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
897 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
898 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
899 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
900 attr_name (string): attribute of the resource (Ex: title, nosy)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
901 input (list): the submitted form of the user
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
902
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
903 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
904 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
905 dict:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
906 status (string): 'ok'
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
907 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
908 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
909 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
910 if not self.db.security.hasPermission(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
911 'Edit', self.db.getuid(), class_name, attr_name, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
912 ):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
913 raise Unauthorised(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
914 'Permission to delete %s%s %s denied' %
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
915 (class_name, item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
916 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
917
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
918 class_obj = self.db.getclass(class_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
919 props = {}
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
920 prop_obj = class_obj.get(item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
921 if isinstance(prop_obj, list):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
922 props[attr_name] = []
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
923 else:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
924 props[attr_name] = None
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
925
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
926 try:
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
927 if not check_etag(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
928 obtain_etags(self.client.request.headers, input),
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
929 class_name,
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
930 item_id):
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
931 raise PreconditionFailed("Etag is missing or does not match."
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
932 "Retreive asset and retry modification if valid.")
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
933
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
934 class_obj.set(item_id, **props)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
935 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
936 except (TypeError, IndexError, ValueError) as message:
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
937 raise ValueError(message)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
938
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
939 result = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
940 'status': 'ok'
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
941 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
942
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
943 return 200, result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
944
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
945 @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
946 @_data_decorator
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
947 def patch_element(self, class_name, item_id, input):
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
948 """PATCH an object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
949
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
950 Patch an element using 3 operators
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
951 ADD : Append new value to the object's attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
952 REPLACE: Replace object's attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
953 REMOVE: Clear object's attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
954
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
955 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
956 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
957 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
958 input (list): the submitted form of the user
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
959
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
960 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
961 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
962 dict: a dictionary represents the modified object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
963 id: id of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
964 type: class name of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
965 link: link to the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
966 attributes: a dictionary represent only changed attributes of
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
967 the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
968 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
969 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
970 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
971 try:
d5a54b1851aa Add default op action for Patch
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5579
diff changeset
972 op = input['op'].value.lower()
d5a54b1851aa Add default op action for Patch
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5579
diff changeset
973 except KeyError:
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
974 op = self.__default_patch_op
5578
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
975 class_obj = self.db.getclass(class_name)
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
976
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
977 if not check_etag(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
978 obtain_etags(self.client.request.headers, input),
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
979 class_name,
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
980 item_id):
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
981 raise PreconditionFailed("Etag is missing or does not match."
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
982 "Retreive asset and retry modification if valid.")
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
983
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
984 # if patch operation is action, call the action handler
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
985 action_args = [class_name + item_id]
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
986 if op == 'action':
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
987 # extract action_name and action_args from form fields
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
988 for form_field in input.value:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
989 key = form_field.name
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
990 value = form_field.value
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
991 if key == "action_name":
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
992 name = value
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
993 elif key.startswith('action_args'):
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
994 action_args.append(value)
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
995
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
996 if name in self.actions:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
997 action_type = self.actions[name]
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
998 else:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
999 raise UsageError(
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1000 'action "%s" is not supported %s' %
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1001 (name, ','.join(self.actions.keys()))
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1002 )
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1003 action = action_type(self.db, self.translator)
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1004 result = action.execute(*action_args)
5578
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
1005
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1006 result = {
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1007 'id': item_id,
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1008 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1009 '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
1010 'result': result
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1011 }
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1012 else:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1013 # else patch operation is processing data
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1014 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
1015
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1016 for prop in props:
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1017 if not self.db.security.hasPermission(
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1018 'Edit', self.db.getuid(), class_name, prop, item_id
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1019 ):
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1020 raise Unauthorised(
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1021 'Permission to edit %s of %s%s denied' %
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1022 (prop, class_name, item_id)
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1023 )
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1024
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1025 props[prop] = self.patch_data(
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1026 op, class_obj.get(item_id, prop), props[prop]
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1027 )
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1028
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1029 try:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1030 result = class_obj.set(item_id, **props)
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1031 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1032 except (TypeError, IndexError, ValueError) as message:
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1033 raise ValueError(message)
5578
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
1034
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1035 result = {
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1036 'id': item_id,
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1037 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1038 '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
1039 'attribute': result
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1040 }
5578
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
1041 return 200, result
5557
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
1042
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1043 @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
1044 @_data_decorator
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1045 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
1046 """PATCH an attribute of an object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1047
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1048 Patch an element using 3 operators
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1049 ADD : Append new value to the attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1050 REPLACE: Replace attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1051 REMOVE: Clear attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1052
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1053 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1054 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
1055 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1056 attr_name (string): attribute of the resource (Ex: title, nosy)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1057 input (list): the submitted form of the user
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1058
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1059 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1060 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1061 dict: a dictionary represents the modified object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1062 id: id of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1063 type: class name of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1064 link: link to the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1065 attributes: a dictionary represent only changed attributes of
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1066 the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1067 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1068 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1069 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1070 try:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1071 op = input['op'].value.lower()
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1072 except KeyError:
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
1073 op = self.__default_patch_op
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1074
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1075 if not self.db.security.hasPermission(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1076 'Edit', self.db.getuid(), class_name, attr_name, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1077 ):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1078 raise Unauthorised(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1079 'Permission to edit %s%s %s denied' %
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1080 (class_name, item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1081 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1082
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1083 prop = attr_name
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1084 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
1085
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1086 if not check_etag(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
1087 obtain_etags(self.client.request.headers, input),
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1088 class_name,
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1089 item_id):
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1090 raise PreconditionFailed("Etag is missing or does not match."
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1091 "Retreive asset and retry modification if valid.")
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1092
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1093 props = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1094 prop: self.prop_from_arg(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1095 class_obj, prop, input['data'].value, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1096 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1097 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1098
5595
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
1099 props[prop] = self.patch_data(
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
1100 op, class_obj.get(item_id, prop), props[prop]
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
1101 )
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1102
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1103 try:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1104 result = class_obj.set(item_id, **props)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1105 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1106 except (TypeError, IndexError, ValueError) as message:
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1107 raise ValueError(message)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1108
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1109 result = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1110 'id': item_id,
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1111 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1112 '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
1113 'attribute': result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1114 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1115 return 200, result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1116
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1117 @Routing.route("/data/<:class_name>", 'OPTIONS')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1118 @_data_decorator
5575
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1119 def options_collection(self, class_name, input):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1120 """OPTION return the HTTP Header for the class uri
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1121
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1122 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1123 int: http status code 204 (No content)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1124 body (string): an empty string
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1125 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1126 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1127 raise NotFound('Class %s not found' % class_name)
5575
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1128 return 204, ""
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1129
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1130 @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
1131 @_data_decorator
5575
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1132 def options_element(self, class_name, item_id, input):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1133 """OPTION return the HTTP Header for the object uri
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1134
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1135 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1136 int: http status code 204 (No content)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1137 body (string): an empty string
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1138 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1139 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1140 raise NotFound('Class %s not found' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1141 self.client.setHeader(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1142 "Accept-Patch",
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1143 "application/x-www-form-urlencoded, multipart/form-data"
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1144 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1145 return 204, ""
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1146
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1147 @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
1148 @_data_decorator
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1149 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
1150 """OPTION return the HTTP Header for the attribute uri
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1151
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1152 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1153 int: http status code 204 (No content)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1154 body (string): an empty string
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1155 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1156 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1157 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1158 self.client.setHeader(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1159 "Accept-Patch",
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1160 "application/x-www-form-urlencoded, multipart/form-data"
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1161 )
5575
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1162 return 204, ""
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1163
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1164 @Routing.route("/summary")
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1165 @_data_decorator
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1166 def summary(self, input):
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1167 """Get a summary of resource from class URI.
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1168
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1169 This function returns only items have View permission
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1170 class_name should be valid already
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1171
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1172 Args:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1173 class_name (string): class name of the resource (Ex: issue, msg)
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1174 input (list): the submitted form of the user
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1175
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1176 Returns:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1177 int: http status code 200 (OK)
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1178 list:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1179 """
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1180 if not self.db.security.hasPermission(
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1181 'View', self.db.getuid(), 'issue'
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1182 ) and not self.db.security.hasPermission(
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1183 'View', self.db.getuid(), 'status'
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1184 ) and not self.db.security.hasPermission(
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1185 'View', self.db.getuid(), 'issue'
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1186 ):
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1187 raise Unauthorised('Permission to view summary denied')
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1188
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1189 old = date.Date('-1w')
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1190
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1191 created = []
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1192 summary = {}
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1193 messages = []
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1194
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1195 # loop through all the recently-active issues
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1196 for issue_id in self.db.issue.filter(None, {'activity': '-1w;'}):
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1197 num = 0
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1198 status_name = self.db.status.get(
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1199 self.db.issue.get(issue_id, 'status'),
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1200 'name'
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1201 )
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1202 issue_object = {
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1203 'id': issue_id,
5621
39dbe83643c0 Fix path of links in /rest/summary.
John Rouillard <rouilj@ieee.org>
parents: 5620
diff changeset
1204 'link': self.base_path + '/data/issue/' + issue_id,
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1205 'title': self.db.issue.get(issue_id, 'title')
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1206 }
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1207 for x, ts, uid, action, data in self.db.issue.history(issue_id):
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1208 if ts < old:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1209 continue
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1210 if action == 'create':
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1211 created.append(issue_object)
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1212 elif action == 'set' and 'messages' in data:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1213 num += 1
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1214 summary.setdefault(status_name, []).append(issue_object)
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1215 messages.append((num, issue_object))
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1216
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1217 messages.sort(reverse=True)
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1218
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1219 result = {
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1220 'created': created,
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1221 'summary': summary,
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1222 'most_discussed': messages[:10]
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1223 }
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1224
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1225 return 200, result
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
1226
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
1227 def dispatch(self, method, uri, input):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1228 """format and process the request"""
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1229 # 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
1230 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
1231 # 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
1232 # User must use POST to "tunnel" DELETE, PUT, OPTIONS etc.
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
1233 override = headers.getheader('X-HTTP-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
1234 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
1235 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
1236 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
1237 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
1238 '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
1239 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
1240 else:
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
1241 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
1242 "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
1243 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
1244 '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
1245 uri)
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1246
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
1247 # parse Accept header and get the content type
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
1248 accept_header = parse_accept_header(headers.getheader('Accept'))
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
1249 accept_type = "invalid"
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
1250 for part in accept_header:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
1251 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
1252 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
1253
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1254 # get the request format for response
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1255 # priority : extension from uri (/rest/issue.json),
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1256 # header (Accept: application/json, application/xml)
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1257 # default (application/json)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1258 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
1259 data_type = ext_type or accept_type or self.__default_accept_type
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1260
5617
38b7c4693d9a Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents: 5616
diff changeset
1261 if ( ext_type ):
38b7c4693d9a Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents: 5616
diff changeset
1262 # strip extension so uri make sense
5619
1c9208fa9127 Make sure a commentis a comment.
John Rouillard <rouilj@ieee.org>
parents: 5618
diff changeset
1263 # .../issue.json -> .../issue
5617
38b7c4693d9a Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents: 5616
diff changeset
1264 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
1265
5577
11e75fbb9edc Added pretty print
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5576
diff changeset
1266 # check for pretty print
11e75fbb9edc Added pretty print
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5576
diff changeset
1267 try:
11e75fbb9edc Added pretty print
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5576
diff changeset
1268 pretty_output = input['pretty'].value.lower() == "true"
11e75fbb9edc Added pretty print
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5576
diff changeset
1269 except KeyError:
11e75fbb9edc Added pretty print
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5576
diff changeset
1270 pretty_output = False
11e75fbb9edc Added pretty print
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5576
diff changeset
1271
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1272 # add access-control-allow-* to support CORS
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1273 self.client.setHeader("Access-Control-Allow-Origin", "*")
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1274 self.client.setHeader(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1275 "Access-Control-Allow-Headers",
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1276 "Content-Type, Authorization, X-HTTP-Method-Override"
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1277 )
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1278 self.client.setHeader(
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1279 "Allow",
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1280 "HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH"
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1281 )
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1282 self.client.setHeader(
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1283 "Access-Control-Allow-Methods",
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1284 "HEAD, OPTIONS, GET, PUT, DELETE, PATCH"
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1285 )
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
1286
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1287 # Call the appropriate method
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1288 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
1289 # 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
1290 # 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
1291 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
1292 output = Routing.execute(self, uri, method, input)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1293 except NotFound as msg:
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1294 output = self.error_obj(404, msg)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1295 except Reject as msg:
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1296 output = self.error_obj(405, msg)
5567
1af57f9d5bf7 Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5566
diff changeset
1297
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
1298 # Format the content type
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
1299 if data_type.lower() == "json":
5589
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
1300 self.client.setHeader("Content-Type", "application/json")
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
1301 if pretty_output:
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
1302 indent = 4
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
1303 else:
5589
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
1304 indent = None
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
1305 output = RoundupJSONEncoder(indent=indent).encode(output)
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
1306 else:
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
1307 self.client.response_code = 406
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
1308 output = "Content type is not accepted by client"
5557
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
1309
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
1310 return output
5566
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
1311
5567
1af57f9d5bf7 Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5566
diff changeset
1312
5566
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
1313 class RoundupJSONEncoder(json.JSONEncoder):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1314 """RoundupJSONEncoder overrides the default JSONEncoder to handle all
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1315 types of the object without returning any error"""
5566
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
1316 def default(self, obj):
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
1317 try:
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
1318 result = json.JSONEncoder.default(self, obj)
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
1319 except TypeError:
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
1320 result = str(obj)
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
1321 return result

Roundup Issue Tracker: http://roundup-tracker.org/