def convertImage(self, node): getAttr = node.getAttribute x, y, width, height = map(getAttr, ('x', 'y', "width", "height")) x, y, width, height = map(self.attrConverter.convertLength, (x, y, width, height)) xlink_href = node.attrib.get('{http://www.w3.org/1999/xlink}href') magic_re = r"^data:image/(jpeg|png);base64" match = re.match(magic_re, xlink_href) if match: img_format = match.groups()[0] image_data = base64.decodestring(xlink_href[(match.span(0)[1] + 1):].encode('ascii')) _, path = tempfile.mkstemp(suffix='.%s' % img_format) with open(path, 'wb') as fh: fh.write(image_data) img = Image(int(x), int(y + height), int(width), int(height), path) # this needs to be removed later, not here... # if exists(path): os.remove(path) else: xlink_href = os.path.join(os.path.dirname(self.svg_source_file), xlink_href) img = Image(int(x), int(y + height), int(width), int(height), xlink_href) try: # this will catch invalid image PDFImage(xlink_href, 0, 0) except IOError: logger.error("Unable to read the image %s. Skipping..." % img.path) return None group = Group(img) group.translate(0, (x + height) * 2) group.scale(1, -1) return group
def convertImage(self, node): logger.warn("Adding box instead of image.") getAttr = node.getAttribute x, y, width, height = map(getAttr, ('x', 'y', "width", "height")) x, y, width, height = map(self.attrConverter.convertLength, (x, y, width, height)) xlink_href = node.attrib.get('{http://www.w3.org/1999/xlink}href') magic = "data:image/jpeg;base64" if xlink_href[:len(magic)] == magic: pat = "data:image/(\w+?);base64" ext = re.match(pat, magic).groups()[0] jpeg_data = base64.decodestring( xlink_href[len(magic):].encode('ascii')) _, path = tempfile.mkstemp(suffix='.%s' % ext) with open(path, 'wb') as fh: fh.write(jpeg_data) img = Image(int(x), int(y + height), int(width), int(-height), path) # this needs to be removed later, not here... # if exists(path): os.remove(path) else: xlink_href = os.path.join(os.path.dirname(self.svg_source_file), xlink_href) img = Image(int(x), int(y + height), int(width), int(-height), xlink_href) try: # this will catch invalid image PDFImage(xlink_href, 0, 0) except IOError: logger.error("Unable to read the image %s. Skipping..." % img.path) return None return img
def convertImage(self, node): getAttr = node.getAttribute x, y, width, height = map(getAttr, ('x', 'y', "width", "height")) x, y, width, height = map(self.attrConverter.convertLength, (x, y, width, height)) xlink_href = node.getAttributeNS('http://www.w3.org/1999/xlink', 'href') embedded = self.embedded_image_magic_re.match(xlink_href) if embedded: ext = embedded.groups()[0] data = base64.decodestring( xlink_href[len(embedded.group(0)):].encode('ascii')) _, path = tempfile.mkstemp(suffix='.%s' % ext) with open(path, 'wb') as fh: fh.write(data) img = Image(int(x), int(y + height), int(width), int(-height), path) # this needs to be removed later, not here... # if exists(path): os.remove(path) else: xlink_href = os.path.join(os.path.dirname(self.svg_source_file), xlink_href) img = Image(int(x), int(y + height), int(width), int(-height), xlink_href) try: # this will catch invalid image PDFImage(xlink_href, 0, 0) except IOError: logger.error("Unable to read the image %s. Skipping..." % img.path) return None return img
def fyll(self): # , firma, faktura): "Fyller fakturaen med data" # firma.sjekkData() # sjekker at ndvendig firmainfo er fylt ut # pdf-metadata self.canvas.setSubject("Faktura #%s til kunde #%s" % (self.faktura['nr'], self.kunde['nr'])) self.canvas.setTitle( "Elektronisk faktura fra %s, utstedt den %s" % (self.firma['firmanavn'], self.faktura['utstedt'])) logoForskyvning = 0 if self.firma['logo']: logging.debug("Har logo!") try: import Image except ImportError: logging.warn( 'Kunne ikke importere PIL. Du kan få problemer hvis logoen ikke er i JPEG' ) logo = self.firma[ 'logo'] # la reportlab ta seg av det, kanskje det går self.canvas.drawImage(logo, 10 * mm, 267 * mm, width=25 * mm, height=25 * mm) else: # PDFImage kan laste JPEG-data (i en str(), altså), et filnavn eller et PIL-objekt # De to siste tilfellene krever at PIL er installert logging.debug(len(self.firma['logo'])) try: # sjekk om det er et filnavn # forutsetter at PATH_MAX=4096, sannsynligvis har ingen systemer har satt den større enfil = len(self.firma['logo']) < 4096 and os.path.exists( self.firma['logo']) except: # path.exists snubler på binær data enfil = False if enfil: # det er et filnavn, last det direkte l = self.firma['logo'] else: l = StringIO.StringIO(self.firma['logo']) self._logo = Image.open(l) logo = PDFImage(self._logo, 10 * mm, 267 * mm, width=25 * mm, height=25 * mm) logo.drawInlineImage(self.canvas, preserveAspectRatio=True) logoForskyvning = 30 # firmanavn: overskrift firmanavn = self.canvas.beginText() firmanavn.setTextOrigin((15 + logoForskyvning) * mm, 270 * mm) # skyv til høyre dersom logo firmanavn.setFont("Helvetica-Bold", 16) firmanavn.textLine(self.firma['firmanavn']) self.canvas.drawText(firmanavn) # firmainfo: oppe til høyre i liten skrift firmainfo = self.canvas.beginText() firmainfo.setTextOrigin(160 * mm, 290 * mm) firmainfo.setFont("Helvetica", 8) firmainfo.setFillGray(0.3) # for z,y in self.firma.iteritems(): # logging.debug("%s (%s): %s" % (z, type(y), y)) print(type(self.firma['kontonummer'])) firmainfo.textLines(("""%(kontaktperson)s %(adresse)s %(postnummer)04i %(poststed)s Telefon: %(telefon)s Bankkonto: %(kontonummer)011i Org.nr: %(organisasjonsnummer)s E-post: %(epost)s""" % self.firma).split('\n')) self.canvas.drawText(firmainfo) self.canvas.line(5 * mm, 265 * mm, 205 * mm, 265 * mm) self.canvas.setFont("Helvetica", 10) # informasjon om kunden kunde = self.canvas.beginText() kunde.setFillGray(0.0) kunde.setTextOrigin(20 * mm, 260 * mm) kunde.textLines( ("Kunde# %03i\n%s" % (self.kunde['nr'], self.kunde['adresse'])).split('\n')) self.canvas.drawText(kunde) # detaljer om fakturaen # FIXME: løpe over flere sider sidenr = 1 totalsider = 1 fakturafakta = self.canvas.beginText() fakturafakta.setTextOrigin(150 * mm, 260 * mm) fakturafakta.textLines(( """FAKTURA Fakturanr: %04i Leveringsdato: %s Fakturadato: %s Forfallsdato: %s Side: %i av %i """ % ( self.faktura['nr'], self.faktura['levert'], self.faktura['utstedt'], self.faktura['forfall'], sidenr, # FIXME: løpe over flere sider totalsider)).split('\n')) self.canvas.drawText(fakturafakta) fakturatekst = self.canvas.beginText() fakturatekst.setTextOrigin(20 * mm, 230 * mm) fakturatekst.textLines(self.paragraf(self.faktura['tekst'], 100)) fakturatekstNedreY = int(fakturatekst.getY() / mm) # logging.debug("fakturateksten strekker seg ned til Y: %i mm (%i PDF pt)" % (fakturatekstNedreY/mm, fakturatekstNedreY)) # if fakturatekstNedreY > sikkerhetsgrense: tekst = self.kutt(faktura.tekst) ... self.canvas.drawText(fakturatekst) regnestykkeY = 215 if fakturatekstNedreY < regnestykkeY: regnestykkeY = fakturatekstNedreY - 10 self.canvas.drawString(20 * mm, regnestykkeY * mm, "Beskrivelse") self.canvas.drawRightString(140 * mm, regnestykkeY * mm, "Pris") self.canvas.drawRightString(160 * mm, regnestykkeY * mm, "Mva") self.canvas.drawRightString(180 * mm, regnestykkeY * mm, "SUM") self.canvas.setDash(1, 0) self.canvas.setLineWidth(0.2 * mm) self.canvas.line(15 * mm, (regnestykkeY - 2) * mm, 195 * mm, (regnestykkeY - 2) * mm) self.canvas.setFont("Helvetica", 8) tekstX = 20 * mm Y = (regnestykkeY - 10) * mm bruttoX = 140 * mm mvaX = 160 * mm prisX = 180 * mm totalBelop = 0 totalMva = 0 totalBrutto = 0 mvagrunnlag = {} # Holder en oppsummering av salg per mva-sats if type(self.ordrelinje) in (types.FunctionType, types.MethodType): for vare in self.ordrelinje(): # regn ut alt som skal regnes brutto = vare.kvantum * vare.enhetspris mva = brutto * vare.mva / 100 pris = brutto + mva totalBrutto += brutto totalMva += mva totalBelop += pris if not vare.mva in mvagrunnlag.keys( ): # legg til i oppsummeringen av salg mvagrunnlag[vare.mva] = [] mvagrunnlag[vare.mva] += [ brutto, ] self.canvas.drawString(tekstX, Y, self._s(vare.detaljertBeskrivelse())) self.canvas.drawRightString(bruttoX, Y, self._kr(brutto)) self.canvas.drawRightString(mvaX, Y, self._kr(mva)) self.canvas.drawRightString(prisX, Y, self._kr(pris)) Y -= 3 * mm elif type(self.ordrelinje) is list: for vare in self.ordrelinje: # [tekst, kvantum, enhetspris, mva] # regn ut alt som skal regnes brutto = vare[1] * vare[2] mva = brutto * vare[3] / 100 pris = brutto + mva totalBrutto += brutto totalMva += mva totalBelop += pris if not vare[3] in mvagrunnlag.keys( ): # legg til i oppsummeringen av salg mvagrunnlag[vare[3]] = [] mvagrunnlag[vare[3]] += [ brutto, ] self.canvas.drawString( tekstX, Y, "%s %s a kr %s" % (vare[1], vare[0], vare[2])) self.canvas.drawRightString(bruttoX, Y, self._kr(brutto)) self.canvas.drawRightString(mvaX, Y, self._kr(mva)) self.canvas.drawRightString(prisX, Y, self._kr(pris)) Y -= 3 * mm # logging.debug("Nå har vi kommet til Y: %i (%i)" % (Y/mm, Y)) # if Y < 140*mm: self.lagNySide() # vi har lagt inn for mange varer til at vi får plass på en side # FIXME: løpe over flere sider sumY = 141 * mm self.canvas.line(90 * mm, sumY, 190 * mm, sumY) # sum mvagrunnlag logging.debug("mvagrunnlag: %s", mvagrunnlag) mvaY = 150 * mm mvaX = 5 * mm self.canvas.drawString(mvaX, mvaY + 4 * mm, "MVA-grunnlag:") self.canvas.setFont("Helvetica", 7) for i, _mva in enumerate(mvagrunnlag.keys()): linjesum = sum(map(float, mvagrunnlag[_mva])) self.canvas.drawString( mvaX, mvaY - (i * 3 * mm), "%.1f%% av %s = %s" % (_mva, self._kr(linjesum), self._kr(linjesum * _mva / 100))) # legg sammen totalen self.canvas.setFont("Helvetica", 8) self.canvas.drawRightString(prisX - 70 * mm, sumY - 7 * mm, "Netto: %s" % self._kr(totalBrutto)) self.canvas.drawRightString(prisX - 40 * mm, sumY - 7 * mm, "MVA: %s" % self._kr(totalMva)) self.canvas.setFont("Helvetica-Bold", 10) self.canvas.drawRightString(prisX, sumY - 7 * mm, "TOTALT: %s" % self._kr(totalBelop)) # standard betalingsvilkår if len(self.faktura['vilkaar'] ): ## FIXME: krype oppover hvis teksten er mer enn en linje høy self.canvas.setFont("Helvetica", 10) vilkar = self.canvas.beginText() vilkar.setTextOrigin(9 * mm, 124 * mm) vilkar.textLines(self.paragraf(self.faktura['vilkaar'], 120)) self.canvas.drawText(vilkar) # Nederste del av skjemaet # den gule betalingsslippen # skal skrives i courier 10 (se issue#38) self.canvas.setFont("Courier", 10) self.canvas.drawString(20 * mm, 105 * mm, "%011i" % self.firma['kontonummer']) self.canvas.drawString(88 * mm, 105 * mm, self._kr(totalBelop)) # betalingsfrist self.canvas.drawString(170 * mm, 95 * mm, self.faktura['forfall']) # fakturainformasjon t = self.canvas.beginText() t.setTextOrigin(15 * mm, 90 * mm) t.textLines("Fakturanr: %05i\nKundenr: %04i\nFakturadato: %s" % \ (self.faktura['nr'], self.kunde['nr'], self.faktura['utstedt'])) self.canvas.drawText(t) adresseboksY = 58 * mm # øverste punkt i adressefelter # mottakerfelt kundeinfo = self.canvas.beginText() ki = self.kunde['adresse'].split('\n') kiY = adresseboksY + (3 * mm * int(len(ki) > 4)) kundeinfo.setTextOrigin(15 * mm, kiY) kundeinfo.textLines(ki) self.canvas.drawText(kundeinfo) # avsenderfelt firmaadresse = self.canvas.beginText() fa = ( "%(firmanavn)s\n%(kontaktperson)s\n%(adresse)s\n%(postnummer)04i %(poststed)s" % (self.firma)).split('\n') faY = adresseboksY + (3 * mm * int(len(fa) > 4)) firmaadresse.setTextOrigin(115 * mm, faY) firmaadresse.textLines(fa) self.canvas.drawText(firmaadresse) # Blankettens underkant # (se http://sourceforge.net/p/finfaktura/tickets/38/, punkt A) underkant = 5.0 / 6.0 * inch # Den fortrykte H -- innstillingsmerke # (se http://sourceforge.net/p/finfaktura/tickets/38/) self.canvas.drawString(2 * mm, underkant, 'H') # KID if self.faktura['kid'] and self.sjekkKid(self.faktura['kid']): self.canvas.drawRightString(72 * mm, underkant, str(self.faktura['kid'])) else: logging.warn('Ugyldig kid, hopper over: %s', self.faktura['kid']) # SUM kr = int(totalBelop) ore = int((totalBelop - kr) * 100) self.canvas.drawString(90 * mm, underkant, str(kr)) self.canvas.drawString(108 * mm, underkant, "%02d" % ore) self.canvas.drawString(135 * mm, underkant, "%011i" % self.firma['kontonummer']) # KONTROLLSIFFER FOR SUM # BBS' brukerhåndbok sier at kontrollsiffer skal utregnes for 'beløp' # tolker 'beløp' som kr+ore.. er dette korrekt? # Håndboka sier også at mod10 skal brukes, testing viser at mange # fakturaer som er i omløp bruker mod11 siffer = self.lagKontrollsifferMod10("%d%02d" % (kr, ore)) self.canvas.drawString(120 * mm, underkant, siffer)
def xlink_href_target(self, node, group=None): """ Return either: - the node targetted by the xlink:href attribute for vector targets - the path to an image file for any raster image targets - None if any problem occurs """ xlink_href = node.attrib.get('{http://www.w3.org/1999/xlink}href') if not xlink_href: return None # First handle any raster embedded image data match = re.match(r"^data:image/(jpeg|png);base64", xlink_href) if match: img_format = match.groups()[0] image_data = base64.decodestring(xlink_href[(match.span(0)[1] + 1):].encode('ascii')) _, path = tempfile.mkstemp(suffix='.%s' % img_format) with open(path, 'wb') as fh: fh.write(image_data) # this needs to be removed later, not here... # if exists(path): os.remove(path) return path # From here, we can assume this is a path. if '#' in xlink_href: iri, fragment = xlink_href.split('#', 1) else: iri, fragment = xlink_href, None if iri: # Only local relative paths are supported yet if not isinstance(self.source_path, str): logger.error( "Unable to resolve image path '%s' as the SVG source is not a file system path." % iri) return None path = os.path.join(os.path.dirname(self.source_path), iri) if not os.access(path, os.R_OK): return None if path == self.source_path: # Self-referencing, ignore the IRI part iri = None if iri: if path.endswith('.svg'): if path not in self._external_svgs: self._external_svgs[path] = load_svg_file(path) svg_node = self._external_svgs[path] if svg_node is not None: return NodeTracker(svg_node) else: # A raster image path try: # This will catch invalid images PDFImage(path, 0, 0) except IOError: logger.error("Unable to read the image %s. Skipping..." % path) return None elif fragment: # A pointer to an internal definition if fragment in self.definitions: return self.definitions[fragment] else: # The missing definition should appear later in the file self.waiting_use_nodes[fragment].append((node, group)) return DELAYED