def _parse_selenium_config(cls, config): """ Parse and convert the selenium sections of the config file and store the values in class variables. :param config: Config object. :type config: A SafeConfigParser instance. """ cls._command_executor = config.get( cls._SELENIUM_CONFIG_SECTION, 'command_executor') cls._base_url = config.get( cls._SELENIUM_CONFIG_SECTION, 'base_url') cls._screenshot_dir = config.get( cls._SELENIUM_CONFIG_SECTION, 'screenshot_dir') display_keys = aslist( config.get(cls._SELENIUM_CONFIG_SECTION, 'display_keys')) browser_keys = aslist( config.get(cls._SELENIUM_CONFIG_SECTION, 'browser_keys')) cls._make_baseline_screenshots = asbool( config.get(cls._SELENIUM_CONFIG_SECTION, 'make_baseline_screenshots')) cls._make_browers(browser_keys, config) cls._make_displays(display_keys, config)
def view_ajax_setup(request): """ This view returns a json object with essential parameters to configure the application. """ meta_url = request.route_url('ajax_meta', _query={'d': "__PATH__"}) stream_url = request.route_url('stream_image', size="__SIZE__", _query={'d': "__PATH__"}) listdir_url = request.route_url('ajax_listdir', _query={'d': '__PATH__', 'pp': '__PERPAGE__', 'p': '__PAGE__'}) zip_url = request.route_url('zip', _query={'files': "__FILES__"}) rebuild_url = request.route_url('ajax_rebuild', _query={'d': "__PATH__"}) getjobs_url = request.route_url('ajax_getjobs') return { 'meta_url': meta_url, 'stream_url': stream_url, 'listdir_url': listdir_url, 'zip_url': zip_url, 'rebuild_url': rebuild_url, 'getjobs_url': getjobs_url, 'sizes': aslist(request.registry.settings.get('image_sizes')), 'thumb_size': aslist(request.registry.settings.get('image_sizes'))[0] }
def __init__(self): """One instance of Globals is created during application initialization and is available during requests via the 'app_globals' variable """ self.map_key = config['map_key'] self.captcha_enabled = asbool(config['captcha_enabled']) self.captcha_pubkey = config['captcha_pubkey'] self.captcha_privkey = config['captcha_privkey'] self.akismet_enabled = asbool(config['akismet_enabled']) self.akismet_key = config['akismet_key'] self.akismet_url = config['akismet_url'] self.allow_tags = aslist(config['allow_tags'], sep=',') host_whitelist = aslist(config['host_whitelist'], sep=',') # prefix www subdomain to all hosts as a convenience self.host_whitelist = set(host_whitelist) for host in host_whitelist: if not host.startswith('www.'): self.host_whitelist.add('www.' + host) self.support_sending_enabled = asbool(config['support_sending_enabled']) self.support_email = config['support_email'] self.smtp_host = config['smtp_server'] self.smtp_port = config['smtp_port']
def search_projects(self, q=None, f=None, page=0, limit=None, **kw): fields = [('shortname', 'shortname'), ('name', 'full name')] add_fields = aslist(tg.config.get('search.project.additional_search_fields'), ',') r = self._search(M.Project, fields, add_fields, q, f, page, limit, **kw) r['search_results_template'] = 'allura:templates/site_admin_search_projects_results.html' r['additional_display_fields'] = \ aslist(tg.config.get('search.project.additional_display_fields'), ',') r['provider'] = ProjectRegistrationProvider.get() return r
def __init__(self, app, config): self.app = app self.compress_level = asint(config.get('gzip.compress_level', '5')) self.compress = set(aslist(config.get('gzip.compress', ''), ',', strip=True)) self.do_not_compress = set(aslist(config.get('gzip.do_not_compress', ''), ',', strip=True)) for m in (self.compress | self.do_not_compress): if mimetypes.guess_extension(m) is None: LOG.warning('Unrecognised mimetype in server configuration: %s', m) self.cache_dir = normpath(config.get('deploy.cache_dir', None))
def search_users(self, q=None, f=None, page=0, limit=None, **kw): fields = [('username', 'username'), ('display_name', 'display name')] add_fields = aslist(tg.config.get('search.user.additional_search_fields'), ',') r = self._search(M.User, fields, add_fields, q, f, page, limit, **kw) r['objects'] = [dict(u, status=h.get_user_status(u['object'])) for u in r['objects']] r['search_results_template'] = 'allura:templates/site_admin_search_users_results.html' r['additional_display_fields'] = \ aslist(tg.config.get('search.user.additional_display_fields'), ',') r['provider'] = AuthenticationProvider.get(request) return r
def index(self, *a, **kw): importer_matrix = defaultdict(dict) tools_with_importers = set() hidden = set(aslist(config.get('hidden_importers'), sep=',')) visible = lambda ep: ep.name not in hidden for ep in filter(visible, h.iter_entry_points('allura.importers')): importer = ep.load() for tool in aslist(importer.target_app): tools_with_importers.add(tool.tool_label) importer_matrix[importer.source][tool.tool_label] = ep.name return { 'importer_matrix': importer_matrix, 'tools': tools_with_importers, }
def process(self, **kw): """ Override and expose this to handle a project import. This should at a minimum create the stub project with the appropriate tools installed and redirect to the new project, presumably with a message indicating that some data will not be available immediately. """ try: with h.push_config(config, **{'project.verify_phone': 'false'}): c.project = self.neighborhood.register_project( kw['project_shortname'], project_name=kw['project_name']) except exceptions.ProjectOverlimitError: flash("You have exceeded the maximum number of projects you are allowed to create", 'error') redirect('.') except exceptions.ProjectRatelimitError: flash("Project creation rate limit exceeded. Please try again later.", 'error') redirect('.') except Exception: log.error('error registering project: %s', kw['project_shortname'], exc_info=True) flash('Internal Error. Please try again later.', 'error') redirect('.') self.after_project_create(c.project, **kw) tools = aslist(kw.get('tools')) for importer_name in tools: ToolImporter.by_name(importer_name).post(**kw) M.AuditLog.log('import project from %s' % self.source) flash('Welcome to the %s Project System! ' 'Your project data will be imported and should show up here shortly.' % config['site_name']) redirect(c.project.script_name + 'admin/overview')
def __init__( self, config, game, chunk_config={}, ): """ """ log.debug("uuss.UserState.__init__") self._config = config self._app_id = self._config['app_id'] self.game = game self.chunk_config = chunk_config self._lazy_load_chunks = converters.asbool(self._config.get('user_state.lazy_load_chunks', False)) # supported syntax is: # user_state.uuss_server = host1:42-49,host2:1111-2000,host3:8765 servers = [] for serverspec in converters.aslist(self._config['user_state.uuss_server'], ','): (host, portspec) = serverspec.split(':') ports = map(int, portspec.split('-')) if len(ports) == 1: minport = ports[0] maxport = minport else: (minport, maxport) = ports for port in range(minport, maxport + 1): servers.append( (host, port) ) self._servers = servers self._socket = None self._disconnected = False self._ping_counter = 0
def view_rebuild(request): """ Rebuild view. """ root = request.registry.settings.get('images_root') path = request.params.get('d', '') what = request.params.get('w', 'thumbs_meta') full_path = "%s/%s" % (root, path) format_ = request.registry.settings.get('resize_format') quality = asint(request.registry.settings.get('resize_quality')) sizes = aslist(request.registry.settings.get('image_sizes')) if not path or '..' in path: return HTTPForbidden() jobs_created = [] for c in os.listdir(full_path): f = "%s/%s" % (full_path, c) if utils.image.is_valid_image(f): options={'what': what, 'path': f, 'format': format_, 'quality': quality, 'sizes': sizes} if not request.db.get_job('rebuild-%s-%s' % (what,f,)): request.db.save_job('rebuild-%s-%s' % (what,f,), options) jobs_created.append('rebuild-%s-%s' % (what,f,)) Thread(target=utils.image.process_resize_jobs, args=(request.db, jobs_created)).start() return {'jobs': jobs_created}
def run_scgi_thread(wsgi_app, global_conf, scriptName='', host=None, port=None, socket=None, umask=None, allowedServers='127.0.0.1', logRequest=True, debug=None): import flup.server.scgi if socket: assert host is None and port is None sock = socket elif host: assert host is not None and port is not None sock = (host, int(port)) ensure_port_cleanup([sock]) else: sock = None if umask is not None: umask = int(umask) if debug is None: debug = global_conf.get('debug', False) s = flup.server.scgi.WSGIServer( wsgi_app, scriptName=scriptName, bindAddress=sock, umask=umask, allowedServers=aslist(allowedServers), debug=asbool(debug), loggingLevel=asbool(logRequest) and logging.INFO or logging.WARNING ) # Remove all the private handlers for handler in s.logger.handlers: s.logger.removeHandler(handler) s.run()
def command(self): config_file = os.path.realpath( self.args[0] if len(self.args) else CONFIG_FILE) import sqlalchemy import helloworld.model as model app_name = self.options.app_name config_uri = 'config:%s#main' % (config_file) config = paste.deploy.appconfig(config_uri) database_url = config['database.url'] engine = sqlalchemy.create_engine(database_url, echo=self.verbose) if app_name != 'main': config_uri = 'config:%s#%s' % (config_file, app_name) config = paste.deploy.appconfig(config_uri) model.Session.configure(bind=engine) session = model.Session() app1 = model.Application(app_name, url = config['url'], scope_prefix = config.get('scope_prefix'), title = config.get('title')) session.add(app1) for s in aslist(config.get('scopes')): session.add(model.Scope(s, app1)) session.commit() return
def iter_entry_points(group, *a, **kw): ''' yield entry points that have not been disabled in the config ''' disabled = aslist(tg.config.get('disable_entry_points.' + group), sep=',') for ep in pkg_resources.iter_entry_points(group, *a, **kw): if ep.name not in disabled: yield ep
def __init__(self, methods_string, entry_points, config): methods = aslist(methods_string) self.filters = [] for m in methods: config = copy(config) config['spam.method'] = m spam_filter = SpamFilter.get(config=config, entry_points=entry_points) self.filters.append(spam_filter)
def __call__(cls, importer, *args, **kw): """ Decorate the `create` post handler with a validator that references the appropriate App for this controller's importer. """ if hasattr(cls, 'create') and getattr(cls.create.decoration, 'validation', None) is None: cls.create = validate(cls.import_form(aslist(importer.target_app)[0]), error_handler=cls.index.__func__)(cls.create) return type.__call__(cls, importer, *args, **kw)
def post(cls, artifact, topic, additional_artifacts_to_match_subscriptions=None, **kw): '''Create a notification and send the notify message''' n = cls._make_notification(artifact, topic, **kw) if n: # make sure notification is flushed in time for task to process it session(n).flush(n) artifacts = [artifact] + aslist(additional_artifacts_to_match_subscriptions) n.fire_notification_task(artifacts, topic) return n
def by_app(app): """ Return a ToolImporter subclass instance given its target_app class. """ importers = {} for ep in h.iter_entry_points('allura.importers'): importer = ep.load() if app in aslist(importer.target_app): importers[ep.name] = importer() return importers
def _find_translations(self, localedir, domain): # Allow users to override if 'web.locale.languages' in self.config: return aslist(self.config['web.locale.languages']) translations = [] for fname in os.listdir(localedir): mo_fname = os.path.join(localedir, fname, 'LC_MESSAGES', '%s.mo' % domain) if os.path.exists(mo_fname): translations.append(fname) return translations
def checkAdmin(self, asbool=False): """Check if user is really an admin""" if (session.get('username')+'@'+session.get('domain')) in aslist(config.get('adminList'), ','): if (asbool): return True return elif (asbool): return False log.warning('User %s tried to acess the admin site without authorization' % session.get('username')) abort(403)
def _get_list(input, strip=True): '''Transforms a string or list to a list''' if input is None: return if input == '': return [] l = converters.aslist(input, ',', True) if strip: return [_strip(x) for x in l] else: return l
def _get_list(input, strip=True): """Transforms a string or list to a list""" if input == None: return if input == "": return [] l = converters.aslist(input, ",", True) if strip: return [_strip(x) for x in l] else: return l
def __call__(cls, *args, **kw): """ Right before the first instance of cls is created, get the list of target_app classes from ep names. Can't do this at cls create/init time b/c g.entry_points is not guaranteed to be loaded at that point. """ if not getattr(cls, 'target_app', None): cls.target_app = [g.entry_points['tool'][ep_name] for ep_name in aslist(cls.target_app_ep_names) if ep_name in g.entry_points['tool']] return type.__call__(cls, *args, **kw)
def _make_browers(cls, browser_keys, config): cls._browsers = {} for browser_key in browser_keys: section_name = '{}:{}{}'.format( cls._SELENIUM_CONFIG_SECTION, cls._SELENIUM_CONFIG_BROWSER_PREFIX, browser_key) section_dict = dict(config.items(section_name)) section_dict['arguments'] = aslist(section_dict['arguments']) section_dict['mobile'] = asbool(section_dict['mobile']) cls._browsers[browser_key] = section_dict
def get_list(input, strip_values=True): '''Transforms a string or list to a list''' if input is None: return if input == '': return [] converters_list = converters.aslist(input, ',', True) if strip_values: return [_strip(x) for x in converters_list] else: return converters_list
def make_middleware( app, global_conf, secret_file=None, trust_ips=None, prefix=None): from wsgiproxy.middleware import WSGIProxyMiddleware if secret_file is None and 'secret_file' in global_conf: secret_file = global_conf['secret_file'] if trust_ips is None and 'trust_ips' in global_conf: trust_ips = global_conf['trust_ips'] trust_ips = converters.aslist(trust_ips) return WSGIProxyMiddleware(app, secret_file=secret_file, trust_ips=trust_ips)
def __init__(self): """One instance of Globals is created during application initialization and is available during requests via the 'app_globals' variable """ memcached_servers = aslist(config['memcached_servers']) self.mc = memcache.Client(memcached_servers, debug=0) self.fps_client = fpys.FlexiblePaymentClient(config['AWS_KEY_ID'], config['AWS_SECRET_KEY'], fps_url=config['fps_api_url'], pipeline_url=config['fps_cbui_url'])
def run_scgi_fork(wsgi_app, global_conf, scriptName='', host='localhost', port='4000', allowedServers='127.0.0.1'): import flup.server.scgi_fork addr = (host, int(port)) ensure_port_cleanup([addr]) s = flup.server.scgi_fork.WSGIServer( wsgi_app, scriptName=scriptName, bindAddress=addr, allowedServers=aslist(allowedServers), ) s.run()
def run_ajp_thread(wsgi_app, global_conf, scriptName='', host='localhost', port='8009', allowedServers='127.0.0.1'): import flup.server.ajp warn('ajp_thread') addr = (host, int(port)) ensure_port_cleanup([addr]) s = flup.server.ajp.WSGIServer( wsgi_app, scriptName=scriptName, bindAddress=addr, allowedServers=aslist(allowedServers), ) s.run()
def sendmail( self, addrs, fromaddr, reply_to, subject, message_id, in_reply_to, message, sender=None, references=None, cc=None, to=None, ): if not addrs: return if to: message["To"] = AddrHeader(h.really_unicode(to)) else: message["To"] = AddrHeader(reply_to) message["From"] = AddrHeader(fromaddr) message["Reply-To"] = AddrHeader(reply_to) message["Subject"] = Header(subject) message["Message-ID"] = Header("<" + message_id + u">") if sender: message["Sender"] = AddrHeader(sender) if cc: message["CC"] = AddrHeader(cc) addrs.append(cc) if in_reply_to: if not isinstance(in_reply_to, basestring): raise TypeError("Only strings are supported now, not lists") message["In-Reply-To"] = Header(u"<%s>" % in_reply_to) if not references: message["References"] = message["In-Reply-To"] if references: references = [u"<%s>" % r for r in aslist(references)] message["References"] = Header(*references) content = message.as_string() smtp_addrs = map(_parse_smtp_addr, addrs) smtp_addrs = [a for a in smtp_addrs if isvalid(a)] if not smtp_addrs: log.warning("No valid addrs in %s, so not sending mail", map(unicode, addrs)) return try: self._client.sendmail(config.return_path, smtp_addrs, content) except: self._connect() self._client.sendmail(config.return_path, smtp_addrs, content)
def fields(self): socialnetworks = aslist(tg.config.get('socialnetworks', ['Facebook', 'Linkedin', 'Twitter', 'Google+']), ',') return [ ew.SingleSelectField( name='socialnetwork', label='Social network', validator=fev.UnicodeString(not_empty=True), options=[ew.Option(py_value=name, label=name) for name in socialnetworks]), ew.TextField( name='accounturl', label='Account url', validator=fev.UnicodeString(not_empty=True)) ]
import pylons from paste.deploy import loadapp from paste.deploy.converters import asbool, aslist from popserver.lib import helpers if len(sys.argv) != 2: print "Usage: %s [path_to_ini_file]" % sys.argv[0] exit(1) loadapp('config:%s' % sys.argv[1], relative_to=os.getcwd()) #helpers.config = pylons.config make_bundle = asbool( pylons.config.get('popego.serve_bundled_stylesheets', False)) bundle_files = aslist( pylons.config.get('popego.stylesheet_bundle_files', None), ',', True) if make_bundle is None: sys.stderr.write( '``popego.serve_bundled_styesheets`` not defined or False. Exiting.') exit(1) if len(bundle_files) == 0: sys.stderr.write( '``popego.stylesheet_bundle_files`` not defined or empty. Exiting.') exit(1) url_rex = re.compile(r'url\((.*)\)') relative_url_rex = re.compile(r'^(?:\.\./)*(.+)$')
def flags(self): if self._flags is None: flags = aslist(self.registry.settings.get('suma.tasks',[])) self._flags = flags return self._flags
def make_cache(global_conf, url, responses, **kwargs): from paste.deploy.converters import aslist responses = aslist(responses) return DapCache(url, responses, **kwargs)
def _make_core_app(root, global_conf, full_stack=True, **app_conf): """ Set allura up with the settings found in the PasteDeploy configuration file used. :param root: The controller module containing the TG root :param global_conf: The global settings for allura (those defined under the ``[DEFAULT]`` section). :type global_conf: dict :param full_stack: Should the whole TG2 stack be set up? :type full_stack: str or bool :return: The allura application with all the relevant middleware loaded. This is the PasteDeploy factory for the allura application. ``app_conf`` contains all the application-specific settings (those defined under ``[app:main]``. """ # Run all the initialization code here mimetypes.init([pkg_resources.resource_filename('allura', 'etc/mime.types')] + mimetypes.knownfiles) # Configure MongoDB ming.configure(**app_conf) # Configure ActivityStream if asbool(app_conf.get('activitystream.recording.enabled', False)): activitystream.configure(**h.convert_bools(app_conf, prefix='activitystream.')) # Configure EW variable provider ew.render.TemplateEngine.register_variable_provider(get_tg_vars) # Set FormEncode language to english, as we don't support any other locales formencode.api.set_stdtranslation(domain='FormEncode', languages=['en']) # Create base app base_config = ForgeConfig(root) load_environment = base_config.make_load_environment() # Code adapted from tg.configuration, replacing the following lines: # make_base_app = base_config.setup_tg_wsgi_app(load_environment) # app = make_base_app(global_conf, full_stack=True, **app_conf) # Configure the TG environment load_environment(global_conf, app_conf) app = tg.TGApp() for mw_ep in h.iter_entry_points('allura.middleware'): Middleware = mw_ep.load() if getattr(Middleware, 'when', 'inner') == 'inner': app = Middleware(app, config) # Required for sessions app = SessionMiddleware(app, config, data_serializer=BeakerPickleSerializerWithLatin1()) # Handle "Remember me" functionality app = RememberLoginMiddleware(app, config) # Redirect 401 to the login page app = LoginRedirectMiddleware(app) # Add instrumentation app = AlluraTimerMiddleware(app, app_conf) # Clear cookies when the CSRF field isn't posted if not app_conf.get('disable_csrf_protection'): app = CSRFMiddleware(app, '_session_id') if asbool(config.get('cors.enabled', False)): # Handle CORS requests allowed_methods = aslist(config.get('cors.methods')) allowed_headers = aslist(config.get('cors.headers')) cache_duration = asint(config.get('cors.cache_duration', 0)) app = CORSMiddleware(app, allowed_methods, allowed_headers, cache_duration) # Setup the allura SOPs app = allura_globals_middleware(app) # Ensure http and https used per config if config.get('override_root') != 'task': app = SSLMiddleware(app, app_conf.get('no_redirect.pattern'), app_conf.get('force_ssl.pattern'), app_conf.get('force_ssl.logged_in')) # Setup resource manager, widget context SOP app = ew.WidgetMiddleware( app, compress=True, use_cache=not asbool(global_conf['debug']), script_name=app_conf.get('ew.script_name', '/_ew_resources/'), url_base=app_conf.get('ew.url_base', '/_ew_resources/'), extra_headers=ast.literal_eval(app_conf.get('ew.extra_headers', '[]')), cache_max_age=asint(app_conf.get('ew.cache_header_seconds', 60*60*24*365)), # settings to pass through to jinja Environment for EW core widgets # these are for the easywidgets' own [easy_widgets.engines] entry point # (the Allura [easy_widgets.engines] entry point is named "jinja" (not jinja2) but it doesn't need # any settings since it is a class that uses the same jinja env as the rest of allura) **{ 'jinja2.auto_reload': asbool(config['auto_reload_templates']), 'jinja2.bytecode_cache': AlluraJinjaRenderer._setup_bytecode_cache(), 'jinja2.cache_size': asint(config.get('jinja_cache_size', -1)), } ) # Handle static files (by tool) app = StaticFilesMiddleware(app, app_conf.get('static.script_name')) # Handle setup and flushing of Ming ORM sessions app = MingMiddleware(app) # Set up the registry for stacked object proxies (SOPs). # streaming=true ensures they won't be cleaned up till # the WSGI application's iterator is exhausted app = RegistryManager(app, streaming=True) # "task" wsgi would get a 2nd request to /error/document if we used this middleware if config.get('override_root') not in ('task', 'basetest_project_root'): if asbool(config['debug']): # Converts exceptions to HTTP errors, shows traceback in debug mode # don't use TG footer with extra CSS & images that take time to load tg.error.footer_html = '<!-- %s %s -->' app = tg.error.ErrorHandler(app, global_conf, **config['tg.errorware']) else: app = ErrorMiddleware(app, config, **config['tg.errorware']) app = SetRequestHostFromConfig(app, config) # Redirect some status codes to /error/document if asbool(config['debug']): app = StatusCodeRedirect(app, base_config.handle_status_codes) else: app = StatusCodeRedirect( app, base_config.handle_status_codes + [500]) for mw_ep in h.iter_entry_points('allura.middleware'): Middleware = mw_ep.load() if getattr(Middleware, 'when', 'inner') == 'outer': app = Middleware(app, config) return app
def active_eps(): disabled = aslist( tg.config.get('disable_entry_points.' + group), sep=',') return [ep for ep in pkg_resources.iter_entry_points(group, *a, **kw) if ep.name not in disabled]
def target_app(self): return aslist(self.importer.target_app)[0]
def tool_label(self): """ The label for this tool importer. Defaults to the `tool_label` from the `target_app`. """ return getattr(aslist(self.target_app)[0], 'tool_label', None)
def tool_option(self): """ The option for this tool importer. Defaults to the `tool_option` from the `target_app`. """ return getattr(aslist(self.target_app)[0], 'tool_option', dict())
def make_proxy(global_conf, url, responses, cache=None, **kwargs): from paste.deploy.converters import aslist responses = aslist(responses) return DapProxy(url, responses, verbose, cache, **kwargs)
def tool_icon(self, theme, size): return theme.app_icon_url(aslist(self.target_app)[0], size)
def update_tickets(self, **post_data): from forgetracker.tracker_main import get_change_text, get_label tickets = Ticket.query.find( dict(_id={ '$in': [ObjectId(id) for id in aslist(post_data['__ticket_ids'])] }, app_config_id=self.app_config_id)).all() fields = set(['status', 'private']) values = {} labels = post_data.get('labels', []) for k in fields: v = post_data.get(k) if v: values[k] = v assigned_to = post_data.get('assigned_to') if assigned_to == '-': values['assigned_to_id'] = None elif assigned_to: user = c.project.user_in_project(assigned_to) if user: values['assigned_to_id'] = user._id private = post_data.get('private') if private: values['private'] = asbool(private) custom_values = {} custom_fields = {} for cf in self.custom_fields or []: v = post_data.get(cf.name) if v: custom_values[cf.name] = v custom_fields[cf.name] = cf changes = {} changed_tickets = {} for ticket in tickets: message = '' if labels: values['labels'] = self.append_new_labels( ticket.labels, labels.split(',')) for k, v in sorted(values.iteritems()): if k == 'assigned_to_id': new_user = User.query.get(_id=v) old_user = User.query.get(_id=getattr(ticket, k)) if new_user: message += get_change_text(get_label(k), new_user.display_name, old_user.display_name) elif k == 'private': def private_text(val): if val: return 'Yes' else: return 'No' message += get_change_text( get_label(k), private_text(v), private_text(getattr(ticket, k))) else: message += get_change_text(get_label(k), v, getattr(ticket, k)) setattr(ticket, k, v) for k, v in sorted(custom_values.iteritems()): def cf_val(cf): return ticket.get_custom_user(cf.name) \ if cf.type == 'user' \ else ticket.custom_fields.get(cf.name) cf = custom_fields[k] old_value = cf_val(cf) if cf.type == 'boolean': v = asbool(v) ticket.custom_fields[k] = v new_value = cf_val(cf) message += get_change_text(cf.label, new_value, old_value) if message != '': changes[ticket._id] = message changed_tickets[ticket._id] = ticket ticket.discussion_thread.post(message, notify=False) ticket.commit() filtered_changes = self.filtered_by_subscription(changed_tickets) users = User.query.find({ '_id': { '$in': filtered_changes.keys() } }).all() def changes_iter(user): for t_id in filtered_changes.get(user._id, []): # mark changes text as safe, thus it wouldn't be escaped in plain-text emails # html part of email is handled by markdown and it'll be properly escaped yield (changed_tickets[t_id], jinja2.Markup(changes[t_id])) mail = dict( sender=c.project.app_instance(self.app_config).email_address, fromaddr=str(c.user._id), reply_to=str(c.user._id), subject='[%s:%s] Mass edit changes by %s' % (c.project.shortname, self.app_config.options.mount_point, c.user.display_name), ) tmpl = g.jinja2_env.get_template('forgetracker:data/mass_report.html') head = [] for f, v in sorted(values.iteritems()): if f == 'assigned_to_id': user = User.query.get(_id=v) v = user.display_name if user else v head.append('- **%s**: %s' % (get_label(f), v)) for f, v in sorted(custom_values.iteritems()): cf = custom_fields[f] if cf.type == 'user': user = User.by_username(v) v = user.display_name if user else v head.append('- **%s**: %s' % (cf.label, v)) tmpl_context = { 'context': c, 'data': { 'header': jinja2.Markup('\n'.join(['Mass edit changing:', ''] + head)) } } for user in users: tmpl_context['data'].update({'changes': changes_iter(user)}) mail.update( dict(message_id=h.gen_message_id(), text=tmpl.render(tmpl_context), destinations=[str(user._id)])) mail_tasks.sendmail.post(**mail) if self.app_config.options.get('TicketMonitoringType') in ( 'AllTicketChanges', 'AllPublicTicketChanges'): monitoring_email = self.app_config.options.get( 'TicketMonitoringEmail') visible_changes = [] for t_id, t in changed_tickets.items(): if (not t.private or self.app_config.options.get('TicketMonitoringType') == 'AllTicketChanges'): visible_changes.append( (changed_tickets[t_id], jinja2.Markup(changes[t_id]))) if visible_changes: tmpl_context['data'].update({'changes': visible_changes}) mail.update( dict(message_id=h.gen_message_id(), text=tmpl.render(tmpl_context), destinations=[monitoring_email])) mail_tasks.sendmail.post(**mail) self.invalidate_bin_counts() ThreadLocalORMSession.flush_all() app = '%s/%s' % (c.project.shortname, self.app_config.options.mount_point) count = len(tickets) text = 'Updated {} ticket{} in {}'.format(count, 's' if count != 1 else '', app) Notification.post_user(c.user, None, 'flash', text=text)
def __init__(self): self.__dict__ = self.__shared_state if self.__shared_state: return self.allura_templates = pkg_resources.resource_filename( 'allura', 'templates') # Setup SOLR self.solr_server = aslist(config.get('solr.server'), ',') # skip empty strings in case of extra commas self.solr_server = [s for s in self.solr_server if s] self.solr_query_server = config.get('solr.query_server') if asbool(config.get('solr.mock')): self.solr = self.solr_short_timeout = MockSOLR() elif self.solr_server: self.solr = make_solr_from_config(self.solr_server, self.solr_query_server) self.solr_short_timeout = make_solr_from_config( self.solr_server, self.solr_query_server, timeout=int(config.get('solr.short_timeout', 10))) else: # pragma no cover self.solr = None self.solr_short_timeout = None self.use_queue = asbool(config.get('use_queue', False)) # Load login/logout urls; only used for SFX logins self.login_url = config.get('auth.login_url', '/auth/') self.logout_url = config.get('auth.logout_url', '/auth/logout') self.login_fragment_url = config.get('auth.login_fragment_url', '/auth/login_fragment') # Setup Gravatar self.gravatar = gravatar.url self.oid_store = M.OpenIdStore() # Setup pygments self.pygments_formatter = utils.LineAnchorCodeHtmlFormatter( cssclass='codehilite', linenos='table') # Setup Pypeline self.pypeline_markup = pypeline_markup # Setup analytics accounts = config.get('ga.account', 'UA-XXXXX-X') accounts = accounts.split(' ') self.analytics = analytics.GoogleAnalytics(accounts=accounts) self.icons = dict( admin=Icon('x', 'ico-admin'), pencil=Icon('p', 'ico-pencil'), help=Icon('h', 'ico-help'), search=Icon('s', 'ico-search'), history=Icon('N', 'ico-history'), feed=Icon('f', 'ico-feed'), mail=Icon('M', 'ico-mail'), reply=Icon('w', 'ico-reply'), tag=Icon('z', 'ico-tag'), flag=Icon('^', 'ico-flag'), undelete=Icon('+', 'ico-undelete'), delete=Icon('#', 'ico-delete'), close=Icon('D', 'ico-close'), table=Icon('n', 'ico-table'), stats=Icon('Y', 'ico-stats'), pin=Icon('@', 'ico-pin'), folder=Icon('o', 'ico-folder'), fork=Icon('R', 'ico-fork'), merge=Icon('J', 'ico-merge'), plus=Icon('+', 'ico-plus'), conversation=Icon('q', 'ico-conversation'), group=Icon('g', 'ico-group'), user=Icon('U', 'ico-user'), secure=Icon('(', 'ico-lock'), unsecure=Icon(')', 'ico-unlock'), star=Icon('S', 'ico-star'), watch=Icon('E', 'ico-watch'), expand=Icon('`', 'ico-expand'), restore=Icon('J', 'ico-restore'), # Permissions perm_read=Icon('E', 'ico-focus'), perm_update=Icon('0', 'ico-sync'), perm_create=Icon('e', 'ico-config'), perm_register=Icon('e', 'ico-config'), perm_delete=Icon('-', 'ico-minuscirc'), perm_tool=Icon('x', 'ico-config'), perm_admin=Icon('(', 'ico-lock'), perm_has_yes=Icon('3', 'ico-check'), perm_has_no=Icon('d', 'ico-noentry'), perm_has_inherit=Icon('2', 'ico-checkcircle'), ) # Cache some loaded entry points def _cache_eps(section_name, dict_cls=dict): d = dict_cls() for ep in h.iter_entry_points(section_name): value = ep.load() d[ep.name] = value return d class entry_point_loading_dict(dict): def __missing__(self, key): self[key] = _cache_eps(key) return self[key] self.entry_points = entry_point_loading_dict( tool=_cache_eps('allura', dict_cls=utils.CaseInsensitiveDict), auth=_cache_eps('allura.auth'), registration=_cache_eps('allura.project_registration'), theme=_cache_eps('allura.theme'), user_prefs=_cache_eps('allura.user_prefs'), spam=_cache_eps('allura.spam'), stats=_cache_eps('allura.stats'), site_stats=_cache_eps('allura.site_stats'), admin=_cache_eps('allura.admin'), ) # Zarkov logger self._zarkov = None # Set listeners to update stats statslisteners = [] for name, ep in self.entry_points['stats'].iteritems(): statslisteners.append(ep()) self.statsUpdater = PostEvent(statslisteners) self.tmpdir = os.getenv('TMPDIR', '/tmp')
def retries(self): t = aslist(config.get('webhook.retry', [60, 120, 240])) return list(map(int, t))
def _convert_options(global_conf, local_conf): """ Build the final options based on PasteDeploy's ``global_conf`` and ``local_conf``. """ # First of all, let's make sure Django will use Paste's "debug" value: if "DEBUG" in global_conf or "DEBUG" in local_conf: raise ValueError("Do not set Django's DEBUG in the configuration file; " "use Paste's 'debug' instead") if "debug" not in global_conf: raise ValueError("Paste's 'debug' option must be set in the " "configuration file") local_conf['DEBUG'] = global_conf['debug'] # Now it's safe to move on with the type casting: custom_booleans = aslist(global_conf.get("twod.booleans", "")) custom_integers = aslist(global_conf.get("twod.integers", "")) custom_tuples = aslist(global_conf.get("twod.tuples", "")) custom_nested_tuples = aslist(global_conf.get("twod.nested_tuples", "")) custom_dictionaries = aslist(global_conf.get("twod.dictionaries", "")) booleans = _DJANGO_BOOLEANS | frozenset(custom_booleans) integers = _DJANGO_INTEGERS | frozenset(custom_integers) tuples = _DJANGO_TUPLES | frozenset(custom_tuples) nested_tuples = _DJANGO_NESTED_TUPLES | frozenset(custom_nested_tuples) dictionaries = _DJANGO_DICTIONARIES | frozenset(custom_dictionaries) options = {} for (option_name, option_value) in local_conf.items(): if option_name in booleans: options[option_name] = asbool(option_value) elif option_name in integers: options[option_name] = asint(option_value) elif option_name in tuples: options[option_name] = tuple(aslist(option_value)) elif option_name in nested_tuples: nested_tuple = tuple( tuple((val.strip()) for val in tuple_.strip().split(";") if val) for tuple_ in option_value.strip().splitlines() ) options[option_name] = nested_tuple elif option_name in dictionaries: lines = option_value.strip().splitlines() items = [option.strip().split("=", 1) for option in lines] dictionary = dict( (key.strip(), value.strip()) for (key, value) in items ) options[option_name] = dictionary elif option_name in _DJANGO_UNSUPPORTED_SETTINGS: raise ValueError("Django setting %s is not (yet) supported; " "you have to define it in your options module." % option_name) else: # Store the option as an string: options[option_name] = option_value # We should not import a module with "__file__" as a global variable: options['paste_configuration_file'] = global_conf.get("__file__") return options
def entry_point_timers(self): timers = [] for ep in h.iter_entry_points('allura.timers'): func = ep.load() timers += aslist(func()) return timers
def can_import_forum(self): tokens = aslist(config.get('oauth.can_import_forum', ''), ',') if self.api_key in tokens: return True return False
def tool_description(self): """ The description for this tool importer. Defaults to the `tool_description` from the `target_app`. """ return getattr(aslist(self.target_app)[0], 'tool_description', None)
def __init__(self): self.__dict__ = self.__shared_state if self.__shared_state: return self.allura_templates = pkg_resources.resource_filename( 'allura', 'templates') # Setup SOLR self.solr_server = aslist(config.get('solr.server'), ',') # skip empty strings in case of extra commas self.solr_server = [s for s in self.solr_server if s] self.solr_query_server = config.get('solr.query_server') if self.solr_server: self.solr = make_solr_from_config(self.solr_server, self.solr_query_server) self.solr_short_timeout = make_solr_from_config( self.solr_server, self.solr_query_server, timeout=int(config.get('solr.short_timeout', 10))) else: # pragma no cover log.warning('Solr config not set; using in-memory MockSOLR') self.solr = self.solr_short_timeout = MockSOLR() # Load login/logout urls; only used for customized logins self.login_url = config.get('auth.login_url', '/auth/') self.logout_url = config.get('auth.logout_url', '/auth/logout') self.login_fragment_url = config.get('auth.login_fragment_url', '/auth/login_fragment/') # Setup Gravatar self.gravatar = gravatar.url # Setup pygments self.pygments_formatter = utils.LineAnchorCodeHtmlFormatter( cssclass='codehilite', linenos='table') # Setup Pypeline self.pypeline_markup = pypeline_markup # Setup analytics accounts = config.get('ga.account', 'UA-XXXXX-X') accounts = accounts.split(' ') self.analytics = analytics.GoogleAnalytics(accounts=accounts) self.icons = dict( move=Icon('fa fa-arrows', 'Move'), edit=Icon('fa fa-edit', 'Edit'), admin=Icon('fa fa-gear', 'Admin'), send=Icon('fa fa-send-o', 'Send'), add=Icon('fa fa-plus-circle', 'Add'), moderate=Icon('fa fa-hand-stop-o', 'Moderate'), pencil=Icon('fa fa-pencil', 'Edit'), help=Icon('fa fa-question-circle', 'Help'), eye=Icon('fa fa-eye', 'View'), search=Icon('fa fa-search', 'Search'), history=Icon('fa fa-calendar', 'History'), feed=Icon('fa fa-rss', 'Feed'), mail=Icon('fa fa-envelope-o', 'Subscribe'), reply=Icon('fa fa-reply', 'Reply'), tag=Icon('fa fa-tag', 'Tag'), flag=Icon('fa fa-flag-o', 'Flag'), undelete=Icon('fa fa-undo', 'Undelete'), delete=Icon('fa fa-trash-o', 'Delete'), close=Icon('fa fa-close', 'Close'), table=Icon('fa fa-table', 'Table'), stats=Icon('fa fa-line-chart', 'Stats'), pin=Icon('fa fa-mail-pin', 'Pin'), folder=Icon('fa fa-folder', 'Folder'), fork=Icon('fa fa-code-fork', 'Fork'), merge=Icon('fa fa-code-fork upside-down', 'Merge'), conversation=Icon('fa fa-comments', 'Conversation'), group=Icon('fa fa-group', 'Group'), user=Icon('fa fa-user', 'User'), secure=Icon('fa fa-lock', 'Lock'), unsecure=Icon('fa fa-unlock', 'Unlock'), star=Icon('fa fa-star', 'Star'), expand=Icon('fa fa-expand', 'Maximize'), restore=Icon('fa fa-compress', 'Restore'), check=Icon('fa fa-check-circle', 'Check'), caution=Icon('fa fa-ban', 'Caution'), vote_up=Icon('fa fa-plus', 'Vote Up'), vote_down=Icon('fa fa-minus', 'Vote Down'), download=Icon('fa fa-download', 'Download'), revert=Icon('fa fa-history', 'Revert'), browse_commits=Icon('fa fa-list', 'Browse Commits'), file=Icon('fa fa-file-o', 'File'), # Permissions perm_read=Icon('fa fa-eye', 'Read'), perm_update=Icon('fa fa-rotate-left', 'Update'), perm_create=Icon('fa fa-flash', 'Create'), perm_register=Icon('fa fa-gear', 'Config'), perm_delete=Icon('fa fa-minus-circle', 'Remove'), perm_tool=Icon('fa fa-gear', 'Tool'), perm_admin=Icon('fa fa-gear', 'Admin'), perm_has_yes=Icon('fa fa-check', 'Check'), perm_has_no=Icon('fa fa-ban', 'No entry'), perm_has_inherit=Icon('fa fa-check-circle', 'Has inherit'), ) # Cache some loaded entry points def _cache_eps(section_name, dict_cls=dict): d = dict_cls() for ep in h.iter_entry_points(section_name): try: value = ep.load() except Exception: log.exception('Could not load entry point [%s] %s', section_name, ep) else: d[ep.name] = value return d class entry_point_loading_dict(dict): def __missing__(self, key): self[key] = _cache_eps(key) return self[key] self.entry_points = entry_point_loading_dict( tool=_cache_eps('allura', dict_cls=utils.CaseInsensitiveDict), auth=_cache_eps('allura.auth'), registration=_cache_eps('allura.project_registration'), theme=_cache_eps('allura.theme'), user_prefs=_cache_eps('allura.user_prefs'), spam=_cache_eps('allura.spam'), phone=_cache_eps('allura.phone'), stats=_cache_eps('allura.stats'), site_stats=_cache_eps('allura.site_stats'), admin=_cache_eps('allura.admin'), site_admin=_cache_eps('allura.site_admin'), # macro eps are used solely for ensuring that external macros are # imported (after load, the ep itself is not used) macros=_cache_eps('allura.macros'), webhooks=_cache_eps('allura.webhooks'), multifactor_totp=_cache_eps('allura.multifactor.totp'), multifactor_recovery_code=_cache_eps( 'allura.multifactor.recovery_code'), ) # Set listeners to update stats statslisteners = [] for name, ep in self.entry_points['stats'].iteritems(): statslisteners.append(ep()) self.statsUpdater = PostEvent(statslisteners) self.tmpdir = os.getenv('TMPDIR', '/tmp')