コード例 #1
0
ファイル: alerts.py プロジェクト: lslaz1/karl
    def emit(self, context, request):
        # Get community in which event occurred and alert members
        community = find_community(context)
        if community is None:
            return  # Will be true for a mailin test trace
        profiles = find_profiles(context)
        all_names = community.member_names | community.moderator_names

        threaded = get_config_setting('use_threads_to_send_email', False) in (True, 'true', 'True')  # noqa
        mailer = getUtility(IMailDelivery)
        if threaded:
            mailer = ThreadedGeneratorMailDelivery()
        queue = []

        reply_enabled = get_setting(context, 'reply_by_email_enabled', True)

        for profile in [profiles[name] for name in all_names]:
            alert = getMultiAdapter((context, profile, request), IAlert)
            preference = profile.get_alerts_preference(community.__name__)
            alert = getMultiAdapter((context, profile, request), IAlert)

            alert.reply_enabled = reply_enabled

            if preference == IProfile.ALERT_IMMEDIATELY:
                if threaded:
                    queue.append(alert)
                else:
                    self._send_immediately(mailer, alert)
            elif preference in (IProfile.ALERT_DAILY_DIGEST,
                                IProfile.ALERT_WEEKLY_DIGEST,
                                IProfile.ALERT_BIWEEKLY_DIGEST):
                self._queue_digest(alert, profile, community.__name__)

        if queue:
            mailer.sendGenerator(_send_alert_queue, mailer, queue)
コード例 #2
0
ファイル: resource.py プロジェクト: cguardia/karl
def delete_resource_view(context, request, num_children=0):

    page_title = 'Delete ' + context.title
    api = TemplateAPI(context, request, page_title)

    confirm = request.params.get('confirm')
    if confirm:
        location = model_url(
            context.__parent__, request,
            query=dict(status_message= 'Deleted %s' % context.title)
            )
        del context.__parent__[context.__name__]
        return HTTPFound(location=location)

    # Get a layout
    layout_provider = get_layout_provider(context, request)
    layout_name = 'generic'
    if find_intranet(context):
        layout_name = 'intranet'
    elif find_community(context):
        layout_name = 'community'
    layout = layout_provider(layout_name)

    return {'api': api,
            'layout': layout,
            'num_children': num_children,
           }
コード例 #3
0
ファイル: workflow.py プロジェクト: boothead/karl
def public_community_containment(context):
    if not_intranets_containment(context):
        community = find_community(context)
        if community is None:
            return False
        return getattr(community, 'security_state', None) == 'public'
    return False
コード例 #4
0
ファイル: adapters.py プロジェクト: Falmarri/karl
 def __init__(self, context, profile, request):
     super(BlogAlert, self).__init__(context, profile, request)
     self._community = find_community(context)
     blogentry = find_interface(context, IBlogEntry)
     if blogentry is None:
         # Comments can also be made against forum topics
         blogentry = find_interface(context, IForumTopic)
     self._blogentry = blogentry
コード例 #5
0
ファイル: imagedrawer.py プロジェクト: boothead/karl
def batch_images(context, request,
                 get_image_info=get_image_info, # unittest
                 get_images_batch=get_images_batch): # unittest

    # Find query parameters based on the 'source' param,
    # which signifies the selection index of the source button
    # in the imagedrawer dialog.
    source = int(request.params.get('source', '0'))
    if source == 0:     # My Recent
        creator = 'admin'
        community_path = None
    elif source == 1:   # This Community
        creator = None
        community = find_community(context)
        # batching api requires the community path
        community_path = model_path(community)
    else:               # All Karl
        creator = None
        community_path = None

    # batching
    # Decide start and size here, don't let the lower levels
    # apply their default. This allows us to enforce
    # a MINIMAL_BATCH size.
    batch_start = int(request.params.get('start', '0'))
    batch_size = max(int(request.params.get('limit', '0')), MINIMAL_BATCH)
    # there is a minimal batch size to enforce, if the client
    # does not ask for one
    # Just pass the values to lower levels where sensible
    # defaults will be applied.
    sort_index = request.params.get('sort_on', None)
    reverse = request.params.get('reverse', None)

    search_params = dict(
        creator=creator,
        community=community_path,
        batch_start=batch_start,
        batch_size=batch_size,
    )
    if sort_index:
        search_params['sort_index'] = sort_index
    if reverse:
        search_params['reverse'] = bool(int(reverse))

    batch_info = get_images_batch(
        context,
        request,
        **search_params
    )

    records = [get_image_info(image, request)
               for image in batch_info['entries']]

    return dict(
        records=records,
        start=batch_info['batch_start'],
        totalRecords=batch_info['total'],
    )
コード例 #6
0
ファイル: adapters.py プロジェクト: lslaz1/karl
def _community_title(context):
    """find the title of a community

    offices also provide ICommunity, but we don't want to consider those
    here.
    """
    obj = find_community(context)
    if obj is None:
        return None
    return obj.title
コード例 #7
0
def context_tools(context, request, tools=None):
    community = find_community(context)
    if community:
        url = request.resource_url(community, 'tagcloud.html')
        selected = 'tagcloud.html' in request.path_url
        tools.append(dict(title="Tags",
                                  url=url,
                                  selected=selected,
                                  id='tagcloud'))
    return {'tools': tools}
コード例 #8
0
ファイル: page.py プロジェクト: boothead/karl
 def __call__(self):
     context = self.context
     request = self.request
     api = TemplateAPI(context, request, 'Add Page')
     community = find_community(context)
     layout_provider = get_layout_provider(context, request)
     if community is not None:
         layout = layout_provider('community')
     else:
         layout = layout_provider('generic')
     return {'api': api, 'actions': (), 'layout': layout}
コード例 #9
0
ファイル: alerts.py プロジェクト: boothead/karl
 def emit(self, context, request):
     # Get community in which event occurred and alert members
     community = find_community(context)
     profiles = find_profiles(context)
     all_names = community.member_names | community.moderator_names
     for profile in [profiles[name] for name in all_names]:
         preference = profile.get_alerts_preference(community.__name__)
         if preference == IProfile.ALERT_IMMEDIATELY:
             self._send_immediately(context, profile, request)
         elif preference == IProfile.ALERT_DIGEST:
             self._queue_digest(context, profile, request)
コード例 #10
0
def _community_title(context):
    """find the title of a community

    offices also provide ICommunity, but we don't want to consider those
    here. offices explicitly provide IIntranets, so we'll discount those that
    way
    """
    obj = find_community(context)
    if obj is None or IIntranets.providedBy(obj):
        return None
    return obj.title
コード例 #11
0
ファイル: __init__.py プロジェクト: claytron/karl
 def __call__(self, docid):
     site = self.context.site
     catalog = find_catalog(site)
     if catalog is None:
         raise ValueError('No catalog')
     path = catalog.document_map.address_for_docid(docid)
     if path is None:
         raise KeyError(docid)
     doc = find_resource(site, path)
     community = find_community(doc)
     return community and community.__name__ or None
コード例 #12
0
ファイル: page.py プロジェクト: cguardia/karl
 def __call__(self):
     context = self.context
     request = self.request
     api = TemplateAPI(context, request, 'Add Page')
     community = find_community(context)
     layout_provider = get_layout_provider(context, request)
     if community is not None:
         layout = layout_provider('community')
     else:
         layout = layout_provider('generic')
     api.karl_client_data['text'] = dict(
             enable_imagedrawer_upload = True,
             )
     return {'api': api, 'actions': (), 'layout': layout}
コード例 #13
0
ファイル: page.py プロジェクト: hj91/karl
def show_page_view(context, request):

    backto = {
        'href': resource_url(context.__parent__, request),
        'title': context.__parent__.title,
        }

    actions = []
    if has_permission('edit', context, request):
        actions.append(('Edit', 'edit.html'))
    if has_permission('delete', context, request):
        actions.append(('Delete', 'delete.html'))
    if has_permission('administer', context, request):
        actions.append(('Advanced', 'advanced.html'))

    page_title = context.title
    api = TemplateAPI(context, request, page_title)

    previous, next = get_previous_next(context, request)

    # provide client data for rendering current tags in the tagbox
    client_json_data = dict(
        tagbox = get_tags_client_data(context, request),
        )

    # Get a layout
    community = find_community(context)
    layout_provider = get_layout_provider(context, request)
    if community is not None:
        layout = layout_provider('community')
    else:
        layout = layout_provider('generic')

    ux2_layout = request.layout_manager.layout
    ux2_layout.section_style = "none"
    return render_to_response(
        'templates/show_page.pt',
        dict(api=api,
             actions=actions,
             attachments=fetch_attachments(context['attachments'], request),
             formfields=api.formfields,
             head_data=convert_to_script(client_json_data),
             backto=backto,
             previous_entry=previous,
             next_entry=next,
             old_layout=layout),
        request = request,
        )
コード例 #14
0
ファイル: workflow.py プロジェクト: boothead/karl
def community_to_private(ob, info):
    community = find_community(ob)
    acl = []
    moderators_group_name = community.moderators_group_name
    members_group_name = community.members_group_name
    acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS))
    acl.append((Allow, moderators_group_name, MODERATOR_PERMS))
    acl.append((Allow, members_group_name, MEMBER_PERMS))
    acl.append(NO_INHERIT)
    msg = None
    added, removed = acl_diff(community, acl)
    if added or removed:
        community.__acl__ = acl
        msg = ts('community-private', model_path(community), added, removed)
    _reindex(community)
    return msg
コード例 #15
0
ファイル: intranets.py プロジェクト: disko/karl
    def handle_submit(self, converted):
        request = self.request
        context = self.context

        intranets_parent = find_community(context)
        name = converted.get('name')
        if name:
            name_from = 'name'
        else:
            name = converted['title']
            name_from = 'title'
        try:
            name = make_name(intranets_parent, name)
        except ValueError, why:
            msg = why[0]
            raise ValidationError(**{name_from: msg})
コード例 #16
0
ファイル: workflow.py プロジェクト: boothead/karl
def blogentry_to_private(ob, info):
    community = find_community(ob)
    acl = [(Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS)]
    acl.append((Allow, ob.creator, MEMBER_PERMS))
    moderators_group_name = community.moderators_group_name
    members_group_name = community.members_group_name
    acl.append((Allow, moderators_group_name, MODERATOR_PERMS))
    acl.append((Allow, members_group_name, GUEST_PERMS))
    acl.append(NO_INHERIT)
    msg = None
    added, removed = acl_diff(ob, acl)
    if added or removed:
        ob.__acl__ = acl
        msg = ts('blogentry-private', model_path(ob), added, removed)
    _reindex(ob)
    return msg
コード例 #17
0
ファイル: page.py プロジェクト: boothead/karl
def show_page_view(context, request):

    backto = {
        'href': model_url(context.__parent__, request),
        'title': context.__parent__.title,
        }

    actions = []
    if has_permission('create', context, request):
        actions.append(
            ('Edit', 'edit.html')
            )
    if has_permission('delete', context, request):
        actions.append(
            ('Delete', 'delete.html'),
        )

    page_title = context.title
    api = TemplateAPI(context, request, page_title)

    previous, next = get_previous_next(context, request)

    # provide client data for rendering current tags in the tagbox
    client_json_data = dict(
        tagbox = get_tags_client_data(context, request),
        )

    # Get a layout
    community = find_community(context)
    layout_provider = get_layout_provider(context, request)
    if community is not None:
        layout = layout_provider('community')
    else:
        layout = layout_provider('generic')

    return render_template_to_response(
        'templates/show_page.pt',
        api=api,
        actions=actions,
        attachments=fetch_attachments(context['attachments'], request),
        formfields=api.formfields,
        head_data=convert_to_script(client_json_data),
        backto=backto,
        previous=previous,
        next=next,
        layout=layout,
        )
コード例 #18
0
ファイル: contentfeeds.py プロジェクト: hathawsh/karl
def _getInfo(profile, content):
    community = context = find_community(content)
    if context is None:
        # try for content inside a profile
        context = find_interface(content, IProfile)
    if context is None:
        context_name = context_url = None
    else:
        context_name = context.title
        context_url = resource_path(context)
    tagger = find_tags(content)
    if tagger is not None:
        cloud = list(tagger.getCloud(items=(content.docid,)))
        tag_counts = sorted(cloud, key=lambda x: x[1], reverse=True)[:3]
        tags = [x[0] for x in tag_counts]
    else:
        tags = ()
    content_type = get_content_type(content)
    desc = getattr(content, "description", "")
    short = len(desc) > 80 and "%s..." % desc[:80] or desc
    if IPosts.providedBy(content):
        comment_count = len(content.get("comments", ()))
    else:
        comment_count = False
    content_creator = profile.__name__
    if IComment.providedBy(content):
        # my content filter needs to know if a comment was made inside my post
        content_creator = content.__parent__.__parent__.creator
    return {
        "content_type": content_type.getTaggedValue("name"),
        "userid": profile.__name__,
        "context_name": context_name,
        "context_url": context_url,
        "content_creator": content_creator,
        "url": resource_path(content),
        "title": content.title,
        "description": desc,
        "short_description": short,
        "allowed": principals_allowed_by_permission(content, "view"),
        "comment_count": comment_count,
        "tags": tags,  # XXX
        "author": profile.title,
        "profile_url": "/profiles/%s" % profile.__name__,
        "thumbnail": "/profiles/%s/profile_thumbnail" % profile.__name__,
        "timestamp": _NOW(),
    }
コード例 #19
0
ファイル: alerts.py プロジェクト: araymund/karl
 def emit(self, context, request):
     # Get community in which event occurred and alert members
     community = find_community(context)
     if community is None:
         return # Will be true for a mailin test trace
     profiles = find_profiles(context)
     all_names = community.member_names | community.moderator_names
     for profile in [profiles[name] for name in all_names]:
         preference = profile.get_alerts_preference(community.__name__)
         if preference == IProfile.ALERT_IMMEDIATELY:
             self._send_immediately(context, profile, request)
         elif preference in (IProfile.ALERT_DAILY_DIGEST,
                             IProfile.ALERT_WEEKLY_DIGEST,
                             IProfile.ALERT_BIWEEKLY_DIGEST,
                            ):
             self._queue_digest(context, profile, request,
                                community.__name__)
コード例 #20
0
ファイル: workflow.py プロジェクト: Falmarri/karl
def community_to_intranet(ob, info):
    community = find_community(ob)
    acl = []
    moderators_group_name = community.moderators_group_name
    members_group_name = community.members_group_name
    acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS))
    acl.append((Allow, moderators_group_name, MODERATOR_PERMS))
    acl.append((Allow, members_group_name, MEMBER_PERMS))
    # inherit from /offices
    #acl.append(NO_INHERIT)
    msg = None
    added, removed = acl_diff(community, acl)
    if added or removed:
        community.__acl__ = acl
        msg = ts('community-intranet', resource_path(community), added, removed)
    _reindex(community)
    return msg
コード例 #21
0
ファイル: contentfeeds.py プロジェクト: araymund/karl
def _getInfo(profile, content):
    community = context = find_community(content)
    if context is None:
        # try for content inside a profile
        context = find_interface(content, IProfile)
    if context is None:
        context_name = context_url = None
    else:
        context_name = context.title
        context_url = resource_path(context)
    tagger = find_tags(content)
    if tagger is not None:
        cloud = list(tagger.getCloud(items=(content.docid,)))
        tag_counts = sorted(cloud, key=lambda x: x[1], reverse=True)[:3]
        tags = [x[0] for x in tag_counts]
    else:
        tags = ()
    content_type = get_content_type(content)
    desc = getattr(content, 'description', '')
    short = len(desc) > 256 and '%s...' % desc[:256] or desc
    if IPosts.providedBy(content):
        comment_count = len(content.get('comments', ()))
    else:
        comment_count = False
    content_creator = profile.__name__
    if IComment.providedBy(content):
        # my content filter needs to know if a comment was made inside my post
        content_creator = content.__parent__.__parent__.creator
    return {'content_type': content_type.getTaggedValue('name'),
            'userid': profile.__name__,
            'context_name': context_name,
            'context_url': context_url,
            'content_creator': content_creator,
            'url': resource_path(content),
            'title': content.title,
            'description': desc,
            'short_description': short,
            'allowed':
                principals_allowed_by_permission(content, 'view'),
            'comment_count': comment_count,
            'tags': tags,                 #XXX
            'author': profile.title,
            'profile_url': '/profiles/%s' % profile.__name__,
            'thumbnail': '/profiles/%s/profile_thumbnail' % profile.__name__,
            'timestamp': _NOW(),
           }
コード例 #22
0
ファイル: blog.py プロジェクト: karlproject/karl
def archive_portlet(context, request):
    stmt = """SELECT
        date_part('year', creation_date) as y,
        date_part('month', creation_date) as m,
        count(*)
      FROM pgtextindex
      WHERE content_type='IBlogEntry' and community_docid='%s'
      GROUP BY y, m
      ORDER BY y DESC, m DESC"""
    community = find_community(context)
    blog = find_interface(context, IBlog)
    catalog = find_catalog(context)
    index = catalog['texts']
    results = index.get_sql_catalog_results(stmt % community.docid)
    return {'archive': [MonthlyActivity(year, month, count,
            request.resource_url(blog, query={'year': year, 'month': month}))
            for (year, month, count) in results]}
コード例 #23
0
ファイル: context_tools.py プロジェクト: araymund/karl
def context_tools(context, request):
    community = find_community(context)
    if community is None:
        return None
    community_info = getMultiAdapter((community, request), ICommunityInfo)

    tools = community_info.tabs
    members = community['members']
    members_path = resource_path(community['members'])
    context_path = resource_path(context)
    in_members = context_path.startswith(members_path)
    tools.append({
        'url': request.resource_url(members),
        'selected': in_members,
        'title': 'Members',
        'name':'members'})

    return tools
コード例 #24
0
ファイル: workflow.py プロジェクト: lslaz1/karl
def community_to_restricted(ob, info):
    community = find_community(ob)
    acl = []
    moderators_group_name = community.moderators_group_name
    members_group_name = community.members_group_name
    acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS))
    acl.append((Allow, moderators_group_name, MODERATOR_PERMS))
    acl.append((Allow, members_group_name, MEMBER_PERMS))
    acl.append((Allow, 'group.KarlStaff', MEMBER_PERMS))
    acl.append((Allow, Authenticated, GUEST_PERMS))
    acl.append(NO_INHERIT)
    msg = None
    added, removed = acl_diff(community, acl)
    if added or removed:
        community.__acl__ = acl
        msg = ts('community-public', resource_path(community), added, removed)
    _reindex(community)
    return msg
コード例 #25
0
ファイル: resource.py プロジェクト: lslaz1/karl
def delete_resource_view(context, request, num_children=0):

    page_title = "Delete " + context.title
    api = TemplateAPI(context, request, page_title)

    confirm = request.params.get("confirm")
    if confirm:
        location = resource_url(context.__parent__, request, query=dict(status_message="Deleted %s" % context.title))
        del context.__parent__[context.__name__]
        return HTTPFound(location=location)

    # Get a layout
    layout_provider = get_layout_provider(context, request)
    layout_name = "generic"
    if find_community(context):
        layout_name = "community"
    layout = layout_provider(layout_name)

    return {"api": api, "layout": layout, "num_children": num_children}
コード例 #26
0
def search(context, request):
    scope_options = []
    scope_options.append(dict(
        path = '',
        name = 'all KARL',
        label = 'all KARL',
        selected = True,
        ))
    # We add a second option, in case, context is inside a community.
    community = find_community(context)
    if community:
        # We are in a community!
        scope_options.append(dict(
            path = resource_path(community),
            name = 'this community',
            label = community.title,
        ))

    return {
        'scope_options': scope_options,
        }
コード例 #27
0
ファイル: page.py プロジェクト: hj91/karl
 def __call__(self):
     context = self.context
     request = self.request
     api = TemplateAPI(context, request, 'Add Page')
     community = find_community(context)
     layout_provider = get_layout_provider(context, request)
     if community is not None:
         old_layout = layout_provider('community')
     else:
         old_layout = layout_provider('generic')
     # ux1
     api.karl_client_data['text'] = dict(
             enable_imagedrawer_upload = True,
             )
     # ux2
     layout = self.request.layout_manager.layout
     layout.section_style = "none"
     layout.head_data['panel_data']['tinymce'] = api.karl_client_data['text']
     return {
         'api': api,             # deprecated UX1
         'actions': (),          # deprecated UX1
         'old_layout': old_layout}   # deprecated UX1
コード例 #28
0
ファイル: admin.py プロジェクト: reebalazs/karl
def _find_dst_container(src_obj, dst_community):
    """
    Given a source object and a destination community, figures out the
    container insider the destination community where source object can be
    moved to.  For example, if source object is a blog entry in community
    `foo` (/communities/foo/blog/entry1) and we want to move it to the `bar`
    community, this will take the relative path of the source object from its
    community and attempt to find analogous containers inside of the
    destination community.  In this example, the relative container path is
    'blog', so we the destination container is /communities/bar/blog.'
    """
    src_container_path = model_path(src_obj.__parent__)
    src_community_path = model_path(find_community(src_obj))
    rel_container_path = src_container_path[len(src_community_path) :]
    dst_container = dst_community
    for node_name in filter(None, rel_container_path.split("/")):
        dst_container = dst_container.get(node_name, None)
        if dst_container is None:
            raise _DstNotFound(
                "Path does not exist in destination community: %s" % model_path(dst_community) + rel_container_path
            )
    return dst_container
コード例 #29
0
ファイル: textindex.py プロジェクト: karlproject/karl
def _get_content_params(obj):
    community = find_community(obj)
    if community is not None:
        community = getattr(community, 'docid', None)

    try:
        content_type = get_content_type(obj)
        content_type = content_type.getName()
    except ValueError:
        content_type = obj.__class__.__name__

    try:
        creation_date = obj.created.isoformat()
    except AttributeError:
        creation_date = None

    try:
        modification_date = obj.modified.isoformat()
    except AttributeError:
        modification_date = None

    return [community, content_type, creation_date, modification_date]
コード例 #30
0
ファイル: stats.py プロジェクト: cguardia/karl
def user_activity_report(context, ids=None):
    """
    Returns a generator which iterates over user profiles yielding rows where
    each row is a tuple of (username, community, last_activity) where
    `last_activity` is the most recent activity for that user in that
    community.  If ids is not specified, report will be generated for all user
    profiles.  Otherwise, the report will only be generated for the given
    profiles.
    """
    if ids is None:
        profiles = find_profiles(context)
        ids = sorted(profiles.keys())
    else:
        ids = sorted(ids)

    search = ICatalogSearch(context)
    for id in ids:
        # communities[community_name] = (community, last_activity_date)
        communities = {}
        count, docids, resolver = search(creator=id)
        for docid in docids:
            doc = resolver(docid)
            created = getattr(doc, 'created', None)
            community = find_community(doc)
            if community is None:
                continue

            name = community.__name__
            if name not in communities:
                communities[name] = (community, created)
                continue

            last_activity = communities[name][1]
            if created > last_activity:
                communities[name] = (community, created)

        for name in sorted(communities.keys()):
            community, last_activity = communities[name]
            yield id, community, last_activity