def test_persistent_settings_add_new(self): from kotti.resources import Settings session = DBSession() [settings] = session.query(Settings).all() data = {'foo.bar': u'spam', 'kotti.db_version': u'next'} new_settings = settings.copy(data) session.add(new_settings) self.assertEqual(get_settings()['foo.bar'], u'spam') self.assertEqual(get_settings()['kotti.db_version'], u'next')
def test_persistent_settings(self): from kotti import get_version from kotti.resources import Settings session = DBSession() [settings] = session.query(Settings).all() self.assertEqual(settings.data, {'kotti.db_version': get_version()}) self.assertEqual(get_settings()['kotti.db_version'], get_version()) settings.data['foo.bar'] = u'baz' self.assertEqual(get_settings()['foo.bar'], u'baz')
def test_persistent_settings_add_new(self): from kotti import DBSession from kotti import get_settings from kotti.resources import Settings [settings] = DBSession.query(Settings).all() data = {"foo.bar": u"spam", "kotti.db_version": u"next"} new_settings = settings.copy(data) DBSession.add(new_settings) self.assertEqual(get_settings()["foo.bar"], u"spam") self.assertEqual(get_settings()["kotti.db_version"], u"next")
def contents_addable(): # Allow Nodes to be added to documents: save_node_type_info = Content.type_info.copy() Content.type_info.addable_to = [u'Document'] Content.type_info.add_view = u'add_document' get_settings()['kotti.available_types'].append(Content) try: yield finally: get_settings()['kotti.available_types'].pop() Content.type_info = save_node_type_info
def test_persistent_settings(self): from kotti import get_settings from kotti import get_version from kotti import DBSession from kotti.resources import Settings session = DBSession() [settings] = session.query(Settings).all() self.assertEqual(settings.data, {"kotti.db_version": get_version()}) self.assertEqual(get_settings()["kotti.db_version"], get_version()) settings.data["foo.bar"] = u"baz" self.assertEqual(get_settings()["foo.bar"], u"baz")
def test_setting_values_as_unicode(self): from kotti import get_settings from kotti import main settings = self.required_settings() settings['kotti.site_title'] = 'K\xc3\xb6tti' # Kötti settings['kotti_foo.site_title'] = 'K\xc3\xb6tti' settings['foo.site_title'] = 'K\xc3\xb6tti' main({}, **settings) assert get_settings()['kotti.site_title'] == u'K\xf6tti' assert get_settings()['kotti_foo.site_title'] == u'K\xf6tti' assert get_settings()['foo.site_title'] == 'K\xc3\xb6tti'
def test_override_settings(self): class MyType(object): pass def my_configurator(conf): conf['kotti.base_includes'] = '' conf['kotti.available_types'] = [MyType] settings = self.required_settings() settings['kotti.configurators'] = [my_configurator] main({}, **settings) self.assertEqual(get_settings()['kotti.base_includes'], []) self.assertEqual(get_settings()['kotti.available_types'], [MyType])
def test_setting_values_as_unicode(self, db_session): from kotti import get_settings from kotti import main settings = self.required_settings() settings["kotti.site_title"] = "K\xc3\xb6tti" # Kötti settings["kotti_foo.site_title"] = "K\xc3\xb6tti" settings["foo.site_title"] = "K\xc3\xb6tti" with patch("kotti.resources.initialize_sql"): main({}, **settings) assert get_settings()["kotti.site_title"] == u"K\xf6tti" assert get_settings()["kotti_foo.site_title"] == u"K\xf6tti" assert get_settings()["foo.site_title"] == "K\xc3\xb6tti"
def test_setting_values_as_unicode(self, db_session): from kotti import get_settings from kotti import main settings = self.required_settings() settings['kotti.site_title'] = 'K\xc3\xb6tti' # Kötti settings['kotti_foo.site_title'] = 'K\xc3\xb6tti' settings['foo.site_title'] = 'K\xc3\xb6tti' with patch('kotti.resources.initialize_sql'): main({}, **settings) assert get_settings()['kotti.site_title'] == u'K\xf6tti' assert get_settings()['kotti_foo.site_title'] == u'K\xf6tti' assert get_settings()['foo.site_title'] == 'K\xc3\xb6tti'
def initialize_sql(engine, drop_all=False): DBSession.registry.clear() DBSession.configure(bind=engine) metadata.bind = engine if drop_all or os.environ.get('KOTTI_TEST_DB_STRING'): metadata.reflect() metadata.drop_all(engine) # Allow users of Kotti to cherry pick the tables that they want to use: settings = _resolve_dotted(get_settings()) tables = settings['kotti.use_tables'].strip() or None if tables: tables = [metadata.tables[name] for name in tables.split()] _adjust_for_engine(engine) # Allow migrations to set the 'head' stamp in case the database is # initialized freshly: if not engine.table_names(): stamp_heads() metadata.create_all(engine, tables=tables) if os.environ.get('KOTTI_DISABLE_POPULATORS', '0') not in TRUE_VALUES: for populate in settings['kotti.populators']: populate() commit() return DBSession
def calculate_friend_auth(cur_user, target_person): myschool = getattr(cur_user, 'school', None) otherschool = getattr(target_person, 'school', None) if not myschool or not otherschool or myschool != otherschool: # We sure the will not reach the friend auth pass else: if cur_user.auth_friend == 0: # 计算是否满足校友认证 count = 0 # We are pretty sure they will make friends next(actully not very sure), so the min count -1 mincount = int( get_settings()['friend_auth_min_count'] ) -1 for myfriend in cur_user.all_friends: school = getattr(myfriend, 'school', None) if myschool == school: count +=1 if count >= mincount: cur_user.auth_friend = 1 if target_person.auth_friend == 0: count = 0 for otherfriend in target_person.all_friends: school = getattr(otherfriend, 'school', None) if otherschool == school: count +=1 if count >= mincount: target_person.auth_friend = 1 break
def __init__(self, context, request, bare=None, **kwargs): self.context, self.request = context, request if request.is_xhr and bare is None: bare = True self.bare = bare S = self.S = get_settings() bare_tmpl = self.BARE_TMPL self.macro_templates = dict( master_view=bare and bare_tmpl or S['kotti.templates.master_view'], master_edit=bare and bare_tmpl or S['kotti.templates.master_edit'], master_cp=bare and bare_tmpl or S['kotti.templates.master_cp'], snippets=S['kotti.templates.snippets'], ) self.base_css = S['kotti.templates.base_css'] self.view_css = S['kotti.templates.view_css'] self.edit_css = S['kotti.templates.edit_css'] if getattr(request, 'template_api', None) is None: request.template_api = self self.slots = Slots(context, request) self.__dict__.update(kwargs)
def test_views(db_session, dummy_request): root = get_root() root['test-document'] = Document() root['test-image'] = Image() # Setup kotti_configure(get_settings()) set_setting('kotti_disqus-disqus_available_types', ['kotti.resources.Document']) # Is shown on Document with the default URL if we do not set it set_setting('kotti_disqus-disqus_shortname', 'test_shortname') set_setting('kotti_disqus-disqus_base_url', '') assert disqus_comments_view(root['test-document'], dummy_request) == \ { 'disqus_url': 'http://example.com/test-document/', 'disqus_shortname': 'test_shortname' } # If we set the URL, it overrides the default one set_setting('kotti_disqus-disqus_base_url', 'http://testing.com/') assert disqus_comments_view(root['test-document'], dummy_request) == \ { 'disqus_url': 'http://testing.com/test-document/', 'disqus_shortname': 'test_shortname' } # Is not shown if we aren't on a Document object, raises PredicateMismatch with pytest.raises(PredicateMismatch): disqus_comments_view(root['test-image'], dummy_request)
def send_set_password(user, request, templates='set-password', add_query=None): site_title = get_settings()['kotti.site_title'] token = make_token(user) user.confirm_token = unicode(token) set_password_query = {'token': token, 'email': user.email} if add_query: set_password_query.update(add_query) url = '%s/@@set-password?%s' % ( request.application_url, urllib.urlencode(set_password_query), ) variables = dict( user_title=user.title, site_title=site_title, url=url, ) if isinstance(templates, str): templates = message_templates[templates] message = Message( recipients=[u'"%s" <%s>' % (user.title, user.email)], # XXX naive? subject=templates['subject'] % variables, body=templates['body'] % variables, ) mailer = get_mailer() mailer.send(message)
def disqus_comments_view(context, request): settings = get_settings_util() available = settings.get('kotti_disqus-disqus_available_types', []) available += get_settings()['kotti_disqus.extra_types'].split() resolver = DottedNameResolver(None) types = tuple(resolver.resolve(typ) for typ in available) if not isinstance(context, types): raise PredicateMismatch() api = template_api(context, request) disqus_url = '' disqus_shortname = settings['kotti_disqus-disqus_shortname'] base_url = settings['kotti_disqus-disqus_base_url'].strip('/') if base_url: disqus_url = base_url + api.url(context)[len(request.application_url):] else: disqus_url = api.url(context) return { 'disqus_shortname': disqus_shortname, 'disqus_url': disqus_url, }
def manifest(request): """ Web App Manifest - see https://w3c.github.io/manifest/#icons-member :param request: Current request :type request: :class:`kotti.request.request` :result: Manifest dictionary :rtype: dict """ result = { 'name': get_settings()['kotti.site_title'], 'icons': [], } for size, density in ( ('36x36', '0.75'), ('48x48', '1.0'), ('72x72', '1.5'), ('96x96', '2.0'), ('144x144', '3.0'), ('192x192', '4.0')): result['icons'].append({ 'src': request.static_url( 'kotti_icons:static/android-icon-{0}.png'.format(size)), 'sizes': size, 'type': 'img/png', 'density': density, }) return result
def populate(): """ Create the root node (:class:`~kotti.resources.Document`) and the 'about' subnode in the nodes tree if there are no nodes yet. """ lrm = LocalizerRequestMixin() lrm.registry = get_current_registry() lrm.locale_name = get_settings()['pyramid.default_locale_name'] localizer = lrm.localizer if DBSession.query(Node).count() == 0: localized_root_attrs = dict( [(k, localizer.translate(v)) for k, v in _ROOT_ATTRS.iteritems()]) root = Document(**localized_root_attrs) root.__acl__ = SITE_ACL DBSession.add(root) localized_about_attrs = dict( [(k, localizer.translate(v)) for k, v in _ABOUT_ATTRS.iteritems()]) root['about'] = Document(**localized_about_attrs) wf = get_workflow(root) if wf is not None: DBSession.flush() # Initializes workflow wf.transition_to_state(root, None, u'public') populate_users()
def initialize_sql(engine, drop_all=False): DBSession.registry.clear() DBSession.configure(bind=engine) metadata.bind = engine if drop_all or os.environ.get('KOTTI_TEST_DB_STRING'): metadata.reflect() metadata.drop_all(engine) # Allow users of Kotti to cherry pick the tables that they want to use: settings = get_current_registry().settings tables = settings['kotti.use_tables'].strip() or None if tables: tables = [metadata.tables[name] for name in tables.split()] if engine.dialect.name == 'mysql': # pragma: no cover from sqlalchemy.dialects.mysql.base import LONGBLOB File.__table__.c.data.type = LONGBLOB() # Allow migrations to set the 'head' stamp in case the database is # initialized freshly: if not engine.table_names(): stamp_heads() metadata.create_all(engine, tables=tables) if os.environ.get('KOTTI_DISABLE_POPULATORS', '0') not in ('1', 'y'): for populate in get_settings()['kotti.populators']: populate() commit() return DBSession
def initialize_sql(engine, drop_all=False): DBSession.registry.clear() DBSession.configure(bind=engine) metadata.bind = engine if drop_all or os.environ.get('KOTTI_TEST_DB_STRING'): metadata.reflect() metadata.drop_all(engine) # Allow users of Kotti to cherry pick the tables that they want to use: settings = get_current_registry().settings tables = settings['kotti.use_tables'].strip() or None if tables: if 'settings' not in tables: tables += ' settings' tables = [metadata.tables[name] for name in tables.split()] if engine.dialect.name == 'mysql': # pragma: no cover from sqlalchemy.dialects.mysql.base import LONGBLOB File.__table__.c.data.type = LONGBLOB() metadata.create_all(engine, tables=tables) for populate in get_settings()['kotti.populators']: populate() commit() return DBSession()
def url_normalizer(text, locale=None, max_length=MAX_URL_LENGTH): key = "kotti.url_normalizer.map_non_ascii_characters" map_non_ascii = get_settings()[key] if map_non_ascii: text = unidecode(text) # lowercase text base = text.lower() ext = "" m = FILENAME_REGEX.match(base) if m is not None: base = m.groups()[0] ext = m.groups()[1] base = base.replace(u" ", "-") base = IGNORE_REGEX.sub(u"", base) base = URL_DANGEROUS_CHARS_REGEX.sub(u"-", base) base = EXTRA_DASHES_REGEX.sub(u"", base) base = MULTIPLE_DASHES_REGEX.sub(u"-", base) base = crop_name(base, maxLength=max_length) if ext != "": base = base + u"." + ext return base
def register(context, request): schema = RegisterSchema().bind(request=request) form = Form(schema, buttons=(Button('register', _(u'Register')),)) rendered_form = None if 'register' in request.POST: try: appstruct = form.validate(request.POST.items()) except ValidationFailure, e: request.session.flash(_(u"There was an error."), 'error') rendered_form = e.render() else: settings = get_settings() appstruct['groups'] = u'' appstruct['roles'] = u'' register_groups = settings['kotti.register.group'] if register_groups: appstruct['groups'] = [register_groups] register_roles = settings['kotti.register.role'] if register_roles: appstruct['roles'] = set(['role:' + register_roles]) appstruct['send_email'] = True form = UserAddFormView(context, request) form.add_user_success(appstruct) success_msg = _( 'Congratulations! You are successfully registered. ' 'You should receive an email with a link to set your ' 'password momentarily.' ) request.session.flash(success_msg, 'success') return HTTPFound(location=request.application_url)
def deferred_default_sender(node, kw): sender = kw.get('sender') if not sender: sender = get_setting( 'default_sender', get_settings().get('mail.default_sender', '')) return sender
def email_set_password(user, request, template_name='kotti:templates/email-set-password.pt', add_query=None): site_title = get_settings()['kotti.site_title'] token = make_token(user) user.confirm_token = unicode(token) set_password_query = {'token': token, 'email': user.email} if add_query: set_password_query.update(add_query) url = '%s/@@set-password?%s' % ( request.application_url, urllib.urlencode(set_password_query), ) variables = dict( user_title=user.title, site_title=site_title, url=url, ) text = render(template_name, variables, request) subject, htmlbody = text.strip().split('\n', 1) subject = subject.replace('Subject:', '', 1).strip() html2text = HTML2Text() html2text.body_width = 0 textbody = html2text.handle(htmlbody).strip() message = Message( recipients=[u'"%s" <%s>' % (user.title, user.email)], # XXX naive? subject=subject, body=textbody, html=htmlbody, ) mailer = get_mailer() mailer.send(message)
def url_normalizer(text, locale=None, max_length=MAX_URL_LENGTH): key = 'kotti.url_normalizer.map_non_ascii_characters' map_non_ascii = asbool(get_settings()[key]) if map_non_ascii: text = unidecode(text) # lowercase text base = text.lower() ext = '' m = FILENAME_REGEX.match(base) if m is not None: base = m.groups()[0] ext = m.groups()[1] base = base.replace(' ', '-') base = IGNORE_REGEX.sub('', base) base = URL_DANGEROUS_CHARS_REGEX.sub('-', base) base = EXTRA_DASHES_REGEX.sub('', base) base = MULTIPLE_DASHES_REGEX.sub('-', base) base = crop_name(base, maxLength=max_length) if ext != '': base = base + '.' + ext return base
def test_override_settings(self): from kotti import main from kotti import get_settings class MyType(object): pass def my_configurator(conf): conf["kotti.base_includes"] = "" conf["kotti.available_types"] = [MyType] settings = self.required_settings() settings["kotti.configurators"] = [my_configurator] main({}, **settings) self.assertEqual(get_settings()["kotti.base_includes"], []) self.assertEqual(get_settings()["kotti.available_types"], [MyType])
def __init__(self, context, request): self.context = context self.request = request use_fanstatic = get_settings().get('kotti_media.use_fanstatic', True) if use_fanstatic and has_permission("edit", self.context, self.request): kotti_media_js.need()
def error_view(exception, request): print str(exception) should_mail = get_settings().get('oekocms.send_error_mails') == "True" if should_mail and exception.code != 404: mail_admin(str(exception) + str(request)) print str(exception) request.response.status_int = exception.code return {}
def validate_file_size_limit(node, value): value["fp"].seek(0, 2) size = value["fp"].tell() value["fp"].seek(0) max_size = get_settings()["kotti.max_file_size"] if size > int(max_size) * 1024 * 1024: msg = _("Maximum file size: ${size}MB", mapping={"size": max_size}) raise Invalid(node, msg)
def validate_file_size_limit(node, value): value['fp'].seek(0, 2) size = value['fp'].tell() value['fp'].seek(0) max_size = get_settings()['kotti.max_file_size'] if size > int(max_size) * 1024 * 1024: msg = _('Maximum file size: ${size}MB', mapping={'size': max_size}) raise Invalid(node, msg)
def __init__(self, f, request, disposition='attachment', cache_max_age=604800, content_type=None, content_encoding=None): """ :param f: the ``UploadedFile`` file field value. :type f: :class:`depot.io.interfaces.StoredFile` :param request: Current request. :type request: :class:`pyramid.request.Request` :param disposition: :type disposition: :param cache_max_age: The number of seconds that should be used to HTTP cache this response. :param content_type: The content_type of the response. :param content_encoding: The content_encoding of the response. It's generally safe to leave this set to ``None`` if you're serving a binary file. This argument will be ignored if you also leave ``content-type`` as ``None``. """ if f.public_url: raise HTTPMovedPermanently(f.public_url) content_encoding, content_type = self._get_type_and_encoding( content_encoding, content_type, f) super(StoredFileResponse, self).__init__( conditional_response=True, content_type=content_type, content_encoding=content_encoding) app_iter = None if request is not None and \ not get_settings()['kotti.depot_replace_wsgi_file_wrapper']: environ = request.environ if 'wsgi.file_wrapper' in environ: app_iter = environ['wsgi.file_wrapper'](f, _BLOCK_SIZE) if app_iter is None: app_iter = FileIter(f) self.app_iter = app_iter # assignment of content_length must come after assignment of app_iter self.content_length = f.content_length self.last_modified = f.last_modified if cache_max_age is not None: self.cache_expires = cache_max_age self.cache_control.public = True self.etag = self.generate_etag(f) self.content_disposition = rfc6266.build_header( f.filename, disposition=disposition, filename_compat=unidecode(f.filename))
def _initTestingDB(): from sqlalchemy import create_engine from kotti import get_settings from kotti.resources import initialize_sql database_url = testing_db_url() get_settings()['sqlalchemy.url'] = database_url session = initialize_sql(create_engine(database_url), drop_all=True) return session
def uploaded_file_url(self, uploaded_file, disposition='inline'): if disposition == 'attachment': suffix = '/download' else: suffix = '' url = '{0}/{1}/{2}{3}'.format(self.application_url, get_settings()['kotti.depot_mountpoint'][1:], uploaded_file.path, suffix) return url
def populate_users(): principals = get_principals() if u'admin' not in principals: principals[u'admin'] = { 'name': u'admin', 'password': get_settings()['kotti.secret'], 'title': u"Administrator", 'groups': [u'role:admin'], }
def test_setting_values_as_unicode(self): from kotti import get_settings from kotti import main settings = self.required_settings() settings['kotti.site_title'] = 'K\xc3\xb6tti' # Kötti main({}, **settings) self.assertEqual(get_settings()['kotti.site_title'], u'K\xf6tti')
def test_override_settings(self, db_session): from kotti import main from kotti import get_settings class MyType: pass def my_configurator(conf): conf["kotti.base_includes"] = "" conf["kotti.available_types"] = [MyType] settings = self.required_settings() settings["kotti.configurators"] = [my_configurator] with patch("kotti.resources.initialize_sql"): main({}, **settings) assert get_settings()["kotti.base_includes"] == [] assert get_settings()["kotti.available_types"] == [MyType]
def content_type_factories(context, request): """Drop down menu for Add button in editor bar. """ all_types = get_settings()['kotti.available_types'] factories = [] for factory in all_types: if factory.type_info.addable(context, request): factories.append(factory) return {'factories': factories}
def pwd_login(context, request): """ Login view. Renders either the login or password forgot form templates or handles their form submission and redirects to came_from on success. :result: Either a redirect response or a dictionary passed to the template for rendering :rtype: pyramid.httpexceptions.HTTPFound or dict """ principals = get_principals() came_from = request.params.get('came_from', request.resource_url(context)) login, password = u'', u'' if 'submit' in request.POST: login = request.params['login'].lower() password = request.params['password'] user = _find_user(login) if (user is not None and user.active and principals.validate_password(password, user.password)): return get_settings()['kotti.login_success_callback'][0](request, user, came_from) request.session.flash(_(u"Login failed."), 'error') if 'reset-password' in request.POST: login = request.params['login'] user = _find_user(login) if user is not None and user.active: return get_settings()['kotti.reset_password_callback'][0](request, user) else: request.session.flash( _(u"That username or email is not known by this system."), 'error') return { 'url': request.application_url + '/@@pwd_login', 'came_from': came_from, 'login': login, 'password': password, }
def login(context, request): """ Login view. Renders either the login or password forgot form templates or handles their form submission and redirects to came_from on success. :result: Either a redirect response or a dictionary passed to the template for rendering :rtype: pyramid.httpexceptions.HTTPFound or dict """ principals = get_principals() came_from = request.params.get('came_from', request.resource_url(context)) login, password = u'', u'' if 'submit' in request.POST: login = request.params['login'].lower() password = request.params['password'] user = _find_user(login) if (user is not None and user.active and principals.validate_password(password, user.password)): headers = remember(request, user.name) request.session.flash( _(u"Welcome, ${user}!", mapping=dict(user=user.title or user.name)), 'success') user.last_login_date = datetime.now() return HTTPFound(location=came_from, headers=headers) request.session.flash(_(u"Login failed."), 'error') if 'reset-password' in request.POST: login = request.params['login'] user = _find_user(login) if user is not None and user.active: email_set_password( user, request, template_name='kotti:templates/email-reset-password.pt') request.session.flash( _(u"You should be receiving an email with a link to reset your " u"password. Doing so will activate your account."), 'success') else: request.session.flash( _(u"That username or email is not known by this system."), 'error') return { 'url': request.application_url + '/@@login', 'came_from': came_from, 'login': login, 'password': password, 'register': asbool(get_settings()['kotti.register']), }
def site_title(self): """ The site title. :result: Value of the ``kotti.site_title`` setting (if specified) or the root item's ``title`` attribute. :rtype: str """ value = get_settings().get("kotti.site_title") if not value: value = self.root.title return value
def get_root(request=None): """Call the function defined by the ``kotti.root_factory`` setting and return its result. :param request: current request (optional) :type request: :class:`kotti.request.Request` :result: a node in the node tree :rtype: :class:`~kotti.resources.Node` or descendant; """ return get_settings()['kotti.root_factory'][0](request)
def uploaded_file_url(self, uploaded_file, disposition="inline"): if disposition == "attachment": suffix = "/download" else: suffix = "" url = "{0}/{1}/{2}{3}".format( self.application_url, get_settings()["kotti.depot_mountpoint"][1:], uploaded_file.path, suffix, ) return url
def result_items(context, request): settings = get_settings() content_types = settings.get('kotti_feed.content_types', 'document').split(' ') items = DBSession.query(Content).filter( Content.type.in_(content_types)).order_by(Content.modification_date) context_path = request.resource_path(context) return [ item for item in items if (has_permission('view', item, request) and request.resource_path(item).startswith(context_path)) ]
def __init__(self, context, request, bare=None, **kwargs): self.context, self.request = context, request if getattr(request, 'template_api', None) is None: request.template_api = self self.S = get_settings() if request.is_xhr and bare is None: bare = True # use bare template that renders just the content area self.bare = bare self.slots = Slots(context, request) self.__dict__.update(kwargs)
def _after_commit(session): request = get_current_request() settings = get_settings() index_action_dotted = settings['kotti_es.index_action'] index_action = DottedNameResolver(None).resolve(index_action_dotted) if request: # use a global alternative session (the session bound to # this hook might be not usable) try: index_action(request) finally: ESSession.remove()
def title_to_name(title, blacklist=()): request = get_current_request() if request is not None: locale_name = get_locale_name(request) else: locale_name = 'en' from kotti import get_settings urlnormalizer = get_settings()['kotti.url_normalizer'][0] name = unicode(urlnormalizer(title, locale_name, max_length=40)) while name in blacklist: name = disambiguate_name(name) return name
def content_type_factories(context, request): """ Renders the drop down menu for Add button in editor bar. :result: Dictionary passed to the template for rendering. :rtype: pyramid.httpexceptions.HTTPFound or dict """ all_types = get_settings()['kotti.available_types'] factories = [] for factory in all_types: if factory.type_info.addable(context, request): factories.append(factory) return {'factories': factories}
def wire_sqlalchemy(): # pragma: no cover global _WIRED_SQLALCHEMY if _WIRED_SQLALCHEMY: return else: _WIRED_SQLALCHEMY = True settings = get_settings() if not asbool(settings.get('kotti_es.disable_indexing', False)): sqlalchemy.event.listen(mapper, 'after_insert', _after_insert_update) sqlalchemy.event.listen(mapper, 'after_update', _after_insert_update) sqlalchemy.event.listen(mapper, 'after_delete', _after_delete) sqlalchemy.event.listen(DBSession, 'after_commit', _after_commit)
def register(context, request): schema = RegisterSchema().bind(request=request) form = Form(schema, buttons=(Button('register', _(u'Register')), )) rendered_form = None if 'register' in request.POST: try: appstruct = form.validate(request.POST.items()) except ValidationFailure as e: request.session.flash(_(u"There was an error."), 'error') rendered_form = e.render() else: settings = get_settings() appstruct['groups'] = u'' appstruct['roles'] = u'' register_groups = settings['kotti.register.group'] if register_groups: appstruct['groups'] = [register_groups] register_roles = settings['kotti.register.role'] if register_roles: appstruct['roles'] = {'role:' + register_roles} appstruct['send_email'] = True form = UserAddFormView(context, request) form.add_user_success(appstruct) success_msg = _( 'Congratulations! You are successfully registered. ' 'You should be receiving an email with a link to set your ' 'password. Doing so will activate your account.') request.session.flash(success_msg, 'success') name = appstruct['name'] notify(UserSelfRegistered(get_principals()[name], request)) return HTTPFound(location=request.application_url) if rendered_form is None: rendered_form = form.render(request.params) api = template_api( context, request, page_title=_(u"Register - ${title}", mapping=dict(title=context.title)), ) return { 'api': api, 'form': rendered_form, }
def extract_from_settings(prefix, settings=None): """ >>> settings = { ... 'kotti_twitter.foo_bar': '1', 'kotti.spam_eggs': '2'} >>> print(extract_from_settings('kotti_twitter.', settings)) {'foo_bar': '1'} """ from kotti import get_settings settings = settings if settings is not None else get_settings() extracted = {} for key, value in settings.items(): if key.startswith(prefix): extracted[key[len(prefix):]] = value return extracted
def populate_users(): """ Create the admin user with the password from the ``kotti.secret`` option if there is no user with name 'admin' yet. """ principals = get_principals() if "admin" not in principals: principals["admin"] = { "name": "admin", "password": get_settings()["kotti.secret"], "title": "Administrator", "groups": ["role:admin"], }
def populate_users(): """ Create the admin user with the password from the ``kotti.secret`` option if there is no user with name 'admin' yet. """ principals = get_principals() if u'admin' not in principals: principals[u'admin'] = { 'name': u'admin', 'password': get_settings()['kotti.secret'], 'title': u"Administrator", 'groups': [u'role:admin'], }
def upgrade(): from kotti import DBSession from kotti import get_settings from kotti.resources import Document from kotti.workflow import get_workflow from kotti.workflow import reset_workflow is_default = get_settings()['kotti.use_workflow'] == 'kotti:workflow.zcml' if not is_default: return reset_workflow() for obj in DBSession.query(Document): workflow = get_workflow(obj) workflow.transition_to_state(obj, None, 'public')
def validate_file_size_limit(node, value): """ File size limit validator. You can configure the maximum size by setting the kotti.max_file_size option to the maximum number of bytes that you want to allow. """ value['fp'].seek(0, 2) size = value['fp'].tell() value['fp'].seek(0) max_size = get_settings()['kotti.max_file_size'] if size > int(max_size) * 1024 * 1024: msg = _('Maximum file size: ${size}MB', mapping={'size': max_size}) raise colander.Invalid(node, msg)
def email_set_password(user, request, template_name='kotti:templates/email-set-password.pt', add_query=None): site_title = get_settings()['kotti.site_title'] token = make_token(user) user.confirm_token = unicode(token) set_password_query = {'token': token, 'email': user.email} if add_query: set_password_query.update(add_query) url = '{0}/@@set-password?{1}'.format(request.application_url, urllib.urlencode(set_password_query)) variables = dict(user_title=user.title, site_title=site_title, url=url) recipients = [u'"{0}" <{1}>'.format(user.title, user.email)] # XXX naive? send_email(request, recipients, template_name, variables)
def set_modification_date(event): """Update ``modification_date`` of the object that triggered the event. :param event: event that trigerred this handler. :type event: :class:`ObjectUpdate` """ exclude = [] for e in get_settings()['kotti.modification_date_excludes']: if isinstance(event.object, e.class_): exclude.append(e.key) if has_changes(event.object, exclude=exclude): event.object.modification_date = datetime.now()
def register(context, request): schema = RegisterSchema().bind(request=request) form = Form(schema, buttons=(Button("register", _("Register")),)) rendered_form = None if "register" in request.POST: try: appstruct = form.validate(request.POST.items()) except ValidationFailure as e: request.session.flash(_("There was an error."), "error") rendered_form = e.render() else: settings = get_settings() appstruct["groups"] = "" appstruct["roles"] = "" register_groups = settings["kotti.register.group"] if register_groups: appstruct["groups"] = [register_groups] register_roles = settings["kotti.register.role"] if register_roles: appstruct["roles"] = {"role:" + register_roles} appstruct["send_email"] = True form = UserAddFormView(context, request) form.add_user_success(appstruct) success_msg = _( "Congratulations! You are successfully registered. " "You should be receiving an email with a link to set your " "password. Doing so will activate your account." ) request.session.flash(success_msg, "success") name = appstruct["name"] notify(UserSelfRegistered(get_principals()[name], request)) return HTTPFound(location=request.application_url) if rendered_form is None: rendered_form = form.render(request.params) api = template_api( context, request, page_title=_("Register - ${title}", mapping=dict(title=context.title)), ) return {"api": api, "form": rendered_form}
def sanitize(html: str, sanitizer: str) -> str: """ Sanitize HTML :param html: HTML to be sanitized :type html: basestring :param sanitizer: name of the sanitizer to use :type sanitizer: str :result: sanitized HTML :rtype: str """ sanitized = get_settings()["kotti.sanitizers"][sanitizer](html) return sanitized
def sanitize(html, sanitizer): """ Sanitize HTML :param html: HTML to be sanitized :type html: basestring :param sanitizer: name of the sanitizer to use :type sanitizer: str :result: sanitized HTML :rtype: unicode """ sanitized = get_settings()['kotti.sanitizers'][sanitizer](html) return sanitized
def email_set_password( user: Principal, request: Request, template_name: Optional[ str] = "kotti:templates/email-set-password.pt", # noqa add_query: Optional[Dict[str, str]] = None, ) -> None: site_title = get_settings()["kotti.site_title"] token = make_token(user) user.confirm_token = token set_password_query = {"token": token, "email": user.email} if add_query: set_password_query.update(add_query) url = "{}/@@set-password?{}".format(request.application_url, urlencode(set_password_query)) variables = dict(user_title=user.title, site_title=site_title, url=url) recipients = [f'"{user.title}" <{user.email}>'] # XXX naive? send_email(request, recipients, template_name, variables)
def test_normalizer_map_non_ascii_characters(self): get_settings()["kotti.url_normalizer.map_non_ascii_characters"] = True assert url_normalizer("simpleandsafe") == "simpleandsafe" assert (url_normalizer(" Whitespace and capital Letters ") == "whitespace-and-capital-letters") assert url_normalizer(">here's another!") == "heres-another" assert url_normalizer( ">>>here'!--s yet another!!!") == "here-s-yet-another" assert url_normalizer("Doe, Joe") == "doe-joe" assert url_normalizer("umläut.doc") == "umlaut.doc" assert url_normalizer("ZAŻÓŁĆ GĘŚLĄ JAŹŃ") == "zazolc-gesla-jazn" assert url_normalizer("zażółć gęślą jaźń") == "zazolc-gesla-jazn" assert url_normalizer("quote-this") == "quote-this" assert url_normalizer("quote 'this'!") == "quote-this" assert url_normalizer("I'm not a FILE.txt") == "im-not-a-file.txt" assert url_normalizer("I'm a big file.TXT") == "im-a-big-file.txt" assert url_normalizer("rest `n` peace") == "rest-n-peace" assert (len(url_normalizer("aa" * 2000))) == 255 assert url_normalizer("short-hello-version", max_length=10) == "short"