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

__author__ = 'helljump'

import logging
import startup
from utils import MyProgressDialog
from ui.imp_cmsimple_ui import Ui_Dialog
from PyQt4 import QtGui
from PyQt4 import QtCore
from dbobj import Document
import chardet
import re
import codecs
from ZODB.utils import p64
import os
from pytils.translit import slugify
from ZODB.POSException import POSKeyError
import transaction


log = logging.getLogger(__name__)


HTML_HEADER = """<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>%s</title>
</head>
<body>
"""


HTML_FOOTER = """</body>
</html>
"""


class Dialog(QtGui.QDialog, Ui_Dialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUi(self)
        #root = startup.CONN.root()
        #prefs = root.

    @QtCore.pyqtSlot()
    def on_lineEditButton_clicked(self):
        fn = QtGui.QFileDialog.getOpenFileName(self, u'Импорт', QtCore.QString(),
            u'CMSimple HTML (*.html)')
        if fn.isEmpty():
            return

    def accept(self):
        self.setResult(1)
        self.hide()


def read_cms(html):
    enc = chardet.detect(html[:1000])
    log.debug('detected %s', enc)
    uhtml = unicode(html, enc['encoding'], 'replace')
    cat = u'Новости'
    splitted = re.split("(?imsu)<h[1-8][^>]*>", uhtml)
    for chunk in splitted:
        spam = re.split("(?imsu)</h([1-8])>", chunk)
        if len(spam) > 1 and len(spam[0].strip()) > 0:
            params = {}
            deep = int(spam[1])
            title = re.sub('<(?!(?:a\s|/a|!))[^>]*>', '', spam[0]).strip()
            if deep == 1:
                cat = title
            elif len(spam) > 2:
                params['title'] = title
                params['cat'] = cat
                params['text'] = spam[2].strip()
                yield params


def reader(parent):
    fn = QtGui.QFileDialog.getOpenFileName(parent, u'Импорт', QtCore.QString(), u'CMSimple HTML (*.html)')
    if fn.isEmpty():
        return False
    fn = unicode(fn)
    pdlg = MyProgressDialog(u'Импорт', u'Чтение файла', u'Отмена', parent=parent)
    pdlg.show()
    root = parent.project.root()
    documents = root["documents"]
    cats = root["cats"]
    docs = 0
    try:
        html = open(fn, 'r').read()
        docs = 0
        for item in read_cms(html):
            doc = Document()
            doc.title = item['title']
            doc.text = item['text']
            doc.cats = set([item['cat']])
            docs += 1
            documents.appendSorted(doc)
            cats.update(doc.cats)
            if docs % 100 == 0:
                QtGui.qApp.processEvents()
            if pdlg.wasCanceled():
                raise IOError('Canceled')
        transaction.commit()
        log.debug('docs %i', docs)
    except:
        transaction.abort()
        raise
    finally:
        pdlg.close()
    return True


def write_cms(prj, fn):
    img_re = re.compile('(cm3\://image/(\d+))')
    prefs = prj.root().get('prefs', {})
    conn = prj.con()
    ww = prefs.get('image_width', 200)
    hh = prefs.get('image_height', 200)
    imgdir = prefs.get('image_dir', 'images')
    documents = prj.root()['documents']
    docs = sorted(documents, key=lambda doc: str(doc.cats))

    if re.match("^[a-z]\:", imgdir, re.IGNORECASE) is None:  # rel path
        imgdir = os.path.join(os.path.dirname(fn), imgdir)
    if not os.path.isdir(imgdir):
        os.makedirs(imgdir)

    fout = codecs.open(fn, 'w', 'utf-8')
    fout.write(HTML_HEADER % prj.title)
    cat = None
    j = 0
    for doc in docs:
        cats = list(doc.cats)
        if cats and cats[0] != cat:
            cat = cats[0]
            fout.write(u'<h1>%s</h1>\n' % cat)
        if cat is None:
            fout.write(u'<h1>Новости</h1>\n')
        fout.write(u'<h2>%s</h2>\n' % doc.title)
        text = doc.text
        #image patch
        for i, row in enumerate(img_re.findall(text)):
            url, oid = row
            try:
                obj = conn.get(p64(int(oid)))
                data = obj.data.open('r').read()
                if data[1:4] == 'PNG':
                    frmt = 'PNG'
                else:
                    frmt = 'JPG'
                img = QtGui.QImage.fromData(data)
                if img.width() > ww or img.height() > hh:
                    img = img.scaled(ww, hh, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
                if i > 0:
                    imgname = "%s-%i.%s" % (slugify(doc.title), i, frmt.lower())
                else:
                    imgname = "%s.%s" % (slugify(doc.title), frmt.lower())
                egg = "%s/%s" % (imgdir, imgname)
                img.save(egg, frmt)
                text = text.replace(url, egg)
            except POSKeyError:
                log.error('wrong link %s', url)
        fout.write(text)
        fout.write('\n')
        j += 1
        yield j
    fout.write(HTML_FOOTER)
    fout.close()


def writer(parent):
    fn = QtGui.QFileDialog.getSaveFileName(parent, u'Экспорт', QtCore.QString(), u'CMSimple HTML (*.html)')
    if fn.isEmpty():
        return False
    fn = unicode(fn)
    prj = parent.project
    documents = prj.root()['documents']
    pdlg = MyProgressDialog(u'Экспорт', u'Сортировка', u'Отмена', 0, len(documents), parent=parent)
    pdlg.show()
    QtGui.qApp.processEvents()
    try:
        for j in write_cms(prj, fn):
            pdlg.set_text(u'Запись')
            pdlg.setValue(j)
            if j % 100 == 0:
                QtGui.qApp.processEvents()
            if pdlg.wasCanceled():
                raise IOError('Canceled')               
        log.debug('done')
    finally:
        pdlg.close()


if __name__ == '__main__':
    #read
    #fn = ur'd:\work\cm2\test\граблики-w.html'
    #html = open(fn, 'r').read()
    #for item in read_cms(html):
    #    print item['title']

    #write
    root = startup.CONN.root()
    prj = root["projects"][0]
    prj.open()
    for j in write_cms(prj, r'd:\work2014\cm3\_test\1.html'):
        print j,
    prj.close()
