import json, cgi, sys

from settings import *
from datetime import datetime, timedelta

from core.core import *
from urllib import *
from math import *
from copy import deepcopy
from uuid import uuid4

from libs.contents.contents import *
from libs.perm.perm import is_admin, user_has_permission
# from libs.perm.perm import *
from core.union import response_json, response_string
import html

def table_data(request):
	"""
	при отрисовке вкладки при нажатии кнопки рефреш, в admin.js там в update_tab
	берем из модели которая в свою очередь берет из закладки  какойто id номер вкладки
	и по роуту вызывается эта функция.
	"""
	proc_id = request.match_info.get('proc_id')
	data = table_data_(request, proc_id)
	return templ('libs.table:main', request, dict(parts = data['parts'], hdata = data['hdata'], map_ = data['map_'], url = data['url'], proc_id = data['proc_id'], select_id =data['select_id']) )

def table_data_(request, proc_id):
	if get_const_value( request, 'is_admin') == "false" and not is_admin(request): return redirect('/')
	data = get_post( request )
	select_id = data['select_id'] if 'select_id' in data else None

	url = ''
	meta_doc = get_mt(request, proc_id)

	meta_table = check_map_perm(request, proc_id, meta_doc['doc'])
	#это для интернационализации
	parts = []
	# строим иерархию по шапкам
	for res in request.db.map.find({"conf.owner": proc_id}):
		parts.append(res)
	_parts = ""
	for tbl in parts:
		if _parts: _parts+=", "
		tp = 'table'; conf = {}
		if 'com:' == tbl['_id'][0:4]: tp = 'comments'
		if tp == 'table':
			conf['columns'] = rec_data_t(request, tbl['doc'])
		conf_ = ""
		for k in conf:
			if conf_: conf_ += ", "
			conf_ +='"' + k + '": '+ conf[k]
		conf_ = "{"+conf_+"}"
		_parts += '{"id": "' + tbl['_id'] + '", "title": "' + \
		          ct(request, tbl['conf']['title']) + '", "conf": ' + conf_ + ', "type": "' + tp + '" }'
	_parts = "["+_parts+"]"
	map_ = rec_data_t(request, meta_table)
	return  {'parts':_parts, 'hdata':meta_doc, 'map_':map_, 'url':url, 'proc_id':proc_id, 'select_id':select_id}

def rec_data_t(request, meta_table):
	# """подсчет полей таблицы чтоли"""
	for res in range(0, len(meta_table)):
		meta_table[res]['title'] = ct(request, meta_table[res]['title'])
		meta_table[res]['hint'] = ct(request, meta_table[res]['hint'])
	map_ = ""
	for key in meta_table:
		if map_:
			map_+=", "
		map_ +='"'+key['id']+'": '+ json.dumps(key)
	map_ = "{"+map_+"}"
	return map_

def sort_body(request, proc_id, meta_table, docs_table):
	"""
	проодит по всем документам, если документ переводной то переводит
	И в зависимости от типа документа рисует соотвествующее значение в ячейке
	:param proc_id:
	:param meta_table:
	:param docs_table:
	:return:
	"""
	from libs.files.files import get_nf
	out_docs = []
	for res in docs_table: #проходим по всем документам
		doc = res['doc']
		for field in meta_table:
			if field['id'] in doc and 'is_translate' in field and field['is_translate']:
				lang = cur_lang(request)
				doc[field['id']] = ct(request, doc[field['id']], lang )
		doc_id = res['_id']; sorted_doc = []; parent = '_'; child= []
		if 'parent' in res and res['parent']: parent = res['parent']
		if 'child' in res and res['child']: child = res['child']
		for key in meta_table:
			if key['id'] in doc:
				select_id = doc[key['id']]
				if 'type' in key and key['type'] == 'checkbox':
					edit_value = doc[key['id']]
					icon = 'fa-check' if doc[key['id']] == 'true' else 'fa-close'
					color = 'green' if doc[key['id']] == 'true' else 'red'
					formatted = "<i style='color:"+color+"; font-size:16px' class='fa "+icon+"'></i>"
				elif 'type' in key and key['type'] == 'passw':
					edit_value = '*****'; formatted = '*****'
				elif 'type' in key and key['type'] == 'html':
					edit_value = ''; formatted = doc[key['id']][:100]
				elif 'type' in key and key['type'] == 'rich_edit':
					edit_value = ''
					formatted = cgi.escape(doc[key['id']][:100], True)
				elif 'type' in key and key['type'] == 'select':
					sel = request.db.doc.find_one({'_id':select_id})
					if sel:
						edit_value = doc[key['id']]
						formatted = cgi.escape(get_doc_title(request, sel, '[%s]' % edit_value))
						edit_value = cgi.escape(edit_value, True)
					else:
						edit_value = ''; formatted = '-'
				else:
					edit_value = html.escape(str(doc[key['id']]), True)
					formatted = html.escape(str(doc[key['id']]))
			else:
				edit_value = ''; formatted = ''
			sorted_doc.append({"id":key['id'], "edit_value":edit_value, "formatted":formatted})

		out_docs.append({"id":doc_id, "doc":sorted_doc, "parent":parent, "child":child, "imgs": get_nf(request, proc_id, doc_id, 2)})
	return out_docs

async def table_data_post(request):
	""" #page=текущая страница page ctr=кол-во pages=отрисованые ссылки на страницу навигация """
	data = get_post(request)
	proc_id = data['proc_id']
	if not user_has_permission(request, proc_id, 'view'):  return {"result": "fail", "error": "You have no permission." }
	filtered = json.loads(data['filter'])
	doc_id = data['doc_id'] if 'doc_id' in data else '_'
	parent = data['parent'] if 'parent' in data else '_'
	id_next = None; id_prev = None
	if 'page' in filtered: page = filtered['page']
	else: page = {'current':1}
	limit = int(get_const_value(request, 'doc_page_limit'))
	bdata, docs_table_count = table_data_post_(request, proc_id, filtered, doc_id, parent)
	otvet = {"result":"ok", "data":bdata,
	         "pages":{"count":int(ceil(float(docs_table_count)/limit)),
			 "current":page['current'], "next": id_next, "prev":id_prev} }
	return response_json(request, otvet)

def table_data_post_(request, proc_id, filter, doc_id, parent, no_limit=False):
	""" Получает id таблицы и значения для фильтрации Берет из базы данные
	формирует из них json и возвращает в нужный шаблон"""
	t = time.time()
	user_name = get_current_user(request)
	meta_doc = request.db.map.find_one({'_id':proc_id})
	meta_table = check_map_perm(request, proc_id, meta_doc['doc'])
	start_date = ''; end_date = '9999999999999999999999999'
	if 'date' in filter:
		if 'start' in filter['date']: start_date = filter['date']['start']
		if 'end' in filter['date']: end_date = filter['date']['end'] + ' 99999999'
	if 'branch_id' in filter: branch_id = filter['branch_id']
	else: branch_id = None
	if 'page' in filter: page = filter['page']
	else: page = {}
	if not 'current' in page:
		page['current'] = 1
	limit = int(get_const_value(request, 'doc_page_limit'))
	skip = (page['current']-1)*limit
	#получаем данные из фильтров и присваиваем их нужной переменой
	condition = {'$and': [{'doc_type':proc_id}]}
#	condition = {'doc_type':proc_id, 'parent':{'$or':(parent)}
	if parent == '_':
		condition['$and'].append({'$or': ({'parent': '_'}, {'parent': {'$exists': 0}} )})
	else:
		condition['$and'].append({'parent': parent })
		no_limit = True
	_meta_table = {}
	#это для получение полного метатейбла с полем user чтоб по нему фильтровать.
	for meta in meta_doc['doc']:
		_meta_table[meta['id']] = meta
	user_in_meta = 'user' in _meta_table
	# это получение уже обрезаного мета тейбла.
	_meta_table = {}
	for meta in meta_table:
		_meta_table[meta['id']] = meta

	if doc_id != '_':
		condition['$and'].append({'owner': doc_id})
	if 'date' in meta_table:
		condition['$and'].append({'doc.date': {'$gte': start_date, '$lte': end_date}})
	if user_in_meta and not is_admin(request) and get_const_value(request, 'user_self') == 'yes' :
		condition['$and'].append({'doc.user': "user:"+user_name})

	if not 'main' in filter or any(filter['main']) == False and any(filter['column'])==False and (branch_id is None):
		pass
	elif 'main' in filter and any(filter['main']):
		regex = re.compile(u'%s' % filter['main'], re.I | re.UNICODE )
		ors = []
		for field in _meta_table:
			suffix = ''
			if 'is_translate' in _meta_table[field] and _meta_table[field]['is_translate']:
				suffix = '.' + cur_lang(request)
			ors.append({'doc.' + field + suffix: regex})
		condition['$and'].append({'$or': ors})
	elif 'column' in filter and any(filter['column']): #фильтр по колонкам
		for field in filter['column']:
			f = filter['column'][field]
			if not 'val' in f and not 'range' in f: continue
			if _meta_table[field]['type'] == 'date':
				condition['$and'].append({'doc.' + field: {'$gte':f['range']['from'], '$lt':f['range']['to'] }})
				continue
			regex = re.compile(u'%s' % str(f['val']), re.I | re.UNICODE)
			suffix = ''
			if 'is_translate' in _meta_table[field] and (_meta_table[field]['is_translate'] == "true" or
					                                             _meta_table[field]['is_translate'] == True):
				suffix = '.' + cur_lang(request)
			if _meta_table[field]['type'] == 'select':
				suffix = '.' + cur_lang(request)
				ids= []
				rel = _meta_table[field]['relation']
				for res in request.db.doc.find({"doc_type":rel, 'doc.'+('name' if rel == 'des:users' else 'title') + suffix: regex }):
					ids.append(res['_id'])
				condition['$and'].append({'doc.' + field:  {'$in':ids}})
			else:
				if 'str_option' in f and f['str_option'] == 'eq':
					condition['$and'].append({'doc.' + field + suffix: f['val']})
				else:
					regex = re.compile('%s%s%s' % ( ('^' if 'str_option' in f and f['str_option'] == 'start' else ''), f['val'],
					                                (('$' if 'str_option' in f and  f['str_option'] == 'end'  else ''))), re.I | re.UNICODE)
					condition['$and'].append({'doc.' + field + suffix: regex})

	#is_ajax = request.header.get('X-Requested-With') == 'XMLHttpRequest'
	docs_table_count = request.db.doc.find(condition).count()
	docs_table = None
	if no_limit:
		docs_table = request.db.doc.find(condition).sort('doc.date', -1)
	else:
		docs_table = request.db.doc.find(condition).sort('doc.date', -1).skip(skip).limit(limit)
	return list( sort_body(request, proc_id, meta_table, docs_table) ),   docs_table_count

def create_date():
	return time.strftime("%Y-%m-%d %H:%M:%S")

p = print

def table_add_row_post(request):
	data      = get_post(request)
	proc_id   = data['proc_id']
	owner     = data.get('owner', None)
	# defaults  = json.loads(data['defaults'] if 'defaults' in data else {})

	auto_fill = data.get('auto_fill', False)

	if not user_has_permission(request, proc_id, 'create'):
		return response_json(request, {"result": "fail", "error": "You have no permission."})
	try:
		doc_id, updated = create_empty_row_(request, proc_id, owner, auto_fill)   # update_row_(proc_id, doc_id, {})
		if doc_id:
			return response_json(request, {"result":"ok", "id":doc_id, "updated": updated})
		else:
			return response_json(request, {"result":"fail", "descr":"not doc_id", "error":json.dumps(updated)})
	except Exception as e:
		return response_json(request, {"result":"fail", "descr":"exception", "error": e})

checkout_error = 'You can not modify the posted document'
def create_empty_row_(request, proc_id, owner, auto_fill, defaults={}, clear_id=True, id=None):
	if not id: id = uuid4().hex
	user = defaults['user'] if 'user' in defaults else get_current_user(request, True)
	date = defaults['date'] if 'date' in defaults else create_date()
	doc_type =  ': ' if clear_id else proc_id, # if you create a document that has been canceled then set :
	doc_s = {"_id":id, "doc": {'date':date, 'rev':uuid4().hex[-9:], "last_art":"true", 'user':user},
	         "type": "table_row", "seq_id":0, 'tags':{}, "doc_type":doc_type,  "owner":owner if owner else '_'}

	doc_s['doc'].update(defaults)

	res = 'ok'; err=''

	if res != 'ok': return {"result":"fail", "error":json.dumps(err) }

	doc_id= request.db.doc.save(doc_s)
	updated = make_updated(request, {}, doc_s['doc'], proc_id)
	if res == 'ok' and doc_s['owner'] != '_':
		print('doc_s', doc_s)
		res, err = on_create_subtable(request, doc_s)
		if res != 'ok': return None, err
	return doc_id, updated

def create_row(request, proc_id, owner, defaults={}):
	doc_id, updated = create_empty_row_(request, proc_id, owner, '', {})
	import time
	time.sleep(0.1)

	update_row_(request, proc_id, doc_id, defaults, '_', no_synh=True)
	return doc_id

def set_val_field(request, doc_id, field={}):
	doc = get_doc(request, doc_id)
	proc_id = doc['doc_type']
	mt = get_mt(request, proc_id)
	k = field.keys()[0]
	v = field[k]
	if not k in [f['id'] for f in mt['doc']]:
		data = {'hint_ru':'', 'hint_en':'','title_ru':k, 'title_en':k, "visible":'true', "oncreate":'edit',
				"type": 'string', 'is_editable':'true', "id":k, 'is_translate':'false'}
		add_field(request, proc_id, data, field_id=None)
	doc['doc'][k] = v
	request.db.doc.save(doc)

def table_get_row_post(request):
	data = get_post(request)
	row_id = data['row_id']
	proc_id = data['proc_id']
	doc = get_doc(request, row_id)
	if not proc_id: proc_id = doc['doc_type']
	doc_id, updated = create_empty_row_(request, proc_id, False, False, defaults={}, clear_id=True)

	updated = make_updated(request, {}, doc['doc'], doc['doc_type'])
	return response_json(request, {"result":"ok", "updated":updated, "row_id": doc_id })

def table_preedit_row_post(request):
	data = get_post(request)
	doc = get_doc(request, data['doc_id'])
	return response_json(request, {"result":"ok", "doc":{
		'title': ct(request, doc['doc']['title']), 'body': ct(request, doc['doc']['body']), 'date': doc['doc']['date']}} )

def save_auto_tags(request, doc, tags):
	"""
		автоопределение тегов  получаем текст и сравниваем его с с теми тегами которые уже есть и вычленяем их из него
		работает только для новостей
		1) разбиваем строчку с тегами через запятую и создаем словарь из всего этого
		2) находим документ с облаком тегов
		3) получаем текст и название новости плюсуем
		4) и выводим отсюда тег нужный
	"""
	try:
		if not doc['doc_type'] in ['des:news']: return 'not des:news'
		if 'tags' in doc['doc'] and doc['doc']['tags']:
			text_tags = dict([(i.strip().lower(), 1) for i in doc['doc']['tags'][cur_lang(request)].split(',') if i.strip()])
		else: text_tags = {}
		tags = request.db.conf.find_one({"_id":tags })
	#	doc_doc = defaultdict(doc['doc'])
		title = doc['doc']['title'][cur_lang(request)] if 'title' in doc['doc'] else ''
		descr = doc['doc']['descr'][cur_lang(request)] if 'descr' in doc['doc'] else ''
		body = doc['doc']['body'][cur_lang(request)] if 'body' in doc['doc'] else ''
		try: text = ' '.join([title, descr, body.decode('UTF-8')])
		except: text = ' '.join([title, descr, body])
		text = text.lower()
		for res in tags['tags'][cur_lang(request)]:
			if ' ' in res[0]: checked = res[0] in text
			else: checked = res[0].encode('UTF-8') in text.split(' \n\t\r.,:;!?%"\'')
			if checked: text_tags[res[0]] = 1

		doc['doc']['tags'][cur_lang(request)] = ', '.join(text_tags.keys())
	except: pass

def count_tags(request, t, t_old, tag_dict):
	""" при сохранении документа пересчитать кол-во тегов в облаке t-скорее всего тег
		вызывается в save_tags
		1) получает документ где хранится облако тегов
		2) идем по тегам и если есть
	"""
	tags = request.db.conf.find_one({"_id":'tags_'+tag_dict[4:]})  # получает документ где хранится облако тегов
	tags = tags['tags'][cur_lang(request)] if tags and 'tags' in tags and cur_lang(request) in tags['tags'] else []
	tags_d = dict(tags)
	for res in t:
		if not res in tags_d: tags_d[res] = 1 #если нету полученого в тегах документа    то прописуем там
		else: tags_d[res] += 1
	for res in t_old:
		if res in tags_d:
			tags_d[res] -= 1
			if tags_d[res] == 0: del tags_d[res]
	tags = [ (res, tags_d[res]) for res in tags_d]
	request.db.conf.save( {"_id":'tags_'+tag_dict[4:],"tags":{cur_lang(request):tags}} )

def save_tags(request, doc, tag_dict):
	"""
	разбиваем строчку тегов в масив и заносим в документ правильно разбитые теги
	call the function that fills in the tag cloud
	tag_dict - справочник из которого теги сохраняются   вроде как удалено из текста
	1) check that the document contains tags
	2) разбиваем строку тегов на слова через запятую и запихиваем в словарь tags = {'tag1':1,'tag2':1}
	"""
	# TODO если теги пустые то мы их не стираем
	lang = cur_lang(request)
	if 'doc' in doc and doc['doc'] and 'tags' in doc['doc'] and doc['doc']['tags']:
		if lang in doc['doc']['tags']:
			if not doc['doc']['tags'][lang]: doc['doc']['tags'][lang] = ''
			t_old = doc['tags'][lang] if 'tags' in doc and lang in doc['tags'] else []
			# разбиваем строку тегов на слова через и запихиваем в словарь tags = {'123':1, '456':1}
			tags = dict([(i.strip().lower(), 1) for i in doc['doc']['tags'][lang].split(',') if i.strip()])
			if not 'tags' in doc: doc['tags'] = {}
			if not is_admin(request) and not user_has_permission(request, doc['doc_type'], 'edit_tag'):
				# наполняем в ифе tags теми перемеными которые не содержат звездочки.
				tags2 = tags; tags = {}
				for res in tags2:
					if not '*' in res:
						tags[res] = tags2[res]
			doc['tags'][lang] = tags
			if doc['doc_type'] in ['des:news', 'des:obj', 'des:banners', 'des:wiki']:
				if 'pub' in doc['doc'] and doc['doc']['pub'] == 'true':
					if 'accept' in doc['doc'] and doc['doc']['accept'] == 'true' or doc['doc_type'] in ['des:banners', 'des:wiki', 'des:news']:
						count_tags(request, tags, t_old, doc['doc_type'])
			elif doc['doc_type'] in ['des:ware']:
				count_tags(request, tags, t_old, doc['doc_type'])
			doc['doc']['tags'][lang] = ', '.join(tags)
			request.db.doc.save(doc)

async def table_update_row_post(request):
	proc_id = request.match_info.get('proc_id')
	force = request.match_info.get('force', False)
	if not force and not user_has_permission(request, proc_id, 'create'):
		return {"result": "fail", "error": "You have no permission."}
	data = get_post(request)
	row_id = data['row_id']
	# print('parent', data['parent'])

	parent = data['parent'] if  'parent' in data else '_'
	data = json.loads(data['data'])
	print( 'data', data )
	if 'rev' in data:
		del data['rev']

	return response_json(request, update_row_(request, proc_id, row_id, data, parent = parent) )

def update_row_(request, proc_id, doc_id, data, parent, noscript=True, no_synh=False, accept_def=False, no_notify=False):
	"""
	:param nouscript:  удаляет теги и стили из текста вроде
	:param no_synh:    не синхронизирует с фейсбуком
	:param accept_def: не публикует документ автоматически, нужно для всяких парсеров
	:param no_notify:
	:return: json format doc[id] proc_id   doc_ = {'body':wiki(body), 'date':date, 'title':title }
	"""

	print('parent', parent)

	doc_meta = get_mt(request, proc_id)
	meta_table = doc_meta['doc']
	doc = get_doc(request, doc_id)
	doc_parent = get_doc(request, parent) if parent != '_' else None
	user = request.db.doc.find_one({'_id':doc['doc']['user']})
	old_row = dict(doc['doc']) # doc из документа который создан create_empty_row_
	#=============================================================================================================================
	for field in meta_table:  # инициализируем поля и устраняем всякие глюки если чегото нет
		if 'is_translate' in field and (field['is_translate'] == True or field['is_translate'] == "true"):
			if not field['id'] in doc["doc"] or type(doc['doc'][field['id']]) != dict: # если в старой записи нет поля или оно не словарь
				doc["doc"][field['id']] = {}
			if not field['id'] in data:  # этот иф можно закоментировать     проверить     если поля нет в новой записи
				data[field['id']] = old_row[field['id']][cur_lang(request)] if field['id'] in old_row and old_row[field['id']] and cur_lang(request) in old_row[field['id']] else ''
			doc["doc"][field['id']][cur_lang(request)] = data[field['id']]
		else:
			if field['oncreate'] == 'edit':
				if not field['id'] in data:
					data[field['id']] = ''
				else:
					doc["doc"][field['id']] = data[field['id']]

	#===================================================================================================================
	if 'body' in doc['doc']:    # очищаем  боди от всякой ерунды
		text = doc['doc']['body'][cur_lang(request)] if  type(doc['doc']['body']) == dict else doc['doc']['body']
		text = re.sub(r'<!--(.|\n)*?-->', '', text)
#		if noscript or True: #==========================================================================================
		if noscript and not is_admin(request):
			text = no_script(text, True)
		if type(doc['doc']['body'] ) == dict:
			doc['doc']['body'][cur_lang(request)] = text
		else: doc['doc']['body'] = text

	#===================================================================================================================
	# if res == 'ok':  # если поле
	doc['doc_type'] = proc_id
#		if not is_admin:

	#сохранение единственого материала для отображения единственого автора в колонке
	if 'last_art' in doc['doc'] and  doc['doc']['last_art'] == 'true':
		for res in request.db.doc.find({'doc_type':proc_id, 'doc.user':doc['doc']['user'], 'doc.last_art':'true'}):
#			for res in db.doc.find({'doc_type':{'$ne':':'}, 'doc.user':doc['doc']['user'], 'doc.last_art':'true'}):
			res['doc']['last_art'] = 'false'
			request.db.doc.save(res)
	#сохранение для разрешенного пользователя
	if is_admin(request) or accept_def or proc_id == 'des:obj' and 'accept' in user['doc'] and user['doc']['accept'] == 'true':
		doc['doc']['accept'] = 'true'
	else: doc['doc']['accept'] = 'false'

	save_auto_tags(request, doc,'tags_'+proc_id[4:]) # автоопределение тегов  получаем текст и сравниваем его с с теми тегами которые уже есть и вычленяем их из него
	save_tags(request, doc, 'tags_'+proc_id[4:])

	#сохранение для разрешенного пользователя
	if accept_def or proc_id == 'des:obj' and 'primary' in user['doc'] and user['doc']['primary'] == 'true':
		doc['doc']['primary'] = 'true'
	else: doc['doc']['primary'] = 'false'

	if 'parent_id' in data and data['parent_id']:
		parent_id = data['parent_id']
		# Удаляем из старого родителя
		request.db.doc.update({'child':{'$in':[doc_id]}}, {'$pull':{'child':doc_id}})
		# Добавляем в нового родителя
		# if parent_id !='_': db.doc.update({'_id':parent_id}, {'$push':{'child':doc_id}})
		request.db.doc.update({'_id':parent_id}, {'$push':{'child':doc_id}})
		# Добавляем себе нового родителя
		doc['parent'] = parent_id
	else:
		doc['parent'] = parent
		if doc_parent: # тут мы получили родительский документ и смотрим если в нем нет себя ребенка то мы себя заносим
			if not 'child' in doc_parent: doc_parent['child'] = []
			doc_parent['child'].append(doc_id)
			request.db.doc.save(doc_parent)

	request.db.doc.update({'_id':doc_id}, doc)

	# =======================================================================
	res, err = event('on_update_row', proc_id, doc_id)
	if res != 'ok': return {"result":"fail", "error":json.dumps(err)}
	# =======================================================================

	doc['final'] = 1

	from core.core import get_settings

	if get_settings('notify_user', False) and check_pub_doc(doc) and proc_id in ['des:obj', 'des:radio', 'des:comments']: subscribe(doc)
	if not no_notify and get_settings('notify_admin', False) and proc_id in ['des:obj', 'des:radio', 'des:comments']: notify_admin(doc)

	if res == 'ok' and 'owner' in doc and doc['owner'] != '_':
		on_update_subtable(request, doc)

	from core.union import clean_cache
	from libs.sites.sites import wiki
	clean_cache(doc)

	doc_ = {'body':wiki(request, ct(request, doc['doc']['body'])), 'date':doc['doc']['date'], 'title':ct(request, doc['doc']['title']) }
	return {"result":"ok", "doc_id":doc['_id'], "proc_id":proc_id, "updated":"", "doc":doc_}

def check_pub_doc(doc, need_accept = True):
	if doc['doc_type'] != 'des:comments':
		return 'pub' in doc['doc'] and doc['doc']['pub'] == 'true' and (not need_accept or 'accept' in doc['doc'] and doc['doc']['accept'] == 'true')
	return True

def check_type_subscribe(doc):
	if doc['doc_type'] == 'des:comments': return 'sub_answ_comm'
	return 'sub_alien'

def subscribe(request, doc):
	if 'mail_sent' in doc:
		return
	doc['mail_sent'] = 1
	request.db.doc.save(doc)
	t = check_type_subscribe(doc)
	cond = {'doc_type':'des:users', 'subscription.'+t:'true'}
	try:
		if t == 'sub_answ_comm': cond['_id'] = doc['doc']['parent_comm']
	except: cond['_id'] = '_'
	author = get_doc(doc['doc']['user'])
	title = ''
	if 'title' in doc['doc']: title = ct(request, doc['doc']['title'])
	for res in request.db.doc.find(cond):
		if not 'mail' in res['doc']: continue
		to = res['doc']['mail']
		dom = get_settings('domain')
		if t == 'sub_answ_comm':
			link = 'http://'+dom+'/news/'+doc['doc']['owner']+'#comm_'+str(doc['doc']['comm_id'])
			text = u"""<html><head></head><body>
			<p>Пользователь {0} оставил ответ на ваш комментарий. Можете просмотреть по адресу {1}
			</p></body></html>""".format( ct(request, author['doc']['name']), link)
		else:
			link = 'http://'+dom+'/news/'+doc['doc']['rev']
			text = u"""<html><head></head><body>
			<p>Пользователь {0} разместил новый материал. <a href="{0}"><b>{2}</b></a></p>
			<p>Можете просмотреть по адресу {1} </p></body></html>""".format( ct(request, author['doc']['name']), link, title)
		from core.core import route_mail
		route_mail(request, to, u'Новые материалы на сайте '+dom, text)

def notify_admin(request, doc):
	if 'mail_admin_sent' in doc: return
	doc['mail_admin_sent'] = 1
	request.db.doc.save(doc)
	author = get_doc(request, doc['doc']['user'])
	author_name = ct(request, author['doc']['name']) if author else u'Аноним'
	from core.core import get_admin
	try:
		to = get_admin(request, True)['doc']['mail']
		text = ''
		domain = get_settings('domain')
		if get_const_value(request, 'only_closed_news', 'false') == 'true':
			if doc['doc_type'] == 'des:obj' and (not 'accept' in author['doc'] or author['doc']['accept'] == 'false'):
				link = 'http://'+domain+'/news/'+doc['doc']['rev']
				text = 'Не удостовереный Пользователь {0} разместил новый материал. Можете просмотреть по адресу {1}'.format( ct(request, author['doc']['name']), link)
		else:
			if doc['doc_type'] == 'des:comments':
				link = 'http://'+domain+'/news/'+doc['doc']['owner']+'#comm_'+str(doc['doc']['comm_id'])
				text = u'Пользователь {0} оставил комментарий. Можете просмотреть по адресу {1}'.format(request, author_name, link)
			else:
				link = 'http://'+domain+'/news/'+doc['doc']['rev']
				text = u'Пользователь {0} разместил новый материал. Можете просмотреть по адресу {1}'.format( ct(request, author['doc']['name']), link)
		from core.core import route_mail
		if text:
			route_mail(request, to, u'Новые материалы на сайте '+domain, text)
	except:
		pass

def check_map_perm(request, proc_id, meta_table, permission = 'view'):
	meta = []
	for i in meta_table:
		if user_has_permission(request, proc_id, permission, i['id']):
			meta.append(i)
	return meta

def find_field(idd, meta_table):
	for field in meta_table:
		if field['id'] == idd:
			return field
	return None

def table_update_cell_post(request):
	proc_id = request.match_info.get('proc_id')
	if not user_has_permission(request, proc_id, 'edit'):
		return {"result": "fail", "error": "You have no permission."}
	data = get_post(request)
	idd = data['id']
	field = data['field']
	value = unquote( data['value'] )
	return response_json(request, update_cell(request, idd, proc_id, field, value) )

def update_cell(request, idd, proc_id, field, value):
	meta_doc = get_mt(request, proc_id)

	meta_table = meta_doc['doc']
	doc = get_doc(request, idd)

	meta = find_field(field, meta_table)
	if meta is None: return {"result":"fail", "error":"there is not such field " + field }

	if 'is_translate' in meta and (meta['is_translate'] == "true" or meta['is_translate'] == True):
		if not field in doc["doc"] or type(doc["doc"][field]) != dict:
			doc["doc"][field] = {}
		doc["doc"][field][cur_lang(request)] = value
	else:
		doc["doc"][field] = value

	request.db.doc.save(doc)
	if proc_id == 'des:news':
		save_auto_tags(request, doc,'tags_'+proc_id[4:])
	save_tags(request, doc, 'tags_'+proc_id[4:])

	updated = updated_edit_cell(request, field, value, proc_id)

	res, err = event('on_update_row', proc_id, idd)

	if res != 'ok': return {"result":"fail", "error":json.dumps(err) }
	otvet = {"result":"ok", "updated": updated }
	if 'owner' in doc and doc['owner'] != '_':
		on_update_subtable(request, doc)
	return otvet

def updated_edit_cell(request, field, value, proc_id):
	"""compares the old and the new value and returns the fields that are changed """
	meta_table = get_mt(request, proc_id)['doc']; updated = ''; meta = {}
	for res in meta_table:
		if field in res.get('id'): meta = res
	if 'type' in meta:
		if meta['type'] == 'passw':
			v = '*****'; formatted = '*****'
		elif meta['type'] == 'checkbox':
			v = str(value)
			if v == 'true':
				color = 'green'; icon = 'fa-check'
			else:
				color = 'red'; icon = 'fa-close'
			formatted = "<span style='color:"+color+"; font-size:16px'><i class='fa "+icon+"'></i></span>"
		elif meta['type'] == 'select':
			v = str(value)
			aaa = get_doc(request, v)
			if aaa: formatted = html.escape(get_doc_title(request, aaa, '[{}]'.format(v) ))
			else: formatted = '-'
		elif meta['type'] == 'cascad_select':
			v = str(value)
			aaa = get_doc(request, v)
			if aaa: formatted = html.escape(get_doc_title_cascad(request, aaa, '[{}]'.format(v) ))
			else: formatted = '-'
		else:
			formatted = value
			v = value
		t = type(v)
		if t == int or t == float or meta['type'] == 'checkbox':
			updated  = { "formatted":formatted, "value":v, 'field_name':field }
		else:
			updated =  { "formatted":formatted, "value": v, 'field_name':field  }
	return updated

def on_update_subtable(request, doc):
	owner = get_doc(request, doc['owner']) # parent doc
	res = 'ok'; err=''
	if res != 'ok': return {"result":"fail", "error":json.dumps(err)}
	request.db.doc.save(owner)
	return 'ok', None

def on_create_subtable(request, doc):
	owner = get_doc(request, doc['owner'])
	print('owner ', owner )
	request.db.doc.save(owner)
	return 'ok', None

def make_updated(request, old_row, new_row, proc_id):
	"""сравнивает старое и новое значеие и возвращает те поля которое изменились  это для изменения всей строки"""
	updated = ''
	meta_table = get_mt(request, proc_id)['doc']
	for k, v in new_row.items():
		if not k in old_row or old_row[k] != v:
			meta = find_field(k, meta_table)
			# преобразовуем название если в поле есть селект
			if meta and 'type' in meta and meta['type'] == 'passw':
				v = '*****'; formatted = '*****'
			elif meta and 'type' in meta and meta['type'] == 'checkbox':
				v = str(v)
				if v == 'true':
					color = 'green'; icon = 'fa-check'
				else:
					color = 'red'; icon = 'fa-close'
				formatted = json.dumps("<span style='color:"+color+"; font-size:16px'><i class='fa "+icon+"'></i></span>")[1:-1]
			elif meta and 'type' in meta and meta['type'] == 'select':
				v = str(v)
				doc = get_doc(request, v)
				if doc: formatted = cgi.escape(get_doc_title(request, doc, '[{}]'.format(v) ))
				else: formatted = '-'
			elif meta and 'type' in meta and meta['type'] == 'cascad_select':
				v = str(v)
				doc = get_doc(request, v)
				if doc: formatted = cgi.escape(get_doc_title_cascad(request, doc, '[{}]'.format(v) ))
				else: formatted = '-'
			else: formatted = ct(request, v)
			if updated: updated += ', '
			# поле int нужно преобразовывать шif type(aaa) == 'int'
			t = type(v)
			if t == int or t == float or meta and 'type' in meta and meta['type'] == 'checkbox':
				updated += '"'+k+'": {"formatted": "%s", "value":"%s"}' % (formatted, v)
			else:
				updated += '"'+k+'":{"formatted": %s, "value": %s}' % (json.dumps(formatted), json.dumps(ct(request, v)))
	updated = '{'+updated+'}'

	return updated

async def table_del_row_post(request):
	data = await request.post()
	# proc_id = data['proc_id'] if 'proc_id' in data else None
	proc_id = data.get('proc_id')
	force = data.get('force', False)
	ids =   data.get('ids')
	ids =   json.loads( ids )
	idsn =  data.get('idsn')
	idsn =  json.loads(idsn)

	print( "4444", data['idsn'])

	for doc in request.db.doc.find({'_id': {'$in': idsn}}):
		final = False
		if not 'final' in doc: final = True
		# запрещаем не админу удалять документы созданые админом
		if not force and final and not user_has_permission(request, proc_id, 'delete') or not is_admin(request):
			return {"result": "fail", "error": "You have no permission."}
	return del_row(request, proc_id, ids)

def del_row(request, proc_id, ids):
	""" Удаление документа
		1) Идем по всем полученым для удаления ids
		2) Делаем какието операции с бугалтерией
		3) Удаляем картинки приатаченый к этому документу
		4) Удаляем сам документ
		5) Выполняем тригер в песочнице связаный с удалением этого документа
		============================================================================
		6) Удаляем себя у всех потомков
		7) Удаляем себя у всех родителей
		8) Очищаем если у документа есть родитель родителя
		9) удаляем теги которые есть в документе из облака тегов
	"""
	ctr = 0; errors = ''
	for current_id in ids:
		doc = get_doc(request, current_id)
		if not doc: return {"result": "fail", "error": 'doc not found'}
		proc_id = doc['doc_type']

		parent = doc['parent'] if 'parent' in doc else '_'
		children = doc['child'] if 'child' in doc else '_'
		old_row = doc['doc']
		from libs.files.files import del_all_files
		del_all_files(request, doc['_id'], proc_id)
		request.db.doc.remove({'_id': doc['_id']})
		try:
			res, err = event('on_del_row', proc_id, {'old_row':old_row, "doc": doc}) # TODO обработать err
			if res != 'ok': errors+=err
		except:pass
		ctr += 1
		request.db.doc.remove({"owner":doc['_id']})
		# request.db.tree.remove({"owner":doc['_id']})
		if children != '_':
			request.db.doc.update_many({'parent':doc['_id']}, {'$set':{'parent':'_'} })
		if parent != '_':
			request.db.doc.update({'child':{'$in':[doc['_id']]}}, {'$pull':{'child':doc['_id']}})
		if not ': ' in proc_id:
			del_doc_tags(request, proc_id, doc)
	if errors:  return {"result": "fail", "error":errors}
	return response_json(request, {"result":"ok", "counter":ctr})

def del_doc_tags(request, proc_id, doc):
	""" при удалении документа пересчитать кол-во тегов в облаке t-скорее всего тег
		идем по всем вложеным спискам в облаке и смотрим что списки у каждого первый елемент не совпадает с одним из удаляемых тегов если совпал
		то удаляем вложеный список или вычитаем единицу из второго элемента
	"""
	cloud_tags = request.db.conf.find_one({"_id":'tags_'+proc_id[4:]})  # get doc where storage cloud tags
	if not cloud_tags: return 'not cloud_tags'
	tags = cloud_tags['tags'][cur_lang(request)] if cloud_tags and 'tags' in cloud_tags and cur_lang(request) in cloud_tags['tags'] else []# берет с нужным языком
	del_tags = doc['tags'][cur_lang(request)] if 'tags' in doc and cur_lang(request) in doc['tags'] else []
	if not del_tags: return 'not del_tags'
	for res in tags:
		if res[0] in del_tags:
			if res[1] == 1: tags.remove(res)
			else: res[1] -= 1
	request.db.conf.save( cloud_tags )
	return 'ok'

def delete_sub_row(request, proc_id, current_id):
	doc = get_doc(request, current_id)
	if doc['owner'] and doc['owner']!='_':
#		for tree in db.view("_design/main/_view/sub_docs", key=current_id, include_docs=True):
		for res in request.db.doc.find({'_id':current_id}):
			request.db.doc.remove(res)
	return {"result":"ok"}

def get_des_field_post(request):
	data = get_post(request)
	proc_id = data['proc_id']
	doc = get_mt(request, proc_id)
	field = doc['doc']
	for l_field in field:
		return {"id":l_field['id'], "title":translate( cur_lang(request), l_field['title'])}

def get_field_post(request):
	data = get_post(request)
	proc_id = data['proc_id']
	doc = get_mt(request, proc_id)
	field = doc['doc']
	list_field = []
	for l_field in field:
		list_field.append({"id":l_field['id'], "title":ct(request, l_field['title'])})
	return response_json(request,{"result":"ok", "list_field":list_field })

def table_transfer_post(request):
	data = get_post(request)
	proc_id = data['proc_id']
	if not user_has_permission(request, proc_id, 'create'):
		return {"result": "fail", "error": "You have no permission."}
	return transfer_doc(request, proc_id, json.loads(get_post('ids')), get_post('to'))

def transfer_doc(request, proc_id, ids, to):
	proc_id = get_post('proc_id')
	if not user_has_permission(request, proc_id, 'create'):
		return {"result": "fail", "error":"You have no permission."}
	ctr = 0
	dat = get_post(request)
	data = json.loads(dat['ids'])
	for current_id in data:
		doc = get_doc(request, current_id)
		if doc is not None:
			doc['doc_type'] = dat['to']
			request.db.doc.save(doc);	ctr += 1
	return response_json(request, {"result":"ok", "counter":ctr})

def table_del_field_post(request):
	data = get_post(request)
	proc_id = data['proc_id']
	field_id = data['field_id']
	doc = get_mt(request, proc_id)
	field = doc['doc']
	for i in field:
		if field_id in i['id']:
			field.remove(i)
			request.db.map.save(doc)
			return response_json(request, {"result":"ok"})
	return response_json(request, {"result":"fail"})

def table_edit_field_post(request):
	data = get_post(request)
	proc_id = data['proc_id']
	field_id = data['field_id']
	data = json.loads(data['data'])
	return add_field(request, proc_id, data, field_id)

def table_add_field_post(request):
	data = get_post(request)
	proc_id = data['proc_id']
	print('1) data===================================================================================================')
	data = json.loads(data['data'])
	print('data', data)
	return add_field(request, proc_id, data)

def add_field(request, proc_id, data, field_id=None): #field_id=None индекс поля которое нужно поменять при редактировании
	if not user_has_permission(request, proc_id, 'create'):
		return response_json(request, {"result": "fail", "error": "You have no permission."})
	print('data===================================================================================================')
	print('data', data)
	if 'relation' in data: relation = data['relation']
	else: relation = ''
	if 'relation_field' in data: relation_field = data['relation_field']
	else: relation_field = ''
	for i in data:
		tp = data['type'] if 'type' in data else 'string'
		field = { "hint": {"ru":data['hint_ru'], "en":data['hint_en']},
				"title": {"ru":data['title_ru'],"en":data['title_en']}, "visible": data['visible'], "oncreate": data['oncreate'],
				"type": tp, "relation":relation, "relation_field":relation_field,
				"is_editable": data['is_editable'], "id": data['id'], "is_translate":data['is_translate']}
	doc = get_mt(request, proc_id)
	if not field_id:
		doc['doc'].append(field)
	else:
		for res in doc['doc']:
			if field_id == res['id']:
				cur = doc['doc'].index(res)
				doc['doc'].remove(res)
				doc['doc'].insert(cur, field)
	request.db.map.save(doc)
	return response_json(request, {"result":"ok"} )

def move_field_post(request, proc_id, field_id, left):
	data = get_post(request)
	left = data['one_field']
	proc_id = data['proc_id']
	doc = get_mt(proc_id)
	for res in doc['doc']:
		if left in res.values():
			left = doc['doc'].index(res)
	for res in doc['doc']:
		if get_post('field_id') in res.values():
			doc['doc'].remove(res)
			doc['doc'].insert(left, res)
			request.db.map.save(doc)
	return {"result":"ok"}

def duplicate_doc_post(request):
	data = get_post(request)
	doc_id = data['row_id']
	doc = dict(get_doc(request, doc_id))
	doc['_id'] = uuid4().hex
	request.db.doc.save(doc)
	for res in request.db.doc.find({'owner':doc_id}):
		sub_doc = dict(res)
		sub_doc['_id'] = uuid4().hex
		sub_doc['owner'] = doc['_id']
		request.db.doc.save(sub_doc)
	updated = make_updated(request, {}, doc['doc'], doc['doc_type'])
	return response_json(request, {"result":"ok", "row_id":doc['_id'], "updated":updated })

def get_event_post(request):
	data = get_post(request)
	proc_id = data['proc_id']
	name_func = data['name_func']

	doc = request.db.map.find_one({'_id':proc_id}, {'events':1})
	e = doc['events'][name_func] if 'events' in doc else ''
	return response_json(request, {"result":"ok", "func_text":json.dumps(e)})

def add_func(request):
	if is_admin(request):
		return templ('libs.auth:conf_', request, {"proc_id":'add_func'})

def table_sort_columns_post(request):
	data = get_post(request)
	proc_id = data['proc_id']
	order = json.loads(data['order'])
	doc = request.db.map.find_one({'_id':proc_id})
	fields = {}
	for res in doc['doc']:
		fields[res['id']] = res

	doc['doc'] = []
	for res in order:
		doc['doc'].append(fields[res])
	request.db.map.save(doc)
	return response_json(request, {"result":"ok"})

def table_copy_doc(request):
	"""
	1) Создаем пустой документа
	"""
	data = get_post(request)
	old_id = data['doc_id']

	from libs.files.files import get_nf, get_file_meta, add_file_raw
	# 1) копируем просто документ
	new_id_owner = simply_copy_doc(request, old_id)
	# 2) Дублирование картинки

	from gridfs import GridFS
	fs = GridFS(request.db)
	for fn in request.db.fs.files.find({'doc_id':old_id, 'file_name':re.compile('^orig_', re.I | re.U)}):
		# TODO таки уменьшать картинку при занесении, сейчас просто название меняется
		if not fn: return None, None, None
		f = fs.get(fn['_id']).read()
		fs.put(f, file_name ='thumb_1'+fn['file_name'], doc_id = new_id_owner, proc_id=fn['proc_id'],  mime = fn['mime'])
		fs.put(f, file_name ='orig_1'+fn['file_name'],  doc_id = new_id_owner, proc_id=fn['proc_id'],  mime = fn['mime'])
		# add_file_raw(fn['proc_id'], old_id, f, fn['mime'], '1'+fn['file_name'] )

	# 3) Дублирование тех документов что он owner
	for res in request.db.doc.find({'owner':old_id}):
		doc_id = simply_copy_doc(request, res['_id'])
		request.db.doc.update({'_id':doc_id}, {'$set':{'owner':new_id_owner}})
	return {"result":"ok"}

def simply_copy_doc(request, old_id):
	new_id = uuid4().hex
	old_doc = request.db.doc.find_one({'_id':old_id})
	old_doc['_id'] = new_id
	old_doc['doc']['rev'] = uuid4().hex[-9:]
	request.db.doc.insert(old_doc)
	return new_id

def table_sort_post(request):
	"""
	1) получаем нужный документ
	2) получаем его предыдущий документ
	3) берем дату предыдущего документа увеличиваем её на 1 секунду и сохраняем
	// снизу - некст, сверху - прев.  !!!!!!!!!
	"""
	data = get_post(request)
	doc_id = data['doc_id']
	prev = data['prev'] if 'prev' in data else ''
	next = data['next'] if 'next' in data else ''
	if next:
		old_date_id  = next
		delta = 1
	else:
		old_date_id  = prev
		delta = -1
	doc = request.db.doc.find_one({'_id':doc_id})
	old_date = request.db.doc.find_one({'_id':old_date_id})

	ddd = datetime.datetime.strptime(old_date['doc']['date'], "%Y-%m-%d %H:%M:%S")
	dd =  ddd + timedelta(seconds=delta)
	datef = datetime.datetime.strftime(dd, "%Y-%m-%d %H:%M:%S")
	datee =  datef
	doc['doc']['date'] = str(datef)
	request.db.doc.save(doc)
	return response_json(request, {"result":"ok", 'datee':datee})


N = 9
w = 595.0
h = 842.0
rows = 3
cols = 2
padding = 20.0
margin = 30.0

import cairo
import math
import sys

output = sys.argv[1]
inp = sys.stdin.read().split()
grids = []
for i in xrange(len(inp)/9):
  grids.append([map(int,l) for l in inp[i*9:(i+1)*9]])
surface = cairo.PDFSurface(output, w, h)

# background
def get_ctx():
  return cairo.Context(surface)
ctx = get_ctx()
ctx.set_source_rgb(1,1,1)
ctx.rectangle(0,0,w,h)
ctx.fill()

def line(x1,y1,x2,y2):
  ctx.move_to(x1,y1)
  ctx.line_to(x2,y2)

def draw(x1,y1,sz,grid):
  ctx.set_line_width(2)
  ctx.set_source_rgb(0, 0, 0)
  ctx.rectangle(x1, y1, sz, sz)
  ctx.stroke()

  ctx.set_line_width(0.1)
  ctx.set_source_rgb(0, 0, 0)
  for i in xrange(1,N):
    line(x1 + i*sz/N, y1, x1 + i*sz/N, y1 + sz)
    line(x1, y1 + i*sz/N, x1 + sz, y1 + i*sz/N)
  ctx.stroke()

  ctx.set_line_width(1.5)
  ctx.set_source_rgb(0, 0, 0)
  n = int(N**0.5)
  for i in xrange(n):
    for j in xrange(n):
      ctx.rectangle(x1 + i * sz/n, y1 + j * sz/n, sz/n, sz/n)
  ctx.stroke()

  ctx.set_font_size(sz/(N+4))
  for i in xrange(N):
    for j in xrange(N):
      if not grid[i][j]: continue
      txt = str(grid[i][j])
      ext = ctx.text_extents(txt)
      tw, th = ext[2], ext[3]
      ctx.move_to(x1 + j*sz/N + (sz/N-tw)/2 - 1, y1 + (i+1)*sz/N - (sz/N - th)/2)
      ctx.show_text(txt)

#
sz = min((w - (cols-1)*padding - 2*margin)/cols,
         (h - (rows-1)*padding - 2*margin)/rows)
xpad = (w - cols*sz - 2*margin)/(cols - 1)
ypad = (h - rows*sz - 2*margin)/(rows - 1)
y = margin
gi = 0
for i in xrange(rows):
  x = margin
  for j in xrange(cols):
    draw(x,y,sz,grids[gi])
    x += sz + xpad
    gi += 1
  y += sz + ypad

ctx.show_page()


import bpy
from bpy import *
from bpy.props import *

from ..utilities.utils import get_prefs
from ..utilities.utils import func_find_collection, func_make_collection
from ..utilities.utils import func_collection
from ..utilities.utils import lock_object, unlock_object

class RTS_OT_RePattern_Camera(bpy.types.Operator):
    """create camera for rendering"""
    bl_idname = "rts_ot.repattern_camera"
    bl_label = "Camera"
    bl_options = {'REGISTER', 'UNDO'}

    def draw(self, context):
        layout = self.layout

        prefs = get_prefs()
        cam_prefs = prefs.camera_type

        col = layout.column(align=True)

        box = col.box().column(align=True)
        box.separator()

        row = box.column(align=True)
        row.prop(cam_prefs, 'cam_reso')

        row.separator()

        row.prop(cam_prefs, 'cam_lens')

        box.separator()
        box.separator()

        row = box.row(align=True)
        row.label(text="Make Collection")

        box.separator()

        row = box.row(align=True)
        row.label(text="New Name...")
        row.prop(cam_prefs, "rb_collection_name_camera", text="")

        box.separator()

        row = box.row(align=True)
        row.label(text="Parent to...")
        row.prop(cam_prefs, "rb_collection_name_exist_camera", text="")

        box.separator()

    def execute(self, context):

        prefs = get_prefs()
        cam_prefs = prefs.camera_type
        coll_prefs = prefs.coll_type

        bpy.ops.view3d.snap_cursor_to_center()

        rota_x = 0
        rota_y = 0
        rota_z = 0

        loca_x = 0
        loca_y = 0

        if cam_prefs.cam_reso == '32px':
            loca_z = 31.25

        if cam_prefs.cam_reso == '64px':
            loca_z = 62.5

        if cam_prefs.cam_reso == '128px':
            loca_z = 125

        if cam_prefs.cam_reso == '256px':
            loca_z = 250

        if cam_prefs.cam_reso == '512px':
            loca_z = 500

        if cam_prefs.cam_reso == '1024px':
            loca_z = 1000

        if cam_prefs.cam_reso == '2048px':
            loca_z = 2000

        if cam_prefs.cam_reso == '4096px':
            loca_z = 4000

         # manage collection
        if cam_prefs.rb_collection_name_exist_camera != '':
            collect_exist = cam_prefs.rb_collection_name_exist_camera
            bpy.context.view_layer.active_layer_collection = bpy.context.view_layer.layer_collection.children[collect_exist]
        else:
            collect_exist = "RePattern"
            if collect_exist in bpy.data.collections:
                bpy.context.view_layer.active_layer_collection = bpy.context.view_layer.layer_collection.children[collect_exist]
            else:
                # create repattern collation
                func_collection(self, context)

                # set active scene collection
                scene_collection = bpy.context.view_layer.layer_collection
                bpy.context.view_layer.active_layer_collection = scene_collection

        # add camera
        bpy.ops.object.camera_add(align='WORLD', enter_editmode=False, location=(loca_x, loca_y, loca_z), rotation=(rota_x, rota_y, rota_z))
        bpy.context.object.name = 'RP_Camera_Top'
        bpy.context.object.data.name = 'RP_Camera_Top'

        # store camera #
        store_camera = bpy.context.view_layer.objects.active

        new_object_name = bpy.context.object.name
        bpy.data.objects[new_object_name].select_set(True)

        #move to scene collection
        bpy.ops.object.move_to_collection(collection_index=0)

        # move to new collection
        selected = bpy.context.selected_objects
        for obj in selected:
            if cam_prefs.rb_collection_name_exist_camera!= '':
                bpy.data.collections[cam_prefs.rb_collection_name_exist_camera].objects.link(obj)
            else:
                collect_exist = "RePattern"
                bpy.data.collections[collect_exist].objects.link(obj)
            bpy.context.scene.collection.objects.unlink(obj)

       # ADD SUBGRID COLLECTION #
        store_collection_name = bpy.data.objects[new_object_name]
        bounds_collection = func_find_collection(bpy.context, store_collection_name)

        id = 0
        numberDigits = 2

        if cam_prefs.rb_collection_name_camera!= '':
            prefix = cam_prefs.rb_collection_name_camera
        else:
            prefix = "RP_Camera"

        # CUSTOM COLLECTION #
        for key, collections in bpy.data.collections.items():
            if key.startswith(prefix):

                addZero = 0
                for i in range(1,numberDigits):
                    mod = int(id / (pow(numberDigits,i)))
                    if mod == 0:
                        addZero += 1

                newNameId = str(id)
                for i in range(0,addZero):
                    newNameId = '' + newNameId

                new_name = prefix + '_' + newNameId
                id += 1

                new_collection = func_make_collection(self, new_name, bounds_collection)
            else:
                new_collection = func_make_collection(self, prefix, bounds_collection)

        new_collection.objects.link(store_collection_name)
        bounds_collection.objects.unlink(store_collection_name)

        # lens
        if cam_prefs.cam_lens == 'ortho':

            # switch orthogonal scale
            bpy.context.object.data.type = 'ORTHO'

            if cam_prefs.cam_reso == '32px':
                scale_o  = 3.125
                scale_c  = 100

            if cam_prefs.cam_reso == '64px':
                scale_o = 6.25
                scale_c = 100

            if cam_prefs.cam_reso == '128px':
                scale_o = 12.5
                scale_c = 100

            if cam_prefs.cam_reso == '256px':
                scale_o = 25
                scale_c = 100

            if cam_prefs.cam_reso == '512px':
                scale_o = 50
                scale_c = 1000

            if cam_prefs.cam_reso == '1024px':
                scale_o = 100
                scale_c = 1000

            if cam_prefs.cam_reso == '2048px':
                scale_o = 200
                scale_c = 10000

            if cam_prefs.cam_reso == '4096px':
                scale_o = 400
                scale_c = 100000
                bpy.context.object.data.clip_end = 100000

            bpy.context.object.data.ortho_scale = scale_o
            bpy.context.object.data.clip_end = scale_c

        # lens
        if cam_prefs.cam_lens == 'persp':

            # switch perspective scale
            bpy.context.object.data.type = 'PERSP'

            scale_f = 32
            bpy.context.object.data.lens = scale_f

        # jump to camera view
        bpy.ops.view3d.object_as_camera()
        bpy.ops.view3d.view_camera()

        # set render resolution
        bpy.context.scene.render.resolution_x = 1024
        bpy.context.scene.render.resolution_y = 1024
        bpy.context.scene.render.resolution_percentage = 100

        # reload camera
        bpy.context.view_layer.objects.active = bpy.data.objects[store_camera.name]
        bpy.data.objects[store_camera.name].select_set(True)

        bpy.ops.view3d.view_camera()

        # restrict transorm
        lock_object(self, context)

        #print(self)
        self.report({'INFO'}, "Added Camera!")
        return {'FINISHED'}

class RTS_OT_RePattern_Camera_Jump(bpy.types.Operator):
    """Camera Render Setup"""
    bl_idname = "rts_ot.repattern_camera_jump"
    bl_label = "Jump To Camera"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        bpy.ops.object.select_all(action='DESELECT')

        cam_name = bpy.context.scene.collection_rp_select_list_cameras
        #cam_name = 'RP_Camera_Top'

        if cam_name in bpy.data.cameras:
            bpy.context.scene.camera = bpy.data.objects[cam_name]
            bpy.context.view_layer.objects.active = bpy.data.objects[cam_name]
            bpy.data.objects[cam_name].select_set(True)
            bpy.ops.view3d.object_as_camera()

            for area in bpy.context.screen.areas:
                if area.type == 'VIEW_3D':
                    area.spaces[0].region_3d.view_perspective = 'CAMERA'
                    break

            bpy.context.view_layer.objects.active = bpy.data.objects[cam_name]
            bpy.data.objects[cam_name].select_set(True)

            #print(self)
            self.report({'INFO'}, "Jump To Camera!")

        else:
            self.report({'INFO'}, "Nope :(!")
        return {'FINISHED'}

# https://blender.stackexchange.com/questions/30643/how-to-toggle-to-camera-view-via-python
# [‘PERSP’, ‘ORTHO’, ‘CAMERA’]
class RTS_OT_RePattern_Camera_Align(bpy.types.Operator):
    """Camera Render Setup"""
    bl_idname = "rts_ot.repattern_camera_align"
    bl_label = "Align Camera"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):

        if bpy.data.cameras:

            bpy.ops.view3d.camera_to_view()

            view_layer = bpy.context.view_layer
            selected = bpy.context.selected_objects
            if selected:
                obj = view_layer.objects.active
                if obj:
                    # store active #
                    target = view_layer.objects.active

            bpy.ops.object.select_all(action='DESELECT')

            cam_name = bpy.context.scene.collection_rp_select_list_cameras
            if cam_name in bpy.data.cameras:
                bpy.context.scene.camera = bpy.data.objects[cam_name]
                bpy.context.view_layer.objects.active = bpy.data.objects[cam_name]
                bpy.data.objects[cam_name].select_set(True)

                bpy.ops.view3d.object_as_camera()

                for area in bpy.context.screen.areas:
                    if area.type == 'VIEW_3D':
                        area.spaces[0].region_3d.view_perspective = 'ORTHO'
                        break

                if selected:
                    obj = view_layer.objects.active
                    if obj:
                        # reload active #
                        view_layer.objects.active = target
                        target.select_set(True)

                        bpy.ops.view3d.camera_to_view_selected()

                    #print(self)
                    self.report({'INFO'}, "Align Camera!")
        else:
            self.report({'INFO'}, "Nope :(!")
        return {'FINISHED'}

class RTS_OT_RePattern_Camera_Remove(bpy.types.Operator):
    """remve repattern camera"""
    bl_idname = "rts_ot.repattern_camera_remove"
    bl_label = "Camera Remove"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):

        # make active
        bpy.ops.object.select_all(action='DESELECT')

        cam_name = bpy.context.scene.collection_rp_select_list_cameras
        #cam_name = "RP_Camera_Top"

        if cam_name in bpy.data.objects:
            bpy.context.view_layer.objects.active = bpy.data.objects[cam_name]
            bpy.data.objects[cam_name].select_set(True)

            for area in bpy.context.screen.areas:
                if area.type == 'VIEW_3D':
                    for space in area.spaces:
                        if space.type == 'VIEW_3D':
                            bpy.ops.view3d.view_persportho()
                            bpy.ops.view3d.snap_cursor_to_center()
                            #bpy.ops.view3d.view_all(center=True)
                            #bpy.ops.view3d.view_center_cursor()

            temp_remove = bpy.data.cameras
            temp_remove.remove(temp_remove[cam_name], do_unlink=True, do_id_user=True, do_ui_user=True)

            self.report({'INFO'}, "Removed Camera!")

        else:
            self.report({'INFO'}, "Nope :(!")
        return {'FINISHED'}


"""

    Title: Large Files: One Million Digits.
    Author: Eric Matthes
    Date: 04/22/2023
    Description: "I've always been curious to know if my birthday appears
    anywhere in the digits of pi. Let's use the program we just wrote to find
    out if someone's birthday appears anywhere in the first million digits of
    pi. We can do this by expressing each birthday as a string of digits and
    seeing if that string appears anywhere in pi_string:"

"""

from pathlib import Path

path = Path("C:/Users/Brooke/Documents/buwebdev/python_crash_course/chapter_10/1_reading_from_file/files/pi_million_digits.txt")

contents = path.read_text()

lines = contents.splitlines()

pi_string = ''

for line in lines:

    pi_string += line.lstrip()

birthday = input("Enter your birthday, in the from mmddyy: ")

if birthday in pi_string:

    print("Your birthday appears in the first million digits of pi!")

else:

    print("Your birthday does not appear in the first million digits of pi.")


import time
from ratelimit.mixins import RatelimitMixin
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.db.models import Count
from django.http import HttpResponse
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import (CreateView, DeleteView, DetailView, FormView,
                                  ListView, TemplateView, UpdateView, View)

from apps.challenges.forms import (AttachmentAddForm, AttachmentDeleteForm,
                                   FlagAddForm, FlagDeleteForm, HintAddForm,
                                   HintDeleteForm, NewChallengeForm,
                                   SubmitFlagForm)
from apps.challenges.models import (Attachment, BadSubmission, Category,
                                    Challenge, FirstBlood, Flag, Solves,
                                    Hint)
from apps.scoreboard.utils import get_key

class UserIsAdminMixin(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.is_staff

class CtfNotEnded(UserPassesTestMixin):
    def test_func(self):
        if get_key('start_time') is None or get_key('end_time') is None:
            return True
        elif int(get_key('start_time')) < int(time.time()) < int(get_key('end_time')):
            return True
        else:
            return False

class ChallengesListView(LoginRequiredMixin, View):

    def get(self, request, *args, **kwargs):
        context = {}
        solves = Solves.objects.prefetch_related(
            'challenge').prefetch_related('account')

        context['challenges'] = Challenge.objects.prefetch_related(
            'category').prefetch_related('solves').all()
        context['categories'] = Category.objects.prefetch_related('challenge_set').all()
        context['solved_by_user'] = solves.prefetch_related('challenge').values_list(
            'challenge', flat=True).filter(account=self.request.user.pk)
        context['solves'] = solves.values("challenge__name").annotate(
            c=Count('challenge')).order_by('-c')
        context['first_bloods'] = FirstBlood.objects.prefetch_related(
            'account').prefetch_related('challenge')
        return render(self.request, 'templates/challenge/list_challenges.html', context=context)

class SubmitFlagView(RatelimitMixin, CtfNotEnded, LoginRequiredMixin, FormView):
    ratelimit_key = 'user'
    ratelimit_rate = '10/m'
    ratelimit_method = 'POST'
    ratelimit_block = True
    form_class = SubmitFlagForm

    def get_context_data(self, **kwargs):
        context = super(SubmitFlagView, self).get_context_data(**kwargs)
        context['challenge'] = Challenge.objects.get(pk=self.kwargs['pk'])
        context['solvers'] = Solves.objects.filter(
            challenge=context['challenge'])
        context['solved_by_user'] = Solves.objects.filter(
            account=self.request.user.pk).values_list('challenge', flat=True)
        return context

    def get_template_names(self):
        return list(['templates/challenge/challenge.html'])

    def form_valid(self, form):
        challenge_id = form.cleaned_data['challenge_id']
        flag = form.cleaned_data['flag']
        challenge = Challenge.objects.get(pk=challenge_id)

        if Solves.objects.filter(challenge=challenge, account=self.request.user).count() == 0:
            if flag in challenge.flag_set.all().values_list('text', flat=True):
                if Solves.objects.filter(challenge=challenge).count() == 0:
                    FirstBlood.objects.create(
                        challenge=challenge,
                        account=self.request.user,
                    )

                Solves.objects.create(
                    challenge=challenge,
                    account=self.request.user,
                )

                return render(self.request, 'templates/challenge/flag_success.html', {'challenge': challenge})
            else:
                new_bad_submission = BadSubmission.objects.create(
                    challenge=challenge,
                    account=self.request.user,
                    flag=flag
                )
                return render(self.request, 'templates/challenge/challenge.html', {'challenge': challenge, 'solvers': Solves.objects.filter(challenge=challenge), 'error': 'Wrong flag!'})
        else:
            return render(self.request, 'templates/challenge/challenge.html', {'challenge': challenge, 'solvers': Solves.objects.filter(challenge=challenge), 'error': 'Already solved!'})

class CreateChallengeView(SuccessMessageMixin, LoginRequiredMixin, UserIsAdminMixin, FormView):
    form_class = NewChallengeForm
    template_name = 'templates/challenge/new_challenge.html'
    success_url = reverse_lazy('administration:challenges')
    success_message = "Challenge %(name)s was created successfully"

    def get_context_data(self, **kwargs):
        context = super(CreateChallengeView, self).get_context_data(**kwargs)
        context['categories'] = Category.objects.all()
        return context

    def form_valid(self, form):
        category = form.cleaned_data['category']

        new_challenge = Challenge(
            category=category,
            name=form.cleaned_data['name'],
            description=form.cleaned_data['description'],
            points=form.cleaned_data['points'],
            visible=True
        )

        new_challenge.save()
        new_flag = Flag(
            challenge=new_challenge,
            text=form.cleaned_data['flag']
        )

        if self.request.FILES:
            files = self.request.FILES.getlist('attachments')
            if files:
                for f in files:
                    Attachment.objects.create(
                        challenge=new_challenge,
                        data=f
                    )

        new_flag.save()
        return super(CreateChallengeView, self).form_valid(form)

class UpdateChallengeView(UserIsAdminMixin, UpdateView):
    model = Challenge
    fields = '__all__'
    template_name = 'templates/challenge/update_challenge.html'
    success_url = reverse_lazy('administration:challenges')

class DeleteChallengeView(UserIsAdminMixin, DeleteView):
    model = Challenge
    template_name = 'templates/challenge/delete_challenge.html'
    success_url = reverse_lazy('administration:challenges')

class ToggleChallengeVisibility(UserIsAdminMixin, View):

    def post(self, request, *args, **kwargs):
        challenge_id = request.POST.get('challenge_id')
        if challenge_id is None:
            return HttpResponse(status=400)
        else:
            challenge = Challenge.objects.get(pk=challenge_id)
            if challenge.visible:
                challenge.visible = False
            else:
                challenge.visible = True
            challenge.save()
            return HttpResponse(status=204)

class AddCategoryView(UserIsAdminMixin, CreateView):
    model = Category
    fields = '__all__'
    template_name = 'templates/category/add_category.html'
    success_url = reverse_lazy('administration:challenges')

class UpdateCategoryView(UserIsAdminMixin, UpdateView):
    model = Category
    fields = '__all__'
    template_name = 'templates/category/update_category.html'
    success_url = reverse_lazy('administration:challenges')

class DeleteCategoryView(UserIsAdminMixin, DeleteView):
    model = Category
    template_name = 'templates/category/delete_category.html'
    success_url = reverse_lazy('administration:challenges')

class FlagsView(UserIsAdminMixin, DetailView):
    model = Challenge
    template_name = 'templates/challenge/flags.html'

class FlagAddView(UserIsAdminMixin, View):
    form_class = FlagAddForm

    def post(self, request, *args, **kwargs):
        form = self.form_class(data=request.POST)
        if form.is_valid():
            challenge_id = form.cleaned_data['challenge_id']
            flag = form.cleaned_data['flag']
            challenge = Challenge.objects.get(pk=challenge_id)

            Flag.objects.create(
                challenge=challenge,
                text=flag
            )

            return HttpResponse(status=204)
        else:
            return HttpResponse(status=400)

class FlagDeleteView(UserIsAdminMixin, View):
    form_class = FlagDeleteForm

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            flag = form.cleaned_data['flag']
            flag = Flag.objects.get(
                pk=flag
            )
            flag.delete()

            return HttpResponse(status=204)
        else:
            return HttpResponse(status=400)

class HintsView(UserIsAdminMixin, DetailView):
    model = Challenge
    template_name = 'templates/challenge/hints.html'

class HintAddView(UserIsAdminMixin, View):
    form_class = HintAddForm

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            challenge_id = form.cleaned_data['challenge_id']
            hint = form.cleaned_data['hint']
            challenge = Challenge.objects.get(pk=challenge_id)

            Hint.objects.create(
                challenge=challenge,
                text=hint
            )

            return HttpResponse(status=204)
        else:
            return HttpResponse(status=400)

class HintDeleteView(UserIsAdminMixin, View):
    form_class = HintDeleteForm

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            hint = form.cleaned_data['hint']
            hint = Hint.objects.get(
                pk=hint
            )
            hint.delete()

            return HttpResponse(status=204)
        else:
            return HttpResponse(status=400)

class AttachmentsView(UserIsAdminMixin, DetailView):
    model = Challenge
    template_name = 'templates/challenge/attachments.html'

class AttachmentAddView(UserIsAdminMixin, View):
    form_class = AttachmentAddForm

    def post(self, request, *args, **kwargs):
        form = self.form_class(data=request.POST, files=request.FILES)
        if form.is_valid():
            challenge_id = form.cleaned_data['challenge_id']
            attachment = form.cleaned_data['data']
            challenge = Challenge.objects.get(pk=challenge_id)

            Attachment.objects.create(
                challenge=challenge,
                data=attachment
            )

            return HttpResponse(status=204)
        else:
            return HttpResponse(status=400)

class AttachmentDeleteView(UserIsAdminMixin, View):
    form_class = AttachmentDeleteForm

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            attachment = form.cleaned_data['attachment']
            attachment = Attachment.objects.get(
                pk=attachment
            )
            attachment.delete()

            return HttpResponse(status=204)
        else:
            return HttpResponse(status=400)


import schedule
import random
from notifypy import Notify
import time
import threading
import sys
import json

def notify(task):
    tune_number=random.randint(1,17)
    notification=Notify()
    notification.title="Schedule Notifications"
    notification.message=task
    notification.audio=f"tune{tune_number}.wav"
    notification.icon="icon.png"
    notification.send(block=False)

def scheduler():
    while(True):
        n=schedule.idle_seconds()
        schedule.run_pending()

def load_saved_tasks():
    with open("tasks.json","r+") as fp:
        # tasks=json.dump([2,3],fp)
        try:
            tasks=json.loads(fp.read())
            return tasks
        except:return []

def schedule_saved_tasks(saved_tasks):
    for i in saved_tasks:
        task,time=i
        schedule.every().day.at(time).do(notify,task=task)

def main():
    print("-"*50)
    print("Welcome to Schedule Notifier program.\nIf you want to close the program then you can press Q or q any time.")
    print("-"*50)
    saved_tasks=load_saved_tasks()
    schedule_saved_tasks(saved_tasks)
    print("Saved tasks from your last session has been scheduled.")
    print("-"*50)
    print("If you want to add any task to the schedule then please enter the task and it's time separated by @")
    print("-"*50)
    notify_thread=threading.Thread(target=scheduler)
    notify_thread.daemon=True
    notify_thread.start()
    while(True):
        command=input()
        if command=="Q" or command=="q":
            #sys.exit()
            with open("tasks.json","w+") as fp:
                json.dump(saved_tasks,fp)
            break
        task,time=command.split("@")
        time=time.strip()
        schedule.every().day.at(time).do(notify,task=task)
        saved_tasks.append((task,time))
        print("Task Scheduled.")

if __name__=="__main__":
    main()


import argparse
import re
from nltk.tokenize import sent_tokenize, word_tokenize
from nltk.corpus import stopwords
def file_scan(pos_file,neg_file):
    #words_df = pd.DataFrame(columns=['Positive','Negative'])
    words = {}
    lines = open(pos_file, encoding='utf8').read().splitlines()
    #lines = open("hotelPosT-train.txt",encoding='utf8').read().splitlines()
    for line in lines:
        line = re.sub('ID-[0-9][0-9][0-9][0-9]\s','',line)
        list_line = re.findall("(?<!\S)[A-Za-z]+(?!\S)|(?<!\S)[A-Za-z]+(?=:(?!\S))", line)
        filtered_line = [word for word in list_line if word not in stopwords.words('english')]
        filtered_line = [x.lower() for x in filtered_line]
        for word in filtered_line:
            if word in words:
                words[word][0] += 1
            else:
                words[word] = [2,1]

    lines = open(neg_file, encoding='utf8').read().splitlines()
    #lines = open("hotelNegT-train.txt", encoding='utf8').read().splitlines()
    for line in lines:
        line = re.sub('ID-[0-9][0-9][0-9][0-9]\s', '', line)
        list_line = re.findall("(?<!\S)[A-Za-z]+(?!\S)|(?<!\S)[A-Za-z]+(?=:(?!\S))", line)
        filtered_line = [word for word in list_line if word not in stopwords.words('english')]
        filtered_line = [x.lower() for x in filtered_line]
        for word in filtered_line:
            if word in words:
                words[word][1] += 1
            else:
                words[word] = [1, 2]

    return words

def naive_bayes(words,test_file):
    lines = open(test_file, encoding='utf8').read().splitlines()
    #lines = open("finalTest.txt", encoding='utf8').read().splitlines()
    answrite = open("answer.txt",'w',encoding='utf8')
    line_count = 0
    pos_count = 0
    neg_count = 0
    stopWord = set(stopwords.words('english'))
    stopWord.update(
        ['','internet','high', 'speed', 'thing', '--', 'place', 'thought', 'paid', 'overall', 'i\'m', 'i\'ll', 'house', 'carrying',
         'around', 'many', 'staying', 'stayed', 'enjoy', 'without', 'partying', 'sitting', 'coming', 'provided',
          'entered', 'events', 'going', 'city', 'life', 'sheraton',  'strip','location',  'questions', 'passed', 'food', 'store', 'actually', 'fan', 'tv',
         'pool', 'paint', 'walls', 'restaurant', 'downstairs','cigarette', 'indoor','street', 'union', 'entire', 'hear', 'wifi','much', 'came', 'late', 'last', 'spot', 'buses', 'ran', 'checked', 'checking',
         'clerk', 'two', '&', 'found', 'king', 'suite', 'called', 'motel', 'back', 'front', 'rooms',
         'breakfast', 'continental', 'area', 'staff', 'located', 'though',  'first', 'ac','us', 'casino', 'starter', 'get', 'hotels', 'movie', 'room'])
    stop_list = list(stopWord)
    for line in lines:
        line_count += 1
        id_no = re.match('ID-[0-9][0-9][0-9][0-9]\s', line)
        line = re.sub('ID-[0-9][0-9][0-9][0-9]\s', '', line)
        list_line = re.findall("(?<!\S)[A-Za-z]+(?!\S)|(?<!\S)[A-Za-z]+(?=:(?!\S))", line)
        filtered_line = [word for word in list_line if word not in stop_list]
        filtered_line = [x.lower() for x in filtered_line]
        pos = 1
        neg = 1
        for word in filtered_line:
            if word in words:
                pos = pos * words[word][0]
                neg = neg * words[word][1]
        if pos >= neg:
            pos_count += 1
            answrite.write(id_no.group(0) + ' POS')
        else:
            neg_count += 1
            answrite.write(id_no.group(0) + ' NEG')
        answrite.write("\n")

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("pos_file")
    parser.add_argument("neg_file")
    parser.add_argument("testfile")
    args = parser.parse_args()
    pos_file = args.pos_file
    neg_file = args.neg_file
    test_file = args.testfile
    words_dict = file_scan(pos_file,neg_file)
    naive_bayes(words_dict,test_file)
if __name__ == '__main__':
    main()


"""
Python compatibility functions.
"""
import sys
import os
import warnings
from typing import Any, Callable

# ------------------------------------------------------------------------------
# Python 2/3 compatibility
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()

def relpath(path: str, start: str = os.curdir) -> str:
    """Return a relative version of a path"""
    try:
        return os.path.relpath(path, start)
    except ValueError:
        return path

# convert_with_2to3():
# support for running 2to3 over config files
def convert_with_2to3(filepath: str) -> str:
    from lib2to3.refactor import RefactoringTool, get_fixers_from_package
    from lib2to3.pgen2.parse import ParseError
    fixers = get_fixers_from_package('lib2to3.fixes')
    refactoring_tool = RefactoringTool(fixers)
    source = refactoring_tool._read_python_source(filepath)[0]
    try:
        tree = refactoring_tool.refactor_string(source, 'conf.py')
    except ParseError as err:
        # do not propagate lib2to3 exceptions
        lineno, offset = err.context[1]
        # try to match ParseError details with SyntaxError details
        raise SyntaxError(err.msg, (filepath, lineno, offset, err.value))
    return str(tree)

def execfile_(filepath: str, _globals: Any, open: Callable = open) -> None:
    with open(filepath, 'rb') as f:
        source = f.read()

    # compile to a code object, handle syntax errors
    filepath_enc = filepath.encode(fs_encoding)
    try:
        code = compile(source, filepath_enc, 'exec')
    except SyntaxError:
        # maybe the file uses 2.x syntax; try to refactor to
        # 3.x syntax using 2to3
        source = convert_with_2to3(filepath)
        code = compile(source, filepath_enc, 'exec')
        warnings.warn('Support for evaluating Python 2 syntax is deprecated '
                      'and will be removed in sphinx-intl 4.0. '
                      'Convert %s to Python 3 syntax.',
                      source=filepath)
    exec(code, _globals)


import os
import requests
from pathlib import Path
from db import fetch_scripts

def download(email,url):
    msg = {'flag':False}
    try:
        res = fetch_scripts.check_client_existance(email)
        if res['flag']:
            dest_folder = str(os.path.join(Path.home(), "Downloads"))
            filename = url.split('/')[-1].replace(" ", "_")  # be careful with file names
            file_path = os.path.join(dest_folder, filename)

            r = requests.get(url, stream=True)
            if r.ok:
                print("saving to", os.path.abspath(file_path))
                with open(file_path, 'wb') as f:
                    for chunk in r.iter_content(chunk_size=1024 * 8):
                        if chunk:
                            f.write(chunk)
                            f.flush()
                            os.fsync(f.fileno())
                msg= {'flag':True,'message':'file downloaded','download_link':url}
            else:  # HTTP status code 4XX/5XX
                msg = {'flag':False,'error':"Download failed: status code {}\n{}".format(r.status_code, r.text)}
        else:
            msg = {'flag':False,'error':'user does not exist'}
    except Exception as e:
        msg = {'flag':False,'error':e}

    return msg


import os
import pandas as pd
import numpy as np
import argparse
import random
import tensorflow as tf
import keras.backend as K
from time import time
from tqdm import tqdm
from deepctr.feature_column import SparseFeat, DenseFeat, get_feature_names, VarLenSparseFeat
from sklearn.preprocessing import LabelEncoder, MinMaxScaler
from tensorflow.python.keras.optimizers import Adam, Adagrad
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import KFold
from tensorflow.python.keras.models import save_model, load_model
from sklearn.preprocessing import label_binarize
from model import AutoInt_, DCN_

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
print(BASE_DIR)

parser = argparse.ArgumentParser(description='seed')
parser.add_argument("--k", metavar='seed', type=int, default=0)
args = parser.parse_args()
k = args.k

seed = k
random.seed(seed)
os.environ['PYTHONHASHSEED'] = str(seed)
np.random.seed(seed)
tf.set_random_seed(seed)

os.environ["CUDA_VISIBLE_DEVICES"] = "0"

config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)

epochs = 80
batch_size = 9192
embedding_dim = 32
n_classes = 10
score_weights = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

# 读取训练集
BEHAVIOR_PATH = '/opt/data/traindata/history_behavior_data/'
DATE_PATH = [BEHAVIOR_PATH + i for i in os.listdir(BEHAVIOR_PATH)]
DATE_PATH = sorted(DATE_PATH)
BEHAVIOR_PATH_ = [i + '/' + os.listdir(i)[0] for i in DATE_PATH]

history_behavior_list = []
for i in tqdm(range(len(BEHAVIOR_PATH_))):
    history_behavior = pd.read_csv(BEHAVIOR_PATH_[i], sep='\t')
    history_behavior_list.append(history_behavior)

history_behavior_df = pd.concat(history_behavior_list)
del history_behavior_list

# 训练集采样
train = history_behavior_df
train1 = train[train['watch_label'] != 0]
print(len(train1))
train2 = train[train['watch_label'] == 0].sample(frac=0.1, random_state=k).reset_index(drop=True)
print(len(train2))
train = pd.concat([train1, train2])
del train1, train2

# 读取测试集
test = pd.read_csv('/opt/data/testdata/test.csv')
test['pt_d'] = '20210503'
data = pd.concat([train, test])

# 视频特征拼接
video_features = pd.read_pickle('/opt/feature/video_features.pkl')
data = pd.merge(data, video_features, on='video_id', how='left')

# 日期特征
data['pt_d'] = data['pt_d'].astype('str')
data['pt_d'] = data['pt_d'].apply(lambda x: x[:4] + '-' + x[4:6] + '-' + x[6:])
data['pt_d'] = pd.to_datetime(data['pt_d'])
data['day'] = (data['pt_d'] - data['video_release_date']).dt.days

# w2v特征
user_features = pd.read_pickle('/opt/feature/user_video_w2v.pkl')
data = pd.merge(data, user_features, on='user_id', how='left')

# 用户属性特征
user_features = pd.read_csv('/opt/data/traindata/user_features_data/user_features_data.csv', sep='\t')
data = pd.merge(data, user_features, on='user_id', how='left')

# 特征数据预处理
data[['video_year', 'video_month']] = data[['video_year', 'video_month']].fillna(0)
data[['video_year', 'video_month']] = data[['video_year', 'video_month']].astype('int32')

target = ['watch_label', 'is_share']
sparse_features = ['province', 'city', 'device_name', 'user_id', 'video_id', 'video_year', 'video_month', 'gender', 'city_level', 'age']
varlen_sparse_features = ['video_tags', 'video_director_list', 'video_actor_list', 'video_second_class']
dense_features = ['video_score', 'video_duration',  'day']

print(len(dense_features))
print(len(sparse_features))
data[dense_features] = data[dense_features].fillna(-1)
scaler = MinMaxScaler()
data[dense_features] = scaler.fit_transform(data[dense_features])
dense_features.extend([f'user_id_video_id_emb_{i}' for i in range(16)])

maxlen_dict = {'video_tags': 81, 'video_director_list': 11, 'video_actor_list': 104, 'video_second_class': 9}
vocab_dict = {'video_tags': 21427, 'video_director_list': 28036, 'video_actor_list': 78291, 'video_second_class': 145}

for f in varlen_sparse_features:
    data[f] = data[f].fillna(0)
    data[f] = data[f].apply(lambda x: [0] * maxlen_dict[f] if x == 0 else x)

train = data[data['pt_d'] <= '2021-05-02']
test = data[data['pt_d'] == '2021-05-03']
print(len(test))
del data

# 构造输入
fixlen_feature_columns = [SparseFeat(feat, vocabulary_size=max(train[feat].max(), test[feat].max()) + 1, embedding_dim=embedding_dim)
                          for feat in sparse_features] + [DenseFeat(feat, 1) for feat in dense_features]

varlen_feature_columns = [VarLenSparseFeat(SparseFeat(feat, vocabulary_size=vocab_dict[feat],
                                                      embedding_dim=embedding_dim), maxlen=maxlen_dict[feat], combiner='mean', weight_name=None) for feat in varlen_sparse_features]

dnn_feature_columns = fixlen_feature_columns + varlen_feature_columns
linear_feature_columns = fixlen_feature_columns + varlen_feature_columns

feature_names = get_feature_names(linear_feature_columns + dnn_feature_columns)

train_model_input = {name: train[name] for name in feature_names}
test_model_input = {name: test[name] for name in feature_names}

for feat in tqdm(varlen_sparse_features):
    train_model_input[feat] = np.asarray(train_model_input[feat].to_list()).astype(np.int32)
    test_model_input[feat] = np.asarray(test_model_input[feat].to_list()).astype(np.int32)

y_binary = label_binarize(train['watch_label'], classes=range(n_classes))
s = train['watch_label'].value_counts().to_dict()
label_num_list = [s[i] for i in sorted(s.keys())]
total_sample_num = sum(label_num_list)

def multi_category_focal_loss(y_true, y_pred):
    gamma = 2.0
    epsilon = 1.e-7

    y_true = tf.cast(y_true, tf.float32)
    y_pred = tf.cast(y_pred, tf.float32)

    classes_weight = [total_sample_num / label_num for label_num in label_num_list]
    classes_weight_norm = [weight / sum(classes_weight) for weight in classes_weight]
    print(classes_weight_norm)
    classes_weight_norm = tf.cast(classes_weight_norm, tf.float32)
    alpha = tf.expand_dims(classes_weight_norm, 1)

    y_pred = tf.clip_by_value(y_pred, epsilon, 1. - epsilon)
    pt = tf.multiply(y_true, y_pred) + tf.multiply(1 - y_true, 1 - y_pred)
    cross_entropy_loss = -K.log(pt)
    weight = tf.pow(tf.subtract(1., pt), gamma)
    focal_loss = tf.matmul(tf.multiply(weight, cross_entropy_loss), alpha)

    return focal_loss

# 模型训练
epochs = 5
model = DCN_(linear_feature_columns, dnn_feature_columns, task='multiclass')
model.compile("adagrad", multi_category_focal_loss)

history = model.fit(train_model_input, y_binary, batch_size=batch_size, epochs=epochs, verbose=1)
# save_model(model, 'dcn_watch' + str(k) + '.h5')
# model.save_weights('dcn_watch_' + str(k) + '.h5')
if not os.path.exists('/opt/sub/'):
    os.makedirs('/opt/sub/')

temp = model.predict(test_model_input, batch_size=batch_size * 4)
np.save('/opt/sub/dcn_watch_' + str(k) + '.npy', temp)


import torch
import torch.nn as nn
from models.utils import (
    Encoder, EncoderLayer,
    Decoder, DecoderLayer,
    MultiHeadAttention, PointerwiseFeedforward,
    LinearEmbedding, LaneNet,
    intChoiceHead
)
from models.STF import STF
import copy

def bool2index(mask):
    seq = torch.arange(mask.shape[-1]).to(mask.device)
    index = mask * seq
    index[mask == 0] = 1000
    index = index.sort(-1).values.to(torch.int64)
    mask = index < 1000
    index[index == 1000] = 0
    return index, mask

class STF_golden_wind(STF):
    def __init__(self, cfg):
        super(STF_golden_wind, self).__init__(cfg)

        d_model = cfg['d_model']
        h = cfg['attention_head']
        dropout = cfg['dropout']
        N = cfg['model_layers_num']
        prop_num = cfg['prop_num']
        dec_out_size = cfg['out_dims']
        pos_dim = 16
        c = copy.deepcopy
        attn = MultiHeadAttention(h, d_model, dropout)
        ff = PointerwiseFeedforward(d_model, d_model * 2, dropout)
        # num of proposal
        self.lanenet = LaneNet(
            cfg['lane_dims'],
            cfg['subgraph_width_unit'],
            cfg['num_subgraph_layers'])
        self.lane_emb = LinearEmbedding(cfg['subgraph_width_unit'] * 2, d_model)
        self.lane_enc = Encoder(EncoderLayer(d_model, c(attn), c(ff), dropout), N)
        self.lane_dec = Decoder(DecoderLayer(d_model, c(attn), c(attn), c(ff), dropout), N)
        self.prediction_head = intChoiceHead(d_model * 2, dec_out_size, dropout)

        self.cent_emb = nn.Sequential(
            nn.Linear(2, pos_dim, bias=True),
            nn.LayerNorm(pos_dim),
            nn.ReLU(),
            nn.Linear(pos_dim, pos_dim, bias=True))
        self.yaw_emb = nn.Sequential(
            nn.Linear(2, pos_dim, bias=True),
            nn.LayerNorm(pos_dim),
            nn.ReLU(),
            nn.Linear(pos_dim, pos_dim, bias=True))

        self.fusion1cent = nn.Sequential(
            nn.Linear(d_model + pos_dim, d_model, bias=True),
            nn.LayerNorm(d_model),
            nn.ReLU(),
            nn.Linear(d_model, d_model, bias=True))
        self.fusion1yaw = nn.Sequential(
            nn.Linear(d_model + pos_dim, d_model, bias=True),
            nn.LayerNorm(d_model),
            nn.ReLU(),
            nn.Linear(d_model, d_model, bias=True))

        self.social_emb = nn.Sequential(
            nn.Linear(prop_num * d_model, d_model, bias=True),
            nn.LayerNorm(d_model),
            nn.ReLU(),
            nn.Linear(d_model, d_model, bias=True))

        # self.social_emb_ped = nn.Sequential(
        #     nn.Linear(prop_num * d_model, d_model, bias=True),
        #     nn.LayerNorm(d_model),
        #     nn.ReLU(),
        #     nn.Linear(d_model, d_model, bias=True))
        # self.social_emb_cyc = nn.Sequential(
        #     nn.Linear(prop_num * d_model, d_model, bias=True),
        #     nn.LayerNorm(d_model),
        #     nn.ReLU(),
        #     nn.Linear(d_model, d_model, bias=True))
        self.social_enc = Encoder(EncoderLayer(d_model, c(attn), c(ff), dropout), N)

    def forward(self, data: dict):

        valid_len = data['valid_len']
        max_agent = max(torch.max(valid_len[:, 0]), self.max_pred_num)
        gather_list, new_data = self._gather_new_data(data, max_agent)
        obj_type = new_data['obj_type']
        # =============one_hot===============
        one_hot = torch.zeros([obj_type.shape[0],obj_type.shape[1],3]).to(obj_type.device)
        one_hot[obj_type==1] = torch.Tensor([1,0,0]).to(obj_type.device)
        one_hot[obj_type==2] = torch.Tensor([0,1,0]).to(obj_type.device)
        one_hot[obj_type==3] = torch.Tensor([0,0,1]).to(obj_type.device)
        one_hot = one_hot.unsqueeze(-2).repeat(1,1,10,1)

        #==================one_hot===============
        max_agent = 2
        gather_adj_mask = gather_list.view(*gather_list.shape,1).repeat(1,1,660)
        adj_mask = torch.gather(data['adj_mask'],1,gather_adj_mask)
        max_adj_lane = torch.max(adj_mask.sum(-1))
        adj_index = torch.gather(data['adj_index'],1,gather_adj_mask)[...,:max_adj_lane]
        adj_mask = adj_mask[...,:max_adj_lane]
        gather_hist = gather_list.view(*gather_list.shape, 1,1).repeat(1,1,10,4)
        hist = torch.gather(data['hist'],1,gather_hist)
        hist_mask = data['hist_mask']
        hist_mask = (torch.gather(hist_mask,1,gather_list.unsqueeze(-1).repeat(1,1,10))).unsqueeze(-2)
        center = hist[:,:,-1,2:].detach().clone()
        yaw = new_data['misc'][:,:,10,4].detach().clone()

        # =======================================trajectory module===================================
        yaw_1 = torch.cat([torch.cos(yaw).unsqueeze(-1),torch.sin(yaw).unsqueeze(-1)],-1)
        center_emb = self.cent_emb(center)
        yaw_emb = self.yaw_emb(yaw_1)

        hist[...,[0,2]]-=center[...,0].reshape(*center.shape[:2],1,1).repeat(1,1,10,2)
        hist[..., [1, 3]] -= center[..., 1].reshape(*center.shape[:2],1,1).repeat(1,1,10,2)
        hist[...,:2] = self._rotate(hist[...,:2],yaw)
        hist[...,2:4] = self._rotate(hist[...,2:4],yaw)
        hist = torch.cat([hist,one_hot],-1)

        #hist_mask = data['hist_mask'].unsqueeze(-2)[:, :max_agent]
        self.query_batches = self.query_embed.weight.view(1, 1, *self.query_embed.weight.shape).repeat(*hist.shape[:2],
                                                                                1, 1)
        hist_out = self.hist_tf(hist, self.query_batches, hist_mask, None)

        # ====================================rg and ts module========================================
        lane = data['lane_vector']
        lane = lane.unsqueeze(1).repeat(1, 2, 1, 1, 1)
        adj_index = adj_index.view(*adj_index.shape,1,1).repeat(1,1,1,*lane.shape[-2:])
        adj_mask = adj_mask.unsqueeze(2)
        lane = torch.gather(lane,2,adj_index)

        lane[...,[0,2]]-=center[...,0].reshape(*center.shape[:2],1,1,1).repeat(1,1,*lane.shape[2:4],2)
        lane[..., [1, 3]] -= center[..., 1].reshape(*center.shape[:2], 1, 1, 1).repeat(1, 1, *lane.shape[2:4], 2)
        lane = lane.reshape(*lane.shape[:2],-1,lane.shape[-1])
        lane[...,:2] = self._rotate(lane[...,:2],yaw)
        lane[..., 2:4] = self._rotate(lane[..., 2:4], yaw)
        lane = lane.reshape(*lane.shape[:2], -1,9, lane.shape[-1])
        lane = lane.reshape(lane.shape[0],-1,*lane.shape[-2:])

        lane_enc = self.lanenet(lane)
        lane_enc = lane_enc.reshape(lane_enc.shape[0],2,max_adj_lane,lane_enc.shape[-1])
        lane_enc = lane_enc.reshape(-1,*lane_enc.shape[-2:])
        lane_mask = adj_mask.reshape(-1,*adj_mask.shape[-2:])

        lane_mem = self.lane_enc(self.lane_emb(lane_enc), lane_mask)
        lane_mem = lane_mem.reshape(*hist_out.shape[:2],*lane_mem.shape[-2:])
        lane_out = self.lane_dec(hist_out, lane_mem, adj_mask, None)

        # ===================high-order interaction module=============================================
        # social_valid_len = data['valid_len'][:, 1] + 1
        social_mask = torch.ones((lane_out.shape[0], 1, max_agent)).to(lane_out.device)
        # for i in range(lane_out.shape[0]):
        #     social_mask[i, 0, :social_valid_len[i]] = 1
        social_emb = self.social_emb(lane_out.view(*lane_out.shape[:2], -1))

        social_emb = torch.cat([center_emb, social_emb], dim=-1)
        social_emb = self.fusion1cent(social_emb)
        social_emb = torch.cat([yaw_emb, social_emb], dim=-1)
        social_emb = self.fusion1yaw(social_emb)

        social_mem = self.social_enc(social_emb, social_mask)
        social_out = social_mem.unsqueeze(dim=2).repeat(1, 1, hist_out.shape[-2], 1)
        out = torch.cat([social_out, lane_out], -1)
        outputs_coord, outputs_class = self.prediction_head(out, new_data['obj_type'])

        return outputs_coord, outputs_class, new_data
    def _gather_new_data(self, data, max_agent):
        # select predict list and gather needed data
        tracks_to_predict = data['objects_of_interest'][:, :max_agent]
        gather_list, gather_mask = self._bool2index(tracks_to_predict)
        gather_list, gather_mask = gather_list[:, :self.max_pred_num], gather_mask[:, :self.max_pred_num]
        # gather obj type
        obj_type = data['obj_type'].to(torch.int64)[:, :max_agent]
        obj_type = torch.gather(obj_type, 1, gather_list)

        # gather other data
        gt = data['gt'][:, :max_agent]
        gather_gt = gather_list.view(*gather_list.shape, 1, 1).repeat(1, 1, *gt.shape[-2:])
        gt = torch.gather(gt, 1, gather_gt)
        gt_mask = data['gt_mask'][:, :max_agent]
        gather_gt_mask = gather_list.view(*gather_list.shape, 1).repeat(1, 1, gt_mask.shape[-1])
        gt_mask = torch.gather(gt_mask, 1, gather_gt_mask)

        misc = data['misc'][:, :max_agent]
        misc = torch.gather(misc, 1, gather_list.view(*gather_list.shape, 1, 1).repeat(1, 1, *misc.shape[-2:]))

        centroid = data['centroid'][:, :max_agent]
        gather_centroid = gather_list.unsqueeze(-1).repeat(1, 1, 2)
        centroid = torch.gather(centroid, 1, gather_centroid)

        new_data = {
            'gt': gt,
            'gt_mask': gt_mask,
            'tracks_to_predict': gather_mask,
            'misc': misc,
            'obj_type': obj_type,
            'centroid': centroid
        }
        return gather_list, new_data


# this is an openapi spec for http://localhost:8100/, create a streamlit config page to let user to read and edit env with nice looking UI components
import streamlit as st
import requests
import pandas as pd
import os
from pages.utils.style import add_style

add_style()

st.title("Configuration")

with st.sidebar:
    add_radio = st.radio(
        "Select Configuration",
        ("Server Status", "Environment Variables", "Tools", "Document Upload")
    )

API_URL = f"http://{os.getenv('INSOURCE_ADMIN_HOST')}"

if add_radio == "Server Status":
    # Create a function to check server status
    def check_server_status(url):
        response = requests.post(f"{API_URL}/chat_server_status", json={"url": url})
        return response.json()

    # Create a function to restart the server
    def restart_server():
        response = requests.get(f"{API_URL}/restart_chat_server")
        return response.json()

    st.header("Check Server Status")
    server_url = st.text_input("Enter chat server URL", f"http://{os.getenv('INSOURCE_CHAT_HOST')}")
    status_button = st.button("Check Status")

    if status_button:
        status = check_server_status(server_url)
        st.write(f"Server status: {status['status']}")

    # Restart server section
    st.header("Restart Chat Server")
    restart_button = st.button("Restart Server")

    if restart_button:
        restart_status = restart_server()
        st.write(f"Server restart status: {restart_status['status']}")

if add_radio == "Environment Variables":
    # Retrieve the available environment variables from the API
    response = requests.get(f"{API_URL}/env")
    env_vars = response.json()

    # Display and edit the environment variables
    st.header("Environment Variables")
    updated_env_vars = {}
    for key, value in env_vars.items():
        new_value = st.text_input(key, value)
        updated_env_vars[key] = new_value

    # Add an update button to submit changes
    if st.button("Update Environment Variables"):
        response = requests.put(f"{API_URL}/env", json=updated_env_vars)
        if response.status_code == 200:
            st.success("Environment variables updated successfully.")
        else:
            st.error("Failed to update environment variables.")

if add_radio == "Tools":

    # Create a function to get all tools
    def get_all_tools():
        response = requests.get(f"{API_URL}/all_tools")
        return response.json()

    # Create a function to get toggle tools
    def get_toggle_tools():
        response = requests.get(f"{API_URL}/toggle_tools")
        return response.json()

    # Create a function to disable all tools
    def disable_all_tools():
        response = requests.get(f"{API_URL}/disable_all_tools")
        return response.json()

    # Create a function to toggle a tool
    def toggle_tool(tool_name):
        response = requests.post(f"{API_URL}/toggle_tools", json={"name": tool_name})
        return response.json()

    # Create Streamlit UI
    st.header("Tools Management")

    tools = get_all_tools()
    toggle_tools = get_toggle_tools()['tools']

    # Create a dictionary to store checkbox states
    checkbox_states = {}

    # Create checkboxes for each tool
    for tool in tools:

        checkbox_states[tool] = st.checkbox(tool, value=tool in toggle_tools, key=tool)

    # Update the toggle_tool function to first disable all tools and then toggle the checked tools
    def toggle_checked_tools():
        disable_all_tools()

        for tool, state in checkbox_states.items():
            if state:
                toggle_tool(tool)

    toggle_button = st.button("Update Tools")

    if toggle_button:
        toggle_checked_tools()
        st.success("Checked tools updated successfully.")

if add_radio == "Document Upload":

    # Create functions for file management
    def read_all():
        response = requests.get(f"{API_URL}/readall/")
        return response.json()

    def upload_file(file, folder, subfolder):
        files = {"file": file}
        response = requests.post(f"{API_URL}/upload/{folder}/{subfolder}", files=files)
        return response.json()

    def delete_file(folder, subfolder, filename):
        response = requests.delete(f"{API_URL}/delete/{folder}/{subfolder}/{filename}")
        return response.json()

    # Create Streamlit UI
    st.header("File Management")

    # Read files section
    st.subheader("Read Files")
    read_button = st.button("Read Files")

    if read_button:
        files = read_all()
        # Create a DataFrame to display files in a user-friendly table format
        file_data = []
        for file in files["files"]:
            for filename in file["files"]:
                file_data.append([file["folder"], file["subfolder"], filename])

        file_df = pd.DataFrame(file_data, columns=["Folder", "Subfolder", "Filename"])
        st.write(file_df)

    # Upload files section
    st.subheader("Upload Files")

    # Folders and subfolders
    col1, col2 = st.columns(2)
    with col1:
        folder_options = ["txts", "pdfs", "words", "csvs", "htmls", "urls", "markdowns", "xmls"]
        folder = st.selectbox("Select a folder", folder_options)
    with col2:
        subfolder = st.text_input("Enter a subfolder")

    uploaded_file = st.file_uploader("Choose a file")

    if uploaded_file:
        file_details = {"FileName": uploaded_file.name, "FileType": uploaded_file.type, "FileSize": uploaded_file.size}
        st.write(file_details)
        upload_button = st.button("Upload File")

        if upload_button:
            upload_status = upload_file(uploaded_file, folder, subfolder)
            if upload_status["filename"]:
                st.success("File uploaded successfully.")

    # Delete files section
    st.subheader("Delete Files")
    delete_expander = st.expander("Delete a file")
    with delete_expander:
        col3, col4 = st.columns(2)
        with col3:
            folder = st.selectbox("Select a folder", folder_options, key="delete_folder")
        with col4:
            subfolder = st.text_input("Enter a subfolder", key="delete_subfolder")
        filename = st.text_input("Enter the filename to delete")

        if filename:
            delete_button = st.button("Delete File")

            if delete_button:
                delete_status = delete_file(folder, subfolder, filename)
                st.write(delete_status)