1414import traceback
1515import xml
1616from roundup import hyperdb
17+ from roundup import date
1718from roundup .exceptions import *
1819
1920
@@ -70,6 +71,7 @@ def format_object(self, *args, **kwargs):
7071 return result
7172 return format_object
7273
74+
7375def parse_accept_header (accept ):
7476 """
7577 Parse the Accept header *accept*, returning a list with 3-tuples of
@@ -111,7 +113,7 @@ def parse_accept_header(accept):
111113 version = media_params .append (('version' ,
112114 float (rest )))
113115 except ValueError :
114- version = 1.0 # could not be parsed
116+ version = 1.0 # could not be parsed
115117 # add the vendor code as a media param
116118 media_params .append (('vendor' , vnd ))
117119 # and re-write media_type to something like application/json so
@@ -130,6 +132,7 @@ def parse_accept_header(accept):
130132 result .sort (lambda x , y : - cmp (x [2 ], y [2 ]))
131133 return result
132134
135+
133136class RestfulInstance (object ):
134137 """The RestfulInstance performs REST request from the client"""
135138
@@ -877,6 +880,68 @@ def option_attribute(self, class_name, item_id, attr_name, input):
877880 )
878881 return 204 , ""
879882
883+ @_data_decorator
884+ def summary (self , input ):
885+ """Get a summary of resource from class URI.
886+
887+ This function returns only items have View permission
888+ class_name should be valid already
889+
890+ Args:
891+ class_name (string): class name of the resource (Ex: issue, msg)
892+ input (list): the submitted form of the user
893+
894+ Returns:
895+ int: http status code 200 (OK)
896+ list:
897+ """
898+ if not self .db .security .hasPermission (
899+ 'View' , self .db .getuid (), 'issue'
900+ ) and not self .db .security .hasPermission (
901+ 'View' , self .db .getuid (), 'status'
902+ ) and not self .db .security .hasPermission (
903+ 'View' , self .db .getuid (), 'issue'
904+ ):
905+ raise Unauthorised ('Permission to view summary denied' )
906+
907+ old = date .Date ('-1w' )
908+
909+ created = []
910+ summary = {}
911+ messages = []
912+
913+ # loop through all the recently-active issues
914+ for issue_id in self .db .issue .filter (None , {'activity' : '-1w;' }):
915+ num = 0
916+ status_name = self .db .status .get (
917+ self .db .issue .get (issue_id , 'status' ),
918+ 'name'
919+ )
920+ issue_object = {
921+ 'id' : issue_id ,
922+ 'link' : self .base_path + 'issue' + issue_id ,
923+ 'title' : self .db .issue .get (issue_id , 'title' )
924+ }
925+ for x , ts , uid , action , data in self .db .issue .history (issue_id ):
926+ if ts < old :
927+ continue
928+ if action == 'create' :
929+ created .append (issue_object )
930+ elif action == 'set' and 'messages' in data :
931+ num += 1
932+ summary .setdefault (status_name , []).append (issue_object )
933+ messages .append ((num , issue_object ))
934+
935+ messages .sort (reverse = True )
936+
937+ result = {
938+ 'created' : created ,
939+ 'summary' : summary ,
940+ 'most_discussed' : messages [:10 ]
941+ }
942+
943+ return 200 , result
944+
880945 def dispatch (self , method , uri , input ):
881946 """format and process the request"""
882947 # if X-HTTP-Method-Override is set, follow the override method
@@ -920,34 +985,42 @@ def dispatch(self, method, uri, input):
920985
921986 # PATH is split to multiple pieces
922987 # 0 - rest
923- # 1 - resource
924- # 2 - attribute
925- uri_split = uri .split ("/" )
926- resource_uri = uri_split [1 ]
927-
928- try :
929- class_name , item_id = hyperdb .splitDesignator (resource_uri )
930- except hyperdb .DesignatorError :
931- class_name = resource_uri
932- item_id = None
988+ # 1 - data
989+ # 2 - resource
990+ # 3 - attribute
991+ uri_split = uri .lower ().split ("/" )
933992
934993 # Call the appropriate method
935- if (class_name not in self .db .classes ) or (len (uri_split ) > 3 ):
936- output = self .error_obj (404 , "Not found" )
937- elif item_id is None :
938- if len (uri_split ) == 2 :
939- output = getattr (
940- self , "%s_collection" % method .lower ()
941- )(class_name , input )
942- else :
943- if len (uri_split ) == 2 :
944- output = getattr (
945- self , "%s_element" % method .lower ()
946- )(class_name , item_id , input )
994+ if len (uri_split ) == 2 and uri_split [1 ] == 'summary' :
995+ output = self .summary (input )
996+ elif 4 >= len (uri_split ) > 2 and uri_split [1 ] == 'data' :
997+ resource_uri = uri_split [2 ]
998+ try :
999+ class_name , item_id = hyperdb .splitDesignator (resource_uri )
1000+ except hyperdb .DesignatorError :
1001+ class_name = resource_uri
1002+ item_id = None
1003+
1004+ if class_name not in self .db .classes :
1005+ output = self .error_obj (404 , "Not found" )
1006+ elif item_id is None :
1007+ if len (uri_split ) == 3 :
1008+ output = getattr (
1009+ self , "%s_collection" % method .lower ()
1010+ )(class_name , input )
1011+ else :
1012+ output = self .error_obj (404 , "Not found" )
9471013 else :
948- output = getattr (
949- self , "%s_attribute" % method .lower ()
950- )(class_name , item_id , uri_split [2 ], input )
1014+ if len (uri_split ) == 3 :
1015+ output = getattr (
1016+ self , "%s_element" % method .lower ()
1017+ )(class_name , item_id , input )
1018+ else :
1019+ output = getattr (
1020+ self , "%s_attribute" % method .lower ()
1021+ )(class_name , item_id , uri_split [3 ], input )
1022+ else :
1023+ output = self .error_obj (404 , "Not found" )
9511024
9521025 # Format the content type
9531026 if data_type .lower () == "json" :
0 commit comments