from dateutil import tz
import datetime
import pytz

import re

pattern = r'^\b(.{4})[:-](.{2})[:-](.{2})\s+(.{2}):(.{2}):(.{2})(Z|([+-])(.{2}):(.{2}))?.*\b$'

class Text2Time:
    def __init__(self, text):
        match = re.search(pattern, text)
        if match:
            groups = match.groups()

            year = int(groups[0].strip())
            month = int(groups[1].strip())
            day = int(groups[2].strip())
            hour = int(groups[3].strip())
            minute = int(groups[4].strip())
            second = int(groups[5].strip())
            if groups[6]:
                if groups[6].strip() == 'Z':
                    timezone_value = 0
                else:
                    timezone_sign = -1 if (groups[7].strip() == '-') else 1
                    timezone_hours = int(groups[8].strip())
                    timezone_minutes = int(groups[9].strip())
                    timezone_value = timezone_sign * (timezone_hours * 60 + timezone_minutes)
            else:
                timezone_value = None
            self.dateTime = Text2Time.create_custom_datetime(
                year, month, day, hour, minute, second, timezone_value)

    @classmethod
    def create_custom_datetime(cls, year, month, day, hour, minute, second, timezone_value=None):
        if timezone_value is None:
            tz_info = tz.tzlocal()
        elif timezone_value == 'Z':
            tz_info = pytz.utc
        else:
            tz_info = tz.tzoffset(None, timezone_value * 60)

        try:
            dt = datetime.datetime(year, month, day, hour, minute, second, tzinfo=tz_info)
            return dt.astimezone(tz.tzlocal())
        except ValueError as e:
            # print(f"Error creating datetime: {e}")
            return None

if __name__ == '__main__':
    time_values = [
        "2014:05:06 14:55:08+05:30",
        "2014:05:06 14:55:08Z",
        "2014:05:06 14:55:08",
        "2014:05:06 14:55: 8",
        "2014:05:06 14: 5: 8"
    ]

    for value in time_values:
        print(f"{value} ==> {Text2Time(value).dateTime}")


import requests
import json
from random import sample, randint
from datetime import datetime, timedelta
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(name)s: %(message)s')

if __name__ == "__main__":

    logins = ['alex', 'john', 'mike', 'nadya', 'sasha', 'peter', 'fox', 'cat', 'dog']
    domains = ['@mail.ru', '@yahoo.com', '@hotmail.com', '@yandex.ru', '@gmail.com', '@ya.ru', '@list.ru']
    fnames = ['Nadya', 'Anya', 'Julia', 'Sasha', 'Alex', 'Alexey', 'Dan', 'Andy', 'Ira', 'Nomi', 'Elka']
    lnames = ['Marchewka', 'Polenka', 'Kozalko', 'Sarowsky', 'Ishkov']

    url = 'http://127.0.0.1:8000/api/users/'

    emails = list()
    names = list()

    for login in logins:
        for domain in domains:
            emails.append(login + domain)

    for fname in fnames:
        for lname in lnames:
            names.append(" ".join([fname, lname]))

    for email in emails:
        row = dict()
        row['name'] = sample(names, 1)[0]
        row['email'] = email
        row['is_guest'] = sample([0,1], 1)[0]
        if row['is_guest'] == 1:
            row['registration_date'] = datetime(1970,1,1,0,0,0)
        else:
            row['registration_date'] = datetime.now()
        row['join_date'] = datetime.now()

        r = requests.post(url, data=row)
        logging.info("{0} - {1}".format(str(r.status_code), str(r.reason)))

    logging.info("Generated {0} users".format(len(emails)))


from typing import List

class Solution:

    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        '''合并两个有序数组

        @Note:
            类似归并排序，从后往前
        '''
        i, j, k = m - 1, n - 1, m + n - 1
        if n == 0:
            return
        while True:
            if nums1[i] > nums2[j]:
                nums1[k] = nums1[i]
                k -= 1
                i -= 1
            else:
                nums1[k] = nums2[j]
                j -= 1
                k -= 1
            if i == -1 or j == -1:
                break
        if i == -1:
            nums1[:j + 1] = nums2[:j + 1]  #注意左闭右开

if __name__ == '__main__':
    nums1 = [1, 0]  #[int(x) for x  in input().strip().split(' ')]
    m = 1  #int(input().strip())
    nums2 = [2]  #[int(x) for x  in input().strip().split(' ')]
    n = 1  #int(input().strip())
    solution = Solution()
    solution.merge(nums1, m, nums2, n)
    print(nums1)


#!/usr/bin/env python
# encoding: utf-8
"""
@author: Mingjun Lei
@file: test_wework.py
@time: 2021/2/26 16:07
@desc: This py file is to test different login scenarios without PO
"""
import json
from time import sleep
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

class TestWeWork:

    def setup(self):
        chrome_arg = webdriver.ChromeOptions()
        chrome_arg.debugger_address = '127.0.0.1:9222'
        # self.driver = webdriver.Chrome(options=chrome_arg)
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(6)

    def teardown(self):
        self.driver.quit()

    # @pytest.mark.skip
    def test_register(self):
        """
        Sign in from homepage of WechatWork
        """
        self.driver.get("https://work.weixin.qq.com/")  # original website
        self.driver.find_element(By.XPATH, "//*[@class='index_top_operation_loginBtn']").click()  # click on login
        self.driver.find_element(By.XPATH, "//*[@class='login_registerBar_link']").click()  # Company registration
        self.driver.find_element(By.XPATH, "//*[@id='corp_name']").send_keys("test")  # company name
        sleep(2)

    # @pytest.mark.skip
    def test_login_with_debugger(self):
        """
        Reusing chrome browser by port
        """
        self.driver.get("https://work.weixin.qq.com/wework_admin/frame")  # website with login user
        self.driver.find_element(By.XPATH, "//*[@id='menu_contacts']").click()  # change to contact tab
        self.driver.find_element(By.XPATH, "//*[@id='menu_apps']").click()  # change to app management tab
        self.driver.find_element(By.XPATH, "//*[@id='menu_customer']").click()
        self.driver.find_element(By.XPATH, "//*[@id='menu_manageTools']").click()
        self.driver.find_element(By.XPATH, "//*[@id='menu_profile']").click()

    # @pytest.mark.skip
    def test_login_with_cookies(self):
        """
        Access to website with cookies
        """
        # store cookie, login status first with debugger
        # cookies = self.driver.get_cookies()
        # print(cookies)
        # with open("temp.txt", "w", encoding="utf-8") as f:
        #     json.dump(cookies, f)

        # read cookie, could use general chromedriver
        self.driver.get("https://work.weixin.qq.com/wework_admin/frame#index")
        with open("temp.txt", "r", encoding="utf-8") as f:
            cookies = json.load(f)
        print(cookies)
        for cookie in cookies:
            self.driver.add_cookie(cookie)
        self.driver.refresh()
        sleep(2)


#!/usr/bin/python3

import os, sys
import time
from numpy.random import random

import re
import csv
import json
import requests
from bs4 import BeautifulSoup as bs

#####
#       UTILS
#####

def parse_url( url:str ):
    '''
    Dado un url devuelve objeto parseado de BeautifulSoup
    '''
    n_attempts=5
    for _ in range(n_attempts):
        try:
            response = requests.get( url )

            if response.status_code != 200:
                print('***Error en request. Status code',response.status_code, url)
                continue

            return bs( response.content, features="lxml" )

        except:
            print('***Error en conexión a', url)

    return None

def get_links(url_search:str) -> list:
    '''
    Devuelve lista con todos los links a publicaciones de alquileres, dada una
    url de búsqueda con el formato que especifica numero de página
    '''
    urls = []

    soup = parse_url( url_search )
    if not soup:
        return []

    tags = soup.find_all( name='a',
                          attrs={'class':'ui-search-result__content ui-search-link'} )

    urls += [ t['href'] for t in tags ]

#    print(f'Se extrajeron {len(urls)} links')
    return urls

def get_data(urls:list) -> list:
    '''
    Devuelve lista de diccionarion con datos del precio, superficie, ubicación...
    Dada una lista de links con publicaciones de inmuebles de mercadolibre,
    '''
    data_list = []
    URL_API = 'https://api.mercadolibre.com/items/'
    PATTERN = "MLA-\d+"

    for i,url in enumerate(urls):
        d_data = {}

        pub_id = re.findall( re.compile( PATTERN ), url )[0]
        pub_id = pub_id.replace('-','')
        try:
            response = requests.get( URL_API + pub_id )
        except:
            print('***Conexión a API malió sal, reintentando...')
            return None

        if response.status_code != 200:
            print('***Request malio sal', response.status_code, url)
        pub_json = response.json()

        to_extract = {'sp_tot':     'attributes.Superficie total',
                      'sp_cub':     'attributes.Superficie cubierta',
                      'nu_ambs':    'attributes.Ambientes',
                      'nu_dorms':   'attributes.Dormitorios',
                      'pr_exp':     'attributes.Expensas',
                      'pr_valor':   'price',
                      'pr_moneda':  'currency_id',
                      'fe_pub':     'start_time',
                      'ub_calle':   'location.address_line'}

        for key, value in to_extract.items():

            d_data[key] = None          #Inicializo

            try:
                if value.startswith('attributes'):
                    attrs_list = pub_json['attributes']
                    attr = value.split('.')[1]
                    for d in attrs_list:
                         if d['name'] == attr:
                            d_data[key] = d['value_name']

                elif value.startswith('location'):
                    d_data[key] = pub_json[value.split('.')[0]][value.split('.')[1]]

                else:
                    d_data[key] = pub_json[value]

            except Exception as e:
                print('***No se encontró valor de: ', value, i, url)

### find lat, lon
        response = requests.get(url)
        try:
            pattern = re.compile( '"location":\{(.*?)\}' )
            locations = re.findall( pattern, str(response.content))

            locations = json.loads( '{'+locations[0]+'}' )

            d_data['ub_lat'] = locations['latitude']
            d_data['ub_lon'] = locations['longitude']
        except:
            d_data['ub_lat'] = None
            d_data['ub_lon'] = None
            print('***No se encontró lat/lon: ',i, url)

        d_data['url'] = re.split( '(.*MLA-\d*)', url)[1] # para no guardar el url entero que contiene una descripcion de la publicacion

        data_list.append(d_data)

#        print(i, d_data)

        time.sleep(random())
    return data_list

def save_data(dicts:list, filepath) -> None:

    dirpath = filepath[:filepath.rfind('/')]
    filename = filepath[filepath.rfind('/')+1:]

    existing_file = filename in os.listdir(dirpath)
    if existing_file:
        mode='a'
    else:
        mode='x'
        print(f'No se encontró {filepath}, se creará a continuación.')

    with open(filepath, mode) as f:
        writer = csv.DictWriter(f, fieldnames=dicts[0].keys())

        if os.path.getsize(filepath)==0:
            writer.writeheader()

        for i, d in enumerate(dicts):
            writer.writerow( d )

#####
#       MAIN
#####
def scrap(url, filename, ni=0, nf=1000):

    for n in range(ni,nf):
        print(f'\tPágina {n}')
        url_page = url + str(n*48)

        print(f'\t\tSacando links')
        links = get_links(url_page)

        if len(links)==0:
            print('Se alcanzó la última página.')
            break

        print(f'\t\tSacando data')
        data = get_data(links)  #TARDA 6' POR PÁGINA!!!

        print(f'\t\tGuardando data')
        save_data( data, filename )

if __name__=='__main__':

    TODAY = time.strftime( "%Y-%m-%d", time.localtime() )
    DIRECTORY = sys.argv[1]

    URL_SEARCH_PHS  = 'https://inmuebles.mercadolibre.com.ar/ph/alquiler/capital-federal/_Desde_'
    URL_SEARCH_CASAS = 'https://inmuebles.mercadolibre.com.ar/casas/alquiler/capital-federal/_Desde_'
    URL_SEARCH_DEPTOS = 'https://inmuebles.mercadolibre.com.ar/departamentos/alquiler/capital-federal/_Desde_'

    search = {'phs': URL_SEARCH_PHS,
              'casas': URL_SEARCH_CASAS,
              'deptos': URL_SEARCH_DEPTOS }

    for tipo, url in search.items():
        filepath = DIRECTORY + '_'.join([TODAY,tipo,'meli.csv'])
        print(f'Escrapeando {tipo}.\tLos datos se guardarán en {filepath}')
        scrap(url, filepath)

    print('Todo OK :D')


import argparse
import tempfile
from pathlib import Path

DEFAULT_DIR = Path(tempfile.gettempdir()) / "ya-drone-swarm"
DEFAULT_PROVIDERS = 2

DEFAULT_CPU_QUOTA = 1024
DEFAULT_CPU_SHARES = 0.5  # core percentage
DEFAULT_MEM = 512  # MB

def arg_parser():
    parser = argparse.ArgumentParser(prog="ya-drone-swarm")
    parser.add_argument(
        "-d",
        "--dir",
        type=str,
        default=DEFAULT_DIR,
        help="override working directory",
    )

    subparsers = parser.add_subparsers(dest="cmd", help="command to run")
    parser_up = subparsers.add_parser("up", help="bring up containers")
    parser_env = subparsers.add_parser("env", help="start environment shell")
    subparsers.add_parser("ps", help="show processes")

    _args_up(parser_up)
    _args_env(parser_env)

    return parser

def _args_up(parser):
    def providers(value):
        count = int(value)
        if count <= 0:
            raise ValueError("Number of providers must be greater than 0")
        return count

    def caps(value):
        if value.lower() == "none":
            return 0, 0
        values = value.split(",")
        if len(values) != 2:
            raise ValueError(f"Invalid caps: {value}, expected 'cpu,mem'")
        return float(values[0]), int(values[1])

    default_caps = f"none"

    parser.add_argument(
        "-s",
        "--subnet",
        default="drones",
        type=str,
        help="subnet to use",
    )
    parser.add_argument(
        "-b",
        "--binary",
        default=[],
        action="append",
        nargs=2,
        metavar=("name", "path"),
        help="override binary path",
    )
    parser.add_argument(
        "-p",
        "--providers",
        default=DEFAULT_PROVIDERS,
        type=providers,
        help="number of providers",
    )
    parser.add_argument(
        "--cap-net",
        default=default_caps,
        type=caps,
        help="net resource cap [cpu_percent,mem_MB]",
    )
    parser.add_argument(
        "--cap-req",
        default=default_caps,
        type=caps,
        help="requestor resource cap [cpu_percent,mem_MB]",
    )
    parser.add_argument(
        "--cap-prov",
        default=default_caps,
        type=caps,
        help="provider resource cap [cpu_percent,mem_MB]",
    )
    parser.add_argument(
        "-c", "--central-net", action="store_true", help="use central network"
    )

def _args_env(parser):
    parser.add_argument(
        "-n",
        "--no-init",
        action="store_true",
        help="do not run requestor setup",
    )