Exemple #1
0
    def tabs(self):
        if self._tabs is None:

            found_current = False

            overview_css_class = ''

            if (ICommunity.providedBy(self.request.context) and
                    self.request.view_name in ['', 'view.html']):
                overview_css_class = 'curr'
                found_current = True

            tabs = [
                {'url': resource_url(self.context, self.request, 'view.html'),
                 'css_class': overview_css_class,
                 'name': 'OVERVIEW'}
                ]

            for toolinfo in get_listitems(IToolFactory):
                toolfactory = toolinfo['component']
                if toolfactory.is_present(self.context, self.request):
                    info = {}
                    info['url'] = toolfactory.tab_url(self.context,
                                                      self.request)
                    info['css_class'] = ''
                    if not found_current:
                        if toolfactory.is_current(self.context, self.request):
                            info['css_class'] = 'curr'
                            found_current = True
                    info['name'] = toolinfo['title'].upper()
                    tabs.append(info)

            self._tabs = tabs

        return self._tabs
Exemple #2
0
    def visit(node):
        if not (ICommunity.providedBy(node) or
                getattr(node, '__parent__', None) is None):
            for ancestor in visit(node.__parent__):
                yield ancestor

        yield dict(title=node.title, href=model_url(node, request))
Exemple #3
0
def redirect_community_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    default_tool = getattr(context, 'default_tool', None)
    if not default_tool:
        default_tool = 'view.html'
    return HTTPFound(location=model_url(context, request, default_tool))
Exemple #4
0
def related_communities_ajax_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    related = []
    principals = effective_principals(request)
    searcher = ICatalogSearch(context)
    search = ' OR '.join(context.title.lower().split())
    total, docids, resolver = searcher(
        interfaces=[ICommunity],
        limit=5,
        reverse=True,
        sort_index="modified_date",
        texts=search,
        allowed={
            'query': principals,
            'operator': 'or'
        },
    )
    for docid in docids:
        model = resolver(docid)
        if model is not None:
            if model is not context:
                adapted = getMultiAdapter((model, request), IGridEntryInfo)
                related.append(adapted)

    return {'items': related}
Exemple #5
0
    def visit(node):
        if not (ICommunity.providedBy(node) or
                getattr(node, '__parent__', None) is None):
            for ancestor in visit(node.__parent__):
                yield ancestor

        yield dict(title=title_or_id(node), href=resource_url(node, request))
Exemple #6
0
    def tabs(self):
        if self._tabs is None:

            found_current = False

            overview_css_class = ''

            if ( ICommunity.providedBy(self.request.context) and
                 self.request.view_name in ['','view.html','ux2_view.html'] ):
                overview_css_class = 'curr'
                found_current = True

            tabs = [
                {'url':resource_url(self.context, self.request, 'view.html'),
                 'css_class':overview_css_class,
                 'name':'OVERVIEW'}
                ]

            for toolinfo in get_listitems(IToolFactory):
                toolfactory = toolinfo['component']
                if toolfactory.is_present(self.context, self.request):
                    info = {}
                    info['url'] = toolfactory.tab_url(self.context,
                                                      self.request)
                    info['css_class'] = ''
                    if not found_current:
                        if toolfactory.is_current(self.context, self.request):
                            info['css_class'] = 'curr'
                            found_current = True
                    info['name'] = toolinfo['title'].upper()
                    tabs.append(info)

            self._tabs = tabs

        return self._tabs
Exemple #7
0
    def tabs(self):
        if self._tabs is None:

            found_current = False

            overview_css_class = ""

            if ICommunity.providedBy(self.request.context) and self.request.view_name in ["", "view.html"]:
                overview_css_class = "curr"
                found_current = True

            tabs = [
                {
                    "url": resource_url(self.context, self.request, "view.html"),
                    "css_class": overview_css_class,
                    "name": "OVERVIEW",
                }
            ]

            for toolinfo in get_listitems(IToolFactory):
                toolfactory = toolinfo["component"]
                if toolfactory.is_present(self.context, self.request):
                    info = {}
                    info["url"] = toolfactory.tab_url(self.context, self.request)
                    info["css_class"] = ""
                    if not found_current:
                        if toolfactory.is_current(self.context, self.request):
                            info["css_class"] = "curr"
                            found_current = True
                    info["name"] = toolinfo["title"].upper()
                    tabs.append(info)

            self._tabs = tabs

        return self._tabs
Exemple #8
0
    def visit(node):
        if not (ICommunity.providedBy(node) or
                getattr(node, '__parent__', None) is None):
            for ancestor in visit(node.__parent__):
                yield ancestor

        yield dict(title=title_or_id(node), href=resource_url(node, request))
Exemple #9
0
    def visit(self, context):
        if IProfile.providedBy(context):
            users = find_users(context)
            person = self._get_person(context.__name__)
            person['first_last'] = ' '.join(
                (context.firstname, context.lastname))
            person['create_date'] = context.created
            person['is_staff'] = users.member_of_group(
                context.__name__, 'group.KarlStaff')
            person['location'] = context.location
            person['department'] = context.department

            tags = find_tags(context)
            person['tags'] = len(tags.getTags(users=[context.__name__]))

        elif ICommunity.providedBy(context):
            for id in context.member_names:
                self._get_person(id)['membership'] += 1
            for id in context.moderator_names:
                self._get_person(id)['communities_moderator'] += 1

        else:
            creator = getattr(context, 'creator', None)
            if creator is not None:
                person = self._get_person(creator)
                person['content_created'] += 1
                if context.created > self.one_month_ago:
                    person['created_this_month'] += 1
Exemple #10
0
def community_recent_items_ajax_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    recent_items = []
    recent_items_batch = get_recent_items_batch(context, request, 5)
    for item in recent_items_batch["entries"]:
        adapted = getMultiAdapter((item, request), IGridEntryInfo)
        recent_items.append(adapted)

    return {'items': recent_items}
Exemple #11
0
def community_recent_items_ajax_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    recent_items = []
    recent_items_batch = get_recent_items_batch(context, request, 5)
    for item in recent_items_batch["entries"]:
        adapted = getMultiAdapter((item, request), IGridEntryInfo)
        recent_items.append(adapted)

    return {'items': recent_items}
Exemple #12
0
def community_members_ajax_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    members = []
    members_batch = get_members_batch(context, request, 5)
    for item in members_batch:
        adapted = getMultiAdapter((item, request), IGridEntryInfo)
        adapted.moderator = item.__name__ in context.moderator_names
        members.append(adapted)

    return {'items': members}
Exemple #13
0
def community_members_ajax_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    members = []
    members_batch = get_members_batch(context, request, 5)
    for item in members_batch:
        adapted = getMultiAdapter((item, request), IGridEntryInfo)
        adapted.moderator = item.__name__ in context.moderator_names
        members.append(adapted)

    return {'items': members}
Exemple #14
0
def show_community_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    user = authenticated_userid(request)
    page_title = 'View Community ' + context.title
    api = TemplateAPI(context, request, page_title)

    # provide client data for rendering current tags in the tagbox
    tagquery = getMultiAdapter((context, request), ITagQuery)
    client_json_data = {
        'tagbox': {
            'docid': tagquery.docid,
            'records': tagquery.tagswithcounts,
        },
    }

    # add tagbox to template
    layout = request.layout_manager.layout

    # inject tagbox data to panel header data
    panel_data = layout.head_data['panel_data']
    panel_data['tagbox'] = client_json_data['tagbox']

    # Filter the actions based on permission
    actions = []
    if has_permission(MODERATE, context, request):
        actions.append(('Edit', 'edit.html'))

    # If user has permission to see this view then has permission to join.
    if not (user in context.member_names or user in context.moderator_names):
        actions.append(('Join', 'join.html'))

    if has_permission(DELETE_COMMUNITY, context, request):
        actions.append(('Delete', 'delete.html'))

    if has_permission(ADMINISTER, context, request):
        actions.append(('Advanced', 'advanced.html'))

    recent_items = []
    recent_items_batch = get_recent_items_batch(context, request)
    for item in recent_items_batch["entries"]:
        adapted = getMultiAdapter((item, request), IGridEntryInfo)
        recent_items.append(adapted)

    feed_url = resource_url(context, request, "atom.xml")

    return {
        'api': api,
        'actions': actions,
        'recent_items': recent_items,
        'batch_info': recent_items_batch,
        'head_data': convert_to_script(client_json_data),
        'feed_url': feed_url
    }
Exemple #15
0
def redirect_community_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    default_tool = getattr(context, 'default_tool', None)
    if not default_tool:
        default_tool = 'view.html'
    # Preserve status_message=, etc in query string
    query = request.GET
    if query:
        location = resource_url(context, request, default_tool, query=query)
    else:
        location = resource_url(context, request, default_tool)
    return HTTPFound(location=location)
Exemple #16
0
def redirect_community_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    default_tool = getattr(context, 'default_tool', None)
    if not default_tool:
        default_tool = 'view.html'
    # Preserve status_message=, etc in query string
    query = request.GET
    if query:
        location = resource_url(context, request, default_tool, query=query)
    else:
        location = resource_url(context, request, default_tool)
    return HTTPFound(location=location)
Exemple #17
0
def show_community_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    user = authenticated_userid(request)
    page_title = 'View Community ' + context.title
    api = TemplateAPI(context, request, page_title)

    # provide client data for rendering current tags in the tagbox
    tagquery = getMultiAdapter((context, request), ITagQuery)
    client_json_data = {'tagbox': {'docid': tagquery.docid,
                                   'records': tagquery.tagswithcounts,
                                  },
                       }

    # add tagbox to template
    layout = request.layout_manager.layout

    # inject tagbox data to panel header data
    panel_data = layout.head_data['panel_data']
    panel_data['tagbox'] = client_json_data['tagbox']

    # Filter the actions based on permission
    actions = []
    if has_permission(MODERATE, context, request):
        actions.append(('Edit', 'edit.html'))

    # If user has permission to see this view then has permission to join.
    if not(user in context.member_names or user in context.moderator_names):
        actions.append(('Join', 'join.html'))

    if has_permission(DELETE_COMMUNITY, context, request):
        actions.append(('Delete', 'delete.html'))

    if has_permission(ADMINISTER, context, request):
        actions.append(('Advanced', 'advanced.html'))

    recent_items = []
    recent_items_batch = get_recent_items_batch(context, request)
    for item in recent_items_batch["entries"]:
        adapted = getMultiAdapter((item, request), IGridEntryInfo)
        recent_items.append(adapted)

    feed_url = resource_url(context, request, "atom.xml")

    return {'api': api,
            'actions': actions,
            'recent_items': recent_items,
            'batch_info': recent_items_batch,
            'head_data': convert_to_script(client_json_data),
            'feed_url': feed_url
           }
Exemple #18
0
def leave_community_view(context, request):
    """
    Users can leaver a community they are a member of
    """
    assert ICommunity.providedBy(context)
    profiles = find_profiles(context)
    user = authenticated_userid(request)
    profile = profiles[user]
    community_users = find_users(context)
    community_users.remove_group(profile.__name__, context.members_group_name)
    status_message = "You are no longer a member of this community!"
    community_href = resource_url(context, request,
                                  query={"status_message": status_message})
    return HTTPFound(location=community_href)
Exemple #19
0
def leave_community_view(context, request):
    """
    Users can leaver a community they are a member of
    """
    assert ICommunity.providedBy(context)
    profiles = find_profiles(context)
    user = authenticated_userid(request)
    profile = profiles[user]
    community_users = find_users(context)
    community_users.remove_group(profile.__name__, context.members_group_name)
    status_message = "You are no longer a member of this community!"
    community_href = resource_url(context,
                                  request,
                                  query={"status_message": status_message})
    return HTTPFound(location=community_href)
Exemple #20
0
    def visit(self, context):
        if ICommunity.providedBy(context):
            self.community = context
            self.row = {
                'community': context.title,
                'id': context.__name__,
                'is_private': is_private(context),
                'members': len(context.member_names),
                'moderators': len(context.moderator_names),
                'last_activity': context.content_modified,
                'create_date': context.created,
                'wiki_pages': 0,
                'blog_entries': 0,
                'blog_comments': 0,
                'files': 0,
                'calendar_events': 0,
                'community_tags': set(),
                'hits_this_month': 'Unknown',
                'percent_engaged': 'Unknown'
                }

        elif self.community is None:
            return

        else:
            last_activity = getattr(context, 'content_modified', None)
            if (last_activity is not None and
                last_activity > self.row['last_activity']):
                self.row['last_activity'] = last_activity

        if IWikiPage.providedBy(context):
            self.row['wiki_pages'] += 1
        elif IBlogEntry.providedBy(context):
            self.row['blog_entries'] += 1
        elif IComment.providedBy(context):
            self.row['blog_comments'] += 1
        elif ICommunityFile.providedBy(context):
            self.row['files'] += 1
        elif ICalendarEvent.providedBy(context):
            self.row['calendar_events'] += 1

        tags = find_tags(context)
        docid = getattr(context, 'docid', None)
        if docid is not None:
            for tag in tags.getTags([docid,]):
                self.row['community_tags'].add(tag)
Exemple #21
0
def show_community_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    user = authenticated_userid(request)
    page_title = 'View Community ' + context.title
    api = TemplateAPI(context, request, page_title)

    # provide client data for rendering current tags in the tagbox
    tagquery = getMultiAdapter((context, request), ITagQuery)
    client_json_data = dict(
        tagbox = dict(
            docid = tagquery.docid,
            records = tagquery.tagswithcounts,
            ),
        )

    # Filter the actions based on permission
    actions = []
    if has_permission(MODERATE, context, request):
        actions.append(('Edit', 'edit.html'))

    # If user has permission to see this view then has permission to join.
    if not(user in context.member_names or user in context.moderator_names):
        actions.append(('Join', 'join.html'))

    if has_permission(DELETE_COMMUNITY, context, request):
        actions.append(('Delete', 'delete.html'))

    recent_items = []
    recent_items_batch = get_recent_items_batch(context, request)
    for item in recent_items_batch["entries"]:
        adapted = getMultiAdapter((item, request), IGridEntryInfo)
        recent_items.append(adapted)

    feed_url = model_url(context, request, "atom.xml")
    return render_template_to_response(
        'templates/community.pt',
        api=api,
        actions=actions,
        recent_items=recent_items,
        batch_info=recent_items_batch,
        head_data=convert_to_script(client_json_data),
        feed_url=feed_url,
    )
Exemple #22
0
def searchresults_view(context, request):
    # We can get here from either the LiveSearch or advanced search
    # screens

    page_title = "Search Results"
    api = TemplateAPI(context, request, page_title)
    if ICommunity.providedBy(context):
        layout = api.community_layout
        community = context.title
    else:
        layout = api.generic_layout
        community = None

    batch = None
    terms = ()
    error = None

    try:
        batch, terms = get_batch(context, request)
    except ParseError, e:
        error = "Error: %s" % e
Exemple #23
0
def related_communities_ajax_view(context, request):
    assert ICommunity.providedBy(context), str(type(context))

    related = []
    principals = effective_principals(request)
    searcher = ICatalogSearch(context)
    search = ' OR '.join(context.title.lower().split())
    total, docids, resolver = searcher(interfaces=[ICommunity],
                                       limit=5,
                                       reverse=True,
                                       sort_index="modified_date",
                                       texts=search,
                                       allowed={'query': principals,
                                                'operator': 'or'},
                                       )
    for docid in docids:
        model = resolver(docid)
        if model is not None:
            if model is not context:
                adapted = getMultiAdapter((model, request), IGridEntryInfo)
                related.append(adapted)

    return {'items': related}
Exemple #24
0
def _searchresults_view(context, request, page_title, calendar_search,
                        show_search_knobs):
    api = TemplateAPI(context, request, page_title)

    # The layout is decided independently of whether we are a
    # calendar search or not. What is taken in consideration: if we are
    # in a community. The /offices section is considered a non-community
    # and will use the wide layout.
    if ICommunity.providedBy(context):
        if calendar_search:
            # We are either in /communities, or in /offices. In the first case:
            # we use the community layout. For offices: we need the wide layout
            # with the generic layout.
            context_path = resource_path(context)
            wide = context_path.startswith('/offices')
            if wide:
                layout = api.generic_layout
            else:
                layout = api.community_layout
        else:
            layout = api.community_layout
        community = context.title
    else:
        layout = api.generic_layout
        community = None

    request.unicode_errors = 'ignore'
    batch = None
    terms = ()
    error = None
    params = request.params.copy()
    if 'batch_start' in params:
        del params['batch_start']
    if 'batch_size' in params:
        del params['batch_size']

    kind_knob = []
    selected_kind = params.get('kind')

    scope_path = request.params.get('scopePath', '')

    # We show the scope knob, but in a limited way.
    # We only have a path here, so we show that path
    # and a single option to go back to All KARL.
    # If we are on all karl already, this knob group
    # will not show at all, defaulting to KARL's legacy
    # behaviour.
    scope_label = request.params.get('scopeLabel', '')
    if scope_path:
        scope_knob = []
        scope_knob.append({
            'name': scope_label,
            'title': scope_label,
            'description': scope_label,
            'icon': None,
            'url': None,
            'selected': True,
        })
        query = params.copy()
        query.update(scopePath='', scopeLabel='All KARL')
        scope_knob.append({
            'name':
            'All KARL',
            'title':
            'All KARL',
            'description':
            'All KARL',
            'icon':
            None,
            'url':
            resource_url(find_root(context),
                         request,
                         request.view_name,
                         query=query),
            'selected':
            False,
        })
    else:
        # The knob will not show at all
        scope_knob = None

    # There is a mapping needed between the livesearch
    # and the advanced search "kind" identifiers. This artifact is
    # a bit of annoyance but it's the easiest to do this
    # transformation here. Previously this was done from js.
    # Currently, if you click on livesearch results to
    # get into the advanced search, the livesearch kinds
    # will be submitted: which is why we convert from here.
    selected_kind = {
        'pages': 'wiki',
        'posts': 'blog',
    }.get(selected_kind, selected_kind)

    # In case we have a calendar search:
    # we will use events only as the content type.
    if calendar_search and selected_kind is None:
        # This means: filter events only in the result.
        selected_kind = 'events'

    for o in get_listitems(IGroupSearchFactory):
        component = o['component']
        if not component.advanced_search:
            continue
        kind = o['name']
        query = params.copy()
        query['kind'] = kind
        kind_knob.append({
            'name':
            kind,
            'title':
            o['title'],
            'icon':
            component.icon,
            'url':
            resource_url(context, request, request.view_name, query=query),
            'selected':
            kind == selected_kind,
        })
    query = params.copy()
    if 'kind' in query:
        del query['kind']
    kind_knob.insert(
        0, {
            'name': 'all_content',
            'title': 'All Content',
            'description': 'All Content',
            'icon': None,
            'url': resource_url(
                context, request, request.view_name, query=query),
            'selected': not selected_kind,
        })

    since_knob = []
    selected_since = params.get('since')
    for id in since_order:
        option = since_options[id].copy()
        query = params.copy()
        if id is not None:
            query['since'] = id
        elif 'since' in query:
            del query['since']
        option['url'] = resource_url(context,
                                     request,
                                     request.view_name,
                                     query=query)
        option['selected'] = id == selected_since
        since_knob.append(option)

    sort_knob = []
    selected_sort = params.get('sort')
    for id in sort_order:
        option = sort_options[id].copy()
        query = params.copy()
        if id is not None:
            query['sort'] = id
        elif 'sort' in query:
            del query['sort']
        option['url'] = resource_url(context,
                                     request,
                                     request.view_name,
                                     query=query)
        option['selected'] = id == selected_sort
        sort_knob.append(option)

    start_time = time.time()
    try:
        batch, terms = get_batch(context, request)
    except ParseError, e:
        error = 'Error: %s' % e
Exemple #25
0
def join_community_view(context, request):
    """ User sends an email to community moderator(s) asking to join
    the community.  Email contains a link to "add_existing" view, in members,
    that a moderator can use to add member to the community.

    """
    assert ICommunity.providedBy(context)

    # Get logged in user
    profiles = find_profiles(context)
    user = authenticated_userid(request)
    profile = profiles[user]

    # first off, see if the community is public, in that case,
    # it does not need to be reviewed to join
    if has_permission('edit', context, request):
        community_users = find_users(context)
        if community_users:
            community_users.add_group(profile.__name__,
                                      context.members_group_name)
            status_message = "You have joined this community!"
            community_href = resource_url(
                context, request, query={"status_message": status_message})
            return HTTPFound(location=community_href)

    # Handle form submission
    if "form.submitted" in request.POST:
        message = request.POST.get("message", "")
        moderators = [profiles[id] for id in context.moderator_names]
        mail = MIMEMultipart('alternative')
        mail["From"] = "%s <%s>" % (profile.title, profile.email)
        mail["To"] = ",".join(
            ["%s <%s>" % (p.title, p.email) for p in moderators])
        mail["Subject"] = "Request to join %s community" % context.title

        body_template = get_renderer(
            "templates/email_join_community.pt").implementation()
        profile_url = resource_url(profile, request)
        accept_url = resource_url(context,
                                  request,
                                  "members",
                                  "add_existing.html",
                                  query={"user_id": user})
        bodyhtml = body_template(message=message,
                                 community_title=context.title,
                                 person_name=profile.title,
                                 profile_url=profile_url,
                                 accept_url=accept_url)
        bodyplain = html2text.html2text(bodyhtml)
        htmlpart = MIMEText(bodyhtml.encode('UTF-8'), 'html', 'UTF-8')
        plainpart = MIMEText(bodyplain.encode('UTF-8'), 'plain', 'UTF-8')
        mail.attach(plainpart)
        mail.attach(htmlpart)

        recipients = [p.email for p in moderators]
        mailer = getUtility(IMailDelivery)
        mailer.send(recipients, mail)

        status_message = "Your request has been sent to the moderators."
        location = resource_url(context,
                                request,
                                query={"status_message": status_message})

        return HTTPFound(location=location)

    # Show form
    page_title = "Join " + context.title
    api = TemplateAPI(context, request, page_title)
    return dict(api=api,
                profile=profile,
                community=context,
                post_url=resource_url(context, request, "join.html"),
                formfields=api.formfields)
Exemple #26
0
 def leave(self, context):
     if ICommunity.providedBy(context):
         assert context is self.community
         self.row['community_tags'] = len(self.row['community_tags'])
         self.rows.append(self.row)
         self.row = self.community = None
Exemple #27
0
def searchresults_view(context, request):
    request.unicode_errors = 'ignore'
    page_title = 'Search Results'
    api = TemplateAPI(context, request, page_title)
    if ICommunity.providedBy(context):
        layout = api.community_layout
        community = context.title
    else:
        layout = api.generic_layout
        community = None

    batch = None
    terms = ()
    error = None
    params = request.params.copy()
    if 'batch_start' in params:
        del params['batch_start']
    if 'batch_size' in params:
        del params['batch_size']

    kind_knob = []
    selected_kind = params.get('kind')
    for o in get_listitems(IGroupSearchFactory):
        component = o['component']
        if not component.advanced_search:
            continue
        kind = o['name']
        query = params.copy()
        query['kind'] = kind
        kind_knob.append({
            'name': kind,
            'title': o['title'],
            'icon': component.icon,
            'url': model_url(context, request, request.view_name,
                             query=query),
            'selected': kind == selected_kind,
        })
    query = params.copy()
    if 'kind' in query:
        del query['kind']
    kind_knob.insert(0, {
        'name': 'all_content',
        'title': 'All Content',
        'description': 'All Content',
        'icon': None,
        'url': model_url(context, request, request.view_name, query=query),
        'selected': not selected_kind,
    })

    since_knob = []
    selected_since = params.get('since')
    for id in since_order:
        option = since_options[id].copy()
        query = params.copy()
        if id is not None:
            query['since'] = id
        elif 'since' in query:
            del query['since']
        option['url'] = model_url(context, request, request.view_name,
                                  query=query)
        option['selected'] = id == selected_since
        since_knob.append(option)

    start_time = time.time()
    try:
        batch, terms = get_batch(context, request)
    except ParseError, e:
        error = 'Error: %s' % e
Exemple #28
0
def join_community_view(context, request):
    """ User sends an email to community moderator(s) asking to join
    the community.  Email contains a link to "add_existing" view, in members,
    that a moderator can use to add member to the community.

    """
    assert ICommunity.providedBy(context)

    # Get logged in user
    profiles = find_profiles(context)
    user = authenticated_userid(request)
    profile = profiles[user]

    # first off, see if the community is public, in that case,
    # it does not need to be reviewed to join
    if has_permission('edit', context, request):
        community_users = find_users(context)
        if community_users:
            community_users.add_group(profile.__name__, context.members_group_name)
            status_message = "You have joined this community!"
            community_href = resource_url(context, request,
                                          query={"status_message": status_message})
            return HTTPFound(location=community_href)

    # Handle form submission
    if "form.submitted" in request.POST:
        message = request.POST.get("message", "")
        moderators = [profiles[id] for id in context.moderator_names]
        mail = MIMEMultipart('alternative')
        mail["From"] = "%s <%s>" % (profile.title, profile.email)
        mail["To"] = ",".join(
            ["%s <%s>" % (p.title, p.email) for p in moderators]
        )
        mail["Subject"] = "Request to join %s community" % context.title

        body_template = get_renderer(
            "templates/email_join_community.pt").implementation()
        profile_url = resource_url(profile, request)
        accept_url = resource_url(
            context, request, "members", "add_existing.html",
            query={"user_id": user})
        bodyhtml = body_template(
            message=message,
            community_title=context.title,
            person_name=profile.title,
            profile_url=profile_url,
            accept_url=accept_url
        )
        bodyplain = html2text.html2text(bodyhtml)
        htmlpart = MIMEText(bodyhtml.encode('UTF-8'), 'html', 'UTF-8')
        plainpart = MIMEText(bodyplain.encode('UTF-8'), 'plain', 'UTF-8')
        mail.attach(plainpart)
        mail.attach(htmlpart)

        recipients = [p.email for p in moderators]
        mailer = getUtility(IMailDelivery)
        mailer.send(recipients, mail)

        status_message = "Your request has been sent to the moderators."
        location = resource_url(
            context, request,
            query={"status_message": status_message})

        return HTTPFound(location=location)

    # Show form
    page_title = "Join " + context.title
    api = TemplateAPI(context, request, page_title)
    return dict(
        api=api,
        profile=profile,
        community=context,
        post_url=resource_url(context, request, "join.html"),
        formfields=api.formfields)
Exemple #29
0
def join_community_view(context, request):
    """ User sends an email to community moderator(s) asking to join
    the community.  Email contains a link to "add_existing" view, in members,
    that a moderator can use to add member to the community.

    """
    assert ICommunity.providedBy(context)

    # Get logged in user
    profiles = find_profiles(context)
    user = authenticated_userid(request)
    profile = profiles[user]

    # Handle form submission
    if "form.submitted" in request.POST:
        message = request.POST.get("message", "")
        moderators = [profiles[id] for id in context.moderator_names]
        mail = Message()
        mail["From"] = "%s <%s>" % (profile.title, profile.email)
        mail["To"] = ",".join(
            ["%s <%s>" % (p.title, p.email) for p in moderators]
        )
        mail["Subject"] = "Request to join %s community" % context.title

        body_template = get_renderer(
            "templates/email_join_community.pt").implementation()
        profile_url = resource_url(profile, request)
        accept_url=resource_url(context, request, "members", "add_existing.html",
                             query={"user_id": user})
        body = body_template(
            message=message,
            community_title=context.title,
            person_name=profile.title,
            profile_url=profile_url,
            accept_url=accept_url
        )

        if isinstance(body, unicode):
            body = body.encode("UTF-8")

        mail.set_payload(body, "UTF-8")
        mail.set_type("text/html")

        recipients = [p.email for p in moderators]
        mailer = getUtility(IMailDelivery)
        mailer.send(recipients, mail)

        status_message = "Your request has been sent to the moderators."
        location = resource_url(context, request,
                             query={"status_message": status_message})

        return HTTPFound(location=location)

    # Show form
    page_title = "Join " + context.title
    api = TemplateAPI(context, request, page_title)
    return dict(api=api,
             profile=profile,
             community=context,
             post_url=resource_url(context, request, "join.html"),
             formfields=api.formfields)
Exemple #30
0
 def __init__(self, context, request):
     assert ICommunity.providedBy(context)
     super(CommunityAtomFeed, self).__init__(context, request)
Exemple #31
0
def _searchresults_view(context, request, page_title, calendar_search, show_search_knobs):
    api = TemplateAPI(context, request, page_title)

    # The layout is decided independently of whether we are a
    # calendar search or not. What is taken in consideration: if we are
    # in a community. The /offices section is considered a non-community
    # and will use the wide layout.
    if ICommunity.providedBy(context):
        if calendar_search:
            # We are either in /communities, or in /offices. In the first case:
            # we use the community layout. For offices: we need the wide layout
            # with the generic layout.
            context_path = resource_path(context)
            wide = context_path.startswith('/offices')
            if wide:
                layout = api.generic_layout
            else:
                layout = api.community_layout
        else:
            layout = api.community_layout
        community = context.title
    else:
        layout = api.generic_layout
        community = None

    request.unicode_errors = 'ignore'
    batch = None
    terms = ()
    error = None
    params = request.params.copy()
    if 'batch_start' in params:
        del params['batch_start']
    if 'batch_size' in params:
        del params['batch_size']

    kind_knob = []
    selected_kind = params.get('kind')

    # In case we have a calendar search:
    # we will use events only as the content type.
    if calendar_search and selected_kind is None:
        # This means: filter events only in the result.
        selected_kind = 'events'

    for o in get_listitems(IGroupSearchFactory):
        component = o['component']
        if not component.advanced_search:
            continue
        kind = o['name']
        query = params.copy()
        query['kind'] = kind
        kind_knob.append({
            'name': kind,
            'title': o['title'],
            'icon': component.icon,
            'url': resource_url(context, request, request.view_name,
                             query=query),
            'selected': kind == selected_kind,
        })
    query = params.copy()
    if 'kind' in query:
        del query['kind']
    kind_knob.insert(0, {
        'name': 'all_content',
        'title': 'All Content',
        'description': 'All Content',
        'icon': None,
        'url': resource_url(context, request, request.view_name, query=query),
        'selected': not selected_kind,
    })

    since_knob = []
    selected_since = params.get('since')
    for id in since_order:
        option = since_options[id].copy()
        query = params.copy()
        if id is not None:
            query['since'] = id
        elif 'since' in query:
            del query['since']
        option['url'] = resource_url(context, request, request.view_name,
                                  query=query)
        option['selected'] = id == selected_since
        since_knob.append(option)

    sort_knob = []
    selected_sort = params.get('sort')
    for id in sort_order:
        option = sort_options[id].copy()
        query = params.copy()
        if id is not None:
            query['sort'] = id
        elif 'sort' in query:
            del query['sort']
        option['url'] = resource_url(context, request, request.view_name,
                                  query=query)
        option['selected'] = id == selected_sort
        sort_knob.append(option)

    start_time = time.time()
    try:
        batch, terms = get_batch(context, request)
    except ParseError, e:
        error = 'Error: %s' % e
Exemple #32
0
 def __init__(self, context, request):
     assert ICommunity.providedBy(context)
     super(CommunityAtomFeed, self).__init__(context, request)
Exemple #33
0
def scrub(site):
    """
    Given root, find content with HTML body, look for bad links or other
    errors.

    """

    searcher = ICatalogSearch(site)
    total, docids, resolver = searcher(interfaces=[IContent], )

    log.info("Found a total of %d documents", total)
    for docid in docids:
        doc = resolver(docid)

        if not hasattr(doc, 'text'):
            continue

        path = model_path(doc)
        log.debug("Checking %s", path)

        text = doc.text

        if not text:
            # Some types we're expecting not to have text, so don't warn
            # about those
            if not (ICommunity.providedBy(doc)
                    or ICalendarEvent.providedBy(doc)):
                log.warn("No text: %s %s", type(doc), path)
            continue

        try:
            try:
                # Will throw ParserError if fragment doesn't have a single
                # root element.
                html = fragment_fromstring(doc.text)
            except ParserError:
                # Wrap in a single div to make the parser happy
                html = fragment_fromstring('<div>%s</div>' % doc.text)

        except XMLSyntaxError:
            log.error("Unparseable: %s", path, exc_info=True)

        # Check and fix links
        def callback(link):
            fixed = _rewrite_link(site, path, link)
            if fixed != link:
                log.info("Link rewritten at %s", path)
                log.info("Old link: %s", link)
                log.info("New link: %s", fixed)

            if not isinstance(fixed, unicode):
                fixed = unicode(fixed, 'utf-8')

            return fixed

        html.rewrite_links(callback)

        # Need to also change any instances of the 'mce_href' attribute to
        # match newly rewritten 'href' attribute.
        for element in html.getiterator():
            if 'mce_href' in element.keys():
                element.set('mce_href', element.get('href'))

        doc.text = unicode(lxml.html.tostring(html, 'utf-8'), 'utf-8')

    log.info("Done.")
    log.info("Unknown schemes: %s", ', '.join(unknown_schemes))
Exemple #34
0
def join_community_view(context, request):
    """ User sends an email to community moderator(s) asking to join
    the community.  Email contains a link to "add_existing" view, in members,
    that a moderator can use to add member to the community.

    """
    assert ICommunity.providedBy(context)

    # Get logged in user
    profiles = find_profiles(context)
    user = authenticated_userid(request)
    profile = profiles[user]

    # Handle form submission
    if "form.submitted" in request.POST:
        message = request.POST.get("message", "")
        moderators = [profiles[id] for id in context.moderator_names]
        mail = Message()
        mail["From"] = "%s <%s>" % (profile.title, profile.email)
        mail["To"] = ",".join(
            ["%s <%s>" % (p.title, p.email) for p in moderators])
        mail["Subject"] = "Request to join %s community" % context.title

        body_template = get_renderer(
            "templates/email_join_community.pt").implementation()
        profile_url = resource_url(profile, request)
        accept_url = resource_url(context,
                                  request,
                                  "members",
                                  "add_existing.html",
                                  query={"user_id": user})
        body = body_template(message=message,
                             community_title=context.title,
                             person_name=profile.title,
                             profile_url=profile_url,
                             accept_url=accept_url)

        if isinstance(body, unicode):
            body = body.encode("UTF-8")

        mail.set_payload(body, "UTF-8")
        mail.set_type("text/html")

        recipients = [p.email for p in moderators]
        mailer = getUtility(IMailDelivery)
        mailer.send(recipients, mail)

        status_message = "Your request has been sent to the moderators."
        location = resource_url(context,
                                request,
                                query={"status_message": status_message})

        return HTTPFound(location=location)

    # Show form
    page_title = "Join " + context.title
    api = TemplateAPI(context, request, page_title)
    return dict(api=api,
                profile=profile,
                community=context,
                post_url=resource_url(context, request, "join.html"),
                formfields=api.formfields)
Exemple #35
0
def _searchresults_view(context, request, page_title, calendar_search, show_search_knobs):
    api = TemplateAPI(context, request, page_title)

    # The layout is decided independently of whether we are a
    # calendar search or not. What is taken in consideration: if we are
    # in a community. The /offices section is considered a non-community
    # and will use the wide layout.
    if ICommunity.providedBy(context):
        if calendar_search:
            # We are either in /communities, or in /offices. In the first case:
            # we use the community layout. For offices: we need the wide layout
            # with the generic layout.
            context_path = resource_path(context)
            wide = context_path.startswith('/offices')
            if wide:
                layout = api.generic_layout
            else:
                layout = api.community_layout
        else:
            layout = api.community_layout
        community = context.title
    else:
        layout = api.generic_layout
        community = None

    request.unicode_errors = 'ignore'
    batch = None
    terms = ()
    error = None
    params = request.params.copy()
    if 'batch_start' in params:
        del params['batch_start']
    if 'batch_size' in params:
        del params['batch_size']

    kind_knob = []
    selected_kind = params.get('kind')

    scope_path = request.params.get('scopePath', '')

    # We show the scope knob, but in a limited way.
    # We only have a path here, so we show that path
    # and a single option to go back to All KARL.
    # If we are on all karl already, this knob group
    # will not show at all, defaulting to KARL's legacy
    # behaviour.
    scope_label = request.params.get('scopeLabel', '')
    if scope_path:
        scope_knob = []
        scope_knob.append({
            'name': scope_label,
            'title': scope_label,
            'description': scope_label,
            'icon': None,
            'url': None,
            'selected': True,
        })
        query = params.copy()
        query.update(scopePath='', scopeLabel='All KARL')
        scope_knob.append({
            'name': 'All KARL',
            'title': 'All KARL',
            'description': 'All KARL',
            'icon': None,
            'url': resource_url(find_root(context), request, request.view_name, query=query),
            'selected': False,
        })
    else:
        # The knob will not show at all
        scope_knob = None

    # There is a mapping needed between the livesearch
    # and the advanced search "kind" identifiers. This artifact is
    # a bit of annoyance but it's the easiest to do this
    # transformation here. Previously this was done from js.
    # Currently, if you click on livesearch results to
    # get into the advanced search, the livesearch kinds
    # will be submitted: which is why we convert from here.
    selected_kind = {
        'pages': 'wiki',
        'posts': 'blog',
        }.get(selected_kind, selected_kind)

    # In case we have a calendar search:
    # we will use events only as the content type.
    if calendar_search and selected_kind is None:
        # This means: filter events only in the result.
        selected_kind = 'events'

    for o in get_listitems(IGroupSearchFactory):
        component = o['component']
        if not component.advanced_search:
            continue
        kind = o['name']
        query = params.copy()
        query['kind'] = kind
        kind_knob.append({
            'name': kind,
            'title': o['title'],
            'icon': component.icon,
            'url': resource_url(context, request, request.view_name,
                             query=query),
            'selected': kind == selected_kind,
        })
    query = params.copy()
    if 'kind' in query:
        del query['kind']
    kind_knob.insert(0, {
        'name': 'all_content',
        'title': 'All Content',
        'description': 'All Content',
        'icon': None,
        'url': resource_url(context, request, request.view_name, query=query),
        'selected': not selected_kind,
    })

    since_knob = []
    selected_since = params.get('since')
    for id in since_order:
        option = since_options[id].copy()
        query = params.copy()
        if id is not None:
            query['since'] = id
        elif 'since' in query:
            del query['since']
        option['url'] = resource_url(context, request, request.view_name,
                                  query=query)
        option['selected'] = id == selected_since
        since_knob.append(option)

    sort_knob = []
    selected_sort = params.get('sort')
    for id in sort_order:
        option = sort_options[id].copy()
        query = params.copy()
        if id is not None:
            query['sort'] = id
        elif 'sort' in query:
            del query['sort']
        option['url'] = resource_url(context, request, request.view_name,
                                  query=query)
        option['selected'] = id == selected_sort
        sort_knob.append(option)

    start_time = time.time()
    try:
        batch, terms = get_batch(context, request)
    except ParseError, e:
        error = 'Error: %s' % e