import os
import discord
import asyncio
from discord.ext import commands
from discord.utils import get
from discord import Game

TOKEN = os.environ['ENV_TOKEN']

bot = commands.Bot(command_prefix='?') #COMMANDS START WITH THIS PREFIX

@bot.command()
async def test(context):
    embed=discord.Embed(title="Hello!", url="https://google.com", type="rich", description="Bot testing")
    await context.send(embed=embed)

@bot.command(name="I wonder",
               description="Provides the wonder emoji",
               brief="Wonder?",
               aliases=["Wonder", "shadowwolf", "wonder?", "Wonder?"],
               pass_context=True)
async def wonder(context):
    msg = "<:emoji_12:660581303367761920>"
    await context.send(msg)

@bot.command()
async def nerf(context):
    msg = "No u. You no good, scruffy-looking, nerf-herder!"
    await context.send(msg)

# WHEN A NEW MEMBER JOINS THE SERVER
# bot.get_channel('665042600096432139') WELCOME CHANNEL ID
@bot.event
async def on_member_join(member):
    msg = 'Hello There, {0.mention}! Please set your discord name to match your SWGOH name. '.format(member)
    await bot.commands.send_message(bot.get_channel('665042600096432139'), msg)

  #These trigger on any message. Not just commands.
# @bot.event
# async def on_message(message):
    # we do not want the bot to reply to itself
    # We also want to make sure it checks for commands first
    # await bot.process_commands(message)
    # if message.author == bot.user:
    # 	return
    # mcont = message.content.lower()
    # if 'hello there' in mcont:
    #     msg = "General Kenobi!"
    #     message.channel.send(msg)
    # if message.author.name == 'shadowwolf':
    #     message.channel.send(message.content)

# When bot loads, do this stuff.
@bot.event
async def on_ready():
    game = Game("Galaxy of Heroes")
    await bot.change_presence(status=discord.Status.idle, activity=game)
    print('Logged in as')
    print(bot.user.name)
    print(bot.user.id)
    print('------')

bot.run(TOKEN)


#!/usr/bin/env python
# coding: utf-8

from kafka import KafkaProducer
from kafka import KafkaConsumer
import requests
from cassandra.cluster import Cluster

producer = KafkaProducer(bootstrap_servers='localhost:9092')
url = 'https://raw.githubusercontent.com/degharbi/Housing-prices-prediction/master/data/kc_house_data.csv'
data_csv = requests.get(url).content
messages = [line.replace('\n','') for line in data_csv.split('\n')[1:]]

# Send each line from the csv into a message with a topic data_raw
for message in messages:
    producer.send('data_raw', message)

# Initiqte a cluster and a cassandra connection
cluster = Cluster()
session = cluster.connect()

# Create keyspace in cassandra
session.execute(
    """
    CREATE KEYSPACE IF NOT EXISTS
    housing_prices
    WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1}
    """
)

# Create a table inside the keyspace
session.execute(
    """
    CREATE TABLE IF NOT EXISTS housing_prices.properties(
     id TEXT,
     date TEXT,
     price FLOAT,
     bedrooms INT,
     bathrooms FLOAT,
     sqft_living INT,
     sqft_lot INT,
     floors FLOAT,
     waterfront INT,
     vue INT,
     condition INT,
     grade INT,
     sqft_above INT,
     sqft_basement INT,
     yr_built INT,
     yr_renovated INT,
     zipcode INT,
     lat FLOAT,
     long FLOAT,
     sqft_living15 INT,
     sqft_lot15 INT,
    PRIMARY KEY (id))
    """
)

# Consume the messages prodeces in the topic data_raw
consumer = KafkaConsumer('data_raw', bootstrap_servers='localhost:9092', auto_offset_reset='earliest')

# Save these messages into our cassandra table
for msg in consumer :
    msg = msg.value.replace("'","").split(',')
    print(msg)
    session.execute(
        """
        INSERT INTO housing_prices.properties (
             id,
             date,
             price,
             bedrooms,
             bathrooms,
             sqft_living,
             sqft_lot,
             floors,
             waterfront,
             vue,
             condition,
             grade,
             sqft_above,
             sqft_basement,
             yr_built,
             yr_renovated,
             zipcode,
             lat,
             long,
             sqft_living15,
             sqft_lot15
         )
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,%s, %s, %s, %s, %s, %s,%s, %s, %s)
        """,
        (
            msg[0],
            msg[1],
            float(msg[2]),
            int(msg[3]),
            float(msg[4]),
            int(msg[5]),
            int(msg[6]),
            float(msg[7]),
            int(msg[8]),
            int(msg[9]),
            int(msg[10]),
            int(msg[11]),
            int(msg[12]),
            int(msg[13]),
            int(msg[14]),
            int(msg[15]),
            int(msg[16]),
            float(msg[17]),
            float(msg[18]),
            int(msg[19]),
            int(msg[20]),
        )
    )


picture = [
    [0, 0, 0, 1, 0, 0, 0],
    [0, 0, 1, 1, 1, 0, 0],
    [0, 1, 1, 1, 1, 1, 0],
    [1, 1, 1, 1, 1, 1, 1],
    [0, 0, 0, 1, 0, 0, 0],
    [0, 0, 0, 1, 0, 0, 0]
]

# # 1
# for row in picture:
#     line = ''
#     for pixel in row:
#         if pixel == 0:
#             line += ' '
#         elif pixel == 1:
#             line += '*'
#     print(line)

# 2
for row in picture:
    for pixel in row:
        if pixel == 0:
            print(' ', end='')
        else:
            # to append any string at the end of the output of the print statement. By default, the print method ends with a newline.
            print('*', end='')
    print(' ')  # to add new line after every row


from queue import Queue
dx = [-1,1,0,0]
dy = [0,0,-1,1]
sx = -1
sy = -1
ex = -1
ey = -1

def check(m, n, matrix, value):
    cnt = 0
    for i in range(m):
        for j in range(n):
            if (i == 0 or i == m-1 or j == 0 or j == n-1) and matrix[i][j]=='.':
                cnt+=1
                if cnt == 1:
                    value.update({'sx': i, 'sy': j})
                if cnt == 2:
	                value.update({'ex': i, 'ey': j})
                if cnt > 2:
                    return False
    if cnt == 2:
        return True
    return False

def BFS(m, n, sx, sy, ex, ey, matrix, visited):
    q = Queue()
    q.put(sx)
    q.put(sy)
    visited[sx][sy] = True

    while not q.empty():
        x = q.get()
        y = q.get()
        if x == ex and y == ey:
            return True
        for i in range(len(dx)):
                u = x + dx[i]
                v = y + dy[i]
                if 0 <= u < m and 0 <= v < n and matrix[u][v] == '.' and not visited[u][v]:
                    visited[u][v] = True
                    q.put(u)
                    q.put(v)
    return False

def main():
    testcase = int(input())
    ans = []
    for _ in range(testcase):
        m, n = list(map(int, input().split()))
        matrix = [[0 for _ in range(n)] for _ in range(m)]
        visited = [[False for _ in range(n)] for _ in range(m)]
        for i in range(m):
            matrix[i] = [e for e in input()]

        value = dict({'sx': - 1, 'sy': -1, 'ex': -1, 'ey': -1})
        if not check(m,n,matrix, value):
            ans.append("invalid")
            continue

        res = BFS(m, n, value['sx'], value['sy'], value['ex'], value['ey'], matrix, visited)
        if res:
            ans.append("valid")
        else:
            ans.append("invalid")

    for e in ans:
        print(e)

if __name__== "__main__":
    main()


#This code works!

from email.mime import base
import requests
import pandas as pd
import json
import pathlib
import csv
import calendar
import datetime
import time as t
from datetime import date, datetime, timedelta
from datetime import datetime, time, timezone
from collections import defaultdict
import urllib
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)

#pd.set_option('max_columns', None)
# Function to get all comments for a specific submission and find the keyword "removed" in the comment body.
# If one comment is found with the keyword, then return the comment.
def mySubmissionHasExplanation(submission_id):
    #Convert submision id from base 36 to base 10 and build the url.
    submission_id_converted = int(submission_id,36)
    # First collect all root comments for the submission - endpoint not working
    url= "https://api.pushshift.io/reddit/comment/search/?q='was removed'|'has been removed'&link_id="+str(submission_id_converted)
    print(f"Url for the comments for each submission: {url}")
    try:
        print("In try")
        comments = requests.get(url)
        print("after requests.get")
        print(f"comments: {comments}")
        # dataframe of all comment_ids
        comments_df = pd.json_normalize(comments.json()['data'])
        length_comments_df = len(comments_df)
        print(f"The lenght of the comment_df: {length_comments_df}")

        for i in range (length_comments_df):
            comment_body = comments_df.loc[i, "body"]
            print(f"Comment body: {comment_body}")
            comment_author = comments_df.loc[i, "author"]
            comment_created_utc = comments_df.loc[i, "created_utc"]
            if ("removed" in comment_body): #or ("was removed" in body) or ("has been removed" in body):
                return comment_body, comment_author, comment_created_utc

    except:
        print("The endpoint could not be reached.")
    return "None", "None", "None"

# Get current working directory
cwd_path = pathlib.Path.cwd()

# Create a new folder to write any files related to reddit_explanations_covid_pushshift
reddit_explanations_pushshift = cwd_path/"reddit_explanations_covid_pushshift"
reddit_explanations_pushshift.mkdir(exist_ok=True)

submissions_file = reddit_explanations_pushshift/"submissions_file.csv"
# Create a file called removed_submissions.csv to write all removed submissions from July 1st to August 31st.
removed_submissions_file = reddit_explanations_pushshift/"removed_submissions.csv"
# removed_submissions_comments_file = reddit_explanations_pushshift/"removed_submissions_comments.csv"

submissions_file.touch()
removed_submissions_file.touch()
# removed_submissions_comments_file.touch()

# List for all submissions id
submissions_id_list = []
comments_list = []
#keys_for_comments_dict = ["submission_id", "comment_body", "comment_author", "comment_created_utc"]
comments_dict = defaultdict(list)
# Get 500 submissions per day with the keywords covid or vaccine between the dates July 1st and August 31st
# Get a list of all the dates between July 1st and August 31st
num_days = 1
# Create base date
base = datetime(2022, 12, 29)
date_list = []
submissions_df = pd.DataFrame()
# Create a list of dates starting on July 1st
for x in range(num_days):
    date_list.append(base + timedelta(days=x))

# Loop through date_list and get begin and end datetimes for each day in utc. Create url to call pushshift api and
# get 500 removed submissions by moderator for each day and add to submissions dataframe.
for dt in date_list:
    begintime_date = datetime.combine(dt, time.min)
    begintime_date = datetime.combine(dt, time.min)# time.min will give me 12:00 am
    print("begintime_date",begintime_date)
    endtime_date = datetime.combine(dt, time.max) # time.max will give me 11:59 pm
    begintime_date_utc = begintime_date.timestamp()
    print("begintime_date_utc",begintime_date_utc)
    endtime_date_utc = endtime_date.timestamp()
    url = "https://api.pushshift.io/reddit/search/submission/?" #This is the pushshift endpoint for getting the submissions.
    params = {"since": int(begintime_date_utc), "until": int(endtime_date_utc), "size": "200", "removed_by_category": "moderator"}
    url = url + urllib.parse.urlencode(params) # Forming the url
    print(url)
    try:
        data= requests.get(url)
        # Add the submissions received from Reddit to a temporary dataframe and add to submissions dataframe.
        # Keep adding to submissions_df each time you loop.
        temp_submissions_df = pd.json_normalize(data.json()['data'])
        #submissions_df = submissions_df.append(temp_submissions_df, ignore_index=True)
        submissions_df = pd.concat([submissions_df,temp_submissions_df])
    except:
        print("The endpoint could not be reached.")

    t.sleep(10)
# Write all the submissions with at least 1 comment containing the keyword "removed" to a file
if not submissions_df.empty:
    submissions_df_with_comments = submissions_df[(submissions_df["num_comments"] > 0)]
    data_top = submissions_df_with_comments.head()
    #print("data_top",data_top)
    list(submissions_df_with_comments.columns)
    #for col_name in submissions_df_with_comments.columns:
        #print(f"Column name: {col_name}")
    submissions_df_with_comments.to_csv(submissions_file)
    for i in range(len(submissions_df_with_comments)):
        try:
            submission_id = submissions_df_with_comments.iloc[i, 28]
            print(f"The submission_id is: {submission_id}")
            # For each submission, check if at least 1 comment contains the word "removed". If True, then add the
            # submission_id to the submissions_id_list.
            comment_body, comment_author, comment_created_utc = mySubmissionHasExplanation(submission_id)
            print(f"Comment author: {comment_author}")
            print(f"Comment body: {comment_body}")
            if comment_body == "None":
                print("This submission has no comments with the word 'removed'.")
            else:
                # Add submission with comment with the word "removed" to the submissions_id_list
                submissions_id_list.append(submission_id)
                #comments_list.extend([submission_id, comment_body, comment_author, comment_created_utc])

                comments_dict["submission_id"].append(submission_id)
                comments_dict["comment_body"].append(comment_body)
                comments_dict["comment_author"].append(comment_author)
                comments_dict["comment_created_utc"].append(comment_created_utc)
        except:
            print("Could not get submission_id.")
        t.sleep(7)
    if comments_dict:
        comments_dict_df = pd.DataFrame(comments_dict)
        print(comments_dict_df.shape)
        # Merge submissions_df_with_comments and comments_list_df with id as left key and submission_id as the right key

        submissions_df_to_write = submissions_df_with_comments[submissions_df_with_comments["id"].isin(submissions_id_list)]
        print(submissions_df_to_write.shape)

        submissions_df_to_write_merged = pd.merge(submissions_df_to_write, comments_dict_df, left_on='id', right_on='submission_id')

        header = ["id", "url", "selftext", "author_fullname", "created_utc", "score", "subreddit", "permalink", 'comment_body', 'comment_author', 'comment_created_utc']
        submissions_df_to_write_merged.to_csv(removed_submissions_file, index=False, columns=header)

    # Sources:

    # https://levelup.gitconnected.com/easily-obtain-reddit-data-with-python-8ce0c576540f

    # https://reddit-api.readthedocs.io/en/latest/#searching-submissions

    # https://github.com/pushshift/api


import numpy as np

def do_nms(dets_all, n_class, th_nms):
    '''
    dets: detection results, (n_dets, 6)
    each row of dets: (class_id, class_prob, xmin, ymin, xmax, ymax)
    '''
    cidx_all = []
    for c in range(n_class):
        cidx = np.where(dets_all[:, 0] == c)[0]
        if cidx.size == 0:
            continue
        dets = dets_all[cidx, :]
        sidx = np.argsort(dets[:, 1])[::-1]
        cidx = cidx[sidx]
        dets = dets[sidx, :]
        vidx = _nms(dets, th_nms)
        cidx = cidx[vidx]
        cidx_all.append(cidx)
    try:
        if cidx_all:
            cidx_all = np.hstack((cidx_all))
        nidx = np.setdiff1d(np.arange(dets_all.shape[0]), cidx_all)
    except:
        import ipdb
        ipdb.set_trace()
    dets_all[nidx, 0] = -1
    return dets_all

def _nms(dets, th_nms):
    '''
    '''
    areas = (dets[:, 4] - dets[:, 2]) * (dets[:, 5] - dets[:, 3])
    vmask = np.ones((dets.shape[0],), dtype=int)
    vidx = []
    for i, d in enumerate(dets):
        if vmask[i] == 0:
            continue
        iw = np.minimum(d[4], dets[i:, 4]) - np.maximum(d[2], dets[i:, 2])
        ih = np.minimum(d[5], dets[i:, 5]) - np.maximum(d[3], dets[i:, 3])
        I = np.maximum(iw, 0) * np.maximum(ih, 0)
        iou = I / np.maximum(areas[i:] + areas[i] - I, 1e-08)
        nidx = np.where(iou > th_nms)[0] + i
        vmask[nidx] = 0
        vidx.append(i)
    return vidx


from flask import current_app as app
from socketio import Namespace
from urllib.parse import urlsplit, parse_qsl

import datetime
import pprint

class ChatUtils(object):
  def __init__(self, sio, *args, **kwargs):
    self.sio = sio
    self.args = args
    self.kwargs = kwargs

  def get_session_user(self, _sid, attr=None, attrs=None):
    session = self.sio.get_session(_sid)

    user = session.get("user", self.dummy_user.copy())

    if isinstance( attr, str ):
      return user[attr]

    elif isinstance( attrs, list ):
      temp = dict()
      for key in attrs:
        temp[key] = user[key]
      return temp

    return user.copy()

  def set_session_user(self, _sid, **kwargs):
    session = self.sio.get_session(_sid)

    user = session.get("user", None)
    if user is None:
      user = self.dummy_user.copy()
    user.update( kwargs )

    session.update({ "user": user })

  def parse_query_string_to_dict(self, query_string):
    return dict(parse_qsl(urlsplit(query_string).path))

class ChatNamespace(Namespace, ChatUtils):
  def __init__(self, sio, namespace, *args, **kwargs):
    super(Namespace, self).__init__(namespace)

    self.sio = sio
    self.args = args
    self.kwargs = kwargs

    self.logger = app.logger

    self.default_room = "lobby"
    self.dummy_user = {
      "sid": None,
      "name": "Unknown",
      "room": "lobby",
      "auth": "normal",
      "loggedIn": None
    }

  def on_connect(self, sid, env):
    remote_addr = env["REMOTE_ADDR"]
    query_string = self.parse_query_string_to_dict(env["QUERY_STRING"])

    self.logger.info(f'[CONNECT] { remote_addr } { sid }')
    self.logger.info(f'[CONNECT][QUERY_STRING] { query_string }')

    self.set_session_user(sid, sid=sid, name=query_string.get("username", "Unknown"))
    self.enter_room(sid, self.default_room)

    emit_data = {
      "user": self.get_session_user(sid),
      "room": self.default_room
    }

    self.emit("room_hello", emit_data, room=self.default_room)
    self.emit("connected", emit_data, room=self.default_room)

  def on_disconnect(self, sid):
    self.logger.info(f"[DISCONNECT] { sid }")

  def on_set_username(self, sid, username):
    user = self.get_session_user(sid)

    self.set_session_user(sid, name=username)

    self.logger.info( f'[SET_USERNAME] { user["name"] } -> { username }')

    return (True, )

  def on_send_message(self, sid, send_data):
    user = self.get_session_user(sid)

    self.logger.info(f'[SEND_MESSAGE][room={ user["room"] }] { user["name"] }: { send_data["message"] }')

    emit_data = send_data.copy()
    emit_data.update({
      "user": user,
    })

    self.emit("receive_message", emit_data, room=send_data["room"])

  def on_enter_room(self, sid, enter_room):
    prev_room = self.get_session_user(sid, attr="room")

    if prev_room != enter_room:
      leave_emit_data = {
        "user": self.get_session_user(sid),
        "room": prev_room
      }
      self.emit("room_bye", leave_emit_data, room=prev_room)
      self.leave_room(sid, prev_room)

      self.logger.info(f'[LEAVE_ROOM][room={ prev_room }]')

    self.enter_room(sid, enter_room)
    self.set_session_user(sid, room=enter_room)

    enter_emit_data = {
      "user": self.get_session_user(sid),
      "room": enter_room
    }

    self.logger.info(f'[ENTER_ROOM][room={ enter_room }]')
    self.logger.info(f'[ENTER_ROOM][ROOMS] { self.rooms(sid) }')

    self.emit("room_hello", enter_emit_data, room=enter_room)

    return (True, )

  def on_leave_room(self, sid, leave_room):
    self.leave_room(sid, leave_room)
    self.set_session_user(sid, room=self.default_room)

    emit_data = {
      "user": self.get_session_user(sid),
      "room": leave_room
    }

    self.emit("room_bye", emit_data, room=leave_room)

    return (True, )


# Python program to count number of vowels using sets in given string

str = "Welcome to the World of Programming"
count = 0

vowel = set("aeiouAEIOU")

for alphabet in str:

    if alphabet in vowel:
        count = count + 1

print("No. of vowels :", count)


from flask import Flask, render_template, redirect, url_for
import datetime
import matplotlib.pyplot as plt
import os

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def home():

    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")

    left = [1, 2, 3, 4, 5]
    # heights of bars
    height = [10, 24, 36, 40, 5]
    # labels for bars
    tick_label = ['one', 'two', 'three', 'four', 'five']
    # plotting a bar chart
    plt.bar(left,
            height,
            tick_label=tick_label,
            width=0.8,
            color=['red', 'green'])

    # naming the y-axis
    plt.ylabel('y - axis')
    # naming the x-axis
    plt.xlabel('x - axis')
    # plot title
    plt.title('My bar chart!')

    plt.savefig(os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             'static/images/plot.png'))

    return render_template('dashboard.html',
                           current_time=current_time,
                           plot='/static/images/plot.png')

if __name__ == '__main__':
    app.run()


import pandas as pd
from sklearn.svm import OneClassSVM
from sklearn import preprocessing
import matplotlib.pyplot as plt
from numpy import where

def get_normalized_dataframe(df: pd.DataFrame) -> pd.DataFrame:
    df_values = df.values
    standard_scaler = preprocessing.StandardScaler()
    df_values_scaled = standard_scaler.fit_transform(df_values)
    return pd.DataFrame(df_values_scaled)

def detect_anomalies_and_save_to_csv(computing_type: str, check: bool = False, normalization: bool = False) -> None:
  data = pd.read_csv('xd.csv')

  df = data.loc[data['type'] == computing_type]
  df = df.drop('type', axis='columns')

  if normalization:
    df_normalized = get_normalized_dataframe(df)

    model = OneClassSVM(kernel = 'rbf', gamma = 5e-2, nu = 0.05).fit(df_normalized)
    y_pred = model.predict(df_normalized)

  else:
    model = OneClassSVM(kernel = 'rbf', gamma = 1e-9, nu = 0.05).fit(df)
    y_pred = model.predict(df)

  outlier_index_list = where(y_pred == -1)
  outlier_df = df.iloc[outlier_index_list]

  normal_guys_index_list = where(y_pred == 1)
  normal_guys_df = df.iloc[normal_guys_index_list]

  if check:
    df_battery_converted = df[' battery'] * -1
    df_battery_converted_outlier = outlier_df[' battery'] * -1

    plt.scatter(df[' time'], df_battery_converted)
    plt.scatter(outlier_df[' time'], df_battery_converted_outlier, c = 'r')
    plt.xlabel('time [ms]', fontsize=12)
    plt.ylabel('battery usage [mAh]', fontsize=12)
    plt.show()

  normal_guys_df.to_csv(f'SVM_{computing_type}_no_anomalies.csv', index=False)

if __name__ == '__main__':
  detect_anomalies_and_save_to_csv('cloud', check=True, normalization=True)
  detect_anomalies_and_save_to_csv('local', check=True, normalization=True)


import sys
import hashlib
import libnum
import base64

e = 65537
p = 3
q = 5
n = p * q
phi = (p-1) * (q-1)
d = libnum.invmod(e, phi)

file_obj = open(r"input.txt", "r")
message = file_obj.readlines()
file_obj.close()

message = ''.join(message)

encoded_bytes = base64.b64encode(message.encode("utf-8"))
# encoded_str = str(encoded_bytes, 'utf-8')
int_b = int.from_bytes(encoded_bytes, 'big')
print()
print(encoded_bytes)
print()
print(int_b)
c = pow(int_b, e, n)

print()
print(encoded_bytes)
print()
print(c)
print()

dc = pow(c, d, n)

dc = (dc).to_bytes((dc.bit_length() + 7) // 8, byteorder='big')

encoded_str = base64.b64decode(dc)
res = str(encoded_str, 'utf-8')
print(res)


# -*- coding: utf-8 -*-
"""
ofood商户排行数据
"""
import airflow
from airflow.operators.python_operator import PythonOperator
from airflow.operators.impala_plugin import ImpalaOperator
from datetime import datetime, timedelta
from utils.connection_helper import get_hive_cursor, get_db_conn, get_db_conf
from utils.validate_metrics_utils import *
from airflow.sensors.s3_prefix_sensor import S3PrefixSensor
from airflow.operators.bash_operator import BashOperator
from airflow.sensors import UFileSensor
from plugins.comwx import ComwxApi
from airflow.sensors import OssSensor
import time
import logging

args = {
    'owner': 'wuduo',
    'start_date': datetime(2019, 8, 18),
    'depends_on_past': False,
    'retries': 3,
    'retry_delay': timedelta(minutes=5),
    'email': ['bigdata_dw@opay-inc.com'],
    'email_on_failure': True,
    'email_on_retry': False,
}

dag = airflow.DAG(
    'app_ofood_merchant_offline_tag_d',
    schedule_interval="00 04 * * *",
    concurrency=5,
    max_active_runs=1,
    default_args=args
)

"""
依赖采集完成
"""
dependence_ods_sqoop_base_jh_order_df = OssSensor(
    task_id='dependence_ods_sqoop_base_jh_order_df',
    bucket_key='{hdfs_path_str}/dt={pt}'.format(
        hdfs_path_str="ofood_dw_sqoop/food_operapay_co/jh_order",
        pt='{{ ds }}'
    ),
    bucket_name='opay-datalake',
    poke_interval=60,
    dag=dag
)

dependence_ods_sqoop_base_jh_order_log_df = OssSensor(
    task_id='dependence_ods_sqoop_base_jh_order_log_df',
    bucket_key='{hdfs_path_str}/dt={pt}'.format(
        hdfs_path_str="ofood_dw_sqoop/food_operapay_co/jh_order_log",
        pt='{{ ds }}'
    ),
    bucket_name='opay-datalake',
    poke_interval=60,
    dag=dag
)

dependence_ods_sqoop_base_jh_waimai_comment_df = OssSensor(
    task_id='dependence_ods_sqoop_base_jh_waimai_comment_df',
    bucket_key='{hdfs_path_str}/dt={pt}'.format(
        hdfs_path_str="ofood_dw_sqoop/food_operapay_co/jh_waimai_comment",
        pt='{{ ds }}'
    ),
    bucket_name='opay-datalake',
    poke_interval=60,
    dag=dag
)

dependence_ods_sqoop_base_jh_order_time_df = OssSensor(
    task_id='dependence_ods_sqoop_base_jh_order_time_df',
    bucket_key='{hdfs_path_str}/dt={pt}'.format(
        hdfs_path_str="ofood_dw_sqoop/food_operapay_co/jh_order_time",
        pt='{{ ds }}'
    ),
    bucket_name='opay-datalake',
    poke_interval=60,
    dag=dag
)

"""
end
"""

sleep_time = BashOperator(
    task_id='sleep_id',
    depends_on_past=False,
    bash_command='sleep 120',
    dag=dag
)

def get_data_from_impala(**op_kwargs):
    ds = op_kwargs.get('ds', time.strftime('%Y-%m-%d', time.localtime(time.time() - 86400)))
    sql = '''
        WITH
        --商家取消单
        merchant_data as
        (
            select
                a1.shop_id,
                count(distinct a1.order_id) cancel_order
            from (select
                    shop_id,
                    order_id
                from ofood_dw_ods.ods_sqoop_base_jh_order_df
                where dt='{pt}' and
                    order_status='-2' and
                    from_unixtime(dateline,'yyyy-MM-dd') between date_sub('{pt}', 6) and '{pt}'
                ) as a1
            join (select
                    order_id
                from ofood_dw_ods.ods_sqoop_base_jh_order_log_df
                where dt='{pt}' and
                    log like '%Merchant cancelling order%'
                ) as a2
            on a1.order_id=a2.order_id
            group by a1.shop_id
        ),
        --评价单小于等于2
        score_data as (
            select
                a1.shop_id,
                count(distinct a1.order_id) as scorelttwo
            from (select
                    shop_id,
                    order_id
                from ofood_dw_ods.ods_sqoop_base_jh_order_df
                where dt='{pt}' and
                    order_status='8' and
                    from_unixtime(dateline,'yyyy-MM-dd') between date_sub('{pt}', 6) and '{pt}'
                ) as a1
            join (select
                    order_id
                from ofood_dw_ods.ods_sqoop_base_jh_waimai_comment_df
                where dt='{pt}' and
                    score_peisong<=2
                ) as a2
            on a1.order_id = a2.order_id
            group by a1.shop_id
        ),
        --大于90分的单子
        order_data as (
            select
                s.shop_id,
                count(distinct s.order_id) as ordersgt90
            from (select
                    a.shop_id,
                    a.order_id,
                    datediff(from_unixtime(b.order_compltet_time,'yyyy-MM-dd HH:mm:ss'),from_unixtime(a.pay_time,'yyyy-MM-dd HH:mm:ss'))*24*60+
                    (hour(from_unixtime(b.order_compltet_time,'yyyy-MM-dd HH:mm:ss'))-hour(from_unixtime(a.pay_time,'yyyy-MM-dd HH:mm:ss')))*60+(minute(from_unixtime(b.order_compltet_time,'yyyy-MM-dd HH:mm:ss'))-minute(from_unixtime(a.pay_time,'yyyy-MM-dd HH:mm:ss'))) as tm
                from (select
                        shop_id,
                        order_id,
                        pay_time
                    from ofood_dw_ods.ods_sqoop_base_jh_order_df
                    where dt='{pt}' and
                        order_status = '8' and
                        from_unixtime(dateline,'yyyy-MM-dd')  between date_sub('{pt}', 6) and '{pt}'
                    ) as a
                join (select
                        order_id,
                        order_compltet_time
                    from ofood_dw_ods.ods_sqoop_base_jh_order_time_df
                    where dt='{pt}'
                    ) as b
                on a.order_id=b.order_id
                group by a.shop_id, a.order_id, datediff(from_unixtime(b.order_compltet_time,'yyyy-MM-dd HH:mm:ss'),from_unixtime(a.pay_time,'yyyy-MM-dd HH:mm:ss'))*24*60+
                    (hour(from_unixtime(b.order_compltet_time,'yyyy-MM-dd HH:mm:ss'))-hour(from_unixtime(a.pay_time,'yyyy-MM-dd HH:mm:ss')))*60+(minute(from_unixtime(b.order_compltet_time,'yyyy-MM-dd HH:mm:ss'))-minute(from_unixtime(a.pay_time,'yyyy-MM-dd HH:mm:ss')))
                ) s
            where s.tm>90
            group by s.shop_id
        ),
        --近7天下单量
        order_7day as (
            select
                shop_id,
                count(distinct order_id) as orders
            from ofood_dw_ods.ods_sqoop_base_jh_order_df
            where dt='{pt}' and
                from_unixtime(dateline,'yyyy-MM-dd')  between date_sub('{pt}', 6) and '{pt}'
            group by shop_id
        ),
        --近30天完单量
        order_30day as (
            select
                shop_id,
                count(distinct order_id) as orderfinish
            from ofood_dw_ods.ods_sqoop_base_jh_order_df
            where dt='{pt}' and
                from_unixtime(dateline,'yyyy-MM-dd')  between date_sub('{pt}', 29) and '{pt}' and
                order_status = '8'
            group by shop_id
        )

        --结果集
        select
            order_7day.shop_id,
            nvl(merchant_data.cancel_order, 0),
            nvl(score_data.scorelttwo, 0),
            nvl(order_data.ordersgt90, 0),
            order_7day.orders,
            nvl(order_30day.orderfinish, 0),
            unix_timestamp('{pt}', 'yyyy-MM-dd')
        from order_7day
        left join merchant_data on order_7day.shop_id = merchant_data.shop_id
        left join score_data on order_7day.shop_id = score_data.shop_id
        left join order_data on order_7day.shop_id = order_data.shop_id
        left join order_30day on order_7day.shop_id = order_30day.shop_id
    '''.format(
        pt=ds
    )
    logging.info(sql)
    hive_cursor = get_hive_cursor()
    hive_cursor.execute(sql)
    result = hive_cursor.fetchall()

    mysql_conn = get_db_conn('mysql_bi')
    mcursor = mysql_conn.cursor()
    __data_to_mysql(mcursor, result,
                    ['shop_id', 'last7_cancel_order', 'last7_low_scores_2_order', 'last7_forward_time_90_order',
                     'last7_request_order', 'last30_finish_order', 'update_time'],
                    '''
                        last7_cancel_order=values(last7_cancel_order),
                        last7_low_scores_2_order=values(last7_low_scores_2_order),
                        last7_forward_time_90_order=values(last7_forward_time_90_order),
                        last7_request_order=values(last7_request_order),
                        last30_finish_order=values(last30_finish_order),
                        update_time=values(update_time)
                    '''
                    )

def __data_to_mysql(conn, data, column, update=''):
    isql = 'insert into bi.ofood_merchant_offline_tag ({})'.format(','.join(column))
    esql = '{0} values {1} on duplicate key update {2}'
    sval = ''
    cnt = 0
    try:
        for (shop_id, cancel_order, scorelttwo, ordersgt90, orders, orderfinish, upt) in data:

            row = [shop_id, cancel_order, scorelttwo, ordersgt90, orders, orderfinish, upt]
            if sval == '':
                sval = '(\'{}\')'.format('\',\''.join([str(x) for x in row]))
            else:
                sval += ',(\'{}\')'.format('\',\''.join([str(x) for x in row]))
            cnt += 1
            if cnt >= 1000:
                logging.info(esql.format(isql, sval, update))
                conn.execute(esql.format(isql, sval, update))
                cnt = 0
                sval = ''

        if cnt > 0 and sval != '':
            logging.info(esql.format(isql, sval, update))
            conn.execute(esql.format(isql, sval, update))
    except BaseException as e:
        logging.info(e)
        return

get_data_from_impala_task = PythonOperator(
    task_id='get_data_from_impala_task',
    python_callable=get_data_from_impala,
    provide_context=True,
    dag=dag
)

comwx = ComwxApi('wwd26d45f97ea74ad2', 'BLE_v25zCmnZaFUgum93j3zVBDK-DjtRkLisI_Wns4g', '1000011')

def check_ds_data(**op_kwargs):
    ds = op_kwargs.get('ds', time.strftime('%Y-%m-%d', time.localtime(time.time() - 86400)))
    sql = '''
        select count(1) as cnt from bi.ofood_merchant_offline_tag where from_unixtime(update_time,'%Y-%m-%d')='{pt}'
    '''.format(pt=ds)
    mysql_conn = get_db_conn('mysql_bi')
    mcursor = mysql_conn.cursor()
    mcursor.execute(sql)
    res = mcursor.fetchall()
    logging.info(sql)
    logging.info(res)
    logging.info(isinstance(res, tuple))
    logging.info(len(res))
    logging.info(res[0])
    if res is None or not isinstance(res, tuple) or len(res) <= 0:
        comwx.postAppMessage('ofood商家订单指标缺少{}数据, 请及时排查'.format(ds), '271')
    else:
        (cnt,) = res[0]
        logging.info(cnt)
        if cnt <= 0:
            comwx.postAppMessage('ofood商家订单指标缺少{}数据, 请及时排查'.format(ds), '271')

check_data = PythonOperator(
    task_id='check_data',
    python_callable=check_ds_data,
    provide_context=True,
    dag=dag
)

dependence_ods_sqoop_base_jh_order_df >> sleep_time
dependence_ods_sqoop_base_jh_order_log_df >> sleep_time
dependence_ods_sqoop_base_jh_waimai_comment_df >> sleep_time
dependence_ods_sqoop_base_jh_order_time_df >> sleep_time

sleep_time >> get_data_from_impala_task >> check_data


import boto3, json

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('cmup_users')

def lambda_handler(event, context):

    response = table.get_item(
        Key={
            'id': event['pathParameters']['user']
        }
    )

    user = response['Item']

    return {
        'statusCode': 200,
        'body': json.dumps(user)
    }


# -*- encoding: utf-8 -*-

from datetime import date, datetime, timedelta
from datetime import time as ttime
import time
import json
from itertools import chain
from decimal import Decimal

from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _
from django.utils import simplejson
from django.db.models import Q
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, redirect, get_object_or_404
from django.forms.util import ErrorList
from django.db.models.query import QuerySet

from django.contrib.auth.models import User
from django.template import RequestContext

from django.conf import settings
from django.http import Http404
from django.http import HttpResponse
from django.http import HttpResponseRedirect

from decorators import paginate
from decorators import only_doctor
from decorators import only_doctor_administrative

from userprofile.models import Profile
from cal.models import Slot
from cal.models import SlotType
from cal.models import Appointment
from cal.models import Vacation
from cal.models import Event
from cal.models import Payment

from cal.forms import SlotForm
from cal.forms import SlotTypeForm
from cal.forms import DoctorSelectionForm
from cal.forms import AppointmentForm
from cal.forms import VacationForm
from cal.forms import EventForm
from cal.forms import SchedulerForm
from cal.forms import PaymentForm
from cal.forms import PaymentFiltersForm

from cal.utils import create_calendar
from cal.utils import add_minutes
from cal.utils import get_weekday
from cal.utils import mnames
from cal.utils import get_doctor_preferences
from cal.utils import check_vacations
from cal.utils import check_scheduled_apps

@login_required
@only_doctor_administrative
def index(request):
    if 'appointment' in request.session:
        del request.session['appointment']
    if 'illness' in request.session:
        del request.session['illness']

    return render_to_response("cal/main/index_cal.html", dict(year = time.localtime()[0],month = time.localtime()[1]),
        context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def main(request, year=None):
    if year:
        year = int(year)
    else:
        year = time.localtime()[0]

    nowy, nowm = time.localtime()[:2]
    lst = []

    for y in [year, year + 1, year + 2]:
        mlst = []
        for n, month in enumerate(mnames):
            slot = current = False
            slots = Slot.objects.filter(date__year=y, date__month=n + 1)

            if slots:
                slot = True
            if y == nowy and n + 1 == nowm:
                current = True
            mlst.append(dict(n=n + 1, name=month, slot=slot,
                current=current))
        lst.append((y, mlst))

    today = time.localtime()[2:3][0]

    data = dict(years=lst, user=request.user, year=year, today=today)

    return render_to_response("cal/app/main.html", data,
        context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def select_month_year(request, year=None):
    if year:
        year = int(year)
    else:
        year = time.localtime()[0]

    nowy, nowm = time.localtime()[:2]
    lst = []

    for y in [year, year + 1, year + 2]:
        mlst = []
        for n, month in enumerate(mnames):
            slot = current = False
            slots = Slot.objects.filter(year=y, month=n)

            if slots:
                slot = True
            if y == nowy and n + 1 == nowm:
                current = True
            mlst.append(dict(n=n + 1, name=month, slot=slot,
                current=current))
        lst.append((y, mlst))

    today = time.localtime()[2:3][0]

    data = dict(years=lst, user=request.user, year=year, today=today)

    return render_to_response("cal/app/select_month_year.html",
        data, context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def scheduler(request, id_patient, year=None):
    patient = get_object_or_404(User, pk=int(id_patient))
    if patient.get_profile().is_patient() and patient.get_profile().doctor is None:
        return HttpResponseRedirect(reverse('cal.select_doctor', args=[id_patient]))
    if year:
        year = int(year)
    else:
        year = time.localtime()[0]

    nowy, nowm = time.localtime()[:2]
    lst = []

    for y in [year, year + 1, year + 2]:
        mlst = []
        for n, month in enumerate(mnames):
            slot = current = False
            slots = Slot.objects.filter(year=y, month=n)

            if slots:
                slot = True
            if y == nowy and n + 1== nowm:
                current = True
            mlst.append(dict(n=n + 1, name=month, slot=slot,
                current=current))
        lst.append((y, mlst))

    today = time.localtime()[2:3][0]

    data = dict(years=lst, year=year, month=nowm, today=today,
            patient_user=patient, doctor=patient.get_profile().doctor)

    return render_to_response("cal/app/scheduler.html",
        data, context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def month(request, year, month, change=None):
    year, month = int(year), int(month)

    if change in ("next", "prev"):
        now, mdelta = date(year, month, 15), timedelta(days=31)

        if change == "next":
            mod = mdelta

        elif change == "prev":
            mod = -mdelta

        year, month = (now + mod).timetuple()[:2]

    if request.user.get_profile().is_doctor():
        lst = create_calendar(year, month, doctor=request.user)
        return render_to_response("cal/doctor/month.html",
            dict(year=year, month=month, user=request.user,
                month_days=lst, mname=mnames[month - 1]),
                context_instance=RequestContext(request))
    else:
        return redirect(reverse("cal.views.doctor_calendar",
            args=(int(year), int(month))))

@login_required
@only_doctor_administrative
@paginate(template_name='cal/doctor/list.html', list_name='events',
    objects_per_page=settings.OBJECTS_PER_PAGE)
def day(request, year, month, day, id_user, change=None):
    user = User.objects.get(pk=int(id_user))
    if user.get_profile().is_doctor():
        doctor = user
        patient = None
    else:
        doctor = user.get_profile().doctor
        patient = user

    if change in ("next", "prev"):
        now, mdelta = date(int(year), int(month), int(day)), timedelta(days=1)

        if change == "next":
            mod = mdelta

        elif change == "prev":
            mod = -mdelta

        year, month, day= (now + mod).timetuple()[:3]

    events = Appointment.objects.filter(date__year=year, date__month=month,
            date__day=day, doctor=doctor).order_by('start_time')
    vacations = check_vacations(doctor, year, month, day)
    lst = create_calendar(int(year), int(month), doctor=doctor)
    doctor_preferences = get_doctor_preferences(year=year, month=month,
                day=day, doctor=doctor.id)

    available, free_intervals = Appointment.objects.availability(
                doctor,
                date(int(year), int(month), int(day)))

    template_data = dict(year=year, month=month, day=day, vacations=vacations,
        doctor=doctor, month_days=lst, mname=mnames[int(month) - 1],
        events=events, free_intervals=free_intervals,
        patient_user=patient, doctor_preferences=doctor_preferences,
        birthdays=Profile.objects.filter(dob__month=month, dob__day=day),
        context_instance=RequestContext(request))

    return template_data

@login_required
@only_doctor_administrative
def calendar(request, year, month, day, id_user, change='this'):

    if change in ("next", "prev"):
        now, mdelta = date(int(year), int(month), 15), timedelta(days=31)

        if change == "next":
            mod = mdelta

        elif change == "prev":
            mod = -mdelta

        year, month = (now + mod).timetuple()[:2]

    user = User.objects.get(pk=int(id_user))
    if user.get_profile().is_doctor():
        doctor = user
        patient = None
    else:
        doctor = user.get_profile().doctor
        patient = user
    lst = create_calendar(int(year), int(month), doctor=doctor)
    if int(day):
        available, free_intervals = Appointment.objects.availability(doctor,
                date(int(year), int(month), int(day)))
        doctor_preferences = get_doctor_preferences(year=year, month=month,
                day=day, doctor=doctor.id)
    else:
        available, free_intervals, doctor_preferences = [],[],[]

    return render_to_response('cal/includes/calendar.html',
                                dict(year=year, month=month, day=day,
                                 doctor=doctor, month_days=lst,
                                 patient_user=patient,
                                 mname=mnames[int(month) - 1],
                                 free_intervals=free_intervals,
                                 doctor_preferences=doctor_preferences),
        context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def calendar_big(request, year, month, change='this', id_doctor=None):

    if change in ("next", "prev"):
        now, mdelta = date(int(year), int(month), 15), timedelta(days=31)

        if change == "next":
            mod = mdelta

        elif change == "prev":
            mod = -mdelta

        year, month = (now + mod).timetuple()[:2]

    doctors = Profile.objects.filter(role=settings.DOCTOR)
    if id_doctor:
        doctor = User.objects.get(pk=int(id_doctor))
        lst = create_calendar(int(year), int(month), doctor=doctor)
    else:
        doctor = None
        lst = create_calendar(int(year), int(month), doctor=request.user)
        if request.user.get_profile().is_administrative():
            for d in doctors:
                dlst = create_calendar(int(year), int(month), doctor=d.user)
                for i in range(len(lst)):
                    for j in range(len(lst[i])):
                        for k in range(len(lst[i][j])):
                            if isinstance(lst[i][j][k], list) and isinstance(dlst[i][j][k], list):
                                lst[i][j][k] += dlst[i][j][k]

    form = DoctorSelectionForm()

    return render_to_response('cal/includes/calendar_big.html',
                                dict(year=year, month=month, doctors=doctors,
                                 doctor=doctor, month_days=lst,
                                 mname=mnames[int(month) - 1], form = form),
        context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
@paginate(template_name='cal/doctor/list_consultation.html',
    list_name='events', objects_per_page=settings.OBJECTS_PER_PAGE)
def day_consultation(request, year, month, day):
    events = Appointment.objects.filter(date__year=year, date__month=month,
            date__day=day, doctor=request.user).order_by('start_time')

    lst = create_calendar(int(year), int(month), doctor=request.user)

    available, free_intervals = Appointment.objects.availability(
                request.user,
                date(int(year), int(month), int(day)))

    template_data = dict(year=year, month=month, day=day,
        user=request.user, month_days=lst, mname=mnames[int(month) - 1],
        events=events, free_intervals=free_intervals,
        birthdays=Profile.objects.filter(dob__month=month, dob__day=day),
        context_instance=RequestContext(request))

    return template_data

@login_required
@only_doctor_administrative
def app_add(request, year, month, day, id_user, check=False):
    user = User.objects.get(pk=int(id_user))
    if user.get_profile().is_doctor():
        doctor = user
        patient = None
    else:
        doctor = user.get_profile().doctor
        patient = user

    lst = create_calendar(int(year), int(month), doctor=doctor)
    vacations = check_vacations(doctor, year, month, day)

    if vacations:
        return render_to_response("cal/app/edit.html",
                {'vacations': vacations,
                 'year': int(year), 'month': int(month), 'day': int(day),
                 'month_days': lst,
                 'doctor': doctor,
                 'patient_user': patient,
                 'not_available_error': True,
                 'error_msg': _('Appointment can not be set. '\
                    'Please, choose another time interval')},
                context_instance=RequestContext(request))

    mname = mnames[int(month) - 1]

    doctor_preferences = get_doctor_preferences(year=year, month=month,
        day=day, doctor=doctor.id)

    if request.method == 'POST':
        sched_form = SchedulerForm(request.POST)
        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'doctor': doctor.id,
            'created_by': request.user.id,
            'date': date(int(year), int(month), int(day)),
            'patient': patient.id # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        })

        id_app_type = request.POST.get('app_type', None)
        start_time = request.POST.get('start_time', None)
        end_time = request.POST.get('end_time', None)

        if id_app_type:
            app_type = get_object_or_404(SlotType, pk=int(id_app_type))
            duration = app_type.duration
            request_params.update({'app_type': app_type.id})

            if end_time:
                end_time = time.strptime(end_time, '%H:%M')
                end_time = ttime(end_time[3], end_time[4], end_time[5])

                if start_time:
                    start_time = time.strptime(start_time, '%H:%M')
                    start_time = ttime(start_time[3], start_time[4], start_time[5])
                    duration = ((datetime.combine(date.today(), end_time) - \
                        datetime.combine(date.today(), start_time)).seconds) / 60
                    #del request_params['app_type']
            else:
                if start_time:
                    start_time = time.strptime(start_time, '%H:%M')
                    end_time = add_minutes(start_time, duration)
                    start_time = ttime(start_time[3], start_time[4], start_time[5])

            request_params.update({'start_time': start_time,
                    'end_time': end_time, 'duration': duration})
        else:
            if start_time and end_time:
                start_time = time.strptime(start_time, '%H:%M')
                start_time = ttime(start_time[3], start_time[4], start_time[5])

                end_time = time.strptime(end_time, '%H:%M')
                end_time = ttime(end_time[3], end_time[4], end_time[5])

                duration = (datetime.combine(date.today(), end_time) - \
                    datetime.combine(date.today(), start_time)).seconds

                request_params.update({'start_time': start_time,
                    'end_time': end_time, 'duration': duration / 60})

        form = AppointmentForm(request_params, user=doctor)

        if form.is_valid() and sched_form.is_valid():
            pre_save_instance = form.save(commit=False)
            available, free_intervals = Appointment.objects.availability(
                doctor,
                date(int(year), int(month), int(day)),
                pre_save_instance)

            if available and not check:
                form.save()
                if sched_form.is_valid():
                    number = sched_form.cleaned_data['number']
                    period = sched_form.cleaned_data['period']
                    interval = sched_form.cleaned_data['interval']
                    if number and period:
                        ok, conflicts = check_scheduled_apps(pre_save_instance, number, period, interval)
                        for app in ok:
                            app.pk = None
                            app.status = settings.RESERVED
                            app.save()

                if 'appointment' in request.session:
                    return redirect(reverse("consulting_main",
                        kwargs={'id_appointment':request.session['appointment'].id,
                            'code_illness':request.session['illness'].code}))
                else:
                    return redirect(reverse("cal.views.day",
                        args=(int(year), int(month), int(day), doctor.id)))
            else:
                error = False
                success = False
                conflicts = []
                msg = ''
                if not available:
                    error = True
                    msg = _(u'Conflicto de fecha y hora con otra cita. '\
                        'Por favor, seleccione un intervalo libre')
                elif sched_form.is_valid():
                    number = sched_form.cleaned_data['number']
                    period = sched_form.cleaned_data['period']
                    interval = sched_form.cleaned_data['interval']
                    if number and period:
                        ok, conflicts = check_scheduled_apps(pre_save_instance, number, period, interval)
                        if conflicts:
                            error = True
                            msg = _(u'La reserva de las siguientes citas presentan conflictos de disponibilidad en su agenda y no se crearán automáticamente' )
                        else:
                            msg = _(u'Es posible efectuar la reserva de las citas solicitadas' )
                            error = False
                            success = True

                return render_to_response("cal/app/add.html",
                    {'form': form,
                     'scheduler': sched_form,
                     'year': int(year), 'month': int(month), 'day': int(day),
                     'month_days': lst,
                     'mname': mname,
                     'doctor': doctor,
                     'patient_user': patient,
                     'conflicts': conflicts,
                     'doctor_preferences': doctor_preferences,
                     'free_intervals': free_intervals,
                     'not_available_error': error,
                     'successful_check': success,
                     'error_msg': msg},
                    context_instance=RequestContext(request))
        else:
            available, free_intervals = Appointment.objects.availability(
                doctor,
                date(int(year), int(month), int(day)))
    else:
        app_type = request.GET.get('type','')
        sched_form = SchedulerForm()
        form = AppointmentForm(user=doctor, initial={'app_type': app_type})
        available, free_intervals = Appointment.objects.availability(
            doctor,
            date(int(year), int(month), int(day)))
    if date(int(year), int(month), int(day)) < date.today():
        form = None

    return render_to_response("cal/app/add.html",
                {'form': form,
                 'scheduler': sched_form,
                 'year': int(year), 'month': int(month), 'day': int(day),
                 'month_days': lst,
                 'mname': mname,
                 'doctor': doctor,
                 'patient_user': patient,
                 'doctor_preferences': doctor_preferences,
                 'free_intervals': free_intervals},
                context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def app_edit(request, pk):
    app = get_object_or_404(Appointment, pk=int(pk))
    if not app.is_editable():
        raise Http404

    patient = app.patient
    doctor = app.doctor

    year = int(app.date.year)
    month = int(app.date.month)
    day = int(app.date.day)

    mname = mnames[int(month) - 1]

    lst = create_calendar(year, month, doctor=doctor)

    vacations = check_vacations(doctor, year, month, day)
    available, free_intervals = Appointment.objects.availability(
            doctor,
            date(int(year), int(month), int(day)))

    doctor_preferences = get_doctor_preferences(year=year, month=month,
        day=day, doctor=doctor.id)

    if request.method == 'POST':
        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'doctor': doctor.id,
            'created_by': request.user.id,
            'patient': patient.id # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        })

        start_time = request.POST.get('start_time', None)
        end_time = request.POST.get('end_time', None)
        app_type = request.POST.get('app_type', None)

        if not app_type is None and not app_type == '':
            app_type = get_object_or_404(SlotType, pk=int(app_type))

            duration = app_type.duration
            request_params.update({'app_type': app_type.id})

            if end_time:
                end_time = time.strptime(end_time, '%H:%M')
                end_time = ttime(end_time[3], end_time[4], end_time[5])

                if start_time:
                    start_time = time.strptime(start_time, '%H:%M')
                    start_time = ttime(start_time[3], start_time[4], start_time[5])
                    duration = (datetime.combine(date.today(), end_time) - \
                        datetime.combine(date.today(), start_time)).seconds / 60
                    #del request_params['app_type']
            else:
                if start_time:
                    start_time = time.strptime(start_time, '%H:%M')
                    end_time = add_minutes(start_time, duration)
                    start_time = ttime(start_time[3], start_time[4], start_time[5])

            request_params.update({'start_time': start_time,
                    'end_time': end_time, 'duration': duration})
        else:
            if end_time:
                end_time = time.strptime(end_time, '%H:%M')
                end_time = ttime(end_time[3], end_time[4], end_time[5])

                if start_time:
                    start_time = time.strptime(start_time, '%H:%M')
                    start_time = ttime(start_time[3], start_time[4], start_time[5])

                    duration = datetime.combine(date.today(), end_time) - \
                        datetime.combine(date.today(), start_time)
                    request_params.update({'end_time': end_time,
                        'start_time': start_time,
                        'duration': duration.seconds / 60})

        selected_date = date(int(year), int(month), int(day))
        request_params.update({'weekday': get_weekday(selected_date)})

        form = AppointmentForm(request_params, instance=app, user=doctor)

        if form.is_valid():
            pre_edit_instance = form.save(commit=False)
            year = int(pre_edit_instance.date.year)
            month = int(pre_edit_instance.date.month)
            day = int(pre_edit_instance.date.day)

            mname = mnames[int(month) - 1]

            lst = create_calendar(year, month, doctor=doctor)

            vacations = check_vacations(doctor, year, month, day)

            doctor_preferences = get_doctor_preferences(year=year, month=month,
                day=day, doctor=doctor.id)

            if vacations:
                return render_to_response("cal/app/edit.html",
                        {'form': form,
                         'event': app,
                         'year': year, 'month': month, 'day': day,
                         'month_days': lst,
                         'mname': mname,
                         'doctor': doctor,
                         'patient_user': patient,
                         'doctor_preferences': doctor_preferences,
                         'free_intervals': free_intervals,
                                'vacations': vacations},
                        context_instance=RequestContext(request))

            available, free_intervals = Appointment.objects.availability(
            doctor,
            date(int(year), int(month), int(day)),
            pre_edit_instance,
            edit=True)

            if available:
                form.save()

                if not request.user.get_profile().is_doctor():
                    return redirect(reverse("doctor_day",
                        args=(doctor.id, year, month, day)))
                else:
                    return redirect(reverse("cal.views.day",
                        args=(year, month, day, doctor.id)))
            else:
                return render_to_response("cal/app/edit.html",
                {'form': form,
                 'event': app,
                 'year': year, 'month': month, 'day': day,
                 'month_days': lst,
                 'mname': mname,
                 'doctor': doctor,
                 'patient_user': patient,
                 'doctor_preferences': doctor_preferences,
                 'free_intervals': free_intervals,
                 'not_available_error': True,
                 'error_msg': _('No se pudo crear la cita. '\
                    'Por favor, seleccione un intervalo de tiempo disponible')},
                context_instance=RequestContext(request))

        else:
            available, free_intervals = Appointment.objects.availability(
                doctor,
                date(int(year), int(month), int(day)))
    else:
        form = AppointmentForm(instance=app, user=doctor)
        available, free_intervals = Appointment.objects.availability(
            doctor,
            date(int(year), int(month), int(day)))

    return render_to_response("cal/app/edit.html",
        {'form': form,
         'event': app,
         'year': year, 'month': month, 'day': day,
         'month_days': lst,
         'mname': mname,
         'doctor': doctor,
         'patient_user': patient,
         'doctor_preferences': doctor_preferences,
         'free_intervals': free_intervals},
        context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def app_delete(request, pk):
    if request.method == 'DELETE':
        data = json.loads(request.raw_post_data)
        app_id = data['app_id']
        if int(app_id) != int(pk):
            raise Exception

        event = get_object_or_404(Appointment, pk=int(app_id))
        event.delete()

        try:
            return HttpResponse(json.dumps({'action': True}),
                status=200,
                mimetype='application/json')
        except:
            return HttpResponse(json.dumps({'action': False}),
                status=200,
                mimetype='application/json')
    else:
        return HttpResponse(json.dumps({'action': False}),
                status=200,
                mimetype='application/json')

@login_required
@only_doctor_administrative
@paginate(template_name='cal/patient/list.html',
    list_name='events', objects_per_page=settings.OBJECTS_PER_PAGE)
def app_list_patient(request, id_patient):
    patient = get_object_or_404(User, pk=int(id_patient))
    events = Appointment.objects.filter(patient=patient).order_by('-date')

    template_data = dict(events=events, doctor=patient.get_profile().doctor,
                        patient=patient,
                        context_instance=RequestContext(request))

    return template_data

@login_required()
@only_doctor_administrative
@paginate(template_name='cal/patient/list.html',
    list_name='events', objects_per_page=settings.OBJECTS_PER_PAGE)
def get_appointments(request, year, month, day):
    logged_user_profile = request.user.get_profile()

    #patient_user_id = request.session['patient_user_id']

    appointments = Appointment.objects.filter(date__year=int(year), date__month=int(month), date__day=int(day)).order_by('-start_time')

    template_data = {}
    template_data.update({'events': appointments})
    return template_data

@login_required
@only_doctor
@paginate(template_name='cal/slot_type/list.html',
    list_name='slot_type', objects_per_page=settings.OBJECTS_PER_PAGE)
def list_slot_type(request):
    slot_type = SlotType.objects.filter(doctor=request.user)

    template_data = dict(user=request.user, slot_type=slot_type,
        context_instance=RequestContext(request))

    return template_data

@login_required
@only_doctor
def add_slot_type(request, template="cal/slot_type/add.html"):
    if request.method == 'POST':
        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'doctor': request.user.id,
            'created_by': request.user.id,
        })

        form = SlotTypeForm(request_params)

        if form.is_valid():
            slot_type = form.save()
            to_url = request.GET.get('next',reverse("cal.list_slot_type"))
            return redirect(to_url+'?type='+str(slot_type.id))
        else:
            return render_to_response(template,
                {'form': form},
                context_instance=RequestContext(request))
    else:
        form = SlotTypeForm()

    return render_to_response(template, {'form': form},
                context_instance=RequestContext(request))

@login_required
@only_doctor
def edit_slot_type(request, pk, template="cal/slot_type/edit.html"):
    slot = get_object_or_404(SlotType, pk=int(pk))

    if request.method == 'POST':
        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'doctor': request.user.id,
            'created_by': request.user.id
        })

        form = SlotTypeForm(request_params, instance=slot)

        if form.is_valid():
            form.save()
            return redirect(reverse("cal.list_slot_type"))
        else:
            return render_to_response(template,
                {"form": form, 'slot_type': slot},
                context_instance=RequestContext(request))
    else:
        form = SlotTypeForm(instance=slot)

    return render_to_response(template,
        {"form": form, 'slot_type': slot},
        context_instance=RequestContext(request))

@login_required
@only_doctor
def delete_slot_type(request):
    if request.method == 'DELETE':
        data = json.loads(request.raw_post_data)
        pk = data['pk']

        slot_type = get_object_or_404(SlotType, pk=int(pk))

        try:
            slot_type.delete()
            return HttpResponse(json.dumps({'action': True}),
                status=200,
                mimetype='application/json')
        except:
            return HttpResponse(json.dumps({'action': False}),
                status=200,
                mimetype='application/json')
    else:
        return HttpResponse(json.dumps({'action': False}),
                status=200,
                mimetype='application/json')

@login_required
@only_doctor
def list_slot(request, year=None):
    if not year:
        year = time.localtime()[0]
    slots = Slot.objects.filter(creator=request.user, year=int(year))

    return render_to_response('cal/slot/list.html',
        dict(slots=slots, year=int(year)),
        context_instance=RequestContext(request))

@login_required
@only_doctor
def add_slot(request, year, month=1):
    if request.method == 'POST':
        start_time = request.POST.get('start_time', None)
        end_time = request.POST.get('end_time', None)
        id_slot_type = request.POST.get('slot_type', None)
        months = request.POST.getlist('months')
        weekdays = request.POST.getlist('weekdays')

        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'months': months,
            'weekdays': weekdays,
            })

        if id_slot_type:
            slot_type = get_object_or_404(SlotType, pk=int(id_slot_type))
            if start_time and not end_time:
                st = time.strptime(start_time, '%H:%M')
                end_time = add_minutes(st, slot_type.duration)

        form = SlotForm(request_params, user=request.user)

        if form.is_valid():
            for m in months:
                for d in weekdays:
                    s = Slot()
                    s.weekday = d
                    s.month = m
                    s.year = int(year)
                    s.start_time = start_time
                    s.end_time = end_time
                    s.creator = request.user
                    s.created_by = request.user
                    s.description = form.cleaned_data['description']
                    s.slot_type = slot_type
                    s.save()
            return redirect(reverse("cal.list_slot", args=(int(year),
                )))
        else:
            return render_to_response('cal/slot/add.html',
                {'form': form, 'year': year,},
                context_instance=RequestContext(request))
    else:
        slot_type = request.GET.get('type','')
        form = SlotForm(user=request.user,initial={'slot_type':slot_type})
        #form.fields['app_type'].initial = [slot_type]

    return render_to_response('cal/slot/add.html', {'form': form,
        'year': year,},
        context_instance=RequestContext(request))

@login_required
@only_doctor
def edit_slot(request, pk):
    slot = get_object_or_404(Slot, pk=int(pk))

    if request.method == 'POST':
        start_time = request.POST.get('start_time', None)
        end_time = request.POST.get('end_time', None)
        id_slot_type = request.POST.get('slot_type', None)
        months = request.POST.get('months')
        weekdays = request.POST.get('weekdays')

        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'months': months,
            'weekdays': weekdays,
            })
        slot_type = get_object_or_404(SlotType, pk=int(id_slot_type))

        if id_slot_type and start_time and not end_time:
            st = time.strptime(start_time, '%H:%M')
            end_time = add_minutes(st, slot_type.duration)

        form = SlotForm(request_params, user=request.user, slot=slot)

        if form.is_valid():
            s = slot
            s.weekday = weekdays
            s.month = months
            s.start_time = start_time
            s.end_time = end_time
            s.creator = request.user
            s.created_by = request.user
            s.description = form.cleaned_data['description']
            s.slot_type = slot_type
            s.save()
            return redirect(reverse("cal.list_slot", args=(slot.year,
                )))
        else:
            return render_to_response('cal/slot/edit.html',
                {"form": form, 'slot': slot,
                 'year': slot.year, 'month': slot.month},
                context_instance=RequestContext(request))
    else:
        form = SlotForm( dict(weekdays=[slot.weekday], months=[slot.month], start_time=slot.start_time, end_time=slot.end_time, slot_type=slot.slot_type), user=request.user, slot=slot)

    return render_to_response('cal/slot/edit.html',
        {"form": form, 'slot': slot, 'year': slot.year,
         'month': slot.month},
        context_instance=RequestContext(request))

@login_required
@only_doctor
def delete_slot(request, pk):
    slot = get_object_or_404(Slot, pk=int(pk))
    year = int(slot.year)
    slot.delete()
    return redirect(reverse("cal.list_slot", args=(year,)))

@login_required
@only_doctor_administrative
def doctor_calendar(request):
    if request.method == 'POST':
        form = DoctorSelectionForm(request.POST)
        if form.is_valid():

            id_doctor = form.cleaned_data['doctor']

            return redirect(reverse("cal.scheduler",
                args=[int(id_doctor),]))
    else:
        form = DoctorSelectionForm()

    return render_to_response('cal/app/admin.html', {'form': form},
        context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def doctor_month(request, year, month, id_doctor, change=None):
    year, month = int(year), int(month)

    doctor = get_object_or_404(User, pk=int(id_doctor))
    if not doctor.get_profile().is_doctor():
        raise Http404

    if change in ("next", "prev"):
        now, mdelta = date(year, month, 15), timedelta(days=31)

        if change == "next":
            mod = mdelta

        elif change == "prev":
            mod = -mdelta

        year, month = (now + mod).timetuple()[:2]

    lst = create_calendar(year, month, doctor=doctor)
    doctor_preferences = get_doctor_preferences(year=year, month=month,
        doctor=id_doctor)

    return render_to_response("cal/app/month.html",
        dict(year=year, month=month, user=request.user, doctor=doctor,
            month_days=lst, mname=mnames[month - 1],
            doctor_preferences=doctor_preferences),
            context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
@paginate(template_name='cal/app/list.html',
    list_name='events', objects_per_page=settings.OBJECTS_PER_PAGE)
def doctor_day(request, id_doctor, year, month, day):
    doctor = get_object_or_404(User, pk=int(id_doctor))
    if not doctor.get_profile().is_doctor():
        raise Http404

    vacations = check_vacations(doctor, year, month, day)

    if not vacations:
        events = Appointment.objects.filter(doctor=doctor, date__year=year,
            date__month=month, date__day=day).order_by('start_time')
    else:
        events = Appointment.objects.none()

    lst = create_calendar(int(year), int(month), doctor=doctor)
    doctor_preferences = get_doctor_preferences(year=year, month=month,
        day=day, doctor=id_doctor)

    available, free_intervals = Appointment.objects.availability(
                doctor,
                date(int(year), int(month), int(day)))

    template_data = dict(year=year, month=month, day=day, user=request.user,
        doctor=doctor, month_days=lst, mname=mnames[int(month) - 1],
        events=events, doctor_preferences=doctor_preferences,
        vacations=vacations, free_intervals=free_intervals,
        context_instance=RequestContext(request))

    return template_data

@login_required
@only_doctor
@paginate(template_name='cal/vacation/list.html',
    list_name='vacations', objects_per_page=settings.OBJECTS_PER_PAGE)
def list_vacation(request):
    vacations = Vacation.objects.filter(doctor=request.user).order_by('-date')
    years = vacations.dates('date','year',order='ASC')
    year = request.GET.get('year', '')
    if year:
        vacations = vacations.filter(date__year=year)

    queries_without_page = request.GET.copy()
    if queries_without_page.has_key('page'):
        del queries_without_page['page']

    template_data = dict(user=request.user, vacations=vacations, year=year,
                        queries=queries_without_page, years=years,
                        context_instance=RequestContext(request))

    return template_data

@login_required
@only_doctor
def add_vacation(request, template="cal/vacation/add.html"):
    if request.method == 'POST':
        start_date = request.POST.get('date', None)
        end_date = request.POST.get('end_date', start_date)
        if not end_date:
            end_date = start_date
        error = None
        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'doctor': request.user.id,
            'created_by': request.user.id,
            'date': start_date
        })
        form = VacationForm(request_params)
        form.is_valid()
        start_date = datetime.strptime(start_date, settings.DATE_INPUT_FORMAT)
        end_date = datetime.strptime(end_date, settings.DATE_INPUT_FORMAT)
        if end_date and end_date >= start_date:
            for n in range(int((end_date - start_date).days)+1):
                if Appointment.objects.filter(doctor=request.user, date=(start_date + timedelta(n))).count():
                    form._errors['__all__'] = ErrorList([u"Existen citas concertadas en el intervalo de vacaciones. Elija otro intervalo de fechas o modifique las citas concertadas."])
                    error = True
                    break
        else:
            form._errors['end_date'] = ErrorList([u"Fecha final debe ser mayor que la fecha inicial"])
            error = True

        if not error:
            for n in range(int((end_date - start_date).days)+1):
                request_params.update({
                    'date': (start_date + timedelta(n)).strftime(settings.DATE_INPUT_FORMAT)
                })

                form = VacationForm(request_params)

                if form.is_valid():
                    form.save()
                else:
                     return render_to_response(template,
                        {'form': form},
                        context_instance=RequestContext(request))
            return redirect(reverse("cal.list_vacation"))
        else:
            return render_to_response(template,
                {'form': form},
                context_instance=RequestContext(request))
    else:
        form = VacationForm()

    return render_to_response(template, {'form': form},
                context_instance=RequestContext(request))

@login_required
@only_doctor
def edit_vacation(request, pk, template="cal/vacation/edit.html"):
    vacation = get_object_or_404(Vacation, pk=int(pk))

    if request.method == 'POST':
        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'doctor': request.user.id,
            'created_by': request.user.id,
        })

        date = request.POST.get('date', None)
        if date:
            date = datetime.now().strptime(date, settings.DATE_INPUT_FORMAT)
            request_params.update({'date': date})

        form = VacationForm(request_params, instance=vacation)

        if form.is_valid():
            form.save()
            return redirect(reverse("cal.list_vacation"))
        else:
            return render_to_response(template,
                {"form": form, 'vacation': vacation},
                context_instance=RequestContext(request))
    else:
        form = VacationForm(instance=vacation)

    return render_to_response(template,
        {"form": form, 'vacation': vacation},
        context_instance=RequestContext(request))

@login_required
@only_doctor
def delete_vacation(request):
    if request.method == 'DELETE':
        data = json.loads(request.raw_post_data)
        pk = data['pk']

        vacation = get_object_or_404(Vacation, pk=int(pk))

        try:
            vacation.delete()
            return HttpResponse(json.dumps({'action': True}),
                status=200,
                mimetype='application/json')
        except:
            return HttpResponse(json.dumps({'action': False}),
                status=200,
                mimetype='application/json')
    else:
        return HttpResponse(json.dumps({'action': False}),
                status=200,
                mimetype='application/json')

@login_required
@only_doctor
@paginate(template_name='cal/event/list.html',
    list_name='events', objects_per_page=settings.OBJECTS_PER_PAGE)
def list_event(request):
    events = Event.objects.filter(doctor=request.user).order_by('-date')
    years = events.dates('date','year',order='ASC')
    year = request.GET.get('year', '')
    if year:
        events = events.filter(date__year=year)

    queries_without_page = request.GET.copy()
    if queries_without_page.has_key('page'):
        del queries_without_page['page']

    template_data = dict(user=request.user, events=events, year=year,
                        queries=queries_without_page, years=years,
                        context_instance=RequestContext(request))

    return template_data

@login_required
@only_doctor
def add_event(request, template="cal/event/add.html"):
    if request.method == 'POST':
        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'doctor': request.user.id,
            'created_by': request.user.id,
            'date': datetime.now()
        })

        date = request.POST.get('date', None)
        if date:
            date = datetime.now().strptime(date, settings.DATE_INPUT_FORMAT)
            request_params.update({'date': date})

        form = EventForm(request_params)

        if form.is_valid():
            form.save()
            return redirect(reverse("cal.list_event"))
        else:
            return render_to_response(template,
                {'form': form},
                context_instance=RequestContext(request))
    else:
        form = EventForm()

    return render_to_response(template, {'form': form},
                context_instance=RequestContext(request))

@login_required
@only_doctor
def edit_event(request, pk, template="cal/event/edit.html"):
    event = get_object_or_404(Event, pk=int(pk))

    if request.method == 'POST':
        request_params = dict([k, v] for k, v in request.POST.items())
        request_params.update({
            'doctor': request.user.id,
            'created_by': request.user.id,
        })

        date = request.POST.get('date', None)
        if date:
            date = datetime.now().strptime(date, settings.DATE_INPUT_FORMAT)
            request_params.update({'date': date})

        form = EventForm(request_params, instance=event)

        if form.is_valid():
            form.save()
            return redirect(reverse("cal.list_event"))
        else:
            return render_to_response(template,
                {"form": form, 'event': event},
                context_instance=RequestContext(request))
    else:
        form = EventForm(instance=event)

    return render_to_response(template,
        {"form": form, 'event': event},
        context_instance=RequestContext(request))

@login_required
@only_doctor
def delete_event(request):
    if request.method == 'DELETE':
        data = json.loads(request.raw_post_data)
        pk = data['pk']

        event = get_object_or_404(Event, pk=int(pk))

        try:
            event.delete()
            return HttpResponse(json.dumps({'action': True}),
                status=200,
                mimetype='application/json')
        except:
            return HttpResponse(json.dumps({'action': False}),
                status=200,
                mimetype='application/json')
    else:
        return HttpResponse(json.dumps({'action': False}),
                status=200,
                mimetype='application/json')

@login_required()
@only_doctor_administrative
def lookfor_patient(request, action=None, year=None, month=None, day=None):
    if action == 'info':
        pass
    elif action == 'new_app':
        if year and month and day:
            destination = 'cal.add'
        else:
            destination = 'cal.scheduler'
    elif action == 'list_app':
        destination = 'cal.app_list_patient'

    return render_to_response('cal/patient/lookfor_patient.html',
            {'destination':destination, 'year':year, 'month':month, 'day':day},
            context_instance=RequestContext(request))

@login_required()
@only_doctor_administrative
def patient_searcher(request):
    logged_user_profile = request.user.get_profile()

    if logged_user_profile.is_administrative() or\
        logged_user_profile.is_doctor():
        data = {'ok': False}
        if request.method == 'POST':
            start = request.POST.get("start", "")

            if logged_user_profile.is_administrative():
                profiles = Profile.objects.filter(
                                Q(role__exact=settings.PATIENT),
                                Q(nif__istartswith=start)|
                                Q(name__istartswith=start)|
                                Q(first_surname__istartswith=start)|
                                Q(second_surname__istartswith=start)).order_by(
                                'name', 'first_surname', 'second_surname')
            else:
                doctor_user = logged_user_profile.user
                profiles = Profile.objects.filter(
                                Q(doctor=doctor_user,
                                role__exact=settings.PATIENT),
                                Q(nif__istartswith=start)|
                                Q(name__istartswith=start)|
                                Q(first_surname__istartswith=start)|
                                Q(second_surname__istartswith=start)).order_by(
                                'name', 'first_surname', 'second_surname')

            data = {'ok': True,
                    'completed_names':
                    [{'id': profile.user.id,
                    'label':
                    (profile.get_full_name()+ ' ['+profile.nif+']')}for profile in profiles]
                    }
        return HttpResponse(simplejson.dumps(data))
    return HttpResponseRedirect(reverse('consulting_index'))

@login_required()
@only_doctor_administrative
def select_doctor(request, id_patient):
    patient_user = get_object_or_404(User, pk=int(id_patient))
    if request.method == 'POST':
        form = DoctorSelectionForm(request.POST)

        if form.is_valid():
            profile = patient_user.get_profile()
            check_transfer(request, id_patient, True)
            profile.doctor = User.objects.get(pk=int(form.cleaned_data['doctor']))
            profile.save()
            if request.is_ajax():
                return HttpResponse('OK');
            return HttpResponseRedirect(reverse('cal.scheduler',
                args=[int(id_patient)]))
        elif request.is_ajax():
            return Http404
    else:
        form = DoctorSelectionForm()

    return render_to_response('cal/app/select_doctor.html', {'form': form,
        'patient_user': patient_user},
        context_instance=RequestContext(request))

@login_required()
@only_doctor_administrative
def check_transfer(request, id_patient, doit=False):
    if request.method == 'POST':
        id_doctor = request.POST.get('doctor',None)
    else:
        return Http404
    transferable, moves = True, 0
    patient_user = get_object_or_404(User, pk=int(id_patient))
    doctor = get_object_or_404(User, pk=int(id_doctor))
    next_apps = Appointment.objects.filter(patient=patient_user,
                            date__gt=date.today(), status__in=[settings.CONFIRMED, settings.RESERVED]).order_by(
                            'date')
    for app in next_apps:
        available, free_intervals = Appointment.objects.availability(
                doctor, app.date, app)
        transferable = available
        if not available and free_intervals:
            for i in free_intervals:
                if i['duration'] >= app.duration:
                    moves += 1
                    transferable = True
                    if doit:
                        app.start_time = i['start_time']
                        app.end_time = add_minutes(i['start_time'], app.duration)
                    break
        if doit:
            if transferable:
                app.doctor = doctor
                #app.description = "%s %s"%(app.app_type.description, app.description)
                #app.app_type = None
            else:
                app.status = settings.CANCELED_BY_DOCTOR
            app.save()
    data = {'ok': transferable,
            'moves': moves}
    if doit:
        return 1
    else:
        return HttpResponse(simplejson.dumps(data))

@login_required
@only_doctor_administrative
@paginate(template_name='cal/payment/list_ajax.html',
    list_name='events', objects_per_page=settings.OBJECTS_PER_PAGE*2)
def get_payment_list(request, query_filter=None):
    apps = Appointment.objects.all().order_by('-date')
    if query_filter:
        apps = apps.filter(query_filter)
    if request.user.get_profile().is_doctor():
        apps = apps.filter(doctor=request.user)

    queries_without_page = request.GET.copy()
    if queries_without_page.has_key('page'):
        del queries_without_page['page']

    template_data = dict(user=request.user,
                        events=apps,
                        queries=queries_without_page,
                        context_instance=RequestContext(request))
    return template_data

@login_required
@only_doctor_administrative
def payment_list(request):
    form = PaymentFiltersForm()
    if request.method == "GET":
        form = PaymentFiltersForm(request.GET, user=request.user)
        query_filter = Q()
        exclude_filter = Q()
        for k, v in request.GET.items():
            if not v:
                continue
            if k.startswith('app_date'):
                day, month, year  = v.split('/')
                if k.endswith('0'):
                    query_filter = query_filter & Q(date__gte=date(int(year),
                                                                int(month),
                                                                int(day)))
                else:
                    query_filter = query_filter & Q(date__lte=date(int(year),
                                                                int(month),
                                                                int(day)))
            elif k.startswith('payment_date'):
                day, month, year  = v.split('/')
                if k.endswith('0'):
                    query_filter = query_filter \
                            & Q(payment_appointment__date__gte=date(int(year),
                                                                int(month),
                                                                int(day)))
                else:
                    query_filter = query_filter \
                            & Q(payment_appointment__date__lte=date(int(year),
                                                                int(month),
                                                                int(day)))
            elif k.startswith('value'):
                if k.endswith('0'):
                    query_filter = query_filter \
                            & Q(payment_appointment__value__gte=Decimal(v))
                else:
                    query_filter = query_filter \
                            & Q(payment_appointment__value__lte=Decimal(v))
            elif k.startswith('discount'):
                if k.endswith('0'):
                    query_filter = query_filter \
                            & Q(payment_appointment__discount__gte=int(v))
                else:
                    query_filter = query_filter \
                            & Q(payment_appointment__discount__lte=int(v))
            elif k.startswith('method'):
                query_filter = query_filter \
                    & Q(payment_appointment__method__in=request.GET.getlist(k))
            elif k.startswith('patient'):
                query_filter = query_filter \
                    & Q(patient__id__in=request.GET.getlist(k))
            elif k.startswith('doctor'):
                query_filter = query_filter \
                    & Q(doctor__id__in=request.GET.getlist(k))
            elif k.startswith('status'):
                subquery = Q()
                for op in request.GET.getlist(k):
                    if int(op)==0:
                        subquery = subquery \
                        | Q(payment_appointment__method__gte=0)
                    elif int(op)==1:
                        subquery = subquery \
                            | (Q(status=settings.CONFIRMED) \
                            & Q(date__gte=date.today()))
                    elif int(op)==2:
                        subquery = subquery \
                                    | Q(status=settings.CONFIRMED) \
                                    & Q(appointment_conclusions__id__gt=0) \
                                    & Q(payment_appointment__isnull=True)
                    elif int(op)==3:
                        subquery = subquery \
                                    | Q(status=settings.RESERVED) \
                                    & Q(date__gte=date.today())
                    elif int(op)==4:
                        subquery = subquery \
                                    | Q(status=settings.CANCELED_BY_DOCTOR) \
                                    | Q(status=settings.CANCELED_BY_PATIENT)
                    elif int(op)==5:
                        subquery = subquery \
                                    | Q(status=settings.RESERVED) \
                                    & Q(date__lt=date.today())
                    elif int(op)==6:
                        subquery = subquery \
                                    | Q(status=settings.CONFIRMED) \
                                    & Q(appointment_conclusions__isnull=True) \
                                    & Q(appointment_tasks__isnull=True) \
                                    & Q(date__lt=date.today())
                query_filter = query_filter & subquery
        if request.is_ajax():
            return get_payment_list(request, query_filter)

    return render_to_response('cal/payment/list.html', {'form': form},
        context_instance=RequestContext(request))

@login_required
@only_doctor_administrative
def payment_edit(request, id_appointment):
    app = get_object_or_404(Appointment, pk=int(id_appointment))
    payment = None
    try:
        payment = Payment.objects.get(appointment=app)
        form = PaymentForm(instance=payment)
    except:
        form = PaymentForm()
    if request.method == 'POST':
        form = PaymentForm(request.POST)
        if payment:
            form = PaymentForm(request.POST, instance=payment)
        if form.is_valid():
            payment = form.save(commit=False)
            payment.created_by = request.user
            payment.appointment = app
            payment.save()
            return HttpResponseRedirect(reverse('cal.list_payment'))

    return render_to_response('cal/payment/edit.html', {'form': form,
        'app': app},
        context_instance=RequestContext(request))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse

from cats_dogs.dnn_api import ModelWrapper

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Train cat/doc classification model.')
    parser.add_argument('model_path', type=str,
                        help='path to save trained model')
    parser.add_argument('train_dir', type=str,
                        help='path to directory with train images')
    parser.add_argument('val_dir', type=str,
                        help='path to directory with validation images')
    parser.add_argument('n_epochs', type=int,
                        help='number of epochs for training')
    parser.add_argument('--load', type=bool, default=True,
                        help='load pre-trained model if True, initialize new if False. True by default')
    args = parser.parse_args()

    if args.load:
        model = ModelWrapper.load(args.model_path)
    else:
        model = ModelWrapper.new()
    model.train(args.train_dir,
                args.val_dir,
                n_epochs=args.n_epochs)
    model.save(args.model_path)