import os
import sys
import traceback
import configparser
import requests
import keyboard
import tkinter
import tkinter.ttk
import tkinter.filedialog
import tkinter.messagebox
import PIL.Image
import PIL.ImageTk
import lib.sheets_client
import lib.igdb_client
import lib.thegamesdb_client
import lib.utils
import lib.canvas_cover
import time

class MainFrame(tkinter.Frame):
	TOKENS_FILENAME = "tokens.ini"
	RESIZED_COVER_FILE_NAME = "cover.png"
	SCRAPER_COVER_FILE_NAME = "scraper_cover.png"

	def __init__(self, window, **kwargs):
		tkinter.Frame.__init__(self, window, **kwargs)

		self.window = window

		self.model = None

		self.timer_id = None

		self.config = configparser.ConfigParser()
		self.config.read("config.ini")

		self.utils = lib.utils.Utils()

		self.pack(expand = tkinter.YES, fill = tkinter.BOTH)

		menu_bar = tkinter.Menu(self.window)
		file_menu = tkinter.Menu(menu_bar, tearoff = 0)
		file_menu.add_command(label = "Open", command = self.on_menu_file_open)
		file_menu.add_command(label = "Save", command = self.on_menu_file_save)
		menu_bar.add_cascade(label = "File", menu = file_menu)

		self.window.config(menu = menu_bar)

		frame_left = tkinter.Frame(self, width = 300)
		frame_left.pack_propagate(False)
		frame_left.pack(side = tkinter.LEFT, fill = tkinter.BOTH)

		frame_right = tkinter.Frame(self, width = 300)
		frame_right.pack_propagate(False)
		frame_right.pack(side = tkinter.RIGHT, fill = tkinter.BOTH)

		frame_cover = tkinter.LabelFrame(self, text = "Jaquette")
		frame_cover.pack(side = tkinter.RIGHT, expand = tkinter.YES, fill = tkinter.BOTH, padx = 5, pady = 5)

		frame_logo = tkinter.Frame(frame_right)
		frame_logo.pack(side = tkinter.BOTTOM, fill = tkinter.BOTH)

		frame_sheet = tkinter.LabelFrame(frame_left, text = "Gdoc")
		frame_sheet.pack(side = tkinter.TOP, fill = tkinter.BOTH, padx = 5, pady = 5)

		frame_sheet_top = tkinter.Frame(frame_sheet)
		frame_sheet_top.pack(side = tkinter.TOP, fill = tkinter.BOTH)

		frame_sheet_bottom = tkinter.Frame(frame_sheet)
		frame_sheet_bottom.pack(side = tkinter.BOTTOM, fill = tkinter.BOTH)

		frame_run = tkinter.LabelFrame(frame_left, text = "Run")
		frame_run.pack(side = tkinter.TOP, fill = tkinter.BOTH, padx = 5, pady = 5)

		frame_run_top = tkinter.Frame(frame_run)
		frame_run_top.pack(side = tkinter.TOP, fill = tkinter.BOTH)

		frame_run_bottom = tkinter.Frame(frame_run)
		frame_run_bottom.pack(side = tkinter.BOTTOM, fill = tkinter.BOTH)

		frame_sheet_labels = tkinter.Frame(frame_sheet_top)
		frame_sheet_labels.pack(side = tkinter.LEFT, fill = tkinter.BOTH)

		frame_sheet_values = tkinter.Frame(frame_sheet_top)
		frame_sheet_values.pack(side = tkinter.RIGHT, expand = tkinter.YES, fill = tkinter.BOTH)

		frame_run_labels = tkinter.Frame(frame_run_top)
		frame_run_labels.pack(side = tkinter.LEFT, fill = tkinter.BOTH)

		frame_run_values = tkinter.Frame(frame_run_top)
		frame_run_values.pack(side = tkinter.RIGHT, expand = tkinter.YES, fill = tkinter.BOTH)

		frame_scraper_game_info = tkinter.LabelFrame(frame_right, text = "Informations jeu")
		frame_scraper_game_info.pack(side = tkinter.TOP, fill = tkinter.BOTH, padx = 5, pady = 5)

		frame_scraper_game_info_top = tkinter.Frame(frame_scraper_game_info)
		frame_scraper_game_info_top.pack(side = tkinter.TOP, fill = tkinter.BOTH)

		frame_scraper_game_info_top_labels = tkinter.Frame(frame_scraper_game_info_top)
		frame_scraper_game_info_top_labels.pack(side = tkinter.LEFT, fill = tkinter.BOTH)

		frame_scraper_game_info_top_values = tkinter.Frame(frame_scraper_game_info_top)
		frame_scraper_game_info_top_values.pack(side = tkinter.RIGHT, expand = tkinter.YES, fill = tkinter.BOTH)

		frame_scraper_game_info_bottom = tkinter.Frame(frame_scraper_game_info)
		frame_scraper_game_info_bottom.pack(side = tkinter.BOTTOM, fill = tkinter.BOTH)

		frame_scraper_game_info_canvas = tkinter.Frame(frame_scraper_game_info)
		frame_scraper_game_info_canvas.pack(side = tkinter.BOTTOM, fill = tkinter.BOTH)

		pil_img = PIL.Image.open("resources/retrolection.png")
		self.img_logo = PIL.ImageTk.PhotoImage(pil_img) # reference to image must be kept to avoid garbage deletion
		canvas = tkinter.Canvas(frame_logo, width = self.img_logo.width(), height = self.img_logo.height())
		canvas.create_image((0, 0), anchor = tkinter.NW, image = self.img_logo)
		canvas.pack(side = tkinter.RIGHT)

		self.combo_consoles = self.create_combo(frame_sheet_labels, frame_sheet_values, "Supports: ", self.on_combo_consoles_changed)
		self.entry_support_suffix = self.create_entry(frame_sheet_labels, frame_sheet_values, "Suffixe support: ")
		self.combo_games = self.create_combo(frame_sheet_labels, frame_sheet_values, "Jeux: ", self.on_combo_games_changed)
		self.entry_game_suffix = self.create_entry(frame_sheet_labels, frame_sheet_values, "Suffixe nom du jeu: ")
		self.label_progression_console = self.create_label(frame_sheet_labels, frame_sheet_values, "Progression console: ")
		self.label_progression_total = self.create_label(frame_sheet_labels, frame_sheet_values, "Progression totale: ")
		self.label_viewer_sub = self.create_label(frame_sheet_labels, frame_sheet_values, "Viewer sub: ")
		self.entry_viewer_sub_suffix = self.create_entry(frame_sheet_labels, frame_sheet_values, "Suffixe viewer sub: ")
		self.label_viewer_don = self.create_label(frame_sheet_labels, frame_sheet_values, "Viewer don: ")
		self.entry_viewer_don_suffix = self.create_entry(frame_sheet_labels, frame_sheet_values, "Suffixe viewer don: ")
		self.label_challenge_sub = self.create_label(frame_sheet_labels, frame_sheet_values, "Défi sub: ")
		self.entry_challenge_sub_suffix = self.create_entry(frame_sheet_labels, frame_sheet_values, "Suffixe défi sub: ")
		self.label_challenge_don = self.create_label(frame_sheet_labels, frame_sheet_values, "Défi don: ")
		self.entry_challenge_don_suffix = self.create_entry(frame_sheet_labels, frame_sheet_values, "Suffixe défi don: ")
		self.create_button(frame_sheet_bottom, "Recharger Gdoc", self.on_reload_sheet_click)
		self.create_button(frame_sheet_bottom, "Envoyer vers OBS", self.on_send_to_obs_click)
		self.label_status = self.create_label(frame_run_labels, frame_run_values, "Statut: ")
		self.label_timer_game = self.create_label(frame_run_labels, frame_run_values, "Temps: ")
		self.label_timer_support = self.create_label(frame_run_labels, frame_run_values, "Temps support: ")
		self.label_timer_total = self.create_label(frame_run_labels, frame_run_values, "Total Retrolection: ")
		self.button_start_pause = self.create_button(frame_run_bottom, "Démarrer", self.on_start_pause_click)
		self.create_button(frame_run_bottom, "Remettre à zéro", self.on_reset_click)
		self.create_button(frame_run_bottom, "Valider", self.on_validate_click)
		self.create_button(frame_cover, "Charger...", self.on_cover_load_click)

		self.canvas_cover = lib.canvas_cover.CanvasCover(frame_cover)

		self.combo_scraper_games = self.create_combo(frame_scraper_game_info_top_labels, frame_scraper_game_info_top_values, "Titre trouvés: ", self.on_combo_scraper_games_changed)
		self.label_scraper_game_release_date = self.create_label(frame_scraper_game_info_top_labels, frame_scraper_game_info_top_values, "Date de sortie: ")
		self.label_scraper_game_modes = self.create_label(frame_scraper_game_info_top_labels, frame_scraper_game_info_top_values, "Modes: ")
		self.label_scraper_game_alternates = self.create_label(frame_scraper_game_info_top_labels, frame_scraper_game_info_top_values, "Titre(s) alternatif(s): ")

		label = tkinter.Label(frame_scraper_game_info_top_labels, anchor = tkinter.W, text = "Jaquette: ")
		label.pack(anchor = tkinter.W)

		self.canvas_scraper_cover = lib.canvas_cover.CanvasCover(frame_scraper_game_info_canvas)

		self.create_button(frame_scraper_game_info_bottom, "<< Utiliser cette jaquette", self.on_use_this_cover_click)
		self.create_button(frame_scraper_game_info_bottom, "Sauvegarder cette jaquette", self.on_save_this_cover_click)

		keyboard.add_hotkey(self.config["HOTKEYS"]["HOTKEY_START_PAUSE"], lambda: window.after(1, self.on_start_pause_click))

	def create_combo(self, frame_label, frame_value, text, on_changed_cb):
		label = tkinter.Label(frame_label, anchor = tkinter.W, text = text)
		label.pack(anchor = tkinter.W, padx = 2, pady = 2)
		combo = tkinter.ttk.Combobox(frame_value, state = "readonly")
		combo.pack(padx = 2, pady = 2, fill = tkinter.X)
		combo.bind("<<ComboboxSelected>>", on_changed_cb)
		return combo

	def create_label(self, frame_label, frame_value, text):
		label = tkinter.Label(frame_label, anchor = tkinter.W, text = text)
		label.pack(anchor = tkinter.W, padx = 2, pady = 2)
		label_value = tkinter.Label(frame_value, anchor = tkinter.W)
		label_value.pack(anchor = tkinter.W, padx = 2, pady = 2)
		return label_value

	def create_entry(self, frame_label, frame_value, text):
		label = tkinter.Label(frame_label, anchor = tkinter.W, text = text)
		label.pack(anchor = tkinter.W, padx = 2, pady = 2)
		entry = tkinter.Entry(frame_value)
		entry.pack(fill = tkinter.X, padx = 2, pady = 3)
		return entry

	def create_button(self, frame, text, on_click_cb):
		button = tkinter.Button(frame, relief = tkinter.GROOVE, text = text, command = on_click_cb)
		button.pack(fill = tkinter.X, padx = 2, pady = 2)
		return button

	def get_combo_value(self, combo):
		current_index = combo.current()
		values = combo.cget("values")
		if current_index >= 0 and current_index < len(values):
			return values[current_index]
		return ""

	def select_combo_value(self, combo, value):
		values = combo.cget("values")

		i = 0
		for v in values:
			if v == value:
				combo.current(i)
				return True
			i += 1

		return False

	def on_menu_file_open(self):
		file_name = tkinter.filedialog.askopenfilename(defaultextension = "*.rcx", filetypes = [("Retrolection context files", "*.rcx")])
		if len(file_name) >= 1:
			self.load_context(file_name)

	def on_menu_file_save(self):
		file_name = tkinter.filedialog.asksaveasfilename(defaultextension = "*.rcx", filetypes = [("Retrolection context files", "*.rcx")])
		if len(file_name) >= 1:
			self.save_context(file_name)

	def on_use_this_cover_click(self):
		if self.canvas_scraper_cover.download_image(MainFrame.SCRAPER_COVER_FILE_NAME):
			self.canvas_cover.load_image(MainFrame.SCRAPER_COVER_FILE_NAME, None, True, MainFrame.RESIZED_COVER_FILE_NAME)

	def on_save_this_cover_click(self):
		file_name = tkinter.filedialog.asksaveasfilename(defaultextension = "*.jpg", filetypes = [("JPEG", "*.jpg")])
		if len(file_name) >= 1:
			self.canvas_scraper_cover.download_image(file_name)

	def on_cover_load_click(self):
		file_name = tkinter.filedialog.askopenfilename()
		self.canvas_cover.load_image(file_name, None, True, MainFrame.RESIZED_COVER_FILE_NAME)
		self.on_send_to_obs_click()

	def set_game_model_value(self, value_label, value):
		model_games = self.model["consoles"][self.model["current_console"]]["games"]
		model_games[self.model["current_game_index"]][value_label] = value

	def set_time(self, time_str):
		self.set_game_model_value("timer", time_str)
		self.label_timer_game.config(text = time_str)
		self.utils.write_file("w", "text-files/timer-game.txt", time_str)

	def set_time_support(self, time_str):
		self.model["consoles"][self.model["current_console"]]["timer_total"] = time_str
		self.label_timer_support.config(text = time_str)
		self.utils.write_file("w", "text-files/timer-support.txt", time_str)

	def set_total_time(self, time_str):
		self.model["timer_total"] = time_str
		self.label_timer_total.config(text = time_str)
		self.utils.write_file("w", "text-files/timer-total.txt", time_str)

	def set_progression_total(self, value):
		self.model["progression_total"] = value
		self.label_progression_total.config(text = value)
		self.utils.write_file("w", "text-files/progression-total.txt", value)

	def set_progression(self, value):
		self.model["consoles"][self.model["current_console"]]["progression"] = value
		self.label_progression_console.config(text = value)
		self.utils.write_file("w", "text-files/progression-console.txt", value)

	def start_timer(self):
		if self.timer_id:
			self.window.after_cancel(self.timer_id)
		self.timer_id = self.window.after(1000, self.update_timer)

	def stop_timer(self):
		if self.timer_id:
			self.window.after_cancel(self.timer_id)
			self.timer_id = None
			return True

		return False

	def on_reload_sheet_click(self):
		self.pause_run(True)
		self.reload_sheet()

	def on_send_to_obs_click(self):
		self.utils.write_file("w", "text-files/support.txt", self.combo_consoles.cget("values")[self.combo_consoles.current()] + self.entry_support_suffix.get())
		self.utils.write_file("w", "text-files/game.txt", self.combo_games.cget("values")[self.combo_games.current()] + self.entry_game_suffix.get())
		self.utils.write_file("w", "text-files/progression-console.txt", self.label_progression_console.cget("text"))
		self.utils.write_file("w", "text-files/progression-total.txt", self.label_progression_total.cget("text"))
		self.utils.write_file("w", "text-files/viewer-sub.txt", self.label_viewer_sub.cget("text") + self.entry_viewer_sub_suffix.get())
		self.utils.write_file("w", "text-files/viewer-don.txt", self.label_viewer_don.cget("text") + self.entry_viewer_don_suffix.get())
		self.utils.write_file("w", "text-files/challenge-sub.txt", self.label_challenge_sub.cget("text") + self.entry_challenge_sub_suffix.get())
		self.utils.write_file("w", "text-files/challenge-don.txt", self.label_challenge_don.cget("text") + self.entry_challenge_don_suffix.get())
		self.utils.write_file("w", "text-files/timer-game.txt", self.label_timer_game.cget("text"))
		self.utils.write_file("w", "text-files/timer-support.txt", self.label_timer_support.cget("text"))
		self.utils.write_file("w", "text-files/timer-total.txt", self.label_timer_total.cget("text"))

		if not self.canvas_cover.has_image():
			self.utils.copy_file("default-cover.png", "img-files/cover.png")
		else:
			self.utils.copy_file(MainFrame.RESIZED_COVER_FILE_NAME, "img-files/cover.png")

	def start_run(self):
		self.button_start_pause.config(text = "Pause")
		self.start_timer()

	def pause_run(self, save_game_to_sheet):
		self.button_start_pause.config(text = "Démarrer")
		# If run in progress
		if self.stop_timer() and save_game_to_sheet:
			self.save_game_to_sheet()

	def on_start_pause_click(self):
		if self.button_start_pause.cget("text") == "Démarrer":
			self.start_run()
		else:
			self.pause_run(True)

	def on_reset_click(self):
		self.pause_run(False)

		model_console = self.model["consoles"][self.model["current_console"]]
		model_game = model_console["games"][self.model["current_game_index"]]

		timer_total_reset_value = self.utils.timeSecToStr(self.utils.timeStrToSec(self.model["timer_total"]) - self.utils.timeStrToSec(model_game["timer"]))
		self.set_total_time(timer_total_reset_value)
		timer_support_reset_value = self.utils.timeSecToStr(self.utils.timeStrToSec(model_console["timer_total"]) - self.utils.timeStrToSec(model_game["timer"]))
		self.set_time_support(timer_total_reset_value)
		self.set_time("00:00:00")

		if model_game["validation_id"] != "":
			value, total = self.utils.progressStrToValues(self.model["progression_total"])
			self.set_progression_total(self.utils.progressValuesToStr(value - 1, total))

			value, total = self.utils.progressStrToValues(model_console["progression"])
			self.set_progression(self.utils.progressValuesToStr(value - 1, total))

			model_game["validation_id"] = ""

		self.update_status()
		self.save_game_to_sheet()

	def on_validate_click(self):
		self.pause_run(False)

		model_console = self.model["consoles"][self.model["current_console"]]
		model_game = model_console["games"][self.model["current_game_index"]]
		if model_game["validation_id"] == "":
			value, total = self.utils.progressStrToValues(self.model["progression_total"])
			self.set_progression_total(self.utils.progressValuesToStr(value + 1, total))

			value, total = self.utils.progressStrToValues(model_console["progression"])
			self.set_progression(self.utils.progressValuesToStr(value + 1, total))

			model_game["validation_id"] = str(value + 1)

			self.update_status()

		self.save_game_to_sheet()

	def save_game_to_sheet(self):
		console = self.model["current_console"]
		model_games = self.model["consoles"][console]["games"]
		current_game_index = self.model["current_game_index"]

		config_sheet = self.config["SHEET"]
		sheet_name = console
		line = str(int(config_sheet["FIRST_GAME_LINE"]) + current_game_index)
		ranges_values = [
			{
				"range": sheet_name + "!" + config_sheet["VALIDATION_COLUMN"] + line + ":" + config_sheet["VALIDATION_COLUMN"] + line,
				"values": [[model_games[current_game_index]["validation_id"]]]
			},
			{
				"range": sheet_name + "!" + config_sheet["TIMER_GAME_COLUMN"] + line + ":" + config_sheet["TIMER_GAME_COLUMN"] + line,
				"values": [[model_games[current_game_index]["timer"]]]
			},
		]

		self.sheets_client.set_values(ranges_values)

	def update_timer(self):
		t = self.utils.timeStrToSec(self.label_timer_game.cget("text"))
		t += 1
		self.set_time(self.utils.timeSecToStr(t))

		t = self.utils.timeStrToSec(self.label_timer_support.cget("text"))
		t += 1
		self.set_time_support(self.utils.timeSecToStr(t))

		t = self.utils.timeStrToSec(self.label_timer_total.cget("text"))
		t += 1
		self.set_total_time(self.utils.timeSecToStr(t))

		self.update_status()

		self.timer_id = self.window.after(1000, self.update_timer)

	def on_combo_consoles_changed(self, event):
		self.process_on_combo_consoles_changed(None)

	def fill_consoles(self, init_values):
		values = []

		for value in self.model["consoles"]:
			values.append(value)

		self.combo_consoles.config(values = values)
		self.combo_consoles.current(0)

		if init_values and ("console" in init_values):
			self.select_combo_value(self.combo_consoles, init_values["console"])

		self.process_on_combo_consoles_changed(init_values)

	def process_on_combo_consoles_changed(self, init_values):
		current_console = self.get_combo_value(self.combo_consoles)
		if current_console != self.model["current_console"]:
			self.model["current_console"] = current_console
			self.fill_games(init_values)
			self.label_progression_console.config(text = self.model["consoles"][current_console]["progression"])
			self.label_timer_support.config(text = self.model["consoles"][current_console]["timer_total"])

	def on_combo_games_changed(self, event):
		self.process_on_combo_games_changed(None)

	def fill_games(self, init_values):
		values = []

		for value in self.model["consoles"][self.model["current_console"]]["games"]:
			values.append(value["name"])

		self.combo_games.config(values = values)
		self.combo_games.current(0)

		if init_values and ("game" in init_values):
			self.select_combo_value(self.combo_games, init_values["game"])

		self.process_on_combo_games_changed(init_values)

	def process_on_combo_games_changed(self, init_values):
		current_game = self.get_combo_value(self.combo_games)

		if current_game != self.model["current_game"]:
			self.pause_run(True)

			self.model["current_game"] = current_game
			current_game_index = self.combo_games.current()
			self.model["current_game_index"] = current_game_index
			model_games = self.model["consoles"][self.model["current_console"]]["games"]

			self.label_viewer_sub.config(text = model_games[current_game_index]["viewer_sub"])
			self.label_viewer_don.config(text = model_games[current_game_index]["viewer_don"])
			self.label_challenge_sub.config(text = model_games[current_game_index]["challenge_sub"])
			self.label_challenge_don.config(text = model_games[current_game_index]["challenge_don"])
			self.label_timer_game.config(text = model_games[current_game_index]["timer"])

			self.update_status()

			self.fill_scraper_games(init_values)
			self.on_send_to_obs_click()

	def update_status(self):
		model_game = self.model["consoles"][self.model["current_console"]]["games"][self.model["current_game_index"]]
		if model_game["validation_id"] != "":
			text = "Fait"
		elif model_game["timer"] != "00:00:00":
			text = "En cours"
		else:
			text = "A faire"

		self.label_status.config(text = text)

	def on_combo_scraper_games_changed(self, event):
		self.process_on_combo_scraper_games_changed(None)

	def fill_scraper_games(self, init_values):
		try:
			if self.game_db_client:
				console = self.model["current_console"]
				game = self.model["current_game"]

				found_games = self.game_db_client.search_game_by_name(game, console)

				self.combo_scraper_games.set("")

				if not found_games:
					self.combo_scraper_games.config(values = [])
				else:
					value_to_id = {}
					values = []

					for v in found_games:
						values.append(v["title"])
						value_to_id[v["title"]] = v["id"]

					self.combo_scraper_games.value_to_id = value_to_id
					self.combo_scraper_games.config(values = values)

					if len(values) >= 1:
						self.combo_scraper_games.current(0)

						if init_values and ("scraper_game" in init_values):
							self.select_combo_value(self.combo_scraper_games, init_values["scraper_game"])

				self.process_on_combo_scraper_games_changed(init_values)

		except Exception as e:
			print("Unexpected error: ", traceback.format_exc())

	def process_on_combo_scraper_games_changed(self, init_values):
		current_scraper_game = self.get_combo_value(self.combo_scraper_games)

		if current_scraper_game != self.model["current_scraper_game"]:
			self.model["current_scraper_game"] = current_scraper_game

			if self.combo_scraper_games.current() < 0:
				self.label_scraper_game_release_date.config(text = "")
				self.label_scraper_game_modes.config(text = "")
				self.label_scraper_game_alternates.config(text = "")
				image_original_path = None
				image_thumb_path = None
			else:
				if self.game_db_client:
					scraper_game = self.combo_scraper_games.cget("values")[self.combo_scraper_games.current()]

					info = self.game_db_client.get_game_info(self.combo_scraper_games.value_to_id[scraper_game])

					self.label_scraper_game_release_date.config(text = info["release_date"])
					self.label_scraper_game_modes.config(text = info["modes"])
					self.label_scraper_game_alternates.config(text = info["alternates"])
					image_original_path = info["url_image"]
					image_thumb_path = info["url_image_thumb"]

			self.canvas_scraper_cover.load_image(image_original_path, image_thumb_path, False, None)

	def set_sheet_data_simple_values_to_model(self, data, model_games, game_start_row, field_name):
		id = data["startRow"] - game_start_row
		if "rowData" not in data:
			return
		for row_data in data["rowData"]:
			if id >= 0 and id < len(model_games):
				if "values" in row_data and "formattedValue" in row_data["values"][0]:
					model_games[id][field_name] = row_data["values"][0]["formattedValue"]
			id += 1

	def set_sheet_data_challenge_values_to_model(self, data, model_games, game_start_row, field_name):
		id = data["startRow"] - game_start_row
		if "rowData" not in data:
			return
		for row_data in data["rowData"]:
			if id >= 0 and id < len(model_games):
				if "values" in row_data:
					values = row_data["values"]

					# Find the first value with a green background color
					for value in values:
						if "formattedValue" in value \
						and "userEnteredFormat" in value \
						and "backgroundColor" in value["userEnteredFormat"]:
							background_color = value["userEnteredFormat"]["backgroundColor"]

							red = 0
							green = 0
							blue = 0
							if "red" in background_color:
								red = background_color["red"];
							if "green" in background_color:
								green = background_color["green"];
							if "blue" in background_color:
								blue = background_color["blue"];

							if red == 0 and green == 1 and blue == 0:
								model_games[id][field_name] = value["formattedValue"]
								break
			id += 1

	def set_sheet_data_simple_value_to_model(self, data, model_console, field_name):
		row_data = data["rowData"][0]
		if "values" in row_data and "formattedValue" in row_data["values"][0]:
			model_console[field_name] = row_data["values"][0]["formattedValue"]

	def set_sheet_data_progression_value_to_model(self, data, model_console, field_name):
		if "rowData" in data:
			row_data = data["rowData"][0]
			if "values" in row_data and "formattedValue" in row_data["values"][0] and "formattedValue" in row_data["values"][2]:
				nb_completed = int(row_data["values"][0]["formattedValue"])
				nb_total = int(row_data["values"][2]["formattedValue"])
				model_console[field_name] = self.utils.progressValuesToStr(nb_completed, nb_total)
				return nb_completed, nb_total

		return 0, 0

	def build_model(self):
		model = {
			"timer_total": "00:00:00",
			"progression_total": "",
			"consoles": {},
			"current_console": "",
			"current_game": "",
			"current_game_index": -1,
			"current_scraper_game": "",
		}

		config_sheet = self.config["SHEET"]

		response = self.sheets_client.get_sheets()

		if response["sheets"]:
			start_index = int(config_sheet["FIRST_GAME_CONSOLE_SHEET"]) - 1
			for i in range(start_index, start_index + int(config_sheet["NUMBER_OF_GAME_CONSOLE_SHEETS"])):
				item = response["sheets"][i];
				if item["properties"] and item["properties"]["title"]:
					model["consoles"][item["properties"]["title"]] = {
						"games": [],
						"progression": "",
						"timer_total": "00:00:00",
					}

		first_line = config_sheet["FIRST_GAME_LINE"]

		ranges = []

		for console in model["consoles"]:
			ranges.append(console + "!" + config_sheet["VALIDATION_COLUMN"] + first_line + ":" + config_sheet["VALIDATION_COLUMN"])
			ranges.append(console + "!" + config_sheet["GAME_NAME_COLUMN"] + first_line + ":" + config_sheet["GAME_NAME_COLUMN"])
			ranges.append(console + "!" + config_sheet["TIMER_GAME_COLUMN"] + first_line + ":" + config_sheet["TIMER_GAME_COLUMN"])
			ranges.append(console + "!" + config_sheet["VIEWER_SUB_COLUMN"] + first_line + ":" + config_sheet["VIEWER_SUB_COLUMN"])
			ranges.append(console + "!" + config_sheet["VIEWER_DON_COLUMN"] + first_line + ":" + config_sheet["VIEWER_DON_COLUMN"])
			ranges.append(console + "!" + config_sheet["CHALLENGE_SUB_COLUMN"] + first_line + ":" + config_sheet["CHALLENGE_SUB_COLUMN"])
			ranges.append(console + "!" + config_sheet["CHALLENGE_DON_FIRST_COLUMN"] + first_line + ":" + config_sheet["CHALLENGE_DON_LAST_COLUMN"])
			ranges.append(console + "!" + config_sheet["PROGRESSION_CELL_RANGE"])
			ranges.append(console + "!" + config_sheet["TIMER_TOTAL_CELL"] + ":" + config_sheet["TIMER_TOTAL_CELL"])

		values = self.sheets_client.get_values(ranges)

		sheets = values["sheets"]

		nb_games_completed = 0
		nb_games_total = 0

		for sheet in sheets:
			console = sheet["properties"]["title"]

			if "data" in sheet:
				data = sheet["data"]

				# Find game column
				game_data = None
				game_start_row = None
				for d in data:
					if "startColumn" in d \
					and d["startColumn"] == self.utils.sheet_a1_value_to_column_number(config_sheet["GAME_NAME_COLUMN"]):
						game_data = d
						game_start_row = d["startRow"]
						break

				for r in game_data["rowData"]:
					if "values" in r \
					and "formattedValue" in r["values"][0]:
						model["consoles"][console]["games"].append({
							"name": r["values"][0]["formattedValue"],
							"validation_id": "",
							"timer": "00:00:00",
							"viewer_sub": "",
							"viewer_don": "",
							"challenge_sub": "",
							"challenge_don": "",
						})

				for d in data:
					if "startColumn" in d:
						column = d["startColumn"]
					else:
						column = 0

					if "startRow" in d:
						row = d["startRow"]
					else:
						row = 0

					if row != 1 and column == self.utils.sheet_a1_value_to_column_number(config_sheet["VALIDATION_COLUMN"]):
						self.set_sheet_data_simple_values_to_model(d, model["consoles"][console]["games"], game_start_row, "validation_id")
					elif column == self.utils.sheet_a1_value_to_column_number(config_sheet["TIMER_GAME_COLUMN"]):
						self.set_sheet_data_simple_values_to_model(d, model["consoles"][console]["games"], game_start_row, "timer")
					elif column == self.utils.sheet_a1_value_to_column_number(config_sheet["VIEWER_SUB_COLUMN"]):
						self.set_sheet_data_simple_values_to_model(d, model["consoles"][console]["games"], game_start_row, "viewer_sub")
					elif column == self.utils.sheet_a1_value_to_column_number(config_sheet["VIEWER_DON_COLUMN"]):
						self.set_sheet_data_simple_values_to_model(d, model["consoles"][console]["games"], game_start_row, "viewer_don")
					elif column == self.utils.sheet_a1_value_to_column_number(config_sheet["CHALLENGE_SUB_COLUMN"]):
						self.set_sheet_data_challenge_values_to_model(d, model["consoles"][console]["games"], game_start_row, "challenge_sub")
					elif column == self.utils.sheet_a1_value_to_column_number(config_sheet["CHALLENGE_DON_FIRST_COLUMN"]):
						self.set_sheet_data_challenge_values_to_model(d, model["consoles"][console]["games"], game_start_row, "challenge_don")
					elif column == self.utils.sheet_a1_value_to_column_number(config_sheet["PROGRESSION_CELL_RANGE"]):
						nb_completed, nb_total = self.set_sheet_data_progression_value_to_model(d, model["consoles"][console], "progression")
						nb_games_completed += nb_completed
						nb_games_total += nb_total
					elif column == self.utils.sheet_a1_value_to_column_number(config_sheet["TIMER_TOTAL_CELL"]):
						self.set_sheet_data_simple_value_to_model(d, model["consoles"][console], "timer_total")

		t = 0
		for console in model["consoles"]:
			t += self.utils.timeStrToSec(model["consoles"][console]["timer_total"])

		model["timer_total"] = self.utils.timeSecToStr(t)

		model["progression_total"] = self.utils.progressValuesToStr(nb_games_completed, nb_games_total)

		return model

	def load(self):
		if not os.path.isfile(MainFrame.TOKENS_FILENAME):
			tkinter.messagebox.showerror("Error", " File "+ MainFrame.TOKENS_FILENAME +" not found. Please run grant_permissions.bat.")
			sys.exit()

		self.game_db_client = None
		if self.config["DATA_BASES"]["GAMES_DB"] == "THEGAMESDB":
			st = time.time()
			self.game_db_client = lib.thegamesdb_client.TheGamesDbClient(self.config["DATA_BASES"]["THEGAMESDB_API_KEY"])
			print(time.time(), "load game_db_client init (ms): ", (time.time() - st) * 1000)
		elif self.config["DATA_BASES"]["GAMES_DB"] == "IGDB":
			st = time.time()
			self.game_db_client = lib.igdb_client.IgdbClient(self.config["DATA_BASES"]["IGDB_API_KEY"])
			print(time.time(), "load igdb_client init (ms): ", (time.time() - st) * 1000)

		st = time.time()
		self.sheets_client = lib.sheets_client.SheetsClient(self.config["SHEET"]["GDOC_API_KEY"], self.config["SHEET"]["OAUTH_CLIENT_ID"], self.config["SHEET"]["OAUTH_CLIENT_SECRET"], self.config["SHEET"]["SPREAD_SHEET_ID"], MainFrame.TOKENS_FILENAME)
		print(time.time(), "load sheets_client init (ms): ", (time.time() - st) * 1000)

		st = time.time()
		self.model = self.build_model()
		print(time.time(), "load build_model (ms): ", (time.time() - st) * 1000)

		self.label_timer_total.config(text = self.model["timer_total"])
		self.label_progression_total.config(text = self.model["progression_total"])

		st = time.time()
		init_values = self.load_context("context.sav")
		print(time.time(), "load load_context (ms): ", (time.time() - st) * 1000)

		self.fill_consoles(init_values)
		st = time.time()
		print(time.time(), "load fill_consoles (ms): ", (time.time() - st) * 1000)

	def reload_sheet(self):
		init_values = {}
		init_values["console"] = self.model["current_console"]
		init_values["game"] = self.model["current_game"]
		init_values["scraper_game"] = self.model["current_scraper_game"]

		self.model = self.build_model()
		self.label_timer_total.config(text = self.model["timer_total"])
		self.label_progression_total.config(text = self.model["progression_total"])
		self.fill_consoles(init_values)

	def load_context(self, file_name):
		init_values = {}
		if os.path.exists(file_name):
			config = configparser.ConfigParser()
			config.read(file_name)

			if "console" in config["CONTEXT"]:
				init_values["console"] = config["CONTEXT"]["console"].replace("<SPACE>", " ")

			if "game" in config["CONTEXT"]:
				init_values["game"] = config["CONTEXT"]["game"].replace("<SPACE>", " ")

			if "scraper_game" in config["CONTEXT"]:
				init_values["scraper_game"] = config["CONTEXT"]["scraper_game"].replace("<SPACE>", " ")

			if "cover" in config["CONTEXT"]:
				self.canvas_cover.load_image(config["CONTEXT"]["cover"], None, True, MainFrame.RESIZED_COVER_FILE_NAME)

			if "support_suffix" in config["CONTEXT"]:
				self.entry_support_suffix.delete(0, tkinter.END)
				self.entry_support_suffix.insert(0, config["CONTEXT"]["support_suffix"].replace("<SPACE>", " "))

			if "game_suffix" in config["CONTEXT"]:
				self.entry_game_suffix.delete(0, tkinter.END)
				self.entry_game_suffix.insert(0, config["CONTEXT"]["game_suffix"].replace("<SPACE>", " "))

			if "challenge_sub_suffix" in config["CONTEXT"]:
				self.entry_challenge_sub_suffix.delete(0, tkinter.END)
				self.entry_challenge_sub_suffix.insert(0, config["CONTEXT"]["challenge_sub_suffix"].replace("<SPACE>", " "))

			if "challenge_don_suffix" in config["CONTEXT"]:
				self.entry_challenge_don_suffix.delete(0, tkinter.END)
				self.entry_challenge_don_suffix.insert(0, config["CONTEXT"]["challenge_don_suffix"].replace("<SPACE>", " "))

			if "viewer_sub_suffix" in config["CONTEXT"]:
				self.entry_viewer_sub_suffix.delete(0, tkinter.END)
				self.entry_viewer_sub_suffix.insert(0, config["CONTEXT"]["viewer_sub_suffix"].replace("<SPACE>", " "))

			if "viewer_don_suffix" in config["CONTEXT"]:
				self.entry_viewer_don_suffix.delete(0, tkinter.END)
				self.entry_viewer_don_suffix.insert(0, config["CONTEXT"]["viewer_don_suffix"].replace("<SPACE>", " "))

		return init_values

	def save_context(self, file_name):
		config = configparser.ConfigParser()

		config["CONTEXT"] = {
			"console": self.model["current_console"].replace(" ", "<SPACE>"),
			"game": self.model["current_game"].replace(" ", "<SPACE>"),
			"support_suffix": self.entry_support_suffix.get().replace(" ", "<SPACE>"),
			"game_suffix": self.entry_game_suffix.get().replace(" ", "<SPACE>"),
			"challenge_sub_suffix": self.entry_challenge_sub_suffix.get().replace(" ", "<SPACE>"),
			"challenge_don_suffix": self.entry_challenge_don_suffix.get().replace(" ", "<SPACE>"),
			"viewer_sub_suffix": self.entry_viewer_sub_suffix.get().replace(" ", "<SPACE>"),
			"viewer_don_suffix": self.entry_viewer_don_suffix.get().replace(" ", "<SPACE>"),
			"scraper_game": self.model["current_scraper_game"].replace(" ", "<SPACE>"),
		}

		image_path = self.canvas_cover.get_image_path()
		if image_path:
			config["CONTEXT"]["cover"] = image_path

		with open(file_name, "w") as f:
			config.write(f)

	def on_close(self):
		self.save_context("context.sav")
		try:
			self.window.destroy()
		except:
			pass

def main():
	window = tkinter.Tk()
	window.title("Retrolection")
	window.geometry("1050x650")
	window.geometry(("+" + str(int((window.winfo_screenwidth() - 1050) / 2)) + "+"+ str(int((window.winfo_screenheight() - (650 + 50)) / 2))))
	f = MainFrame(window)
	window.protocol("WM_DELETE_WINDOW", f.on_close)
	icon = tkinter.PhotoImage(file = "resources/icon.png")
	window.tk.call("wm", "iconphoto", window._w, icon)
	window.after(1, f.load)
	window.mainloop()

class Logger(object):
	def __init__(self, filename = "logs.txt"):
		self.terminal = sys.stdout
		self.log = open(filename, "w")

	def write(self, message):
		self.terminal.write(message)
		self.log.write(message)
		self.log.flush()

	def flush(self):
		self.terminal.flush()
		self.log.flush()

if __name__ == "__main__":
	logger = Logger()
	sys.stdout = logger
	sys.stderr = logger
	main()


#!/usr/bin/python3
"""Print the first state from data"""
import sys
from sqlalchemy import (create_engine)
from sqlalchemy.orm import sessionmaker
from model_state import Base, State

if __name__ == "__main__":
    engine = create_engine('mysql+mysqldb://{}:{}@localhost/{}'
                           .format(sys.argv[1], sys.argv[2],
                                   sys.argv[3]), pool_pre_ping=True)
    Base.metadata.create_all(engine)
    Session = sessionmaker(bind=engine)
    session = Session()
    name = session.query(State).first()
    if name:
        print(f"{name.id}: {name.name}")
    else:
        print("Nothing")
    session.close()


#!/usr/bin/env python3
# -*- coding: utf-8
"""
Created on 2018/12/29
@author yrh

"""

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F

__all__ = ['Embedding', 'LSTMEncoder', 'MLAttention', 'AttentionWeights', 'FastMLAttention', 'MLLinear']

class Embedding(nn.Module):
    """

    """
    def __init__(self, vocab_size=None, emb_size=None, emb_init=None, emb_trainable=True, padding_idx=0, dropout=0.2):
        super(Embedding, self).__init__()
        if emb_init is not None:
            if vocab_size is not None:
                assert vocab_size == emb_init.shape[0]
            if emb_size is not None:
                assert emb_size == emb_init.shape[1]
            vocab_size, emb_size = emb_init.shape
        self.emb = nn.Embedding(vocab_size, emb_size, padding_idx=padding_idx, sparse=True,
                                _weight=torch.from_numpy(emb_init).float() if emb_init is not None else None)
        self.emb.weight.requires_grad = emb_trainable
        self.dropout = nn.Dropout(dropout)
        self.padding_idx = padding_idx

    def forward(self, inputs):
        emb_out = self.dropout(self.emb(inputs))
        lengths, masks = (inputs != self.padding_idx).sum(dim=-1), inputs != self.padding_idx
        return emb_out[:, :lengths.max()], lengths, masks[:, :lengths.max()]

class LSTMEncoder(nn.Module):
    """

    """
    def __init__(self, input_size, hidden_size, layers_num, dropout):
        super(LSTMEncoder, self).__init__()
        self.lstm = nn.LSTM(input_size, hidden_size, layers_num, batch_first=True, bidirectional=True)
        self.init_state = nn.Parameter(torch.zeros(2*2*layers_num, 1, hidden_size))
        self.dropout = nn.Dropout(dropout)

    def forward(self, inputs, lengths, **kwargs):
        self.lstm.flatten_parameters()
        init_state = self.init_state.repeat([1, inputs.size(0), 1])
        cell_init, hidden_init = init_state[:init_state.size(0)//2], init_state[init_state.size(0)//2:]
        idx = torch.argsort(lengths, descending=True)
        packed_inputs = nn.utils.rnn.pack_padded_sequence(inputs[idx], lengths[idx], batch_first=True)
        outputs, _ = nn.utils.rnn.pad_packed_sequence(
            self.lstm(packed_inputs, (hidden_init, cell_init))[0], batch_first=True)
        return self.dropout(outputs[torch.argsort(idx)])

class MLAttention(nn.Module):
    """

    """
    def __init__(self, labels_num, hidden_size):
        super(MLAttention, self).__init__()
        self.attention = nn.Linear(hidden_size, labels_num, bias=False)
        nn.init.xavier_uniform_(self.attention.weight)

    def forward(self, inputs, masks):
        masks = torch.unsqueeze(masks, 1)  # N, 1, L
        attention = self.attention(inputs).transpose(1, 2).masked_fill(1.0 - masks, -np.inf)  # N, labels_num, L
        attention = F.softmax(attention, -1)
        return attention @ inputs   # N, labels_num, hidden_size

class AttentionWeights(nn.Module):
    """

    """
    def __init__(self, labels_num, hidden_size, device_ids=None):
        super(AttentionWeights, self).__init__()
        if device_ids is None:
            device_ids = list(range(1, torch.cuda.device_count()))
        assert labels_num >= len(device_ids)
        group_size, plus_num = labels_num // len(device_ids), labels_num % len(device_ids)
        self.group = [group_size + 1] * plus_num + [group_size] * (len(device_ids) - plus_num)
        assert sum(self.group) == labels_num
        self.emb = nn.ModuleList(nn.Embedding(size, hidden_size, sparse=True).cuda(device_ids[i])
                                 for i, size in enumerate(self.group))
        std = (6.0 / (labels_num + hidden_size)) ** 0.5
        with torch.no_grad():
            for emb in self.emb:
                emb.weight.data.uniform_(-std, std)
        self.group_offset, self.hidden_size = np.cumsum([0] + self.group), hidden_size

    def forward(self, inputs: torch.Tensor):
        outputs = torch.zeros(*inputs.size(), self.hidden_size, device=inputs.device)
        for left, right, emb in zip(self.group_offset[:-1], self.group_offset[1:], self.emb):
            index = (left <= inputs) & (inputs < right)
            group_inputs = (inputs[index] - left).to(emb.weight.device)
            outputs[index] = emb(group_inputs).to(inputs.device)
        return outputs

class FastMLAttention(nn.Module):
    """

    """
    def __init__(self, labels_num, hidden_size, parallel_attn=False):
        super(FastMLAttention, self).__init__()
        if parallel_attn:
            self.attention = nn.Embedding(labels_num + 1, hidden_size, sparse=True)
            nn.init.xavier_uniform_(self.attention.weight)

    def forward(self, inputs, masks, candidates, attn_weights: nn.Module):
        masks = torch.unsqueeze(masks, 1)   # N, 1, L
        attn_inputs = inputs.transpose(1, 2)    # N, hidden, L
        attn_weights = self.attention(candidates) if hasattr(self, 'attention') else attn_weights(candidates)
        attention = (attn_weights @ attn_inputs).masked_fill(1.0 - masks, -np.inf)  # N, sampled_size, L
        attention = F.softmax(attention, -1)    # N, sampled_size, L
        return attention @ inputs   # N, sampled_size, hidden_size

class MLLinear(nn.Module):
    """

    """
    def __init__(self, linear_size, output_size):
        super(MLLinear, self).__init__()
        self.linear = nn.ModuleList(nn.Linear(in_s, out_s)
                                    for in_s, out_s in zip(linear_size[:-1], linear_size[1:]))
        for linear in self.linear:
            nn.init.xavier_uniform_(linear.weight)
        self.output = nn.Linear(linear_size[-1], output_size)
        nn.init.xavier_uniform_(self.output.weight)

    def forward(self, inputs):
        linear_out = inputs
        for linear in self.linear:
            linear_out = F.relu(linear(linear_out))
        return torch.squeeze(self.output(linear_out), -1)


import os
import logging
import six

from cathay_spark import SparkBuilder

from cathay_jinja.jinja_injector import JinjaInjector

from cathay.setting.config.config_utils import get_full_keys

logger = logging.getLogger(__name__)

class SparkSession(object):

    spark = None
    mode = None
    spark_configs = None

    def __init__(self, config=None):
        self.config = config

    def _set_config(self):
        '''
            overwrite if reading config from elsewhere
        '''
        pass

    def _set_spark_app_name(self):
        '''
            overwrite if app name need to be changed
        '''
        assert self.config is not None, "config is None"
        self.app_name = self.config.get('hippo.name')

    def _set_spark_mode(self):
        '''
            overwrite if changing spark mode
        '''
        if os.environ['ENV'] == 'dev':
            self.mode = 'local'
        else:
            self.mode = 'yarn'

    def _set_spark_session_conf(self):
        '''
            set spark session from conf/spark.conf
        '''
        logger.info('set spark configuration ...')
        self.spark_configs = get_full_keys(self.config.get("spark", None), "spark")
        for key in self.spark_configs:
            if isinstance(self.spark_configs[key], six.string_types):
                self.spark_configs[key] = JinjaInjector.string_render_args(
                    content=self.spark_configs[key], env=os.environ)

    def _init_spark_session(self):
        '''
            init spark session from default base config
        '''
        logger.info('get spark session, mode: {} ...'.format(self.mode))
        sb = SparkBuilder(self.app_name, self.mode, self.spark_configs)
        self.spark = sb.get_spark()

    def _set_spark_logger(self):
        logger = SparkBuilder.get_logger(self.spark)

        # set custom log level after sparkSession create
        logger.LogManager.getRootLogger().setLevel(logger.Level.INFO)

    def set_spark_session(self):
        if self.config is None:
            self._set_config()
        self._set_spark_mode()
        self._set_spark_app_name()
        self._set_spark_session_conf()
        self._init_spark_session()
        self._set_spark_logger()

    def get_spark_session(self):
        if self.spark is None:
            self.set_spark_session()
        return self.spark

    def close_spark_session(self):
        logger.info('close spark session ...')
        if self.spark is not None:
            self.spark.stop()
        else:
            logger.warn('No such spark session')


from co2mpas.__main__ import init_logging
from co2mpas.sampling import cfgcmd
from co2mpas.sampling.baseapp import pump_cmd, collect_cmd
import logging
import os
import unittest

import ddt

import os.path as osp
import subprocess as sbp

init_logging(level=logging.DEBUG)

log = logging.getLogger(__name__)

mydir = osp.dirname(__file__)

class T(unittest.TestCase):

    @unittest.expectedFailure
    def test_paths_valid_yaml(self):
        import yaml
        res = collect_cmd(cfgcmd.PathsCmd().run())
        ystr = '\n'.join(res)

        yaml.load(ystr)

@ddt.ddt
class TcfgcmdShell(unittest.TestCase):
    def test_paths_smoketest(self):
        ret = sbp.check_call('co2dice config paths', env=os.environ)
        self.assertEqual(ret, 0)

    @ddt.data('', 'proj', '-e proj', '-el proj')
    def test_show_smoketest(self, case):
        cmd = ('co2dice config show ' + case).strip()
        ret = sbp.check_call(cmd, env=os.environ)
        self.assertEqual(ret, 0)

    @ddt.data('', 'TstampReceiver', 'recv', '-l rec', '-e rec', '-le rec'
              '-ecl rec', '-cl rec')
    def test_desc_smoketest(self, case):
        cmd = ('co2dice config desc ' + case).strip()
        ret = sbp.check_call(cmd, env=os.environ)
        self.assertEqual(ret, 0)


import os
import importlib.util

class Dispatcher():
    """
    Viper dispatcher

    Handles requests coming through any of the application's communication
    interfaces and dispatches the appropriate controller.
    """

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

    def dispatch(self, requestProtocol, requestPayload):
        """
        Dispatch the request to the appropriate handler.

        :param requestProtocol: <AbstractApplicationInterfaceProtocol> request protocol
        :param requestPayload: <dict> request
            :param version: <float> version
            :param method: <str> method name
            :param parameters: <dict> data parameters
        :return: <void>
        """
        # method decoding
        method = requestPayload["method"].split(".")
        if len(method) != 3:
            requestProtocol.failRequestWithErrors(["InvalidMethod"])
            return

        # parsing method name
        methodModule = method[0]
        methodController = method[1]
        methodAction = method[2]

        # checking if module exists
        if not self.application.isModuleLoaded(methodModule):
            requestProtocol.failRequestWithErrors(["InvalidMethodModule"])
            return

        # checking if controller exists
        controllerPath = os.path.join(
            "application",
            "module",
            methodModule,
            "controller",
            "{}.py".format(methodController)
        )
        if not os.path.isfile(controllerPath):
            requestProtocol.failRequestWithErrors(["InvalidMethodController"])
            return

        # importing controller
        controllerSpec = importlib.util.spec_from_file_location(
            methodController,
            controllerPath
        )
        controller = importlib.util.module_from_spec(controllerSpec)
        controllerSpec.loader.exec_module(controller)

        # instancing controller
        controllerInstance = controller.Controller(
            self.application,
            requestProtocol,
            requestPayload["version"],
            requestPayload["parameters"]
        )

        # checking if action exists
        action = getattr(
            controllerInstance,
            "{}Action".format(methodAction),
            None
        )
        if not callable(action):
            requestProtocol.failRequestWithErrors(["InvalidMethodAction"])
            return

        # executing action
        requestProtocol.requestPassedDispatcherValidation()

        preDispatchAction = getattr(controllerInstance, "preDispatch")
        postDispatchAction = getattr(controllerInstance, "postDispatch")

        preDispatchAction()
        action()
        postDispatchAction()


import argparse
import configparser
import os
import misc_helpers

def get_config(filename):
    """
    All settings are stored in an external text file.
    """
    config = configparser.ConfigParser()
    config.read(filename)
    return config

def get_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument("-c", "--config",
        required=False,
        default="options.cfg",
        help="path to program options file")
    parser.add_argument("-s", "--song",
        required=False,
        help="use this song instead of the one in the config file")
    parser.add_argument("-r", "--right",
        required=False,
        help="create song for the right hand [possible values: 0,1] ")
    parser.add_argument("-l", "--left",
        required=False,
        help="create song for the left hand [possible values: 0,1] ")
    parser.add_argument("-d", "--device",
        required=False,
        help="number of the MIDI device (use aconnect to find out)")
    parser.add_argument("-p", "--present",
        required=False,
        help="display in presentation mode")
    return parser

def get_options_from_config(config):
    true_strings = misc_helpers.get_true_strings()
    options = {}
    options["song"] = config["PLAY_OPTIONS"]["song"]
    options["play_right"] = True if config["PLAY_OPTIONS"]["play_right"] in true_strings else False
    options["play_left"] = True if config["PLAY_OPTIONS"]["play_left"] in true_strings else False
    options["presentation_mode"] = True if config["PLAY_OPTIONS"]["presentation_mode"] in true_strings else False
    options["songs_folder"] = misc_helpers.normalize_folder_string(config["PLAY_OPTIONS"]["songs_folder"])
    options["midi_device_no"] = int(config["PLAY_OPTIONS"]["midi_device_no"])
    options["image_width"] = int(config["SHARED_OPTIONS"]["screen_width"])
    options["image_height"] = int(config["SHARED_OPTIONS"]["screen_height"])
    return options

def replace_options_from_command_line(options, args):
    true_strings = misc_helpers.get_true_strings()
    if args["song"]:
        options["song"] = args["song"]
    if args["left"]:
        options["play_left"] = True if args["left"] in true_strings else False
    if args["right"]:
        options["play_right"] = True if args["right"] in true_strings else False
    if args["device"]:
        options["midi_device_no"] = int(args["device"])
    if args["present"]:
        options["presentation_mode"] = True if args["present"] in true_strings else False

def create_complete_paths(options):
    hand_string = misc_helpers.get_folder_hand_string(options)
    options["song_folder_complete"] = os.path.join(options["songs_folder"], options["song"], hand_string) + "/"

def get_options():
    parser = get_parser()
    parsed_arguments = vars(parser.parse_args())
    filename = parsed_arguments["config"]
    config = get_config(filename)
    options = get_options_from_config(config)

    replace_options_from_command_line(options, parsed_arguments)
    create_complete_paths(options)

    return options


import re
import random
import nltk
from nltk.corpus import wordnet

def mutate_simple_condition(cond_str):
    possible_changes = []
    if '==' in cond_str:
        possible_changes.extend([(m.start(), m.end(), '!=') for m in re.finditer('==',cond_str)])
    if '!=' in cond_str:
        possible_changes.extend([(m.start(), m.end(), '==') for m in re.finditer('!=', cond_str)])
    if ' not ' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' ') for m in re.finditer(' not ', cond_str)])
    if '>=' in cond_str:
        possible_changes.extend([(m.start(), m.end(), '<') for m in re.finditer('>=', cond_str)])
    if '>' in cond_str:
        possible_changes.extend([(m.start(), m.end(), '<=') for m in re.finditer('>', cond_str)])
    if '<=' in cond_str:
        possible_changes.extend([(m.start(), m.end(), '>') for m in re.finditer('<=', cond_str)])
    if '<' in cond_str:
        possible_changes.extend([(m.start(), m.end(), '>=') for m in re.finditer('<', cond_str)])
    if 'True' in cond_str:
        possible_changes.extend([(m.start(), m.end(), 'False') for m in re.finditer('True', cond_str)])
    if 'False' in cond_str:
        possible_changes.extend([(m.start(), m.end(), 'True') for m in re.finditer('False', cond_str)])
    if ' not in ' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' in ') for m in re.finditer(' not in ', cond_str)])
    elif ' in ' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' not in ') for m in re.finditer(' in ', cond_str)])
    if ' is not ' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' is ') for m in re.finditer(' is not ', cond_str)])
    elif ' is ' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' is not ') for m in re.finditer(' is ', cond_str)])
    if ' and ' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' or ') for m in re.finditer(' and ', cond_str)])
    if ' or ' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' and ') for m in re.finditer(' or ', cond_str)])
    if ' any(' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' all(') for m in re.finditer(' any\(', cond_str)])
    if ' all(' in cond_str:
        possible_changes.extend([(m.start(), m.end(), ' any(') for m in re.finditer(' all\(', cond_str)])
    if cond_str.startswith('not '):
        possible_changes.extend([(0, 4, '')])
    if 'len(' in cond_str:
        start = cond_str.find('len(')
        end = cond_str[start:].find(')')+1
        word = cond_str[start+4:start+end-1]
        possible_changes.extend([(start, start+end, word)])
    if len(possible_changes)==0:
        possible_changes.append((0, 0, 'not '))
    return possible_changes

def apply_condition_mutations(data_pairs):
    X_data = []
    y_data = []
    for c, m in data_pairs:
        possible_changes = mutate_simple_condition(c)
        for change in possible_changes:
            mutated_condition = c[:change[0]] + change[2] + c[change[1]:]
            X_data.append((mutated_condition, m))
            y_data.append(1.)

        X_data.append((c, m))
        y_data.append(0.)
    return X_data, y_data

def mutate_message(m):
    mutated_messages = []
    tokenized = m.split(' ')
    tags = nltk.pos_tag(tokenized)

    for tag in tags:
        if tag[1].startswith('JJ'):
            for syn in wordnet.synsets(tag[0]):
                for lm in syn.lemmas():
                    if lm.antonyms():
                        mutated_messages.append(m.replace(tag[0], lm.antonyms()[0].name()))
        if tag[1].startswith('MD'):
            if not tag[0].endswith("n't"):
                mutated_messages.append(m.replace(tag[0], tag[0] +' not').replace(' not not ', ' '))
        if tag[1].startswith('VBN'):
            mutated_messages.append(m.replace(tag[0], 'not '+tag[0]).replace(' not not ', ' '))
    if ' is not ' in m:
        mutated_messages.append(m.replace(' is not ', ' is '))
    elif ' is ' in m:
        mutated_messages.append(m.replace(' is ', ' is not '))
    if ' are not ' in m:
        mutated_messages.append(m.replace(' are not ', ' are '))
    elif ' are ' in m:
        mutated_messages.append(m.replace(' are ', ' are not '))
    if ' was not ' in m:
        mutated_messages.append(m.replace(' was not ', ' was '))
    elif ' was ' in m:
        mutated_messages.append(m.replace(' was ', ' was not '))
    if ' not in ' in m:
        mutated_messages.append(m.replace(' not in ', ' in '))
    elif ' in ' in m:
        mutated_messages.append(m.replace(' in ', ' not in '))
    return mutated_messages


# -*- coding: utf-8 -*-
# @Author: 曾辉
import xlwt
import xlrd
import numpy as np
import datetime
from xlutils.copy import copy

source_xls = '楼宇安防.xls'

data = xlrd.open_workbook(source_xls)

# 创建一个新的工作簿
wb = xlwt.Workbook()
# 把读取到的工作簿的内容全部复制到 新的工作簿上
wb = copy(data)

for i in range(len(data.sheets())):
	table = data.sheets()[i]  # 对应的获取 工作表的内容
	#获取第2列的温度的数据，并且求平均温度，平均人数，以及异常的人数(温度>=37.4)
	temp_value = table.col_values(colx=1,start_rowx=1)  # 把标题除外了
	temp_ndarray = np.array(temp_value)
	abnormal = np.argwhere(temp_ndarray>=37.4)
	# [[0]
	#  [2]
	#  [6]
	#  [8]]
	# 返回True结果的Index  是嵌套的
	# print(temp_ndarray)
	# print(abnormal)
	# 判断是否为空的工作表
	if table.nrows == 0:continue
	# 每日的汇总统计
	now_time = datetime.datetime.now().strftime('%Y-%m-%d')  # 把datetime转变为字符串
	result = '备注:\n 时间：{}\n总进出人数:{}\n异常人数:{}\n平均温度:{}'.format(now_time,len(temp_value),len(abnormal),np.mean(temp_ndarray))
	# print(now_time)
	row_index = len(temp_value)+2  # 与数据空 两行的位置
	col_index = 0
	wokrsheet = wb.get_sheet(i)  # 访问当前的工作表 然后进行操作
	#合并单元表，并且把result写在下面
	wokrsheet.write_merge(row_index, row_index+1,col_index, 2, result)

	# 将异常人的这一行信息都变为高亮
	# 高亮的格式
	style = xlwt.XFStyle()
	pattern = xlwt.Pattern()
	pattern.pattern = xlwt.Pattern.SOLID_PATTERN  # May be: NO_PATTERN, SOLID_PATTERN, or 0x00 through 0x12
	pattern.pattern_fore_colour = 5
	# 0 = Black, 1 = White, 2 = Red, 3 = Green, 4 = Blue, 5 = Yellow,
	style.pattern = pattern

	# 首先要获取异常人的所有信息
	time_list=[]
	for j in abnormal:
		rown = j[0]  # 行
		for col in range(table.ncols):  #table.ncols 工作表的列数
			content = table.cell_value(rown+1,col)    # 把要标题算上

			if col ==2:
				# style.num_format_str = 'M/D/YY'      # 第二列的时候才是时间的格式
				# wokrsheet.write(rown + 1, col,content,style)
				# style.num_format_str = ''
				time_list.append((content,(rown + 1,col)))
			else:
				wokrsheet.write(rown + 1, col, content,style)

	# style.num_format_str = 'M/D/YY'  时间的格式会导致 数字显示不正常

	style.num_format_str = 'M/D/YY'
	for t in time_list:
		wokrsheet.write(t[1][0], t[1][1], t[0], style)

wb.save('楼宇安防_日报.xls')


# -*- coding: utf-8 -*-
# ███╗   ███╗ █████╗ ███╗   ██╗██╗ ██████╗ ██████╗ ███╗   ███╗██╗ ██████╗
# ████╗ ████║██╔══██╗████╗  ██║██║██╔════╝██╔═══██╗████╗ ████║██║██╔═══██╗
# ██╔████╔██║███████║██╔██╗ ██║██║██║     ██║   ██║██╔████╔██║██║██║   ██║
# ██║╚██╔╝██║██╔══██║██║╚██╗██║██║██║     ██║   ██║██║╚██╔╝██║██║██║   ██║
# ██║ ╚═╝ ██║██║  ██║██║ ╚████║██║╚██████╗╚██████╔╝██║ ╚═╝ ██║██║╚██████╔╝
# ╚═╝     ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚═╝ ╚═════╝ ╚═════╝ ╚═╝     ╚═╝╚═╝ ╚═════╝
#     [+] @GorpoOrko 2020 - Telegram Bot and Personal Assistant [+]
#     |   TCXS Project Hacker Team - https://tcxsproject.com.br   |
#     |   Telegram: @GorpoOrko Mail:gorpoorko@protonmail.com      |
#     [+]        Github Gorpo Dev: https://github.com/gorpo     [+]

from spellchecker import SpellChecker

def corrigirPalavras(msg):
    spell = SpellChecker(language='pt')
    mensagem = msg
    misspelled = spell.unknown(mensagem.split())
    palavra_errada = list(misspelled)[0]  # retorna a palavra que estava errada na frase
    for palavra_final in misspelled:
        corrigir = spell.correction(palavra_final)
        candidatos = spell.candidates(palavra_final)
        mensagem_corrigida = mensagem.replace(palavra_errada, corrigir).replace('corrigir', '')
    return  mensagem_corrigida


'''
实现RGB2GRAY(手工实现+调接口)
实现二值化
'''

import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2gray

def read_img(img_path):
    return cv2.imdecode(np.fromfile(img_path, dtype=np.uint8), -1)  # 不直接用cv2.imread()，解决中文路径问题

def DIY_RGB2GRAY(img):
    B, G, R = img[:, :, 0], img[:, :, 1], img[:, :, 2]
    img = 0.11 * B + 0.59 * G + 0.3 * R
    return img.astype(np.uint8)

def DIY_BINARYZATION(img):
    img = DIY_RGB2GRAY(img)
    img = np.where(img >= 127, 1, 0)
    return img

img = read_img("lenna.png")
print("----img-----")
print(img)

plt.subplot(221)
diy_gray_img = DIY_RGB2GRAY(img)
plt.title("DIY_RGB2GRAY")
plt.imshow(diy_gray_img, cmap="gray")
print("----diy_gray_img-----")
print(diy_gray_img, diy_gray_img.shape)

plt.subplot(222)
skimage_rgb2gray = rgb2gray(img)
plt.title("SKIMAGE_RGB2GRAY")
plt.imshow(skimage_rgb2gray, cmap="gray")
print("----skimage_rgb2gray-----")
print(skimage_rgb2gray, skimage_rgb2gray.shape)  # 转成0-1之间的小数了

plt.subplot(223)
diy_binaryzation = DIY_BINARYZATION(img)
plt.title("DIY_BINARYZATION")
plt.imshow(diy_binaryzation, cmap="gray")
print("----diy_binaryzation-----")
print(diy_binaryzation, diy_binaryzation.shape)

plt.subplot(224)
img_other = cv2.cvtColor(img, cv2.COLOR_BGR2Luv)
plt.title("other")
plt.imshow(img_other, cmap="gray")

plt.show()

184-袁周立-北京/第二周/第二周.py


import os
import json
import csv
import pandas as pd

# Obtener la ruta absoluta del directorio actual
directorio_actual = os.path.abspath(os.path.dirname(__file__))
directory = 'games_month_all'
extension = '.json'
# Crear la ruta completa del directorio
ruta = os.path.join(directorio_actual, directory)
ruta_csv = os.path.join(directorio_actual, directory + '.csv')
archivos_json = [archivo for archivo in os.listdir(ruta) if archivo.endswith(extension)]

# Datos que deseas guardar en el archivo CSV
data_csv = []
data_csv.append(["Date", "Name", "HR"])
data_date   = []
data_name   = []
data_hr     = []
table       = {}
for archivo in archivos_json:
    print(archivo)
    ruta_completa = os.path.join(ruta, archivo)  # Obtiene la ruta completa del archivo
    with open(ruta_completa, 'r', encoding="utf-8") as archivo_json:
        datos = json.load(archivo_json)  # Carga los datos JSON del archivo en un diccionario

    # Aquí puedes trabajar con los datos como lo harías con un diccionario de Python
    # print(datos["home_team"]["name"])
    for batter in datos["home_team"]["batters"]:
        if batter['HR'] != "":
            # print(datos["date"])
            # print(batter['name'])
            # print(batter['HR'])
            data_csv.append([datos["date"], batter['name'], batter['HR']])
            data_date.append(datos["date"])
            data_name.append(batter["name"])
            data_hr.append(batter["HR"])
            # Verificar si la clave '20230401' existe en el diccionario table
            fecha = datos["date"]
            nombre_bateador = batter["name"]
            hr = batter["HR"]
            if fecha in table:
                # Verificar si la clave 'nombre_bateador' existe en el diccionario anidado
                if nombre_bateador in table[fecha]:
                    # La clave 'nombre_bateador' existe, actualiza el valor
                    table[fecha][nombre_bateador] = str(int(table[fecha][nombre_bateador]) + int(hr))
                else:
                    # La clave 'nombre_bateador' no existe, crea una nueva entrada
                    table[fecha][nombre_bateador] = hr
            else:
                # La clave 'fecha' no existe, crea una nueva entrada con el diccionario anidado
                table[fecha] = {nombre_bateador: hr}

    # print(datos["away_team"]["name"])
    for batter in datos["away_team"]["batters"]:
        if batter['HR'] != "":
            # print(datos["date"])
            # print(batter['name'])
            # print(batter['HR'])
            data_csv.append([datos["date"], batter['name'], batter['HR']])
            data_date.append(datos["date"])
            data_name.append(batter["name"])
            data_hr.append(batter["HR"])
            fecha = datos["date"]
            nombre_bateador = batter["name"]
            hr = batter["HR"]
            if fecha in table:
                # Verificar si la clave 'nombre_bateador' existe en el diccionario anidado
                if nombre_bateador in table[fecha]:
                    # La clave 'nombre_bateador' existe, actualiza el valor
                    table[fecha][nombre_bateador] = str(int(table[fecha][nombre_bateador]) + int(hr))
                else:
                    # La clave 'nombre_bateador' no existe, crea una nueva entrada
                    table[fecha][nombre_bateador] = hr
            else:
                # La clave 'fecha' no existe, crea una nueva entrada con el diccionario anidado
                table[fecha] = {nombre_bateador: hr}

# Abre el archivo CSV en modo escritura
with open(ruta_csv, mode='w', newline='', encoding="utf-8") as archivo_csv:
    escritor_csv = csv.writer(archivo_csv, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)

    # Escribe los datos en el archivo CSV
    for fila in data_csv:
        escritor_csv.writerow(fila)

# Crear un DataFrame desde los datos CSV originales
data = {
    "Date": data_date,
    "Name": data_name,
    "HR": data_hr
}
# print(data_hr)

# TEST 01
# df = pd.DataFrame(data)
# # Realizar un pivot para obtener un DataFrame con una columna para cada jugador
# # pivot_df = df.pivot(index="Date", columns="Name", values="HR")
# pivot_df = df.pivot_table(index="Date", columns="Name", values="HR", aggfunc='sum', fill_value=0)
# # Rellenar los valores NaN con 0 (si un jugador no tiene HR en una fecha, se establecerá como 0)
# pivot_df.fillna(0, inplace=True)
# # Guardar el DataFrame pivot en un nuevo archivo CSV
# ruta_csv = os.path.join(directorio_actual, directory + '_pivot.csv')
# pivot_df.to_csv(ruta_csv)

# TEST 02
print(table)
# Obtener la lista de nombres de bateadores únicos
ruta_csv = os.path.join(directorio_actual, directory + '_pivot.csv')
nombres_bateadores = set()
for datos_bateadores in table.values():
    nombres_bateadores.update(datos_bateadores.keys())

# Abrir el archivo CSV en modo de escritura
with open(ruta_csv, 'w', newline='', encoding="utf-8") as csvfile:
    # Crear un objeto escritor CSV
    csv_writer = csv.writer(csvfile)

    # Escribir la primera fila con los encabezados (nombre de bateadores)
    encabezados = ['Fecha'] + list(nombres_bateadores)
    csv_writer.writerow(encabezados)

    # Iterar a través del diccionario y escribir los datos en el archivo CSV
    for fecha, datos_bateadores in table.items():
        fila = [fecha]
        for bateador in nombres_bateadores:
            fila.append(datos_bateadores.get(bateador, 0))
        csv_writer.writerow(fila)

# TEST 03
# df = pd.DataFrame(data)
# # Agrupar los datos por fecha y nombre, y sumar los valores de 'HR'
# df = df.groupby(['Date', 'Name'])['HR'].sum().reset_index()
# # Realizar un pivot después de eliminar los duplicados
# pivot_df = df.pivot(index="Date", columns="Name", values="HR")
# pivot_df.fillna(0, inplace=True)
# ruta_csv = os.path.join(directorio_actual, directory + '_pivot.csv')
# pivot_df.to_csv(ruta_csv)


import os, logging
from ConfigParser import NoSectionError, NoOptionError
from fnmatch import fnmatch

from gitosis import group

def pathMatchPatterns(path, repos):
    """
    Check existence of given path against list of path patterns

    The pattern definition is the as fnmatch.fnmatch.
    """
    for repo in repos:
        if fnmatch(path, repo):
            return True
    return False

def haveAccess(config, user, mode, path):
    """
    Map request for write access to allowed path.

    Note for read-only access, the caller should check for write
    access too.

    Returns ``None`` for no access, or a tuple of toplevel directory
    containing repositories and a relative path to the physical repository.
    """
    log = logging.getLogger('gitosis.access.haveAccess')

    log.debug(
        'Access check for %(user)r as %(mode)r on %(path)r...'
        % dict(
        user=user,
        mode=mode,
        path=path,
        ))

    basename, ext = os.path.splitext(path)
    if ext == '.git':
        log.debug(
            'Stripping .git suffix from %(path)r, new value %(basename)r'
            % dict(
            path=path,
            basename=basename,
            ))
        path = basename

    sections = ['group %s' % item for item in
                 group.getMembership(config=config, user=user)]
    sections.insert(0, 'user %s' % user)

    for sectname in sections:
        try:
            repos = config.get(sectname, mode)
        except (NoSectionError, NoOptionError):
            repos = []
        else:
            repos = repos.split()

        mapping = None

        if pathMatchPatterns(path, repos):
            log.debug(
                'Access ok for %(user)r as %(mode)r on %(path)r'
                % dict(
                user=user,
                mode=mode,
                path=path,
                ))
            mapping = path
        else:
            try:
                mapping = config.get(sectname,
                                     'map %s %s' % (mode, path))
            except (NoSectionError, NoOptionError):
                pass
            else:
                log.debug(
                    'Access ok for %(user)r as %(mode)r on %(path)r=%(mapping)r'
                    % dict(
                    user=user,
                    mode=mode,
                    path=path,
                    mapping=mapping,
                    ))

        if mapping is not None:
            prefix = None
            try:
                prefix = config.get(sectname, 'repositories')
            except (NoSectionError, NoOptionError):
                try:
                    prefix = config.get('gitosis', 'repositories')
                except (NoSectionError, NoOptionError):
                    prefix = 'repositories'

            log.debug(
                'Using prefix %(prefix)r for %(path)r'
                % dict(
                prefix=prefix,
                path=mapping,
                ))
            return (prefix, mapping)


import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)

import os
from io import BytesIO
from subprocess import call

import cv2
import numpy as np
import onnxruntime
import requests
import streamlit as st
from PIL import Image

from utils import Preprocess

@st.experimental_memo(show_spinner=False)
def download_model():
    call('gdown -q "1bjXhuTt0CNc5tqNN8ogcfB_F1V_RxnXM" -O models/', shell=True)

st.set_option('deprecation.showfileUploaderEncoding', False)
st.title("Cartoon Image Generator")
st.text("Either Upload or Provide URL of Your Image")

with st.spinner('Wait for model download...'):
    download_model()

path = st.text_input('Enter Image URL to Classify...')
img_file_buffer = st.file_uploader("Upload Your Image to Cartoonify...")

if img_file_buffer is not None:
    image = img_file_buffer
    image_out = Image.open(img_file_buffer)
    st.image(image_out, caption='Your Image', use_column_width=False, width=400)
    im1 = image_out.save("input.jpg")
    image_input = cv2.imread("input.jpg")
    if im1:
        call('rm -R "input.jpg" ', shell=True)
else:
    if path:
        test_image = repr(path)
    else:
        test_image = r'https://6.vikiplatform.com/image/c65419246af34d5982e5e9f1d59b0e0d.jpg'
    image_input = requests.get(test_image, stream=True).raw
    image_input = np.asarray(bytearray(image_input.read()), dtype="uint8")
    image_input = cv2.imdecode(image_input, cv2.IMREAD_COLOR)

    defualt_url = 'https://6.vikiplatform.com/image/c65419246af34d5982e5e9f1d59b0e0d.jpg'
    image_url_content = requests.get(defualt_url).content
    image_out = Image.open(BytesIO(image_url_content))
    st.image(image_out, caption='Your Image', use_column_width=False, width=400)

class Photo2Cartoon:
    def __init__(self):
        self.pre = Preprocess()

        assert os.path.exists(
            './models/photo2cartoon_weights.onnx'), "[Step1: load weights] Can not find 'photo2cartoon_weights.onnx' in folder 'models!!!'"
        self.session = onnxruntime.InferenceSession(
            './models/photo2cartoon_weights.onnx')
        print('[Step1: load weights] success!')

    def inference(self, img):
        # face alignment and segmentation
        face_rgba = self.pre.process(img)
        if face_rgba is None:
            print('[Step2: face detect] can not detect face!!!')
            return None

        print('[Step2: face detect] success!')
        face_rgba = cv2.resize(face_rgba, (256, 256), interpolation=cv2.INTER_AREA)
        face = face_rgba[:, :, :3].copy()
        mask = face_rgba[:, :, 3][:, :, np.newaxis].copy() / 255.
        face = (face*mask + (1-mask)*255) / 127.5 - 1

        face = np.transpose(face[np.newaxis, :, :, :],
                            (0, 3, 1, 2)).astype(np.float32)

        # inference
        cartoon = self.session.run(['output'], input_feed={'input': face})

        # post-process
        cartoon = np.transpose(cartoon[0][0], (1, 2, 0))
        cartoon = (cartoon + 1) * 127.5
        cartoon = (cartoon * mask + 255 * (1 - mask)).astype(np.uint8)
        cartoon = cv2.cvtColor(cartoon, cv2.COLOR_RGB2BGR)
        print('[Step3: photo to cartoon] success!')
        return cartoon

if st.button('Generate'):
    if image_input is None:
        st.error("Please Upload Your Image")
    else:
        with st.spinner('Abra ka dabra...'):
            img = cv2.cvtColor(image_input, cv2.COLOR_BGR2RGB)
            c2p = Photo2Cartoon()
            cartoon = c2p.inference(img)
            if cartoon is not None:
                cv2.imwrite("cartoon_result.png", cartoon)
                st.image("cartoon_result.png", caption='Cartoon Image',
                        use_column_width=False, width=300)
                with open("cartoon_result.png", "rb") as file:
                    btn = st.download_button(
                        label="Download Cartoon Image",
                        data=file,
                        file_name="cartoon_result.png",
                        mime="image/png"
                    )
                st.success('Cartoon portrait has been made successfully!')


"""tutorial URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.9/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
from tutorial.quickstart import views, moduletest
from django.conf.urls import patterns, url

#Rita http://www.django-rest-framework.org/

# Serializers define the API representation.
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')

# ViewSets define the view behavior.
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    # ViewSets define the view behavior for records.
#class RecordViewSet:
    #print "Indivo Testing"
    #queryset = User.objects.all()
    #serializer_class = UserSerializer

"""
class Shape:
   def __init__(self,x,y):
        self.x = x
        self.y = y
    description = "This shape has not been described yet"
    author = "Nobody has claimed to make this shape yet"
    def area(self):
        return self.x * self.y
    def perimeter(self):
        return 2 * self.x + 2 * self.y
    def describe(self,text):
        self.description = text
    def authorName(self,text):
        self.author = text
    def scaleSize(self,scale):
        self.x = self.x * scale
    self.y = self.y * scale

rectangle = Shape(100,45)
#print rectangle.area()

# Below is the function
def hello():
    print "hello"
    return 1234

"""
"""
class RecordList:
    print moduletest.ageofqueen
cfcpiano = moduletest.Piano()
cfcpiano.printdetails()
"""

# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'groups', views.GroupViewSet)
#router.register(r'records', RecordList)

# Comment out by rita
"""
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
"""

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.

"""
urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    url(r'^authors/$', views.AuthorView.as_view(), name='author-list')
]"""

urlpatterns = patterns(
    'talk.views',
    url(r'^$', 'home'),

    # api
    url(r'^api/v1/posts/$', 'post_collection'),
    url(r'^api/v1/posts/(?P<pk>[0-9]+)$', 'post_element')
)


"""Business model"""

# Django
from django.db import models
from django.core.validators import RegexValidator

# Utilities
from api.utils.models import BaseModel

class Business(BaseModel):
    """ Business model. """

    name = models.CharField(max_length = 150)
    image = models.CharField(max_length=150)
    phone_regex = RegexValidator(
        regex=r'\+?1?\d{9,15}$',
        message='Phone nubmer must be entered in the format : +999999999. Up to 15 digits allowed.'
    )
    phone_number = models.CharField(
        validators=[phone_regex],
        max_length=17,
        blank=True
    )
    email = models.EmailField(
        'email address',
        unique=True,
        error_messages={
            'unique': 'A user with that email already exists.'
        }
    )
    rating = models.IntegerField()
    description = models.CharField(max_length=250)

    # admin_profiles = models.ManyToManyField('guatudu.AdminProfile')

    def __str__(self):
        """ Return business string representation"""
        return str(self.name)

    class Meta:
        db_table = 'business'


import torch.nn as nn
import torch
import torch.nn.functional as F
from torch.autograd import Variable
import numpy as np

## utils
from models import model_config, model_utils, model_res34unet, se_layer
config = model_config.res34unet_params
_c = model_utils._c
##

class Interpolate(nn.Module):
    def __init__(self, size=None, mode='bilinear'):
        super(Interpolate, self).__init__()
        self.interp = nn.functional.interpolate
        self.size = size
        self.mode = mode

    def forward(self, x):
        x = self.interp(x, size=self.size, mode=self.mode, align_corners=True)
        return x

class SEHyperRes34Unet(nn.Module):

    def __init__(self):
        super().__init__()

        resunet = model_res34unet.Res34Unet()

        out_e5 = config['out_encoder5']
        out_e4 = config['out_encoder4']
        out_e3 = config['out_encoder3']
        out_e2 = config['out_encoder2']

        out_bot = config['out_bottom']

        out_d5 = config['out_decoder5']
        out_d4 = config['out_decoder4']
        out_d3 = config['out_decoder3']
        out_d2 = config['out_decoder2']
        out_d1 = config['out_decoder1']

        out_logit = config['out_logit']

        self.encoder1 = nn.Sequential(
            resunet.encoder1
        )
        self.encoder2 = nn.Sequential(
            resunet.encoder2,
            se_layer.scSELayer(out_e2)
        )
        self.encoder3 = nn.Sequential(
            resunet.encoder3,
            se_layer.scSELayer(out_e3)
        )
        self.encoder4 = nn.Sequential(
            resunet.encoder4,
            se_layer.scSELayer(out_e4)
        )
        self.encoder5 = nn.Sequential(
            resunet.encoder5,
            se_layer.scSELayer(out_e5)
        )

        self.bottom = resunet.bottom

        self.decoder5 = nn.Sequential(
            resunet.decoder5,
            se_layer.scSELayer(out_d5)
        )
        self.decoder4 = nn.Sequential(
            resunet.decoder4,
            se_layer.scSELayer(out_d4)
        )
        self.decoder3 = nn.Sequential(
            resunet.decoder3,
            se_layer.scSELayer(out_d3)
        )
        self.decoder2 = nn.Sequential(
            resunet.decoder2,
            se_layer.scSELayer(out_d2)
        )
        self.decoder1 = nn.Sequential(
            resunet.decoder1,
            se_layer.scSELayer(out_d1)
        )

        self.hyper_bot = nn.Conv2d(out_bot,  out_d1, kernel_size=1, padding=0)

        self.hyper5 = nn.Sequential(
            nn.Conv2d(out_d5,  out_d1, kernel_size=1, padding=0),
        )

        self.hyper4 = nn.Sequential(
            nn.Conv2d(out_d4,  out_d1, kernel_size=1, padding=0),
        )

        self.hyper3 = nn.Sequential(
            nn.Conv2d(out_d3,  out_d1, kernel_size=1, padding=0),
        )

        self.hyper2 = nn.Sequential(
            nn.Conv2d(out_d2,  out_d1, kernel_size=1, padding=0),
        )

        self.hyper1 = nn.Sequential(
            nn.Conv2d(out_d1,  out_d1, kernel_size=1, padding=0),
        )

        self.hypercol = nn.Conv2d(out_d1*6,  out_d1, kernel_size=3, padding=1)
        self.dropout  = nn.Dropout2d(p=0.4,inplace=True)

        self.logit = nn.Sequential(
            nn.Conv2d(out_d1,  out_logit, kernel_size=1, padding=0),
        )

    def forward(self, x):

        e1  = self.encoder1(x)
        e2  = self.encoder2(e1)
        e3  = self.encoder3(e2)
        e4  = self.encoder4(e3)
        e5  = self.encoder5(e4)

        bot = self.bottom(e5)

        d  = self.decoder5(_c(bot,e5))
        h  = _c(
                F.upsample(
                    self.hyper_bot(bot), scale_factor=2, mode='bilinear', align_corners=True),
                self.hyper5(d)
            )
        d  = self.decoder4(_c(d,e4))
        h  = _c(
                F.upsample(
                    h, scale_factor=2, mode='bilinear', align_corners=True),
                self.hyper4(d)
            )
        d  = self.decoder3(_c(d,e3))
        h  = _c(
                F.upsample(
                    h, scale_factor=2, mode='bilinear', align_corners=True),
                self.hyper3(d)
            )
        d  = self.decoder2(_c(d,e2))
        h  = _c(
                F.upsample(
                    h, scale_factor=2, mode='bilinear', align_corners=True),
                self.hyper2(d)
            )
        d  = self.decoder1(d)
        h  = _c(
                F.upsample(
                    h, scale_factor=2, mode='bilinear', align_corners=True),
                self.hyper1(d)
            )

        h  = self.hypercol(h)
        h  = self.dropout(h)

        h  = self.logit(h)
        return h


from elasticsearch import Elasticsearch
from itertools import permutations
from whoswho import who

SEARCH_SIZE = 100
INDEX = 'authors'

def get_authors_body(search_after=None) -> dict:
    body = {
        'size': SEARCH_SIZE,
        'query': {
            'bool': {
                'must': [
                    {
                        'nested': {
                            'path': 'papers',
                            'query': {
                                'exists': {
                                    'field': 'papers'
                                }
                            }
                        }
                    }
                ]
            }
        },
        'sort': [
            {
                '_id': 'asc'
            }
        ]
    }

    if search_after:
        body['search_after'] = [search_after]

    return body

def match_authors_body(name: str, search_after=None):
    body = {
        'size': SEARCH_SIZE,
        "query": {
            "bool": {
                "must": [
                    {
                        "nested": {
                            "path": "papers",
                            "query": {
                                "exists": {
                                    "field": "papers"
                                }
                            }
                        }
                    }
                ],
                "filter": [
                    {
                        "match": {
                            "name": name
                        }
                    }
                ]
            }
        },
        'sort': [
            {
                '_id': 'asc'
            }
        ]
    }

    if search_after:
        body['search_after'] = [search_after]

    return body

def match_authors(author1: str, author2: str) -> bool:
    if author1 == author2:
        return True

    # match according to the package whoswho
    # case insensitive
    # different name formats
    # handles excess dots and commas
    if who.match(author1, author2):
        return True

    # handle the option when one of the names is just the last name
    if (len(author1.split()) == 1
            and len(author2.split()) == 2
            and (author2.lower().split()[1] == author1.lower()
                 or author2.lower().split(', ')[0] == author1.lower())):
        return True

    if (len(author2.split()) == 1
            and len(author1.split()) == 2
            and (author1.lower().split()[1] == author2.lower()
                 or author1.lower().split(', ')[0] == author2.lower())):
        return True

    # remove excess spaces, separating dots and commas
    mod_author1 = author1.lower().split()
    mod_author1 = ' '.join(
        filter(None, [x.strip('.,') for x in mod_author1])
    )
    mod_author2 = author2.lower().split()
    mod_author2 = ' '.join(
        filter(None, [x.strip('.,') for x in mod_author2])
    )

    # match after removing dots and commas
    if mod_author1 == mod_author2:
        return True

    # at this point both names split into lists must be of same length
    if len(mod_author1) != len(mod_author2):
        return False

    # match permutations
    author1_perm = permutations(mod_author1.split())
    author1_perm = [' '.join(x) for x in author1_perm]
    if mod_author2 in author1_perm:
        return True

    return False

def match_authors_list(authors1: list, authors2: list) -> bool:
    for author1 in authors1:
        for author2 in authors2:
            if match_authors(author1, author2):
                return True

    return False

def main():
    es = Elasticsearch()
    processed_authors = 0

    print('Getting initial authors batch...')
    authors = es.search(index=INDEX, body=get_authors_body())

    while authors['hits']['hits']:
        print('Processing authors from _id: {} to _id: {}'.format(
            authors['hits']['hits'][0]['sort'][0],
            authors['hits']['hits'][-1]['sort'][0]
        ))

        last_id = authors['hits']['hits'][-1]['sort'][0]
        last_match_id = None

        for author in authors['hits']['hits']:
            is_modified = False
            docs_to_delete = list()

            # get coauthors and fields of study for current author
            coauthors1 = list()
            fields1 = list()
            for paper in author['_source']['papers']:
                if paper['coauthors']:
                    coauthors1 += paper['coauthors'].split('\n')
                if paper['fields_of_study']:
                    fields1 += paper['fields_of_study'].split('\n')

            if not coauthors1 and not fields1:
                continue

            coauthors1 = list(set(coauthors1))
            fields1 = list(set(fields1))

            matched_authors = es.search(
                index=INDEX,
                body=match_authors_body(author['_source']['name'],
                                        last_match_id)
            )

            while matched_authors['hits']['hits']:
                last_match_id = matched_authors['hits']['hits'][-1]['sort'][0]

                for match in matched_authors['hits']['hits']:
                    if match['_id'] == author['_id']:
                        continue

                    is_match = match_authors(author['_source']['name'],
                                             match['_source']['name'])

                    if is_match:
                        # get all coauthors and fields of study
                        coauthors2 = list()
                        fields2 = list()
                        for paper in match['_source']['papers']:
                            if paper['coauthors']:
                                coauthors2 += paper['coauthors'].split('\n')
                            if paper['fields_of_study']:
                                fields2 += paper['fields_of_study'].split('\n')

                        if not coauthors2 and not fields2:
                            continue

                        matched_fields = list(
                            set(fields1).intersection(fields2)
                        )

                        matched_coauthors = list(
                            set(coauthors1).intersection(coauthors2)
                        )

                        if not matched_coauthors:
                            matched_coauthors = match_authors_list(coauthors1,
                                                                   coauthors2)

                        # match both coauthors and fields
                        # match fields and empty coauthors
                        # match coauthors and empty fields
                        if ((matched_coauthors and matched_fields)
                                or (matched_fields
                                    and (not coauthors1 or not coauthors2))
                                or (matched_coauthors
                                    and (not fields1 or not fields2))):

                            if not author['_source']['other_names']:
                                author['_source']['other_names'] = list()

                            author['_source']['other_names'].append(
                                {'name': match['_source']['name']})
                            author['_source']['papers'] += match['_source'][
                                'papers']

                            is_modified = True
                            docs_to_delete.append(match['_id'])

                matched_authors = es.search(
                    index=INDEX,
                    body=match_authors_body(author['_source']['name'],
                                            last_match_id)
                )

            # update author
            if is_modified:
                print('Updating document with _id: {}'.format(author['_id']))
                print('Deleting documents: {}'.format(docs_to_delete))
                es.index(index=INDEX, id=author['_id'], body=author['_source'])
                for doc in docs_to_delete:
                    es.delete(index=INDEX, id=doc)

        processed_authors += len(authors['hits']['hits'])
        print('Done processing authors {}/52847108'.format(processed_authors))
        print('Getting authors after _id: {}'.format(last_id))
        authors = es.search(index=INDEX,
                            body=get_authors_body(search_after=last_id))

if __name__ == '__main__':
    main()


import regex as reg
import gdb

class RobinHoodPrinter(object):
    "Print a robin hood hashmap"

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

    def children(self):
        childCount = int(self.val['mNumElements'])
        keyvalPtr = self.val['mKeyVals']
        infoPtr = self.val['mInfo']
        result = []
        for i in range(0, childCount):
            while int(infoPtr.dereference()) == 0:
                infoPtr += 1
                keyvalPtr += 1

            if bool(self.val['is_flat']):
                keyval = ("key_" + str(i), keyvalPtr.dereference()['mData']['first'])
                result.append(keyval)
                keyval = ("value_" + str(i), keyvalPtr.dereference()['mData']['second'])
                result.append(keyval)
            elif bool(self.val['is_map']):
                keyval = ("key_" + str(i), keyvalPtr.dereference()['mData'].dereference()['first'])
                result.append(keyval)
                keyval = ("value_" + str(i), keyvalPtr.dereference()['mData'].dereference()['second'])
                result.append(keyval)
            else:
                keyval = (str(i), keyvalPtr.dereference()['mData'])
                result.append(keyval)

            infoPtr += 1
            keyvalPtr += 1
        return result

    def to_string(self):
        if bool(self.val['is_flat']):
            return 'robin_hood::unordered_flat_map with ' + str(int(self.val['mNumElements'])) + ' elements'
        elif bool(self.val['is_map']):
            return 'robin_hood::unordered_node_map with ' + str(int(self.val['mNumElements'])) + ' elements'
        elif bool(self.val['is_set']):
            return 'robin_hood::unordered_set with ' + str(int(self.val['mNumElements'])) + ' elements'

    def display_hint(self):
        if(bool(self.val['is_flat']) or bool(self.val['is_map'])):
            return 'map'
        else:
            return 'array'

def robin_hood_lookup_function(val):
    lookup_tag = val.type.strip_typedefs().tag
    if lookup_tag is None:
        return None
    regex = reg.compile("^robin_hood::detail::Table<.*>$")
    nodeTag = reg.compile("^robin_hood::detail::Table<.*>::DataNode<.*>$")
    iterTag = reg.compile("^robin_hood::detail::Table<.*>::Iter<.*>$")
    if regex.match(lookup_tag) and not nodeTag.match(lookup_tag) and not iterTag.match(lookup_tag):
        return RobinHoodPrinter(val)
    return None

def register_robinhood_printers():
    gdb.pretty_printers.append(robin_hood_lookup_function)


import json
import os
import logging

from shutil import copy2
from time import strftime, gmtime

from configurations import CONFIG_DIR
from data import EXPERIMENTS_RUNS_DIR, VECTORS_DIR

parameters = {}

class ParameterStore(type):
    def __getitem__(cls, key: str):
        global parameters
        return parameters[key]

    def __setitem__(cls, key, value):
        global parameters
        parameters[key] = value

    def __contains__(self, item):
        global parameters
        return item in parameters

class Configuration(object, metaclass=ParameterStore):
    """
    Configuration class that contains all the parameters of the experiment.
    The experiment parameters are loaded from the corresponding configuration file
    (e.g. "finer_transformer.json)

    It instantiates the experiment logger.
    The output of the experiment is saved at the EXPERIMENTS_RUNS_DIR (data/experiments_runs)
    """

    @staticmethod
    def configure(method, mode):
        global parameters

        os.makedirs(name=os.path.join(EXPERIMENTS_RUNS_DIR), exist_ok=True)
        os.makedirs(name=os.path.join(VECTORS_DIR), exist_ok=True)

        if method in ['transformer', 'bilstm']:
            config_filepath = os.path.join(CONFIG_DIR, f'{method}.json')
            if os.path.exists(config_filepath):
                with open(config_filepath) as config_file:
                    parameters = json.load(config_file)
            else:
                raise Exception(f'Configuration file "{method}.json" does not exist')
        else:
            raise NotImplementedError(f'"FINER-139" experiment does not support "{method}" method')

        parameters['task'] = {}
        parameters['task']['model'] = method
        parameters['task']['mode'] = mode
        parameters['configuration_filename'] = f'{method}.json'

        # Setup Logging
        timestamp = strftime("%Y_%m_%d_%H_%M_%S", gmtime())
        log_name = f"FINER139_{timestamp}"

        # Set experiment_path and create necessary directories
        if mode == 'train':
            experiment_path = os.path.join(EXPERIMENTS_RUNS_DIR, log_name)
            os.makedirs(name=os.path.join(experiment_path, 'model'), exist_ok=True)
            copy2(src=os.path.join(CONFIG_DIR, f'{method}.json'),
                  dst=os.path.join(experiment_path, f'{method}.json'))

        elif mode == 'evaluate':
            pretrained_model = parameters['evaluation']['pretrained_model']
            if pretrained_model is None or pretrained_model.strip() == '':
                raise Exception(f'No pretrained_model provided in configuration')
            if os.path.exists(os.path.join(EXPERIMENTS_RUNS_DIR, pretrained_model, 'model')):
                experiment_path = os.path.join(EXPERIMENTS_RUNS_DIR, pretrained_model)
                pretrained_model_path = os.path.join(experiment_path, 'model')
            else:
                raise Exception(f'Model "{pretrained_model}" does not exist')

            configuration_path = os.path.join(experiment_path, f'{method}.json')
            if os.path.exists(configuration_path):
                with open(configuration_path) as fin:
                    original_parameters = json.load(fin)
                    for key in ['train_parameters', 'general_parameters', 'hyper_parameters']:
                        parameters[key] = original_parameters[key]
                    parameters['task']['mode'] = mode
            else:
                raise Exception(f'Configuration "{configuration_path}" does not exist')

            parameters['evaluation']['pretrained_model_path'] = pretrained_model_path
            log_name = f"{log_name}_EVALUATE_{'_'.join(parameters['evaluation']['pretrained_model'].split(os.sep))}"

        else:
            raise Exception(f'Mode "{mode}" is not supported')

        parameters['task']['log_name'] = log_name
        parameters['experiment_path'] = experiment_path

        # If in debug mode set workers and max_queue_size to minimum and multiprocessing to False
        if parameters['general_parameters']['debug']:
            parameters['general_parameters']['workers'] = 1
            parameters['general_parameters']['max_queue_size'] = 1
            parameters['general_parameters']['use_multiprocessing'] = False
            parameters['general_parameters']['run_eagerly'] = True

        # Clean loggers
        root = logging.getLogger()
        if root.handlers:
            for handler in root.handlers:
                root.removeHandler(handler)

        logging.basicConfig(level=logging.INFO,
                            format='%(message)s',
                            datefmt='%m-%d %H:%M',
                            filename=os.path.join(experiment_path, f'{log_name}.txt'),
                            filemode='a')

        # define a Handler which writes INFO messages or higher to the sys.stderr
        console = logging.StreamHandler()
        console.setLevel(logging.INFO)
        # set a format which is simpler for console use
        formatter = logging.Formatter('%(message)s')
        # tell the handler to use this format
        console.setFormatter(formatter)
        # add the handler to the root logger
        logging.getLogger('').addHandler(console)

    @classmethod
    def __getitem__(cls, item: str):
        global parameters
        return parameters[item]


"""
Create a new file out.xlsx from a TM1 application file.
"""
import configparser
config = configparser.ConfigParser()
config.read('..\config.ini')

from TM1py import TM1Service

with TM1Service(**config['tm1srv01']) as tm1:
    # path in TM1 Application-Tree
    path = 'Finance/P&L.xlsx'

    # get the application
    application = tm1.applications.get(path)

    # write it to xlsx file
    application.to_xlsx("out.xlsx")