class MailingList(Item): members_order = ["title", "mailings"] title = schema.String( required = True, unique = True, indexed = True, normalized_index = True, full_text_indexed = True, descriptive = True, translated = True ) users = schema.Collection( items = "woost.models.User", bidirectional = True, listed_by_default = False ) mailings = schema.Collection( items = "woost.extensions.mailer.mailing.Mailing", bidirectional = True, editable = False, listed_by_default = False )
class RenderPermission(ContentPermission): """Permission to obtain images representing instances of a content type.""" instantiable = True factories = schema.Collection( items = schema.Reference(type = ImageFactory), related_end = schema.Collection(), edit_control = "cocktail.html.CheckList", searchable = False ) def match(self, target, image_factory, verbose = False): if self.factories and image_factory not in self.factories: print permission_doesnt_match_style("factory doesn't match") return False return ContentPermission.match(self, target, verbose) @classmethod def permission_not_found(cls, user, verbose = False, **context): # If no specific render permission is found, a read permission will do return user.has_permission( ReadPermission, target = context["target"], verbose = verbose )
def _load(self): from woost.extensions.facebookpublication import ( strings, fbpublishuseraction, fbpublishauthuseraction, facebookpublicationpermission) from woost.extensions.facebookpublication.facebookpublicationtarget \ import FacebookPublicationTarget FacebookPublicationExtension.add_member( schema.Collection( "targets", items=schema.Reference(type=FacebookPublicationTarget), integral=True, bidirectional=True, related_end=schema.Collection())) from woost.controllers.backoffice.backofficecontroller \ import BackOfficeController from woost.extensions.facebookpublication.facebookpublicationcontroller \ import FacebookPublicationController BackOfficeController.fbpublish = FacebookPublicationController from woost.extensions.facebookpublication.facebookalbumscontroller \ import FacebookAlbumsController BackOfficeController.fbpublish_albums = FacebookAlbumsController
class VideoBlock(Block): instantiable = True view_class = "woost.views.VideoBlockView" block_display = "woost.views.VideoBlockDisplay" member_order = ["element_type", "video", "player_settings"] element_type = ElementType(member_group="content") video = schema.Reference(type=Publishable, required=True, relation_constraints={"resource_type": "video"}, related_end=schema.Collection(), invalidates_cache=True, member_group="content") player_settings = schema.Reference(type=VideoPlayerSettings, required=True, related_end=schema.Collection(), invalidates_cache=True, member_group="content") def get_block_image(self): return self.video def init_view(self, view): Block.init_view(self, view) view.tag = self.element_type view.video = self.video view.player_settings = self.player_settings view.depends_on(self.video)
def _load(self): from woost.extensions.twitterpublication import ( strings, tweetuseraction, twitterauthuseraction, tweetpermission ) from woost.extensions.twitterpublication.twitterpublicationtarget \ import TwitterPublicationTarget TwitterPublicationExtension.add_member( schema.Collection("targets", items = schema.Reference(type = TwitterPublicationTarget), integral = True, bidirectional = True, related_end = schema.Collection() ) ) from woost.controllers.backoffice.backofficecontroller \ import BackOfficeController from woost.extensions.twitterpublication.tweetcontroller \ import TweetController BackOfficeController.tweet = TweetController self.install()
def form_schema(self): return schema.Schema("FacebookPublicationForm", members = [ schema.Collection("subset", items = schema.Reference( type = Publishable, required = True, enumeration = lambda ctx: self.selection ), min = 1, default = schema.DynamicDefault(lambda: self.selection) ), schema.Collection("published_languages", items = schema.String( translate_value = lambda value, language = None, **kwargs: "" if not value else translations(value, language, **kwargs), enumeration = lambda ctx: self.eligible_languages ), min = 1, default = schema.DynamicDefault( lambda: self.eligible_languages ) ), schema.Collection("publication_targets", items = schema.Reference( type = FacebookPublicationTarget, required = True, enumeration = lambda ctx: self.allowed_publication_targets ), min = 1, default = schema.DynamicDefault( lambda: self.allowed_publication_targets ) ) ])
class CampaignMonitorList(Item): edit_node_class = \ "woost.extensions.campaign3.campaignmonitorlisteditnode.CampaignMonitorListEditNode" members_order = [ "title", "list_id", "confirmation_page", "confirmation_success_page", "unsubscribe_page", ] title = schema.String(required=True, descriptive=True) list_id = schema.String(required=True, unique=True, text_search=False) confirmation_page = schema.Reference(type="woost.models.Publishable", related_end=schema.Collection()) confirmation_success_page = schema.Reference( type="woost.models.Publishable", related_end=schema.Collection()) unsubscribe_page = schema.Reference(type="woost.models.Publishable", related_end=schema.Collection()) def update(self): list = List( { "api_key": Configuration.instance.get_setting("campaign_monitor_api_key") }, self.list_id) details = list.details() if self.confirmation_success_page: confirmation_success_page = self.confirmation_success_page.get_uri( host=".") else: confirmation_success_page = None if self.unsubscribe_page: unsubscribe_page = self.unsubscribe_page.get_uri( host=".") + "?email=[email]" else: unsubscribe_page = None list.update(details.Title, unsubscribe_page, details.ConfirmedOptIn, confirmation_success_page, unsubscribe_setting=details.UnsubscribeSetting)
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 _load(self): from woost.extensions.campaignmonitor import (campaignmonitorlist, strings, useraction) # Setup the synchronization view from woost.controllers.backoffice.backofficecontroller \ import BackOfficeController from woost.extensions.campaignmonitor.synccontroller import \ SyncCampaignMonitorListsController BackOfficeController.sync_campaign_monitor_lists = \ SyncCampaignMonitorListsController # Extension fields from woost.extensions.campaignmonitor.campaignmonitorlist \ import CampaignMonitorList CampaignMonitorExtension.add_member( schema.String("api_key", required=True, text_search=False)) CampaignMonitorExtension.add_member( schema.String("client_id", required=True, text_search=False)) CampaignMonitorExtension.add_member( schema.Collection("lists", items=schema.Reference(type=CampaignMonitorList), integral=True, related_end=schema.Reference())) self.install()
class MenuBlock(Block): instantiable = True view_class = "woost.views.Menu" root = schema.Reference(type=Document, related_end=schema.Collection(), member_group="content") root_visible = schema.Boolean(required=True, default=False, member_group="content") max_depth = schema.Integer(member_group="content") expanded = schema.Boolean(required=True, default=False, member_group="content") def init_view(self, view): Block.init_view(self, view) view.root = self.root view.root_visible = self.root_visible view.max_depth = self.max_depth view.expanded = self.expanded
class Tag(PersistentObject): instance_count = 0 documents = schema.Collection( items=schema.Reference(type=Document), related_end=schema.Collection("tags", indexed=True), indexed=True) def __init__(self, *args, **kwargs): PersistentObject.__init__(self, *args, **kwargs) self.__class__.instance_count += 1 self.number = self.instance_count def __repr__(self): return "Tag %d" % self.number
def selection(self): return get_parameter(schema.Collection("selection", items=schema.Reference( type=Publishable, required=True), min=1), errors="raise")
class OpenGraphCategory(Item): members_order = [ "title", "code", "types" ] title = schema.String( required = True, unique = True, translated = True, spellcheck = True, descriptive = True ) code = schema.String( required = True, unique = True, indexed = True ) types = schema.Collection( items = "woost.extensions.opengraph.opengraphtype.OpenGraphType", bidirectional = True, cascade_delete = True )
class ValidationErrorResponse(ErrorResponse): """Response type for schema validation errors.""" status = 400 error_schema = schema.Schema( members={ "type": schema.String( required=True, doc="An identifier for the validation rule that failed"), "message": schema.String( required=True, doc="A human readable description of the validation error"), "members": schema.Collection( items=schema.String( required=True, doc="The name of a member of the validated schema"), doc="The members involved in the validation error") }) def get_data(self, error: Exception) -> json_object: data = super().get_data(error) data["members"] = [ member.name for member in error.invalid_members if member.name ] return data
class SubscriptionFormBlock(Block): instantiable = True type_group = "blocks.forms" members_order = ["subscriber_model", "lists"] default_controller = \ "woost.extensions.campaign3.subscriptioncontroller.SubscriptionController" subscriber_model = schema.String( required=True, default="woost.extensions.campaign3.subscriber.Subscriber", text_search=False, member_group="content") lists = schema.Collection(items=schema.Reference(type=CampaignMonitorList), min=1, member_group="content", listed_by_default=False) view_class = schema.String(required=True, shadows_attribute=True, before_member="controller", member_group="behavior")
class Change(PersistentObject): """A persistent record of an action performed on a CMS item.""" indexed = True changeset = schema.Reference(required=True, type="woost.models.ChangeSet") action = schema.String(required=True, indexed=True, enumeration=["create", "modify", "delete"]) target = schema.Reference(required=True, type="woost.models.Item", bidirectional=True) changed_members = schema.Collection(type=set, items=schema.String()) item_state = schema.Mapping(required=False) def __translate__(self, language, **kwargs): return translations( "woost.models.changesets.Change description", action=self.action, target=self.target) or PersistentObject.__translate__( self, language, **kwargs)
class MemberPermission(Permission): """Base class for permissions that restrict operations on members.""" matching_members = schema.Collection( default_type=set, items=schema.String( enumeration=lambda ctx: set(_eligible_members()), translate_value=lambda value, language=None, **kwargs: "" if not value else translations(_resolve_matching_member_reference( value), language, qualified=True)), edit_control="woost.views.MemberList") def match(self, member, verbose=False): member = member.original_member.schema.full_name + "." + member.name members = self.matching_members if members and member not in members: if verbose: print permission_doesnt_match_style("member doesn't match"), return False return True def iter_matching_members(self): for compound_name in self.matching_members: yield _resolve_matching_member_reference(compound_name)
class FacebookIdentityProvider(IdentityProvider): provider_name = "Facebook" user_identifier = "x_identity_facebook_user_id" members_order = [ "client_id", "client_secret", "scope" ] client_id = schema.String( required=True, text_search=False ) client_secret = schema.String( required=True, text_search=False ) scope = schema.Collection( min=1, default=schema.DynamicDefault(lambda: ["public_profile", "email"]), items=schema.String() ) def get_auth_url(self, target_url = None): return ( "/facebook_oauth/%d/step1?%s" % ( self.id, urlencode({ "target_url": target_url or get_request_url() }) ) )
class RenderPermission(ContentPermission): """Permission to obtain images representing instances of a content type.""" instantiable = True def _image_factories_enumeration(ctx): from woost.models.rendering.factories import image_factories return image_factories.keys() image_factories = schema.Collection( items=schema.String(enumeration=_image_factories_enumeration), searchable=False) del _image_factories_enumeration def match(self, target, image_factory, verbose=False): if self.image_factories and image_factory not in self.image_factories: print permission_doesnt_match_style("image_factory doesn't match") return False return ContentPermission.match(self, target, verbose) @classmethod def permission_not_found(cls, user, verbose=False, **context): # If no specific render permission is found, a read permission will do return user.has_permission(ReadPermission, target=context["target"], verbose=verbose)
class TranslationPermission(Permission): """Base class for permissions that restrict operations on languages.""" def _matching_languages_enumeration(ctx): from woost.models import Configuration return Configuration.instance.languages matching_languages = schema.Collection( edit_control="cocktail.html.CheckList", items=schema.String( enumeration=_matching_languages_enumeration, translate_value=lambda value, language=None, **kwargs: u"" if not value else translations(value, language, **kwargs))) del _matching_languages_enumeration def match(self, language, verbose=False): languages = self.matching_languages if languages and language not in languages: if verbose: print permission_doesnt_match_style("language doesn't match"), return False return True
def visible_languages(self): return get_parameter(schema.Collection("language", items=schema.String(), default=[get_language()]), source=CookieParameterSource( cookie_naming="visible_languages", cookie_duration=self.settings_duration))
class Template(Item): type_group = "customization" members_order = ["title", "identifier", "documents"] title = schema.String(required=True, unique=True, indexed=True, normalized_index=True, full_text_indexed=True, descriptive=True, translated=True) identifier = schema.String(required=True, unique=True, indexed=True, max=255, text_search=False) documents = schema.Collection(items="woost.models.Document", bidirectional=True, editable=False, synchronizable=False, visible_in_reference_list=False)
class CustomDefinition(Item): visible_from_root = False members_order = [ "title", "identifier", "definition_type", "enabled", "content_types", "initialization" ] title = schema.String(required=True, indexed=True, unique=True, translated=True, descriptive=True) identifier = schema.String() definition_type = schema.String(required=True, default="dimension", enumeration=["dimension", "metric"]) enabled = schema.Boolean(required=True, default=True) content_types = schema.Collection( items=schema.Reference(class_family=Item), default=[Publishable], min=1) initialization = schema.CodeBlock(language="python") def applies(self, publishable, website=None): return isinstance(publishable, tuple(self.content_types)) def apply(self, publishable, values, index=None, env=None): if not self.initialization: return if index is None: from woost.models import Configuration defs = Configuration.instance.google_analytics_custom_definitions index = defs.index(self) context = { "publishable": publishable, "index": index, "value": schema.undefined, "undefined": schema.undefined, "env": {} if env is None else env } CustomDefinition.initialization.execute(self, context) index = context["index"] if index is not None: value = context["value"] if value is not schema.undefined: key = self.definition_type + str(index) value = get_ga_value(value) values[key] = value
class CampaignMonitorList(Item): members_order = [ "title", "list_id", "confirmation_page", "confirmation_success_page", "unsubscribe_page", ] title = schema.String(required=True, descriptive=True, spellcheck=True) list_id = schema.String(required=True, unique=True, text_search=False) confirmation_page = schema.Reference(type=Page, related_end=schema.Collection()) confirmation_success_page = schema.Reference( type=Page, related_end=schema.Collection()) unsubscribe_page = schema.Reference(type=Page, related_end=schema.Collection()) def update(self): list = List({"api_key": get_setting("x_campaign3_api_key")}, self.list_id) details = list.details() if self.confirmation_success_page: confirmation_success_page = \ self.confirmation_success_page.get_uri(host = "!") else: confirmation_success_page = None if self.unsubscribe_page: unsubscribe_page = (self.unsubscribe_page.get_uri(host="!").merge( URL(query={"email": "[email]"}))) else: unsubscribe_page = None list.update(details.Title, unsubscribe_page, details.ConfirmedOptIn, confirmation_success_page, unsubscribe_setting=details.UnsubscribeSetting)
class B(PersistentObject): full_text_indexed = True text = schema.String() parent = schema.Reference(bidirectional=True) children = schema.Collection(bidirectional=True, text_search=True)
def expanded_items(self): if self.params.read(schema.String("expanded")) == "all": return "all" else: return self.params.read( schema.Collection("expanded", type=set, items=schema.Integer(), default=set()))
def _load(self): from woost.controllers.backoffice.backofficecontroller \ import BackOfficeController from woost.extensions.staticsite import (useraction, strings, staticsitesnapshoter, exportationpermission, exportstaticsitecontroller) from woost.extensions.staticsite.staticsitesnapshoter \ import StaticSiteSnapShoter from woost.extensions.staticsite.staticsitedestination \ import StaticSiteDestination BackOfficeController.export_static = \ exportstaticsitecontroller.ExportStaticSiteController StaticSiteExtension.add_member( schema.Collection("snapshoters", items=schema.Reference( type=StaticSiteSnapShoter, ), bidirectional=True, integral=True, related_end=schema.Reference(), min=1)) StaticSiteExtension.add_member( schema.Collection("destinations", items=schema.Reference( type=StaticSiteDestination, ), bidirectional=True, integral=True, related_end=schema.Reference(), min=1)) # Disable interactive features from rendered pages when rendering # static content from woost.controllers.cmscontroller import CMSController @when(CMSController.producing_output) def disable_user_controls(event): if context.get("exporting_static_site", False): event.output["show_user_controls"] = False
class CampaignMonitorList(Item): visible_from_root = False members_order = [ "list_id", "pending_page", "confirmation_success_page", "unsubscribe_page", ] default_pending_page = schema.DynamicDefault( lambda: StandardPage.get_instance( qname = u"woost.extensions.campaignmonitor.pending_page" ) ) title = schema.String( editable = False, listed_by_default = False, descriptive = True ) list_id = schema.String( unique = True, editable = False, text_search = False ) unsubscribe_page = schema.Reference( type = "woost.models.Publishable", related_end = schema.Collection() ) pending_page = schema.Reference( required = True, type = "woost.models.Publishable", related_end = schema.Collection() ) confirmation_success_page = schema.Reference( type = "woost.models.Publishable", related_end = schema.Collection() )
def _load(self): from woost.controllers.notifications import notify_user from woost.controllers.backoffice.basebackofficecontroller import \ BaseBackOfficeController from woost.controllers.backoffice.itemcontroller import \ ItemController from woost.extensions.mailer import ( sendemailaction, createmailingaction, strings ) from woost.extensions.mailer.mailing import Mailing, \ RunningMailingError from woost.extensions.mailer.sendemailcontroller import \ SendEmailController ItemController.send_email = SendEmailController Template.add_member( schema.Boolean( "per_user_customizable", default = False, listed_by_default = False ) ) Template.members_order.append("per_user_customizable") User.add_member( schema.Collection( "mailingLists", items = "woost.extensions.mailer.mailinglist.MailingList", bidirectional = True, listed_by_default = False ) ) @when(BaseBackOfficeController.exception_raised) def handle_exception_raised(event): if isinstance( event.exception, RunningMailingError ): notify_user(translations(event.exception), "error") raise cherrypy.HTTPRedirect(event.source.contextual_uri()) # Disable interactive features from rendered pages when rendering # static content from woost.controllers.cmscontroller import CMSController @when(CMSController.producing_output) def disable_user_controls(event): if context.get("sending_email", False): event.output["show_user_controls"] = False
class SendEmailPermission(Permission): """Permission to send an email.""" instantiable = True lists = schema.Collection(items=schema.Reference(type=MailingList, ), related_end=schema.Collection(), edit_control="cocktail.html.CheckList") def match(self, mailingList=None, verbose=False): if mailingList and self.lists and mailingList not in self.lists: if verbose: print permission_doesnt_match_style( "Mailing list doesn't match") return False return Permission.match(self, verbose)