# -*- coding: windows-1251 -*-
'''
Created on 27.06.2013

@author: scond_000
'''
from urllib2 import urlopen, URLError
from urllib import urlretrieve
from xml.etree.ElementTree import parse
from datetime import date
import logging
logging.basicConfig(level=logging.INFO)
stat = logging.info


def reporthook(count, block_size, total_size):
    #percent = int(count * block_size * 100 / total_size)
    stat("Загрузка файлов БИК")


def dot2date(dot):
    parts = dot.split('.')
    return date(int(parts[2]), int(parts[1]), int(parts[0]))


def GetBik(tgt, dat=None):
    '''Скачивает и сохраняет в папку 'tgt' файлы справочника БИК
    Если дата 'dat' указана, то скачивает БИК не новее этой даты.
    '''
    import zipfile
    stat("Загрузка истории БИК")
    biklist = parse(urlopen('http://www.cbr.ru/Queries/FileSource/33409/GetBicCatalogDB.xml?inline=True'))
    lastbik = ('', date(100, 1, 1))
    for bik in biklist.findall('item'):
        bikdate = dot2date(bik.get('date'))
        if bikdate > lastbik[1] and ((dat is None) or bikdate <= dat):
            lastbik = (bik.get('file'), bikdate)
    stat("Загрузка файлов БИК")
    fname = urlretrieve('http://www.cbr.ru'+biklist.getroot().get('Base') + lastbik[0],
                        reporthook=reporthook)[0]
    bikzip = zipfile.ZipFile(fname)
    if not os.path.exists(tgt):
        os.makedirs(tgt)
    for it in bikzip.infolist():
        if it.filename.upper() == 'BNKSEEK.DBF' or\
           it.filename.upper() == 'KORREK.DBF':
            bikzip.extract(it, tgt)


def UpdateCurs(tbcode, cbcode, fil):
    import ConfigParser
    from os import rename, remove
    stat("Обновление курса" + tbcode)
    config = ConfigParser.RawConfigParser()
    sec = "Курс." + tbcode
    try:
        config.readfp(open(fil))
        pre = config.items(sec)
        pre = filter(lambda it: not it[0].startswith('--'), pre)  # remove comments
        dates = [dot2date(it[0]) for it in pre]
        lastdate = max(dates)
    except:
        config.add_section(sec)
        lastdate = date(date.today().year - 1, 12, 31)
    cbcurs = parse(urlopen('http://www.cbr.ru/scripts/XML_dynamic.asp' + \
                           '?date_req1=' + lastdate.strftime("%d/%m/%Y") + \
                           '&date_req2=' + date.today().strftime("%d/%m/%Y") + \
                           '&VAL_NM_RQ=' + cbcode))
    curs = [(dot2date(it.get("Date")), it.findtext('Value')) for it in cbcurs.findall("Record")]
    curs.sort(key=lambda it: it[0])
    for cur in curs:
        config.set(sec, cur[0].strftime("%d.%m.%Y"), cur[1].replace(",", "."))
    try:
        remove(fil + '.bak')
    except:
        pass
    try:
        rename(fil, fil + '.bak')
    except:
        pass
    config.write(open(fil, 'w'))

vals = {'USD': 'R01235', 'EUR': 'R01239'}
if __name__ == '__main__':
    import argparse
    import os
    pars = argparse.ArgumentParser(description="Tool for get up-to-date data for TB.Budget from cbr site")
    pars.add_argument("folder", help="Folder with TBB.Buhgalter configuration", nargs="?")
    pars.add_argument('--kurs', '-k', '--val', '-v', action='append', choices=['USD', 'EUR'],
                      help="Get rate of exchenge for target currency")
    pars.add_argument('--bik', '-b', action='store_true', help="Get BIK database")
    #pars.print_help()
    p = pars.parse_args()
    if p.folder:
        if p.bik:
            GetBik(os.sep.join((p.folder, "БИК")))
        for val in p.kurs if p.kurs else []:
            if not os.path.exists(os.sep.join((p.folder, "Переменные"))):
                os.makedirs(os.sep.join((p.folder, "Переменные")))
            UpdateCurs(val, vals[val], os.sep.join((p.folder, "Переменные", "Курс" + val + ".var")))
    else:
        import wx
        app = wx.App()

        class Window(wx.Frame):
            def OnGoPress(self, event):
                self.progress = wx.ProgressDialog("Обновление", "Обновление данных с сайта ЦБ",
                                                  style=wx.PD_ELAPSED_TIME)
                folder = self.txt1.GetPath().encode('cp1251')
                try:
                    if self.bik.IsChecked():
                        GetBik(os.sep.join((folder, "БИК")))
                    if not os.path.exists(os.sep.join((folder, "Переменные"))):
                        os.makedirs(os.sep.join((folder, "Переменные")))
                    if self.usd.IsChecked():
                        UpdateCurs('USD', vals['USD'],
                               os.sep.join((folder, "Переменные",
                                            "КурсUSD.var")))
                    if self.eur.IsChecked():
                        UpdateCurs('EUR', vals['EUR'],
                               os.sep.join((folder, "Переменные",
                                            "КурсEUR.var")))
                except URLError:
                    msg = wx.MessageBox("Ошибка доступа к сайту ЦБ", style=wx.OK | wx.ICON_ERROR)
                stat('')
                self.progress.Destroy()
                self.progress = None

            def __init__(self, parent, title):
                global stat
                wx.Frame.__init__(self, parent, title=title)
                self.config = wx.BoxSizer(wx.VERTICAL)
                self.config.AddSpacer(5)
                self.panel = wx.Panel(self)
                self.panel.SetSizer(self.config)

                self.fld = wx.BoxSizer(wx.HORIZONTAL)
                self.config.Add(self.fld)
                self.capt1 = wx.StaticText(self.panel, label="Выберите папку бухгалтерии:",
                                           style=wx.ALIGN_LEFT)
                self.fld.AddSpacer(10)
                self.fld.Add(self.capt1, flag=wx.ALIGN_CENTRE)
                self.txt1 = wx.DirPickerCtrl(self.panel,
                                             message="Выберите папку бухгалтерии",
                                              style=wx.DIRP_USE_TEXTCTRL +\
                                              wx.DIRP_DIR_MUST_EXIST)
                self.fld.Add(self.txt1)
                #self.btn1 = wx.Button(self.panel, label='...')
                #self.fld.Add(self.btn1)
                self.bik = wx.CheckBox(self.panel, label='Обновить БИК')
                #self.kurs = wx.(self.panel, label='')
                self.config.AddSpacer(10)
                self.config.Add(self.bik, flag=wx.LEFT, border=10)
                self.kurs = wx.StaticBox(self.panel, label="Обновить курсы валют")
                self.kurss = wx.StaticBoxSizer(self.kurs, wx.VERTICAL)
                self.config.Add(self.kurss, flag=wx.ALL + wx.EXPAND, border=10)
                self.usd = wx.CheckBox(self.panel, label='USD')
                self.kurss.Add(self.usd)
                self.kurss.AddSpacer(5)
                self.eur = wx.CheckBox(self.panel, label='EUR')
                self.kurss.Add(self.eur)
                self.gobtn = wx.Button(self.panel, label='Обновить')
                self.Bind(wx.EVT_BUTTON, self.OnGoPress, self.gobtn)
                self.config.Add(self.gobtn, flag=wx.LEFT + wx.DOWN, border=10)
                #self.sb = wx.StatusBar(self)
                #self.SetStatusBar(self.sb)
                self.progress = None
                global stat
                def statbup(txt):
                    if self.progress:
                        self.progress.Pulse(txt)

                stat = statbup

                self.panel.Fit()
                self.Fit()
                self.Show(True)

        wnd = Window(None, "Обновление данных с сайта ЦБ")
        app.MainLoop()
