Ejemplo n.º 1
0
    def get(self, request, *args, **kwargs):
        # `kwargs` will be used as `nav_param` so extract channel_oid from `kwargs` instead of creating param.
        channel_oid_str = kwargs.get("channel_oid", "")
        channel_oid = safe_cast(channel_oid_str, ObjectId)
        u_profs = ProfileManager.get_user_profiles(channel_oid, get_root_oid(request))

        if u_profs:
            return render_template(
                self.request, _("Channel Management - {}").format(channel_oid), "account/channel/manage.html", {
                    "user_profiles": u_profs,
                    "perm_sum": sorted(ProfileManager.get_permissions(u_profs), key=lambda x: x.code),
                    "channel_oid": channel_oid
                }, nav_param=kwargs)
        else:
            c_prof = ChannelManager.get_channel_oid(channel_oid)

            if c_prof:
                messages.info(
                    request, _("You are redirected to the channel info page "
                               "because you don't have any connections linked to the channel."),
                    extra_tags="info"
                )

                return redirect(reverse("info.channel", kwargs={"channel_oid": channel_oid}))
            else:
                return WebsiteErrorView.website_error(
                    request, WebsiteError.PROFILE_LINK_NOT_FOUND, {"channel_oid": channel_oid_str})
Ejemplo n.º 2
0
    def collate_child_channel_data(root_oid: ObjectId, child_channel_oids: List[ObjectId]) \
            -> List[CollatedChannelData]:
        accessible: List[CollatedChannelData] = []
        inaccessible: List[CollatedChannelData] = []

        missing_oids = []

        for ccoid in child_channel_oids:
            cdata = ChannelManager.get_channel_oid(ccoid)

            if cdata:
                ccd = CollatedChannelData(
                    channel_name=cdata.get_channel_name(root_oid),
                    channel_data=cdata)

                if cdata.bot_accessible:
                    accessible.append(ccd)
                else:
                    inaccessible.append(ccd)
            else:
                missing_oids.append(ccoid)

        if missing_oids:
            MailSender.send_email_async(
                f"No associated channel data found of the channel IDs below:<br>"
                f"<pre>{' / '.join([str(oid) for oid in missing_oids])}</pre>")

        accessible = sorted(accessible,
                            key=lambda data: data.channel_data.id,
                            reverse=True)
        inaccessible = sorted(inaccessible,
                              key=lambda data: data.channel_data.id,
                              reverse=True)

        return accessible + inaccessible
Ejemplo n.º 3
0
    def get(self, request, **kwargs):
        profile_result = get_profile_data(kwargs)

        if not profile_result.ok:
            return WebsiteErrorView.website_error(
                request, WebsiteError.PROFILE_NOT_FOUND,
                {"profile_oid": profile_result.oid_org})

        root_oid = get_root_oid(request)
        profile_model = profile_result.model

        channel_model = ChannelManager.get_channel_oid(
            profile_model.channel_oid)
        permissions = ProfileManager.get_user_permissions(
            channel_model.id, root_oid)

        # noinspection PyTypeChecker
        return render_template(
            request,
            _("Profile Info - {}").format(profile_model.name),
            "info/profile.html", {
                "profile_data":
                profile_model,
                "profile_controls":
                ProfileHelper.get_user_profile_controls(
                    channel_model, profile_model.id, root_oid, permissions),
                "perm_cats":
                list(ProfilePermission),
                "is_default":
                profile_model.id == channel_model.config.default_profile_oid
            },
            nav_param=kwargs)
Ejemplo n.º 4
0
def get_channel_data(kwargs) -> ChannelDataGetResult:
    channel_oid_str = kwargs.get("channel_oid", "")
    channel_oid = safe_cast(channel_oid_str, ObjectId)

    model = ChannelManager.get_channel_oid(channel_oid)

    return ChannelDataGetResult(ok=model is not None, model=model, oid_org=channel_oid_str)
Ejemplo n.º 5
0
    def get_channel_profiles(
            channel_oid: ObjectId,
            partial_name: Optional[str] = None) -> List[ChannelProfileEntry]:
        ret = []

        # Get channel profiles. Terminate if no available profiles
        profs = list(
            ProfileManager.get_channel_profiles(channel_oid, partial_name))
        if not profs:
            return ret

        # Get channel data. Terminate if no channel data found
        channel_model = ChannelManager.get_channel_oid(channel_oid)
        if not channel_model:
            return ret

        # Get user names, and the prof-channel dict
        user_oids_dict = ProfileManager.get_profiles_user_oids(
            [prof.id for prof in profs])
        user_oids = []
        for k, v in user_oids_dict.items():
            user_oids.extend(v)
        user_names = IdentitySearcher.get_batch_user_name(user_oids,
                                                          channel_model,
                                                          on_not_found=None)

        for prof in profs:
            uids = user_oids_dict.get(prof.id, [])

            ret.append(
                ChannelProfileEntry(prof,
                                    [user_names.get(uid) for uid in uids]))

        return ret
Ejemplo n.º 6
0
    def get_default_profile(self, channel_oid: ObjectId) -> GetPermissionProfileResult:
        """
        Automatically creates a default profile for `channel_oid` if not exists.
        """
        ex = None

        cnl = ChannelManager.get_channel_oid(channel_oid)
        if not cnl:
            return GetPermissionProfileResult(GetOutcome.X_CHANNEL_NOT_FOUND, None, ex)

        try:
            prof_oid = cnl.config.default_profile_oid
        except AttributeError:
            return GetPermissionProfileResult(GetOutcome.X_CHANNEL_CONFIG_ERROR, None, ex)

        if not cnl.config.is_field_none("DefaultProfileOid"):
            perm_prof = self.find_one_casted({OID_KEY: prof_oid}, parse_cls=ChannelProfileModel)

            if perm_prof:
                return GetPermissionProfileResult(GetOutcome.O_CACHE_DB, perm_prof, ex)

        create_result = self.create_default_profile(channel_oid)

        return GetPermissionProfileResult(
            GetOutcome.O_ADDED if create_result.success else GetOutcome.X_DEFAULT_PROFILE_ERROR,
            create_result.model, ex)
Ejemplo n.º 7
0
    def get_attachable_profiles(self, channel_oid: ObjectId, root_uid: ObjectId) -> List[ChannelProfileModel]:
        profiles = self.get_user_profiles(channel_oid, root_uid)
        exist_perm = self.get_permissions(profiles)
        highest_perm = self.get_highest_permission_level(profiles)
        attachables = {prof.id: prof
                       for prof in self._prof.get_attachable_profiles(channel_oid, exist_perm, highest_perm)}

        # Remove default profile
        channel_data = ChannelManager.get_channel_oid(channel_oid)
        del attachables[channel_data.config.default_profile_oid]

        return list(attachables.values())
Ejemplo n.º 8
0
    def _trans_ar_search_(model: ExtraContentModel) -> str:
        from mongodb.factory import ChannelManager, AutoReplyManager
        from mongodb.helper import IdentitySearcher

        # Early termination for falsy or not-an-array content
        if not model.content or not isinstance(model.content, list):
            return ""

        tab_list: List[str] = []
        tab_content: List[str] = []

        module_list = list(AutoReplyManager.get_conn_list_oids(model.content))

        uids = []
        for module in module_list:
            uids.append(module.creator_oid)
            if not module.active and module.remover_oid:
                uids.append(module.remover_oid)

        username_dict = {}
        if model.channel_oid:
            username_dict = IdentitySearcher.get_batch_user_name(
                uids, ChannelManager.get_channel_oid(model.channel_oid))

        for module in module_list:
            common_key = f"msg-{id(module)}"
            content = loader.render_to_string("ar/module-card.html", {
                "username_dict": username_dict,
                "module": module
            })

            tab_list.append(
                f'<a class="list-group-item list-group-item-action" '
                f'id="list-{common_key}" '
                f'data-toggle="list" href="#{common_key}" role="tab">{module.keyword.content_html}</a>'
            )
            tab_content.append(
                f'<div class="tab-pane fade" id="{common_key}" role="tabpanel" '
                f'aria-labelledby="list-{common_key}">{content}</div>')

        return f'<div class="row">' \
               f'<div class="col-4"><div class="list-group" id="list-tab" role="tablist">{"".join(tab_list)}' \
               f'</div></div>' \
               f'<div class="col-8"><div class="tab-content" id="nav-tabContent">{"".join(tab_content)}</div>' \
               f'</div></div>'
Ejemplo n.º 9
0
    def post(self, request, **kwargs):
        sender_oid = get_root_oid(request)

        profile_result = get_profile_data(kwargs)

        if not profile_result.ok:
            return HttpResponse(status=404)

        channel_model = ChannelManager.get_channel_oid(
            profile_result.model.channel_oid)

        # --- Get form data

        action = InfoPageActionControl.parse(request.POST.get("action"))
        target_uid = safe_cast(request.POST.get("uid"), ObjectId)

        if not action.is_argument_valid(target_uid):
            return HttpResponse(status=400)

        # --- Check permission

        permissions = ProfileManager.get_user_permissions(
            channel_model.id, sender_oid)

        # --- Execute corresponding action

        profile_oid = profile_result.model.id

        if action == InfoPageActionControl.DETACH:
            return InfoPageActionControl.action_detach(request,
                                                       channel_model.id,
                                                       sender_oid, target_uid,
                                                       permissions,
                                                       profile_oid)
        elif action == InfoPageActionControl.DELETE:
            return InfoPageActionControl.action_delete(request, channel_model,
                                                       profile_oid)
        else:
            return HttpResponse(status=501)
Ejemplo n.º 10
0
    def search_channel(
            keyword: str,
            root_oid: Optional[ObjectId] = None) -> List[ChannelData]:
        """The keyword could be
        - A piece of the message comes from a channel
        - The name of the channel"""
        checked_choid: Set[ObjectId] = set()
        ret: List[ChannelData] = []
        missing = []

        for ch_model in ChannelManager.get_channel_default_name(
                keyword, hide_private=True):
            checked_choid.add(ch_model.id)
            ret.append(
                ChannelData(ch_model, ch_model.get_channel_name(root_oid)))

        for channel_oid in MessageRecordStatisticsManager.get_messages_distinct_channel(
                keyword):
            if channel_oid not in checked_choid:
                checked_choid.add(channel_oid)
                ch_model = ChannelManager.get_channel_oid(channel_oid,
                                                          hide_private=True)

                if ch_model:
                    ret.append(
                        ChannelData(ch_model,
                                    ch_model.get_channel_name(root_oid)))
                else:
                    missing.append(channel_oid)

        if missing:
            MailSender.send_email_async(
                f"Channel OID have no corresponding channel data in message record.\n"
                f"{' | '.join([str(i) for i in missing])}",
                subject="Missing Channel Data")

        return ret
Ejemplo n.º 11
0
    def target_channel(self):
        from mongodb.factory import ChannelManager

        return ChannelManager.get_channel_oid(self.target_channel_oid)