# -*- coding: utf-8 -*-
"""
Created on Thu Jul 27 10:44:28 2017

@author: datkin10
"""

from loggerhelpers import LoggerHelper
import datetime
import json
import pandas
import smtplib
import re
# This class is a singleton instance
class NotificationManager:

    __instance = []

    @staticmethod
    def getInstance(userID):
        for instance in NotificationManager.__instance:
            if instance.userID == userID:
                return instance

        instance = NotificationManager(userID)
        return instance

    @staticmethod
    def removeInstance(userID):
        for instance in NotificationManager.__instance:
            if instance.userID == userID:
                NotificationManager.__instance.remove(instance)

    def __init__(self, userID):
        self.userID = userID
        self.notificationList = []
        self.typeList =[]
        self.fromList = []
        self.indexList = []
        self.index = 0
        self.EMAIL_HOST = "mailo2.uhc.com"
        self.EMAIL_PORT = 25
        self.FROM = "parkinsontracker@optum.com"
        self.newStartGiven = False
        lh = LoggerHelper().getInstance()
        self.logger = lh.createLoggerWorker("Notification Manager","DEBUG",2)
        self.logger.info("Instantiated for user: {}".format(self.userID))

        # Appends the users online singleton list
        NotificationManager.__instance.append(self)

    # This function sets a notification for a user
    def addNotification(self, notification,nType,nFrom):

        if nType == 'deterioration':
            for t in self.typeList:
                if t == 'deterioration':
                    return
        time =  datetime.datetime.now()
        timeStamp = time.strftime("%H:%M:%S - ")
        self.indexList.append(self.index)
        self.index+=1
        self.notificationList.append(timeStamp + notification)
        self.typeList.append(nType)
        self.fromList.append(nFrom)

        self.logger.debug("Added Notifcicatio: {}\n {}\n {}\n".format(notification,nType,nFrom))

    # not tested yet
    # This function sends an email to a Doctor.
    def sendDoctorNotification(self,message,doctorEmail):
        try:
            server = smtplib.SMTP(self.EMAIL_HOST,self.EMAIL_PORT)
            server.sendmail(self.FROM,doctorEmail,message)
            server.quit()
        except Exception as e:
            return False

    # This function gets a notification by creating a JSON and returning that JSON back.
    def getUserNotifications(self):

        if len(self.notificationList) == 0:
            return json.dumps("No notifications to display")
        else:
            message = pandas.Series(data = self.notificationList,index=self.indexList,name="message")
            ntype = pandas.Series(data = self.typeList,index=self.indexList,name="type")
            nfrom = pandas.Series(data = self.fromList,index=self.indexList,name="from")

            frame = pandas.concat([message,ntype,nfrom], axis=1)

        if re.search("welcome to PAPA",self.notificationList[0]):
            self.notificationList.remove(self.notificationList[0])
            self.typeList.remove(self.typeList[0])
            self.fromList.remove(self.fromList[0])

        frame.to_json('static/json/notifications.json')
        file = open('static/json/notifications.json','r')
        jsonstring = file.read()
        return jsonstring


from django.shortcuts import render
from django.http import HttpResponseRedirect
from django import forms
from django.urls import reverse

tasks = []#this will take the tasks to do

class NewTaskForm(forms.Form):
    task = forms.CharField(label="New Task")#the form field will take characters

def index(request):
    if "tasks" not in request.session:
        request.session["tasks"] = []

    return render(request, 'tasks/indexT.html', {
        "tasks": request.session["tasks"]
    })

def add(request):
    if request.method == "POST":
        form = NewTaskForm(request.POST)#this will input the inserted data into form using "request.POST"
        if form.is_valid():#if data entered is valid
            task = form.cleaned_data["task"]#this is var to hold task entered in field or hold all data entered
            tasks.append(task)#if the task is valid we put the task in the list
            return render(request, 'tasks/indexT.html', {"tasks": tasks})#after text is added return us to the index page
        else:
            #if the data is not valid we shall serve up the same form they had so they can correct errors
            return render(request, "tasks/add.html", {
                "form": form
            })

    return render(request, 'tasks/add.html', {
        "form": NewTaskForm()
    })


import streamlit as st
import pickle
import nltk
import sklearn
import string
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
from tensorflow.keras.models import load_model
from keras.utils import pad_sequences

ps = PorterStemmer()

def transform_text(text):
  text  = text.lower()
  text = nltk.word_tokenize(text)
  y =[]
  for i in text:
    if i.isalnum():
      y.append(i)

  text = y[:]
  y.clear()

  for i in text:
    if i not in stopwords.words('english') and i not in string.punctuation:
      y.append(i)

  text = y[:]
  y.clear()
  for i in text:
    y.append(ps.stem(i))
  return " ".join(y)

tfidf = pickle.load(open("vectorizer.pkl", 'rb'))
model = pickle.load(open('model.pkl', 'rb'))
tokenizer = pickle.load(open('tokenizer.pkl','rb'))
lstm_model = load_model("lstm_model.h5")

st.title("Email/Spam Classifier")

input_sms = st.text_input("Enter the message")

st.title("Prediction Through ML")
button1 = st.button("Predict by ML")
if button1:

  transform_sms = transform_text(input_sms)

  vector_input = tfidf.transform([transform_sms]).toarray()

  result  = model.predict(vector_input)[0]

  if result == 1:
    st.header("Spam")

  else:
    st.header("Not Spam")

st.title("Prediction Through RNN_LSTM")
button2 = st.button("Button by LSTM")
if button2:
  max_len = 150
  transform_sms = transform_text(input_sms)

  txt_sms = tokenizer.texts_to_sequences(transform_sms)
  vector_input = pad_sequences(txt_sms, maxlen=max_len)

  result = lstm_model.predict(vector_input)[0]

  if result ==1:
    st.header("Spam")

  else:
    st.header("Not Spam")


import json
import os
from itertools import chain
from operator import itemgetter

import requests
from pymongo import MongoClient

leagues_file = 'leagues.json'

def get_db():
    client = MongoClient('localhost', 27017)
    return client['fotmob']

class API:
    def __init__(self):
        self.host = 'https://www.fotmob.com/api'

    def get_all_leagues(self):
        response = requests.get(f'{self.host}/allLeagues')
        response.raise_for_status()
        return response.json()

    def get_league(self, league_id):
        response = requests.get(f'{self.host}/leagues', params={'id': league_id})
        response.raise_for_status()
        return response.json()

    def get_fixtures(self, league_id, season):
        response = requests.get(f'{self.host}/fixtures', params={'id': league_id, 'season': season})
        response.raise_for_status()
        return response.json()

    def get_player(self, player_id):
        response = requests.get(f'{self.host}/playerData', params={'id': player_id})
        response.raise_for_status()
        return response.json()

def get_all_leagues():
    if os.path.exists(leagues_file):
        with open(leagues_file) as f:
            return json.load(f)

    leagues = API().get_all_leagues()
    leagues = list(chain(*itemgetter('international', 'countries')(leagues)))
    with open(leagues_file, 'w') as f:
        json.dump(leagues, f, indent=4)

    return leagues

def get_league(league_id):
    ids = list(chain(*[[j['id'] for j in i['leagues']] for i in get_all_leagues()]))
    if league_id in ids:
        table = get_db()['leagues']
        league = table.find_one({'id': league_id})
        if not league:
            league = API().get_league(league_id)
            seasons = league['allAvailableSeasons']
            stats = league['stats'] or {}
            stat_links = stats.get('seasonStatLinks', [])
            league = {'id': league_id, 'seasons': seasons, 'stat_links': stat_links}
            table.insert_one(league)
        return league

def get_totw_rounds(league_id, season):
    league = get_league(league_id)
    if league:
        table = get_db()['totw_rounds']
        query = {'league_id': league_id, 'season': season}
        totw_rounds = table.find_one(query)
        if not totw_rounds:
            totw_info = [i for i in league['stat_links'] if i['Name'] == season]
            if len(totw_info) == 1:
                url = totw_info[0]['TotwRoundsLink']
                response = requests.get(url)
                response.raise_for_status()
                totw_rounds = response.json()
                totw_rounds = {**query, 'rounds': totw_rounds['rounds']}
                table.insert_one(totw_rounds)
        return totw_rounds

def get_totw_teams(league_id, season):
    totw_rounds = get_totw_rounds(league_id, season)['rounds']
    table = get_db()['totw_team']
    query = {'league_id': league_id, 'season': season}
    totw_teams = table.find(query)
    missing_rounds = {i['roundId'] for i in totw_rounds} - {i['round_id'] for i in totw_teams}
    if len(missing_rounds) > 0:
        teams = []
        for i in totw_rounds:
            round_id, link = itemgetter('roundId', 'link')(i)
            if round_id in missing_rounds:
                print(f'Fetching team from {link}')
                team = requests.get(link).json()
                teams.append({**query, 'round_id': round_id, 'players': team['players']})
        table.insert_many(teams)
    return list(table.find(query))

def get_totw_players(league_id, season):
    teams = get_totw_teams(league_id, season)
    players = list(chain(*[[j for j in i['players']] for i in teams]))
    return players


import itertools
import logging
import os
import numpy as np

import pytest
import cocotb_test.simulator

import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, FallingEdge
from cocotb.regression import TestFactory

import matplotlib.pyplot as plt

class TB:
    def __init__(self, dut):
        self.dut = dut
        self.signal_a = []
        self.signal_b = []
        self.signal_c = []

        self.getbit = [2048,1024,512,256,128,64,32,16,8,4,2,1]

        self.log = logging.getLogger("cocotb.tb")
        self.log.setLevel(logging.DEBUG)

        cocotb.cocotb.start_soon(Clock(dut.i_clk, 10,units="ns").start())

    async def reset(self):
        self.dut.i_rstn.setimmediatevalue(0)
        self.dut.phase_a.setimmediatevalue(0)
        self.dut.phase_b.setimmediatevalue(0)
        self.dut.phase_c.setimmediatevalue(0)

        self.dut.i_ld.setimmediatevalue(0)
        self.dut.i_step.setimmediatevalue(1)
        self.dut.i_lgcoeff.setimmediatevalue(11)
        #self.dut.m_axis_tready.setimmediatevalue(0)
        # self.dut.EnableSampleGeneration.setimmediatevalue(0)
        await RisingEdge(self.dut.i_clk)
        await RisingEdge(self.dut.i_clk)
        self.dut.i_rstn.value = 0
        await RisingEdge(self.dut.i_clk)
        await RisingEdge(self.dut.i_clk)
        self.dut.i_ce.value = 1
        self.dut.i_rstn.value = 1
        #self.dut.m_axis_tready.value = 1
        await RisingEdge(self.dut.i_clk)
        await RisingEdge(self.dut.i_clk)

    async def write_sig_a_thead(self, signal):
        for i in range(len(signal)):
            data = int(signal[i])
            await FallingEdge(self.dut.i_clk)
            self.dut.phase_a.value  = data

    async def write_sig_b_thead(self, signal):
        for i in range(len(signal)):
            data = int(signal[i])
            await FallingEdge(self.dut.i_clk)
            self.dut.phase_b.value  = data

    async def write_sig_c_thead(self, signal):
        for i in range(len(signal)):
            data = int(signal[i])
            await FallingEdge(self.dut.i_clk)
            self.dut.phase_c.value  = data

    def toSigned32(self, n):
        n = n & 0xffffffff
        return n | (-(n & (1<<31)))

    def toSigned8(self, n):
        n = n & 0xff
        return n | (-(n & (1<<7)))

    def toSigned16(self, n):
        n = n & 0xffff
        return n | (-(n & (1<<15)))

    def generateSin(self, freq, time, amp,  sample_rate, random, random_range, channel):
        samples = np.arange(0, time, 1/sample_rate)
        noise = 0
        if random == 1:
              noise = np.random.randint(random_range, size=(len(samples)))
        if channel == 0:
            self.signal_a = amp/2 * np.sin(2 * np.pi * freq * samples)  + amp/2  + noise
            self.signal_a = np.int16(self.signal_a)
        elif channel == 1:
            self.signal_b = amp/2 * np.sin(2 * np.pi * freq * samples - (2*np.pi/3))  + amp/2 + noise
            self.signal_b = np.int16(self.signal_b)
        elif channel == 2:
            self.signal_c = amp/2 * np.sin(2 * np.pi * freq * samples + (2*np.pi/3)) + amp/2  + noise
            self.signal_c = np.int16(self.signal_c)

async def run_test(dut):

    tb = TB(dut)

    #id_count = 2**len(tb.source.bus.tid)

    cur_id = 1

    for i in range(3):
        tb.generateSin(0.06,100,3500,1e3,1,500,i)

    #plt.plot(tb.signal_a)
    #plt.plot(tb.signal_b)
    #plt.show()
    await tb.reset()

    #await tb.write(20,12)

    # Run reset_dut concurrently
    write_thread_0 = cocotb.start_soon(tb.write_sig_a_thead(tb.signal_a))
    write_thread_1 = cocotb.start_soon(tb.write_sig_b_thead(tb.signal_b))
    write_thread_2 = cocotb.start_soon(tb.write_sig_c_thead(tb.signal_c))

    assert 1 == 1
    # await RisingEdge(dut.CLK100MHz)
    # await RisingEdge(dut.CLK100MHz)

    # Wait for the other thread to complete
    await write_thread_0
    await write_thread_1
    await write_thread_2

if cocotb.SIM_NAME:
    factory = TestFactory(run_test)
    factory.generate_tests()

# cocotb-test

tests_dir = os.path.abspath(os.path.dirname(__file__))
hdl_dir = os.path.abspath(os.path.join(tests_dir, '..',  'hdl'))
pll_dir = os.path.abspath(os.path.join(hdl_dir, '..',  'pll'))

@pytest.mark.parametrize("data_width", [12])
def test_pll(request, data_width):
    dut = "pll"
    module = os.path.splitext(os.path.basename(__file__))[0]
    toplevel = dut

    verilog_sources = [
        os.path.join(hdl_dir, f"{dut}.v"),
        #os.path.join(hdl_dir, "pi_controller.v"),
        #os.path.join(pll_dir, "fd.v"),
        #os.path.join(pll_dir, "lp.v"),
        #os.path.join(pll_dir, "pd.v"),
        #os.path.join(pll_dir, "vcodiv.v"),
    ]

    parameters = {}

    parameters['ADC_DATA_WIDTH'] = data_width

    extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}

    sim_build = os.path.join(tests_dir, "sim_build",
        request.node.name.replace('[', '-').replace(']', ''))

    cocotb_test.simulator.run(
        python_search=[tests_dir],
        verilog_sources=verilog_sources,
        toplevel=toplevel,
        module=module,
        parameters=parameters,
        sim_build=sim_build,
        extra_env=extra_env,
    )


from django.shortcuts import render
from home.models import Blogpost , Contect
from django.contrib import messages

# Create your views here.

def home(request):
    posts = Blogpost.objects.filter(publish=True)
    context = {'posts': posts}
    return render(request, "home.html", context)

def blog(request):
    posts = Blogpost.objects.filter(publish=True)
    context = {'posts': posts}
    return render(request, "blog.html", context)

def blogview(request, slug):
    posts = Blogpost.objects.filter(slug=slug).first()
    context = {'posts': posts}
    return render(request, "pview/blogview.html", context)

def contect(request):
    if request.method == 'POST':
        fname = request.POST['fname']
        Lname = request.POST['lname']
        mob = request.POST['mobile']
        email = request.POST['email']
        desc = request.POST['description']
        if len(fname) < 3 or len(Lname) < 3 or len(mob) < 10 or len(email) < 5 or len(desc) < 5:
            messages.error(request, 'Please fill the form correctly')
        else:
            contect = Contect(fname=fname, Lname=Lname , mob=mob,
                              email=email, desc=desc,)
            contect.save()
            messages.success(request, 'Your messages has Submited Successfuly')
    return render(request, "contect.html")

def about(request):
    return render(request, "about.html")


import os
import time
import requests
import bs4
from urllib.parse import urljoin
import pymongo
from dotenv import load_dotenv
from datetime import datetime
import locale
locale.setlocale(locale.LC_ALL, 'ru_RU')

class ParseError(Exception):
    def __init__(self, text):
        self.text = text

class MagnitParser:
    _headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15'
    }
    _params = {
        'geo': 'moskva'
    }
    _cookies = {'mg_geo_id': '2398'}

    def __init__(self, start_url, data_client):
        self.start_url = start_url
        self.data_client = data_client
        self.data_base = self.data_client["magnit_parse_db"]

    @staticmethod
    def _get_response(url, *args, **kwargs):
        while True:
            try:
                response = requests.get(url, *args, **kwargs)
                if response.status_code > 399:
                    raise ParseError(response.status_code)
                time.sleep(0.1)
                return response
            except (requests.RequestException, ParseError):
                time.sleep(0.5)
                continue

    @staticmethod
    def _get_soup(response):
        return bs4.BeautifulSoup(response.text, 'lxml')

    def run(self):
        for product in self.parse(self.start_url):
            self.save(product)

    def parse(self, url) -> dict:
        resp = self._get_response(url, params=self._params, headers=self._headers, cookies=self._cookies)
        print(resp)
        soup = self._get_soup(resp)
        # print(soup)
        catalog_main = soup.find('div', attrs={'class': 'сatalogue__main'})
        # print(catalog_main)
        for product_tag in catalog_main.find_all('a', attrs={'class': 'card-sale'}):
            yield self._get_product_data(product_tag)

    @staticmethod
    def get_price(product_tag, attr: str) -> float or None:
       try:
           price: list = (product_tag.find('div', attrs={'class' : attr}).text)[1 : -1].split('\n')
           return float('.'.join(price))
       except:
           return None

    @staticmethod
    def get_date(product_tag, binary: bin) -> datetime or None:
        try:
            date = product_tag.find('div', class_='card-sale__date').findChildren()[binary].text[2:].strip()
            return datetime.strptime(f"{date} {datetime.now().year}", "%d %B %Y")
        except:
            return None

    @property
    def data_template(self) -> dict:
        return {
            'url': lambda tag: urljoin(self.start_url, tag.attrs.get('href')),
            'promo_name':lambda tag: tag.find('div', attrs={'class' : 'card-sale__header'}).text,
            'product_name': lambda tag: tag.find('div', attrs={'class': 'card-sale__title'}).text,
            'old_price': lambda tag: self.get_price(tag, 'label__price_old'),
            'new_price': lambda tag: self.get_price(tag, 'label__price_new'),
            'image_url': lambda tag: urljoin(self.start_url, tag.find('source').attrs.get('data-srcset')),
            'date_from': lambda tag: self.get_date(tag, 0),
            'date_to': lambda tag: self.get_date(tag, 1)
        }

    def _get_product_data(self, product_tag: bs4.Tag) -> dict:
        data = {}
        for key, pattern in self.data_template.items():
            try:
                data[key] = pattern(product_tag)
            except AttributeError:
                pass
        return data

    def save(self, data):
        print(data)
        collection = self.data_base["magnit"]
        collection.insert_one(data)
        pass

if __name__ == '__main__':
    load_dotenv(".env")
    data_base_url = os.getenv('DATA_BASE_URL')
    data_client = pymongo.MongoClient(data_base_url)
    url = 'https://magnit.ru/promo/'
    parser = MagnitParser(url, data_client)
    parser.run()