|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- # -*- coding: utf8 -*-
- from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden
- from pyramid.response import Response
-
- try:
- from StringIO import StringIO
- except ImportError:
- from io import StringIO
- import io
- from pyramid.view import view_config
- from .models import DBSession, User
- from reportlab.pdfgen import canvas
- from reportlab.pdfbase import pdfmetrics
- from reportlab.pdfbase.ttfonts import TTFont
- from reportlab.lib.units import mm
- import qrcode
- import subprocess
- from .upload import MediaPath
- from jm2l.const import CurrentYear
-
- # Create PDF container
- EXPIRATION_TIME = 300 # seconds
- WIDTH = 85 * mm
- HEIGHT = 60 * mm
- ICONSIZE = 10 * mm
-
-
- def JM2L_Logo(canvas, Offset=(0, 0)):
- off_x, off_y = Offset
- logo_object = canvas.beginText()
- logo_object.setFont('Logo', 32)
- logo_object.setFillColorRGB(.83, 0, .33)
- logo_object.setTextOrigin(off_x + 5, off_y + 17)
- logo_object.textLines("JM2L")
- canvas.drawText(logo_object)
-
- year_object = canvas.beginText()
- year_object.setFont("Helvetica-Bold", 10)
- year_object.setFillColorRGB(1, 1, 1)
- year_object.setTextRenderMode(0)
- year_object.setTextOrigin(off_x + 12, off_y + 35)
- year_object.setWordSpace(13)
- year_object.textLines(" ".join(str(CurrentYear)))
- canvas.drawText(year_object)
-
-
- def Tiers_Logo(canvas, DispUser, start_pos=None, Offset=(0, 0)):
- border = 0
- off_x, off_y = Offset
- if start_pos is None:
- start_pos = (30 * mm, 2)
- start_x, start_y = start_pos
- max_x, max_y = 34 * mm, 18 * mm
- num = 0
- canvas.setStrokeColorRGB(0.5, 0.5, 0.5)
- list_logos = list()
- for thumb in DispUser.tiers:
- if thumb.ThumbLinks:
- list_logos.append(thumb.ThumbLinks[:3])
- # list_logos = list(filter(lambda x: x.ThumbLinks, DispUser.tiers)[:3])
- # Should We compute a better positionning for logos ?
- DicPos = {}
- DicPos[1] = {0: (1. / 2, 1. / 2)}
- DicPos[2] = {0: (1. / 3, 1. / 2), 1: (2. / 3, 1. / 2)}
- DicPos[3] = {0: (1. / 2, 1. / 4), 1: (1. / 3, 3. / 4), 2: (2. / 3, 3. / 4)}
- DicPos[4] = {0: (1. / 3, 1. / 4), 1: (2. / 3, 1. / 4), 2: (1. / 3, 3. / 4),
- 3: (2. / 3, 3. / 4)}
- DicPos[5] = {0: (1. / 3, 1. / 4), 1: (2. / 3, 1. / 4), 2: (1. / 6, 3. / 4),
- 3: (3. / 6, 3. / 4), 4: (5. / 6, 3. / 4)}
- DicPos[6] = {0: (1. / 6, 1. / 4), 1: (3. / 6, 1. / 4), 2: (5. / 6, 1. / 4),
- 3: (1. / 6, 3. / 4), 4: (3. / 6, 3. / 4), 5: (5. / 6, 3. / 4)}
- DicPos[7] = {0: (1. / 6, 1. / 4), 1: (3. / 6, 1. / 4), 2: (5. / 6, 1. / 4),
- 3: (1. / 8, 3. / 4), 4: (3. / 8, 3. / 4), 5: (5. / 8, 3. / 4),
- 6: (7. / 8, 3. / 4)}
- DicPos[8] = {0: (1. / 8, 1. / 4), 1: (3. / 8, 1. / 4), 2: (5. / 8, 1. / 4),
- 3: (7. / 8, 1. / 4), 4: (1. / 8, 3. / 4), 5: (3. / 8, 3. / 4),
- 6: (5. / 8, 3. / 4), 7: (7. / 8, 3. / 4)}
- # draw overall border
- # canvas.roundRect(start_x, start_y, max_x, max_y, radius=2, stroke=True)
- for tiers in list_logos:
- file_name = tiers.ThumbLinks.pop().split("/")[-1]
- image_path = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, file_name)
- pos_x = off_x + start_x + DicPos[len(list_logos)][num][0] * max_x - (ICONSIZE + border) / 2
- pos_y = off_y + start_y + DicPos[len(list_logos)][num][1] * max_y - (ICONSIZE + border) / 2
- canvas.setLineWidth(.1)
- if len(list_logos) > 1:
- size = ICONSIZE
- else:
- size = ICONSIZE * 1.5
- canvas.drawImage(image_path,
- pos_x, pos_y, size, size,
- preserveAspectRatio=True,
- anchor='c',
- mask='auto'
- )
- # draw icon border
- # canvas.roundRect(pos_x, pos_y, ICONSIZE, ICONSIZE, radius=2, stroke=True)
- num += 1
-
-
- def QRCode(DispUser):
- qr = qrcode.QRCode(
- version=1,
- error_correction=qrcode.constants.ERROR_CORRECT_L,
- box_size=10,
- border=2,
- )
- # Data of QR code
- qr.add_data('http://jm2l.linux-azur.org/user/%s' % DispUser.slug)
- qr.make(fit=True)
-
- return qr.make_image()
-
-
- def one_badge(c, DispUser, Offset=(0, 0)):
- # Logo on Top
- JM2L_Logo(c, Offset)
- off_x, off_y = Offset
-
- c.rect(off_x - 3, off_y - 3, WIDTH + 6, HEIGHT + 6, fill=0, stroke=1)
- if DispUser.Staff:
- # Staff
- c.setFillColorRGB(.83, 0, .33)
- c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
- c.setFillColorRGB(1, 1, 1)
- c.setFont('Liberation', 30)
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "STAFF")
- elif DispUser.is_Intervenant:
- # Intervenant
- c.setFillColorRGB(.21, .67, .78)
- c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
- c.setFillColorRGB(1, 1, 1)
- c.setFont('Liberation', 30)
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Intervenant")
- elif DispUser.is_crew:
- # Benevole
- c.setFillColorRGB(.18, .76, .23)
- c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
- c.setFillColorRGB(1, 1, 1)
- c.setFont('Liberation', 30)
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Bénévole")
- else:
- # Visiteur
- c.setFillColorRGB(.8, .8, .8)
- c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
- c.setFillColorRGB(1, 1, 1)
- c.setFont('Liberation', 30)
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Visiteur")
-
- c.restoreState()
-
- c.setFont('Liberation', 18)
- c.setStrokeColorRGB(0, 0, 0)
- c.setFillColorRGB(0, 0, 0)
- # Feed Name and SurName
- if DispUser.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom) > 18:
- if DispUser.pseudo:
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s" % DispUser.prenom)
- # c.setFont('Courier', 17)
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
- else:
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 4 * mm, "%s" % DispUser.prenom)
- # c.setFont('Courier', 17)
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
- else:
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s %s" % (DispUser.prenom, DispUser.nom))
-
- if DispUser.pseudo:
- c.setFont("Helvetica-Oblique", 18)
- c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 10 * mm, "%s" % DispUser.pseudo)
-
- # Put QR code to user profile
- c.drawInlineImage(QRCode(DispUser),
- off_x + WIDTH - 20 * mm - 5, off_y + 5,
- 20 * mm, 20 * mm,
- preserveAspectRatio=True,
- anchor='s')
-
- Tiers_Logo(c, DispUser, None, Offset)
-
-
- @view_config(route_name='badge_user') # , http_cache=(EXPIRATION_TIME, {'public': True}))
- def badge_user(request):
- isoutpng = request.params.get('png')
- user_slug = request.matchdict.get('user_slug', None)
- if user_slug is None or len(user_slug) == 0:
- raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu")
- # Query database
- DispUser = User.by_slug(user_slug)
- if DispUser is None:
- raise HTTPNotFound()
-
- # Ok let's generate a PDF Badge
-
- # Register LiberationMono font
- ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
- pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
- # Import font
- ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
- pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
-
- pdf = io.BytesIO()
- out_img = io.BytesIO()
-
- c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT))
- c.translate(mm, mm)
-
- # Feed some metadata
- c.setCreator("linux-azur.org")
- c.setTitle("Badge")
-
- c.saveState()
-
- one_badge(c, DispUser)
- out_pdf = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf')
- c.showPage()
- c.save()
- pdf.seek(0)
- if isoutpng:
- out_png = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
- # Let's generate a png file for website
- with open("./%s" % out_pdf, 'wb') as pdff:
- pdff.write(pdf.read())
-
- Command = ["convert", "-density", "150x150", out_pdf, out_png]
- subprocess.call(Command)
-
- with open("./%s" % out_png, 'rb') as pngfile:
- out_img.write(pngfile.read()) # pngfile.read(), "utf8"))
-
- out_img.seek(0)
- return Response(app_iter=out_img, content_type='image/png')
- else:
- return Response(app_iter=pdf, content_type='application/pdf')
-
-
- @view_config(route_name='all_badges')
- def planche_badge(request):
- if request.user is None:
- # Don't answer to users that aren't logged
- raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
- # Query database about selected Year.
- Users = DBSession.query(User)
- # .join(User_Event)\
- # .filter(User_Event.year_uid == year)
-
- # Register LiberationMono font
- ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
- pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
- # Import font
- ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
- pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
-
- pdf = io.BytesIO()
-
- FULLWIDTH = 210 * mm
- FULLHEIGHT = 297 * mm
-
- c = canvas.Canvas(pdf, pagesize=(FULLWIDTH, FULLHEIGHT))
- c.translate(mm, mm)
-
- # Feed some metadata
- c.setCreator("linux-azur.org")
- c.setTitle("Badge")
- t = 0
- list_user = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users)
- for num, disp_user in enumerate(list_user):
- c.saveState()
- offsets = (((num - t) % 2) * (WIDTH + 40) + 40, int(((num - t) / 2)) * (HEIGHT + 25) + 40)
- one_badge(c, disp_user, offsets)
- if num % 8 == 7:
- t = num + 1
- c.showPage()
-
- c.showPage()
- c.save()
- pdf.seek(0)
- return Response(app_iter=pdf, content_type='application/pdf')
|