from zerver.models import Backlog, BacklogAccessory, UpdateBacklog, Statement, StatementBacklog, StatementAccessory, \
    StatementState, UserProfile, Stream, ZgStatementComment, ZgReplyComment,UserProfile
from django.http import JsonResponse
import datetime, time, json, calendar
from zerver.lib import avatar

from datetime import timezone, timedelta
from zerver.views.zg_tools import zg_send_tools

import re, math
from django.views.decorators.csrf import csrf_exempt
from zerver.lib.actions import get_user_ids_for_streams
from zerver.tornado.event_queue import send_event

def nuw_time():
    stockpile_time = datetime.datetime.utcnow()
    stockpile_time = stockpile_time.replace(tzinfo=timezone.utc)
    tzutc_8 = timezone(timedelta(hours=8))
    stockpile_time = stockpile_time.astimezone(tzutc_8)
    return stockpile_time

# 查看日志评论
def statement_review(request, user_profile):
    table_id = request.GET.get('table_id')
    if not table_id:
        return JsonResponse({'errno': 1, 'message': "缺少必要参数"})
    table_id = int(table_id)
    comment_list = []
    try:
        comment_obj_list = ZgStatementComment.objects.filter(topic_id=table_id)
    except Exception:
        return JsonResponse({'errno': 2, 'message': "获取评论失败"})

    for comment_obj in comment_obj_list:
        comment_dict = {}
        comment_dict['comment_id'] = comment_obj.id
        comment_dict['comment_content'] = comment_obj.content
        comment_dict['comment_time'] = comment_obj.comment_time
        user = UserProfile.objects.filter(id=comment_obj.from_uid)
        user = user[0]
        comment_dict['comment_user_name'] = user.full_name
        comment_dict['comment_user_avatar_url'] = avatar.absolute_avatar_url(user)
        reply_obj_list = ZgReplyComment.objects.filter(comment_id=comment_obj)
        comment_dict['comment_reply_list'] = []
        for reply_obj in reply_obj_list:
            reply_dict = {}

            # 用户回复id
            reply_dict['reply_user_id'] = reply_obj.reply_user_id
            if reply_obj.reply_user_id:
                user_obj = UserProfile.objects.get(id=reply_obj.reply_user_id)
                reply_dict['reply_user_name'] = user_obj.full_name

            # 回复内容
            reply_dict['reply_content'] = reply_obj.content
            # 回复用户id
            reply_dict['user_reply_id'] = reply_obj.from_uid
            user_obj = UserProfile.objects.get(id=reply_obj.from_uid)
            reply_dict['user_reply_avatar'] = avatar.absolute_avatar_url(user_obj)
            reply_dict['user_reply_name'] = user_obj.full_name

            # 回复时间
            reply_dict['reply_time'] = reply_obj.reply_time

            comment_dict['comment_reply_list'].append(reply_dict)

        comment_list.append(comment_dict)

    return JsonResponse({'errno': 0, 'message': "获取成功", 'comment_list': comment_list})

# 添加评论
def statement_review_post(request, user_profile):
    req = request.body
    req = req.decode()
    req = json.loads(req)
    table_id = req.get('table_id')
    comment = req.get('comment')
    if not all([table_id, comment]):
        return JsonResponse({'errno': 1, 'message': "缺少必要参数"})
    print(table_id, comment)
    try:
        comment_obj = ZgStatementComment.objects.create(topic_id=table_id, content=comment, from_uid=user_profile.id,
                                                        comment_time=time.time(), topic_type='statement')

    except Exception:
        return JsonResponse({'errno': 1, 'message': "添加评论失败"})

    return JsonResponse({'errno': 0, 'message': "评论成功", 'comment_id': comment_obj.id})

# 添加评论回复
def reply_comment(request, user_profile):
    req = request.body
    req = req.decode()
    req = json.loads(req)
    comment_id = req.get('comment_id')
    content = req.get('content')
    reply_id = req.get('reply_id')
    if not all([comment_id, content]):
        return JsonResponse({'errno': 1, 'message': "缺少必要参数"})
    try:
        a = ZgStatementComment.objects.get(id=comment_id)
        reply_obj = ZgReplyComment(comment_id=a, content=content, reply_type='reply_comment',
                                   from_uid=user_profile.id, reply_time=time.time())
        reply_obj.save()
        if reply_id:
            reply_obj.reply_user_id = reply_id
            reply_obj.save()
            reply_id = reply_obj.id

    except Exception:
        return JsonResponse({'errno': 1, 'message': "添加回复失败"})
    return JsonResponse({'errno': 0, 'message': "评论成功", 'reply_id': reply_id})

# 已读未读
def state_view(request, user_profile):
    table_id = request.GET.get('table_id')
    states = request.GET.get('state')

    if not all([table_id, states]):
        return JsonResponse({'errno': 2, 'message': "缺少必要参数", })
    if states == 't':
        try:
            read_table = StatementState.objects.filter(statement_id=table_id, state='t').order_by('-id')
        except Exception:
            return JsonResponse({'errno': 1, 'message': "获取已读信息失败", })
        user_list = []
        for table in read_table:
            user_dict = {}
            user = UserProfile.objects.get(id=table.staff)
            user_dict['avatar'] = avatar.absolute_avatar_url(user)
            user_dict['user_name'] = user.full_name
            user_dict['table_id'] = table_id
            user_list.append(user_dict)
        return JsonResponse({'errno': 0, 'message': "成功", 'user_list': user_list})

    elif states == 'f':
        try:
            read_table = StatementState.objects.filter(statement_id=table_id, state='f').order_by('-id')

        except Exception:
            return JsonResponse({'errno': 3, 'message': "获取已读信息失败", })
        user_list = []
        for table in read_table:
            user_dict = {}
            user = UserProfile.objects.get(id=table.staff)
            user_dict['avatar'] = avatar.absolute_avatar_url(user)
            user_dict['user_name'] = user.full_name
            user_dict['table_id'] = table_id
            user_list.append(user_dict)

        return JsonResponse({'errno': 0, 'message': "成功", 'user_list': user_list})

# 查看自己和他人的报表
def look_table(request, user_profile):
    table_id = request.GET.get('table_id')
    print(table_id)

    if not table_id:
        return JsonResponse({'errno': 2, 'message': "缺少必要参数", })

    try:

        statement = Statement.objects.get(id=table_id)
        a = StatementState.objects.filter(statement_id=statement.id, staff=user_profile.id)
        if a:
            a[0].state = True
            a[0].save()

        statement_backlogs_list = StatementBacklog.objects.filter(statement_id=statement).order_by('-id')
        user = UserProfile.objects.get(email=statement.user)

        table_dict = dict()
        table_dict['avatar'] = avatar.absolute_avatar_url(user)
        table_dict['user_name'] = user.full_name
        table_dict['generate_time'] = statement.generate_time
        table_dict['accomplish'] = statement.accomplish
        table_dict['overdue'] = statement.overdue
        table_dict['underway'] = statement.underway
        table_dict['type'] = statement.types
        backlog_list = []
        table_dict['backlog_list'] = backlog_list
        for statement_backlogs in statement_backlogs_list:
            backlogs_dict = {}
            backlogs = Backlog.objects.get(id=statement_backlogs.backlog_id)
            backlogs_dict['task'] = backlogs.task
            backlogs_dict['over_time'] = backlogs.over_time
            backlog_list.append(backlogs_dict)

        url_list = []
        table_dict['url_list'] = url_list
        accessory_list = StatementAccessory.objects.filter(statement_id=table_id, is_delete='f').order_by('-id')
        if accessory_list:
            for accessory in accessory_list:
                accessory_dict = {}
                accessory_dict['url'] = accessory.statement_accessory_url
                accessory_dict['size'] = accessory.accessory_size
                accessory_dict['name'] = accessory.accessory_name
                url_list.append(accessory_dict)

    except Exception as e:
        print(e)
        return JsonResponse({'errno': 1, 'message': "获取数据失败", })
    # #
    return JsonResponse({'errno': 0, 'message': "获取数据成功", 'table_dict': table_dict})

# web接收到日志
def web_my_receive(request, user_profile):
    page = int(request.GET.get('page', 1))
    generate_time = request.GET.get('start_time')
    screen_over_time = request.GET.get('over_time')
    sender = request.GET.get('sender')
    date_type = request.GET.get('date_type')
    filter_dict = dict()
    if generate_time:
        filter_dict['receive_time__range'] = (generate_time, time.time())
    if screen_over_time:
        filter_dict['receive_time__range'] = ('0', screen_over_time)
    if all([generate_time, screen_over_time]):
        filter_dict['receive_time__range'] = (generate_time, screen_over_time)
    if sender:
        filter_dict['staff'] = sender
    else:
        filter_dict['staff'] = user_profile.id
    if date_type:
        filter_dict['types'] = date_type

    try:
        page1 = (page - 1) * 10
        page2 = page * 10
        statement_state_list = StatementState.objects.filter(**filter_dict).order_by('-id')[page1:page2]
        page_count = StatementState.objects.filter(**filter_dict).count()
        page_count = math.ceil(page_count / 10)

    except Exception:
        return JsonResponse({'errno': 1, 'message': "获取我收到的报表失败"})

    try:

        receive_table_list = []
        for statement_state in statement_state_list:

            web_my_receive_dict = {}
            s = Statement.objects.get(id=statement_state.statement_id.id)
            statement_state.state = True
            statement_state.save()

            user = UserProfile.objects.filter(email=s.user)
            user = user[0]

            web_my_receive_dict['avatarurl'] = avatar.absolute_avatar_url(user)
            web_my_receive_dict['fullname'] = user.full_name
            web_my_receive_dict['generate_time'] = statement_state.receive_time
            web_my_receive_dict['table_id'] = s.id
            web_my_receive_dict['accomplish'] = s.accomplish
            web_my_receive_dict['overdue'] = s.overdue
            web_my_receive_dict['underway'] = s.underway
            web_my_receive_dict['type'] = s.types
            backlog_list = []
            web_my_receive_dict['backlog_list'] = backlog_list
            statement_backlogs_list = StatementBacklog.objects.filter(statement_id=s).order_by('-id')
            for statement_backlogs in statement_backlogs_list:
                backlogs_dict = {}
                backlogs = Backlog.objects.get(id=statement_backlogs.backlog_id)
                backlogs_dict['task'] = backlogs.task
                backlogs_dict['over_time'] = backlogs.over_time
                backlog_list.append(backlogs_dict)

            url_list = []
            web_my_receive_dict['url_list'] = url_list
            accessory_list = StatementAccessory.objects.filter(statement_id=s, is_delete='f').order_by('-id')
            for accessory in accessory_list:
                accessory_dict = {}
                accessory_dict['url'] = accessory.statement_accessory_url
                accessory_dict['size'] = accessory.accessory_size
                accessory_name = accessory.accessory_name
                accessory_dict['name'] = accessory_name
                types = accessory_name.split('.')
                accessory_dict['type'] = types[-1]
                url_list.append(accessory_dict)
            receive_table_list.append(web_my_receive_dict)
    except Exception:
        return JsonResponse({'errno': 2, 'message': "获取信息失败"})
    return JsonResponse({'errno': 0, 'message': "成功", 'receive_table_list': receive_table_list, 'page': page_count})

# web发送的日志
def web_my_send(request, user_profile):
    page = int(request.GET.get('page', 1))
    generate_time = request.GET.get('start_time')
    screen_over_time = request.GET.get('over_time')
    date_type = request.GET.get('date_type')

    filter_dict = dict()
    if generate_time:
        filter_dict['generate_time__range'] = (generate_time, time.time())
    if screen_over_time:
        filter_dict['generate_time__range'] = ('0', screen_over_time)
    if all([generate_time, screen_over_time]):
        filter_dict['generate_time__range'] = (generate_time, screen_over_time)
    if date_type:
        filter_dict['types'] = date_type
    filter_dict['user'] = user_profile.email

    try:
        page1 = (page - 1) * 10
        page2 = page * 10
        statement = Statement.objects.filter(**filter_dict).order_by('-id')[page1:page2]
        page_count = Statement.objects.filter(**filter_dict).count()
        page_count = math.ceil(page_count / 10)
    except Exception as e:
        print(e)
        return JsonResponse({'errno': 1, 'message': "获取我收到的报表失败"})

    try:
        send_table_list = []
        for statement_state in statement:
            web_my_receive_dict = {}

            user = UserProfile.objects.get(email=statement_state.user)
            web_my_receive_dict['avatarurl'] = avatar.absolute_avatar_url(user_profile)
            web_my_receive_dict['fullname'] = user.full_name
            web_my_receive_dict['generate_time'] = statement_state.generate_time
            web_my_receive_dict['table_id'] = statement_state.id
            web_my_receive_dict['accomplish'] = statement_state.accomplish
            web_my_receive_dict['overdue'] = statement_state.overdue
            web_my_receive_dict['underway'] = statement_state.underway
            web_my_receive_dict['type'] = statement_state.types
            backlog_list = []
            web_my_receive_dict['backlog_list'] = backlog_list

            statement_backlogs_list = StatementBacklog.objects.filter(statement_id=statement_state)
            for statement_backlogs in statement_backlogs_list:
                backlogs_dict = {}
                backlogs = Backlog.objects.get(id=statement_backlogs.backlog_id)
                backlogs_dict['task'] = backlogs.task
                backlogs_dict['over_time'] = backlogs.over_time
                backlog_list.append(backlogs_dict)

            url_list = []
            web_my_receive_dict['url_list'] = url_list
            accessory_list = StatementAccessory.objects.filter(statement_id=statement_state, is_delete='f')
            for accessory in accessory_list:
                accessory_dict = dict()
                accessory_dict['url'] = accessory.statement_accessory_url
                accessory_dict['size'] = accessory.accessory_size
                accessory_name = accessory.accessory_name
                accessory_dict['name'] = accessory_name
                types = accessory_name.split('.')
                accessory_dict['type'] = types[-1]

                url_list.append(accessory_dict)

            try:
                read_table = StatementState.objects.filter(statement_id=statement_state.id, state='t').order_by('-id')
            except Exception:
                return JsonResponse({'errno': 1, 'message': "获取已读信息失败", })
            already_list = []
            for table in read_table:
                user_dict = {}
                user = UserProfile.objects.get(id=table.staff)
                user_dict['avatar'] = avatar.absolute_avatar_url(user)
                user_dict['user_name'] = user.full_name
                user_dict['table_id'] = statement_state.id
                already_list.append(user_dict)
            web_my_receive_dict['already_list'] = already_list

            try:
                read_table = StatementState.objects.filter(statement_id=statement_state.id, state='f').order_by('-id')
            except Exception:
                return JsonResponse({'errno': 3, 'message': "获取已读信息失败", })
            unread_list = []
            for table in read_table:
                user_dict = {}
                user = UserProfile.objects.get(id=table.staff)
                user_dict['avatar'] = avatar.absolute_avatar_url(user)
                user_dict['user_name'] = user.full_name
                user_dict['table_id'] = statement_state.id
                unread_list.append(user_dict)
            web_my_receive_dict['already_count'] = len(already_list)
            web_my_receive_dict['unread_count'] = len(unread_list)
            web_my_receive_dict['unread_list'] = unread_list

            send_table_list.append(web_my_receive_dict)

    except Exception:
        return JsonResponse({'errno': 2, 'message': "获取信息失败"})
    return JsonResponse({'errno': 0, 'message': "成功", 'send_table_list': send_table_list, 'page': page_count})

# 我发出的
def my_send(request, user_profile):
    page = int(request.GET.get('page', 1))

    generate_time = request.GET.get('start_time')
    screen_over_time = request.GET.get('over_time')
    date_type = request.GET.get('date_type')

    try:
        page1 = (page - 1) * 10
        page2 = page * 10
        filter_dict = dict()

        if generate_time:
            filter_dict['generate_time__range'] = (generate_time, time.time())
        if screen_over_time:
            filter_dict['generate_time__range'] = ('0', screen_over_time)
        if all([generate_time, screen_over_time]):
            filter_dict['generate_time__range'] = (generate_time, screen_over_time)
        if date_type:
            filter_dict['types'] = date_type
        filter_dict['user'] = user_profile.email

        statement = Statement.objects.filter(**filter_dict).order_by('-id')[page1:page2]
        page_count = Statement.objects.filter(**filter_dict).count()
        page_count = math.ceil(page_count / 10)
    except Exception:
        return JsonResponse({'errno': 2, 'message': "获取我收到的报表失败", })

    try:
        send_table_list = []
        for st in statement:
            user_dict = {}
            user_dict['avatarurl'] = avatar.absolute_avatar_url(user_profile)
            user_dict['fullname'] = user_profile.full_name
            user_dict['generate_time'] = st.generate_time
            user_dict['table_id'] = st.id
            user_dict['type'] = st.types
            send_table_list.append(user_dict)

    except Exception:
        return JsonResponse({'errno': 1, 'message': "获取数据失败", })

    return JsonResponse({'errno': 0, 'message': "成功", 'send_table_list': send_table_list, 'page': page_count})

# 我收到的
def my_receive(request, user_profile):
    generate_time = request.GET.get('start_time')
    screen_over_time = request.GET.get('over_time')
    sender = request.GET.get('sender')
    date_type = request.GET.get('date_type')

    page = int(request.GET.get('page', 1))
    page1 = (page - 1) * 10
    page2 = page * 10
    try:
        filter_dict = dict()
        if generate_time:
            filter_dict['receive_time__range'] = (generate_time, time.time())
        if screen_over_time:
            filter_dict['receive_time__range'] = ('0', screen_over_time)

        if all([generate_time, screen_over_time]):
            filter_dict['receive_time__range'] = (generate_time, screen_over_time)

        if sender:
            filter_dict['staff'] = sender
        else:
            filter_dict['staff'] = user_profile.id
        if date_type:
            filter_dict['types'] = date_type

        statement_state_list = StatementState.objects.filter(**filter_dict).order_by('-id')[page1:page2]
        page_count = StatementState.objects.filter(**filter_dict).count()
        page_count = math.ceil(page_count / 10)

    except Exception:
        return JsonResponse({'errno': 1, 'message': "获取我收到的报表失败"})

    try:
        receive_table_list = []
        for statement_state in statement_state_list:
            user_dict = {}
            s = Statement.objects.get(id=statement_state.statement_id.id)
            user = UserProfile.objects.get(email=s.user)
            user_dict['avatarurl'] = avatar.absolute_avatar_url(user)
            user_dict['fullname'] = user.full_name
            user_dict['generate_time'] = statement_state.receive_time
            user_dict['table_id'] = s.id
            user_dict['state'] = statement_state.state
            user_dict['type'] = s.types

            receive_table_list.append(user_dict)
    except Exception:
        return JsonResponse({'errno': 2, 'message': "获取信息失败"})
    return JsonResponse({'errno': 0, 'message': "成功", 'receive_table_list': receive_table_list, 'page': page_count})

# 日志助手
def log_assistant(request, user_profile):
    try:
        a = StatementState.objects.filter(staff=user_profile.id, state='f').count()
    except Exception:
        return JsonResponse({'errno': 1, 'message': "查询失败"})
    return JsonResponse({'errno': 0, 'message': "成功", 'count': a})

# 获取群组人员信息
def stream_recipient_data(request, user_profile):
    streams_list = Stream.objects.all()
    streams_user_list = get_user_ids_for_streams(streams_list)
    streams_dict = {}
    for streams_user_id_list in streams_user_list:
        streams_user_data_list = []
        streams_user_lists = streams_user_list[streams_user_id_list]
        if user_profile.id in streams_user_lists:
            streams_user_lists.remove(user_profile.id)
        for user_id in streams_user_lists:
            user_data_dict = {}
            user = UserProfile.objects.get(id=user_id)
            user_data_dict['avatarurl'] = avatar.absolute_avatar_url(user)
            user_data_dict['id'] = user.id
            user_data_dict['fullname'] = user.full_name
            user_data_dict['email'] = user.email
            streams_user_data_list.append(user_data_dict)
        a = Stream.objects.get(id=streams_user_id_list)
        streams_dict[a.name] = streams_user_data_list
        streams_dict['no_strems'] = []
    return JsonResponse({'errno': 0, 'message': "获取成功", 'streams_dict': streams_dict})

# 发送报表
def table_view(request, user_profile):
    user = str(user_profile)
    user = re.match(r"<UserProfile: (.*) <.*>>", user).group(1)
    req = request.body
    req = req.decode()
    req = json.loads(req)
    accomplish = req.get('accomplish')
    overdue = req.get("overdue")
    underway = req.get('underway')

    date_type = req.get('date_type')
    backlogs_list = req.get('backlog_list')
    statement_accessory_list = req.get('statement_accessory_list')
    send = req.get('send_list')

    if not all([date_type, accomplish]):
        return JsonResponse({'errno': 1, 'message': "缺少必要参数"})
    try:
        generate_time = time.time()
        a = Statement(user=user, generate_time=generate_time, types=date_type, accomplish=accomplish)

        if overdue:
            a.overdue = overdue

        if underway:
            a.underway = underway

        a.save()

        if backlogs_list:
            for backlog_id in backlogs_list:
                StatementBacklog.objects.create(statement_id=a, backlog_id=backlog_id)

        if statement_accessory_list:
            for statement_accessory_dict in statement_accessory_list:
                StatementAccessory.objects.create(statement_accessory_url=statement_accessory_dict['url'],
                                                  accessory_size=statement_accessory_dict['size'],
                                                  accessory_name=statement_accessory_dict['name'],
                                                  statement_id=a)
        if send:
            b = time.time()
            for staff in send:
                StatementState.objects.create(statement_id=a, staff=staff, receive_time=b)
            even = {'zg_type': 'DailyReport',
                    'theme': user_profile.full_name + '的日志',
                    'time': nuw_time(),
                    'avatar_url': avatar.absolute_avatar_url(user_profile),
                    'user_name': user_profile.full_name,
                    }
            send_event(zg_send_tools(even), send)

    except Exception as e:
        print(e)
        return JsonResponse({'errno': 2, 'message': "储存周报失败"})

    return JsonResponse({'errno': 0, 'message': "成功", 'table_id': a.id})

# 一键生成
def generate_table(request, user_profile):
    now = int(time.time())
    user = str(user_profile)
    user = re.match(r"<UserProfile: (.*) <.*>>", user).group(1)
    date_type = request.GET.get('date_type')

    if not all([user, date_type]):
        return JsonResponse({'errno': 1, 'message': "缺少参数"})

    if date_type == 'month':

        day_now = time.localtime()
        day_begin = '%d-%02d-01' % (day_now.tm_year, day_now.tm_mon)
        wday, monthRange = calendar.monthrange(day_now.tm_year,
                                               day_now.tm_mon)
        day_end = '%d-%02d-%02d' % (day_now.tm_year, day_now.tm_mon, monthRange)

        day_begin = day_begin + " " + '00:00:00'
        day_end = day_end + " " + "23:59:00"
        day_begin = time.mktime(time.strptime(day_begin, '%Y-%m-%d %H:%M:%S'))
        day_end = time.mktime(time.strptime(day_end, '%Y-%m-%d %H:%M:%S'))

        month_backlog_list = Backlog.objects.filter(user=user, create_time__range=(day_begin, day_end),
                                                    is_delete='f').order_by('-id')

        month_accomplish_list = []
        month_overdue_list = []
        month_underway_list = []
        month_accessory_list = []

        for month_backlog in month_backlog_list:
            if month_backlog.state == 0:
                month_accomplish_list.append(month_backlog.task)

            if month_backlog.over_time < now and month_backlog.state == 2:
                month_overdue_list.append(month_backlog.task)

            if month_backlog.over_time > now and month_backlog.state == 2:
                month_underway_list.append(month_backlog.task)

            month_accessory_obj_list = BacklogAccessory.objects.filter(backlog_id=month_backlog)
            month_accessory_obj_dict = {}

            for month_accessory_obj in month_accessory_obj_list:
                month_accessory_obj_dict['url'] = month_accessory_obj.accessory_url
                month_accessory_obj_dict['size'] = month_accessory_obj.accessory_size
                accessory_name = month_accessory_obj.accessory_name
                month_accessory_obj_dict['name'] = accessory_name
                types = accessory_name.split('.')
                month_accessory_obj_dict['type'] = types[-1]

            if month_accessory_obj_dict:
                month_accessory_list.append(month_accessory_obj_dict)
        month_backlog_count = Backlog.objects.filter(user=user, create_time__range=(day_begin, day_end),
                                                     is_delete='f', state=0).count()
        completeness = 0
        if month_backlog_count + len(month_overdue_list):
            completeness = month_backlog_count / (month_backlog_count + len(month_overdue_list))

        return JsonResponse(
            {'errno': 0, 'message': "成功", 'accomplish_list': month_accomplish_list, 'overdue_list':
                month_overdue_list, "underway_list": month_underway_list, 'completeness': completeness,
             'accessory_list': month_accessory_list})

    elif date_type == 'week':

        today = datetime.date.today()
        monday = datetime.date.today() - datetime.timedelta(days=datetime.date.today().weekday())
        sunday = today + datetime.timedelta(6 - today.weekday())
        a = time.mktime(monday.timetuple())
        b = time.mktime(sunday.timetuple())
        week_backlog_list = Backlog.objects.filter(user=user, create_time__range=(a, b), is_delete='f').order_by('-id')
        week_accomplish_list = []
        week_overdue_list = []
        week_underway_list = []
        week_accessory_list = []

        for week_backlog in week_backlog_list:
            if week_backlog.state == 0:
                week_accomplish_list.append(week_backlog.task)

            if week_backlog.over_time < now and week_backlog.state == 2:
                week_overdue_list.append(week_backlog.task)

            if week_backlog.over_time > now and week_backlog.state == 2:
                week_underway_list.append(week_backlog.task)

            month_accessory_obj_list = BacklogAccessory.objects.filter(backlog_id=week_backlog)
            month_accessory_obj_dict = {}

            for month_accessory_obj in month_accessory_obj_list:
                month_accessory_obj_dict['url'] = month_accessory_obj.accessory_url
                month_accessory_obj_dict['size'] = month_accessory_obj.accessory_size
                accessory_name = month_accessory_obj.accessory_name
                month_accessory_obj_dict['name'] = accessory_name
                types = accessory_name.split('.')
                month_accessory_obj_dict['type'] = types[-1]

            if month_accessory_obj_dict:
                week_accessory_list.append(month_accessory_obj_dict)

        week_backlog_count = Backlog.objects.filter(user=user, create_time__range=(a, b), is_delete='f',
                                                    state=0).count()
        completeness = 0
        if week_backlog_count + len(week_overdue_list):
            completeness = week_backlog_count / (week_backlog_count + len(week_overdue_list))

        return JsonResponse(
            {'errno': 0, 'message': "成功", 'accomplish_list': week_accomplish_list, 'overdue_list':
                week_overdue_list, "underway_list": week_underway_list, 'completeness': completeness,
             'accessory_list': week_accessory_list})

    elif date_type == "day":
        a = int(time.mktime(time.strptime(str(datetime.date.today()), '%Y-%m-%d')))
        b = int(time.mktime(time.strptime(str(datetime.date.today()
                                              + datetime.timedelta(days=1)), '%Y-%m-%d'))) - 1

        day_backlog_list = Backlog.objects.filter(user=user, create_time__range=(a, b), is_delete='f').order_by('-id')

        day_accomplish_list = []
        day_overdue_list = []
        day_underway_list = []
        day_accessory_list = []

        for day_backlog in day_backlog_list:
            if day_backlog.state == 0:
                day_accomplish_list.append(day_backlog.task)

            if day_backlog.over_time < now and day_backlog.state == 2:
                day_overdue_list.append(day_backlog.task)

            if day_backlog.over_time > now and day_backlog.state == 2:
                day_underway_list.append(day_backlog.task)

            month_accessory_obj_list = BacklogAccessory.objects.filter(backlog_id=day_backlog)
            month_accessory_obj_dict = {}

            for month_accessory_obj in month_accessory_obj_list:
                month_accessory_obj_dict['url'] = month_accessory_obj.accessory_url
                month_accessory_obj_dict['size'] = month_accessory_obj.accessory_size
                accessory_name = month_accessory_obj.accessory_name
                month_accessory_obj_dict['name'] = accessory_name
                types = accessory_name.split('.')
                month_accessory_obj_dict['type'] = types[-1]

            if month_accessory_obj_dict:
                day_accessory_list.append(month_accessory_obj_dict)

        day_backlog_count = Backlog.objects.filter(user=user, create_time__range=(a, b), is_delete='f', state=0).count()
        completeness = 0
        if day_backlog_count + len(day_overdue_list):
            completeness = day_backlog_count / (day_backlog_count + len(day_overdue_list))

        return JsonResponse(
            {'errno': 0, 'message': "成功", 'accomplish_list': day_accomplish_list, 'overdue_list':
                day_overdue_list, "underway_list": day_underway_list, 'completeness': completeness,
             'accessory_list': day_accessory_list})

# 待办事项增
def backlogs_view_po(request, user_profile):
    import re
    user = str(user_profile)
    user = re.match(r"<UserProfile: (.*) <.*>>", user).group(1)

    req = request.body
    req = req.decode()
    req = json.loads(req)
    task = req.get('task')
    over_time = req.get('over_time')
    task_details = req.get('task_details')
    create_time = req.get('create_time')

    if not create_time:
        create_time = int(time.time())

    if not all([task, over_time]):
        return JsonResponse({'errno': 1, 'message': '缺少必要参数'})

    over_time = int(over_time)
    create_time = int(create_time)
    if create_time > over_time:
        return JsonResponse({'errno': 3, 'message': '截止时间不能早于当前时间'})
    try:
        backlog = Backlog.objects.create(user=user, create_time=create_time, task=task,
                                         over_time=over_time, task_details=task_details
                                         )
        backlog_id = backlog.id
        time_array = time.localtime(create_time)
        other_styley_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
        update_create_time = "%s创建了事项" % other_styley_time
        UpdateBacklog.objects.create(backlog_id=backlog, update_backlog=update_create_time)

    except ImportError:
        return JsonResponse({'errno': 2, 'message': '创建事项失败'})

    return JsonResponse({'errno': 0, 'message': '事项创建成功，记得如期完成哦', 'backlog_id': backlog_id})

# 删
def backlogs_view_d(request, user_profile):
    req = request.body
    req = req.decode()
    req = json.loads(req)

    backlog_id = req.get('backlog_id')
    if not backlog_id:
        return JsonResponse({'errno': 2, 'message': '缺少参数'})

    try:
        backlog = Backlog.objects.get(id=backlog_id)
        backlog.is_delete = True
        backlog.save()
        a = BacklogAccessory.objects.filter(backlog_id=backlog_id, is_delete='f')
        for i in a:
            i.is_delete = True
            i.save()
    except Exception:
        return JsonResponse({'errno': 1, 'message': '删除失败'})

    return JsonResponse({'errno': 0, 'message': '删除成功'})

# 改
def backlogs_view_pu(request, user_profile):
    now = int(time.time())
    time_array = time.localtime(now)
    uodate_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
    req = request.body
    req = req.decode()
    req = json.loads(req)
    put_id = req.get('backlog_id')
    try:
        backlog = Backlog.objects.get(id=put_id)
        del req['backlog_id']
        for re in req:
            if re == "create_time":
                if not req['create_time']:
                    return JsonResponse({'errno': 1, 'message': '创建时间不能为空'})
                backlog.create_time = int(req['create_time'])
                time_array = time.localtime(req['create_time'])
                other_style_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)

                updatetime = '%s修改了事项的开始时间为:%s' % (uodate_time, other_style_time)
                UpdateBacklog.objects.create(update_backlog=updatetime, backlog_id=backlog)

            if re == "over_time":
                if not req['over_time']:
                    return JsonResponse({'errno': 2, 'message': '结束时间不能为空'})
                backlog.over_time = int(req['over_time'])
                time_array = time.localtime(req['over_time'])
                other_style_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
                updatetime = '%s修改了事项的完成时间为%s' % (uodate_time, other_style_time)
                UpdateBacklog.objects.create(update_backlog=updatetime, backlog_id=backlog)

            if re == "task":
                backlog.task = req['task']
                update_task = '%s修改事项为%s' % (uodate_time, req['task'])
                UpdateBacklog.objects.create(update_backlog=update_task, backlog_id=backlog)

            if re == 'task_details':
                backlog.task_details = req['task_details']
                update_task_details = "%s 修改事项详情为: %s" % (uodate_time, req['task_details'])
                UpdateBacklog.objects.create(update_backlog=update_task_details, backlog_id=backlog)

            if re == 'state':
                if req['state'] == 0:
                    if backlog.over_time < now:
                        backlog.state = req['state']
                        update_state = '%s逾期完成了事项' % uodate_time
                        UpdateBacklog.objects.create(update_backlog=update_state, backlog_id=backlog)

                    else:
                        backlog.state = req['state']
                        update_state = '%s完成了事项' % uodate_time
                        UpdateBacklog.objects.create(update_backlog=update_state, backlog_id=backlog)

                elif req['state'] == 2:
                    backlog.state = req['state']
        backlog.save()
    except Exception:
        return JsonResponse({'errno': 3, 'message': '保存数据失败'})
    return JsonResponse({'errno': 0, 'message': '成功'})

# 更新待办事项附件
def accessory_up(request, user_profile):
    req = request.body
    req = req.decode()
    req = json.loads(req)
    now = int(time.time())
    time_array = time.localtime(now)
    uodate_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
    accessory_list = req['accessory_list']
    backlog_id = req['backlog_id']

    try:
        accessory_lists = []
        backlog = Backlog.objects.get(id=backlog_id)
        for i in accessory_list:
            if i['type'] == 'add':
                accessory_dict = {}
                if not all([i['url'], i['size'], i['name']]):
                    return JsonResponse({'errno': 2, 'message': '缺少必要参数'})
                a = BacklogAccessory.objects.create(backlog_id=backlog,
                                                    accessory_url=i['url'],
                                                    accessory_size=i['size'],
                                                    accessory_name=i['name'])

                accessory_dict['name'] = a.accessory_name
                accessory_dict['url'] = a.accessory_url
                accessory_dict['size'] = a.accessory_size
                accessory_dict['id'] = a.id
                accessory_lists.append(accessory_dict)

            elif i['type'] == 'del':
                if not i['accessory_id']:
                    return JsonResponse({'errno': 3, 'message': '缺少必要参数'})
                accessory = BacklogAccessory.objects.get(id=i['accessory_id'])
                accessory.is_delete = True
                accessory.save()
        UpdateBacklog.objects.create(update_backlog="%s修改了附件" % uodate_time, backlog_id=backlog)
    except Exception:
        return JsonResponse({'errno': 1, 'message': '错误'})

    if accessory_list:
        return JsonResponse({'errno': 0, 'message': '修改完成', 'accessory_list': accessory_lists})
    return JsonResponse({'errno': 0, 'message': '修改完成'})

# 待办事项列表
def backlogs_view_g(request, user_profile):
    user = str(user_profile)
    import re
    user = re.match(r"<UserProfile: (.*) <.*>>", user).group(1)
    # 获取当前时间戳
    now = int(time.time())
    try:
        backlogs_list = Backlog.objects.filter(user=user, state=2, is_delete='f').order_by('-id')
    except Exception:
        return JsonResponse({'errno': 1, 'message': '获取数据失败'})
    # 过期
    past_due_list = []
    backlog_list = []

    for bl in backlogs_list:
        if bl.over_time < now:
            a = {}
            a['backlog_id'] = bl.id
            time_array = time.localtime(bl.create_time)
            create_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
            a['create_time'] = create_time
            a['create_timestamp'] = bl.create_time
            a['over_timestamp'] = bl.over_time
            time_array = time.localtime(bl.over_time)
            over_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
            a['over_time'] = over_time
            a['task'] = bl.task
            a['task_details'] = bl.task_details
            a['state'] = bl.state
            accessory_lists = BacklogAccessory.objects.filter(backlog_id=bl.id, is_delete='f')
            accessory_list = []
            if accessory_lists:
                for accessory in accessory_lists:
                    accessory_list.append(accessory.accessory_url)
                a["accessory_list"] = accessory_list
            past_due_list.append(a)

        else:
            b = {}
            b['backlog_id'] = bl.id
            time_array = time.localtime(bl.create_time)
            create_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
            b['create_time'] = create_time
            b['create_timestamp'] = bl.create_time
            time_array = time.localtime(bl.over_time)
            over_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
            b['over_time'] = over_time
            b['over_timestamp'] = bl.over_time
            b['task'] = bl.task
            b['task_details'] = bl.task_details
            if bl.over_time - now < 86400:
                b['warn'] = True

            else:
                b['warn'] = False
            b['state'] = bl.state

            accessory_lists = BacklogAccessory.objects.filter(backlog_id=bl.id, is_delete='f')
            accessory_list = []
            if accessory_lists:
                for accessory in accessory_lists:
                    accessory_list.append(accessory.accessory_url)
                b["accessory_list"] = accessory_list

            backlog_list.append(b)

    return JsonResponse({'errno': 0, 'message': '成功', 'past_due_list': past_due_list, 'backlog_list': backlog_list})

# 事项详情
def backlogs_details(request, user_profile):
    backlog_id = request.GET.get('backlog_id')
    try:

        backlogs = Backlog.objects.get(id=backlog_id)
        update_backlog = UpdateBacklog.objects.filter(backlog_id=backlog_id).order_by('-id')
        backlogs_accessory_list = BacklogAccessory.objects.filter(backlog_id=backlog_id, is_delete='f')
    except Exception:
        return JsonResponse({'errno': 1, 'message': '获取事项详情失败'})

    update_backlog_list = []
    for i in update_backlog:
        update_backlog_list.append(i.update_backlog)

    backlogs_dict = dict()
    backlogs_dict['id'] = backlogs.id
    backlogs_dict['create_time'] = backlogs.create_time
    backlogs_dict['over_time'] = backlogs.over_time
    backlogs_dict['task'] = backlogs.task
    backlogs_dict['task_details'] = backlogs.task_details
    backlogs_dict['state'] = backlogs.state
    accessory_list = []
    for accessory in backlogs_accessory_list:
        accessory_dict = dict()
        accessory_dict['id'] = accessory.id
        accessory_dict['url'] = accessory.accessory_url
        accessory_dict["size"] = accessory.accessory_size
        accessory_name = accessory.accessory_name
        accessory_dict['name'] = accessory_name
        types = accessory_name.split('.')
        accessory_dict['type'] = types[-1]
        accessory_list.append(accessory_dict)
    backlogs_dict['accessory_list'] = accessory_list

    return JsonResponse(
        {'errno': 0, 'message': '成功', 'backlog_dict': backlogs_dict, "update_backlog_list": update_backlog_list})

# 查看已完成事项
def accomplis_backlogs_view(request, user_profile):
    user = str(user_profile)
    user = re.match(r"<UserProfile: (.*) <.*>>", user).group(1)

    page = request.GET.get('page')
    generate_time = request.GET.get('start_time')
    over_time = request.GET.get('over_time')
    accomplis_task = request.GET.get('accomplis_task')
    filter_dict = {}

    if generate_time:
        filter_dict['create_time__range'] = (generate_time, time.time())
    if over_time:
        filter_dict['create_time__range'] = ('0', over_time)
    if all([generate_time, over_time]):
        filter_dict['create_time__range'] = (generate_time, over_time)

    if accomplis_task:
        filter_dict['task__contains'] = accomplis_task
    filter_dict['user'] = user
    filter_dict['state'] = 0
    filter_dict['is_delete'] = 'f'

    try:
        page = int(page)
        sums1 = 0
        sums2 = 20
        if page != 1:
            sums1 = (page - 1) * 20
            sums2 = page * 20
        accomplis_backlogs_list = Backlog.objects.filter(**filter_dict).order_by('-id')[sums1:sums2]
    except Exception:
        return JsonResponse({'errno': 1, 'message': '获取数据失败'})

    accomplis_backlogs_listss = []
    for accomplis_backlogs in accomplis_backlogs_list:
        a = {}
        a['id'] = accomplis_backlogs.id

        time_array = time.localtime(accomplis_backlogs.create_time)
        create_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
        a['create_time'] = create_time

        time_array = time.localtime(accomplis_backlogs.over_time)
        over_time = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
        a['over_time'] = over_time

        a['task'] = accomplis_backlogs.task
        a['task_details'] = accomplis_backlogs.task_details
        accessory_list = BacklogAccessory.objects.filter(backlog_id=accomplis_backlogs.id)
        if accessory_list:
            accessory_dict = {}
            for accessory in accessory_list:
                accessory_dict[accessory.id] = accessory.accessory_url
                accessory_dict["size"] = accessory.accessory_size
                accessory_name = accessory.accessory_name
                accessory_dict['name'] = accessory_name
                types = accessory_name.split('.')
                accessory_dict['type'] = types[-1]
            a["accessory_dict"] = accessory_dict

        a['state'] = accomplis_backlogs.state
        accomplis_backlogs_listss.append(a)

    return JsonResponse({'errno': 0, 'message': '成功', 'accomplis_backlog_list': accomplis_backlogs_listss})

def users_view(request, user_profile):
    users = UserProfile.objects.all().order_by('full_name')
    user_list = list()
    for user in users:
        if user == user_profile or user.full_name[-3:] == 'Bot':
            continue

        user_dict = dict()
        user_dict['user_avatar'] = avatar.absolute_avatar_url(user)
        user_dict['name'] = user.full_name
        user_dict['id'] = user.id
        user_dict['email'] = user.email
        user_dict['short_name'] = user.short_name
        user_list.append(user_dict)
    return JsonResponse({'errno': '0', 'message': '成功', 'user_list': user_list, 'user_me': user_profile.full_name,
                         'user_id': user_profile.id})


import socket
import sys
import time
import math
import pygame

MSGLEN = 128
PRINT_STUFF = True
SERV_IP = "10.0.0.12"

WIN_SIZE_X = 600
WIN_SIZE_Y = 600

WHITE = [255,255,255]

class XO_ClientGUI:

    def __init__(self, id:str):
        self.my_turn = False
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.board = [['N' for i in range(3)] for j in range(3)]

        # Change self.host to server's ip
        self.host = socket.gethostname()

        self.port = 12345
        self.s.connect( (self.host, self.port))

        self.id = id

        self.init_board()
        self.play()

    def play(self):
        print("Waiting for confirmation from server")
        msg = self.s.recv(1).decode()
        while msg != 'X' and msg != 'O':
            msg = self.s.recv(1).decode()
            time.sleep(0.2)
        print("Got confirmation")
        self.id = msg
        print(f'I am {self.id}')

        pygame.draw.line(self.screen, WHITE, [WIN_SIZE_X / 3, 0], [WIN_SIZE_X / 3,WIN_SIZE_Y])
        pygame.draw.line(self.screen, WHITE, [(2*WIN_SIZE_X) / 3, 0], [(2*WIN_SIZE_X) / 3,WIN_SIZE_Y])
        pygame.draw.line(self.screen, WHITE, [0, WIN_SIZE_Y / 3], [WIN_SIZE_X,WIN_SIZE_Y / 3])
        pygame.draw.line(self.screen, WHITE, [0, 2*WIN_SIZE_Y/3], [WIN_SIZE_X,2*WIN_SIZE_Y/3])
        pygame.display.flip()

        reply = "!NO!"
        run = True
        while run:

            while not self.my_turn:
                reply = self.s.recv(MSGLEN).decode()

                if len(reply) == 0:
                    continue

                if len(reply.strip("WAIT")) == 9:

                    current_board = []
                    for char in reply:
                        if char == 'X' or char == 'O' or char == 'N':
                            current_board.append(char)
                    temp = [['N' for i in range(3)] for j in range(3)]
                    k = 0
                    for i in range(3):
                        for j in range(3):
                            temp[i][j] = current_board[k]
                            k += 1

                    self.update_my_board(temp)

                if self.stop_indicator(reply):
                    run = False
                    break

                if "GO" in reply:
                    self.my_turn = True

            reply = "!NO!"
            while self.my_turn:

                # Get mouse pressed location
                pos = None
                while pos is None:
                    events = pygame.event.get()
                    for ev in events:
                        if ev.type == pygame.QUIT:
                            run = False
                            break
                        if ev.type == pygame.MOUSEBUTTONUP:
                            pos = pygame.mouse.get_pos()
                    self.clock.tick(30)

                # Translate it to a number from 0 to 2
                x, y = pos[0] / (WIN_SIZE_X / 3), pos[1] / (WIN_SIZE_Y / 3)
                x = min(int(x),2)
                y = min(int(y),2)
                val = str(x) + "," + str(y)

                # val = input()
                if 'q' in val.lower():
                    self.send_message('q')
                    run = False
                    break

                if not self.valid_message(val):
                    continue

                self.send_message(val)
                reply = self.s.recv(MSGLEN).decode()
                if PRINT_STUFF: print(reply)

                if "!NO!" not in reply:
                    self.my_turn = False
                    self.board[x][y] = self.id
                    a_bit = 40
                    start_x = self.x_to_window(x) + a_bit
                    start_y = self.y_to_window(y) + a_bit
                    end_x = self.y_to_window(x + 1) - a_bit
                    end_y = self.y_to_window(y + 1) - a_bit

                    if self.id == 'X':
                        self.drawX(start_x, start_y, end_x, end_y, end_x, start_y, start_x, end_y)
                    else:
                        self.drawO((start_x + end_x) / 2, (start_y + end_y) / 2, a_bit)

                if self.stop_indicator(reply):
                    run = False
                    break

        self.s.close()

    def init_board(self):
        pygame.init()
        self.clock = pygame.time.Clock()
        self.screen = pygame.display.set_mode([WIN_SIZE_X,WIN_SIZE_Y])

    def stop_indicator(self, reply):
        return reply == "DC" or reply == "W" or reply == "L" or reply == "DRAW"

    def valid_message(self, msg:str):
        msg = msg.split(",")
        if len(msg) != 2:
            return False
        try:
            i = int(msg[0])
            j = int(msg[1])

            if 0<=i<=2 and 0<=j<=2:
                return True
            return False

        except ValueError or ArithmeticError or IndexError:
            return False

    def send_message(self, message):
        print(f'Sending this message: {message}')
        message = self.id + message
        self.s.send(message.encode())

    def update_my_board(self, reply):

        diff_char = 'N'
        ind = 0
        no_diff = True
        print(reply)
        print(self.board)
        for i in range(3):
            for j in range(3):
                if self.board[i][j] != reply[i][j]:
                    diff_char = reply[i][j]
                    print(f'false, {reply[i][j]}, {self.board[i][j]}')
                    x, y = i, j
                    no_diff = False
                    break
                else:
                    ind += 1

        if no_diff:
            return
        print(f'diff : {diff_char}, pos : {x},{y}')

        self.board[x][y] = diff_char
        print(f'board now\n{self.board}')

        a_bit = 40
        start_x = self.x_to_window(x) + a_bit
        start_y = self.y_to_window(y) + a_bit
        end_x = self.y_to_window(x + 1) - a_bit
        end_y = self.y_to_window(y + 1) - a_bit

        if diff_char == 'X':
            self.drawX(start_x, start_y, end_x, end_y, end_x, start_y, start_x, end_y)
        else:
            self.drawO((start_x + end_x)/2,(start_y + end_y)/2, a_bit)

    def drawX(self, ax, ay, bx, by, cx, cy, dx, dy):
        R = 4
        D = 2

        dt = (ax - ay) / D
        x = ax
        y = ay
        while x <= bx:
            x += D
            y += D
            pygame.draw.circle(self.screen, WHITE, [x, y], R)
            pygame.display.flip()
            self.clock.tick(100)

        x = cx
        y = cy
        while x >= dx:
            x -= D
            y += D
            pygame.draw.circle(self.screen, WHITE, [x, y], R)
            pygame.display.flip()
            self.clock.tick(100)

    def drawO(self, x, y, radius):
        cenx = x
        ceny = y
        R = 2

        x += radius
        theta = math.pi / 90
        cos_theta = math.cos(theta)
        sin_theta = math.sin(theta)

        for i in range(180):
            pygame.draw.circle(self.screen, WHITE, [x, y], R)
            pygame.display.flip()

            temp_x = ((x - cenx) * cos_theta) - ((y - ceny) * sin_theta)
            temp_y = ((x - cenx) * sin_theta) + ((y - ceny) * cos_theta)

            x = temp_x + cenx
            y = temp_y + ceny

            pos = [x, y]
            self.clock.tick(100)

    def x_to_window(self, x):
        return x * (WIN_SIZE_X / 3)

    def y_to_window(self, y):
        return y * (WIN_SIZE_Y / 3)
if __name__ == '__main__':
    p = XO_ClientGUI(id='A')


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('server', '0100_driver_ssn'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='driver',
            name='defensive_cert_image',
        ),
    ]


from django.conf.urls import url, include

from . import views
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'pages', views.PageViewSet)

urlpatterns = [
    url(r'^insert-nbsp', views.insert_nbsp),
    url(r'^search-documents/de', views.search_documents_de),
    url(r'^search-documents/en', views.search_documents_en),
    url(r'^', include(router.urls, namespace='main_api')),
    url(r'^api-auth/', include('rest_framework.urls',
                               namespace='main_rest_framework'))
]


# -*- coding: utf-8 -*-
"""
Created on Wed Jun 14 22:57:20 2023

@author: Zeo
"""

import numpy as np
import matplotlib.pyplot as plt

def classical_walk(samples):
    posN = np.zeros(P);
    posN[N]= 1;
    for i in range (N):
        posN = (np.roll(posN, 1)+ np.roll(posN, -1)) /2;
    return posN;
N = 100;
P = 2 * N + 1;
samples = 1000;
prob = classical_walk(N);
# Plot the probability distribution
plt.bar(np.arange(-N, N+1), prob);
plt.xlabel('Position')
plt.ylabel('Probability')
plt.title('Classical Random Walk Probability Distribution (Time)')
plt.savefig('Images\classical_walk_time', dpi=1080)
plt.show();


"""
EXPERIMENTAL
============

Lightweight connection pooling for peewee.

In a single-threaded application, only one connection will be created. It will
be continually recycled until either it exceeds the stale timeout or is closed
explicitly (using `.manual_close()`).

In a multi-threaded application, up to `max_connections` will be opened.
"""
import heapq
import logging
import threading
import time

from peewee import MySQLDatabase
from peewee import PostgresqlDatabase

logger = logging.getLogger('peewee.pool')

class PooledDatabase(object):
    def __init__(self, database, max_connections=20, stale_timeout=None,
                 **kwargs):
        self.max_connections = max_connections
        self.stale_timeout = stale_timeout
        self._connections = []
        self._in_use = {}
        self._closed = set()
        self.conn_key = id

        super(PooledDatabase, self).__init__(database, **kwargs)

    def _connect(self, *args, **kwargs):
        while True:
            try:
                ts, conn = heapq.heappop(self._connections)
                key = self.conn_key(conn)
            except IndexError:
                ts = conn = None
                logger.debug('No connection available in pool.')
                break
            else:
                if self.stale_timeout and self._is_stale(ts):
                    logger.debug('Connection %s was stale, closing.', key)
                    self._close(conn, True)
                    ts = conn = None
                elif self._is_closed(key, conn):
                    logger.debug('Connection %s was closed.', key)
                    ts = conn = None
                    self._closed.discard(key)
                else:
                    break

        if conn is None:
            if self.max_connections and (
                    len(self._in_use) >= self.max_connections):
                raise ValueError('Exceeded maximum connections.')
            conn = super(PooledDatabase, self)._connect(*args, **kwargs)
            ts = time.time()
            key = self.conn_key(conn)
            logger.debug('Created new connection %s.', key)

        self._in_use[key] = ts
        return conn

    def _is_stale(self, timestamp):
        return (time.time() - timestamp) > self.stale_timeout

    def _is_closed(self, key, conn):
        return key in self._closed

    def _close(self, conn, close_conn=False):
        key = self.conn_key(conn)
        if close_conn:
            self._closed.add(key)
            super(PooledDatabase, self)._close(conn)
        elif key in self._in_use:
            logger.debug('Returning %s to pool.', key)
            ts = self._in_use[key]
            del self._in_use[key]
            heapq.heappush(self._connections, (ts, conn))

    def manual_close(self):
        """
        Close the underlying connection without returning it to the pool.
        """
        conn = self.get_conn()
        self.close()
        self._close(conn, close_conn=True)

    def close_all(self):
        """
        Close all connections managed by the pool.
        """
        for _, conn in self._connections:
            self._close(conn, close_conn=True)
        for conn in self._in_use:
            self._close(conn, close_conn=True)

class PooledMySQLDatabase(PooledDatabase, MySQLDatabase):
    def _is_closed(self, key, conn):
        is_closed = super(PooledMySQLDatabase, self)._is_closed(key, conn)
        if not is_closed:
            if hasattr(conn, 'open'):
                # MySQLdb `ping()` seems to always return `None` in my testing.
                # So the `open` attribute will be used instead.
                is_closed = not bool(conn.open)
            else:
                # pymysql `ping([reconnect=True])` will indicate if the conn
                # is closed or not.
                try:
                    is_closed = not conn.ping(False)
                except:
                    is_closed = True
        return is_closed

class _PooledPostgresqlDatabase(PooledDatabase):
    def _is_closed(self, key, conn):
        is_closed = super(_PooledPostgresqlDatabase, self)._is_closed(key, conn)
        if not is_closed:
            is_closed = bool(conn.closed)
        return is_closed

class PooledPostgresqlDatabase(_PooledPostgresqlDatabase, PostgresqlDatabase):
    pass

try:
    from playhouse.postgres_ext import PostgresqlExtDatabase

    class PooledPostgresqlExtDatabase(_PooledPostgresqlDatabase, PostgresqlExtDatabase):
        pass
except ImportError:
    pass


import nltk
import random #to shuffle up data so that no bias
from nltk.corpus import movie_reviews #contains 2000 +ve and -ve reviews
import pickle
from nltk.classify.scikitlearn import SklearnClassifier
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords

#list out all words document-wise and add the category also in a list of tupple
#documents = []
#for category in movie_reviews.categories():
#	for fileid in movie_reviews.fileids(category):
#		documents.append((list(movie_reviews.words(fileid)),category))

#random.shuffle(documents)

#print(documents[1])

short_pos = open("mypos.txt","r").read()
short_neg = open("myneg.txt","r").read()

documents = []
for r in short_pos.split('\n'):
	documents.append((r,'pos'))
for r in short_neg.split('\n'):
	documents.append((r,'neg'))

random.shuffle(documents)
print(documents[:20])
#print(documents)

all_words= []

short_pos_words = word_tokenize(short_pos)
short_neg_words = word_tokenize(short_neg)

#for w in movie_reviews.words():
#	all_words.append(w.lower())

for w in short_pos_words:
	all_words.append(w.lower())
for w in short_neg_words:
	all_words.append(w.lower())

all_words = nltk.FreqDist(all_words)
#print(all_words.most_common())
word_features = list(all_words.keys())[:100]
#print(all_words["awesome"])

def findfeatures(document):
	words = set(document)
	features = {}
	for w in word_features:
		features[w] = (w in words)
	return features

#print((findfeatures(movie_reviews.words('neg/cv000_29416.txt'))))
featuresets = [(findfeatures(rev),category) for (rev,category) in documents]

random.shuffle(featuresets)

#myline="mattei's underdeveloped effort here is nothing but a convenient conveyor belt of brooding personalities that parade about as if they were coming back from stock character camp -- a drowsy drama infatuated by its own pretentious self-examination . "

myline = "i know how to do this"
mydoc = []
mydoc.append((list(word_tokenize(myline)),'pos'))
myinputfeatures = [(findfeatures(rev),category) for (rev,category) in mydoc]

training_set = featuresets[:]

#testing_set = featuresets[:500]
testing_set = myinputfeatures[:]
print()
print()
#print(testing_set)
print()
print()
classifier = nltk.NaiveBayesClassifier.train(training_set)
classifier.show_most_informative_features(100)
#classifier_f = open("naivebayes.pickle","rb")

#classifier = pickle.load(classifier_f)
#classifier_f.close()
print("Accuracy: ", (nltk.classify.accuracy(classifier, testing_set))*100)

print("Classification:",classifier.classify(testing_set[0][0]))

#pickling
#save_classifier = open("naivebayes.pickle","wb")
#pickle.dump(classifier,save_classifier)
#save_classifier.close()


import requests
from bs4 import BeautifulSoup
import csv
import time

MAX_RETRIES = 3
RETRY_DELAY = 5  # Seconds between retries

# ... (rest of the functions remain unchanged) ...

def retry_request(url):
    retries = 0
    while retries < MAX_RETRIES:
        try:
            response = requests.get(url)
            response.raise_for_status()  # Check for successful response
            return response
        except requests.exceptions.RequestException as e:
            print(f"Failed to retrieve data from {url}. Error: {e}")
            retries += 1
            time.sleep(RETRY_DELAY)

    return None

def scrape_product_listing_page(url):
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
    }

    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()  # Check for successful response
    except requests.exceptions.RequestException as e:
        print(f"Failed to retrieve data from {url}. Error: {e}")
        return []

    soup = BeautifulSoup(response.text, "html.parser")
    products = []

    product_cards = soup.find_all("div", class_="s-include-content-margin")

    for card in product_cards:
        product_url = card.find("a", class_="a-link-normal")
        if product_url:
            product_url = f"https://www.amazon.in{product_url['href']}"
        else:
            continue

        product_name = card.find("span", class_="a-size-medium")
        if product_name:
            product_name = product_name.text.strip()
        else:
            continue

        product_price = card.find("span", class_="a-offscreen")
        if product_price:
            product_price = product_price.text.strip()
        else:
            continue

        product_rating = card.find("span", class_="a-icon-alt")
        if product_rating:
            product_rating = float(product_rating.text.split()[0])
        else:
            product_rating = None

        product_reviews = card.find("span", {"data-component-type": "s-product-rating"})
        if product_reviews:
            product_reviews = int(product_reviews.text.replace(",", ""))
        else:
            product_reviews = 0

        products.append({
            "URL": product_url,
            "Name": product_name,
            "Price": product_price,
            "Rating": product_rating,
            "Number of Reviews": product_reviews
        })

    return products

def scrape_product_details_page(url):
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
    }

    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()  # Check for successful response
    except requests.exceptions.RequestException as e:
        print(f"Failed to retrieve data from {url}. Error: {e}")
        return {}

    soup = BeautifulSoup(response.text, "html.parser")

    description = soup.find("div", {"id": "productDescription"})
    description_text = description.text.strip() if description else ""

    asin_tag = soup.find("th", text="ASIN")
    asin = asin_tag.find_next("td").text.strip() if asin_tag else ""

    product_description = soup.find("meta", {"name": "description"})["content"]

    manufacturer_tag = soup.find("th", text="Manufacturer")
    manufacturer = manufacturer_tag.find_next("td").text.strip() if manufacturer_tag else ""

    return {
        "Description": description_text,
        "ASIN": asin,
        "Product Description": product_description,
        "Manufacturer": manufacturer
    }

def scrape_multiple_pages(base_url, num_pages=20):
    all_products = []
    for page_num in range(1, num_pages + 1):
        url = f"{base_url}&page={page_num}"
        products = scrape_product_listing_page(url)
        all_products.extend(products)
        time.sleep(2)  # Adding a delay of 2 seconds to avoid rate-limiting

    # Fetch additional details for each product
    for product in all_products:
        url = product["URL"]
        additional_details = scrape_product_details_page(url)
        product.update(additional_details)

    return all_products

def export_to_csv(data, filename):
    keys = ["URL", "Name", "Price", "Rating", "Number of Reviews", "Description", "ASIN", "Product Description", "Manufacturer"]
    with open(filename, "w", newline="", encoding="utf-8") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=keys)
        writer.writeheader()
        writer.writerows(data)

if __name__ == "__main__":
    base_url = "https://www.amazon.in/s?k=bags&crid=2M096C61O4MLT&qid=1653308124&sprefix=ba%2Caps%2C283&ref=sr_pg_"
    num_pages = 20

    scraped_data = scrape_multiple_pages(base_url, num_pages)

    # Export data to CSV
    export_to_csv(scraped_data, "amazon_bags_data.csv")


import numpy as np
import matplotlib.pyplot as plt
from Utils.Bcolor import Bcolors
from math import fabs
from Utils.Debug_Levels import Debug_Levels as verbos
import time
from Libraries.Enums import NNLibs
from Libraries.Torch import Torch
from Libraries.Simplynet import SimplyNet
from Libraries.Sklearn import Sklearn
from Libraries.Reader import Reader

#TODO give credit to asian
#TODO make docstring like numpy

class Brain:
    """
    Draw a neural network graph using matplotlib

    parameters :
        - ax : matplotlib.axes.AxesSubplot
            The axes on which to plot the cartoon (get e.g. by plt.gca())
        - fig_size :
            Figure size in the X,Y directions
        - offset_left : float
            The center of the leftmost node(s) will be placed here
        - offset_right : float
            The center of the rightmost node(s) will be placed here
        - offset_bottom : float
            The center of the bottommost node(s) will be placed here
        - offset_top : float
            The center of the topmost node(s) will be placed here
        - layer_sizes : list of int
            List of layer sizes, including input and output dimensionality
        - weights :(list) length (n_layers - 1) The ith element in the list represents the weight matrix corresponding to layer i.
        - bias_weights : (list) length (n_layers - 1)The ith element in the list represents the bias vector corresponding to layer i + 1.
        - n_iter: (int) : The number of iterations the solver has ran.
        - loss: (float) : The current loss computed with the loss function.
        - debug_level (Debug_Levels): Check levels on Debug_Levels.py
    """

    def __init__(self, nn_lib, show_weights=False, show_arrows=False, show_text=False,
                fig_size_x=12, fig_size_y=12, debug_level=verbos.NO):
        '''
        Initialize brain.

        Parameters
        ----------
        nn_lib : list
            Weights of the model.

        nn_bias_weights : list
            Biases of the model.
        '''
        self.layer_sizes    = None
        self.ax             = None

        # Figure sizes in percentage
        self.fig            = None
        self.fig_size_x     = fig_size_x
        self.fig_size_y     = fig_size_y

        self.left           = 0.1
        self.right          = 0.9
        self.bottom         = 0.1
        self.top            = 0.9

        self.offset_all     = [self.left, self.right, self.bottom, self.top]
        self.weights        = None
        self.bias_weights   = None

        self.n_layers       = None
        self.v_spacing      = None
        self.h_spacing      = None

        self.show_weights   = show_weights
        self.show_arrows    = show_arrows
        self.show_texts     = show_text

        # Beautiful printing
        self.bcolors = Bcolors()

        # To see debugs, give higher number than 0
        self.debug_level = debug_level

        # Initate limits of figure
        self.init_graph()

        # Neural network library reader
        self.reader = Reader()

        # Set neural network library
        self.set_lib(nn_lib)

    def set_lib(self,nn_lib):
        """Choose library to read neural network

        Args:
            nn_lib (Reader):
        """
        if nn_lib == NNLibs.Torch:
            self.reader = Torch()

        elif nn_lib == NNLibs.SimplyNet:
            self.reader = SimplyNet()

        elif nn_lib == NNLibs.Sklearn:
            self.reader = Sklearn()

        elif nn_lib == NNLibs.Tensorflow:
            pass

    def visualize(self, weights, load_from_path=False, loss_ = None, n_iter_ = None, interval=1):
        '''
        Plot everything(nodes, edges, arrows, input, output)

        Parameters
        ----------
        loss_ (int) : Brain's latest loss value.
        n_iter_ (int): Number of iterations/epochs.
        load_from_path (bool) : Set true for keeping figure after visualization in directly vis from weights
        '''
        self.reader.read(weights)
        self.weights        = self.reader.weights_list
        self.bias_weights   = self.reader.biases_list
        self.ax.cla()

        # If loss or iter no is not given dont show title
        if loss_ is None or n_iter_ is None:
            pass
        else:
            self.ax.set_title("Loss : {0:.3} / Iteration : {1}".format(loss_,n_iter_))

        self.ax.axis('off')
        self.set_figure()
        self.plot_input_arrows()
        self.plot_nodes()
        self.plot_bias_nodes()
        self.plot_edge_node_connections()
        self.plot_bias_edge_connections()
        self.plot_output_arrows(loss_,n_iter_)
        # plt.show()
        plt.pause(interval)
        plt.draw()

        # If loading network from path, dont close figure after its drawn
        if load_from_path:
            self.bcolors.print_warning("Please press enter to close the figure.")
            input()

    def init_graph(self):
        '''
        Creates the figure to plot the brain.
        '''
        if self.debug_level.value >= verbos.MEDIUM.value:
            self.bcolors.print_header("Initiating visualization graphics")
        try :
            plt.ion()
            self.fig = plt.figure(figsize=(self.fig_size_x, self.fig_size_y))
            # Get current axes (gca)
            self.ax  = self.fig.gca()
            self.ax.axis('off')
            #TODO This gives error: "TypeError: 'AxesSubplot' object is not callable", fig.gca() returns AxesSubplot object
            # self.ax(autoscale=False)

        except:
            print("Graph could not be set !\nPlease enter the figure sizes correctly")

    def set_figure(self):
        '''
        Check if there is a problem with figure offset, layer sizes to continue procedure.

        Returns
        -------
        is_figure_set : boolean
            True if the figure's offset and layer sizes are ok.
        '''
        is_figure_set = False
        is_offset_ok = self.is_fig_offsets_ok()
        is_layer_sizes_ok = self.set_layer_sizes()
        if self.debug_level.value >= verbos.LOW.value:
            print("Layer Sizes : ",self.layer_sizes)
        if is_offset_ok and is_layer_sizes_ok:
            if self.debug_level.value >= verbos.MEDIUM.value:
                self.bcolors.print_inform("Visualization graphics are set !")
            self.n_layers  = len(self.layer_sizes)
            self.v_spacing = (self.top - self.bottom)/float(max(self.layer_sizes))
            self.h_spacing = (self.right - self.left)/float(self.n_layers)

            is_figure_set = True
        return is_figure_set

    def is_fig_offsets_ok(self):
        #TODO Why?
        '''
        Checks if figure's offsets are between (0-100).

        Returns
        -------
        is_correct: boolean
            True/False based on the condition.
        '''
        is_correct = True
        for size in self.offset_all:
            if size > 100 or size < 0 :
                is_correct = False
                break
        return is_correct

    def set_layer_sizes(self):
        '''
        Set layer sizes.

        Returns
        -------
        True/False
            If there are no layers, return False.
        '''
        self.layer_sizes = []
        num_of_layers = len(self.weights)

        for i in range(num_of_layers):
            layer_shape = self.weights[i].shape

            # First Layer
            if(i == 0):
                layer_size = layer_shape[0]
                self.layer_sizes.append(layer_size)

            # Other layers
            layer_size = layer_shape[1]
            self.layer_sizes.append(layer_size)

        if(len(self.layer_sizes) > 0):
            return True
        else:
            return False

    def plot_input_arrows(self):
        if self.show_arrows:
            if self.debug_level.value >= verbos.MEDIUM.value :
                self.bcolors.print_ok("Plotting input arrows ..")
            self.layer_top_0 = self.v_spacing*(self.layer_sizes[0] - 1)/2. + (self.top + self.bottom)/2.
            for m in range(self.layer_sizes[0]):
                arrow_posx = self.left-0.18
                arrow_posy = self.layer_top_0 - m*self.v_spacing
                # print(arrow_posx,arrow_posy)
                plt.arrow(arrow_posx,arrow_posy , 0.12, 0,  lw =1, head_width=0.01, head_length=0.02)

    def plot_nodes(self):
        '''
        Plot nodes, input(X1, X2,...) and output(y1, y2,...).
        '''
        if self.debug_level.value >= verbos.MEDIUM.value :
            self.bcolors.print_ok("Plotting nodes ..")
        for n, layer_size in enumerate(self.layer_sizes):
            layer_top = self.v_spacing*(layer_size - 1)/2. + (self.top + self.bottom)/2.
            for m in range(layer_size):
                circle = plt.Circle((n*self.h_spacing + self.left, layer_top - m*self.v_spacing), self.v_spacing/8.,\
                                color='w', ec='k', zorder=4)

                if self.show_texts:
                    # Add texts
                    if n == 0:
                        plt.text(self.left-0.125, layer_top - m*self.v_spacing, r'$X_{'+str(m+1)+'}$', fontsize=15)
                    elif (self.n_layers == 3) & (n == 1):
                        plt.text(n*self.h_spacing + self.left+0.00, layer_top - m*self.v_spacing+ (self.v_spacing/8.+0.01*self.v_spacing), r'$H_{'+str(m+1)+'}$', fontsize=15)
                    elif n == self.n_layers -1:
                        plt.text(n*self.h_spacing + self.left+0.10, layer_top - m*self.v_spacing, r'$y_{'+str(m+1)+'}$', fontsize=15)

                self.ax.add_artist(circle)

    def plot_bias_nodes(self):
        if self.debug_level.value >= verbos.MEDIUM.value :
            self.bcolors.print_ok("Plotting bias nodes ..")
        # Bias-Nodes
        for n in range(len(self.layer_sizes)):
            if n < self.n_layers -1:
                x_bias = (n + 0.5) * self.h_spacing + self.left
                y_bias = self.top + 0.005
                circle = plt.Circle((x_bias, y_bias), self.v_spacing/8.,\
                                    color='w', ec='k', zorder=4)
                if self.show_texts:
                    # Add texts
                    plt.text(x_bias-(self.v_spacing/8.+0.10*self.v_spacing+0.01), y_bias, r'$1$', fontsize=15)

                self.ax.add_artist(circle)

    def plot_edge_node_connections(self):
        if self.debug_level.value >= verbos.MEDIUM.value :
            self.bcolors.print_ok("Plotting edge-node connections ..")

        # Edges between nodes
        for n, (layer_size_a, layer_size_b) in enumerate(zip(self.layer_sizes[:-1], self.layer_sizes[1:])):
            layer_top_a = self.v_spacing*(layer_size_a - 1)/2. + (self.top + self.bottom)/2.
            layer_top_b = self.v_spacing*(layer_size_b - 1)/2. + (self.top + self.bottom)/2.

            # Normalize layer weights
            layer_weights = self.weights[n]
            normalized_weights = self.normalize_weights(layer_weights)

            for m in range(layer_size_a):
                for o in range(layer_size_b):

                    alpha_val, color = self.get_alpha_and_color(normalized_weights[m, o])

                    line = plt.Line2D([n*self.h_spacing + self.left, (n + 1)*self.h_spacing + self.left],
                                      [layer_top_a - m*self.v_spacing, layer_top_b - o*self.v_spacing], c=color, alpha=alpha_val)
                    self.ax.add_artist(line)
                    xm = (n*self.h_spacing + self.left)
                    xo = ((n + 1)*self.h_spacing + self.left)
                    ym = (layer_top_a - m*self.v_spacing)
                    yo = (layer_top_b - o*self.v_spacing)
                    rot_mo_rad = np.arctan((yo-ym)/(xo-xm))
                    rot_mo_deg = rot_mo_rad*180./np.pi
                    xm1 = xm + (self.v_spacing/8.+0.05)*np.cos(rot_mo_rad)
                    if n == 0:
                        if yo > ym:
                            ym1 = ym + (self.v_spacing/8.+0.12)*np.sin(rot_mo_rad)
                        else:
                            ym1 = ym + (self.v_spacing/8.+0.05)*np.sin(rot_mo_rad)
                    else:
                        if yo > ym:
                            ym1 = ym + (self.v_spacing/8.+0.12)*np.sin(rot_mo_rad)
                        else:
                            ym1 = ym + (self.v_spacing/8.+0.04)*np.sin(rot_mo_rad)

                    if self.show_texts:
                        plt.text( xm1, ym1,\
                                str(round(self.weights[n][m, o],4)),\
                                rotation = rot_mo_deg, \
                                fontsize = 10)

    def plot_bias_edge_connections(self):
        if self.debug_level.value >= verbos.MEDIUM.value :
            self.bcolors.print_ok("Plotting bias-edge connections ..")
        # Edges between bias and nodes
        for n, (_, layer_size_b) in enumerate(zip(self.layer_sizes[:-1], self.layer_sizes[1:])):
            # Normalize layer weights
            bias_weights = self.bias_weights[n]
            normalized_weights = self.normalize_weights(bias_weights)

            if n < self.n_layers-1:
                #layer_top_b: y of highest node of the next layer
                layer_top_b = self.v_spacing*(layer_size_b - 1)/2. + (self.top + self.bottom)/2.
                x_bias = (n+0.5)*self.h_spacing + self.left
                y_bias = self.top + 0.005
            for o in range(layer_size_b):
                alpha_val, color = self.get_alpha_and_color(normalized_weights[o])

                line = plt.Line2D([x_bias, (n + 1)*self.h_spacing + self.left],
                              [y_bias, layer_top_b - o*self.v_spacing], c=color, alpha=alpha_val)
                self.ax.add_artist(line)
                xo = ((n + 1)*self.h_spacing + self.left)
                yo = (layer_top_b - o*self.v_spacing)
                rot_bo_rad = np.arctan((yo-y_bias)/(xo-x_bias))
                rot_bo_deg = rot_bo_rad*180./np.pi
                xo2 = xo - (self.v_spacing/8.+0.01)*np.cos(rot_bo_rad)
                yo2 = yo - (self.v_spacing/8.+0.01)*np.sin(rot_bo_rad)
                xo1 = xo2 -0.05 *np.cos(rot_bo_rad)
                yo1 = yo2 -0.05 *np.sin(rot_bo_rad)
                if self.show_texts:
                    plt.text( xo1, yo1,\
                        str(round(self.bias_weights[n][o],4)),\
                        rotation = rot_bo_deg, \
                        fontsize = 10)

    def plot_output_arrows(self,loss,n_iter):
        if self.show_arrows:
            if self.debug_level.value >= verbos.MEDIUM.value :
                self.bcolors.print_ok("Plotting output arrows ..")
            # Output-Arrows
            layer_top_0 = self.v_spacing*(self.layer_sizes[-1] - 1)/2. + (self.top + self.bottom)/2.
            for m in range(self.layer_sizes[-1]):
                plt.arrow(self.right+0.015, layer_top_0 - m*self.v_spacing, 0.16*self.h_spacing, 0,  lw =1, head_width=0.01, head_length=0.02)

        # # Record the n_iter_ and loss
        # plt.text(self.left + (self.right-self.left)/3., self.bottom - 0.005*self.v_spacing, \
        #          'Steps:'+str(n_iter)+'    Loss: {0:.2f}'.format(loss), fontsize = 15)

    def normalize_weights(self, weights):
        return weights / np.linalg.norm(weights)

    def get_alpha_and_color(self, normalized_weights):
        """Get alpha(transparency) and color of weight

        Args:
            normalized_weights (np.ndarray)

        Returns:
            alpha_val (integer), color(string)
        """
        color = 'g'
        # For positive values draw lines blue, for negative ones draw as red
        if normalized_weights < 0:
            alpha_val = -normalized_weights
            color = 'r'
        else:
            alpha_val = normalized_weights
            color = 'b'

        return alpha_val, color


#!/usr/bin/env python
import pickle
import config
import socket
from user_token import User_token
# http://grokbase.com/t/python/python-list/0369kdpe56/scanning-for-local-servers-getting-a-broadcast-address
# http://www.tutorialspoint.com/python/python_networking.htm
# we will send list of tokens
def run_token_client(ip,user_tokens,port=config.token_serv_port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
    if ip == "<broadcast>":
        sock.setsockopt (socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    while len(user_tokens)!=0:
        tmp_tkns=[]
        while len(pickle.dumps(tmp_tkns)) < config.udp_max_data_size and len(user_tokens)!=0:
            tmp_tkns.append(user_tokens.pop())
        # The last element would have crossed the limit
        if len(pickle.dumps(tmp_tkns)) > config.udp_max_data_size:
            user_tokens.append(tmp_tkns.pop())
        sock.sendto(pickle.dumps(tmp_tkns), (ip, port))


import cv2
import numpy as np

fn = ['12345.png', 'cir.png']

for ii, n in enumerate(fn):
    planets = cv2.imread(n)
    planets = cv2.resize(planets, (650, 400))

    gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
    img = cv2.medianBlur(gray_img, 5)
    cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 120, param1=100,
                               param2=30, minRadius=0, maxRadius=0)
    if circles is not None:

        circles = np.uint16(np.around(circles))

        for i in circles[0, :]:
            # draw	the	outer	circle
            cv2.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2)
            print((i[0], i[1]), i[2])
            # draw	the	center	of	the	circle
            cv2.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3)

        cv2.imshow(f"HoughCirlces_{ii}", planets)

cv2.waitKey()
cv2.destroyAllWindows()


# -*- coding: utf-8 -*-
"""
Created on Mon Mar 30 13:50:15 2020

@author: DELL
"""
import numpy as np
from PIL import Image
w = 5
h = 5
array= np.zeros([w,h,3] , dtype = np.uint8)
img = Image.fromarray(array)
img.save('AREA_img1.png')
array1= np.zeros([100,200,3] , dtype = np.uint8)
array1[: ,:100 ] =  [255,128,0]  #orange
array1[: ,100: ] = [0,0,255]    #blue
img = Image.fromarray(array1)
img.save('AREA_img2.png')


# Databricks notebook source
# MAGIC %md
# MAGIC ##### Welcome  to Azurelib Academy By Deepak Goyal
# MAGIC ##### You can master the Databricks here: www.adeus.azurelib.com
# MAGIC ##### Author of this blog: Arud Seka Berne S in

# COMMAND ----------

# MAGIC %md
# MAGIC #### Pyspark Concat_Ws() Function in Azure Databricks

# COMMAND ----------

# MAGIC %md
# MAGIC ###### Gentle reminder:
# MAGIC In Databricks,
# MAGIC   - sparkSession made available as spark
# MAGIC   - sparkContext made available as sc
# MAGIC
# MAGIC In case, you want to create it manually, use the below code.

# COMMAND ----------

from pyspark.sql.session import SparkSession

spark = SparkSession.builder \
    .master("local[*]") \
    .appName("azurelib.com") \
    .getOrCreate()

sc = spark.sparkContext

# COMMAND ----------

# MAGIC %md
# MAGIC ##### a) Create manual PySpark DataFrame

# COMMAND ----------

data = [
    (1, "Andie", "Ebbutt", ['Andie', 'Ebbutt']),
    (2, "Hobie", "Deegan", ['Hobie', 'Deegan']),
    (3, "Denys", "Belverstone", ['Denys', 'Belverstone']),
    (4, "Delphine", "Pietersma", ['Delphine', 'Pietersma']),
    (5, "Putnem", "Chasson", ['Putnem', 'Chasson'])
]

df = spark.createDataFrame(data, schema=["id", "f_name", "l_name", "name_list"])
df.printSchema()
df.show(truncate=False)

# COMMAND ----------

# MAGIC %md
# MAGIC ##### b) Create PySpark DataFrame by reading files

# COMMAND ----------

file_path = "/mnt/practice/name_list.json"
# replace the file_path with the source file location which you have downloaded.

df_2 = spark.read.format("json").load(file_path)
df_2.printSchema()

# COMMAND ----------

# MAGIC %md
# MAGIC ##### Note: Here, I will be using the manually created dataframe

# COMMAND ----------

# MAGIC %md
# MAGIC ##### 1. Concat ArrayType column into StringType column with separator

# COMMAND ----------

from pyspark.sql.functions import concat_ws

# 1. using select
df.select(concat_ws(",", "name_list").alias("concat_1")).show()

# 2. using withColumn
df.withColumn(
    "concat_2",
    concat_ws("-", "name_list")
).select("concat_2").show()

# 3. using SQL Expression
df.createOrReplaceTempView("name_list")
spark.sql("SELECT CONCAT_WS('||', name_list) AS concat_3 FROM name_list").show()

# COMMAND ----------

# MAGIC %md
# MAGIC ##### 2. Concate multiple columns into single StringType column

# COMMAND ----------

from pyspark.sql.functions import concat_ws

# 1. using select
df.select(concat_ws(",", "id", "f_name").alias("concat_1")).show()

# 2. using withColumn
df.withColumn(
    "concat_2",
    concat_ws("-", "id", "f_name")
).select("concat_2").show()

# 3. using SQL Expression
df.createOrReplaceTempView("name_list")
spark.sql("""SELECT CONCAT_WS('||', id, f_name) AS concat_3 FROM name_list""").show()

34. Pyspark Concat_Ws() Function/Pyspark Concat_Ws() Function - Notebook.py