import sys
import decimal
import re

from PyQt5.QtWidgets import QDialog
from PyQt5.QtCore import Qt

import user as userdetail
from lib.utils.evalenv import evalenv
from db.models import Selfdefinedformat, Forms
from product.controllers.productcontroller import ProductController
from stuff.controllers.stuffcontroller import StuffController
from labrecord.controllers.labrecordscontroller import LabrecordsController

from lib.xmlwidget.xmlcheckbox import XmlCheckBox
from lib.xmlwidget.xmlcombobox import XmlComboBox
from lib.xmlwidget.xmlexprbox import XmlExprBox
from lib.xmlwidget.xmllineedit import XmlLineEdit
from lib.xmlwidget.xmlsignbox import XmlSignBox
from lib.xmlwidget.xmllabel import XmlTextEdit

from tesui import Ui_Form

# 批记录产品信息类变量
PRODUCT_DICT = {'PBIANHAO': 'prodid', 'PMING': 'prodname', 'PGUIGE': 'spec',
                'PBZGG': 'package', 'PTMING': 'commonname', 'PPIHAO': 'batchno',
                'PSHIJI': 'realamount', 'PJIHUA': 'planamount',
                'PJIXING': 'medkind'
                }
# 批记录物料信息类变量
STUFF_DICT = {'ID': 'stuffid', 'MING': 'stuffname', 'PIHAO': 'batchno',
              'LEIBIE': 'kind', 'GUIGE': 'spec', 'BZGG': 'package',
              'JBDW': 'unit', 'XBZDW': 'spunit', 'ZBZDW': 'mpunit',
              'DBZDW': 'bpunit',
              'JIHUA': 'presamount', 'SHIJI': 'realamount',
              'LINGQU': 'drawamount',
              'SHENGYU': 'restamount', 'TUIKU': 'backamount',
              'SHUIFEN': 'water',
              'HANLIANG': 'content', 'CHANGJIA': 'producer'
              }
STUFF_KIND = {'ZF': (0, 1), 'ZC': 0, 'FC': 1, 'NB': 2, 'WB': 3, 'BC': (2, 3),
              'QC': 4}
# 检验报告类信息变量
# 检品编号，检品名称，批号，半成品取样，成品取样，生产厂家，报告编号，检品数量
LAB_DICT = {'SID': 'chkid', 'SMING': 'chkname', 'JPPIHAO': 'batchno',
            'MQUYANG': 'samplecount', 'PQUYANG': 'samplecount',
            'SPRODUCER': 'producer', 'SBGBH': 'paperno',
            'JPSHULIANG': 'checkamount'
            }

# 对齐方式
alignment = ('L', 'C', 'R')
qtalign = (Qt.AlignLeft, Qt.AlignHCenter, Qt.AlignRight)

class ReadXML(QDialog, Ui_Form):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.reader = QtCore.QXmlStreamReader()
        self.writer = QtXmlPatterns.QXmlQuery()
        # self.pix = QtGui.QPixmap(800, 600)
        # self.pix.fill(QtCore.Qt.white)
        # 线框，先把所有线框的信息都保存了，最后再刷新
        self.line_border = list()

        self.current_X = 20
        self.current_Y = 10
        self.form = parent
        # 要查询的记录id
        self.autoid = 0
        # 要查询的内容,0测试，1生产，2检验
        self.type = 0
        self.proddetail = None
        self.stuffdetail = None
        self.mstuffdetail = None
        self.labdetail = None
        self.stuffdetailZF = list()
        self.stuffdetailZC = list()
        self.stuffdetailFC = list()
        self.stuffdetailNB = list()
        self.stuffdetailWB = list()
        self.stuffdetailBC = list()
        self.stuffdetailQC = list()

        self.stuffdetailMZF = list()
        self.stuffdetailMZC = list()
        self.stuffdetailMFC = list()
        self.stuffdetailMNB = list()
        self.stuffdetailMWB = list()
        self.stuffdetailMBC = list()
        self.stuffdetailMQC = list()

    # 中文：14个像素 英文：7个像素，系统中的长度*7 = 像素
    # 中文数*2 = 系统中的长度，中位数*14 = 像素
    # 系统中长度*7 = 像素
    def read(self, file):

        # 传入的是地址
        qfile = QtCore.QFile(file)
        # 找到文件,则设置引擎,否则向xml文件直接添加数据
        if qfile.open(QtCore.QFile.ReadWrite | QtCore.QFile.Text):
            self.reader.setDevice(file)
            self.writer.setDevice(file)
        else:
            self.reader.addData(file)
            s = self.writer.setQuery(file + '/GMPPaper/Title[2]')
            print(s)
        self.reader.setNamespaceProcessing(0)
        self.reader.readNextStartElement()
        if self.reader.isStartDocument():
            self.reader.readNextStartElement()
        # 如果没有读到文档结尾，而且没有出现错误
        while not self.reader.atEnd():
            if self.reader.isStartElement():
                name = self.reader.name()
                if name == "GMPPaper":
                    pass
                # 标题框
                elif name == "Title":
                    self.titleBox()
                # 标题输入框
                elif name == "TextBox":
                    self.inputBox()
                # 线框
                elif name == "Box":
                    self.wireframe()
                # 检测框
                elif name == "CheckBox":
                    self.checkBox()
                # 下拉框
                elif name == "ComboBox":
                    self.comboBox()
                # 签名框
                elif name == "Signature":
                    self.signBox()
                elif name == "Expr":
                    self.exprBox()
                elif name == "br":
                    self.wrapBox()
            # 空格组成的字符，包括换行
            elif self.reader.isWhitespace():
                pass
            # 纯文本
            elif self.reader.isCharacters():
                pass
            self.reader.readNextStartElement()
            # 如果读取过程中出现错误，那么输出错误信息
            # if self.reader.hasError():
            #    print(self.reader.errorString())
            # raise ValueError
        if qfile.isOpen():
            qfile.close()
        # self.update()
        self.scrollAreaWidgetContents.setLineBorder(self.line_border)
        '''
        try:

        except Exception as e:
            print(repr(e))
            pass
            # raise ValueError
        '''

    # 标题框
    def titleBox(self):
        widget = QtWidgets.QLabel(self.scrollAreaWidgetContents)
        widget.setContentsMargins(2, 0, 0, 0)
        self.boxresize(widget)
        # L C R ,左中右对齐
        align = self.reader.attributes().value("align")
        widget.setAlignment(
            QtCore.Qt.AlignVCenter | qtalign[alignment.index(align)])
        widget.setText(self.set_vars(self.reader.readElementText()))

    # 输入框
    def inputBox(self):
        widgetlabel = QtWidgets.QLabel(self.scrollAreaWidgetContents)
        widgetlineedit = QtWidgets.QLineEdit(self.scrollAreaWidgetContents)
        # self.reader.lineNumber()

        # widgetlineedit.setObjectName('widget' + self.reader.columnNumber())
        widgetlabel.setContentsMargins(2, 0, 0, 0)
        widgetlineedit.setContentsMargins(1, 0, 1, 0)
        # self.boxresize(widgetlineedit)
        widgetlabel.move(self.current_X, self.current_Y)
        widgetlabel.setText(
            self.set_vars(self.reader.attributes().value("Title")))
        widgetlineedit.editingFinished.connect(self.widgetedit)

        L_width = int(self.reader.attributes().value("Width")) * 7
        L_height = int(self.reader.attributes().value(
            "Height")) * 7 if self.reader.attributes().value(
            "Height") else 20
        if L_width:
            # 标题长度不为0
            widgetlabel.resize(L_width, L_height)
            self.current_X += L_width
        else:
            # 标题内容不为空
            if self.reader.attributes().value("Title"):
                widgetlabel.adjustSize()
                widgetlabel.resize(widgetlabel.size().width(), L_height)
            else:
                widgetlabel.resize(0, L_height)
            self.current_X += widgetlabel.size().width()
        self.boxresize(widgetlineedit, "MaxLength", "MaxHeight")
        wid = self.reader.attributes().value("ID")
        widgetlineedit.setText(self.set_vars(self.reader.readElementText()))
        if wid:
            try:
                setattr(self, wid, decimal.Decimal(widgetlineedit.text()))
            except:
                setattr(self, wid, '')

    # 线框
    def wireframe(self):
        linewidth = int(self.reader.attributes().value("width")) * 7
        lineheight = int(self.reader.attributes().value("height")) * 20
        penwidth = int(self.reader.attributes().value("PenWidth"))

        qrect = QtCore.QRect(self.current_X, self.current_Y, linewidth,
                             lineheight)

        self.line_border.append((qrect, penwidth))

    # 检测框
    def checkBox(self):
        self.reader.readNextStartElement()
        widget = QtWidgets.QCheckBox(self.scrollAreaWidgetContents)
        # widget.setContentsMargins(2, 0, 0, 0)
        self.boxresize(widget)
        widget.setText(self.set_vars(self.reader.attributes().value("name")))
        widget.setChecked(int(self.reader.readElementText()))
        # self.boxresize(widget)

    # 下拉框
    def comboBox(self):
        index = 0
        widget = QtWidgets.QComboBox(self.scrollAreaWidgetContents)
        self.boxresize(widget)

        # 允许自己填内容，则显示“value”的内容，
        # 否则显示index序号的内容
        if int(self.reader.attributes().value("style")):
            widget.setEditable(
                int(self.reader.attributes().value("style")))
            widget.setCurrentText(
                self.reader.attributes().value("value"))
        else:
            index = int(self.reader.attributes().value("index"))
        # self.boxresize(widget)
        # 循环添加下拉菜单的项目。
        while 1:
            self.reader.readNext()
            if self.reader.name() != 'Item':
                break
            widget.addItem(self.set_vars(self.reader.readElementText()))
        widget.setCurrentIndex(index)

    # 签名框
    def signBox(self):
        widget = QtWidgets.QLineEdit(self.scrollAreaWidgetContents)
        self.boxresize(widget)
        widget.setEnabled(False)
        widget.setStyleSheet("background-color: rgb(255, 0, 0);")
        widget.setText(self.reader.readElementText(1))

    # 表达式
    def exprBox(self):
        widget = QtWidgets.QLineEdit(self.scrollAreaWidgetContents)
        self.boxresize(widget)
        widget.setEnabled(False)
        widget.setStyleSheet("background-color: rgb(85, 255, 255);")
        # style = self.reader.attributes().value("showformat")
        # 后缀
        sibfix = ''
        # 计算过程
        expr = ''
        # 显示的表达式
        va = ''
        vid = self.reader.attributes().value("ID")
        while 1:
            self.reader.readNextStartElement()
            if self.reader.isEndElement() and self.reader.name() == "Expr":
                break
            if self.reader.name() == "subfix":
                sibfix = self.reader.readElementText()
            elif self.reader.name() == "expr":
                expr = self.reader.readElementText()
            elif self.reader.name() == "vars":
                va = self.reader.readElementText()

        # 把文件中的#变量，改为实例中的变量。
        expr = expr.replace('#', 'self.')
        expr = self.set_vars(expr)
        va = self.set_vars(va)

        try:
            result = str(eval(expr, evalenv(self)))
            widget.setText(va + result + sibfix)
            if id:
                setattr(self, id, decimal.Decimal(result))
        except:
            return "公式格式错误"
        # widget.setText(self.reader.readElementText(1))
        if vid:
            setattr(self, vid, result)

    # 换行框
    def wrapBox(self):
        self.current_X = 20
        self.current_Y += 20

    # 设置控件的尺寸
    # w:控件的宽度变量名
    # h:控件的高度变量名
    def boxresize(self, widget, w="width", h="height"):
        self.setStyleSheet("margin:2 2;")
        width = int(self.reader.attributes().value(
            w)) * 7 + 4 if self.reader.attributes().value(
            w) else 134
        height = int(self.reader.attributes().value(
            h)) * 24 if self.reader.attributes().value(
            h) else 24
        widget.resize(width, height)
        widget.move(self.current_X, self.current_Y)
        self.current_X += width

    # 设置表达式
    def set_vars(self, exp):
        items, sys_items = self.get_vars(exp)
        if items:
            for item in set(items):
                try:
                    exp = exp.replace(item, str(getattr(self, item[1:-1])))
                except AttributeError:
                    exp = exp.replace(item, '')
        if sys_items:
            for item in set(sys_items):
                try:
                    # 切片去除头尾的@
                    # 日期类变量
                    if item[1: -1] in (
                    'NIAN', 'YUE', 'RI', 'SHI', 'FEN', 'MIAO'):
                        exp = exp.replace(item,
                                          str(getattr(userdetail, item[1:-1])))
                    # 产品信息类变量
                    elif item[1: -1] in PRODUCT_DICT:
                        if self.proddetail is not None:
                            exp = exp.replace(item, str(
                                self.proddetail[PRODUCT_DICT[item[1: -1]]]))
                        else:
                            try:
                                self.get_sys_vars(0)
                                exp = exp.replace(item, str(
                                    self.proddetail[PRODUCT_DICT[item[1: -1]]]))
                            except IndexError:
                                exp = exp.replace(item, str(''))
                    # 产品物料，分批次
                    elif item[3: -2] in STUFF_DICT or item[3: -3] in STUFF_DICT:
                        # 变量的后缀
                        num = int(re.search(r'\d+', item).group(0)) - 1
                        vals = [x for x in re.split(r'@|\d', item) if x][0]
                        var_list = getattr(self, 'stuffdetail' + item[1: 3])
                        if len(var_list):
                            exp = exp.replace(item, str(
                                getattr(var_list[num], STUFF_DICT[vals[2:]])))
                        else:
                            self.get_sys_vars(1)
                            var_list = getattr(self, 'stuffdetail' + item[1: 3])
                            exp = exp.replace(item, str(
                                getattr(var_list[num], STUFF_DICT[vals[2:]])))
                    # 产品物料，不分批次
                    elif item[4: -2] in STUFF_DICT or item[4: -3] in STUFF_DICT:
                        # 变量的后缀
                        num = int(re.search(r'\d+', item).group(0)) - 1
                        vals = [x for x in re.split(r'@|\d', item) if x][0]
                        var_list = getattr(self, 'stuffdetail' + item[1: 4])
                        if len(var_list):
                            exp = exp.replace(item, str(
                                getattr(var_list[num], STUFF_DICT[vals[3:]])))
                        else:
                            self.get_sys_vars(2)
                            var_list = getattr(self, 'stuffdetail' + item[1: 4])
                            exp = exp.replace(item, str(
                                getattr(var_list[num], STUFF_DICT[vals[3:]])))
                    # 检验报告类信息变量
                    elif item[1: -1] in LAB_DICT:
                        if self.labdetail is not None:
                            exp = exp.replace(item, str(
                                self.labdetail[LAB_DICT[item[1: -1]]]))
                        else:
                            self.get_sys_vars(3)
                            exp = exp.replace(item, str(
                                self.labdetail[LAB_DICT[item[1: -1]]]))
                except:
                    exp = exp.replace(item, str(''))
        return exp

    # 获取系统变量的值
    # kind  获取的数据类型，0生产，1物料，2检验
    def get_sys_vars(self, kind=0):
        if self.autoid != 0:
            try:
                if kind == 0:
                    pm = ProductController()
                    self.proddetail = pm.get_producingplan(autoid=self.autoid)[
                        0]
                elif kind == 1:
                    sm = StuffController()
                    self.stuffdetail = sm.get_prodstuff(self.autoid)
                    for item in self.stuffdetail:
                        stufftype = item.stufftype
                        if stufftype == 0:
                            self.stuffdetailZC.append(item)
                            self.stuffdetailZF.append(item)
                        elif stufftype == 1:
                            self.stuffdetailFC.append(item)
                            self.stuffdetailZF.append(item)
                        elif stufftype == 2:
                            self.stuffdetailNB.append(item)
                            self.stuffdetailBC.append(item)
                        elif stufftype == 3:
                            self.stuffdetailWB.append(item)
                            self.stuffdetailBC.append(item)
                        elif stufftype == 4:
                            self.stuffdetailQC.append(item)
                elif kind == 2:
                    sm = StuffController()
                    self.mstuffdetail = sm.get_Mprodstuff(self.autoid)
                    for item in self.mstuffdetail:
                        stufftype = item.stufftype
                        if stufftype == 0:
                            self.stuffdetailMZC.append(item)
                            self.stuffdetailMZF.append(item)
                        elif stufftype == 1:
                            self.stuffdetailMFC.append(item)
                            self.stuffdetailMZF.append(item)
                        elif stufftype == 2:
                            self.stuffdetailMNB.append(item)
                            self.stuffdetailMBC.append(item)
                        elif stufftype == 3:
                            self.stuffdetailMWB.append(item)
                            self.stuffdetailMBC.append(item)
                        elif stufftype == 4:
                            self.stuffdetailMQC.append(item)
                elif kind == 3:
                    lm = LabrecordsController()
                    self.labdetail = lm.get_labrecord(1, autoid=self.autoid)[0]
            except:
                # traceback.print_exc()
                pass

    # 获得表达式中的普通变量和系统变量
    # {\w*} 普通变量
    # @\w*@ 系统变量
    def get_vars(self, exp):
        pattern1 = re.compile(r'{\w*}')
        pattern2 = re.compile(r'@\w*@')
        return pattern1.findall(exp), pattern2.findall(exp)

    '''
    def paintEvent(self, event):
        if self.line_border:
            #self.pix = self.pix.scaled(self.size())
            pp = QtGui.QPainter(self)
            #pp = QtGui.QPainter(self.pix)
            pen = QtGui.QPen()  # 定义笔格式对象
            for index, item in enumerate(self.line_border):
                print(item)
                pen.setWidth(item[1])  # 设置笔的宽度
                pen.setColor(QtCore.Qt.red)
                pp.setPen(pen)  # 将笔格式赋值给 画笔
                # 根据鼠标指针前后两个位置绘制直线
                pp.drawRect(item[0])
                #self.line_border.pop(index)

            #painter = QtGui.QPainter(self)
            # 在画布上画出
            #painter.drawPixmap(0, 0, self.pix)
    '''

    def widgetedit(self):
        widget = self.sender().objectName()
        # s = self.writer.setQuery("GMPPaper/Title[2]")
        # for item in s:
        #    print(s)
        # num = widget[6:]
        # self.writer.writeCurrentToken()
        # print(self.reader.namespaceUri())

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    mainmenu = ReadXML()

    res = Selfdefinedformat.objects.filter(autoid=2855)
    mainmenu.__setattr__('autoid', 50)
    mainmenu.read(res[0].format)
    mainmenu.show()
    sys.exit(app.exec_())


from sqlalchemy import Column, ForeignKey, String, DateTime, Boolean, Enum
from sqlalchemy import func, exc
from sqlalchemy.dialects.postgresql import UUID
from uuid import uuid4
from .. import db
from enum import Enum
from datetime import datetime

#? https://stackoverflow.com/questions/33612625/how-to-model-enums-backed-by-integers-with-sqlachemy
#? https://docs.sqlalchemy.org/en/14/core/type_basics.html#sqlalchemy.types.Enum
class CategoryEnum(Enum):
  tollBooth = "toll booth"
  passage   = "passage"
  food      = "food"
  others    = "others"

class ExtraExpenses(db.Model):

    __tablename__ = "extra_expenses"
    id          = Column(UUID(as_uuid=True), primary_key=True, default=uuid4())
    id_move     = Column(UUID(as_uuid=True), ForeignKey("moves.id", ondelete="CASCADE", name="id_move"))
    description = Column(String(255), nullable=False)
    #* Opción 1
    category    = Column(Enum(CategoryEnum), nullable=False)
    #* Opción 2, no tengo pruebas, pero tampoco dudas
    #! category      = Column(Enum(["toll booth", "passage", "food", "others" ]), nullable=False)
    amount    = Column(String(18), nullable=False)
    #? https://stackoverflow.com/questions/13370317/sqlalchemy-default-datetime
    startedAt = Column(DateTime(timezone=True), nullable=False, server_default=func.now())
    updatedAt = Column(DateTime(timezone=True), nullable=True, onupdate=func.now())
    deletedAt = Column(DateTime(timezone=True), nullable=True)
    active    = Column(Boolean(), nullable=False, default=True)

    def save(**kwargs):
      try:
        expense = ExtraExpenses(**kwargs)
        db.session.add(expense)
        db.session.commit()
        return expense
      except Exception as error:
        print(error)
        return {}
      finally:
        pass

    def find():
      try:
        return ExtraExpenses.query.filter_by().all()
      except:
        return {}
      finally:
        pass

    def find_one(**kwargs):
      try:
        return db.session.query(ExtraExpenses).filter_by(**kwargs).first()
      except exc.SQLAlchemyError as err:
        print(err)
        return {}
      finally:
        db.session.close()

    def update(**update):
      try:
        update["updatedAt"] = datetime.now()
        updated = (
          db.session.query(ExtraExpenses)
          .filter_by(id=str(update["id"]))
          .update(update, synchronize_session="fetch")
        )
        db.session.commit()
        return updated
      except Exception as error:
        print(error)
        return {}

    def delete(**kwargs) -> int:
      try:
        updated = (
          db.session.query(ExtraExpenses)
          .filter_by(**kwargs)
          .update(
            {"active": False, "deletedAt": datetime.now()},
            synchronize_session="fetch",
          )
        )
        db.session.commit()
        return updated
      except exc.SQLAlchemyError as err:
        print(err)
        db.session.rollback()
        return {}


import time

import pandas as pd
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

from datetime import datetime # Config file purpose

options = Options()
options.add_argument("--incognito")
options.add_argument("--window-size=1920x1080")

# Driver path
driver = webdriver.Chrome(options=options, executable_path="../chromedriver_win32/chromedriver.exe")

def layer_three(layer_two_file):
    print("Layer three is starting")
    '''

    This layer will retrieve layer_two.csv.
    Layer one contains author name and its profile url
    Layer two contains paper name and its url.

    The objective of layer three is retrieve paper title, description, paperlink, authors and date.
    This is the final layer to obtain the data.

    '''

    # Define dataframe for third layer
    layer_three_data = pd.DataFrame(
        columns=["df_paper_title", "df_paper_url", "df_paper_abstract", "df_paper_author", "df_paper_date"])
    data = {}

    df_layer_two_file = pd.read_csv(layer_two_file)
    print("Loading dataframe")
    print(df_layer_two_file)
    print("dataframe loaded")

    for i in range(len(df_layer_two_file["df_title_url"])):
        time.sleep(2)
        print("Moving to " + (df_layer_two_file["df_title_url"][i]))
        driver.get(df_layer_two_file["df_title_url"][i])  # Moves to unique paper page
        print("No of paper accessed", i)

        # columns = ["df_paper_title", "df_paper_doi", "df_paper_abstract", "df_paper_author", "df_paper_date"])

        # Obtain title
        paperTitle = driver.find_elements_by_css_selector(".container > div > div > div:nth-child(1) > h1")
        paperTitles = [el.text for el in paperTitle]
        print("Pasting paper title")
        data['df_paper_title'] = paperTitles

        # Obtain link
        paper_title_links = driver.find_elements_by_css_selector(
            ".rendering_contributiontojournal_publicationaccessrenderer > ul.dois > li > div > a")
        paperlink = [el.get_attribute("href") for el in paper_title_links]
        print("Pasting paper url")
        data['df_paper_url'] = paperlink

        # Obtain Abstract
        paper_abstract = driver.find_elements_by_css_selector(
            ".rendering_abstractportal.rendering_contributiontojournal_abstractportal > div")
        paper_abstracts = [el.text for el in paper_abstract]
        print("Pasting paper abstract")
        data['df_paper_abstract'] = paper_abstracts

        # Obtain authors
        paper_authors = driver.find_elements_by_css_selector(
            ".rendering_contributiontojournal_associatespersonsclassifiedportal > p > a:nth-child(1) > span")
        paper_author = [el.text for el in paper_authors]
        print("Pasting paper authors")
        data['df_paper_author'] = paper_author

        # Obtain publication date
        paper_publication_dates = driver.find_elements_by_css_selector(
            ".rendering_contributiontojournal_detailsportal > div > table > tbody > tr.status > td > span.date")
        paper_publication_date = [el.text for el in paper_publication_dates]
        print("Pasting paper publication date")
        data['df_paper_date'] = paper_publication_date

        layer_three_data = layer_three_data.append(data, ignore_index=True)

        layer_three_data.to_csv("./layer_three_data.csv", index=False)
        print("CSV saved, number of paper", i)

    df_layer_three_file = pd.read_csv(layer_three_data)

    df_layer_three_file['df_paper_title'] = df_layer_three_file['df_paper_title'].str.strip('[]')
    df_layer_three_file['df_paper_title'] = df_layer_three_file['df_paper_title'].str.strip("''")

    df_layer_three_file['df_paper_url'] = df_layer_three_file['df_paper_url'].str.strip('[]')
    df_layer_three_file['df_paper_url'] = df_layer_three_file['df_paper_url'].str.strip("''")

    df_layer_three_file['df_paper_abstract'] = df_layer_three_file['df_paper_abstract'].str.strip('[]')
    df_layer_three_file['df_paper_abstract'] = df_layer_three_file['df_paper_abstract'].str.strip("''")

    df_layer_three_file['df_paper_author'] = df_layer_three_file['df_paper_author'].str.strip('[]')
    df_layer_three_file['df_paper_author'] = df_layer_three_file['df_paper_author'].str.strip("''")

    df_layer_three_file['df_paper_date'] = df_layer_three_file['df_paper_date'].str.strip('[]')
    df_layer_three_file['df_paper_date'] = df_layer_three_file['df_paper_date'].str.strip("''")

    df_layer_three_file.to_csv("./layer_three_data.csv", index=False)
    print("CSV saved")

    print("End of layer three")

    f = open("version.cfg", "x")

    # datetime object containing current date and time
    now = datetime.now()

    # dd/mm/YY H:M:S
    dt = now.strftime("%d/%m/%Y %H:%M:%S")
    print("Saved version: ", dt)

    f.write(dt)
    f.close()

    driver.close()
    return True

# layer_three("layer_two_data.csv")


# -*- coding: utf-8 -*-
from __future__ import absolute_import

from enigma import eInputDeviceManager, eTimer
from Screens.Screen import Screen
from Screens.Rc import Rc
from Components.Sources.List import List
from Components.ActionMap import ActionMap
from Components.config import config
from Components.Sources.StaticText import StaticText
from Tools.Directories import pathExists, resolveFilename, SCOPE_CURRENT_SKIN
from Tools.LoadPixmap import LoadPixmap
from Tools.Log import Log

from os import path as os_path

import six

from .CharJump import CharJump
from .InputDeviceIRDatabase import irdb
from .IrProtocols.ProtocolMaster import ProtocolMaster
from .KeyBindingList import KeyBindingList

class InputDeviceIRProg(Screen, CharJump):
	PLUGIN_IMAGES_PATH = "%s/images/" % (os_path.dirname(__file__))
	SKIN_IMAGES_PATH = resolveFilename(SCOPE_CURRENT_SKIN, config.skin.primary_skin.value.replace("/skin.xml", "/images/"))
	MAJOR_CODELIST_ITEMS = [ "amp", "av ", "tv", "vcr", "sat"]

	def __init__(self, session, remote):
		Screen.__init__(self, session)
		CharJump.__init__(self, session)
		self._remote = remote

		self["actions"] = ActionMap(["ListboxActions", "OkCancelActions", "EPGSelectActions"],
		{
			"ok": self._onKeyOK,
			"cancel": self._onKeyExit,
			"info" : self._onKeyInfo
		}, -1)

		self["list"] = List()
		self["list"].onSelectionChanged.append(self._onSelectionChanged)
		self._status = StaticText()
		self["status"] = self._status

		self._vendorPixmap = self._loadPixmap("vendor.svg")
		self._seperatorPixmap = self._loadPixmap("div-h.svg")
		self._level = 0
		self._lastLevel = 0
		self._lastVendor = ""
		self._keysAcknowledged = 0
		self._keysAckTimer = eTimer()
		self.__keysAckTimer_connection = self._keysAckTimer.timeout.connect(self._onKeysAckTimeout)
		self.__onIrKeycount_connection = eInputDeviceManager.getInstance().irKeyCount.connect(self._onIrKeyCount)
		self.onLayoutFinish.append(self._reload)

	def _onIrKeyCount(self, address, count):
		if address == self._remote.address():
			self._keysAcknowledged = count
			self._keysAckTimer.startLongTimer(2)

	def _onKeysAckTimeout(self):
		self.session.toastManager.showToast(_("%s IR codes acknowledged!") %(self._keysAcknowledged))
		self._keysAcknowledged = 0

	def _loadPixmap(self, filename, desktop=None):
		picfile = None
		if filename[0] == "/" and pathExists(filename):
			picfile = filename
		else:
			for p in (self.SKIN_IMAGES_PATH, self.PLUGIN_IMAGES_PATH):
				imagepath = "%s%s" % (p, filename)
				if pathExists(imagepath):
					picfile = "%s%s" % (p, filename)
					break
		if picfile:
			return LoadPixmap(path=picfile, desktop=desktop, cached=False)
		return None

	def _onKeyExit(self):
		if self._level == 1:
			self._level = 0
			self._reload()
			return
		self.close()

	def _getFirstForChar(self, char):#CharJump
		idx = 0
		for x in self["list"].list:
			val = x[0][0]
			Log.w(val)
			if val and val[0].upper() == char: # and not val.lower() in self.MAJOR_VENDORS:
				self["list"].setIndex(idx)
				break
			idx += 1

	def _onKey0(self, unused):#CharJump
		if self["list"].count():
			self["list"].setIndex(0)

	def _reload(self, dlist={}):
		if self._level == 0:
			dlist = irdb.data
		mlist = []
		for x, y in dlist.items():
			x = six.ensure_str(x)
			title = x
			subtitle = ""
			pic = self._seperatorPixmap
			if self._level == 0:
				lendev = len(y)
				if lendev == 1:
					subtitle = "%s" % (six.ensure_str(y.keys()[0]))
				else:
					subtitle = _("%s devices") % (lendev,)
			else:
				models = y.get("models", [])
				sorted_models = []
				if models:
					for dev in models:
						dev = six.ensure_str(dev)
						append = True
						for item in self.MAJOR_CODELIST_ITEMS:
							if dev.lower().startswith(item):
								append = False
						if append:
							sorted_models.append(dev)
						else:
							sorted_models.insert(0, dev)
					title = " / ".join(sorted_models)
				if title == "":
					title = _("Unknown")
				if not len(y["keys"]):
					Log.w("No known automap-keys for %s" % (title,))
				subtitle = _("%s mapped keys") % (len(y["keys"]))
			mlist.append(((x, y), self._vendorPixmap, subtitle, title, pic))
		if self._level != 0:
			def sortCodelist(x):
				x = x[0][0]
				val = "000000"
				items = self.MAJOR_CODELIST_ITEMS[:]
				items.reverse()
				for key in items:
					if x.lower().startswith(key):
						return val + x
					val = "{}{}".format(val, "000000")
				return x

			mlist = sorted(mlist, key=sortCodelist)
		self["list"].setList(mlist)
		if self._level == 0:
			self["list"].setIndex(self._lastLevel)
			self.setTitle(_("Vendors"))
			self["status"].setText("%s entries" % (len(mlist),))
		else:
			self.setTitle(self._lastVendor)
			self._onSelectionChanged()

	def _onKeyOK(self):
		sel = self["list"].getCurrent()
		entry = sel and sel[0]
		if not len(entry):
			return
		if self._level == 0:
			self._level = 1
			self._lastLevel = self["list"].getIndex()
			self._lastVendor = six.ensure_str(entry[0])
			self._reload(entry[1])
		else:
			self._send(entry[1])

	def _onKeyInfo(self):
		if self._level == 0:
			return
		sel = self["list"].getCurrent()
		entry = sel and sel[0]
		if not len(entry):
			return
		device, data = entry[0:2]
		title = six.ensure_str("%s - %s (%s - %s:%s)" %(self._lastVendor, device, data["protocol"], data["device"], data["subdevice"]))
		self.session.open(InputDeviceKeyInfo, title, data["keys"].keys())

	def _send(self, data):
		protocolData = ProtocolMaster.buildProtocol(data)
		self._remote.resetIr()
		for d in protocolData: #initial / repeat
			protocol, isRepeat, keys = d
			if protocol:
				self._remote.setIrProtocol(isRepeat, protocol)
			for irKey in keys:
				self._remote.setIrKey(irKey)
		self._remote.getIrKeyCount()
		self.session.toastManager.showToast(_("%s IR codes sent!") %(len(keys)), 3)

	def _onSelectionChanged(self):
		if self._level == 0:
			return
		entry = self["list"].getCurrent()
		entry = entry and entry[0]
		if not entry:
			return
		device, data = entry
		count = len(data["keys"])
		self["status"].setText(_("Press OK to apply assign %s keys of '%s'") %(count, device))

class InputDeviceKeyInfo(Screen, Rc):
	def __init__(self, session, title, boundKeys):
		Screen.__init__(self, session, windowTitle=title)
		Rc.__init__(self, 3)
		keys = sorted([six.ensure_str(x) for x in boundKeys])
		self["list"] = KeyBindingList(3, keys)
		self["list"].onSelectionChanged.append(self._onSelectionChanged)
		self["actions"] = ActionMap(["OkCancelActions"],
		{
			"cancel": self.close,
		}, -1)
		self.onLayoutFinish.append(self._onSelectionChanged)

	def _onSelectionChanged(self):
		self.clearSelectedKeys()
		selection = self["list"].getCurrent()
		Log.w(selection)
		selection = selection and selection[0]
		if not selection:
			return
		self.selectKey(selection)


import os

import networkx as nx
from networkx.drawing.nx_agraph import write_dot

from tree_parser.parser import DependencyParser

_path = os.path.dirname(__file__)

_save_filename = os.path.join(_path, '../data/tree_parser.model')

_text = """
In nuclear physics, the island of stability is a predicted set of isotopes of superheavy elements
that may have considerably longer half-lives than known isotopes of these elements.
"""

if __name__ == '__main__':
    parser = DependencyParser(_save_filename)
    g = parser.parse(_text)

    print('Node words:')
    print(nx.get_node_attributes(g, 'token'))
    print('Node POS tags:')
    print(nx.get_node_attributes(g, 'pos'))
    print('edge labels:')
    print(nx.get_edge_attributes(g, 'label'))

    write_dot(g, 'test.dot')


import os
import sys

if sys.platform[:4] == "java": # Jython
    import uk.ac.cam.ch.wwmm.opsin as opsin
else: # CPython
    import jpype
    if not jpype.isJVMStarted():
        _jvm = os.environ['JPYPE_JVM']
        if _jvm[0] == '"': # Handle trailing quotes
            _jvm = _jvm[1:-1]
        _cp = os.environ['CLASSPATH']
        jpype.startJVM(_jvm, "-Djava.class.path=" + _cp)
    opsin = jpype.JPackage("uk").ac.cam.ch.wwmm.opsin

try:
    _nametostruct = opsin.NameToStructure.getInstance()
    _restoinchi = opsin.NameToInchi.convertResultToInChI
except TypeError:
    raise ImportError("The OPSIN Jar file cannot be found.")

informats = {'iupac': 'IUPAC name'}
"""A dictionary of supported input formats"""
outformats = {'cml': "Chemical Markup Language", 'inchi': "InChI",
              'smi': "SMILES"}
"""A dictionary of supported output formats"""

def readstring(format, string):
    """Read in a molecule from a string.

    Required parameters:
       format - see the informats variable for a list of available
                input formats
       string

    Example:
    >>> input = "propane"
    >>> mymol = readstring("iupac", input)
    """
    if format!="iupac":
        raise ValueError("%s is not a recognised OPSIN format" % format)

    result = _nametostruct.parseChemicalName(string)
    if str(result.getStatus()) == "FAILURE":
        raise IOError("Failed to convert '%s' to format '%s'\n%s" % (
            string, format, result.getMessage()))

    return Molecule(result)

class Molecule(object):
    """Represent a opsinjpype Molecule.

    Required parameters:
       OpsinResult -- the result of using OPSIN to parse an IUPAC string

    Methods:
       write()

    The underlying OpsinResult can be accessed using the attribute:
       OpsinResult
    """
    _cinfony = True

    def __init__(self, OpsinResult):
        if hasattr(OpsinResult, "_cinfony"):
            raise IOError("An opsin Molecule cannot be created from another Cinfony Molecule")

        self.OpsinResult = OpsinResult

    def __str__(self):
        return self.write()
    @property
    def _exchange(self):
        return (0, self.write("smi"))
    def write(self, format="smi", filename=None, overwrite=False):
        """Write the molecule to a file or return a string.

        Optional parameters:
           format -- see the outformats variable for a list of available
                     output formats (default is "smi")
           filename -- default is None
           overwite -- if the output file already exists, should it
                       be overwritten? (default is False)

        If a filename is specified, the result is written to a file.
        Otherwise, a string is returned containing the result.
        """
        if format not in outformats:
            raise ValueError("%s is not a recognised OPSIN format" % format)

        if filename is not None and not overwrite and os.path.isfile(filename):
            raise IOError("%s already exists. Use 'overwrite=True' to overwrite it." % filename)

        if format == "cml":
            result = str(self.OpsinResult.getCml().toXML())
        elif format == "inchi":
            result = str(_restoinchi(self.OpsinResult))
        elif format == "smi":
            result = str(self.OpsinResult.getSmiles())

        if filename:
            outputfile = open(filename, "w")
            with open(outputfile,'w') as fp:
                print(result,file=fp)
        else:
            return result

if __name__=="__main__": #pragma: no cover
    mol = readstring("iupac", "propane")
    print(mol.write("inchi"))


from pathlib import Path
import requests
import json

# user is the name of the user
# type is either "ANIME" or "MANGA"
def get_list(user, type = "ANIME", queries = None):
    if queries is None: queries = load_queries()
    variables = {
        'name': user,
        'type': type
    }
    url = 'https://graphql.anilist.co'
    r = requests.post(url, json={'query': queries['animelist'],
                                 'variables': variables})
    j = r.json()
    return r.json()

def trim_list(l, type = "anime"):
    unified_list = [y for x in
                            l['data']['MediaListCollection']['lists']
                            for y in x['entries']]
    return unified_list

def load_queries() -> {str: str}:
    query_dir = 'anilist_queries'
    queries = [x for x in Path(query_dir).iterdir() if x.suffix == '.query']
    return {query.stem: open(query).read() for query in queries}

if __name__ == '__main__':
    #queries = load_queries()
    #test_write(get_list('Darn', queries = queries), 'balls2')
    trim_list(get_list('Darn'))


import logging
class LoggingService:
    def __init__(self, name) -> None:

        self.logger = logging.getLogger(name)
        self.handler = logging.StreamHandler()
        self.formatter = logging.Formatter(
            '%(asctime)s [%(name)-12s] %(levelname)-8s %(message)s')
        self.handler.setFormatter(self.formatter)
        self.logger.addHandler(self.handler)
        self.logger.setLevel(logging.DEBUG)


import itertools
from unittest.mock import Mock

from sukoon.kernel import SukoonKernel

def test_all():
    test_data = open("test/basic.py")

    test = ''
    expected = ''
    for line in itertools.chain(test_data, ['']):
        if line.startswith('##'):
            expected += line[2:].lstrip()
        elif line.strip() == '' and test and expected:
            run_single(test, expected)
            test = ''
            expected = ''
        else:
            test += line

def run_single(test, expected):
    kernel = SukoonKernel()
    send_response = Mock()
    kernel.send_response = send_response
    kernel.do_execute(test, False)

    response = send_response.call_args[0][2]['text']
    assert expected == response