def add_subscriber(self, context, fields): request = self.request alsoProvides(request, IDisableCSRFProtection) form = EasyFormForm(context, request) form.updateFields() form.updateWidgets() data, errors = form.extractData() period_id = data.get("period") if isinstance(period_id, list): period_id = period_id[0] period = context.aq_parent.get(period_id) title = "{0} {1}".format(data.get("last_name"), data.get("first_name")) subscriber = api.content.create( container=period, type="subscriber", title=title ) self.add_subscriber_in_period(context, period, subscriber, form, data) if not IPloneAppMultilingualInstalled.providedBy(request): return registry = getUtility(IRegistry) langs = list(registry['plone.available_languages']) current_lang = api.portal.get_current_language()[:2] langs.remove(current_lang) for lang in langs: trans = ITranslationManager(period).get_translation(lang) if trans: new_subscriber = api_lng.translate(subscriber, lang) new_subscriber.title = title self.add_subscriber_in_period(context, trans, new_subscriber, form, data)
def available(self): if not IPloneAppMultilingualInstalled.providedBy(self.request): return False lt = getToolByName(self.context, 'portal_languages', None) if lt is None: return False supported = lt.listSupportedLanguages() if len(supported) < 2: return False return True
def available(self): if not IPloneAppMultilingualInstalled.providedBy(self.request): return False lt = getToolByName(self.context, 'portal_languages', None) if lt is None: return False supported = lt.listSupportedLanguages() if len(supported) < 2: return False return True
def createdEvent(obj, event): """ Subscriber to set language on the child folder It can be a - IObjectRemovedEvent - don't do anything - IObjectMovedEvent - IObjectAddedEvent - IObjectCopiedEvent """ if IObjectRemovedEvent.providedBy(event): return request = getattr(event.object, 'REQUEST', getRequest()) if not IPloneAppMultilingualInstalled.providedBy(request): return # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is # always equal to event.newParent. parent = aq_parent(event.object) # special parent handling if not ITranslatable.providedBy(parent): set_recursive_language(obj, LANGUAGE_INDEPENDENT) return # Normal use case # We set the tg, linking language = ILanguage(parent).get_language() set_recursive_language(obj, language) request = getattr(event.object, 'REQUEST', getRequest()) try: ti = request.translation_info except AttributeError: return # AT check portal = getSite() portal_factory = getToolByName(portal, 'portal_factory', None) if ( not IDexterityContent.providedBy(obj) and portal_factory is not None and not portal_factory.isTemporary(obj) ): return IMutableTG(obj).set(ti['tg']) modified(obj) tm = ITranslationManager(obj) old_obj = tm.get_translation(ti['source_language']) ILanguageIndependentFieldsManager(old_obj).copy_fields(obj)
def createdEvent(obj, event): """ Subscriber to set language on the child folder It can be a - IObjectRemovedEvent - don't do anything - IObjectMovedEvent - IObjectAddedEvent - IObjectCopiedEvent """ if IObjectRemovedEvent.providedBy(event): return request = getattr(event.object, 'REQUEST', getRequest()) if not IPloneAppMultilingualInstalled.providedBy(request): return # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is # always equal to event.newParent. parent = aq_parent(event.object) # special parent handling if not ITranslatable.providedBy(parent): set_recursive_language(obj, LANGUAGE_INDEPENDENT) return # Normal use case # We set the tg, linking language = ILanguage(parent).get_language() set_recursive_language(obj, language) request = getattr(event.object, 'REQUEST', getRequest()) try: ti = request.translation_info except AttributeError: return # AT check portal = getSite() portal_factory = getToolByName(portal, 'portal_factory', None) if (not IDexterityContent.providedBy(obj) and portal_factory is not None and not portal_factory.isTemporary(obj)): return IMutableTG(obj).set(ti['tg']) modified(obj) tm = ITranslationManager(obj) old_obj = tm.get_translation(ti['source_language']) ILanguageIndependentFieldsManager(old_obj).copy_fields(obj)
def link_translations(request, registration): if not IPloneAppMultilingualInstalled.providedBy(request): return if not IRegistration.providedBy(registration): return if not ITranslatable.providedBy(registration): return registry = getUtility(IRegistry) langs = list(registry["plone.available_languages"]) current_lang = api.portal.get_current_language()[:2] langs.remove(current_lang) types = ["EasyForm", "Event"] for lang in langs: trans_registration = ITranslationManager(registration).get_translation( lang) if not trans_registration: continue for portal_type in types: brains = api.content.find(context=registration, portal_type=portal_type) if len(brains) != 1: continue obj = brains[0].getObject() if not ITranslatable.providedBy(obj): continue trans = ITranslationManager(obj).get_translation(lang) if trans: continue trans_brains = api.content.find( context=trans_registration, portal_type=portal_type, ) if len(trans_brains) != 1: continue trans_obj = trans_brains[0].getObject() ITranslationManager(obj).register_translation(lang, trans_obj) ILanguage(trans_obj).set_language(lang)
def available(self): # Is PAM installed? if not IPloneAppMultilingualInstalled.providedBy(self.request): return False # Do we have portal_languages? lt = getToolByName(self.context, 'portal_languages', None) if lt is None: return False # Do we have multiple languages? supported = lt.listSupportedLanguages() if len(supported) < 2: return False # And now check permissions sm = getSecurityManager() if not sm.checkPermission(ManageTranslations, self.context): return False return True
def available(self): # Is PAM installed? if not IPloneAppMultilingualInstalled.providedBy(self.request): return False # Do we have portal_languages? lt = getToolByName(self.context, 'portal_languages', None) if lt is None: return False # Do we have multiple languages? supported = lt.listSupportedLanguages() if len(supported) < 2: return False # And now check permissions sm = getSecurityManager() if not sm.checkPermission(ManageTranslations, self.context): return False return True
def __call__(self, content, event): """Called by the event system.""" request = getattr(event.object, 'REQUEST', getRequest()) if not IPloneAppMultilingualInstalled.providedBy(request): return translation_info = getattr(request, 'translation_info', {}) if 'tg' in translation_info.keys(): # In case it's a on the fly translation avoid return if IDexterityTranslatable.providedBy(content): self.canonical = ITranslationManager(content).query_canonical() if event.descriptions \ and len(event.descriptions) > 1 \ and event.descriptions[1] == self.canonical: return if IObjectModifiedEvent.providedBy(event): self.handle_modified(content)
def __call__(self, content, event): """Called by the event system.""" request = getattr(event.object, 'REQUEST', getRequest()) if not IPloneAppMultilingualInstalled.providedBy(request): return translation_info = getattr(request, 'translation_info', {}) if 'tg' in translation_info.keys(): # In case it's a on the fly translation avoid return if IDexterityTranslatable.providedBy(content): self.canonical = ITranslationManager(content).query_canonical() if event.descriptions \ and len(event.descriptions) > 1 \ and event.descriptions[1] == self.canonical: return if IObjectModifiedEvent.providedBy(event): self.handle_modified(content)
def is_plone_app_multilingual_installed(request): return IPloneAppMultilingualInstalled.providedBy(request)
def do_reply(self): """This is the reply method from plone.restapi, overrided to manage returning the fullobject after creation or the summary.""" # imio.restapi, nothing changed until next comment "imio.restapi ..." comment data = json_body(self.request) type_ = data.get("@type", None) id_ = data.get("id", None) title = data.get("title", None) translation_of = data.get("translation_of", None) language = data.get("language", None) if not type_: raise BadRequest("Property '@type' is required") # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) try: obj = create(self.context, type_, id_=id_, title=title) except Unauthorized as exc: self.request.response.setStatus(403) return dict(error=dict(type="Forbidden", message=str(exc))) except BadRequest as exc: self.request.response.setStatus(400) return dict(error=dict(type="Bad Request", message=str(exc))) # Acquisition wrap temporarily to satisfy things like vocabularies # depending on tools temporarily_wrapped = False if IAcquirer.providedBy(obj) and not safe_hasattr(obj, "aq_base"): obj = obj.__of__(self.context) temporarily_wrapped = True # Update fields deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: self.request.response.setStatus(501) return dict( error=dict(message="Cannot deserialize type {}".format(obj.portal_type)) ) try: deserializer(validate_all=True, create=True) except DeserializationError as e: self.request.response.setStatus(400) return dict(error=dict(type="DeserializationError", message=str(e))) if temporarily_wrapped: obj = aq_base(obj) if not getattr(deserializer, "notifies_create", False): notify(ObjectCreatedEvent(obj)) obj = add(self.context, obj, rename=not bool(id_)) # Link translation given the translation_of property if PAM_INSTALLED and PLONE5: from plone.app.multilingual.interfaces import ( IPloneAppMultilingualInstalled, ) # noqa from plone.app.multilingual.interfaces import ITranslationManager if ( IPloneAppMultilingualInstalled.providedBy(self.request) and translation_of and language ): source = self.get_object(translation_of) if source: manager = ITranslationManager(source) manager.register_translation(language, obj) self.request.response.setStatus(201) self.request.response.setHeader("Location", obj.absolute_url()) # imio.restapi, begin changes, manage returning full object or summary return_full_object = data.get( "return_fullobject", get_return_fullobject_after_creation_default()) if return_full_object: serializer = queryMultiAdapter((obj, self.request), ISerializeToJson) else: serializer = queryMultiAdapter((obj, self.request), ISerializeToJsonSummary) serialized_obj = serializer() # imio.restapi, end changes, manage returning full object or summary # HypermediaBatch can't determine the correct canonical URL for # objects that have just been created via POST - so we make sure # to set it here serialized_obj["@id"] = obj.absolute_url() return serialized_obj
def is_plone_app_multilingual_installed(request): return IPloneAppMultilingualInstalled.providedBy(request)
def import_item(self, dirpath, *filenames): __traceback_info__ = dirpath logger.info("Importing item at %s", dirpath) all_info = {} blobs = {} for name in filenames: filepath = os.path.join(dirpath, name) key, ext = os.path.splitext(name) if ext != ".json": logger.info("Found non json file, will use as blob, at %s", filepath) blobs[key] = filepath continue logger.info("Reading %s", filepath) with open(filepath) as myfile: content = json.loads(myfile.read()) all_info[key] = content # Get meta info. We might also get some of this from default.json. # Maybe we need less in meta. meta = all_info["meta"] # if "front-page" in meta.get("path", ""): # import pdb; pdb.set_trace() # See if the object already exists. obj = self.get_object(**meta) if obj is None: # We need to get some parent, either from default["parent"] or meta. path = meta["path"] parent_path = path.rpartition("/")[0] parent_obj = self.get_object(path=parent_path) if parent_obj is None: logger.warning( "Parent object not found, cannot create content for %s", path) return default = all_info["default"] # Code taken from plone.restapi add.py FolderPost.reply. # It would be nice if we could call that method directly, but it does too much. # We would need to split it a bit, especially: # don't get json from the request body, and don't change the response. type_ = default.get("@type", None) id_ = default.get("id", None) title = default.get("title", None) translation_of = default.get("translation_of", None) language = default.get("language", None) # except Unauthorized / BadRequest obj = create(parent_obj, type_, id_=id_, title=title) # Acquisition wrap temporarily to satisfy things like vocabularies # depending on tools temporarily_wrapped = False if IAcquirer.providedBy(obj) and not safe_hasattr(obj, "aq_base"): obj = obj.__of__(self.context) temporarily_wrapped = True deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: logger.error("Cannot deserialize type %s", obj.portal_type) return if blobs: for fieldname, path in blobs.items(): if fieldname in default: with open(path, "rb") as myfile: default[fieldname]["data"] = myfile.read() # except DeserializationError as e: deserializer(validate_all=True, data=default, create=True) if temporarily_wrapped: obj = aq_base(obj) if not getattr(deserializer, "notifies_create", False): notify(ObjectCreatedEvent(obj)) obj = add(parent_obj, obj, rename=not bool(id_)) obj_path = "/".join(obj.getPhysicalPath()) logger.info("Created %s at %s", type_, obj_path) # Link translation given the translation_of property if PAM_INSTALLED: # Note: untested. from plone.app.multilingual.interfaces import ( IPloneAppMultilingualInstalled, ) # noqa from plone.app.multilingual.interfaces import ITranslationManager if (IPloneAppMultilingualInstalled.providedBy(self.request) and translation_of and language): source = self.get_object(translation_of) if source: manager = ITranslationManager(source) manager.register_translation(language, obj) # TODO: call other, named deserializers, but they do not work currently anyway. else: obj_path = "/".join(obj.getPhysicalPath()) if is_locked(obj, self.request): # TODO: We could throw an error, but we should probably just unlock. logger.warning("Content is locked: %s", obj_path) logger.info("Updating existing content at %s", obj_path) deserializers = getAdapters((obj, self.request), IDeserializeFromJson) if not deserializers: logger.error("Cannot deserialize type %s", obj.portal_type) return for name, deserializer in deserializers: if not name: name = "default" # XXX This traceback info overrides the previous. # When done in a separate method, it should be fine. # __traceback_info__ = name __traceback_info__ = dirpath, name content = all_info[name] if name == "local_roles": # TODO Fix this in plone.restapi. logger.info( "Ignoring local_roles deserializer for now, as it does not accept a content parameter." ) continue if name == "default" and blobs: for fieldname, path in blobs.items(): if fieldname in content: with open(path, "rb") as myfile: content[fieldname]["data"] = myfile.read() try: deserializer(data=content) except TypeError: # Happens for site root. But I want to fix it there too, if that is acceptable. logger.info( "TypeError, likely because deserializer does not accept data keyword argument: %s", deserializer) # TODO: maybe try / except DeserializationError # Report back that we made an import. return True
def reply(self): data = json_body(self.request) type_ = data.get("@type", None) id_ = data.get("id", None) title = data.get("title", None) translation_of = data.get("translation_of", None) language = data.get("language", None) uid = data.get("UID", None) if not type_: raise BadRequest("Property '@type' is required") # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) sm = getSecurityManager() # ManagePortal is required to set the uid of an object during creation if uid and not sm.checkPermission(ManagePortal, self.context): self.request.response.setStatus(403) msg = "Setting UID of an object requires Manage Portal permission" return dict(error=dict(type="Forbidden", message=msg)) try: obj = create(self.context, type_, id_=id_, title=title) except Unauthorized as exc: self.request.response.setStatus(403) return dict(error=dict(type="Forbidden", message=str(exc))) except BadRequest as exc: self.request.response.setStatus(400) return dict(error=dict(type="Bad Request", message=str(exc))) # Acquisition wrap temporarily to satisfy things like vocabularies # depending on tools temporarily_wrapped = False if IAcquirer.providedBy(obj) and not safe_hasattr(obj, "aq_base"): obj = obj.__of__(self.context) temporarily_wrapped = True # Update fields deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: self.request.response.setStatus(501) return dict(error=dict( message=f"Cannot deserialize type {obj.portal_type}")) try: deserializer(validate_all=True, create=True) except DeserializationError as e: self.request.response.setStatus(400) return dict( error=dict(type="DeserializationError", message=str(e))) if temporarily_wrapped: obj = aq_base(obj) if uid: setattr(obj, "_plone.uuid", uid) if not getattr(deserializer, "notifies_create", False): notify(ObjectCreatedEvent(obj)) obj = add(self.context, obj, rename=not bool(id_)) # Link translation given the translation_of property if (IPloneAppMultilingualInstalled.providedBy(self.request) and translation_of and language): source = self.get_object(translation_of) if source: manager = ITranslationManager(source) manager.register_translation(language, obj) self.request.response.setStatus(201) self.request.response.setHeader("Location", obj.absolute_url()) serializer = queryMultiAdapter((obj, self.request), ISerializeToJson) serialized_obj = serializer() # HypermediaBatch can't determine the correct canonical URL for # objects that have just been created via POST - so we make sure # to set it here serialized_obj["@id"] = obj.absolute_url() return serialized_obj