#! -*- coding: utf8 -*-
from html.parser import HTMLParser
from datetime import datetime
import os
import re
import json
import time

def yt_playerConf(lv, el) :
	YOUTUBE_DATA_PATTERN = re.compile(r'ytplayer.config\s*=\s*(?P<content>\{.+\})\s*;\s*ytplayer\.load')
	(tag,_id,_cls,_attrs,_children,_data) = el
	if len(_data)<=0 or _data[0] is None or len(_data[0])<=0 : return None
	mtch = YOUTUBE_DATA_PATTERN.search(_data[0])
	if mtch is None : return None
	return mtch.group('content')

def fb_page_dict(lv, el) :
	(tag,_id,_cls,_attrs,_children,_data) = el
	if _attrs is None : return None

	FACEBOOK_PAGE_ID_PATTERN = re.compile('fb://page/(\?id=)?(?P<uid>\d+)')
	FACEBOOK_PAGE_NAME_PATTERN = re.compile('\d+;\s+URL=/(?P<code>[^/\?]+)(/(?P<mtype>\w+)/(?P<mid>\d+).+)?.*\??')

	for (att_key, att_val) in _attrs :
		if att_key == 'content' :
			id_match = FACEBOOK_PAGE_ID_PATTERN.search(att_val)
			name_match = FACEBOOK_PAGE_NAME_PATTERN.search(att_val)
			if id_match is not None :
				return id_match.groupdict()
			elif name_match is not None :
				return name_match.groupdict()
	return None

def fb_post_dict(lv, el) :
	(tag,_id,_cls,_attrs,_children,_data) = el
	if _data is None or len(_data)<=0 : return None

	FACEBOOK_POST_UID_PATTERN = re.compile('"page_id":"(?P<uid>\d+)"');
	dt_match = FACEBOOK_POST_UID_PATTERN.search(_data[0])

	if dt_match is not None :
		return dt_match.groupdict()
	return None

def tw_post(lv, el) :
	(tag,_id,_cls,_attrs,_children,_data) = el

	if _attrs is None : return None

	values = dict()
	for k,v in _attrs :
		if k[0:5] == 'data-' :
			values[k[5:]] = v
	if 0<len(values) :
		return values
	return None

class Xax(HTMLParser) :
	FB_UID_PATTERN = re.compile('ownerid"?\s*:\s*"(?P<uid>\d+)"')
	FB_MID_PATTERN = re.compile('sharefbid"?\s*:\s*"(?P<mid>\d+)"')
	FB_PERMALINK_PATTERN = re.compile('permalink"?\s*:\s*"(?P<permalink>[^"]+)"')

	def __init__(self) :
		super().__init__()

		self._html_stack = list()
		self.__elements = list()

		document_root = self._element('document', None)
		self.document = document_root
		self._html_stack.append(document_root)

	def __iter__(self) :
		return self.__elements.__iter__()

	def __ig_user_dict(self, udata) :
		rets = {
			'channel': 'instagram',
			'uid': udata['id'],
			'code': udata['username'],
			'title': udata['full_name'],
			'profile': udata['profile_pic_url'],
			'url': 'https://www.instagram.com/%s/'%(udata['username']),
			'is_private': udata['is_private'],
			'is_verified': udata['is_verified'],
		}
		if 'biography' in udata : rets['description'] = udata['biography']
		if 'followed_by' in udata: rets['subscribers'] = udata['followed_by']['count']
		if 'follows' in udata: rets['followings'] = udata['follows']['count']
		if 'media' in udata: rets['uploads'] = udata['media']['count']
		return rets

	def __ig_post_dict(self, mdata) :
		mcode = None
		caption = None
		likes = None
		comments = None
		timestamp = None
		# media code
		if 'shortcode' in mdata : mcode = mdata['shortcode']
		elif 'code' in mdata : mcode = mdata['code']
		else :
			return None
		# caption
		if 'caption' in mdata: caption = mdata['caption']
		elif 'edge_media_to_caption' in mdata : caption = mdata['edge_media_to_caption']['edges'][-1]['node']['text']
		else : caption = None
		# likes
		if 'likes' in mdata : likes = mdata['likes']['count']
		elif 'edge_liked_by' in mdata: likes = mdata['edge_liked_by']['count']
		elif 'edge_media_preview_like' in mdata: likes = mdata['edge_media_preview_like']['count']
		# comments
		if 'comments' in mdata : comments = mdata['comments']['count']
		elif 'edge_media_to_comment' in mdata: comments = mdata['edge_media_to_comment']['count']

		if 'date' in mdata: timestamp = mdata['date']
		elif 'taken_at_timestamp': timestamp = mdata['taken_at_timestamp']

		rets = {
			'channel': 'instagram',
			'uid': mdata['owner']['id'],
			'mid': mdata['id'],
			'permalink': 'https://www.instagram.com/p/%s'%(mcode),
			'mtype': mdata['__typename'],
			'content': caption,
			'likes': likes,
			'comments': comments,
			'interactions': likes+comments if likes is not None and comments is not None else None,
			'published_at': timestamp
		}
		if 'thumbnail_src' in mdata: rets['thumbnail'] = mdata['thumbnail_src']
		if 'is_ad' in mdata: rets['is_ad'] = mdata['is_ad'];
		return rets

	def __yt_video_dict(self, playerConf, uid=None, code=None, mid=None) :
		if 'args' in playerConf :
			_arg = playerConf['args']

			if mid is None :
				return {
					'channel': 'youtube',
					'uid': _arg['ucid'],
					'code': _arg['ucid']
				}
			else :
				return {
					'channel': 'youtube',
					'uid': _arg['ucid'],
					'code': _art['ucid'],
					'mid': _arg['video_id'],
					'title': _arg['title'],
					'thumbnail': _arg['thumbnail_url'],
					'impressions': _arg['view_count']}

	def validate(self,channel,uid=None,code=None,mid=None) :
		if channel == 'instagram':
			return self.__validate_ig(uid,code,mid)
		elif channel == 'youtube':
			return self.__validate_yt(uid,code,mid)
		elif channel == 'facebook':
			return self.__validate_fb(uid,code,mid)
		elif channel == 'twitter':
			return self.__validate_tw(uid,code,mid)
		elif channel == 'naver':
			return self.__validate_nb(uid,code,mid)

	def ig_data(self) :
		def ig_sharedData(lv, el) :
			INSTAGRAM_DATA_PATTERN = re.compile(r'^(\s*window\.)?_sharedData\s*=\s*(?P<data>.+);$')
			(tag,_id,_cls,_attrs,_children,_data) = el
			if len(_data)<=0 or _data[0] is None or len(_data[0])<=0 : return None
			data = _data[0]
			mtch = INSTAGRAM_DATA_PATTERN.search(data)
			if mtch is None : return None

			return mtch.group('data')

		x,_sharedData = self.selector('script', None, None, ig_sharedData, True)
		try :
			_data = json.loads(_sharedData)
			entry_data = _data['entry_data']
			if 'ProfilePage' in entry_data:
				return entry_data['ProfilePage'][0]['user']
			elif 'PostPage' in entry_data:
				return entry_data['PostPage'][0]['graphql']['shortcode_media']
			elif 'TagPage' in entry_data:
				return entry_data['TagPage'][0]['graphql']['hashtag']
		except Exception as ex :
			pass
		return None

	def __validate_ig(self, uid, code, mid) :
		def ig_sharedData(lv, el) :
			INSTAGRAM_DATA_PATTERN = re.compile(r'^(\s*window\.)?_sharedData\s*=\s*(.+);$')
			(tag,_id,_cls,_attrs,_children,_data) = el
			if len(_data)<=0 or _data[0] is None or len(_data[0])<=0 : return None
			data = _data[0]
			mtch = INSTAGRAM_DATA_PATTERN.search(data)
			if mtch is None : return None

			return mtch.group(2)
		_sharedData = self.selector('script', None, None, ig_sharedData, True)
		if _sharedData is not None :
			_data = json.loads(_sharedData[1])
			entry_data = _data['entry_data']

			if 'ProfilePage' in entry_data :
				_profile = entry_data['ProfilePage'][0]
				_user = _profile['user']
				return self.__ig_user_dict(_user)
			elif 'PostPage' in entry_data :
				_media = entry_data['PostPage'][0]['graphql']['shortcode_media']
				return self.__ig_post_dict(_media)
			else :
				return None
	def __validate_yt(self, uid, code, mid) :
		playerConf = self.selector('script', None, None, yt_playerConf, True)
		if playerConf is not None :
			playerConf = re.sub('"', '\"', playerConf[1])
			_data = json.loads(playerConf, uid, code, mid)
			return self.__yt_video_dict(_data)
		return None
	def __validate_fb(self, uid, code, mid) :
		is_facebook = self.selector('html', 'facebook', None, None, True)
		values = None
		if is_facebook is not None :
			# load owner data
			uid_mt = self.selector('script',None, None,
				lambda lv,el: self.FB_UID_PATTERN.search(el[5][0]) if 0<len(el[5]) else None,
				True)
			mid_mt = self.selector('script',None, None,
				lambda lv,el: self.FB_MID_PATTERN.search(el[5][0]) if 0<len(el[5]) else None,
				True)
			link_mt = self.selector('script',None, None,
				lambda lv,el: self.FB_PERMALINK_PATTERN.search(el[5][0]) if 0<len(el[5]) else None,
				True)

			_uid = uid
			_mid = mid
			_permalink = None

			if uid_mt is not None and 1<len(uid_mt) :
				mtch = uid_mt[1]
				_uid = mtch.group('uid')
			if mid_mt is not None and 1<len(mid_mt) :
				mtch = mid_mt[1]
				_mid = mtch.group('mid')
			if link_mt is not None and 1<len(link_mt) :
				mtch = link_mt[1]
				_permalink = mtch.group('permalink')

			return {
				'channel':'facebook',
				'uid': _uid,
				'mid': _mid,
				'code': code,
				'permalink': 'https://www.facebook.com'+_permalink
			}
		else : return None

	def __validate_tw(self, uid, code, mid) :
		tweets = self.selector('div', None, ('tweet'), tw_post)
		users = dict()
		media = list()
		for tw in tweets :
			data = tw[1]
			_user = {
				'channel': 'twitter',
				'uid': data['user-id'],
				'code': data['screen-name'],
				'title': data['name']
			}
			if mid is None and code ==data['screen-name'] :
				return _user

			_media = {
				'channel': 'twitter',
				'uid': data['user-id'],
				'mid': data['item-id'],
				'permalink': data['permalink-path'],
				'owner': data['screen-name']
			}
			if mid is not None and mid == data['item-id'] :
				return _media
		return None

	def __validate_nb(self, uid, code, mid) :
		if self.document is not None and 0<len(self._html_stack) :
			if mid is None :
				return {
					'channel': 'naver',
					'uid': uid,
					'code': uid,
					'url': 'http://blog.naver.com/%s'%(uid)
				}
			else :
				return {
					'channel': 'naver',
					'uid': uid,
					'code': uid,
					'mid': mid,
					'permalink': 'http://blog.naver.com/%s/%s'%(uid,mid)
				}
		return None

	def selector(self, tag=None, _id=None, classes=None, fn=None, quick=False, _from=None) :
		if tag is None and _id is None and classes is None :
			return None

		_cls = None
		if isinstance(classes, list) :
			_cls = tuple(classes)
		elif classes is not None :
			_cls = [classes]

		found = list()
		level = 0
		stack = list()

		_from = _from if _from is not None else self.document
		stack.append((0, _from))

		while 0<len(stack) :
			(lv,el) = stack.pop(0)
			if el is True or el is False : continue
			if 4<=len(el) and 0<len(el[4]) :
				for c in el[4] :
					stack.append((lv+1, c))
			if tag is not None and 1<=len(el) and tag.lower()!=el[0].lower() : continue
			if _id is not None and 2<=len(el) and _id!=el[1] : continue
			if _cls is not None and 3<=len(el) and el[2] is not None :
				foundall = True
				for c in _cls :
					if c not in el[2] :
						foundall = False
						break
				if not foundall :
					continue

			if fn is not None :
				rs = fn(lv, el)
				if(rs is not None) :
					found.append((el, rs))
			else :
				found.append((el, None))

			if quick and 0<len(found) :
				return found[0]

		return found

	def _element(self, tagName, attrs) :
		_id = None
		_cls = None
		if attrs is not None :
			for (k,v) in attrs :
				if k.lower() == 'id' :
					_id = v
				elif k.lower() == 'class':
					_cls = v
		else :
			attrs = tuple()
		_el = (tagName,_id,_cls,attrs,[],[])

		self.__elements.append(_el)
		return _el

	def _append(self, parent, child) :
		#if parent[4] is None : parent[4] = list()
		parent[4].append(child)

	def __starttag(self, tag, attrs, data=None) :
		element = self._element(tag, attrs)
		self._append(self._html_stack[-1], element)

		return element

	def handle_starttag(self, tag, attrs) :
		element = self.__starttag(tag, attrs)
		if not (self._html_stack[-1][0].lower()=='head' and tag.lower() in ('meta','link')) :
			self._html_stack.append(element)

	def handle_startendtag(self, tag, attrs) :
		self.__starttag(tag, attrs)

	def handle_endtag(self, tag) :
		element = self._html_stack.pop()

	def handle_data(self, data) :
		if data is None or len(data)<=0 or len(self._html_stack)<=0 : return
		self._html_stack[-1][5].append(data)

	def handle_comment(self, data) :
		#self._html_stack[-1][5].append(data)
		pass

	def unknown_decl(self, data) :
		self._html_stack[-1][5].append(data)

	def __pretty_print_element(self, element) :
		buf = ''
		if 0<len(element[4]):
			buf += '+'
		else :
			buf += '-'

		buf += ' '+element[0]

		if element[1] is not None :
			buf += '#'+element[1]
		if element[2] is not None :
			buf += '.' + '.'.join(element[2].split('\s+'))
		if 0<len(element[5]) :
			buf += ' ;'
			if 12<len(element[5][0]) :
				buf += element[5][0][0:12] + '...'
			else :
				buf += element[5][0]
		return buf

	def pretty_print(self) :
		stack = list()
		stack.append((0, self.document))
		while 0<len(stack) :
			(level, cursor) = stack.pop()
			line = ''
			for i in range(0, level) : line += ' '
			if 0<len(cursor[4]) :
				line += self.__pretty_print_element(cursor)
				for child in cursor[4] :
					stack.append((level+1, child))
			else :
				line += self.__pretty_print_element(cursor)
			print(line)

	def attribute(self, el, keyname) :
		for (k,v) in el[3]:
			if k == keyname :
				return v
		return None

	def inner_text(self, el, includeLink=False, includeMedia=False) :
		stack = list()
		stack.append((0, el))
		text = list()
		while 0<len(stack) :
			(level, cursor) = stack.pop()
			# append content
			if 5<len(cursor) and 0<len(cursor[5]) :
				text += cursor[5]
			if includeLink and cursor[0] == 'a' :
				text.append('[%s|%s]'%(cursor[0], self.attribute(cursor, 'href')))
			if includeMedia and cursor[0] in ('img','embed','video') :
				text.append('[%s|%s]'%(cursor[0], self.attribute(cursor, 'src')))
			if 4<len(cursor) and 0<len(cursor[4]) :
				stack += [(level+1, child) for child in cursor[4]]
		return text

	def nb_subscribers(self) :
		# buddy_cnt_admin element
		rs = self.selector('div', None, 'function_box', None, True)
		if len(rs)<=0 : return None
		(cnt_admin,x) = rs
		cnt_e = self.selector('strong', None, None, None, True, cnt_admin)
		if len(cnt_e)<=1:
			return None
		(cnt_count,x) = cnt_e

		# lists
		(fr_list,x) = self.selector('ul', None, 'my_buddy_list',None,True)
		_frs = list()
		for (li,x) in self.selector('li', None,None,None,False,fr_list) :
			try :
				(nd,x) = self.selector('a',None,'buddy_name',None,True,li)
				(thumb,x) = self.selector('img',None,None,None,True,li)
				(dd,x) = self.selector('a',None,'blog_name',None,True,li)
				_url = self.attribute(nd,'href')
				_uid = _url[_url.rfind('/')+1:]

				_frs.append({
					'uid': _uid,
					'title': nd[5][0].strip(),
					'url': _url,
					'profile': self.attribute(thumb,'src'),
					'description': dd[5][0].strip(),
				})
			except Exception as ex :
				continue
		return {
			'count': int(cnt_count[5][0]),
			'list': _frs
		}

	def nb_followings(self) :
		rs = self.selector('div', None, 'function_box', None, True)
		if len(rs)<=0 : return None

		cnt_e = self.selector('p',None,'desc',None,True,rs[0])
		if len(cnt_e)<=1 : return None
		(cnt_admin,x) = cnt_e
		em = cnt_admin[4][0]
		_frs = list()
		fr_list = self.selector('ul', None, 'my_buddy_list',None,True)
		for (li,x) in self.selector('li', None,None,None,False,fr_list[0]) :
			try :
				ndx = self.selector('a',None,'buddy_name',None,True,li)
				if len(ndx)<=1 : continue
				(nd,x) = ndx
				tmx = self.selector('img',None,None,None,True,li)
				if len(tmx)<=1 : continue
				(thumb,x) = tmx
				ddx = self.selector('a',None,'blog_name',None,True,li)
				if len(ddx)<=1 : continue
				(dd,x) = ddx
				_url = self.attribute(nd,'href')
				_uid = _url[_url.rfind('/')+1:]

				_frs.append({
					'uid': _uid,
					'title': nd[5][0].strip(),
					'url': _url,
					'profile': self.attribute(thumb,'src'),
					'description': dd[5][0].strip(),
				})
			except Exception as ex :
				continue
		return {
			'count': int(em[5][0]),
			'list': _frs
		}

	def nb_postinfo(self,mid) :
		title_el = self.selector('meta',None,None,lambda lv,el: self.attribute(el, 'og:title'), True)
		(x, title) = title_el if title_el is not None and 1<len(title_el) else (None, None)
		thumb_el = self.selector('meta',None,None,lambda lv,el: self.attribute(el, 'og:image'), True)
		(x,thumb) = thumb_el if thumb_el is not None and 1<len(thumb_el) else (None, None)

		contents = self.selector(None,'post-view%s'%(mid),None,None,True)
		texts = self.inner_text(contents, True, True)
		(pdate,x) = self.selector('span',None,'se_publishDate',None,True)
		if pdate is None :
			(pdate,x) = self.selector('p',None,'date',None,True)
		dt = pdate[5][0].strip()
		return {
			'title': title,
			'thumbnail': thumb,
			'published_at': dt,
			'content': texts
		}

	def nb_comments(self) :
		cmts = list()
		cmt_list = self.selector('ul', 'commentList', None, None, True)
		for (li, x) in self.selector('li', None, None, lambda lv,el : None if 'reply' in el[2] else True, False, cmt_list) :
			first_child = li[4][0]
			if 'nonview' in first_child[2] :
				cmts.append(None)
			else :
				user_link = self.selector('a',None,'nick',None,True,li)
				profile = self.selector('img', None,None,None,True,li)
				date_span = self.selector('span',None,'date',None,True,li)
				text_span = self.selector('dd',None,'comm',None,True,li)
				_url = self.attribute(user_link,'href')
				_uid = _url[_url.rfind('/')+1:]

				cmts.append({
					'uid': _uid,
					'url': _url,
					'title': user_link[5][0],
					'profile': self.attribute(profile, 'src'),
					'ptime': datetime.strptime(date_span[5][0], '%Y.%m.%d %H:%M').timestamp(),
					'content': text_span[5][0]
				})
		next_page = None
		paginate = self.selector('div',None,'cc_paginate',None,None,True)
		if paginate is not None :
			current_page = None
			for pgs in paginate[4] :
				if current_page is not None and pgs[0].lower()=='a' :
					next_page = pgs[5][0]
				if pgs[0].lower() == 'strong' :
					current_page = pgs
					continue
		return {
			'count': len(cmts),
			'comments': cmts,
			'next': next_page
		}

	def nb_favorites(self) :
		favs = list()
		fav_list = self.selector('table',None,'lst',None,True)
		next_page = None
		if fav_list is not None and len(fav_list)<=0 :
			for (row,x) in self.selector('tr',None,None,None,False,fav_list) :
				try :
					th = row[4][0]
					td = row[4][1]
					tha = th[4][0]
					tda = td[4][0]
					_url = self.attribute(tha, 'href')
					dt = self.selector('span',None,'date',None,True,row)
					favs.append({
						'uid': _url[_url.rfind('/')+1:],
						'url': _url,
						'title': self.attribute(tda, 'title'),
						'description': self.attribute(tha, 'title'),
						'ptime': datetime.strftime(dt[5][0], '%Y.%m.%d. %H:%M').timestamp()
					})
				except : pass
			paginate = self.selector('table',None,'page-navigation',None,None,True)
			if paginate is not None :
				current_page = None
				for (pgs,x) in self.selector('a',None,None,None,False,paginate) :
					if current_page is not None and 3<len(pgs) and 'pcol2' in pgs[3] :
						next_page = int(pgs[5][0])
					if 3<len(pgs) and 'pcol3' in pgs[3] :
						current_page = int(pgs[5][0])
		return {
			'count': len(favs),
			'likes': favs,
			'next': next_page
		}

	def nb_searches(self) :
		amount_em = self.selector('em',None,'search_number',None,True)
		search_list = self.selector('div',None,'area_list_search',None,True)

		if search_list is None or len(search_list)<=0 :
			return {
				'amounts': 0,
				'count': 0,
				'list': []
			}

		posts = list()
		counts = 0
		url_pattern = re.compile('blog\.naver\.com/(?P<uid>[^/]+)/(?P<mid>[^/]+)')

		for (post,x) in self.selector('div',None,'info_post',None,False,search_list) :
			counts += 1
			try :
				hyperlink = self.selector('a',None,'desc_inner',None,True,post)
				profile = self.selector('img',None,'img_author',None,True,post)
				user_title = self.selector('em',None,'name_author',None,True,post)
				post_title = self.selector('span',None,'title',None,True,hyperlink)
				post_time = self.selector('span',None,'date',None,True,hyperlink)
				thumbnail = self.selector('img',None,'img_post',None,True,post)

				permalink = self.attribute(hyperlink, 'href')
				pdata = {
					'user': {
						'uid': None,
						'profile': self.attribute(profile, 'src'),
						'title': self.inner_text(user_title)
					},
					'post': {
						'mid': None,
						'permalink': permalink,
						'title': self.inner_text(post_title),
						'ptime': self.inner_text(post_time),
						'thumbnail': self.inner_text(thumbnail),
					}
				}

				mt = url_pattern.search(permalink)
				if mt is not None :
					pdata['user']['uid'] = mt.group('uid')
					pdata['post']['mid'] = mt.group('mid')
					posts.append(pdata)

			except: pass
		return {
			'amounts': self.inner_text(amount_em),
			'count': counts,
			'list': posts
		}

def parser(document) :
	p = Xax()
	p.feed(document)
	return p

# test
"""
import json
sample_folder = './example/'
INSTAGRAM_DATA_PATTERN = re.compile(r'^(\s*window\.)?_sharedData\s*=\s*(.+);$')

for fname in os.listdir(sample_folder) :
	with open(sample_folder+fname, 'r', encoding='utf8') as fin :
		print('[%s] %s'%(str(datetime.now()), fname))
		parser = Xax()
		parser.feed(fin.read())
		mt = re.search('^(\w+)\.', fname)
		if mt is not None :
			ch = mt.group(1)
			if ch == 'x': continue
			elif ch == 'youtube':
				#print(youtube(fname, parser))
				pass
			elif ch == 'instagram':
				#print(instagram(fname, parser))
				pass
			elif ch == 'facebook':
				#print(facebook(fname, parser))
				pass
			elif ch == 'twitter':
				print(twitter(fname, parser))
				#parser.pretty_print()

"""
# test closing


#!/usr/bin/python3

import redis

for x in range(2512):
    conn = redis.Connection(host="10.20.1.71", port=1339, socket_timeout=2)
    conn.connect()
    conn.send_command("ping")
    print(conn.read_response())


#!/usr/bin/env python
# encoding: utf-8

__auther__ = "kevin tsui"

from Katana import os, QtGui, QtCore, QT4Widgets, QT4FormWidgets, QT4Color, Utils
import UI4

import SettingWidget

Common2D = UI4.FormMaster.NodeHints.Common2D
__all__ = ['MonitorCCPanel']
_iconsDir = os.path.join(os.path.dirname(__file__), 'icons')

class kImageWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QLabel.__init__(self, parent)
        self.picture = None

        self.setMinimumSize(250,250)
        self.setMaximumSize(20480,8580)

    def setPixmap(self, picture):
        self.picture = picture

    def paintEvent(self, event):
        if self.picture:
            painter = QtGui.QPainter(self)
            painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform)
            width = self.parent().width()
            height = self.parent().height()
            if height >  (width * 429)/1024:
                rect = QtCore.QRect(0, (height-(width * 429)/1024)/2, width, (width * 429)/1024)
            else:
                rect = QtCore.QRect((width-(height * 1024)/429)/2, 0, (height * 1024)/429, height)
            painter.drawPixmap(rect, self.picture)

class kTitleLabel(QtGui.QLabel):
    resized = QtCore.pyqtSignal()
    def __init__(self, parent=None):
        QtGui.QToolButton.__init__(self, parent)
        self.resized.connect(self.setButtonGeometry)
        self.h = 40
        self.button = QtGui.QToolButton()
        self.button.setAutoRaise(True)
        self.button.setIconSize(QtCore.QSize(28,28))
        self.button.setParent(self)
    def resizeEvent(self, event):
        self.resized.emit()
        return super(kTitleLabel, self).resizeEvent(event)
    def setButtonGeometry(self):

        self.button.setGeometry(self.width()-self.h,0,self.h,self.h)
    def setIcon(self, path):
        self.button.setIcon(QtGui.QIcon(path))
    def setScript(self,function):
        self.button.clicked.connect(lambda arg=None,args=function:self.runScript(args))
    def runScript(self,script):
        exec (script)
    def setHeight(self,height):
        self.h = height
        self.setFixedHeight(height)

#UI4.Tabs.BaseTab
class ShotColorReference(UI4.Tabs.BaseTab):
    def __init__(self, parent):
        QtGui.QWidget.__init__(self, parent)
        QtGui.QVBoxLayout(self)

        self._pre_shot_name = None
        self._post_shot_name = None
        self._pre_shot_frame = None
        self._post_shot_frame = None
        self._pre_shot_frame_range = None
        self._post_shot_frame_range = None

        # add title
        commonLabel = kTitleLabel()
        commonLabel.setIcon(os.path.join(_iconsDir, "settings-work-tool.png"))
        commonLabel.button.clicked.connect(lambda arg=None,args=None:self.buttonScript())
        commonLabel.setHeight(40)
        commonLabel.setMinimumWidth(330)
        palette = QtGui.QPalette()
        palette.setColor(QtGui.QPalette.Background,QtGui.QColor(0.5*255,0.5*255,0.6*255))
        palette.setColor(QtGui.QPalette.WindowText,QtGui.QColor(0.0,0.0,0.0))
        commonLabel.setAutoFillBackground(True)
        commonLabel.setText("Lighting Shot Color Reference")
        commonLabel.setPalette(palette)
        commonLabel.setAlignment(QtCore.Qt.AlignCenter)
        commonLabel.setFont(QtGui.QFont("Rome times",10,QtGui.QFont.Bold))

        self.layout().setContentsMargins(0,0,0,0)
        self.layout().setSpacing(0)
        self.layout().addWidget(commonLabel)
        main_widget = self.create()
        scroll = QtGui.QScrollArea()
        scroll.setWidget(main_widget)
        scroll.setWidgetResizable(True)
        self.layout().addWidget(scroll)

        SettingWidget.init(self)

    def create(self):
        widget = QtGui.QWidget()
        widget_a = QtGui.QWidget()
        widget_b = QtGui.QWidget()
        palette = widget.palette()
        palette.setColor(widget.backgroundRole(), QtGui.QColor(0.14*255,0.14*255,0.14*255))
        widget.setPalette(palette)

        layout = QtGui.QVBoxLayout(widget)
        layout.setSpacing(5)
        layout.setContentsMargins(0,0,0,0)
        layout_a = QtGui.QVBoxLayout(widget_a)
        layout_b = QtGui.QVBoxLayout(widget_b)
        layout_a.setContentsMargins(10,10,10,10)
        layout_b.setContentsMargins(10,10,10,10)
        widget_line = QtGui.QFrame()
        widget_line.setFrameShape(QtGui.QFrame.HLine)
        widget_line.setFrameShadow(QtGui.QFrame.Sunken)
        layout.addWidget(widget_a)
        layout.addWidget(widget_line)
        layout.addWidget(widget_b)

        self.pre_shot_image = kImageWidget()
        pre_shot_image_path = os.path.join(_iconsDir, "no-image.svg")
        pixmap = QtGui.QPixmap(pre_shot_image_path)
        self.pre_shot_image.setPixmap(pixmap)

        self.post_shot_image = kImageWidget()
        post_shot_image_path = os.path.join(_iconsDir, "no-image.svg")
        pixmap = QtGui.QPixmap(post_shot_image_path)
        self.post_shot_image.setPixmap(pixmap)

        self.pre_shot_label = QtGui.QLabel()
        self.pre_shot_label.setFont(QtGui.QFont("Rome times", 6,QtGui.QFont.Bold))
        self.pre_shot_label.setText("Pre Shot : None")
        self.pre_shot_label.setAlignment(QtCore.Qt.AlignLeft)
        self.pre_shot_label.setGeometry(5,5,300,100)
        self.pre_shot_label.setParent(self.pre_shot_image)
        self.post_shot_label = QtGui.QLabel()
        self.post_shot_label.setFont(QtGui.QFont("Rome times", 6,QtGui.QFont.Bold))
        self.post_shot_label.setText("Post Shot : None")
        self.post_shot_label.setAlignment(QtCore.Qt.AlignLeft)
        self.post_shot_label.setGeometry(5,5,300,100)
        self.post_shot_label.setParent(self.post_shot_image)

        layout_a.addWidget(self.pre_shot_image)
        layout_b.addWidget(self.post_shot_image)

        return widget

    def buttonScript(self):
        reload(SettingWidget)
        SettingWidget.main(self)


#!/usr/bin/env python
# encoding: utf-8

import os

tooldir = os.path.dirname(__file__)

def options(ctx):
    ctx.load('wurf_tools')
    ctx.load('python')

    ctx.load_external_tool('utils', 'utils')

def configure(ctx):
    ctx.load('wurf_tools')
    ctx.load('python')

    ctx.load_external_tool('utils', 'utils')

    tools_node = ctx.root.find_dir(tooldir)
    if not tools_node:
        ctx.fatal('Unable to locate the google_closure tool directory.')
    ctx.env.CLOSURE_TOOLS = tools_node.abspath()

    closure_library_node = tools_node.find_dir('closure-library')
    if not closure_library_node:
        ctx.fatal('Unable to locate the closure library directory.')
    ctx.env.CLOSURE_LIBRARY = closure_library_node.abspath()

    # Locate closure library scripts
    closure_scripts_node = closure_library_node.find_dir('closure/bin/build')
    if not closure_scripts_node:
        ctx.fatal('''Unable to locate the closure library scripts directory.
Note: Did you run `git submodule init` and `git submodule update`''')
    ctx.env.CLOSURE_SCRIPTS = closure_scripts_node.abspath()

    try:
        ctx.find_python_program('closurebuilder', path_list=[ctx.env.CLOSURE_SCRIPTS], var='CLOSURE_BUILDER')
    except:
        ctx.fatal('Unable to locate the closurebuilder script in the closure library repository.')


from game.onlinelib.sockutils import *

def main(win, addr):
    if addr is None:
        return

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    addr = "192.168.0.200"

    try:
        sock.connect((addr, 9090))
    except:
        print("Cant Connect Server")
        return

    write(sock, "HELLO")
    msg = read()

    sock.close()


from flask_restful import Resource
from database import Database

class ApiGetSKUs(Resource):
    def get(self):
        conn = Database()

        cursor = conn.execute("""
            select skuid as tblskuid,
            refid as tblrefid,
            catid,
            sap_name as sku_name,
            case_barcode,
            product_barcode,
            gross_price_case,
            gross_price_piece,
            packs_or_bags,
            quantity_per_case,
            '.' as image_path
            from skus""",result=True)

        data  = [dict(((cursor.description[i][0]), value) for i, value in enumerate(row)) for row in cursor.fetchall()]
        # print('ApiGetSKUs > data',data)
        return data


"""Utility functions for Z-Wave JS nodes."""
import json
from typing import Optional, Union

from ..const import CommandClass, ConfigurationValueType
from ..exceptions import InvalidNewValue, NotFoundError, SetValueFailed
from ..model.node import Node
from ..model.value import ConfigurationValue, get_value_id

async def async_set_config_parameter(
    node: Node,
    new_value: Union[int, str],
    property_or_property_name: Union[int, str],
    property_key: Optional[Union[int, str]] = None,
) -> ConfigurationValue:
    """
    Set a value for a config parameter on this node.

    new_value and property_ can be provided as labels, so we need to resolve them to
    the appropriate key
    """
    config_values = node.get_configuration_values()

    # If a property name is provided, we have to search for the correct value since
    # we can't use value ID
    if isinstance(property_or_property_name, str):
        try:
            zwave_value = next(
                config_value
                for config_value in config_values.values()
                if config_value.property_name == property_or_property_name
            )
        except StopIteration:
            raise NotFoundError(
                "Configuration parameter with parameter name "
                f"{property_or_property_name} could not be found"
            ) from None
    else:
        value_id = get_value_id(
            node,
            CommandClass.CONFIGURATION,
            property_or_property_name,
            endpoint=0,
            property_key=property_key,
        )

        try:
            zwave_value = config_values[value_id]
        except KeyError:
            raise NotFoundError(
                f"Configuration parameter with value ID {value_id} could not be "
                "found"
            ) from None

    # Validate that new value for enumerated configuration parameter is a valid state
    # key or label
    if (
        zwave_value.configuration_value_type == ConfigurationValueType.ENUMERATED
        and str(new_value)
        not in [
            *zwave_value.metadata.states,
            *zwave_value.metadata.states.values(),
        ]
    ):
        raise InvalidNewValue(
            "Must provide a value that represents a valid state key or label from "
            f"{json.dumps(zwave_value.metadata.states)}"
        )

    # If needed, convert a state label to its key. We know the state exists because
    # of the validation above.
    if isinstance(new_value, str):
        new_value = int(
            next(
                key
                for key, label in zwave_value.metadata.states.items()
                if label == new_value
            )
        )

    if zwave_value.configuration_value_type == ConfigurationValueType.UNDEFINED:
        # We need to use the Configuration CC API to set the value for this type
        raise NotImplementedError("Configuration values of undefined type can't be set")

    # Validate that new value for range configuration parameter is within bounds
    max_ = zwave_value.metadata.max
    min_ = zwave_value.metadata.min
    if zwave_value.configuration_value_type == ConfigurationValueType.RANGE and (
        (max_ is not None and new_value > max_)
        or (min_ is not None and new_value < min_)
    ):
        bounds = []
        if min_ is not None:
            bounds.append(f"Min: {min_}")
        if max_ is not None:
            bounds.append(f"Max: {max_}")
        raise InvalidNewValue(
            f"Must provide a value within the target range ({', '.join(bounds)})"
        )

    # Finally attempt to set the value and return the Value object if successful
    if not await node.async_set_value(zwave_value, new_value, wait_for_result=True):
        raise SetValueFailed(
            "Unable to set value, refer to "
            "https://zwave-js.github.io/node-zwave-js/#/api/node?id=setvalue for "
            "possible reasons"
        )

    return zwave_value


# Python3 program imitating a clock server

from functools import reduce
from dateutil import parser
import ntplib
from time import ctime
import threading
import datetime
import socket
import time

# datastructure used to store client address and clock data
client_data = {}
K = 1

# Return NTP in seconds
def getNTP():
    c = ntplib.NTPClient()
    response = c.request('time.google.com', version=3)
    return parser.parse(ctime(response.tx_time))

CURRENT_TIME = getNTP()

# client thread function used to send time at client side
def startSendingTime(listening_client):

    print("OIOIOIOI", CURRENT_TIME, listening_client)

    while True:
        # provide server with clock time at the client
        listening_client.send(str(CURRENT_TIME).encode())

        print("Recent time sent successfully", end = "\n\n")

        time.sleep(5)

# client thread function used to receive synchronized time
def startReceivingTime(listening_client):

    while True:
        # receive data from the server
        Synchronized_time = parser.parse(listening_client.recv(1024).decode())

        print("HELP", listening_client.getpeername())

        print("Synchronized time at the process 2 is: " + str(Synchronized_time), end = "\n\n")

def startRecieveingClockTime(connector, address):

    while True:
        clock_time_string = connector.recv(1024).decode()
        clock_time = parser.parse(clock_time_string)
        clock_time_diff = getNTP()- clock_time

        print("Client time before syncronize", clock_time, "\n")

        if clock_time_diff.total_seconds() > K:
            synchronizeAllClocks()

        client_data[address] = {
            "clock_time": clock_time,
            "time_difference": clock_time_diff,
            "connector": connector,
        }

        print("Client Data updated with: "+ str(address), end = "\n\n")
        time.sleep(5)

''' master thread function used to open portal for
	accepting clients over given port '''
def startConnecting(main_socket):

    # fetch clock time at slaves / clients
    while True:
        # accepting a client / slave clock client
        master_slave_connector, addr = main_socket.accept()
        slave_address = str(addr[0]) + ":" + str(addr[1])

        print(slave_address + " got connected successfully")

        current_thread = threading.Thread(
            target=startRecieveingClockTime,
            args = (master_slave_connector, slave_address, )
        )

        current_thread.start()

# subroutine function used to fetch average clock difference
def getAverageClockDiff():

    current_client_data = client_data.copy()

    time_difference_list = list(client['time_difference'] for client_addr, client in client_data.items())

    sum_of_clock_difference = sum(time_difference_list, datetime.timedelta(0, 0))

    average_clock_difference = sum_of_clock_difference / len(client_data)

    return average_clock_difference

''' master sync thread function used to generate
	cycles of clock synchronization in the network '''
def synchronizeAllClocks():

    while True:

        print("New synchroniztion cycle started.")
        print("Number of clients to be synchronized: " + str(len(client_data)))

        if len(client_data) > 0:

            average_clock_difference = getAverageClockDiff()

            for client_addr, client in client_data.items():
                try:
                    synchronized_time = getNTP() + average_clock_difference

                    print("Client new syncronized time ", synchronized_time)

                    client['connector'].send(str(synchronized_time).encode())

                except Exception as e:
                    print("Something went wrong while sending synchronized time through " + str(client_addr))

        else:
            print("No client data. Synchronization not applicable.")

        print("\n\n")

        time.sleep(5)

# function used to Synchronize client process time
def connectToProccess(port):

    listening_client = socket.socket()

    # connect to the clock server on local computer
    connection = listening_client.connect_ex(('127.0.0.1', port))

    while connection is not 0:
        connection = listening_client.connect_ex(('127.0.0.1', port))

    # start sending time to server
    print("Starting to receive time from server\n")
    send_time_thread = threading.Thread(target = startSendingTime, args = (listening_client, ))

    send_time_thread.start()

    # start recieving synchronized from server
    print("Starting to recieving synchronized time from server\n")

    receive_time_thread = threading.Thread(target = startReceivingTime, args = (listening_client, ))
    receive_time_thread.start()

# function used to initiate the Clock Server / Master Node
def initiateClockServer():

    main_socket = socket.socket()
    main_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    print("Socket at master node created successfully\n")

    main_socket.bind(('', 8081))

    # Start listening to requests
    main_socket.listen(10)
    print("Clock server started...\n")

    # start making connections
    print("Starting to make connections...\n")
    main_socket_thread = threading.Thread(target = startConnecting, args = (main_socket, ))
    main_socket_thread.start()

    # start synchroniztion
    print("Starting synchronization parallely...\n")
    sync_thread = threading.Thread(target = synchronizeAllClocks, args = ())
    sync_thread.start()

    connectToProccess(8080)
    connectToProccess(8082)
    connectToProccess(8083)

# Driver function
if __name__ == '__main__':

	# Trigger the Clock Server
	initiateClockServer()


from csxtools.image import rotate90
import numpy as np
from numpy.testing import assert_array_equal

def test_rotate90():
    x = np.arange(4*20, dtype=np.float32).reshape(4, 20)
    y = rotate90(np.array([x, x, x, x]), 'ccw')
    for i in y:
        assert_array_equal(i, np.rot90(x, 1))

    y = rotate90(np.array([x, x, x, x]), 'cw')
    for i in y:
        assert_array_equal(i, np.rot90(x, -1))


from django.urls import path
from bidding import views

app_name = 'bidding'

urlpatterns = [
    path('home/', views.home, name ='home'),
    path('', views.login_page, name='login'),
    path('register_user/', views.register_user, name='register_user'),
    path('logout/', views.logout_user, name='logout_user'),
    path('user_bid/<int:p_id>/', views.user_bid, name='user_bid'),
    path('bid_list/<int:p_id>/', views.bid_list, name='bid_list'),

]


#! /usr/bin/python3
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
# File name: <+FILE NAME+>
# First Edit: <+DATE+>
# Last Change: 14-Sep-2017.

'''
question
'<+CURSOR+>'
data

ans

'''

# from __future__ import print_function
# import os
# import sys
# from collections import deque, Counter
# import itertools

def input_l(N=1, type=0, str=' '):
    data = []
    for i in range(N):
        if type == 0:
            data.extend(list(map(int, input().split(str))))
        elif type == 1:
            data.extend(input().split(str))
        elif type == 2:
            data.extend([list(map(int, input().split(str)))])
        elif type == 3:
            data.append(input().split(str))
    return data

N = []
data = []

'''
raw_data = input_l()
N = int(raw_data[0])
print(N)
data = input_l(N, 3)
print(data)
'''

ans = []
print(ans)

'''
 if __name__ == "__main__":
    execute only if run as a script
    main()
'''


#!/usr/bin/env python
import os
import sys

import dotenv

dotenv.read_dotenv()

if __name__ == "__main__":
	ENVIRONMENT = os.getenv('ENVIRONMENT')

	if ENVIRONMENT == 'STAGING':
		settings = 'staging'
	elif ENVIRONMENT == 'PRODUCTION':
		settings = 'local'
	else:
		settings = 'development'

	os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tienda.settings")

	from django.core.management import execute_from_command_line

	execute_from_command_line(sys.argv)


import logging
from abc import abstractmethod
from typing import Mapping, Sequence

from ..core.base import ExecutorEntity, LoggingEntity
from ..core.formatter import FormattedEntity
from ..http import URL
from ..net.web.client import Session
from . import StorageError, base

class StorageConnectionError(StorageError):
    pass

class StorageDataFormatError(StorageError):
    pass

class AbstractHttpStorage(
    FormattedEntity, LoggingEntity, base.AbstractStorageReadOnly,
):
    """ ReadOnly storage over http GET
    config:
        conn_limit: int = 1
        conn_timeout: float
        read_timeout: float
        allow_hosts: list
        return_status: bool, method get returns tuple (CODE, VALUE)
        prefix: url prefix
        headers: Mapping or None
        template: url template
        format: [json|str|bytes], default json
    """
    def __init__(self, *args, **kwargs):
        self.session = None
        super().__init__(*args, **kwargs)

    async def init(self):
        self._prefix = self.config.get('prefix')
        self._template = self.config.get('template')
        if self._prefix:
            self._prefix = URL(self._prefix)
        self._allow_hosts = self.config.get('allow_hosts')
        self._format = self.config.get('format', 'json')
        self._return_status = self.config.get('return_status', False)

        headers = self.config.get('headers')
        self.session_params = {}
        if headers:
            self.session_params['headers'] = headers
        for param in ('conn_timeout', 'read_timeout'):
            if param in self.config:
                self.session_params[param] = self.config[param]
        self.session = await self.session_factory(**self.session_params)
        self.context.on_stop.append(self.stop)

    @abstractmethod
    async def session_factory(self, **kwargs):
        pass

    async def reset_session(self, **kwargs):
        if self.session is not None:
            await self.session.close()
        if kwargs:
            kwargs = {**self.session_params, **kwargs}
        else:
            kwargs = self.session_params
        self.session = await self.session_factory(**kwargs)

    async def stop(self):
        await self.session.close()

    def raw_key(self, key):
        if self._prefix:
            url = self._prefix / key
        elif self._template and isinstance(key, Mapping):
            url = URL(self._template.format_map(key))
        elif self._template and isinstance(key, Sequence):
            url = URL(self._template.format(*key))
        elif self._template:
            url = URL(self._template.format(key))
        elif isinstance(key, str):
            url = URL(key)
        else:
            url = key
        if self._allow_hosts and url.host not in self._allow_hosts:
            raise KeyError(key)
        return url

    async def request(self, url, **kwargs):
        async with self.session.request(url, **kwargs) as response:
            data = await response.read()
        try:
            formatter = self.registry.get(response.headers['Content-Type'])
        except KeyError:
            formatter = self
        result = formatter.decode(data)
        if self._return_status:
            return response.status, result
        else:
            return result

    def get(self, key):
        url = self.raw_key(key)
        return self.request(url)

    async def copy(self, key_source, storage_dest, key_dest):
        """ Return True if data are copied
        * optimized for http->fs copy
        * not supported return_status
        """
        from aioworkers.storage.filesystem import FileSystemStorage
        if not isinstance(storage_dest, FileSystemStorage):
            return super().copy(key_source, storage_dest, key_dest)
        url = self.raw_key(key_source)
        async with self.session(url, method='get') as response:
            if response.status == 404:
                return
            elif response.status >= 400:
                if self.logger.getEffectiveLevel() == logging.DEBUG:
                    self.logger.debug(
                        'HttpStorage request to %s '
                        'returned code %s:\n%s' % (
                            url, response.status,
                            (await response.read()).decode()))
                return
            async with storage_dest.raw_key(key_dest).open('wb') as f:
                async for chunk in response.content.iter_any():
                    await f.write(chunk)
                return True

class RoStorage(ExecutorEntity, AbstractHttpStorage):
    def set_config(self, config):
        cfg = config.new_parent(executor=config.get_int('conn_limit', 1))
        super().set_config(cfg)

    async def session_factory(self, **kwargs):
        return Session.from_entity(self, **kwargs)

    async def request(self, url, **kwargs):
        try:
            return await super().request(url, **kwargs)
        except Exception as e:
            raise StorageError() from e

class Storage(RoStorage, base.AbstractStorageWriteOnly):
    """ RW storage over http
    config:
        conn_limit: int
        allow_hosts: list
        return_status: bool, method get returns tuple (CODE, VALUE)
        prefix: url prefix
        template: url template
        headers: Mapping or None
        format: [json|str|bytes], default json
        set: [post|put|patch], default post
    """

    def set(self, key, value):
        url = self.raw_key(key)
        data = self.encode(value)
        headers = {}
        if self._formatter.mimetypes:
            headers['Content-Type'] = self._formatter.mimetypes[0]

        return self.request(
            url, method=self.config.get('set', 'post'),
            data=data, headers=headers)


import sys
import DBManager

from PyQt5 import QtWidgets,QtGui,QtCore
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtGui import QPixmap, QDesktopServices
from PyQt5.uic import loadUiType

Ui_OrchidGUI, QMainWindow = loadUiType('Orchid.ui')

class Orchid(QMainWindow, Ui_OrchidGUI):
    def __init__(self):
        super(Orchid, self).__init__()
        self.setupUi(self)
        self.setWindowTitle("Orchideen Datenbank")

        self.db = DBManager.DBManager()
        self.search()
        # constuct the labels
        self.setComboBox(self.UIKultur, self.db.labels['Kultur'])
        self.setComboBox(self.UIKlima, self.db.labels['Klima'])
        self.setComboBox(self.UIWasser, self.db.labels['Wasser'])
        self.setComboBox(self.UIRuhe, self.db.labels['Ruhe'])
        self.setComboBox(self.UILicht, self.db.labels['Licht'])

        # events
        self.UISuche.textEdited.connect(self.search)
        self.UIResult.currentItemChanged.connect(self.infofromlist)
        self.UISave.clicked.connect(self.saveRecord)
        self.UINew.clicked.connect(self.newRecord)
        self.UIImageUpdate.clicked.connect(self.updateImage)
        self.UILaunchPflege.clicked.connect(self.launchWeb)
        self.UILaunchInternet.clicked.connect(self.launchWeb)
        self.actionSave.triggered.connect(self.saveDB)
        self.actionReport.triggered.connect(self.reportDB)
        self.recordID=-1

    def setComboBox(self,combo,labs):
        combo.clear()
        for lab in labs:
            combo.addItem(lab)
        combo.setCurrentIndex(0)

    def reportDB(self):
        self.db.report()

    def launchWeb(self):
        if self.recordID < 0:
            return
        name = str(self.UIName.text())
        tag = 'Internet'
        if self.sender() is self.UILaunchPflege:
            tag = 'Pflege'
        if tag in self.db.db[name].keys() and len(self.db.db[name][tag]) > 0:
            QDesktopServices.openUrl(QtCore.QUrl(self.db.db[name][tag]))

    def updateImage(self):
        if self.recordID < 0:
            return
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self, "Orchideen Photo", "",
                                                  "PNG Files (*.png);JPEG Files (*.jpg)", options=options)
        if fileName:
            name = str(self.UIName.text())
            self.db.db[name]['Photo']=fileName
            self.info(str(self.UIResult.currentItem().text()))

    def saveDB(self):
        self.db.saveDB()

    def search(self):
        regexp = str(self.UISuche.text())
        res = self.db.search(regexp)
        self.UIResult.clear()
        nlen = len(res)
        self.UIResult.setRowCount(nlen)
        self.UIResult.setColumnCount(1)
        for i in range(nlen):
            self.UIResult.setItem(i,0,QtWidgets.QTableWidgetItem(res[i]))
        self.UIResult.verticalHeader().hide()
        self.UIResult.horizontalHeader().hide()
        self.UIResult.horizontalHeader().setSectionResizeMode(0,QtWidgets.QHeaderView.Stretch)
        self.UIAnzahl.setText('%d' % nlen)

    def newRecord(self):
        maxID = -1
        for key in self.db.db.keys():
            if self.db.db[key]['ID']> maxID:
                maxID = self.db.db[key]['ID']
        maxID += 1
        name = str(self.UIName.text())
        if not name:
            name = 'New Entry'
        if name in self.db.db.keys():
            QtWidgets.QMessageBox.about(self, 'Duplicate Entry', 'The record %s exists already' % name)
            return
        self.db.db[name] = {}
        self.db.db[name]['ID'] = maxID
        self.recordID = maxID
        self.saveRecord()
        self.info(name)

    def saveRecord(self):
        if self.recordID < 0:
            return
        name = str(self.UIName.text())

        if not name in self.db.db.keys():   # key name has changed
            checkID = self.db.checkID(self.recordID)  # get former name for ID
            if checkID is None:
                return
            self.db.db[name] = self.db.db[checkID]
            del self.db.db[checkID]
        else:
            if not self.recordID == self.db.db[name]['ID']:   # name was changed to already existing key name
                QtWidgets.QMessageBox.about(self, 'Duplicate Entry', 'The record %s exists already' % name)
                return
        self.db.db[name]['Kultur'] = self.UIKultur.currentIndex()
        self.db.db[name]['Klima'] = self.UIKlima.currentIndex()
        self.db.db[name]['Wasser'] = self.UIWasser.currentIndex()
        self.db.db[name]['Licht'] = self.UILicht.currentIndex()
        self.db.db[name]['Ruhe'] = self.UIRuhe.currentIndex()
        self.db.db[name]['Anzahl'] = int(str(self.UIExemplare.text()))
        self.db.db[name]['Gattung'] = str(self.UIGattung.text())
        self.db.db[name]['Internet'] = str(self.UIInternetLink.text())
        self.db.db[name]['Pflege'] = str(self.UIPflege.text())

    def info(self, name):
        print(name)
        if name is None or not name in self.db.db.keys():
            self.UIName.clear()
            self.UIGattung.clear()
            self.UIExemplare.clear()
            self.UIKultur.setCurrentIndex(0)
            self.UIKlima.setCurrentIndex(0)
            self.UIWasser.setCurrentIndex(0)
            self.UILicht.setCurrentIndex(0)
            self.UIRuhe.setCurrentIndex(0)
            self.UIPflege.clear()
            self.UIInternetLink.clear()
            self.recordID = -1
            return
        item = self.db.db[name]
        self.recordID = item['ID']
        self.UIName.setText(name)
        self.UIGattung.setText(str(item['Gattung']))
        self.UIExemplare.setText('%d' % item['Anzahl'])
        self.UIKultur.setCurrentIndex(self.db.checkIntField(name, 'Kultur'))
        self.UIKlima.setCurrentIndex(self.db.checkIntField(name, 'Klima'))
        self.UIWasser.setCurrentIndex(self.db.checkIntField(name, 'Wasser'))
        self.UIRuhe.setCurrentIndex(self.db.checkIntField(name, 'Ruhe'))
        self.UILicht.setCurrentIndex(self.db.checkIntField(name, 'Licht'))
        self.UIInternetLink.setText(self.db.checkStrField(name, 'Internet'))
        self.UIPflege.setText(self.db.checkStrField(name, 'Pflege'))
        if 'Photo' in item.keys() and len(item['Photo'])>0:
            pixmap = QPixmap(item['Photo'])
            self.UIImage.setPixmap(pixmap.scaled(self.UIImage.width(),self.UIImage.height(),QtCore.Qt.KeepAspectRatio))
        else:
            self.UIImage.clear()

    def infofromlist(self):
        entry=self.UIResult.currentItem()
        if entry is None:
            self.info(None)
        else:
            self.info(str(entry.text()))

# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    main = Orchid()
    main.show()
    sys.exit(app.exec_())


import tommy_queue as Queue

# Defining the node of ternary search tree
class Node:
    def __init__(self, data, left=None, mid=None, right=None):
        self.data = data
        self.left = left
        self.mid = mid
        self.right = right

# __str__ for the user to display the data
    def __str__(self):
        # return f'Data= {self.data}  L= {self._get_name(self.left)}   M= {self._get_name(self.mid)}    R= {self._get_name(self.right)}'
        return f'{self.data}'

# Used when displaying an object
    def __repr__(self):
        # return f'Data= {self.data}  L= {self._get_name(self.left)}   M= {self._get_name(self.mid)}    R= {self._get_name(self.right)}'
        return f'{self.data}'

    def _get_name(self,node):
        if node is not None:
            return node.data
        else:
            return f'No data'

    def __eq__(self, other):
        if self.data == other.data:
            return True
        else:
            return False

# Defining the nodes in the tree
# node_a1 = Node('a')
# node_a2 = Node('a')
# node_b = Node('b')
# print(f'Checking if node a1 = a2: {node_a1 == node_a2}')
# print(f'Checking if node a2 = b: {node_a2 == node_b}')

node_10 = Node(10)
node_85 = Node(85)
node_30 = Node(30)
node_7 = Node(7)
node_31 = Node(31)
node_15 = Node(15)
node_40 = Node(40)
node_63 = Node(63)
node_1 = Node(1)
node_17 = Node(17)

# Defining the node positions
node_10.left = node_85
node_10.mid = node_30
node_10.right = node_7
node_85.left = node_31
node_85.mid = node_15
node_85.right = node_40
node_30.left = node_63
node_30.mid = node_1
node_30.right = node_17

# Defining the function 'Search the Start Node and the Nodes attached to it', print the Nodes
def BFS(start_node, search_node):
    # current_node = start_node
    q = Queue.TommyQueue()
    q.push(start_node)
    print(f'Added {start_node} to start of queue')
    while q.queue:
        current_node = q.pop()
        print(f'Got {current_node} from the queue')
        if search_node == current_node:
            print(f'Found the node: {current_node}')
        else:
            if current_node.left is not None:
                q.push(current_node.left)
                print(f'Added {current_node.left} to the queue')
            if current_node.mid is not None:
                q.push(current_node.mid)
                print(f'Added {current_node.mid} to the queue')
            if current_node.right is not None:
                q.push(current_node.right)
                print(f'Added {current_node.right} to the queue')
        print(f'Current queue {q}')
    print(f'Node not found')

BFS(node_10, Node(300))


# -*- coding: utf-8 -*-
# @Time    : 2021/5/25 12:05
# @Author  : Yan
# @Email   : 18843010983@163.com
# @File    : conftest.py
# @Software: PyCharm

import os
import pytest
from appium import webdriver
from pages.page_action import PageAction

driver = None

@pytest.fixture(scope='session')
def handler():

    caps = {"platformName": "Android",
            "platformVersion": "5",
            "deviceName": "127.0.0.1:21503",
            "appPackage": "com.lchr.diaoyu",
            "appActivity": "com.lchr.diaoyu.SplashActivity",
            "noReset": True,
            "newCommandTimeout": 6000,
            "skipServerInstallation": True,
            "automationName": "UiAutomator2",
            "ensureWebviewsHavePages": True}

    driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
    pa = PageAction(driver)
    pa.sleep(8)

    yield driver, pa

    driver.quit()

def pytest_configure(config):
    markers = ['smoke', 'last']
    for mark in markers:
        config.addinivalue_line('markers', mark)


#!/usr/bin/env python3
# Copyright (c) 2021, NVIDIA CORPORATION.  All rights reserved.
#
# 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 tensorrt as trt
import os
import sys
import platform
import onnx
import ctypes
import struct
import numpy as np
sys.path.insert(0, os.getcwd())

from importlib import import_module
from code.common import logging, dict_get, BENCHMARKS
from code.common import get_system
from code.common.builder import BenchmarkBuilder
import pycuda.autoinit
RN50Calibrator = import_module("code.resnet50.tensorrt.calibrator").RN50Calibrator
AUTOSINIAN_CNN_PLUGIN_LIBRARY = "code/resnet50/tensorrt/libautosiniancnnplugin_ampere.so" if pycuda.autoinit.device.compute_capability()[0] > 7 else "code/resnet50/tensorrt/libautosiniancnnplugin_turing.so"
if not os.path.isfile(AUTOSINIAN_CNN_PLUGIN_LIBRARY):
    raise IOError("{}\n".format(
        "Failed to load library ({}).".format(AUTOSINIAN_CNN_PLUGIN_LIBRARY)
    ))
ctypes.CDLL(AUTOSINIAN_CNN_PLUGIN_LIBRARY)

class ResNet50(BenchmarkBuilder):
    """Resnet50 engine builder."""

    def __init__(self, args):
        workspace_size = dict_get(args, "workspace_size", default=(1 << 30))
        logging.info("Use workspace_size: {:}".format(workspace_size))

        super().__init__(args, name=BENCHMARKS.ResNet50, workspace_size=workspace_size)

        # Model path
        self.model_path = dict_get(args, "model_path", default="code/resnet50/tensorrt/ofa_autosinian_is176.onnx")
        logging.info("Using AutoSinian optimized once-for-all network")

        self.cache_file = None
        self.need_calibration = False

        if self.precision == "int8":
            # Get calibrator variables
            calib_batch_size = dict_get(self.args, "calib_batch_size", default=1)
            calib_max_batches = dict_get(self.args, "calib_max_batches", default=500)
            force_calibration = dict_get(self.args, "force_calibration", default=False)
            cache_file = dict_get(self.args, "cache_file", default="code/resnet50/tensorrt/calibrator.cache")
            preprocessed_data_dir = dict_get(self.args, "preprocessed_data_dir", default="build/preprocessed_data")
            calib_data_map = dict_get(self.args, "calib_data_map", default="data_maps/imagenet/cal_map.txt")
            calib_image_dir = os.path.join(preprocessed_data_dir, "imagenet/ResNet50/fp32")

            # Set up calibrator
            self.calibrator = RN50Calibrator(calib_batch_size=calib_batch_size, calib_max_batches=calib_max_batches,
                                             force_calibration=force_calibration, cache_file=cache_file,
                                             image_dir=calib_image_dir, calib_data_map=calib_data_map)
            self.builder_config.int8_calibrator = self.calibrator
            self.cache_file = cache_file
            self.need_calibration = force_calibration or not os.path.exists(cache_file)

    def initialize(self):
        """
        Parse input ONNX file to a TRT network. Apply layer optimizations and fusion plugins on network.
        """

        # Query system id for architecture
        self.system = get_system()
        self.gpu_arch = self.system.arch

        # Create network.
        self.network = self.builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))

        # Parse from onnx file.
        parser = trt.OnnxParser(self.network, self.logger)

        with open(self.model_path, "rb") as f:
            model = f.read()
        success = parser.parse(model)
        if not success:
            raise RuntimeError("ofa_autusinian onnx model processing failed! Error: {:}".format(parser.get_error(0).desc()))
        # Set input dtype and format
        input_tensor = self.network.get_input(0)
        if self.input_dtype == "int8":
            input_tensor.dtype = trt.int8
            scale = struct.unpack('!f', bytes.fromhex('3caa5293'))[0]
            input_tensor.dynamic_range = (-scale*127.0, scale*127.0)
        if self.input_format == "linear":
            input_tensor.allowed_formats = 1 << int(trt.TensorFormat.LINEAR)
        elif self.input_format == "chw4":
            input_tensor.allowed_formats = 1 << int(trt.TensorFormat.CHW4)

        # Get the layers we care about.
        nb_layers = self.network.num_layers

        while self.network.num_outputs > 0:
            logging.info("Unmarking output: {:}".format(self.network.get_output(0).name))
            self.network.unmark_output(self.network.get_output(0))
        #add top-k
        last_fc_layer = self.network.get_layer(nb_layers - 1)
        topk_layer = self.network.add_topk(last_fc_layer.get_output(0), trt.TopKOperation.MAX, 1, 2)
        topk_layer.name = "topk_layer"
        topk_layer.get_output(0).name = "topk_layer_output_value"
        topk_layer.get_output(1).name = "topk_layer_output_index"
        self.network.mark_output(topk_layer.get_output(1))

        if self.network.num_outputs != 1:
            logging.warning("num outputs should be 1 after unmarking! Has {:}".format(self.network.num_outputs))
            raise Exception

        if self.precision == "int8" and self.batch_size > 1 and (not self.need_calibration):
            self.autosinian_optimize()

        self.initialized = True

    def autosinian_optimize(self):
        logging.info("Applying AutoSinian Optimization...")
        optimize_points = [(10,15), (21,26), (27,32), (38,43), (44,49), (55,60), (61,66), (67,72), (78,83), (84,89), (90,95), (0,4), (5,9), (16,20), (33,37), (50,54), (73,77), (96,100)]
        optimizer = AutoSinian_Optimizer(self.cache_file)
        for point in optimize_points:
            optimizer.optimize(self.network, point)

class AutoSinian_Optimizer:
    '''AutoSinian optimizer, optimize the hardware implementation of the layers.'''
    def __init__(self, cache_file = None):
        self.plugin_registery = trt.get_plugin_registry()
        foundPlugin = False
        for plugin_creator in self.plugin_registery.plugin_creator_list:
            if plugin_creator.name == self.name:
                self.creator = self.plugin_registery.get_plugin_creator(self.name,'1','')
                foundPlugin = True if self.creator else False
                break
        assert(foundPlugin), "fail to found %s!" % self.name
        self.scale_map = {}
        with open(cache_file, "r") as f:
            for line in f:
                pair = line.rstrip().split(':')
                if len(pair) == 2:
                    self.scale_map[pair[0]] = struct.unpack('!f', bytes.fromhex(pair[1]))[0]
        self.count = 0

    @property
    def name(self):
        return "AutoSinianCNN_TRT"

    def optimize(self, network, point):
        fields = trt.PluginFieldCollection()
        saved = [] #values must be alive when creating the plugin.
        inputs = [network.get_layer(point[0]).get_input(0)]
        append_fields(network, point[0], fields, saved, self.scale_map)
        append_fields(network, point[0]+2, fields, saved, self.scale_map)
        append_fields(network, point[0]+4, fields, saved, self.scale_map)

        plugin=self.creator.create_plugin(self.name, fields)
        if plugin is None:
            raise Exception("Plugin creation failed")

        plugin_layer = network.add_plugin_v2(inputs, plugin)
        plugin_layer.name = self.name + "_%d" % self.count
        self.count += 1
        origin_output = network.get_layer(point[1]).get_output(0)
        plugin_output = plugin_layer.get_output(0)
        assert(origin_output.name in self.scale_map), "%s not found!" % origin_output.name
        dynamic_range=self.scale_map[origin_output.name]*127.0
        plugin_output.set_dynamic_range(-dynamic_range, dynamic_range)
        for j in range(network.num_layers):
            layer = network.get_layer(j)
            if layer.name==plugin_layer.name :
                continue
            for k in range(layer.num_inputs):
                if layer.get_input(k) == origin_output:
                    layer.set_input(k, plugin_output)

def append_fields(network, index, fields, saved, scale_map):
    layer = network.get_layer(index)
    assert(isinstance(layer, trt.ILayer) and (layer.type == trt.LayerType.CONVOLUTION)), "must be a conv layer"
    layer.__class__ = trt.IConvolutionLayer
    output_layer = layer

    npa1 = np.array([layer.kernel_size.h], dtype=np.int32)
    saved.append(npa1)

    npa2 = np.array([layer.num_output_maps], dtype=np.int32)
    saved.append(npa2)

    npa3 = np.array([layer.num_groups], dtype=np.int32)
    saved.append(npa3)

    npa4 = np.array([layer.stride.h], dtype=np.int32)
    saved.append(npa4)

    npa5 = np.array([layer.pre_padding[0]], dtype=np.int32)
    saved.append(npa5)

    npa6 = np.array([layer.post_padding[0]], dtype=np.int32)
    saved.append(npa6)

    npa7 = np.array([layer.get_input(0).shape[1]], dtype=np.int32)
    saved.append(npa7)

    next_layer = network.get_layer(index+1)

    elemwise_add = -1
    if (next_layer.type == trt.LayerType.ACTIVATION):
        next_layer.__class__ = trt.IActivationLayer
        output_layer = next_layer
    elif (next_layer.type == trt.LayerType.ELEMENTWISE):
        next_layer.__class__ = trt.IElementWiseLayer
        elemwise_add = 0
        output_layer = next_layer
    npa8 = np.array([elemwise_add], dtype=np.int32)
    saved.append(npa8)

    npa9 = np.array([0], dtype=np.int32)
    saved.append(npa9)

    npa10 = 0
    if index == 0:
        npa10 = struct.unpack('!f', bytes.fromhex('3caa5293'))[0]
    npa10 = np.array([npa10], dtype=np.float32)
    saved.append(npa10)

    npa11 = np.array([6], dtype=np.float32)
    saved.append(npa11)

    name = output_layer.get_output(0).name
    assert(name in scale_map), "Missing scale for %s"%name
    scale = scale_map[name]
    npa12 = np.array([scale], dtype=np.float32)
    saved.append(npa12)

    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa1), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa2), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa3), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa4), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa5), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa6), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa7), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa8), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa9), trt.PluginFieldType.INT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa10), trt.PluginFieldType.FLOAT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa11), trt.PluginFieldType.FLOAT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", memoryview(npa12), trt.PluginFieldType.FLOAT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", layer.kernel.data, trt.PluginFieldType.FLOAT32))
    fields.append(trt.PluginField("asn_cnn_plg_field", layer.bias.data, trt.PluginFieldType.FLOAT32))


import threading
import random
import matplotlib.pyplot as plt
from datetime import datetime

sum = 0

def _mul(arg1, arg2):
    s = 0
    for values in zip(arg1, arg2):
        s += values[0] * values[1]
    global sum
    sum += s

a = [random.randint(0, 10**10) for x in range (2 * 10**6)]
b = [random.randint(0, 10**10) for x in range (2 * 10**6)]
n = len(a)
'''
start = datetime.now()
_mul(a, b)
time1 = (datetime.now() - start).seconds
'''
time_arr = []
for j in range(1, 5):
    tmp = []
    for qwerty in range (3):
        start = datetime.now()
        step = n // j
        for i in range(j):
            a1 = a[step*(i-1):step*i]
            b1 = b[step*(i-1):step*i]
            threading.Thread(target=_mul, args=(a1, b1)).start()
        a1 = a[step*(j-1):]
        b1 = b[step*(j-1):]
        threading.Thread(target=_mul, args=(a1, b1)).start()
        tmp.append((datetime.now() - start).microseconds)
    time_ = 0
    for i in tmp:
        time_ += i
    time_iter = time_/len(tmp)
    time_arr.append(time_iter)
plt.plot([1, 2, 3, 4], time_arr)
plt.grid()
plt.ylabel('Время выполнения, [мс]')
plt.xlabel('Число потоков')
plt.show()


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import compas_rhino

from compas.datastructures import Mesh
from compas.geometry import smooth_area

from compas_rhino.helpers import mesh_from_guid
from compas_rhino.conduits import LinesConduit
from compas_rhino.geometry import RhinoSurface
from compas_rhino.artists import MeshArtist

# make a mesh datastructure from a Rhino mesh object
guid = compas_rhino.select_mesh()
mesh = mesh_from_guid(Mesh, guid)

# make a target surface
guid = compas_rhino.select_surface()
surf = RhinoSurface(guid)

# extract the input for the smoothing algorithm from the mesh
# and identify the boundary as fixed
vertices  = mesh.get_vertices_attributes('xyz')
faces     = [mesh.face_vertices(fkey) for fkey in mesh.faces()]
adjacency = [mesh.vertex_faces(key, ordered=True) for key in mesh.vertices()]
fixed     = set(mesh.vertices_on_boundary())

# convert the edges of the mesh to lines
edges = list(mesh.edges())
lines = [[vertices[u], vertices[v]] for u, v in edges]

# make a conduit for visualization
conduit = LinesConduit(lines, refreshrate=5)

# make a callback for updating the conduit
# and for pulling the free vertices back to the surface
# at every iteration
def callback(k, args):
    for index in range(len(vertices)):
        if index in fixed:
            continue
        x, y, z = surf.closest_point(vertices[index])
        vertices[index][0] = x
        vertices[index][1] = y
        vertices[index][2] = z
    # update the conduit
    conduit.lines = [[vertices[u], vertices[v]] for u, v in edges]
    conduit.redraw(k)

# with the conduit enabled
# run the smoothing algorithm
with conduit.enabled():
    smooth_area(
        vertices,
        faces,
        adjacency,
        fixed=fixed,
        kmax=100,
        callback=callback)

# update the mesh when smoothing is done
for key, attr in mesh.vertices(True):
    attr['x'] = vertices[key][0]
    attr['y'] = vertices[key][1]
    attr['z'] = vertices[key][2]

# draw the result
artist = MeshArtist(mesh, layer='mesh-out')
artist.draw_mesh()


import web

urls=(
        '/fuck','fuck',

       '/(.*)','hello'
        )

app = web.application(urls,globals())

class fuck:
    def GET(self):
        ss=web.input()
        return ss

class hello :
    def GET(self,name):
        if not name:
            name ='world'
        return '<h1>' + 'Hello,' + name +'!' + '</h1>'

if __name__=="__main__":
    app.run()


from typing import List

import pytest
import strawberry
from graphql import GraphQLError
from strawberry import auto

import strawberry_django

from . import models, utils

@pytest.fixture
def user_group(users, groups):
    users[0].group = groups[0]
    users[0].save()

@strawberry_django.type(models.User)
class User:
    id: auto
    name: auto
    group: "Group"

@strawberry_django.type(models.Group)
class Group:
    id: auto
    name: auto
    users: List[User]

@strawberry_django.type(models.Fruit)
class BerryFruit:
    id: auto
    name: auto
    name_upper: str
    name_lower: str

    @classmethod
    def get_queryset(cls, queryset, info):
        return queryset.filter(name__contains="berry")

@strawberry_django.type(models.Fruit, is_interface=True)
class FruitInterface:
    id: auto
    name: auto

@strawberry_django.type(models.Fruit)
class BananaFruit(FruitInterface):
    @classmethod
    def get_queryset(cls, queryset, info):
        return queryset.filter(name__contains="banana")

@strawberry.type
class Query:
    user: User = strawberry_django.field()
    users: List[User] = strawberry_django.field()
    group: Group = strawberry_django.field()
    groups: List[Group] = strawberry_django.field()
    berries: List[BerryFruit] = strawberry_django.field()
    bananas: List[BananaFruit] = strawberry_django.field()

@pytest.fixture
def query(db):
    return utils.generate_query(Query)

pytestmark = [
    pytest.mark.asyncio,
    pytest.mark.django_db(transaction=True),
]

async def test_single(query, users):
    result = await query("{ user(pk: 1) { name } }")

    assert not result.errors
    assert result.data["user"] == {"name": users[0].name}

async def test_required_pk_single(query, users):
    result = await query("{ user { name } }")

    assert bool(result.errors)
    assert len(result.errors) == 1
    assert isinstance(result.errors[0], GraphQLError)
    assert (
        result.errors[0].message
        == "Field 'user' argument 'pk' of type 'ID!' is "
        "required, but it was not provided."
    )

async def test_many(query, users):
    result = await query("{ users { name } }")

    assert not result.errors
    assert result.data["users"] == [
        {"name": users[0].name},
        {"name": users[1].name},
        {"name": users[2].name},
    ]

async def test_relation(query, users, groups, user_group):
    result = await query("{ users { name group { name } } }")

    assert not result.errors
    assert result.data["users"] == [
        {"name": users[0].name, "group": {"name": groups[0].name}},
        {"name": users[1].name, "group": None},
        {"name": users[2].name, "group": None},
    ]

async def test_reverse_relation(query, users, groups, user_group):
    result = await query("{ groups { name users { name } } }")

    assert not result.errors
    assert result.data["groups"] == [
        {"name": groups[0].name, "users": [{"name": users[0].name}]},
        {"name": groups[1].name, "users": []},
        {"name": groups[2].name, "users": []},
    ]

async def test_type_queryset(query, fruits):
    result = await query("{ berries { name } }")

    assert not result.errors
    assert result.data["berries"] == [
        {"name": "strawberry"},
        {"name": "raspberry"},
    ]

async def test_querying_type_implementing_interface(query, fruits):
    result = await query("{ bananas { name } }")

    assert not result.errors
    assert result.data["bananas"] == [{"name": "banana"}]

async def test_model_properties(query, fruits):
    result = await query("{ berries { nameUpper nameLower } }")

    assert not result.errors
    assert result.data["berries"] == [
        {"nameUpper": "STRAWBERRY", "nameLower": "strawberry"},
        {"nameUpper": "RASPBERRY", "nameLower": "raspberry"},
    ]


import functools
from abc import ABC
from typing import Optional

import numpy as np

def _format_simulator(_simulate):
    """Formats input and output of the _simulator method"""

    @functools.wraps(_simulate)
    def decorator(self, size: int, reps: Optional[int] = None):
        if reps is not None:
            if not isinstance(reps, int) or reps <= 0:
                raise ValueError('`reps` must be an integer greater than 0')

        value = _simulate(self, size, reps)

        if isinstance(value, (int, float)):
            value = np.array([value], value)
        return np.asarray(value)

    return decorator

class DistributionMixin(ABC):
    def __init__(self):
        self._custom_dist: np.ndarray = None

    def check_dist_size(self, size):
        """Checks that the size required for the simulation is within the generated custom dist bounds"""
        if self.custom_dist is None:
            raise ValueError(f'method should not be called when custom_dist is not specified')

        if len(self.custom_dist) < size:
            times = round(np.ceil(size / len(self.custom_dist) * 100) / 100, 2)
            raise ValueError(f'rvs array too short. Increase the number of uniform rvs generated by {times}x')

    @property
    def custom_dist(self) -> Optional[np.ndarray]:
        """
        Optional density with fitted object from which to simulate

        The custom.dist option allows for defining a custom density which exists in the users workspace with methods for “r” (sampling, e.g. rnorm) and “d” (density e.g. dnorm). It must take a single fit object as its second argument. Alternatively, custom.dist can take any name in the name slot (e.g.“sample”) and a matrix in the fit slot with dimensions equal to m.sim (columns) and n.sim (rows). It is understood that what is supplied are the standardized (0,1) innovations and not the unstandardized residuals. The usefulness of this becomes apparent when one is considering the copula-GARCH approach or the bootstrap method.

        Returns
        -------
        {ndarray, None}
            Array of density values or None
        """
        return self._custom_dist

    @custom_dist.setter
    def custom_dist(self, values: Optional[np.ndarray]):
        if values is None:
            self._custom_dist = None
        else:
            values = np.asarray(values)
            self._custom_dist = float(values) if values.size == 1 else values


from .apod_client import APOD
import aiohttp
import asyncio
import argparse

import json
import yaml

from datetime import date, timedelta, datetime

"""
TEST SCRIPT FOR APOD API WRAPPER
"""

VALID_FILE_TYPES = ['csv', 'json', 'yaml']

parser = argparse.ArgumentParser()

parser.add_argument('--date', '-d')
parser.add_argument('--from')
parser.add_argument('--to')
parser.add_argument('--since')
parser.add_argument('--print', '-p', action='store_true')
parser.add_argument('--dump')
parser.add_argument('--download')
parser.add_argument('--key')

def process_date(day):
    keywords = {
        'today': date.today(),
        'yesterday': date.today() - timedelta(days=1)
    }
    if day in keywords.keys():
        return keywords[day]

    dt = datetime.strptime(day, '%Y-%m-%d')
    return date(dt.year, dt.month, dt.day)

def dump_to_json(data, filename):
    with open(filename, 'w') as f:
        json.dump(data, f)

def dump_to_csv(data, filename):
    with open(filename, 'w') as f:
        if not isinstance(data, list):  # batch_get
            data = [data]
        for _dict in data:
            items = [str(value) for value in _dict.values()]
            f.write(','.join(items) + '\n')

def dump_to_yaml(data, filename):
    with open(filename, 'w') as f:
        yaml.dump(data, f, yaml.Dumper)

async def get(day, _print, dump, download, key):
    day = process_date(day)

    async with APOD(key if key else 'DEMO_KEY') as apod:
        response = await apod.get(day, as_json=True)

    if _print:
        s = ""
        for key, value in response.items():
            s += f"{key}: {value}\n"
        print(s)

    if dump:
        split = dump.split('.')
        ext = split[-1]

        if ext.lower() == 'json':
            dump_to_json(response, dump)
        elif ext.lower() == 'csv':
            dump_to_csv(response, dump)
        elif ext.lower() == 'yaml':
            dump_to_yaml(response, dump)

    if download:
        async with aiohttp.ClientSession() as session:
            url = response.get('hdurl')
            url = url if url else response['url']

            if url.startswith('http://apod.nasa.gov') or url.startswith('https://apod.nasa.gov'):
                filename = url.split('/')[-1]

            else:  # todo: add support for non-apod images (youtube etc)
                raise Exception("URL not supported by download function. File could not be downloaded.")

            async with session.get(url) as image_response:
                image = await image_response.read()

            filepath = download + '/' + filename
            with open(filepath, 'wb') as f:
                f.write(image)

async def batch_get(start_date, end_date, _print, dump, download, key):
    start_date = process_date(start_date)
    end_date = process_date(end_date)

    apod = APOD(key if key else 'DEMO_KEY')

    response = await apod.batch_get(start_date, end_date, as_json=True)

    await apod.close()

    if _print:
        s = ""
        for entry in response:
            for key, value in entry.items():
                s += f"{key}: {value}\n"
            s += "\n"
        print(s)

    if dump:
        split = dump.split('.')
        ext = split[-1]

        if ext.lower() == 'json':
            dump_to_json(response, dump)
        elif ext.lower() == 'csv':
            dump_to_csv(response, dump)
        elif ext.lower() in {'yaml', 'yml'}:
            dump_to_yaml(response, dump)

    if download:  # todo: fucking clean this up
        async with aiohttp.ClientSession() as session:
            for entry in response:
                url = entry.get('hdurl')
                url = url if url else entry['url']

                # do this with regex later
                if url.startswith('http://apod.nasa.gov') or url.startswith('https://apod.nasa.gov'):
                    filename = url.split('/')[-1]

                else:  # todo: add support for non-apod images (youtube etc)
                    continue

                async with session.get(url) as image_response:
                    image = await image_response.read()

                filepath = download + '/' + filename
                with open(filepath, 'wb') as f:
                    f.write(image)

async def main():
    args = parser.parse_args()
    _date = args.date
    start_date = args.start_date
    end_date = args.end_date
    since = args.since
    _print = args.print
    dump = args.dump
    download = args.download
    key = args.key

    if _date:
        if start_date or end_date or since:
            raise argparse.ArgumentError("date and start-date/end-date/since are not compatible arguments.")
        await get(_date, _print, dump, download, key)

    elif since:
        if start_date or end_date:
            raise argparse.ArgumentError("since and start-date/end-date are not compatible arguments.")
        await batch_get(since, 'today', _print, dump, download, key)

    elif start_date or end_date:
        if not (start_date and end_date):
            raise argparse.ArgumentError("start-date and end-date are both required arguments when requesting a range.")
        await batch_get(start_date, end_date, _print, dump, download, key)

    else:
        await get('today', _print, dump, download, key)

if __name__ == "__main__":
    asyncio.run(main())


# -*- coding: utf-8 -*-
"""
Date Modified: Sun Jan 19 2020

@author: Ajay Pallekonda
"""

#TEST SCENARIO 1: change Dominion.Thief to Dominion.Spy in the testUtility.py file
#Originally: box["Thief"] = [Dominion.Thief()]*10
#Changed to: box["Thief"] = [Dominion.Spy()]*10

#Result: player is not able to buy a thief card despite having
#        enough buying power and available card

import Dominion
import random
import testUtility
from collections import defaultdict

#Get player names
player_names = ["Annie","*Ben","*Carla"]

#number of curses and victory cards
if len(player_names)>2:
    nV=12
else:
    nV=8
nC = -10 + 10 * len(player_names)

#Define box
box = testUtility.theBox(nV)
supply_order = testUtility.theOrder()

#Pick 10 cards from box to be in the supply.
boxlist = [k for k in box]
random.shuffle(boxlist)
random10 = boxlist[:10]
supply = testUtility.supply(boxlist, random10, nV, box, player_names, nC)

#initialize the trash
trash = []

#Costruct the Player objects
players = testUtility.makePlayers(player_names)

#Play the game
turn  = 0
while not Dominion.gameover(supply):
    turn += 1
    print("\r")
    for value in supply_order:
        print (value)
        for stack in supply_order[value]:
            if stack in supply:
                print (stack, len(supply[stack]))
    print("\r")
    for player in players:
        print (player.name,player.calcpoints())
    print ("\rStart of turn " + str(turn))
    for player in players:
        if not Dominion.gameover(supply):
            print("\r")
            player.turn(players,supply,trash)

#Final score
dcs=Dominion.cardsummaries(players)
vp=dcs.loc['VICTORY POINTS']
vpmax=vp.max()
winners = testUtility.theWinner(vp, dcs, vpmax)