def useradd(request): LOGGER.debug( 'User add page accessed using method {}'.format(request.method), request, request.POST) err_message = None if request.method == 'GET': form = UserAddForm() else: form = UserAddForm(request.POST) if form.is_valid(): cld = form.cleaned_data user = User.objects.create_user(cld['username'], cld['email'], cld['password1']) if user: user.first_name = cld['first_name'] user.last_name = cld['last_name'] user.save() logout(request) LOGGER.info( 'New user "{0.username}" ({0.id:d}) created'.format(user), request) return redirect('useradded') LOGGER.error('Failed to create user', request) return error(request) # pragma: no cover else: LOGGER.debug('Invalid form', request) err_message = INERR if 'Duplicate username' in form['username'].errors.as_text(): err_message = 'Toto uživatelské jméno se již používá' LOGGER.debug('Duplicate user name', request) elif 'Wrong answer' in form['captcha'].errors.as_text(): err_message = 'Chybná odpověď na kontrolní otázku' LOGGER.debug('Wrong answer', request) elif 'Different passwords' in form['password2'].errors.as_text(): err_message = 'Rozdílná hesla' LOGGER.debug('Different passwords', request) else: err_message = 'Slabé heslo' LOGGER.debug('Weak password', request) return render( request, 'useradd.xhtml', { 'form': form, 'page_title': 'Registrace nového uživatele', 'err_message': err_message, })
def cron_find(): now = datetime.now() try: dec = Decision.objects.filter(anonfilename='', date__gte=(now - OBS)).earliest('updated') dec.updated = now dec.save() res = get(FIND_URL) soup = BeautifulSoup(res.text, 'html.parser') form = soup.find('form') dct = {i['name']: i['value'] for i in form.find_all('input') if i['type'] == 'hidden' and i.has_attr('value')} ref = ('{} '.format(dec.senate) if dec.senate else '') ref += '{0.register} {0.number:d}/{0.year:d}'.format(dec) dct['_ctl0:ContentPlaceMasterPage:_ctl0:txtDatumOd'] = dct['_ctl0:ContentPlaceMasterPage:_ctl0:txtDatumDo'] = \ '{0.day:02d}.{0.month:02d}.{0.year:d}'.format(dec.date) dct['_ctl0:ContentPlaceMasterPage:_ctl0:txtSpisovaZnackaFull'] = ref dct['_ctl0_ContentPlaceMasterPage__ctl0_rbTypDatum_0'] = 'on' res = post(FIND_URL, dct) soup = BeautifulSoup(res.text, 'html.parser') for anchor in soup.select('table#_ctl0_ContentPlaceMasterPage__ctl0_grwA')[0].select('a[title^=Anonymizovan]'): fileurl = anchor['href'] filename = fileurl.split('/')[-1] if not FRE.match(filename): continue res = get(ROOT_URL + fileurl) if not res.ok: continue LOGGER.info( 'Writing anonymized decision "{}"' .format(composeref(dec.senate, dec.register, dec.number, dec.year))) with open(join(REPO_PREF, filename), 'wb') as outfile: if not outfile.write(res.content): # pragma: no cover LOGGER.error( 'Failed to write anonymized decision "{}"' .format(composeref(dec.senate, dec.register, dec.number, dec.year))) return adddoc(APP, filename, ROOT_URL + fileurl) dec.anonfilename = filename dec.save() return except: # pragma: no cover LOGGER.warning('Find failed')
def partybatchform(request): LOGGER.debug('Party import page accessed using method {}'.format(request.method), request) err_message = '' uid = request.user.id uname = request.user.username if request.method == 'POST': button = getbutton(request) if button == 'load': infile = request.FILES.get('load') if not infile: err_message = 'Nejprve zvolte soubor k načtení' else: errors = [] try: count = 0 with infile: idx = 0 for line in csvreader(StringIO(infile.read().decode())): idx += 1 errlen = len(errors) if not line: continue line = line[0].strip() if ':' in line: line, party_opt = line.split(':', 1) else: party_opt = '*' if not between(MIN_LENGTH, len(line), MAX_LENGTH): errors.append((idx, 'Chybná délka řetězce')) continue if party_opt not in TEXT_OPTS_ABBR: errors.append((idx, 'Chybná zkratka pro posici')) continue if len(errors) == errlen: try: Party.objects.update_or_create( uid_id=uid, party=line, defaults={'party_opt': TEXT_OPTS_AI[party_opt]} ) except: errors.append((idx, 'Řetězci "{}" odpovídá více než jeden účastník'.format(line))) continue count += 1 LOGGER.info('User "{}" ({:d}) imported {} party/ies'.format(uname, uid, count), request) return render( request, 'sur_partybatchresult.xhtml', {'app': APP, 'page_title': 'Import účastníků řízení ze souboru', 'count': count, 'errors': errors}) except: # pragma: no cover LOGGER.error('Error reading file', request) err_message = 'Chyba při načtení souboru' else: LOGGER.debug('Invalid form', request) err_message = INERR return render( request, 'sur_partybatchform.xhtml', {'app': APP, 'page_title': 'Import účastníků řízení ze souboru', 'err_message': err_message, 'min_length': MIN_LENGTH, 'max_length': MAX_LENGTH})
def debtorbatchform(request): LOGGER.debug('Debtor import page accessed using method {}'.format(request.method), request) err_message = '' uid = request.user.id uname = request.user.username if request.method == 'POST': button = getbutton(request) if button == 'load': infile = request.FILES.get('load') if not infile: err_message = 'Nejprve zvolte soubor k načtení' else: errors = [] try: count = 0 with infile: idx = 0 for line in csvreader(StringIO(infile.read().decode())): idx += 1 errlen = len(errors) if not line: continue desc = line[0].strip() court = name = first_name = genid = taxid = birthid = date_birth = year_birth_from \ = year_birth_to = None name_opt = first_name_opt = 0 if not desc: errors.append((idx, 'Prázdný popis')) continue if len(desc) > 255: errors.append((idx, 'Příliš dlouhý popis')) continue for term in line[1:]: if '=' not in term: errors.append((idx, 'Chybný formát')) continue key, val = map( lambda x: x.strip(), term.split('=', 1)) if not val: continue if key == 'soud': court = val elif key == 'název': if ':' in val: name, name_opt = val.split(':', 1) if name_opt not in TEXT_OPTS_ABBR: errors.append((idx, 'Chybná zkratka pro posici v poli <q>název</q>')) continue name_opt = TEXT_OPTS_AI[name_opt] else: name = val name_opt = 0 if len(name) > MAX_LENGTH: errors.append((idx, 'Příliš dlouhé pole <q>název</q>')) continue elif key == 'jméno': if ':' in val: first_name, first_name_opt = val.split(':', 1) if first_name_opt not in TEXT_OPTS_ABBR: errors.append((idx, 'Chybná zkratka pro posici v poli <q>jméno</q>')) continue first_name_opt = TEXT_OPTS_AI[first_name_opt] else: first_name = val first_name_opt = 0 if len(first_name) > MAX_LENGTH: errors.append((idx, 'Příliš dlouhé pole <q>jméno</q>')) continue elif key == 'IČO': if not compile(IC_RE_STR).match(val): errors.append((idx, 'Chybná hodnota pro IČO')) continue genid = val elif key == 'DIČ': if len(val) > 14: errors.append((idx, 'Chybná hodnota pro DIČ')) continue taxid = val elif key == 'RČ': if not compile(RC_FULL_RE_STR).match(val): errors.append((idx, 'Chybná hodnota pro rodné číslo')) continue birthid = val.replace('/', '') elif key == 'datumNarození': try: date_birth = date(*map(int, val.split('.')[2::-1])) assert date_birth.year >= 1900 except: errors.append((idx, 'Chybná hodnota pro datum narození')) continue elif key == 'rokNarozeníOd': try: year_birth_from = int(val) assert year_birth_from >= 1900 except: errors.append((idx, 'Chybná hodnota pro pole <q>rokNarozeníOd</q>')) continue elif key == 'rokNarozeníDo': try: year_birth_to = int(val) assert year_birth_to >= 1900 except: errors.append((idx, 'Chybná hodnota pro pole <q>rokNarozeníDo</q>')) continue else: errors.append((idx, 'Chybný parametr: "{}"'.format(key))) continue if year_birth_from and year_birth_to and year_birth_from > year_birth_to: errors.append((idx, 'Chybný interval pro rok narození')) continue if len(errors) == errlen: try: Debtor.objects.update_or_create( uid_id=uid, desc=desc, defaults={ 'court': court, 'name': name, 'name_opt': name_opt, 'first_name': first_name, 'first_name_opt': first_name_opt, 'genid': genid, 'taxid': taxid, 'birthid': birthid, 'date_birth': date_birth, 'year_birth_from': year_birth_from, 'year_birth_to': year_birth_to} ) except: errors.append((idx, 'Popisu "{}" odpovídá více než jeden dlužník'.format(desc))) continue count += 1 LOGGER.info('User "{}" ({:d}) imported {:d} debtor(s)'.format(uname, uid, count), request) return render( request, 'dir_debtorbatchresult.xhtml', {'app': APP, 'page_title': 'Import dlužníků ze souboru', 'count': count, 'errors': errors}) except: # pragma: no cover LOGGER.error('Error reading file', request) err_message = 'Chyba při načtení souboru' else: LOGGER.debug('Invalid form', request) err_message = INERR return render( request, 'dir_debtorbatchform.xhtml', {'app': APP, 'page_title': 'Import dlužníků ze souboru', 'err_message': err_message})
def insbatchform(request): LOGGER.debug('Proceedings import page accessed using method {}'.format(request.method), request) err_message = '' uid = request.user.id uname = request.user.username if request.method == 'POST': button = getbutton(request) if button == 'load': infile = request.FILES.get('load') if not infile: err_message = 'Nejprve zvolte soubor k načtení' else: errors = [] try: count = 0 with infile: idx = 0 for line in csvreader(StringIO(infile.read().decode())): idx += 1 errlen = len(errors) if not line: continue desc = line[0].strip() if not desc: errors.append((idx, 'Prázdný popis')) continue if len(desc) > 255: errors.append((idx, 'Příliš dlouhý popis')) continue try: number = int(line[1]) assert number > 0 except: errors.append((idx, 'Chybné běžné číslo')) continue try: year = int(line[2]) assert year >= 2008 except: errors.append((idx, 'Chybný ročník')) continue detailed = line[3].strip() if detailed == 'ano': detailed = True elif detailed == 'ne': detailed = False else: errors.append((idx, 'Chybný údaj pro pole Vše')) continue if len(errors) == errlen: try: Insolvency.objects.update_or_create( uid_id=uid, desc=desc, defaults={ 'number': number, 'year': year, 'detailed': detailed} ) except: errors.append((idx, 'Popisu "{}" odpovídá více než jedno řízení'.format(desc))) continue count += 1 LOGGER.info('User "{}" ({:d}) imported {:d} proceedings'.format(uname, uid, count), request) return render( request, 'sir_insbatchresult.xhtml', {'app': APP, 'page_title': 'Import řízení ze souboru', 'count': count, 'errors': errors}) except: # pragma: no cover LOGGER.error('Error reading file', request) err_message = 'Chyba při načtení souboru' return render( request, 'sir_insbatchform.xhtml', {'app': APP, 'page_title': 'Import řízení ze souboru', 'err_message': err_message})
def cron_update(): nss = Court.objects.get(pk=SUPREME_ADMINISTRATIVE_COURT) try: res = get(FORM_URL) soup = BeautifulSoup(res.text, 'html.parser') form = soup.find('form') dct = {i['name']: i['value'] for i in form.find_all('input') if i['type'] == 'hidden' and i.has_attr('value')} while True: dct['_ctl0:ContentPlaceMasterPage:_ctl0:ddlSortName'] = '5' dct['_ctl0:ContentPlaceMasterPage:_ctl0:ddlSortDirection'] = '1' res = post(FORM_URL, dct) soup = BeautifulSoup(res.text, 'html.parser') for item in soup.select('table.item'): try: ttr = item.select('tr') senate, register, number, year, page = decomposeref(ttr[0].td.text.strip()) if Decision.objects.filter( senate=senate, register=register, number=number, year=year, page=page).exists(): continue fileurl = ttr[4].a['href'] filename = fileurl.split('/')[-1] if not FRE.match(filename): continue res = get(ROOT_URL + fileurl) if not res.ok: continue LOGGER.info('Writing abridged decision "{}"'.format(composeref(senate, register, number, year))) with open(join(REPO_PREF, filename), 'wb') as outfile: if not outfile.write(res.content): # pragma: no cover LOGGER.error( 'Failed to write abridged decision "{}"' .format(composeref(senate, register, number, year))) continue adddoc(APP, filename, ROOT_URL + fileurl) agenda = Agenda.objects.get_or_create(desc=ttr[2].td.text.strip())[0] dat = date(*map(int, list(reversed(ttr[3].td.text.split('.'))))) dec = Decision( senate=senate, register=register, number=number, year=year, page=page, agenda=agenda, date=dat, filename=filename) dec.save() for query in ttr[1].td: if 'strip' in dir(query): qstrip = query.strip() party = Party.objects.get_or_create(name=qstrip)[0] dec.parties.add(party) sur_check( {'check_udn': True}, qstrip, nss, senate, register, number, year, DEC_URL.format(senate, quote(register), number, year, page)) except: # pragma: no cover pass pagers = soup.select('div#PagingBox2')[0] cpag = int(pagers.b.text[1:-1]) pager = pagers.select('a') if cpag > len(pager): break form = soup.find('form') dct = {i['name']: i['value'] for i in form.find_all('input') if i['type'] == 'hidden' and i.has_attr('value')} dct['__EVENTTARGET'] = pager[cpag - 1]['href'][70:-34] dct['__EVENTARGUMENT'] = '' except: # pragma: no cover LOGGER.warning('Update failed')
def procbatchform(request): LOGGER.debug( 'Proceedings import page accessed using method {}'.format( request.method), request) err_message = '' uid = request.user.id uname = request.user.username today = date.today() if request.method == 'POST': button = getbutton(request) if button == 'load': infile = request.FILES.get('load') if not infile: err_message = 'Nejprve zvolte soubor k načtení' else: errors = [] try: count = 0 with infile: idx = 0 for line in csvreader(StringIO( infile.read().decode())): idx += 1 errlen = len(errors) if not line: continue if len(line) != 3: errors.append((idx, 'Chybný formát')) continue desc = line[0].strip() if not desc: errors.append((idx, 'Prázdný popis')) continue if len(desc) > 255: errors.append((idx, 'Příliš dlouhý popis')) continue try: court = line[1] assert Court.objects.get(id=court) except: errors.append((idx, 'Chybná zkratka soudu')) continue try: senate, register, number, year = decomposeref( line[2]) assert senate >= 0 assert register in REGISTERS assert number > 0 assert year >= 1990 and year <= today.year except: errors.append((idx, 'Chybná spisová značka')) continue if len(errors) == errlen: proc = Proceedings.objects.filter( uid_id=uid, desc=desc, court=court, senate=senate, register=register, number=number, year=year) if not proc.exists(): try: proc = Proceedings.objects.update_or_create( uid_id=uid, desc=desc, defaults={ 'court_id': court, 'senate': senate, 'register': register, 'number': number, 'year': year, 'changed': None, 'updated': None, 'hash': '', 'auxid': 0, 'notify': False })[0] updateproc(proc) proc.save() except: errors.append(( idx, 'Popisu "{}" odpovídá více než jedno řízení' .format(desc))) continue count += 1 LOGGER.info( 'User "{}" ({:d}) imported {:d} proceedings'.format( uname, uid, count), request) return render( request, 'szr_procbatchresult.xhtml', { 'app': APP, 'page_title': 'Import řízení ze souboru', 'count': count, 'errors': errors }) except: # pragma: no cover LOGGER.error('Error reading file', request) err_message = 'Chyba při načtení souboru' return render( request, 'szr_procbatchform.xhtml', { 'app': APP, 'page_title': 'Import řízení ze souboru', 'err_message': err_message })
def insbatchform(request): LOGGER.debug( 'Proceedings import page accessed using method {}'.format( request.method), request) err_message = '' uid = request.user.id uname = request.user.username if request.method == 'POST': button = getbutton(request) if button == 'load': infile = request.FILES.get('load') if not infile: err_message = 'Nejprve zvolte soubor k načtení' else: errors = [] try: count = 0 with infile: idx = 0 for line in csvreader(StringIO( infile.read().decode())): idx += 1 errlen = len(errors) if not line: continue desc = line[0].strip() if not desc: errors.append((idx, 'Prázdný popis')) continue if len(desc) > 255: errors.append((idx, 'Příliš dlouhý popis')) continue try: number = int(line[1]) assert number > 0 except: errors.append((idx, 'Chybné běžné číslo')) continue try: year = int(line[2]) assert year >= 2008 except: errors.append((idx, 'Chybný ročník')) continue detailed = line[3].strip() if detailed == 'ano': detailed = True elif detailed == 'ne': detailed = False else: errors.append( (idx, 'Chybný údaj pro pole Vše')) continue if len(errors) == errlen: try: Insolvency.objects.update_or_create( uid_id=uid, desc=desc, defaults={ 'number': number, 'year': year, 'detailed': detailed }) except: errors.append(( idx, 'Popisu "{}" odpovídá více než jedno řízení' .format(desc))) continue count += 1 LOGGER.info( 'User "{}" ({:d}) imported {:d} proceedings'.format( uname, uid, count), request) return render( request, 'sir_insbatchresult.xhtml', { 'app': APP, 'page_title': 'Import řízení ze souboru', 'count': count, 'errors': errors }) except: # pragma: no cover LOGGER.error('Error reading file', request) err_message = 'Chyba při načtení souboru' return render( request, 'sir_insbatchform.xhtml', { 'app': APP, 'page_title': 'Import řízení ze souboru', 'err_message': err_message })
def partybatchform(request): LOGGER.debug( 'Party import page accessed using method {}'.format(request.method), request) err_message = '' uid = request.user.id uname = request.user.username if request.method == 'POST': button = getbutton(request) if button == 'load': infile = request.FILES.get('load') if not infile: err_message = 'Nejprve zvolte soubor k načtení' else: errors = [] try: count = 0 with infile: idx = 0 for line in csvreader(StringIO( infile.read().decode())): idx += 1 errlen = len(errors) if not line: continue line = line[0].strip() if ':' in line: line, party_opt = line.split(':', 1) else: party_opt = '*' if not between(MIN_LENGTH, len(line), MAX_LENGTH): errors.append((idx, 'Chybná délka řetězce')) continue if party_opt not in TEXT_OPTS_ABBR: errors.append( (idx, 'Chybná zkratka pro posici')) continue if len(errors) == errlen: try: Party.objects.update_or_create( uid_id=uid, party=line, defaults={ 'party_opt': TEXT_OPTS_AI[party_opt] }) except: errors.append(( idx, 'Řetězci "{}" odpovídá více než jeden účastník' .format(line))) continue count += 1 LOGGER.info( 'User "{}" ({:d}) imported {} party/ies'.format( uname, uid, count), request) return render( request, 'sur_partybatchresult.xhtml', { 'app': APP, 'page_title': 'Import účastníků řízení ze souboru', 'count': count, 'errors': errors }) except: # pragma: no cover LOGGER.error('Error reading file', request) err_message = 'Chyba při načtení souboru' else: LOGGER.debug('Invalid form', request) err_message = INERR return render( request, 'sur_partybatchform.xhtml', { 'app': APP, 'page_title': 'Import účastníků řízení ze souboru', 'err_message': err_message, 'min_length': MIN_LENGTH, 'max_length': MAX_LENGTH })
def get_fx_rate(curr, dat, log=None, use_fixed=False, log_fixed=None): LOGGER.debug( 'FX rate requested, currency "{0}" for {1.year:d}-{1.month:02d}-{1.day:02d}, fixed "{2}"' .format(curr, dat, use_fixed)) fixed_list = { 'XEU': {'currency_to': 'EUR', 'fixed_rate': 1, 'date_from': date(1999, 1, 1)}, 'ATS': {'currency_to': 'EUR', 'fixed_rate': 13.7603, 'date_from': date(1998, 12, 31)}, 'BEF': {'currency_to': 'EUR', 'fixed_rate': 40.3399, 'date_from': date(1998, 12, 31)}, 'NLG': {'currency_to': 'EUR', 'fixed_rate': 2.20371, 'date_from': date(1998, 12, 31)}, 'FIM': {'currency_to': 'EUR', 'fixed_rate': 5.94573, 'date_from': date(1998, 12, 31)}, 'FRF': {'currency_to': 'EUR', 'fixed_rate': 6.55957, 'date_from': date(1998, 12, 31)}, 'DEM': {'currency_to': 'EUR', 'fixed_rate': 1.95583, 'date_from': date(1998, 12, 31)}, 'IEP': {'currency_to': 'EUR', 'fixed_rate': .787564, 'date_from': date(1998, 12, 31)}, 'ITL': {'currency_to': 'EUR', 'fixed_rate': 1936.27, 'date_from': date(1998, 12, 31)}, 'LUF': {'currency_to': 'EUR', 'fixed_rate': 40.3399, 'date_from': date(1998, 12, 31)}, 'MCF': {'currency_to': 'EUR', 'fixed_rate': 6.55957, 'date_from': date(1998, 12, 31)}, 'PTE': {'currency_to': 'EUR', 'fixed_rate': 200.482, 'date_from': date(1998, 12, 31)}, 'SML': {'currency_to': 'EUR', 'fixed_rate': 1936.27, 'date_from': date(1998, 12, 31)}, 'ESP': {'currency_to': 'EUR', 'fixed_rate': 166.386, 'date_from': date(1998, 12, 31)}, 'VAL': {'currency_to': 'EUR', 'fixed_rate': 1936.27, 'date_from': date(1998, 12, 31)}, 'GRD': {'currency_to': 'EUR', 'fixed_rate': 340.75, 'date_from': date(2000, 6, 19)}, 'SIT': {'currency_to': 'EUR', 'fixed_rate': 239.64, 'date_from': date(2006, 7, 11)}, 'CYP': {'currency_to': 'EUR', 'fixed_rate': .585274, 'date_from': date(2007, 7, 10)}, 'MTL': {'currency_to': 'EUR', 'fixed_rate': .4293, 'date_from': date(2007, 7, 10)}, 'SKK': {'currency_to': 'EUR', 'fixed_rate': 30.126, 'date_from': date(2008, 7, 8)}, 'EEK': {'currency_to': 'EUR', 'fixed_rate': 15.6466, 'date_from': date(2010, 7, 13)}, 'ROL': {'currency_to': 'RON', 'fixed_rate': 10000, 'date_from': date(2005, 7, 1)}, 'RUR': {'currency_to': 'RUB', 'fixed_rate': 1000, 'date_from': date(1998, 1, 1)}, 'MXP': {'currency_to': 'MXN', 'fixed_rate': 1000, 'date_from': date(1993, 1, 1)}, 'UAK': {'currency_to': 'UAH', 'fixed_rate': 100000, 'date_from': date(1996, 9, 2)}, 'TRL': {'currency_to': 'TRY', 'fixed_rate': 1000000, 'date_from': date(2005, 1, 1)}, 'BGL': {'currency_to': 'BGN', 'fixed_rate': 1000, 'date_from': date(1999, 7, 5)}, 'PLZ': {'currency_to': 'PLN', 'fixed_rate': 10000, 'date_from': date(1995, 1, 1)}, 'CSD': {'currency_to': 'RSD', 'fixed_rate': 1, 'date_from': date(2003, 1, 1)}, } today = date.today() if dat.year < 1991 or dat > today: return None, None, None, 'Chybné datum, data nejsou k disposici' rat = FXrate.objects.filter(date=dat) if rat: txt = rat[0].text else: surl = ( 'https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.xml?' 'date={0.day:d}.{0.month:d}.{0.year:d}'.format(dat)) txt = getcache(surl, DOWNLOAD_REPEAT)[0] if not txt: LOGGER.warning('No connection to CNB server') return None, None, None, 'Chyba spojení se serverem ČNB' try: soup = new_xml(txt) assert soup assert soup.find( 'tabulka', {'typ': 'XML_TYP_CNB_KURZY_DEVIZOVEHO_TRHU'}) dreq = soup.find('kurzy', {'banka': 'CNB'})['datum'] dreq = date(int(dreq[6:]), int(dreq[3:5]), int(dreq[:2])) except: LOGGER.error('Invalid FX table structure for {0.year:d}-{0.month:02d}-{0.day:02d}'.format(dat)) return None, None, None, 'Chyba struktury kursové tabulky' if not rat and (dreq == dat or (today - dat) > DOWNLOAD_WAIT): FXrate(date=dat, text=txt).save() lin = soup.find('radek', {'kod': curr}) frat = 1 curr_rq = curr if not lin: if use_fixed and curr in fixed_list and fixed_list[curr]['date_from'] <= dat: curr = fixed_list[curr]['currency_to'] lin = soup.find('radek', {'kod': curr}) if not lin: return None, None, dreq, 'Kurs není v kursové tabulce' frat = fixed_list[curr_rq]['fixed_rate'] if log_fixed != None: log_fixed.append( {'currency_from': curr_rq, 'currency_to': fixed_list[curr_rq]['currency_to'], 'rate': fixed_list[curr_rq]['fixed_rate'], 'date_from': fixed_list[curr_rq]['date_from']}) else: return None, None, dreq, 'Kurs není v kursové tabulce' try: qty = int(lin['mnozstvi']) if lin.has_attr('kurz'): rate = lin['kurz'] elif lin.has_attr('pomer'): rate = lin['pomer'] rate = float(rate.replace(',', '.')) except: LOGGER.error('Invalid FX table line for {0.year:d}-{0.month:02d}-{0.day:02d}'.format(dat)) return None, None, dreq, 'Chyba řádku kursové tabulky' if log != None: log.append( {'currency': curr, 'quantity': qty, 'rate': rate, 'date_required': dat, 'date': dreq}) return rate / frat, qty, dreq, None
def get_mpi_rate(typ, dat, log=None): LOGGER.debug('MPI rate of type "{0}" requested for {1.year:d}-{1.month:02d}-{1.day:02d}'.format(typ, dat)) now = datetime.now() prefix = 'https://www.cnb.cz/cs/faq/vyvoj_' suffix = '_historie.txt' types = { 'DISC': ('diskontni', 'PLATNA_OD|CNB_DISKONTNI_SAZBA_V_%'), 'LOMB': ('lombard', 'PLATNA_OD|CNB_LOMBARDNI_SAZBA_V_%'), 'REPO': ('repo', 'PLATNA_OD|CNB_REPO_SAZBA_V_%'), } if typ not in types.keys(): return None, 'Chybný druh sazby' if dat.year < 1990 or dat > now.date(): return None, 'Chybné datum, data nejsou k disposici' stat = MPIstat.objects.get_or_create(type=typ) updated = stat[0].timestamp_update.date() if stat[1] or (not MPIrate.objects.filter(type=typ, valid__gte=dat).exists() and (updated - dat) < DOWNLOAD_WAIT): surl = prefix + types[typ][0] + suffix txt = getcache(surl, DOWNLOAD_REPEAT)[0] if not txt: LOGGER.warning('No connection to CNB server') return None, 'Chyba spojení se serverem ČNB' txt = txt.replace('\r', '').split('\n') if txt[0] != types[typ][1]: LOGGER.error('Error in rate table for {}'.format(types[typ][0])) return None, 'Chyba tabulky sazeb (1)' rates = [] try: for lin in txt[1:]: assert lin[8] == '|' rates.append( (float(lin[9:].replace(',', '.')), date(int(lin[:4]), int(lin[4:6]), int(lin[6:8])))) except: LOGGER.error('Error in rate table for {}'.format(types[typ][0])) return None, 'Chyba tabulky sazeb (2)' try: for rat in rates: if stat[1] or (updated - rat[1]) < DOWNLOAD_WAIT: MPIrate.objects.get_or_create( type=typ, rate=rat[0], valid=rat[1]) except: # pragma: no cover LOGGER.error('Error writing in database') return None, 'Chyba zápisu do database (1)' try: MPIstat.objects.get_or_create(type=typ)[0].save() except: # pragma: no cover LOGGER.error('Error writing in database') return None, 'Chyba zápisu do database (2)' res = MPIrate.objects.filter(type=typ, valid__lte=dat).order_by('-valid') if not res.exists(): return None, 'Sazba není k disposici' if log != None: log.append({'type': typ, 'rate': res[0].rate, 'date': dat}) return res[0].rate, None
def get_fx_rate(curr, dat, log=None, use_fixed=False, log_fixed=None): LOGGER.debug( 'FX rate requested, currency "{0}" for {1.year:d}-{1.month:02d}-{1.day:02d}, fixed "{2}"' .format(curr, dat, use_fixed)) fixed_list = { 'XEU': { 'currency_to': 'EUR', 'fixed_rate': 1, 'date_from': date(1999, 1, 1) }, 'ATS': { 'currency_to': 'EUR', 'fixed_rate': 13.7603, 'date_from': date(1998, 12, 31) }, 'BEF': { 'currency_to': 'EUR', 'fixed_rate': 40.3399, 'date_from': date(1998, 12, 31) }, 'NLG': { 'currency_to': 'EUR', 'fixed_rate': 2.20371, 'date_from': date(1998, 12, 31) }, 'FIM': { 'currency_to': 'EUR', 'fixed_rate': 5.94573, 'date_from': date(1998, 12, 31) }, 'FRF': { 'currency_to': 'EUR', 'fixed_rate': 6.55957, 'date_from': date(1998, 12, 31) }, 'DEM': { 'currency_to': 'EUR', 'fixed_rate': 1.95583, 'date_from': date(1998, 12, 31) }, 'IEP': { 'currency_to': 'EUR', 'fixed_rate': .787564, 'date_from': date(1998, 12, 31) }, 'ITL': { 'currency_to': 'EUR', 'fixed_rate': 1936.27, 'date_from': date(1998, 12, 31) }, 'LUF': { 'currency_to': 'EUR', 'fixed_rate': 40.3399, 'date_from': date(1998, 12, 31) }, 'MCF': { 'currency_to': 'EUR', 'fixed_rate': 6.55957, 'date_from': date(1998, 12, 31) }, 'PTE': { 'currency_to': 'EUR', 'fixed_rate': 200.482, 'date_from': date(1998, 12, 31) }, 'SML': { 'currency_to': 'EUR', 'fixed_rate': 1936.27, 'date_from': date(1998, 12, 31) }, 'ESP': { 'currency_to': 'EUR', 'fixed_rate': 166.386, 'date_from': date(1998, 12, 31) }, 'VAL': { 'currency_to': 'EUR', 'fixed_rate': 1936.27, 'date_from': date(1998, 12, 31) }, 'GRD': { 'currency_to': 'EUR', 'fixed_rate': 340.75, 'date_from': date(2000, 6, 19) }, 'SIT': { 'currency_to': 'EUR', 'fixed_rate': 239.64, 'date_from': date(2006, 7, 11) }, 'CYP': { 'currency_to': 'EUR', 'fixed_rate': .585274, 'date_from': date(2007, 7, 10) }, 'MTL': { 'currency_to': 'EUR', 'fixed_rate': .4293, 'date_from': date(2007, 7, 10) }, 'SKK': { 'currency_to': 'EUR', 'fixed_rate': 30.126, 'date_from': date(2008, 7, 8) }, 'EEK': { 'currency_to': 'EUR', 'fixed_rate': 15.6466, 'date_from': date(2010, 7, 13) }, 'ROL': { 'currency_to': 'RON', 'fixed_rate': 10000, 'date_from': date(2005, 7, 1) }, 'RUR': { 'currency_to': 'RUB', 'fixed_rate': 1000, 'date_from': date(1998, 1, 1) }, 'MXP': { 'currency_to': 'MXN', 'fixed_rate': 1000, 'date_from': date(1993, 1, 1) }, 'UAK': { 'currency_to': 'UAH', 'fixed_rate': 100000, 'date_from': date(1996, 9, 2) }, 'TRL': { 'currency_to': 'TRY', 'fixed_rate': 1000000, 'date_from': date(2005, 1, 1) }, 'BGL': { 'currency_to': 'BGN', 'fixed_rate': 1000, 'date_from': date(1999, 7, 5) }, 'PLZ': { 'currency_to': 'PLN', 'fixed_rate': 10000, 'date_from': date(1995, 1, 1) }, 'CSD': { 'currency_to': 'RSD', 'fixed_rate': 1, 'date_from': date(2003, 1, 1) }, } today = date.today() if dat.year < 1991 or dat > today: return None, None, None, 'Chybné datum, data nejsou k disposici' rat = FXrate.objects.filter(date=dat) if rat: txt = rat[0].text else: surl = ( 'https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.xml?' 'date={0.day:d}.{0.month:d}.{0.year:d}'.format(dat)) txt = getcache(surl, DOWNLOAD_REPEAT)[0] if not txt: LOGGER.warning('No connection to CNB server') return None, None, None, 'Chyba spojení se serverem ČNB' try: soup = new_xml(txt) assert soup assert soup.find('tabulka', {'typ': 'XML_TYP_CNB_KURZY_DEVIZOVEHO_TRHU'}) dreq = soup.find('kurzy', {'banka': 'CNB'})['datum'] dreq = date(int(dreq[6:]), int(dreq[3:5]), int(dreq[:2])) except: LOGGER.error( 'Invalid FX table structure for {0.year:d}-{0.month:02d}-{0.day:02d}' .format(dat)) return None, None, None, 'Chyba struktury kursové tabulky' if not rat and (dreq == dat or (today - dat) > DOWNLOAD_WAIT): FXrate(date=dat, text=txt).save() lin = soup.find('radek', {'kod': curr}) frat = 1 curr_rq = curr if not lin: if use_fixed and curr in fixed_list and fixed_list[curr][ 'date_from'] <= dat: curr = fixed_list[curr]['currency_to'] lin = soup.find('radek', {'kod': curr}) if not lin: return None, None, dreq, 'Kurs není v kursové tabulce' frat = fixed_list[curr_rq]['fixed_rate'] if log_fixed != None: log_fixed.append({ 'currency_from': curr_rq, 'currency_to': fixed_list[curr_rq]['currency_to'], 'rate': fixed_list[curr_rq]['fixed_rate'], 'date_from': fixed_list[curr_rq]['date_from'] }) else: return None, None, dreq, 'Kurs není v kursové tabulce' try: qty = int(lin['mnozstvi']) if lin.has_attr('kurz'): rate = lin['kurz'] elif lin.has_attr('pomer'): rate = lin['pomer'] rate = float(rate.replace(',', '.')) except: LOGGER.error( 'Invalid FX table line for {0.year:d}-{0.month:02d}-{0.day:02d}'. format(dat)) return None, None, dreq, 'Chyba řádku kursové tabulky' if log != None: log.append({ 'currency': curr, 'quantity': qty, 'rate': rate, 'date_required': dat, 'date': dreq }) return rate / frat, qty, dreq, None
def get_mpi_rate(typ, dat, log=None): LOGGER.debug( 'MPI rate of type "{0}" requested for {1.year:d}-{1.month:02d}-{1.day:02d}' .format(typ, dat)) now = datetime.now() prefix = 'https://www.cnb.cz/cs/faq/vyvoj_' suffix = '_historie.txt' types = { 'DISC': ('diskontni', 'PLATNA_OD|CNB_DISKONTNI_SAZBA_V_%'), 'LOMB': ('lombard', 'PLATNA_OD|CNB_LOMBARDNI_SAZBA_V_%'), 'REPO': ('repo', 'PLATNA_OD|CNB_REPO_SAZBA_V_%'), } if typ not in types.keys(): return None, 'Chybný druh sazby' if dat.year < 1990 or dat > now.date(): return None, 'Chybné datum, data nejsou k disposici' stat = MPIstat.objects.get_or_create(type=typ) updated = stat[0].timestamp_update.date() if stat[1] or ( not MPIrate.objects.filter(type=typ, valid__gte=dat).exists() and (updated - dat) < DOWNLOAD_WAIT): surl = prefix + types[typ][0] + suffix txt = getcache(surl, DOWNLOAD_REPEAT)[0] if not txt: LOGGER.warning('No connection to CNB server') return None, 'Chyba spojení se serverem ČNB' txt = txt.replace('\r', '').split('\n') if txt[0] != types[typ][1]: LOGGER.error('Error in rate table for {}'.format(types[typ][0])) return None, 'Chyba tabulky sazeb (1)' rates = [] try: for lin in txt[1:]: assert lin[8] == '|' rates.append((float(lin[9:].replace(',', '.')), date(int(lin[:4]), int(lin[4:6]), int(lin[6:8])))) except: LOGGER.error('Error in rate table for {}'.format(types[typ][0])) return None, 'Chyba tabulky sazeb (2)' try: for rat in rates: if stat[1] or (updated - rat[1]) < DOWNLOAD_WAIT: MPIrate.objects.get_or_create(type=typ, rate=rat[0], valid=rat[1]) except: # pragma: no cover LOGGER.error('Error writing in database') return None, 'Chyba zápisu do database (1)' try: MPIstat.objects.get_or_create(type=typ)[0].save() except: # pragma: no cover LOGGER.error('Error writing in database') return None, 'Chyba zápisu do database (2)' res = MPIrate.objects.filter(type=typ, valid__lte=dat).order_by('-valid') if not res.exists(): return None, 'Sazba není k disposici' if log != None: log.append({'type': typ, 'rate': res[0].rate, 'date': dat}) return res[0].rate, None
def procbatchform(request): LOGGER.debug('Proceedings import page accessed using method {}'.format(request.method), request) err_message = '' uid = request.user.id uname = request.user.username today = date.today() if request.method == 'POST': button = getbutton(request) if button == 'load': infile = request.FILES.get('load') if not infile: err_message = 'Nejprve zvolte soubor k načtení' else: errors = [] try: count = 0 with infile: idx = 0 for line in csvreader(StringIO(infile.read().decode())): idx += 1 errlen = len(errors) if not line: continue if len(line) != 3: errors.append((idx, 'Chybný formát')) continue desc = line[0].strip() if not desc: errors.append((idx, 'Prázdný popis')) continue if len(desc) > 255: errors.append((idx, 'Příliš dlouhý popis')) continue try: court = line[1] assert Court.objects.get(id=court) except: errors.append((idx, 'Chybná zkratka soudu')) continue try: senate, register, number, year = decomposeref(line[2]) assert senate >= 0 assert register in REGISTERS assert number > 0 assert year >= 1990 and year <= today.year except: errors.append((idx, 'Chybná spisová značka')) continue if len(errors) == errlen: proc = Proceedings.objects.filter( uid_id=uid, desc=desc, court=court, senate=senate, register=register, number=number, year=year) if not proc.exists(): try: proc = Proceedings.objects.update_or_create( uid_id=uid, desc=desc, defaults={ 'court_id': court, 'senate': senate, 'register': register, 'number': number, 'year': year, 'changed': None, 'updated': None, 'hash': '', 'auxid': 0, 'notify': False})[0] updateproc(proc) proc.save() except: errors.append((idx, 'Popisu "{}" odpovídá více než jedno řízení'.format(desc))) continue count += 1 LOGGER.info('User "{}" ({:d}) imported {:d} proceedings'.format(uname, uid, count), request) return render( request, 'szr_procbatchresult.xhtml', {'app': APP, 'page_title': 'Import řízení ze souboru', 'count': count, 'errors': errors}) except: # pragma: no cover LOGGER.error('Error reading file', request) err_message = 'Chyba při načtení souboru' return render( request, 'szr_procbatchform.xhtml', {'app': APP, 'page_title': 'Import řízení ze souboru', 'err_message': err_message})