def test_index_is_updated_after_deleting_website(self): from woost.models import Website, Publishable index = Publishable.per_website_publication_index w1 = Website() w1.insert() w2 = Website() w2.insert() p1 = Publishable() p1.websites = [w1] p1.insert() p2 = Publishable() p2.websites = [w1, w2] p2.insert() w1.delete() assert set(index.items()) == set([(None, p1.id), (w2.id, p2.id)]) w2.delete() assert set(index.items()) == set([(None, p1.id), (None, p2.id)])
def iter_exportable_languages(publishable: Publishable, user: User = None) -> Iterable[str]: """Iterates over all the translations for the given object that can be statically exported. :param publishable: The publishable object to evaluate. :param user: The user for which the export should be performed. Defaults to the active user. :return: An iterable sequence of language codes. """ if publishable.x_staticpub_exportable and publishable.enabled: if user is None: user = app.user if publishable.per_language_publication: for language in publishable.enabled_translations: if publishable.is_accessible( user=user, language=language, website=PublishableObject.any_website): yield language else: if publishable.is_accessible( user=user, website=PublishableObject.any_website): yield None
def content_parser(selector): if selector.startswith("branch:"): doc_id = selector.split(":", 1)[1] try: document = Document.require_instance(int(doc_id)) except: raise ArgumentTypeError( f"{doc_id} is not a valid branch ID" ) else: return ("branch", ("post", document)) elif selector.startswith("delbranch:"): doc_id = selector.split(":", 1)[1] try: document = Document.require_instance(int(doc_id)) except: raise ArgumentTypeError( f"{doc_id} is not a valid branch ID" ) else: return ("branch", ("delete", document)) elif selector.startswith("item:"): pub_id = selector.split(":", 1)[1] try: publishable = Publishable.require_instance(int(pub_id)) except: raise ArgumentTypeError( f"{pub_id} is not a valid branch ID" ) else: return ("item", ("post", publishable)) elif selector.startswith("delitem:"): pub_id = selector.split(":", 1)[1] try: publishable = Publishable.require_instance(int(pub_id)) except: raise ArgumentTypeError( f"{pub_id} is not a valid branch ID" ) else: return ("item", ("delete", publishable)) elif selector.startswith("export:"): export_id = selector.split(":", 1)[1] try: export = Export.require_instance(int(export_id)) except: raise ArgumentTypeError( f"{export_id} is not a valid export ID" ) else: return ("export", export)
def test_content_is_not_indexed_until_website_is_inserted(self): from woost.models import Website, Publishable index = Publishable.per_website_publication_index w1 = Website() p1 = Publishable() p1.insert() p1.websites = [w1] assert (w1.id, p1.id) not in list(index.items())
def test_content_can_change_its_designated_websites(self): from woost.models import Website, Publishable index = Publishable.per_website_publication_index p1 = Publishable() p1.insert() w1 = Website() w1.insert() w2 = Website() w2.insert() assert list(index.items()) == [(None, p1.id)] p1.websites = [w1] assert list(index.items()) == [(w1.id, p1.id)] p1.websites = [w2] assert list(index.items()) == [(w2.id, p1.id)] p1.websites = [w1, w2] assert set(index.items()) == set([(w1.id, p1.id), (w2.id, p1.id)]) p1.websites = [] assert list(index.items()) == [(None, p1.id)]
def test_permission_expression(self): from woost.models import (Item, Publishable, User, ReadPermission, PermissionExpression) self.everybody_role.permissions.append( ReadPermission(matching_items={ "type": "woost.models.publishable.Publishable" }, authorized=True)) i1 = Item() i2 = Item() d1 = Publishable() d2 = Publishable() i1.insert() i2.insert() d1.insert() d2.insert() results = set( Item.select( filters=[PermissionExpression(User(), ReadPermission)])) assert results == set([d1, d2])
def preserve_woost2_info(e): from woost.models import Configuration, Publishable # Rename the staticpub_default_dest member config = Configuration.instance try: default_dest = config._staticpub_default_dest except AttributeError: pass else: del config._staticpub_default_dest del default_dest._Configuration_staticpub_default_dest config.x_staticpub_default_dest = default_dest # Rename the 'included_in_static_publication' member datastore.root.pop( "woost.models.item.Item.included_in_static_publication", None ) for pub in Publishable.select(): value = pub._included_in_static_publication try: del pub._included_in_static_publication except AttributeError: pass else: pub.x_staticpub_exportable = value
def submit(self): ProceedForm.submit(self) order = Basket.pop() order.status = "payment_pending" order.update_cost() datastore.commit() payments = PaymentsExtension.instance # Redirect the user to the payment gateway if payments.enabled \ and payments.payment_gateway \ and order.payment_type == "payment_gateway": payments.payment_request(order.id) # No payment gateway available, redirect the user to the success # page; the payment will have to be handled manually by the site's # personnel else: raise cherrypy.HTTPRedirect( Publishable.require_instance( qname="woost.extensions.ecommerce.success_page"). get_uri(parameters={"order": order.id}))
def _install(self): from woost.models import (Publishable, Document, Controller, extension_translations) # Sitemap controller sitemap_controller = self._create_asset( Controller, "sitemap_controller", title=extension_translations, python_name= "woost.extensions.sitemap.sitemapcontroller.SitemapController") # Sitemap document sitemap_doc = self._create_asset(Document, "sitemap_document", title=extension_translations, path="sitemap_xml", per_language_publication=False, mime_type="text/xml", hidden=True, sitemap_indexable=False, controller=sitemap_controller) # Force indexing of the 'sitemap_indexable' member # (can't rely on defaults when executing queries) for item in Publishable.select(): if not hasattr(item, "_sitemap_indexable"): item.sitemap_indexable = \ item.sitemap_indexable and not item.hidden
def _get_document_properties(self): properties = Publishable.get_open_graph_properties(self) if self.description: properties["og:description"] = export_content(self.description) return properties
def test_unlink(self): template = list(Template.select())[0] publishable = Publishable() publishable.set("enabled", True, "en") publishable.template = template publishable.insert() datastore.commit() browser.open("/en/cms/content/%d/fields" % publishable.id) admin_login() assert not browser.is_element_present( "css=.template_field .control .new") assert not browser.is_element_present( "css=.template_field .control .delete") browser.click("css=.template_field .control .unlink") browser.wait_for_page_to_load(10000) val = browser.get_value("edited_item_template") assert not browser.get_value("edited_item_template")
def confirmation_url(self): confirmation_page = Publishable.require_instance( qname='woost.password_change_confirmation_page') return confirmation_page.get_uri(host=".", parameters={ "user": self.identifier, "hash": generate_confirmation_hash( self.identifier) })
def iter_entries(self): language_subset = app.website.get_published_languages( languages=self.included_locales or None) content = Publishable.select_accessible( Publishable.robots_should_index.equal(True), language=language_subset) if self.content_expression: context = {"site_map": self, "content": content} SiteMap.content_expression.execute(self, context) content = context["content"] for publishable in content: if not publishable.is_internal_content(): continue if publishable.per_language_publication: languages = language_subset & publishable.enabled_translations else: languages = (None, ) if not languages: continue properties = {} if publishable.x_sitemap_priority: properties["priority"] = publishable.x_sitemap_priority if publishable.x_sitemap_change_frequency: properties[ "changefreq"] = publishable.x_sitemap_change_frequency entries = [(properties, [(language, publishable.get_uri(host="!", language=language)) for language in languages])] if self.entries_expression: context = { "site_map": self, "publishable": publishable, "languages": languages, "entries": entries, "default_properties": properties } SiteMap.entries_expression.execute(self, context) entries = context["entries"] for entry in entries: yield entry
def test_allowed(self): from woost.models import Publishable, ReadPermission a = Publishable() a.enabled = True a.insert() b = Publishable() b.enabled = True b.insert() self.everybody_role.permissions.append( ReadPermission( matching_items={ "type": "woost.models.publishable.Publishable", "filter": "member-id", "filter_operator0": "ne", "filter_value0": str(b.id) })) assert self.accessible_items() == set([a])
def remove_document_resources(e): from woost.models import Publishable, Document, MemberPermission for document in Document.select(): try: del document._branch_resources except AttributeError: pass try: del document._page_resources except AttributeError: pass for publishable in Publishable.select(): try: del publishable._Document_branch_resources except AttributeError: pass try: del publishable._Document_page_resources except AttributeError: pass try: del publishable._inherit_resources except AttributeError: pass members = ("woost.models.document.Document.branch_resources", "woost.models.document.Document.page_resources", "woost.models.publishable.Publishable.inherit_resources") for permission in MemberPermission.select(): if permission.matching_members: removed = False for full_member_name in members: try: permission.matching_members.remove(full_member_name) except (KeyError, ValueError): pass else: removed = True if removed and not permission.matching_members: permission.delete()
def prefix_members(e): from woost.models import Publishable for pub in Publishable.select(): for key in ("priority", "change_frequency"): old_key = "sitemap_" + key try: value = getattr(pub, old_key) except AttributeError: pass else: delattr(pub, old_key) setattr(pub, "x_sitemap_" + key, value)
class SignUpPage(Document): members_order = [ "user_type", "roles", "confirmation_target", "confirmation_email_template" ] # Defines the persistent class that will be # used like schema in signup process user_type = schema.Reference(class_family=User, required=True, member_group="signup_process") # The collection of roles that will be applyed # to each instance (of user_type class) created throw # a signuppage roles = schema.Collection( items="woost.models.Role", related_end=schema.Collection(name="related_signup_pages", visible=False), member_group="signup_process", relation_constraints=lambda ctx: [excluded_roles()]) # If is None, doesn't require an email confirmation # process to complete signup process confirmation_email_template = schema.Reference( type=EmailTemplate, related_end=schema.Collection(), member_group="signup_process") confirmation_target = schema.Reference(type="woost.models.Publishable", related_end=schema.Collection(), member_group="signup_process", required=True) default_template = schema.DynamicDefault(lambda: Template.get_instance( qname=u"woost.extensions.signup.signup_template")) default_controller = schema.DynamicDefault(lambda: Controller.get_instance( qname=u"woost.extensions.signup.signup_controller")) default_confirmation_email_template = schema.DynamicDefault( lambda: EmailTemplate.get_instance( qname=u"woost.extensions.signup.signup_confirmation_email_template" )) default_confirmation_target = schema.DynamicDefault( lambda: Publishable.get_instance( qname=u"woost.extensions.signup.signup_confirmation_target"))
def resolve_path(self, path): if path: try: id = int(path[0]) except: pass else: publishable = Publishable.get_instance(id) if publishable is not None: return PathResolution( self, publishable, [path[0]], path[1:] )
def test_target(self): from woost.models import (ContentTrigger, Item, Publishable, StandardPage, User, set_current_user) self.assert_match( ContentTrigger(matching_items={ "type": "woost.models.publishable.Publishable" }), (Publishable(), None, {}, True), (StandardPage(), None, {}, True), (Item(), None, {}, False), (ContentTrigger(), None, {}, False)) user = User() set_current_user(user) self.assert_match( ContentTrigger( matching_items={ "type": "woost.models.publishable.Publishable", "filter": "member-qname", "filter_operator0": "eq", "filter_value0": "foobar" }), (Publishable(), user, {}, False), (Publishable(qname="foobar"), user, {}, True))
def initializer(session): if open_browser: # Find the web console document webconsole = Publishable.require_instance( qname="woost.extensions.webconsole.page") # Determine the URI for the breakpoint session webconsole_location = Location.get_current_host() webconsole_location.path_info = webconsole.get_uri() webconsole_location.query_string["session_id"] = session.id # Open a web browser tab pointing at the URI from webbrowser import open open(str(webconsole_location))
def test_content_is_published_for_all_websites_by_default(self): from woost.models import Website, Publishable index = Publishable.per_website_publication_index w1 = Website() w1.insert() p1 = Publishable() p1.insert() assert list(index.items()) == [(None, p1.id)] p2 = Publishable() p2.insert() assert set(index.items()) == set([(None, p1.id), (None, p2.id)])
def resolve_path(self, path): remaining_path = list(path) extra_path = [] while remaining_path: page = Publishable.get_instance( full_path = u"/".join(remaining_path) ) if page: return PathResolution( self, page, remaining_path, extra_path ) extra_path.append(remaining_path.pop())
def test_content_permissions(self): from woost.models import (Item, Publishable, User, Role, Permission, CreatePermission, ReadPermission, ModifyPermission, DeletePermission) class TestPermission(Permission): pass item = Item() doc = Publishable() for permission_type in [ CreatePermission, ReadPermission, ModifyPermission, DeletePermission ]: role = Role() user = User(roles=[role]) # Permission denied (no permissions defined) self.assert_not_authorized(user, permission_type, target=doc) # Permission granted role.permissions.append( permission_type(matching_items={ "type": "woost.models.publishable.Publishable" }, authorized=True)) self.assert_authorized(user, permission_type, target=doc) # Permission denied (wrong target) self.assert_not_authorized(user, permission_type, target=item) # Permission denied (wrong permission type) self.assert_not_authorized(user, TestPermission) # Permission denied (prevailing negative permission) role.permissions.insert( 0, permission_type( matching_items={"type": "woost.models.item.Item"}, authorized=False)) self.assert_not_authorized(user, permission_type, target=doc)
def submit(self): Form.submit(self) Basket.get().add_purchase(self.instance) Basket.store() notify_user(translations( "woost.extensions.ecommerce.product_added_notice", product=self.product), "product_added", transient=False) if self.redirect_to_basket: raise cherrypy.HTTPRedirect( Publishable.require_instance( qname="woost.extensions.ecommerce.basket_page"). get_uri()) else: Location.get_current().go("GET")
def preserve_woost2_info(e): from woost.models import Configuration, Website, Publishable from .opengraphtype import OpenGraphType broken = datastore.root.get("woost2_broken_objects") ext_map = \ broken and broken.get("woost.extensions.opengraph.OpenGraphExtension") ext = ext_map and ext_map.popitem()[1] if ext: # Must run before rebuild_indexes_after_conversion_to_python3, since # the index rebuilding can trigger the default value production for # Publication.x_opengraph_type, which in turn will attempt to obtain # a type by code. OpenGraphType.code.rebuild_index() def rename_attrib(obj, name, new_name=None): old_key = "_open_graph_" + name try: value = getattr(obj, old_key) except AttributeError: pass else: delattr(obj, old_key) new_key = "_x_opengraph_" + (new_name or name) setattr(obj, new_key, value) # Disable installation for the extension extensions_manager.set_installed("opengrah", True) for config in Configuration.select(): rename_attrib(config, "default_image") if ext: config._x_opengraph_fb_admins = ext["_facebook_administrators"] config._x_opengraph_fb_apps = ext["_facebook_applications"] for website in Website.select(): rename_attrib(website, "default_image") for pub in Publishable.select(): rename_attrib(pub, "enabled") rename_attrib(pub, "type")
def set_exportable_flag(): for item in [Configuration.instance] + list(Website.select()): for key in ("login_page", "maintenance_page", "generic_error_page", "not_found_error_page", "forbidden_error_page"): page = getattr(item, key, None) if page: page.x_staticpub_exportable = False for qname in ("woost.password_change_page", "woost.password_change_confirmation_page"): page = Publishable.get_instance(qname=qname) if page: page.included_in_static_publication = False for cls in get_publishable_models(): member = cls.get_member("x_staticpub_exportable") if member and member.indexed: member.rebuild_index()
def fix_opengraph_type_references(e): from woost.models import Publishable from .opengraphtype import OpenGraphType for og_type in OpenGraphType.select(): try: del og_type._Publishable_open_graph_type except AttributeError: pass for pub in Publishable.select(): try: og_type = pub._x_opengraph_type except AttributeError: pass else: del pub._x_opengraph_type pub.x_opengraph_type = og_type
def requires_agreement(form, name = "terms", document = None): if document is None: document = "%s.%s" % (app.package, name) if isinstance(document, basestring): document = Publishable.require_instance(qname = document) if document is None: raise ValueError( "Must specify a document detailing the end user agreement" ) member = schema.Boolean( name = name, required = True, __translate__ = lambda language, **kwargs: schema.Boolean.__translate__(member, language, **kwargs) or translations( "woost.controllers.formagreement.%s" % member.name, member = member ) or translations("woost.controllers.formagreement", member = member), member_group = "form_agreement" ) member.agreement_document = document member.add_validation(_validate_consent) form.schema.add_member(member) if form.schema.groups_order: if "form_agreement" not in form.schema.groups_order: if not isinstance(form.schema.groups_order, list): form.schema.groups_order = list(form.schema.groups_order) form.schema.groups_order.append("form_agreement") form.adapter.exclude(name) return member
def test_translation_enabled(self): from cocktail.translations import language_context from woost.models import (Publishable, ReadPermission, ReadTranslationPermission) self.everybody_role.permissions.append( ReadPermission(matching_items={ "type": "woost.models.publishable.Publishable" })) self.everybody_role.permissions.append(ReadTranslationPermission()) self.config.languages = ["en"] self.config.published_languages = [] with language_context("en"): a = Publishable() a.per_language_publication = True a.translation_enabled = True a.insert() b = Publishable() b.per_language_publication = True b.translation_enabled = False b.insert() c = Publishable() c.per_language_publication = True c.translation_enabled = True c.insert() d = Publishable() d.per_language_publication = True d.set("translation_enabled", True, "de") d.insert() e = Publishable() e.per_language_publication = False e.enabled = True e.insert() accessible = self.accessible_items() print a in accessible print b in accessible print c in accessible print d in accessible print e in accessible assert self.accessible_items() == set([a, c, e]) self.config.published_languages = ["en"] assert self.accessible_items() == set([a, c, e]) with language_context("de"): self.config.published_languages = ["de"] assert self.accessible_items() == set([d, e])
def test_enabled(self): from woost.models import Publishable, ReadPermission self.everybody_role.permissions.append( ReadPermission(matching_items={ "type": "woost.models.publishable.Publishable" })) a = Publishable() a.enabled = True a.insert() b = Publishable() b.enabled = False b.insert() c = Publishable() c.enabled = True c.insert() d = Publishable() d.enabled = False d.insert() assert self.accessible_items() == set([a, c])