| @@ -95,6 +95,7 @@ def main(global_config, **settings): | |||
| # ICal Routes | |||
| config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics') | |||
| config.add_route('progr_dyn_iCal', '/{year:\d+}/JM2L_dyn.ics') | |||
| # JSON Routes | |||
| config.add_route('users_json', '/json-users') | |||
| @@ -154,6 +155,7 @@ def main(global_config, **settings): | |||
| config.add_route('show_user', '/user/{user_slug:([\w-]+)?}') | |||
| config.add_route('badge_user', '/user/{user_slug:([\w-]+)?}/badge') | |||
| config.add_route('all_badges', '/badges') | |||
| config.add_route('place_print', '/place_print') | |||
| # HTML Routes - Logged | |||
| #config.add_route('profil', 'MesJM2L') | |||
| @@ -17,90 +17,6 @@ WIDTH = 85 * mm | |||
| HEIGHT = 60 * mm | |||
| ICONSIZE = 10 * mm | |||
| def Ribbon35(DispUser, canvas): | |||
| canvas.saveState() | |||
| canvas.rotate(35) | |||
| offset_u=0 | |||
| if DispUser.Staff: | |||
| # Staff | |||
| canvas.setFillColorRGB(1,.2,.2) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(1,1,1) | |||
| canvas.setFont('Liberation', 20) | |||
| canvas.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+5, "STAFF") | |||
| elif DispUser.is_Intervenant: | |||
| # Intervenant | |||
| canvas.setFillColorRGB(.3,.3,1) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(1,1,1) | |||
| canvas.setFont('Liberation', 15) | |||
| canvas.drawCentredString(WIDTH/2-15, HEIGHT/2-offset_u+10, "Intervenant") | |||
| else: | |||
| # Visiteur | |||
| canvas.setFillColorRGB(.8,.8,.8) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(0,0,0) | |||
| canvas.setFont('Liberation', 12) | |||
| canvas.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+7, "Visiteur") | |||
| canvas.restoreState() | |||
| return canvas | |||
| def Ribbon45(DispUser, canvas): | |||
| canvas.saveState() | |||
| canvas.rotate(45) | |||
| offset_u=0 | |||
| if DispUser.Staff: | |||
| # Staff | |||
| canvas.setFillColorRGB(1,.2,.2) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(1,1,1) | |||
| canvas.setFont('Liberation', 20) | |||
| canvas.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+5, "STAFF") | |||
| elif DispUser.is_Intervenant: | |||
| # Intervenant | |||
| canvas.setFillColorRGB(.3,.3,1) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(1,1,1) | |||
| canvas.setFont('Liberation', 15) | |||
| canvas.drawCentredString(WIDTH/2-15, HEIGHT/2-offset_u+10, "Intervenant") | |||
| else: | |||
| # Visiteur | |||
| canvas.setFillColorRGB(.8,.8,.8) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(0,0,0) | |||
| canvas.setFont('Liberation', 12) | |||
| canvas.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+7, "Visiteur") | |||
| canvas.restoreState() | |||
| return canvas | |||
| def Ribbon90(DispUser, canvas): | |||
| canvas.saveState() | |||
| canvas.rotate(90) | |||
| offset_u=0 | |||
| if DispUser.Staff: | |||
| # Staff | |||
| canvas.setFillColorRGB(1,.2,.2) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(1,1,1) | |||
| canvas.setFont('Liberation', 20) | |||
| canvas.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+5, "STAFF") | |||
| elif DispUser.is_Intervenant: | |||
| # Intervenant | |||
| canvas.setFillColorRGB(.3,.3,1) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(1,1,1) | |||
| canvas.setFont('Liberation', 15) | |||
| canvas.drawCentredString(WIDTH/2-15, HEIGHT/2-offset_u+10, "Intervenant") | |||
| else: | |||
| # Visiteur | |||
| canvas.setFillColorRGB(.8,.8,.8) | |||
| canvas.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||
| canvas.setFillColorRGB(0,0,0) | |||
| canvas.setFont('Liberation', 12) | |||
| canvas.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+7, "Visiteur") | |||
| canvas.restoreState() | |||
| return canvas | |||
| def JM2L_Logo(canvas, Offset=(0,0)): | |||
| OffX, OffY = Offset | |||
| logoobject = canvas.beginText() | |||
| @@ -137,6 +137,10 @@ class User(Base): | |||
| 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' ) | |||
| @@ -13,7 +13,7 @@ | |||
| <div class="span8"> | |||
| <a href="/sign/jm2l/${uprofil.my_hash}">Mon lien de connection</a> - | |||
| <a href="/user/${request.user.slug}">Mon profil public</a><br> | |||
| <h3>${profil_form.prenom.data} ${profil_form.nom.data}</h3> | |||
| <h3>${profil_form.prenom.data} ${profil_form.nom.data}</h3> | |||
| <% | |||
| DicFormA = { | |||
| 'nom': {'PlaceHolder':u"Mon Nom", 'ContainerClass':"span6", 'next':False}, | |||
| @@ -61,7 +61,22 @@ DicForm2 = { | |||
| ${helpers.DisplayRespForm(profil_form, DicFormA)} | |||
| </div> | |||
| <div class="span4"> | |||
| ${helpers.show_my_pictures(uprofil)} | |||
| <div class="borderbox" style="background: rgb(240, 250, 250) url(/img/wifi.png) no-repeat scroll 0px 0px;width: 220px;text-align:center;margin: auto;"> | |||
| <u>Vos identifiants wifi:</u> | |||
| <dl> | |||
| <dt>SSID</dt> | |||
| <dd>Unice-HotSpot</dd> | |||
| <dt>Votre utilisateur:</dt> | |||
| <dd>${uprofil.wifi_user}</dd> | |||
| <dt>Le mot de passe:</dt> | |||
| <dd>${uprofil.wifi_pass}</dd> | |||
| </dl> | |||
| <a href="https://wifi.unice.fr/">Plus de détails ...</a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,135 @@ | |||
| # -*- coding: utf8 -*- | |||
| from pyramid.response import Response | |||
| import cStringIO as StringIO | |||
| from pyramid.view import view_config | |||
| from .models import DBSession, Event, Salles | |||
| from reportlab.pdfgen import canvas | |||
| from reportlab.pdfbase import pdfmetrics | |||
| from reportlab.pdfbase.ttfonts import TTFont | |||
| from reportlab.lib.units import mm | |||
| from .upload import MediaPath | |||
| CurrentYear = 2015 | |||
| # Create PDF container | |||
| EXPIRATION_TIME = 300 # seconds | |||
| WIDTH = 210 * mm | |||
| HEIGHT = 297 * mm | |||
| ICONSIZE = 10 * mm | |||
| def JM2L_large_Logo(canvas, Offset=(0,0)): | |||
| OffX, OffY = Offset | |||
| canvas.setFont('Logo', 110) | |||
| canvas.setFillColorRGB(.83,0,.33) | |||
| canvas.drawCentredString(WIDTH/2-OffY, HEIGHT-100-OffX, "JM2L") | |||
| canvas.setFont("Helvetica-Bold", 30) | |||
| yearobject = canvas.beginText() | |||
| yearobject.setFillColorRGB(1,1,1) | |||
| yearobject.setTextRenderMode(0) | |||
| yearobject.setTextOrigin(WIDTH/2-OffY-120, HEIGHT-36-OffX) | |||
| yearobject.setWordSpace(48) | |||
| yearobject.textLines("2 0 1 5") | |||
| yearobject.setWordSpace(1) | |||
| canvas.drawText(yearobject) | |||
| def one_time_step(canvas, str, hour, max_size, offset): | |||
| max_x, max_y = max_size | |||
| off_x, off_y = offset | |||
| step_y = max_y/9 | |||
| half_step = step_y/2 | |||
| canvas.drawCentredString(off_x-30, max_y-step_y*hour+off_y-3, str) | |||
| hour_place = step_y*hour+off_y | |||
| canvas.line(off_x-5, hour_place, off_x, hour_place) | |||
| if hour<9: | |||
| canvas.line(off_x-2, hour_place+half_step, off_x, hour_place+half_step) | |||
| @view_config(route_name='place_print', http_cache = (EXPIRATION_TIME, {'public':True})) | |||
| def place_print(request): | |||
| # Ok let's generate a print for place schedule | |||
| # Register LiberationMono font | |||
| ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf" | |||
| pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) | |||
| # Import font | |||
| ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf" | |||
| pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo)) | |||
| pdf = StringIO.StringIO() | |||
| c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) ) | |||
| c.translate(mm, mm) | |||
| # Feed some metadata | |||
| c.setCreator("linux-azur.org") | |||
| c.setTitle("Planning Salle") | |||
| c.saveState() | |||
| year = int(request.matchdict.get('year', CurrentYear)) | |||
| # Initialization | |||
| # Compute days used by all events matching the specified input year | |||
| place_used = DBSession.query(Event.salle_uid)\ | |||
| .filter(Event.for_year == year)\ | |||
| .filter(Event.event_type != 'Stand')\ | |||
| .group_by(Event.salle_uid) | |||
| for place in place_used: | |||
| place_uid = place[0] | |||
| place_obj = Salles.by_id(place_uid) | |||
| # Logo on Top | |||
| JM2L_large_Logo(c) | |||
| max_size = (WIDTH-110, HEIGHT-300) | |||
| offset = (70, 90) | |||
| c.setFillColorRGB(.5,.5,.5) | |||
| c.setFont('Liberation', 40) | |||
| c.drawCentredString(WIDTH/2, HEIGHT-190, place_obj.name, 1) | |||
| c.setFont('Liberation', 35) | |||
| c.drawCentredString(WIDTH/2, HEIGHT-145, place_obj.place_type, 0 ) | |||
| c.setFont('Helvetica', 20) | |||
| c.drawCentredString(WIDTH/2, 55, place_obj.phy.name, 0) | |||
| # Timetable container | |||
| c.setLineWidth(.1) | |||
| c.setLineCap(2) | |||
| #c.setFillColorRGB(0,0,1) | |||
| c.rect(offset[0], offset[1], max_size[0], max_size[1], fill=0, stroke=1) | |||
| c.setLineWidth(.5) | |||
| # create time mark | |||
| c.setFillColorRGB(0,0,0) | |||
| c.setFont('Helvetica', 10) | |||
| for i in range(0,10): | |||
| one_time_step(c, "%.2dh00" % (i+10), i, max_size, offset) | |||
| c.setFont('Helvetica', 12) | |||
| Events = DBSession.query(Event)\ | |||
| .filter(Event.for_year == year)\ | |||
| .filter(Event.salle_uid == place_uid)\ | |||
| .order_by(Event.start_time) | |||
| for ev in Events: | |||
| place_time(c, ev, max_size, offset) | |||
| #c.rect(70, 50, WIDTH-100, HEIGHT-250, fill=0, stroke=1) | |||
| c.showPage() | |||
| c.save() | |||
| pdf.seek(0) | |||
| return Response(app_iter=pdf, content_type = 'application/pdf' ) | |||
| def place_time(c, ev, max_size, offset): | |||
| max_x, max_y = max_size | |||
| off_x, off_y = offset | |||
| minute = max_y/(9*60) | |||
| start_pos_y = ((int( ev.start_time.strftime('%H') )-10)*60 + int( ev.start_time.strftime('%M') )) * minute | |||
| stop_pos_y = ((int( ev.end_time.strftime('%H') )-10)*60 + int( ev.end_time.strftime('%M') )) * minute | |||
| c.setFillColorRGB(1,1,1) | |||
| c.rect(offset[0], max_y + off_y - start_pos_y, max_size[0], start_pos_y-stop_pos_y, fill=1, stroke=1) | |||
| c.setFillColorRGB(0,0,0) | |||
| #c.drawString(off_x+5, max_y + off_y - 15 - start_pos_y, ev.start_time.strftime('%H:%M'), 0) | |||
| c.drawCentredString(WIDTH/2, max_y + off_y - 35 - start_pos_y, ev.name, 0) | |||
| intervs = ','.join( [x.slug for x in ev.intervenants] ) | |||
| c.drawString(WIDTH/2, max_y + off_y - 45 - start_pos_y, intervs, 0) | |||
| @@ -73,6 +73,43 @@ def ICal_Progamme_Request(request): | |||
| request.response.content_type = "text/calendar" | |||
| return cal.to_ical() | |||
| ## =-=- Here, We handle ICal requests -=-= | |||
| @view_config(route_name='progr_dyn_iCal', renderer="string") | |||
| def ICal_Progamme_Dyn_Request(request): | |||
| year = int(request.matchdict.get('year', CurrentYear)) | |||
| # Initialization | |||
| # Compute days used by all events matching the specified input year | |||
| Events = DBSession.query(Event)\ | |||
| .filter(Event.for_year == year)\ | |||
| .filter(Event.event_type != 'Stand')\ | |||
| .order_by(Event.start_time) | |||
| cal = Calendar() | |||
| cal.add('prodid', '-//Programme %d//jm2l.linux-azur.org//' % year) | |||
| cal.add('version', '2.0') | |||
| today = datetime.datetime.now() | |||
| tz = timezone('Europe/Paris') | |||
| for i, ev in enumerate(Events): | |||
| if ev.event_type: | |||
| event = Evt() | |||
| event['uid'] = "%d/%d" % ( year, ev.uid ) | |||
| event.add('summary', ev.name +'_night' ) | |||
| event.add('dtstart', ev.start_time.replace(tzinfo=tz, day=today.day, month = today.month, hour=(ev.start_time.hour)%24) ) | |||
| event.add('dtend', ev.end_time.replace(tzinfo=tz, day=today.day, month = today.month, hour=(ev.end_time.hour)%24) ) | |||
| event.add('created', ev.last_change.replace(tzinfo=tz) ) | |||
| if i%2: | |||
| event.add('description', "http://video.webmfiles.org/big-buck-bunny_trailer.webm" ) | |||
| else: | |||
| event.add('description', "http://video.webmfiles.org/elephants-dream.webm" ) | |||
| event.add('location', "http://jm2l.linux-azur.org/image/tasks/89/le-projet-de-learning-centre-sophiatech-32-638.jpg" ) | |||
| event.add('url', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) ) | |||
| event.add('salle', "%s" % (ev.Salle.name) ) | |||
| event.add('priority', 5) | |||
| cal.add_component(event) | |||
| request.response.content_type = "text/calendar" | |||
| return cal.to_ical() | |||
| ## =-=- Here, We handle Json requests -=-= | |||
| @view_config(route_name='users_json', renderer="json") | |||
| def JSON_User_Request(request): | |||
| @@ -213,9 +250,9 @@ def JSON_TimeLine_Request(request): | |||
| "text":"<i><span class='c1'>9ème Édition</span></i>", | |||
| "asset": | |||
| { | |||
| "media":"https://www.youtube.com/watch?v=DnfjrxVoLao", | |||
| "credit":"JM2L", | |||
| "caption":"" | |||
| "media":"https://www.youtube.com/watch?v=91X65eEKxvU&t=6s", | |||
| "credit":"Polytech nice sophia", | |||
| "caption":"JM2L 2015" | |||
| } | |||
| } | |||
| elif year==2011: | |||