"""script d'installation"""
from pathlib import Path
from setuptools import setup, find_packages

DESCRIPTION = "Outil de vote en ligne au lycée Immaculée Conception de Pau"
APP_ROOT = Path(__file__).parent
README = (APP_ROOT / "README.md").read_text()
AUTHOR = "Mainguy Côme, Labrouche Ilona, Hourdebaight Yan, Lescoulié Maël, Degos Arnaud"
PROJECT_URLS = {
    "Documentation": "https://...",
    "Source Code": "https://....",
}
INSTALL_REQUIRES = [
    "Flask",
    "Flask-Migrate",
    "Flask-SQLAlchemy",
    "Flask-Mail",
    "python-dateutil",
    "python-dotenv",
    "requests",
    "urllib3",
    "werkzeug",
    "GitPython"
]
EXTRAS_REQUIRE = {
    "dev": [
        "black",
        "flake8",
        "pydocstyle",
        "pytest",
        "pytest-black",
        "pytest-clarity",
        "pytest-dotenv",
        "pytest-flake8",
        "pytest-flask",
        "pre-commit",
    ]
}

setup(
    name="vote",
    description=DESCRIPTION,
    long_description=README,
    long_description_content_type="text/markdown",
    version="0.1",
    author=AUTHOR,
    maintainer=AUTHOR,
    license="GPL",
    url="https://...",
    project_urls=PROJECT_URLS,
    packages=find_packages(where="src"),
    package_dir={"": "src"},
    python_requires=">=3.6",
    install_requires=INSTALL_REQUIRES,
    extras_require=EXTRAS_REQUIRE,
)


class Solution:
    def divisorSubstrings(self, num: int, k: int) -> int:
        strnum = str(num)
        n = len(strnum)
        ctr = 0
        for i in range(n - k + 1):
            curr = int(strnum[i:i+k])
            if curr != 0 and num % curr == 0:
                ctr += 1
        return ctr


import datetime
import enum
import ipaddress
from typing import List, Optional

from sqlalchemy import Column, ForeignKey, Integer, Unicode, UniqueConstraint
from sqlalchemy.orm import backref, relationship
from sqlalchemy_utils import IPAddressType

import cnaas_nms.db.base
import cnaas_nms.db.device
import cnaas_nms.db.site
from cnaas_nms.devicehandler.sync_history import add_sync_event

class Linknet(cnaas_nms.db.base.Base):
    __tablename__ = "linknet"
    __table_args__ = (
        None,
        UniqueConstraint("device_a_id", "device_a_port"),
        UniqueConstraint("device_b_id", "device_b_port"),
    )
    id = Column(Integer, autoincrement=True, primary_key=True)
    ipv4_network = Column(Unicode(18))
    device_a_id = Column(Integer, ForeignKey("device.id"))
    device_a = relationship(
        "Device", foreign_keys=[device_a_id], backref=backref("linknets_a", cascade="all, delete-orphan")
    )
    device_a_ip = Column(IPAddressType)
    device_a_port = Column(Unicode(64))
    device_b_id = Column(Integer, ForeignKey("device.id"))
    device_b = relationship(
        "Device", foreign_keys=[device_b_id], backref=backref("linknets_b", cascade="all, delete-orphan")
    )
    device_b_ip = Column(IPAddressType)
    device_b_port = Column(Unicode(64))
    site_id = Column(Integer, ForeignKey("site.id"))
    site = relationship("Site")
    description = Column(Unicode(255))

    def as_dict(self):
        """Return JSON serializable dict."""
        d = {}
        for col in self.__table__.columns:
            value = getattr(self, col.name)
            if issubclass(value.__class__, enum.Enum):
                value = value.value
            elif issubclass(value.__class__, cnaas_nms.db.base.Base):
                continue
            elif issubclass(value.__class__, ipaddress.IPv4Address):
                value = str(value)
            elif issubclass(value.__class__, datetime.datetime):
                value = str(value)
            d[col.name] = value
        return d

    def get_port(self, device_id):
        if device_id == self.device_a_id:
            return self.device_a_port
        if device_id == self.device_b_id:
            return self.device_b_port
        raise ValueError(f"The device_id {device_id} is not part of this linknet")

    def get_ip(self, device_id):
        if device_id == self.device_a_id:
            return self.device_a_ip
        if device_id == self.device_b_id:
            return self.device_b_ip
        raise ValueError(f"The device_id {device_id} is not part of this linknet")

    def get_ipif(self, device_id):
        if device_id == self.device_a_id:
            return f"{self.device_a_ip}/{ipaddress.IPv4Network(self.ipv4_network).prefixlen}"
        if device_id == self.device_b_id:
            return f"{self.device_b_ip}/{ipaddress.IPv4Network(self.ipv4_network).prefixlen}"
        raise ValueError(f"The device_id {device_id} is not part of this linknet")

    @staticmethod
    def deduplicate_linknet_dicts(linknets: List[dict]) -> List[dict]:
        """Take a list of dicts as returned from Device.get_linknets_as_dict
        and return a list of dicts without any duplicate entries based on
        hostname+port combinations."""
        populated_links = []
        ret = []
        for linknet in linknets:
            linknet_str_a = ":".join(
                [
                    linknet["device_a_hostname"],
                    linknet["device_a_port"],
                    linknet["device_b_hostname"],
                    linknet["device_b_port"],
                ]
            )
            linknet_str_b = ":".join(
                [
                    linknet["device_b_hostname"],
                    linknet["device_b_port"],
                    linknet["device_a_hostname"],
                    linknet["device_a_port"],
                ]
            )
            if linknet_str_a in populated_links or linknet_str_b in populated_links:
                continue
            populated_links.append(linknet_str_a)
            populated_links.append(linknet_str_b)
            ret.append(linknet)
        return ret

    @classmethod
    def create_linknet(
        cls,
        session,
        hostname_a: str,
        interface_a: str,
        hostname_b: str,
        interface_b: str,
        ipv4_network: Optional[ipaddress.IPv4Network] = None,
        strict_check: bool = True,
    ):
        """Add a linknet between two devices. If ipv4_network is specified both
        devices must be of type CORE or DIST."""
        dev_a: cnaas_nms.db.device.Device = (
            session.query(cnaas_nms.db.device.Device)
            .filter(cnaas_nms.db.device.Device.hostname == hostname_a)
            .one_or_none()
        )
        if not dev_a:
            raise ValueError(f"Hostname {hostname_a} not found in database")
        if (
            strict_check
            and ipv4_network
            and dev_a.device_type not in [cnaas_nms.db.device.DeviceType.DIST, cnaas_nms.db.device.DeviceType.CORE]
        ):
            raise ValueError(
                "Linknets can only be added between two core/dist devices "
                + "(hostname_a is {})".format(str(dev_a.device_type))
            )
        dev_b: cnaas_nms.db.device.Device = (
            session.query(cnaas_nms.db.device.Device)
            .filter(cnaas_nms.db.device.Device.hostname == hostname_b)
            .one_or_none()
        )
        if not dev_b:
            raise ValueError(f"Hostname {hostname_b} not found in database")
        if (
            strict_check
            and ipv4_network
            and dev_b.device_type not in [cnaas_nms.db.device.DeviceType.DIST, cnaas_nms.db.device.DeviceType.CORE]
        ):
            raise ValueError(
                "Linknets can only be added between two core/dist devices "
                + "(hostname_b is {})".format(str(dev_b.device_type))
            )

        new_linknet: Linknet = Linknet()
        new_linknet.device_a = dev_a
        new_linknet.device_a_port = interface_a
        new_linknet.device_b = dev_b
        new_linknet.device_b_port = interface_b
        if ipv4_network:
            if not isinstance(ipv4_network, ipaddress.IPv4Network) or ipv4_network.prefixlen != 31:
                raise ValueError("Linknet must be an IPv4Network with prefix length of 31")
            ip_a, ip_b = ipv4_network.hosts()
            new_linknet.device_a_ip = ip_a
            new_linknet.device_b_ip = ip_b
            new_linknet.ipv4_network = str(ipv4_network)
        if strict_check:
            dev_a.synchronized = False
            add_sync_event(dev_a.hostname, "linknet_created")
            dev_b.synchronized = False
            add_sync_event(dev_b.hostname, "linknet_created")
        return new_linknet


import sys
import argparse

def createParser ():
    parser = argparse.ArgumentParser()
    parser.add_argument('name', type = int)

    return parser

if __name__ == '__main__':
    parser = createParser()
    namespace = parser.parse_args()
    print(namespace.name)
    n = int(namespace.name)
    a = 0
    b = 1
    for __ in range(n):
        a, b = b, a + b
    print( a )


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

from django.db import migrations, models

def create_anyone_group(apps, schema_editor):
    # We can't import the Person model directly as it may be a newer
    # version than this migration expects. We use the historical version.
    FollowerGroup = apps.get_model("let_me_auth", "FollowerGroup")
    anyone_group, _ = FollowerGroup.objects.get_or_create(
        name="anyone", verbose_name="anyone")
    Event = apps.get_model("let_me_app", "Event")
    for event in Event.objects.all():
        anyone_group.targets.add(event)
    anyone_group.save()

class Migration(migrations.Migration):

    dependencies = [
        ('let_me_app', '0018_galleryvideo'),
        ('let_me_auth', '0008_followergroup'),
    ]

    operations = [
        migrations.AddField(
            model_name='followergroup',
            name='targets',
            field=models.ManyToManyField(to='let_me_app.Followable', related_name='target_groups'),
        ),
        migrations.AddField(
            model_name='followergroup',
            name='verbose_name',
            field=models.CharField(verbose_name='verbose name', default='admin group', max_length=80),
            preserve_default=False,
        ),
        migrations.AlterField(
            model_name='followergroup',
            name='followable',
            field=models.ForeignKey(null=True, related_name='group_owners', to='let_me_app.Followable'),
        ),
        migrations.RunPython(create_anyone_group),
    ]


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

import scipy.stats as sps

# This script plots the main figure for the jargon analysis (fig 5a). Also calculates the Pearson correlation and confidence intervals.

easywords=pd.read_json('./jargon/lang_generalsciencejargon.json')
easywords.reset_index()

datavg = easywords.groupby(easywords.year).mean()
datavg['year']=datavg.index

fig,ax = plt.subplots(1,1)
ax.scatter(datavg.year, datavg.classic2949, color='k')
ax.scatter(datavg.year, datavg.generalScienceJargon, data=datavg, color='r')
ax.grid(True)
ax.set_xlim([1880,2020])

fig.savefig('./jargon/easywords_pruned.pdf')

fig,ax = plt.subplots(1,1)
ax.scatter(datavg.year, datavg.classic2949, color='k')
ax.scatter(datavg.year, datavg.science2949, data=datavg, color='g')
ax.grid(True)
ax.set_xlim([1880,2020])

fig.savefig('./jargon/easywords_2949.pdf')

fig,ax = plt.subplots(1,1)
ax.scatter(datavg.year, datavg.classic2949, color='k')
ax.scatter(datavg.year, datavg.generalScienceJargon, data=datavg, color='r')
ax.scatter(datavg.year, datavg.science2949, data=datavg, color='g')
ax.grid(True)
ax.set_xlim([1880,2020])
fig.savefig('./jargon/easywords_combined.pdf')
fig.savefig('./figures/fig6a.pdf')
fig.savefig('./figures/fig6a.png')

rc=sps.pearsonr(datavg.year,datavg.classic2949)
rj=sps.pearsonr(datavg.year,datavg.generalScienceJargon)
rs=sps.pearsonr(datavg.year,datavg.science2949)

# Print confidence intervals
n=len(datavg.year)
def CI(r,n):
    z = np.arctanh(r)
    standard_error = 1/np.sqrt(n-3)
    ci = z + np.array([-1,1]) * standard_error * sps.norm.pdf((1+0.95)/2)
    return np.tanh(ci)

print(CI(rc[0],n))
print(CI(rs[0],n))
print(CI(rj[0],n))


import io
import os
import platform
import time
import pyautogui
# Windows 10 functions
import pyperclip
import keyboard
from PIL import ImageGrab
import win32clipboard
import win32con
import subprocess
# macOS functions
def escape_applescript_string(s):
    return s.replace('"', '\\"').replace("'", "\\'")

def run_applescript(script):
    escaped_script = escape_applescript_string(script)
    os.system(f"osascript -e '{escaped_script}'")

def set_clipboard_macos(text):
    text = escape_applescript_string(text)
    run_applescript(f'set the clipboard to "{text}"')

def set_image_to_clipboard_macos(image):
    buffer = io.BytesIO()
    image.save(buffer, format='PNG')
    img_data = buffer.getvalue()
    buffer.close()
    run_applescript(f'set the clipboard to (read (POSIX file "/dev/stdin") as JPEG picture) as «class PNGf»' + '«data PNGf' + img_data.hex() + '»')

def activate_wechat_and_send_message_macos(message=None, screenshot=None):
    if message:
        message = escape_applescript_string(message)
        set_clipboard_macos(message)
    elif screenshot:
        set_image_to_clipboard_macos(screenshot)

    run_applescript('activate application "WeChat"')
    run_applescript('delay 1')
    run_applescript('tell application "System Events" to keystroke "v" using command down')
    run_applescript('tell application "System Events" to keystroke return')

# Windows 10 functions
def escape_windows_string(s):
    return s.replace('"', '\\"').replace("'", "\\'")

def set_clipboard_windows(text):
    text = escape_windows_string(text)
    pyperclip.copy(text)

def paste_and_send_message_windows():
    keyboard.press('ctrl')
    keyboard.press('v')
    keyboard.release('v')
    keyboard.release('ctrl')
    keyboard.press('enter')
    keyboard.release('enter')

# def activate_wechat_and_send_message_windows(message):
#     message = escape_windows_string(message)
#     set_clipboard_windows(message)

#     # You might need to adjust the sleep duration and hotkey to switch to WeChat
#     # time.sleep(1)
#     # keyboard.press('alt')
#     # keyboard.press('tab')
#     # keyboard.release('tab')
#     # keyboard.release('alt')

#     time.sleep(1)
#     paste_and_send_message_windows()

def set_image_to_clipboard_windows(image):
    output = io.BytesIO()
    image.convert("RGB").save(output, "BMP")
    data = output.getvalue()[14:]
    output.close()

    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(win32con.CF_DIB, data)
    win32clipboard.CloseClipboard()

def activate_wechat_and_send_message_windows(message=None, screenshot=None):
    if message:
        message = escape_windows_string(message)
        set_clipboard_windows(message)
    elif screenshot:
        set_image_to_clipboard_windows(screenshot)

    # Activate WeChat
    # wechat_window_title = "WeChat"  # Replace with the actual WeChat window title
    # pyautogui.getWindowsWithTitle(wechat_window_title)[0].activate()
    # You might need to adjust the sleep duration and hotkey to switch to WeChat
    time.sleep(1)

    # 路径需要替换成你实际的AutoHotkey.exe所在路径
    autohotkey_path = "C:\\Program Files\\AutoHotkey\\AutoHotkey.exe"
    script_path = "activate_wechat.ahk"

    subprocess.run([autohotkey_path, script_path])

    time.sleep(1)
    paste_and_send_message_windows()

def activate_wechat_and_send_message(message=None, screenshot=None):
    current_os = platform.system()

    if current_os == "Darwin":  # macOS
        activate_wechat_and_send_message_macos(message, screenshot)
    elif current_os == "Windows":
        activate_wechat_and_send_message_windows(message, screenshot)
    else:
        print("Unsupported operating system.")


import time
from selenium.webdriver.support.wait import WebDriverWait

def test_status_create(driver, login_as):
    status_input = driver.find_element_by_name("status")

    test_text = "Something"
    expected_text = test_text
    time.sleep(2)
    status_input.send_keys(test_text)

    send_button = driver.find_element_by_name("save")
    send_button.click()

    time.sleep(5)

    text_element = driver.find_elements_by_class_name("ow_newsfeed_content")
    print(text_element[0].text)

    assert text_element[0].text == expected_text


from tkinter import *

class CenteredWindow(Tk):

    def center_window(self):
        self.update()
        wn_width = self.winfo_width()
        wn_height = self.winfo_height()
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()

        x = int((screen_width / 2) - (wn_width / 2))
        y = int((screen_height / 2) - (wn_height / 2))

        self.geometry(f"{wn_width}x{wn_height}+{x}+{y}")