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
+50 -37
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,32 +158,38 @@ 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,
u"personnelles. Vous pouvez prendre un créneau horaire déjà réservé si vous avez des contraintes " description=u"C'est une heure indicative correspondant au mieux à vos préférences "
u"particulières. L'équipe des JM2L mettra à disposition plus de salle si nécessaire. En cas de conflit," + u"personnelles. Vous pouvez prendre un créneau horaire déjà réservé si vous avez des contraintes "
u"l'organisation se réserve le droit de changer la salle et l'heure avec votre accord." u"particulières. L'équipe des JM2L mettra à disposition plus de salle si nécessaire. "
) u"En cas de conflit,"
duration = SelectField(u'Durée', coerce=int, u"l'organisation se réserve le droit de changer la salle et l'heure avec votre accord."
description=u"Précisez ici la durée de votre intervention" )
)
salle_uid = SelectField(u'Salle', coerce=int, duration = SelectField(
description=u"Choisissez ici la salle en fonction " u'Durée', coerce=int,
u"du nombres de personnes potentiellement intéressé par votre intervention " + description=u"Précisez ici la durée de votre intervention")
u"l'organisation se réserve le droit de changer la salle (avec votre accord)."
) 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)."
)
name = StringField(u'Le nom de votre ', name = StringField(
[validators.DataRequired(u'Vous devez spécifier un nom pour votre intérvention'), u'Le nom de votre ',
validators.Length(min=1, max=80, message='entre 1 et 80 car')], [validators.DataRequired(u'Vous devez spécifier un nom pour votre intérvention'),
filters=[strip_filter]) validators.Length(min=1, max=80, message='entre 1 et 80 car')],
filters=[strip_filter]
)
description = TextAreaField(u'Décrivez ici quelques détails à propos de votre intervention ', description = TextAreaField(
[validators.Optional(), validators.Length(max=1000000)], u'Décrivez ici quelques détails à propos de votre intervention ',
filters=[strip_filter] [validators.Optional(), validators.Length(max=1000000)],
) filters=[strip_filter]
)
class ConfUpdateForm(ConfCreateForm): class ConfUpdateForm(ConfCreateForm):
@@ -223,9 +232,10 @@ 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.Regexp("^[0-9]+\.?[0-9]+,[0-9]+\.?[0-9]+$", [validators.Length(max=30),
message=u"Le GPS devrait être sous la forme 43.6158372,7.0723401")], validators.Regexp("^[0-9]+\.?[0-9]+,[0-9]+\.?[0-9]+$",
message=u"Le GPS devrait être sous la forme 43.6158372,7.0723401")],
filters=[strip_filter]) filters=[strip_filter])
adresse = TextAreaField('Adresse', [validators.Length(max=100)], adresse = TextAreaField('Adresse', [validators.Length(max=100)],
filters=[strip_filter]) filters=[strip_filter])
@@ -600,13 +610,16 @@ 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(
description=u"Choisissez une catégorie de bien matériel" u'Catégorie de matériel', coerce=int,
) 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=u"Décrivez ici quelques détails sur le matériel que vous souhaitez " description = TextAreaField(
+ u"proposer. N'hésitez pas à donner des détails." u'Ajoutez quelques mots autour du matériel que vous proposez',
) 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."
)
class UpdateAskCForm(AskCForm, UpdateExchangeForm): class UpdateAskCForm(AskCForm, UpdateExchangeForm):
+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
+76 -79
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
@@ -14,55 +11,56 @@ from .upload import MediaPath
from jm2l.const import CurrentYear from jm2l.const import CurrentYear
# Create PDF container # Create PDF container
EXPIRATION_TIME = 300 # seconds EXPIRATION_TIME = 300 # seconds
WIDTH = 210 * mm WIDTH = 210 * mm
HEIGHT = 297 * mm 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,67 +118,67 @@ 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:
place_uid = place[0] place_uid = place[0]
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',