from pathlib import Path
from datetime import datetime, timedelta
import time
import csv
from pins import *

class Alarmmod():
    def __init__(self, Main):
        self.Main = Main

        self.alarms = []
        self.alarm_path = Path(__file__).resolve().parent / "alarms.txt"
        self.alarm_format = "%d.%m.%y %H:%M"

        self.selected = 0       # index of selected rel to alarms
        self.displayed = []     # index of displayed lines from disp_list
        # complete list of alarms, ordered, [[{alarm: opt}, selected?, active?], ...]

        self.mod_alarm = None       # holds alarm which is getting modifyied
        self.sound_selected = 0      # index of dict
        self.light_selected = 0
        self.light_opt = ["Aus", "Sonnenaufgang"]
        self.light_delay = 0

        self.load_alarms()

    def is_set24(self):
        '''Whether an alarm is set for the next 24h.
        '''
        for alarm in self.alarms:
            if alarm.get_armed24():
                return True
        return False

    def get_set24(self):
        '''Returns list of all alarms set for the next 36h.
        '''
        armed = []
        for alarm in self.alarms:
            if alarm.get_armed24():
                armed.append(alarm)
        return armed

    def load_alarms(self):
        with self.alarm_path.open(newline='') as alarm_file:
            alarm_reader = csv.reader(alarm_file, skipinitialspace=True)
            for alarm_line in alarm_reader:
                alarm_date = datetime.strptime(
                    alarm_line[0], self.alarm_format)
                active = bool(alarm_line[1] == "True")
                self.alarms.append(Alarm(
                    alarm_date, sound=alarm_line[2],
                    light=alarm_line[3], light_delay=alarm_line[4], active=active))
        print("befor sorting: \n", self.alarms)
        self.alarms.sort()
        print("after sorting: \n", self.alarms)

    def save_alarms(self):
        print("Saving alarms..")
        with self.alarm_path.open("w", newline='') as alarm_file:
            for alarm in self.alarms:
                alarm_date_str = alarm.get_a_datetime().strftime(
                    self.alarm_format)
                row = "{}, {}, {}, {}, {}\n".format(
                    alarm_date_str, alarm.active, alarm.sound, alarm.light,
                    int(alarm.light_delay.seconds/60))
                print("saving alarms: ", row)
                alarm_file.write(row)

    def get_disp_list(self):
        if self.displayed == []:     # fill initally the list "displayed"
            self.displayed.extend(
                [i for i, _ in enumerate(self.alarms) if i < 3])
            self.alarms[0].set_selected()

        self.updated_displayed()
        return [self.alarms[i] for i in self.displayed]

    def updated_displayed(self):
        while self.selected not in self.displayed:
            if self.selected < min(self.displayed):
                self.displayed = [i - 1 for i in self.displayed]
            elif self.selected > max(self.displayed):
                self.displayed = [i + 1 for i in self.displayed]

            self.displayed = [len(self.alarms) +
                              i if i < 0 else i for i in self.displayed]
            self.displayed = [i - len(self.alarms)
                              if i > len(self.alarms) - 1
                              else i for i in self.displayed]

    def del_mod(self):
        self.alarms.remove(self.mod_alarm)

# -----Multiline button handling-----
    def sel_up(self):
        print("Selection UP")
        self.selected -= 1
        if self.selected < 0:
            self.selected = len(self.alarms) - 1
        self.alarms[self.selected].set_selected(True, self.alarms)
        self.Main.Disp.disp_update = True

    def sel_down(self):
        print("Selection Down")
        self.selected += 1
        if self.selected > len(self.alarms) - 1:
            self.selected = 0
        self.alarms[self.selected].set_selected(True, self.alarms)
        self.Main.Disp.disp_update = True

    def sel_ok(self):
        print("Selection OK")
        if not self.alarms[self.selected].get_armed24():   # inactive -> active
            print("inactive --> active")
            self.alarms[self.selected].set_armed24()
            self.save_alarms()
        else:
            self.Main.menu_mode = "Main"                # active -> settings
            self.Main.Menu.set_crr_menu("mod_alarm")
            self.Main.Disp.set_disp_mode(1)
            self.mod_alarm = self.alarms[self.selected]

        self.Main.Disp.disp_update = True

    def sel_back(self):
        print("Selection BACK")
        self.displayed = []
        self.Main.menu_mode = "Main"
        self.Main.Menu.set_crr_menu("main")
        self.Main.Disp.set_disp_mode(1)
        self.Main.Disp.disp_update = True

# -----alarm clock setting-----
    def set_clock(self, ch):
        ''' Handles buttons if menu_mode = "alarm_set"
        '''
        # -----hours-----
        if self.mod_alarm.mod_part == "h":
            repeats = 1
            while True:
                if ch == UP:
                    print("mod a_datetime: ", self.mod_alarm.a_datetime)
                    self.mod_alarm.a_datetime -= timedelta(hours=1)
                    self.Main.Disp.disp_update = True
                    print("mod a_datetime + 1h: ", self.mod_alarm.a_datetime)
                    if GPIO.input(UP):
                        time.sleep(1 / repeats)
                        if GPIO.input(UP):
                            if repeats <= 4:
                                repeats += 1
                            continue
                elif ch == DOWN:
                    self.mod_alarm.a_datetime += timedelta(hours=1)
                    self.Main.Disp.disp_update = True
                    if GPIO.input(DOWN):
                        time.sleep(1 / repeats)
                        if GPIO.input(DOWN):
                            if repeats <= 4:
                                repeats += 1
                            continue

                elif ch == BACK:
                    print("Canceled!")
                    self.Main.menu_mode = "alarm_multiL"
                    self.Main.Disp.set_disp_mode(3)

                elif ch == OK:
                    self.mod_alarm.mod_part = "min"
                    self.Main.Disp.disp_update = True
                break
        # -----minutes-----
        elif self.mod_alarm.mod_part == "min":
            repeats = 1
            while True:
                if ch == UP:
                    self.mod_alarm.a_datetime -= timedelta(minutes=1)
                    self.Main.Disp.disp_update = True
                    if GPIO.input(UP):
                        time.sleep(1 / repeats)
                        if GPIO.input(UP):
                            if repeats <= 10:
                                repeats += 1
                            continue
                elif ch == DOWN:
                    self.mod_alarm.a_datetime += timedelta(minutes=1)
                    self.Main.Disp.disp_update = True
                    if GPIO.input(DOWN):
                        time.sleep(1 / repeats)
                        if GPIO.input(DOWN):
                            if repeats <= 10:
                                repeats += 1
                            continue

                elif ch == BACK:
                    self.mod_alarm.mod_part = "h"
                    self.Main.Disp.disp_update = True
                elif ch == OK:
                    self.mod_alarm.mod_part = "sound"
                    self.Main.Disp.disp_update = True
                break
        # -----sound-----
        elif self.mod_alarm.mod_part == "sound":
            if ch == UP:
                self.sound_selected -= 1
            elif ch == DOWN:
                self.sound_selected += 1
            elif ch == BACK:
                self.mod_alarm.mod_part = "min"

            if self.sound_selected < 0:
                self.sound_selected = len(self.Main.Speakers.sounds_list) - 1
            elif self.sound_selected > len(self.Main.Speakers.sounds_list) - 1:
                self.sound_selected = 0
            #self.mod_alarm.sound = self.Main.Speakers.sounds_list[self.sound_selected]

            if ch == OK:
                print("Alarm old: ", self.mod_alarm.sound)
                self.mod_alarm.sound = self.Main.Speakers.sounds_list[self.sound_selected]
                print("ALARM new: ",
                      self.Main.Speakers.sounds_list[self.sound_selected])
                self.sound_selected = 0
                self.mod_alarm.mod_part = "light"
            self.Main.Disp.disp_update = True
        # -----light-----
        elif self.mod_alarm.mod_part == "light":
            if ch == UP:
                print("light: UP")
                self.light_selected += 1
            elif ch == DOWN:
                print("light: DOWN")
                self.light_selected -= 1
            elif ch == BACK:
                print("light: Back")
                self.mod_alarm.mod_part = "sound"

            if self.light_selected < 0:
                self.light_selected = len(self.light_opt) - 1
            elif self.light_selected > len(self.light_opt) - 1:
                self.light_selected = 0

            if ch == OK:
                self.mod_alarm.light = self.light_opt[self.light_selected]
                if self.mod_alarm.light != "Aus":
                    self.mod_alarm.mod_part = "light_delay"
                else:
                    self.mod_alarm.mod_part = None
                    self.mod_alarm.set_armed24()
                    self.save_alarms()
                    self.Main.tasks.put(["Blink", -1, "green"])
                    self.Main.menu_mode = "alarm_multiL"
                    self.Main.Disp.set_disp_mode(3)
            self.Main.Disp.disp_update = True

        # -----light delay-----
        elif self.mod_alarm.mod_part == "light_delay":
            if ch == UP:
                self.light_delay -= 1 if self.light_delay > 0 else 0
            elif ch == DOWN:
                self.light_delay += 1 if self.light_delay < 30 else 0
            elif ch == BACK:
                self.mod_alarm.mod_part = "light"
            elif ch == OK:
                self.mod_alarm.light_delay = timedelta(
                    minutes=self.light_delay)
                self.mod_alarm.mod_part = None
                self.mod_alarm.set_armed24()
                self.save_alarms()
                self.Main.tasks.put(["Blink", -1, "green"])
                self.Main.menu_mode = "alarm_multiL"
                self.Main.Disp.set_disp_mode(3)

            self.Main.Disp.disp_update = True

# -----Ringing-----
    def ring(self, alarm):
        '''Handles alarm ringing. Sets the light and sound. \n
        Gets called from taskmanager 30 min befor the alarm.
        '''
        print("START: ring() ", alarm)
        # Wait for light
        while not alarm.a_datetime - alarm.light_delay < datetime.now():
            time.sleep(10)

        # Start light if set:
        if alarm.light == "Sonnenaufgang":
            self.Main.tasks.put(
                ["sunrise", -1, alarm.light_delay.total_seconds()])

        # Wait for alarm
        while not alarm.a_datetime < datetime.now() and not self.Main.abort_alarm:
            time.sleep(10)

        if self.Main.abort_alarm:
            self.Main.abort_alarm = False
            self.Main.ringing = False
            return

        # waking display up
        if self.Main.menu_mode == "night":
            self.Main.menu_mode = "full_screen"
            self.Main.Disp.set_disp_mode(2)

        # start alarm sound
        print("Start Alarm")
        if alarm.sound in self.Main.Speakers.stations:
            print("..in 'stations'")
            self.Main.Speakers.radio(alarm.sound)
        elif alarm.sound in self.Main.Speakers.musik:
            print("..in 'musik'")
            file_uri = self.Main.Speakers.musik[alarm.sound]
            print(file_uri)
            self.Main.Speakers.play_file(file_uri)
        self.Main.Menu.make_submenus("Radio_on")

        time.sleep(10)

        if self.Main.abort_alarm:
            self.Main.abort_alarm = False
            self.Main.ringing = False
            return
        if not self.Main.Speakers.is_playing:
            print("Alarm sound not playing after 5s, playing local track.")
            self.Main.Speakers.play_file(
                self.Main.Speakers.get_audio_files().popitem()[1])

# -----Scheduler-----

    def alarm_scheduler(self):
        ''' Checks every 60s for set alarms. Activates a alarm 30 min befor
        the alarmtime by passing it to ring().
        '''

        print("alarm_scheduler initialized")
        while not self.Main.exit_flag:
            time.sleep(60)
            if not self.is_set24():
                # print("alarm_scheduler: No alarm active, sleeping...")
                pass
            else:
                act_alarms = self.get_set24()
                # print("alarm_scheduler: ", act_alarms)
                soonest = act_alarms[0]
                for alarm in act_alarms:
                    if alarm.a_datetime < soonest.a_datetime:
                        soonest = alarm

                if not soonest.a_datetime < datetime.now() + timedelta(minutes=35):
                    # print("alarm_scheduler: No alarm the next 40 min, sleeping...")
                    pass
                elif not self.Main.ringing:
                    self.Main.tasks.put(("ring", [-1], soonest))
                    soonest.active = False
                else:
                    print("Already ringing!! ", soonest)

        print("alarm_sceduler: EXIT")

class Alarm():
    def __init__(self, a_datetime, sound="SWR3", light="Aus", light_delay=0, active=True):
        self.a_datetime = a_datetime
        self.sound = sound
        self.light = light
        self.light_delay = timedelta(minutes=int(light_delay))
        self.active = active
        self.selected = False
        self.mod_part = None    # "h", "min", "sound", "light"

    def __lt__(self, other):  # self < other?
        if self.get_armed24() == other.get_armed24():
            if self.a_datetime < other.a_datetime:
                return True
            return False

        return self.get_armed24()

    def __eq__(self, other):
        return (self.get_armed24() == other.get_armed24()) and self.a_datetime == other.a_datetime

    def __str__(self):
        return "--".join((self.a_datetime.strftime("%d.%m.%y %H:%M"), str(self.active), "\n"))

    def set_active(self, active=True):
        if active:
            self.active = True
        else:
            self.active = False

    def get_selected(self):
        return self.selected

    def set_selected(self, selected=True, all_alarms=None):
        if all_alarms is not None:
            for alarm in all_alarms:
                alarm.set_selected(False)
        self.selected = selected

    def get_armed24(self):
        '''Whether the alarm is set and active in the next 36 h.
        '''
        if self.active:
            tomorrow = datetime.now() + timedelta(days=1, hours=12)
            if (datetime.now() < self.a_datetime) and (self.a_datetime < tomorrow):
                return True
        return False

    def set_armed24(self):
        '''Activates the alarm, if the date is in the past, sets it to tomorrow.
        '''
        print("set_armed24")
        self.active = True

        self.a_datetime = datetime.combine(
            datetime.today(), self.a_datetime.time())
        if self.a_datetime < datetime.now():
            # set date to tomorrow, keep time
            tomorrow = datetime.now() + timedelta(days=1)
            self.a_datetime = datetime.combine(
                tomorrow, self.a_datetime.time())
        print("a_datetime was changed: ", self.a_datetime)
        print("get_armed24: ", self.get_armed24())
        # else:
        #     print("set_armed24: a_datetime not changed.")

    def get_text_line(self):
        return [self.a_datetime, self.active, self.selected]

    def set_a_datetime(self, a_datetime):
        self.a_datetime = a_datetime

    def get_a_datetime(self):
        return self.a_datetime

    __repr__ = __str__


__author__ = 'Sergey Osipov <Serega.Osipov@gmail.com>'

import miepython as mp
import numpy as np

def get_mie_efficiencies(ri, r_data, wavelength):
    """

    :param ri:
    :param r_data: units should be the same as wavelength
    :param wavelength: units should be the same as radius
    :return:
    """
    # mp.mie can take x vector as input
    # these are the ext and sca efficiencies, compare to cross sections (qext * A)
    qext = np.empty((len(wavelength), len(r_data)))
    qsca = np.empty((len(wavelength), len(r_data)))

    for wl_index in range(len(wavelength)):
        for r_index in range(len(r_data)):
            m = ri[wl_index]
            # miepython sign convention: imaginary part has to be negative; complex RI = real -j * imaginary
            m = m.real - 1j * m.imag
            x = 2 * np.pi * r_data[r_index] / wavelength[wl_index]
            # efficiencies are without units, area will be in um^2
            qext[wl_index, r_index], qsca[wl_index, r_index], qback, g = mp.mie(m,x)

    mie_vo = {}
    mie_vo['qext'] = qext
    mie_vo['qsca'] = qsca
    mie_vo['wavelength'] = wavelength
    mie_vo['r_data'] = r_data
    return mie_vo


'''
I started this as a joke among friends, telling that converting numbers to other integer bases is for n00bs,
while an actual coder at least converts numbers to more complex bases like pi
(or π or however you wish to spell it in your language), so they dared me proving I was better.

And I did it in few hours, discovering that what I started as a joke actually has some math ground
and application (particularly the conversion to base pi, it seems).

That said, now I am daring you to do the same, that is to build a function so that it takes a number
(any number, you are warned!) and optionally the number of decimals (default: 0) and a base (default: pi),
returning the proper conversion as a string:

#Note In Java there is no easy way with optional parameters so all three parameters will be given;
the same in C# because, as of now, the used version is not known.

converter(13) #returns '103'
converter(13,3) #returns '103.010'
converter(-13,0,2) #returns '-1101'

I know most of the world uses a comma as a decimal mark, but as English language
and culture are de facto the Esperanto of us coders, we will stick to our common glorious traditions and uses,
adopting the trivial dot (".") as decimal separator; if the absolute value of the result is <1,
you have of course to put one (and only one) leading 0 before the decimal separator.

Finally, you may assume that decimals if provided will always be >= 0
and that no test base will be smaller than 2 (because, you know, converting to base 1 is pretty lame)
or greater than 36; as usual, for digits greater than 9 you can use uppercase alphabet letter,
so your base of numeration is going to be: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.

That is my first 3-languages-kata, so I count on you all to give me extensive feedback,
no matter how harsh it may sound, so to improve myself even further :)
'''

from math import pi, log

def converter(n, decimals=0, base=pi):
    """takes n in base 10 and returns it in any base (default is pi
    with optional x decimals"""
    rep = []
    if n < 0:
        rep.append('-')
        n *= -1
    if n == 0:
        k = 0
    else:
        k = int(log(n, base))

    for i in [pow(base, p) for p in range(k, -1 - decimals, -1)]:
        rn = int(n / i)
        n -= rn * i
        rep.append('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'[rn])
        if i == 1 and decimals > 0:
            rep.append('.')
    return ''.join(rep)

kyu4/Decimal to any Rational or Irrational Base Converter.py


from bs4 import BeautifulSoup

def parse_paragraph(tag):
	for content in tag.contents:
		if content.name is not None:
			if content.find("b") is not None:
				if content.get('class') == "pb":
					page_div.extend(tags)
					output.append(str(page_div).replace('\n', ''))
					tags = []
					page_div = BeautifulSoup(features="lxml-xml").new_tag('div')
					page_div.attrs = {"id": content.get('id'), "class": type_class}
					tag.contents[0].decompose()
				else:
					[tags, page_div, output] = parse_paragraph(tag, tags, page_div, output, type_class)
			else:
				tags.append(tag)
	return [tags, page_div, output]

html_doc = """
<title>The Dormouse's story</title>

Once upon a time there were three little sisters; and their names were
Elsie,

The Dormouse's story

Lacie and
Tillie;
and they lived at the bottom of a well.

...

"""

soup = BeautifulSoup(html_doc, 'lxml-xml')
body = soup.find('p', {'class': "story"})
for item in body.next_element.next_siblings:
	if item is not None and item.name is not None:
		if item.get('class') == 'title':
			print("Ok **** :", item)
		else:
			print("**/*/*", item)

# for content in body.next_siblings:
# 	if content is not None and content.name is not None:
# 		if content.find("b") is not None:
# 			if content.name == "b":
# 				print("Yes :", content.name)


import urllib.request

from mutagen.easyid3 import EasyID3
from mutagen.flac import FLAC, Picture
from mutagen.id3 import APIC, COMM, ID3, TORY, TPUB, TYER, USLT
from mutagen.mp4 import MP4, MP4Cover

from core.const import M4A_TAG_PRESET, TAG_PRESET, log

def compare(music_file, metadata):
    """Check if the input music file title matches the expected title."""
    already_tagged = False
    try:
        if music_file.endswith('.mp3'):
            audiofile = EasyID3(music_file)
            already_tagged = audiofile['title'][0] == metadata['name']
        elif music_file.endswith('.m4a'):
            audiofile = MP4(music_file)
            already_tagged = audiofile['\xa9nam'][0] == metadata['name']
    except (KeyError, TypeError):
        pass

    return already_tagged

def embed(music_file, meta_tags):
    """ Embed metadata. """
    embed = EmbedMetadata(music_file, meta_tags)
    if music_file.endswith('.m4a'):
        log.info('Applying metadata')
        return embed.as_m4a()
    elif music_file.endswith('.mp3'):
        log.info('Applying metadata')
        return embed.as_mp3()
    elif music_file.endswith('.flac'):
        log.info('Applying metadata')
        return embed.as_flac()
    else:
        log.warning('Cannot embed metadata into given output extension')
        return False

class EmbedMetadata:
    def __init__(self, music_file, meta_tags):
        self.music_file = music_file
        self.meta_tags = meta_tags

    def as_mp3(self):
        """ Embed metadata to MP3 files. """
        music_file = self.music_file
        meta_tags = self.meta_tags
        # EasyID3 is fun to use ;)
        # For supported easyid3 tags:
        # https://github.com/quodlibet/mutagen/blob/master/mutagen/easyid3.py
        # Check out somewhere at end of above linked file
        audiofile = EasyID3(music_file)
        self._embed_basic_metadata(audiofile, preset=TAG_PRESET)
        audiofile['media'] = meta_tags['type']
        audiofile['author'] = meta_tags['artists'][0]['name']
        audiofile['lyricist'] = meta_tags['artists'][0]['name']
        audiofile['arranger'] = meta_tags['artists'][0]['name']
        audiofile['performer'] = meta_tags['artists'][0]['name']
        audiofile['website'] = meta_tags['external_urls']['spotify']
        audiofile['length'] = str(meta_tags['duration'])
        if meta_tags['publisher']:
            audiofile['encodedby'] = meta_tags['publisher']
        if meta_tags['external_ids']['isrc']:
            audiofile['isrc'] = meta_tags['external_ids']['isrc']
        audiofile.save(v2_version=3)

        # For supported id3 tags:
        # https://github.com/quodlibet/mutagen/blob/master/mutagen/id3/_frames.py
        # Each class represents an id3 tag
        audiofile = ID3(music_file)
        audiofile['TORY'] = TORY(encoding=3, text=meta_tags['year'])
        audiofile['TYER'] = TYER(encoding=3, text=meta_tags['year'])
        audiofile['TPUB'] = TPUB(encoding=3, text=meta_tags['publisher'])
        audiofile['COMM'] = COMM(encoding=3,
                                 text=meta_tags['external_urls']['spotify'])
        if meta_tags['lyrics']:
            audiofile['USLT'] = USLT(
                encoding=3, desc=u'Lyrics', text=meta_tags['lyrics'])
        try:
            albumart = urllib.request.urlopen(
                meta_tags['album']['images'][0]['url'])
            audiofile['APIC'] = APIC(encoding=3, mime='image/jpeg', type=3,
                                     desc=u'Cover', data=albumart.read())
            albumart.close()
        except IndexError:
            pass

        audiofile.save(v2_version=3)
        return True

    def as_m4a(self):
        """ Embed metadata to M4A files. """
        music_file = self.music_file
        meta_tags = self.meta_tags
        audiofile = MP4(music_file)
        self._embed_basic_metadata(audiofile, preset=M4A_TAG_PRESET)
        audiofile[M4A_TAG_PRESET['year']] = meta_tags['year']
        if meta_tags['lyrics']:
            audiofile['lyrics'] = meta_tags['lyrics']
        try:
            albumart = urllib.request.urlopen(
                meta_tags['album']['images'][0]['url'])
            audiofile[M4A_TAG_PRESET['albumart']] = [MP4Cover(
                albumart.read(), imageformat=MP4Cover.FORMAT_JPEG)]
            albumart.close()
        except IndexError:
            pass

        audiofile.save()
        return True

    def as_flac(self):
        music_file = self.music_file
        meta_tags = self.meta_tags
        audiofile = FLAC(music_file)
        self._embed_basic_metadata(audiofile)
        audiofile['year'] = meta_tags['year']
        audiofile['comment'] = meta_tags['external_urls']['spotify']
        if meta_tags['lyrics']:
            audiofile['lyrics'] = meta_tags['lyrics']

        image = Picture()
        image.type = 3
        image.desc = 'Cover'
        image.mime = 'image/jpeg'
        albumart = urllib.request.urlopen(
            meta_tags['album']['images'][0]['url'])
        image.data = albumart.read()
        albumart.close()
        audiofile.add_picture(image)

        audiofile.save()
        return True

    def _embed_basic_metadata(self, audiofile, preset=TAG_PRESET):
        meta_tags = self.meta_tags
        audiofile[preset['artist']] = meta_tags['artists'][0]['name']
        audiofile[preset['albumartist']] = meta_tags['artists'][0]['name']
        audiofile[preset['album']] = meta_tags['album']['name']
        audiofile[preset['title']] = meta_tags['name']
        audiofile[preset['date']] = meta_tags['release_date']
        audiofile[preset['originaldate']] = meta_tags['release_date']
        if meta_tags['genre']:
            audiofile[preset['genre']] = meta_tags['genre']
        if meta_tags['copyright']:
            audiofile[preset['copyright']] = meta_tags['copyright']
        if self.music_file.endswith('.flac'):
            audiofile[preset['discnumber']] = str(meta_tags['disc_number'])
        else:
            audiofile[preset['discnumber']] = [(meta_tags['disc_number'], 0)]
        if self.music_file.endswith('.flac'):
            audiofile[preset['tracknumber']] = str(meta_tags['track_number'])
        else:
            if preset['tracknumber'] == TAG_PRESET['tracknumber']:
                audiofile[preset['tracknumber']] = '{}/{}'.format(
                    meta_tags['track_number'], meta_tags['total_tracks'])
            else:
                audiofile[preset['tracknumber']] = [
                    (meta_tags['track_number'], meta_tags['total_tracks'])
                ]


#!/usr/bin/python
#/** @file
# * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
# * SPDX-License-Identifier : Apache-2.0
# *
# * Licensed under the Apache License, Version 2.0 (the "License");
# * you may not use this file except in compliance with the License.
# * You may obtain a copy of the License at
# *
# *  http://www.apache.org/licenses/LICENSE-2.0
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
#**/

import sys

if (len(sys.argv) != 8):
	print("\nPlease provide following inputs")
	print("\narg1 : target name")
	print("\narg2 : val_target.h")
	print("\narg3 : tbsa_tgt.cfg")
	print("\narg4 : intermediate source file")
	print("\narg5 : output database file\n")
	print("\narg6 : name for table\n")
	print("\narg7 : section name for database table\n")
	sys.exit(1)

target       = sys.argv[1]
in_val_tgt   = sys.argv[2]
in_tbsa_tgt  = sys.argv[3]
out_source   = sys.argv[4]
out_database = sys.argv[5]
table_name   = sys.argv[6]
section_name = sys.argv[7]

minor_major_map = {}
unique_major_groups = []
unique_minor_components = []

def get_minor_major_map():
	""" This method populates the dictionary which maps between every available minor component to their major group """
	try:
		with open(in_val_tgt, mode="r") as f:
			for line in f:
				if "GROUP_" in line:
					temp_list = line.split()
					if "=" in temp_list[1] and "GROUP_" in temp_list[2]:
						minor_major_map.update({temp_list[0]:temp_list[2][6:temp_list[2].find(',')]})
						if minor_major_map[temp_list[0]] not in unique_major_groups:
							unique_major_groups.append(minor_major_map[temp_list[0]])
	except:
		print("Cannot open %s" %in_val_tgt)

def generate_source():
	"""" This method generates the source file which gets compiled on host machine.
		The compiled output then generates the database file for a given target """
	try:
		with open(out_source, mode="a") as o_f:
			o_f.write("#include <stdio.h>\n")
			o_f.write("#include \"val_target.h\"\n\n")
			o_f.write("int main (void)\n")
			o_f.write("{\n")
			try:
				with open(in_tbsa_tgt, mode="r") as i_f:
					num = ''
					for line in i_f:
						if "/" in line[0:1]:
							""" Ignoring the commented lines """
							pass
						elif (".num" in line) and (line[line.find('.')+1:line.find('.')+4] == "num"):
							""" Pick the lines which tells the total instances of a component """
							minor_comp = line[:line.find('.')]
							num        = "".join(line[line.find('=')+1:line.find(';')].replace(" ",""))
							if (int(num)) != 0:
								o_f.write("\t%s_desc_t %s[%s] = {0};\n" %(minor_major_map[minor_comp.upper()].lower(), minor_comp, num))
								o_f.write("\tint %s_num_instances = %s;\n" %(minor_comp, num))
								num = int(num)
								for instance in range(num):
									o_f.write("\t%s[%d].cfg_type.cfg_id = ((GROUP_%s << 24) + (%s_%s << 16) + %d);\n" \
										%(minor_comp, instance, minor_major_map[minor_comp.upper()],\
											minor_major_map[minor_comp.upper()], minor_comp.upper(), instance))
									o_f.write("\t%s[%d].cfg_type.size   = sizeof(%s)/%s_num_instances;\n" %(minor_comp, instance, minor_comp, minor_comp))
									o_f.write("\t%s[%d].cfg_type.size  |= (%s_num_instances << 24);\n" %(minor_comp, instance, minor_comp))
								unique_minor_components.append(minor_comp.upper())
						elif ("=" in line) and (";" in line) and (int(num) != 0):
							""" Pick the lines which tells the component details """
							period_1 = line.find('.')
							period_2 = period_1 + line[period_1+1:].find('.') + 1
							o_f.write("\t%s[%s].%s;\n" %(line[:period_1], line[period_1+1:period_2], line[period_2+1:line.find(';')]))
						else:
							o_f.write("\n")
					o_f.write("\n")
			except:
				print("Cannot open input file %s" %in_tbsa_tgt)

			""" Populate major structure details """
			for group in unique_major_groups:
				o_f.write("\t%s_hdr_t group_%s = {0};\n" %(group.lower(), group.lower()))
				o_f.write("\tgroup_%s.cfg_type.cfg_id = (GROUP_%s << 24);\n" %(group.lower(), group))
				o_f.write("\tgroup_%s.cfg_type.size  += sizeof(group_%s);\n" %(group.lower(), group.lower()))
				for minor in unique_minor_components:
					if group == minor_major_map[minor]:
						o_f.write("\tgroup_%s.cfg_type.size  += sizeof(%s);\n" %(group.lower(), minor.lower()))
						o_f.write("\tgroup_%s.num            += %s_num_instances;\n" %(group.lower(), minor.lower()))
				o_f.write("\n")

			""" Start pushing fprintf into the source resposible for generating the database table """
			o_f.write("\tuint32_t *word_ptr;\n")
			o_f.write("\tint      byte_no  = 0;\n")
			o_f.write("\tFILE     *fp;\n\n")
			o_f.write("\tfp = fopen(\"%s\", \"w\");\n\n" %(out_database))
			temp_out_file = out_database
			while '/' in temp_out_file:
				temp_out_file = "".join(temp_out_file[temp_out_file.find('/')+1:])
			o_f.write("\tfprintf(fp, \"#ifndef _%s_H_\\n\");\n" %(temp_out_file[:temp_out_file.find('.')].upper()))
			o_f.write("\tfprintf(fp, \"#define _%s_H_\\n\");\n\n" %(temp_out_file[:temp_out_file.find('.')].upper()))
			if section_name:
				o_f.write("\tfprintf(fp, \"__attribute__((section(\\\"%s\\\")))\\n\");\n" %(section_name))
			o_f.write("\tfprintf(fp, \"const uint32_t static %s[] = {\\n\");\n" %(table_name))
			o_f.write("\tfprintf(fp, \"0x%x\", \'T\');\n")
			o_f.write("\tfprintf(fp, \"%x\", \'B\');\n")
			o_f.write("\tfprintf(fp, \"%x\", \'S\');\n")
			o_f.write("\tfprintf(fp, \"%x,\\n\", \'A\');\n")
			o_f.write("\tfprintf(fp, \"0x%x\", \'_\');\n")
			o_f.write("\tfprintf(fp, \"%x\", \'C\');\n")
			o_f.write("\tfprintf(fp, \"%x\", \'F\');\n")
			o_f.write("\tfprintf(fp, \"%x,\\n\", \'G\');\n")
			required_target_name_len = 4
			new_target = target
			if (len(target) < required_target_name_len):
				while(required_target_name_len - len(target)):
					new_target += " "
					required_target_name_len -= 1
			o_f.write("\tfprintf(fp, \"0x%x\", ")
			o_f.write("\'%c\');\n" %(new_target[0:1]))
			o_f.write("\tfprintf(fp, \"%x\", ")
			o_f.write("\'%c\');\n" %(new_target[1:2]))
			o_f.write("\tfprintf(fp, \"%x\", ")
			o_f.write("\'%c\');\n" %(new_target[2:3]))
			o_f.write("\tfprintf(fp, \"%x,\\n\", ")
			o_f.write("\'%c\');\n" %(new_target[3:4]))
			o_f.write("\tfprintf(fp, \"0x%x\", \'_\');\n")
			o_f.write("\tfprintf(fp, \"%x\", \'C\');\n")
			o_f.write("\tfprintf(fp, \"%x\", \'F\');\n")
			o_f.write("\tfprintf(fp, \"%x,\\n\", \'G\');\n")
			o_f.write("\tuint32_t version = 1;\n")
			o_f.write("\tfprintf(fp, \"0x%08x,\\n\", version);\n")
			o_f.write("\tuint32_t total_size = 0;\n")
			for group in unique_major_groups:
				o_f.write("\ttotal_size += group_%s.cfg_type.size;\n" %(group.lower()))
			o_f.write("\ttotal_size += (8 + 8 + 4 + 4);\n")
			o_f.write("\tfprintf(fp, \"0x%08x,\\n\", total_size);\n")

			""" Start writing component values to database file """
			for group in unique_major_groups:
				o_f.write("\t/* Writing major group details to the file */\n")
				o_f.write("\tword_ptr = (uint32_t *)&group_%s;\n" %(group.lower()))
				o_f.write("\tfor(byte_no=0; byte_no<sizeof(group_%s); byte_no += 4) {\n" %(group.lower()))
				o_f.write("\t\tfprintf(fp, \"0x%08x,\\n\", *word_ptr);\n")
				o_f.write("\t\tword_ptr++;\n")
				o_f.write("\t}\n")
				o_f.write("\t/* Writing minor group details to the file */\n")
				for minor in unique_minor_components:
					if group == minor_major_map[minor]:
						o_f.write("\tword_ptr = (uint32_t *)&%s[0];\n" %(minor.lower()))
						o_f.write("\tfor(byte_no=0; byte_no<sizeof(%s); byte_no += 4) {\n" %(minor.lower()))
						o_f.write("\t\tfprintf(fp, \"0x%08x,\\n\", *word_ptr);\n")
						o_f.write("\t\tword_ptr++;\n")
						o_f.write("\t}\n")
			o_f.write("\tfprintf(fp, \"0x%08x\\n\", 0xffffffff);\n")
			o_f.write("\tfprintf(fp, \"};\\n\\n\");\n")
			o_f.write("\tfprintf(fp, \"#endif\\n\");\n")
			o_f.write("\treturn 0;\n")
			o_f.write("}\n")
	except:
		print("Cannot open output file %s" %out_source)

get_minor_major_map()
generate_source()


import sys
import os
new_path = sys.path[0] + '\\monkeys'
sys.path.insert(1,new_path)
import threading
import time
import webbrowser
from Test_Ui_Functions import TestUiFunctionsClass as func
from Test_Ui_Functions import rangeErrorException
from ui_main import Ui_MainWindow
from guide_ui import Ui_GuideWindow
from test_ui_d.test_ui import Ui_TestWindow
from test_ui_d.in_device_infor import Ui_In_dev_infor
from test_ui_d.add_test_ui import Ui_Add_test
from PyQt5.QtWidgets import QApplication, QMainWindow,QMessageBox
from PyQt5 import QtCore, QtGui, QtWidgets
from functools import wraps
from datetime import datetime
from test_ui_d.add_point import Ui_addPointWindow

now_point_index = 1
now_drag_index = 1
nowp = 1
empty_error_code = 0
number_error_code = 1
range_error_code = 2
resolution_ration_error_code = 3
something_else_error_code = 4
have_not_connect_error_code = 5
not_successful_connected_error_code = 6

min_click_times = 1
max_click_times = 9999
min_interval_time = 0.1
max_interval_time = 99.9
min_drag_times_number = 1
max_drag_times_number = 9999
min_drag_during_time =0.1
max_drag_during_time = 9.9
min_drag_interval_time = 0.1
max_drag_interval_time = 99.9
x_rate = 1024
y_rate = 768
begin_connect_time = None
'''
    通过装饰器实现一个单例模式
    保证只有一个和窗体类功能类↓
'''
def singleton(cls):
    instances = {}
    @wraps(cls)
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance
def reset_test_window():
    test_window = t_window()
    test_window.setupUi(test_window)
    test_window.t_init()
class rangeErrorException(Exception):
    def __init__(self):
        pass
class TimeWaitThread(QtCore.QThread):
    test_window = None
    def __init__(self,t,parent = None):
        super(TimeWaitThread,self).__init__(parent)
        self.finished.connect(t.wait_about)
    def run(self):
        self.sleep(10)
class WaitConnect(QtCore.QThread):
    def __init__(self, t, parent=None):
        super(WaitConnect, self).__init__(parent)
        self.t = t
        self.finished.connect(t.after_connect)
    def run(self):
        self.t.successfully_connect = functions_class.connect()

class WaitMonkeyRunnerStart(QtCore.QThread):
    test_window = None
    def __init__(self,t,parent = None):
        super(WaitMonkeyRunnerStart,self).__init__(parent)
        self.finished.connect(t.wait_monkey)
    def run(self):
        self.sleep(6)
@singleton
class mywindow(QtWidgets.QMainWindow,Ui_MainWindow):
    #successfully_connect = 1

    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
    def click_guide_b(self):
        #print("打开引导界面")
        g_ui.show()
    def click_test_b(self):
        #print("打开测试界面")
        t_ui.t_init()
        t_ui.show()

    def click_feedback_b(self):
        webbrowser.open("https://link.jiandaoyun.com/f/5cb9215b196c2d1d50253635")
    def closeEvent(self,event):
        functions_class.close_monkeyrunner()
        functions_class.close_model()
        #print("close window")
        event.accept()
        #super(mywindow,self).closeEvent(event)

@singleton
class g_window(QtWidgets.QMainWindow,Ui_GuideWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        Ui_GuideWindow.__init__(self)
        self.setupUi(self)
    def click_left_b(self):
        print("引导界面图片左划")
        global nowp
        if(nowp == 1):
            nowp = 9
        else:
            nowp = nowp-1
        #g_ui.guidePictures.setPixmap(QtGui.QPixmap(":/gp/"+str(nowp)+".png"))
        g_ui.guidePictures.setStyleSheet("border-image: url(:/gp/"+str(nowp)+".png);")
        if (nowp == 1):
            g_ui.textEdit.setText("主界面如上图所示。")
        elif(nowp == 2):
            g_ui.textEdit.setText("打开测试界面，请先等待后台程序启动。然后点击连接按钮。")
        elif(nowp == 3):
            g_ui.textEdit.setText("点击“输入要测试的APP参数”按钮，输入各项参数。")
        elif (nowp == 4):
            g_ui.textEdit.setText("点击“选择测试”按钮，例如图中“单点点击测试”。")
        elif (nowp == 5):
            g_ui.textEdit.setText("这里以“完全随机”测试为例，点击“加入测试队列”按钮，确定测试队列后点击“测试队列创建完成”按钮")
        elif (nowp == 6):
            g_ui.textEdit.setText("返回到测试界面")
        elif (nowp == 7):
            g_ui.textEdit.setText("点击“开始测试”按钮，可以看到测试报告栏里已开始记录测试的报告")
        elif (nowp == 8):
            g_ui.textEdit.setText("如图，检测到异常！")
        elif (nowp == 9):
            g_ui.textEdit.setText("续上图，已在exception_1.txt文件中记录了本次测试队列。")
    def click_right_b(self):
        print("引导界面图片右划")
        global nowp
        if (nowp == 9):
            nowp = 1
        else:
            nowp = nowp + 1
        #g_ui.guidePictures.setPixmap(QtGui.QPixmap(":/gp/" + str(nowp) + ".png"))
        g_ui.guidePictures.setStyleSheet("border-image: url(:/gp/"+str(nowp)+".png);")
        if (nowp == 1):
            g_ui.textEdit.setText("主界面如上图所示。")
        elif(nowp == 2):
            g_ui.textEdit.setText("打开测试界面，请先等待后台程序启动。然后点击连接按钮。")
        elif(nowp == 3):
            g_ui.textEdit.setText("点击“输入要测试的APP参数”按钮，输入各项参数。")
        elif (nowp == 4):
            g_ui.textEdit.setText("点击“选择测试”按钮，例如图中“单点点击测试”。")
        elif (nowp == 5):
            g_ui.textEdit.setText("这里以“完全随机”测试为例，点击“加入测试队列”按钮，确定测试队列后点击“测试队列创建完成”按钮")
        elif (nowp == 6):
            g_ui.textEdit.setText("返回到测试界面")
        elif (nowp == 7):
            g_ui.textEdit.setText("点击“开始测试”按钮，可以看到测试报告栏里已开始记录测试的报告")
        elif (nowp == 8):
            g_ui.textEdit.setText("如图，检测到异常！")
        elif (nowp == 9):
            g_ui.textEdit.setText("续上图，已在exception_1.txt文件中记录了本次测试队列。")
@singleton
class t_window(QtWidgets.QMainWindow,Ui_TestWindow):
    max_x = 1024
    max_y = 768
    connect_thread = None
    successfully_connect = None
    time_counter_thread = None
    wait_monkey_thread = None
    rate_tuple = None
    #begin_connect_time = None
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        Ui_TestWindow.__init__(self)
        self.setupUi(self)
        self.connectDeviceButton.setEnabled(False)
        self.connectDeviceButton.setText('等待相关部件启动')
        self.wait_monkey_thread = WaitMonkeyRunnerStart(self)
        self.wait_monkey_thread.start()
        #self.queueList.itemChanged.connect(self.not_empty_set)
    def wait_monkey(self):
        self.connectDeviceButton.setEnabled(True)
        self.connectDeviceButton.setText('连接设备')
    def closeEvent(self,e):
        if(self.connectDeviceButton.text() == '连接中...'):
            e.ignore()
    def after_connect(self):
        if (isinstance(self.successfully_connect, tuple)):
            self.max_x = int(self.successfully_connect[0])
            self.max_y = int(self.successfully_connect[1])
            # self.rate_tuple = self.su
            self.InputAssignmentButton.setEnabled(True)
            self.connectDeviceButton.setEnabled(False)
            self.loadButton.setEnabled(True)
            self.connectDeviceButton.setText('已成功连接')
            # self.connectDeviceButton.setText("重新连接")
        elif (self.successfully_connect == False):
            self.connectDeviceButton.setEnabled(True)
            # self.successfully_connect = None
            self.connectDeviceButton.setText('重新连接')
    def wait_about(self):
        if(self.successfully_connect == None):
            QMessageBox.about(self,'提示','连接时间过长，请检查您的环境配置和连接状态')
            self.connectDeviceButton.setEnabled(True)
            self.successfully_connect = None
            self.connectDeviceButton.setText('重新连接')

    def set_rate(self,x,y):
        global x_rate
        x_rate = x
        global y_rate
        y_rate = y
        self.max_x = x
        self.max_y = y
    def not_empty_set(self):
        if(self.queueList.count() == 0):
            self.saveButton.setEnabled(False)
            self.loadButton.setEnabled(True)
        else:
            self.loadButton.setEnabled(False)
            self.saveButton.setEnabled(True)
            self.startButton.setEnabled(True)
    def click_in_index_b(self):
        i_d_window = in_dev_infor()
        i_d_window.xPositionValue.setPlaceholderText('手机分辨率:'+ str(self.max_x))
        i_d_window.yPositionValue.setPlaceholderText('手机分辨率:'+ str(self.max_y))
        #print("点击 输入app参数 按钮")
        i_d_ui.show()
    def click_add_test(self):
        #print("点击 选择测试类型 按钮")
      #  a_t_ui.now_point_num.hide()
        a_t_ui.v_m_touch_point_num.setProperty("value", 1)
        a_t_ui.v_m_touch_point_num.show()
        a_t_ui.confirmMultiTouchTestButton.show()

        '''a_t_ui.now_drag_num.hide()
        a_t_ui.v_m_drag_num.setProperty("value", 1)
        a_t_ui.v_m_drag_num.show()'''
        #a_t_ui.confirm_m_drag_n_b.show()
        a_t_ui.confirmMultiDragButton.show()
        a_t_ui.show()
    def click_add_point_b(self):
        a_p_ui.show()

    def t_init(self):
        t_ui.loadButton.show()
        t_ui.saveButton.show()
        t_ui.startButton.show()
        t_ui.pauseButton.hide()
        t_ui.resumeButton.hide()
        t_ui.stopButton.hide()
        #t_ui.InputAssignmentButton.setEnabled(True)

        t_ui.chooseTypeButton.setEnabled(False)
        '''
            if debug
        '''
        #t_ui.chooseTypeButton.setEnabled(True)
    def thread_waitingfor_connect(self):
        while(self.successfully_connect == None ):
            self.successfully_connect = functions_class.connect()
            if(isinstance(self.successfully_connect,tuple)):
                test_window = t_window()
                self.max_x = int(self.successfully_connect[0])
                self.max_y = int(self.successfully_connect[1])
                #self.rate_tuple = self.su
                self.InputAssignmentButton.setEnabled(True)
                self.connectDeviceButton.setEnabled(False)
                self.loadButton.setEnabled(True)
                self.connectDeviceButton.setText('已成功连接')
                break
                #self.connectDeviceButton.setText("重新连接")
            elif(self.successfully_connect == False):
                self.connectDeviceButton.setEnabled(True)
                #self.successfully_connect = None
                self.connectDeviceButton.setText('重新连接')
                break

    '''点击连接设备按钮'''
    def click_connect_b(self):
        #print("点击连接设备按钮")

        self.connectDeviceButton.setText('连接中...')
        self.connectDeviceButton.setEnabled(False)

        '''self.connect_thread = threading.Thread(target = self.thread_waitingfor_connect)'''
        self.connect_thread = WaitConnect(self)
        self.connect_thread.start()

        self.time_counter_thread = TimeWaitThread(self)
        self.time_counter_thread.start()

        #elf.connectDeviceButton.setEnabled(()

    def click_load_b(self):
        test_window = t_window()
        print("点击读档按钮")
        functions_class.load()
        if(test_window.queueList.count() == 0):
            test_window.saveButton.setEnabled(False)
            test_window.loadButton.setEnabled(True)
        else:
            test_window.loadButton.setEnabled(False)
            test_window.saveButton.setEnabled(True)
            test_window.startButton.setEnabled(True)
    def click_save_b(self):
        print("点击存档按钮")
        functions_class.save()
    def click_start_b(self):
        self.chooseTypeButton.setEnabled((False))
        functions_class.start()
        print("点击开始按钮")
    def click_pause_b(self):
        self.pauseButton.setEnabled(False)
        functions_class.pause()
        self.resumeButton.setEnabled(True)
        #functions_class.test_found_exception()
        print("点击暂停按钮")
    def click_resume_b(self):
        self.resumeButton.setEnabled(False)
        functions_class.resume()
        self.pauseButton.setEnabled(True)

        print("点击继续按钮")
    def click_stop_b(self):
        if(self.stopButton.text() == '退出'):
            main_window = mywindow()
            main_window.close()
            self.close()
        self.chooseTypeButton.setEnabled((True))
        functions_class.stop()
        print("点击终止按钮")
@singleton
class in_dev_infor(QtWidgets.QDialog,Ui_In_dev_infor):
    has_finished = 0
    def __init__(self):
        QtWidgets.QDialog.__init__(self)
        Ui_In_dev_infor.__init__(self)
        self.setupUi(self)
    def click_fin_b(self):
        try:
            x_rate_value = int(self.xPositionValue.text())
            y_rate_value = int(self.yPositionValue.text())
            if not functions_class.judge_input_ration(x_rate_value,y_rate_value):
                raise rangeErrorException
            functions_class.set_monkey_ration(x_rate_value,y_rate_value)
            test_window = t_window()
            test_window.set_rate(x_rate_value,y_rate_value)
            if(self.packageNameValue.text() != '' and self.PackageActivityName.text() != ''):
                functions_class.open_app(self.packageNameValue.text(),self.PackageActivityName.text())
            if(i_d_ui.has_finished == 0):
                test_window.InputAssignmentButton.setText('重新输入')
                test_window.chooseTypeButton.setEnabled(True)

            self.has_finished = 1
        except ValueError:
            functions_class.error_message_prompt(self,empty_error_code)
        #reset_test_window()
        except rangeErrorException:
            functions_class.error_message_prompt(self,functions_class.logic_error_code,"分辨率超出手机本身分辨率：")
        '''test_window.loadButton.setEnabled(True)
        test_window.saveButton.setEnabled(True)
        test_window.startButton.setEnabled(True)'''
        self.close()
        #print("参数信息输入完毕")
@singleton
class add_test(QtWidgets.QDialog,Ui_Add_test):
    points_list_touch =None#初始化
    points_list_drag = None

    def __init__(self):

        QtWidgets.QDialog.__init__(self)

        Ui_Add_test.__init__(self)

        self.setupUi(self)
        #self.currentQueueList.clear()
        self.setFixedSize(self.width(),self.height())
        self.currentQueueList.setDragDropMode(self.currentQueueList.InternalMove)
        self.pointSelectComboBox.currentIndexChanged.connect(self.change_final_point_button_text)
        self.dragSelectComboBox.currentIndexChanged.connect(self.change_multi_drag_comboxBox)
        self.currentQueueList.clear()

    def delete_current_row(self):
        if(self.currentQueueList.count() == 0):
            return
        row = a_t_ui.currentQueueList.currentRow()
        if(row == -1):
            return
        #index = self.currentQueueList.currentIndex()
        print("删除第"+str(row+1)+"条测试")
        functions_class.delete_from_queue(row + 1)
        a_t_ui.currentQueueList.takeItem(row)
    #多点点击测试
    '''多点点击测试选项卡下的
        确定并加输入下一点 按钮
        先读取当前输入框内的内容
        按下按钮后 左边comboBox变为下一个点 然后继续输入
        如果已经是最后一个点 按钮文本变为"确定"
    '''
    def mul_touch_next_p(self):
        functions_class.mul_touch_next_p()
    '''
        多点测试的确定按钮
        按下以后 按钮文本变为“修改”
        同时左侧的文本框不可选定 直到再按下按钮
        设置点个数以后 下一行的comboBox里出现与个数相同的item 同时右边的按钮变为enbale
    '''
    def confirm_m_touch_p_num(self):
        #a_t_ui.now_point_num.setText(a_t_ui.v_m_touch_point_num.text())
        if(self.confirmMultiTouchTestButton.text() == '确定'):
            self.multiTouchNextPointButton.setEnabled(True)
            self.v_m_touch_point_num.setEnabled(False)
            self.confirmMultiTouchTestButton.setText('修改')
            self.pointSelectComboBox.clear()
            point_num = int(self.v_m_touch_point_num.text())
            self.points_list_touch = [(-1,-1) for p in range(point_num)]
            for i in range(1,point_num + 1):
                self.pointSelectComboBox.addItem("第%d点（未设置）"%i)
        else:
            self.confirmMultiTouchTestButton.setText('确定')
            self.v_m_touch_point_num.setEnabled(True)
    def reset_point_no(self):
        self.pointSelectComboBox.clear()
        self.pointSelectComboBox.addItem('未确认点的个数')
        self.confirmMultiTouchTestButton.setText('确定')
        self.multiTouchNextPointButton.setText('确定并输入下一个点')
        self.v_m_touch_point_num.setEnabled(True)
        self.multiTouchNextPointButton.setEnabled(False)

    #多端滑动测试

    '''多点点击测试选项卡下的
        确定并加输入下一点 按钮
        先读取当前输入框内的内容
        按下按钮后 左边comboBox变为下一个点 然后继续输入
        如果已经是最后一个点 按钮文本变为"确定"
    '''
    def mul_drag_next_l(self):

        '''global now_drag_index #注意
        if(now_drag_index < int(a_t_ui.now_drag_num.text())):
            now_drag_index = now_drag_index + 1
            text1 = "第" + str(now_drag_index)+"次滑动起点坐标:(X,Y)"
            text2 = "第" + str(now_drag_index) + "次滑动终点坐标:(X,Y)"
            a_t_ui.m_drag_start_p.setText(text1)
            a_t_ui.m_drag_end_p.setText(text2)'''
        functions_class.mul_drag_next_P()
    def change_final_point_button_text(self):
        if(self.pointSelectComboBox.count() == 0 or self.pointSelectComboBox.currentText == '未确认点的个数'):
            return
        if(self.pointSelectComboBox.currentIndex() == self.pointSelectComboBox.count() - 1):
            self.multiTouchNextPointButton.setText('确定')
        else:
            self.multiTouchNextPointButton.setText('确定并输入下一个点')
    def change_multi_drag_comboxBox(self):
        if(self.dragSelectComboBox.count() == 0 or self.dragSelectComboBox.currentText() == '待输入'):
            return
        if(not '待输入' in self.dragSelectComboBox.currentText()):
            points = self.points_list_drag
            index = self.dragSelectComboBox.currentIndex()
            self.v_m_drag_start_p_x.setText(str(points[index][0][0]))
            self.v_m_drag_start_p_y.setText(str(points[index][0][1]))
            self.v_m_drag_end_p_x.setText(str(points[index][1][0]))
            self.v_m_drag_end_p_y.setText(str(points[index][1][1]))
        else:
            self.v_m_drag_start_p_x.clear()
            self.v_m_drag_start_p_y.clear()
            self.v_m_drag_end_p_x.clear()
            self.v_m_drag_end_p_y.clear()
        if(self.dragSelectComboBox.currentIndex() == self.dragSelectComboBox.count() - 1):
            self.multiDragNextButton.setText('确定')
        else:
            self.multiDragNextButton.setText('确定并输入下次滑动')
    '''
        点击多线滑动的确定按钮
        和多点点击类似
        使左侧不可修改
    '''
    def confirm_m_drag_num(self):
        #a_t_ui.now_drag_num.setText(a_t_ui.v_m_drag_num.text())
        if(self.confirmMultiDragButton.text() == '确定'):
            self.confirmMultiDragButton.setEnabled(True)
            self.v_m_drag_num.setEnabled(False)
            self.confirmMultiDragButton.setText('修改')
            self.dragSelectComboBox.clear()
            drag_num = int(self.v_m_drag_num.text())
            self.points_list_drag = [((-1,-1),(-1,-1)) for p in range(drag_num)]
            for i in range(1,drag_num + 1):
                self.dragSelectComboBox.addItem("待输入滑动%d"%i)
            self.multiDragNextButton.setEnabled(True)
        else:
            self.confirmMultiDragButton.setText('确定')
            self.v_m_drag_num.setEnabled(True)
    def reset_drag_no(self):
        self.dragSelectComboBox.clear()
        self.dragSelectComboBox.addItem('待输入')
        self.multiDragNextButton.setText('确定并输入下一个点')

        self.confirmMultiDragButton.setText('确定')
        self.v_m_drag_num.setEnabled(True)
        self.multiDragNextButton.setEnabled(False)

    def add_new_test_b(self):
        test_w = t_window()
        test_w.InputAssignmentButton.setEnabled(False)
        if(a_t_ui.tabWidget.currentIndex() == 0):
            #print("加入单点点击测试")
            functions_class.add_single_point_test()
        elif(a_t_ui.tabWidget.currentIndex() == 1):
            #print("加入单点长按测试")
            functions_class.add_single_long_touch_test()
        elif (a_t_ui.tabWidget.currentIndex() == 2):
            functions_class.multi_touch_test()
            #print("加入多点点击测试")
        elif (a_t_ui.tabWidget.currentIndex() == 3):
            functions_class.random_touch_test()
            #print("加入随机点击测试")
        elif (a_t_ui.tabWidget.currentIndex() == 4):
            functions_class.drag_test()
            #print("加入单线滑动测试")
        elif (a_t_ui.tabWidget.currentIndex() == 5):
            functions_class.multi_drag_test()
            #print("加入多线滑动测试")
        elif (a_t_ui.tabWidget.currentIndex() == 6):
            functions_class.random_drag_test()
            #print("加入随机滑动测试")
        elif (a_t_ui.tabWidget.currentIndex() == 7):
            functions_class.long_touch_drag_test()
            #print("加入长按滑动测试")
        elif(self.tabWidget.currentIndex() == 8):
            functions_class.all_random_test()
    def update_queue_lists(self):
        test_window = t_window()
        queue_items = [self.currentQueueList.item(i).text() for i in range(self.currentQueueList.count())]
        #test_window.queueList.setFocus(True)
        test_window.tabWidget.setCurrentIndex(0)
        test_window.queueList.addItems(queue_items)
    def fin_queue_edit(self):
        test_window = t_window()
        #print("队列输入完毕")
        self.update_queue_lists()
        if(test_window.queueList.count() == 0):
            test_window.saveButton.setEnabled(False)
            test_window.loadButton.setEnabled(True)
        else:
            test_window.loadButton.setEnabled(False)
            test_window.saveButton.setEnabled(True)
            test_window.startButton.setEnabled(True)
        self.currentQueueList.clear()
        a_t_ui.close()

@singleton
class a_p_window(QtWidgets.QDialog,Ui_addPointWindow):
    global functions_class
    def __init__(self):
        QtWidgets.QDialog.__init__(self)
        Ui_addPointWindow.__init__(self)
        self.setupUi(self)
    def click_ap_b(self):
        functions_class.refresh()
        a_p_window.label.setPixmap(QtGui.QPixmap("refreshshot.png"))

if __name__ == '__main__':
    global functions_class

    app = QApplication(sys.argv)
    ui = mywindow()
    g_ui = g_window()

    t_ui = t_window()
    i_d_ui = in_dev_infor()
    a_t_ui = add_test()
    a_p_ui = a_p_window()
    functions_class = func(t_ui,a_t_ui)
    functions_class.read_exception()
    ui.show()
    sys.exit(app.exec_())
# queueList
# reportList


import aiohttp
from application.config import Config
from application.server import app
from gatco.response import json
import hashlib, binascii
from gatco_restapi.helpers import to_dict
from application.extensions import auth
from application.database import db, redisdb
from application.models.models import *
import random, string

def get_makehoach_new():
    makehoach = redisdb.spop("makehoach")
    if makehoach is None:
        generate_key(1000)
        makehoach = redisdb.spop("makehoach")
    return makehoach

def generate_key(size):
    arr_prekey = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20']
    for key in arr_prekey:
        data_key = 'prekey_makehoach_'+str(key)
        data_value = redisdb.get(data_key)

        if(data_value is not None):
            print(redisdb.smembers("prekey_makehoach_*"))
            print('generate key is exited!, please send other key')
            print(redisdb.keys("prekey_makehoach_*"))
            continue
        else:
            key_check = str(key)+'00000001'
            check_existed = db.session.query(KeHoachThanhTra).filter(KeHoachThanhTra.id == key_check).count()
            if(check_existed is not None and check_existed >0):
                continue
            redisdb.setnx(data_key, key)
        for x in range(0,size):
            value = key
            length = len(str(x))
            if length < 8:
                for i in range(0, (8-length)):
                    value += str('0')
            elif length>8:
                return False
            value += str(x)
            redisdb.sadd('makehoach', value)

#         print(redisdb.smembers("user_key"))
        total = redisdb.scard("makehoach")
        print('total_'+str(total))
#         print(redisdb.spop( "user_key"))
        return False
    return False

async def get_user_with_permission(user):
    user_info = to_dict(user)
    roles = [{"id":str(role.id),"description":role.description,"role_name":role.name} for role in user.roles]
    roleids = [role.id for role in user.roles]
    print("roles====",roles)
    user_info["roles"] = roles

    #permission:
#     perms = Permission.query.filter(Permission.role_id.in_(roleids)).order_by(Permission.subject).all()
#     permobj = {}
#
#     for perm in perms:
#         if perm.subject not in permobj:
#             permobj[perm.subject] = {}
#
#         if perm.permission not in permobj[perm.subject]:
#             permobj[perm.subject][perm.permission] = perm.value
#         elif not permobj[perm.subject][perm.permission]:
#             permobj[perm.subject][perm.permission] = perm.value
#     user_info["permission"] = permobj
    exclude_attr = ["password",  "created_at", "created_by", "updated_at", "updated_by",\
                        "deleted_by", "deleted_at", "deleted","salt","active","phone_country_prefix","phone_national_number"]

    for attr in exclude_attr:
        if attr in user_info:
            del(user_info[attr])
    return user_info

def check_content_json(request):
    ret = False
    try:
        content_type = request.headers.get('Content-Type', "")
        ret = content_type.startswith('application/json')
    except:
        pass
    return ret

def valid_phone_number(phone_number):
    if phone_number is None:
        return False
    if phone_number.isdigit() and len(phone_number)>=8 and len(phone_number)<=12 and phone_number.startswith("0"):
        return True
    return False

async def current_user(request):
    uid = auth.current_user(request)
    if uid is not None:
        user_info = db.session.query(User).filter(User.id == uid).first()
        return user_info
    else:
        return None

def auth_func(request=None, **kw):
    user = auth.current_user(request)
    if user is None:
        return json({"error_code":"SESSION_EXPIRED","error_message":"auth_func can not found uid"},status=520)

def deny_func(request=None, **kw):
    return json({"error_code":"PERMISSION_DENY","error_message":"permission deny"},status=520)

async def hasRole(request, role):
    currentUser = await current_user(request)
    if currentUser is not None:
        return currentUser.has_role(role)
    else:
        return False;

def current_uid(request):
    user_token = request.headers.get("X-USER-TOKEN", request.args.get("access_token", None))
    if user_token is None:
        return None
    uid = redisdb.get("sessions:" + user_token)
    if uid is not None:
        return uid.decode('utf8')

    return None

def generate_user_token(uid, expired_time=None):
    token = binascii.hexlify(uuid.uuid4().bytes).decode()
    if expired_time is None:
        expired_time = app.config.get('SESSION_EXPIRE_TIME', 86400)
    p = redisdb.pipeline()
    p.set("sessions:" + token, str(uid))
    p.expire("sessions:" + token, expired_time)
    p.execute()
    return token

def generator_salt():
    data = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(24))
    return data

async def get_account_kit(account_kit_token=None):
    # check account kit using token
    url = app.config.get("ACCOUNT_KIT_URL") + "/v1.3/me/"
#     account_kit_secret = app.config.get("FACEBOOK_ACCOUNT_KIT_SECRET")
#     dk = hashlib.pbkdf2_hmac('sha256', bytes(account_kit_token,'utf-8'), bytes(account_kit_secret,'utf-8'), 100000)
#     appsecret_proof = binascii.hexlify(dk)
    params = {
        'access_token': account_kit_token
    }
    async with aiohttp.ClientSession() as session:
        async with session.get(url, params=params) as response:
            print("get_account_kit.response===",response)
            if response.status == 200:
                resp = await response.json()
                print("====resp=====",resp)
                return resp
    return None

async def verify_account_kit(account_kit_token=None, data={}):
    # check account kit using token
    url = app.config.get("ACCOUNT_KIT_URL") + "/v1.3/me/"
    params = {
        'access_token': account_kit_token
    }
    async with aiohttp.ClientSession() as session:
        async with session.get(url, params=params) as response:
            if response.status == 200:
                resp = await response.json()
                if 'phone' in resp:
                    phone = resp['phone']
                    if (data["phone_number"] == phone['number']) or (data["phone_national_number"] == phone['national_number']):
                        data["phone_number"] = phone['number']
                        data["phone_country_prefix"] = phone['country_prefix']
                        data["phone_national_number"] = phone['national_number']
                        return True
    return False

async def verify_facebook_token(access_token=None, facebook_id=None):
    # check facebook using token
    return True

    if (facebook_id is None) or (access_token is None):
        return False

    url = app.config.get("FACEBOOK_GRAPH_URL") + "/me"
    params = {
        "fields": "id,name",
        'access_token': access_token
    }
    async with aiohttp.ClientSession() as session:
        async with session.get(url, params=params) as response:
            if response.status == 200:
                resp = await response.json()
                if 'id' in resp:
                    if resp['id'] == facebook_id:
                        return True
    return False


from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

DATABASE_URL = 'sqlite:///new.db'
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread":False})
Session = sessionmaker(bind=engine, autocommit=False, autoflush=False)
Base = declarative_base()

def get_db():
    db = Session()
    try:
        yield db
    finally:
        db.close()


# Makes the wordPatterns.py File
# http://inventwithpython.com/hacking (BSD Licensed)

# Creates wordpatterns.py based on the words in our dictionary
# text file, wordlist.txt.

import pprint

# Returns the word pattern for a given word, eg. "PUPPY" => "0.1.0.0.2"
def word_pattern(word):
    word = word.upper()
    next = 0
    letternums = {}
    wordpattern = []
    for letter in word:
        if letter not in letternums:
            letternums[letter] = str(next)
            next += 1
        wordpattern.append(letternums[letter])
    return '.'.join(wordpattern)

def main():
    allPatterns = {}

    fo = open('wordlist.txt')
    wordList = fo.read().splitlines()
    fo.close()

    for word in wordList:
        # Get the pattern for each string in wordList.
        pattern = word_pattern(word)

        if pattern not in allPatterns:
            allPatterns[pattern] = [word]
        else:
            allPatterns[pattern].append(word)

    # This is code that writes code. The 7-wordpatterns.py file contains
    # one very, very large assignment statement.
    fo = open('wordpatterns.py', 'w')
    fo.write('wpatterns = ')
    fo.write(pprint.pformat(allPatterns))
    fo.close()


#!/usr/bin/env python3
"""RTL-SDR P2000 Receiver for Home Assistant."""

# See README for installation instructions
import calendar
import configparser
import fnmatch
import json
import os
import re
import subprocess
import sys
import threading
import time
from datetime import datetime

import requests

VERSION = "0.0.1"

class MessageItem:
    """Contains all the Message data."""

    def __init__(self):
        self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.message_raw = ""
        self.timestamp = ""
        self.timereceived = time.monotonic()
        self.groupid = ""
        self.receivers = ""
        self.capcodes = []
        self.body = ""
        self.location = ""
        self.postcode = ""
        self.city = ""
        self.address = ""
        self.street = ""
        self.region = ""
        self.priority = 0
        self.disciplines = ""
        self.remarks = ""
        self.is_posted = False

def load_config():
    """Create default or load existing config file."""
    config = configparser.ConfigParser()
    if config.read("config.ini"):
        print("Loading configuration from 'config.ini'")
        return config

    config["main"] = {"debug": False}
    config["rtl-sdr"] = {
        "cmd": "rtl_fm -f 169.65M -M fm -s 22050 | multimon-ng -a FLEX -t raw -"
    }
    config["home-assistant"] = {
        "baseurl": "http://192.168.2.123:8123",
        "token": "Place Your Long-Lived Access Token Here",
        "sensorname": "P2000",
    }
    with open("config.ini", "w") as configfile:
        config.write(configfile)
    print("Created config file 'config.ini', edit it and restart the program.")
    sys.exit(0)

def check_requirements():
    """Check if required software is installed."""
    print("Checking if required software is installed")
    # Check if rtl_fm is installed
    process = subprocess.Popen(
        "rtl_fm", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    # Wait for the process to finish
    dummy, err = process.communicate()
    error_str = err.decode("utf8")
    if "not found" in error_str or "not recognized" in error_str:
        print("rtl_fm command not found, please install RTL-SDR software")
        return False

    print("rtl_fm is found")

    # Check if multimon-ng is installed
    process = subprocess.Popen(
        "multimon-ng -h", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    # Wait for the process to finish
    dummy, err = process.communicate()
    error_str = err.decode("utf8")
    if "not found" in error_str:
        print("multimon-ng not found, please install the multimon-ng package")
        return False

    print("multimon-ng is found")
    return True

def load_capcodes_dict(filename):
    """Load capcodes to dictionary."""
    capcodes = {}
    try:
        print("Loading data from '{}'".format(filename))
        with open(filename, "r") as csv_file:
            csv_list = [
                [val.strip() for val in r.split(",")] for r in csv_file.readlines()
            ]

        (_, *header), *data = csv_list
        for row in data:
            key, *values = row
            capcodes[key] = {key: value for key, value in zip(header, values)}
        print("{} records loaded".format(len(capcodes)))
    except KeyError:
        print(f"Could not parse file contents of: {filename}")
    except OSError:
        print(f"Could not open/read file: {filename}, ignore filter")

    return capcodes

def load_capcodes_filter_dict(filename):
    """Load capcodes ignore or match data to dictionary."""
    capcodes = dict()
    try:
        print("Loading data from '{}'".format(filename))
        with open(filename, "r") as text_file:
            lines = text_file.readlines()
            for item in lines:
                if item[0] == "#":
                    continue

                fields = item.split(",")
                if len(fields) == 2:
                    capcodes[fields[0].strip()] = fields[1].strip()
                elif len(fields) == 1:
                    capcodes[fields[0].strip()] = 'NO DESCR'
        print("{} records loaded".format(len(capcodes)))
        return capcodes
    except KeyError:
        print(f"Could not parse file contents of: {filename}")
    except OSError:
        print(f"Could not open/read file: {filename}, ignore filter")

    return capcodes

def load_list(filename):
    """Load data in list."""
    tmplist = []
    try:
        print("Loading data from '{}'".format(filename))
        with open(filename, "r") as text_file:
            lines = text_file.readlines()
            lines_strip = map((lambda line: line.strip()), lines)
            tmplist = list(
                filter(
                    lambda line: len(line) > 0
                    and line[0:1] != "#"
                    and line[0:1] != ";",
                    lines_strip,
                )
            )
        print("{} records loaded".format(len(tmplist)))
        return tmplist
    except KeyError:
        print(f"Could not parse file contents of: {filename}")
    except OSError:
        print(f"Could not open/read file: {filename}")

    return tmplist

def check_filter(mylist, text):
    """Check filter data."""
    # If list is not loaded or empty allow all
    if len(mylist) == 0:
        return True

    # Check if text applied matches at least one filter
    for f_str in mylist:
        if fnmatch.fnmatch(text, f_str):
            return True

    return False

def to_local_datetime(utc_dt):
    """Convert utc to local time."""
    time_tuple = time.strptime(utc_dt, "%Y-%m-%d %H:%M:%S")
    return time.ctime(calendar.timegm(time_tuple))

def p2000_get_prio(message):
    """Look for priority strings and return level."""
    priority = 0

    regex_prio1 = r"^A\s?1|\s?A\s?1|PRIO\s?1|^P\s?1"
    regex_prio2 = r"^A\s?2|\s?A\s?2|PRIO\s?2|^P\s?2"
    regex_prio3 = r"^B\s?1|^B\s?2|^B\s?3|PRIO\s?3|^P\s?3"
    regex_prio4 = r"^PRIO\s?4|^P\s?4"

    if re.search(regex_prio1, message, re.IGNORECASE):
        priority = 1
    elif re.search(regex_prio2, message, re.IGNORECASE):
        priority = 2
    elif re.search(regex_prio3, message, re.IGNORECASE):
        priority = 3
    elif re.search(regex_prio4, message, re.IGNORECASE):
        priority = 4

    return priority

class Main:
    """Main class, start of application."""

    def __init__(self):
        self.running = True
        self.messages = []

        print(f"RTL-SDR P2000 Receiver for Home Assistant Version {VERSION}\n")
        # Set current folder so we can find the config files
        os.chdir(os.path.dirname(os.path.abspath(__file__)))

        # Check if required software is installed
        if not check_requirements():
            print("Application stopped, required software was not found!")
            sys.exit(0)

        # Load configuration
        self.config = load_config()
        self.debug = self.config.getboolean("main", "debug")
        self.rtlfm_cmd = self.config.get("rtl-sdr", "cmd")
        self.baseurl = self.config.get("home-assistant", "baseurl")
        self.token = self.config.get("home-assistant", "token")
        self.sensorname = self.config.get("home-assistant", "sensorname")

        # Load capcodes data
        self.capcodes = load_capcodes_dict("db_capcodes.txt")

        # Load plaatsnamen data
        self.plaatsnamen = load_list("db_plaatsnamen.txt")

        # Load plaatsnamen afkortingen data
        self.pltsnmn = load_capcodes_dict("db_pltsnmn.txt")

        # Load capcodes ignore data
        self.ignorecapcodes = load_capcodes_filter_dict("ignore_capcodes.txt")

        # Load text ignore data
        self.ignoretext = load_list("ignore_text.txt")

        # Load match text filter data
        self.matchtext = load_list("match_text.txt")

        # Load match capcodes filter data
        self.matchcapcodes = load_capcodes_filter_dict("match_capcodes.txt")

        # Start thread to get data from RTL-SDR stick
        data_thread = threading.Thread(target=self.data_thread_call)
        data_thread.start()

        # Start thread to post messages to Home Assistant
        post_thread = threading.Thread(target=self.post_thread_call)
        post_thread.start()

        # Run the wait loop
        while True:
            try:
                time.sleep(1)
            except KeyboardInterrupt:
                break

        # Application is interrupted and is stopping
        self.running = False
        print("Application stopped")

    def post_to_homeassistant(self, msg):
        """Post data to Home Assistant via Rest API."""
        data = {
            "state": msg.body,
            "attributes": {
                "time received": msg.timestamp,
                "group id": msg.groupid,
                "receivers": msg.receivers,
                "capcodes": msg.capcodes,
                "priority": msg.priority,
                "disciplines": msg.disciplines,
                "raw message": msg.message_raw,
                "region": msg.region,
                "location": msg.location,
                "postcode": msg.postcode,
                "city": msg.city,
                "address": msg.address,
                "street": msg.street,
                "remarks": msg.remarks,
            },
        }

        try:
            headers = {
                "Authorization": "Bearer " + self.token,
                "content-type": "application/json",
            }

            response = requests.post(
                self.baseurl + "/api/states/sensor." + self.sensorname,
                headers=headers,
                data=json.dumps(
                    data, default=lambda o: o.__dict__, sort_keys=True, indent=4
                ),
            )
            response.raise_for_status()
            if self.debug:
                print(f"POST status: {response.status_code} {response.reason}")
                print(f"POST text: {response.text}")
        except requests.HTTPError:
            print(
                f"HTTP Error while trying to post data, check your baseurl and token in config.ini: {response.status_code} {response.reason}"
            )
        except requests.exceptions.SSLError as err:
            print(
                f"SSL Error occurred while trying to post data, check baseurl in config.ini:\n{err}"
            )
        except requests.exceptions.ConnectionError as err:
            print(
                f"Connection Error occurred while trying to post data, check your baseurl in config.ini:\n{err}"
            )
        finally:
            # Mark as posted to prevent race conditions
            msg.is_posted = True

    def data_thread_call(self):
        """Thread for parsing data from RTL-SDR."""
        print(f"RTL-SDR process started with: {self.rtlfm_cmd}")
        multimon_ng = subprocess.Popen(
            self.rtlfm_cmd, stdout=subprocess.PIPE, shell=True
        )
        try:
            while self.running:
                # Read line from process
                line = multimon_ng.stdout.readline()
                try:
                    line = line.decode("utf8", "backslashreplace")
                except UnicodeDecodeError:
                    if self.debug:
                        print(f"Error while decoding utf8 string: {line}")
                    line = ""
                multimon_ng.poll()
                if line.startswith("FLEX") and line.__contains__("ALN"):
                    line_data = line.split("|")
                    timestamp = line_data[1]
                    groupid = line_data[3].strip()
                    capcodes = line_data[4].strip()
                    message = line_data[6].strip()
                    priority = p2000_get_prio(message)
                    location = ""
                    postcode = ""
                    city = ""
                    address = ""
                    street = ""

                    if self.debug:
                        print(line.strip())

                    # Get address info if any, look for valid postcode and get the two words around them
                    # A2 (DIA: ja) AMBU 17106 Schiedamseweg 3134BA Vlaardingen VLAARD bon 8576
                    regex_address = r"(\w*.) ([1-9][0-9]{3}[a-zA-Z]{2}) (.\w*)"
                    addr = re.search(regex_address, message)
                    if addr:
                        street = addr.group(1)
                        postcode = addr.group(2)
                        city = addr.group(3)
                        address = f"{street} {postcode} {city}"

                    # Try to get city only when there is one after a prio
                    # A1 Breda
                    else:
                        regex_prio_loc = r"(^A\s?1|\s?A\s?2|B\s?1|^B\s?2|^B\s?3|PRIO\s?1|^P\s?1|PRIO\s?2|^P\s?2) (.\w*)"
                        loc = re.search(regex_prio_loc, message)
                        if loc and loc.group(2) in self.plaatsnamen:
                            city = loc.group(2)
                        else:
                            # Find all uppercase words and check if there is a valid city name amoung them
                            # A2 Ambulancepost Moordrecht Middelweg MOORDR V
                            regex_afkortingen = "[A-Z]{2,}"
                            afkortingen = re.findall(regex_afkortingen, message)
                            for afkorting in afkortingen:
                                if afkorting in self.pltsnmn:
                                    city = self.pltsnmn[afkorting]["plaatsnaam"]

                    if not check_filter(self.matchtext, message):
                        if self.debug:
                            print(
                                f"Message '{message}' ignored (didn't match match_text)")
                    else:
                        if check_filter(self.ignoretext, message):
                            if self.debug:
                                print(
                                    f"Message '{message}' ignored (matched ignore_text)")
                        else:
                            # There can be several capcodes in one message
                            ignore = False
                            for capcode in capcodes.split(" "):
                                # Apply filter
                                if not capcode in self.matchcapcodes and self.matchcapcodes:
                                    if self.debug:
                                        print(
                                            f"Message '{message}' ignored (didn't match match_capcodes)"
                                        )
                                    ignore = True
                                    break
                                if capcode in self.ignorecapcodes and self.ignorecapcodes:
                                    if self.debug:
                                        print(
                                            f"Message '{message}' to '{capcode}' ignored (capcode in ignore_capcodes)"
                                        )
                                    ignore = True
                                    break

                            if not ignore:
                                for capcode in capcodes.split(" "):
                                    # Get data from capcode, if exist
                                    if capcode in self.capcodes:
                                        receiver = "{} ({})".format(
                                            self.capcodes[capcode]["description"], capcode
                                        )
                                        discipline = "{} ({})".format(
                                            self.capcodes[capcode]["discipline"], capcode
                                        )
                                        region = self.capcodes[capcode]["region"]
                                        location = self.capcodes[capcode]["location"]
                                        remark = self.capcodes[capcode]["remark"]
                                    else:
                                        receiver = capcode
                                        discipline = ""
                                        region = ""
                                        remark = ""

                                    # If this message was already received, only add extra info
                                    if len(self.messages) > 0 and self.messages[0].body == message:
                                        if self.messages[0].receivers == "":
                                            self.messages[0].receivers = receiver
                                        elif receiver:
                                            self.messages[0].receivers += ", " + receiver

                                        if self.messages[0].disciplines == "":
                                            self.messages[0].disciplines = discipline
                                        elif discipline:
                                            self.messages[0].disciplines += ", " + discipline
                                        if self.messages[0].remarks == "":
                                            self.messages[0].remarks = remark
                                        elif remark:
                                            self.messages[0].remarks += ", " + remark

                                        self.messages[0].capcodes.append(capcode)
                                        self.messages[0].location = location
                                        self.messages[0].postcode = postcode
                                        self.messages[0].city = city
                                        self.messages[0].street = street
                                        self.messages[0].address = address
                                    else:
                                        msg = MessageItem()
                                        msg.groupid = groupid
                                        msg.receivers = receiver
                                        msg.capcodes = [capcode]
                                        msg.body = message
                                        msg.message_raw = line.strip()
                                        msg.disciplines = discipline
                                        msg.priority = priority
                                        msg.region = region
                                        msg.location = location
                                        msg.postcode = postcode
                                        msg.city = city
                                        msg.street = street
                                        msg.address = address
                                        msg.remarks = remark
                                        msg.timestamp = to_local_datetime(timestamp)
                                        msg.is_posted = False
                                        self.messages.insert(0, msg)

                                # Limit the message list size
                                if len(self.messages) > 100:
                                    self.messages = self.messages[:100]

        except KeyboardInterrupt:
            os.kill(multimon_ng.pid, 9)

        if self.debug:
            print("Data thread stopped")

    # Thread for posting data to Home Assistant
    def post_thread_call(self):
        """Thread for posting data."""
        if self.debug:
            print("Post thread started")
        while True:
            if self.running is False:
                break

            now = time.monotonic()
            for msg in self.messages:
                if msg.is_posted is False and now - msg.timereceived >= 1.0:
                    self.post_to_homeassistant(msg)
            time.sleep(1.0)
        if self.debug:
            print("Post thread stopped")

# Start application
Main()


import json
import numpy as np
from skimage import color

def modifiedDeltaE(l1, l2):
    return color.deltaE_ciede2000(l1, l2, 1E30, 1, 1)

def getProbabilities(groupsMean, groupsV):
    PMatrix = np.zeros((200, 200, len(groupsMean)))
    for i in range(-100, 100):
        print(i)
        for j in range(-100, 100):
            D = [np.exp(-modifiedDeltaE([0.0, m[0], m[1]], [0.0, i + 0.5, j + 0.5])**2 / groupsV[mi] / 2) for mi, m in enumerate(groupsMean)]
            sumRec = sum(D)
            P = [a / sumRec for a in D]
            PMatrix[i + 100][j + 100] = P
    return PMatrix

def getLabGroups(groupsMean):
    labGroups = np.zeros((200, 200))
    for i in range(-100, 100):
        print(i)
        for j in range(-100, 100):
            D = [(modifiedDeltaE([0.0, m[0], m[1]], [0.0, i + 0.5, j + 0.5]), g) for g, m in enumerate(groupsMean)]
            D.sort()
            labGroups[i + 100][j + 100] = D[0][1]
    return labGroups

with open('groupMeans11.json', 'r') as f:
    means = json.load(f)
groupsNames = [g[0] for g in means]
groupsMean = [g[1] for g in means]

with open('groupVs11.json', 'r') as f:
    vs = json.load(f)
groupsV = [g[1] for g in vs]

P = getProbabilities(groupsMean, groupsV)
np.save('groupProb11.npy', P)

labGroups = getLabGroups(groupsMean)
np.save('labGroups11.npy', labGroups)


"""empty message

Revision ID: 93d33c6f7725
Revises: None
Create Date: 2016-04-21 02:08:06.362118

"""

# revision identifiers, used by Alembic.
revision = '93d33c6f7725'
down_revision = None

from alembic import op
import sqlalchemy as sa

import sqlalchemy_utils.types.encrypted

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.create_table('aws_pricing',
    sa.Column('offer', sa.String(length=63), nullable=False),
    sa.Column('version', sa.String(length=63), nullable=False),
    sa.Column('etag', sa.String(length=63), nullable=True),
    sa.Column('value', sa.BLOB(length=16000000), nullable=False),
    sa.PrimaryKeyConstraint('offer', 'version')
    )
    op.create_table('user',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('email', sa.String(length=64), nullable=True),
    sa.Column('firstname', sa.String(length=32), nullable=True),
    sa.Column('lastname', sa.String(length=32), nullable=True),
    sa.Column('password_hash', sa.String(length=128), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('email')
    )
    op.create_table('aws_key',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('id_user', sa.Integer(), nullable=False),
    sa.Column('key', sa.String(length=20), nullable=False),
    sa.Column('secret', sqlalchemy_utils.types.encrypted.EncryptedType(), nullable=False),
    sa.Column('pretty', sa.String(length=63), nullable=True),
    sa.Column('billing_bucket_name', sa.String(length=63), nullable=True),
    sa.Column('last_fetched', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['id_user'], ['user.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('user_session_token',
    sa.Column('id', sa.String(length=40), nullable=False),
    sa.Column('id_user', sa.Integer(), nullable=False),
    sa.Column('expires', sa.DateTime(), nullable=True),
    sa.ForeignKeyConstraint(['id_user'], ['user.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    ### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('user_session_token')
    op.drop_table('aws_key')
    op.drop_table('user')
    op.drop_table('aws_pricing')
    ### end Alembic commands ###


# import urllib.request
# #构建一个HTTPHandler处理器对象,支持处理HTTP请求
# #若在HttpHandler方法中增加参数debuglevel=1,会将 Debug Log也打开,这样程序在执行时,会把收包和抓包的报头自动打印,以便调试
# http_handler = urllib.request.HTTPHandler(debuglevel=1)
# #调用urllib.build_opener()方法,创建支持处理HTTP请求的opener对象
# opener = urllib.request.build_opener(http_handler)
# #构建Request请求
# request = urllib.request.Request('http://www.baidu.com/')
# #调用自定义的opener对象的open()方法,发送request请求
# #(注意区别: 不再通过urllib.request.urlopen()发送请求)
# response = opener.open(request)
# #获取服务器响应内容
# print(response.read())
from urllib import request,parse
url = 'http://www.itcast.cn'
headers={
	'User-Agent':'Mozilla/5.0 (comoatible;MSIE 9.0;windows NT6.0;Trident/5.0)',
	'Host':'httpbin.org'
}
dict_demo = {'name':'itcast'}
data = bytes(parse.urlencode(dict_demo).encode('utf-8'))
requestcontent = request.Request(url,headers=headers,data=data)
respons = request.urlopen(requestcontent)
html = respons.read().decode('utf-8')
print(html)


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from segregation import Segregation
from termcolor import colored
import progressbar
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats
import scipy as sp
import argparse

def mean_confidence_interval(data, confidence=0.95):
    a = 1.0*np.array(data)
    n = len(a)
    m, se = np.mean(a), scipy.stats.sem(a)
    h = se * sp.stats.t._ppf((1+confidence)/2., n-1)
    return m, m-h, m+h

# Setup - Getting user arguments
parser = argparse.ArgumentParser(description='Segregation using potential differential.')
parser.add_argument('--robots', help='Total number of robots.', default=50, type=int)
parser.add_argument('--groups', help='Total number of group of robots.', default=5, type=int)
parser.add_argument('--iterations', help='Total number of iterations on the control.', default=200, type=int)
# Reduce the steps if the robots are too shaky
parser.add_argument('--behavior', help='Choice between cluster (default) and radial', default="cluster", type=str)
parser.add_argument('--steps', help='Time-step on the control.', default=0.08, type=int)
parser.add_argument('--world', help='Size of the enviroment in meters', default=30, type=int)
parser.add_argument('--alpha', help='Control gain. See the paper for more information.', default=1.0, type=float)
parser.add_argument('--dAA', help='Same-type robot interaction factor. See the paper for more information.', default=2.0, type=float)
parser.add_argument('--dAB', help='Differente-type robot interaction factor. See the paper for more information.', default=5.0, type=float)
parser.add_argument('--noise_sensor', help='Add gaussian noise (max 1.0) on sensor model.', default=0.0, type=float)
parser.add_argument('--noise_actuation', help='Add gaussian noise (max 1.0) on actuator model.', default=0.0, type=float)
parser.add_argument('--sensing_radius', help='Limit the sensing radius.', default=100000000.0, type=float)
parser.add_argument('--seed', help='Random seed.', default=0, type=int)
args = parser.parse_args()

bar = progressbar.ProgressBar(maxval=args.iterations,
                              widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])

print(colored("[Starting numeric simulation...]", 'green'))

# Radial segregation (check dAA)
if args.behavior == 'radial':
	s = Segregation(ROBOTS=args.robots, GROUPS=args.groups, WORLD=args.world, dt=args.steps, alpha=args.alpha,  noise_sensor=args.noise_sensor, noise_actuation=args.noise_sensor, dAA=np.linspace(args.dAA, args.groups*args.dAA, args.groups), dAB=args.dAB, seed=args.seed, radius=args.sensing_radius, display_mode=True, which_metric='')
else:
	# Cluster segregation
	s = Segregation(ROBOTS=args.robots, GROUPS=args.groups, WORLD=args.world, dt=args.steps, alpha=args.alpha,  noise_sensor=args.noise_sensor, noise_actuation=args.noise_sensor, dAA=np.array([args.dAA]), dAB=args.dAB, seed=args.seed, radius=args.sensing_radius, display_mode=True, which_metric='')

bar.start()
for j in range(args.iterations):
    bar.update(j)
    s.update()
    s.display()
	# s.screenshot("log/image_{:06d}.png".format(j))

# s.screenshot("radial.png")
plt.close('all')

print(colored("[Finish]", 'green'))


# Copyright (C) Fraunhofer FOKUS

# Created by Ranjan Shrestha (ranjan.shrestha@fokus.fraunhofer.de)

__author__ = 'rsh'

import os, json
import sys

rtt_avg = 0.
count_rtt = 0

# Check if user has specified a directory name
l = len(sys.argv) # count the arguments number
if l == 1:
	dirnames = [name for name in os.listdir(".") if os.path.isdir(name)]
elif l == 2:
	dirnames = [sys.argv[1]]
else:
	print ('Too many parameters. Terminating the program.')
	sys.exit(0)

print ('List of directories  {}'.format(dirnames))
for dirname in dirnames:
	json_files = [pos_json for pos_json in os.listdir(''.join(['./', dirname])) if pos_json.endswith('.json')]
	print('List of files in the folder {}: {} '.format(dirname, json_files))
	for filename in json_files:
		filepath = ''.join(['./', dirname, '/', filename])
		with open(filepath, "r") as f:
			for line in f:
				json_data = json.loads(line)
				if 'Rtt' in json_data:
					rtt_avg += json_data['Rtt']
					count_rtt += 1
			f.close()

if count_rtt != 0:
	print ("The average RTT is {} ms".format(rtt_avg/count_rtt))
	print ("Total number of items: {}".format(count_rtt))
else:
	print ("Cannot calculate average RTT value")


import requests
from bs4 import BeautifulSoup
from datetime import datetime
import re
import json
import pandas

def getNewsdetial(newsurl):
     res = requests.get(newsurl)
     res.encoding = 'utf-8'
     soup = BeautifulSoup(res.text,'html.parser')
     newsTitle = soup.select('.page-header h1')[0].text.strip()
     nt = datetime.strptime(soup.select('.time-source')[0].contents[0].strip(),'%Y %m %d %H:%M')
     newsTime = datetime.strftime(nt,'%Y-%m-%d %H:%M')
     newsArticle = getnewsArticle(soup.select('.article p'))
     newsAuthor = newsArticle[-1]
     return newsTitle,newsTime,newsArticle,newsAuthor
def getnewsArticle(news):
     newsArticle = []
     for p in news:
          newsArticle.append(p.text.strip())
     return newsArticle

def getCommentCount(newsurl):
     m = re.search('doc-i(.+).shtml',newsurl)
     newsid = m.group(1)
     commenturl = 'http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-{}&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20'
     comment = requests.get(commenturl.format(newsid))
     jd = json.loads(comment.text.lstrip('var data='))
     return jd['result']['count']['total']

def getNewsLinkUrl():
     urlFormat = 'http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page={}&callback=newsloadercallback&_=1501000415111'
     url = []
     for i in range(1,10):
         res = requests.get(urlFormat.format(i))
         jd = json.loads(res.text.lstrip('  newsloadercallback(').rstrip(');'))
         url.extend(getUrl(jd))
     return url

def getUrl(jd):
    url = []
    for i in jd['result']['data']:
         url.append(i['url'])
    return url

def getNewsDetial():
     title_all = []
     author_all = []
     commentCount_all = []
     article_all = []
     time_all = []
     url_all = getNewsLinkUrl()
     for url in url_all:
         title_all.append(getNewsdetial(url)[0])
         time_all.append(getNewsdetial(url)[1])
         article_all.append(getNewsdetial(url)[2])
         author_all.append(getNewsdetial(url)[3])
     commentCount_all.append(getCommentCount(url))
     total_2 = {'a_title':title_all,'b_article':article_all,'c_commentCount':commentCount_all,'d_time':time_all,'e_editor':author_all}
     return total_2

df = pandas.DataFrame(getNewsDetial())
df.to_excel('news2.xlsx')


import Node

class Tree():

    def __init__(self):
        self.root = Node.Node('root', 'root', 'root')
        self.cursor = self.root

    @staticmethod
    def read_tree(tree, nfile):
        story = open(nfile + ".txt")
        nodes = story.readlines()
        for lines in nodes:
            param = lines.split('|')
            node = Node.Node(param[1], param[2], param[0])
            positions = param[0].split("-")
            tree.root.push_node(positions, 0, node)