def timeline(self, request, input, params, method): """ Get the user's timeline. @param request: Information about the HTTP request. @type request: BaseHttpRequest @param input: Any data that came in the body of the request. @type input: string @param params: Dictionary of parameter values. @type params: dict @param method: The HTTP request method. @type method: string @return: The output data of this service. @rtype: string """ # Get my parameters self.httpSetCredentials(params['account_name'], params['account_password']) code, obj_str = self.httpGet("http://api.twitter.com/1/statuses/user_timeline.json") if code == 200: obj = json.loads(obj_str) else: obj = obj_str return code, obj
def _send_data(relative_url, obj): """ Helper method that POSTs an object to URL as JSON. @param relative_url: The relative URL on the server. A starting slash may be specified, but either way, it's always interpreted to be relative to "/". @type relative_url: string @param obj: The object to be parsed to JSON and sent. @type obj: object @return: The JSON interpreted data and the response object as a tuple. @rtype tuple """ if relative_url.startswith("/"): relative_url = relative_url[1:] resp = http.urlopen("POST", SERVER_URL + "/" + relative_url, headers={"Accept" : "application/json"}, data=json.dumps(obj)) buf = resp.read() if resp.getStatus() >= 200 and resp.getStatus() <= 300: data = json.loads(buf) else: data = buf return (data, resp)
def matches(self, request, input, params, method): storage = self.getFileStorage() order_list = storage.listFiles() salesforce_resource_uri = params['salesforce_resource'] match_count = 0 out = dict() for order_id in order_list: order = json.loads(storage.loadFile(order_id)) # # The ID and customer field are at the same location in both # types of orders. There is only one element in the top-level # dictionary, so we can say: top_level_key = order.keys()[0] d = order[top_level_key] customer_email = d['customer']['email'] print "customer email: ", customer_email print "salesforce URI: ", salesforce_resource_uri code, matches = accessResource('%s/contact/data/email/"%s"' % (salesforce_resource_uri, customer_email)) if code != 200: raise GluException("Error accessing Salesforce resource: " + str(matches)) print matches if top_level_key == 'product-order': prod_name = d['product-item']['product-ref'] prod_type = "product" else: prod_name = d['registration'][0]['course-event-ref']['course-ref'] prod_type = "registration" keystr = "%s, %s (%s) of %s ordered training %s '%s' for $%s" % (d['customer']['last-name'], d['customer']['first-name'], \ d['customer']['email'], d['customer-organization-ref'], \ prod_type, prod_name, d['taxable-subtotal']) if matches: match_count += len(matches) desc = dict() mo = list() for m in matches: td = dict() td[' Name'] = m['Name'] td['Address 1: Street'] = m['MailingStreet'] td['Address 2: City'] = m['MailingCity'] td['Address 3: State'] = m['MailingState'] td['Address 4: Country'] = m['MailingCountry'] td['CLICK HERE TO UPDATE SALESFORCE'] = self.getMyResourceUri() + "/integrate/" + order_id + "/" + m['Id'] mo.append(td) order_data = { keystr : mo } else: order_data = { keystr : None } out[order_id] = order_data out['summary'] = "%d matches." % match_count return 200, out
def __convert_salesforce_results_to_dict(self, res): """ The salesforce query results are dictionary/list like, but use their own type. Their string representation looks like those of basic types, so a quick and dirty way to convert to basic types is to let JSON do the job. I probably should upgrade the representation layer, so that it can deal with dictionary/list 'like' objects, but this works for now. """ encoded = json.gludumps(res) return json.loads(encoded)
def loadResourceFromStorage(self, resource_name): """ Load the specified resource from storage. @param resource_name: Name of the selected resource. @type resource_name: string @return A Python dictionary representation or None if not found. @rtype dict """ resources = ResourceStorage.gql("WHERE name = :1", resource_name) resource = resources[0] return json.loads(resource.data)
def search(self, request, input, params, method): """ Perform a Google search. @param request: Information about the HTTP request. @type request: BaseHttpRequest @param input: Any data that came in the body of the request. @type input: string @param params: Dictionary of parameter values. @type params: dict @param method: The HTTP request method. @type method: string @return: The output data of this service. @rtype: string """ # Get my parameters query = params['query'] num = params['num'] key = params['api_key'] # This is the official API, which seems to require the API key #code, data = self.httpGet("http://base.google.com/base/feeds/snippets?q=%s&key=%s" % (query, key)) # # But we like things in JSON. There is another Google search API, which does things in JSON, # and which does not require the API key. It only seems to read 10 (or so) results at any # time, so we put this in a loop until we have the requested number of results. # start = 1 results = [] while len(results) < num: url = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=%s&start=%d" % (query, start) code, data_str = self.httpGet(url) if code == 200: try: data = json.loads(data_str) new_batch = data['responseData']['results'] results += new_batch except Exception, e: return 400, "Result data was malformed: " + str(e)
def __get_status(self, accountname): """ Get a the latest twitter status for the specified account. @param accountname: Name of the account for which we get the status. @type accountname: string @return: The status text. @rtype: string """ # Get the status for this account from Twitter (we get it in JSON format) code, data = self.httpGet("http://api.twitter.com/1/users/show.json?screen_name=%s" % accountname) if code == 200: obj = json.loads(data) else: return "Problem with Twitter: " + data # Return the requested information, in this case the latest status return obj['status']['text']
def _get_data(relative_url): """ Helper method accesses a URL on the server and returns the data (interprets the JSON). @param relative_url: The relative URL on the server. A starting slash may be specified, but either way, it's always interpreted to be relative to "/". @type relative_url: string @return: The JSON interpreted data and the response object as a tuple. @rtype tuple """ if relative_url.startswith("/"): relative_url = relative_url[1:] resp = http.urlopen("GET", SERVER_URL + "/" + relative_url, headers={"Accept" : "application/json"}) buf = resp.read() if resp.getStatus() == 200: data = json.loads(buf) else: data = buf return (data, resp)
def __process_post(self): """ Process a POST request. The only allowed POST requests to code are requests to the base URI of a component. This creates a new resource. @return: HTTP return code and data as a tuple. @rtype: tuple """ # # Start by processing and sanity-checking the request. # component_class = getComponentClass(self.request.getRequestPath()) if not component_class: return (404, "Unknown component") #component = component_class() body = self.request.getRequestBody() try: param_dict = json.loads(body) except Exception, e: raise GluException("Malformed request body: " + str(e))
def _accessComponentService(component, services, complete_resource_def, resource_name, service_name, positional_params, runtime_param_dict, input, request="GET", method=None, direct_call=False): """ Passes control to a service method exposed by a component. @param component: An instance of the component. @type component: BaseComponent (object of child class) @param services: Dictionary of services definitions for this component. Can be had by calling _getServices() on the component. But we would need the resource's base URI to get those URIs exported properly. Since we already did this call in process() from where we called this method, we just pass the services dictionary in, rather than calling _getServices() again. @param services: dict @param complete_resource_def: The entire resource definition as it was retrieved from storage. @type complete_resource_def: dict @param resource_name: Name of the resource. This may contain '/' if positional parameters are defined in the URL. @type resource_name: string @param service_name: The name of the requested service @type service_name: string @param positional_params: List of positional parameters. @type positional_params: list @param runtime_param_dict: Dictionary of URL command line arguments. @type runtime_param_dict: dict @param input: Any potential input (came in the request body) @type input: string @param request: HTTP request structure. @type request: BaseHttpRequest @param direct_call: Set this if the function is called directly from another component or piece of code that's not part of Glu. In that case, it wraps the actual exception in a 'normal' exception and passes it up. That allows the framework code to react differently to exceptions in here than direct-call code. @type direct_call: boolean """ try: service_def = services.get(service_name) if not service_def: raise GluException("Service '%s' is not available in this resource." % service_name) # # Some runtime parameters may have been provided as arguments on # the URL command line. They need to be processed and added to # the parameters if necessary. # # Parameters may either appear as named arguments after the URL, # like this: http://resource/somename?name1=val1&name2=val2 # # If positional parameters are defined for the service then they # may be extracted from the URL. For example, if the positional # parameters are defined as [ "name1", "name2" ] then the URL can # be this: http://resource/somename/val1/val2/ # With that URL and using the order that's defined in the # positional parameter definition, the values are assigned # like this: name1=val1, name2=val2 # # Parameters specified in the first form (named arguments after '?') # override the same parameters specified in the URL itself. # # Why did we not check for those parameters earlier when the # runtime_param_dict parameter was created before this function # was called? Because we may have been called out of the accessResource() # method, which could possibly use a complete # if positional_params: try: pos_param_def = complete_resource_def['public']['services'][service_name]['positional_params'] except Exception, e: pos_param_def = None if pos_param_def: # Iterating over all the positional parameters that are provided in the URI # There might be some empty ones (when the URL has two // in a row or ends # in a /). In that case, we skip that parameter. pos_def_index = 0 for value in positional_params: if value: pname = pos_param_def[pos_def_index] pos_def_index += 1 # Put the new value in the runtime_parameter_dict, but only if it # doesn't exist there already (parameters specified after a '?' # are in there and they take precedence). if pname not in runtime_param_dict: runtime_param_dict[pname] = value if pos_def_index == len(pos_param_def): # No more positional parameters defined? We will ignore whatever # else is in the URL break runtime_param_def = service_def.get('params') if runtime_param_def: # If the 'allow_params_in_body' flag is set for a service then we # allow runtime parameters to be passed in the request body PUT or POST. # So, if the URL command line parameters are not specified then we # should take the runtime parameters out of the body. # Sanity checking and filling in of defaults for the runtime parameters if service_def.get('allow_params_in_body') and input: # Take the base definition of the parameters from the request body try: base_params = json.loads(input.strip()) except ValueError, e: # Probably couldn't parse JSON properly. base_param = {} # Load the values from the body into the runtime_param_dict, but # only those which are not defined there yet. This allows the # command line args to overwrite what's specified in the body. for name, value in base_params.items(): if name not in runtime_param_dict: runtime_param_dict[name] = value paramSanityCheck(runtime_param_dict, runtime_param_def, "runtime parameter") fillDefaults(runtime_param_def, runtime_param_dict) convertTypes(runtime_param_def, runtime_param_dict)
""" Load the specified resource from storage. @param resource_name: Name of the selected resource. @type resource_name: string @return A Python dictionary representation or None if not found. @rtype dict """ try: buf = self.loadFile(resource_name) except GluFileNotFound, e: return None obj = json.loads(buf) return obj def deleteResourceFromStorage(self, resource_name): """ Delete the specified resource from storage. @param resource_name: Name of the selected resource. @type resource_name: string """ self.deleteFile(resource_name) def listResourcesInStorage(self): """ Return list of resources which we currently have in storage.