# 結果は yafuoku_seller_crawl.csv として出力する

import scrapy
from scrapy.exceptions import CloseSpider
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
import datetime

class YafuokuSellerCrawlSpider(CrawlSpider):
    name = "yafuoku_seller_crawl"
    allowed_domains = ["auctions.yahoo.co.jp"]
    start_urls = [
        # セラーの出品での評価リスト
        "https://auctions.yahoo.co.jp/jp/show/rating?userID=k_h_112&role=seller",
        "https://auctions.yahoo.co.jp/jp/show/rating?userID=mlamb63401&role=seller",
    ]

    rules = (
        # 詳細ページへのリンク
        Rule(LinkExtractor(restrict_xpaths='//table[@bgcolor="#ffffff"]//a[contains(@href,"page")]'), callback="parse_item", follow=True),
        # 次のページへのリンク
        Rule(LinkExtractor(restrict_xpaths='(//a[contains(text(),"次の25件")])[1]')),
    )

    # def get_name(self, elem):
    #     if elem:
    #         return elem.replace('　', ' ')
    #     return 'No Name'

    def get_price(self, elem):
        if elem:
            return int(elem.split()[0].replace(',', '').replace('円', ''))
        return 0

    # def get_tax(self, elem):
    #     if '税込' in elem:
    #         return int(elem.replace('（税込 ', '').replace(' 円）', '').replace(',', ''))
    #     elif '税' in elem:
    #         return int(elem.replace('（税 ', '').replace(' 円）', '').replace(',', ''))
    #     return 0

    def get_bid_num(self, elem):
        if elem:
            return int(elem.replace('件', ''))
        return 0

    def get_seller(self, elem):
        if elem:
            return elem.strip()
        return elem

    def get_seller_rating(self, elem):
        if elem:
            return elem[0].strip().replace(',', '')
        return 0

    def get_end_date(self, elem):
        if elem:
            end_datetime = datetime.datetime.strptime(elem.strip().split('（')[0], '%Y.%m.%d')
            end_date = datetime.date(end_datetime.year, end_datetime.month, end_datetime.day)
            diff_date = datetime.date.today() - end_date
            if diff_date.days > 60:
                print(f'■ {diff_date} ■')
                raise CloseSpider('■■■ 古い情報になったため調査を終了します ■■■')
            print(f'■ {diff_date} ■')
            return end_date
        return 0

    def parse_item(self, response):
        # print('▼ parse_item ▼')
        yield {
            'name': response.xpath('//h1/text()').get(),
            'price': self.get_price(response.xpath('(//dd[@class="Price__value"]/text())[1]').get()),
            'tax': response.xpath('//span[@class="Price__tax u-fontSize14"]/text()').get(),
            # 'tax': self.get_tax(response.xpath('//span[@class="Price__tax u-fontSize14"]/text()').get()),
            'bid_num': self.get_bid_num(response.xpath('//span[contains(@class,"Count__detail") and contains(text(),"件")]/text()').get()),
            'postage': response.xpath('//span[@class="Price__postageValue Price__postageValue--free"]/text()').get(),
            'postage_due': response.xpath('(//dt[contains(text(),"送料負担")]/following-sibling::dd/text())[2]').get(),
            'free_postage': response.xpath('(//span[@title="送料無料"]/text())[1]').get(),
            'unused': response.xpath('(//span[@title="未使用"]/text())[1]').get(),
            'seller': self.get_seller(response.xpath('//p[@class="Seller__name"]/a/text()').get()),
            'seller_rating': self.get_seller_rating(response.xpath('//a[@class="Seller__ratingLink"]/text()').getall()),
            'info_get_date': datetime.datetime.now(),
            'end_date': self.get_end_date(response.xpath('//th[contains(text(),"終了日時")]/following-sibling::td/text()').get()),
            'url': response.url
        }


# -*- coding: utf-8 -*-

import os
from pelican import signals, contents
from pelican.utils import strftime, set_date_tzinfo
from datetime import datetime
from git_wrapper import git_wrapper

def datetime_from_timestamp(timestamp, content):
    """
    Helper function to add timezone information to datetime,
    so that datetime is comparable to other datetime objects in recent versions
    that now also have timezone information.
    """
    return set_date_tzinfo(
        datetime.fromtimestamp(timestamp),
        tz_name=content.settings.get('TIMEZONE', None))

def filetime_from_git(content):
    if isinstance(content, contents.Static):
        return

    git = git_wrapper('.')
    tz_name = content.settings.get('TIMEZONE', None)

    gittime = content.metadata.get('gittime', 'yes').lower()
    gittime = gittime.replace("false", "no").replace("off", "no")
    if gittime == "no":
        return

    # 1. file is not managed by git
    #    date: fs time
    # 2. file is staged, but has no commits
    #    date: fs time
    # 3. file is managed, and clean
    #    date: first commit time, update: last commit time or None
    # 4. file is managed, but dirty
    #    date: first commit time, update: fs time
    path = content.source_path
    if git.is_file_managed_by_git(path):
        commits = git.get_commits(
            path, follow=content.settings.get('GIT_FILETIME_FOLLOW', False))

        if len(commits) == 0:
            # never commited, but staged
            content.date = git.datetime_from_timestamp(
                os.stat(path).st_ctime, content)
        else:
            # has commited
            content.date = git.get_commit_date(
                commits[-1], tz_name)

            if git.is_file_modified(path):
                # file has changed
                content.modified = datetime_from_timestamp(
                    os.stat(path).st_ctime, content)
            else:
                # file is not changed
                if len(commits) > 1:
                    content.modified = git.get_commit_date(
                        commits[0], tz_name)
    else:
        # file is not managed by git
        content.date = datetime_from_timestamp(os.stat(path).st_ctime, content)

    if not hasattr(content, 'modified'):
        content.modified = content.date

    if hasattr(content, 'date'):
        content.locale_date = strftime(content.date, content.date_format)

    if hasattr(content, 'modified'):
        content.locale_modified = strftime(
            content.modified, content.date_format)

def register():
    signals.content_object_init.connect(filetime_from_git)


import csv
import io

from scdatatools.sc.config import ACTION_MAP_FIELD_NAMES
from starfab.gui import qtc, qtg, qtw
from starfab.gui.widgets.dock_widgets.common import StarFabStaticWidget
from starfab.resources import RES_PATH

class ActionItem(qtg.QStandardItem):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setEditable(False)

class ActionMapView(StarFabStaticWidget):
    __ui_file__ = str(RES_PATH / "ui" / "ActionMapView.ui")

    def __init__(self, starfab, proxy_model=None, *args, **kwargs):
        super().__init__(starfab, *args, **kwargs)

        self.debounce = qtc.QTimer()
        self.debounce.setInterval(500)
        self.debounce.setSingleShot(True)
        self.debounce.timeout.connect(self._update_search)

        self.starfab.sc_manager.p4k_model.loaded.connect(self.handle_sc_opened)

        self.tree_model = None
        self.proxy_model = qtc.QSortFilterProxyModel(self)
        self.proxy_model.setRecursiveFilteringEnabled(True)
        self.proxy_model.setFilterCaseSensitivity(qtc.Qt.CaseInsensitive)
        self.proxy_model.setSortCaseSensitivity(qtc.Qt.CaseInsensitive)
        self.tree.installEventFilter(self)

        self.search_bar.textChanged.connect(self.debounce.start)
        self.search_bar.setClearButtonEnabled(True)
        self.exportButton.clicked.connect(self.export)

        # TODO: filter will require some tweaking to show parents before search works
        # self.search_bar.hide()

    def _update_search(self):
        self.proxy_model.setFilterWildcard(self.search_bar.text())

    def copy_selection(self):
        selections = self.table.selectedIndexes()
        if len(selections) == 1:
            qtg.QGuiApplication.clipboard().setText(selections[0].data())
        else:
            rows = sorted(index.row() for index in selections)
            columns = sorted(index.column() for index in selections)
            rowcount = rows[-1] - rows[0] + 1
            colcount = columns[-1] - columns[0] + 1
            table = [[""] * colcount for _ in range(rowcount)]
            for index in selections:
                row = index.row() - rows[0]
                column = index.column() - columns[0]
                table[row][column] = index.data()
            stream = io.StringIO()
            csv.writer(stream).writerows(table)
            qtg.QGuiApplication.clipboard().setText(stream.getvalue())

    def eventFilter(self, source, event):
        if event.type() == qtc.QEvent.KeyPress and event.matches(qtg.QKeySequence.Copy):
            # self.copy_selection()
            return True
        return super().eventFilter(source, event)

    def _fill_tree(self):
        self.tree_model.setHorizontalHeaderLabels(ACTION_MAP_FIELD_NAMES + ["filter"])
        am = self.starfab.sc.default_profile.actionmap()
        root = self.tree_model.invisibleRootItem()
        # empty_action_item = ActionItem("")
        for ui_category, action_category in am.items():
            ui_category_item = ActionItem(ui_category)
            root.appendRow([ui_category_item])
            for category, actions in action_category.items():
                category_item = ActionItem(category)
                ui_category_item.appendRow([category_item])
                for label, action in actions.items():
                    row = [ActionItem(""), ActionItem(label)]
                    row[1].setToolTip(label)
                    for _ in ACTION_MAP_FIELD_NAMES[2:]:
                        txt = str(action.get(_, ""))
                        row.append(ActionItem(txt))
                        row[-1].setToolTip(txt)
                    row.append(
                        ActionItem(
                            "".join(
                                [category, label] + [str(_) for _ in action.values()]
                            )
                        )
                    )
                    category_item.appendRow(row)

    def export(self):
        path, _ = qtw.QFileDialog.getSaveFileName(self, "Export Action Map", '', "*.csv")
        if path:
            with open(path, 'w', newline='') as out:
                self.starfab.sc.default_profile.dump_actionmap_csv(out)

    def handle_sc_opened(self):
        if self.starfab.sc is not None and self.starfab.sc.is_loaded("p4k"):
            self.tree_model = qtg.QStandardItemModel(self)
            self._fill_tree()
            self.proxy_model.setSourceModel(self.tree_model)
            self.proxy_model.setFilterKeyColumn(len(ACTION_MAP_FIELD_NAMES))
            self.tree.setModel(self.proxy_model)
            self.tree.hideColumn(len(ACTION_MAP_FIELD_NAMES))
            self.tree.setWordWrap(True)
            self.tree.setAlternatingRowColors(True)
            self.tree.setColumnWidth(0, 250)
            self.tree.setColumnWidth(1, 250)
            self.tree.setSortingEnabled(True)
            self.tree.sortByColumn(0, qtc.Qt.AscendingOrder)
            self.tree.expandAll()


# !/usr/bin/env python
# -*- coding:utf-8 -*-
from appium import webdriver
import time
d = {
  "platformName": "Android",
  "platformVersion": "5.1.1",
  "deviceName": "emulator-5554",
  "appPackage": "com.baidu.input",
  "appActivity": ".ImeAppMainActivity",
  # "noReset": "true",
  'unicodeKeyboard': "true",
  'resetKeyboard': "true"
}
dr = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_capabilities=d)

dr.find_element_by_id("com.baidu.input:id/setdefault").click()
time.sleep(2)
a = dr.find_elements_by_class_name("android.widget.RadioButton")
b = 0
for i in a:
    b += 1
    if b == 2:
        i.click()
        break
    else:
        continue
time.sleep(2)
dr.find_element_by_id("com.baidu.input:id/finishsetting").click()
def get_size():
    x = dr.get_window_size()
    return x
size = get_size()
time.sleep(0.5)
x = size['width']
y = size['height']
time.sleep(1)
dr.swipe(x*0.5, y*0.65, x*0.5, y*0.35, 600)
dr.find_element_by_id("com.baidu.input:id/ID_PULLTOREFRESH_GRIDVIEW").find_element_by_xpath("//*[@index='4']").click()
dr.find_element_by_id("com.baidu.input:id/apply_btn").click()
time.sleep(10)


import numpy as np
import scipy.signal as sig
import copy
import librosa

def bandpower(ps, mode="time"):
    """
    estimate bandpower, see https://de.mathworks.com/help/signal/ref/bandpower.html
    """
    if mode == "time":
        x = ps
        l2norm = np.linalg.norm(x) ** 2.0 / len(x)
        return l2norm
    elif mode == "psd":
        return sum(ps)

def getIndizesAroundPeak(arr, peakIndex, searchWidth=1000):
    peakBins = []
    magMax = arr[peakIndex]
    curVal = magMax
    for i in range(searchWidth):
        newBin = peakIndex + i
        if newBin >= len(arr):
            break
        newVal = arr[newBin]
        if newVal > curVal:
            break
        else:
            peakBins.append(int(newBin))
            curVal = newVal
    curVal = magMax
    for i in range(searchWidth):
        newBin = peakIndex - i
        if newBin < 0:
            break
        newVal = arr[newBin]
        if newVal > curVal:
            break
        else:
            peakBins.append(int(newBin))
            curVal = newVal
    return np.array(list(set(peakBins)))

def freqToBin(fAxis, Freq):
    return np.argmin(abs(fAxis - Freq))

def getPeakInArea(psd, faxis, estimation, searchWidthHz=10):
    """
    returns bin and frequency of the maximum in an area
    """
    binLow = freqToBin(faxis, estimation - searchWidthHz)
    binHi = freqToBin(faxis, estimation + searchWidthHz)
    peakbin = binLow + np.argmax(psd[binLow : binHi + 1])
    return peakbin, faxis[peakbin]

def getHarmonics(fund, sr, nHarmonics=6, aliased=False):
    harmonicMultipliers = np.arange(2, nHarmonics + 2)
    harmonicFs = fund * harmonicMultipliers
    if not aliased:
        harmonicFs[harmonicFs > sr / 2] = -1
        harmonicFs = np.delete(harmonicFs, harmonicFs == -1)
    else:
        nyqZone = np.floor(harmonicFs / (sr / 2))
        oddEvenNyq = nyqZone % 2
        harmonicFs = np.mod(harmonicFs, sr / 2)
        harmonicFs[oddEvenNyq == 1] = (sr / 2) - harmonicFs[oddEvenNyq == 1]
    return harmonicFs

def extract_snr(audio, sr=None):
    """Extract Signal-to-Noise Ratio for a given audio."""
    if sr != None:
        audio, _ = librosa.load(audio, sr=sr)
    else:
        audio, sr = librosa.load(audio, sr=sr)
    faxis, ps = sig.periodogram(
        audio, fs=sr, window=("kaiser", 38)
    )  # get periodogram, parametrized like in matlab
    fundBin = np.argmax(
        ps
    )  # estimate fundamental at maximum amplitude, get the bin number
    fundIndizes = getIndizesAroundPeak(
        ps, fundBin
    )  # get bin numbers around fundamental peak
    fundFrequency = faxis[fundBin]  # frequency of fundamental

    nHarmonics = 18
    harmonicFs = getHarmonics(
        fundFrequency, sr, nHarmonics=nHarmonics, aliased=True
    )  # get harmonic frequencies

    harmonicBorders = np.zeros([2, nHarmonics], dtype=np.int16).T
    fullHarmonicBins = np.array([], dtype=np.int16)
    fullHarmonicBinList = []
    harmPeakFreqs = []
    harmPeaks = []
    for i, harmonic in enumerate(harmonicFs):
        searcharea = 0.1 * fundFrequency
        estimation = harmonic

        binNum, freq = getPeakInArea(ps, faxis, estimation, searcharea)
        harmPeakFreqs.append(freq)
        harmPeaks.append(ps[binNum])
        allBins = getIndizesAroundPeak(ps, binNum, searchWidth=1000)
        fullHarmonicBins = np.append(fullHarmonicBins, allBins)
        fullHarmonicBinList.append(allBins)
        harmonicBorders[i, :] = [allBins[0], allBins[-1]]

    fundIndizes.sort()
    pFund = bandpower(ps[fundIndizes[0] : fundIndizes[-1]])  # get power of fundamental

    noisePrepared = copy.copy(ps)
    noisePrepared[fundIndizes] = 0
    noisePrepared[fullHarmonicBins] = 0
    noiseMean = np.median(noisePrepared[noisePrepared != 0])
    noisePrepared[fundIndizes] = noiseMean
    noisePrepared[fullHarmonicBins] = noiseMean

    noisePower = bandpower(noisePrepared)

    r = 10 * np.log10(pFund / noisePower)

    return r, 10 * np.log10(noisePower)


import settings
import utils
import visualization.visualization_utils as vUtils
import matplotlib.pyplot as plt
import string
from datetime import datetime, timedelta

class FragmentationKaandorpPartial_timeseries:
    def __init__(self, scenario, figure_direc, shore_time, lambda_frag, rho, simulation_length, weight,
                 input='LebretonDivision'):
        # Simulation parameters
        self.scenario = scenario
        self.shore_time = shore_time
        self.lambda_frag = lambda_frag
        self.rho = rho
        self.simulation_length = simulation_length
        self.class_num = settings.SIZE_CLASS_NUMBER
        self.weight = weight
        self.input = input
        # Data parameters
        self.output_direc = figure_direc + 'timeseries/'
        self.data_direc = settings.DATA_OUTPUT_DIREC + 'timeseries/FragmentationKaandorpPartial/'
        utils.check_direc_exist(self.output_direc)
        self.prefix = 'timeseries'
        self.beach_state_list = ['beach', 'adrift', 'total']
        # Figure parameters
        self.figure_size = (20, 14)
        self.figure_shape = (self.beach_state_list.__len__(), 1)
        self.ax_label_size = 16
        self.ax_ticklabel_size = 14
        self.legend_size = 14
        self.y_label = 'Mass'
        self.x_label = 'Time'
        self.xmin, self.xmax = datetime(settings.STARTYEAR, 1, 1), \
                               datetime(settings.STARTYEAR + self.simulation_length, 1, 1)
        self.ymin, self.ymax = 1e-3, 6500
        self.ax_range = self.xmax, self.xmin, self.ymax, self.ymin
        self.number_of_plots = self.beach_state_list.__len__()

    def plot(self):
        # Loading data
        timeseries_dict = {}
        for size_class in range(self.class_num):
            timeseries_dict[size_class] = {}
            data_dict = vUtils.FragmentationKaandorpPartial_load_data(scenario=self.scenario, prefix=self.prefix,
                                                                      data_direc=self.data_direc,
                                                                      shore_time=self.shore_time,
                                                                      lambda_frag=self.lambda_frag, rho=self.rho,
                                                                      postprocess=True, input=self.input)
            for beach_state in self.beach_state_list:
                timeseries_dict[size_class][beach_state] = data_dict[beach_state][size_class][self.weight]

        # creating a time axis
        time_list = []
        for time in data_dict['time']:
            time_list.append(datetime(settings.STARTYEAR, 1, 1, 12) + timedelta(seconds=time))

        # Creating figure
        ax = vUtils.base_figure(fig_size=self.figure_size, ax_range=self.ax_range, y_label=self.y_label,
                                x_label=self.x_label, ax_label_size=self.ax_label_size,
                                ax_ticklabel_size=self.ax_ticklabel_size, shape=self.figure_shape,
                                plot_num=self.number_of_plots, legend_axis=True, log_yscale=True, x_time_axis=True,
                                width_ratios=[1, 0.3], all_x_labels=True)

        # Setting the subfigure titles
        for ax_index in range(self.number_of_plots):
            ax[ax_index].set_title(subfigure_title(ax_index, self.beach_state_list[ax_index]),
                                   fontsize=self.ax_label_size)

        # Creating a legend
        size_colors = [plt.plot([], [], c=vUtils.discrete_color_from_cmap(sc, subdivisions=self.class_num),
                                label=size_label(sc), linestyle='-')[0] for sc in range(self.class_num)]
        ax[-1].legend(handles=size_colors, fontsize=self.legend_size, loc='upper right')

        # Plotting the various fractions
        for size_class in range(self.class_num):
            for beach_index, beach_state in enumerate(self.beach_state_list):
                color_size = vUtils.discrete_color_from_cmap(size_class, subdivisions=self.class_num)
                ax[beach_index].plot(time_list, timeseries_dict[size_class][beach_state], linestyle='-',
                                     c=color_size)

        # Saving the figure
        plt.savefig(file_name(self.input, self.output_direc, self.shore_time, self.lambda_frag), bbox_inches='tight')

def file_name(output_direc, shore_time, lambda_frag, input):
    str_format = input, shore_time, lambda_frag
    return output_direc + 'FragmentationKaandorpPartial_beach_state_timeseries-{}_ST={}_lamf={}.png'.format(*str_format)

def subfigure_title(index, beach_state):
    """
    setting the title of the subfigure
    :param index:
    :return:
    """
    alphabet = string.ascii_lowercase
    return '({}) {}'.format(alphabet[index], beach_state)

def size_label(size_class):
    particle_size = settings.INIT_SIZE * settings.P_FRAG ** size_class
    return 'Size class {}, d = {:.2f} mm'.format(size_class, particle_size * 1e3)


import os
from celery import Celery
from django.conf import settings

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookstore.settings')

# 实例化Celery
app = Celery('bookstore', broker='redis://127.0.0.1:6379/6')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
# 使用django的settings文件配置celery
app.config_from_object('django.conf:settings')

#Celery加载所有注册的应用
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))


from discord.ext import commands
from typing import List

import discord
import emoji as discord_emoji
from discord.ext import commands

import helper as _helper
from core import botbase
from core import helper
from . import config
from . import pollcontroller
from .models import poll

class PollCog(commands.Cog, name="Poll"):
    def __init__(self, bot: botbase.BotBase):
        self.bot: botbase.BotBase = bot
        self.logger = _helper.Logger().get_logger(self.__class__.__name__)

    @commands.command(name="poll", help="Poll with multiple options", description="Creates a customizable poll with an "
                                                                                "interactive menu. The user can "
                                                                                "choose his own emojis or use "
                                                                                "default (1-10).")
    async def create_simple_poll(self, ctx, channel: discord.TextChannel = None):
        """
        Creates a customizable poll with an interactive menu. The user can choose his own emojis or use default (1-10).

        :param ctx: Context
        :param channel: Channel to send the finished poll
        """

        req = "Insert your poll title"
        title = await helper.interactive_menu.request_string(self.bot, ctx.channel, ctx.author, req)

        req = "How many options should be in the poll"
        options = await helper.interactive_menu.request_int(self.bot, ctx.channel, ctx.author, req)

        req = "Do you want to assign special emoji for each role? (max 10 roles)"
        assign_emoji = await helper.interactive_menu.request_bool(self.bot, ctx.channel, ctx.author, req)

        p = []
        for i in range(options):
            if assign_emoji:
                req = f"Select an emoji for option number {i+1}"
                emoji = await helper.interactive_menu.request_emoji(self.bot, ctx.channel, ctx.author, req)
            else:
                # to many roles
                if i > 9:
                    return
                emoji = discord_emoji.emojize(f":keycap_{i+1}:")

            req = f"Input a description for option number {i+1}"
            option = await helper.interactive_menu.request_string(self.bot, ctx.channel, ctx.author, req)

            p.append((emoji, option))

        p = poll.Poll(None, None, title, p, 1)

        await pollcontroller.simple_poll(self.bot, ctx.guild, channel or ctx.channel, p)
        await ctx.message.delete()

    @commands.command(name="shortpoll", help="Poll with 2 options", description="Creates a simple poll with "
                                                                                "`thump up/down` reaction.")
    async def create_short_poll(self, ctx, channel: discord.TextChannel = None):
        """
        Creates a simple poll with `thump up/down` reaction.

        :param ctx: Context
        :param channel: Channel to send the finished poll
        """

        req = "Insert your poll title"
        title = await helper.interactive_menu.request_string(self.bot, ctx.channel, ctx.author, req)

        p = poll.Poll(None, None, title, [("👍",), ("👎",)], 1)

        await pollcontroller.title_poll(self.bot, ctx.guild, channel or ctx.channel, p)
        await ctx.message.delete()

    @commands.command(name="rp_create", help="Poll to assign roles", description="Creates a customizable role poll with"
                                                                                " an interactive menu. The user can "
                                                                                "choose his own emojis or use "
                                                                                "default (1-10).")
    async def create_poll(self, ctx, channel: discord.TextChannel = None):
        """
        Creates a customizable role poll with an interactive menu. The user can choose his own emojis or use
        default (1-10).

        :param ctx: Context
        :param channel: Channel to send the finished poll
        """

        role_controller = self.bot.get_role_controller(ctx.guild)
        extension_controller = self.bot.get_extension_config_handler(ctx.guild, config.EXTENSION_NAME)

        _poll: List[List[str, str, int]] = []

        req = "Insert the title of your poll"
        title = await helper.interactive_menu.request_string(self.bot, ctx.channel, ctx.author, req)

        req = "Insert all available roles"
        roles = await helper.interactive_menu.request_roles(self.bot, ctx.channel, ctx.author, req)

        req = "Do you want to assign special emoji for each role? (max 10 roles)"
        assign_emoji = await helper.interactive_menu.request_bool(self.bot, ctx.channel, ctx.author, req)

        for num, role in enumerate(roles):
            req = f"Insert the displayed name '{role.name}' (insert '-' for none)"
            displayed = await helper.interactive_menu.request_string(self.bot, ctx.channel, ctx.author, req)

            if assign_emoji:
                req = f"Insert the displayed emoji '{role.name}'"
                emoji = await helper.interactive_menu.request_emoji(self.bot, ctx.channel, ctx.author, req)
            else:
                # to many roles
                if num > 9:
                    return
                emoji = discord_emoji.emojize(f":keycap_{num+1}:")

            _poll.append([emoji, displayed, role.id])

        p = poll.Poll(message_id=0, channel_id=ctx.channel.id, title=title, poll=_poll)

        await pollcontroller.create_poll(self.bot, ctx.guild, channel or ctx.channel, p)
        await ctx.message.delete()

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload):
        emoji = str(payload.emoji)
        message_id = payload.message_id
        channel_id = payload.channel_id
        member = payload.member
        guild_id = payload.guild_id

        channel = await self.bot.fetch_channel(channel_id)
        message = await channel.fetch_message(message_id)
        guild = await self.bot.fetch_guild(guild_id)

        if message.content.startswith(pollcontroller.RP_PREFIX):
            self.logger.info(f"adding role to user {member.name} - user_id:{member.id}")
            await pollcontroller.add_reaction(self.bot, guild, channel, message_id, member, emoji)

    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, payload):
        emoji = str(payload.emoji)
        message_id = payload.message_id
        channel_id = payload.channel_id
        guild_id = payload.guild_id

        channel = await self.bot.fetch_channel(channel_id)
        message = await channel.fetch_message(message_id)
        guild = await self.bot.fetch_guild(guild_id)
        member: discord.Member = await guild.fetch_member(payload.user_id)

        if message.content.startswith(pollcontroller.RP_PREFIX):
            self.logger.info(f"removing role from user {member.name} - user_id:{member.id}")
            await pollcontroller.remove_reaction(self.bot, guild, channel, message_id, member, emoji)

async def setup(bot):
    await bot.add_cog(PollCog(bot))


import sys

from sfa.util.config import Config
from sfa.util.xrn import Xrn, get_authority, hrn_to_urn

from sfa.senslab.slabdriver import SlabDriver
from sfa.senslab.slabpostgres import SenslabXP, slab_dbsession

from sfa.trust.certificate import Keypair,convert_public_key
from sfa.trust.gid import create_uuid

from sfa.storage.alchemy import dbsession
from sfa.storage.model import RegRecord, RegAuthority, RegSlice, RegNode, \
                                                    RegUser, RegKey
from sfa.util.sfalogging import logger

from sqlalchemy.exc import SQLAlchemyError

def _get_site_hrn(site):
    hrn = site['name']
    return hrn

class SlabImporter:

    def __init__ (self, auth_hierarchy, loc_logger):
        self.auth_hierarchy = auth_hierarchy
        self.logger = loc_logger
        self.logger.setLevelDebug()

    def hostname_to_hrn_escaped(self, root_auth, hostname):
        return '.'.join( [root_auth,Xrn.escape(hostname)] )

    def slicename_to_hrn(self, person_hrn):
        return  (person_hrn +'_slice')

    def add_options (self, parser):
        # we don't have any options for now
        pass

    def find_record_by_type_hrn(self,type,hrn):
        return self.records_by_type_hrn.get ( (type, hrn), None)

    def locate_by_type_pointer (self, type, pointer):
        print>>sys.stderr, " \r\n \r\n \t SLABPOSTGRES locate_by_type_pointer  .........................."
        ret = self.records_by_type_pointer.get ( (type, pointer), None)
        print>>sys.stderr, " \r\n \r\n \t SLABPOSTGRES locate_by_type_pointer  "
        return ret

    def update_just_added_records_dict (self, record):
        tuple = (record.type, record.hrn)
        if tuple in self.records_by_type_hrn:
            self.logger.warning ("SlabImporter.update_just_added_records_dict: duplicate (%s,%s)"%tuple)
            return
        self.records_by_type_hrn [ tuple ] = record

    def run (self, options):
        config = Config()

        slabdriver = SlabDriver(config)

        #Create special slice table for senslab

        if not slabdriver.db.exists('slab_xp'):
            slabdriver.db.createtable()
            self.logger.info ("SlabImporter.run:  slab_xp table created ")

        #retrieve all existing SFA objects
        all_records = dbsession.query(RegRecord).all()

        #create hash by (type,hrn)
        #used  to know if a given record is already known to SFA

        self.records_by_type_hrn = \
            dict ( [ ( (record.type,record.hrn) , record ) for record in all_records ] )
        print>>sys.stderr,"\r\n SLABIMPORT \t all_records[0] %s all_records[0].email %s \r\n" %(all_records[0].type, all_records[0])
        self.users_rec_by_email = \
            dict ( [ (record.email, record) for record in all_records if record.type == 'user' ] )

        # create hash by (type,pointer)
        self.records_by_type_pointer = \
            dict ( [ ( (str(record.type),record.pointer) , record ) for record in all_records  if record.pointer != -1] )

        # initialize record.stale to True by default, then mark stale=False on the ones that are in use
        for record in all_records:
            record.stale=True

        nodes_listdict  = slabdriver.GetNodes()
        nodes_by_id = dict([(node['node_id'],node) for node in nodes_listdict])
        sites_listdict  = slabdriver.GetSites()

        ldap_person_listdict = slabdriver.GetPersons()
        print>>sys.stderr,"\r\n SLABIMPORT \t ldap_person_listdict %s \r\n" %(ldap_person_listdict)
        slices_listdict = slabdriver.GetSlices()
        try:
            slices_by_userid = dict ( [ (one_slice['reg_researchers']['record_id'], one_slice ) for one_slice in slices_listdict ] )
        except TypeError:
             self.logger.log_exc("SlabImporter: failed to create list of slices by user id.")
             pass

        for site in sites_listdict:
            site_hrn = _get_site_hrn(site)
            site_record = self.find_record_by_type_hrn ('authority', site_hrn)
            if not site_record:
                try:
                    urn = hrn_to_urn(site_hrn, 'authority')
                    if not self.auth_hierarchy.auth_exists(urn):
                        self.auth_hierarchy.create_auth(urn)
                    auth_info = self.auth_hierarchy.get_auth_info(urn)
                    site_record = RegAuthority(hrn=site_hrn, gid=auth_info.get_gid_object(),
                                               pointer='-1',
                                               authority=get_authority(site_hrn))
                    site_record.just_created()
                    dbsession.add(site_record)
                    dbsession.commit()
                    self.logger.info("SlabImporter: imported authority (site) : %s" % site_record)
                    self.update_just_added_records_dict(site_record)
                except SQLAlchemyError:
                    # if the site import fails then there is no point in trying to import the
                    # site's child records (node, slices, persons), so skip them.
                    self.logger.log_exc("SlabImporter: failed to import site. Skipping child records")
                    continue
            else:
                # xxx update the record ...
                pass
            site_record.stale=False

         # import node records in site
            for node_id in site['node_ids']:
                try:
                    node = nodes_by_id[node_id]
                except:
                    self.logger.warning ("SlabImporter: cannot find node_id %s - ignored"%node_id)
                    continue
                site_auth = get_authority(site_hrn)
                site_name = site['name']
                escaped_hrn =  self.hostname_to_hrn_escaped(slabdriver.root_auth, node['hostname'])
                print>>sys.stderr, "\r\n \r\n SLABIMPORTER node %s " %(node)
                hrn =  node['hrn']

                # xxx this sounds suspicious
                if len(hrn) > 64: hrn = hrn[:64]
                node_record = self.find_record_by_type_hrn( 'node', hrn )
                if not node_record:
                    try:
                        pkey = Keypair(create=True)
                        urn = hrn_to_urn(escaped_hrn, 'node')
                        node_gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey)
                        def slab_get_authority(hrn):
                            return hrn.split(".")[0]

                        node_record = RegNode (hrn=hrn, gid=node_gid,
                                                pointer = '-1',
                                                authority=slab_get_authority(hrn))
                        node_record.just_created()
                        dbsession.add(node_record)
                        dbsession.commit()
                        #self.logger.info("SlabImporter: imported node: %s" % node_record)
                        self.update_just_added_records_dict(node_record)
                    except:
                        self.logger.log_exc("SlabImporter: failed to import node")
                else:
                    # xxx update the record ...
                    pass
                node_record.stale=False

        # import persons
        for person in ldap_person_listdict :

            print>>sys.stderr,"SlabImporter: person: %s" %(person['hrn'])
            if 'ssh-rsa' not in person['pkey']:
                #people with invalid ssh key (ssh-dss, empty, bullshit keys...)
                #won't be imported
                continue
            person_hrn = person['hrn']
            slice_hrn = self.slicename_to_hrn(person['hrn'])

            # xxx suspicious again
            if len(person_hrn) > 64: person_hrn = person_hrn[:64]
            person_urn = hrn_to_urn(person_hrn, 'user')

            print>>sys.stderr," \r\n SlabImporter:  HEYYYYYYYYYY" , self.users_rec_by_email

            #Check if user using person['email'] form LDAP is already registered
            #in SFA. One email = one person. Inb this case, do not create another
            #record for this person
            #person_hrn  returned by GetPErson based on senslab root auth + uid ldap
            user_record = self.find_record_by_type_hrn('user', person_hrn)
            if not user_record and  person['email'] in self.users_rec_by_email:
                user_record = self.users_rec_by_email[person['email']]
                person_hrn = user_record.hrn
                person_urn = hrn_to_urn(person_hrn, 'user')

            slice_record = self.find_record_by_type_hrn ('slice', slice_hrn)

            # return a tuple pubkey (a plc key object) and pkey (a Keypair object)
            def init_person_key (person, slab_key):
                pubkey = None
                if  person['pkey']:
                    # randomly pick first key in set
                    pubkey = slab_key

                    try:
                        pkey = convert_public_key(pubkey)
                    except TypeError:
                        #key not good. create another pkey
                        self.logger.warn('SlabImporter: \
                                            unable to convert public \
                                            key for %s' % person_hrn)
                        pkey = Keypair(create=True)

                else:
                    # the user has no keys. Creating a random keypair for the user's gid
                    self.logger.warn("SlabImporter: person %s does not have a  public key"%person_hrn)
                    pkey = Keypair(create=True)
                return (pubkey, pkey)

            try:
                slab_key = person['pkey']
                # new person
                if not user_record:
                    (pubkey,pkey) = init_person_key (person, slab_key )
                    if pubkey is not None and pkey is not None :
                        person_gid = self.auth_hierarchy.create_gid(person_urn, create_uuid(), pkey)
                        if person['email']:
                            print>>sys.stderr, "\r\n \r\n SLAB IMPORTER PERSON EMAIL OK email %s " %(person['email'])
                            person_gid.set_email(person['email'])
                            user_record = RegUser (hrn=person_hrn, gid=person_gid,
                                                    pointer='-1',
                                                    authority=get_authority(person_hrn),
                                                    email=person['email'])
                        else:
                            user_record = RegUser (hrn=person_hrn, gid=person_gid,
                                                    pointer='-1',
                                                    authority=get_authority(person_hrn))

                        if pubkey:
                            user_record.reg_keys = [RegKey (pubkey)]
                        else:
                            self.logger.warning("No key found for user %s"%user_record)
                        user_record.just_created()
                        dbsession.add (user_record)
                        dbsession.commit()
                        self.logger.info("SlabImporter: imported person: %s" % user_record)
                        self.update_just_added_records_dict( user_record )
                else:
                    # update the record ?
                    # if user's primary key has changed then we need to update the
                    # users gid by forcing an update here
                    sfa_keys = user_record.reg_keys

                    new_key=False
                    if slab_key is not sfa_keys :
                        new_key = True
                    if new_key:
                        print>>sys.stderr,"SlabImporter: \t \t USER UPDATE person: %s" %(person['hrn'])
                        (pubkey,pkey) = init_person_key (person, slab_key)
                        person_gid = self.auth_hierarchy.create_gid(person_urn, create_uuid(), pkey)
                        if not pubkey:
                            user_record.reg_keys=[]
                        else:
                            user_record.reg_keys=[ RegKey (pubkey)]
                        self.logger.info("SlabImporter: updated person: %s" % user_record)

                    if person['email']:
                        user_record.email = person['email']

                dbsession.commit()

                user_record.stale = False
            except:
                self.logger.log_exc("SlabImporter: failed to import person  %s"%(person) )

            try:
                slice = slices_by_userid[user_record.record_id]
            except:
                self.logger.warning ("SlabImporter: cannot locate slices_by_userid[user_record.record_id] %s - ignored"%user_record)

            if not slice_record :
                try:
                    pkey = Keypair(create=True)
                    urn = hrn_to_urn(slice_hrn, 'slice')
                    slice_gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey)
                    slice_record = RegSlice (hrn=slice_hrn, gid=slice_gid,
                                                pointer='-1',
                                                authority=get_authority(slice_hrn))

                    slice_record.just_created()
                    dbsession.add(slice_record)
                    dbsession.commit()

                    #Serial id created after commit
                    #Get it
                    sl_rec = dbsession.query(RegSlice).filter(RegSlice.hrn.match(slice_hrn)).all()

                    #slab_slice = SenslabXP( slice_hrn = slice_hrn, record_id_slice=sl_rec[0].record_id, record_id_user= user_record.record_id)
                    #print>>sys.stderr, "\r\n \r\n SLAB IMPORTER SLICE IMPORT NOTslice_record %s \r\n slab_slice %s" %(sl_rec,slab_slice)
                    #slab_dbsession.add(slab_slice)
                    #slab_dbsession.commit()
                    #self.logger.info("SlabImporter: imported slice: %s" % slice_record)
                    self.update_just_added_records_dict ( slice_record )

                except:
                    self.logger.log_exc("SlabImporter: failed to import slice")

            #No slice update upon import in senslab
            else:
                # xxx update the record ...
                self.logger.warning ("Slice update not yet implemented")
                pass
            # record current users affiliated with the slice

            slice_record.reg_researchers =  [user_record]
            dbsession.commit()
            slice_record.stale=False

         ### remove stale records
        # special records must be preserved
        system_hrns = [slabdriver.hrn, slabdriver.root_auth,  slabdriver.hrn+ '.slicemanager']
        for record in all_records:
            if record.hrn in system_hrns:
                record.stale=False
            if record.peer_authority:
                record.stale=False

        for record in all_records:
            if record.type == 'user':
                print>>sys.stderr,"SlabImporter: stale records: hrn %s %s" %(record.hrn,record.stale)
            try:
                stale=record.stale
            except:
                stale=True
                self.logger.warning("stale not found with %s"%record)
            if stale:
                self.logger.info("SlabImporter: deleting stale record: %s" % record)
                #if record.type == 'user':
                    #rec = slab_dbsession.query(SenslabXP).filter_by(record_id_user = record.record_id).first()
                    #slab_dbsession.delete(rec)
                    #slab_dbsession.commit()
                dbsession.delete(record)
                dbsession.commit()


from uuid import uuid4
from fastapi import FastAPI, HTTPException
import os
import json
from pydantic import BaseModel
from typing import Optional, Literal
from fastapi.encoders import jsonable_encoder

app = FastAPI()

class Book(BaseModel):
	name: str
	price: float
	genre: Literal["fiction","non-fiction"]
	book_id: Optional[str] = uuid4().hex

BOOKS_FILE = "books.json"
BOOK_DATABASE = []

if os.path.exists(BOOKS_FILE):
	with open(BOOKS_FILE,"r") as f:
		BOOK_DATABASE = json.load(f)

@app.get("/")
def root():
    return {"Message": "Ikea World"}

@app.get("/list-books")
async def list_books():
	return {"books": BOOK_DATABASE}

@app.get("/book-by-index/{index}")
async def book_by_index(index: int):
	if index < 0 or index >= len(BOOK_DATABASE):
		raise HTTPException(404, f"Index {index} not working")
	else:
		return {"book": BOOK_DATABASE[index]}

@app.post("/add-book")
async def add_book(book: Book):
	book.book_id = uuid4().hex
	json_book = jsonable_encoder(book)
	BOOK_DATABASE.append(json_book)
	with open(BOOKS_FILE,"w") as f:
		json.dump(BOOK_DATABASE, f)
	return {"message": f"Book {book} added"}

@app.post("/new-name")
async def new_name():
	return "new name"

#this would be inventory of item or location
#location would have shelf, room, house, city
#house would have a model
#verbs to move things around
#goal - is to find the tool or the memory to move forward


import sys
from PySide2 import QtCore, QtWidgets, QtGui

from ui.window_design_new_task import Ui_NewTaskForm

class NewTask(QtWidgets.QWidget):
    send_new_task_data = QtCore.Signal(dict)

    def __init__(self, parent=None):
        super(NewTask, self).__init__(parent)
        self.ui = Ui_NewTaskForm()
        self.ui.setupUi(self)

        self.task_name = {'Сделать': 'WidgetDo',
                          'В процессе': 'WidgetDoing',
                          'Выполнено': 'WidgetDone'}

        self.ui.comboBoxCategory.addItems(self.task_name.keys())
        self.ui.comboBoxDoer.addItems(['Vasya', 'Petya', 'Vanya'])

        self.ui.pushButton.clicked.connect(self.send_data)

    def send_data(self):
        data = {'category': self.task_name[self.ui.comboBoxCategory.currentText()],
                'doer': self.ui.comboBoxDoer.currentText(),
                'task_name': self.ui.lineEditTaskName.text(),
                'description': self.ui.plainTextEditDescription.toPlainText(),
                'date_end': self.ui.dateEditEnd.date().toString()}
        self.send_new_task_data.emit(data)
        self.close()

if __name__ == '__main__':
    app = QtWidgets.QApplication()
    window = NewTask()
    window.show()
    sys.exit(app.exec_())


from lxml import etree

file_url = input('本地网页文档:')

fp = open(file_url, 'rb')
page_text = fp.read().decode('utf-8')
fp.close()

tree = etree.HTML(page_text)

imfor1 = tree.xpath('//div[@class="CyBottom"]//div[@class="fl"]/text()')
imfor2 = tree.xpath('//div[@class="CyBottom"]//div[@class="fl"]/p/text()')

with open('text.txt', 'w', encoding='utf-8') as fp:
    for text in imfor1+imfor2:
        fp.write(text + '\n')


from IPython.display import clear_output
import numpy as np
import matplotlib.pyplot as plt

class ExperimentLogger:
    def log(self, values):
        for k, v in values.items():
            if k not in self.__dict__:
                self.__dict__[k] = [v]
            else:
                self.__dict__[k] += [v]

def display_train_stats(cfl_stats, eps_1, eps_2, communication_rounds):
    clear_output(wait=True)

    plt.figure(figsize=(12,4))

    plt.subplot(1,2,1)
    acc_mean = np.mean(cfl_stats.acc_clients, axis=1)
    acc_std = np.std(cfl_stats.acc_clients, axis=1)
    plt.fill_between(cfl_stats.rounds, acc_mean-acc_std, acc_mean+acc_std, alpha=0.5, color="C0")
    plt.plot(cfl_stats.rounds, acc_mean, color="C0")

    if "split" in cfl_stats.__dict__:
        for s in cfl_stats.split:
            plt.axvline(x=s, linestyle="-", color="k", label=r"Split")

    plt.text(x=communication_rounds, y=1, ha="right", va="top",
             s="Clusters: {}".format([x.tolist() for x in cfl_stats.clusters[-1]]))

    plt.xlabel("Communication Rounds")
    plt.ylabel("Accuracy")

    plt.xlim(0, communication_rounds)
    plt.ylim(0,1)

    plt.subplot(1,2,2)

    plt.plot(cfl_stats.rounds, cfl_stats.mean_norm, color="C1", label=r"$\|\sum_i\Delta W_i \|$")
    plt.plot(cfl_stats.rounds, cfl_stats.max_norm, color="C2", label=r"$\max_i\|\Delta W_i \|$")

    plt.axhline(y=eps_1, linestyle="--", color="k", label=r"$\varepsilon_1$")
    plt.axhline(y=eps_2, linestyle=":", color="k", label=r"$\varepsilon_2$")

    if "split" in cfl_stats.__dict__:
        for s in cfl_stats.split:
            plt.axvline(x=s, linestyle="-", color="k", label=r"Split")

    plt.xlabel("Communication Rounds")
    plt.legend()

    plt.xlim(0, communication_rounds)
    #plt.ylim(0, 2)

    plt.show()


from hypothesis import given
from hypothesis import strategies as st

from .typeclass import Type
from haskpy.internal import class_function, abstract_class_function
from haskpy.testing import assert_output
from haskpy import testing

class Contravariant(Type):
    """Contravariant functor

    Minimal complete definition:

    - ``contramap`` method

    """

    def contramap(self, f):
        """f b -> (a -> b) -> f a"""
        raise NotImplementedError()

    def contrareplace(self, x):
        """f b -> b -> f a"""
        return self.contramap(lambda _: x)

    #
    # Sampling methods for property tests
    #

    @abstract_class_function
    def sample_contravariant_type_constructor(cls):
        pass

    #
    # Test typeclass laws
    #

    @class_function
    @assert_output
    def assert_contravariant_identity(cls, v):
        from haskpy.utils import identity
        return(
            v,
            v.contramap(identity),
        )

    @class_function
    @given(st.data())
    def test_contravariant_identity(cls, data):
        # Draw types
        a = data.draw(testing.sample_type())
        t = data.draw(cls.sample_contravariant_type_constructor())
        ta = t(a)

        # Draw values
        v = data.draw(ta)

        cls.assert_contravariant_identity(v, data=data)
        return

    @class_function
    @assert_output
    def assert_contravariant_composition(cls, v, f, g):
        return (
            v.contramap(f).contramap(g),
            v.contramap(lambda x: f(g(x))),
        )

    @class_function
    @given(st.data())
    def test_contravariant_composition(cls, data):
        # Draw types
        a = data.draw(testing.sample_type())
        b = data.draw(testing.sample_eq_type())
        c = data.draw(testing.sample_eq_type())
        t = data.draw(cls.sample_contravariant_type_constructor())
        ta = t(a)

        # Draw values
        v = data.draw(ta)
        f = data.draw(testing.sample_function(b))
        g = data.draw(testing.sample_function(c))

        cls.assert_contravariant_composition(v, f, g, data=data)
        return

    #
    # Test laws based on default implementations
    #

    @class_function
    @assert_output
    def assert_contravariant_contramap(cls, v, f):
        from haskpy import contramap
        return (
            v.contramap(f),
            contramap(f, v),
        )

    @class_function
    @given(st.data())
    def test_contravariant_contramap(cls, data):
        # Draw types
        a = data.draw(testing.sample_type())
        b = data.draw(testing.sample_eq_type())
        t = data.draw(cls.sample_contravariant_type_constructor())
        ta = t(a)

        # Draw values
        v = data.draw(ta)
        f = data.draw(testing.sample_function(b))

        cls.assert_contravariant_contramap(v, f, data=data)
        return

    @class_function
    @assert_output
    def assert_contravariant_contrareplace(cls, v, x):
        from haskpy import contrareplace
        return (
            Contravariant.contrareplace(v, x),
            contrareplace(x, v),
            v.contrareplace(x),
        )

    @class_function
    @given(st.data())
    def test_contravariant_contrareplace(cls, data):
        # Draw types
        a = data.draw(testing.sample_type())
        b = data.draw(testing.sample_eq_type())
        t = data.draw(cls.sample_contravariant_type_constructor())
        ta = t(a)

        # Draw values
        v = data.draw(ta)
        x = data.draw(b)

        cls.assert_contravariant_contrareplace(v, x, data=data)
        return

{'identity': 'haskpy.utils.identity', 'contramap': 'haskpy.contramap', 'contrareplace': 'haskpy.contrareplace'}.contrareplace


import numpy as np
import matplotlib.pyplot as plt
import cvxpy as cv
from mkdata import st_ops
from seven_cons import cons
from seven_adam import adam
from seven_adagrad import adagrad
from seven_rms import rms
from seven_adad import adad
from seven_nadam import nadam

x_1 = np.arange(-1.5, 3, 0.01)
x_2 = np.arange(-1.5, 3, 0.02)

X1, X2 = np.mgrid[-1.5:3:0.01, -1.5:3:0.02]
fValue = np.zeros((len(x_1), len(x_2)))

A = np.array([[250, 15],
              [ 15,  4]])
mu = np.array([[1],
               [2]])
lam = 0.89

for i in range(len(x_1)):
  for j in range(len(x_2)):
    inr = np.vstack([x_1[i], x_2[j]])
    fValue[i, j] = np.dot(np.dot((inr-mu).T, A), (inr- mu)) + lam * (np.abs(x_1[i]) + np.abs(x_2[j]))

# cvx
w_lasso = cv.Variable((2,1))
obj_fn = cv.quad_form(w_lasso - mu, A) +  lam * cv.norm(w_lasso, 1)
objective = cv.Minimize(obj_fn)
constraints = []
prob = cv.Problem(objective, constraints)
result = prob.solve(solver=cv.CVXOPT)
w_lasso = w_lasso.value

#plt.contour(X1, X2, fValue, 80)
cons = cons(A,mu,lam)
adam = adam(A,mu,lam)
adagrad = adagrad(A,mu,lam)
rms = rms(A,mu,lam)
adad = adad(A,mu,lam)
nadam = nadam(A,mu,lam)

minfvalue = np.dot(np.dot((w_lasso - mu).T, A), (w_lasso - mu)) + lam * np.sum(np.abs(w_lasso))
minOfMin = np.min([minfvalue,
                   np.min(adam[1]),
                   np.min(adagrad[1]),
                   np.min(rms[1]),
                   np.min(adad[1]),
                   np.min(nadam[1])])

#plt.semilogy(cons[1] - minOfMin, 'r-')
plt.semilogy(adam[1] - minOfMin, 'bs-', markersize=1, linewidth=0.5,label='adam',c='skyblue')
plt.semilogy(adagrad[1] - minOfMin, 'bs-', markersize=1, linewidth=0.5,label='adagrad',c='blue')
plt.semilogy(rms[1] - minOfMin, 'bs-', markersize=1, linewidth=0.5,label='rms',c='green')
plt.semilogy(adad[1] - minOfMin, 'bs-', markersize=1, linewidth=0.5,label='adad',c='brown')
plt.semilogy(nadam[1] - minOfMin, 'bs-', markersize=1, linewidth=0.5,label='nadam',c='black')
plt.yscale('log')
plt.legend()
plt.show()


#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#import sympy as sp

from math import copysign

minimal_difference = 0.003
from scipy import array as ar
m_d = minimal_difference
minimal_speed = 0.002; m_s = minimal_speed

def vector_value(v):
    return (v[0]**2+v[1]**2)**0.5

def compose_equation_line(segment): # ax+by+c=0
    global m_d
    if len(segment) == 4:
        l = segment
        if abs(l[2]-l[0])<=m_d:
            b=0; a=1; c=-l[0]
        elif abs(l[3]-l[1])<=m_d:
            a=0; b=1; c=-l[1]
        else:
            a=-(l[3]-l[1])/(l[2]-l[0])
            b=1
            c=0-a*l[2]-b*l[3]
        return [a,b,c]

    elif len(segment) == 2:
        l = segment
        if abs(l[1][0]-l[0][0])<=m_d:
            b=0; a=1; c=-l[0][0]
        elif abs(l[1][1]-l[0][1])<=m_d:
            a=0; b=1; c=-l[0][1]
        else:
            a=-(l[1][1]-l[0][1])/(l[1][0]-l[0][0])
            b=1
            c=0-a*l[1][0]-b*l[1][1]
        return [a,b,c]

def compose_normal_line(coefs,optcoords=None):
    if type(optcoords)!= type(None):
        ss = compose_normal_line(coefs)
        c=0-ss[0]*optcoords[0]-ss[1]*optcoords[1]
        return ar([ss[0],ss[1],c])

    else:
        if coefs[0]==0:
            return ar([1,0,0])
        if coefs[1]==0:
            return ar([0,1,0])
        else:
            if coefs[1]!=1:
                return compose_normal_line(ar(coefs)/coefs[1])

            a=-1/coefs[0]
            b=coefs[1]
            return ar([a,b,0])

def seq_to_line(points):
    xprev = -1; yprev=-1
    lines = list()
    for point in points:
        if xprev==-1:
            xprev=point[0]; yprev=point[1]
        else:
            line = [xprev,yprev,point[0],point[1]]
            xprev = point[0]; yprev = point[1]
            lines.append(line)
    return lines

def find_intersection(line1,line2):
    a1=line1[0];a2=line2[0];b1=line1[1];b2=line2[1]
    c1=line1[2];c2=line2[2]
    if abs(b1*b2)>m_d:
        x=(-c1/b1+c2/b2)/(a1/b1-a2/b2)
        y=(-c1-a1*x)/b1
    elif abs(b1)<m_d and abs(b2)>m_d:
        x = -c1/a1
        y = (-c2-a2*x)/b2
    elif abs(b2)<m_d and abs(b1)>m_d:
        x = -c2/a2
        y = (-c1-a1*x)/b1
    elif abs(b2)<m_d and abs(b1)<m_d:
        return []
    return[x,y]

def segments_have_intersection(seg1coords,seg2coords):
    s1 = seg1coords; s2 = seg2coords
    if (min(s1[0],s1[2])<max(s2[0],s2[2]) and max(s1[0],s1[2])>min(s2[0],s2[2])): #or (min(s2[0],s2[2])<max(s1[0],s1[2]) and max(s2[0],s2[2])>min(s1[0],s1[2])):
        if (min(s1[1],s1[3])<max(s2[1],s2[3]) and max(s1[1],s1[3])>min(s2[1],s2[3])):
            return True
    return False

def distance_point_point(point1,point2):
    return vector_value(point2-point1)

def resultant_speed(obj1,obj2):
    return [obj2.mass/obj1.mass*(-1)*obj1.vx, obj2.mass/obj1.mass * (-1)* obj1.vy]

def cos_vect(v1,v2):
    return (scal_mult(v1,v2)/vector_value(v1)/vector_value(v2))

def shortest_segment_point_segment(point,segment):
    if len(segment)>2:
        return shortest_segment_point_segment(point,divide_segment_into_points(segment))
    try:
        if len(point[0])>1:
            return shortest_segment_point_segment(segment,point)
    except:
        pass
    vect1 = segment[0] - point
    vect2 = segment[1] - point

    try:
        if cos_vect(vect1, segment[0]-segment[1]) <= 0:
            return ar([point,segment[0]])
        if cos_vect(vect2, segment[1]-segment[0]) <= 0:
            return ar([point,segment[1]])
    except:
        a = 9
    normal = compose_normal_line(compose_equation_line(segment),point)
    return ar([point,find_intersection(normal,compose_equation_line(segment))])

def scal_mult(v1,v2):
    return v1[0]*v2[0]+v2[1]*v1[1]

def distance_segment_point(segment,pointcoords):
    if len(pointcoords)>2:
        return distance_segment_point(pointcoords,segment)
    d = shortest_segment_point_segment(pointcoords,segment)
    return distance_point_point(d[0],d[1])

def projection_velocity_segment(v,segment):
    l = ar([segment[1][0]-segment[0][0],segment[1][1]-segment[0][1]])
    cos = cos_vect(v,l)
    return cos*vector_value(v)/vector_value(l)*l

    '''l = [segment[1][0]-segment[0][0],segment[1][1]-segment[0][1]]
    cos = vector_value(v)*vector_value(l)/(l[0]*v[1]+l[1]*v[0])
    endless_line = compose_equation_line(segment)
    a=endless_line[0]; b = endless_line[1]
    return ar([vector_value(v)*cos*b,vector_value(v)*a])'''

def distance_segment_segment(seg1coords,seg2coords):
    dpp = distance_point_point
    s1 = seg1coords; s2 = seg2coords
    if segments_have_intersection(s1,s2):
        return 0
    else:
        return min(dpp([s1[0],s[1]],[s2[0],s2[1]]), dpp([s1[0],s[1]],[s2[2],s2[3]]), dpp([s1[2],s[3]],[s2[0],s2[1]]), dpp([s1[2],s[3]],[s2[2],s2[3]]))

def line_to_segment(line):
    if line[1]>m_d:
        return [0,(-line[0]*0-line[2])/line[1],1000,(-line[0]*1000-line[2])/line[1]]
    else:
        return [-line[2]/line[0],0,-line[2]/line[0],1000]

def vector_x_direction(v):
    if v[0]<0:
        return -1
    elif v[0]>0:
        return 1
    else:
        return 0

def sign_of(x):
    if x>0:
        return 1
    elif x<0:
        return -1
    else:
        return 0

def get_unary_vector(line,direction=1):
    l = line
    if l[0]==0:
        return ar([0,1])*direction
    if l[1]==0:
        return ar([1,0])*direction
    else:
        k = l[1]/l[0]
        x = (1/(1+1/k**2))**0.5
        return ar([x, -x/k]) * sign_of(x) * direction

def divide_segment_into_points(segment):
    if len(segment)==4:
        return ar([ar([segment[0],segment[1]]), ar( [ segment[2], segment[3] ]) ])
    else:
        return segment

def get_rebound_vector(v,segment,direction=1):
    return vector_value(v) * get_unary_vector(compose_normal_line(compose_equation_line(segment))) * direction

def edge_rebound_velocity(v,segment):
    if len(segment) > 2:
        return edge_rebound_velocity(v,divide_segment_into_points(segment))

    if segment[0][0]==segment[1][0]:
        return ar([-v[0],v[1]])
    if segment[0][1]==segment[1][1]:
        return ar([v[0],-v[1]])

    projv = projection_velocity_segment(v,segment)

    return 2*projv - v

    '''global m_d
    l = [segment[2]-segment[0],segment[3]-segment[1]]
    if abs(l[0])<m_d:
        return ar([-v[0],v[1]])
    if abs(l[1])<m_d:
        return ar([v[0],-v[1]])
    proj = projection_velocity_segment(v,segment)
    to_reflect = [v[0]-proj[0],v[1]-proj[1]]
    return ar([v[0]-to_reflect[0],v[1]-to_reflect[1]])'''

def ball_ball_rebound_velocity(ball1,ball2):
    center_line = ar([ball1.coords,ball2.coords])
    vprojection = projection_velocity_segment(ball2.v,center_line)
    m1 = ball1.mass; m2 = ball2.mass; v1 = ball1.v; v2 = vprojection#ball2.v
    return ((m1-m2)*v1 + 2*m2*v2)/(m1+m2)

def distance_between_objects(obj1,obj2):
    if obj1.type == 'ball' == obj2.type:
        return distance_point_point(obj1.coords,obj2.coords)-obj1.r-obj2.r
    elif obj1.type == 'ball' and obj2.type == 'edge':
        return distance_segment_point(obj2.coords,obj1.coords)-obj1.r
    elif obj2.type == 'skeleton' and obj1.type == 'ball':
        dist = list()
        for edge in obj2:
            dist.append(distance_segment_point(obj1.coords,edge.coords)-obj1.r)
        return min(dist)
    elif obj1.type == 'skeleton' and obj2.type == 'edge':
        distances = list()
        for edge in obj1:
            distances.append(distance_between_objects(edge,obj2))
        return min(distances)
    elif obj1.type == 'skeleton' == obj2.type:
        distances = list()
        for edge in obj1:
            distances.append(distance_between_objects(edge,obj2))
        return min(distances)
    elif obj1.type==obj2.type=="edge":
        return distance_segment_segment(obj1.coords,obj2.coords)
    else:
        return distance_between_objects(obj2,obj1)

def anomalistic(obj1,obj2,distance_between_objects_given=-1):
    if distance_between_objects_given>-1:
        return distance_between_objects_given<=-m_d
    return (distance_between_objects(obj1,obj2)<=-m_d)

def move_along_velocity(obj,distance):
    if vector_value(obj.v) > m_s:
        mult = distance/vector_value(obj.v)
        obj.move(mult*obj.v)
    else:
        obj.move(ar([0,distance]))

def get_away_direction(ball1,ball2):
    central_segment = ar( [ ball1.coords, ball2.coords ] )

    if ball1.coords[0]<ball2.coords[0]:
        direction = -1
    elif ball1.coords[0]>ball2.coords[0]:
        direction = 1
    elif ball1.coords[1]<ball2.coords[1]:
        direction = -1
    else:
        direction = 1

    return get_unary_vector(compose_equation_line(central_segment), direction)

def get_ball_edge_away_direction(ball,edge):
    ss = shortest_segment_point_segment(ball.coords,edge.coords)

def operate_anomaly(obj1,obj2,distance_between_objects_given=-1):
    if distance_between_objects_given != -1:
        dbo = distance_between_objects_given
    else:
        dbo = distance_between_objects(obj1,obj2)

    if obj1.type=='ball'==obj2.type:
        obj1_away_direction = get_away_direction(obj1,obj2)
        obj1.move(dbo*(-1)*obj1_away_direction)
        obj2.move(dbo*obj1_away_direction)
    elif obj1.type=='ball' and obj2.type=='edge':
        ss = shortest_segment_point_segment(obj2.coords, obj1.coords)
        obj1.move((ss[1]-ss[0])*dbo*0.05)
        #obj1.v *= 0.995
    else:
        operate_anomaly(obj2,obj1,distance_between_objects_given)

def obj_close(obj1,obj2,crit=10*m_d):
    pass

def invert_sincos(sincos):
    return (1-sincos**2)**0.5

def main():
    line = [200,180,160,140]
    print(compose_equation_line(line))
##    point = [180,140]
##    print(distance_line_point(line,point))
##    line = [-1/3,1,-1]
##    print(compose_normal_line(line,point))

if __name__ == '__main__':
    main()


from fastapi import APIRouter, Depends, HTTPException, status

from app.lib.auth.prisma import JWTBearer, decodeJWT
from app.lib.prisma import prisma

router = APIRouter()

@router.get("/users/me")
async def read_user_me(token=Depends(JWTBearer())):
    decoded = decodeJWT(token)

    if "userId" in decoded:
        userId = decoded["userId"]
        user = prisma.user.find_unique(where={"id": userId}, include={"profile": True})

        return {"success": True, "data": user}

    raise HTTPException(
        status_code=status.HTTP_404_NOT_FOUND,
        detail=f"User with id {userId} not found",
    )

@router.get("/users/{userId}")
async def read_user(userId: str):
    user = prisma.user.find_unique(where={"id": userId}, include={"profile": True})

    if user:
        return {"success": True, "data": user}

    raise HTTPException(
        status_code=status.HTTP_404_NOT_FOUND,
        detail=f"User with id {userId} not found",
    )


from django.shortcuts import render, redirect
from .models import Stream, Student

def home(request):
    return render(request, 'home.html')

def stream_list(request):
    streams = Stream.objects.all()
    return render(request, 'streams.html', {'streams': streams})

def stream_detail(request, pk):
    stream = Stream.objects.get(pk=pk)
    students = Student.objects.filter(stream=stream)
    return render(request, 'stream_detail.html', {'stream': stream, 'students': students})

def student_list(request):
    students = Student.objects.all()
    return render(request, 'students.html', {'students': students})

def student_detail(request, pk):
    student = Student.objects.get(pk=pk)
    return render(request, 'student_detail.html', {'student': student})

def student_create(request):
    if request.method == 'POST':
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        admission_number = request.POST['admission_number']
        stream_pk = request.POST['stream']
        stream = Stream.objects.get(pk=stream_pk)
        student = Student(first_name=first_name, last_name=last_name, admission_number= admission_number,stream=stream)
        student.save()
        return redirect('student_list')
    streams = Stream.objects.all()
    return render(request, 'student_create.html', {'streams': streams})

def student_update(request, pk):
    student = Student.objects.get(pk=pk)
    if request.method == 'POST':
        student.first_name = request.POST['first_name']
        student.last_name = request.POST['last_name']
        student.admission_number = request.POST['admission_number']
        stream_pk = request.POST['stream']
        stream = Stream.objects.get(pk=stream_pk)
        student.stream = stream
        student.save()
        return redirect('student_list')
    streams = Stream.objects.all()
    return render(request, 'student_update.html', {'student': student, 'streams': streams})

def student_delete(request, pk):
    student = Student.objects.get(pk=pk)
    student.delete()
    return redirect('student_list')

def create_stream(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        Stream.objects.create(name=name)
        return redirect('list_streams')
    return render(request, 'create_stream.html')

def delete_stream(request, stream_id):
    Stream.objects.get(id=stream_id).delete()
    return redirect('list_streams')


from turtle import Screen
from paddle import Paddle
from ball import Ball
from scoreboard import Scoreboard

screen = Screen()
screen.title("PPArcade")
screen.setup(width=800, height=600)
screen.bgcolor("black")
screen.tracer(0)

paddle = Paddle(x_pos=360)
computer_paddle = Paddle(x_pos=-360)
ball = Ball()
scoreboard = Scoreboard()

screen.listen()
screen.onkey(key="w", fun=paddle.up)
screen.onkey(key="s", fun=paddle.down)
screen.onkey(key="e", fun=computer_paddle.up)
screen.onkey(key="d", fun=computer_paddle.down)

game_is_on = True
while game_is_on:
    screen.update()
    ball.moving()

    if ball.ycor() >= 290 or ball.ycor() <= -290:
        ball.touched_vertical_wall()
    if (350 <= ball.xcor() < 360) and ball.distance(paddle) < 50:
        ball.touched_paddle()
    elif (-350 >= ball.xcor() > -360) and ball.distance(computer_paddle) < 50:
        ball.touched_paddle()
    if ball.xcor() >= 400:
        ball.reset()
        scoreboard.computer_won()
    elif ball.xcor() <= -400:
        ball.reset()
        scoreboard.player_won()
screen.exitonclick()


from module.processing import *
# from module.firebaseupload import *
import pickle, os
import configparser
from tqdm import tqdm

def clear():
    if os.name in ('nt', 'dos'):
        os.system('cls')
    else:
        os.system('clear')

def main():
    clear()
    conf = configparser.ConfigParser()
    conf.read('version.ini', encoding='utf-8')
    version = conf['DEFAULT']['version']
    print(f'''
    화학테러 논문조 더미 및 계측기 데이터 가공 프로그램 ({version})

    - 이 프로그램을 통해 CSV파일을 엑셀파일로 가공하게 됩니다.

    중요!!!: 폴더 안에 가공된 파일이 이미 있다면 덮어씌워집니다.
    주의!! : 동시에 실험했던 같은 종류의 데이터만 한 폴더에 넣으세요.
    참고   : 엑셀 내 차트 디자인은 프로그램에서 적용할 수 없습니다. 엑셀에서 직접 서식파일을 선택하세요.''')

    # try:
    #     rtdb = Database()
    #     print('\n\n[정보] 인터넷 연결 성공')
    # except:
    #     rtdb = None
    #     print('\n\n[경고] 인터넷 연결 실패 - 가공된 데이터가 인터넷에 업로드되지 않습니다.')

    # DIALOG

    while True:
        time = TimeInfo()
        errCount = 0

        # 실험 차수 수집
        # try:
        #     with open('order.pkl', 'rb') as f:
        #         order = pickle.load(f)
        # except:
        #     order = None

        # if order != None:
        #     try:
        #         print('[ 실험 차수 확인 ]\n')
        #         print(f'이전에 데이터를 가공했던 실험의 차수가 [{order}차] 입니다.')
        #         print(f'이번에 가공할 데이터의 차수는 [{order+1}차]가 맞습니까?')
        #         print('\n맞으면 엔터를, 아니라면 실험 차수를 숫자로 입력해주세요.')
        #         order = int(input('> '))
        #         try:
        #             with open('order.pkl', 'wb') as f:
        #                 pickle.dump(order, f)
        #         except:
        #             pass
        #     except:
        #         order += 1
        #         try:
        #             with open('order.pkl', 'wb') as f:
        #                 pickle.dump(order, f)
        #         except:
        #             pass
        # else:
        #     while True:
        #         try:
        #             print('실험이 "몇차" 실험인지 "차수"를 "숫자"로 입력해주세요.')
        #             order = int(input('> '))
        #             try:
        #                 with open('order.pkl', 'wb') as f:
        #                     pickle.dump(order, f)
        #             except:
        #                 pass
        #             break
        #         except:
        #             print('[오류] 숫자를 입력하셔야 합니다.')

        print('\n\n\n[ 데이터 종류 설정 ]\n')
        print('가공할 데이터 종류를 선택해주세요.')
        print('1. 이산화탄소 계측기')
        print('2. 헬륨 계측기')
        print('3. 산소 계측기')
        print('4. 더미')
        while True:
            n = input('번호를 입력해주세요 > ')
            sel = {'1':'CO2', '2':'He', '3':'O2', '4':'dummy'}
            if n in sel:
                file_type = sel[n]
                break
            print('잘못 입력하셨습니다.')

        print("\n\n\n[ 폴더 경로 설정 ]\n")
        print("처리해야되는 폴더의 경로를 입력해주세요.")
        while True:
            try:
                lists = filter_csv_from_dir(input("> "), file_type=file_type)
                break
            except FileNotFoundError:
                print('[오류] 해당 경로가 존재하지 않습니다. 다시 시도하세요.\n')
            except NotADirectoryError:
                print('[오류] 해당 경로는 폴더가 아닙니다. 다시 시도하세요.\n')

        print("\n\n\n[ 실험 시작시간 설정 ]\n")
        while True:
            try:
                print("실험 시작시간을 직접 입력해주세요 ( 예시[14시 8분] -> 14:8 )")
                _time = input("> ")
                _time = list(map(int, _time.split(':')))
                time.set_time(_time, only_time=True)
                break
            except:
                print('\n잘못 입력하신 것 같습니다.')

        # print("\n\n\n[ 안정화 시간 설정 ]\n")
        # while True:
        #     try:
        #         print('실험 시작 후 반응시간을 계산하기 위해서 안정화 시간을 입력해야합니다.')
        #         print('실험 안정화 시간을 초로 입력해주세요.')
        #         __stabililze_period = int(input('>' ))
        #         time.set_stab_period(__stabililze_period)
        #         break
        #     except:
        #         print('\n잘못 입력하셨습니다.')
        # 임시로 0초 설정
        time.set_stab_period(0)

        try:
            print('\n\n\n[ 실험 지속시간(진행시간) 설정 ]\n')
            print(f'기본 설정되어있는 실험 지속시간(진행시간)은 [{time.get_duration()}초] 입니다.')
            print('\n맞으면 엔터를, 아니라면 지속시간(단위:초)을 숫자로 입력해주세요.')
            du = int(input('> '))
            time.set_duration(du)
        except:
            pass

        # PROCESS

        clear()
        print(f'이제 실험 데이터 가공을 시작하겠습니다. 아래의 내용을 확인해주세요.\n')
        # print(f'> {order}차 실험 데이터')
        print(f'> 데이터 종류: {file_type}')
        print(f'> 실험 시작시간: {time.timedatalist[0]}시 {time.timedatalist[1]}분')
        print(f'> 실험 지속시간: {time.get_duration()}초')
        input("\n>> 진행하려면 엔터키를 눌러주세요.\n\n")

        for i, e in enumerate(lists):
            try:
                bar = tqdm(total = 100, desc=f'[{i+1}/{len(lists)}] {e.name}', bar_format='{desc:30.28}{percentage:3.0f}%|{bar:30}|', smoothing=1)

                df = preprocess_to_df(e, time)
                bar.update(20)

                # 그래프 분석을 위한 데이터 생성
                if e.type == 'CO2': #TODO: 계측기 데이터 늘어나면 맞게 수정한다.
                    calculated_dict = calculate_df(df, time.get_stab_period())
                else:
                    calculated_dict = None

                wb = dataframe_to_excel(df)
                bar.update(10)

                wb = formular_process(wb, e.type)
                bar.update(10)

                # if e.type != "dummy" and rtdb != None: # dummy 데이터 외(dummy는 total로만) 백업하기
                #     dataDict = firebase_process(wb, e, e.type)
                #     bar.update(10)

                #     rtdb.upload_dummy(time, order, dataDict, e.type)
                #     bar.update(20)
                # else:
                #     bar.update(30)
                bar.update(30)

                wb = expression_process(wb, e)
                bar.update(10)

                if calculated_dict != None:
                    wb = insert_calculated_values(wb, calculated_dict)

                chart_process(wb, e)
                bar.update(10)

                wb.save(f"{e.dirPath}/{e.name[:-4]} 정리.xlsx")
                bar.update(10)
                bar.close()

            except Exception as err:
                bar.close()
                errCount += 1
                print('\r[오류] ', end='')
                print(err)
                print('[오류] ' + e.name + "의 파일 변환 중 오류가 발생하여 가공하지 않고 넘어갑니다.\n")

        # FINISH

        print(f'\n총 {len(lists)}개의 파일 중에서 {len(lists)-errCount}개의 파일 가공에 성공하였습니다.')
        print("새로운 폴더에서 가공을 시작하시려면 'Y'를, 종료하시려면 'N'을 입력해주세요.")
        while True:
            isLoop = input('> ')
            if isLoop == "Y" or isLoop == "y" or isLoop == "N" or isLoop == "n":
                break
            print("\n새로운 폴더에서 가공을 시작하시려면 'Y'를, 종료하시려면 'N'을 입력해주세요.")

        if isLoop == 'N' or isLoop == "n":
            break

if __name__ == '__main__':
    main()


import dataset
import requests
from lxml import html
import time
import sqlalchemy

INFO = {
    'en': {
        'url': 'https://cambodiadaily.com',
        'db': 'sqlite:///archive_en.db'
    },
    'kh': {
        'url': 'https://cambodiadailykhmer.com',
        'db': 'sqlite:///archive_kh.db'
    }
}

def scrape_page(url, table, language):
    page = requests.get(url)
    tree = html.fromstring(page.content)
    article_urls = tree.xpath('//*[contains(concat( " ", @class, " " ), concat( " ", "entry-title", " " ))]//a/@href')
    for url in article_urls:
        url = url.strip()
        try:
            table.insert(dict(url=url))
        except sqlalchemy.exc.IntegrityError:
            pass
    if language == 'kh':
        paginated_url = tree.xpath('//*[contains(concat( " ", @class, " " ), concat( " ", "alignright", " " ))]//a/@href')
    else:
        paginated_url = tree.xpath('//*[contains(concat( " ", @class, " " ), concat( " ", "pagination-next", " " ))]//a/@href')
    time.sleep(5)
    return paginated_url

def scrape_site(url, table, language):
    homepage = requests.get(url)
    tree = html.fromstring(homepage.content)
    date_urls = [url for url in tree.xpath('//*[@id="archivesdropfront"]/select/option/@value') if url]
    for url in date_urls:
        table.insert(dict(url=url))
        page = 1
        print('scraping: {}'.format(url))
        paginated_url = scrape_page(url, table, language)
        print('...page {}'.format(page))
        while paginated_url:
            table.insert(dict(url=paginated_url))
            page += 1
            url = paginated_url[0]
            print('...page {}'.format(page))
            paginated_url = scrape_page(url, table, language)

def run(language):
    print('beginning scrape of {} site'.format(language))
    db = dataset.connect(INFO[language]['db'])
    table = db.get_table('url', primary_id='url', primary_type='String')
    scrape_site(INFO[language]['url'], table, language)

if __name__ == '__main__':
    run('en')
    run('kh')


from requests import Session
from json import loads

class Room:
    URL = "https://mafia.gg/api/rooms"

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

    def list_rooms(self):
        with Session() as s:
            self.json = loads(s.get(self.URL, cookies=self.payload).content)
        rooms = self.json['rooms']
        num = len(rooms)
        lobbies = []
        if num > 0:
            lobbies = [r['name'] for r in rooms]
        return num, lobbies


from setuptools import find_packages, setup

__plugin_name__ = 'AddTorrentCheck'
__author__ = 'idiocrazy'
__author_email__ = 'yourname@example.com'
__version__ = '0.3'
__url__ = ''
__license__ = 'GPLv3'
__description__ = ''
__long_description__ = """Automatically forces re-announces on newly added torrent where tracker does not report 'Announce OK' for 5 min."""
__pkg_data__ = {'deluge_'+__plugin_name__.lower(): ['data/*']}

setup(
    name=__plugin_name__,
    version=__version__,
    description=__description__,
    author=__author__,
    author_email=__author_email__,
    url=__url__,
    license=__license__,
    long_description=__long_description__,

    packages=find_packages(),
    package_data=__pkg_data__,

    entry_points="""
    [deluge.plugin.core]
    %s = deluge_%s:CorePlugin
    [deluge.plugin.gtk3ui]
    %s = deluge_%s:Gtk3UIPlugin
    [deluge.plugin.web]
    %s = deluge_%s:WebUIPlugin
    """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
)