Fixing python3 issues

This commit is contained in:
2020-08-08 17:02:12 +02:00
parent 588ce76eee
commit 2b3e8116d5
10 changed files with 304 additions and 283 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ If no error occurs, the webserver should be available on http://localhost:8080/
Enjoy ! Enjoy !
sudo apt install virtualenv git python3-virtualenv sudo apt install virtualenv git python3-virtualenv imagemagick
sudo mkdir -p /srv/jm2l sudo mkdir -p /srv/jm2l
cd /srv/jm2l/ cd /srv/jm2l/
-1
View File
@@ -15,7 +15,6 @@ pyramid.debug_notfound = false
pyramid.debug_routematch = false pyramid.debug_routematch = false
pyramid.default_locale_name = en pyramid.default_locale_name = en
pyramid.includes = pyramid.includes =
pyramid_mailer.testing
pyramid_debugtoolbar pyramid_debugtoolbar
pyramid_tm pyramid_tm
pyramid_mako pyramid_mako
+16 -13
View File
@@ -30,31 +30,31 @@ def add_renderer_globals(event):
event['CurrentYear'] = CurrentYear event['CurrentYear'] = CurrentYear
# @sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=07) # @sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=7)
def mailer_tasks(config): def mailer_tasks(config):
# Send the Welcome Mail # Send the Welcome Mail
mailer = config.registry['mailer'] mailer = config.registry['mailer']
Contact = DBSession.query(User).filter(User.uid == 1).one() contact = DBSession.query(User).filter(User.uid == 1).one()
request = Request.blank('/', base_url='http://jm2l.linux-azur.org') request = Request.blank('/', base_url='http://jm2l.linux-azur.org')
request.registry = config.registry request.registry = config.registry
for StaffUser in DBSession.query(User).filter(User.Staff == True): for staff_user in DBSession.query(User).filter(User.Staff is True):
# Skip mail to contact # Skip mail to contact
if StaffUser == Contact: if staff_user == contact:
continue continue
# Skip those that have no task assigned # Skip those that have no task assigned
if len(filter(lambda k: not k.closed, StaffUser.task_assoc)) == 0: if len(filter(lambda k: not k.closed, staff_user.task_assoc)) == 0:
continue continue
# Prepare Plain Text Message : # Prepare Plain Text Message :
Mail_template = Template(filename='jm2l/templates/mail_plain.mako') mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = Mail_template.render(request=request, User=StaffUser, Contact=Contact, action="Tasks") mail_plain = mail_template.render(request=request, User=staff_user, Contact=contact, action="Tasks")
# Prepare HTML Message : # Prepare HTML Message :
Mail_template = Template(filename='jm2l/templates/mail_html.mako') mail_template = Template(filename='jm2l/templates/mail_html.mako')
mail_html = Mail_template.render(request=request, User=StaffUser, Contact=Contact, action="Tasks") mail_html = mail_template.render(request=request, User=staff_user, Contact=contact, action="Tasks")
# Prepare Message # Prepare Message
message = Message(subject="[JM2L] Le mail de rappel pour les JM2L !", message = Message(subject="[JM2L] Le mail de rappel pour les JM2L !",
sender="contact@jm2l.linux-azur.org", sender="contact@jm2l.linux-azur.org",
recipients=[StaffUser.mail], recipients=[staff_user.mail],
body=mail_plain, html=mail_html) body=mail_plain, html=mail_html)
message.add_bcc("spam@style-python.fr") message.add_bcc("spam@style-python.fr")
@@ -81,8 +81,11 @@ def main(global_config, **settings):
authentication_policy=authentication_policy, authentication_policy=authentication_policy,
authorization_policy=authorization_policy authorization_policy=authorization_policy
) )
#config.include('pyramid_mailer')
config.include('pyramid_mailer.debug')
config.add_subscriber(add_renderer_globals, BeforeRender) config.add_subscriber(add_renderer_globals, BeforeRender)
config.registry['mailer'] = mailer_factory_from_settings(settings) print(settings)
# config.registry['mailer'] = mailer_factory_from_settings(settings)
config.registry['event_date'] = JM2L_Year.get_latest_jm2l_startdate() config.registry['event_date'] = JM2L_Year.get_latest_jm2l_startdate()
sched = BackgroundScheduler() sched = BackgroundScheduler()
sched.add_job(mailer_tasks, 'cron', day_of_week='fri', hour=18, args=[config]) sched.add_job(mailer_tasks, 'cron', day_of_week='fri', hour=18, args=[config])
@@ -154,7 +157,7 @@ def main(global_config, **settings):
config.add_route('edit_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}') config.add_route('edit_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}')
config.add_route('delete_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete') config.add_route('delete_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete')
## Entities # Entities
config.add_route('entities', '/entities') # {sep:/*}{Nature:\w+?}') config.add_route('entities', '/entities') # {sep:/*}{Nature:\w+?}')
config.add_route('add_entity', '/entity') config.add_route('add_entity', '/entity')
config.add_route('delete_entity', r'/entity/{entity_id:(\d+)}/delete') config.add_route('delete_entity', r'/entity/{entity_id:(\d+)}/delete')
@@ -162,7 +165,7 @@ def main(global_config, **settings):
config.add_route('edit_entity', r'/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)}/edit') config.add_route('edit_entity', r'/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)}/edit')
config.add_route('edit_entity_cat', '/categorie/entity') config.add_route('edit_entity_cat', '/categorie/entity')
## Users # Users
config.add_route('pict_user', '/user_picture') config.add_route('pict_user', '/user_picture')
config.add_route('show_user', r'/user/{user_slug:([\w-]+)?}') config.add_route('show_user', r'/user/{user_slug:([\w-]+)?}')
config.add_route('badge_user', r'/user/{user_slug:([\w-]+)?}/badge') config.add_route('badge_user', r'/user/{user_slug:([\w-]+)?}/badge')
+78 -79
View File
@@ -6,6 +6,7 @@ try:
from StringIO import StringIO from StringIO import StringIO
except ImportError: except ImportError:
from io import StringIO from io import StringIO
import io
from pyramid.view import view_config from pyramid.view import view_config
from .models import DBSession, User from .models import DBSession, User
from reportlab.pdfgen import canvas from reportlab.pdfgen import canvas
@@ -25,38 +26,38 @@ ICONSIZE = 10 * mm
def JM2L_Logo(canvas, Offset=(0, 0)): def JM2L_Logo(canvas, Offset=(0, 0)):
OffX, OffY = Offset off_x, off_y = Offset
logoobject = canvas.beginText() logo_object = canvas.beginText()
logoobject.setFont('Logo', 32) logo_object.setFont('Logo', 32)
logoobject.setFillColorRGB(.83, 0, .33) logo_object.setFillColorRGB(.83, 0, .33)
logoobject.setTextOrigin(OffX + 5, OffY + 17) logo_object.setTextOrigin(off_x + 5, off_y + 17)
logoobject.textLines("JM2L") logo_object.textLines("JM2L")
canvas.drawText(logoobject) canvas.drawText(logo_object)
yearobject = canvas.beginText() year_object = canvas.beginText()
yearobject.setFont("Helvetica-Bold", 10) year_object.setFont("Helvetica-Bold", 10)
yearobject.setFillColorRGB(1, 1, 1) year_object.setFillColorRGB(1, 1, 1)
yearobject.setTextRenderMode(0) year_object.setTextRenderMode(0)
yearobject.setTextOrigin(OffX + 12, OffY + 35) year_object.setTextOrigin(off_x + 12, off_y + 35)
yearobject.setWordSpace(13) year_object.setWordSpace(13)
yearobject.textLines(" ".join(str(CurrentYear))) year_object.textLines(" ".join(str(CurrentYear)))
canvas.drawText(yearobject) canvas.drawText(year_object)
def Tiers_Logo(canvas, DispUser, StartPos=None, Offset=(0, 0)): def Tiers_Logo(canvas, DispUser, start_pos=None, Offset=(0, 0)):
Border = 0 border = 0
OffX, OffY = Offset off_x, off_y = Offset
if StartPos is None: if start_pos is None:
StartPos = (30 * mm, 2) start_pos = (30 * mm, 2)
StartX, StartY = StartPos start_x, start_y = start_pos
MaxX, MaxY = 34 * mm, 18 * mm max_x, max_y = 34 * mm, 18 * mm
num = 0 num = 0
canvas.setStrokeColorRGB(0.5, 0.5, 0.5) canvas.setStrokeColorRGB(0.5, 0.5, 0.5)
Logos = list() list_logos = list()
for thumb in DispUser.tiers: for thumb in DispUser.tiers:
if thumb.ThumbLinks: if thumb.ThumbLinks:
Logos.append(thumb.ThumbLinks[:3]) list_logos.append(thumb.ThumbLinks[:3])
# Logos = list(filter(lambda x: x.ThumbLinks, DispUser.tiers)[:3]) # list_logos = list(filter(lambda x: x.ThumbLinks, DispUser.tiers)[:3])
# Should We compute a better positionning for logos ? # Should We compute a better positionning for logos ?
DicPos = {} DicPos = {}
DicPos[1] = {0: (1. / 2, 1. / 2)} DicPos[1] = {0: (1. / 2, 1. / 2)}
@@ -75,25 +76,25 @@ def Tiers_Logo(canvas, DispUser, StartPos=None, Offset=(0, 0)):
3: (7. / 8, 1. / 4), 4: (1. / 8, 3. / 4), 5: (3. / 8, 3. / 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)} 6: (5. / 8, 3. / 4), 7: (7. / 8, 3. / 4)}
# draw overall border # draw overall border
# canvas.roundRect(StartX, StartY, MaxX, MaxY, radius=2, stroke=True) # canvas.roundRect(start_x, start_y, max_x, max_y, radius=2, stroke=True)
for tiers in Logos: for tiers in list_logos:
FileName = tiers.ThumbLinks.pop().split("/")[-1] file_name = tiers.ThumbLinks.pop().split("/")[-1]
ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName) image_path = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, file_name)
PosX = OffX + StartX + DicPos[len(Logos)][num][0] * MaxX - (ICONSIZE + Border) / 2 pos_x = off_x + start_x + DicPos[len(list_logos)][num][0] * max_x - (ICONSIZE + border) / 2
PosY = OffY + StartY + DicPos[len(Logos)][num][1] * MaxY - (ICONSIZE + Border) / 2 pos_y = off_y + start_y + DicPos[len(list_logos)][num][1] * max_y - (ICONSIZE + border) / 2
canvas.setLineWidth(.1) canvas.setLineWidth(.1)
if len(Logos) > 1: if len(list_logos) > 1:
size = ICONSIZE size = ICONSIZE
else: else:
size = ICONSIZE * 1.5 size = ICONSIZE * 1.5
canvas.drawImage(ImagePath, canvas.drawImage(image_path,
PosX, PosY, size, size, pos_x, pos_y, size, size,
preserveAspectRatio=True, preserveAspectRatio=True,
anchor='c', anchor='c',
mask='auto' mask='auto'
) )
# draw icon border # draw icon border
# canvas.roundRect(PosX, PosY, ICONSIZE, ICONSIZE, radius=2, stroke=True) # canvas.roundRect(pos_x, pos_y, ICONSIZE, ICONSIZE, radius=2, stroke=True)
num += 1 num += 1
@@ -114,37 +115,37 @@ def QRCode(DispUser):
def one_badge(c, DispUser, Offset=(0, 0)): def one_badge(c, DispUser, Offset=(0, 0)):
# Logo on Top # Logo on Top
JM2L_Logo(c, Offset) JM2L_Logo(c, Offset)
OffX, OffY = Offset off_x, off_y = Offset
c.rect(OffX - 3, OffY - 3, WIDTH + 6, HEIGHT + 6, fill=0, stroke=1) c.rect(off_x - 3, off_y - 3, WIDTH + 6, HEIGHT + 6, fill=0, stroke=1)
if DispUser.Staff: if DispUser.Staff:
# Staff # Staff
c.setFillColorRGB(.83, 0, .33) c.setFillColorRGB(.83, 0, .33)
c.rect(OffX - 3, OffY + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0) c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1) c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30) c.setFont('Liberation', 30)
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT - 24, "STAFF") c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "STAFF")
elif DispUser.is_Intervenant: elif DispUser.is_Intervenant:
# Intervenant # Intervenant
c.setFillColorRGB(.21, .67, .78) c.setFillColorRGB(.21, .67, .78)
c.rect(OffX - 3, OffY + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0) c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1) c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30) c.setFont('Liberation', 30)
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT - 24, "Intervenant") c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Intervenant")
elif DispUser.is_crew: elif DispUser.is_crew:
# Benevole # Benevole
c.setFillColorRGB(.18, .76, .23) c.setFillColorRGB(.18, .76, .23)
c.rect(OffX - 3, OffY + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0) c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1) c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30) c.setFont('Liberation', 30)
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT - 24, "Bénévole") c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Bénévole")
else: else:
# Visiteur # Visiteur
c.setFillColorRGB(.8, .8, .8) c.setFillColorRGB(.8, .8, .8)
c.rect(OffX - 3, OffY + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0) c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1) c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30) c.setFont('Liberation', 30)
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT - 24, "Visiteur") c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Visiteur")
c.restoreState() c.restoreState()
@@ -154,25 +155,25 @@ def one_badge(c, DispUser, Offset=(0, 0)):
# Feed Name and SurName # Feed Name and SurName
if DispUser.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom) > 18: if DispUser.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom) > 18:
if DispUser.pseudo: if DispUser.pseudo:
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 + 0 * mm, "%s" % DispUser.prenom) c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s" % DispUser.prenom)
# c.setFont('Courier', 17) # c.setFont('Courier', 17)
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom) c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
else: else:
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 + 4 * mm, "%s" % DispUser.prenom) c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 4 * mm, "%s" % DispUser.prenom)
# c.setFont('Courier', 17) # c.setFont('Courier', 17)
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom) c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
else: else:
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 + 0 * mm, "%s %s" % (DispUser.prenom, DispUser.nom)) c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s %s" % (DispUser.prenom, DispUser.nom))
if DispUser.pseudo: if DispUser.pseudo:
c.setFont("Helvetica-Oblique", 18) c.setFont("Helvetica-Oblique", 18)
c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 + 10 * mm, "%s" % DispUser.pseudo) c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 10 * mm, "%s" % DispUser.pseudo)
#  Put QR code to user profile #  Put QR code to user profile
c.drawInlineImage(QRCode(DispUser), \ c.drawInlineImage(QRCode(DispUser),
OffX + WIDTH - 20 * mm - 5, OffY + 5, \ off_x + WIDTH - 20 * mm - 5, off_y + 5,
20 * mm, 20 * mm, \ 20 * mm, 20 * mm,
preserveAspectRatio=True, \ preserveAspectRatio=True,
anchor='s') anchor='s')
Tiers_Logo(c, DispUser, None, Offset) Tiers_Logo(c, DispUser, None, Offset)
@@ -192,14 +193,14 @@ def badge_user(request):
# Ok let's generate a PDF Badge # Ok let's generate a PDF Badge
# Register LiberationMono font # Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf" ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font #  Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf" ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo)) pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = StringIO() pdf = io.BytesIO()
out_img = StringIO() out_img = io.BytesIO()
c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT)) c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT))
c.translate(mm, mm) c.translate(mm, mm)
@@ -211,23 +212,21 @@ def badge_user(request):
c.saveState() c.saveState()
one_badge(c, DispUser) one_badge(c, DispUser)
OutPDF = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf') out_pdf = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf')
c.showPage() c.showPage()
c._filename = OutPDF
c.save() c.save()
pdf.seek(0) pdf.seek(0)
if isoutpng: if isoutpng:
out_png = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
OutPNG = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
#  Let's generate a png file for website #  Let's generate a png file for website
with open("./%s" % OutPDF, 'wb') as pdff: with open("./%s" % out_pdf, 'wb') as pdff:
pdff.write(bytes(pdf.read(), 'utf8')) # .encode('utf8')) pdff.write(pdf.read())
Command = ["convert", "-density", "150x150", OutPDF, OutPNG] Command = ["convert", "-density", "150x150", out_pdf, out_png]
subprocess.call(Command) subprocess.call(Command)
with open("./%s" % OutPNG, 'r') as pngfile: with open("./%s" % out_png, 'rb') as pngfile:
out_img.write(bytes(pngfile.read(), 'utf8')) # bytes(pngfile.read(), "utf8")) out_img.write(pngfile.read()) # pngfile.read(), "utf8"))
out_img.seek(0) out_img.seek(0)
return Response(app_iter=out_img, content_type='image/png') return Response(app_iter=out_img, content_type='image/png')
@@ -246,13 +245,13 @@ def planche_badge(request):
# .filter(User_Event.year_uid == year) # .filter(User_Event.year_uid == year)
# Register LiberationMono font # Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf" ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font #  Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf" ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo)) pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = StringIO.StringIO() pdf = io.BytesIO()
FULLWIDTH = 210 * mm FULLWIDTH = 210 * mm
FULLHEIGHT = 297 * mm FULLHEIGHT = 297 * mm
@@ -264,11 +263,11 @@ def planche_badge(request):
c.setCreator("linux-azur.org") c.setCreator("linux-azur.org")
c.setTitle("Badge") c.setTitle("Badge")
t = 0 t = 0
ListUser = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users) list_user = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users)
for num, DispUser in enumerate(ListUser): for num, disp_user in enumerate(list_user):
c.saveState() c.saveState()
Offsets = (((num - t) % 2) * (WIDTH + 40) + 40, ((num - t) / 2) * (HEIGHT + 25) + 40) offsets = (((num - t) % 2) * (WIDTH + 40) + 40, int(((num - t) / 2)) * (HEIGHT + 25) + 40)
one_badge(c, DispUser, Offsets) one_badge(c, disp_user, offsets)
if num % 8 == 7: if num % 8 == 7:
t = num + 1 t = num + 1
c.showPage() c.showPage()
+4 -4
View File
@@ -115,8 +115,8 @@ class _PyCaptcha_SineWarp(_PyCaptcha_WarpBase):
@view_config(route_name='captcha') @view_config(route_name='captcha')
def DoCaptcha(request): def DoCaptcha(request):
ImgSize = (230, 100) img_size = (230, 100)
work_img = Image.new('RGBA', ImgSize, (255, 255, 255, 0)) work_img = Image.new('RGBA', img_size, (255, 255, 255, 0))
Xmax, Ymax = work_img.size Xmax, Ymax = work_img.size
# Write something on it # Write something on it
draw = ImageDraw.Draw(work_img) draw = ImageDraw.Draw(work_img)
@@ -129,7 +129,7 @@ def DoCaptcha(request):
# Choose a word for captcha # Choose a word for captcha
text = random.choice(TabMots) text = random.choice(TabMots)
Xt, Yt = font.getsize(text) Xt, Yt = font.getsize(text)
OrX, OrY = (ImgSize[0] - Xt) / 2, (ImgSize[1] - Yt) / 2 OrX, OrY = (img_size[0] - Xt) / 2, (img_size[1] - Yt) / 2
draw.text((OrX, OrY), text, font=font, fill="#000000") draw.text((OrX, OrY), text, font=font, fill="#000000")
# Apply a Blur # Apply a Blur
# work_img=work_img.filter(ImageFilter.BLUR) # work_img=work_img.filter(ImageFilter.BLUR)
@@ -140,7 +140,7 @@ def DoCaptcha(request):
tx, ty = (random.uniform(0, 0.0003), random.uniform(0, 0.0003)) tx, ty = (random.uniform(0, 0.0003), random.uniform(0, 0.0003))
bx, by = (random.uniform(0.5, 0.8), random.uniform(0, 0.2)) bx, by = (random.uniform(0.5, 0.8), random.uniform(0, 0.2))
# Apply perspective to Captcha # Apply perspective to Captcha
work_img = work_img.transform(ImgSize, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty)) work_img = work_img.transform(img_size, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty))
# Apply SinWarp to Captcha # Apply SinWarp to Captcha
tr = Captcha_Img(Xmax, Ymax) tr = Captcha_Img(Xmax, Ymax)
tr._image = work_img tr._image = work_img
+38 -25
View File
@@ -11,17 +11,20 @@ from wtforms.csrf.session import SessionCSRF
from datetime import timedelta from datetime import timedelta
from jm2l.const import CurrentYear from jm2l.const import CurrentYear
# What about an helper function # What about an helper function
#def strip_filter(x) def strip_filter(x):
# if x is no # strip_filter = lambda x: x.strip() if x else None
strip_filter = lambda x: x.strip() if x else None if x:
return x.strip()
return None
# get random string password with letters, digits, and symbols # get random string password with letters, digits, and symbols
def get_random_string(length): def get_random_string(length):
csrf_characters = string.ascii_letters + string.digits + string.punctuation csrf_characters = string.ascii_letters + string.digits + string.punctuation
csrf = ''.join(random.choice(password_characters) for i in range(length)) csrf = ''.join(random.choice(csrf_characters) for i in range(length))
return csrf return bytes(csrf, 'utf8')
class MyBaseForm(Form): class MyBaseForm(Form):
@@ -155,29 +158,35 @@ class ConfCreateForm(MyBaseForm):
start_time = HiddenField() start_time = HiddenField()
end_time = HiddenField() end_time = HiddenField()
start_sel = SelectField(u'Début', coerce=int, start_sel = SelectField(
description=u"C'est une heure indicative correspondant au mieux à vos préférences " + u'Début', coerce=int,
description=u"C'est une heure indicative correspondant au mieux à vos préférences "
u"personnelles. Vous pouvez prendre un créneau horaire déjà réservé si vous avez des contraintes " u"personnelles. Vous pouvez prendre un créneau horaire déjà réservé si vous avez des contraintes "
u"particulières. L'équipe des JM2L mettra à disposition plus de salle si nécessaire. En cas de conflit," + u"particulières. L'équipe des JM2L mettra à disposition plus de salle si nécessaire. "
u"En cas de conflit,"
u"l'organisation se réserve le droit de changer la salle et l'heure avec votre accord." u"l'organisation se réserve le droit de changer la salle et l'heure avec votre accord."
) )
duration = SelectField(u'Durée', coerce=int,
description=u"Précisez ici la durée de votre intervention" duration = SelectField(
u'Durée', coerce=int,
description=u"Précisez ici la durée de votre intervention")
salle_uid = SelectField(
u'Salle', coerce=int,
description=u"Choisissez ici la salle en fonction du nombres de personnes potentiellement "
u"intéressé par votre intervention l'organisation se réserve le droit de changer"
u" la salle (avec votre accord)."
) )
salle_uid = SelectField(u'Salle', coerce=int, name = StringField(
description=u"Choisissez ici la salle en fonction " u'Le nom de votre ',
u"du nombres de personnes potentiellement intéressé par votre intervention " +
u"l'organisation se réserve le droit de changer la salle (avec votre accord)."
)
name = StringField(u'Le nom de votre ',
[validators.DataRequired(u'Vous devez spécifier un nom pour votre intérvention'), [validators.DataRequired(u'Vous devez spécifier un nom pour votre intérvention'),
validators.Length(min=1, max=80, message='entre 1 et 80 car')], validators.Length(min=1, max=80, message='entre 1 et 80 car')],
filters=[strip_filter]) filters=[strip_filter]
)
description = TextAreaField(u'Décrivez ici quelques détails à propos de votre intervention ', description = TextAreaField(
u'Décrivez ici quelques détails à propos de votre intervention ',
[validators.Optional(), validators.Length(max=1000000)], [validators.Optional(), validators.Length(max=1000000)],
filters=[strip_filter] filters=[strip_filter]
) )
@@ -223,7 +232,8 @@ class PlaceCreateForm(MyBaseForm):
filters=[strip_filter]) filters=[strip_filter])
name = StringField('Nom Complet', [validators.Length(min=1, max=80)], name = StringField('Nom Complet', [validators.Length(min=1, max=80)],
filters=[strip_filter]) filters=[strip_filter])
gps_coord = StringField(u'Coordonnées GPS', [validators.Length(max=30), gps_coord = StringField(u'Coordonnées GPS',
[validators.Length(max=30),
validators.Regexp("^[0-9]+\.?[0-9]+,[0-9]+\.?[0-9]+$", validators.Regexp("^[0-9]+\.?[0-9]+,[0-9]+\.?[0-9]+$",
message=u"Le GPS devrait être sous la forme 43.6158372,7.0723401")], message=u"Le GPS devrait être sous la forme 43.6158372,7.0723401")],
filters=[strip_filter]) filters=[strip_filter])
@@ -600,12 +610,15 @@ class PropMForm(MyBaseForm):
message=u"doit être sous la forme HH:MM")], message=u"doit être sous la forme HH:MM")],
filters=[strip_filter]) filters=[strip_filter])
end_time = HiddenField() end_time = HiddenField()
exch_categ = SelectField(u'Catégorie de matériel', coerce=int, exch_categ = SelectField(
u'Catégorie de matériel', coerce=int,
description=u"Choisissez une catégorie de bien matériel" description=u"Choisissez une catégorie de bien matériel"
) )
description = TextAreaField(u'Ajoutez quelques mots autour du matériel que vous proposez', filters=[strip_filter], description = TextAreaField(
description=u"Décrivez ici quelques détails sur le matériel que vous souhaitez " u'Ajoutez quelques mots autour du matériel que vous proposez',
+ u"proposer. N'hésitez pas à donner des détails." filters=[strip_filter],
description=u"Décrivez ici quelques détails sur le matériel "
u"que vous souhaitez proposer. N'hésitez pas à donner des détails."
) )
+51 -46
View File
@@ -5,6 +5,11 @@ import itertools
from jm2l.const import CurrentYear from jm2l.const import CurrentYear
def get_current_year():
""" This function is intended to return the year of the next edition """
return CurrentYear
class DummySejour(object): class DummySejour(object):
def __init__(self, event): def __init__(self, event):
@@ -29,78 +34,78 @@ class Sejour_helpers(DummySejour):
# This function return the start of the event # This function return the start of the event
return self.CurrentYear return self.CurrentYear
def PossibleDate(self, typedate="arrival"): def PossibleDate(self, type_date="arrival"):
arrival, departure = False, False arrival, departure = False, False
TabResult = list() tab_result = list()
if typedate == "arrival": if type_date == "arrival":
# Let's say people should arrive until 2 day before # Let's say people should arrive until 2 day before
arrival = True arrival = True
myDayRange = range(2, -1, -1) my_day_range = range(2, -1, -1)
elif typedate == "departure": elif type_date == "departure":
# Let's say people should go back home until 2 day after # Let's say people should go back home until 2 day after
departure = True departure = True
myDayRange = range(3) my_day_range = range(3)
else: else:
return TabResult return tab_result
if self.Sejour: if self.Sejour:
ArrDate = datetime.strftime(self.Sejour.arrival_time, "%d %B %Y") arr_date = datetime.strftime(self.Sejour.arrival_time, "%d %B %Y")
DepDate = datetime.strftime(self.Sejour.depart_time, "%d %B %Y") dep_date = datetime.strftime(self.Sejour.depart_time, "%d %B %Y")
else: else:
ArrDate = datetime.strftime(self.CurrentEventYear.start_time, "%d %B %Y") arr_date = datetime.strftime(self.CurrentEventYear.start_time, "%d %B %Y")
DepDate = datetime.strftime(self.CurrentEventYear.end_time, "%d %B %Y") dep_date = datetime.strftime(self.CurrentEventYear.end_time, "%d %B %Y")
for oneday in myDayRange: for one_day in my_day_range:
if arrival: if arrival:
TmpDay = self.CurrentEventYear.end_time - timedelta(days=oneday) tmp_day = self.CurrentEventYear.end_time - timedelta(days=one_day)
elif departure: elif departure:
TmpDay = self.CurrentEventYear.start_time + timedelta(days=oneday) tmp_day = self.CurrentEventYear.start_time + timedelta(days=one_day)
DayName = datetime.strftime(TmpDay, "%A") day_name = datetime.strftime(tmp_day, "%A")
DayNum = datetime.strftime(TmpDay, "%d/%m/%y") day_num = datetime.strftime(tmp_day, "%d/%m/%y")
DayString = datetime.strftime(TmpDay, "%d %B %Y") day_string = datetime.strftime(tmp_day, "%d %B %Y")
if arrival and ArrDate == DayString: if arrival and arr_date == day_string:
TabResult.append((DayNum, DayName, 'selected="selected"')) tab_result.append((day_num, day_name, 'selected="selected"'))
elif departure and DepDate == DayString: elif departure and dep_date == day_string:
TabResult.append((DayNum, DayName, 'selected="selected"')) tab_result.append((day_num, day_name, 'selected="selected"'))
else: else:
TabResult.append((DayNum, DayName, "")) tab_result.append((day_num, day_name, ""))
return TabResult return tab_result
def PossibleTime(self, typedate="arrival"): def PossibleTime(self, type_date="arrival"):
ArrTime, DepTime = "10:00", "19:00" arr_time, dep_time = "10:00", "19:00"
TabResult = list() tab_result = list()
if self.Sejour: if self.Sejour:
ArrTime = datetime.strftime(self.Sejour.arrival_time, "%H:%M") arr_time = datetime.strftime(self.Sejour.arrival_time, "%H:%M")
DepTime = datetime.strftime(self.Sejour.depart_time, "%H:%M") dep_time = datetime.strftime(self.Sejour.depart_time, "%H:%M")
for hour in range(24): for hour in range(24):
for minutes in range(0, 60, 10): for minutes in range(0, 60, 10):
StrTime = "%.2d:%.2d" % (hour, minutes) str_time = "%.2d:%.2d" % (hour, minutes)
DispTime = "%dh%.2d" % (hour, minutes) disp_time = "%dh%.2d" % (hour, minutes)
if typedate == "arrival" and StrTime == ArrTime: if type_date == "arrival" and str_time == arr_time:
TabResult.append((StrTime, DispTime, 'selected="selected"')) tab_result.append((str_time, disp_time, 'selected="selected"'))
elif typedate == "departure" and StrTime == DepTime: elif type_date == "departure" and str_time == dep_time:
TabResult.append((StrTime, DispTime, 'selected="selected"')) tab_result.append((str_time, disp_time, 'selected="selected"'))
else: else:
TabResult.append((StrTime, DispTime, "")) tab_result.append((str_time, disp_time, ""))
return TabResult return tab_result
def IsCheck(self, InputControl): def IsCheck(self, InputControl):
ListControlA = ['Arrival', 'Departure'] list_control_a = ['Arrival', 'Departure']
ListControlB = ['PMR', 'Cov', 'Bras', 'Other'] list_control_b = ['PMR', 'Cov', 'Bras', 'Other']
if InputControl not in map(':'.join, itertools.product(ListControlA, ListControlB)): if InputControl not in map(':'.join, itertools.product(list_control_a, list_control_b)):
return "" return ""
if self.Sejour: if self.Sejour:
if InputControl.startswith('Arrival'): if InputControl.startswith('Arrival'):
CtrlVal = 2 ** ListControlB.index(InputControl[8:]) ctrl_val = 2 ** list_control_b.index(InputControl[8:])
if self.Sejour.arrival_check & CtrlVal == CtrlVal: if self.Sejour.arrival_check & ctrl_val == ctrl_val:
return "checked=\"checked\"" return "checked=\"checked\""
else: else:
return "" return ""
elif InputControl.startswith('Departure'): elif InputControl.startswith('Departure'):
CtrlVal = 2 ** ListControlB.index(InputControl[10:]) ctrl_val = 2 ** list_control_b.index(InputControl[10:])
if self.Sejour.depart_check & CtrlVal == CtrlVal: if self.Sejour.depart_check & ctrl_val == ctrl_val:
return "checked=\"checked\"" return "checked=\"checked\""
else: else:
return "" return ""
@@ -146,9 +151,9 @@ class Orga_helpers(DummySejour):
def ChoosedList(self): def ChoosedList(self):
""" Return choice validated by user """ """ Return choice validated by user """
ListOrga = [] list_orga = []
for num in range(0, len(self.Orga_tasks)): for num in range(0, len(self.Orga_tasks)):
curs = 2 ** num curs = 2 ** num
if self.Sejour.orga_part & curs == curs: if self.Sejour.orga_part & curs == curs:
ListOrga.append(self.Orga_tasks[num]) list_orga.append(self.Orga_tasks[num])
return ListOrga return list_orga
+74 -77
View File
@@ -1,9 +1,6 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
import io
from pyramid.response import Response from pyramid.response import Response
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from pyramid.view import view_config from pyramid.view import view_config
from .models import DBSession, Event, Salles from .models import DBSession, Event, Salles
from reportlab.pdfgen import canvas from reportlab.pdfgen import canvas
@@ -20,49 +17,50 @@ HEIGHT = 297 * mm
ICONSIZE = 10 * mm ICONSIZE = 10 * mm
def JM2L_large_Logo(canvas, Offset=(0,0)): def JM2L_large_Logo(canvas, Offset=(0, 0)):
OffX, OffY = Offset OffX, OffY = Offset
canvas.setFont('Logo', 110) canvas.setFont('Logo', 110)
canvas.setFillColorRGB(.83,0,.33) canvas.setFillColorRGB(.83, 0, .33)
canvas.drawCentredString(WIDTH/2-OffY, HEIGHT-100-OffX, "JM2L") canvas.drawCentredString(WIDTH / 2 - OffY, HEIGHT - 100 - OffX, "JM2L")
canvas.setFont("Helvetica-Bold", 30) canvas.setFont("Helvetica-Bold", 30)
yearobject = canvas.beginText() year_object = canvas.beginText()
yearobject.setFillColorRGB(1,1,1) year_object.setFillColorRGB(1, 1, 1)
yearobject.setTextRenderMode(0) year_object.setTextRenderMode(0)
yearobject.setTextOrigin(WIDTH/2-OffY-120, HEIGHT-36-OffX) year_object.setTextOrigin(WIDTH / 2 - OffY - 120, HEIGHT - 36 - OffX)
yearobject.setWordSpace(48) year_object.setWordSpace(48)
yearobject.textLines("2 0 1 5") year_object.textLines("2 0 1 5")
yearobject.setWordSpace(1) year_object.setWordSpace(1)
canvas.drawText(yearobject) canvas.drawText(year_object)
def one_time_step(canvas, str, hour, max_size, offset): def one_time_step(canvas, str, hour, max_size, offset):
max_x, max_y = max_size max_x, max_y = max_size
off_x, off_y = offset off_x, off_y = offset
step_y = max_y/9 step_y = max_y / 9
half_step = step_y/2 half_step = step_y / 2
canvas.drawCentredString(off_x-30, max_y-step_y*hour+off_y-3, str) canvas.drawCentredString(off_x - 30, max_y - step_y * hour + off_y - 3, str)
hour_place = step_y*hour+off_y hour_place = step_y * hour + off_y
canvas.line(off_x-5, hour_place, off_x, hour_place) canvas.line(off_x - 5, hour_place, off_x, hour_place)
if hour<9: if hour < 9:
canvas.line(off_x-2, hour_place+half_step, off_x, hour_place+half_step) canvas.line(off_x - 2, hour_place + half_step, off_x, hour_place + half_step)
@view_config(route_name='stand_print', http_cache = (EXPIRATION_TIME, {'public':True})) @view_config(route_name='stand_print', http_cache=(EXPIRATION_TIME, {'public': True}))
def stand_print(request): def stand_print(request):
# Ok let's generate a print for place schedule # Ok let's generate a print for place schedule
# Register LiberationMono font # Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf" ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
# Import font #  Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf" ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo)) pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = StringIO.StringIO() pdf = io.BytesIO()
c = canvas.Canvas( pdf, pagesize=(HEIGHT, WIDTH) ) c = canvas.Canvas(pdf, pagesize=(HEIGHT, WIDTH))
c.translate(mm, mm) c.translate(mm, mm)
# Feed some metadata # Feed some metadata
@@ -73,43 +71,42 @@ def stand_print(request):
year = int(request.matchdict.get('year', CurrentYear)) year = int(request.matchdict.get('year', CurrentYear))
Events = DBSession.query(Event)\ Events = DBSession.query(Event) \
.filter(Event.for_year == year)\ .filter(Event.for_year == year) \
.filter(Event.event_type == "Stand") .filter(Event.event_type == "Stand")
for ev in Events: for ev in Events:
c.setFont('Logo', 50) c.setFont('Logo', 50)
c.setFillColorRGB(.5,.5,.5) c.setFillColorRGB(.5, .5, .5)
c.drawString(HEIGHT-150, 30, "JM2L") c.drawString(HEIGHT - 150, 30, "JM2L")
c.setFont('Logo', 100) c.setFont('Logo', 100)
c.setFillColorRGB(0.5,0.5,0.5) c.setFillColorRGB(0.5, 0.5, 0.5)
c.drawCentredString(HEIGHT/2, WIDTH-90, "STAND", 0) c.drawCentredString(HEIGHT / 2, WIDTH - 90, "STAND", 0)
c.setFillColorRGB(0,0,0) c.setFillColorRGB(0, 0, 0)
c.setFont('Helvetica', 42) c.setFont('Helvetica', 42)
c.drawCentredString(HEIGHT/2, WIDTH/2, ev.name, 0) c.drawCentredString(HEIGHT / 2, WIDTH / 2, ev.name, 0)
c.showPage() c.showPage()
c.save() c.save()
pdf.seek(0) pdf.seek(0)
return Response(app_iter=pdf, content_type = 'application/pdf' ) return Response(app_iter=pdf, content_type='application/pdf')
@view_config(route_name='place_print', http_cache=(EXPIRATION_TIME, {'public': True}))
@view_config(route_name='place_print', http_cache = (EXPIRATION_TIME, {'public':True}))
def place_print(request): def place_print(request):
# Ok let's generate a print for place schedule # Ok let's generate a print for place schedule
# Register LiberationMono font # Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf" ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
# Import font #  Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf" ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo)) pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = StringIO.StringIO() pdf = io.BytesIO()
c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) ) c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT))
c.translate(mm, mm) c.translate(mm, mm)
# Feed some metadata # Feed some metadata
@@ -121,9 +118,9 @@ def place_print(request):
year = int(request.matchdict.get('year', CurrentYear)) year = int(request.matchdict.get('year', CurrentYear))
# Initialization # Initialization
# Compute days used by all events matching the specified input year # Compute days used by all events matching the specified input year
place_used = DBSession.query(Event.salle_uid)\ place_used = DBSession.query(Event.salle_uid) \
.filter(Event.for_year == year)\ .filter(Event.for_year == year) \
.filter(Event.event_type != 'Stand')\ .filter(Event.event_type != 'Stand') \
.group_by(Event.salle_uid) .group_by(Event.salle_uid)
for place in place_used: for place in place_used:
@@ -131,57 +128,57 @@ def place_print(request):
place_obj = Salles.by_id(place_uid) place_obj = Salles.by_id(place_uid)
# Logo on Top # Logo on Top
JM2L_large_Logo(c) JM2L_large_Logo(c)
max_size = (WIDTH-110, HEIGHT-300) max_size = (WIDTH - 110, HEIGHT - 300)
offset = (70, 90) offset = (70, 90)
c.setFillColorRGB(.5,.5,.5) c.setFillColorRGB(.5, .5, .5)
c.setFont('Liberation', 40) c.setFont('Liberation', 40)
c.drawCentredString(WIDTH/2, HEIGHT-190, place_obj.name, 1) c.drawCentredString(WIDTH / 2, HEIGHT - 190, place_obj.name, 1)
c.setFont('Liberation', 35) c.setFont('Liberation', 35)
c.drawCentredString(WIDTH/2, HEIGHT-145, place_obj.place_type, 0 ) c.drawCentredString(WIDTH / 2, HEIGHT - 145, place_obj.place_type, 0)
c.setFont('Helvetica', 20) c.setFont('Helvetica', 20)
c.drawCentredString(WIDTH/2, 55, place_obj.phy.name, 0) c.drawCentredString(WIDTH / 2, 55, place_obj.phy.name, 0)
# Timetable container # Timetable container
c.setLineWidth(.1) c.setLineWidth(.1)
c.setLineCap(2) c.setLineCap(2)
#c.setFillColorRGB(0,0,1) # c.setFillColorRGB(0,0,1)
c.rect(offset[0], offset[1], max_size[0], max_size[1], fill=0, stroke=1) c.rect(offset[0], offset[1], max_size[0], max_size[1], fill=0, stroke=1)
c.setLineWidth(.5) c.setLineWidth(.5)
# create time mark # create time mark
c.setFillColorRGB(0,0,0) c.setFillColorRGB(0, 0, 0)
c.setFont('Helvetica', 10) c.setFont('Helvetica', 10)
for i in range(0,10): for i in range(0, 10):
one_time_step(c, "%.2dh00" % (i+10), i, max_size, offset) one_time_step(c, "%.2dh00" % (i + 10), i, max_size, offset)
#c.setFont('Helvetica', 12) # c.setFont('Helvetica', 12)
Events = DBSession.query(Event)\ Events = DBSession.query(Event) \
.filter(Event.for_year == year)\ .filter(Event.for_year == year) \
.filter(Event.salle_uid == place_uid)\ .filter(Event.salle_uid == place_uid) \
.order_by(Event.start_time) .order_by(Event.start_time)
for ev in Events: for ev in Events:
place_time(c, ev, max_size, offset) place_time(c, ev, max_size, offset)
#c.rect(70, 50, WIDTH-100, HEIGHT-250, fill=0, stroke=1) # c.rect(70, 50, WIDTH-100, HEIGHT-250, fill=0, stroke=1)
c.showPage() c.showPage()
c.save() c.save()
pdf.seek(0) pdf.seek(0)
return Response(app_iter=pdf, content_type = 'application/pdf' ) return Response(app_iter=pdf, content_type='application/pdf')
def place_time(c, ev, max_size, offset): def place_time(c, ev, max_size, offset):
max_x, max_y = max_size max_x, max_y = max_size
off_x, off_y = offset off_x, off_y = offset
minute = max_y/(9*60) minute = max_y / (9 * 60)
start_pos_y = ((int( ev.start_time.strftime('%H') )-10)*60 + int( ev.start_time.strftime('%M') )) * minute start_pos_y = ((int(ev.start_time.strftime('%H')) - 10) * 60 + int(ev.start_time.strftime('%M'))) * minute
stop_pos_y = ((int( ev.end_time.strftime('%H') )-10)*60 + int( ev.end_time.strftime('%M') )) * minute stop_pos_y = ((int(ev.end_time.strftime('%H')) - 10) * 60 + int(ev.end_time.strftime('%M'))) * minute
c.setFillColorRGB(0.98,0.98,0.98) c.setFillColorRGB(0.98, 0.98, 0.98)
c.rect(offset[0], max_y + off_y - start_pos_y, max_size[0], start_pos_y-stop_pos_y, fill=1, stroke=1) c.rect(offset[0], max_y + off_y - start_pos_y, max_size[0], start_pos_y - stop_pos_y, fill=1, stroke=1)
c.setFillColorRGB(0,0,0) c.setFillColorRGB(0, 0, 0)
#c.drawString(off_x+5, max_y + off_y - 15 - start_pos_y, ev.start_time.strftime('%H:%M'), 0) # c.drawString(off_x+5, max_y + off_y - 15 - start_pos_y, ev.start_time.strftime('%H:%M'), 0)
c.setFont('Helvetica', 12) c.setFont('Helvetica', 12)
c.drawCentredString(WIDTH/2, max_y + off_y - 35 - start_pos_y, ev.name, 0) c.drawCentredString(WIDTH / 2, max_y + off_y - 35 - start_pos_y, ev.name, 0)
intervs = ', '.join( [x.slug for x in ev.intervenants] ) intervs = ', '.join([x.slug for x in ev.intervenants])
c.setFont('Helvetica', 10) c.setFont('Helvetica', 10)
c.drawCentredString(WIDTH/2, max_y + off_y - 55 - start_pos_y, intervs, 0) c.drawCentredString(WIDTH / 2, max_y + off_y - 55 - start_pos_y, intervs, 0)
+4 -2
View File
@@ -29,6 +29,7 @@ try:
from StringIO import StringIO from StringIO import StringIO
except ImportError: except ImportError:
from io import StringIO from io import StringIO
import io
import paginate import paginate
import unicodedata import unicodedata
import datetime import datetime
@@ -1002,7 +1003,7 @@ def list_users_csv(request):
.outerjoin(adalias) \ .outerjoin(adalias) \
.order_by(User.slug) \ .order_by(User.slug) \
.all() .all()
FileHandle = StringIO.StringIO() FileHandle = io.BytesIO()
fileWriter = csv.writer(FileHandle, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC) fileWriter = csv.writer(FileHandle, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
fileWriter.writerow(["Identifiant_JM2L", "Nom", "Prenom", "Status_%s" % for_year]) fileWriter.writerow(["Identifiant_JM2L", "Nom", "Prenom", "Status_%s" % for_year])
for user, sejour in Data: for user, sejour in Data:
@@ -1358,7 +1359,8 @@ def participer(request):
NewUser = TmpUsr NewUser = TmpUsr
# Send the Welcome Mail # Send the Welcome Mail
mailer = request.registry['mailer'] # mailer = request.registry['mailer']
mailer = request.mailer
# Prepare Plain Text Message : # Prepare Plain Text Message :
Mail_template = Template(filename='jm2l/templates/mail_plain.mako') Mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = Mail_template.render(request=request, User=NewUser, action="Welcome") mail_plain = Mail_template.render(request=request, User=NewUser, action="Welcome")
+5 -2
View File
@@ -11,6 +11,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
## Do not forget to run for lxml dependencies ## Do not forget to run for lxml dependencies
## apt-get install libxml2-dev libxslt1-dev ## apt-get install libxml2-dev libxslt1-dev
requires = [ requires = [
'pyramid', 'pyramid',
'pyramid_chameleon', 'pyramid_chameleon',
@@ -36,9 +37,11 @@ requires = [
'passlib', 'passlib',
'argon2_cffi', 'argon2_cffi',
'paginate', 'paginate',
'markupsafe' 'markupsafe',
'webhelpers2',
'email_validator',
'pyramid-scheduler'
] ]
setup(name='JM2L', setup(name='JM2L',
version='0.1', version='0.1',
description='JM2L', description='JM2L',