from pymatgen.core import Structure
from pymatgen.analysis.magnetism.analyzer import MagneticStructureEnumerator, CollinearMagneticStructureAnalyzer
from pymatgen.io.vasp.inputs import Poscar, Incar, Kpoints
from pymatgen.io.vasp.sets import MPRelaxSet, MPStaticSet, MPSOCSet
import os

def create_job_script(out_path, job_id='JobName'):
    """
    Args:
        out_path (str)   -   folder where job script will be created.
        job_id   (str)   -   preferable name of your job in squeue,
        and also the name of the folder for your vasp files.
        As a result in the folder with name 'job_id' will be created job script
    """
    job_script_text = f"""#!/bin/bash
#SBATCH --nodes=1
#SBATCH --ntasks=8
#SBATCH --time=06:00:00
#SBATCH --job-name={job_id}
#SBATCH --output=log
#SBATCH --error=err
#SBATCH -p lenovo
module load mpi/impi-5.0.3 intel/mkl-11.2.3 vasp/vasp-5.4.4
mpirun vasp_std"""
    if not os.path.exists(out_path):
        os.mkdir(out_path)
    with open(f'{out_path}/jobscript.sh', 'w') as job:
        job.writelines(job_script_text)

def get_VASP_inputs(input_path, mag_prec=0.1, enum_prec=0.00001):
    init_structure = Structure.from_file(os.path.join(input_path, 'POSCAR'))
    enum_struct_list = MagneticStructureEnumerator(init_structure, transformation_kwargs={
                                                   'symm_prec': mag_prec, 'enum_precision_parameter': enum_prec})

    for i, magnetic_structure in enumerate(enum_struct_list.ordered_structures):
        magnetic_type = enum_struct_list.ordered_structure_origins[i]
        str_id = magnetic_type + str(i)
        vasp_out_path = os.path.join(input_path, 'vasp_inputs', str_id)
        relax_set = MPStaticSet(structure=magnetic_structure)
        relax_set.get_vasp_input().write_input(vasp_out_path)
        create_job_script(vasp_out_path, job_id=str_id)

def afm_atom_creator(in_data: list, custom_atom='Po') -> list:
    """
    Args:
        in_data (list) - list of rows from POSCAR type file.

    Add one type of "Fake" atom into the POSCAR structure.
    This allows it to be treated as an atoms with spin up and down respectively,
    thus estimate number of positive and negative contributions into the total energy.
    """
    out_data = in_data.copy()
    out_data[5] = 'Po ' + out_data[5]
    return out_data

def up_down_spin_counter(in_data: list) -> list:
    spin_down = 0
    spin_up = 0
    no_spin = 0
    for row in in_data[8:]:
        if 'spin=-' in row:
            spin_down += 1
        elif 'spin=' in row:
            spin_up += 1
        else:
            no_spin += 1
    return [spin_up, spin_down, no_spin]

def spin_row_replacer(in_data: list) -> list:
    out_data = in_data.copy()
    out_data[6] = ' '.join(str(i) for i in up_down_spin_counter(in_data)) + '\n'
    return out_data

def siman_POSCAR_writer(in_path: str, out_path: str) -> None:
    """
    Args:
        in_path  (str)  -   path to the POSCAR type file which needs to be made
                            readable for siman
        out_path (str)  -   path where refactored version of this file will be
                            written
    """
    with open(in_path) as in_f:
        in_data = in_f.readlines()

    out_data = spin_row_replacer(afm_atom_creator(in_data))

    with open(out_path, 'w+') as out_f:
        out_f.writelines(out_data)

def get_siman_inputs(input_path: str):
    out_path = os.path.join(input_path, 'siman_inputs')
    if not os.path.exists(out_path):
        os.mkdir(out_path)
    vasp_inputs_path = os.path.join(input_path, 'vasp_inputs')
    afm_foldrs = [os.path.join(vasp_inputs_path, i)
                  for i in [i for i in os.listdir(vasp_inputs_path) if 'afm' in i]]
    for folder in afm_foldrs:
        tmp_out_path = os.path.join(out_path, 'POSCAR_' + folder.split("/")[-1])
        siman_POSCAR_writer(in_path=os.path.join(folder, 'POSCAR'), out_path=tmp_out_path)

def submit_all_jobs(input_folder: str) -> None:
    vasp_inputs_path = os.path.join(input_folder, 'vasp_inputs')
    initial_path = os.getcwd()
    for folder_name in os.listdir(vasp_inputs_path):
        os.chdir(initial_path)
        tmp_path = os.path.join(vasp_inputs_path, folder_name)
        os.chdir(tmp_path)
        os.system('sbatch jobscript.sh')
    os.chdir(initial_path)

def main_runner(input_path):
    assert os.path.exists(input_path), f'Input path: {input_path} does not exist!'
    assert os.path.exists(os.path.join(input_path, 'POSCAR')
                          ), f'Please specify POSCAR file in you input folder: {input_path}'
    get_VASP_inputs(input_path=input_path)
    get_siman_inputs(input_path=input_path)
    submit_all_jobs(input_path)

if __name__ == '__main__':
    input_path = input('Specifie your input folder: ')
    main_runner(input_path)


import datetime
import queue
import random
import re
import time
import urllib
import urllib.robotparser

import requests
from bs4 import BeautifulSoup

USER_AGENT = [{'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'},\
              {'User-Agent':'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11'},\
              {'User-Agent':'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'},\
              {'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0'},\
              {'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/44.0.2403.89 Chrome/44.0.2403.89 Safari/537.36'},\
              {'User-Agent':'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'},\
              {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'},\
              {'User-Agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0'},\
              {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'},\
              {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'},\
              {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11'},\
              {'User-Agent':'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11'},\
              {'User-Agent':'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11'}]

DELAY_SEC = 5
SUCCESS_CODE = 200

def download_page(url, num_retries=2, headers=None, data=None):
    """下载网页内容，如果状态码不匹配，返回空字符串。否则返回utf-8编码的字符串
    """
    print(time.ctime(), ' : ', 'Downloading...:', url)
    # headers = header.update(USER_AGENT[random.randrange(0, len(USER_AGENT))])
    headers = headers or {}
    try:
        response = requests.get(url, headers=headers, data=data)
        code = response.status_code
        page_content = str(response.content, encoding='utf-8')
    except requests.RequestException as e:
        print(time.ctime(), ' : Download error ', e.args)
        page_content = ''
        if num_retries > 0:
            time.sleep(DELAY_SEC)
            return download_page(url, num_retries-1, data=data)

    if code != SUCCESS_CODE:
        print(time.ctime(), ' : The status code is:', code, '\nPlease check!')
        page_content = ''
    if page_content:
        print(time.ctime(), ' : Response string is not None')
        # print(page_content)
    return page_content

def link_crawler(seed_url, link_regex=None, delay=DELAY_SEC, max_depth=-1, max_urls=-1, **kw):
    """通过匹配链接关键字从种子链接开始爬取网页
    """
    # 待爬取队列
    crawl_queue = queue.deque([seed_url])
    # 口路url是否已被爬取，以及所在深度
    seen = {seed_url: 0}
    # 记录爬取的总页面数
    num_urls = 0
    # 记录被禁止访问的页面
    blocked_url = []
    # 记录抓取数据
    crawled_data = []

    robot_parse = get_robot(seed_url)
    throttles = throttle(delay)
    headers = kw.get('headers', {})

    while crawl_queue:
        url = crawl_queue.pop()
        # 检查url是否通过网站robots.txt的限制
        user_agent = USER_AGENT[random.randrange(0, len(USER_AGENT))]
        if robot_parse.can_fetch(user_agent, url):
            throttles.wait(url)
            headers.update(user_agent)
            html = download_page(url, headers=headers)
            links = []

            depth = seen.get(url, -1)
            if depth != max_depth:
                # 深度不匹配， 还可以继续抓取页面
                if link_regex:
                    # 搜寻匹配的网址
                    links.extend(link for link in get_links(html) if re.search(link_regex, link))

                for link in links:
                    link = normalize(seed_url, link)
                    # 检查是否已经爬取过该地址
                    if link not in seen:
                        seen[link] = depth + 1
                        # 检查网页是否在本网站之内
                        if same_domain(seed_url, link):
                            # 是就加入爬取队列之中
                            crawl_queue.append(link)

            # 检查是否已经达到最大下载数量
            num_urls = num_urls + 1
            if num_urls == max_urls:
                break

        else:
            blocked_url.append(url)
            print('Blocked by robots.txt: ', url)

class throttle(object):
    """通过time.sleep()控制对相同网站下载网页的间隔
    """
    def __init__(self, delay):
        # 两次下载的间隔时间
        self.delay = delay
        # 记录上次访问网站时的时间戳
        self.domains_time_stamp = {}
        # 记录睡眠睡眠次数
        self.times = 0

    def wait(self, url):
        domain = urllib.parse.urlparse(url).netloc
        last_accessed_time = self.domains_time_stamp.get(domain)
        now_time = datetime.datetime.now()
        if self.delay > 0 and last_accessed_time is not None:
            sleep_secs = self.delay - (now_time - last_accessed_time).seconds
            if sleep_secs > 0:
                time.sleep(sleep_secs)
                self.times = self.times + 1
                print(time.ctime(), ': Sleeped : ', sleep_secs, self.times)
        self.domains_time_stamp[domain] = now_time

def get_robot(seed_url):
    """返回robots.txt的解析对象
    """
    # robot_parse = urllib.robotparser.RobotFileParser()
    robot_parse = urllib.robotparser.RobotFileParser()
    robot_parse.set_url(urllib.parse.urljoin(seed_url, '/robots.txt'))
    robot_parse.read()
    return robot_parse

def normalize(seed_url, link):
    """去除链接干扰项
    """
    parse_result = urllib.parse.urlparse(link)
    return urllib.parse.urljoin(seed_url, parse_result.path)

def same_domain(url1, url2):
    """如果两个网址属于同一网站，返回True
    """
    return urllib.parse.urlparse(url1).netloc == urllib.parse.urlparse(url2).netloc

def get_links(html):
    """通过正则匹配获取链接
    """
    webpage_regex = re.compile(r'.*?', re.S)
    return webpage_regex.findall(html)

if __name__ == '__main__':
    # link_crawler('http://example.webscraping.com', '/(index|view)', delay=0, num_retries=1, user_agent='BadCrawler')
    link_crawler('http://example.webscraping.com', '/(index|view)', delay=5, num_retries=1, max_depth=1, user_agent='GoodCrawler')


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
file_name= 'PAPER_INITIAL_10.csv'
df=pd.read_csv(file_name,sep=';')
new_data=np.zeros((15,55,5))

for j in range(15):
    for k in range(55):
        for l in range(5):
            part_1='BPR:'
            part_2=str(j+1)
            part_3=','+str(k+1)
            part_4=','+str(l+1)
            layer_name=part_1+ part_2+ part_3+part_4
            data = df[layer_name]
            value = data.to_numpy()[-1]
            new_data[j,k,l] = value

plt.imshow(new_data[:,:,1],cmap='jet',vmin=4120,vmax=np.max(new_data[:,:,1])*1.)
plt.colorbar()
plt.show()

x1=open('X-pressure.csv','w')

for j in range(15):
	for k in range(55):
		for l in range(5):
			x1.write(str(new_data[j,k,l])+',')
x1.write('\n')

x1.close()


# -*- coding: utf-8 -*- #
# Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests for coshell module."""

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

import io
import os
import signal
import subprocess
import sys

from googlecloudsdk.command_lib.interactive import coshell
from googlecloudsdk.core.util import files
from tests.lib import sdk_test_base
from tests.lib import test_case
import six
from six.moves import range

def _GetOpenFds():
  """Returns the set of open fds."""
  fds = set()
  for fd in range(64):
    try:
      os.fstat(fd)
      fds.add(fd)
    except OSError:
      pass
  return fds

class _CoshellTestBase(sdk_test_base.SdkBase, test_case.WithContentAssertions):

  def SetUp(self):
    self.StartDictPatch(os.environ)
    if 'ENV' in os.environ:
      del os.environ['ENV']
    self.coshell = None
    self.tmp = self.CreateTempDir()
    self.output_file = os.path.join(self.tmp, 'coshell.out')
    self.error_file = os.path.join(self.tmp, 'coshell.err')
    self.CoOpen()

  def TearDown(self):
    self.CoClose()

  def CoOpen(self):
    if self.coshell:
      self.coshell.Close()

    if six.PY3:
      stdout = os.open(self.output_file, os.O_CREAT | os.O_WRONLY)
      stderr = os.open(self.error_file, os.O_CREAT | os.O_WRONLY)
      self.coshell = coshell.Coshell(stdout=stdout, stderr=stdout)
      os.close(stdout)
      os.close(stderr)
    else:
      # py3 test framework can't suffer these fd shenanigans
      sys.stdout.flush()
      sys.stderr.flush()

      old_out_fd = os.dup(1)
      new_out_fd = os.open(self.output_file, os.O_CREAT | os.O_WRONLY)
      os.dup2(new_out_fd, 1)
      os.close(new_out_fd)

      old_err_fd = os.dup(2)
      new_err_fd = os.open(self.error_file, os.O_CREAT | os.O_WRONLY)
      os.dup2(new_err_fd, 2)
      os.close(new_err_fd)

      self.coshell = coshell.Coshell()

      os.dup2(old_out_fd, 1)
      os.close(old_out_fd)

      os.dup2(old_err_fd, 2)
      os.close(old_err_fd)

  def CoClose(self):
    if self.coshell:
      self.coshell.Close()
      self.coshell = None

  def GetOutput(self):
    with io.open(self.output_file, 'r', encoding='utf-8') as f:
      return f.read()

  def GetErr(self):
    with io.open(self.error_file, 'r', encoding='utf-8') as f:
      return f.read()

  def AssertOutputEquals(self, expected, normalize_space=False):
    self._AssertEquals(expected, self.GetOutput(), 'output',
                       normalize_space=normalize_space)

  def AssertOutputContains(self, expected, normalize_space=False):
    self._AssertContains(expected, self.GetOutput(), 'output',
                         normalize_space=normalize_space)

  def AssertOutputMatches(self, expected, normalize_space=False):
    self._AssertMatches(expected, self.GetOutput(), 'output',
                        normalize_space=normalize_space)

  def AssertErrEquals(self, expected, normalize_space=False):
    self._AssertEquals(expected, self.GetErr(), 'error',
                       normalize_space=normalize_space)

  def AssertErrContains(self, expected, normalize_space=False):
    self._AssertContains(expected, self.GetErr(), 'error',
                         normalize_space=normalize_space)

  def AssertErrMatches(self, expected, normalize_space=False):
    self._AssertMatches(expected, self.GetErr(), 'error',
                        normalize_space=normalize_space)

@test_case.Filters.DoNotRunOnWindows  # UNIX specific tests.
@test_case.Filters.DoNotRunOnMac  # Config based output capture flakes?
@sdk_test_base.Filters.DoNotRunOnGCE  # Config based output capture flakes?
@test_case.Filters.SkipOnPy3('test framework fd 0 interaction', 'b/80533542')
class UnixCoshellTest(_CoshellTestBase):

  def testUnixCoshellEditMode(self):
    self.assertEqual('emacs', self.coshell.edit_mode)
    self.coshell.Run('set -o vi')
    self.assertEqual('vi', self.coshell.edit_mode)
    self.coshell.Run('set -o emacs')
    self.assertEqual('emacs', self.coshell.edit_mode)

  def testUnixCoshellIgnoreEof(self):
    self.assertFalse(self.coshell.ignore_eof)
    self.coshell.Run('set -o ignoreeof')
    self.assertTrue(self.coshell.ignore_eof)
    self.coshell.Run('set +o ignoreeof')
    self.assertFalse(self.coshell.ignore_eof)

  def testUnixCoshellStateIsPreserved(self):
    self.assertTrue(self.coshell.state_is_preserved)

  def testUnixCoshellENV(self):
    os.environ['ENV'] = self.Touch(
        directory=self.tmp,
        name='coshell.env',
        contents='set -o vi\nset -o ignoreeof\n')
    self.CoOpen()
    self.assertEqual('vi', self.coshell.edit_mode)
    self.assertTrue(self.coshell.ignore_eof)

  def testUnixCoshellTrueStatus(self):
    status = self.coshell.Run('true')
    self.assertEqual(0, status)

  def testUnixCoshellFalseStatus(self):
    status = self.coshell.Run('false')
    self.assertEqual(1, status)

  def testUnixCoshellEcho(self):
    self.coshell.Run('echo foo')
    self.CoClose()
    self.AssertOutputEquals('foo\n')

  def testUnixCoshellPwdState(self):
    self.coshell.Run('pwd=$PWD')
    self.coshell.Run('cd /')
    self.assertEqual('/', os.getcwd())
    self.coshell.Run('pwd')
    self.coshell.Run('cd /bin')
    self.assertEqual('/bin', os.getcwd())
    self.coshell.Run('pwd')
    self.coshell.Run('cd $pwd')
    self.CoClose()
    self.AssertOutputEquals('/\n/bin\n')

  def testUnixCoshellVariableState(self):
    self.coshell.Run('echo original :$foo:')
    self.coshell.Run('foo=bar')
    self.coshell.Run('echo updated :$foo:')
    self.CoClose()
    self.AssertOutputEquals('original ::\nupdated :bar:\n')

  def testUnixCoshellVariableStateBackground(self):
    self.coshell.Run('echo original :$foo: &')
    self.coshell.Run('foo=bar')
    self.coshell.Run('echo updated :$foo: &')
    self.coshell.Run('wait')
    # Output order from the two background processes is not guaranteed.
    self.CoClose()
    self.AssertOutputContains('original ::\n')
    self.AssertOutputContains('updated :bar:\n')

  def testUnixCoshellUnicode(self):
    self.coshell._encoding = 'utf-8'
    self.coshell.Run('echo Ṳᾔḯ¢◎ⅾℯ')
    self.AssertOutputContains('Ṳᾔḯ¢◎ⅾℯ\n')

  def testUnixCoshellCreateDelete(self):
    with files.TemporaryDirectory(change_to=True):
      self.CoOpen()
      tmp = 'coshell.tst'
      self.AssertFileNotExists(tmp)
      self.coshell.Run('echo foo > {}'.format(tmp))
      self.AssertFileExists(tmp)
      self.coshell.Run('rm {}'.format(tmp))
      self.AssertFileNotExists(tmp)

  def testUnixCoshellFdLeaks(self):
    self.CoClose()
    old_fds = _GetOpenFds()
    self.CoOpen()
    self.CoClose()
    new_fds = _GetOpenFds()
    self.assertEqual(set(), old_fds ^ new_fds)

  def testUnixCoshellJobsBackground(self):
    self.coshell.Run('sleep 1 && echo EXPIRED &')
    self.coshell.Run('jobs')
    self.coshell.Run('fg')
    self.coshell.Run('wait')
    self.CoClose()
    self.AssertOutputMatches(r'^\[1\]\+ Running sleep 1 && echo EXPIRED &$',
                             normalize_space=True)
    self.AssertOutputMatches(r'^sleep 1 && echo EXPIRED$',
                             normalize_space=True)
    self.AssertOutputMatches('^EXPIRED$', normalize_space=True)

  def testUnixCoshellInterrupt(self):
    self.coshell.Run('trap "echo INTERRUPTED" INT')
    self.coshell.Interrupt()
    # Must run some command here to avoid race between INTERRUPTED being printed
    # and checking the output file for INTERRUPTED.
    self.coshell.Run('wait')
    self.CoClose()
    self.AssertOutputMatches('^INTERRUPTED$', normalize_space=True)

  def testUnixCoshellExit(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('exit')
    self.assertEqual(0, self.coshell.Close())

  def testUnixCoshellExit0(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('exit 0')
    self.assertEqual(0, self.coshell.Close())

  @test_case.Filters.skip('rare annoying exit 0 flakes', 'b/65456434')
  def testUnixCoshellExit1(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('exit 1')
    self.assertEqual(1, self.coshell.Close())

  def testUnixCoshellRunAfterExit(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('exit')
      self.coshell.Run(':')
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('echo oops')
    self.assertEqual(0, self.coshell.Close())

  def testUnixCoshellRunAfterClose(self):
    self.assertEqual(0, self.coshell.Close())
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('echo oops')

  def testUnixCoshellDied(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('kill -TERM $$')
    # 15 = index(SIGTERM); 271 = 256 + 15
    status = self.coshell.Close()
    # subprocess.Popen().returncode flakes to 0 in some test environments.
    if status:
      self.assertEqual(271, status)

  def testUnixCoshellSyntaxError(self):
    self.coshell.Run('echo "oops')
    self.coshell.Run('echo ok')
    self.assertEqual(0, self.coshell.Close())
    self.AssertOutputContains('ok\n')
    self.AssertErrContains('unexpected EOF while looking for matching')
    self.AssertErrContains('syntax error: unexpected end of file')

  def testUnixCoshellShellFdRedirections(self):
    self.CoClose()

    # Set up unrelated fds on SHELL_STATUS_FD and SHELL_STDIN_FD.

    shell_status_path = self.Touch(
        directory=self.tmp,
        name='coshell.status',
        contents='SHELL_STATUS_FD')
    try:
      old_shell_status_fd = os.dup(coshell._UnixCoshellBase.SHELL_STATUS_FD)
    except OSError:
      old_shell_status_fd = -1
    fd = os.open(shell_status_path, os.O_RDONLY)
    if fd != coshell._UnixCoshellBase.SHELL_STATUS_FD:
      os.dup2(fd, coshell._UnixCoshellBase.SHELL_STATUS_FD)
      os.close(fd)

    shell_stdin_path = self.Touch(
        directory=self.tmp,
        name='coshell.stdin',
        contents='SHELL_STDIN_FD')
    try:
      old_shell_stdin_fd = os.dup(coshell._UnixCoshellBase.SHELL_STDIN_FD)
    except OSError:
      old_shell_stdin_fd = -1
    fd = os.open(shell_stdin_path, os.O_RDONLY)
    if fd != coshell._UnixCoshellBase.SHELL_STDIN_FD:
      os.dup2(fd, coshell._UnixCoshellBase.SHELL_STDIN_FD)
      os.close(fd)

    # Open and close a coshell object.

    self.CoOpen()
    self.CoClose()

    # Make sure original SHELL_STATUS_FD and SHELL_STDIN_FD weren't clobbered.

    shell_status_contents = os.read(
        coshell._UnixCoshellBase.SHELL_STATUS_FD, 1024)
    self.assertEqual(b'SHELL_STATUS_FD', shell_status_contents)
    if old_shell_status_fd >= 0:
      os.dup2(old_shell_status_fd, coshell._UnixCoshellBase.SHELL_STATUS_FD)

    shell_stdin_contents = os.read(
        coshell._UnixCoshellBase.SHELL_STDIN_FD, 1024)
    self.assertEqual(b'SHELL_STDIN_FD', shell_stdin_contents)
    if old_shell_stdin_fd >= 0:
      os.dup2(old_shell_stdin_fd, coshell._UnixCoshellBase.SHELL_STDIN_FD)

@test_case.Filters.DoNotRunOnWindows  # UNIX specific tests.
@test_case.Filters.DoNotRunOnMac  # Config based output capture flakes?
@sdk_test_base.Filters.DoNotRunOnGCE  # Config based output capture flakes?
@test_case.Filters.SkipOnPy3('test framework fd 0 interaction', 'b/80533542')
class UnixCoshellInteractiveTest(_CoshellTestBase):

  def _RawInput(self, prompt):
    if not self._input:
      raise EOFError('EOF')
    return self._input.pop(0)

  def _HandleInterrupt(self, signal_number=None, frame=None):
    """Handles keyboard interrupts (aka SIGINT, ^C)."""
    del signal_number, frame  # currently unused
    raise KeyboardInterrupt('Test harness interrupted.')

  def _InteractiveLoop(self):
    """A typical coshell interactive loop."""
    cosh = coshell.Coshell()
    prompt = '$ '

    try:
      old_handler = signal.signal(signal.SIGINT, self._HandleInterrupt)

      while True:

        try:
          command = self._RawInput(prompt)
        except EOFError:
          if not cosh.ignore_eof:
            break
          sys.stdout.write('\b' * len(prompt))
          continue
        except KeyboardInterrupt:
          sys.stdout.write('\n')
          continue

        if command == 'TEST-Interrupt':
          cosh.Interrupt()
          continue
        try:
          cosh.Run(command)
        except coshell.CoshellExitException:
          break

    finally:
      signal.signal(signal.SIGINT, old_handler)

    return cosh.Close()

  def Interactive(self, commands):
    self._input = commands
    self.CoClose()
    old_out_fd = os.dup(1)
    old_err_fd = os.dup(2)
    new_out_fd = os.open(self.output_file, os.O_CREAT | os.O_WRONLY)
    new_err_fd = os.open(self.error_file, os.O_CREAT | os.O_WRONLY)
    os.dup2(new_out_fd, 1)
    os.dup2(new_err_fd, 2)
    os.close(new_out_fd)
    os.close(new_err_fd)

    status = 127
    try:
      status = self._InteractiveLoop()
    finally:
      os.dup2(old_out_fd, 1)
      os.dup2(old_err_fd, 2)
      os.close(old_out_fd)
      os.close(old_err_fd)
    return status

  def testUnixCoshellInteractiveTrue(self):
    status = self.Interactive([
        'true',
    ])
    self.assertEqual(0, status)

  def testUnixCoshellInteractiveFalse(self):
    status = self.Interactive([
        'false',
    ])
    self.assertEqual(1, status)

  @test_case.Filters.skip('rare annoying exit 0 flakes', 'b/65456434')
  def testUnixCoshellInteractiveExit(self):
    status = self.Interactive([
        'exit 123',
    ])
    self.assertEqual(123, status)

  def testUnixCoshellInteractiveEcho(self):
    status = self.Interactive([
        'echo foo',
        'echo bar',
    ])
    self.assertEqual(0, status)
    self.AssertOutputEquals('foo\nbar\n')

  def testUnixCoshellInteractiveInterrupt(self):
    status = self.Interactive([
        'trap "echo INTERRUPTED" INT',
        'sleep 2 &',
        'TEST-Interrupt',
        'echo DONE',
    ])
    self.assertEqual(0, status)
    self.AssertOutputEquals('INTERRUPTED\nDONE\n')

@test_case.Filters.DoNotRunOnWindows  # UNIX specific tests.
@test_case.Filters.DoNotRunOnMac  # Config based output capture flakes?
@sdk_test_base.Filters.DoNotRunOnGCE  # Config based output capture flakes?
@test_case.Filters.SkipOnPy3('test framework fd 0 interaction', 'b/80533542')
class MingWCoshellOnUnixTest(_CoshellTestBase):

  def _Popen(self):
    return subprocess.Popen(
        '/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE)

  def CoOpen(self):
    if self.coshell:
      self.coshell.Close()
    else:
      self.StartObjectPatch(
          coshell._MinGWCoshell, '_Popen', side_effect=self._Popen)

    sys.stdout.flush()
    sys.stderr.flush()

    old_out_fd = os.dup(1)
    new_out_fd = os.open(self.output_file, os.O_CREAT | os.O_WRONLY)
    os.dup2(new_out_fd, 1)
    os.close(new_out_fd)

    old_err_fd = os.dup(2)
    new_err_fd = os.open(self.error_file, os.O_CREAT | os.O_WRONLY)
    os.dup2(new_err_fd, 2)
    os.close(new_err_fd)

    self.coshell = coshell._MinGWCoshell()
    self.coshell.STDIN_PATH = '/dev/null'
    self.coshell.STDOUT_PATH = self.output_file

    os.dup2(old_out_fd, 1)
    os.close(old_out_fd)

    os.dup2(old_err_fd, 2)
    os.close(old_err_fd)

  def testMinGWCoshellEditMode(self):
    self.assertEqual('emacs', self.coshell.edit_mode)
    self.coshell.Run('set -o vi')
    self.assertEqual('vi', self.coshell.edit_mode)
    self.coshell.Run('set -o emacs')
    self.assertEqual('emacs', self.coshell.edit_mode)

  def testMinGWCoshellIgnoreEof(self):
    self.assertFalse(self.coshell.ignore_eof)
    self.coshell.Run('set -o ignoreeof')
    self.assertTrue(self.coshell.ignore_eof)
    self.coshell.Run('set +o ignoreeof')
    self.assertFalse(self.coshell.ignore_eof)

  def testMinGWCoshellStateIsPreserved(self):
    self.assertTrue(self.coshell.state_is_preserved)

  def testMinGWCoshellTrueStatus(self):
    status = self.coshell.Run('true')
    self.assertEqual(0, status)

  def testMinGWCoshellFalseStatus(self):
    status = self.coshell.Run('false')
    self.assertEqual(1, status)

  def testMinGWCoshellEcho(self):
    self.coshell.Run('echo foo')
    self.CoClose()
    self.AssertOutputEquals('foo\n')

  def testMinGWCoshellPwdState(self):
    self.coshell.Run('pwd=$PWD')
    self.coshell.Run('cd /')
    self.coshell.Run('pwd')
    self.coshell.Run('cd /bin')
    self.coshell.Run('pwd')
    self.coshell.Run('cd $pwd')
    self.CoClose()
    self.AssertOutputEquals('/\n/bin\n')

  def testMinGWCoshellVariableState(self):
    self.coshell.Run('echo original :$foo:')
    self.coshell.Run('foo=bar')
    self.coshell.Run('echo updated :$foo:')
    self.CoClose()
    self.AssertOutputEquals('original ::\nupdated :bar:\n')

  def testMinGWCoshellVariableStateBackground(self):
    self.coshell.Run('echo original :$foo: &')
    self.coshell.Run('foo=bar')
    self.coshell.Run('echo updated :$foo: &')
    self.coshell.Run('wait')
    # Output order from the two background processes is not guaranteed.
    self.CoClose()
    self.AssertOutputContains('original ::\n')
    self.AssertOutputContains('updated :bar:\n')

  @test_case.Filters.SkipInDebPackage('Flakes', 'b/67582029')
  @test_case.Filters.SkipInRpmPackage('Flakes', 'b/67582029')
  def testMinGWCoshellExit(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('exit')
    self.assertEqual(0, self.coshell.Close())

  def testMinGWCoshellExit0(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('exit 0')
    self.assertEqual(0, self.coshell.Close())

  def testMinGWCoshellExit1(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('exit 1')
    # EPIPE before status can be retrieved.
    # self.assertEqual(1, self.coshell.Close())

  def testMinGWCoshellRunAfterExit(self):
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('exit')
      self.coshell.Run(':')
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('echo oops')
    self.assertEqual(0, self.coshell.Close())

  def testMinGWCoshellRunAfterClose(self):
    self.assertEqual(0, self.coshell.Close())
    with self.assertRaises(coshell.CoshellExitException):
      self.coshell.Run('echo oops')

class WindowsCoshellTest(_CoshellTestBase):
  """Funny that the Windows sepcific tests run everywhere."""

  def SetUp(self):
    # Mock the coshell module generic "is running on windows" test.
    self.StartObjectPatch(coshell, '_RunningOnWindows', return_value=True)
    # Un-memoize the initial implementation.
    coshell.Coshell._IMPLEMENTATION = None
    # This coshell.Open() will think its running on Windows.
    self.CoOpen()
    # True if its Windows cmd.exe coshell, MinGW bash otherwise.
    self.is_windows_cmd = isinstance(self.coshell, coshell._WindowsCoshell)
    if not self.is_windows_cmd:
      # /dev/tty doesn't work in the test environment.
      self.coshell.STDIN_PATH = '/dev/null'
      self.coshell.STDOUT_PATH = self.output_file

  def testWindowsCoshellUnixCoshellNotSelected(self):
    self.assertFalse(isinstance(self.coshell, coshell._UnixCoshell))

  def testWindowsCoshellEditMode(self):
    self.assertEqual('emacs', self.coshell.edit_mode)

  def testWindowsCoshellIgnoreEof(self):
    self.assertFalse(self.coshell.ignore_eof)

  def testWindowsCoshellStateIsPreserved(self):
    # If the test is running on a system with MinGW or git installed then bash
    # is available and preserves state across commands.
    self.assertEqual(not self.is_windows_cmd, self.coshell.state_is_preserved)

  def testWindowsCoshellCreateDelete(self):
    tmp = os.path.join(self.tmp, 'coshell.tst')
    self.AssertFileNotExists(tmp)
    self.coshell.Run("echo foo > '{}'".format(tmp))
    self.AssertFileExists(tmp)

  # No output tests yet because cmd.exe is entwined with the terminal and
  # we don't know how to intercept that.

if __name__ == '__main__':
  sdk_test_base.main()


import telegram
import logging
import requests
import datetime
from flask import Flask, request
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler, ConversationHandler)

logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

app = Flask(__name__)
logger = logging.getLogger(__name__)

bot_token = "579475538:AAFjEgtt1BFPIU_f4IjYyaix-heREgouX3g"

updater = Updater(token=bot_token)
dispatcher = updater.dispatcher

def get_url(method):
  return "https://api.telegram.org/bot{}/{}".format(bot_token,method)

def marca(bot, update):
    update.message.reply_text("Jogo marcado!")

def confirma(bot, update):
    update.message.reply_text("Confirmado.")

def desconfirma(bot, update):
    update.message.reply_text("Desconfirmado!")

def cancel(bot, update):
    update.message.reply_text('Sem futebol essa semana entao...', reply_markup=ReplyKeyboardRemove())
    return ConversationHandler.END

marca_handler = CommandHandler('marca', marca)
dispatcher.add_handler(marca_handler)

confirmar_handler = CommandHandler('confirma', confirma)
dispatcher.add_handler(confirmar_handler)

desconfirmar_handler = CommandHandler('desconfirma', desconfirma)
dispatcher.add_handler(desconfirmar_handler)

updater.start_polling()


import logging
import os
from BlorgMusicData.models import DataSource, SongPost
from BlorgMusicHelper.stringhelper import *
from google.appengine.ext import db

__author__ = 'abeaupre'

class Dao():
    @classmethod
    def fetchSourceList(cls):
        return DataSource.objects.all()

    @classmethod
    def fetchSongPostList(cls, sourceKey = None, page = 1, size = 50):
        dataSource = None
        if sourceKey:
            dataSource = DataSource.objects.get(pk=sourceKey)

        songList = Dao.GetSongPostList(dataSource, size, page, 'CreateTime', True)

        if dataSource:
            dataLength = SongPostDataSourceList.objects.filter(DataSource_id = dataSource.id).count()
        else:
            dataLength = SongPost.objects.count()

        result = dict()
        result['songList'] = songList
        result['dataLength'] = dataLength
        return result

    @classmethod
    def ArtistItem_GetOrAdd(cls, name, hasCover=False, hasFeaturing=False, hasMashup=False, hasRemix=False):
        return ArtistItem.objects.get_or_create(Name=name, defaults=
            {'HasRemix':hasRemix, 'HasMashup':hasMashup, 'HasCover':hasCover, 'HasFeaturing':hasFeaturing})[0]

    @classmethod
    def GetArtistItem(cls, key):
        return ArtistItem.objects.get(key)

    @classmethod
    def GetArtistItemList(cls, pageSize, pageOffset, orderBy, orderDesc):
        itemOffset = (pageOffset-1)*pageSize
        orderString = ('-' if orderDesc else '') + orderBy
        return ArtistItem.objects.order_by(orderString)[itemOffset:pageSize]

    @classmethod
    def SongItem_GetList(cls, pageSize, pageOffset, orderBy, orderDesc):
        itemOffset = (pageOffset-1)*pageSize
        orderString = ('-' if orderDesc else '') + orderBy
        itemList = SongItem.objects.order_by(orderString)[itemOffset:pageSize]
        for item in itemList:
            item.ArtistRoleList = Dao.SongArtistRoleList_GetAll(item)

    @classmethod
    def GetParseItemList(cls, pageSize, pageOffset, orderBy, orderDesc):
        itemOffset = (pageOffset-1)*pageSize
        orderString = ('-' if orderDesc else '') + orderBy
        return ParseItem.objects.order_by(orderString)[itemOffset:pageSize]

    @classmethod
    def SongItem_Get(cls, key):
        songItem = SongItem.objects.get(pk=key)
        songItem.ArtistRoleList = Dao.SongArtistRoleList_GetAll(songItem)
        return songItem

    @classmethod
    def GetParseItem(cls, key):
        return ParseItem.objects.get(pk=key)

    @classmethod
    def GetSongPost(cls, key):
        return SongPost.objects.get(pk=key)

    @classmethod
    def GetBlogPost(cls, key):
        return BlogPost.objects.get(pk=key)

    @classmethod
    def GetSongPostList(cls, dataSource, pageSize, pageOffset, orderBy, orderDesc):
        itemOffset = (pageOffset-1)*pageSize
        orderString = ('-' if orderDesc else '') + orderBy
        if dataSource:
            #return SongPostDataSourceList.objects.filter(DataSource_id = dataSourceId).order_by(orderString)[itemOffset:pageSize]
            #TODO:  determine the best way to perform this query.  Denormalization or get list of SongPostIDs and iterate or investigate django-nonrel Indexing module (supports joins)
            songPostSourceList = SongPostDataSourceList.objects.filter(DataSource_id = dataSource.id).order_by(orderString)[itemOffset:pageSize]
            songPostList = []
            for item in songPostSourceList:
                songPost = SongPost.objects.get(pk=item.SongPost_id)
                songPostList.append(songPost)
            return songPostList
        else:
            return SongPost.objects.order_by(orderString)[itemOffset:pageSize]

    @classmethod
    def SongPost_AddFromParseData(cls, parsedText, songUrl, blogPostItem):
        if parsedText['successful']:

            songTitle = parsedText['songTitle']
            primaryArtistName = parsedText['primaryArtist']
            artistRoleList = parsedText['artistRoleList']
            songNotes = parsedText['songNote']
            inputString = parsedText['inputString']

            #for each of the listed artists, getoradd
            songKeyArtists = []
            primaryArtist = None
            for artistRole in artistRoleList:
                roleType = artistRole['role']
                artistName = artistRole['name']
                artistItem = cls.ArtistItem_GetOrAdd(artistName)
                if artistItem:
                    songKeyArtists.append({'artistItem':artistItem, 'roleType': roleType})
                    if roleType == 'P':
                        primaryArtist = artistItem

            #generate the SongKey
            songKey = cls.generateSongKey(songTitle, songKeyArtists)
            formattedSongTitle = formatSongTitle(songTitle, songNotes, artistRoleList)

            #look for the existing song
            songItemDefaults = {
                'SongTitle':songTitle,
                'FormattedSongTitle':formattedSongTitle,
                'SongNotes':songNotes,
                'PrimaryArtist': primaryArtist
            }

            songItem =  SongItem.objects.get_or_create(SongKey=songKey, defaults=songItemDefaults)[0]
            songPostDefaults = {
                'CanonicalSong' : songItem,
                'Blog' : blogPostItem,
                'OriginalText': inputString
            }
            return SongPost.objects.get_or_create(SongUrl = songUrl, defaults=songPostDefaults)[0]

    @classmethod
    def AddParseItem(cls, parsedText):
        inputString = parsedText['inputString']
        return ParseItem.objects.get_or_create(InputString=inputString)[0]

    @classmethod
    def AddParseItemSourceItemList(cls, parsedSong, dataSource):
        logging.info(parsedSong)
        return ParseItemSourceList.objects.get_or_create(Parse = parsedSong, SourceItem = dataSource)[0]

    @classmethod
    def GetDataSource(cls, dataSourceName):
        try:
            dataSource = DataSource.objects.get(SourceName=dataSourceName)
        except DataSource.DoesNotExist:
            dataSource = None
        return dataSource

    @classmethod
    def GetOrAddParseItem(cls, inputString, mp3href, blogPostItem):
        try:
            parseItem = ParseItem.objects.get(InputString=inputString)
        except ParseItem.DoesNotExist:
            parseItem = ParseItem(InputString=inputString, Url=mp3href, SourceUrl=blogPostItem.PostUrl)
            parseItem.save()
        return parseItem

    @classmethod
    def BlogSource_GetOrInsert(cls, sourceDomain, blogName):
        return BlogSource.objects.get_or_create(BlogUrl=sourceDomain, defaults={'BlogName':blogName})[0]

    @classmethod
    def BlogPost_GetOrInsert(cls, sourceUrl, blogPostSummary, blogSource):
        return BlogPost.objects.get_or_create(PostUrl = sourceUrl, defaults={'Summary':blogPostSummary, 'Blog':blogSource})[0]

    @classmethod
    def BlogPost_Get(cls, sourceUrl):
        return BlogPost.objects.get(PostUrl = sourceUrl)

    @classmethod
    def DeleteArtistItem(cls, artistItem):
        artistItem.delete()

    @classmethod
    def DeleteSongItem(cls, songItem):
        songItem.delete()

    @classmethod
    def DeleteParseItem(cls, parseItem):
        parseItem.delete()

    @classmethod
    def DataSource_GetOrAdd(cls, dataSourceName, dataSourceUrl):
        return DataSource.objects.get_or_create(SourceName = dataSourceName, defaults={'SourceUrl': dataSourceUrl})[0]

    @classmethod
    def FormatSongKey(cls, songTitle):
        return toLowerAndStripPunct(songTitle)

    # Key is defined as:
    #  formatted title + a sorted list of artistIds in CSV
    @classmethod
    def generateSongKey(cls, songTitle, artistRoleList):
        artistKey =''
        comma = ''
        for artistRoleItem in sorted(artistRoleList, key=lambda roleItem: roleItem['artistItem'].id):
            if artistRoleItem['roleType'] in['P', 'R', 'M']:
                artistKey += comma + str(artistRoleItem['artistItem'].id)
                comma =','
        return cls.FormatSongKey(songTitle) + '_' + artistKey

    @classmethod
    def DataSource_GetListAll(cls):
        dataSourceList = DataSource.objects.all()
        if not dataSourceList:
            Dao.DataSource_GetOrAdd('twitter', 'http://api.twitter.com/1/evilnohear/lists/all-music/statuses.xml')
            Dao.DataSource_GetOrAdd('twitter-electronic', 'http://api.twitter.com/1/evilnohear/lists/electronic-blogs/statuses.xml')
            Dao.DataSource_GetOrAdd('twitter-indie', 'http://api.twitter.com/1/evilnohear/lists/indie-blogs/statuses.xml')

        return dataSourceList

    @classmethod
    def ParseItem_GetListAll(cls):
        return ParseItem.objects.all()

    @classmethod
    def SongArtistRoleList_GetAll(cls, songItem):
        SongArtistRoleList.objects.filter(Song=songItem)


__author__ = 'paulpatterson'

from unittest import TestCase
import xml.etree.ElementTree as ET
from pathlib import Path
import shutil
from collections import namedtuple
import tempfile

from jack_compiler.AbstractSyntaxTree import stringify_xml
from jack_compiler.JackCompiler import JackCompiler
from tests.globals import NAND_2_TETRIS, ACTUAL_COMPARE, EXPECTED_COMPARE

TestStrings = namedtuple("TestStrings", "actual expected")

TESTFILE = NAND_2_TETRIS / "JackCompiler" / "tests" / "CompilationTests.xml"
PARSE_TREE = NAND_2_TETRIS / "JackCompiler" / "tests" / "ParseTree.xml"

class CompilerVMGeneration(TestCase):

    @classmethod
    def setUpClass(cls):
        cls.tests = ET.parse(TESTFILE.as_posix()).getroot()

        cls.jack_project_directory = None
        cls.jack_file_path = None
        cls.vm_file_path = None

    def tearDown(self):
        if self.jack_project_directory is not None:
            parent_directory = self.jack_project_directory.parent
            shutil.rmtree(parent_directory.as_posix())
            self.jack_project_directory = None

    def _get_test_components(self, test_id):
        test_tree = self.tests.find("*[@id='{}']".format(test_id))
        expected_vm = test_tree.find("expected_vm").text.strip()
        jack_code = test_tree.find("jack_class").text
        return jack_code, expected_vm

    def make_temporary_test_directory(self, dir_name):
        tmp_dir = Path(tempfile.mkdtemp())
        proj_dir = tmp_dir / dir_name
        proj_dir.mkdir(parents=False)
        return proj_dir

    def set_up_compilable_jack_project(self, test_id, jack_code):
        self.jack_project_directory= self.make_temporary_test_directory(test_id)
        self.jack_file_path = self.jack_project_directory / "Main.jack"
        self.vm_file_path = self.jack_file_path.with_name("Main.vm")
        with open(self.jack_file_path.as_posix(), "w+") as jack_file:
            jack_file.write(jack_code)

    def _write_results_to_compare_files(self, actual_vm, expected_vm):
        with open(ACTUAL_COMPARE.as_posix(), 'w') as compareOne:
            with open(EXPECTED_COMPARE.as_posix(), 'w') as compareTwo:
                compareOne.write(actual_vm)
                compareTwo.write(expected_vm)

    def _write_abstract_syntax_tree(self, ast):
        with open(PARSE_TREE.as_posix(), "w") as astfile:
            astfile.write(str(ast))

    def _vm_strings_for_test(self, test_id):
        jack_code, expected_vm = self._get_test_components(test_id)

        # the next step sets the value of self.jack_project_directory, self.jack_file_path, and self.vm_file_path
        self.set_up_compilable_jack_project(test_id, jack_code)

        try:
            compiler = JackCompiler(path=self.jack_file_path)
            compiler.compile()
        except Exception as e:
            print(e)
            return None

        self._write_abstract_syntax_tree(compiler.abstract_syntax_trees[0])
        with open(self.vm_file_path.as_posix()) as vmfile:
            actual_vm = vmfile.read().strip()
            test_strings = TestStrings(actual_vm, expected_vm)

        self._write_results_to_compare_files(test_strings.actual, test_strings.expected)

        return test_strings

    def test_numbers(self):
        test_strings = self._vm_strings_for_test("Numbers")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_seven(self):
        test_strings = self._vm_strings_for_test("Seven")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_c2b_main(self):
        test_strings = self._vm_strings_for_test("C2BMain")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_if(self):
        test_strings = self._vm_strings_for_test("simple-if")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_if_else(self):
        test_strings = self._vm_strings_for_test("simple-if-else")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_nested_if_else(self):
        test_strings = self._vm_strings_for_test("simple-if-else")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_while(self):
        test_strings = self._vm_strings_for_test("simple-while")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_convert_to_binary(self):
        test_strings = self._vm_strings_for_test("ConvertToBin")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_simple_array(self):
        test_strings = self._vm_strings_for_test("simple-array")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_two_arrays(self):
        test_strings = self._vm_strings_for_test("two-simple-arrays")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_index_assignment(self):
        test_strings = self._vm_strings_for_test("indexed-assignment")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_complex_arrays_fragment(self):
        test_strings = self._vm_strings_for_test("complex-arrays-fragment")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_average(self):
        test_strings = self._vm_strings_for_test("Average")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_pong_main(self):
        test_strings = self._vm_strings_for_test("Pong-Main")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_pong_ponggame(self):
        test_strings = self._vm_strings_for_test("Pong-PongGame")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_pong_bat(self):
        test_strings = self._vm_strings_for_test("Pong-Bat")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_pong_ball(self):
        test_strings = self._vm_strings_for_test("Pong-Ball")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_square_main(self):
        test_strings = self._vm_strings_for_test("Square-Main")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)
    #
    def test_square_squaregame(self):
        test_strings = self._vm_strings_for_test("Square-SquareGame")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_square_square(self):
        test_strings = self._vm_strings_for_test("Square-Square")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)

    def test_complex_arrays(self):
        test_strings = self._vm_strings_for_test("ComplexArrays")
        self.assertIsNotNone(test_strings, "failed to generate either expected vm code, actual vm code, or both.")
        self.assertMultiLineEqual(test_strings.actual, test_strings.expected)


#!/usr/bin/env python3
# -*- coding: utf8 -*-
# ulogme_serve_https.py for https://github.com/Naereen/uLogMe/
# MIT Licensed, https://lbesson.mit-license.org/
#
"""
ulogme_serve_https.py - simple HTTP server supporting SSL.

- Replace fpem with the location of your .pem server file ('server.pem' by default).
- The default port is 8443.

Usage: python ulogme_serve_https.py

From https://www.piware.de/2011/01/creating-an-https-server-in-python/ and https://stackoverflow.com/a/22436756/5889533
"""
from __future__ import print_function   # Python 2 compatibility
from __future__ import absolute_import  # Python 2 compatibility

import sys
import os
import os.path
import ssl
import socket
from subprocess import check_output
from http.server import HTTPServer

# Local imports
from ulogme_serve import printc, CustomHandler
from notify import notify

# Utility functions
default_fpem = "server.pem"
default_fpem_path = os.path.join("..", "render", default_fpem)

def generate_certificate(fpem=default_fpem_path):
    print("Generating the SSL certificate to {} in the current directory ({}) ...".format(fpem, os.getcwd()))
    args = [
        "openssl",
        "req",
        "-newkey rsa:4096",
        "-x509",
        "-keyout {}".format(fpem),
        "-out {}".format(fpem),
        "-days 365",  # Only valid one year!
        "-nodes"
    ]
    print("Executing '{}' ...".format(' '.join(args)))
    print(check_output(' '.join(args), shell=True))

if __name__ == "__main__":
    httpd = None  # Make sure the variable exist, or the finally: case below can mess up

    # Port setting
    if len(sys.argv) > 1:
        PORT = int(sys.argv[1])
        assert PORT > 2024 or PORT == 443, "Error, you should not ask to use a PORT reserved by the system (<= 2024)"
    else:
        PORT = 443
        # PORT = 8443

    # Address setting
    if len(sys.argv) > 2:
        IP = str(sys.argv[2])
    else:
        # IP = "ulogme"  # IP address to use by default
        IP = "localhost"  # IP address to use by default
        # Instead of "", more secure, thanks to https://github.com/karpathy/ulogme/issues/48

    # Certificate setting
    if len(sys.argv) > 3:
        fpem = str(sys.argv[3])
    else:
        fpem = default_fpem_path

    if not os.path.isfile(fpem):
        printc("<red>The SSL certificate<white> file <black>{}<white> is not present, trying to generate it with a 'openssl' command ...".format(fpem))
        generate_certificate(fpem)
    printc("<green>Using the SSL certificate<white> from the information in the file <black>{}<white> ...".format(fpem))

    # Serve render/ folder, not current folder
    os.chdir(os.path.join("..", "render"))

    try:
        httpd = HTTPServer((IP, PORT), CustomHandler)
        httpd.socket = ssl.wrap_socket(httpd.socket, certfile=fpem, server_side=True)
        sa = httpd.socket.getsockname()
        IP, PORT = sa[0], sa[1]
        printc("<green>Serving uLogMe<white> on a HTTPS server, see it locally on '<black>https://{}:{}<white>' ...".format(IP, PORT))
        notify("Serving uLogMe on a HTTPS server, see it locally on 'https://{}:{}' ...".format(IP, PORT), icon="terminal")  # DEBUG
        httpd.serve_forever()
    except socket.error as e:
        if e.errno == 98:
            printc("<red>The port {} was already used ...<white>".format(PORT))
            printc("Try again in some time (about 1 minute on Ubuntu), or launch the script again with another port: '<black>$ ulogme_serve_https.py {}<white>' ...".format(PORT + 1))
        else:
            printc("<red>Error, ulogme_serve.py was interrupted, giving:<white>")
            printc("<red>Exception:<white> ", e)
            # print("Exception: dir(e) =", dir(e))  # DEBUG
    except KeyboardInterrupt:
        printc("\n<red>You probably asked to interrupt<white> the '<black>ulogme_serve.py<white>' HTTPS server ...")
    finally:
        try:
            if httpd is not None:
                printc("\n<yellow>Closing the HTTPS server<white> (address '<black>{}<white>', port '<black>{}<white>') ...".format(IP, PORT))
                httpd.server_close()
        except Exception as e:
            printc("<red>The HTTPS server<white> (address '<black>{}<white>', port '<black>{}<white>') <red>might not have been closed<white> ...".format(IP, PORT))
            printc("<red>Exception:<white> e =", e)


from scipy import constants as C
import numpy as np
import dispersion
import surface
import volume
import input_tools

# Example of separating Nd:glass wavelength and its second harmonic in a Pellin-Broca prism.

# Suggested plotter command
# python ray_plotter.py out/test o3d

# Units and scales

mks_length = 1.054e-6 / (2*np.pi)
bundle_scale = 1e-4
mm = 1000*mks_length
inch = 100*mks_length/2.54
fs = 1e15*mks_length/C.c
deg = 180/np.pi
helper = input_tools.InputHelper(mks_length)
mess = 'Processing input file...\n'

# Setup pulse parameters

theta = 0.0 # initial propagation angle
a00 = 1.0
w00 = 1.0
r00 = 0.1/mm # spot size of radiation
rb = r00*bundle_scale
t00 = 500/fs
band = (0.9,2.1)

# Setup prism

material = dispersion.BK7(mks_length)
nrefr = np.sqrt(1+material.chi(w00)[0])
prism_box = (1/inch,1/inch,0.75/inch)
refraction_angle = 30/deg
incidence_angle = np.arcsin(nrefr*np.sin(refraction_angle))
mess += 'TIR angle = ' + str(np.arcsin(1/nrefr)*deg) + ' deg\n'

# Set up dictionaries

sim = {}
wave = []
ray = []
optics = []
diagnostics = {}

sim['mks_length'] = mks_length
sim['mks_time'] = mks_length/C.c
sim['message'] = mess

ray.append({})
ray[-1]['number'] = (64,1,4,1)
ray[-1]['bundle radius'] = (rb,rb,rb,rb)
ray[-1]['loading coordinates'] = 'cylindrical'
# Ray box is always put at the origin
# It will be transformed appropriately by SeaRay to start in the wave
ray[-1]['box'] = band + (0.0,3*r00) + (0.0,2*np.pi) + (0.0,0.0)

wave.append({}) # fundamental
wave[-1]['a0'] = (0.0,a00*np.cos(theta),0.0,-a00*np.sin(theta)) # EM 4-potential (eA/mc^2) , component 0 not used
wave[-1]['r0'] = (t00,r00,r00,t00) # 4-vector of pulse metrics: duration,x,y,z 1/e spot sizes
wave[-1]['k0'] = (w00,w00*np.sin(theta),0.0,w00*np.cos(theta)) # 4-wavenumber: omega,kx,ky,kz
# 0-component of focus is time at which pulse reaches focal point.
# If time=0 use paraxial wave, otherwise use spherical wave.
# Thus in the paraxial case the pulse always starts at the waist.
wave[-1]['focus'] = (0.0,0.0,0.0,-31/mm)
wave[-1]['supergaussian exponent'] = 2

wave.append({}) # second harmonic
wave[-1]['a0'] = (0.0,a00*np.cos(theta),0.0,-a00*np.sin(theta)) # EM 4-potential (eA/mc^2) , component 0 not used
wave[-1]['r0'] = (t00,r00,r00,t00) # 4-vector of pulse metrics: duration,x,y,z 1/e spot sizes
wave[-1]['k0'] = (2*w00,2*w00*np.sin(theta),0.0,2*w00*np.cos(theta)) # 4-wavenumber: omega,kx,ky,kz
# 0-component of focus is time at which pulse reaches focal point.
# If time=0 use paraxial wave, otherwise use spherical wave.
# Thus in the paraxial case the pulse always starts at the waist.
wave[-1]['focus'] = (0.0,0.0,0.0,-31/mm)
wave[-1]['supergaussian exponent'] = 2

optics.append({})
optics[-1]['object'] = volume.PellinBroca('P1')
optics[-1]['dispersion outside'] = dispersion.Vacuum()
optics[-1]['dispersion inside'] = material
optics[-1]['size'] = prism_box
optics[-1]['angle'] = refraction_angle
optics[-1]['origin'] = (-10/mm,0.,0.)
optics[-1]['euler angles'] = helper.rot_zx(incidence_angle)

optics.append({})
optics[-1]['object'] = surface.EikonalProfiler('det')
optics[-1]['size'] = (1/inch,1/inch)
optics[-1]['origin'] = (100/mm,0.0,10/mm)
optics[-1]['euler angles'] = helper.rot_zx(-90/deg)

diagnostics['suppress details'] = False
diagnostics['clean old files'] = True
diagnostics['orbit rays'] = (16,1,4,1)
diagnostics['base filename'] = 'out/test'


import requests
import lxml.html
import rdflib

problems = ['Directed by', '\n', 'Produced by', '[a]', '[1]', '[2]', '[3]', '[4]', '[5]', '[6]', '[7]', '[8]',
                '[9]', ' (p.g.a.)', 'Executive Producer', ': ', ' ', ', ', '', 'Running time', 'Starring']

people_link_problems = ['#cite_note-1', '#cite_note-2', '#cite_note-Elliot-1', '#cite_note-comingsoon-1', '#cite_note-Fletcher-2']

def get_producers(doc):
    producers = []

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Produced by')]//@title"):
        producers.append(t)

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Produced by')]//text()"):
         t = t.strip()
         if t not in problems:
             skip = False
             for producer in producers:
                 if t in producer:
                     skip = True
                     break
             if(not skip):
                producers.append(t)

    producers.sort()
    return producers

def get_directors(doc):
    directors = []

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Directed by')]//@title"):
        directors.append(t)

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Directed by')]//text()"):
        t = t.strip()
        if t not in problems:
            skip = False
            for director in directors:
                if t in director:
                    skip = True
                    break
            if not skip:
                directors.append(t)

    directors.sort()
    return directors

def get_running_time(doc):
    runningtime = []

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Running time')]//text()"):
        if t not in problems:
            runningtime.append(t.strip())

    return runningtime

def get_starring(doc):
    starring = []

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Starring')]//@title"):
        starring.append(t)

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Starring')]//text()"):
        t = t.strip()
        if t not in problems:
            skip = False
            for star in starring:
                if t in star:
                    skip = True
                    break
            if not skip:
                starring.append(t)

    starring.sort()
    return starring

def check_octavia_spencer(films_list, films_names, starring_list):
    for i in range(len(films_list)):
        if "The Shape of Water" == films_names[i]:
            stars = starring_list[i]
            for star in stars:
                if "Octavia Spencer" == star:
                    print("Yes")
                    print("---------")
                    print(films_list[i])
                    print(films_names[i])
                    print(starring_list[i])
                    return
    print("No")

def check_meryl_streep(films_list, starring_list):
    count_meryl_strip = 0
    for i in range(len(films_list)):
        stars = starring_list[i]
        for star in stars:
            if "Meryl Streep" == star:
                print(films_list[i])
                count_meryl_strip += 1
    print("Number of films is " + str(count_meryl_strip))

def get_release_date(doc):
    release_dates = []

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Release date')]//span[@class = 'bday dtstart published updated']//text()"):
        release_dates.append(t)

    #TODO: CHECK IF TO SORT, CHECK MORE EXAMPLES OF MISSING DATES
    return release_dates

def get_based_on(doc):
    based_on = []

    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Based on')]"):
        based_on.append("Yes")
        return based_on

    based_on.append("No")
    return based_on

def get_people(people_set, doc):
    for t in doc.xpath("//table[@class = 'infobox vevent']//tr[contains(.//text(),'Directed by') or " +
                       "contains(.//text(),'Produced by') or contains(.//text(),'Starring')]//a//@href"):
        if t not in people_link_problems:
            people_set.add("https://en.wikipedia.org" + t)

def get_birthday(doc):
    bd = []
    for t in doc.xpath("//table[@class = 'infobox biography vcard' or @class = 'infobox vcard']//tr[contains(.//text(),'Born')]//span[@class = 'bday']//text()"):
        bd.append(t)

    return bd

def create():
    start_link = "https://en.wikipedia.org/wiki/List_of_Academy_Award-winning_films"

    ontology = rdflib.Graph()

    r = requests.get(start_link)
    doc = lxml.html.fromstring(r.content)

    films_entities = []
    films_list = []
    films_names = []
    producers_list = []
    directors_list = []
    running_time_list = []
    starring_list = []
    based_on_list = []
    release_date_list = []
    people_set = set()

    for t in doc.xpath("//table[@class = 'wikitable sortable']//tr[position() > 1 and td[position()=2]//text() > 2009]//td[position() = 1]//a//@href"):
        films_list.append("https://en.wikipedia.org" + t)

    for t in doc.xpath("//table[@class = 'wikitable sortable']//tr[position() > 1 and td[position()=2]//text() > 2009]//td[position() = 1]//a//@title"):
        films_names.append(t)

    for link in films_list:
        r = requests.get(link)
        doc = lxml.html.fromstring(r.content)

        print(link)
        producers_list.append(get_producers(doc))
        print(producers_list[-1])
        #directors_list.append(get_directors(doc))
        #running_time_list.append(get_running_time(doc))
        #starring_list.append(get_starring(doc))
        #release_date_list.append(get_release_date(doc))
        #based_on_list.append(get_based_on(doc))
        #print(based_on_list[-1])
        #get_people(people_set, doc)

    #people_list = list(people_set)
    #bdays = []
    #occupations = []
    # for people_link in people_list:
    #     r = requests.get(people_link)
    #     doc = lxml.html.fromstring(r.content)

        #bdays.append(get_birthday(doc))
        # occupations.append(get_occupation(doc))
        #
        # print(people_link)
        # print(occupations[-1])

    #     occ = []
    #     for t in doc.xpath("//table[@class = 'infobox biography vcard' or @class = 'infobox vcard']//tr[contains(.//text(),'Occupation')]//li//text()"):
    #         if t not in problems:
    #             occ.append(t)
    #
    #
    #     for t in doc.xpath("//table[@class = 'infobox biography vcard' or @class = 'infobox vcard']//tr[contains(.//text(),'Occupation')]//td[@class = 'infobox-data role' or @class='infobox-data']//text()"):
    #         if t not in problems:
    #             occ.append(t)
    #
    #
    #     occupations.append(sorted(list(set(occ))))
    #     #print(occupations[-1])

    # for i in range(len(films_list)):
    #     print(str(i) + " " + films_list[i])
    #     print(directors_list[i])
    #     print(producers_list[i])
    #     print(running_time_list[i])
    #     print(starring_list[i])
    #     print(release_date_list[i])
    #     print("--------------")

    # for i in range(len(people_list)):
    #     print(str(i) + " " + people_list[i])
    #     print(bdays[i])

    # print("------------------------")
    # check_meryl_streep(films_list, starring_list)
    # print("------------------------")
    # check_octavia_spencer(films_list, films_names, starring_list)

create()


from .config import Config
from .exceptions import Handler
from .log import log, logging
from .response import HTTPResponse
from .router import Router
from .server import serve
from .exceptions import ServerError
from inspect import isawaitable
from traceback import format_exc

class Sanic:
    name = None
    debug = None
    router = None
    error_handler = None
    routes = []

    def __init__(self, name, router=None, error_handler=None):
        self.name = name
        self.router = router or Router()
        self.error_handler = error_handler or Handler(self)
        self.config = Config()

    # -------------------------------------------------------------------- #
    # Decorators
    # -------------------------------------------------------------------- #

    def route(self, uri, methods=None):
        """
        Decorates a function to be registered as a route
        :param uri: path of the URL
        :param methods: list or tuple of methods allowed
        :return: decorated function
        """
        def response(handler):
            self.router.add(uri=uri, methods=methods, handler=handler)
            return handler

        return response

    def exception(self, *exceptions):
        """
        Decorates a function to be registered as a route
        :param uri: path of the URL
        :param methods: list or tuple of methods allowed
        :return: decorated function
        """
        def response(handler):
            for exception in exceptions:
                self.error_handler.add(exception, handler)
            return handler

        return response

    # -------------------------------------------------------------------- #
    # Request Handling
    # -------------------------------------------------------------------- #

    async def handle_request(self, request, response_callback):
        """
        Takes a request from the HTTP Server and returns a response object to be sent back
        The HTTP Server only expects a response object, so exception handling must be done here
        :param request: HTTP Request object
        :param response_callback: Response function to be called with the response as the only argument
        :return: Nothing
        """
        try:
            handler, args, kwargs = self.router.get(request)
            if handler is None:
                raise ServerError("'None' was returned while requesting a handler from the router")

            response = handler(request, *args, **kwargs)
            if isawaitable(response):
                response = await response

        except Exception as e:
            try:
                response = self.error_handler.response(request, e)
                if isawaitable(response):
                    response = await response
            except Exception as e:
                if self.debug:
                    response = HTTPResponse("Error while handling error: {}\nStack: {}".format(e, format_exc()))
                else:
                    response = HTTPResponse("An error occured while handling an error")

        response_callback(response)

    # -------------------------------------------------------------------- #
    # Execution
    # -------------------------------------------------------------------- #

    def run(self, host="127.0.0.1", port=8000, debug=False, before_start=None, before_stop=None):
        """
        Runs the HTTP Server and listens until keyboard interrupt or term signal.
        On termination, drains connections before closing.
        :param host: Address to host on
        :param port: Port to host on
        :param debug: Enables debug output (slows server)
        :param before_start: Function to be executed after the event loop is created and before the server starts
        :param before_stop: Function to be executed when a stop signal is received before it is respected
        :return: Nothing
        """
        self.error_handler.debug=True
        self.debug = debug

        if debug:
            log.setLevel(logging.DEBUG)
        log.debug(self.config.LOGO)

        # Serve
        log.info('Goin\' Fast @ {}:{}'.format(host, port))

        try:
            serve(
                host=host,
                port=port,
                debug=debug,
                before_start=before_start,
                before_stop=before_stop,
                request_handler=self.handle_request,
                request_timeout=self.config.REQUEST_TIMEOUT,
                request_max_size=self.config.REQUEST_MAX_SIZE,
            )
        except:
            pass


from StringIO import StringIO

from Products.CMFCore.utils import getToolByName

from Products.PluggableAuthService.interfaces.plugins \
    import IGroupsPlugin
from Products.PluggableAuthService.interfaces.plugins \
    import IPropertiesPlugin
from Products.PluggableAuthService.interfaces.plugins \
    import IUserFactoryPlugin

from Products.PlonePAS.Extensions.Install import activatePluginInterfaces

from interfaces import IUserAdder
from config import TOOLNAME
from config import USE_COLLECTIVE_INDEXING

def _doRegisterUserAdderUtility(context, step_name, profile_id,
                                utility_name, utility):
    """ registers utility for adding ExampleMembers """
    portal = context.getSite()

    sm = portal.getSiteManager()
    logger = context.getLogger(step_name)
    if sm.queryUtility(IUserAdder, name=utility_name) is None:
        sm.registerUtility(
            provided=IUserAdder,
            component=utility,
            name=utility_name)
        logger.info("Registered IUserAdder utility: %s" %
                    utility_name)
        mbtool = getToolByName(portal, TOOLNAME)
        if not mbtool.user_adder:
            # we become the default if one isn't already specified
            mbtool.user_adder = utility_name
    else:
        logger.info("IUserAdder utility '%s' already registered" %
                    utility_name)

def _setupPlugins(portal, out):
    """
    Install and prioritize the membrane PAS plug-ins.
    """
    uf = getToolByName(portal, 'acl_users')
    plugins = uf.plugins

    membrane = uf.manage_addProduct['membrane']
    existing = uf.objectIds()

    if 'membrane_users' not in existing:
        membrane.addMembraneUserManager('membrane_users')
        print >> out, "Added User Manager."
        activatePluginInterfaces(portal, 'membrane_users', out)

    if 'membrane_groups' not in existing:
        membrane.addMembraneGroupManager('membrane_groups')
        print >> out, "Added Group Manager."
        activatePluginInterfaces(portal, 'membrane_groups', out)
        plugins.movePluginsUp(IGroupsPlugin, ['membrane_groups'])

    if 'membrane_roles' not in existing:
        membrane.addMembraneRoleManager('membrane_roles')
        print >> out, "Added Role Manager."
        activatePluginInterfaces(portal, 'membrane_roles', out)

    if 'membrane_properties' not in existing:
        membrane.addMembranePropertyManager('membrane_properties')
        print >> out, "Added Property Manager."
        activatePluginInterfaces(portal, 'membrane_properties', out)
        plugins.movePluginsUp(IPropertiesPlugin, ['membrane_properties'])
        plugins.movePluginsUp(IPropertiesPlugin, ['membrane_properties'])

    if 'membrane_user_factory' not in existing:
        membrane.addMembraneUserFactory('membrane_user_factory')
        print >> out, "Added User Factory."
        activatePluginInterfaces(portal, 'membrane_user_factory', out)
        plugins.movePluginsUp(IUserFactoryPlugin, ['membrane_user_factory'])

def setupPlugins(context):
    """ initialize membrane plugins """
    if context.readDataFile('membrane-setup-plugins.txt') is None:
        return

    portal = context.getSite()
    out = StringIO()
    if USE_COLLECTIVE_INDEXING:
        setup_tool = getToolByName(portal, 'portal_setup')
        try:
            setup_tool.runAllImportStepsFromProfile(
                'profile-collective.indexing:default')
        except KeyError:
            # collective.indexing 2.0 has no install and needs no install.
            pass
    _setupPlugins(portal, out)
    logger = context.getLogger("plugins")
    logger.info(out.getvalue())


from typing import List

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        result = [0]
        digits[-1] += 1
        result[1:] = digits
        for i in range(len(result) - 1, 0, -1):
            if result[i] // 10 == 0:
                return result[1:]
            result[i] %= 10
            result[i - 1] += 1
        return result

def main():
    print("hello world")
    slt = Solution()
    print(slt.plusOne([9,9,9]))

if __name__ == "__main__":
    main()