from xml.sax.saxutils import quoteattr
import argparse
import os
import re
import sys
import unittest

# Read at most 100MB of a test log.
# Rarely would this be exceeded, but we don't want to end up
# swapping, etc.
MAX_MEMORY = 100 * 1024 * 1024

START_TESTCASE_RE = re.compile(r'\[ RUN\s+\] (.+)$')
END_TESTCASE_RE = re.compile(r'\[\s+(?:OK|FAILED)\s+\] (.+)$')
ASAN_ERROR_RE = re.compile('ERROR: (AddressSanitizer|LeakSanitizer)')
TSAN_ERROR_RE = re.compile('WARNING: ThreadSanitizer.*')
END_TSAN_ERROR_RE = re.compile('SUMMARY: ThreadSanitizer.*')
UBSAN_ERROR_RE = re.compile(r'SUMMARY: UndefinedBehaviorSanitizer')
FATAL_LOG_RE = re.compile(r'^F\d\d\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d\s+\d+ (.*)')
LINE_RE = re.compile(r"^.*$", re.MULTILINE)
STACKTRACE_ELEM_RE = re.compile(r'^    @')
IGNORED_STACKTRACE_ELEM_RE = re.compile(
  r'(google::logging|google::LogMessage|\(unknown\)| testing::)')
TEST_FAILURE_RE = re.compile(r'.*\d+: Failure$')
GLOG_LINE_RE = re.compile(r'^[WIEF]\d\d\d\d \d\d:\d\d:\d\d')

class ParsedTest(object):
  """
  The LogParser creates one instance of this class for each test that is discovered
  while parsing the log.
  """
  def __init__(self, test_name):
    self.test_name = test_name
    self.errors = []

class LogParser(object):
  """
  Parser for textual gtest output
  """
  def __init__(self):
    self._tests = []
    self._cur_test = None

  @staticmethod
  def _consume_rest(line_iter):
    """ Consume and return the rest of the lines in the iterator. """
    return [l for l in line_iter]

  @staticmethod
  def _consume_until(line_iter, end_re):
    """
    Consume and return lines from the iterator until one matches 'end_re'.
    The line matching 'end_re' will not be returned, but will be consumed.
    """
    ret = []
    for line in line_iter:
      if end_re.search(line):
        break
      ret.append(line)
    return ret

  @staticmethod
  def _remove_glog_lines(lines):
    """ Remove any lines from the list of strings which appear to be GLog messages. """
    return [l for l in lines if not GLOG_LINE_RE.search(l)]

  def _record_error(self, error):
    if self._cur_test is None:
      # TODO(todd) would be nice to have a more specific name indicating which
      # test file caused the issue.
      self._start_test("General.OutsideOfAnyTestCase")
      self._record_error(error)
      self._end_test()
    else:
      self._cur_test.errors.append(error)

  def _start_test(self, test_name):
    assert test_name is not None
    self._cur_test = ParsedTest(test_name)
    self._tests.append(self._cur_test)

  def _end_test(self):
    self._cur_test = None

  @staticmethod
  def _fast_re(substr, regexp, line):
    """
    Implements a micro-optimization: returns true if 'line' matches 'regexp,
    but short-circuited by a much faster check whether 'line' contains 'substr'.
    This provides a big speed-up since substring searches execute much more
    quickly than regexp matches.
    """
    if substr not in line:
      return None
    return regexp.search(line)

  def parse_text(self, log_text):
    # Iterate over the lines, using finditer instead of .split()
    # so that we don't end up doubling memory usage.
    def line_iter():
      for match in LINE_RE.finditer(log_text):
        yield match.group(0)
    self.parse_lines(line_iter())

  def parse_lines(self, line_iter):
    """
    Arguments:
      lines: generator which should yield lines of log output
    """
    for line in line_iter:
      # Track the currently-running test case
      m = self._fast_re('RUN', START_TESTCASE_RE, line)
      if m:
        self._start_test(m.group(1))
        continue

      m = self._fast_re('[', END_TESTCASE_RE, line)
      if m:
        self._end_test()
        continue

      # Look for ASAN errors.
      m = self._fast_re('ERROR', ASAN_ERROR_RE, line)
      if m:
        error_signature = line + "\n"
        # ASAN errors kill the process, so we consume the rest of the log
        # and remove any lines that don't look like part of the stack trace
        asan_lines = self._remove_glog_lines(self._consume_rest(line_iter))
        error_signature += "\n".join(asan_lines)
        self._record_error(error_signature)
        continue

      # Look for TSAN errors
      m = self._fast_re('ThreadSanitizer', TSAN_ERROR_RE, line)
      if m:
        error_signature = m.group(0)
        error_signature += "\n".join(self._remove_glog_lines(
          self._consume_until(line_iter, END_TSAN_ERROR_RE)))
        self._record_error(error_signature)
        continue

      # Look for UBSAN errors
      m = self._fast_re('UndefinedBehavior', UBSAN_ERROR_RE, line)
      if m:
        # UBSAN errors are a single line.
        # TODO: there is actually some info on the previous line but there
        # is no obvious prefix to look for.
        self._record_error(line)
        continue

      # Look for test failures
      # - slight micro-optimization to check for substring before running the regex
      m = self._fast_re('Failure', TEST_FAILURE_RE, line)
      if m:
        error_signature = m.group(0) + "\n"
        error_signature += "\n".join(self._remove_glog_lines(
          self._consume_until(line_iter, END_TESTCASE_RE)))
        self._record_error(error_signature)
        self._end_test()
        continue

      # Look for fatal log messages (including CHECK failures)
      # - slight micro-optimization to check for 'F' before running the regex
      m = line and line[0] == 'F' and FATAL_LOG_RE.search(line)
      if m:
        error_signature = m.group(1) + "\n"
        remaining_lines = self._consume_rest(line_iter)
        remaining_lines = [l for l in remaining_lines if STACKTRACE_ELEM_RE.search(l) and
                           not IGNORED_STACKTRACE_ELEM_RE.search(l)]
        error_signature += "\n".join(remaining_lines)
        self._record_error(error_signature)

    # Sometimes we see crashes that the script doesn't know how to parse.
    # When that happens, we leave a generic message to be picked up by Jenkins.
    if self._cur_test and not self._cur_test.errors:
      self._record_error("Unrecognized error type. Please see the error log for more information.")

  # Return failure summary formatted as text.
  def text_failure_summary(self):
    msgs = []
    for test in self._tests:
      for error in test.errors:
        msgs.append("%s: %s\n" % (test.test_name, error))

    return "\n".join(msgs)

  def xml_failure_summary(self):
    # Example format:
    """
    <testsuites>
      <testsuite name="ClientTest">
        <testcase name="TestReplicatedMultiTabletTableFailover" classname="ClientTest">
          <error message="Check failed: ABC != XYZ">
            <![CDATA[ ... stack trace ... ]]>
          </error>
        </testcase>
      </testsuite>
    </testsuites>
    """
    ret = ""

    cur_test_suite = None
    ret += '<testsuites>\n'

    found_test_suites = False
    for test in self._tests:
      if not test.errors:
        continue

      (test_suite, test_case) = test.test_name.split(".")

      # Test suite initialization or name change.
      if test_suite and test_suite != cur_test_suite:
        if cur_test_suite:
          ret += '  </testsuite>\n'
        cur_test_suite = test_suite
        ret += '  <testsuite name="%s">\n' % cur_test_suite
        found_test_suites = True

      # Print each test case.
      ret += '    <testcase name="%s" classname="%s">\n' % (test_case, cur_test_suite)
      errors = "\n\n".join(test.errors)
      first_line = re.sub("\n.*", '', errors)
      ret += '      <error message=%s>\n' % quoteattr(first_line)
      ret += '<![CDATA[\n'
      ret += errors
      ret += ']]>\n'
      ret += '      </error>\n'
      ret += '    </testcase>\n'

    if found_test_suites:
      ret += '  </testsuite>\n'
    ret += '</testsuites>\n'
    return ret

# Parse log lines and return failure summary formatted as text.
#
# Print failure summary based on desired output format.
# 'tests' is a list of all tests run (in order), not just the failed ones.
# This allows us to print the test results in the order they were run.
# 'errors_by_test' is a dict of lists, keyed by test name.
#
# This helper function is part of a public API called from test_result_server.py
def extract_failure_summary(log_text, format='text'):
  p = LogParser()
  p.parse_text(log_text)
  if format == 'text':
    return p.text_failure_summary()
  else:
    return p.xml_failure_summary()

class Test(unittest.TestCase):
  _TEST_DIR = os.path.join(os.path.dirname(__file__), "build-support-test-data")

  def __init__(self, *args, **kwargs):
    super(Test, self).__init__(*args, **kwargs)
    self.regenerate = os.environ.get('REGENERATE_TEST_EXPECTATIONS') == '1'

  def test_all(self):
    for child in os.listdir(self._TEST_DIR):
      if not child.endswith(".txt") or '-out' in child:
        continue
      base, _ = os.path.splitext(child)

      p = LogParser()
      with open(os.path.join(self._TEST_DIR, child)) as f:
        p.parse_text(f.read())
      self._do_test(p.text_failure_summary(), base + "-out.txt")
      self._do_test(p.xml_failure_summary(), base + "-out.xml")

  def _do_test(self, got_value, filename):
    path = os.path.join(self._TEST_DIR, filename)
    if self.regenerate:
      print("Regenerating %s" % path)
      with open(path, "w") as f:
        f.write(got_value)
    else:
      with open(path) as f:
        self.assertEquals(got_value, f.read())

def main():
  parser = argparse.ArgumentParser()
  parser.add_argument("-x", "--xml",
                      help="Print output in JUnit report XML format (default: plain text)",
                      action="store_true")
  parser.add_argument("path", nargs="?", help="File to parse. If not provided, parses stdin")
  args = parser.parse_args()

  if args.path:
    in_file = open(args.path)
  else:
    in_file = sys.stdin
  log_text = in_file.read(MAX_MEMORY)
  if in_file is not sys.stdin:
    in_file.close()
  format = args.xml and 'xml' or 'text'
  sys.stdout.write(extract_failure_summary(log_text, format))

if __name__ == "__main__":
  main()


from django.urls import path
from . import views
from django.shortcuts import render, redirect

urlpatterns = [
    path("", views.index ,name="index"),
    path("index.html", views.index ,name="index"),
    path("robots.txt", views.robots ,name="robots"),
    path("ads.txt", (lambda request: render(request, "ads.txt") ), name="ads.txt"),
    path("sitemap.xml", views.sitemap, name="sitemap"),
    path("sitemap/", views.sitemap, name="s"),
    path("<category>/<htmlname>", views.page, name="page"),
    path("about.html/", views.about, name="about"),
    path("<category_name>/", views.category_page, name="page")
]


"""TCP hole punching and peer communication."""

import socket
import threading
from typing import Callable

class Error(Exception):
    pass

class Tunnel:
    """High-level packet transmission."""

class Listener:
    """Automatic tunnel creation on port."""

    def __init__(self, port: int, backlog: int = None):
        self._sock = socket.socket()
        self._sock.bind(('', port))
        self._sock.listen(backlog)

        self._lock = threading.RLock()
        self._running = False
        self._thread = None  # type: threading.Thread

    @property
    def running(self):
        """Return whether listener is currently running."""
        with self._lock:
            return self._running and (self._thread is not None)

    def start(self, handler: Callable):
        """Spawn thread to act as listener."""
        with self._lock:
            if self._thread is not None:
                raise Error('listener already started')
            self._running = True
            self._thread = threading.Thread(target=self._loop, args=(handler,), daemon=True)
            self._thread.start()

    def _loop(self, handler: Callable):
        """Spawn new threads to handle incoming connections."""
        while self.running:
            threading.Thread(target=handler, args=(self._sock.accept(),)).start()

    def stop(self):
        with self._lock:
            self._running = False
            self._thread.join()
            self._thread = None


import pandas
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
data = pandas.read_csv("database.csv")
crop = pandas.read_csv("crop.csv")
city = data['city'].to_list()
max_temp = list(map(int, data['max temperature'].to_list()))
min_temp = list(map(int, data['min temperature'].to_list()))
max_humid = list(map(int, data['max humidity'].to_list()))
min_humid = list(map(int, data['min humidity'].to_list()))
min_ph = list(map(int, data['min ph'].to_list()))
max_ph = list(map(int, data['max ph'].to_list()))
wheat_humidity = 80.5
wheat_ph = 9
avg_humi = {}
avg_humidity = []
avg_tempa = {}
avg_temp = []
for i in range(len(data)):
    avg_tempa[city[i]] = (max_temp[i]+min_temp[i])/2
    avg_temp.append((max_temp[i]+min_temp[i])/2)
for i in range(27):
    avg_humi[city[i]] = (max_humid[i]+min_humid[i])/2
    avg_humidity.append((max_humid[i]+min_humid[i])/2)
avg_phs = {}
avg_ph = []
for i in range(27):
    avg_phs[city[i]] = (max_ph[i]+min_ph[i])/2
    avg_ph.append((max_ph[i]+min_ph[i])/2)
datafram = {'city': city, 'temp': avg_temp, 'ph': avg_ph, 'humidity': avg_humidity}
new = pd.DataFrame(datafram)
columns = list(new.head())[1:len(list(new.head()))]
clf = DecisionTreeClassifier()
target = 'crop'
clf.fit(crop[columns], crop[target])
predictions = clf.predict(new[columns])
final = pd.DataFrame({'City': city, 'Temperature': avg_temp, 'pH': avg_ph, 'Humidity': avg_humidity, 'Crop': predictions})
data['avg humidity'] = avg_humidity
data['avg_temp'] = avg_temp
data['avg ph'] = avg_ph
name = input("Enter the name of the city:").lower()
if name not in city:
    print("City Not Found....")
else:
    print("City Crop Predicted Data")
    plot_data = final[final['City'] == name]
    print(plot_data)
    crops=list(plot_data['Crop'])
    crop_data=crop[crop['crop']==crops[0]]
    print("Crop Data")
    print(crop_data)
    crop_cols=['temp','ph','humidity']
    plot_columns = list(plot_data.head())[1:len(list(plot_data.head()))-1]
    plot_array = []
    for i in list(final.head())[1:len(list(final.head()))-1]:
        plot_array.append(np.array(final[i]))
    for i in range(len(plot_array)):
        dt=pd.DataFrame({'City':city,name+"\'s "+plot_columns[i]:float(plot_data[plot_columns[i]]),plot_columns[i]:final[plot_columns[i]],crops[0]+'\'s '+plot_columns[i]:float(crop_data[crop_cols[i]])})
        dt.plot()
        plt.xlabel("City")
        plt.ylabel(plot_columns[i])
        plt.show()


import requests as req

# api url
url = "https://animechan.vercel.app/api"

def res_to_str(data):
    character = data["character"]
    anime = data["anime"]
    quote = data["quote"]
    res_string = f"\nQuote by: {character}\nFrom: {anime}\nQuote: {quote}\n"
    return res_string

def get_data(full_url):
    print("Getting the data.\n")
    response = req.get(full_url)
    data = response.json()

    if type(data) == type([]):
        for i in range(len(data)):
            res_string = res_to_str(data[i])
            print(f"{i + 1}. {res_string}")
    elif type(data) == type({}):
        res_string = res_to_str(data)
        print(res_string)

api_options = [ "Get a random quote.", "Get random quote by anime name.", "Get 10 random quotes", "Get 10 quotes by anime name."]

while True:
    for i in range(len(api_options)):
        print(f"{i + 1}. {api_options[i]}")

    user_choice = int(input("Choose an option: "))

    if user_choice == 1:
        get_data(f"{url}/random")
    elif user_choice == 2:
        anime_name = input("Enter Anime name:")
        get_data(f"{url}/random/anime?title={anime_name}")
    elif user_choice == 3:
        get_data(f"{url}/quotes")
    elif user_choice == 4:
        anime_name = input("Enter Anime name:")
        get_data(f"{url}/quotes/anime?title={anime_name}")
    else:
        print("Invalid Choice!")


from django.db import models
import uuid

class CategoriesOfProducts(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64)
    seq = models.IntegerField(blank=True, unique=True)

    class Meta:
        verbose_name = 'CategoryOfProducts'
        verbose_name_plural = 'CategoriesOfProducts'

    def __str__(self):
        return self.name

class GroupsOfProducts(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, unique=True, editable=False)
    category_id = models.ForeignKey(CategoriesOfProducts, on_delete=models.PROTECT)
    name = models.CharField(max_length=64)
    description = models.TextField()
    seq = models.IntegerField(blank=True, unique=True)

    class Meta:
        verbose_name = 'GroupOfProducts'
        verbose_name_plural = 'GroupsOfProducts'

    def __str__(self):
        return self.name

class Products(models.Model):
    id = models.AutoField(primary_key=True)
    group_id = models.ForeignKey(GroupsOfProducts, on_delete=models.PROTECT)
    name = models.CharField(max_length=64)
    price = models.DecimalField(decimal_places=2, max_digits=10)
    hidden = models.BooleanField(default=False)

    class Meta:
        verbose_name = 'Product'
        verbose_name_plural = 'Products'

    def __str__(self):
        return self.name


import io
import sys
import json

from smoke.io.wrap import demo as io_wrp_dm
from smoke.replay import demo as rply_dm
from smoke.replay.const import Data

class Chat(object):
    def __init__(self, player, message):
        self.player = player
        self.message = message

class Player(object):
    def __init__(self, steamid, username):
        self.steamid = steamid
        self.username = username

class Game(object):
    def __init__(self, gameid, dire_players, radiant_players, chats, end_time, duration):
        self.gameid = gameid
        self.dire_players = dire_players
        self.radiant_players = radiant_players
        self.chats = chats
        self.end_time = end_time
        self.duration = duration

def parse_game(fn):
    with io.open(fn, 'rb') as infile:
        demo_io = io_wrp_dm.Wrap(infile)
        demo_io.bootstrap()

        parse = Data.UserMessages
        demo = rply_dm.Demo(demo_io, parse=parse)
        demo.bootstrap()

        msgs =  [msg for match in demo.play()
                     for msgs in match.user_messages.values()
                     for msg in msgs
                     if hasattr(msg, 'chat') and msg.chat]
        demo.finish()
        overview = demo.match.overview
    radiant = [Player(p['steam_id'], p['player_name']) for p in overview['game']['players'] if p['game_team'] == 2]
    dire = [Player(p['steam_id'], p['player_name']) for p in overview['game']['players'] if p['game_team'] == 3]
    players = {p.username: p for p in (radiant + dire)}
    chats = [Chat(players[msg.prefix], msg.text) for msg in msgs]
    return Game(overview['game']['match_id'], dire, radiant, chats, overview['game']['end_time'], overview['playback']['time'])

if __name__ == '__main__':
    filename = sys.argv[1]
    for filename in sys.argv[1:]:
        game = parse_game(filename)
        print(json.dumps(game, default = lambda o : o.__dict__, indent = 2))


from django.core.mail import send_mail

from fitness.celery import app
from fitness.settings import EMAIL_HOST_USER
from django.utils.translation import gettext_lazy as _

@app.task
def send_code_to_email(code_user, email_user):
    """
    Отправка письма с кодом подтверждения
    """
    mail_sent = send_mail(
        _('Код подтверждения'),
        _(f'Забыл пароль, дорогой? :) Лови код для входа: {code_user}'),
        EMAIL_HOST_USER,
        [email_user],
        fail_silently=False,
    )
    return mail_sent


from datetime import datetime
from PySide2.QtCore import Qt, QAbstractItemModel, QModelIndex
from PySide2.QtGui import QBrush
from jal.constants import BookAccount, PredefinedAsset, CustomColor
from jal.widgets.helpers import g_tr
from jal.db.helpers import executeSQL
from jal.widgets.delegates import GridLinesDelegate

# ----------------------------------------------------------------------------------------------------------------------
class ReportTreeItem():
    def __init__(self, begin, end, id, name, parent=None):
        self._parent = parent
        self._id = id
        self.name = name
        self._y_s = int(datetime.utcfromtimestamp(begin).strftime('%Y'))
        self._m_s = int(datetime.utcfromtimestamp(begin).strftime('%-m'))
        self._y_e = int(datetime.utcfromtimestamp(end).strftime('%Y'))
        self._m_e = int(datetime.utcfromtimestamp(end).strftime('%-m'))
        # amounts is 2D-array of per month amounts:
        # amounts[year][month] - amount for particular month
        # amounts[year][0] - total per year
        self._amounts = [ [0] * 13 for _ in range(self._y_e - self._y_s + 1)]
        self._total = 0
        self._children = []

    def appendChild(self, child):
        child.setParent(self)
        self._children.append(child)

    def getChild(self, id):
        if id < 0 or id > len(self._children):
            return None
        return self._children[id]

    def childrenCount(self):
        return len(self._children)

    def dataCount(self):
        if self._y_s == self._y_e:
            return self._m_e - self._m_s + 3  # + 1 for year, + 1 for totals
        else:
            # 13 * (self._y_e - self._y_s - 1) + (self._m_e + 1) + (12 - self._m_s + 2) + 1 simplified to:
            return 13 * (self._y_e - self._y_s - 1) + (self._m_e - self._m_s + 16)

    def column2calendar(self, column):
        # column 0 - name of row - return (-1, -1)
        # then repetition of [year], [jan], [feb] ... [nov], [dec] - return (year, 0), (year, 1) ... (year, 12)
        # last column is total value - return (0, 0)
        if column == 0:
            return -1, -1
        if column == self.dataCount():
            return 0, 0
        if column == 1:
            return self._y_s, 0
        column = column + self._m_s - 2
        year = self._y_s + int(column / 13)
        month = column % 13
        return year, month

    def setParent(self, parent):
        self._parent = parent

    def getParent(self):
        return self._parent

    def addAmount(self, year, month, amount):
        y_i = year - self._y_s
        self._amounts[y_i][month] += amount
        self._amounts[y_i][0] += amount
        self._total += amount
        if self._parent is not None:
            self._parent.addAmount(year, month, amount)

    # Return amount for given date and month or total amount if year==0
    def getAmount(self, year, month):
        if year == 0:
            return self._total
        y_i = year - self._y_s
        return self._amounts[y_i][month]

    def getLeafById(self, id):
        if self._id == id:
            return self
        leaf = None
        for child in self._children:
            leaf = child.getLeafById(id)
        return leaf

    @property
    def year_begin(self):
        return self._y_s

    @property
    def month_begin(self):
        return self._m_s

    @property
    def year_end(self):
        return self._y_e

    @property
    def month_end(self):
        return self._m_e

# ----------------------------------------------------------------------------------------------------------------------
class IncomeSpendingReport(QAbstractItemModel):
    COL_LEVEL = 0
    COL_ID = 1
    COL_PID = 2
    COL_NAME = 3
    COL_PATH = 4
    COL_TIMESTAMP = 5
    COL_AMOUNT = 6

    def __init__(self, parent_view):
        super().__init__(parent_view)
        self._view = parent_view
        self._root = None
        self._grid_delegate = None
        self._report_delegate = None
        self.month_name = [g_tr('Reports', 'Jan'),
                           g_tr('Reports', 'Feb'),
                           g_tr('Reports', 'Mar'),
                           g_tr('Reports', 'Apr'),
                           g_tr('Reports', 'May'),
                           g_tr('Reports', 'Jun'),
                           g_tr('Reports', 'Jul'),
                           g_tr('Reports', 'Aug'),
                           g_tr('Reports', 'Sep'),
                           g_tr('Reports', 'Oct'),
                           g_tr('Reports', 'Nov'),
                           g_tr('Reports', 'Dec')]

    def rowCount(self, parent=None):
        if not parent.isValid():
            parent_item = self._root
        else:
            parent_item = parent.internalPointer()
        if parent_item is not None:
            return parent_item.childrenCount()
        else:
            return 0

    def columnCount(self, parent=None):
        if parent is None:
            parent_item = self._root
        elif not parent.isValid():
            parent_item = self._root
        else:
            parent_item = parent.internalPointer()
        if parent_item is not None:
            return parent_item.dataCount() + 1  # + 1 for row header
        else:
            return 0

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if orientation == Qt.Horizontal:
            if role == Qt.DisplayRole:
                year, month = self._root.column2calendar(section)
                if year < 0:
                    col_name = ''
                elif year == 0:
                    col_name = g_tr("Reports", "TOTAL")
                else:
                    if month == 0:
                        status = '▼' if self._view.isColumnHidden(section + 1) else '▶'
                        col_name = f"{year} " + status
                    else:
                        col_name = self.month_name[month-1]
                return col_name
            if role == Qt.TextAlignmentRole:
                return Qt.AlignCenter
        return None

    def index(self, row, column, parent=None):
        if not parent.isValid():
            parent = self._root
        else:
            parent = parent.internalPointer()
        child = parent.getChild(row)
        if child:
            return self.createIndex(row, column, child)
        return QModelIndex()

    def parent(self, index=None):
        if not index.isValid():
            return QModelIndex()
        child_item = index.internalPointer()
        parent_item = child_item.getParent()
        if parent_item == self._root:
            return QModelIndex()
        return self.createIndex(0, 0, parent_item)

    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return None
        item = index.internalPointer()
        if role == Qt.DisplayRole:
            if index.column() == 0:
                return item.name
            else:
                year, month = self._root.column2calendar(index.column())
                return f"{item.getAmount(year, month):,.2f}"
        if role == Qt.ForegroundRole:
            if index.column() != 0:
                year, month = self._root.column2calendar(index.column())
                if item.getAmount(year, month) == 0:
                    return QBrush(CustomColor.Grey)
        if role == Qt.TextAlignmentRole:
            if index.column() == 0:
                return Qt.AlignLeft
            else:
                return Qt.AlignRight
        return None

    def configureView(self):
        self._grid_delegate = GridLinesDelegate(self._view)
        for column in range(self.columnCount()):
            self._view.setItemDelegateForColumn(column, self._grid_delegate)
            if column == 0:
                self._view.setColumnWidth(column, 300)
            else:
                self._view.setColumnWidth(column, 100)
        font = self._view.header().font()
        font.setBold(True)
        self._view.header().setFont(font)

        self._view.header().sectionDoubleClicked.connect(self.toggeYearColumns)

    def toggeYearColumns(self, section):
        year, month = self._root.column2calendar(section)
        if year >= 0 and month == 0:
            if year == self._root.year_begin:
                year_columns = 12 - self._root.month_begin + 1
            elif year == self._root.year_end:
                year_columns = self._root.month_end
            else:
                year_columns = 12
            for i in range(year_columns):
                new_state = not self._view.isColumnHidden(section + i + 1)
                self._view.setColumnHidden(section + i + 1, new_state)
            self.headerDataChanged.emit(Qt.Horizontal, section, section)

    def prepare(self, begin, end, account_id, group_dates):
        query = executeSQL("WITH "
                           "_months AS (SELECT strftime('%s', datetime(timestamp, 'unixepoch', 'start of month') ) "
                           "AS month, asset_id, MAX(timestamp) AS last_timestamp "
                           "FROM quotes AS q "
                           "LEFT JOIN assets AS a ON q.asset_id=a.id "
                           "WHERE a.type_id=:asset_money "
                           "GROUP BY month, asset_id), "
                           "_category_amounts AS ( "
                           "SELECT strftime('%s', datetime(t.timestamp, 'unixepoch', 'start of month')) AS month_start, "
                           "t.category_id AS id, sum(-t.amount * coalesce(q.quote, 1)) AS amount "
                           "FROM ledger AS t "
                           "LEFT JOIN _months AS d ON month_start = d.month AND t.asset_id = d.asset_id "
                           "LEFT JOIN quotes AS q ON d.last_timestamp = q.timestamp AND t.asset_id = q.asset_id "
                           "WHERE (t.book_account=:book_costs OR t.book_account=:book_incomes) "
                           "AND t.timestamp>=:begin AND t.timestamp<=:end "
                           "GROUP BY month_start, category_id) "
                           "SELECT ct.level, ct.id, c.pid, c.name, ct.path, ca.month_start, "
                           "coalesce(ca.amount, 0) AS amount "
                           "FROM categories_tree AS ct "
                           "LEFT JOIN _category_amounts AS ca ON ct.id=ca.id "
                           "LEFT JOIN categories AS c ON ct.id=c.id "
                           "ORDER BY path, month_start",
                           [(":asset_money", PredefinedAsset.Money), (":book_costs", BookAccount.Costs),
                            (":book_incomes", BookAccount.Incomes), (":begin", begin), (":end", end)])
        query.setForwardOnly(True)
        self._root = ReportTreeItem(begin, end, -1, "ROOT")  # invisible root
        self._root.appendChild(ReportTreeItem(begin, end, 0, g_tr("Reports", "TOTAL")))  # visible root
        indexes = range(query.record().count())
        while query.next():
            values = list(map(query.value, indexes))
            leaf = self._root.getLeafById(values[self.COL_ID])
            if leaf is None:
                parent = self._root.getLeafById(values[self.COL_PID])
                leaf = ReportTreeItem(begin, end, values[self.COL_ID], values[self.COL_NAME], parent)
                parent.appendChild(leaf)
            if values[self.COL_TIMESTAMP]:
                year = int(datetime.utcfromtimestamp(int(values[self.COL_TIMESTAMP])).strftime('%Y'))
                month = int(datetime.utcfromtimestamp(int(values[self.COL_TIMESTAMP])).strftime('%-m'))
                leaf.addAmount(year, month, values[self.COL_AMOUNT])
        self.modelReset.emit()
        self._view.expandAll()


import json
import os
from datetime import datetime

from flask import Flask
from flask import request
from flask import Response
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop

from kaner.context import GlobalContext as gctx
from kaner.adapter.tokenizer import CharTokenizer
from kaner.adapter.knowledge import Gazetteer
from kaner.trainer import NERTrainer, TrainerConfig
from kaner.common import load_json

gctx.init()
__APP__ = Flask(__name__)
__TRAINER__ = None

@__APP__.route("/", methods=["GET"])
def _hello():
    """Return welcome!"""
    return "
Welcome to KANER!
"

@__APP__.route("/kaner/predict", methods=["POST", "OPTIONS"])
def _predict_span():
    """
    Given a list of text, predicting their spans. The format of the requested data should be as the same as
    the following example:

        data = {"texts": ["document1", "document2", ...]}
    """
    start_time = datetime.now()
    rsp = {
        "success": True
    }
    try:
        data = json.loads(request.data)
        if "texts" not in data.keys() or not isinstance(data["texts"], list):
            rsp["success"] = False
            rsp["info"] = "The requested data should contain a list of document named `texts`."
            return json.dumps(rsp, ensure_ascii=False, indent=2)
        if len(data["texts"]) <= 0:
            rsp["success"] = False
            rsp["info"] = "The length of the list `texts` should be greater than 0"
            return json.dumps(rsp, ensure_ascii=False, indent=2)
        for i in range(len(data["texts"])):
            text = data["texts"][i]
            if not isinstance(text, str) or len(text) == 0:
                rsp["success"] = False
                rsp["info"] = "The {0}-th element in the list is not a string or is empty. {1}。".format(i + 1, text)
                return json.dumps(rsp, ensure_ascii=False, indent=2)
        if "debug" not in data.keys():
            data["debug"] = False
        global __TRAINER__
        if __TRAINER__ is None:
            rsp["success"] = False
            rsp["info"] = "The server is not prepared. Please wait a while..."
        else:
            results = []
            for _, text in enumerate(data["texts"]):
                fragments = []
                for i in range(0, len(text), __TRAINER__._config.max_seq_len):
                    fragments.append(text[i: i + __TRAINER__._config.max_seq_len])
                raw_result = __TRAINER__.predict(fragments)
                result = {
                    "text": text,
                    "spans": []
                }
                for i in range(0, len(text), __TRAINER__._config.max_seq_len):
                    idx = i//__TRAINER__._config.max_seq_len
                    for j in range(len(raw_result[idx]["spans"])):
                        raw_result[idx]["spans"][j]["start"] += i
                        raw_result[idx]["spans"][j]["end"] += i
                    result["spans"].extend(raw_result[idx]["spans"])
                results.append(result)
            rsp["data"] = results
            rsp["model"] = __TRAINER__._config.model
            rsp["dataset"] = __TRAINER__._config.dataset
    except RuntimeError as runtime_error:
        rsp["success"] = False
        rsp["info"] = "Runtime Error {}.".format(str(runtime_error))
    except json.decoder.JSONDecodeError as json_decode_error:
        rsp["success"] = False
        rsp["info"] = "Parsing JSON String Error {}.".format(str(json_decode_error))
    except Exception as exception:
        rsp["success"] = False
        rsp["info"] = str(exception)
    rsp["time"] = (datetime.now() - start_time).seconds
    rsp = Response(json.dumps(rsp, ensure_ascii=False, indent=2))
    rsp.headers["content-type"] = "application/json"
    # A CORS preflight request is a CORS request that checks to see if the CORS protocol is
    # understood and a server is aware using specific methods and headers.
    # https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
    rsp.headers["Access-Control-Allow-Origin"] = "*"
    rsp.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept"

    return rsp

def serve(model_folder: str, host: str, port: int) -> None:
    """
    Start a service for predicting texts.

    Args:
        model_folder (str): The folder where the trained model exists.
        host (str): Address.
        port (str): Listen port.
    """
    options = load_json("utf-8", model_folder, "config.json")
    options["output_folder"] = model_folder
    options["identity"] = os.path.basename(os.path.normpath(model_folder))
    config = TrainerConfig(options)
    tokenizer = CharTokenizer(model_folder)
    gazetteer = Gazetteer(model_folder)
    out_adapter = gctx.create_outadapter(config.out_adapter, dataset_folder=model_folder, file_name="labels")
    in_adapters = (
        gctx.create_inadapter(
            config.in_adapter, dataset=[], tokenizer=tokenizer, out_adapter=out_adapter, gazetteer=gazetteer,
            **config.hyperparameters
        )
        for _ in range(3)
    )
    collate_fn = gctx.create_batcher(
        config.model, input_pad=tokenizer.pad_id, output_pad=out_adapter.unk_id, lexicon_pad=gazetteer.pad_id, device=config.device
    )
    model = gctx.create_model(config.model, **config.hyperparameters)
    trainer = NERTrainer(
        config, tokenizer, in_adapters, out_adapter, collate_fn, model, None,
        gctx.create_traincallback(config.model), gctx.create_testcallback(config.model)
    )
    trainer.startp()
    global __TRAINER__, __APP__
    __TRAINER__ = trainer
    server = HTTPServer(WSGIContainer(__APP__))
    print("->    :: Web Service ::    ")
    print("service starts at \x1b[1;32;40mhttp://{0}:{1}\x1b[0m".format(host, port))
    server.listen(port, host)
    IOLoop.instance().start()


from spacy.lang.en import English
import numpy as np

import srsly

from flask import Flask, render_template

patterns = srsly.read_jsonl("Backend/skill_patterns.jsonl")

nlp = English()

ruler = nlp.add_pipe("entity_ruler")
ruler.add_patterns(patterns)

def extract_keywords(txt):

    doc = nlp(txt)
    keywords = list(doc.ents)
    # remove duplicates
    keywords = [str(k) for k in keywords]
    keywords = list(set(keywords))

    return keywords

def calculate_score(resume_kws, job_kws):

    resume_kws = np.array(resume_kws)
    job_kws = np.array(job_kws)

    match_count = 0
    for i in resume_kws:
      for j in job_kws:
        if i == j:
          match_count += 1
          continue

    score = 2 * match_count / (resume_kws.size + job_kws.size)
    return score

def calculate_similarity(resume_str, job_str):
    resume_keywords = extract_keywords(resume_str)
    job_keywords = extract_keywords(job_str)

    score = calculate_score(resume_keywords, job_keywords)
    return score


# Released under the MIT License. See LICENSE for details.
#
"""Various functionality related to achievements."""
from __future__ import annotations

import logging
from typing import TYPE_CHECKING

import babase
import bascenev1
import bauiv1

if TYPE_CHECKING:
    from typing import Any, Sequence

    import baclassic

# This could use some cleanup.
# We wear the cone of shame.
# pylint: disable=too-many-lines
# pylint: disable=too-many-statements
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches

# FIXME: We should probably point achievements
#  at coop levels instead of hard-coding names.
#  (so level name substitution works right and whatnot).
ACH_LEVEL_NAMES = {
    'Boom Goes the Dynamite': 'Pro Onslaught',
    'Boxer': 'Onslaught Training',
    'Flawless Victory': 'Rookie Onslaught',
    'Gold Miner': 'Uber Onslaught',
    'Got the Moves': 'Uber Football',
    'Last Stand God': 'The Last Stand',
    'Last Stand Master': 'The Last Stand',
    'Last Stand Wizard': 'The Last Stand',
    'Mine Games': 'Rookie Onslaught',
    'Off You Go Then': 'Onslaught Training',
    'Onslaught God': 'Infinite Onslaught',
    'Onslaught Master': 'Infinite Onslaught',
    'Onslaught Training Victory': 'Onslaught Training',
    'Onslaught Wizard': 'Infinite Onslaught',
    'Precision Bombing': 'Pro Runaround',
    'Pro Boxer': 'Pro Onslaught',
    'Pro Football Shutout': 'Pro Football',
    'Pro Football Victory': 'Pro Football',
    'Pro Onslaught Victory': 'Pro Onslaught',
    'Pro Runaround Victory': 'Pro Runaround',
    'Rookie Football Shutout': 'Rookie Football',
    'Rookie Football Victory': 'Rookie Football',
    'Rookie Onslaught Victory': 'Rookie Onslaught',
    'Runaround God': 'Infinite Runaround',
    'Runaround Master': 'Infinite Runaround',
    'Runaround Wizard': 'Infinite Runaround',
    'Stayin\' Alive': 'Uber Runaround',
    'Super Mega Punch': 'Pro Football',
    'Super Punch': 'Rookie Football',
    'TNT Terror': 'Uber Onslaught',
    'The Great Wall': 'Uber Runaround',
    'The Wall': 'Pro Runaround',
    'Uber Football Shutout': 'Uber Football',
    'Uber Football Victory': 'Uber Football',
    'Uber Onslaught Victory': 'Uber Onslaught',
    'Uber Runaround Victory': 'Uber Runaround',
}

class AchievementSubsystem:
    """Subsystem for achievement handling.

    Category: **App Classes**

    Access the single shared instance of this class at 'ba.app.ach'.
    """

    def __init__(self) -> None:
        self.achievements: list[Achievement] = []
        self.achievements_to_display: (
            list[tuple[baclassic.Achievement, bool]]
        ) = []
        self.achievement_display_timer: bascenev1.BaseTimer | None = None
        self.last_achievement_display_time: float = 0.0
        self.achievement_completion_banner_slots: set[int] = set()
        self._init_achievements()

    def _init_achievements(self) -> None:
        """Fill in available achievements."""

        achs = self.achievements

        # 5
        achs.append(
            Achievement('In Control', 'achievementInControl', (1, 1, 1), '', 5)
        )
        # 15
        achs.append(
            Achievement(
                'Sharing is Caring',
                'achievementSharingIsCaring',
                (1, 1, 1),
                '',
                15,
            )
        )
        # 10
        achs.append(
            Achievement(
                'Dual Wielding', 'achievementDualWielding', (1, 1, 1), '', 10
            )
        )

        # 10
        achs.append(
            Achievement(
                'Free Loader', 'achievementFreeLoader', (1, 1, 1), '', 10
            )
        )
        # 20
        achs.append(
            Achievement(
                'Team Player', 'achievementTeamPlayer', (1, 1, 1), '', 20
            )
        )

        # 5
        achs.append(
            Achievement(
                'Onslaught Training Victory',
                'achievementOnslaught',
                (1, 1, 1),
                'Default:Onslaught Training',
                5,
            )
        )
        # 5
        achs.append(
            Achievement(
                'Off You Go Then',
                'achievementOffYouGo',
                (1, 1.1, 1.3),
                'Default:Onslaught Training',
                5,
            )
        )
        # 10
        achs.append(
            Achievement(
                'Boxer',
                'achievementBoxer',
                (1, 0.6, 0.6),
                'Default:Onslaught Training',
                10,
                hard_mode_only=True,
            )
        )

        # 10
        achs.append(
            Achievement(
                'Rookie Onslaught Victory',
                'achievementOnslaught',
                (0.5, 1.4, 0.6),
                'Default:Rookie Onslaught',
                10,
            )
        )
        # 10
        achs.append(
            Achievement(
                'Mine Games',
                'achievementMine',
                (1, 1, 1.4),
                'Default:Rookie Onslaught',
                10,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Flawless Victory',
                'achievementFlawlessVictory',
                (1, 1, 1),
                'Default:Rookie Onslaught',
                15,
                hard_mode_only=True,
            )
        )

        # 10
        achs.append(
            Achievement(
                'Rookie Football Victory',
                'achievementFootballVictory',
                (1.0, 1, 0.6),
                'Default:Rookie Football',
                10,
            )
        )
        # 10
        achs.append(
            Achievement(
                'Super Punch',
                'achievementSuperPunch',
                (1, 1, 1.8),
                'Default:Rookie Football',
                10,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Rookie Football Shutout',
                'achievementFootballShutout',
                (1, 1, 1),
                'Default:Rookie Football',
                15,
                hard_mode_only=True,
            )
        )

        # 15
        achs.append(
            Achievement(
                'Pro Onslaught Victory',
                'achievementOnslaught',
                (0.3, 1, 2.0),
                'Default:Pro Onslaught',
                15,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Boom Goes the Dynamite',
                'achievementTNT',
                (1.4, 1.2, 0.8),
                'Default:Pro Onslaught',
                15,
            )
        )
        # 20
        achs.append(
            Achievement(
                'Pro Boxer',
                'achievementBoxer',
                (2, 2, 0),
                'Default:Pro Onslaught',
                20,
                hard_mode_only=True,
            )
        )

        # 15
        achs.append(
            Achievement(
                'Pro Football Victory',
                'achievementFootballVictory',
                (1.3, 1.3, 2.0),
                'Default:Pro Football',
                15,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Super Mega Punch',
                'achievementSuperPunch',
                (2, 1, 0.6),
                'Default:Pro Football',
                15,
            )
        )
        # 20
        achs.append(
            Achievement(
                'Pro Football Shutout',
                'achievementFootballShutout',
                (0.7, 0.7, 2.0),
                'Default:Pro Football',
                20,
                hard_mode_only=True,
            )
        )

        # 15
        achs.append(
            Achievement(
                'Pro Runaround Victory',
                'achievementRunaround',
                (1, 1, 1),
                'Default:Pro Runaround',
                15,
            )
        )
        # 20
        achs.append(
            Achievement(
                'Precision Bombing',
                'achievementCrossHair',
                (1, 1, 1.3),
                'Default:Pro Runaround',
                20,
                hard_mode_only=True,
            )
        )
        # 25
        achs.append(
            Achievement(
                'The Wall',
                'achievementWall',
                (1, 0.7, 0.7),
                'Default:Pro Runaround',
                25,
                hard_mode_only=True,
            )
        )

        # 30
        achs.append(
            Achievement(
                'Uber Onslaught Victory',
                'achievementOnslaught',
                (2, 2, 1),
                'Default:Uber Onslaught',
                30,
            )
        )
        # 30
        achs.append(
            Achievement(
                'Gold Miner',
                'achievementMine',
                (2, 1.6, 0.2),
                'Default:Uber Onslaught',
                30,
                hard_mode_only=True,
            )
        )
        # 30
        achs.append(
            Achievement(
                'TNT Terror',
                'achievementTNT',
                (2, 1.8, 0.3),
                'Default:Uber Onslaught',
                30,
                hard_mode_only=True,
            )
        )

        # 30
        achs.append(
            Achievement(
                'Uber Football Victory',
                'achievementFootballVictory',
                (1.8, 1.4, 0.3),
                'Default:Uber Football',
                30,
            )
        )
        # 30
        achs.append(
            Achievement(
                'Got the Moves',
                'achievementGotTheMoves',
                (2, 1, 0),
                'Default:Uber Football',
                30,
                hard_mode_only=True,
            )
        )
        # 40
        achs.append(
            Achievement(
                'Uber Football Shutout',
                'achievementFootballShutout',
                (2, 2, 0),
                'Default:Uber Football',
                40,
                hard_mode_only=True,
            )
        )

        # 30
        achs.append(
            Achievement(
                'Uber Runaround Victory',
                'achievementRunaround',
                (1.5, 1.2, 0.2),
                'Default:Uber Runaround',
                30,
            )
        )
        # 40
        achs.append(
            Achievement(
                'The Great Wall',
                'achievementWall',
                (2, 1.7, 0.4),
                'Default:Uber Runaround',
                40,
                hard_mode_only=True,
            )
        )
        # 40
        achs.append(
            Achievement(
                'Stayin\' Alive',
                'achievementStayinAlive',
                (2, 2, 1),
                'Default:Uber Runaround',
                40,
                hard_mode_only=True,
            )
        )

        # 20
        achs.append(
            Achievement(
                'Last Stand Master',
                'achievementMedalSmall',
                (2, 1.5, 0.3),
                'Default:The Last Stand',
                20,
                hard_mode_only=True,
            )
        )
        # 40
        achs.append(
            Achievement(
                'Last Stand Wizard',
                'achievementMedalMedium',
                (2, 1.5, 0.3),
                'Default:The Last Stand',
                40,
                hard_mode_only=True,
            )
        )
        # 60
        achs.append(
            Achievement(
                'Last Stand God',
                'achievementMedalLarge',
                (2, 1.5, 0.3),
                'Default:The Last Stand',
                60,
                hard_mode_only=True,
            )
        )

        # 5
        achs.append(
            Achievement(
                'Onslaught Master',
                'achievementMedalSmall',
                (0.7, 1, 0.7),
                'Challenges:Infinite Onslaught',
                5,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Onslaught Wizard',
                'achievementMedalMedium',
                (0.7, 1.0, 0.7),
                'Challenges:Infinite Onslaught',
                15,
            )
        )
        # 30
        achs.append(
            Achievement(
                'Onslaught God',
                'achievementMedalLarge',
                (0.7, 1.0, 0.7),
                'Challenges:Infinite Onslaught',
                30,
            )
        )

        # 5
        achs.append(
            Achievement(
                'Runaround Master',
                'achievementMedalSmall',
                (1.0, 1.0, 1.2),
                'Challenges:Infinite Runaround',
                5,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Runaround Wizard',
                'achievementMedalMedium',
                (1.0, 1.0, 1.2),
                'Challenges:Infinite Runaround',
                15,
            )
        )
        # 30
        achs.append(
            Achievement(
                'Runaround God',
                'achievementMedalLarge',
                (1.0, 1.0, 1.2),
                'Challenges:Infinite Runaround',
                30,
            )
        )

    def award_local_achievement(self, achname: str) -> None:
        """For non-game-based achievements such as controller-connection."""
        plus = babase.app.plus
        if plus is None:
            logging.warning('achievements require plus feature-set')
            return
        try:
            ach = self.get_achievement(achname)
            if not ach.complete:
                # Report new achievements to the game-service.
                plus.report_achievement(achname)

                # And to our account.
                plus.add_v1_account_transaction(
                    {'type': 'ACHIEVEMENT', 'name': achname}
                )

                # Now attempt to show a banner.
                self.display_achievement_banner(achname)

        except Exception:
            logging.exception('Error in award_local_achievement.')

    def display_achievement_banner(self, achname: str) -> None:
        """Display a completion banner for an achievement.

        (internal)

        Used for server-driven achievements.
        """
        try:
            # FIXME: Need to get these using the UI context or some other
            #  purely local context somehow instead of trying to inject these
            #  into whatever activity happens to be active
            #  (since that won't work while in client mode).
            activity = bascenev1.get_foreground_host_activity()
            if activity is not None:
                with activity.context:
                    self.get_achievement(achname).announce_completion()
        except Exception:
            logging.exception('Error in display_achievement_banner.')

    def set_completed_achievements(self, achs: Sequence[str]) -> None:
        """Set the current state of completed achievements.

        (internal)

        All achievements not included here will be set incomplete.
        """

        # Note: This gets called whenever game-center/game-circle/etc tells
        # us which achievements we currently have.  We always defer to them,
        # even if that means we have to un-set an achievement we think we have.

        cfg = babase.app.config
        cfg['Achievements'] = {}
        for a_name in achs:
            self.get_achievement(a_name).set_complete(True)
        cfg.commit()

    def get_achievement(self, name: str) -> Achievement:
        """Return an Achievement by name."""
        achs = [a for a in self.achievements if a.name == name]
        assert len(achs) < 2
        if not achs:
            raise ValueError("Invalid achievement name: '" + name + "'")
        return achs[0]

    def achievements_for_coop_level(self, level_name: str) -> list[Achievement]:
        """Given a level name, return achievements available for it."""

        # For the Easy campaign we return achievements for the Default
        # campaign too. (want the user to see what achievements are part of the
        # level even if they can't unlock them all on easy mode).
        return [
            a
            for a in self.achievements
            if a.level_name
            in (level_name, level_name.replace('Easy', 'Default'))
        ]

    def _test(self) -> None:
        """For testing achievement animations."""

        def testcall1() -> None:
            self.achievements[0].announce_completion()
            self.achievements[1].announce_completion()
            self.achievements[2].announce_completion()

        def testcall2() -> None:
            self.achievements[3].announce_completion()
            self.achievements[4].announce_completion()
            self.achievements[5].announce_completion()

        bascenev1.basetimer(3.0, testcall1)
        bascenev1.basetimer(7.0, testcall2)

def _get_ach_mult(include_pro_bonus: bool = False) -> int:
    """Return the multiplier for achievement pts.

    (just for display; changing this here won't affect actual rewards)
    """
    plus = babase.app.plus
    classic = babase.app.classic
    if plus is None or classic is None:
        return 5
    val: int = plus.get_v1_account_misc_read_val('achAwardMult', 5)
    assert isinstance(val, int)
    if include_pro_bonus and classic.accounts.have_pro():
        val *= 2
    return val

def _display_next_achievement() -> None:
    # Pull the first achievement off the list and display it, or kill the
    # display-timer if the list is empty.
    app = babase.app
    assert app.classic is not None
    ach_ss = app.classic.ach
    if app.classic.ach.achievements_to_display:
        try:
            ach, sound = ach_ss.achievements_to_display.pop(0)
            ach.show_completion_banner(sound)
        except Exception:
            logging.exception('Error in _display_next_achievement.')
            ach_ss.achievements_to_display = []
            ach_ss.achievement_display_timer = None
    else:
        ach_ss.achievement_display_timer = None

class Achievement:
    """Represents attributes and state for an individual achievement.

    Category: **App Classes**
    """

    def __init__(
        self,
        name: str,
        icon_name: str,
        icon_color: Sequence[float],
        level_name: str,
        award: int,
        hard_mode_only: bool = False,
    ):
        self._name = name
        self._icon_name = icon_name
        self._icon_color: Sequence[float] = list(icon_color) + [1]
        self._level_name = level_name
        self._completion_banner_slot: int | None = None
        self._award = award
        self._hard_mode_only = hard_mode_only

    @property
    def name(self) -> str:
        """The name of this achievement."""
        return self._name

    @property
    def level_name(self) -> str:
        """The name of the level this achievement applies to."""
        return self._level_name

    def get_icon_ui_texture(self, complete: bool) -> bauiv1.Texture:
        """Return the icon texture to display for this achievement"""
        return bauiv1.gettexture(
            self._icon_name if complete else 'achievementEmpty'
        )

    def get_icon_texture(self, complete: bool) -> bascenev1.Texture:
        """Return the icon texture to display for this achievement"""
        return bascenev1.gettexture(
            self._icon_name if complete else 'achievementEmpty'
        )

    def get_icon_color(self, complete: bool) -> Sequence[float]:
        """Return the color tint for this Achievement's icon."""
        if complete:
            return self._icon_color
        return 1.0, 1.0, 1.0, 0.6

    @property
    def hard_mode_only(self) -> bool:
        """Whether this Achievement is only unlockable in hard-mode."""
        return self._hard_mode_only

    @property
    def complete(self) -> bool:
        """Whether this Achievement is currently complete."""
        val: bool = self._getconfig()['Complete']
        assert isinstance(val, bool)
        return val

    def announce_completion(self, sound: bool = True) -> None:
        """Kick off an announcement for this achievement's completion."""

        app = babase.app
        plus = app.plus
        classic = app.classic
        if plus is None or classic is None:
            logging.warning('ach account_completion not available.')
            return

        ach_ss = classic.ach

        # Even though there are technically achievements when we're not
        # signed in, lets not show them (otherwise we tend to get
        # confusing 'controller connected' achievements popping up while
        # waiting to sign in which can be confusing).
        if plus.get_v1_account_state() != 'signed_in':
            return

        # If we're being freshly complete, display/report it and whatnot.
        if (self, sound) not in ach_ss.achievements_to_display:
            ach_ss.achievements_to_display.append((self, sound))

        # If there's no achievement display timer going, kick one off
        # (if one's already running it will pick this up before it dies).

        # Need to check last time too; its possible our timer wasn't able to
        # clear itself if an activity died and took it down with it.
        if (
            ach_ss.achievement_display_timer is None
            or babase.apptime() - ach_ss.last_achievement_display_time > 2.0
        ) and bascenev1.getactivity(doraise=False) is not None:
            ach_ss.achievement_display_timer = bascenev1.BaseTimer(
                1.0, _display_next_achievement, repeat=True
            )

            # Show the first immediately.
            _display_next_achievement()

    def set_complete(self, complete: bool = True) -> None:
        """Set an achievement's completed state.

        note this only sets local state; use a transaction to
        actually award achievements.
        """
        config = self._getconfig()
        if complete != config['Complete']:
            config['Complete'] = complete

    @property
    def display_name(self) -> babase.Lstr:
        """Return a babase.Lstr for this Achievement's name."""
        name: babase.Lstr | str
        try:
            if self._level_name != '':
                campaignname, campaign_level = self._level_name.split(':')
                classic = babase.app.classic
                assert classic is not None
                name = (
                    classic.getcampaign(campaignname)
                    .getlevel(campaign_level)
                    .displayname
                )
            else:
                name = ''
        except Exception:
            name = ''
            logging.exception('Error calcing achievement display-name.')
        return babase.Lstr(
            resource='achievements.' + self._name + '.name',
            subs=[('${LEVEL}', name)],
        )

    @property
    def description(self) -> babase.Lstr:
        """Get a babase.Lstr for the Achievement's brief description."""
        if (
            'description'
            in babase.app.lang.get_resource('achievements')[self._name]
        ):
            return babase.Lstr(
                resource='achievements.' + self._name + '.description'
            )
        return babase.Lstr(
            resource='achievements.' + self._name + '.descriptionFull'
        )

    @property
    def description_complete(self) -> babase.Lstr:
        """Get a babase.Lstr for the Achievement's description when complete."""
        if (
            'descriptionComplete'
            in babase.app.lang.get_resource('achievements')[self._name]
        ):
            return babase.Lstr(
                resource='achievements.' + self._name + '.descriptionComplete'
            )
        return babase.Lstr(
            resource='achievements.' + self._name + '.descriptionFullComplete'
        )

    @property
    def description_full(self) -> babase.Lstr:
        """Get a babase.Lstr for the Achievement's full description."""
        return babase.Lstr(
            resource='achievements.' + self._name + '.descriptionFull',
            subs=[
                (
                    '${LEVEL}',
                    babase.Lstr(
                        translate=(
                            'coopLevelNames',
                            ACH_LEVEL_NAMES.get(self._name, '?'),
                        )
                    ),
                )
            ],
        )

    @property
    def description_full_complete(self) -> babase.Lstr:
        """Get a babase.Lstr for the Achievement's full desc. when completed."""
        return babase.Lstr(
            resource='achievements.' + self._name + '.descriptionFullComplete',
            subs=[
                (
                    '${LEVEL}',
                    babase.Lstr(
                        translate=(
                            'coopLevelNames',
                            ACH_LEVEL_NAMES.get(self._name, '?'),
                        )
                    ),
                )
            ],
        )

    def get_award_ticket_value(self, include_pro_bonus: bool = False) -> int:
        """Get the ticket award value for this achievement."""
        plus = babase.app.plus
        if plus is None:
            return 0
        val: int = plus.get_v1_account_misc_read_val(
            'achAward.' + self._name, self._award
        ) * _get_ach_mult(include_pro_bonus)
        assert isinstance(val, int)
        return val

    @property
    def power_ranking_value(self) -> int:
        """Get the power-ranking award value for this achievement."""
        plus = babase.app.plus
        if plus is None:
            return 0
        val: int = plus.get_v1_account_misc_read_val(
            'achLeaguePoints.' + self._name, self._award
        )
        assert isinstance(val, int)
        return val

    def create_display(
        self,
        x: float,
        y: float,
        delay: float,
        outdelay: float | None = None,
        color: Sequence[float] | None = None,
        style: str = 'post_game',
    ) -> list[bascenev1.Actor]:
        """Create a display for the Achievement.

        Shows the Achievement icon, name, and description.
        """
        # pylint: disable=cyclic-import
        from bascenev1 import CoopSession
        from bascenev1lib.actor.image import Image
        from bascenev1lib.actor.text import Text

        # Yeah this needs cleaning up.
        if style == 'post_game':
            in_game_colors = False
            in_main_menu = False
            h_attach = Text.HAttach.CENTER
            v_attach = Text.VAttach.CENTER
            attach = Image.Attach.CENTER
        elif style == 'in_game':
            in_game_colors = True
            in_main_menu = False
            h_attach = Text.HAttach.LEFT
            v_attach = Text.VAttach.TOP
            attach = Image.Attach.TOP_LEFT
        elif style == 'news':
            in_game_colors = True
            in_main_menu = True
            h_attach = Text.HAttach.CENTER
            v_attach = Text.VAttach.TOP
            attach = Image.Attach.TOP_CENTER
        else:
            raise ValueError('invalid style "' + style + '"')

        # Attempt to determine what campaign we're in
        # (so we know whether to show "hard mode only").
        if in_main_menu:
            hmo = False
        else:
            try:
                session = bascenev1.getsession()
                if isinstance(session, CoopSession):
                    campaign = session.campaign
                    assert campaign is not None
                    hmo = self._hard_mode_only and campaign.name == 'Easy'
                else:
                    hmo = False
            except Exception:
                logging.exception('Error determining campaign.')
                hmo = False

        objs: list[bascenev1.Actor]

        if in_game_colors:
            objs = []
            out_delay_fin = (delay + outdelay) if outdelay is not None else None
            if color is not None:
                cl1 = (2.0 * color[0], 2.0 * color[1], 2.0 * color[2], color[3])
                cl2 = color
            else:
                cl1 = (1.5, 1.5, 2, 1.0)
                cl2 = (0.8, 0.8, 1.0, 1.0)

            if hmo:
                cl1 = (cl1[0], cl1[1], cl1[2], cl1[3] * 0.6)
                cl2 = (cl2[0], cl2[1], cl2[2], cl2[3] * 0.2)

            objs.append(
                Image(
                    self.get_icon_texture(False),
                    host_only=True,
                    color=cl1,
                    position=(x - 25, y + 5),
                    attach=attach,
                    transition=Image.Transition.FADE_IN,
                    transition_delay=delay,
                    vr_depth=4,
                    transition_out_delay=out_delay_fin,
                    scale=(40, 40),
                ).autoretain()
            )
            txt = self.display_name
            txt_s = 0.85
            txt_max_w = 300
            objs.append(
                Text(
                    txt,
                    host_only=True,
                    maxwidth=txt_max_w,
                    position=(x, y + 2),
                    transition=Text.Transition.FADE_IN,
                    scale=txt_s,
                    flatness=0.6,
                    shadow=0.5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    color=cl2,
                    transition_delay=delay + 0.05,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
            )
            txt2_s = 0.62
            txt2_max_w = 400
            objs.append(
                Text(
                    self.description_full if in_main_menu else self.description,
                    host_only=True,
                    maxwidth=txt2_max_w,
                    position=(x, y - 14),
                    transition=Text.Transition.FADE_IN,
                    vr_depth=-5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    scale=txt2_s,
                    flatness=1.0,
                    shadow=0.5,
                    color=cl2,
                    transition_delay=delay + 0.1,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
            )

            if hmo:
                txtactor = Text(
                    babase.Lstr(resource='difficultyHardOnlyText'),
                    host_only=True,
                    maxwidth=txt2_max_w * 0.7,
                    position=(x + 60, y + 5),
                    transition=Text.Transition.FADE_IN,
                    vr_depth=-5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    h_align=Text.HAlign.CENTER,
                    v_align=Text.VAlign.CENTER,
                    scale=txt_s * 0.8,
                    flatness=1.0,
                    shadow=0.5,
                    color=(1, 1, 0.6, 1),
                    transition_delay=delay + 0.1,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
                txtactor.node.rotate = 10
                objs.append(txtactor)

            # Ticket-award.
            award_x = -100
            objs.append(
                Text(
                    babase.charstr(babase.SpecialChar.TICKET),
                    host_only=True,
                    position=(x + award_x + 33, y + 7),
                    transition=Text.Transition.FADE_IN,
                    scale=1.5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    h_align=Text.HAlign.CENTER,
                    v_align=Text.VAlign.CENTER,
                    color=(1, 1, 1, 0.2 if hmo else 0.4),
                    transition_delay=delay + 0.05,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
            )
            objs.append(
                Text(
                    '+' + str(self.get_award_ticket_value()),
                    host_only=True,
                    position=(x + award_x + 28, y + 16),
                    transition=Text.Transition.FADE_IN,
                    scale=0.7,
                    flatness=1,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    h_align=Text.HAlign.CENTER,
                    v_align=Text.VAlign.CENTER,
                    color=cl2,
                    transition_delay=delay + 0.05,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
            )

        else:
            complete = self.complete
            objs = []
            c_icon = self.get_icon_color(complete)
            if hmo and not complete:
                c_icon = (c_icon[0], c_icon[1], c_icon[2], c_icon[3] * 0.3)
            objs.append(
                Image(
                    self.get_icon_texture(complete),
                    host_only=True,
                    color=c_icon,
                    position=(x - 25, y + 5),
                    attach=attach,
                    vr_depth=4,
                    transition=Image.Transition.IN_RIGHT,
                    transition_delay=delay,
                    transition_out_delay=None,
                    scale=(40, 40),
                ).autoretain()
            )
            if complete:
                objs.append(
                    Image(
                        bascenev1.gettexture('achievementOutline'),
                        host_only=True,
                        mesh_transparent=bascenev1.getmesh(
                            'achievementOutline'
                        ),
                        color=(2, 1.4, 0.4, 1),
                        vr_depth=8,
                        position=(x - 25, y + 5),
                        attach=attach,
                        transition=Image.Transition.IN_RIGHT,
                        transition_delay=delay,
                        transition_out_delay=None,
                        scale=(40, 40),
                    ).autoretain()
                )
            else:
                if not complete:
                    award_x = -100
                    objs.append(
                        Text(
                            babase.charstr(babase.SpecialChar.TICKET),
                            host_only=True,
                            position=(x + award_x + 33, y + 7),
                            transition=Text.Transition.IN_RIGHT,
                            scale=1.5,
                            h_attach=h_attach,
                            v_attach=v_attach,
                            h_align=Text.HAlign.CENTER,
                            v_align=Text.VAlign.CENTER,
                            color=(1, 1, 1, (0.1 if hmo else 0.2)),
                            transition_delay=delay + 0.05,
                            transition_out_delay=None,
                        ).autoretain()
                    )
                    objs.append(
                        Text(
                            '+' + str(self.get_award_ticket_value()),
                            host_only=True,
                            position=(x + award_x + 28, y + 16),
                            transition=Text.Transition.IN_RIGHT,
                            scale=0.7,
                            flatness=1,
                            h_attach=h_attach,
                            v_attach=v_attach,
                            h_align=Text.HAlign.CENTER,
                            v_align=Text.VAlign.CENTER,
                            color=(0.6, 0.6, 0.6, (0.2 if hmo else 0.4)),
                            transition_delay=delay + 0.05,
                            transition_out_delay=None,
                        ).autoretain()
                    )

                    # Show 'hard-mode-only' only over incomplete achievements
                    # when that's the case.
                    if hmo:
                        txtactor = Text(
                            babase.Lstr(resource='difficultyHardOnlyText'),
                            host_only=True,
                            maxwidth=300 * 0.7,
                            position=(x + 60, y + 5),
                            transition=Text.Transition.FADE_IN,
                            vr_depth=-5,
                            h_attach=h_attach,
                            v_attach=v_attach,
                            h_align=Text.HAlign.CENTER,
                            v_align=Text.VAlign.CENTER,
                            scale=0.85 * 0.8,
                            flatness=1.0,
                            shadow=0.5,
                            color=(1, 1, 0.6, 1),
                            transition_delay=delay + 0.05,
                            transition_out_delay=None,
                        ).autoretain()
                        assert txtactor.node
                        txtactor.node.rotate = 10
                        objs.append(txtactor)

            objs.append(
                Text(
                    self.display_name,
                    host_only=True,
                    maxwidth=300,
                    position=(x, y + 2),
                    transition=Text.Transition.IN_RIGHT,
                    scale=0.85,
                    flatness=0.6,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    color=(
                        (0.8, 0.93, 0.8, 1.0)
                        if complete
                        else (0.6, 0.6, 0.6, (0.2 if hmo else 0.4))
                    ),
                    transition_delay=delay + 0.05,
                    transition_out_delay=None,
                ).autoretain()
            )
            objs.append(
                Text(
                    self.description_complete if complete else self.description,
                    host_only=True,
                    maxwidth=400,
                    position=(x, y - 14),
                    transition=Text.Transition.IN_RIGHT,
                    vr_depth=-5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    scale=0.62,
                    flatness=1.0,
                    color=(
                        (0.6, 0.6, 0.6, 1.0)
                        if complete
                        else (0.6, 0.6, 0.6, (0.2 if hmo else 0.4))
                    ),
                    transition_delay=delay + 0.1,
                    transition_out_delay=None,
                ).autoretain()
            )
        return objs

    def _getconfig(self) -> dict[str, Any]:
        """
        Return the sub-dict in settings where this achievement's
        state is stored, creating it if need be.
        """
        val: dict[str, Any] = babase.app.config.setdefault(
            'Achievements', {}
        ).setdefault(self._name, {'Complete': False})
        assert isinstance(val, dict)
        return val

    def _remove_banner_slot(self) -> None:
        classic = babase.app.classic
        assert classic is not None
        assert self._completion_banner_slot is not None
        classic.ach.achievement_completion_banner_slots.remove(
            self._completion_banner_slot
        )
        self._completion_banner_slot = None

    def show_completion_banner(self, sound: bool = True) -> None:
        """Create the banner/sound for an acquired achievement announcement."""
        from bascenev1lib.actor.text import Text
        from bascenev1lib.actor.image import Image

        app = babase.app
        assert app.classic is not None
        app.classic.ach.last_achievement_display_time = babase.apptime()

        # Just piggy-back onto any current activity
        # (should we use the session instead?..)
        activity = bascenev1.getactivity(doraise=False)

        # If this gets called while this achievement is occupying a slot
        # already, ignore it. (probably should never happen in real
        # life but whatevs).
        if self._completion_banner_slot is not None:
            return

        if activity is None:
            print('show_completion_banner() called with no current activity!')
            return

        if sound:
            bascenev1.getsound('achievement').play(host_only=True)
        else:
            bascenev1.timer(
                0.5, lambda: bascenev1.getsound('ding').play(host_only=True)
            )

        in_time = 0.300
        out_time = 3.5

        base_vr_depth = 200

        # Find the first free slot.
        i = 0
        while True:
            if i not in app.classic.ach.achievement_completion_banner_slots:
                app.classic.ach.achievement_completion_banner_slots.add(i)
                self._completion_banner_slot = i

                # Remove us from that slot when we close.
                # Use an app-timer in an empty context so the removal
                # runs even if our activity/session dies.
                with babase.ContextRef.empty():
                    babase.apptimer(
                        in_time + out_time, self._remove_banner_slot
                    )
                break
            i += 1
        assert self._completion_banner_slot is not None
        y_offs = 110 * self._completion_banner_slot
        objs: list[bascenev1.Actor] = []
        obj = Image(
            bascenev1.gettexture('shadow'),
            position=(-30, 30 + y_offs),
            front=True,
            attach=Image.Attach.BOTTOM_CENTER,
            transition=Image.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth - 100,
            transition_delay=in_time,
            transition_out_delay=out_time,
            color=(0.0, 0.1, 0, 1),
            scale=(1000, 300),
        ).autoretain()
        objs.append(obj)
        assert obj.node
        obj.node.host_only = True
        obj = Image(
            bascenev1.gettexture('light'),
            position=(-180, 60 + y_offs),
            front=True,
            attach=Image.Attach.BOTTOM_CENTER,
            vr_depth=base_vr_depth,
            transition=Image.Transition.IN_BOTTOM,
            transition_delay=in_time,
            transition_out_delay=out_time,
            color=(1.8, 1.8, 1.0, 0.0),
            scale=(40, 300),
        ).autoretain()
        objs.append(obj)
        assert obj.node
        obj.node.host_only = True
        obj.node.premultiplied = True
        combine = bascenev1.newnode(
            'combine', owner=obj.node, attrs={'size': 2}
        )
        bascenev1.animate(
            combine,
            'input0',
            {
                in_time: 0,
                in_time + 0.4: 30,
                in_time + 0.5: 40,
                in_time + 0.6: 30,
                in_time + 2.0: 0,
            },
        )
        bascenev1.animate(
            combine,
            'input1',
            {
                in_time: 0,
                in_time + 0.4: 200,
                in_time + 0.5: 500,
                in_time + 0.6: 200,
                in_time + 2.0: 0,
            },
        )
        combine.connectattr('output', obj.node, 'scale')
        bascenev1.animate(obj.node, 'rotate', {0: 0.0, 0.35: 360.0}, loop=True)
        obj = Image(
            self.get_icon_texture(True),
            position=(-180, 60 + y_offs),
            attach=Image.Attach.BOTTOM_CENTER,
            front=True,
            vr_depth=base_vr_depth - 10,
            transition=Image.Transition.IN_BOTTOM,
            transition_delay=in_time,
            transition_out_delay=out_time,
            scale=(100, 100),
        ).autoretain()
        objs.append(obj)
        assert obj.node
        obj.node.host_only = True

        # Flash.
        color = self.get_icon_color(True)
        combine = bascenev1.newnode(
            'combine', owner=obj.node, attrs={'size': 3}
        )
        keys = {
            in_time: 1.0 * color[0],
            in_time + 0.4: 1.5 * color[0],
            in_time + 0.5: 6.0 * color[0],
            in_time + 0.6: 1.5 * color[0],
            in_time + 2.0: 1.0 * color[0],
        }
        bascenev1.animate(combine, 'input0', keys)
        keys = {
            in_time: 1.0 * color[1],
            in_time + 0.4: 1.5 * color[1],
            in_time + 0.5: 6.0 * color[1],
            in_time + 0.6: 1.5 * color[1],
            in_time + 2.0: 1.0 * color[1],
        }
        bascenev1.animate(combine, 'input1', keys)
        keys = {
            in_time: 1.0 * color[2],
            in_time + 0.4: 1.5 * color[2],
            in_time + 0.5: 6.0 * color[2],
            in_time + 0.6: 1.5 * color[2],
            in_time + 2.0: 1.0 * color[2],
        }
        bascenev1.animate(combine, 'input2', keys)
        combine.connectattr('output', obj.node, 'color')

        obj = Image(
            bascenev1.gettexture('achievementOutline'),
            mesh_transparent=bascenev1.getmesh('achievementOutline'),
            position=(-180, 60 + y_offs),
            front=True,
            attach=Image.Attach.BOTTOM_CENTER,
            vr_depth=base_vr_depth,
            transition=Image.Transition.IN_BOTTOM,
            transition_delay=in_time,
            transition_out_delay=out_time,
            scale=(100, 100),
        ).autoretain()
        assert obj.node
        obj.node.host_only = True

        # Flash.
        color = (2, 1.4, 0.4, 1)
        combine = bascenev1.newnode(
            'combine', owner=obj.node, attrs={'size': 3}
        )
        keys = {
            in_time: 1.0 * color[0],
            in_time + 0.4: 1.5 * color[0],
            in_time + 0.5: 6.0 * color[0],
            in_time + 0.6: 1.5 * color[0],
            in_time + 2.0: 1.0 * color[0],
        }
        bascenev1.animate(combine, 'input0', keys)
        keys = {
            in_time: 1.0 * color[1],
            in_time + 0.4: 1.5 * color[1],
            in_time + 0.5: 6.0 * color[1],
            in_time + 0.6: 1.5 * color[1],
            in_time + 2.0: 1.0 * color[1],
        }
        bascenev1.animate(combine, 'input1', keys)
        keys = {
            in_time: 1.0 * color[2],
            in_time + 0.4: 1.5 * color[2],
            in_time + 0.5: 6.0 * color[2],
            in_time + 0.6: 1.5 * color[2],
            in_time + 2.0: 1.0 * color[2],
        }
        bascenev1.animate(combine, 'input2', keys)
        combine.connectattr('output', obj.node, 'color')
        objs.append(obj)

        objt = Text(
            babase.Lstr(
                value='${A}:',
                subs=[('${A}', babase.Lstr(resource='achievementText'))],
            ),
            position=(-120, 91 + y_offs),
            front=True,
            v_attach=Text.VAttach.BOTTOM,
            vr_depth=base_vr_depth - 10,
            transition=Text.Transition.IN_BOTTOM,
            flatness=0.5,
            transition_delay=in_time,
            transition_out_delay=out_time,
            color=(1, 1, 1, 0.8),
            scale=0.65,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        objt = Text(
            self.display_name,
            position=(-120, 50 + y_offs),
            front=True,
            v_attach=Text.VAttach.BOTTOM,
            transition=Text.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth,
            flatness=0.5,
            transition_delay=in_time,
            transition_out_delay=out_time,
            flash=True,
            color=(1, 0.8, 0, 1.0),
            scale=1.5,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        objt = Text(
            babase.charstr(babase.SpecialChar.TICKET),
            position=(-120 - 170 + 5, 75 + y_offs - 20),
            front=True,
            v_attach=Text.VAttach.BOTTOM,
            h_align=Text.HAlign.CENTER,
            v_align=Text.VAlign.CENTER,
            transition=Text.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth,
            transition_delay=in_time,
            transition_out_delay=out_time,
            flash=True,
            color=(0.5, 0.5, 0.5, 1),
            scale=3.0,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        objt = Text(
            '+' + str(self.get_award_ticket_value()),
            position=(-120 - 180 + 5, 80 + y_offs - 20),
            v_attach=Text.VAttach.BOTTOM,
            front=True,
            h_align=Text.HAlign.CENTER,
            v_align=Text.VAlign.CENTER,
            transition=Text.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth,
            flatness=0.5,
            shadow=1.0,
            transition_delay=in_time,
            transition_out_delay=out_time,
            flash=True,
            color=(0, 1, 0, 1),
            scale=1.5,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        # Add the 'x 2' if we've got pro.
        if app.classic.accounts.have_pro():
            objt = Text(
                'x 2',
                position=(-120 - 180 + 45, 80 + y_offs - 50),
                v_attach=Text.VAttach.BOTTOM,
                front=True,
                h_align=Text.HAlign.CENTER,
                v_align=Text.VAlign.CENTER,
                transition=Text.Transition.IN_BOTTOM,
                vr_depth=base_vr_depth,
                flatness=0.5,
                shadow=1.0,
                transition_delay=in_time,
                transition_out_delay=out_time,
                flash=True,
                color=(0.4, 0, 1, 1),
                scale=0.9,
            ).autoretain()
            objs.append(objt)
            assert objt.node
            objt.node.host_only = True

        objt = Text(
            self.description_complete,
            position=(-120, 30 + y_offs),
            front=True,
            v_attach=Text.VAttach.BOTTOM,
            transition=Text.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth - 10,
            flatness=0.5,
            transition_delay=in_time,
            transition_out_delay=out_time,
            color=(1.0, 0.7, 0.5, 1.0),
            scale=0.8,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        for actor in objs:
            bascenev1.timer(
                out_time + 1.000,
                babase.WeakCall(actor.handlemessage, bascenev1.DieMessage()),
            )


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import gzip
import os
import shutil
import tempfile

import numpy
from six.moves import urllib
import tensorflow as tf

# CVDF mirror of http://yann.lecun.com/exdb/mnist/
SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/'
WORK_DIRECTORY = 'data'
IMAGE_SIZE = 28
NUM_CHANNELS = 1
PIXEL_DEPTH = 255
VALIDATION_SIZE = 5000

def maybe_download(filename):
  """Download the data from Yann's website, unless it's already here."""
  if not tf.gfile.Exists(WORK_DIRECTORY):
    tf.gfile.MakeDirs(WORK_DIRECTORY)
  filepath = os.path.join(WORK_DIRECTORY, filename)
  if not tf.gfile.Exists(filepath):
    filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath)
    with tf.gfile.GFile(filepath) as f:
      size = f.size()
    print('Successfully downloaded', filename, size, 'bytes.')
  return filepath

def extract_data(filename, num_images):
  """Extract the images into a 4D tensor [image index, y, x, channels].
  Values are rescaled from [0, 255] down to [-0.5, 0.5].
  """
  print('Extracting', filename)
  with gzip.open(filename) as bytestream:
    bytestream.read(16)
    buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS)
    data = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.float32)
    data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH
    data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)
    return data

def extract_labels(filename, num_images):
  """Extract the labels into a vector of int64 label IDs."""
  print('Extracting', filename)
  with gzip.open(filename) as bytestream:
    bytestream.read(8)
    buf = bytestream.read(1 * num_images)
    labels = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.int64)
  return labels

train_data_filename = maybe_download('train-images-idx3-ubyte.gz')
train_labels_filename = maybe_download('train-labels-idx1-ubyte.gz')
test_data_filename = maybe_download('t10k-images-idx3-ubyte.gz')
test_labels_filename = maybe_download('t10k-labels-idx1-ubyte.gz')

# Extract it into numpy arrays.
train_data = extract_data(train_data_filename, 60000)
train_labels = extract_labels(train_labels_filename, 60000)
test_data = extract_data(test_data_filename, 10000)
test_labels = extract_labels(test_labels_filename, 10000)

validation_data = train_data[:VALIDATION_SIZE, ...]
validation_labels = train_labels[:VALIDATION_SIZE]
train_data = train_data[VALIDATION_SIZE:, ...]
train_labels = train_labels[VALIDATION_SIZE:]

train_size = train_labels.shape[0]
image_size = train_data.shape[1:]
test_size = test_data.shape[0]

# Example of curried function: a function that returns an other function.
def feed_dict_gen(BATCH_SIZE, step, type='train'):
  """format data to feed to session"""
  if (type=='train'):
    data, labels, size = train_data, train_labels, train_size
  else:
    data, labels, size = test_data, test_labels, test_size

  offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE)
  batch_data = train_data[offset:(offset + BATCH_SIZE), ...]
  batch_labels = train_labels[offset:(offset + BATCH_SIZE)]

  return [batch_labels, batch_data]


from PyQt4 import QtCore, QtGui
import xml.etree.cElementTree as ET
from log_manager import logger
import csv

SYNC_CONFIG_FILE = "storj_sync_config.xml"
SYNC_DIRECTORIES_FILE = "storj_sync_dirs.csv"

# Configuration backend section
class SyncConfiguration():

    def __init__(self, load_config=False):
        if load_config:

            et = None

            try:
                et = ET.parse(CONFIG_FILE)
            except:
                logger.error("Unspecified XML parse error")

            for tags in et.iter(str("same_file_name_prompt")):
                if tags.text == "1":
                    self.sameFileNamePrompt = True
                elif tags.text == "0":
                    self.sameFileNamePrompt = False
                else:
                    self.sameFileNamePrompt = True
            for tags in et.iter(str("same_file_hash_prompt")):
                if tags.text == "1":
                    self.sameFileHashPrompt = True
                elif tags.text == "0":
                    self.sameFileHashPrompt = False
                else:
                    self.sameFileHashPrompt = True
            for tags in et.iter(str("max_chunk_size_for_download")):
                if tags.text is not None:
                    self.maxDownloadChunkSize = int(tags.text)
                else:
                    self.maxDownloadChunkSize = 1024

    def get_config_parametr_value(self, parametr):
        output = ""
        try:
            et = ET.parse(CONFIG_FILE)
            for tags in et.iter(str(parametr)):
                output = tags.text
        except:
            logger.error("Unspecified error")

        return output

    def load_config_from_xml(self):
        try:
            et = ET.parse(SYNC_CONFIG_FILE)
            for tags in et.iter('password'):
                output = tags.text
        except:
            logger.error("Unspecified error")

    def paint_config_to_ui(self, settings_ui):

        self.load_sync_directories(settings_ui.sync_directories_tableWidget)

        et = None

        try:
            et = ET.parse(SYNC_CONFIG_FILE)

            for tags in et.iter(str("max_shard_size")):
                settings_ui.max_shard_size.setValue(int(tags.text))
            for tags in et.iter(str("max_connections_onetime")):
                settings_ui.connections_onetime.setValue(int(tags.text))
            for tags in et.iter(str("bridge_request_timeout")):
                settings_ui.bridge_request_timeout.setValue(int(tags.text))
            for tags in et.iter(str("crypto_keys_location")):
                settings_ui.crypto_keys_location.setText(str(tags.text))
            for tags in et.iter(str("max_download_bandwidth")):
                settings_ui.max_download_bandwidth.setText(str(tags.text))
            for tags in et.iter(str("max_upload_bandwidth")):
                settings_ui.max_upload_bandwidth.setText(str(tags.text))
            for tags in et.iter(str("default_file_encryption_algorithm")):
                settings_ui.default_crypto_algorithm.setCurrentIndex(int(tags.text))
            for tags in et.iter(str("shard_size_unit")):
                settings_ui.shard_size_unit.setCurrentIndex(int(tags.text))
            for tags in et.iter(str("custom_max_shard_size_enabled")):
                if int(tags.text) == 1:
                    settings_ui.max_shard_size_enabled_checkBox.setChecked(True)
                else:
                    settings_ui.max_shard_size_enabled_checkBox.setChecked(False)

        except Exception as e:
            logger.error("Unspecified XML parse error" + str(e))

    def save_sync_configuration(self, settings_ui):

        self.save_sync_directories(settings_ui.sync_directories_tableWidget)

        with open(SYNC_CONFIG_FILE, 'r') as conf_file:
            XML_conf_data = conf_file.read().replace('\n', '')

        tree = ET.parse(SYNC_CONFIG_FILE)

        #root = ET.Element("configuration")
        #doc = ET.SubElement(root, "client")

        # settings_ui = Ui_
        if settings_ui.sync_enabled_checkBox.isChecked():
            sync_enabled_checkbox = '1'
        else:
            sync_enabled_checkbox = '0'

        if settings_ui.start_sync_on_boot_checkBox.isChecked():
            start_sync_on_boot_checkbox = '1'
        else:
            start_sync_on_boot_checkbox = '0'

        if settings_ui.show_sync_tray_icon_checkBox.isChecked():
            show_sync_tray_icon_checkbox = '1'
        else:
            show_sync_tray_icon_checkbox = '0'

        tree.write(SYNC_CONFIG_FILE)

    def load_sync_directories(self, sync_directories_table):
        with open(unicode(SYNC_DIRECTORIES_FILE), 'rb') as stream:
            sync_directories_table.setRowCount(0)
            sync_directories_table.setColumnCount(0)
            for rowdata in csv.reader(stream):
                row = sync_directories_table.rowCount()
                sync_directories_table.insertRow(row)
                sync_directories_table.setColumnCount(len(rowdata))
                for column, data in enumerate(rowdata):
                    item = QtGui.QTableWidgetItem(data.decode('utf8'))
                    sync_directories_table.setItem(row, column, item)

    def save_sync_directories(self, sync_directories_table):
        with open(unicode(SYNC_DIRECTORIES_FILE), 'wb') as stream:
            writer = csv.writer(stream)
            for row in range(sync_directories_table.rowCount()):
                rowdata = []
                for column in range(sync_directories_table.columnCount()):
                    item = sync_directories_table.item(row, column)
                    if item is not None:
                        rowdata.append(
                            unicode(item.text()).encode('utf8'))
                    else:
                        rowdata.append('')
                writer.writerow(rowdata)