# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/03-notificator.ipynb (unless otherwise specified).

__all__ = ['TelegramNotificator', 'send', 'Driver', 'get_driver', 'TimewebNotificator', 'authorize',
           'check_expiration_date', 'check_servers', 'run']

# Cell

import telebot

import fastcore.basics as fcb
from .core import logger

from selenium.webdriver.chrome.service import Service
from random import choice
from bs4 import BeautifulSoup

from selenium import webdriver
from selenium.webdriver.common.by import By

from bs4 import BeautifulSoup
from time import sleep

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

# Cell

class TelegramNotificator:
    def __init__(self, token='6190703828:AAFksjz6MrtXDkQpTdiy7-A4zig0wT_g1Uo', chat_id='662822665'):

        # create attribute bot:
        self.bot = telebot.TeleBot(token)

        # create attribute chat_id:
        self.chat_id = chat_id

        logger.info(f"SUCCESS: started bot")

# Cell

@fcb.patch_to(TelegramNotificator)
def send(self, text):

    """
    METHOD TO SEND A TEXT MESSAGE.
    """
    bot = self.bot
    bot.send_message(self.chat_id, text)
    logger.info(f"SUCCESS: sent message")

# Cell

class Driver:
    def __init__(self, executable_path='/usr/local/bin/chromedriver', headless=True):

        # create executable_path:
        s = Service(executable_path=executable_path)

        # create options for the driver:
        options = webdriver.ChromeOptions()

        if headless:
            options.add_argument('--headless')

        options.add_argument("--disable-extensions")
        options.add_argument("--disable-notifications")
        options.add_argument("--disable-gpu")
        options.add_argument("--no-sandbox")
        options.add_argument("--disable-dev-shm-usage")


        options.add_argument('--disable-infobars')

        options.add_argument('--disable-default-apps')
        options.add_argument('--disable-translate')
        options.add_argument('--disable-crash-reporter')
        options.add_argument('--disk-cache-size=0')
        options.add_argument('--disable-cache')

        # new:
        options.add_argument("--disable-backgrounding-occluded-windows")
        options.add_argument("--disable-renderer-backgrounding")
        options.add_argument("--disable-background-timer-throttling")
        options.add_argument("--disable-application-cache")
        options.add_argument("--v8-cache-options=off")
        options.add_argument("--disable-offline-load-stale-cache")
        options.add_argument("--disable-back-forward-cache")

        # use random user-agent string:
        user_agent_strings = ['Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36',
                              'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36',
                              'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36',
                              'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15',
                              'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
                              'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
                              'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
                              'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36',
                              'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36']

        random_user_agent = choice(user_agent_strings)
        options.add_argument(f"--user-agent={random_user_agent}")

        # start driver:
        self.driver = webdriver.Chrome(options=options, service=s)

        logger.info(f"SUCCESS: Chrome driver was created")

# Cell

@fcb.patch_to(Driver)
def get_driver(self):

    """
    METHOD TO CREATE DRIVER.
    Return: selenium.webdriver
    """
    return self.driver

# Cell

class TimewebNotificator:
    def __init__(self, login, password, executable_path='/usr/local/bin/chromedriver', headless=True):

        # get attributes login and password:
        self.login = login
        self.password = password

        # get attribute driver:
        self.driver = Driver(headless=headless, executable_path=executable_path).get_driver()

# Cell

@fcb.patch_to(TimewebNotificator)
def authorize(self):

    """
    METHOD TO AUTHORIZE AT TIMEWEB.COM.
    """

    driver = self.driver
    login_url = 'https://hosting.timeweb.ru/login'
    driver.get(login_url)

    # wait the page to upload for up to 60 secs:
    WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, '//*[@id="login-page"]/div/div[1]/div/div/section/form/div[1]/input')))

    # input login and password:
    login_locator = driver.find_element(By.XPATH, '//*[@id="login-page"]/div/div[1]/div/div/section/form/div[1]/input')
    password_locator = driver.find_element(By.XPATH, '//*[@id="login-page"]/div/div[1]/div/div/section/form/div[2]/input')
    login_locator.send_keys(self.login)
    password_locator.send_keys(self.password)

    # click submit button:
    submit_button = driver.find_element(By.XPATH, '//*[@id="login-page"]/div/div[1]/div/div/section/form/div[4]/button')
    submit_button.click()
    sleep(0.1)

    # exit banner:
    try:
        WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[3]/div/div[2]/button')))
        exit_button_locator = driver.find_element(By.XPATH, '/html/body/div[3]/div/div[2]/button')
        exit_button_locator.click()
        logger.info(f"SUCCESS: exited banner")
    except:
        pass
    finally:
        # wait the main page to upload for up to 60 secs:
        WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div/main/div[3]/div/div[1]/div[2]/a')))
        logger.info(f"SUCCESS: entered main page")

# Cell

@fcb.patch_to(TimewebNotificator)
def check_expiration_date(self):

    """
    METHOD TO GET THE DATE WHEN BALANCE WILL BE EXPIRED AT TIMEWEB.COM.
    """

    # get driver:
    driver = self.driver

    # go to page 'Баланс и платежи' for up to 60 secs:
    driver.get('https://timeweb.cloud/my/finances/payment')
    WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div/main/div[3]/div/div[1]/div[2]/span')))
    logger.info(f"SUCCESS: entered page «БАЛАНС И ПЛАТЕЖИ»")

    # get Beautifulsoup object:
    pageSource = driver.page_source
    bs = BeautifulSoup(pageSource, 'html.parser')

    # get days till expiration of balance:
    days = bs.find('span', {'class':'text_m--NH5_i text_bold--vHjQC text_grey--XwvUo text_align_left--Lozmh'}).get_text().split(' ')[2]
    days = int(days)

    # get current balance:
    balance = bs.find('h1', {'class':'page__title--TN3UA h1--WqT1f'}).get_text().replace('\xa0', '').split(' ')[1]
    balance = int(balance)

    # payment amount:
    payment = (balance / days) * 31

    # notify:
    TelegramNotificator().send(f'Current balance at timeweb.com: {balance} rub.')
    TelegramNotificator().send(f'Expires in: {days} days')

    if days <= 10:
        TelegramNotificator().send(f'NOTIFICATION! Replenish balance by {payment:.0f} rub. Card 0953')

# Cell

@fcb.patch_to(TimewebNotificator)
def check_servers(self):

    """
    METHOD TO CHECK SERVERS' DISK UTILIZATION AT TIMEWEB.COM.
    """

    logger.info(f"SUCCESS: started checking servers at timeweb.com")

    # get driver:
    driver = self.driver

    # go to page with servers list:
    servers_url = 'https://timeweb.cloud/my/servers'
    driver.get(servers_url)

    # wait for up to 60 secs the page with server list to upload:
    WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div/main/div[3]/div/div[1]/div[1]/h1')))
    logger.info(f"SUCCESS: entered page «ОБЛАЧНЫЕ СЕРВЕРЫ»")

    # get BeautifulSoup object:
    pageSource = driver.page_source
    bs = BeautifulSoup(pageSource, 'html.parser')

    # get server pages' URLs:
    server_urls = []
    for server_block in bs.findAll('a', {'class':'serverRow--Jq0NO row--kH1Hw row_body--Or9xB link--FmBtP tw-link link_primary--Mg8Wz link_s--GwZb4'}):
        server_url = f'https://timeweb.cloud{server_block["href"]}'
        server_urls.append(server_url)

    # visit each server's page and get disk utiliation:
    for server_url in server_urls:

        driver.get(server_url)

        # wait for up to 60 secs the server's page to upload:
        WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div/main/div[3]/div/div[2]/div[2]/a')))
        logger.info(f"SUCCESS: entered page {server_url}")

        # get BeautifulSoup object:
        pageSource = driver.page_source
        bs = BeautifulSoup(pageSource, 'html.parser')

        # get server's name and disk utilization:
        name = bs.find('a', {'class':'page__title--TN3UA h1--WqT1f'}).get_text()
        disk_utilization = bs.find('p', {'class':'chartValue--EH_cO text_s--Lpx31 text_dark--dYeD2 text_align_left--Lozmh'}).get_text()

        # notify:
        TelegramNotificator().send(f'Server «{name}». Disk utilization: {disk_utilization}')

# Cell

@fcb.patch_to(TimewebNotificator)
def run(self):

    """
    METHOD TO CHECK BALANCE AND SERVERS AT TIMEWEB.COM.
    """
    # get driver:
    driver = self.driver

    # authorize:
    self.authorize()

    # check balance and expiration date:
    self.check_expiration_date()

    # check servers:
    self.check_servers()

    # close driver:
    driver.close()