def aggregate(dataset, measures=['amount'], drilldowns=None, cuts=None, page=1, pagesize=10000, order=None, inflate=None): """ Do an aggregation over a single dataset. This method calls the aggregation method of the dataset but in case inflation is asked for, this method takes care of those computations """ # If we have to inflate we need to add a year to the drilldowns # (since inflation only supports years at the moment). if inflate: drilldowns.append('time.year') # Aggregate the dataset via its own aggregate function result = dataset.aggregate(measures=measures, drilldowns=drilldowns, cuts=cuts, page=page,pagesize=pagesize, order=order) # If we have to inflate we do some inflation calculations if inflate: try: # Since different parts of the drilldowns are going to change # (differently) we need to recompute the sumamry total summary_total = 0 # We collect adjusted drilldowns into a new dict since if # inflation fails we can still serve the uninflated content adjusted_drilldowns = {} # We remove the time.year we added to the drilldowns hash_key = drilldowns[:] hash_key.remove('time.year') for item in result['drilldown']: # Get the inflated amount for this year (returns an inflation # dictionary with values for reference and target dates along # with original and inflated amounts) adjustment = helpers.inflate(item['amount'], inflate, item['time'], dataset.territories) # We make the reference and target datestrings with ISO format # (ISO format is yyyy-mm-dd). adjustment['reference'] = adjustment['reference'].isoformat() adjustment['target'] = adjustment['target'].isoformat() # Get the inflated amount into its own variable inflated_amount = adjustment['inflated'] # Get the item key item_key = unicode([get_value(k, item) for k in hash_key]) if item_key not in adjusted_drilldowns: # We copy the item in case something happens (then we # catch it and serve the original aggregation result) adjusted_drilldown = item.copy() remove_excessive_time(hash_key, adjusted_drilldown) adjusted_drilldown['inflation_adjustment'] = [adjustment] adjusted_drilldown['amount'] = inflated_amount adjusted_drilldowns[item_key] = adjusted_drilldown else: adjusted_drilldowns[item_key]['inflation_adjustment']\ .append(adjustment) adjusted_drilldowns[item_key]['amount'] += inflated_amount summary_total += inflated_amount result['drilldown'] = adjusted_drilldowns.values() result['summary']['original'] = result['summary']['amount'] result['summary']['amount'] = summary_total except KeyError, error: # If inflation fails because a date wasn't found in the inflation # data, then it raises a KeyError (returning the date in the # exception message # Note we do not remove time.year from the drilldown here since # it can help resolve the warning (and it's bothersome) result['warning'] = {'inflation': 'Unable to do inflation adjustment', 'error': 'Inflation error: %s' % error}
def view(self, dataset, id, format='html'): """ Get a specific entry in the dataset, identified by the id. Entry can be return as html (default), json or csv. """ # Generate the dataset self._get_dataset(dataset) # Get the entry that matches the given id. c.dataset.entries is # a generator so we create a list from it's responses based on the # given constraint entries = list(c.dataset.entries(c.dataset.alias.c.id == id)) # Since we're trying to get a single entry the list should only # contain one entry, if not then we return an error if not len(entries) == 1: abort(404, _('Sorry, there is no entry %r') % id) # Add urls to the dataset and assign assign it as a context variable c.entry = entry_apply_links(dataset, entries.pop()) # Get and set some context variables from the entry # This shouldn't really be necessary but it's here so nothing gets # broken c.id = c.entry.get('id') c.from_ = c.entry.get('from') c.to = c.entry.get('to') c.currency = c.entry.get('currency', c.dataset.currency).upper() c.time = c.entry.get('time') # Get the amount for the entry amount = c.entry.get('amount') # We adjust for inflation if the user as asked for this to be inflated if 'inflate' in request.params: try: # Inflate the amount. Target date is provided in request.params # as value for inflate and reference date is the date of the # entry. We also provide a list of the territories to extract # a single country for which to do the inflation c.inflation = h.inflate(amount, request.params['inflate'], c.time, c.dataset.territories) # The amount to show should be the inflated amount # and overwrite the entry's amount as well c.amount = c.inflation['inflated'] c.entry['amount'] = c.inflation['inflated'] # We include the inflation response in the entry's dict # HTML description assumes every dict value for the entry # includes a label so we include a default "Inflation # adjustment" for it to work. c.inflation['label'] = 'Inflation adjustment' c.entry['inflation_adjustment'] = c.inflation except: # If anything goes wrong in the try clause (and there's a lot # that can go wrong). We just say that we can't adjust for # inflation and set the context amount as the original amount h.flash_notice(_('Unable to adjust for inflation')) c.amount = amount else: # If we haven't been asked to inflate then we just use the # original amount c.amount = amount # Add custom html for the dataset entry if the dataset has some # custom html # 2013-11-17 disabled this as part of removal of genshi as depended on # a genshi specific helper. # TODO: reinstate if important # c.custom_html = h.render_entry_custom_html(c.dataset, c.entry) # Add the rest of the dimensions relating to this entry into a # extras dictionary. We first need to exclude all dimensions that # are already shown and then we can loop through the dimensions excluded_keys = ('time', 'amount', 'currency', 'from', 'to', 'dataset', 'id', 'name', 'description') c.extras = {} if c.dataset: # Create a dictionary of the dataset dimensions c.desc = dict([(d.name, d) for d in c.dataset.dimensions]) # Loop through dimensions of the entry for key in c.entry: # Entry dimension must be a dataset dimension and not in # the predefined excluded keys if key in c.desc and \ key not in excluded_keys: c.extras[key] = c.entry[key] # Return entry based on if format == 'json': return to_jsonp(c.entry) elif format == 'csv': return write_csv([c.entry], response) else: return templating.render('entry/view.html')
def view(self, dataset, id, format='html'): """ Get a specific entry in the dataset, identified by the id. Entry can be return as html (default), json or csv. """ # Generate the dataset self._get_dataset(dataset) # Get the entry that matches the given id. c.dataset.entries is # a generator so we create a list from it's responses based on the # given constraint entries = list(c.dataset.entries(c.dataset.alias.c.id == id)) # Since we're trying to get a single entry the list should only # contain one entry, if not then we return an error if not len(entries) == 1: abort(404, _('Sorry, there is no entry %r') % id) # Add urls to the dataset and assign assign it as a context variable c.entry = entry_apply_links(dataset, entries.pop()) # Get and set some context variables from the entry # This shouldn't really be necessary but it's here so nothing gets # broken c.id = c.entry.get('id') c.from_ = c.entry.get('from') c.to = c.entry.get('to') c.currency = c.entry.get('currency', c.dataset.currency).upper() c.time = c.entry.get('time') # Get the amount for the entry amount = c.entry.get('amount') # We adjust for inflation if the user as asked for this to be inflated if request.params.has_key('inflate'): try: # Inflate the amount. Target date is provided in request.params # as value for inflate and reference date is the date of the # entry. We also provide a list of the territories to extract # a single country for which to do the inflation c.inflation = h.inflate(amount, request.params['inflate'], c.time, c.dataset.territories) # The amount to show should be the inflated amount # and overwrite the entry's amount as well c.amount = c.inflation['inflated'] c.entry['amount'] = c.inflation['inflated'] # We include the inflation response in the entry's dict # HTML description assumes every dict value for the entry # includes a label so we include a default "Inflation # adjustment" for it to work. c.inflation['label'] = 'Inflation adjustment' c.entry['inflation_adjustment'] = c.inflation except: # If anything goes wrong in the try clause (and there's a lot # that can go wrong). We just say that we can't adjust for # inflation and set the context amount as the original amount h.flash_notice(_('Unable to adjust for inflation')) c.amount = amount else: # If we haven't been asked to inflate then we just use the # original amount c.amount = amount # Add custom html for the dataset entry if the dataset has some # custom html # 2013-11-17 disabled this as part of removal of genshi as depended on # a genshi specific helper. # TODO: reinstate if important # c.custom_html = h.render_entry_custom_html(c.dataset, c.entry) # Add the rest of the dimensions relating to this entry into a # extras dictionary. We first need to exclude all dimensions that # are already shown and then we can loop through the dimensions excluded_keys = ('time', 'amount', 'currency', 'from', 'to', 'dataset', 'id', 'name', 'description') c.extras = {} if c.dataset: # Create a dictionary of the dataset dimensions c.desc = dict([(d.name, d) for d in c.dataset.dimensions]) # Loop through dimensions of the entry for key in c.entry: # Entry dimension must be a dataset dimension and not in # the predefined excluded keys if key in c.desc and \ not key in excluded_keys: c.extras[key] = c.entry[key] # Return entry based on if format == 'json': return to_jsonp(c.entry) elif format == 'csv': return write_csv([c.entry], response) else: return templating.render('entry/view.html')
def aggregate(dataset, measures=['amount'], drilldowns=None, cuts=None, page=1, pagesize=10000, order=None, inflate=None): """ Do an aggregation over a single dataset. This method calls the aggregation method of the dataset but in case inflation is asked for, this method takes care of those computations """ # If we have to inflate we need to add a year to the drilldowns # (since inflation only supports years at the moment). if inflate: drilldowns.append('time.year') # Aggregate the dataset via its own aggregate function result = dataset.aggregate(measures=measures, drilldowns=drilldowns, cuts=cuts, page=page, pagesize=pagesize, order=order) # If we have to inflate we do some inflation calculations if inflate: try: # Since different parts of the drilldowns are going to change # (differently) we need to recompute the sumamry total summary_total = 0 # We collect adjusted drilldowns into a new dict since if # inflation fails we can still serve the uninflated content adjusted_drilldowns = {} # We remove the time.year we added to the drilldowns hash_key = drilldowns[:] hash_key.remove('time.year') for item in result['drilldown']: # Get the inflated amount for this year (returns an inflation # dictionary with values for reference and target dates along # with original and inflated amounts) adjustment = helpers.inflate(item['amount'], inflate, item['time'], dataset.territories) # We make the reference and target datestrings with ISO format # (ISO format is yyyy-mm-dd). adjustment['reference'] = adjustment['reference'].isoformat() adjustment['target'] = adjustment['target'].isoformat() # Get the inflated amount into its own variable inflated_amount = adjustment['inflated'] # Get the item key item_key = unicode([get_value(k, item) for k in hash_key]) if item_key not in adjusted_drilldowns: # We copy the item in case something happens (then we # catch it and serve the original aggregation result) adjusted_drilldown = item.copy() remove_excessive_time(hash_key, adjusted_drilldown) adjusted_drilldown['inflation_adjustment'] = [adjustment] adjusted_drilldown['amount'] = inflated_amount adjusted_drilldowns[item_key] = adjusted_drilldown else: adjusted_drilldowns[item_key]['inflation_adjustment'] \ .append(adjustment) adjusted_drilldowns[item_key]['amount'] += inflated_amount summary_total += inflated_amount result['drilldown'] = adjusted_drilldowns.values() result['summary']['original'] = result['summary']['amount'] result['summary']['amount'] = summary_total except KeyError as error: # If inflation fails because a date wasn't found in the inflation # data, then it raises a KeyError (returning the date in the # exception message # Note we do not remove time.year from the drilldown here since # it can help resolve the warning (and it's bothersome) result['warning'] = { 'inflation': 'Unable to do inflation adjustment', 'error': 'Inflation error: %s' % error } return result