def get_userinfo(self, ob): """ returns a list of objects based on the ob type""" site = self.getSite() cat = site.getCatalogTool() user = self.REQUEST.AUTHENTICATED_USER.getId() filters = {"contributor": user} if ob == "events": filters["meta_type"] = "Naaya Event" ob_list = cat.search(filters) elif ob == "news": filters["meta_type"] = "Naaya News" ob_list = cat.search(filters) elif ob == "topics": ob_list = cat.search({"path": ofs_path(site.topics), "contributor": user}) elif ob == "resources": ob_list = cat.search({"path": ofs_path(site.resources), "contributor": user}) elif ob == "forums": forum_meta_types = ["Naaya Forum Topic", "Naaya Forum Message"] ob_list = cat.search({"meta_type": forum_meta_types, "contributor": user}) elif ob == "contacts": ob_list = cat.search({"meta_type": "Naaya Contact", "contributor": user}) sorted_list = site.utSortObjsListByAttr(ob_list, "releasedate") userinfo = [ [item.title, item.absolute_url, item.releasedate.strftime("%d %b '%y")] for item in sorted_list[:50] ] return json.dumps(userinfo)
def get_linked_pointer_brains(obj): """ Tests if object had met condition to be synced with pointers and returns brains to existing ones. Used by handlers to keep them in sync. """ site = obj.getSite() q_both = _qualifies_for_both(obj) q_topics = _qualifies_for_topics_only(obj) pointers = [] if q_topics or q_both: cat = site.getCatalogTool() pointers = cat.search({ 'meta_type': 'Naaya Pointer', 'path': [ ofs_path(site.countries), ofs_path(site.topics), ofs_path(getattr(site, 'resources')), # kept for pointers prior to v 1.1 ofs_path(getattr(site, 'who-who')) ], 'pointer': path_in_site(obj) }) return pointers
def _update(self, portal): context = portal.restrictedTraverse('who-who/destinet-users') cat = portal['portal_catalog'] acl_users = portal['acl_users'] users = acl_users.getUsers() auth_tool = portal.getAuthenticationTool() #manager = self.request.AUTHENTICATED_USER.getUserName() # first, cleanup wrongly created users wrong = [o for o in context.objectValues() if o._owner[1] == 'tibiadmin'] self.log.info("Deleting %s wrong contacts" % len(wrong)) for obj in wrong: cat.uncatalog_object(ofs_path(obj)) context.manage_delObjects([o.id for o in wrong]) self.log.info("Migration: start migration of contacts for old users") EmailTool.divert_mail() counter = 0 for user in users: fullname = auth_tool.getUserFullNameByID(user.name) contacts = cat.searchResults(path=ofs_path(context), contributor=user.name) if not contacts: counter += 1 id = uniqueId( slugify(user.name or 'contact', removelist=[]), lambda x: context._getOb(x, None) is not None) ob = _create_NyContact_object(context, id, user.name) ob.approveThis(1, user.name) # 1, manager ob.submitThis() ob.set_localpropvalue('title', 'en', fullname) ob.set_localpropvalue('description', 'en', "") #ob.release_date = DateTime() new_user = user.__of__(acl_users) ob.changeOwnership(user=new_user) ob.giveEditRights() context.recatalogNyObject(ob) #crashes with unicodedecodeerror: #notify(NyContentObjectAddEvent(ob, user.name, {})) #log post date auth_tool.changeLastPost(user.name) self.log.info("Migration: %s - added contact for user: %s", counter, id) EmailTool.divert_mail(False) self.log.info("Migration: end migration") return True
def handle_edit_content(event): """ Test whether this requires adding pointers and perform the action """ obj = event.context site = obj.getSite() if not getattr(site, 'destinet.publisher', False): return None q_both = _qualifies_for_both(obj) q_topics = _qualifies_for_topics_only(obj) if q_topics or q_both: # clean-up all existing pointers, then re-add them cat = site.getCatalogTool() pointers = cat.search({'meta_type': 'Naaya Pointer', 'path': [ofs_path(site.countries), ofs_path(site.topics), ofs_path(getattr(site, 'resources')), # kept for pointers prior to v 1.1 ofs_path(getattr(site, 'who-who'))], 'pointer': path_in_site(obj)}) for brain in pointers: pointer = brain.getObject() pointer.aq_parent._delObject(pointer.id) if q_both: place_pointers(obj) else: place_pointers(obj, exclude=['target-groups'])
def handle_del_content(obj, event): """ Test whether this required adding pointers and perform the cleanup of pointers. """ site = obj.getSite() if not getattr(site, 'destinet.publisher', False): return None q_both = _qualifies_for_both(obj) q_topics = _qualifies_for_topics_only(obj) if q_topics or q_both: # clean-up all existing pointers cat = site.getCatalogTool() pointers = cat.search({ 'meta_type': 'Naaya Pointer', 'path': [ ofs_path(site.countries), ofs_path(site.topics), ofs_path(getattr(site, 'resources')), # kept for pointers prior to v 1.1 ofs_path(getattr(site, 'who-who')) ], 'pointer': path_in_site(obj) }) for brain in pointers: pointer = brain.getObject() pointer.aq_parent._delObject(pointer.id)
def get_userinfo(self, ob): """ returns a list of objects based on the ob type""" site = self.getSite() cat = site.getCatalogTool() user = self.REQUEST.AUTHENTICATED_USER.getId() filters = {'contributor': user} if ob == 'events': filters['meta_type'] = 'Naaya Event' ob_list = cat.search(filters) elif ob == 'news': filters['meta_type'] = 'Naaya News' ob_list = cat.search(filters) elif ob == 'topics': ob_list = cat.search({'path': ofs_path(site.topics), 'contributor': user}) elif ob == 'resources': ob_list = cat.search({'path': ofs_path(site.resources), 'contributor': user}) elif ob == 'forums': forum_meta_types = ['Naaya Forum Topic', 'Naaya Forum Message'] ob_list = cat.search({'meta_type': forum_meta_types, 'contributor': user}) elif ob == 'contacts': ob_list = cat.search({'meta_type': 'Naaya Contact', 'contributor': user}) sorted_list = site.utSortObjsListByAttr(ob_list, 'releasedate') userinfo = [[item.title, item.absolute_url, item.releasedate.strftime('%d %b \'%y')] for item in sorted_list[:50]] return json.dumps(userinfo)
def _send_newsletter(self, notif_type, when_start, when_end): """ We'll look in the ``Products.Naaya.NySite.getActionLogger`` for object creation/modification log entries. Then we'll send notifications for the period between `when_start` and `when_end` using the `notif_type` template. """ notif_logger.info( 'Notifications newsletter on site %r, type %r, ' 'from %s to %s', ofs_path(self.getSite()), notif_type, when_start, when_end) objects_by_email = {} langs_by_email = {} subscriptions_by_email = {} anonymous_users = {} for log_type, ob in utils.get_modified_objects(self.getSite(), when_start, when_end): notif_logger.info('.. modified object: %r', ofs_path(ob)) for subscription in utils.fetch_subscriptions(ob, inherit=True): if subscription.notif_type != notif_type: continue if not subscription.check_permission(ob): continue email = subscription.get_email(ob) if email is None: continue content_types = getattr(subscription, 'content_types', []) if content_types and ob.meta_type not in content_types: continue notif_logger.info('.. .. sending newsletter to %r', email) objects_by_email.setdefault(email, []).append({ 'ob': ob, 'type': log_type, }) langs_by_email[email] = subscription.lang subscriptions_by_email[email] = subscription anonymous_users[email] = isinstance(subscription, AnonymousSubscription) messages_by_email = {} for email in objects_by_email: messages_by_email[email] = { 'objs': objects_by_email[email], '_lang': langs_by_email[email], 'subscription': subscriptions_by_email[email], 'here': self, 'anonymous': anonymous_users[email] } template = self._get_template(notif_type) self._send_notifications(messages_by_email, template)
def _send_newsletter(self, notif_type, when_start, when_end): """ We'll look in the ``Products.Naaya.NySite.getActionLogger`` for object creation/modification log entries. Then we'll send notifications for the period between `when_start` and `when_end` using the `notif_type` template. """ notif_logger.info('Notifications newsletter on site %r, type %r, ' 'from %s to %s', ofs_path(self.getSite()), notif_type, when_start, when_end) objects_by_email = {} langs_by_email = {} subscriptions_by_email = {} anonymous_users = {} for log_type, ob in utils.get_modified_objects(self.getSite(), when_start, when_end): notif_logger.info('.. modified object: %r', ofs_path(ob)) for subscription in utils.fetch_subscriptions(ob, inherit=True): if subscription.notif_type != notif_type: continue if not subscription.check_permission(ob): continue email = subscription.get_email(ob) if email is None: continue content_types = getattr(subscription, 'content_types', []) if content_types and ob.meta_type not in content_types: continue notif_logger.info('.. .. sending newsletter to %r', email) objects_by_email.setdefault(email, []).append({ 'ob': ob, 'type': log_type, }) langs_by_email[email] = subscription.lang subscriptions_by_email[email] = subscription anonymous_users[email] = isinstance(subscription, AnonymousSubscription) messages_by_email = {} for email in objects_by_email: messages_by_email[email] = { 'objs': objects_by_email[email], '_lang': langs_by_email[email], 'subscription': subscriptions_by_email[email], 'here': self, 'anonymous': anonymous_users[email] } template = self._get_template(notif_type) self._send_notifications(messages_by_email, template)
def test_add_entry(self): glossary = helpers.make_glossary(self.portal) bucket = helpers.add_folder(glossary, '1', "Bucket") bucket.manage_addGlossaryElement('2', "Water") water = bucket['2'] self.assertEqual(search(glossary, path=ofs_path(water)), [water]) self.assertEqual(search(glossary, English="Water"), [water])
def test_thread(self): from time import sleep from threading import Semaphore from naaya.core.zope2util import ofs_path, launch_job import transaction job_done = Semaphore(0) def threaded_job(context): context.hello = "world" transaction.commit() job_done.release() folder = self.portal['info'] launch_job(threaded_job, folder, ofs_path(folder)) transaction.commit() for c in range(100): if job_done.acquire(blocking=False): break sleep(0.1) else: self.fail("Waited 10 seconds and the job did not finish yet") transaction.abort() self.assertEqual(folder.hello, "world")
def generate_news(obj_list): news = [] for obj in obj_list: if obj.istranslated(lang): #Description tag if mesg_type == 'html': desc_elem = E.description(sanitize_xml_data( obj.getLocalProperty('description', lang)) ) else: desc_elem = E.description(sanitize_xml_data( self.utStripAllHtmlTags( obj.getLocalProperty('description', lang) ) )) #News tag try: news.append(E.news(desc_elem, { 'title': sanitize_xml_data( obj.getLocalProperty('title', lang)), 'source': sanitize_xml_data( obj.getLocalProperty('source', lang)), 'source_link': sanitize_xml_data(obj.source_link), 'file_link': sanitize_xml_data(obj.file_link), 'url': sanitize_xml_data(obj.absolute_url(0)), 'lang': sanitize_xml_data(lang), 'isrtl': sanitize_xml_data( str(self.is_arabic(lang))), })) except: logger.exception("Failed to add %r to xml", ofs_path(obj)) raise return tuple(news)
def get_countries(ob): """ Extracts coverage from ob, iterates countries and returns nyfolders of them in `countries` location (creates them if missing) """ ret = [] site = ob.getSite() cat = site.getCatalogTool() filters = { 'title': '', 'path': ofs_path(site.countries), 'meta_type': 'Naaya Folder' } coverage = list(set(getattr(ob, 'coverage', u'').strip(',').split(','))) for country_item in coverage: country = country_item.strip() if country: country_folders = [] filters['title'] = country bz = cat.search(filters) for brain in bz: if brain.title.strip().lower() == country.lower(): country_folders.append(brain.getObject()) ret.extend(country_folders) if not country_folders: logger.info("Country '%s' not found in destinet countries", country) return ret
def allowed(context, permission=None): """ Roles that have `permission` and why. Returns {PERM_NAME: {'Role': (REASON, META), ..}, ..} where `REASON` in ('assigned', 'inherited'). `META` can be None or dict supplying extra info, like `source` of permission inheritance. """ out = {} all_roles = context.valid_roles() permissions = context.ac_inherited_permissions(1) if permission: permissions = [x for x in permissions if x[0] == permission] for perm in permissions: name, value = perm[:2] maps = out[name] = {} perm = Permission(name, value, context) roles = perm.getRoles(default=[]) for role in roles: maps[role] = ('assigned', None) if isinstance(roles, list): from_parent = allowed(context.aq_parent, name) for role in set(all_roles) - set(roles): parent_permission = from_parent[name].get(role) if parent_permission: reason, meta = parent_permission if reason == 'assigned': maps[role] = ('inherited', {'source': ofs_path(context.aq_parent)}) elif reason == 'inherited': maps[role] = parent_permission return out
def userinfo(self): """ Renders a view with everything the member posted """ site = self.getSite() auth_tool = site.getAuthenticationTool() user = self.REQUEST.AUTHENTICATED_USER.getId() cat = site.getCatalogTool() user_obj = auth_tool.getUser(user) contact_obj = None if user_obj: user_info = { 'first_name': user_obj.firstname, 'last_name': user_obj.lastname, 'email': user_obj.email } # --- since destinet.registration: --- # container = site['who-who']['destinet-users'] candidate_brains = cat.search({ 'path': ofs_path(container), 'contributor': user }) for candidate_br in candidate_brains: try: candidate = candidate_br.getObject() except Exception, e: continue else: owner_tuple = candidate.getOwnerTuple() if owner_tuple and owner_tuple[1] == user: contact_obj = candidate break
def _processExtFile(self, mid, ctype): """ Apply media converters to self subobject with given id (mid) which is stored outside Data.fs, with original content-type ctype. """ from OFS.ObjectManager import ObjectManager media = ObjectManager._getOb(self, mid) launch_job(media2flv, self.aq_parent, ofs_path(media))
def notify_maintainer(self, ob, folder, **kwargs): """ Process and notify by email that B{p_object} has been uploaded into the B{p_folder}. """ auth_tool = self.getSite().getAuthenticationTool() emails = self.getMaintainersEmails(ob) person = self.REQUEST.AUTHENTICATED_USER.getUserName() if len(emails) > 0: maintainers_data = {} for email in emails: maintainers_data[email] = { 'ob': ob, 'here': self, 'person': auth_tool.name_from_userid(person), 'ob_edited': kwargs.get('ob_edited'), 'approved': ob.approved, 'container_basket': '%s/basketofapprovals_html' % folder.absolute_url(), } notif_logger.info('Maintainer notifications on %r', ofs_path(ob)) template = self._get_template('maintainer') self._send_notifications(maintainers_data, template)
def allowed(context, permission=None): """ Roles that have `permission` and why. Returns {PERM_NAME: {'Role': (REASON, META), ..}, ..} where `REASON` in ('assigned', 'inherited'). `META` can be None or dict supplying extra info, like `source` of permission inheritance. """ out = {} all_roles = context.valid_roles() permissions = context.ac_inherited_permissions(1) if permission: permissions = [x for x in permissions if x[0] == permission] for perm in permissions: name, value = perm[:2] maps = out[name] = {} perm = Permission(name, value, context) roles = perm.getRoles(default=[]) for role in roles: maps[role] = ('assigned', None) if isinstance(roles, list): for role in set(all_roles) - set(roles): from_parent = allowed(context.aq_parent, name) parent_permission = from_parent[name].get(role) if parent_permission: reason, meta = parent_permission if reason == 'assigned': maps[role] = ('inherited', {'source': ofs_path(context.aq_parent)}) elif reason == 'inherited': maps[role] = parent_permission return out
def notify_comment_instant(self, comment, parent, user_id): """ send instant notifications because a comment was added to object `ob` by the user `user_id` """ if not self.config['enable_instant']: return # Don't send notifications if the object is unapproved, but store them # into a queue to send them later when it becomes approved if not parent.approved: return auth_tool = self.getSite().getAuthenticationTool() subscribers_data = utils.get_subscribers_data(self, parent, **{ 'comment': comment, 'parent': parent, 'person': auth_tool.name_from_userid(user_id), }) if len(subscribers_data.keys()) > 0: notif_logger.info('Comment instant notifications on %r', ofs_path(parent)) template = self._get_template('instant') self._send_notifications(subscribers_data, template)
def xliff_header(self, folders, language): """ return the xliff header """ results = [] r_append = results.append #alias for append function. For optimization purposes # Generate the XLIFF file header if folders == '/': folders='all' else: folders = string.split(folders, '/')[-1] r_append('<?xml version="1.0" encoding="UTF-8"?>') r_append('<!DOCTYPE xliff SYSTEM "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd">') r_append(u'<!-- XLIFF Format Copyright \xa9 OASIS Open 2001-2003 -->') r_append('<xliff version="1.0">') r_append('<file') r_append(' original="%s"' % ofs_path(self)) r_append(' product-name="NaayaGlossary"') r_append(' product-version="1.1.x"') r_append(' datatype="plaintext"') r_append(' source-language="English"') r_append(' target-language="%s"' % language) r_append(' date="%s"' % DateTime().HTML4()) r_append('>') r_append('<body>') return results
def latest_visible_uploads(self, meta_type=None): """ Generator that yields latest uploaded object viewable by user. """ filters = {'submitted': 1, 'approved': 1, 'sort_on': 'releasedate', 'sort_order': 'reverse'} if meta_type: filters['meta_type'] = self.utConvertToList(meta_type) else: filters['meta_type'] = self.searchable_content check_perm = getSecurityManager().checkPermission # Performance trick: First filter top level objects where user # has access and only search by those paths paths = [] top_level = self.getSite().objectValues(self.searchable_content) paths = [ofs_path(ob) for ob in top_level if check_perm(view, ob)] if not paths: return else: filters['path'] = paths all_brains = self.__searchCatalog(filters) for brain in all_brains: try: obj = brain.getObject() except Exception: continue else: if check_perm(view, obj): yield obj
def notify_comment_maintainer(self, comment, parent, **kwargs): """ Process and notify by email that a comment B{comemnt} has been added to the object B{parent}. """ auth_tool = self.getSite().getAuthenticationTool() emails = self.getMaintainersEmails(parent) if len(emails) > 0: maintainers_data = {} for email in emails: maintainers_data[email] = { 'parent': parent, 'here': self, 'comment': comment, 'person': auth_tool.name_from_userid(comment.author), 'container_basket': '%s/basketofapprovals_html' % parent.absolute_url(), } notif_logger.info('Maintainer comment notifications on %r', ofs_path(parent)) template = self._get_template('maintainer') self._send_notifications(maintainers_data, template)
def get_countries(ob): """ Extracts coverage from ob, iterates countries and returns nyfolders of them in `countries` location (creates them if missing) """ ret = [] site = ob.getSite() cat = site.getCatalogTool() filters = {'title': '', 'path': ofs_path(site.countries), 'meta_type': 'Naaya Folder'} coverage = list(set(getattr(ob, 'coverage', u'').strip(',').split(','))) for country_item in coverage: country = country_item.strip() if country: country_folders = [] filters['title'] = country bz = cat.search(filters) for brain in bz: if brain.title.strip().lower() == country.lower(): country_folders.append(brain.getObject()) ret.extend(country_folders) if not country_folders: logger.info("Country '%s' not found in destinet countries", country) return ret
def notify_administrative(self, ob, user_id, ob_edited=False): """ send administrative notifications because object `ob` was added or edited by the user `user_id` """ auth_tool = self.getSite().getAuthenticationTool() subscribers_data = utils.get_subscribers_data( self, ob, notif_type='administrative', **{ 'person': auth_tool.name_from_userid(user_id), 'ob_edited': ob_edited, 'approved': ob.approved, 'container_basket': '%s/basketofapprovals_html' % ob.aq_parent.absolute_url(), }) if len(subscribers_data.keys()) > 0: notif_logger.info('Administrative notifications on %r', ofs_path(ob)) template = self._get_template('administrative') self._send_notifications(subscribers_data, template)
def userinfo(self): """ Renders a view with everything the member posted """ site = self.getSite() auth_tool = site.getAuthenticationTool() user = self.REQUEST.AUTHENTICATED_USER.getId() cat = site.getCatalogTool() user_obj = auth_tool.getUser(user) contact_obj = None if user_obj: user_info = {'first_name': user_obj.firstname, 'last_name': user_obj.lastname, 'email': user_obj.email} # --- since destinet.registration: --- # container = site['who-who']['destinet-users'] candidate_brains = cat.search({'path': ofs_path(container), 'contributor': user}) for candidate_br in candidate_brains: try: candidate = candidate_br.getObject() except Exception, e: continue else: owner_tuple = candidate.getOwnerTuple() if owner_tuple and owner_tuple[1] == user: contact_obj = candidate break
def notify_comment_instant(self, comment, parent, user_id): """ send instant notifications because a comment was added to object `ob` by the user `user_id` """ if not self.config['enable_instant']: return # Don't send notifications if the object is unapproved, but store them # into a queue to send them later when it becomes approved if not parent.approved: return auth_tool = self.getSite().getAuthenticationTool() subscribers_data = utils.get_subscribers_data( self, parent, **{ 'comment': comment, 'parent': parent, 'person': auth_tool.name_from_userid(user_id), }) if len(subscribers_data.keys()) > 0: notif_logger.info('Comment instant notifications on %r', ofs_path(parent)) template = self._get_template('instant') self._send_notifications(subscribers_data, template)
def remove_item_from_glossary_catalog(item, event): try: catalog = item.getGlossaryCatalog() item_path = ofs_path(item) if catalog.getrid(item_path) is not None: catalog.uncatalog_object(item_path) except: log.exception("Failed to remove %r from glossary catalog", item)
def uncatalog_comments(obj): catalog = obj.getSite().getCatalogTool() container = obj._get_comments_container() if container is not None: for comment in container.objectValues(NyComment.meta_type): try: catalog.uncatalog_object(ofs_path(comment)) except: obj.getSite().log_current_error()
def handle_edit_content(event): """ Test whether this requires adding pointers and perform the action """ obj = event.context site = obj.getSite() if not getattr(site, 'destinet.publisher', False): return None q_both = _qualifies_for_both(obj) q_topics = _qualifies_for_topics_only(obj) if q_topics or q_both: # clean-up all existing pointers, then re-add them cat = site.getCatalogTool() pointers = cat.search({ 'meta_type': 'Naaya Pointer', 'path': [ ofs_path(site.countries), ofs_path(site.topics), ofs_path(getattr(site, 'resources')), # kept for pointers prior to v 1.1 ofs_path(getattr(site, 'who-who')) ], 'pointer': path_in_site(obj) }) for brain in pointers: pointer = brain.getObject() pointer.aq_parent._delObject(pointer.id) if q_both: place_pointers(obj) else: place_pointers(obj, exclude=['target-groups']) # Make sure that the Destinet User keyword is added #langs = obj.aq_parent.gl_get_languages() if (obj.meta_type == "Naaya Contact"): set_address(obj) obj.geo_type = _get_geo_type(obj) if (obj.aq_parent.getId() == "destinet-users"): alter_contact(obj) obj.aq_parent.recatalogNyObject(obj)
def recursive_tree(ob): icon_url = '/misc_/NaayaGlossary/%s.gif' % icons_map[ob.meta_type] kids = ob.objectValues([ NAAYAGLOSSARY_FOLDER_METATYPE, NAAYAGLOSSARY_ELEMENT_METATYPE ]) kids = sorted(kids, key=lambda ob: ob.getId()) children = [recursive_tree(kid) for kid in kids if kid.approved] translation_missing = '' if ob is glossary: translation = None title = ob.title_or_id() definition = ofs_path(ob) else: translation = ob.get_translation_by_language(language_name) if translation: title = translation else: translation = None title = ob.get_translation_by_language('English') if not title: title = ob.title_or_id() translation_missing = ( ' <span class="glossary-translation-missing">(' + language_name + ' translation missing)</span>') definition = ob.get_def_trans_by_language(language_name) insertable = (ob.meta_type != NAAYAGLOSSARY_FOLDER_METATYPE or glossary.parent_anchors) tree_item = { 'attributes': { 'title': definition, 'type': icons_map.get(ob.meta_type), }, 'data': { 'title': title + translation_missing, 'icon': icon_url, }, 'children': children, } if ob is glossary: tree_item['state'] = 'open' else: tree_item['attributes']['glossary-translation'] = (translation or title) if insertable: tree_item['attributes']['rel'] = 'insertable' return tree_item
def get_userinfo(self, ob): """ returns a list of objects based on the ob type""" site = self.getSite() cat = site.getCatalogTool() user = self.REQUEST.AUTHENTICATED_USER.getId() filters = {'contributor': user} if ob == 'events': filters['meta_type'] = 'Naaya Event' ob_list = cat.search(filters) elif ob == 'news': filters['meta_type'] = 'Naaya News' ob_list = cat.search(filters) elif ob == 'topics': ob_list = cat.search({ 'path': ofs_path(site.topics), 'contributor': user }) elif ob == 'resources': ob_list = cat.search({ 'path': ofs_path(site.resources), 'contributor': user }) elif ob == 'forums': forum_meta_types = ['Naaya Forum Topic', 'Naaya Forum Message'] ob_list = cat.search({ 'meta_type': forum_meta_types, 'contributor': user }) elif ob == 'contacts': ob_list = cat.search({ 'meta_type': 'Naaya Contact', 'contributor': user }) sorted_list = site.utSortObjsListByAttr(ob_list, 'releasedate') userinfo = [[ item.title, item.absolute_url, item.releasedate.strftime('%d %b \'%y') ] for item in sorted_list[:50]] return json.dumps(userinfo)
def get_linked_pointer_brains(obj): """ Tests if object had met condition to be synced with pointers and returns brains to existing ones. Used by handlers to keep them in sync. """ site = obj.getSite() q_both = _qualifies_for_both(obj) q_topics = _qualifies_for_topics_only(obj) pointers = [] if q_topics or q_both: cat = site.getCatalogTool() pointers = cat.search({'meta_type': 'Naaya Pointer', 'path': [ofs_path(site.countries), ofs_path(site.topics), ofs_path(getattr(site, 'resources')), # kept for pointers prior to v 1.1 ofs_path(getattr(site, 'who-who'))], 'pointer': path_in_site(obj)}) return pointers
def generate_events(obj_list, ignore_desc=False): events = [] for obj in obj_list: if obj.istranslated(lang): #Description tag if ignore_desc is False: if mesg_type == 'html': desc_elem = E.description( sanitize_xml_data( obj.getLocalProperty('description', lang))) else: desc_elem = E.description( sanitize_xml_data( self.utStripAllHtmlTags( obj.getLocalProperty( 'description', lang)))) else: desc_elem = E.description('') #Address tag addr_elem = E.address( sanitize_xml_data(obj.getLocalProperty('', lang))) #Events tag try: events.append( E.event( desc_elem, addr_elem, { 'title': sanitize_xml_data( obj.getLocalProperty('title', lang)), 'start_date': sanitize_xml_data(str(obj.start_date)), 'end_date': sanitize_xml_data(str(obj.end_date)), 'source': sanitize_xml_data( obj.getLocalProperty('source', lang)), 'source_link': sanitize_xml_data(obj.source_link), 'file_link': sanitize_xml_data(obj.file_link), 'url': sanitize_xml_data(obj.absolute_url(0)), 'lang': sanitize_xml_data(lang), 'isrtl': sanitize_xml_data(str( self.is_arabic(lang))), })) except: logger.exception("Failed to add %r to xml", ofs_path(obj)) raise return tuple(events)
def get_close_answers(self, title_en, title_ru, year, original_title): """ """ def string_to_match(title): if title.startswith("Google translation: "): title = title[len("Google translation: "):] ret = title.lower() for c in ' -/().,;!?': ret = ret.replace(c, '') return ret def get_close_answers_by_lang_title(shadows, title, lang): shadows_by_title = dict((string_to_match(shadow.get('title', lang)), shadow) for shadow in shadows) matched_titles = get_close_matches(string_to_match(title), shadows_by_title.keys(), n=5, cutoff=0.5) return [{'title': shadows_by_title[t].get('title', lang), 'answer_url': shadows_by_title[t].target_answer().absolute_url()} for t in matched_titles] def get_close_answers_by_lang_original(shadows, title, lang): shadows_by_title = dict((string_to_match(shadow.original_title[lang]), shadow) for shadow in shadows if lang in shadow.original_title) matched_titles = get_close_matches(string_to_match(title), shadows_by_title.keys(), n=5, cutoff=0.9) return [{'title': shadows_by_title[t].original_title[lang], 'answer_url': shadows_by_title[t].target_answer().absolute_url()} for t in matched_titles] ret = [] catalog = self.getSite().getCatalogTool() brains = catalog(path=ofs_path(self), viewer_year=year) shadows = [b.getObject() for b in brains] if original_title: original_title_map = shadow.extract_original_title_dict(original_title) for lang in original_title_map: ret.extend(get_close_answers_by_lang_original(shadows, original_title_map[lang], lang)) if title_en: ret.extend(get_close_answers_by_lang_title(shadows, title_en, 'en')) if title_ru: ret.extend(get_close_answers_by_lang_title(shadows, title_ru, 'ru')) return json.dumps(ret)
def recursive_tree(ob): icon_url = '/misc_/NaayaGlossary/%s.gif' % icons_map[ob.meta_type] kids = ob.objectValues([NAAYAGLOSSARY_FOLDER_METATYPE, NAAYAGLOSSARY_ELEMENT_METATYPE]) kids = sorted(kids, key=lambda ob: ob.getId()) children = [recursive_tree(kid) for kid in kids if kid.approved] translation_missing = '' if ob is glossary: translation = None title = ob.title_or_id() definition = ofs_path(ob) else: translation = ob.get_translation_by_language(language_name) if translation: title = translation else: translation = None title = ob.get_translation_by_language('English') if not title: title = ob.title_or_id() translation_missing = (' <span class="glossary-translation-missing">(' + language_name + ' translation missing)</span>') definition = ob.get_def_trans_by_language(language_name) insertable = (ob.meta_type != NAAYAGLOSSARY_FOLDER_METATYPE or glossary.parent_anchors) tree_item = { 'attributes': { 'title': definition, 'type': icons_map.get(ob.meta_type), }, 'data': { 'title': title + translation_missing, 'icon': icon_url, }, 'children': children, } if ob is glossary: tree_item['state'] = 'open' else: tree_item['attributes']['glossary-translation'] = ( translation or title) if insertable: tree_item['attributes']['rel'] = 'insertable' return tree_item
def log_user_access(context, who, how): """ On open/download of a content type """ if how not in ALLOWED_SLUGS[ACCESS]: log.info("Invalid value for `how`: %r in logging access", how) return data = { 'type': ACCESS, 'action': how, 'who': who, 'content_path': ofs_path(context), } site_logger = get_site_logger(context.getSite()) site_logger.info(data)
def handle_approval_unapproval(obj, approved, approved_by): """ Approve/Unapprove pointers. Used by the two event handlers for approval """ pointer_brains = get_linked_pointer_brains(obj) for brain in pointer_brains: pointer = brain.getObject() try: pointer.approveThis(1, approved_by) except Exception: logger.exception("Can set approve=%s by %s for pointer %s", approved, approved_by, ofs_path(pointer))
def handle_del_content(obj, event): """ Test whether this required adding pointers and perform the cleanup of pointers. """ site = obj.getSite() if not getattr(site, 'destinet.publisher', False): return None q_both = _qualifies_for_both(obj) q_topics = _qualifies_for_topics_only(obj) if q_topics or q_both: # clean-up all existing pointers cat = site.getCatalogTool() pointers = cat.search({'meta_type': 'Naaya Pointer', 'path': [ofs_path(site.countries), ofs_path(site.topics), ofs_path(getattr(site, 'resources')), # kept for pointers prior to v 1.1 ofs_path(getattr(site, 'who-who'))], 'pointer': path_in_site(obj)}) for brain in pointers: pointer = brain.getObject() pointer.aq_parent._delObject(pointer.id)
def generate_news(obj_list): news = [] for obj in obj_list: if obj.istranslated(lang): #Description tag if mesg_type == 'html': desc_elem = E.description( sanitize_xml_data( obj.getLocalProperty('description', lang))) else: desc_elem = E.description( sanitize_xml_data( self.utStripAllHtmlTags( obj.getLocalProperty('description', lang)))) #News tag try: news.append( E.news( desc_elem, { 'title': sanitize_xml_data( obj.getLocalProperty('title', lang)), 'source': sanitize_xml_data( obj.getLocalProperty('source', lang)), 'source_link': sanitize_xml_data(obj.source_link), 'file_link': sanitize_xml_data(obj.file_link), 'url': sanitize_xml_data(obj.absolute_url(0)), 'lang': sanitize_xml_data(lang), 'isrtl': sanitize_xml_data(str( self.is_arabic(lang))), })) except: logger.exception("Failed to add %r to xml", ofs_path(obj)) raise return tuple(news)
def notify_comment_administrative(self, comment, parent, user_id): """ send administrative notifications because a comment was added to object `ob` by the user `user_id` """ auth_tool = self.getSite().getAuthenticationTool() subscribers_data = utils.get_subscribers_data( self, parent, notif_type='administrative', **{'comment': comment, 'parent': parent, 'here': self, 'person': auth_tool.name_from_userid(user_id), }) if len(subscribers_data.keys()) > 0: notif_logger.info('Administrative comment notifications on %r', ofs_path(parent)) template = self._get_template('administrative') self._send_notifications(subscribers_data, template)
def notify_administrative(self, ob, user_id, ob_edited=False): """ send administrative notifications because object `ob` was added or edited by the user `user_id` """ auth_tool = self.getSite().getAuthenticationTool() subscribers_data = utils.get_subscribers_data(self, ob, notif_type='administrative', **{ 'person': auth_tool.name_from_userid(user_id), 'ob_edited': ob_edited, 'approved': ob.approved, 'container_basket': '%s/basketofapprovals_html' % ob.aq_parent.absolute_url(), }) if len(subscribers_data.keys()) > 0: notif_logger.info('Administrative notifications on %r', ofs_path(ob)) template = self._get_template('administrative') self._send_notifications(subscribers_data, template)
def log_user_management_action(context, who, whom, assigned, unassigned): """ It is called where user management logging is required, guarantees consistency in log messages. * `who` and `whom` are user ids * `assigned` and `unnasigned` are lists of roles, both can not be empty """ site_logger = get_site_logger(context.getSite()) data = { 'type': USER_MAN, 'who': who, 'whom': whom, 'content_path': ofs_path(context), } if unassigned: site_logger.info(dict(data, action='UNASSIGNED', roles=unassigned)) if assigned: site_logger.info(dict(data, action='ASSIGNED', roles=assigned))
def notify_instant(self, ob, user_id, ob_edited=False): """ send instant notifications because object `ob` was changed by the user `user_id` """ notif_logger.info('Instant notifications on %r', ofs_path(ob)) if not self.config['enable_instant']: return #Don't send notifications if the object is unapproved, but store them #into a queue to send them later when it becomes approved if not ob.approved: return subscribers_data = utils.get_subscribers_data(self, ob, **{ 'person': user_id, 'ob_edited': ob_edited, }) template = self._get_template('instant') self._send_notifications(subscribers_data, template)
def generate_events(obj_list, ignore_desc=False): events = [] for obj in obj_list: if obj.istranslated(lang): #Description tag if ignore_desc is False: if mesg_type == 'html': desc_elem = E.description(sanitize_xml_data( obj.getLocalProperty('description', lang)) ) else: desc_elem = E.description(sanitize_xml_data( self.utStripAllHtmlTags( obj.getLocalProperty('description', lang) ) )) else: desc_elem = E.description('') #Address tag addr_elem = E.address(sanitize_xml_data( obj.getLocalProperty('', lang))) #Events tag try: events.append(E.event(desc_elem, addr_elem, { 'title': sanitize_xml_data( obj.getLocalProperty('title', lang)), 'start_date': sanitize_xml_data(str(obj.start_date)), 'end_date': sanitize_xml_data(str(obj.end_date)), 'source': sanitize_xml_data( obj.getLocalProperty('source', lang)), 'source_link': sanitize_xml_data(obj.source_link), 'file_link': sanitize_xml_data(obj.file_link), 'url': sanitize_xml_data(obj.absolute_url(0)), 'lang': sanitize_xml_data(lang), 'isrtl': sanitize_xml_data(str(self.is_arabic(lang))), })) except: logger.exception("Failed to add %r to xml", ofs_path(obj)) raise return tuple(events)
def notify_comment_maintainer(self, comment, parent, **kwargs): """ Process and notify by email that a comment B{comemnt} has been added to the object B{parent}. """ auth_tool = self.getSite().getAuthenticationTool() emails = self.getMaintainersEmails(parent) if len(emails) > 0: maintainers_data = {} for email in emails: maintainers_data[email] = { 'parent': parent, 'here': self, 'comment': comment, 'person': auth_tool.name_from_userid(comment.author), 'container_basket': '%s/basketofapprovals_html' % parent.absolute_url(), } notif_logger.info('Maintainer comment notifications on %r', ofs_path(parent )) template = self._get_template('maintainer') self._send_notifications(maintainers_data, template)
def notify_instant(self, ob, user_id, ob_edited=False): """ send instant notifications because object `ob` was changed by the user `user_id` """ if not self.config['enable_instant']: return # Don't send notifications if the object is unapproved, but store them # into a queue to send them later when it becomes approved if not ob.approved: return auth_tool = self.getSite().getAuthenticationTool() subscribers_data = utils.get_subscribers_data(self, ob, **{ 'person': auth_tool.name_from_userid(user_id), 'ob_edited': ob_edited, }) if len(subscribers_data.keys()) > 0: notif_logger.info('Instant notifications on %r', ofs_path(ob)) template = self._get_template('instant') self._send_notifications(subscribers_data, template)
def inaccessible_parents(context): """ Returns top-most parent that can not be accessed by each role. Pseudoroles inheritance is not disregarded. E.g.: {'Anonymous': <Library at ./..>, ..} """ roles = set(context.valid_roles()) ob = context result = {} ob = ob.aq_parent while ofs_path(ob): having_view = allowed2(ob, 'View')['View'] if 'Anonymous' in having_view: ob = ob.aq_parent continue for role in roles - set(having_view.keys()): result[role] = ob roles = roles.intersection(set(having_view.keys())) if not roles: break ob = ob.aq_parent return result