Ejemplo n.º 1
0
    def get(self, request, *args, **kwargs):
        channel_data = self.get_channel_data(*args, **kwargs)
        chcoll_data: Optional[ChannelCollectionModel] = \
            ChannelCollectionManager.get_chcoll_child_channel(channel_data.model.id)

        root_oid = get_root_oid(request)
        channel_name = channel_data.model.get_channel_name(root_oid)

        msgdata_1d = MessageStatsDataProcessor.get_user_channel_messages(channel_data.model, hours_within=24)
        msgdata_7d = MessageStatsDataProcessor.get_user_channel_messages(channel_data.model, hours_within=168)
        member_info = InfoProcessor.get_member_info(channel_data.model)

        return render_template(
            self.request, _("Channel Info - {}").format(channel_name), "info/channel/main.html",
            {
                "channel_name": channel_name,
                "channel_data": channel_data.model,
                "chcoll_data": chcoll_data,
                "user_message_data1d": msgdata_1d,
                "user_message_data7d": msgdata_7d,
                "member_info": member_info,
                "manageable": bool(ProfileManager.get_user_profiles(channel_data.model.id, root_oid)),
                "bot_usage_7d": BotFeatureUsageDataManager.get_channel_usage(channel_data.model.id, hours_within=168),
                "bot_usage_all": BotFeatureUsageDataManager.get_channel_usage(channel_data.model.id)
            },
            nav_param=kwargs)
Ejemplo n.º 2
0
def render_template(request, title, template_name, context=None, content_type=None, status=None,
                    using=None, nav_param=None) -> HttpResponse:
    if context is None:
        context = dict()
    if nav_param is None:
        nav_param = dict()

    # Append variable for base template
    context["title"] = title

    # Append navigation bar items
    nav = construct_nav(request, nav_param)
    context["nav_bar_html"] = nav.to_html()
    context["nav_bread"] = nav.to_bread()
    context["static_keys_result"] = result
    context["static_keys_param"] = param

    # Append user id vars
    context["api_token"] = request.COOKIES.get(keys.Cookies.USER_TOKEN)
    context["root_oid"] = get_root_oid(request)

    # Append version numbers for footer
    context["boot_dt"] = timezone.localtime(get_boot_dt()).strftime("%m/%d %H:%M (UTC%z)")

    return render(request, template_name, context, content_type, status, using)
Ejemplo n.º 3
0
    def process_request(self, request):
        root_oid = get_root_oid(request)

        if root_oid is None:
            timezone.activate(default_locale.to_tzinfo())
        else:
            timezone.activate(RootUserManager.get_tzinfo_root_oid(root_oid))
Ejemplo n.º 4
0
    def get(self, request, *args, **kwargs):
        keyword = request.GET.get("w")
        include_inactive = safe_cast(request.GET.get("include_inactive"), bool)

        channel_data = self.get_channel_data(*args, **kwargs)
        channel_name = channel_data.model.get_channel_name(
            get_root_oid(request))

        module_list = list(
            AutoReplyManager.get_conn_list(channel_data.model.id, keyword,
                                           not include_inactive))

        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 = IdentitySearcher.get_batch_user_name(
            uids, channel_data.model, on_not_found="")

        return render_template(
            request,
            _("Auto-Reply search in {}").format(channel_name),
            "ar/search-main.html", {
                "channel_name": channel_name,
                "channel_oid": channel_data.model.id,
                "module_list": module_list,
                "username_dict": username_dict,
                "include_inactive": include_inactive,
                "keyword": keyword or ""
            },
            nav_param=kwargs)
Ejemplo n.º 5
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.º 6
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.º 7
0
    def process_response(self, request, response):
        api_action = request.session.pop(Session.APIStatisticsCollection.API_ACTION,
                                         APIStatisticModel.ApiAction.default_value)
        dict_response = request.session.pop(Session.APIStatisticsCollection.DICT_RESPONSE,
                                            APIStatisticModel.Response.default_value)
        dict_params = request.session.pop(Session.APIStatisticsCollection.DICT_PARAMS,
                                          APIStatisticModel.Parameter.default_value)
        success = request.session.pop(Session.APIStatisticsCollection.SUCCESS,
                                      APIStatisticModel.Success.default_value
                                      if dict_params is None
                                      else dict_params.get(
                                          result.SUCCESS, APIStatisticModel.Success.default_value))
        collect = request.session.pop(Session.APIStatisticsCollection.COLLECT, False)

        path_params = None
        if request.method == "GET":
            path_params = request.GET
        elif request.method == "POST":
            path_params = request.POST

        if collect:
            rec_result = APIStatisticsManager.record_stats(
                api_action, get_root_oid(request), dict_response, dict_params, success, path_params,
                request.path_info, request.get_full_path_info()
            )

            if settings.DEBUG and not rec_result.success:
                if rec_result.exception is None:
                    raise RuntimeError(f"Stats not recorded. Result: {repr(rec_result.serialize())}")
                else:
                    raise rec_result.exception

        return response
Ejemplo n.º 8
0
    def get(self, request, *args, **kwargs):
        root_uid = get_root_oid(request)

        return render_template(
            request, _("Add an Auto-Reply module"), "ar/add.html", {
                "max_responses":
                AutoReply.MaxResponses,
                "max_length":
                AutoReply.MaxContentLength,
                "platform_list":
                list(Platform),
                "contenttype_list_kw": [
                    t for t in list(AutoReplyContentType)
                    if t != AutoReplyContentType.IMAGE
                ],
                "contenttype_list_rep":
                list(AutoReplyContentType),
                "tag_splitter":
                AutoReply.TagSplitter,
                "user_ch_list":
                ProfileManager.get_user_channel_profiles(
                    root_uid, inside_only=True, accessbible_only=True),
                "root_uid_str":
                str(root_uid),
                "perm_pin_access":
                ProfilePermission.AR_ACCESS_PINNED_MODULE.code,
                "oid_key":
                OID_KEY
            })
Ejemplo n.º 9
0
    def post(self, request, *args, **kwargs):
        if not self.post_response_specified:
            return HttpResponseNotAllowed(self.allowed_response_classes)
        else:
            response_api = self.__class__.post_response_class(request.POST, get_root_oid(request))

            return self.process_api_response(request, response_api, *args, **kwargs)
Ejemplo n.º 10
0
    def get(self, request, *args, **kwargs):
        root_uid = get_root_oid(request)

        return render_template(
            request, _("Auto-Reply ranking channel list"), "ar/rk-chlist.html",
            {
                "channel_list": ProfileManager.get_user_channel_profiles(
                    root_uid, inside_only=True, accessbible_only=True)
            }, nav_param=kwargs)
Ejemplo n.º 11
0
    def get(self, request, *args, **kwargs):
        config = RootUserManager.get_config_root_oid(get_root_oid(request))

        return render_template(
            self.request, _("Account Settings"), "account/settings.html", {
                "locale_list": sorted(locales,
                                      key=lambda item: item.description),
                "lang_list": sorted(languages, key=lambda item: item.code),
                "current_config": config
            })
Ejemplo n.º 12
0
    def get(self, request, *args, **kwargs):
        keyword = request.GET.get("w", "")
        channel_list = []

        if keyword:
            channel_list = IdentitySearcher.search_channel(keyword, get_root_oid(request))

        return render_template(
            self.request, _("Channel Info Search"), "info/channel/search.html",
            {"channel_list": channel_list, "keyword": keyword}, nav_param=kwargs)
Ejemplo n.º 13
0
    def get(self, request, *args, **kwargs):
        channel_data = self.get_channel_data(*args, **kwargs)

        hours_within = safe_cast(request.GET.get("hours_within"), int)
        incl_unav = safe_cast(request.GET.get("incl_unav"), bool)
        period_count = safe_cast(request.GET.get("period"), int) or Website.Message.DefaultPeriodCount
        if period_count <= 0:
            messages.warning(request, _("Period count cannot be less than or equal to 0."))
            period_count = Website.Message.DefaultPeriodCount

        # Get starting timestamp
        dt_start = self.get_timestamp(
            request, "start",
            msg_parse_failed=_("Failed to parse the starting timestamp. Received: {}"),
            msg_out_of_range=_("Start time out of range.")
        )

        # Get ending timestamp
        dt_end = self.get_timestamp(
            request, "end",
            msg_parse_failed=_("Failed to parse the ending timestamp. Received: {}"),
            msg_out_of_range=_("End time out of range.")
        )

        # Check starting and ending timestamp
        if dt_start and dt_end and dt_start > dt_end:
            dt_start = None
            dt_end = None
            messages.warning(
                request, _("Invalid timestamp: Ending time is before the starting time."))

        channel_name = channel_data.model.get_channel_name(get_root_oid(request))

        pkg = get_msg_stats_data_package(
            channel_data.model, get_current_timezone(), incl_unav,
            hours_within=hours_within, start=dt_start, end=dt_end, period_count=period_count)

        hours_within = pkg[KEY_MSG_INTV_FLOW].hr_range or hours_within
        msg_count = pkg[KEY_MSG_USER_CHANNEL].msg_count

        ctxt = {
            "channel_name": channel_name,
            "channel_data": channel_data.model,
            "hr_range": hours_within,
            "dt_start": dt_start.replace(tzinfo=None).isoformat() if dt_start else "",
            "dt_end": dt_end.replace(tzinfo=None).isoformat() if dt_end else "",
            "message_frequency": (hours_within * 3600) / msg_count if msg_count > 0 else 0,
            "incl_unav": incl_unav,
            "period_count": period_count
        }
        ctxt.update(pkg)

        return render_template(
            self.request, _("Channel Message Stats - {}").format(channel_name),
            "info/msgstats/main.html", ctxt, nav_param=kwargs)
Ejemplo n.º 14
0
    def process_request(self, request):
        root_oid = get_root_oid(request)

        if root_oid:
            l_code = RootUserManager.get_lang_code_root_oid(root_oid)

            if l_code:
                activate(l_code)
                return

        deactivate()
Ejemplo n.º 15
0
    def post(self, request, *args, **kwargs):
        data = get_post_keys(request.POST)
        root_uid = get_root_oid(request)

        model = ProfileManager.register_new(root_uid, ProfileManager.process_create_profile_kwargs(data))

        if model:
            messages.info(request, _("Profile successfully created."))
        else:
            messages.warning(request, _("Failed to create the profile."))

        return redirect(reverse("info.profile", kwargs={"profile_oid": model.id}))
Ejemplo n.º 16
0
    def post(self, request, *args, **kwargs):
        update_result = RootUserManager.update_config(
            get_root_oid(request), **get_post_keys(request.POST))

        if update_result.success:
            return simple_str_response(
                request,
                f"success/{localtime(now_utc_aware()):%m-%d %H:%M:%S (%Z)} - "
                f"{_('Account settings updated.')}")
        else:
            return simple_str_response(
                request,
                f"danger/{localtime(now_utc_aware()):%m-%d %H:%M:%S (%Z)} - "
                f"{_('Account settings failed to update.')}")
Ejemplo n.º 17
0
    def get(self, request, *args, **kwargs):
        channel_result = self.get_channel_data(*args, **kwargs)

        permissions = ProfileManager.get_user_permissions(channel_result.model.id, get_root_oid(request))
        can_ced_profile = ProfilePermission.PRF_CED in permissions

        return render_template(
            self.request, _("List Profile"), "account/channel/prof/list.html",
            {
                "prof_entry": ProfileHelper.get_channel_profiles(channel_result.model.id),
                "perm_cats": list(ProfilePermission),
                "can_ced_profile": can_ced_profile,
                "channel_oid": channel_result.model.id
            }, nav_param=kwargs)
Ejemplo n.º 18
0
    def get(self, request, *args, **kwargs):
        root_oid = get_root_oid(request)
        channel_data = self.get_channel_data(*args, **kwargs)
        profiles = ProfileManager.get_user_profiles(channel_data.model.id, root_oid)
        max_perm_lv = ProfileManager.get_highest_permission_level(profiles)

        return render_template(
            self.request, _("Create Profile"), "account/channel/prof/create.html",
            {
                "channel_oid": channel_data.model.id,
                "max_perm_lv": max_perm_lv,
                "perm_cats_controllable": ProfilePermissionDefault.get_overridden_permissions(max_perm_lv),
                "perm_cats": list(ProfilePermission),
                "value_color": ColorFactory.DEFAULT.color_hex
            }, nav_param=kwargs)
Ejemplo n.º 19
0
    def get(self, request, *args, **kwargs):
        root_oid = get_root_oid(request)
        if root_oid and now_utc_aware() - root_oid.generation_time < timedelta(
                days=Website.NewRegisterThresholdDays):
            messages.info(
                request,
                _('It seems that you haven\'t integrate your account. '
                  'Visit <a href="{}{}">this page</a> to know what to do to fully utilize this bot!'
                  ).format(
                      HostUrl,
                      reverse("page.doc.botcmd.cmd",
                              kwargs={"code": cmd_uintg.main_cmd_code})),
                extra_tags="safe")

        return render_template(request, _("Home Page"), "index.html")
Ejemplo n.º 20
0
    def dispatch(self, request, *args, **kwargs):
        root_oid = get_root_oid(request)

        pass_ = ProfileManager.get_user_permissions(self.get_channel_data(*args, **kwargs).model.id, root_oid)\
            .issuperset(self.required_permission())

        if not pass_:
            return WebsiteErrorView.website_error(
                request,
                WebsiteError.INSUFFICIENT_PERMISSION, {
                    "channel_oid": self.get_channel_data(*args, **
                                                         kwargs).oid_org,
                    "required_permission": self.required_permission()
                },
                nav_param=kwargs)
        else:
            return super().dispatch(request, *args, **kwargs)
Ejemplo n.º 21
0
    def get(self, request, *args, **kwargs):
        root_oid = get_root_oid(request)

        access_ok = []
        access_no = []
        for channel_conn in ProfileManager.get_user_channel_profiles(root_oid, accessbible_only=False):
            if channel_conn.channel_data.bot_accessible:
                access_ok.append(channel_conn)
            else:
                access_no.append(channel_conn)

        return render_template(
            self.request, _("Channel List"), "account/channel/list.html", {
                "conn_access_ok": access_ok,
                "conn_access_no": access_no,
                "bot_cmd_info_code": cmd_id.main_cmd_code
            })
Ejemplo n.º 22
0
    def get(self, request, *args, **kwargs):
        root_oid = get_root_oid(request)
        channel_data = self.get_channel_data(*args, **kwargs)
        channel_oid = channel_data.model.id

        attach_member = ProfileManager.can_control_profile_member(
            ProfileManager.get_user_permissions(channel_oid, root_oid))

        member_list = {}
        if attach_member:
            member_list = IdentitySearcher.get_batch_user_name(
                ProfileManager.get_channel_member_oids(channel_oid, available_only=True), channel_data.model)
            member_list = sorted(member_list.items(), key=lambda item: item[1])

        return render_template(
            self.request, _("Attach Profile"), "account/channel/prof/attach.html",
            {
                "channel_oid": channel_oid,
                "attachable_profiles": ProfileManager.get_attachable_profiles(channel_data.model.get_oid(), root_oid),
                "member_list": member_list
            }, nav_param=kwargs)
Ejemplo n.º 23
0
    def get(self, request, *args, **kwargs):
        # `kwargs` will be used as `nav_param` so extract chcoll_oid from `kwargs` instead of creating param.

        # `chcoll_oid` may be misformatted.
        # If so, `safe_cast` will yield `None` while the original parameter needs to be kept for the case of not found.
        chcoll_oid_str = kwargs.get("chcoll_oid", "")
        chcoll_oid = safe_cast(chcoll_oid_str, ObjectId)

        chcoll_data: Optional[
            ChannelCollectionModel] = ChannelCollectionManager.get_chcoll_oid(
                chcoll_oid)

        if not chcoll_data:
            return WebsiteErrorView.website_error(
                request,
                WebsiteError.CHANNEL_COLLECTION_NOT_FOUND,
                {"chcoll_oid": chcoll_oid_str},
                nav_param=kwargs)

        msgdata_1d = MessageStatsDataProcessor.get_user_chcoll_messages(
            chcoll_data, hours_within=24)
        msgdata_7d = MessageStatsDataProcessor.get_user_chcoll_messages(
            chcoll_data, hours_within=168)

        return render_template(
            self.request,
            _("Channel Collection Info - {}").format(chcoll_oid),
            "info/chcoll/main.html", {
                "chcoll_data":
                chcoll_data,
                "chcoll_cch_data":
                InfoProcessor.collate_child_channel_data(
                    get_root_oid(request), chcoll_data.child_channel_oids),
                "user_message_data1d":
                msgdata_1d,
                "user_message_data7d":
                msgdata_7d
            },
            nav_param=kwargs)
Ejemplo n.º 24
0
    def get(self, request, *args, **kwargs):
        channel_data = self.get_channel_data(*args, **kwargs)

        # Check if the user is in the channel
        root_oid = get_root_oid(request)
        profs = ProfileManager.get_user_profiles(channel_data.model.id,
                                                 root_oid)
        if not profs or profs == ChannelProfileConnectionModel.ProfileOids.none_obj(
        ):
            return WebsiteErrorView.website_error(
                request,
                WebsiteError.NOT_IN_THE_CHANNEL,
                {"channel_oid": channel_data.oid_org},
                nav_param=kwargs)

        # Process the necessary data
        channel_name = channel_data.model.get_channel_name(root_oid)

        limit = get_limit(request.GET, Website.RecentActivity.MaxMessageCount)

        ctxt = {
            "channel_name":
            channel_name,
            "channel_data":
            channel_data.model,
            "recent_msg_limit":
            limit or "",
            "recent_msg_limit_max":
            Website.RecentActivity.MaxMessageCount,
            "recent_msg_data":
            MessageStatsDataProcessor.get_recent_messages(
                channel_data.model, limit)
        }

        return render_template(self.request,
                               _("Recent Messages - {}").format(channel_name),
                               "info/recent/message.html",
                               ctxt,
                               nav_param=kwargs)
Ejemplo n.º 25
0
    def action_delete(request, channel_model, profile_oid):
        # Terminate if the profile to be deleted is the default profile
        if channel_model.config.default_profile_oid == profile_oid:
            messages.warning(
                request,
                _("Attempted to delete the default profile which is not allowed."
                  ))
            return redirect(
                reverse("info.profile", kwargs={"profile_oid": profile_oid}))

        # Detach profile from all users and delete the profile from the database
        deleted = ProfileManager.delete_profile(channel_model.id, profile_oid,
                                                get_root_oid(request))

        # Alert messages
        if deleted:
            messages.info(request, _("Profile deleted."))
            return redirect(reverse("account.channel.list"))
        else:
            messages.warning(request, _("Failed to delete the profile."))
            return redirect(
                reverse("info.profile", kwargs={"profile_oid": profile_oid}))
Ejemplo n.º 26
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.º 27
0
    def get(self, request, *args, **kwargs):
        channel_data = self.get_channel_data(*args, **kwargs)
        hours_within = safe_cast(request.GET.get("hours_within"), int)

        # channel_members = ProfileManager.get_channel_members(channel_oid)  # Reserved for per member analysis

        channel_name = channel_data.model.get_channel_name(
            get_root_oid(request))

        pkg = get_bot_stats_data_package(channel_data.model, hours_within,
                                         get_current_timezone())

        ctxt = {
            "channel_name": channel_name,
            "channel_data": channel_data.model,
            "hr_range": hours_within or pkg[KEY_HR_FLOW].hr_range
        }
        ctxt.update(pkg)

        return render_template(self.request,
                               _("Bot Usage Stats - {}").format(channel_name),
                               "info/botstats/main.html",
                               ctxt,
                               nav_param=kwargs)
Ejemplo n.º 28
0
 def get(self, request, *args, **kwargs):
     return render_template(
         self.request, _("Short URL Service"), "services/shorturl/main.html",
         {"records": ShortUrlDataManager.get_user_record(get_root_oid(request))})
Ejemplo n.º 29
0
 def test_func(self):
     return get_root_oid(
         self.request
     ) is not None and keys.Cookies.USER_TOKEN in self.request.COOKIES