import numpy as np
import pandas as pd
import sys
import re
import os
import gc
import h5py
import hdf5_getters
from optparse import OptionParser
from ediblepickle import checkpoint

parser = OptionParser()
parser.add_option('--i_dir',dest='i_dir',help='input directory',default='./')
parser.add_option('--o_dir',dest='o_dir',help='output directory',default='./')

(options, args) = parser.parse_args()
i_dir = options.i_dir
o_dir = options.o_dir

cache_dir = 'h5_to_df_cache'
if not os.path.exists(cache_dir):
    os.mkdir(cache_dir)

if not os.path.exists(o_dir):
    os.mkdir(o_dir)

@checkpoint(key=lambda args, kwargs: re.sub('/|MillionSong','',args[0]) +'.pkl', work_dir=cache_dir)
def gen_df_h5(my_dir):
    '''
    Pulls information from all .h5 files and stores as a pandas DataFrame
    Target .h5 files are from Million Song Dataset
    Data being pulled, in order, includes
        song_ID, artist_ID, title, artist_name, release, artist_7digitalid, track_7digitalid,
        analysis_sample_rate, sections_start, segments_pitches, segments_timbre, segments_start,
        tempo, time_signature, key, mode, end_of_fade_in, start_of_fade_out, duration, danceability,
        energy, loudness, song_hotttnesss, artist_hotttnesss, artist_mbtags, artist_terms,
        artist_terms_freq, artist_terms_weight, similar_artists
    Inputs:
        my_dir: str
            directory containined .h5 files
    Outputs:
        df: pandas dataframe
            dataframe containing information from .h5 file
    '''
    columns = '''song_ID, artist_ID, title, artist_name, release, artist_7digitalid, track_7digitalid,
        analysis_sample_rate, sections_start, segments_pitches, segments_timbre, segments_start,
        tempo, time_signature, key, mode, end_of_fade_in, start_of_fade_out, duration, danceability,
        energy, loudness, song_hotttnesss, artist_hotttnesss, artist_mbtags, artist_terms,
        artist_terms_freq, artist_terms_weight, similar_artists'''
    columns = re.split(', ',re.sub('\n\s*','',columns))

    df = pd.DataFrame(columns=columns)
    files = os.listdir(my_dir)

    for f in files:
        h5 = hdf5_getters.open_h5_file_read(my_dir+f)
        my_dict = dict.fromkeys(columns)

        my_dict['song_ID'] = [hdf5_getters.get_song_id(h5).decode()]
        my_dict['artist_ID'] = [hdf5_getters.get_artist_id(h5).decode()]
        my_dict['title'] = [hdf5_getters.get_title(h5).decode()]
        my_dict['artist_name'] = [hdf5_getters.get_artist_name(h5).decode()]
        my_dict['release'] = [hdf5_getters.get_release(h5).decode()]
        my_dict['artist_7digitalid'] = [hdf5_getters.get_artist_7digitalid(h5)]
        my_dict['track_7digitalid'] = [hdf5_getters.get_track_7digitalid(h5)]
        my_dict['analysis_sample_rate'] = [hdf5_getters.get_analysis_sample_rate(h5)]
        my_dict['sections_start'] = [hdf5_getters.get_sections_start(h5)]
        my_dict['segments_pitches'] = [hdf5_getters.get_segments_pitches(h5)]
        my_dict['segments_timbre'] = [hdf5_getters.get_segments_timbre(h5)]
        my_dict['segments_start'] = [hdf5_getters.get_segments_start(h5)]
        my_dict['tempo']  = [hdf5_getters.get_tempo(h5)]
        my_dict['time_signature'] = [hdf5_getters.get_time_signature(h5)]
        my_dict['key'] = [hdf5_getters.get_key(h5)]
        my_dict['mode'] = [hdf5_getters.get_mode(h5)]
        my_dict['end_of_fade_in'] = [hdf5_getters.get_end_of_fade_in(h5)]
        my_dict['start_of_fade_out'] = [hdf5_getters.get_start_of_fade_out(h5)]
        my_dict['duration'] = [hdf5_getters.get_duration(h5)]
        my_dict['danceability'] = [hdf5_getters.get_danceability(h5)]
        my_dict['energy'] = [hdf5_getters.get_energy(h5)]
        my_dict['loudness'] = [hdf5_getters.get_loudness(h5)]
        my_dict['song_hotttnesss'] = [hdf5_getters.get_song_hotttnesss(h5)]
        my_dict['artist_hotttness'] = [hdf5_getters.get_artist_hotttnesss(h5)]
        my_dict['artist_mbtags'] = [np.array([x.decode() for x in hdf5_getters.get_artist_mbtags(h5)])]
        my_dict['artist_terms'] = [hdf5_getters.get_artist_terms(h5).astype(str)]
        my_dict['artist_terms_freq'] = [hdf5_getters.get_artist_terms_freq(h5)]
        my_dict['artist_terms_weight'] = [hdf5_getters.get_artist_terms_weight(h5)]
        my_dict['similar_artists'] = [hdf5_getters.get_similar_artists(h5).astype(str)]

        df = pd.concat([df, pd.DataFrame(my_dict)], axis=0, ignore_index=True)

    return df

def merge_df(my_dir, i_dir):
    '''
    Merges pickled df files
    Returns combined df
    '''
    li = []

    files = os.listdir(my_dir)
    for f in files:
        if re.sub('/','',i_dir) in f:
            df = pd.read_pickle(my_dir+'/'+f)
            for x in df.to_dict(orient='records'):
                li.append(x)

    return pd.DataFrame(li)

if re.sub('/','',i_dir)+'_df.pkl' in os.listdir(o_dir):
    sys.exit(i_dir+' already processed and can be found as '+re.sub('/','',i_dir)+'_df.pkl'+' in '+o_dir)

root = i_dir
for lett in os.listdir(root):
    for d in os.listdir(root+lett+'/'):
        gen_df_h5(root+lett+'/'+d+'/')
        gc.collect()

total_df = merge_df('h5_to_df_cache/', i_dir)
total_df.to_pickle(o_dir+'/'+re.sub('/','',i_dir)+'_df.pkl')


from absympla.core.api_router import SymplaAPIRouter
from absympla.core.types.event import Event
from absympla.log import get_logger
from typing import Iterator

class SymplaEvents(SymplaAPIRouter):
    ROUTES = {
        "list_events": "/public/v3/events",
        "get_event": "/public/v3/events/{}"
    }
    logger = get_logger(__name__)

    def get_event(self, event_id: str) -> Event:
        self.logger.info(f'Reading event ({event_id}) info')
        handler = self.get(url=self.ROUTES["get_event"].format(event_id))
        handler.raise_for_status()
        response = handler.json()
        return Event(**response.get("data"))

    def list_events(self) -> Iterator[Event]:
        has_next = True
        page = 1

        while has_next:
            self.logger.info(f'Reading list_events page ({page})')

            handler = self.get(url=self.ROUTES["list_events"], params={
                "page": page
            })

            handler.raise_for_status()

            response = handler.json()

            sorting_field = response.get("sort", {}).get("field_sort", "unknown")
            sorting_method = response.get("sort", {}).get("sort", "ASC")
            self.logger.info(f'Sorting by: {sorting_field} ({sorting_method})')

            has_next = response.get("pagination", {}).get("has_next", False)

            self.logger.info(f"Has next: {'yes' if has_next else 'no'}")

            for event_info in response.get("data"):
                yield Event(**event_info)

            page += 1

        self.logger.info(f'list_of_events has come to an end')


import discord
from discord.ext import commands
listener = commands.Cog.listener

class events(commands.Cog):

	def __init__(self, client):
		self.client = client

	@listener()
	async def on_member_ban(self, server, user):
		channel = self.client.get_channel(869134199855149056)
		await channel.send(f'Пользователь {user.mention} был забанен')

	@listener()
	async def on_message_unban(self, server, user):
		channel = self.client.get_channel(869134199855149056)
		await channel.send(f'Пользователь {user.mention} был разбанен')

	@listener()
	async def on_member_join(self, member):
		channel = self.client.get_channel(869134199855149056)
		role1 = member.guild.get_role(870347664116551771)
		await member.add_roles(role1)
		await channel.send(f"Добро пожаловать в клан 'Берлога', {member.mention}!")
	@listener()
	async def on_member_remove(self, member):
		channel = self.client.get_channel(869134199855149056)
		await channel.send(f"{member.mention} Покинул нас!")

	@listener()
	async def on_button_click(self, res):
		await res.respond(type=6)
	@listener()
	async def on_voice_state_update(self,member,before,after):
		if after.channel.id == 870945646507610122:
			mainCategory = discord.utils.get(member.guild.categories, id=870945493985923123)
			channel2 = await member.guild.create_voice_channel(name=f"Комната {member.display_name}",category=mainCategory)
			await member.move_to(channel2)
			await channel2.set_permissions(member,mute_members=True,move_members=True,manage_channels=True)
			def check(a,b,c):
				return len(channel2.members) == 0
			await self.client.wait_for('voice_state_update', check=check)
			await channel2.delete()

def setup(client):
	client.add_cog(events(client))


from datetime import datetime
import random
import time

odds = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57,
        59]

this_minute = datetime.today().minute

for i in range(5):
    if this_minute in odds:
        print("This is an odd minute")
    else:
        print("This is an even minute")
    wait = random.randint(1, 60)
    time.sleep(wait)


import logging
from util import func

import generalEquations as equ
import mode

class RocketEngine(object):
	def __init__(self, engineStats):
		self.attached = True
		self.throt_cur = 0.0
		self.throt_prev = 0.0
		self.burn_rate = 0.0
		self.messages = []
		self.thrust_total = 0.0
		self.reached_max = False

		# The following are overwritten by engine stats
		self.event = {}
		self.power_down_start_time = None
		self.ignition_time = None
		self.jettison_time = None
		self.min_throt = 0.0
		self.max_throt = 1.0
		self.engine_count = 0
		self.thrust_sl = 0.0
		self.thrust_vac = 0.0
		self.stage = None
		self.throt_rate_of_change_limit = 1.0
		self.name = "Not set yet"
		self.specImp_sl = 0.0
		self.specImp_vac = 0.0

		for key, value in engineStats.items():
			setattr(self, key, value)

		if self.power_down_start_time:
			self.power_down_start_time = round(self.power_down_start_time, 1)
		if self.ignition_time:
			self.ignition_time = round(self.ignition_time, 1)
		if self.jettison_time:
			self.jettison_time = round(self.jettison_time, 1)
	def __str__(self):
		return "Name={} Throt={} Eff Burn Rate={} Thrust={} Count={} Stage={}".format(self.name, self.throt_avg, self.get_eff_fuel_burn_rate(), self.get_thrust_total(), self.engine_count, self.stage)

	@staticmethod
	def factory(engine_data):
		''' creates engines that burn either solid or liquid fuel '''
		if engine_data["type"] == "Solid":
			return SolidRocketEngine(engine_data)
		elif engine_data["type"] == "Liquid":
			return LiquidRocketEngine(engine_data)
		else:
			raise ValueError("Unsupported engine type.")

	def set_fuel_source(self, source):
		self.fuel_source = source

	def engine_stats(self, starting_throttle, power_down_start_time, ignition_time=None, jettison_time=None):

		stat_time = 0.0
		if ignition_time:
			stat_time = ignition_time

		if power_down_start_time == float('inf'):
			sim_end = stat_time + 6
			# 6 seconds is more than enough time for any engine to hit max
		else:
			sim_end = power_down_start_time + 5.0
		time_inc = 0.1
		stats = {
			"max_reached_time": None,
			"engine_cutoff_time": None,
			"min_reached_time" : None,
			"throttle_at_end_time": None
		}
		if starting_throttle == 0 and not ignition_time:
			# if the engine is never turned on, get out of here
			return stats
		max_reached = False
		min_reached = False
		self.setThrottleOverride(starting_throttle)
		self.setThrottleOverride(starting_throttle)
		while stat_time < sim_end:
			#print(stat_time, self.throt_cur)
			if stat_time != 0:
				self.events(stat_time, time_inc)
			if not max_reached:
				if self.throt_cur == self.max_throt:
					max_reached = True
					stats['max_reached_time'] = stat_time

			if stat_time == jettison_time:
				stats['engine_cutoff_time'] = stat_time

				return stats
			if max_reached and not min_reached and func.less_than_or_almost_equals(self.throt_avg, self.min_throt):
				min_reached = True
				stats['min_reached_time'] = stat_time

			if max_reached and self.throt_avg == 0.0:
				stats['engine_cutoff_time'] = stat_time
				return stats
			stats['throttle_at_end_time'] = self.throt_cur # keep updating the throttle at end, until the end
			stat_time += time_inc
		return stats

	def requested_throt_to_float(self, requested_throt):
		''' Converts the requested throttle to a floating point number between 0.0 and 1.0 '''
		assert func.is_float(requested_throt) or requested_throt in ["min", "max", "off"]
		if requested_throt == "max":
			requested_throt = self.max_throt
		elif requested_throt == "min":
			requested_throt = self.min_throt
		elif requested_throt == "off":
			requested_throt = 0.0

		if requested_throt >= self.max_throt:
			requested_throt = self.max_throt
		assert func.is_float(requested_throt) and requested_throt >= 0.0 and requested_throt <= 1.0
		return requested_throt

	def setThrottleOverride(self, requested_throt):
		''' allows setting throttle without regard to the engine's max rate of change '''
		self.throt_prev = self.throt_cur
		requested_throt = self.requested_throt_to_float(requested_throt)
		self.throt_cur = requested_throt

	@property
	def throt_avg(self):
		return equ.average(self.get_throt(), self.get_throt("prev"))

	def get_throt(self, when="current"):
		if when == "current":
			return self.throt_cur
		elif when == "prev":
			return self.throt_prev
		else:
			raise ValueError("Only current and prev values stored")

	def get_burn_rate(self, when="current"):
		return self.burn_rate

	def get_thrust_total(self, when="current"):
		return self.thrust_total

	def get_thrust_per_engine(self):
		return self.thrust_total / self.engine_count

	def setThrottle(self, requested_throt, time_inc):
		self.throt_prev = self.throt_cur
		#Limit the throttle to its max change limit
		requested_throt = self.requested_throt_to_float(requested_throt)

		if requested_throt == self.get_throt():
			self.throt_cur = requested_throt
			return requested_throt

		if requested_throt > self.get_throt():
			direction = 1.0
			verb = "increased"
		else:
			direction = -1.0
			verb = "decreased"
		#direction 1 for pos and -1 for neg changes
		if abs(requested_throt - self.get_throt()) > (self.throt_rate_of_change_limit * time_inc):
			throt = self.get_throt() + time_inc * self.throt_rate_of_change_limit * direction
		else:
			throt = requested_throt
		if throt > self.max_throt:
			logging.debug("Max Throt achieved for %s", self.name)
			self.throt_cur = self.max_throt
		elif throt < self.min_throt:
			if direction < 0:
				logging.debug("%s Engine shutoff", self.name)
				self.throt_cur = 0
			else:
				logging.debug("%s Engine set to min throt", self.name)
				self.throt_cur = self.min_throt
		else:
			self.throt_cur = throt

		if self.get_throt("prev") != self.get_throt():
			self.messages.append("\nEVENT: {} Throttle {} from {} to {} time inc {}".format(self.name, verb, self.get_throt("prev"), self.get_throt(), time_inc))

	def thrustAtAlt(self, alt):
		''' calculates the thrust at altitude and stores and returns that value '''
		patm = equ.percentOfAtmosphericPressure(alt)
		pctVac = 1.0 - patm
		if mode.THROTTLE_FINAL_UP and self.get_throt("prev") < self.get_throt():
			self.thrust_total = self.engine_count * self.get_throt() * (self.thrust_sl + (pctVac * (self.thrust_vac - self.thrust_sl)))
		else:
			self.thrust_total = self.engine_count * self.throt_avg * (self.thrust_sl + (pctVac * (self.thrust_vac - self.thrust_sl)))
		return self.get_thrust_total()

	def get_eff_fuel_burn_rate(self, for_all=True):
		''' returns the average throttle times the burn rate '''
		if for_all:
			return self.throt_avg * self.get_burn_rate() * self.engine_count
		else:
			return self.throt_avg * self.get_burn_rate()

	def burn_fuel(self, time_inc, alt=None):
		''' Burns fuel (increasing the total fuel used)
		Alt is ignored for this engine type
		'''
		if self.throt_avg > 0.0:
			inc_fuel_used = self.get_eff_fuel_burn_rate() * time_inc
			# print self.name, self.stage, "\nthrot_avg", self.throt_avg, "\neff burn rate", self.get_eff_fuel_burn_rate(), "\ntime_inc", time_inc, "\nInc fuel used", inc_fuel_used, "\n"
			self.fuel_source.fuel_used += inc_fuel_used

	def specific_impulse_at_alt(self, alt):
		''' calculates the specific impulse at the given altitude '''
		patm = equ.percentOfAtmosphericPressure(alt)
		pctVac = 1 - patm
		return self.specImp_sl + (pctVac * (self.specImp_vac - self.specImp_sl))

	def events(self, time, time_inc):
		decimal_precision = 3
		if self.throt_avg > 0.0 and not self.reached_max:
			self.setThrottle(self.max_throt, time_inc)
			if self.throt_avg == self.max_throt:
				self.reached_max = True

class SolidRocketEngine(RocketEngine):
	engine_type = "Solid"
	def __init__(self, engine_data):
		RocketEngine.__init__(self, engine_data)
		self.power_down_start_time = None
		self.power_down_fuel_level = engine_data["power_down_fuel_level"]
		self.power_down_burn_rates = engine_data["power_down_burn_rates"]

	def set_assigned_thrust_per_engine(self, thrust):
		self.thrust_total = thrust * self.engine_count

	def burn_fuel(self, time_inc, alt):

		if self.throt_avg > 0.0:
			self.burn_rate = self.get_thrust_total()  / self.specific_impulse_at_alt(alt)
			self.fuel_source.fuel_used += self.get_burn_rate() * time_inc * self.get_throt()
		# print "solid rocket {} at alt {}".format(self.get_burn_rate(), alt)
	def adjust_thrust_to_burn_at_rate_per_engine(self, rate, alt):
		thrust = rate * self.specific_impulse_at_alt(alt)
		message = "EVENT: Set burn rate of {} (thrust = {})".format(rate, thrust)
		self.messages.append(message)
		self.set_assigned_thrust_per_engine(thrust)

	def change_thrust(self, rate, time_inc):
		currentThrust = self.get_thrust_per_engine()
		newThrust = currentThrust + rate * time_inc
		self.set_assigned_thrust_per_engine(newThrust)
		message = None
		if rate < 0:
			message = "\nEVENT: Reduced thrust of {} to {}".format(self.name, newThrust)
		if rate > 0:
			message = "\nEVENT: Increased thrust of {} to {}".format(self.name, newThrust)
		if message:
			self.messages.append(message)

	def thrustAtAlt(self, alt):
		return self.get_thrust_total() * self.get_throt()

	def events(self, time, time_inc):
		super(SolidRocketEngine, self).events(time, time_inc)
		if self.event:
			if func.between_floats(time, self.event["start_time"], self.event["end_time"]):
				if self.event["name"] == "Change Thrust" and time < self.event["end_time"]:
					self.change_thrust(self.event["rate"], time_inc)

	def power_down_by_burn_rates(self, time, alt, stage):
		time_since_start = time - self.power_down_start_time
		if func.almost_equal(time_since_start, round(time_since_start)):
			try:
				self.burn_rate_per_engine = self.power_down_burn_rates.pop(0)
			except IndexError:
				stage.jettison()
		if stage.attached:
			self.adjust_thrust_to_burn_at_rate_per_engine(self.burn_rate_per_engine, alt)

class LiquidRocketEngine(RocketEngine):
	''' Liquid Rocket Engine class '''
	power_down_in_progress = False
	engine_type = "Liquid"
	def events(self, time, time_inc):
		super(LiquidRocketEngine, self).events(time, time_inc)
		if self.ignition_time and func.almost_equal(time, self.ignition_time, 0.1):
			self.setThrottle(self.min_throt, time_inc)

		if self.power_down_in_progress or self.power_down_start_time and func.almost_equal(time, self.power_down_start_time, 0.1):
			self.setThrottle(0, time_inc)
			self.power_down_in_progress = True
			if self.throt_avg == 0:
				self.power_down_in_progress = False


import pandas as pd
import requests
from statsmodels.tsa.stattools import adfuller
import scipy
import matplotlib.pyplot as plt
import numpy as np

sch, tmkt = pd.read_csv('CSUSHPISA.csv'), pd.read_csv('WILL5000INDFC.csv')
rt, gld = pd.read_csv('WILLREITIND.csv'), pd.read_csv('GOLDPMGBD228NLBM.csv')

def assignDates(df, colIndex):
    '''assign date type'''
    x = pd.to_datetime(df.iloc[:,colIndex], yearfirst = True)
    df.iloc[:,colIndex] = pd.DataFrame(x)
    return df

rt, sch = assignDates(rt, 0), assignDates(sch, 0)
gld, tmkt = assignDates(gld, 0), assignDates(tmkt, 0)

def checkIndexing(df):
    holder, ogDF = list(df.iloc[:,0]), df
    time2 = holder[1:]
    lst = [t2 - t1 for t1, t2 in zip(holder, time2)]

    delta = pd.DataFrame(df.iloc[1:,:])
    delta.iloc[:, 0] = lst
    lst = [int(str(i)[:2]) for i in lst]
    d = int(str(delta['DATE'].std())[0])
    irregular = []
    delta.index = [i for i in range(len(delta))]

    for i, j in enumerate(lst):
        if not j - d <= 0 <= j + d:
            irregular.append(i)

    for i, j in zip(enumerate(df.iloc[:,0]), irregular):
        if i[0] == j:
            df = df.drop(labels = j)

    df.index = [i for i in range(len(df))]

    if delta['DATE'].std() / delta['DATE'].mean() > 1:
        return df
    else:
        return ogDF

rt, gld = checkIndexing(rt), checkIndexing(gld)
tmkt, sch = checkIndexing(tmkt), checkIndexing(sch)

def checkHiddenNulls(df, colIndex):
    '''check whether columns have any non-null meaningless values'''
    cleaning = df.iloc[:, colIndex]
    for idx, value in zip(range(len(cleaning)), cleaning):
        try:
            if float(value) / float(value) != 1: #filter out n/a values
                df = df.drop(index = idx)
        except:
            df = df.drop(index = idx)
            #same statement as above because above one won't be executed
            #if it raises error

    df.iloc[:, colIndex] = df.iloc[:, colIndex].astype(float)
    return df

sch, tmkt = checkHiddenNulls(sch, 1), checkHiddenNulls(tmkt, 1)
reit, gld = checkHiddenNulls(rt, 1), checkHiddenNulls(gld, 1)

def getHTML(url):
    '''extract html via url'''
    connection = requests.get(url)
    if connection.ok:
        txt = connection.text.lower()
        text = txt[txt.find('<head>'): txt.find('</head>')]
        text = text.split(' ')
    return text

gldText = getHTML('https://fred.stlouisfed.org/series/GOLDPMGBD228NLBM')
reitText = getHTML('https://fred.stlouisfed.org/series/WILLREITIND')
tmktText = getHTML('https://fred.stlouisfed.org/series/WILL5000INDFC')
schillerText = getHTML('https://fred.stlouisfed.org/series/CSUSHPISA')

def seasonallyAdjust(df):
    '''create boolean seasonal indicator variables'''
    df['Spring'], df['Summer'] = False, False
    df['Fall'], df['Winter'] = False, False
    spring, summer = list(df['Spring']), list(df['Summer'])
    fall, winter = list(df['Fall']), list(df['Winter'])

    count = 0
    for date in df.iloc[:,0]:
        if date.month == 1 or date.month == 2 or date.month == 3:
            winter[count] = True
            count += 1
        elif date.month == 4 or date.month == 5 or date.month == 6:
            spring[count] = True
            count += 1
        elif date.month == 7 or date.month == 8 or date.month == 9:
            summer[count] = True
            count += 1
        elif date.month == 10 or date.month == 11 or date.month == 12:
            fall[count] = True
            count += 1

    df['Fall'], df['Winter'] = fall, winter
    df['Summer'], df['Spring'] = summer, spring
    return df

reit, gld = seasonallyAdjust(reit), seasonallyAdjust(gld)
schiller, tmkt = seasonallyAdjust(tmkt), seasonallyAdjust(sch)

def firstDifference(df, colIndex):
    '''insure against autocorrelation by first-differencing the data'''
    holder = list(df.iloc[:, colIndex])
    time2 = holder[1:]
    lst = [t2 - t1 for t1, t2 in zip(holder, time2)]

    delta = pd.DataFrame(df.loc[1:,:]) #was raising error w/o pd.DF wrapper
    delta.iloc[:, colIndex] = lst
    return delta

reit, gld = firstDifference(reit, 1), firstDifference(gld, 1)
tmkt, sch = firstDifference(tmkt, 1), firstDifference(schiller, 1)

def unitRootTest(df, colIndex):
    '''Run Dickey-Fuller test on column to check for unit root'''
    x = df.iloc[:, colIndex]
    dfuller = adfuller(x)
    results = {'ADF Statistic': dfuller[0],
            'p-value': dfuller[1], 'Critical Values': dfuller[4]}
    if float(dfuller[1]) < .05:
        results['Reject Null'] = True #no unit root
    else:
        results['Reject Null'] = False #yes unit root
    return results

reitRoot, gldRoot = unitRootTest(reit, 1), unitRootTest(gld, 1)
sRoot, tmktRoot = unitRootTest(schiller, 1), unitRootTest(tmkt, 1)
#if unit root present, too much risk to create linear model

def kurtosisMaxObservation(df, colIndex):
    '''return the percentage of kurtosis due to one observation'''
    data = df.iloc[:, colIndex]
    mean = data.mean()
    num, den = [], []

    for i, j in enumerate(data):
        distance = j - mean
        num.append(distance ** 4)
        den.append(distance ** 2)
    for a, b in enumerate(num):
        if b == max(num):
            location = a
    num, den = np.array(num), np.array(den)
    numAv, denAv = num.mean(), (den.mean()) ** 2
    kurtosis = (numAv / denAv) - 3
    if kurtosis == scipy.stats.kurtosis(df.iloc[:, colIndex]):
        proportion = num.max() / sum(num)
        return proportion * 100, location
    else:
        raise Exception('The kurtosis is incorrect')

sA, rA = kurtosisMaxObservation(sch, 1), kurtosisMaxObservation(reit, 1)
gA, tA = kurtosisMaxObservation(gld, 1), kurtosisMaxObservation(tmkt, 1)

def plotKurtosisObs(df, iloc, text, idx, kurtosis, condition):
    '''visualize vectors with max single-obs. kurtosis'''
    text = str(text) #extract title from html
    t = text[text.find('<title>'):text.find('</title>')].strip("")
    t, var = t.split(','), str()
    for i in t:
        var += i
    t = var[7:]
    figure = plt.figure()
    ax = figure.add_subplot(111)
    ax.plot(df.iloc[:, iloc], 'steelblue', 3)
    ax.annotate('Kurtosis: ' + str(round(kurtosis, 3)) + '%',
                xy = (idx, df.iloc[idx,iloc]))
    plt.ylabel('Delta')
    plt.xlabel('Time 0: ' + str(df.iloc[0, 0])[:-9] + '\n'
               'Time n: ' + str(df.iloc[-1, 0])[:-9] + '\n'
               'Unit Root: ' + str(not condition))
    plt.ylim(top = 1.5 * max(df.iloc[:,iloc]))
    plt.title(t)
    plt.show()

plotKurtosisObs(sch, 1, schillerText, sA[1], sA[0], sRoot['Reject Null'])
plotKurtosisObs(reit, 1, reitText, rA[1], rA[0], reitRoot['Reject Null'])
plotKurtosisObs(gld, 1, gldText, gA[1], gA[0], gldRoot['Reject Null'])
plotKurtosisObs(tmkt, 1, tmktText, tA[1], tA[0], tmktRoot['Reject Null'])


#task1, 2

'''Попросите пользователя ввести год, а затем используйте модуль datetime, чтобы проверить,
является ли этот год високосным, и выведите результат.

Попросите пользователя ввести две даты (начальную и конечную), а затем используйте модуль datetime
для подсчета количества рабочих дней между этими датами, исключая выходные дни.'''

#task1

# сделал через calendar так как для datetime нет метода isleap()

import datetime

import calendar

year = int(input("Enter year: "))

is_leap = calendar.isleap(year)

if is_leap:
    print(str(year) + " is leap year")
else:
    print(str(year) + " is not leap year")

#task2

def get_days(start_date, end_date):

    start_date = (datetime.datetime.strptime(start_date, "%Y-%m-%d")).date()
    end_date = (datetime.datetime.strptime(end_date, "%Y-%m-%d")).date()

    all_days = ((end_date - start_date).days + 1)
    print("Общее количество дней в заданном периоде: " + str(all_days))

    days_in_period = (start_date + datetime.timedelta(x) for x in range((end_date - start_date).days + 1))
    work_days = sum(1 for day in days_in_period if day.weekday() < 5)

    print("Количество рабочих дней в заданном периоде: " + str(work_days))

get_days(input('Введите начальную дату в формате "XXXX-XX-XX" (год-месяц-день): '),
         input('Введите конечную дату в формате "XXXX-XX-XX" (год-месяц-день): '))


import findspark
findspark.init()

import re
from pyspark import SparkConf, SparkContext
import collections

''' Set local context '''
conf = SparkConf().setMaster("local").setAppName("WordCount")
sc = SparkContext(conf = conf)

def normalize_words(line):
    return re.compile(r'\W+', re.UNICODE).split(line.lower())

''' Read in the file and get relevant rdd '''
lines = sc.textFile("Book.txt")
rdd = lines.flatMap(normalize_words)

'''
word_counts = rdd.countByValue()
for w, c in word_counts.items():
    clean_word = w.encode('ascii', 'ignore')
    if clean_word:
        print(clean_word, c)
'''

word_counts = rdd.map(lambda x: (x, 1)).reduceByKey(lambda x, y: x + y).collect()
for w, c in sorted(word_counts, key=lambda x: (x[1], x[0])):
    clean_word = w.encode('ascii', 'ignore')
    if clean_word:
        print(clean_word, c)


import discord
from discord.ext import commands

import database.db_access as dba
import game_management.output as output
from environment import PREFIX, TOKEN
from game_management.game import find_game
from game_management.tools import Group
# setup of logging and env-vars
# logging must be initialized before environment, to enable logging in environment
from log_setup import logger

"""
This bot is based on a template by nonchris
https://github.com/nonchris/discord-bot
The bot is now maintained by kesslermaximilian and nonchris on
https://github.com/kesslermaximilian/JustOneBot
"""

intents = discord.Intents.all()
bot = commands.Bot(command_prefix=PREFIX, intents=intents)

# login message
@bot.event
async def on_ready():
    print(f'{bot.user.name} has connected')

    logger.info(f"Bot has connected, active on {len(bot.guilds)} guilds")

    print(f'Bot is connected to the following guilds:')
    print()
    member_count = 0
    for g in bot.guilds:
        print(f"{g.name} - {g.id} - Members: {g.member_count}")
        member_count += g.member_count
    print()
    await bot.change_presence(
        activity=discord.Activity(type=discord.ActivityType.watching, name=f"{PREFIX}help"))

    # Deleting all open resources from previous runs
    role_entries = dba.get_resources(resource_type="role")  # roles
    if role_entries:
        for entry in role_entries:
            for g in bot.guilds:
                if g.id == entry.guild_id:
                    try:
                        await g.get_role(entry.value).delete()
                        break  # Break the iteration over the guilds
                    except:
                        print('Role not found on this server')
            dba.del_resource(g.id, value=entry.value, resource_type="role")  # Delete role from database now

    text_channel_entries = dba.get_resources(resource_type="text_channel")  # Text Channels
    if text_channel_entries:
        for entry in text_channel_entries:
            for g in bot.guilds:
                if g.id == entry.guild_id:
                    try:
                        await g.get_channel(entry.value).delete()
                        break  # Break the iteration over the guilds
                    except:
                        print('TextChannel not found on this server')
            dba.del_resource(g.id, value=entry.value, resource_type="text_channel")  # Delete role from database now

@bot.event
async def on_message(message: discord.Message):
    while_in_game_commands = [f'{PREFIX}abort']
    game = find_game(message.channel)
    if game is None or game.phase.value >= 130:
        await bot.process_commands(message)
        return
    for always_command in while_in_game_commands:
        if message.content.startswith(always_command):
            await bot.process_commands(message)
            return
    if message.content.startswith(PREFIX):
        await game.message_sender.send_message(embed=output.game_running_warning(), reaction=False, group=Group.warn)

# LOADING Extensions
bot.remove_command('help')  # unload default help message
initial_extensions = [
    'cogs.misc',
    'cogs.help',
    'cogs.just_one',
    'cogs.settings',
    'cogs.manage_moderators'
]

if __name__ == '__main__':
    for extension in initial_extensions:
        bot.load_extension(extension)

    bot.run(TOKEN)


#charcoal, outfitters, gulahmad, chenone, stylo, khaadi, bareeze

url = 'https://www.khaadi.com/pk'
image_folder = './images/'

import requests
from bs4 import BeautifulSoup as soup
import time
import os

image_name = 1
for i in range(1, 12):
    print("retrieving page " + str(i))
    url = 'https://www.khaadi.com/pk/woman.html?p=' + str(i) + '&product_list_limit=45'

    r = requests.get(url, headers={'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'}, timeout=15)
    content = r.content
    r.close()
    page = soup(content, "html.parser")

    product_images = page.find_all("img", class_="product-image-photo")
    print("total images: " + str(len(product_images)))
    for p in product_images:
        print('retrieving image')
        src = p.get('src')
        try:
            imagefile = open(image_folder + str(image_name) + ".jpg", "wb")
            print('saving ' + imagefile.name)
            imagefile.write(requests.get(src, headers={'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'}, timeout=15).content)
            imagefile.close()
            print("[done]")
        except:
            print('an error occured while retrieving file')
        image_name += 1
        time.sleep(1)
    time.sleep(1)

print("Crawling completed")


from datetime import date
from typing import Optional
from pydantic import BaseModel
from datetime import datetime
from infrastructure.models.patient import gender_enum

class Patient(BaseModel):
    id: int
    patient_id: Optional[str] = None
    name: str
    gender: gender_enum
    date_of_birth: Optional[date] = None
    age: str
    address: str
    contact_details: Optional[str] = None
    created_time: Optional[datetime] = None
    updated_time: Optional[datetime] = None
    created_user_id: Optional[int] = None
    updated_user_id: Optional[int] = None
    class Config():
        orm_mode = True


import numpy as np
from lib.task import Task, Task03
from lib.solver.base import BaseSolver
from lib.util.bert import Bert
from lib.util.sentence_encoder import SentenceEncoder

from typing import Optional, Any

class Task03Solver(BaseSolver):
    def __init__(self, bert: Optional[Bert] = None, sentence_encoder: Optional[SentenceEncoder] = None):
        if bert is None:
            bert = Bert()
        self.bert: Bert = bert

        if sentence_encoder is None:
            sentence_encoder = SentenceEncoder()
        self.sentence_encoder: SentenceEncoder = sentence_encoder

    def get_task_type(self) -> str:
        return Task.TYPE_03

    def solve(self, task: Task03) -> Any:
        text = task.lines[task.line_num]

        sims = []
        for i, choice in enumerate(task.choices):
            sim = self.sentence_encoder.get_similarity(choice['text'], text)[0]
            sims.append(sim)

        max_idx = int(np.argmax(sims))
        return [str(max_idx + 1)]


class Solution:
    def longestSubarray(self, nums: List[int], limit: int) -> int:
        ## sliding window
        # the max_abs = max_val - min_val,
        # if max_abs of subarray <= limit, then any two elements of this subarray <= limit
        max_len = 0
        # the start index
        s=0
        max_q = []
        min_q = []

        for i in range(len(nums)):
            while max_q and (nums[max_q[-1]] < nums[i]):
                max_q.pop()
            max_q.append(i)

            while min_q and (nums[min_q[-1]] > nums[i]):
                min_q.pop()
            min_q.append(i)

            max_val = nums[max_q[0]]
            min_val = nums[min_q[0]]

            if (max_val - min_val) <= limit:
                max_len = max(max_len, i-s+1)
            else:
                if s == max_q[0]:
                    max_q.pop(0)
                if s == min_q[0]:
                    min_q.pop(0)
                s += 1

        return max_len


import sys, glob, operator
from ColumnDataFile import ColumnDataFile as CDF
import matplotlib.pyplot as plt
from pylab import *
import PlotUtility
import numpy
import Smoothing

def fixPlot(axs):
	axs.set_xlabel(r'r ($\AA$)', fontsize='36')
	xlim(0.5,5.0)
	ylim(0.0,2.0)
	xticks([1,2,3,4,5],fontsize=36)
	yticks([0.5,1,1.5], fontsize=36)

files = ['malonic-rdf-alcO-cp2k.dat', 'malonic-rdf-carbO-cp2k.dat', 'MalonicRDF-rdf-alcO-oldparms.dat', 'MalonicRDF-rdf-carbO-oldparms.dat', 'malonic-rdf-alcO-amber.dat', 'malonic-rdf-carbO-amber.dat', 'MalonicRDF-rdf-alcO-newparms.dat', 'MalonicRDF-rdf-carbO-newparms.dat', 'MalonicRDF-rdf-alcO-1.dat', 'MalonicRDF-rdf-carbO-1.dat']
cdfs = [CDF(f) for f in files]

fig = plt.figure(num=1, facecolor='w', edgecolor='w', frameon=True)
fig.subplots_adjust(left=0.06, right=0.97)

axs1 = fig.add_subplot(1,2,1)
fixPlot(axs1)
axs2 = fig.add_subplot(1,2,2)
fixPlot(axs2)

for c in range(len(cdfs)):
	x_data = numpy.array(cdfs[c][0])
	y_data = numpy.array(cdfs[c][1])

	if c == 1:
		y_data = y_data * 0.8

	axs = axs1
	if (c+1)%2 == 0:
		axs = axs2

	name = files[c].split('.')[-2].split('-')[-1]
	sys = files[c].split('-')[2]
	axs.plot (x_data, y_data, linewidth=3.0, label=name+sys)

	minorLocator = MultipleLocator(0.25)
	axs.yaxis.set_minor_locator(minorLocator)

	#if c < 2:
	#else:
		#xticks([1,2,3,4,5],fontsize=42)
		#yticks([0.5,1,1.5], fontsize=42)
	#if c > 1:
	#axs.set_ylabel(r'g(r)', fontsize='54')

PlotUtility.ShowLegend(axs1)
PlotUtility.ShowLegend(axs2)
plt.show()


import os
import unittest
import warnings

import torch
import yaml

from warp_drive.training.example_training_script_pycuda import setup_trainer_and_train
from warp_drive.training.utils.device_child_process.child_process_base import ProcessWrapper
from warp_drive.training.utils.distributed_train.distributed_trainer_pycuda import (
    perform_distributed_training,
)
from warp_drive.utils.common import get_project_root

_ROOT_DIR = get_project_root()

def launch_process(func, kwargs):
    """
    Run a Python function on a separate process.
    """
    p = ProcessWrapper(target=func, kwargs=kwargs)
    p.start()
    p.join()
    if p.exception:
        raise p.exception

class MyTestCase(unittest.TestCase):
    """
    Test the end-to-end training loop
    """

    num_gpus = torch.cuda.device_count()

    def get_config(self, env_name):
        config_path = os.path.join(
            _ROOT_DIR, "warp_drive", "training", "run_configs", f"{env_name}.yaml"
        )
        if not os.path.exists(config_path):
            raise ValueError(
                "Invalid environment specified! The environment name should "
                "match the name of the yaml file in training/run_configs/."
            )

        with open(config_path, "r", encoding="utf8") as fp:
            run_config = yaml.safe_load(fp)
        return run_config

    def test_tag_gridworld_training(self):
        run_config = self.get_config("tag_gridworld")
        try:
            launch_process(
                setup_trainer_and_train,
                kwargs={"run_configuration": run_config, "verbose": False},
            )
        except AssertionError:
            self.fail("TagGridWorld environment training failed")

    def test_tag_continuous_training(self):
        run_config = self.get_config("tag_continuous")
        try:
            run_config["env"]["num_taggers"] = 2
            run_config["env"]["num_runners"] = 10
            launch_process(
                setup_trainer_and_train,
                kwargs={"run_configuration": run_config, "verbose": False},
            )
        except AssertionError:
            self.fail("TagContinuous environment training failed")

    def test_tag_gridworld_training_with_multiple_devices(self):
        if self.num_gpus <= 1:
            warnings.warn(
                "Only single GPU is detected, we skip trainer test for multiple devices"
            )
            return

        run_config = self.get_config("tag_gridworld")
        run_config["trainer"]["num_gpus"] = self.num_gpus
        try:
            perform_distributed_training(setup_trainer_and_train, run_config)
        except AssertionError:
            self.fail(
                f"TagGridWorld environment training failed for {self.num_gpus} GPUs"
            )


#!flask/bin/python

# Steps to deploy:
# az login
# az webapp deployment source config-local-git --name parkwatch-backend --resource-group ParkWatch
# OR
# az webapp create -g ParkWatch -p ASP-ParkWatch-9dbf -n parkwatch-backend --runtime "python|3.6" --deployment-local-git

# parkwatch_ranger, (same password as elsewhere)

# Copy url under deployment center > credentials
# git remote add azure <url>
# git push azure <current branch>:master

# https://docs.microsoft.com/en-us/azure/app-service/containers/how-to-configure-python

import jsonpickle
import logging
import re
import time
import atexit

from apscheduler.schedulers.background import BackgroundScheduler
from flask import Flask, jsonify, render_template, make_response, request, render_template, abort, json
from flask_cors import CORS
from controllers.report import Report, ReportHandler
from controllers.weather import Rule, WeatherHandler
from controllers.parking import ParkingLot, ParkingHandler
from controllers.user import UserHandler
from controllers.fire import Fire, WildFireHandler
from controllers.park import Park, ParkHandler
from controllers.email import EmailHandler

documentation_filepath = "parkranger_docs_4-7.html"

app = Flask(__name__, template_folder="templates", static_url_path='/static')
logging.basicConfig(level=logging.DEBUG)
cors = CORS(app)

report_handler = ReportHandler()
weather_handler = WeatherHandler()
parking_handler = ParkingHandler()
user_handler = UserHandler()
fire_handler = WildFireHandler()
park_handler = ParkHandler()
email_handler = EmailHandler()

# Email scheduler
scheduler = BackgroundScheduler()
scheduler.add_job(func=email_handler.send_all_emails, trigger="interval", hours=12)
scheduler.start()

# Shut down the scheduler when exiting the app
atexit.register(lambda: scheduler.shutdown())

@app.route('/pw/api/docs')
def docs():
    return app.send_static_file(documentation_filepath)

################################################################
#                            Parks                             #
################################################################

#region Parks

@app.route('/pw/api/parks', methods=['GET', 'POST', 'DELETE'])
def get_parks_base():
    log_str = "{}\n{}\n{}".format(str(request.method), str(request.args), str(request.json))
    print(log_str)

    park_id = request.args.get('park')
    token = request.args.get('token')

    if request.method == 'GET':
        if park_id:
            return get_park(int(park_id))
        return get_parks()

    elif request.method == 'POST':
        if token:
            if user_handler.check_user(token, 99): # TODO(IAN) Using park 99 as super user.
                if park_id:
                    return update_park(park_id, request)
                else:
                    return create_park(request)
            else:
                abort(401, "Invalid token. Parks can only be created by users from park 99.")
        else:
            abort(400, "Missing url parameters.")

    elif request.method == 'DELETE':
        if token:
            if user_handler.check_user(token, 99):
                if park_id:
                    return delete_park(park_id)
                else:
                    abort(400, "Missing park_id and report_id.")
            else:
                abort(401, "Invalid token.")
        else:
            abort(400, "Missing user token.")
    else:
        abort(400, "We only accept GET/POST/DELETE")

def get_parks():
    parks_list_json = park_handler.get_parks_json()
    return parks_list_json

def get_park(park_id):
    park_json = park_handler.get_park_json(park_id)
    return park_json

def create_park(request):
    """

    """
    check_json_park(request)

    park_json = park_handler.create_park(request.json['park_name'],
                     request.json['park_lat'],
                     request.json['park_lon'],
                     request.json['park_org'],
                     request.json['park_cover_image'],
                     request.json['park_logo'])

    return park_json

def check_json_park(request):
    if not request.json:
        abort(400, "Error in create report request, missing request body")

    if 'park_name' not in request.json:
        abort(400, "Missing park name in request body")

    elif len(request.json['park_name']) <= 0:
        abort(400, "Park name must not be an empty string")

    if 'park_lat' not in request.json:
        abort(400, "Missing park lat in request body")

    if 'park_lon' not in request.json:
        abort(400, "Missing park lon in request body")

    if 'park_org' not in request.json:
        abort(400, "Missing park org in request body")

    elif len(request.json['park_org']) <= 0:
        abort(400, "Park org must not be an empty string")

    if 'park_cover_image' not in request.json:
        abort(400, "Missing park cover image in request body")

    elif len(request.json['park_cover_image']) <= 0:
        abort(400, "Park cover image must not be an empty string")

    if 'park_logo' not in request.json:
        abort(400, "Missing park logo in request body")

    elif len(request.json['park_logo']) <= 0:
        abort(400, "Park logo must not be an empty string")

def delete_park(park_id):
    result = park_handler.delete_park(park_id)
    return app.response_class(json.dumps(result), content_type='application/json')

def update_park(park_id, request):
    check_json_park(request)

    park_json = park_handler.update_park(
                        request.json['park_name'],
                        park_id,
                        request.json['park_lat'],
                        request.json['park_lon'],
                        request.json['park_org'],
                        request.json['park_cover_image'],
                        request.json['park_logo'])

    print(park_json, flush=True)
    return park_json

#endregion

################################################################
#                            LOGIN                             #
################################################################

#region Login
@app.route('/pw/api/login', methods=['POST'])
def login_base():
    """
    """
    log_str = "{}\n{}\n{}".format(str(request.method), str(request.args), str(request.json))
    print(log_str)
    if request.method == 'POST':
        login_code = login(request)
        if login_code == -1:
            abort(401, "Invalid username or password")
        else:
            return login_code
    else:
        abort(400, "Login URI only accepts POST requests.")

def login(request):
    if 'email' not in request.json:
        abort(400, "Missing email in request body")
    if 'password' not in request.json:
        abort(400, "Missing password in request body")
    if 'park_id' not in request.json:
        abort(400, "Missing park_id in request body")

    login_json = user_handler.login(request.json['email'],
                                    request.json['password'],
                                    request.json['park_id'])

    return login_json

@app.route('/pw/api/login/new', methods=['POST'])
def new_login_base():
    """
    """
    log_str = "{}\n{}\n{}".format(str(request.method), str(request.args), str(request.json))
    print(log_str)

    if request.method == 'POST':
        return create_user(request)
    else:
        abort(400, "Login URI only accepts POST requests.")

def check_user_body(request):
    regex = '^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$'

    if not re.search(regex, request.json['email']):
        abort(400, "Invalid email")
    if len(request.json['password']) < 8:
        abort(400, "Password must be at least 8 characters")
    if len(request.json['f_name']) == 0:
        abort(400, "First name cannot be empty")
    if len(request.json['l_name']) == 0:
        abort(400, "Last name cannot be empty")

def create_user(request):
    if 'email' not in request.json:
        abort(400, "Missing email in request body")
    if 'password' not in request.json:
        abort(400, "Missing password in request body")
    if 'park_id' not in request.json:
        abort(400, "Missing park_id in request body")
    if 'f_name' not in request.json:
        abort(400, "Missing f_name in request body")
    if 'l_name' not in request.json:
        abort(400, "Missing l_name in request body")

    check_user_body(request)

    new_user_json = user_handler.create_user(request.json['email'],
                                             request.json['password'],
                                             request.json['f_name'],
                                             request.json['l_name'],
                                             request.json['park_id'])
    # Just making sure that we return the correct error codes.
    if new_user_json == -1:
        abort(401, "A user with this email already exists")
    else:
        return new_user_json
#endregion

#region Update Account
@app.route('/pw/api/password', methods=['POST'])
def change_password_base():
    """
    """
    uID = request.args.get('uID')
    token = request.args.get('token')
    print(request.__dict__)

    if request.method == 'POST':
        if uID and token:
            if user_handler.check_uID(uID, token):
                return change_password(request)
            else:
                abort(401, "Invalid token.")
        else:
            abort(401, "Missing uID or token")
    else:
        abort(400, "Password change URI only accepts POST requests.")

def change_password(request):
    if not request.json or not 'password' in request.json or not 'new_password' in request.json:
        abort(400, "Error in change password request, missing request body")

    new_password_json = user_handler.change_password(request.json['uID'],
        request.json['password'],
        request.json['new_password'])
    # Just making sure that we return the correct error codes.
    if new_password_json == -1:
        abort(401, "Invalid uID")
    else:
        print(new_password_json, flush=True)
        return new_password_json

@app.route('/pw/api/profile', methods=['POST'])
def update_user_base():
    """
    """
    uID = request.args.get('uID')
    token = request.args.get('token')
    print(request.__dict__)

    if request.method == 'POST':
        if uID and token:
            if user_handler.check_uID(uID, token):
                return update_user(request)
            else:
                abort(401, "Invalid token")
        else:
            abort(401, "Missing uID or token")
    else:
        abort(400, "Account update URI only accepts POST requests.")

def update_user(request):
    if 'uID' not in request.json:
        abort(400, "Missing uID in request body")
    if 'email' not in request.json:
        abort(400, "Missing email in request body")
    if 'token' not in request.json:
        abort(400, "Missing token in request body")
    if 'park_id' not in request.json:
        abort(400, "Missing park_id in request body")
    if 'f_name' not in request.json:
        abort(400, "Missing f_name in request body")
    if 'l_name' not in request.json:
        abort(400, "Missing l_name in request body")

    updated_user_json = user_handler.update_user(request.json['uID'],
                                             request.json['email'],
                                             request.json['f_name'],
                                             request.json['l_name'],
                                             request.json['park_id'],
                                             request.json['token'])
    # Just making sure that we return the correct error codes.
    if updated_user_json == -1:
        abort(401, "Invalid uID")
    else:
        print(updated_user_json, flush=True)
        return updated_user_json
#endregion

#region Reports
@app.route('/pw/api/reports', methods=['GET', 'POST', 'DELETE'])
def get_report_base():
    """
    Base method that handles all requests ending in /reports.
    If the method is GET and only park id is provided then returns a list of all reports for that park.
    Otherwise, if park id and report id are provided, returns that specific report.

    If the method is POST then creates a new report object for that park.

    Args:
        None
    Returns:
        GET - A single json report
        GET - A list of json reports
        POST - The new report
    """
    park_id = request.args.get('park')
    report_id = request.args.get('id')
    min_severity = request.args.get('minSeverity')
    max_severity = request.args.get('maxSeverity')
    severity = request.args.get('severity')
    approved_status = request.args.get('approvedStatus')
    closure = request.args.get('closure')
    loc_lon = request.args.get('locLon')
    loc_lat = request.args.get('locLat')
    loc_range = request.args.get('locRange')
    min_date = request.args.get('minDate')
    max_date = request.args.get('maxDate')

    token = request.args.get('token')
    log_str = "{}\n{}\n{}\n".format(str(request.method), str(request.args), '%.500s' % str(request.json))
    print(log_str)

    if request.method == 'GET':
        if park_id and not report_id: # If only the park was provided then get list of all reports
            # return get_reports(int(park_id))
            return get_reports_filter_json(int(park_id),
                                      min_severity,
                                      max_severity,
                                      severity,
                                      approved_status,
                                      closure,
                                      loc_lon,
                                      loc_lat,
                                      loc_range,
                                      min_date,
                                      max_date
                                    )

        elif park_id and report_id: # If park and report id were provided then return specified report
            return get_report(int(park_id), int(report_id))

    elif request.method == 'POST':
        if park_id and not report_id and not token:
            return create_report(request)
        elif token:
            if user_handler.check_user(token, park_id):
                if park_id and report_id:
                    return update_report(park_id, report_id, request)
            else:
                abort(401, "Invalid token.")
        else:
            abort(400, "Missing url parameters.")

    elif request.method == 'DELETE':
        if token:
            if user_handler.check_user(token, park_id):
                if park_id and report_id:
                    return delete_report(park_id, report_id)
                else:
                    abort(400, "Missing park_id and report_id.")
            else:
                abort(401, "Invalid token.")
        else:
            abort(400, "Missing user token.")
    else:
        abort(400, "We only accept GET/POST/DELETE")

def get_reports(park_id):
    """
    Helper function that gets all reports associated with the park

    Args:
        park_id: The id of the park
    Returns:
        A list of json report objects
    """
    reports_list_json = report_handler.get_reports_list_json(park_id)
    return reports_list_json

def get_reports_filter_json(park_id, minSeverity = None, maxSeverity = None, specificSeverity = None, approvedStatus = None, closure = None, locLon = None, locLat = None, locRange = None, minDate = None, maxDate = None):
    reports_list_json = report_handler.get_reports_filter_json(park_id, minSeverity, maxSeverity, specificSeverity, approvedStatus, closure, locLon, locLat, locRange, minDate, maxDate)
    return reports_list_json

def get_report(park_id, report_id):
    """
    Helper function that gets a specfic report

    Args:
        park_id: The id of the park
        reprot_id: The id of the report
    Returns:
        A single json report object
    """
    report_json = report_handler.get_report_json(park_id, report_id)
    return report_json

def check_report_request(request):
    if not request.json:
        abort(400, "Missing request body")
    if 'loc_name' not in request.json:
        abort(400, "Missing loc name in request body")
    if 'loc_lat' not in request.json:
        abort(400, "Missing loc lat in request body")
    if 'loc_long' not in request.json:
        abort(400, "Missing loc long in request body")
    if 'description' not in request.json:
        abort(400, "Missing description in request body")
    if 'severity' not in request.json:
        abort(400, "Missing severity in request body")
    if 'closure' not in request.json:
        abort(400, "Missing closure in request body")
    if 'photo' not in request.json:
        abort(400, "Missing photo in request body")

def create_report(request):
    """
    Calls report handler to create a new report object, puts it into the db, and returns it

    Args:
        request: The request object
    Returns:
        The newly created json report object
    """
    check_report_request(request)

    park_id = int(request.args.get('park'))

    report_json = report_handler.create_report(request.json['loc_name'],
                     park_id,
                     request.json['loc_lat'],
                     request.json['loc_long'],
                     request.json['description'],
                     request.json['severity'],
                     request.json['closure'],
                     0,
                     request.json['photo'])

    return report_json

def update_report(park_id, report_id, request):
    """
    Calls report handler to create a new report object, puts it into the db, and returns it

    Args:
        request: The request object
    Returns:
        The newly created json report object
    """
    check_report_request(request)

    if 'approved_status' not in request.json:
        abort(400, "Missing approved status in request body")

    report_json = report_handler.update_report(
                        park_id,
                        report_id,
                        request.json['loc_name'],
                        request.json['loc_lat'],
                        request.json['loc_long'],
                        request.json['description'],
                        request.json['severity'],
                        request.json['closure'],
                        request.json['approved_status'],
                        request.json['photo'])

    # print(report_json, flush=True)
    return report_json
#endregion

################################################################
#                           WEATHER                            #
################################################################

#region Weather
@app.route('/pw/api/weather', methods=['GET', 'POST', 'DELETE'])
def get_rules_base():
    """
    If the method is POST then creates a new report object for that park.

    Args:
        None
    Returns:
        GET - A single json report
        GET - A list of json reports
        POST - The new report
    """
    park_id = request.args.get('park')
    rule_id = request.args.get('id')
    refresh = request.args.get('refresh')
    token = request.args.get('token')

    condition = request.args.get('condition')
    interval_value = request.args.get('interval_value')
    interval_symbol = request.args.get('interval_symbol')
    activated = request.args.get('active')
    area_lat = request.args.get('center_lat')
    area_lon = request.args.get('center_long')
    area_range = request.args.get('area_range')

    log_str = "{}\n{}\n{}".format(str(request.method), str(request.args), str(request.json))
    print(log_str)

    if request.method == 'GET':
        if park_id and not rule_id:
            return get_rules_filter(park_id,
                                    condition,
                                    interval_value,
                                    interval_symbol,
                                    activated,
                                    area_lat,
                                    area_lon,
                                    area_range,
                                    refresh)
        elif park_id and rule_id:
            if refresh:
                refreshed = refresh_rules(park_id, None)
            return get_rule(park_id, rule_id)

    elif request.method == 'POST':
        if token:
            if user_handler.check_user(token, park_id):
                if park_id and rule_id:
                    return update_rule(park_id, rule_id, request)
                elif park_id:
                    return create_rule(request)
            else:
                abort(400, "Invalid token.")
        else:
            abort(400, "Missing user token.")

    elif request.method == 'DELETE':
        if token:
            if user_handler.check_user(token, park_id):
                if park_id and rule_id:
                    return delete_rule(park_id, rule_id)
                else:
                    abort(400, "Missing park_id and rule_id")
            else:
                abort(401, "Invalid token.")
        else:
            abort(400, "Missing user token.")
    else:
        abort(400, "We only accept GET/POST/DELETE")

def refresh_rules(park_id, active):
    weather_handler.refresh_rules(park_id)

    if active:
        return get_active_rules(park_id, active)
    else:
        return get_rules(park_id)

def get_rule(park_id, rule_id):
    fetched_rule = weather_handler.get_rule_json(park_id, rule_id)

    if not fetched_rule:
        abort(400, f"No rule with park_id={park_id} and rule_id={rule_id} was found.")

    return fetched_rule

def get_rules(park_id):
    """
    Helper function that gets all rules associated with the park

    Args:
        park_id: The id of the park
    Returns:
        A list of json rule objects
    """
    rules_list_json = weather_handler.get_rules_json(park_id)
    return rules_list_json

def get_rules_filter(park_id, condition, interval_value, interval_symbol, activated, areaLat, areaLon, areaRange, refresh):
    rules_list_json = weather_handler.get_rules_filter_json(park_id,
                                                       condition,
                                                       interval_value,
                                                       interval_symbol,
                                                       activated,
                                                       areaLat,
                                                       areaLon,
                                                       areaRange,
                                                       refresh)
    return rules_list_json

def check_weather_request(request):
    if not request.json:
        abort(400, "Missing request body")
    if 'condition_type' not in request.json:
        abort(400, "Missing condition_type in request body")
    if 'condition_interval_value' not in request.json:
        abort(400, "Missing condition_interval_value in request body")
    if 'name' not in request.json:
        abort(400, "Missing name in request body")
    if 'description' not in request.json:
        abort(400, "Missing description in request body")
    if 'path' not in request.json:
        abort(400, "Missing path in request body")

def create_rule(request):
    check_weather_request(request)

    park_id = int(request.args.get('park'))

    print(request)

    # Example post json

    #"{"condition_interval_symbol\":\">\",\"condition_interval_value\":0,
    # \"condition_type\":\"rain\",\"description\":\"Test description\",
    # \"name\":\"Test Name\", \"path\":[{\"lat\":36.86149,\"lng\":30.63743},{\"lat\":36.86341,\"lng\":30.72463}]}"

    report_json = weather_handler.add_rule(request.json['condition_type'],
                     request.json['condition_interval_value'],
                     request.json['condition_interval_symbol'],
                     request.json['description'],
                     request.json['name'],
                     park_id,
                     json.dumps(request.json['path']),
                     request.json['forecast']
                     )

    return report_json

def update_rule(park_id, rule_id, request):
    check_weather_request(request)

    # Example post json

    #"{"condition_interval_symbol\":\">\",\"condition_interval_value\":0,
    # \"condition_type\":\"rain\",\"description\":\"Test description\",
    # \"name\":\"Test Name\", \"path\":[{\"lat\":36.86149,\"lng\":30.63743},{\"lat\":36.86341,\"lng\":30.72463}]}"

    report_json = weather_handler.update_rule(
                     rule_id,
                     request.json['condition_type'],
                     request.json['condition_interval_value'],
                     request.json['condition_interval_symbol'],
                     request.json['description'],
                     request.json['name'],
                     park_id,
                     json.dumps(request.json['path']),
                     request.json['forecast']
                     )

    return report_json

def get_active_rules(park_id, active):
    """
    Helper function that gets all active rules associated with the park

    Args:
        park_id: The id of the park
    Returns:
        A list of json rule objects
    """
    report_json = weather_handler.get_active_rules_json(park_id, active)
    return report_json

def delete_rule(park_id, rule_id):
    result = weather_handler.delete_rule(park_id, rule_id)
    return app.response_class(json.dumps(result), content_type='application/json')

def delete_report(park_id, report_id):
    result = report_handler.delete_report(park_id, report_id)
    return app.response_class(json.dumps(result), content_type='application/json')
#endregion

################################################################
#                           PARKING                            #
################################################################

#region Parking
@app.route('/pw/api/parking', methods=['GET', 'POST', 'DELETE'])
def get_parking_base():
    """
    Base method that handles all requests ending in /parking.

    Args:
        None
    Returns:
        GET - A single json report
        GET - A list of json reports
        POST - The new report
    """
    park_id = request.args.get('park')
    lot_id = request.args.get('id')
    token = request.args.get('token')
    status = request.args.get('severity')
    log_str = "{}\n{}\n{}".format(str(request.method), str(request.args), str(request.json))
    print(log_str)

    if request.method == 'GET':
        if park_id and not lot_id: # If only the park was provided then get list of all reports
            return get_parking_lots(int(park_id), status)

        elif park_id and lot_id: # If park and report id were provided then return specified report
            return get_parking_lot(int(park_id), int(lot_id))

    elif request.method == 'POST':
        if token:
            if user_handler.check_user(token, park_id):
                if park_id and lot_id:
                    return update_parking_lot(park_id, lot_id, request)
                elif park_id:
                    return create_parking_lot(request)
            else:
                abort(401, "Invalid token.")
        else:
            abort(400, "Missing user token.")

    elif request.method == 'DELETE':
        if token:
            if user_handler.check_user(token, park_id):
                if park_id and lot_id:
                    return delete_parking_lot(park_id, lot_id)
                else:
                    abort(400, "Missing park_id and lot_id")
            else:
                abort(401, "Invalid token.")
        else:
            abort(400, "Missing user token.")
    else:
        abort(400)

def get_parking_lots(park_id, status):
    """
    Helper function that gets all parking lots associated with the park

    Args:
        park_id: The id of the park
    Returns:
        A list of json report objects
    """
    parking_lots_list_json = parking_handler.get_parking_lots_list_json(park_id, status)
    return parking_lots_list_json

def get_parking_lot(park_id, lot_id):
    """
    Helper function that gets a specfic parking lot

    Args:
        park_id: The id of the park
        reprot_id: The id of the report
    Returns:
        A single json report object
    """
    parking_lot_json = parking_handler.get_parking_lot_json(park_id, lot_id)
    return parking_lot_json

def check_parking_request(request):
    if not request.json:
        abort(400, "Missing request body")
    if 'lot_lat' not in request.json:
        abort(400, "Missing lot_lat in request body")
    if 'lot_long' not in request.json:
        abort(400, "Missing lot_long in request body")
    if 'lot_name' not in request.json:
        abort(400, "Missing lot_name in request body")
    if 'description' not in request.json:
        abort(400, "Missing description in request body")
    if 'severity' not in request.json:
        abort(400, "Missing severity in request body")

def create_parking_lot(request):
    check_parking_request(request)

    park_id = int(request.args.get('park'))

    lot_json = parking_handler.create_parking_lot(request.json['lot_name'],
                     park_id,
                     request.json['lot_lat'],
                     request.json['lot_long'],
                     request.json['description'],
                     request.json['severity']
                     )

    return lot_json

def update_parking_lot(park_id, lot_id, request):
    check_parking_request(request)

    lot_json = parking_handler.update_parking_lot(lot_id,
                     request.json['lot_name'],
                     park_id,
                     request.json['lot_lat'],
                     request.json['lot_long'],
                     request.json['description'],
                     request.json['severity']
                     )

    return lot_json

def delete_parking_lot(park_id, lot_id):
    result = parking_handler.delete_parking_lot(park_id, lot_id)
    return app.response_class(json.dumps(result), content_type='application/json')

#endregion

################################################################
#                           FIRE                               #
################################################################

#region fire
@app.route('/pw/api/wildfire', methods=['GET'])
def get_fire_base():
    """
    Gets wildfires in the US

    Args:
        None
    Returns:
        GET - A wildfire
    """
    loc_lon = request.args.get('locLon')
    loc_lat = request.args.get('locLat')
    loc_range = request.args.get('locRange')

    log_str = "{}\n{}\n{}".format(str(request.method), str(request.args), str(request.json))
    print(log_str)

    if request.method == 'GET':
        if loc_lat and loc_lon and loc_range:
            return fire_handler.get_and_parse_json_filter(float(loc_lon), float(loc_lat), float(loc_range))
        else:
            return fire_handler.get_and_parse_json_filter()
    else:
        abort(400, "We only accept GET")
#endregion

@app.route('/')
def home():
    return render_template('home.html', title='Home')

@app.errorhandler(404)
def not_found(e):
    return jsonify(error=str(e)), 404

@app.errorhandler(400)
def bad_request(e):
    return jsonify(error=str(e)), 400

@app.errorhandler(401)
def invalid_login(e):
    return jsonify(error=str(e)), 401

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


from netcontrol.api import *
from netcontrol.com import *
import threading
import json

class HealthMonitor (Component):
    name = 'health-monitor'

    def on_starting(self):
        self._cond_refresh = threading.Condition()
        self._cond_refreshed = threading.Condition()
        self._lock_refresh = threading.Lock()
        self._state = {}

    def refresh(self):
        with self._lock_refresh:
            with self._cond_refresh:
                self._cond_refresh.notify()
        with self._cond_refreshed:
            self._cond_refreshed.wait()

    def iterate(self):
        cfg = json.loads(self.app.gconfig.get('meters', 'config'))
        res = {}
        for cls in cfg:
            try:
                inst = self.app.grab_plugins(IMeter, lambda x:x.plugin_id==cls)[0]
                for var in cfg[cls]:
                    constr = cfg[cls][var]
                    i = inst.prepare(var)
                    res[i] = getattr(self, 'validate_%s'%i.type)(i.format_value(), constr)
            except:
                pass
        self._state = res

    def get(self):
        return self._state

    def run(self):
        while True:
            with self._lock_refresh:
                try:
                    self.iterate()
                except:
                    pass
            with self._cond_refreshed:
                self._cond_refreshed.notify()
            with self._cond_refresh:
                self._cond_refresh.wait(1000*60*5)

    def validate_binary(self, val, cfg):
        return 'good' if val['value'] == cfg['good_state'] else 'dang'

    def validate_decimal(self, val, cfg):
        if cfg['limit_susp'] < cfg['limit_dang']:
            if val['value'] < cfg['limit_susp']:
                return 'good'
            if val['value'] > cfg['limit_dang']:
                return 'dang'
        if cfg['limit_susp'] > cfg['limit_dang']:
            if val['value'] > cfg['limit_susp']:
                return 'good'
            if val['value'] < cfg['limit_dang']:
                return 'dang'
        return 'susp'

    validate_linear = validate_decimal

class MetersExporter (Plugin, URLHandler):

    @url('^/api/meters$')
    def export(self, req, sr):
        clss = self.app.grab_plugins(IMeter)
        r = {}

        for cls in clss:
            variants = cls.get_variants()
            for v in variants:
                inst = cls.prepare(v)
                r.setdefault(cls.category, {}).setdefault(cls.plugin_id, {})[v] = \
                    {
                        'name': inst.name,
                        'mtype': inst.type,
                        'text': inst.text,
                        'variant': v,
                        'transform': inst.transform,
                        'data': inst.format_value(),
                    }

        return json.dumps(r)

class HealthExporter (Plugin, URLHandler):

    @url('^/api/health$')
    def export(self, req, sr):
        mon = ComponentManager.get().find('health-monitor')
        data = json.loads(self.app.gconfig.get('meters', 'config', '{}'))
        nd = {}
        mon.refresh()
        for i in mon.get():
            nd.setdefault(i.category, {}).setdefault(i.plugin_id, {})[i.variant] = {
                'value': i.format_value(),
                'info': {
                    'text': i.text,
                    'name': i.name,
                    'type': i.type,
                    'variant': i.variant,
                    'transform': i.transform,
                },
                'contraints': data[i.plugin_id][i.variant],
                'state': mon.get()[i],
            }
        return json.dumps(nd)


# -*- coding: utf_8 -*-
#
# $Id: Buff_62004.py,v 1.2 2008-09-04 07:46:27 kebiao Exp $

"""
持续性效果
"""

import BigWorld
import csconst
import csdefine
from bwdebug import *
from SpellBase import *
from Buff_Normal import Buff_Normal

class Buff_99019( Buff_Normal ):
	"""
	example:物理攻击力提高40 * 怪物数量%,法术攻击力提高40 * 怪物数量%。
				<Param1>	40	</Param1>
				<Param2>	怪物className	</Param3>
				<Param3>	寻找范围	</Param4>
	"""
	def __init__( self ):
		"""
		构造函数。
		"""
		Buff_Normal.__init__( self )

	def init( self, dict ):
		"""
		读取技能配置
		@param dict: 配置数据
		@type  dict: python dict
		"""
		Buff_Normal.init( self, dict )
		self._p1 = int( dict[ "Param1" ] if len( dict[ "Param1" ] ) > 0 else 0 )  * 100
		self._p2 = str( dict[ "Param2" ] if len( dict[ "Param2" ] ) > 0 else 0 )
		self._p3 = int( dict[ "Param3" ] if len( dict[ "Param3" ] ) > 0 else 0 )

	def addEffect( self, receiver ):
		"""
		"""
		num = 0
		monsterList = receiver.entitiesInRangeExt( self._p3, "Monster", receiver.position )
		for e in monsterList:
			if e.className == self._p2:
				num += 1

		receiver.damage_min_percent += self._p1 * ( num - receiver.queryTemp( "99019Num", 0 ) )
		receiver.damage_max_percent += self._p1 * ( num - receiver.queryTemp( "99019Num", 0 ) )
		receiver.magic_damage_percent += self._p1 * ( num - receiver.queryTemp( "99019Num", 0 ) )
		receiver.calcDamageMin()
		receiver.calcDamageMax()
		receiver.calcMagicDamage()
		receiver.setTemp( "99019Num", num )		# 记录目前怪物的数量

	def doBegin( self, receiver, buffData ):
		"""
		Virtual method; call only by real entity.
		效果开始的处理。

		@param receiver: 效果要影响的实体
		@type  receiver: BigWorld.Entity
		@param buffData: BUFF
		@type  buffData: BUFF
		@return: None
		"""
		Buff_Normal.doBegin( self, receiver, buffData )
		self.addEffect( receiver )

	def doReload( self, receiver, buffData ):
		"""
		Virtual method; call only by real entity.
		效果重新加载的处理。

		@param receiver: 效果要影响的实体
		@type  receiver: BigWorld.Entity
		@param buffData: BUFF
		@type  buffData: BUFF
		@return: None
		"""
		Buff_Normal.doReload( self, receiver, buffData )
		self.addEffect( receiver )

	def doEnd( self, receiver, buffData ):
		"""
		Virtual method; call only by real entity.
		效果结束的处理。

		@param receiver: 效果要影响的实体
		@type  receiver: BigWorld.Entity
		@param buffData: BUFF
		@type  buffData: BUFF
		"""
		Buff_Normal.doEnd( self, receiver, buffData )
		self.addEffect( receiver )

	def doLoop( self, receiver, buffData ):
		"""
		Virtual method; call only by real entity.
		用于buff，表示buff在每一次心跳时应该做什么。

		@param receiver: 效果要影响的实体
		@type  receiver: BigWorld.Entity
		@param buffData: BUFF
		@type  buffData: BUFF
		@return: BOOL；如果允许继续则返回True，否则返回False
		@rtype:  BOOL
		"""
		self.addEffect( receiver )
		return Buff_Normal.doLoop( self, receiver, buffData )

#
# $Log: not supported by cvs2svn $
# Revision 1.1  2008/07/14 04:05:32  kebiao
# no message
#
#
#


from __future__ import print_function
import streamlit as st
import base64
from email.message import EmailMessage
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from google.oauth2.credentials import Credentials
from Utilities import isResponseYes,validateEmail
from test import speakText, transcribe_speech_with_repeat_for_send

def speakAndWrite(val):
    # st.write(val)
    speakText(val)

SCOPES = ['https://www.googleapis.com/auth/gmail.readonly',
          "https://mail.google.com/",
          "https://www.googleapis.com/auth/gmail.modify",
          "https://www.googleapis.com/auth/gmail.compose",
          "https://www.googleapis.com/auth/gmail.send"]

def gmail_send_message():
    """Create and send an email message
    Print the returned  message id
    Returns: Message object, including message id

    Load pre-authorized user credentials from the environment.
    TODO(developer) - See https://developers.google.com/identity
    for guides on implementing OAuth2 for the application.
    """
    creds = Credentials.from_authorized_user_file('token.json', SCOPES)

    try:
        service = build('gmail', 'v1', credentials=creds)
        message = EmailMessage()

        message.set_content('This is automated draft mail')

        message['To'] = 'ayush2000mickey@gmail.com',
        message['From'] = 'saiprashant.saxena@gmail.com'
        message['Subject'] = 'Automated draft'

        # encoded message
        encoded_message = base64.urlsafe_b64encode(message.as_bytes()) \
            .decode()

        create_message = {
            'raw': encoded_message
        }
        # pylint: disable=E1101
        send_message = (service.users().messages().send
                        (userId="me", body=create_message).execute())
        print(F'Message Id: {send_message["id"]}')
    except HttpError as error:
        print(F'An error occurred: {error}')
        send_message = None
    return send_message

if __name__ == '__main__':
    gmail_send_message()

def handleSendMail(creds):
    st.markdown("**:blue[What is the subject of the mail?]**")
    speakAndWrite("What is the subject of the mail?")
    subject = transcribe_speech_with_repeat_for_send()
    st.markdown("**:blue[What is the body of the email?]**")
    speakAndWrite("What is the body of the email")
    body = transcribe_speech_with_repeat_for_send()
    st.markdown("**:blue[What is receivers's mail id?]**")
    speakAndWrite("What is receivers's  mail id")
    mailID = transcribe_speech_with_repeat_for_send()
    mailID = mailID.replace(" ", "").replace("attherate", "@").lower()
    while (not validateEmail(mailID)):
        st.error("This Email is Invalid! Can you please repeat...", icon="ðŸ’€")
        speakAndWrite("This Email is Invalid!")
        speakAndWrite("Can you please repeat?")
        mailID = transcribe_speech_with_repeat_for_send()
        mailID = mailID.replace(" ", "").replace("attherate", "@").lower()

    st.markdown("**:blue[Do you want to add cc to this mail?]**")
    speakAndWrite("Do you want to add cc to this mail?")
    shouldAddCc = transcribe_speech_with_repeat_for_send()
    ccMailID = ""
    if (isResponseYes(shouldAddCc)):
        st.markdown("**:blue[What is the mail id?]**")
        speakAndWrite("What is the mail id?")
        ccMailID = transcribe_speech_with_repeat_for_send()
        ccmailID = ccmailID.replace(" ", "").replace("attherate", "@").lower()
        while (not validateEmail(ccmailID)):
            st.error("This Email is Invalid! Can you please repeat...", icon="ðŸ’€")
            speakAndWrite("This Email is Invalid!")
            speakAndWrite("Can you please repeat?")
            ccmailID = transcribe_speech_with_repeat_for_send()
            ccmailID = ccmailID.replace(" ", "").replace("attherate", "@").lower()

    try:
        service = build('gmail', 'v1', credentials=creds)
        message = EmailMessage()
        message.set_content(body)
        message['To'] = mailID
        if (len(ccMailID) > 0):
            message['cc'] = ccMailID.replace(
                " ", "").replace("attherate", "@").lower()
        print(message['To'])
        message['Subject'] = subject
        # encoded message
        encoded_message = base64.urlsafe_b64encode(message.as_bytes()) \
            .decode()
        create_message = {
            'raw': encoded_message
        }
        send_message = (service.users().messages().send
                        (userId="me", body=create_message).execute())
        print(F'Message Id: {send_message["id"]}')
        st.markdown("**:green[Mail Sent Successfully!]**")
        speakAndWrite("Mail Sent Successfully!")
    except HttpError as error:
        print(F'An error occurred: {error}')
        st.text("Receiver's Email Id Incorrect!")
        speakAndWrite("Receiver's Email Id Incorrect!")
        send_message = None