#!/usr/bin/python

from flask import Flask, Response, request, g
from time import time
from lxml import etree as ET
from xml.dom import minidom
from base64 import b64encode, b64decode

import segno, tempfile

app = Flask(__name__, static_url_path='/static')
app.debug = True

@app.before_request
def before_request():
  g.t = time()

@app.after_request
def after_request(response):
  rt = "{:10.4f}".format(time() - g.t)
  print "Runtime %s" % rt
  import os
#  with open("/tmp/output.txt", "w") as text_file:
#    text_file.write("Path: %s\n" % os.getcwd())
#    text_file.write("Path: %s\n" % os.path.realpath(__file__))
#    text_file.write("Path: %s\n" % os.path.join(os.path.dirname(os.path.realpath(__file__)), 'shipping.xslt'))
  response.headers["X-Runtime"] = rt
  return response

@app.route("/spp/<int:mode>/<int:list_id>/<path:ids>")
def spp_availability(mode=0, list_id=0, ids=0):
  from os import system
  from subprocess import call, check_output
  from flask import send_from_directory, make_response, abort
 
  if mode not in [0, 1]:
    abort(400)

  shell = """mysql -u F5VksfQsYW -h 192.168.10.10 -pmWaq9FiGC6\
  --default-character-set=utf8\
  --skip-column-names\
  --raw\
  --execute="CALL spp_spare_parts(%d, '%s', %d)"\
  NESA > /tmp/spp_spare_parts.output
  """ % (list_id, ",".join(str(ids).split("/")), mode)
  system(shell)

  response = send_from_directory('/tmp', filename="spp_spare_parts.output")

  response.headers['Content-Type'] = 'application/xml' if mode==0 else 'application/json'
  return response

@app.route("/pdf/<int:top>/<int:right>/<int:bottom>/<int:left>/<int:orientation>/")
def pdf(top, right, bottom, left, orientation):
  from subprocess import call, check_output
  from shlex import split
  from flask import make_response
  from base64 import b64decode

  url = "https://192.168.200.6/support/spare_parts.jsp"
  title = "Axiomes"
  orientation = 'Landscape' if orientation==0 else 'Portrait'
 
  shell = '/usr/local/bin/./wkhtmltopdf.sh -q --title %s -T %d -L %d -R %d -B %d -O %s -s A4 --print-media-type %s -'
  shell = shell % (title, top, left, right, bottom, orientation, url)
  print shell

  pdf = check_output(split(shell))
  response = make_response(pdf)
  response.headers['Content-Type'] = 'application/pdf'
  response.headers['Content-Disposition'] = 'inline; filename=%s.pdf' % 'spare_parts'
  return response

@app.route("/pdf/addresses/<int:all>")
def addresses(all):
  from subprocess import call, check_output
  from shlex import split
  from flask import make_response
  from os import path

  if request.args.get("all"):
    all = 1 if request.args.get("all")=="true" else 0

  xslt = path.join(path.dirname(path.realpath(__file__)), 'shipping.xslt')

  shell = 'curl -o /tmp/invoices.xml http://192.168.200.6/support/invoices_xml.jsp?all=' + ('true' if all==1 else 'false')
  check_output(split(shell))

  shell = 'xsltproc -o /tmp/addresses.html %s /tmp/invoices.xml' % xslt
  check_output(split(shell))

#  shell = '/usr/local/bin/./wkhtmltopdf.sh -q --title Axiomes -L 0 -R 0 -T 0 -B 0 --print-media-type --page-width 100mm --page-height 35mm /tmp/addresses.html -'
  shell = '/usr/local/bin/./wkhtmltopdf.sh -q --title Axiomes -L 0 -R 0 -T 0 -B 0 --print-media-type --page-width 148mm --page-height 102mm /tmp/addresses.html -'
  print shell

  pdf = check_output(split(shell))
  response = make_response(pdf)
  response.headers['Content-Type'] = 'application/pdf'
  response.headers['Content-Disposition'] = 'inline; filename=%s.pdf' % 'addresses'
  return response

@app.route("/pdf/invoices/<int:all>")
def invoices(all):
  from subprocess import call, check_output
  from shlex import split
  from flask import make_response
  from os import path

  if request.args.get("all"):
    all = 1 if request.args.get("all")=="true" else 0

  xslt = path.join(path.dirname(path.realpath(__file__)), 'invoice.xslt')

  shell = 'curl -o /tmp/invoices.xml http://192.168.200.6/support/invoices_xml.jsp?all=' + ('true' if all==1 else 'false')
  check_output(split(shell))

  with open('/tmp/invoices.xml', 'r+') as f:
    etree = ET.fromstring(f.read())
    xml = qr_invoice(etree)
    xml = ET.tostring(etree, encoding='utf8', method='xml')
    f.seek(0)
    f.write(xml)
    f.truncate()
    xml = minidom.parseString(xml)

  shell = 'xsltproc -o /tmp/invoices.html %s /tmp/invoices.xml' % xslt
  check_output(split(shell))

  shell = '/usr/local/bin/./wkhtmltopdf.sh -q --title Axiomes -L 0 -R 0 -T 0 -B 0 --print-media-type -s A4 /tmp/invoices.html -'
  print shell

  pdf = check_output(split(shell))
  response = make_response(pdf)
  response.headers['Content-Type'] = 'application/pdf'
  response.headers['Content-Disposition'] = 'inline; filename=%s.pdf' % 'invoices'
  return response

def qr_content(invoice):
  alias = dict(de='Rechnung', fr='Facture', it='Fattura', en='Invoice') 
  content = u"""SPC
0200
1
CH133000529741329601K
S
Axiomes Engineering SA
Chemin de l'Orio
30A
1032
Romanel-sur-Lausanne
CH







{}
CHF
K
{}
CH
QRR
{}
{}
EPD"""
  qrr = invoice.xpath('paymentSlip')[0].get('qrr')
  amount = invoice.xpath('paymentSlip')[0].get('amount')
  address_lines = [a.text for a in invoice.xpath('paymentSlip/paidBy/line')]
  payee = []
  payee.append(u'{} {}'.format(address_lines[0] or '', address_lines[1] or ''))
  payee.append(u'{} {}'.format(address_lines[2] or '', address_lines[3] or ''))
  payee.append(address_lines[4])
  payee = [p.strip()[0:70] for p in (payee + ['',''])]

  lang = invoice.get('lang')
  reference = invoice.get('invoiceReference')
  further_info = u'{} {}'.format(alias.get(lang, alias.get('de')), reference)
  qr_content = content.format(amount, '\n'.join(payee[0:5]), qrr, further_info)
  qr_element = ET.Element('qrcode')
  invoice.append(qr_element)

  qr_element.set('information', further_info)
  qr_paid_by = ET.Element('paidBy')
  qr_element.append(qr_paid_by)
  for p in [p for p in payee if len(p) > 0]:
    elem = ET.Element('line')
    elem.text = p
    qr_paid_by.append(elem)
  qr_raw = ET.Element('raw')
  qr_raw.text = qr_content
  qr_element.append(qr_raw)
  qr_b64 = ET.Element('base64')
  qr_b64.text = b64encode(qr_content.encode('utf-8'))
  qr_element.append(qr_b64)

  svg = qr_code_gen(qr_content, correction='m', format='svg', border=0, scale=6) 
  qr_datauri = ET.Element('datauri')
  qr_datauri.text = 'data:image/svg+xml;base64,{}'.format(b64encode(svg.encode('utf-8')))
  qr_element.append(qr_datauri)

def qr_invoice(root):
  invoices = root.xpath('//invoice')
  for invoice in invoices:
    qr_content(invoice)

  return root

@app.route("/pdf/invoice/<int:reference>/")
@app.route("/pdf/invoice/<int:reference>/<int:hide_slip>/")
@app.route("/pdf/invoice/<int:reference>/<int:hide_slip>/<int:source>/")
def invoice(reference, hide_slip=0, source=0):
  from subprocess import call, check_output
  from shlex import split
  from flask import make_response
  from os import path, system

  xslt = path.join(path.dirname(path.realpath(__file__)), 'invoice.xslt')

  shell = """mysql -u F5VksfQsYW -h 192.168.10.10 -pmWaq9FiGC6\
  --default-character-set=utf8\
  --skip-column-names\
  --raw\
  --execute="CALL ord_generate_xml_invoice('%s', %s)"\
  NESA > /tmp/invoice_%d.xml
  """ % (reference, 'TRUE' if hide_slip==1 else 'FALSE', reference)
  system(shell)

  with open('/tmp/invoice_{}.xml'.format(reference), 'r+') as f:
    etree = ET.fromstring(f.read())
    xml = qr_invoice(etree)
    xml = ET.tostring(etree, encoding='utf8', method='xml')
    f.seek(0)
    f.write(xml)
    f.truncate()
    xml = minidom.parseString(xml)

  shell = 'xsltproc -o /tmp/invoice_%d.html %s /tmp/invoice_%d.xml' % (reference, xslt, reference)
  check_output(split(shell))

  if source==1:
    with open('/tmp/invoice_%d.html' % reference, 'rb') as f:
      html = f.read()
      
    response = make_response(html)
    response.headers['Content-Type'] = 'text/html'
    return response

  shell = '/usr/local/bin/./wkhtmltopdf.sh -q --title Axiomes -L 0 -R 0 -T 0 -B 0 --print-media-type -s A4 /tmp/invoice_%d.html -' % reference
  print shell

  pdf = check_output(split(shell))

  shell = 'rm /tmp/invoice_%d.html /tmp/invoice_%d.xml' % (reference, reference)
  system(shell)

  response = make_response(pdf)
  response.headers['Content-Type'] = 'application/pdf'
  response.headers['Content-Disposition'] = 'inline; filename=%s_%d.pdf' % ('Invoice', reference)
  return response

def qr_code_gen(code, correction='m', format='png', border=0, scale=1):
  qrcode = segno.make(code, micro=False, error=correction)
  with tempfile.NamedTemporaryFile(suffix='.' + format.lower()) as f:
    qrcode.save(f.name, border=border, scale=scale)
    binary = f.read()
    f.close()
  return binary

@app.route("/pdf/qr/<string:correction>/<string:format>/<int:border>/<int:scale>/<string:code>/")
def qr_code(code, correction, format, border, scale):
  try:
    code = b64decode(code)
  except:
    pass

  binary = qr_code_gen(code, correction, format.lower(), border, scale)
  mime_types = dict(png='image/png', svg='image/svg+xml')
  return Response(binary, mimetype=mime_types.get(format, 'image/png'))


if __name__ == "__main__":
  app.run(host='0.0.0.0', port=7000, debug=True, threaded=True)
