예제 #1
0
def get_ip_area(ip):
    try:
        qqzeng = IpSearch()
        result = ' '.join(qqzeng.Find(ip).split('|')[:6])
    except:
        result = ''
    return result
예제 #2
0
def sub_account_login(request):
    from django.contrib.auth.models import update_last_login
    from django.contrib.auth.views import logout, auth_login
    from django.contrib.auth import authenticate
    from django.contrib.auth.signals import user_logged_in

    parent_user_id = request.user.id
    client_ip = get_client_ip(request)
    agent = request.META.get('HTTP_USER_AGENT', None)
    ip_search = IpSearch()
    ip_info = ip_search.Find(client_ip)
    area, title = split_ip_to_area_title(ip_info)
    customer_id = request.POST.get('subloging_customer_id', '')
    auth = request.POST.get('subloging_auth', '')
    obj = get_customer_child_obj(request, customer_id)

    if auth == hashlib.md5(
            '%s-%s' %
        (settings.WEB_API_AUTH_KEY,
         datetime.datetime.now().strftime("%Y%m%d"))).hexdigest():
        logout(request)
        CoreLog.objects.create(
            user_id=parent_user_id,
            user_type='users',
            target_id=customer_id,
            target_name=u'{0} - {0}'.format(obj.username),
            action='user_login',
            ip=client_ip,
            desc=u'登录IP:{}<br>登录地区:{}<br>浏览器信息:{}'.format(
                client_ip, title, agent),
        )
        user = authenticate(username=obj.username,
                            password='',
                            t_password=obj.password)
        user_logged_in.disconnect(update_last_login)
        auth_login(request, user)
        user_logged_in.connect(update_last_login)
        return HttpResponseRedirect(reverse('home'))
    raise Http404
예제 #3
0
def track_export_email(request):
    if not request.user.service().is_track_export:
        raise Http404
    data = request.GET
    action = data.get('action', '')
    link_id = data.get('link_id', '')
    user_id = request.user.id

    ident = data.get('ident', '')
    content_id = data.get('content_id', '')
    stat_objs = TrackStat.objects.filter(task_ident=ident, customer_id=user_id)
    if content_id:
        stat_objs = stat_objs.filter(content_id=content_id)
    track_ids = stat_objs.values_list('id', flat=True)

    cr = connections['mm-track'].cursor()
    tablename = '{}_track_email'.format(user_id)
    tablename_click = '{}_track_click'.format(user_id)
    if request.user.lang_code == 'en-us':
        list = [[
            u'邮件地址', u'首次使用IP', u'首次IP区域', u'最后使用IP', u'最后IP区域', u'打开总数',
            u'首次打开时间', u'最后打开时间', u'点击总数', u'首次点击时间', u'最后点击时间'
        ]]
    else:
        list = [[
            u'邮件地址', u'首次使用IP', u'首次IP区域', u'最后使用IP', u'最后IP区域', u'打开总数',
            u'首次打开时间', u'最后打开时间', u'点击总数', u'首次点击时间', u'最后点击时间'
        ]]
    sql = """
    SELECT email, ip_first, COALESCE(ip_last, '') ip_last,
            open_total, open_first, COALESCE(open_last, '') open_last,
            click_total, COALESCE(click_first, '') click_first, COALESCE(click_last, '') click_last
    FROM {} WHERE track_id in ({})""".format(
        tablename, ','.join(map(lambda s: str(s), track_ids)))
    where_str = ''
    if action == 'click':
        where_str += " AND click_total > 0 "
    if link_id:
        where_str += " AND email_id IN (SELECT email_id FROM {} WHERE link_id={})".format(
            tablename_click, link_id)
    sql += where_str
    cr.execute(sql)
    rows = cr.fetchall()
    ip_search = IpSearch()
    # pattern ='([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])'
    pattern = '(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)'
    ip_compile = re.compile(pattern)
    lang_code = (request.user.lang_code == 'en-us' and 'en-us') or "zh-hans"
    for r in rows:
        title_f, title_l = '', ''
        email, ip_first, ip_last, open_total, open_first, open_last, click_total, click_first, click_last = r
        open_last = '' if open_last == '0000-00-00 00:00:00' else open_last
        click_first = '' if click_first == '0000-00-00 00:00:00' else click_first
        click_last = '' if click_last == '0000-00-00 00:00:00' else click_last
        if ip_first:
            m = ip_compile.search(ip_first)
            if m:
                ip_first = m.group(0)
                ip_info = ip_search.Find(ip_first)
                area, title_f = ipparse.get_ip_detail(ip_info, lang_code)
        if ip_last:
            m = ip_compile.search(ip_last)
            if m:
                ip_last = m.group(0)
                ip_info = ip_search.Find(ip_last)
                area, title_l = ipparse.get_ip_detail(ip_info, lang_code)
        list.append([
            email, ip_first, title_f, ip_last, title_l, open_total, open_first,
            open_last, click_total, click_first, click_last
        ])
    return ExcelResponse(list, 'mail', encoding='gbk')
예제 #4
0
def ajax_track_email(request):
    data = request.GET
    user_id = request.user.id
    cr = connections['mm-track'].cursor()
    tablename = '{}_track_email'.format(user_id)
    ident = data.get('ident', '')
    content_id = data.get('content_id', '')
    stat_objs = TrackStat.objects.filter(task_ident=ident, customer_id=user_id)
    if content_id:
        stat_objs = stat_objs.filter(content_id=content_id)
    track_ids = stat_objs.values_list('id', flat=True)
    order_column = data.get('order[0][column]', '')
    order_dir = data.get('order[0][dir]', '')
    search = data.get('search[value]', '')
    colums = [
        'email_id', 'email', 'open_total', 'browser', 'ip_first', 'open_first',
        'click_first'
    ]

    where_str = u'track_id in ({})'.format(','.join(
        map(lambda s: str(s), track_ids)))
    if search:
        where_str += u""" and email like '%{0}%' """.format(search)

    order_by_str = ''
    if order_column and int(order_column) < len(colums):
        if order_dir == 'desc':
            order_by_str = u'order by %s desc' % colums[int(order_column)]
        else:
            order_by_str = u'order by %s asc' % colums[int(order_column)]

    sql = u"SELECT COUNT(1) FROM %s WHERE %s;" % (tablename, where_str)
    cr.execute(sql)
    rows = cr.fetchall()
    count = rows[0][0]

    try:
        length = int(data.get('length', 1))
    except ValueError:
        length = 1

    try:
        start_num = int(data.get('start', '0'))
    except ValueError:
        start_num = 0
    limit_str = u'limit %s offset %s' % (length, start_num)
    sql = u"""
    SELECT email, open_total, click_total, browser, os, ip_first, ip_last,
            open_first, open_last, click_first, click_last, email_id
    FROM %s WHERE %s %s %s;
    """ % (tablename, where_str, order_by_str, limit_str)
    cr.execute(sql)
    rows = cr.fetchall()
    rs = {
        "sEcho": 0,
        "iTotalRecords": count,
        "iTotalDisplayRecords": count,
        "aaData": []
    }
    page = start_num / length + 1
    number = length * (page - 1) + 1
    ip_search = IpSearch()
    # pattern ='([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])'
    pattern = '(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)'
    ip_compile = re.compile(pattern)
    lang_code = (request.user.lang_code == 'en-us' and 'en-us') or "zh-hans"
    for r in rows:
        email, open_total, click_total, browser, os, ip_first, ip_last, open_first, open_last, click_first, click_last, email_id = r
        open_first = open_first if open_first else u'-'
        open_last = open_last if open_last else u'-'
        click_first = click_first if click_first else u'-'
        click_last = click_last if click_last else u'-'
        ip_first_html = _(
            u'首:<span style="cursor: default;color: #004F99;font-size: 11px;">-</span>'
        ) % {}
        ip_last_html = _(
            u'<br>后:<span style="cursor: default;color: #CC0000;font-size: 11px;">-</span>'
        ) % {}
        if ip_first:
            m = ip_compile.search(ip_first)
            if m:
                ip_first = m.group(0)
                ip_info = ip_search.Find(ip_first)
                area, title = ipparse.get_ip_detail(ip_info, lang_code)
                ip_first_html = _(
                    u'首:<span style="color: Gray;" title="%(title)s">[%(area)s] </span><span style="cursor: default;color: #004F99;font-size: 11px;">%(ip_first)s</span>'
                ) % {
                    'title': title,
                    'area': area,
                    'ip_first': ip_first
                }
        if ip_last:
            m = ip_compile.search(ip_last)
            if m:
                ip_last = m.group(0)
                ip_info = ip_search.Find(ip_last)
                area, title = ipparse.get_ip_detail(ip_info, lang_code)
                ip_last_html = _(
                    u'<br>后:<span style="color: Gray;" title="%(title)s">[%(area)s] </span><span style="cursor: default;color: #004F99;font-size: 11px;">%(ip_last)s</span>'
                ) % {
                    'title': title,
                    'area': area,
                    'ip_last': ip_last
                }
        ip_html = ip_first_html + ip_last_html
        rs["aaData"].append([
            number,
            email,
            _(u""" %(open_total)d / <a href='/track/click/?ident=%(ident)s&content_id=%(content_id)s&email_id=%(email_id)d' title='查看点击详情'>%(click_total)d</a>"""
              ) % {
                  'open_total': int(open_total),
                  'ident': ident,
                  'content_id': content_id,
                  'email_id': int(email_id),
                  'click_total': int(click_total)
              },
            u'{}<br>{}'.format(browser, os),
            ip_html,
            _(u'首:<span style="cursor: default;color: #004F99;font-size: 11px;">%(open_first)s</span><br>后:<span style="cursor: default;color: #CC0000;font-size: 11px;">%(open_last)s</span>'
              ) % {
                  'open_first': open_first,
                  'open_last': open_last
              },
            _(u'首:<span style="cursor: default;color: #004F99;font-size: 11px;">%(click_first)s</span><br>后:<span style="cursor: default;color: #CC0000;font-size: 11px;">%(click_last)s</span>'
              ) % {
                  'click_first': click_first,
                  'click_last': click_last
              },
            "",
        ])
        number += 1
    return HttpResponse(json.dumps(rs, ensure_ascii=False),
                        content_type="application/json")
예제 #5
0
def mail_statistics_report_pdf_context(request, task_id):
    # key = ":django:edmweb:statistics:mail_statistics_report_pdf_context:report:{task_id}:".format(
    #     task_id=task_id)
    # context = cache.get(key, None)
    context = None
    if not context:
        obj = get_object(SendTask, request.user, task_id)
        if obj.send_status != 3:
            raise Http404
        # 任务发送数
        task_send_total = obj.get_real_send_qty()

        # 取得任务实际发送量
        value = StatTask.objects.filter(customer_id=request.user.id,
                                        task_ident=obj.send_name).aggregate(
                                            count_send=Sum('count_send'),
                                            count_error=Sum('count_error'),
                                            count_err_1=Sum('count_err_1'),
                                            count_err_2=Sum('count_err_2'),
                                            count_err_3=Sum('count_err_3'),
                                            count_err_5=Sum('count_err_5'),
                                        )
        count_send = value['count_send'] if value['count_send'] else 0
        count_error = int(
            value['count_error']) if value['count_error'] else 0  # 发送失败
        count_succes = count_send - count_error  # 发送成功数

        # 格式错误、无效
        # count_invalid = send_total - count_send
        # -------------------
        # 格式错误、无效
        count_invalid = obj.error_count
        # 一共发送数
        send_total = count_send + count_invalid
        # -------------------

        # 邮箱不存在
        count_err_1 = value['count_err_1'] if value['count_err_1'] else 0
        # 空间不足
        count_err_2 = value['count_err_2'] if value['count_err_2'] else 0
        # 用户拒收
        count_err_3 = value['count_err_3'] if value['count_err_3'] else 0
        # 垃圾拒绝发送
        count_err_5 = value['count_err_5'] if value['count_err_5'] else 0
        total_error = count_invalid + count_err_1 + count_err_2 + count_err_3 + count_err_5

        # 邮件打开
        stat_objs = TrackStat.objects.filter(task_ident=obj.send_name,
                                             customer_id=request.user.id)
        stat_obj = stat_objs[0] if stat_objs else None
        open_unique, click_unique = 0, 0
        show_stat_rate, show_link_rate, show_link_rate_suc = '0%', '0%', '0%'

        # 浏览器、操作系统、 地域 点击链接 统计
        link_objs = None
        ip_search = IpSearch()
        browser_count = {'ie': 0, 'firefox': 0, 'chrome': 0, 'other': 0}
        os_count = {'windows': 0, 'linux': 0, 'macintosh': 0, 'other': 0}
        area_list, area_lists, country_list, country_lists = [], {}, [], {}
        domain_data_click, domain_data_all = [], []
        track_id = 0
        pattern = '([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])'
        ip_compile = re.compile(pattern)
        if stat_objs:
            track_id = stat_obj.id
            # open_total = stat_obj.open_total
            open_unique = stat_obj.open_unique
            click_unique = stat_obj.click_unique
            show_stat_rate = statistics_tools.get_rate(stat_obj.open_unique,
                                                       count_succes)
            show_link_rate = statistics_tools.get_rate(click_unique,
                                                       open_unique)
            show_link_rate_suc = statistics_tools.get_rate(
                click_unique, count_succes)

            link_objs = TrackLink.objects.filter(track_id=track_id).order_by(
                '-click_unique', '-click_total')[:50]
            cr = connections['mm-track'].cursor()
            tablename = '{}_track_email'.format(request.user.id)

            sql = u""" SELECT email FROM {0} WHERE track_id={1} AND click_total > 0; """.format(
                tablename, track_id)
            cr.execute(sql)
            domain_data_click = statistics_tools.get_domain_data(cr.fetchall())

            sql = u""" SELECT email FROM {0} WHERE track_id={1} AND open_total > 0; """.format(
                tablename, track_id)
            cr.execute(sql)
            domain_data_all = statistics_tools.get_domain_data(cr.fetchall())

            # 地域分布
            sql = u"""
            SELECT browser, os, ip_first, ip_last, open_total, click_total, email
            FROM {0} WHERE track_id={1};
            """.format(tablename, track_id)
            cr.execute(sql)
            rows = cr.fetchall()

            for row in rows:
                if row[0].lower().startswith('msie'):
                    browser_count['ie'] += 1
                elif row[0].lower().startswith('firefox'):
                    browser_count['firefox'] += 1
                elif row[0].lower().startswith('chrome'):
                    browser_count['chrome'] += 1
                else:
                    browser_count['other'] += 1

                if row[1].lower().startswith('windows'):
                    os_count['windows'] += 1
                elif row[1].lower().startswith('linux'):
                    os_count['linux'] += 1
                elif row[1].lower().startswith('macintosh'):
                    os_count['macintosh'] += 1
                else:
                    os_count['other'] += 1

                ip = ''
                if row[2]:
                    ip = row[2]
                elif row[3]:
                    ip = row[3]
                if not ip:
                    continue

                m = ip_compile.search(ip)
                if m:
                    ip = m.group(0)
                else:
                    continue

                ip_info = ip_search.Find(ip)
                country, area = statistics_tools.split_ip_info(ip_info)
                if not country:
                    continue
                if country not in country_list:
                    country_list.append(country)
                    country_lists.update({country: [row[4], 1]})
                else:
                    country_lists.update({
                        country: [
                            country_lists[country][0] + row[4],
                            country_lists[country][1] + 1,
                        ]
                    })

                if not area:
                    continue

                if area not in area_list:
                    area_list.append(area)
                    area_lists.update({area: [row[4], 1]})
                else:
                    area_lists.update({
                        area: [
                            area_lists[area][0] + row[4],
                            area_lists[area][1] + 1,
                        ]
                    })

        area_sort_tmp = sorted(area_lists.items(),
                               key=lambda e: e[1][0],
                               reverse=True)[:10]
        country_sort_tmp = sorted(country_lists.items(),
                                  key=lambda e: e[1][0],
                                  reverse=True)[:10]
        area_data, country_data = {}, {}
        area_sort, country_sort = [], []
        for d in area_sort_tmp:
            if d[0] in AREA_CODE.keys():
                area_data.update({
                    AREA_CODE[d[0]]: int(d[1][0]),
                })
            area_sort.append((d[0], int(d[1][0]), int(d[1][1])))
        for d in country_sort_tmp:
            if d[0] in JC_CODE_COUNTRY:
                country_data.update({
                    JC_CODE_COUNTRY[d[0]]: int(d[1][0]),
                })
            country_sort.append((d[0], int(d[1][0]), int(d[1][1])))
        area_max = statistics_tools.get_gfc_max_data(
            area_sort_tmp[0][1][0]) if area_sort_tmp else 5000
        country_max = statistics_tools.get_gfc_max_data(
            country_sort_tmp[0][1][0]) if area_sort_tmp else 5000

        context = {
            'task_obj':
            obj,
            'task_id':
            task_id,
            'task_send_total':
            task_send_total,
            'send_total':
            send_total,
            'count_send':
            count_send,
            'count_succes':
            count_succes,
            'count_succes_rate':
            statistics_tools.get_rate(count_succes, count_send - count_err_5),
            'count_error':
            count_error,
            'count_error_rate':
            statistics_tools.get_rate(count_error - count_err_5,
                                      count_send - count_err_5),
            'total_error':
            total_error,
            'count_invalid': {
                'value': count_invalid,
                'width': statistics_tools.get_width(count_invalid,
                                                    total_error),
                'rate': statistics_tools.get_rate(count_invalid, total_error)
            },
            'count_err_1': {
                'value': count_err_1,
                'width': statistics_tools.get_width(count_err_1, total_error),
                'rate': statistics_tools.get_rate(count_err_1, total_error)
            },
            'count_err_2': {
                'value': count_err_2,
                'width': statistics_tools.get_width(count_err_2, total_error),
                'rate': statistics_tools.get_rate(count_err_2, total_error)
            },
            'count_err_3': {
                'value': count_err_3,
                'width': statistics_tools.get_width(count_err_3, total_error),
                'rate': statistics_tools.get_rate(count_err_3, total_error)
            },
            'count_err_5': {
                'value': count_err_5,
                'width': statistics_tools.get_width(count_err_5, total_error),
                'rate': statistics_tools.get_rate(count_err_5, total_error)
            },
            'stat_obj':
            stat_obj,
            'show_stat_rate':
            show_stat_rate,
            'open_unique':
            open_unique,
            'open_unique_rate':
            statistics_tools.get_rate(open_unique, count_succes),
            'no_open':
            count_succes - open_unique,
            'no_open_rate':
            statistics_tools.get_rate(count_succes - open_unique,
                                      count_succes),
            'click_unique':
            click_unique,
            'show_link_rate':
            show_link_rate,
            'show_link_rate_suc':
            show_link_rate_suc,
            'no_click':
            count_succes - click_unique,
            'no_click_rate':
            statistics_tools.get_rate(count_succes - click_unique,
                                      count_succes),
            'link_objs':
            link_objs,
            'track_id':
            track_id,
            'domain_data_click':
            domain_data_click,
            'domain_data_all':
            domain_data_all,
            'area_sort':
            area_sort,
            'country_sort':
            country_sort,
            'area_data':
            area_data,
            'country_data':
            country_data,
            'area_max':
            area_max,
            'country_max':
            country_max,
            'os_count':
            os_count,
            'browser_count':
            browser_count,
            'filename':
            u"{}_{}.pdf".format(obj.send_name, task_id)
        }
        # cache.set(key, context, 300)
    return context
예제 #6
0
    def clean(self):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')
        captcha = self.cleaned_data.get('captcha')
        redis = get_redis_connection()
        key = 'captcha:{}'.format(captcha)
        if redis.hget(key, 'res') != 'True':
            raise forms.ValidationError(
                self.error_messages_captcha['invalid_login'],
                code='invalid_login',
                params={'username': self.username_field.verbose_name},
            )
        redis.delete(key)

        if username and password:
            self.user_cache = authenticate(username=username,
                                           password=password)
            login_ip = get_client_ip(self.request)
            ##### 地区登录保护 #####
            if self.user_cache:
                if self.user_cache.disabled == '1':
                    raise forms.ValidationError(
                        self.error_messages_disabled['invalid_login'],
                        code='invalid_login',
                        params={'username': self.username_field.verbose_name},
                    )
                if self.user_cache.parent and self.user_cache.parent.disabled == '1':
                    raise forms.ValidationError(
                        self.error_messages_disabled2['invalid_login'],
                        code='invalid_login',
                        params={'username': self.username_field.verbose_name},
                    )
                weixin_customer_id = self.user_cache.weixin_customer_id
                customer_id = self.user_cache.id
                ip_search = IpSearch()
                ip_info = ip_search.Find(login_ip)
                login_area1, login_area2 = parse_login_area(ip_info)
                obj, _created = CoreLoginAreaIp.objects.get_or_create(
                    user_id=customer_id)
                is_open = False if _created else obj.is_open
                _exists = CoreLoginAreaIp.objects.filter(
                    Q(user_id=customer_id, ip__icontains=login_ip)
                    | Q(user_id=customer_id, area__icontains=login_area1)
                    | Q(user_id=customer_id, area__icontains=login_area2)
                ).exists()
                if is_open and not _exists:
                    j_area, j_title = split_ip_to_area_title(ip_info)
                    redis.rpush(
                        'edm_web_notice_queue',
                        json.dumps({
                            "type": "1",
                            'customer_id': customer_id,
                            "area": j_title,
                            'point': '',
                            'domain': '',
                            'task': '',
                        }))
                    if weixin_customer_id:
                        raise forms.ValidationError(
                            self.error_messages_loginsafe['invalid_login'],
                            code='invalid_login',
                            params={
                                'username': self.username_field.verbose_name
                            },
                        )
                    else:
                        raise forms.ValidationError(
                            self.error_messages_loginsafe2['invalid_login'],
                            code='invalid_login',
                            params={
                                'username': self.username_field.verbose_name
                            },
                        )

            if self.user_cache is None:
                raise forms.ValidationError(
                    self.error_messages['invalid_login'],
                    code='invalid_login',
                    params={'username': self.username_field.verbose_name},
                )
            else:
                self.user_cache.last_ip = login_ip
                self.user_cache.last_login = timezone.now()
                self.user_cache.save(update_fields=['last_ip', 'last_login'])
                agent = self.request.META.get('HTTP_USER_AGENT', None)
                self.user_cache.save_login_log(login_ip, ip_info, agent)
                self.confirm_login_allowed(self.user_cache)

                # 关注用户上线通知
                s = self.user_cache.service()
                if s and s.is_pushcrew:
                    action = "service"
                    title = u"登录提醒"
                    message = u"{}(ID: {}) 于 {} 时间登录平台".format(
                        self.user_cache.company, self.user_cache.id,
                        datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
                    pushcrew_notice(action, title, message)

        return self.cleaned_data