def constructPageID(self, view, context, view_names=()): """Given a view, figure out what its page ID should be. This provides a hook point for subclasses to override. """ if context is None: pageid = '' else: # ZCML registration will set the name under which the view # is accessible in the instance __name__ attribute. We use # that if it's available, otherwise fall back to the class # name. if safe_hasattr(view, '__name__'): view_name = view.__name__ else: view_name = view.__class__.__name__ names = [ n for n in [view_name] + list(view_names) if n is not None] context_name = context.__class__.__name__ # Is this a view of a generated view class, # such as ++model++ view of Product:+bugs. Recurse! if ' ' in context_name and safe_hasattr(context, 'context'): return self.constructPageID(context, context.context, names) view_names = ':'.join(names) pageid = '%s:%s' % (context_name, view_names) # The view name used in the pageid usually comes from ZCML and so # it will be a unicode string although it shouldn't. To avoid # problems we encode it into ASCII. return pageid.encode('US-ASCII')
def constructPageID(self, view, context, view_names=()): """Given a view, figure out what its page ID should be. This provides a hook point for subclasses to override. """ if context is None: pageid = '' else: # ZCML registration will set the name under which the view # is accessible in the instance __name__ attribute. We use # that if it's available, otherwise fall back to the class # name. if safe_hasattr(view, '__name__'): view_name = view.__name__ else: view_name = view.__class__.__name__ names = [ n for n in [view_name] + list(view_names) if n is not None ] context_name = context.__class__.__name__ # Is this a view of a generated view class, # such as ++model++ view of Product:+bugs. Recurse! if ' ' in context_name and safe_hasattr(context, 'context'): return self.constructPageID(context, context.context, names) view_names = ':'.join(names) pageid = '%s:%s' % (context_name, view_names) # The view name used in the pageid usually comes from ZCML and so # it will be a unicode string although it shouldn't. To avoid # problems we encode it into ASCII. return pageid.encode('US-ASCII')
def architecture_options(self): """Return the architecture options for the context.""" # Guard against contexts that cannot tell us the available # distroarchseries. if safe_hasattr(self.context, 'architectures') is False: return [] # Grab all the architecture tags for the context. arch_tags = [ arch.architecturetag for arch in self.context.architectures] # We cannot assume that the arch_tags will be distinct, so # create a distinct and sorted list: arch_tags = sorted(set(arch_tags)) # Create the initial 'all architectures' option. if self.arch_tag is None: selected = 'selected' else: selected = None options = [ dict(name='All architectures', value='all', selected=selected)] # Create the options for the select box, ensuring to mark # the currently selected one. for arch_tag in arch_tags: if arch_tag == self.arch_tag: selected = 'selected' else: selected = None options.append( dict(name=arch_tag, value=arch_tag, selected=selected)) return options
def template(self): # Check for the magical "index" added by the browser:page template # machinery. If it exists this is actually the # zope.browserpage.simpleviewclass.simple class that is magically # mixed in by the browser:page zcml directive the template defined in # the directive should be used. if safe_hasattr(self, 'index'): return super(HasSpecificationsView, self).template # Sprints and Persons don't have a usage enum for blueprints, so we # have to fallback to the default. if (ISprint.providedBy(self.context) or IPerson.providedBy(self.context)): return self.default_template # ProjectGroups are a special case, as their products may be a # combination of usage settings. To deal with this, check all # products via the involvment menu. if (IProjectGroup.providedBy(self.context) or IProjectGroupSeries.providedBy(self.context)): involvement = getMultiAdapter( (self.context, self.request), name='+get-involved') if service_uses_launchpad(involvement.blueprints_usage): return self.default_template else: return self.not_launchpad_template # Otherwise, determine usage and provide the correct template. service_usage = IServiceUsage(self.context) if service_uses_launchpad(service_usage.blueprints_usage): return self.default_template else: return self.not_launchpad_template
def uninstall_feature_controller(): """Remove, if it exists, the current feature controller from this thread. This function is used to create a pristine environment in tests. """ if safe_hasattr(per_thread, 'features'): del per_thread.features
def template(self): # Check for the magical "index" added by the browser:page template # machinery. If it exists this is actually the # zope.browserpage.simpleviewclass.simple class that is magically # mixed in by the browser:page zcml directive the template defined in # the directive should be used. if safe_hasattr(self, 'index'): return super(HasSpecificationsView, self).template # Sprints and Persons don't have a usage enum for blueprints, so we # have to fallback to the default. if (ISprint.providedBy(self.context) or IPerson.providedBy(self.context)): return self.default_template # ProjectGroups are a special case, as their products may be a # combination of usage settings. To deal with this, check all # products via the involvment menu. if (IProjectGroup.providedBy(self.context) or IProjectGroupSeries.providedBy(self.context)): involvement = getMultiAdapter((self.context, self.request), name='+get-involved') if service_uses_launchpad(involvement.blueprints_usage): return self.default_template else: return self.not_launchpad_template # Otherwise, determine usage and provide the correct template. service_usage = IServiceUsage(self.context) if service_uses_launchpad(service_usage.blueprints_usage): return self.default_template else: return self.not_launchpad_template
def summarise_tal_links(links): """List the links and their attributes in the dict or list. :param links: A dictionary or list of menu links returned by `lp.app.browser.tales.MenuAPI`. """ is_dict = zope_isinstance(links, dict) if is_dict: keys = sorted(links) else: keys = links for key in keys: if is_dict: link = links[key] else: link = key if ILink.providedBy(link): print 'link %s' % link.name attributes = ('url', 'enabled', 'menu', 'selected', 'linked') for attrname in attributes: if not safe_hasattr(link, attrname): continue print ' %s:' % attrname, getattr(link, attrname) else: print 'attribute %s: %s' % (key, link)
def verify_url_scheme_and_handler(self, scheme, handler): self.assert_(scheme in self.walker.URL_SCHEMES) self.assert_(handler in self.walker.handlers) # urllib2 uses a naming convention to select the handler for # a URL scheme. This test is sanity to check to ensure that the # HTTPWalker's configuration of the OpenerDirector is will work. method_name = '%s_open' % scheme self.assert_(safe_hasattr(handler, method_name))
def main(self): self.setUpUtilities() # Materialize the list of files to parse. It is better to do the # checks now, rather than potentially hours later when the # generator gets around to it, because there is a reasonable # chance log rotation will have kicked in and removed our oldest # files. Note that we still error if a file we want to parse # disappears before we get around to parsing it, which is # desirable behaviour. files_to_parse = list( get_files_to_parse( glob.glob(os.path.join(self.root, self.log_file_glob)))) country_set = getUtility(ICountrySet) parsed_lines = 0 max_parsed_lines = getattr(config.launchpad, 'logparser_max_parsed_lines', None) max_is_set = max_parsed_lines is not None for fd, position in files_to_parse: # If we've used up our budget of lines to process, stop. if (max_is_set and parsed_lines >= max_parsed_lines): break downloads, parsed_bytes, parsed_lines = parse_file( fd, position, self.logger, self.getDownloadKey) # Use a while loop here because we want to pop items from the dict # in order to free some memory as we go along. This is a good # thing here because the downloads dict may get really huge. while downloads: file_id, daily_downloads = downloads.popitem() update_download_count = self.getDownloadCountUpdater(file_id) # The object couldn't be retrieved (maybe it was deleted). # Don't bother counting downloads for it. if update_download_count is None: continue for day, country_downloads in daily_downloads.items(): for country_code, count in country_downloads.items(): try: country = country_set[country_code] except NotFoundError: # We don't know the country for the IP address # where this request originated. country = None update_download_count(day, country, count) fd.seek(0) first_line = fd.readline() fd.close() create_or_update_parsedlog_entry(first_line, parsed_bytes) self.txn.commit() if safe_hasattr(fd, 'name'): name = fd.name else: name = fd self.logger.info('Finished parsing %s' % name) self.logger.info('Done parsing apache log files')
def main(self): self.setUpUtilities() # Materialize the list of files to parse. It is better to do the # checks now, rather than potentially hours later when the # generator gets around to it, because there is a reasonable # chance log rotation will have kicked in and removed our oldest # files. Note that we still error if a file we want to parse # disappears before we get around to parsing it, which is # desirable behavior. files_to_parse = list(get_files_to_parse( glob.glob(os.path.join(self.root, self.log_file_glob)))) country_set = getUtility(ICountrySet) parsed_lines = 0 max_parsed_lines = getattr( config.launchpad, 'logparser_max_parsed_lines', None) max_is_set = max_parsed_lines is not None for fd, position in files_to_parse: # If we've used up our budget of lines to process, stop. if (max_is_set and parsed_lines >= max_parsed_lines): break downloads, parsed_bytes, parsed_lines = parse_file( fd, position, self.logger, self.getDownloadKey) # Use a while loop here because we want to pop items from the dict # in order to free some memory as we go along. This is a good # thing here because the downloads dict may get really huge. while downloads: file_id, daily_downloads = downloads.popitem() update_download_count = self.getDownloadCountUpdater(file_id) # The object couldn't be retrieved (maybe it was deleted). # Don't bother counting downloads for it. if update_download_count is None: continue for day, country_downloads in daily_downloads.items(): for country_code, count in country_downloads.items(): try: country = country_set[country_code] except NotFoundError: # We don't know the country for the IP address # where this request originated. country = None update_download_count(day, country, count) fd.seek(0) first_line = fd.readline() fd.close() create_or_update_parsedlog_entry(first_line, parsed_bytes) self.txn.commit() if safe_hasattr(fd, 'name'): name = fd.name else: name = fd self.logger.info('Finished parsing %s' % name) self.logger.info('Done parsing apache log files')
def selected_value(self): """ String representation of field value associated with the picker. Default implementation is to return the 'name' attribute. """ val = self._getFormValue() if val is not None and safe_hasattr(val, 'name'): return getattr(val, 'name') return None
def selected_value(self): """ String representation of field value associated with the picker. Default implementation is to return the 'name' attribute. """ if self.context is None: return None val = getattr(self.context, self.exported_field.__name__) if val is not None and safe_hasattr(val, 'name'): return getattr(val, 'name') return None
def vocabulary_to_choice_edit_items( vocab, include_description=False, css_class_prefix=None, disabled_items=None, excluded_items=None, as_json=False, name_fn=None, value_fn=None, description_fn=None): """Convert an enumerable to JSON for a ChoiceEdit. :vocab: The enumeration to iterate over. :css_class_prefix: If present, append this to an item's value to create the css_class property for it. :disabled_items: A list of items that should be displayed, but disabled. :name_fn: A function receiving an item and returning its name. :value_fn: A function receiving an item and returning its value. """ if disabled_items is None: disabled_items = [] items = [] for item in vocab: # Introspect to make sure we're dealing with the object itself. # SimpleTerm objects have the object itself at item.value. if safe_hasattr(item, 'value'): item = item.value if excluded_items and item in excluded_items: continue if name_fn is not None: name = name_fn(item) else: name = item.title if value_fn is not None: value = value_fn(item) else: value = item.title if description_fn is None: description_fn = lambda item: getattr(item, 'description', '') description = '' if include_description: description = description_fn(item) new_item = { 'name': name, 'value': value, 'description': description, 'description_css_class': 'choice-description', 'style': '', 'help': '', 'disabled': False} for disabled_item in disabled_items: if disabled_item == item: new_item['disabled'] = True break if css_class_prefix is not None: new_item['css_class'] = css_class_prefix + item.name items.append(new_item) if as_json: return simplejson.dumps(items) else: return items
def __getattribute__(self, name): func = object.__getattribute__(self, name) if (safe_hasattr(func, '__call__') and (func.__name__ == 'searchForTerms' or func.__name__ == 'search')): def do_search(query=None, vocab_filter=None, *args, **kwargs): if isinstance(vocab_filter, basestring): for filter in self.supportedFilters(): if filter.name == vocab_filter: vocab_filter = filter break else: raise ValueError("Invalid vocab filter value: %s" % vocab_filter) return func(query, vocab_filter, *args, **kwargs) return do_search else: return func
def __getattribute__(self, name): func = object.__getattribute__(self, name) if (safe_hasattr(func, '__call__') and ( func.__name__ == 'searchForTerms' or func.__name__ == 'search')): def do_search( query=None, vocab_filter=None, *args, **kwargs): if isinstance(vocab_filter, basestring): for filter in self.supportedFilters(): if filter.name == vocab_filter: vocab_filter = filter break else: raise ValueError( "Invalid vocab filter value: %s" % vocab_filter) return func(query, vocab_filter, *args, **kwargs) return do_search else: return func
def raw_connect(self): if config.launchpad_session.database is not None: dsn = ConnectionString(config.launchpad_session.database) dsn.user = config.launchpad_session.dbuser self._dsn = str(dsn) else: # This is fallback code for old config files. It can be # removed when all live configs have been updated to use the # 'database' setting instead of 'dbname' + 'dbhost' settings. self._dsn = 'dbname=%s user=%s' % (config.launchpad_session.dbname, config.launchpad_session.dbuser) if config.launchpad_session.dbhost: self._dsn += ' host=%s' % config.launchpad_session.dbhost flags = _get_dirty_commit_flags() raw_connection = super(LaunchpadSessionDatabase, self).raw_connect() if safe_hasattr(raw_connection, 'auto_close'): raw_connection.auto_close = False raw_connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) _reset_dirty_commit_flags(*flags) return raw_connection
def raw_connect(self): if config.launchpad_session.database is not None: dsn = ConnectionString(config.launchpad_session.database) dsn.user = config.launchpad_session.dbuser self._dsn = str(dsn) else: # This is fallback code for old config files. It can be # removed when all live configs have been updated to use the # 'database' setting instead of 'dbname' + 'dbhost' settings. self._dsn = 'dbname=%s user=%s' % ( config.launchpad_session.dbname, config.launchpad_session.dbuser) if config.launchpad_session.dbhost: self._dsn += ' host=%s' % config.launchpad_session.dbhost flags = _get_dirty_commit_flags() raw_connection = super(LaunchpadSessionDatabase, self).raw_connect() if safe_hasattr(raw_connection, 'auto_close'): raw_connection.auto_close = False raw_connection.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) _reset_dirty_commit_flags(*flags) return raw_connection
def attach_http_request(report, context): """Add request metadata into the error report. This reads the exc_info and http_request keys from the context and will write to: * url * ignore * username * topic * req_vars """ info = context.get('exc_info') request = context.get('http_request') if request is None: return # XXX jamesh 2005-11-22: Temporary fix, which Steve should # undo. URL is just too HTTPRequest-specific. if safe_hasattr(request, 'URL'): # URL's are byte strings, but possibly str() will fail - safe_unicode # handles all those cases, and then we can safely encode it to utf8. # This is strictly double handling as a URL should never have unicode # characters in it anyway (though it may have them % encoded, which is # fine). Better safe than sorry, and the safe_unicode handling won't # cause double-encoding, so it is safe. url = oops.createhooks.safe_unicode(request.URL).encode('utf8') report['url'] = url if WebServiceLayer.providedBy(request) and info is not None: webservice_error = getattr( info[1], '__lazr_webservice_error__', 500) if webservice_error / 100 != 5: request.oopsid = None # Tell the oops machinery to ignore this error report['ignore'] = True missing = object() principal = getattr(request, 'principal', missing) if safe_hasattr(principal, 'getLogin'): login = principal.getLogin() elif principal is missing or principal is None: # Request has no principal (e.g. scriptrequest) login = None else: # Request has an UnauthenticatedPrincipal. login = '******' if _get_type(report) in ( _ignored_exceptions_for_unauthenticated_users): report['ignore'] = True if principal is not None and principal is not missing: username = '******'.join([ unicode(login), unicode(request.principal.id), unicode(request.principal.title), unicode(request.principal.description)]) report['username'] = username if getattr(request, '_orig_env', None): report['topic'] = request._orig_env.get('launchpad.pageid', '') for key, value in request.items(): if _is_sensitive(request, key): value = '<hidden>' if not isinstance(value, basestring): value = oops.createhooks.safe_unicode(value) # keys need to be unicode objects. The form items (a subset of # request.items) are generally just the url query_string url decoded, # which means the keys may be invalid in bson docs (bson requires that # they be unicode). key = oops.createhooks.safe_unicode(key) report['req_vars'][key] = value if IXMLRPCRequest.providedBy(request): args = request.getPositionalArguments() # Request variables are strings: this could move to its own key and be # raw. report['req_vars']['xmlrpc args'] = unicode(args)
def push(db_policy): """See `IStoreSelector`.""" if not safe_hasattr(_local, 'db_policies'): _local.db_policies = [] db_policy.install() _local.db_policies.append(db_policy)
def text(self): milestone = IMilestoneData(self.context) if safe_hasattr(milestone, 'code_name') and milestone.code_name: return '%s "%s"' % (milestone.name, milestone.code_name) else: return milestone.name
def vocabulary_to_choice_edit_items(vocab, include_description=False, css_class_prefix=None, disabled_items=None, excluded_items=None, as_json=False, name_fn=None, value_fn=None, description_fn=None): """Convert an enumerable to JSON for a ChoiceEdit. :vocab: The enumeration to iterate over. :css_class_prefix: If present, append this to an item's value to create the css_class property for it. :disabled_items: A list of items that should be displayed, but disabled. :name_fn: A function receiving an item and returning its name. :value_fn: A function receiving an item and returning its value. """ if disabled_items is None: disabled_items = [] items = [] for item in vocab: # Introspect to make sure we're dealing with the object itself. # SimpleTerm objects have the object itself at item.value. if safe_hasattr(item, 'value'): item = item.value if excluded_items and item in excluded_items: continue if name_fn is not None: name = name_fn(item) else: name = item.title if value_fn is not None: value = value_fn(item) else: value = item.title if description_fn is None: description_fn = lambda item: getattr(item, 'description', '') description = '' if include_description: description = description_fn(item) new_item = { 'name': name, 'value': value, 'description': description, 'description_css_class': 'choice-description', 'style': '', 'help': '', 'disabled': False } for disabled_item in disabled_items: if disabled_item == item: new_item['disabled'] = True break if css_class_prefix is not None: new_item['css_class'] = css_class_prefix + item.name items.append(new_item) if as_json: return simplejson.dumps(items) else: return items
def __init__(self, context, exported_field, label, label_tag="span", attribute_type="default", vocabulary=None, header=None, empty_display_value="None", selected_items=list(), items_tag="span", items_style='', content_box_id=None, edit_view="+edit", edit_url=None, edit_title=''): """Create a widget wrapper. :param context: The object that is being edited. :param exported_field: The attribute being edited. This should be a field from an interface of the form ISomeInterface['fieldname'] :param label: The label text to display above the checkboxes :param label_tag: The tag in which to wrap the label text. :param attribute_type: The attribute type. Currently only "reference" is supported. Used to determine whether to linkify the selected checkbox item values. So ubuntu/hoary becomes http://launchpad.net/devel/api/ubuntu/hoary :param vocabulary: The name of the vocabulary which provides the items or a vocabulary instance. :param header: The text to display as the title of the popup form. :param empty_display_value: The text to display if no items are selected. :param selected_items: The currently selected items. :param items_tag: The tag in which to wrap the items checkboxes. :param items_style: The css style to use for each item checkbox. :param content_box_id: The HTML id to use for this widget. Automatically generated if this is not provided. :param edit_view: The view name to use to generate the edit_url if one is not specified. :param edit_url: The URL to use for editing when the user isn't logged in and when JS is off. Defaults to the edit_view on the context. :param edit_title: Used to set the title attribute of the anchor. """ super(InlineMultiCheckboxWidget, self).__init__(context, exported_field, content_box_id, edit_view, edit_url, edit_title) linkify_items = attribute_type == "reference" if header is None: header = self.exported_field.title + ":" self.header = header, self.empty_display_value = empty_display_value self.label = label self.label_open_tag = "<%s>" % label_tag self.label_close_tag = "</%s>" % label_tag self.items = selected_items self.items_open_tag = ("<%s id='%s'>" % (items_tag, self.content_box_id + "-items")) self.items_close_tag = "</%s>" % items_tag self.linkify_items = linkify_items if vocabulary is None: if ICollection.providedBy(exported_field): vocabulary = exported_field.value_type.vocabularyName else: vocabulary = exported_field.vocabularyName if isinstance(vocabulary, basestring): vocabulary = getVocabularyRegistry().get(context, vocabulary) # Construct checkbox data dict for each item in the vocabulary. items = [] style = ';'.join(['font-weight: normal', items_style]) for item in vocabulary: item_value = item.value if safe_hasattr(item, 'value') else item checked = item_value in selected_items if linkify_items: save_value = canonical_url(item_value, force_local_path=True) else: save_value = item_value.name new_item = { 'name': item.title, 'token': item.token, 'style': style, 'checked': checked, 'value': save_value } items.append(new_item) self.has_choices = len(items) # JSON encoded attributes. self.json_content_box_id = simplejson.dumps(self.content_box_id) self.json_attribute = simplejson.dumps(self.api_attribute) self.json_attribute_type = simplejson.dumps(attribute_type) self.json_items = simplejson.dumps(items) self.json_description = simplejson.dumps( self.exported_field.description)
def __init__(self, context, exported_field, label, label_tag="span", attribute_type="default", vocabulary=None, header=None, empty_display_value="None", selected_items=list(), items_tag="span", items_style='', content_box_id=None, edit_view="+edit", edit_url=None, edit_title=''): """Create a widget wrapper. :param context: The object that is being edited. :param exported_field: The attribute being edited. This should be a field from an interface of the form ISomeInterface['fieldname'] :param label: The label text to display above the checkboxes :param label_tag: The tag in which to wrap the label text. :param attribute_type: The attribute type. Currently only "reference" is supported. Used to determine whether to linkify the selected checkbox item values. So ubuntu/hoary becomes http://launchpad.net/devel/api/ubuntu/hoary :param vocabulary: The name of the vocabulary which provides the items or a vocabulary instance. :param header: The text to display as the title of the popup form. :param empty_display_value: The text to display if no items are selected. :param selected_items: The currently selected items. :param items_tag: The tag in which to wrap the items checkboxes. :param items_style: The css style to use for each item checkbox. :param content_box_id: The HTML id to use for this widget. Automatically generated if this is not provided. :param edit_view: The view name to use to generate the edit_url if one is not specified. :param edit_url: The URL to use for editing when the user isn't logged in and when JS is off. Defaults to the edit_view on the context. :param edit_title: Used to set the title attribute of the anchor. """ super(InlineMultiCheckboxWidget, self).__init__( context, exported_field, content_box_id, edit_view, edit_url, edit_title) linkify_items = attribute_type == "reference" if header is None: header = self.exported_field.title + ":" self.header = header, self.empty_display_value = empty_display_value self.label = label self.label_open_tag = "<%s>" % label_tag self.label_close_tag = "</%s>" % label_tag self.items = selected_items self.items_open_tag = ("<%s id='%s'>" % (items_tag, self.content_box_id + "-items")) self.items_close_tag = "</%s>" % items_tag self.linkify_items = linkify_items if vocabulary is None: if ICollection.providedBy(exported_field): vocabulary = exported_field.value_type.vocabularyName else: vocabulary = exported_field.vocabularyName if isinstance(vocabulary, basestring): vocabulary = getVocabularyRegistry().get(context, vocabulary) # Construct checkbox data dict for each item in the vocabulary. items = [] style = ';'.join(['font-weight: normal', items_style]) for item in vocabulary: item_value = item.value if safe_hasattr(item, 'value') else item checked = item_value in selected_items if linkify_items: save_value = canonical_url(item_value, force_local_path=True) else: save_value = item_value.name new_item = { 'name': item.title, 'token': item.token, 'style': style, 'checked': checked, 'value': save_value} items.append(new_item) self.has_choices = len(items) # JSON encoded attributes. self.json_content_box_id = simplejson.dumps(self.content_box_id) self.json_attribute = simplejson.dumps(self.api_attribute) self.json_attribute_type = simplejson.dumps(attribute_type) self.json_items = simplejson.dumps(items) self.json_description = simplejson.dumps( self.exported_field.description)