From ad9883ae09bd463486f7dd8cc2048e9075306dce Mon Sep 17 00:00:00 2001 From: tr4ck3ur Date: Sun, 26 Jul 2020 17:38:55 +0200 Subject: [PATCH] Migration to python 3 --- jm2l/__init__.py | 4 +- jm2l/auth.py | 2 +- jm2l/badge.py | 240 +-- jm2l/captcha.py | 5 +- jm2l/const.py | 2 +- jm2l/helpers.py | 81 +- jm2l/models.py | 753 ++++---- jm2l/scripts/initializedb.py | 25 +- jm2l/templates/Errors/403.mako | 2 +- jm2l/templates/Errors/404.mako | 2 +- .../Interventions/Interventions.mako | 24 +- jm2l/templates/Logistique/Dialog_Covoit.mako | 2 +- jm2l/templates/Logistique/Dialog_Heberg.mako | 2 +- jm2l/templates/Logistique/Dialog_Matos.mako | 4 +- jm2l/templates/Logistique/Logistique.mako | 34 +- jm2l/templates/Logistique/Tables.mako | 8 +- jm2l/templates/Profil/Profil.mako | 8 +- jm2l/templates/Profil/Sejour.mako | 26 +- jm2l/templates/Public/Programme.mako | 2 +- jm2l/templates/Salles/list_phy.mako | 4 +- jm2l/templates/Salles/salle.mako | 4 +- jm2l/templates/Staff/compta.mako | 2 +- jm2l/templates/Staff/list.mako | 2 +- jm2l/templates/edit_event.mako | 6 +- jm2l/templates/helpers.mako | 28 +- jm2l/templates/jm2l.mako | 14 +- jm2l/templates/layout.mako | 32 +- jm2l/templates/mail_html.mako | 6 +- jm2l/templates/mail_plain.mako | 6 +- jm2l/templates/show_user.mako | 2 +- jm2l/templates/view_event.mako | 4 +- jm2l/templates/view_tiers.mako | 2 +- jm2l/templates/view_user.mako | 2 +- jm2l/to_print.py | 5 +- jm2l/upload.py | 340 ++-- jm2l/views.py | 1527 +++++++++-------- setup.py | 5 +- 37 files changed, 1670 insertions(+), 1547 deletions(-) diff --git a/jm2l/__init__.py b/jm2l/__init__.py index 54cb251..5dc5a07 100644 --- a/jm2l/__init__.py +++ b/jm2l/__init__.py @@ -19,7 +19,7 @@ from pyramid.request import Request from mako.template import Template from .models import User from jm2l.const import CurrentYear -from models import JM2L_Year +from .models import JM2L_Year import logging @@ -80,7 +80,7 @@ def main(global_config, **settings): authorization_policy=authorization_policy ) config.add_subscriber(add_renderer_globals, BeforeRender) - config.registry['mailer'] = mailer_factory_from_settings(settings) + # config.registry['mailer'] = mailer_factory_from_settings(settings) config.registry['event_date'] = JM2L_Year.get_latest_jm2l_startdate() sched = BackgroundScheduler() sched.add_job(mailer_tasks, 'cron', day_of_week='fri', hour=18, args=[ config ]) diff --git a/jm2l/auth.py b/jm2l/auth.py index 7a3e836..aae3197 100644 --- a/jm2l/auth.py +++ b/jm2l/auth.py @@ -8,7 +8,7 @@ from pyramid_mailer import get_mailer from pyramid_mailer.message import Attachment, Message from .forms import UserPasswordForm from passlib.hash import argon2 -from security import check_logged +from .security import check_logged import datetime import re diff --git a/jm2l/badge.py b/jm2l/badge.py index 1b19e90..b14b48e 100644 --- a/jm2l/badge.py +++ b/jm2l/badge.py @@ -1,7 +1,11 @@ # -*- coding: utf8 -*- from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden from pyramid.response import Response -import cStringIO as StringIO + +try: + from StringIO import StringIO +except ImportError: + from io import StringIO from pyramid.view import view_config from .models import DBSession, User from reportlab.pdfgen import canvas @@ -12,78 +16,86 @@ import qrcode import subprocess from .upload import MediaPath from jm2l.const import CurrentYear + # Create PDF container -EXPIRATION_TIME = 300 # seconds +EXPIRATION_TIME = 300 # seconds WIDTH = 85 * mm HEIGHT = 60 * mm ICONSIZE = 10 * mm -def JM2L_Logo(canvas, Offset=(0,0)): + +def JM2L_Logo(canvas, Offset=(0, 0)): OffX, OffY = Offset logoobject = canvas.beginText() logoobject.setFont('Logo', 32) - logoobject.setFillColorRGB(.83,0,.33) - logoobject.setTextOrigin(OffX+5, OffY+17) + logoobject.setFillColorRGB(.83, 0, .33) + logoobject.setTextOrigin(OffX + 5, OffY + 17) logoobject.textLines("JM2L") canvas.drawText(logoobject) - + yearobject = canvas.beginText() yearobject.setFont("Helvetica-Bold", 10) - yearobject.setFillColorRGB(1,1,1) + yearobject.setFillColorRGB(1, 1, 1) yearobject.setTextRenderMode(0) - yearobject.setTextOrigin(OffX+12 , OffY+35) + yearobject.setTextOrigin(OffX + 12, OffY + 35) yearobject.setWordSpace(13) yearobject.textLines(" ".join(str(CurrentYear))) canvas.drawText(yearobject) -def Tiers_Logo(canvas, DispUser, StartPos=None, Offset=(0,0)): + +def Tiers_Logo(canvas, DispUser, StartPos=None, Offset=(0, 0)): Border = 0 OffX, OffY = Offset if StartPos is None: - StartPos = ( 30 * mm, 2 ) + StartPos = (30 * mm, 2) StartX, StartY = StartPos - MaxX, MaxY = 34*mm, 18*mm + MaxX, MaxY = 34 * mm, 18 * mm num = 0 - canvas.setStrokeColorRGB(0.5,0.5,0.5) - Logos = filter(lambda x:x.ThumbLinks, DispUser.tiers)[:3] + canvas.setStrokeColorRGB(0.5, 0.5, 0.5) + Logos = list() + for thumb in DispUser.tiers: + if thumb.ThumbLinks: + Logos.append(thumb.ThumbLinks[:3]) + # 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) } + 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(StartX, StartY, MaxX, MaxY, radius=2, stroke=True) for tiers in Logos: FileName = tiers.ThumbLinks.pop().split("/")[-1] - ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName) - PosX = OffX+StartX + DicPos[len(Logos)][num][0] * MaxX - (ICONSIZE+Border)/2 - PosY = OffY+StartY + DicPos[len(Logos)][num][1] * MaxY - (ICONSIZE+Border)/2 + ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName) + PosX = OffX + StartX + DicPos[len(Logos)][num][0] * MaxX - (ICONSIZE + Border) / 2 + PosY = OffY + StartY + DicPos[len(Logos)][num][1] * MaxY - (ICONSIZE + Border) / 2 canvas.setLineWidth(.1) - if len(Logos)>1: + if len(Logos) > 1: size = ICONSIZE else: - size = ICONSIZE*1.5 - canvas.drawImage(ImagePath, - PosX, PosY, size, size,\ - preserveAspectRatio=True, - anchor='c', - mask='auto' - ) + size = ICONSIZE * 1.5 + canvas.drawImage(ImagePath, + PosX, PosY, size, size, + preserveAspectRatio=True, + anchor='c', + mask='auto' + ) # draw icon border # canvas.roundRect(PosX, PosY, ICONSIZE, ICONSIZE, radius=2, stroke=True) - num+=1 + num += 1 + def QRCode(DispUser): qr = qrcode.QRCode( @@ -98,78 +110,79 @@ def QRCode(DispUser): return qr.make_image() -def one_badge(c, DispUser, Offset=(0,0)): + +def one_badge(c, DispUser, Offset=(0, 0)): # Logo on Top JM2L_Logo(c, Offset) OffX, OffY = Offset - - c.rect(OffX-3, OffY-3, WIDTH+6, HEIGHT+6, fill=0, stroke=1) + + c.rect(OffX - 3, OffY - 3, WIDTH + 6, HEIGHT + 6, fill=0, stroke=1) if DispUser.Staff: # Staff - c.setFillColorRGB(.83,0,.33) - c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0) - c.setFillColorRGB(1,1,1) + c.setFillColorRGB(.83, 0, .33) + c.rect(OffX - 3, OffY + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0) + c.setFillColorRGB(1, 1, 1) c.setFont('Liberation', 30) - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "STAFF") + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT - 24, "STAFF") elif DispUser.is_Intervenant: # Intervenant - c.setFillColorRGB(.21,.67,.78) - c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0) - c.setFillColorRGB(1,1,1) + c.setFillColorRGB(.21, .67, .78) + c.rect(OffX - 3, OffY + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0) + c.setFillColorRGB(1, 1, 1) c.setFont('Liberation', 30) - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Intervenant") + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT - 24, "Intervenant") elif DispUser.is_crew: # Benevole - c.setFillColorRGB(.18,.76,.23) - c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0) - c.setFillColorRGB(1,1,1) + c.setFillColorRGB(.18, .76, .23) + c.rect(OffX - 3, OffY + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0) + c.setFillColorRGB(1, 1, 1) c.setFont('Liberation', 30) - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Bénévole") + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT - 24, "Bénévole") else: # Visiteur - c.setFillColorRGB(.8,.8,.8) - c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0) - c.setFillColorRGB(1,1,1) + c.setFillColorRGB(.8, .8, .8) + c.rect(OffX - 3, OffY + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0) + c.setFillColorRGB(1, 1, 1) c.setFont('Liberation', 30) - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Visiteur") + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT - 24, "Visiteur") c.restoreState() - + c.setFont('Liberation', 18) - c.setStrokeColorRGB(0,0,0) - c.setFillColorRGB(0,0,0) + 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.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom) > 18: if DispUser.pseudo: - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 0 * mm , "%s" % DispUser.prenom ) - #c.setFont('Courier', 17) - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 - 8 * mm , "%s" % DispUser.nom ) + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 + 0 * mm, "%s" % DispUser.prenom) + # c.setFont('Courier', 17) + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom) else: - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 4 * mm , "%s" % DispUser.prenom ) - #c.setFont('Courier', 17) - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 - 8 * mm , "%s" % DispUser.nom ) + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 + 4 * mm, "%s" % DispUser.prenom) + # c.setFont('Courier', 17) + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom) else: - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 0 * mm , "%s %s" % (DispUser.prenom, DispUser.nom) ) + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 + 0 * mm, "%s %s" % (DispUser.prenom, DispUser.nom)) if DispUser.pseudo: c.setFont("Helvetica-Oblique", 18) - c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 10 * mm , "%s" % DispUser.pseudo ) - - # Put QR code to user profile + c.drawCentredString(OffX + WIDTH / 2, OffY + HEIGHT / 2 + 10 * mm, "%s" % DispUser.pseudo) + + #  Put QR code to user profile c.drawInlineImage(QRCode(DispUser), \ - OffX+WIDTH - 20 * mm -5, OffY+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})) + OffX + WIDTH - 20 * mm - 5, OffY + 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: + 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) @@ -177,48 +190,49 @@ def badge_user(request): raise HTTPNotFound() # Ok let's generate a PDF Badge - + # Register LiberationMono font ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf" pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) - # Import font + #  Import font ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf" pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo)) - pdf = StringIO.StringIO() - out_img = StringIO.StringIO() - - c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) ) + pdf = StringIO() + out_img = StringIO() + + 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) + one_badge(c, DispUser) + OutPDF = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf') c.showPage() + c._filename = OutPDF c.save() pdf.seek(0) if isoutpng: - OutPDF = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf') + OutPNG = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png') - # Let's generate a png file for website - with open( OutPDF ,'wb') as pdff: - pdff.write(pdf.read()) - - Command = ["convert","-density","150x150", OutPDF, OutPNG] + #  Let's generate a png file for website + with open("./%s" % OutPDF, 'wb') as pdff: + pdff.write(bytes(pdf.read(), 'utf8')) # .encode('utf8')) + + Command = ["convert", "-density", "150x150", OutPDF, OutPNG] subprocess.call(Command) - - with open( OutPNG, 'rb') as pngfile: - out_img.write(pngfile.read()) - + + with open("./%s" % OutPNG, 'r') as pngfile: + out_img.write(bytes(pngfile.read(), 'utf8')) # bytes(pngfile.read(), "utf8")) + out_img.seek(0) - return Response(app_iter=out_img, content_type = 'image/png' ) + return Response(app_iter=out_img, content_type='image/png') else: - return Response(app_iter=pdf, content_type = 'application/pdf' ) + return Response(app_iter=pdf, content_type='application/pdf') @view_config(route_name='all_badges') @@ -234,32 +248,32 @@ def planche_badge(request): # Register LiberationMono font ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf" pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) - # Import font + #  Import font ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf" pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo)) - + pdf = StringIO.StringIO() FULLWIDTH = 210 * mm FULLHEIGHT = 297 * mm - c = canvas.Canvas( pdf, pagesize=(FULLWIDTH, FULLHEIGHT) ) + c = canvas.Canvas(pdf, pagesize=(FULLWIDTH, FULLHEIGHT)) c.translate(mm, mm) - + # Feed some metadata c.setCreator("linux-azur.org") c.setTitle("Badge") - t=0 + t = 0 ListUser = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users) for num, DispUser in enumerate(ListUser): c.saveState() - Offsets = (((num-t)%2)*(WIDTH+40)+40, ((num-t)/2)*(HEIGHT+25)+40) + Offsets = (((num - t) % 2) * (WIDTH + 40) + 40, ((num - t) / 2) * (HEIGHT + 25) + 40) one_badge(c, DispUser, Offsets) - if num%8==7: - t=num+1 + 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' ) + return Response(app_iter=pdf, content_type='application/pdf') diff --git a/jm2l/captcha.py b/jm2l/captcha.py index f7dd768..985f7e6 100644 --- a/jm2l/captcha.py +++ b/jm2l/captcha.py @@ -3,7 +3,10 @@ import random from PIL import Image, ImageDraw, ImageFont, ImageFilter -import cStringIO as StringIO +try: + from StringIO import StringIO +except ImportError: + from io import StringIO import math from pyramid.view import view_config from .words import TabMots diff --git a/jm2l/const.py b/jm2l/const.py index c264c9f..9b7a5a6 100644 --- a/jm2l/const.py +++ b/jm2l/const.py @@ -1 +1 @@ -CurrentYear = 2018 +CurrentYear = 2020 diff --git a/jm2l/helpers.py b/jm2l/helpers.py index 2a0aa6f..c0fb852 100644 --- a/jm2l/helpers.py +++ b/jm2l/helpers.py @@ -4,61 +4,63 @@ from datetime import timedelta, datetime import itertools from jm2l.const import CurrentYear + class DummySejour(object): - + def __init__(self, event): self.Me = event['request'].user - self.CurrentEventYear = DBSession.query(JM2L_Year).filter(JM2L_Year.state=='Ongoing').first() + self.CurrentEventYear = DBSession.query(JM2L_Year).filter(JM2L_Year.state == 'Ongoing').first() self.Sejour = None if self.Me: - self.Sejour = DBSession.query(Sejour)\ - .filter(Sejour.user_id==self.Me.uid)\ - .filter(Sejour.for_year==self.CurrentEventYear.year_uid)\ + self.Sejour = DBSession.query(Sejour) \ + .filter(Sejour.user_id == self.Me.uid) \ + .filter(Sejour.for_year == self.CurrentEventYear.year_uid) \ .first() + class Sejour_helpers(DummySejour): def __init__(self, event): super(Sejour_helpers, self).__init__(event) if self.Sejour and self.Sejour.arrival_time is None: self.Sejour = None - + def StartEvent(self): # This function return the start of the event return self.CurrentYear - + def PossibleDate(self, typedate="arrival"): arrival, departure = False, False TabResult = list() if typedate == "arrival": # Let's say people should arrive until 2 day before arrival = True - myDayRange = xrange(2,-1,-1) + myDayRange = range(2, -1, -1) elif typedate == "departure": # Let's say people should go back home until 2 day after - departure = True - myDayRange = xrange(3) + departure = True + myDayRange = range(3) else: return TabResult - + if self.Sejour: - ArrDate = datetime.strftime(self.Sejour.arrival_time,"%d %B %Y").decode('utf-8') - DepDate = datetime.strftime(self.Sejour.depart_time,"%d %B %Y").decode('utf-8') + ArrDate = datetime.strftime(self.Sejour.arrival_time, "%d %B %Y") + DepDate = datetime.strftime(self.Sejour.depart_time, "%d %B %Y") else: - ArrDate = datetime.strftime( self.CurrentEventYear.start_time,"%d %B %Y" ).decode('utf-8') - DepDate = datetime.strftime( self.CurrentEventYear.end_time,"%d %B %Y" ).decode('utf-8') - + ArrDate = datetime.strftime(self.CurrentEventYear.start_time, "%d %B %Y") + DepDate = datetime.strftime(self.CurrentEventYear.end_time, "%d %B %Y") + for oneday in myDayRange: if arrival: TmpDay = self.CurrentEventYear.end_time - timedelta(days=oneday) elif departure: TmpDay = self.CurrentEventYear.start_time + timedelta(days=oneday) - DayName = datetime.strftime(TmpDay,"%A") - DayNum = datetime.strftime(TmpDay,"%d/%m/%y") - DayString = datetime.strftime(TmpDay,"%d %B %Y").decode('utf-8') - if arrival and ArrDate==DayString: + DayName = datetime.strftime(TmpDay, "%A") + DayNum = datetime.strftime(TmpDay, "%d/%m/%y") + DayString = datetime.strftime(TmpDay, "%d %B %Y") + if arrival and ArrDate == DayString: TabResult.append((DayNum, DayName, 'selected="selected"')) - elif departure and DepDate==DayString: + elif departure and DepDate == DayString: TabResult.append((DayNum, DayName, 'selected="selected"')) else: TabResult.append((DayNum, DayName, "")) @@ -67,21 +69,21 @@ class Sejour_helpers(DummySejour): def PossibleTime(self, typedate="arrival"): ArrTime, DepTime = "10:00", "19:00" TabResult = list() - + if self.Sejour: - ArrTime = datetime.strftime(self.Sejour.arrival_time,"%H:%M") - DepTime = datetime.strftime(self.Sejour.depart_time,"%H:%M") - + ArrTime = datetime.strftime(self.Sejour.arrival_time, "%H:%M") + DepTime = datetime.strftime(self.Sejour.depart_time, "%H:%M") + for hour in range(24): - for minutes in range(0,60,10): + for minutes in range(0, 60, 10): StrTime = "%.2d:%.2d" % (hour, minutes) DispTime = "%dh%.2d" % (hour, minutes) - if typedate == "arrival" and StrTime==ArrTime: - TabResult.append( (StrTime, DispTime, 'selected="selected"') ) - elif typedate == "departure" and StrTime==DepTime: - TabResult.append( (StrTime, DispTime, 'selected="selected"') ) + if typedate == "arrival" and StrTime == ArrTime: + TabResult.append((StrTime, DispTime, 'selected="selected"')) + elif typedate == "departure" and StrTime == DepTime: + TabResult.append((StrTime, DispTime, 'selected="selected"')) else: - TabResult.append( (StrTime, DispTime, "") ) + TabResult.append((StrTime, DispTime, "")) return TabResult def IsCheck(self, InputControl): @@ -91,13 +93,13 @@ class Sejour_helpers(DummySejour): return "" if self.Sejour: if InputControl.startswith('Arrival'): - CtrlVal = 2**ListControlB.index(InputControl[8:]) + CtrlVal = 2 ** ListControlB.index(InputControl[8:]) if self.Sejour.arrival_check & CtrlVal == CtrlVal: return "checked=\"checked\"" else: return "" elif InputControl.startswith('Departure'): - CtrlVal = 2**ListControlB.index(InputControl[10:]) + CtrlVal = 2 ** ListControlB.index(InputControl[10:]) if self.Sejour.depart_check & CtrlVal == CtrlVal: return "checked=\"checked\"" else: @@ -107,6 +109,7 @@ class Sejour_helpers(DummySejour): else: return "" + class Orga_helpers(DummySejour): def __init__(self, event): @@ -129,10 +132,10 @@ class Orga_helpers(DummySejour): u"Faire du café et s'assurer de sa disponibilité.", u"Participer à la publication / au montage des vidéos des conférenciers.", u"Autres" - ] + ] def IsChecked(self, nb): - nb = 2**nb + nb = 2 ** nb if self.Sejour and self.Sejour.orga_part: if self.Sejour.orga_part & nb == nb: return "checked=\"checked\"" @@ -140,12 +143,12 @@ class Orga_helpers(DummySejour): return "" else: return "" - + def ChoosedList(self): """ Return choice validated by user """ ListOrga = [] - for num in range(0,len(self.Orga_tasks)): - curs = 2**num + for num in range(0, len(self.Orga_tasks)): + curs = 2 ** num if self.Sejour.orga_part & curs == curs: ListOrga.append(self.Orga_tasks[num]) - return ListOrga \ No newline at end of file + return ListOrga diff --git a/jm2l/models.py b/jm2l/models.py index e817bf9..4ca8baa 100644 --- a/jm2l/models.py +++ b/jm2l/models.py @@ -15,85 +15,98 @@ from sqlalchemy import ( Enum, Boolean, ForeignKey - ) +) from slugify import slugify -from webhelpers.text import urlify -from webhelpers.paginate import PageURL_WebOb, Page -from webhelpers.date import time_ago_in_words +# from webhelpers.text import urlify +from paginate import Page # PageURL_WebOb +from webhelpers2.date import time_ago_in_words from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import ( scoped_session, sessionmaker - ) +) -from zope.sqlalchemy import ZopeTransactionExtension +# from zope.sqlalchemy import ZopeTransactionExtension +from zope.sqlalchemy import register from jm2l.const import CurrentYear from passlib.hash import argon2 -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) + +def urlify(in_string, in_string_length): + return ''.join('%20' if c == ' ' else c for c in in_string[:in_string_length]) + + +DBSession = scoped_session(sessionmaker(autoflush=False)) +register(DBSession) + +# DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) Base = declarative_base() + class TasksArea(Base): __tablename__ = 'staff_tasks_area' - uid = Column(Integer, primary_key=True) - year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) - name = Column(Unicode(80)) - description = Column(UnicodeText) + uid = Column(Integer, primary_key=True) + year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) + name = Column(Unicode(80)) + description = Column(UnicodeText) @classmethod def by_id(cls, uid): return DBSession.query(cls).filter(cls.uid == uid).first() + class Tasks(Base): __tablename__ = 'staff_tasks' - uid = Column(Integer, primary_key=True) - area_uid = Column(Integer, ForeignKey('staff_tasks_area.uid') ) - year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) - due_date = Column(DateTime, default=None) - closed_by = Column(Integer, ForeignKey('users.uid') ) - closed_date = Column(DateTime, default=None) - closed = Column(Integer, default=0) - name = Column(Unicode(80)) - description = Column(UnicodeText) - area = relationship(TasksArea, backref=backref("tasks") ) - - assignee = relationship('User', backref=backref("task_assoc") ) + uid = Column(Integer, primary_key=True) + area_uid = Column(Integer, ForeignKey('staff_tasks_area.uid')) + year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) + due_date = Column(DateTime, default=None) + closed_by = Column(Integer, ForeignKey('users.uid')) + closed_date = Column(DateTime, default=None) + closed = Column(Integer, default=0) + name = Column(Unicode(80)) + description = Column(UnicodeText) + area = relationship(TasksArea, backref=backref("tasks")) + + assignee = relationship('User', backref=backref("task_assoc")) @classmethod def by_id(cls, uid): return DBSession.query(cls).filter(cls.uid == uid).first() + class User_Event(Base): """ Créer le lien entre la personne et l' évenement en fonction de l'année""" __tablename__ = 'user_event_link' uid = Column(Integer, primary_key=True) - event_uid = Column(Integer, ForeignKey('events.uid') ) - #, primary_key=True) + event_uid = Column(Integer, ForeignKey('events.uid')) + # , primary_key=True) # - user_uid = Column(Integer, ForeignKey('users.uid') ) - #, primary_key=True) + user_uid = Column(Integer, ForeignKey('users.uid')) + # , primary_key=True) # - year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) - role = Column(Unicode(80)) + year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) + role = Column(Unicode(80)) # Define some relation - #user = relationship('User', backref=backref("events_assoc") ) - #event = relationship('events', backref=backref("users_assoc") ) + # user = relationship('User', backref=backref("events_assoc") ) + # event = relationship('events', backref=backref("users_assoc") ) + class JM2L_Year(Base): __tablename__ = 'jm2l_year' - year_uid = Column(Integer, primary_key=True) - description = Column(UnicodeText) - doss_presse = Column(UnicodeText) - state = Column(Enum('Archived', 'Cancelled', 'Ongoing')) - start_time = Column(DateTime, default=datetime.datetime.now) - end_time = Column(DateTime, default=datetime.datetime.now) - created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) + year_uid = Column(Integer, primary_key=True) + description = Column(UnicodeText) + doss_presse = Column(UnicodeText) + state = Column(Enum('Archived', 'Cancelled', 'Ongoing')) + start_time = Column(DateTime, default=datetime.datetime.now) + end_time = Column(DateTime, default=datetime.datetime.now) + created = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) @classmethod def get_latest_jm2l_startdate(cls, fakeparam=None): @@ -102,22 +115,22 @@ class JM2L_Year(Base): .filter(JM2L_Year.start_time == DBSession.query(func.max(JM2L_Year.start_time)) ).one() - return last_record.start_time.strftime("%A %d %B %Y").decode('utf-8') + return last_record.start_time.strftime("%A %d %B %Y") # .decode('utf-8') @property def AvailableTimeSlots(self, TimeStep=30): Available = self.end_time - self.start_time - NbMinutes = Available.total_seconds()/60 - NbSteps = NbMinutes/TimeStep + NbMinutes = Available.total_seconds() / 60 + NbSteps = NbMinutes / TimeStep # Create the range of date each 30min - date_list = [self.start_time + datetime.timedelta(minutes=TimeStep*x) for x in range(0, int(NbSteps))] + date_list = [self.start_time + datetime.timedelta(minutes=TimeStep * x) for x in range(0, int(NbSteps))] # Remove out of range datetime # Remove hours > 19h - date_list = filter(lambda x:x.hour < 19, date_list) + date_list = filter(lambda x: x.hour < 19, date_list) # Remove hours < 10h - date_list = filter(lambda x:x.hour >= 10, date_list) + date_list = filter(lambda x: x.hour >= 10, date_list) # Remove 12h < hours < 13h - date_list = filter(lambda x: x.hour<12 or x.hour>=13, date_list) + date_list = filter(lambda x: x.hour < 12 or x.hour >= 13, date_list) return date_list @property @@ -125,36 +138,37 @@ class JM2L_Year(Base): from .upload import MediaPath return sorted(MediaPath().get_all('presse', self.year_uid)) + class User(Base): __tablename__ = 'users' - uid = Column(Integer, primary_key=True) - user_id = Column(Integer) - nom = Column(Unicode(80)) - prenom = Column(Unicode(80)) - pseudo = Column(Unicode(80)) - slug = Column(Unicode(164)) - mail = Column(Unicode(100)) - password = Column(Unicode(100), nullable=False) - fonction = Column(Unicode(80)) - website = Column(Unicode(100)) - phone = Column(Unicode(10)) - created = Column(DateTime, default=datetime.datetime.now) + uid = Column(Integer, primary_key=True) + user_id = Column(Integer) + nom = Column(Unicode(80)) + prenom = Column(Unicode(80)) + pseudo = Column(Unicode(80)) + slug = Column(Unicode(164)) + mail = Column(Unicode(100)) + password = Column(Unicode(100), nullable=False) + fonction = Column(Unicode(80)) + website = Column(Unicode(100)) + phone = Column(Unicode(10)) + created = Column(DateTime, default=datetime.datetime.now) last_logged = Column(DateTime, default=datetime.datetime.now) last_change = Column(DateTime, default=datetime.datetime.now) - active = Column(Integer, default=1) - bio = Column(UnicodeText) - gpg_key = Column(UnicodeText) - soc_link = Column(UnicodeText) - Staff = Column(Integer, default=0) - vote_logo = Column(Integer, default=0) - - wifi_user = Column(Unicode(80), nullable=True) - wifi_pass = Column(Unicode(80), nullable=True) - + active = Column(Integer, default=1) + bio = Column(UnicodeText) + gpg_key = Column(UnicodeText) + soc_link = Column(UnicodeText) + Staff = Column(Integer, default=0) + vote_logo = Column(Integer, default=0) + + wifi_user = Column(Unicode(80), nullable=True) + wifi_pass = Column(Unicode(80), nullable=True) + # relations - tiers = relationship('Tiers', secondary='user_tiers_link' ) - events = relationship('Event', secondary='user_event_link' ) - tiersship = relationship('User_Tiers', backref="matching_users") + tiers = relationship('Tiers', secondary='user_tiers_link') + events = relationship('Event', secondary='user_event_link') + tiersship = relationship('User_Tiers', backref="matching_users") @classmethod def by_id(cls, uid): @@ -171,7 +185,7 @@ class User(Base): @classmethod def by_user_id(cls, user_id): return DBSession.query(cls).filter(cls.user_id == user_id).first() - + @classmethod def by_name(cls, name): return DBSession.query(cls).filter(cls.nom == name).first() @@ -179,61 +193,59 @@ class User(Base): @classmethod def by_hash(cls, tsthash): for u in DBSession.query(cls): - if u.my_hash==tsthash: - return u + if u.my_hash == tsthash: + return u return None @property def is_Intervenant(self): """ This property will return if User do an event on specified year """ return DBSession.query(Event).join(User_Event) \ - .filter(User_Event.user_uid==self.uid) \ - .filter(Event.for_year==CurrentYear).count() + .filter(User_Event.user_uid == self.uid) \ + .filter(Event.for_year == CurrentYear).count() def is_IntervenantOnYear(self, year=CurrentYear): """ This property will return if User do an event on specified year """ return DBSession.query(Event).join(User_Event) \ - .filter(User_Event.user_uid==self.uid) \ - .filter(Event.for_year==year).count() + .filter(User_Event.user_uid == self.uid) \ + .filter(Event.for_year == year).count() @property def is_crew(self, year=CurrentYear): """ This property will return if User subscribe orga task on specified year """ - orga_checked = DBSession.query(User, Sejour.orga_part)\ + orga_checked = DBSession.query(User, Sejour.orga_part) \ .outerjoin(Sejour) \ - .filter(Sejour.for_year == year)\ + .filter(Sejour.for_year == year) \ .filter(User.uid == self.uid).first() if orga_checked: return orga_checked else: return False - - + def year_events(self, EventType='All', year=CurrentYear): - if EventType=='All': - return filter(lambda e: e.for_year==year, self.events) + if EventType == 'All': + return list(filter(lambda e: e.for_year == year, self.events)) else: - return filter(lambda e: e.for_year==year and e.event_type==EventType, self.events) + return list(filter(lambda e: e.for_year == year and e.event_type == EventType, self.events)) - @property def my_hash(self): m = hashlib.sha1() - m.update("Nobody inspects ") + m.update("Nobody inspects ".encode('utf-8')) if self.nom: - m.update(unicode.encode(self.nom,'utf8')) + m.update(self.nom.encode('utf-8')) # unicode.encode(self.nom, 'utf8')) if self.pseudo: - m.update(unicode.encode(self.pseudo,'utf8')) - if self.prenom: - m.update(unicode.encode(self.prenom,'utf8')) - m.update(" the spammish repetition") + m.update(self.pseudo.encode('utf-8')) # unicode.encode(self.pseudo, 'utf8')) + if self.prenom: + m.update(self.prenom.encode('utf-8')) # unicode.encode(self.prenom, 'utf8')) + m.update(" the spammish repetition".encode('utf-8')) return m.hexdigest() - + @property def Photos(self): return DBSession.query(Media.filename) \ - .filter(Media.media_table=='users') \ - .filter(Media.media_type=='Image') \ + .filter(Media.media_table == 'users') \ + .filter(Media.media_type == 'Image') \ .filter(Media.link_id == self.user_id).all() @property @@ -245,79 +257,81 @@ class User(Base): def PhotosThumb(self): from .upload import MediaPath return MediaPath().get_thumb('users', self.uid) - + def verify_password(self, password): - if not argon2.identify(self.password): # Update existing clear-text password + if not argon2.identify(self.password): # Update existing clear-text password self.password = argon2.using(rounds=4).hash(self.password) DBSession.merge(self) return argon2.verify(password, self.password) + class TiersOpt(Base): __tablename__ = 'tiers_opt' - uid = Column(Integer, primary_key=True) - entity_type = Column(Unicode(80), nullable=False) + uid = Column(Integer, primary_key=True) + entity_type = Column(Unicode(80), nullable=False) entity_subtype = Column(Unicode(80)) - entity_role = Column(Unicode(80)) + entity_role = Column(Unicode(80)) @property def slug_entity_type(self): return slugify(self.entity_type) - + @property def slug_entity_subtype(self): - return slugify(self.entity_subtype) - + return slugify(self.entity_subtype) + @classmethod def get_entity_type(cls): - return DBSession.query(cls, func.count(Tiers.ent_type).label('count'))\ - .outerjoin(Tiers)\ + return DBSession.query(cls, func.count(Tiers.ent_type).label('count')) \ + .outerjoin(Tiers) \ .group_by(cls.entity_type).all() - + @classmethod def get_entity_sub_type(cls, entity_type): - return DBSession.query(cls, func.count(Tiers.ent_type).label('count'))\ - .outerjoin(Tiers)\ - .filter(cls.entity_type == entity_type)\ + return DBSession.query(cls, func.count(Tiers.ent_type).label('count')) \ + .outerjoin(Tiers) \ + .filter(cls.entity_type == entity_type) \ .group_by(cls.entity_subtype).all() - + @classmethod def by_id(cls, uid): - return DBSession.query(cls).filter(cls.uid == uid).first() - + return DBSession.query(cls).filter(cls.uid == uid).first() + + class Tiers(Base): __tablename__ = 'tiers' - uid = Column(Integer, primary_key=True) - tiers_id = Column(Integer) - name = Column(Unicode(100), nullable=False) - slug = Column(Unicode(100)) - description = Column(UnicodeText) - website = Column(Unicode(100)) - tiers_type = Column(Integer, ForeignKey('tiers_opt.uid'), default=1) - created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) + uid = Column(Integer, primary_key=True) + tiers_id = Column(Integer) + name = Column(Unicode(100), nullable=False) + slug = Column(Unicode(100)) + description = Column(UnicodeText) + website = Column(Unicode(100)) + tiers_type = Column(Integer, ForeignKey('tiers_opt.uid'), default=1) + created = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) # relations - ent_type = relationship('TiersOpt') - #members = relationship('User', secondary='user_tiers_link' ) - members = relationship(User, - secondary='user_tiers_link', - backref=backref('associate', uselist=False), - lazy='dynamic') - creator_id = Column(Integer) - membership = relationship('User_Tiers', backref="matching_tiers") - roles = relationship('Role_Tiers', backref="roles_tiers") #secondary='role_tiers_link' ) - + ent_type = relationship('TiersOpt') + # members = relationship('User', secondary='user_tiers_link' ) + members = relationship(User, + secondary='user_tiers_link', + backref=backref('associate', uselist=False), + lazy='dynamic') + creator_id = Column(Integer) + membership = relationship('User_Tiers', backref="matching_tiers") + roles = relationship('Role_Tiers', backref="roles_tiers") # secondary='role_tiers_link' ) + @classmethod def by_id(cls, uid): return DBSession.query(cls).filter(cls.uid == uid).first() - + @classmethod def by_slug(cls, slug): return DBSession.query(cls).filter(cls.slug == slug).first() @property def get_entity_type(self): - return DBSession.query(TiersOpt)\ + return DBSession.query(TiersOpt) \ .filter(TiersOpt.uid == self.tiers_type).first() @property @@ -330,9 +344,9 @@ class Tiers(Base): @property def DocLinks(self): from .upload import MediaPath - return zip( sorted( MediaPath().get_list('tiers', self.uid, 'Other') ), - sorted( MediaPath().get_thumb('tiers', self.uid, 'Other') ) - ) + return zip(sorted(MediaPath().get_list('tiers', self.uid, 'Other')), + sorted(MediaPath().get_thumb('tiers', self.uid, 'Other')) + ) @property def PhotosLinks(self): @@ -344,319 +358,330 @@ class Tiers(Base): from .upload import MediaPath return MediaPath().get_thumb('tiers', self.uid) + class Role_Tiers(Base): """ Créer le lien entre le tiers et son rôle dans l'évenement en fonction de l'année""" __tablename__ = 'role_tiers_link' - uid_role = Column(Integer, primary_key=True) - year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) - tiers_uid = Column(Integer, ForeignKey('tiers.uid')) - tiers = relationship(Tiers, backref=backref("roles_assoc") ) + uid_role = Column(Integer, primary_key=True) + year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) + tiers_uid = Column(Integer, ForeignKey('tiers.uid')) + tiers = relationship(Tiers, backref=backref("roles_assoc")) tiers_role = Column(Enum('Exposant', 'Sponsor', 'Donateur')) - event_uid = Column(Integer, default=None) # Optionnal link with Event + event_uid = Column(Integer, default=None) # Optionnal link with Event + class User_Tiers(Base): """ Créer le lien entre la personne et le tiers en fonction de l'année""" __tablename__ = 'user_tiers_link' uid_tiers = Column(Integer, primary_key=True) - year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) + year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) tiers_uid = Column(Integer, ForeignKey('tiers.uid')) - tiers = relationship(Tiers, backref=backref("users_assoc") ) - user_uid = Column(Integer, ForeignKey('users.uid')) - user = relationship(User, backref=backref("tiers_assoc") ) - role = Column(Unicode(80)) + tiers = relationship(Tiers, backref=backref("users_assoc")) + user_uid = Column(Integer, ForeignKey('users.uid')) + user = relationship(User, backref=backref("tiers_assoc")) + role = Column(Unicode(80)) + class Media(Base): __tablename__ = 'medias' - media_id = Column(Integer, primary_key=True) - for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) - media_table = Column(Enum('users', 'tiers', 'place', 'salle', 'RIB', 'Justif', 'event' )) - media_type = Column(Enum('Image', 'Video', 'Pres', 'Document')) - link_id = Column(Integer) - mime_type = Column(Unicode(20)) - size = Column(Integer) - width = Column(Integer) - height = Column(Integer) - length = Column(Integer) - filename = Column(UnicodeText) - created = Column(DateTime, default=datetime.datetime.now) - + media_id = Column(Integer, primary_key=True) + for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) + media_table = Column(Enum('users', 'tiers', 'place', 'salle', 'RIB', 'Justif', 'event')) + media_type = Column(Enum('Image', 'Video', 'Pres', 'Document')) + link_id = Column(Integer) + mime_type = Column(Unicode(20)) + size = Column(Integer) + width = Column(Integer) + height = Column(Integer) + length = Column(Integer) + filename = Column(UnicodeText) + created = Column(DateTime, default=datetime.datetime.now) + @property def get_path(self): - #return '/upload/%s/%s/%s' % (self.media_type, self.media_table, self.filename) + # return '/upload/%s/%s/%s' % (self.media_type, self.media_table, self.filename) return '/resources/%s/%s/%s' % (self.for_year, self.media_type, self.filename) + class SallePhy(Base): """ Représente une salle dans les locaux """ __tablename__ = 'phy_salle' - uid = Column(Integer, primary_key=True) - name = Column(Unicode(40)) # Numéro de salle vu de polytech - slug = Column(Unicode(40)) - description = Column(UnicodeText) # Description du matériel disponible - nb_places = Column(Integer, default=0) # Nombre de places assises - + uid = Column(Integer, primary_key=True) + name = Column(Unicode(40)) # Numéro de salle vu de polytech + slug = Column(Unicode(40)) + description = Column(UnicodeText) # Description du matériel disponible + nb_places = Column(Integer, default=0) # Nombre de places assises + @classmethod def by_id(cls, uid): - return DBSession.query(cls).filter(cls.uid == uid).first() + return DBSession.query(cls).filter(cls.uid == uid).first() @property def PhotosLinks(self): from .upload import MediaPath return MediaPath().get_list('salle', self.uid, 'Image') - + + class Salles(Base): __tablename__ = 'salle' - salle_id = Column(Integer, primary_key=True) - phy_salle_id = Column(Integer, ForeignKey('phy_salle.uid')) - year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) - name = Column(Unicode(40)) - place_type = Column(Enum('Conference', 'Stand', 'Atelier', 'Table ronde', 'MAO', 'Repas', 'Autres')) - description = Column(UnicodeText) # Description du matériel disponible - created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) - - phy = relationship(SallePhy) + salle_id = Column(Integer, primary_key=True) + phy_salle_id = Column(Integer, ForeignKey('phy_salle.uid')) + year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) + name = Column(Unicode(40)) + place_type = Column(Enum('Conference', 'Stand', 'Atelier', 'Table ronde', 'MAO', 'Repas', 'Autres')) + description = Column(UnicodeText) # Description du matériel disponible + created = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) + + phy = relationship(SallePhy) + @classmethod def by_id(cls, uid): return DBSession.query(cls).filter(cls.salle_id == uid).first() + class Place(Base): __tablename__ = 'place' - place_id = Column(Integer, primary_key=True) - usage = Column(Boolean, default=False) # By Default / Extended - place_type = Column(Enum('Aeroport', 'Gare', 'JM2L', \ - 'Hotel', 'Habitant', 'Restaurant', 'Autres')) - display_name = Column(Unicode(20)) - name = Column(Unicode(80)) - slug = Column(Unicode(80)) - specific = Column(Unicode(80)) # eg Terminal 2 - gps_coord = Column(Unicode(30)) - adresse = Column(Unicode(100)) - codePostal = Column(Unicode(5)) - ville = Column(Unicode(40)) - website = Column(Unicode(100)) - description = Column(UnicodeText) - created_by = Column(Integer, ForeignKey('users.user_id')) - created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) + place_id = Column(Integer, primary_key=True) + usage = Column(Boolean, default=False) # By Default / Extended + place_type = Column(Enum('Aeroport', 'Gare', 'JM2L', \ + 'Hotel', 'Habitant', 'Restaurant', 'Autres')) + display_name = Column(Unicode(20)) + name = Column(Unicode(80)) + slug = Column(Unicode(80)) + specific = Column(Unicode(80)) # eg Terminal 2 + gps_coord = Column(Unicode(30)) + adresse = Column(Unicode(100)) + codePostal = Column(Unicode(5)) + ville = Column(Unicode(40)) + website = Column(Unicode(100)) + description = Column(UnicodeText) + created_by = Column(Integer, ForeignKey('users.user_id')) + created = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) @classmethod def by_id(cls, uid): return DBSession.query(cls).filter(cls.place_id == uid).first() - + @classmethod def get_list(cls, All=False): if All: return DBSession.query(cls).all() else: - return DBSession.query(cls).filter(cls.usage==True).all() + return DBSession.query(cls).filter(cls.usage == True).all() + class Itineraire(Base): __tablename__ = 'itineraire' - itin_id = Column(Integer, primary_key=True) - start_place = Column(Integer, ForeignKey('place.place_id')) # Place link - arrival_place = Column(Integer, ForeignKey('place.place_id')) # Place link - distance = Column(Integer) - duration = Column(Integer) - price = Column(Integer) - tr_pied = Column(Boolean, default=False) - tr_velo = Column(Boolean, default=False) - tr_moto = Column(Boolean, default=False) - tr_voiture = Column(Boolean, default=False) - tr_bus = Column(Boolean, default=False) - tr_taxi = Column(Boolean, default=False) - tr_avion = Column(Boolean, default=False) - description = Column(UnicodeText) - created_by = Column(Integer, ForeignKey('users.user_id')) # User link - created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) + itin_id = Column(Integer, primary_key=True) + start_place = Column(Integer, ForeignKey('place.place_id')) # Place link + arrival_place = Column(Integer, ForeignKey('place.place_id')) # Place link + distance = Column(Integer) + duration = Column(Integer) + price = Column(Integer) + tr_pied = Column(Boolean, default=False) + tr_velo = Column(Boolean, default=False) + tr_moto = Column(Boolean, default=False) + tr_voiture = Column(Boolean, default=False) + tr_bus = Column(Boolean, default=False) + tr_taxi = Column(Boolean, default=False) + tr_avion = Column(Boolean, default=False) + description = Column(UnicodeText) + created_by = Column(Integer, ForeignKey('users.user_id')) # User link + created = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) # relations - start = relationship(Place, foreign_keys=[start_place]) - arrival = relationship(Place, foreign_keys=[arrival_place]) + start = relationship(Place, foreign_keys=[start_place]) + arrival = relationship(Place, foreign_keys=[arrival_place]) + class Exchange_Cat(Base): __tablename__ = 'exchange_category' - cat_id = Column(Integer, primary_key=True) - exch_type = Column(Enum('H', 'C', 'M')) # Heberg, Co-voit, Materiel - exch_subtype = Column(Unicode(80)) - description = Column(UnicodeText) + cat_id = Column(Integer, primary_key=True) + exch_type = Column(Enum('H', 'C', 'M')) # Heberg, Co-voit, Materiel + exch_subtype = Column(Unicode(80)) + description = Column(UnicodeText) + class Exchange(Base): __tablename__ = 'exchanges' - exch_id = Column(Integer, primary_key=True) - for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year - exch_done = Column(Boolean, default=False) - exch_state = Column(Enum('Ask', 'Proposal')) - exch_type = Column(Enum('H', 'C', 'M')) # Heberg, Co-Voit, Materiel - exch_categ = Column(Integer, ForeignKey('exchange_category.cat_id')) # Exchange_Cat link + exch_id = Column(Integer, primary_key=True) + for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year + exch_done = Column(Boolean, default=False) + exch_state = Column(Enum('Ask', 'Proposal')) + exch_type = Column(Enum('H', 'C', 'M')) # Heberg, Co-Voit, Materiel + exch_categ = Column(Integer, ForeignKey('exchange_category.cat_id')) # Exchange_Cat link # Users - asker_id = Column(Integer, ForeignKey('users.uid')) # User link - provider_id = Column(Integer, ForeignKey('users.uid')) # User link - start_time = Column(DateTime, default=datetime.datetime.now) - end_time = Column(DateTime, default=datetime.datetime.now) + asker_id = Column(Integer, ForeignKey('users.uid')) # User link + provider_id = Column(Integer, ForeignKey('users.uid')) # User link + start_time = Column(DateTime, default=datetime.datetime.now) + end_time = Column(DateTime, default=datetime.datetime.now) # Co-voiturage - itin_id = Column(Integer, ForeignKey('itineraire.itin_id')) # Itineraire link + itin_id = Column(Integer, ForeignKey('itineraire.itin_id')) # Itineraire link # Hebergement - place_id = Column(Integer, ForeignKey('place.place_id')) # Place link + place_id = Column(Integer, ForeignKey('place.place_id')) # Place link # Materiel - duration = Column(Integer) - description = Column(UnicodeText) - pictures = Column(Unicode(80)) - created_by = Column(Integer) # User link - created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) + duration = Column(Integer) + description = Column(UnicodeText) + pictures = Column(Unicode(80)) + created_by = Column(Integer) # User link + created = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) # relations - Category = relationship(Exchange_Cat, backref="exchanges") - Itin = relationship(Itineraire, backref="exchanged") - asker = relationship(User, foreign_keys=[asker_id], backref="asked") - provider = relationship(User, foreign_keys=[provider_id], backref="provided") - + Category = relationship(Exchange_Cat, backref="exchanges") + Itin = relationship(Itineraire, backref="exchanged") + asker = relationship(User, foreign_keys=[asker_id], backref="asked") + provider = relationship(User, foreign_keys=[provider_id], backref="provided") + @classmethod def by_id(cls, uid): - return DBSession.query(cls).filter(cls.exch_id == uid).first() + return DBSession.query(cls).filter(cls.exch_id == uid).first() @classmethod def get_counters(cls): - return DBSession.query(cls.exch_state, cls.exch_type, cls.exch_done, func.count(cls.exch_id))\ - .filter(cls.for_year==CurrentYear)\ + return DBSession.query(cls.exch_state, cls.exch_type, cls.exch_done, func.count(cls.exch_id)) \ + .filter(cls.for_year == CurrentYear) \ .group_by(cls.exch_state, cls.exch_type, cls.exch_done) @classmethod def get_my_counters(cls, uid): - return DBSession.query(cls.exch_state, cls.exch_type, cls.exch_done, func.count(cls.exch_id))\ - .filter(cls.for_year==CurrentYear)\ - .filter( or_(cls.asker_id==uid, cls.provider_id==uid) )\ - .group_by(cls.exch_state, cls.exch_type, cls.exch_done) - + return DBSession.query(cls.exch_state, cls.exch_type, cls.exch_done, func.count(cls.exch_id)) \ + .filter(cls.for_year == CurrentYear) \ + .filter(or_(cls.asker_id == uid, cls.provider_id == uid)) \ + .group_by(cls.exch_state, cls.exch_type, cls.exch_done) + @classmethod def get_overview(cls, uid): # Build a Dic with all exchange to save database access - DicResult= {} - for extype in ['F','C','H','M']: + DicResult = {} + for extype in ['F', 'C', 'H', 'M']: DicResult[extype] = {} - for exstate in ['Ask','Proposal','Missing','Agree']: - DicResult[extype][exstate]=[] - DicResult[extype]['Counters']={'AllAsk':0, 'AllProp':0, 'AllAgree':0} - Query = DBSession.query(cls)\ - .filter(cls.for_year==CurrentYear)\ + for exstate in ['Ask', 'Proposal', 'Missing', 'Agree']: + DicResult[extype][exstate] = [] + DicResult[extype]['Counters'] = {'AllAsk': 0, 'AllProp': 0, 'AllAgree': 0} + Query = DBSession.query(cls) \ + .filter(cls.for_year == CurrentYear) \ .order_by(cls.start_time).all() for item in Query: if item.exch_done: - DicResult[item.exch_type]['Counters']['AllAgree']+=1 - if item.exch_state=='Ask': - DicResult[item.exch_type]['Counters']['AllAsk']+=1 - if item.exch_state=='Proposal': - DicResult[item.exch_type]['Counters']['AllProp']+=1 - if item.asker_id==uid or item.provider_id==uid: - if item.asker_id==uid and item.exch_state=='Ask': + DicResult[item.exch_type]['Counters']['AllAgree'] += 1 + if item.exch_state == 'Ask': + DicResult[item.exch_type]['Counters']['AllAsk'] += 1 + if item.exch_state == 'Proposal': + DicResult[item.exch_type]['Counters']['AllProp'] += 1 + if item.asker_id == uid or item.provider_id == uid: + if item.asker_id == uid and item.exch_state == 'Ask': DicResult[item.exch_type]['Ask'].append(item) - if item.provider_id==uid and item.exch_state=='Ask': + if item.provider_id == uid and item.exch_state == 'Ask': DicResult[item.exch_type]['Proposal'].append(item) - if item.asker_id==uid and item.exch_state=='Proposal': + if item.asker_id == uid and item.exch_state == 'Proposal': DicResult[item.exch_type]['Ask'].append(item) - if item.provider_id==uid and item.exch_state=='Proposal': + if item.provider_id == uid and item.exch_state == 'Proposal': DicResult[item.exch_type]['Proposal'].append(item) if item.exch_done: DicResult[item.exch_type]['Agree'].append(item) else: - DicResult[item.exch_type]['Missing'].append(item) - + DicResult[item.exch_type]['Missing'].append(item) + return DicResult - + @classmethod def get_pub_list(cls, exch_type): - return DBSession.query(cls).filter(cls.for_year==CurrentYear and cls.exch_state in ['Ask','Proposal'])\ - .filter(cls.exch_type=='%s' % exch_type)\ - .filter(cls.exch_done==False)\ + return DBSession.query(cls).filter(cls.for_year == CurrentYear and cls.exch_state in ['Ask', 'Proposal']) \ + .filter(cls.exch_type == '%s' % exch_type) \ + .filter(cls.exch_done == False) \ .all() - + @classmethod def get_my_list(cls, uid, exch_type): DicResult = {} - DicResult['Ask']=DBSession.query(cls)\ - .filter(cls.for_year==CurrentYear)\ - .filter( or_(cls.asker_id==uid, cls.provider_id==uid) )\ - .filter(cls.exch_type=='%s' % exch_type)\ - .filter(cls.exch_state=='Ask')\ + DicResult['Ask'] = DBSession.query(cls) \ + .filter(cls.for_year == CurrentYear) \ + .filter(or_(cls.asker_id == uid, cls.provider_id == uid)) \ + .filter(cls.exch_type == '%s' % exch_type) \ + .filter(cls.exch_state == 'Ask') \ .order_by(cls.start_time).all() - DicResult['Proposal']=DBSession.query(cls)\ - .filter(cls.for_year==CurrentYear)\ - .filter( or_(cls.asker_id==uid, cls.provider_id==uid) )\ - .filter(cls.exch_type=='%s' % exch_type)\ - .filter(cls.exch_state=='Proposal')\ + DicResult['Proposal'] = DBSession.query(cls) \ + .filter(cls.for_year == CurrentYear) \ + .filter(or_(cls.asker_id == uid, cls.provider_id == uid)) \ + .filter(cls.exch_type == '%s' % exch_type) \ + .filter(cls.exch_state == 'Proposal') \ .order_by(cls.start_time).all() return DicResult - + + class Sejour(Base): __tablename__ = 'sejour' - sej_id = Column(Integer, primary_key=True) - user_id = Column(Integer, ForeignKey('users.uid')) # User link - for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year - arrival_time = Column(DateTime) - arrival_place = Column(Integer, ForeignKey('place.place_id')) # Place link + sej_id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey('users.uid')) # User link + for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year + arrival_time = Column(DateTime) + arrival_place = Column(Integer, ForeignKey('place.place_id')) # Place link arrival_check = Column(Integer, default=0) - arrival_text = Column(Unicode(100)) - depart_time = Column(DateTime) - depart_place = Column(Integer, ForeignKey('place.place_id')) # Place link - depart_check = Column(Integer, default=0) - depart_text = Column(Unicode(100)) - repas = Column(Integer) - repas_allerg = Column(Unicode(100)) - repas_contr = Column(Unicode(100)) - orga_part = Column(Integer, default=0) + arrival_text = Column(Unicode(100)) + depart_time = Column(DateTime) + depart_place = Column(Integer, ForeignKey('place.place_id')) # Place link + depart_check = Column(Integer, default=0) + depart_text = Column(Unicode(100)) + repas = Column(Integer) + repas_allerg = Column(Unicode(100)) + repas_contr = Column(Unicode(100)) + orga_part = Column(Integer, default=0) travel_detail = Column(UnicodeText) - created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) - + created = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) + @classmethod def by_user(cls, uid, year): - return DBSession.query(cls)\ - .filter(cls.user_id == uid)\ - .filter(cls.for_year == year)\ - .first() + return DBSession.query(cls) \ + .filter(cls.user_id == uid) \ + .filter(cls.for_year == year) \ + .first() + class Event(Base): __tablename__ = 'events' - uid = Column(Integer, primary_key=True) - salle_uid = Column(Integer, ForeignKey('salle.salle_id')) - event_uid = Column(Integer) - for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year - name = Column(Unicode(100), nullable=False) - slug = Column(Unicode(100)) - event_type = Column(Enum('Conference', 'Stand', 'Atelier', 'Table ronde', 'MAO', 'Repas', 'Autres')) - start_time = Column(DateTime, default=datetime.datetime.now) - end_time = Column(DateTime, default=datetime.datetime.now) - description = Column(UnicodeText) - created = Column(DateTime, default=datetime.datetime.now) - last_change = Column(DateTime, default=datetime.datetime.now) - intervenants = relationship(User, - secondary='user_event_link', - backref=backref('participate', uselist=False), - lazy='dynamic') + uid = Column(Integer, primary_key=True) + salle_uid = Column(Integer, ForeignKey('salle.salle_id')) + event_uid = Column(Integer) + for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year + name = Column(Unicode(100), nullable=False) + slug = Column(Unicode(100)) + event_type = Column(Enum('Conference', 'Stand', 'Atelier', 'Table ronde', 'MAO', 'Repas', 'Autres')) + start_time = Column(DateTime, default=datetime.datetime.now) + end_time = Column(DateTime, default=datetime.datetime.now) + description = Column(UnicodeText) + created = Column(DateTime, default=datetime.datetime.now) + last_change = Column(DateTime, default=datetime.datetime.now) + intervenants = relationship(User, + secondary='user_event_link', + backref=backref('participate', uselist=False), + lazy='dynamic') interventions = relationship(User_Event, backref="matching_events") - Salle = relationship(Salles, backref='allevents') - + Salle = relationship(Salles, backref='allevents') + @classmethod def by_id(cls, uid): - return DBSession.query(cls)\ + return DBSession.query(cls) \ .filter(cls.uid == uid).first() - @classmethod def by_slug(cls, slug, year=None): if not year is None: - return DBSession.query(cls)\ - .filter(cls.for_year==year)\ + return DBSession.query(cls) \ + .filter(cls.for_year == year) \ .filter(cls.slug == slug).first() else: - return DBSession.query(cls)\ + return DBSession.query(cls) \ .filter(cls.slug == slug).first() def get_linked_tiers(self): ListLink = DBSession.query(Role_Tiers.tiers_uid) \ - .filter(Role_Tiers.year_uid==self.for_year) \ - .filter(Role_Tiers.tiers_role=="Exposant") \ - .filter(Role_Tiers.event_uid==self.uid) - return DBSession.query(Tiers).filter( Tiers.uid.in_( ListLink ) ) + .filter(Role_Tiers.year_uid == self.for_year) \ + .filter(Role_Tiers.tiers_role == "Exposant") \ + .filter(Role_Tiers.event_uid == self.uid) + return DBSession.query(Tiers).filter(Tiers.uid.in_(ListLink)) @property def video(self): @@ -671,42 +696,44 @@ class Event(Base): .filter(Media.media_table == 'event') \ .filter(Media.media_type == 'Pres') \ .filter(Media.link_id == self.uid) - + @property def created_in_words(self): return time_ago_in_words(self.created) - + + class Entry(Base): __tablename__ = 'entries' id = Column(Integer, primary_key=True) - active = Column(Integer, default=True) - title = Column(Unicode(255), unique=True, nullable=False) - body = Column(UnicodeText, default=u'') - created = Column(DateTime, default=datetime.datetime.now) - edited = Column(DateTime, default=datetime.datetime.now) - + active = Column(Integer, default=True) + title = Column(Unicode(255), unique=True, nullable=False) + body = Column(UnicodeText, default=u'') + created = Column(DateTime, default=datetime.datetime.now) + edited = Column(DateTime, default=datetime.datetime.now) + @classmethod def all(cls): return DBSession.query(Entry).order_by(sa.desc(Entry.created)) - + @classmethod def by_id(cls, uid): return DBSession.query(Entry).filter(Entry.id == uid).first() - + @property def slug(self): return urlify(self.title) - + @property def created_in_words(self): return time_ago_in_words(self.created) - + @classmethod def get_paginator(cls, request, page=1): page_url = PageURL_WebOb(request) return Page(Entry.all(), page, url=page_url, items_per_page=5) -#class Seances(Base): + +# class Seances(Base): # __tablename__ = 'seances' def get_user(request): # the below line is just an example, use your own method of @@ -717,28 +744,28 @@ def get_user(request): if userid is not None: # this should return None if the user doesn't exist # in the database - return DBSession.query(User).filter(User.uid==userid).first() + return DBSession.query(User).filter(User.uid == userid).first() def get_sponsors(request, Year): if Year: - return DBSession.query(Tiers)\ - .join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid )\ - .filter( Role_Tiers.tiers_role == 'Sponsor')\ - .filter( Role_Tiers.year_uid == Year) + return DBSession.query(Tiers) \ + .join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid) \ + .filter(Role_Tiers.tiers_role == 'Sponsor') \ + .filter(Role_Tiers.year_uid == Year) else: - return DBSession.query(Tiers)\ - .join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid )\ - .filter( Role_Tiers.tiers_role == 'Sponsor') + return DBSession.query(Tiers) \ + .join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid) \ + .filter(Role_Tiers.tiers_role == 'Sponsor') + def get_exposants(request, Year): if Year: - return DBSession.query(Tiers)\ - .join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid )\ - .filter( Role_Tiers.tiers_role == 'Exposant')\ - .filter( Role_Tiers.year_uid == Year) + return DBSession.query(Tiers) \ + .join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid) \ + .filter(Role_Tiers.tiers_role == 'Exposant') \ + .filter(Role_Tiers.year_uid == Year) else: - return DBSession.query(Tiers)\ - .join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid )\ - .filter( Role_Tiers.tiers_role == 'Exposant') - + return DBSession.query(Tiers) \ + .join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid) \ + .filter(Role_Tiers.tiers_role == 'Exposant') diff --git a/jm2l/scripts/initializedb.py b/jm2l/scripts/initializedb.py index cda8d2e..5cb67dd 100644 --- a/jm2l/scripts/initializedb.py +++ b/jm2l/scripts/initializedb.py @@ -48,14 +48,14 @@ def pull_data(from_db, to_db, tables): destination, dengine = make_session(to_db) for table_name in tables: - print 'Processing', table_name - print 'Pulling schema from source server' + print('Processing', table_name) + print('Pulling schema from source server') table = Table(table_name, smeta, autoload=True) - print 'Creating table on destination server' + print('Creating table on destination server') table.metadata.create_all(dengine) NewRecord = quick_mapper(table) columns = table.columns.keys() - print 'Transferring records' + print('Transferring records') for record in source.query(table).all(): data = dict( [(str(column), getattr(record, column)) for column in columns] @@ -69,20 +69,20 @@ def pull_data(from_db, to_db, tables): try: destination.merge(NewRecord(**data)) except: - print data + print(data) pass - print 'Committing changes' + print('Committing changes') destination.commit() def main(argv=sys.argv): - connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite" + connection_string = "sqlite:////home/tr4ck3ur/git_repository/jm2l/JM2L.sqlite" engine = create_engine(connection_string, echo=False, convert_unicode=True) DBSession.configure(bind=engine) Users = DBSession.query(User) ListUser = filter(lambda x: x.is_Intervenant, Users) for i in ListUser: - print i.mail + print(i.mail) def main4(argv=sys.argv): import csv @@ -116,7 +116,7 @@ def main4(argv=sys.argv): u.wifi_user = w_user u.wifi_pass = w_pass DBSession.merge(u) - print row, u + print(row, u) finally: f.close() @@ -130,7 +130,7 @@ def main_3(argv=sys.argv): connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite" engine = create_engine(connection_string, echo=True, convert_unicode=True) DBSession.configure(bind=engine) - p0, p1 = orm.aliased(User,name="p0"), orm.aliased(User ,name="p1") + p0, p1 = orm.aliased(User, name="p0"), orm.aliased(User , name="p1") import pprint ## permtation @@ -141,7 +141,7 @@ def main_3(argv=sys.argv): .filter(p0.last_logged${reason}

% else: -

Vous n'êtes pas authentifié, ou n'avez pas les authorisations nécessaires.

+

Vous n'êtes pas authentifié, ou n'avez pas les authorisations nécessaires.

% endif diff --git a/jm2l/templates/Errors/404.mako b/jm2l/templates/Errors/404.mako index addc398..6379cd4 100644 --- a/jm2l/templates/Errors/404.mako +++ b/jm2l/templates/Errors/404.mako @@ -54,7 +54,7 @@ -

Page non trouvée

+

Page non trouvée

% if reason:

${reason}

% else: diff --git a/jm2l/templates/Interventions/Interventions.mako b/jm2l/templates/Interventions/Interventions.mako index a783f67..29d765f 100644 --- a/jm2l/templates/Interventions/Interventions.mako +++ b/jm2l/templates/Interventions/Interventions.mako @@ -10,7 +10,7 @@ - Conférences + Conférences % if len( request.user.year_events('Conference') ): % for evt in request.user.year_events('Conference'): % endfor @@ -106,11 +106,11 @@ elif Type=='T': %> % if Type!='O':
- Vos ${CurTitles} programmés pour ${CurrentYear} + Vos ${CurTitles} programmés pour ${CurrentYear} <% -Selection = filter(lambda x:(x.event_type==CurEventType and x.for_year==CurrentYear), uprofil.events) +Selection = list(filter(lambda x:(x.event_type==CurEventType and x.for_year==CurrentYear), uprofil.events)) HeadHistTitle = u"L'historique de vos %s ( %d ) " % ( CurTitles, len(Selection) ) -NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent +NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent %> ${helpers.show_Interventions(Selection, "Sujet", NothingTitle )}
@@ -118,21 +118,21 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent % if Type=='C':

- Proposer une conférence / un lighting talk
+ Proposer une conférence / un lighting talk

- Nous serons heureux de vous écouter. + Nous serons heureux de vous écouter.
- Nous souhaitons proposer des conférences pour un public débutant + Nous souhaitons proposer des conférences pour un public débutant autant que pour des visiteurs avertis. Les sujets ne doivent pas - forcément être techniques, mais aussi d’ordre général avec la seule + forcément être techniques, mais aussi d’ordre général avec la seule contrainte de traiter de près ou de loin des logiciels libres, de la - communauté ou de vos propres expériences d’utilisateur quotidien.
+ communauté ou de vos propres expériences d’utilisateur quotidien.
Le but de ces conférences est double : @@ -90,7 +90,7 @@ fieldset:disabled {
- Départ + Départ
Je repars - d'assistance : Personne à mobilité réduite (PMR) + + d'assistance : Personne à mobilité réduite (PMR)
  • @@ -151,7 +151,7 @@ fieldset:disabled { Autres + placeholder="Précisions à propos de mon départ…" />
  • diff --git a/jm2l/templates/Public/Programme.mako b/jm2l/templates/Public/Programme.mako index 42cb752..d45f06e 100644 --- a/jm2l/templates/Public/Programme.mako +++ b/jm2l/templates/Public/Programme.mako @@ -111,7 +111,7 @@ if Counter==0: vid = event.video.first() pres = event.presentation.first() %> - ${event.start_time.strftime("%a %d %b").decode('utf-8')}
    + ${event.start_time.strftime("%a %d %b")}
    ${event.start_time.strftime("%H:%M")} - ${event.end_time.strftime("%H:%M")} diff --git a/jm2l/templates/Salles/list_phy.mako b/jm2l/templates/Salles/list_phy.mako index 23aaa29..5b4959a 100644 --- a/jm2l/templates/Salles/list_phy.mako +++ b/jm2l/templates/Salles/list_phy.mako @@ -24,7 +24,7 @@ from slugify import slugify % if len(DicSallePhy)==0: - Il n'y a pas de salle définie pour le moment. + Il n'y a pas de salle définie pour le moment. % endif @@ -43,7 +43,7 @@ from slugify import slugify % if SallePhy.uid: [ ${SallePhy.nb_places} places ] % else: - [ Créer ] + [ Créer ] % endif diff --git a/jm2l/templates/Salles/salle.mako b/jm2l/templates/Salles/salle.mako index 8bdcb49..cb53667 100644 --- a/jm2l/templates/Salles/salle.mako +++ b/jm2l/templates/Salles/salle.mako @@ -29,9 +29,9 @@ %endif <% DicForm = { - 'year_uid': {'PlaceHolder':u"Année", "FieldStyle":"width:7em;", "ContainerStyle":"float:left;" }, + 'year_uid': {'PlaceHolder':u"Année", "FieldStyle":"width:7em;", "ContainerStyle":"float:left;" }, 'phy_salle_id': {'PlaceHolder':u"Salle Physique", "FieldStyle":"width:20em;", "ContainerStyle":"float:left;" }, - 'place_type': {'PlaceHolder':u"Type d'évènement","FieldStyle":"width:15em;" }, + 'place_type': {'PlaceHolder':u"Type d'évènement","FieldStyle":"width:15em;" }, 'name': {'PlaceHolder':u"Nom de la salle", "FieldStyle":"width:90%;" }, 'description': {'PlaceHolder':u"Description", "ContainerStyle":"width:95%;min-height:150px;padding-top: 12px;", "ckeditor":"1" }, } diff --git a/jm2l/templates/Staff/compta.mako b/jm2l/templates/Staff/compta.mako index e734fa4..90c874f 100644 --- a/jm2l/templates/Staff/compta.mako +++ b/jm2l/templates/Staff/compta.mako @@ -46,7 +46,7 @@ % endif - % for item, one_dic in found.iteritems(): + % for item, one_dic in found.items(): diff --git a/jm2l/templates/Staff/list.mako b/jm2l/templates/Staff/list.mako index ce0ce39..2558733 100644 --- a/jm2l/templates/Staff/list.mako +++ b/jm2l/templates/Staff/list.mako @@ -63,7 +63,7 @@ from slugify import slugify - ${task.assignee.pseudo or ' '.join([task.assignee.prenom, task.assignee.nom]) } - - ${task.due_date.strftime("%d %b").decode("utf-8")} + - ${task.due_date.strftime("%d %b")} % endif diff --git a/jm2l/templates/edit_event.mako b/jm2l/templates/edit_event.mako index 765612d..99771da 100644 --- a/jm2l/templates/edit_event.mako +++ b/jm2l/templates/edit_event.mako @@ -30,7 +30,7 @@ %endif % if 'uid' in form._fields:
    - ${event.start_time.strftime('%d %b %Y').decode('utf-8')} - + ${event.start_time.strftime('%d %b %Y')} - ${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} %if event.Salle: - Salle: ${event.Salle.name} @@ -184,10 +184,10 @@ DicForm = {
     
    -

    Créé le ${event.created.strftime('%d %b %Y').decode('utf-8')}

    +

    Créé le ${event.created.strftime('%d %b %Y')}

    %else:

    Créé le - ${datetime.now().strftime('%d %b %Y').decode('utf-8')} + ${datetime.now().strftime('%d %b %Y')}

    % endif
    diff --git a/jm2l/templates/helpers.mako b/jm2l/templates/helpers.mako index 22a3d3e..53b9054 100644 --- a/jm2l/templates/helpers.mako +++ b/jm2l/templates/helpers.mako @@ -7,7 +7,7 @@ TabJs = {'select':[], 'desc':[]} %>
    % for FieldName, Field in form._fields.items(): - % if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("Ignore"): + % if Field.name in DicFormat and DicFormat[Field.name].get("Ignore"): <% continue %> % endif % if Field.type in ['HiddenField', 'CSRFTokenField']: @@ -27,7 +27,7 @@ TabJs = {'select':[], 'desc':[]} % endif - % if DicFormat.has_key(Field.name): + % if Field.name in DicFormat: <% PlaceHolder = DicFormat[Field.name].get("PlaceHolder") Class = [False,"ckeditor"][ "ckeditor" in DicFormat[Field.name] ] @@ -49,7 +49,7 @@ TabJs = {'select':[], 'desc':[]} % endfor
    -% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("next")==True: +% if Field.name in DicFormat and DicFormat[Field.name].get("next")==True:
    % endif @@ -72,7 +72,7 @@ TabJs = {'select':[], 'desc':[]} TabJs = {'select':[], 'desc':[]} %> % for FieldName, Field in form._fields.items(): - % if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("Ignore"): + % if Field.name in DicFormat and DicFormat[Field.name].get("Ignore"): <% continue %> % endif % if Field.type in ['HiddenField', 'CSRFTokenField']: @@ -81,11 +81,11 @@ TabJs = {'select':[], 'desc':[]} % elif Field.type=="SelectField": <% TabJs['select'].append(Field.label.field_id) %> % endif -% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("fieldset"): +% if Field.name in DicFormat and DicFormat[Field.name].get("fieldset"):
    ${Field.label.text} % else: - % if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("ContainerStyle"): + % if Field.name in DicFormat and DicFormat[Field.name].get("ContainerStyle"):
    % else:
    @@ -101,7 +101,7 @@ TabJs = {'select':[], 'desc':[]} % endif % endif - % if DicFormat.has_key(Field.name): + % if Field.name in DicFormat: <% PlaceHolder = DicFormat[Field.name].get("PlaceHolder") FieldStyle = DicFormat[Field.name].get("FieldStyle") @@ -122,7 +122,7 @@ TabJs = {'select':[], 'desc':[]} ${ error }
    % endfor -% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("fieldset"): +% if Field.name in DicFormat and DicFormat[Field.name].get("fieldset"):
    % else:
    @@ -142,7 +142,7 @@ TabJs = {'select':[], 'desc':[]} <%def name="sejour_wrapper(Places)">
    - Départ : + Départ : % for place in Places: @@ -184,7 +184,7 @@ TabJs = {'select':[], 'desc':[]} ${itin_form.arrival_place(style='width:17em;')}
    - Si je n´ai pas trouvé le lieu dont j´ai besoin dans ces listes... + Si je n´ai pas trouvé le lieu dont j´ai besoin dans ces listes...
    Je peux @@ -350,9 +350,9 @@ TabJs = {'select':[], 'desc':[]} % if NotFoundTitle: - ${NotFoundTitle} + ${NotFoundTitle | h} % else: - Désolé, Il n'y a rien dans l'historique. + Désolé;, Il n'y a rien dans l'historique. % endif @@ -366,7 +366,7 @@ TabJs = {'select':[], 'desc':[]} vid = event.video.first() pres = event.presentation.first() %> - ${event.start_time.strftime('%d %b %Y').decode('utf-8')} + ${event.start_time.strftime('%d %b %Y')} ${start.hour}:${"%.2d" % start.minute}-${end.hour}:${"%.2d" % end.minute} ${event.event_type}: diff --git a/jm2l/templates/jm2l.mako b/jm2l/templates/jm2l.mako index cda6be0..48ed3bb 100644 --- a/jm2l/templates/jm2l.mako +++ b/jm2l/templates/jm2l.mako @@ -61,7 +61,7 @@
    diff --git a/jm2l/templates/view_event.mako b/jm2l/templates/view_event.mako index b7f87dd..31381e7 100644 --- a/jm2l/templates/view_event.mako +++ b/jm2l/templates/view_event.mako @@ -13,7 +13,7 @@
    ${event.event_type}:
    - ${event.start_time.strftime('%d %b %Y').decode('utf-8')} - + ${event.start_time.strftime('%d %b %Y')} - ${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')}
    % if event.for_year==CurrentYear and request.user and (request.user.Staff or request.user in event.intervenants): @@ -116,7 +116,7 @@

    % endfor
     
    -

    Créé le ${event.created.strftime('%d %b %Y').decode('utf-8')}

    +

    Créé le ${event.created.strftime('%d %b %Y')}



    diff --git a/jm2l/templates/view_tiers.mako b/jm2l/templates/view_tiers.mako index dbc8ad6..2c87c29 100644 --- a/jm2l/templates/view_tiers.mako +++ b/jm2l/templates/view_tiers.mako @@ -103,7 +103,7 @@ ${The_entity_type.entity_subtype}

    % endfor

    -

    Créé le ${entity.created.strftime('%d %b %Y').decode('utf-8')}

    +

    Créé le ${entity.created.strftime('%d %b %Y')}



    diff --git a/jm2l/templates/view_user.mako b/jm2l/templates/view_user.mako index f058e70..87a87f3 100644 --- a/jm2l/templates/view_user.mako +++ b/jm2l/templates/view_user.mako @@ -47,7 +47,7 @@

    Ses interventions :

    ${helpers.show_Interventions(DispUser.events)} % endif -

    Créé le ${DispUser.created.strftime('%d %b %Y').decode('utf-8')}

    +

    Créé le ${DispUser.created.strftime('%d %b %Y')}

    \ No newline at end of file diff --git a/jm2l/to_print.py b/jm2l/to_print.py index 82102de..2560e12 100644 --- a/jm2l/to_print.py +++ b/jm2l/to_print.py @@ -1,6 +1,9 @@ # -*- coding: utf8 -*- from pyramid.response import Response -import cStringIO as StringIO +try: + from StringIO import StringIO +except ImportError: + from io import StringIO from pyramid.view import view_config from .models import DBSession, Event, Salles from reportlab.pdfgen import canvas diff --git a/jm2l/upload.py b/jm2l/upload.py index 6e26b39..c560a43 100644 --- a/jm2l/upload.py +++ b/jm2l/upload.py @@ -9,113 +9,114 @@ from os import path import mimetypes import magic import subprocess -import cStringIO as StringIO +try: + from StringIO import StringIO +except ImportError: + from io import StringIO # Database access imports from .models import User, Place, Tiers, Event, SallePhy from .blenderthumbnailer import blend_extract_thumb, write_png from jm2l.const import CurrentYear from slugify import slugify -MIN_FILE_SIZE = 1 # bytes -MAX_FILE_SIZE = 500000000 # bytes +MIN_FILE_SIZE = 1 # bytes +MAX_FILE_SIZE = 500000000 # bytes IMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)') ACCEPTED_MIMES = ['application/pdf', - 'application/vnd.oasis.opendocument.text', - 'application/vnd.oasis.opendocument.text-template', - 'application/vnd.oasis.opendocument.graphics', - 'application/vnd.oasis.opendocument.graphics-template', - 'application/vnd.oasis.opendocument.presentation', - 'application/vnd.oasis.opendocument.presentation-template', - 'application/vnd.oasis.opendocument.spreadsheet', - 'application/vnd.oasis.opendocument.spreadsheet-template', - 'image/svg+xml', - 'application/x-blender' -] - - + 'application/vnd.oasis.opendocument.text', + 'application/vnd.oasis.opendocument.text-template', + 'application/vnd.oasis.opendocument.graphics', + 'application/vnd.oasis.opendocument.graphics-template', + 'application/vnd.oasis.opendocument.presentation', + 'application/vnd.oasis.opendocument.presentation-template', + 'application/vnd.oasis.opendocument.spreadsheet', + 'application/vnd.oasis.opendocument.spreadsheet-template', + 'image/svg+xml', + 'application/x-blender' + ] ACCEPT_FILE_TYPES = IMAGE_TYPES THUMBNAIL_SIZE = 80 -EXPIRATION_TIME = 300 # seconds -IMAGEPATH = [ 'images' ] -DOCPATH = [ 'document' ] -THUMBNAILPATH = [ 'images', 'thumbnails' ] +EXPIRATION_TIME = 300 # seconds +IMAGEPATH = ['images'] +DOCPATH = ['document'] +THUMBNAILPATH = ['images', 'thumbnails'] # change the following to POST if DELETE isn't supported by the webserver -DELETEMETHOD="DELETE" +DELETEMETHOD = "DELETE" mimetypes.init() -class MediaPath(): + +class MediaPath(): def get_all(self, media_table, linked_id, MediaType=None): filelist = list() curpath = self.get_mediapath(media_table, linked_id, None) - thumbpath = os.path.join( curpath, 'thumbnails') + thumbpath = os.path.join(curpath, 'thumbnails') if not os.path.isdir(curpath) or not os.path.isdir(thumbpath): return list() for f in os.listdir(curpath): - filename, ext = os.path.splitext( f ) - if os.path.isdir(os.path.join(curpath,f)): + filename, ext = os.path.splitext(f) + if os.path.isdir(os.path.join(curpath, f)): continue if f.endswith('.type'): continue if f: ress_url = '/image/%s/%d/%s' % (media_table, linked_id, f.replace(" ", "%20")) - thumb_url = '/image/%s/%d/thumbnails/%s' % (media_table, linked_id, f.replace(" ","%20")) + thumb_url = '/image/%s/%d/thumbnails/%s' % (media_table, linked_id, f.replace(" ", "%20")) if MediaType is None: - if os.path.exists(os.path.join(thumbpath, f +".jpg")): - filelist.append((ress_url, thumb_url +".jpg")) + if os.path.exists(os.path.join(thumbpath, f + ".jpg")): + filelist.append((ress_url, thumb_url + ".jpg")) else: filelist.append((ress_url, thumb_url)) - elif MediaType=='Image' and len( os.path.splitext(filename)[1] )==0: + elif MediaType == 'Image' and len(os.path.splitext(filename)[1]) == 0: filelist.append((ress_url, thumb_url)) - elif MediaType=='Other' and len( os.path.splitext(filename)[1] ): + elif MediaType == 'Other' and len(os.path.splitext(filename)[1]): filelist.append((ress_url, thumb_url)) return filelist - def get_list(self, media_table, linked_id, MediaType=None): filelist = list() curpath = self.get_mediapath(media_table, linked_id, None) if not os.path.isdir(curpath): return list() for f in os.listdir(curpath): - if os.path.isdir(os.path.join(curpath,f)): + if os.path.isdir(os.path.join(curpath, f)): continue if f.endswith('.type'): continue if f: - filename, ext = os.path.splitext( f ) - tmpurl = '/image/%s/%d/%s' % (media_table, linked_id, f.replace(" ","%20")) + filename, ext = os.path.splitext(f) + tmpurl = '/image/%s/%d/%s' % (media_table, linked_id, f.replace(" ", "%20")) if MediaType is None: filelist.append(tmpurl) - elif MediaType=='Image' and ext.lower() in ['.gif','.jpg','.png','.svg','.jpeg']: + elif MediaType == 'Image' and ext.lower() in ['.gif', '.jpg', '.png', '.svg', '.jpeg']: filelist.append(tmpurl) - elif MediaType=='Other' and ext.lower() not in ['.gif','.jpg','.png','.svg','.jpeg']: + elif MediaType == 'Other' and ext.lower() not in ['.gif', '.jpg', '.png', '.svg', '.jpeg']: filelist.append(tmpurl) return filelist - + def get_thumb(self, media_table, linked_id, MediaType=None): filelist = list() curpath = self.get_mediapath(media_table, linked_id, None) - curpath = os.path.join( curpath, 'thumbnails') + curpath = os.path.join(curpath, 'thumbnails') if not os.path.isdir(curpath): return list() for f in os.listdir(curpath): - filename, ext = os.path.splitext( f ) - if os.path.isdir(os.path.join(curpath,f)): + filename, ext = os.path.splitext(f) + if os.path.isdir(os.path.join(curpath, f)): continue if f.endswith('.type'): continue if f: - tmpurl = '/image/%s/%d/thumbnails/%s' % (media_table, linked_id, f.replace(" ","%20")) + tmpurl = '/image/%s/%d/thumbnails/%s' % (media_table, linked_id, f.replace(" ", "%20")) if MediaType is None: filelist.append(tmpurl) - elif MediaType=='Image' and len( os.path.splitext(filename)[1] )==0: + elif MediaType == 'Image' and len(os.path.splitext(filename)[1]) == 0: filelist.append(tmpurl) - elif MediaType=='Other' and len( os.path.splitext(filename)[1] ): + elif MediaType == 'Other' and len(os.path.splitext(filename)[1]): filelist.append(tmpurl) - return filelist + return filelist def move_mediapath(self, media_table, from_id, to_id): """ @@ -126,8 +127,8 @@ class MediaPath(): :return: Error if any """ if media_table in ['tiers', 'place', 'salle', 'users']: - src = IMAGEPATH + [ media_table, from_id ] - dst = IMAGEPATH + [ media_table, to_id ] + src = IMAGEPATH + [media_table, from_id] + dst = IMAGEPATH + [media_table, to_id] else: raise RuntimeError("Sorry, Media '%s' not supported yet for move." % media_table) @@ -153,51 +154,51 @@ class MediaPath(): linked_id = str(linked_id) if media_table in ['tiers', 'place', 'salle']: # Retrieve Slug - if media_table=='tiers': + if media_table == 'tiers': slug = Tiers.by_id(linked_id).slug - if media_table=='place': + if media_table == 'place': slug = Place.by_id(linked_id).slug or slugify(Place.by_id(linked_id).name) - if media_table=='salle': + if media_table == 'salle': slug = SallePhy.by_id(linked_id).slug - p = IMAGEPATH + [ media_table, slug ] - elif media_table=='presse': + p = IMAGEPATH + [media_table, slug] + elif media_table == 'presse': # Use Year in linked_id - p = IMAGEPATH + [ media_table, linked_id ] - elif media_table=='tasks': + p = IMAGEPATH + [media_table, linked_id] + elif media_table == 'tasks': # Use Current Year - p = IMAGEPATH + [ str(CurrentYear), media_table, linked_id ] - elif media_table=='poles': + p = IMAGEPATH + [str(CurrentYear), media_table, linked_id] + elif media_table == 'poles': # Use Current Year - p = IMAGEPATH + [ str(CurrentYear), media_table, linked_id ] + p = IMAGEPATH + [str(CurrentYear), media_table, linked_id] elif media_table in ['RIB', 'Justif']: slug = User.by_id(linked_id).slug - p = IMAGEPATH + ['users', slug , media_table ] + p = IMAGEPATH + ['users', slug, media_table] elif media_table in ['users', 'badge']: user = User.by_id(linked_id) if not user: raise HTTPNotFound() else: slug = user.slug - p = IMAGEPATH + [media_table, slug ] - elif media_table=='event': + p = IMAGEPATH + [media_table, slug] + elif media_table == 'event': ev = Event.by_id(linked_id) slug = ev.slug year = ev.for_year - p = IMAGEPATH + ['event', str(year), slug ] + p = IMAGEPATH + ['event', str(year), slug] if name: - p += [ name ] + p += [name] TargetPath = os.path.join('jm2l/upload', *p) if not os.path.isdir(os.path.dirname(TargetPath)): try: os.makedirs(os.path.dirname(TargetPath)) - except OSError, e: + except OSError as e: if e.errno != 17: raise e - return os.path.join('jm2l/upload', *p) + return os.path.join('jm2l/upload', *p) def ExtMimeIcon(self, mime): - if mime=='application/pdf': + if mime == 'application/pdf': return "/img/PDF.png" def check_blend_file(self, fileobj): @@ -217,12 +218,12 @@ class MediaPath(): fileobj.seek(0) # Check if the binary file is a blender file - if ( mimetype == "application/octet-stream" or mimetype == "application/x-gzip" ) and self.check_blend_file(fileobj): + if (mimetype == "application/octet-stream" or mimetype == "application/x-gzip") and self.check_blend_file( + fileobj): return "application/x-blender", True else: return mimetype, False - def get_mimetype(self, name): """ This function return the mime-type based on .type file """ try: @@ -232,6 +233,7 @@ class MediaPath(): except IOError: return None + @view_defaults(route_name='media_upload') class MediaUpload(MediaPath): @@ -256,17 +258,17 @@ class MediaUpload(MediaPath): # Try to determine mime type from content uploaded found_mime = magic.from_buffer(filecontent.read(1024), mime=True) filecontent.seek(0) - + # Do a special statement for specific detected mime type if found_mime in ["application/octet-stream", "application/x-gzip"]: # Lets see if it's a bender file if self.check_blend_file(filecontent): found_mime = "application/x-blender" # MonKey Patch of content type - result['type'] = found_mime - - # Reject mime type that don't match - if found_mime!=result['type']: + result['type'] = found_mime + + # Reject mime type that don't match + if found_mime != result['type']: result['error'] = 'L\'extension du fichier ne correspond pas à son contenu - ' result['error'] += "( %s vs %s )" % (found_mime, result['type']) return False @@ -281,7 +283,7 @@ class MediaUpload(MediaPath): result['error'] = 'le fichier est trop petit' elif result['size'] > MAX_FILE_SIZE: result['error'] = 'le fichier est trop voluminueux' - #elif not ACCEPT_FILE_TYPES.match(file['type']): + # elif not ACCEPT_FILE_TYPES.match(file['type']): # file['error'] = u'les type de fichiers acceptés sont png, jpg et gif' else: return True @@ -289,80 +291,80 @@ class MediaUpload(MediaPath): return False def get_file_size(self, fileobj): - fileobj.seek(0, 2) # Seek to the end of the file - size = fileobj.tell() # Get the position of EOF - fileobj.seek(0) # Reset the file position to the beginning + fileobj.seek(0, 2) # Seek to the end of the file + size = fileobj.tell() # Get the position of EOF + fileobj.seek(0) # Reset the file position to the beginning return size - def thumbnailurl(self,name): - return self.request.route_url('media_view',name='thumbnails', - media_table=self.media_table, - uid=self.linked_id) + '/' + name + def thumbnailurl(self, name): + return self.request.route_url('media_view', name='thumbnails', + media_table=self.media_table, + uid=self.linked_id) + '/' + name - def thumbnailpath(self,name): + def thumbnailpath(self, name): origin = self.mediapath(name) - TargetPath = os.path.join( os.path.dirname(origin), 'thumbnails', name) + TargetPath = os.path.join(os.path.dirname(origin), 'thumbnails', name) if not os.path.isdir(os.path.dirname(TargetPath)): - os.makedirs(os.path.dirname(TargetPath)) + os.makedirs(os.path.dirname(TargetPath)) return TargetPath def createthumbnail(self, filename): - image = Image.open( self.mediapath(filename) ) + image = Image.open(self.mediapath(filename)) image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) timage.paste( image, ((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2)) TargetFileName = self.thumbnailpath(filename) - timage.save( TargetFileName ) - return self.thumbnailurl( os.path.basename(TargetFileName) ) + timage.save(TargetFileName) + return self.thumbnailurl(os.path.basename(TargetFileName)) def pdfthumbnail(self, filename): TargetFileName = self.thumbnailpath(filename) - Command = ["convert","./%s[0]" % self.mediapath(filename),"./%s_.jpg" % TargetFileName] + Command = ["convert", "./%s[0]" % self.mediapath(filename), "./%s_.jpg" % TargetFileName] Result = subprocess.call(Command) - if Result==0: - image = Image.open( TargetFileName+"_.jpg" ) - pdf_indicator = Image.open( "jm2l/static/img/PDF_Thumb_Stamp.png" ) + if Result == 0: + image = Image.open(TargetFileName + "_.jpg") + pdf_indicator = Image.open("jm2l/static/img/PDF_Thumb_Stamp.png") image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) # Add thumbnail timage.paste( - image, + image, ((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2)) # Stamp with PDF file type timage.paste( pdf_indicator, - (timage.size[0]-30, timage.size[1]-30), + (timage.size[0] - 30, timage.size[1] - 30), pdf_indicator, - ) - timage.convert('RGB').save( TargetFileName+".jpg", 'JPEG') - os.unlink(TargetFileName+"_.jpg") - return self.thumbnailurl( os.path.basename(TargetFileName+".jpg") ) + ) + timage.convert('RGB').save(TargetFileName + ".jpg", 'JPEG') + os.unlink(TargetFileName + "_.jpg") + return self.thumbnailurl(os.path.basename(TargetFileName + ".jpg")) return self.ExtMimeIcon('application/pdf') def svgthumbnail(self, filename): TargetFileName = self.thumbnailpath(filename) - Command = ["convert","./%s[0]" % self.mediapath(filename),"./%s_.jpg" % TargetFileName] + Command = ["convert", "./%s[0]" % self.mediapath(filename), "./%s_.jpg" % TargetFileName] Result = subprocess.call(Command) - if Result==0: - image = Image.open( TargetFileName+"_.jpg" ) - pdf_indicator = Image.open( "jm2l/static/img/svg-icon.png" ) + if Result == 0: + image = Image.open(TargetFileName + "_.jpg") + pdf_indicator = Image.open("jm2l/static/img/svg-icon.png") image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) # Add thumbnail timage.paste( - image, + image, ((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2)) # Stamp with PDF file type timage.paste( pdf_indicator, - (timage.size[0]-30, timage.size[1]-30), + (timage.size[0] - 30, timage.size[1] - 30), pdf_indicator, - ) - timage.convert('RGB').save( TargetFileName+".jpg", 'JPEG') - os.unlink(TargetFileName+"_.jpg") - return self.thumbnailurl( os.path.basename(TargetFileName+".jpg") ) + ) + timage.convert('RGB').save(TargetFileName + ".jpg", 'JPEG') + os.unlink(TargetFileName + "_.jpg") + return self.thumbnailurl(os.path.basename(TargetFileName + ".jpg")) return self.ExtMimeIcon('image/svg+xml') def docthumbnail(self, filename): @@ -370,29 +372,30 @@ class MediaUpload(MediaPath): # let's take the thumbnail generated inside the document Command = ["unzip", "-p", self.mediapath(filename), "Thumbnails/thumbnail.png"] ThumbBytes = subprocess.check_output(Command) - image = Image.open( StringIO.StringIO(ThumbBytes) ) + image = Image.open(StringIO.StringIO(ThumbBytes)) image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) # Use the correct stamp - f, ext = os.path.splitext( filename ) - istamp = [ ('Writer','odt'), - ('Impress','odp'), - ('Calc','ods'), - ('Draw','odg')] - stampfilename = filter(lambda (x,y): ext.endswith(y), istamp) - stamp = Image.open( "jm2l/static/img/%s-icon.png" % stampfilename[0][0]) + f, ext = os.path.splitext(filename) + istamp = [('Writer', 'odt'), + ('Impress', 'odp'), + ('Calc', 'ods'), + ('Draw', 'odg')] + stampfilename = filter(lambda x, y: ext.endswith(y), istamp) + stamp = Image.open("jm2l/static/img/%s-icon.png" % stampfilename[0][0]) + timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) # Add thumbnail timage.paste( - image, + image, ((THUMBNAIL_SIZE - image.size[0]) / 2, (THUMBNAIL_SIZE - image.size[1]) / 2)) # Stamp with PDF file type timage.paste( stamp, - (timage.size[0]-30, timage.size[1]-30), + (timage.size[0] - 30, timage.size[1] - 30), stamp, - ) - timage.convert('RGB').save( TargetFileName+".jpg", 'JPEG') - return self.thumbnailurl( os.path.basename(TargetFileName+".jpg") ) + ) + timage.convert('RGB').save(TargetFileName + ".jpg", 'JPEG') + return self.thumbnailurl(os.path.basename(TargetFileName + ".jpg")) def blendthumbnail(self, filename): blendfile = self.mediapath(filename) @@ -400,18 +403,18 @@ class MediaUpload(MediaPath): if 0: head = fileobj.read(12) fileobj.seek(0) - + if head[:2] == b'\x1f\x8b': # gzip magic import zlib head = zlib.decompress(fileobj.read(), 31)[:12] - fileobj.seek(0) - + fileobj.seek(0) + buf, width, height = blend_extract_thumb(blendfile) if buf: png = write_png(buf, width, height) TargetFileName = self.thumbnailpath(filename) image = Image.open(StringIO.StringIO(png)) - blender_indicator = Image.open( "jm2l/static/img/Blender_Thumb_Stamp.png" ) + blender_indicator = Image.open("jm2l/static/img/Blender_Thumb_Stamp.png") image.thumbnail((THUMBNAIL_SIZE, THUMBNAIL_SIZE), Image.ANTIALIAS) timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0)) # Add thumbnail @@ -421,24 +424,24 @@ class MediaUpload(MediaPath): # Stamp with Blender file type timage.paste( blender_indicator, - (timage.size[0]-30, timage.size[1]-30), + (timage.size[0] - 30, timage.size[1] - 30), blender_indicator, - ) - timage.save( TargetFileName+".png") - return self.thumbnailurl( os.path.basename(TargetFileName+".png") ) + ) + timage.save(TargetFileName + ".png") + return self.thumbnailurl(os.path.basename(TargetFileName + ".png")) return self.ExtMimeIcon('application/x-blender') - def fileinfo(self,name): - filename = self.mediapath(name) + def fileinfo(self, name): + filename = self.mediapath(name) f, ext = os.path.splitext(name) - if ext!='.type' and os.path.isfile(filename): + if ext != '.type' and os.path.isfile(filename): info = {} info['name'] = name info['size'] = os.path.getsize(filename) info['url'] = self.request.route_url('media_view', - name=name, - media_table=self.media_table, - uid=self.linked_id) + name=name, + media_table=self.media_table, + uid=self.linked_id) mime = self.get_mimetype(name) if IMAGE_TYPES.match(mime): @@ -448,8 +451,8 @@ class MediaUpload(MediaPath): thumbext = ".jpg" if mime == "application/x-blender": thumbext = ".png" - if os.path.exists( thumb + thumbext ): - info['thumbnailUrl'] = self.thumbnailurl(name)+thumbext + if os.path.exists(thumb + thumbext): + info['thumbnailUrl'] = self.thumbnailurl(name) + thumbext else: info['thumbnailUrl'] = self.ExtMimeIcon(mime) else: @@ -457,10 +460,10 @@ class MediaUpload(MediaPath): if not self.display_only: info['deleteType'] = DELETEMETHOD info['deleteUrl'] = self.request.route_url('media_upload', - sep='', - name='', - media_table=self.media_table, - uid=self.linked_id) + '/' + name + sep='', + name='', + media_table=self.media_table, + uid=self.linked_id) + '/' + name if DELETEMETHOD != 'DELETE': info['deleteUrl'] += '&_method=DELETE' return info @@ -488,7 +491,7 @@ class MediaUpload(MediaPath): n = self.fileinfo(f) if n: filelist.append(n) - return { "files":filelist } + return {"files": filelist} @view_config(request_method='DELETE', xhr=True, accept="application/json", renderer='json') def delete(self): @@ -498,32 +501,32 @@ class MediaUpload(MediaPath): except IOError: pass except OSError: - pass + pass try: os.remove(self.thumbnailpath(filename)) except IOError: pass - except OSError: + except OSError: pass try: - os.remove(self.thumbnailpath(filename+".jpg")) + os.remove(self.thumbnailpath(filename + ".jpg")) except IOError: pass - except OSError: - pass + except OSError: + pass try: os.remove(self.mediapath(filename)) except IOError: return False return True - + @view_config(request_method='POST', xhr=True, accept="application/json", renderer='json') def post(self): if self.request.matchdict.get('_method') == "DELETE": return self.delete() results = [] for name, fieldStorage in self.request.POST.items(): - if isinstance(fieldStorage,unicode): + if isinstance(fieldStorage, unicode): continue result = {} result['name'] = os.path.basename(fieldStorage.filename) @@ -531,63 +534,64 @@ class MediaUpload(MediaPath): result['size'] = self.get_file_size(fieldStorage.file) if self.validate(result, fieldStorage.file): - filename, file_extension = os.path.splitext( result['name'] ) - local_filename = slugify( filename ) + file_extension + filename, file_extension = os.path.splitext(result['name']) + local_filename = slugify(filename) + file_extension # Keep mime-type in .type file - with open( self.mediapath( local_filename ) + '.type', 'w') as f: + with open(self.mediapath(local_filename) + '.type', 'w') as f: f.write(result['type']) - + # Store uploaded file fieldStorage.file.seek(0) - with open( self.mediapath( local_filename ), 'wb') as f: - shutil.copyfileobj( fieldStorage.file , f) + with open(self.mediapath(local_filename), 'wb') as f: + shutil.copyfileobj(fieldStorage.file, f) if re.match(IMAGE_TYPES, result['type']): result['thumbnailUrl'] = self.createthumbnail(local_filename) - elif result['type']=='application/pdf': + elif result['type'] == 'application/pdf': result['thumbnailUrl'] = self.pdfthumbnail(local_filename) - elif result['type']=='image/svg+xml': + elif result['type'] == 'image/svg+xml': result['thumbnailUrl'] = self.svgthumbnail(local_filename) elif result['type'].startswith('application/vnd'): result['thumbnailUrl'] = self.docthumbnail(local_filename) - elif result['type']=='application/x-blender': + elif result['type'] == 'application/x-blender': result['thumbnailUrl'] = self.blendthumbnail(local_filename) else: result['thumbnailUrl'] = self.ExtMimeIcon(result['type']) result['deleteType'] = DELETEMETHOD result['deleteUrl'] = self.request.route_url('media_upload', - sep='', - name='', - media_table=self.media_table, - uid=self.linked_id) + '/' + local_filename + sep='', + name='', + media_table=self.media_table, + uid=self.linked_id) + '/' + local_filename result['url'] = self.request.route_url('media_view', - media_table=self.media_table, - uid=self.linked_id, - name=local_filename) + media_table=self.media_table, + uid=self.linked_id, + name=local_filename) if DELETEMETHOD != 'DELETE': result['deleteUrl'] += '&_method=DELETE' results.append(result) - return {"files":results} + return {"files": results} + @view_defaults(route_name='media_view') class MediaView(MediaPath): - def __init__(self,request): + def __init__(self, request): self.request = request self.media_table = self.request.matchdict.get('media_table') self.linked_id = self.request.matchdict.get('uid') - def mediapath(self,name): + def mediapath(self, name): return self.get_mediapath(self.media_table, self.linked_id, name) - - @view_config(request_method='GET', http_cache = (EXPIRATION_TIME, {'public':True})) + + @view_config(request_method='GET', http_cache=(EXPIRATION_TIME, {'public': True})) def get(self): name = self.request.matchdict.get('name') self.request.response.content_type = self.get_mimetype(name) try: - self.request.response.body_file = open( self.mediapath(name), 'rb', 10000) + self.request.response.body_file = open(self.mediapath(name), 'rb', 10000) except IOError: raise NotFound return self.request.response diff --git a/jm2l/views.py b/jm2l/views.py index c49e142..2426367 100644 --- a/jm2l/views.py +++ b/jm2l/views.py @@ -16,17 +16,20 @@ from .helpers import Orga_helpers from sqlalchemy import func, or_, text, and_ from sqlalchemy.orm import aliased from os import path, makedirs, listdir -# Usefull tools +#  Usefull tools from slugify import slugify from icalendar import Calendar from pytz import timezone from icalendar import Event as Evt from pyramid_mailer.message import Message -from security import check_staff, check_logged +from .security import check_staff, check_logged # Then, standard libs import csv -import cStringIO as StringIO -import webhelpers.paginate as paginate +try: + from StringIO import StringIO +except ImportError: + from io import StringIO +import paginate import unicodedata import datetime import re @@ -36,6 +39,7 @@ from jm2l.const import CurrentYear from passlib.hash import argon2 + ## =-=- Here, We keep some usefull function -=-= def remove_accents(input_str): """ This function is intended to remove all accent from input unicode string """ @@ -43,6 +47,7 @@ def remove_accents(input_str): only_ascii = nkfd_form.encode('ASCII', 'ignore') return only_ascii + def embeed_video(mime_type, link): Container = "