| @@ -95,6 +95,7 @@ def main(global_config, **settings): | |||||
| # ICal Routes | # ICal Routes | ||||
| config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics') | config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics') | ||||
| config.add_route('progr_dyn_iCal', '/{year:\d+}/JM2L_dyn.ics') | |||||
| # JSON Routes | # JSON Routes | ||||
| config.add_route('users_json', '/json-users') | 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('show_user', '/user/{user_slug:([\w-]+)?}') | ||||
| config.add_route('badge_user', '/user/{user_slug:([\w-]+)?}/badge') | config.add_route('badge_user', '/user/{user_slug:([\w-]+)?}/badge') | ||||
| config.add_route('all_badges', '/badges') | config.add_route('all_badges', '/badges') | ||||
| config.add_route('place_print', '/place_print') | |||||
| # HTML Routes - Logged | # HTML Routes - Logged | ||||
| #config.add_route('profil', 'MesJM2L') | #config.add_route('profil', 'MesJM2L') | ||||
| @@ -17,90 +17,6 @@ WIDTH = 85 * mm | |||||
| HEIGHT = 60 * mm | HEIGHT = 60 * mm | ||||
| ICONSIZE = 10 * 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)): | def JM2L_Logo(canvas, Offset=(0,0)): | ||||
| OffX, OffY = Offset | OffX, OffY = Offset | ||||
| logoobject = canvas.beginText() | logoobject = canvas.beginText() | ||||
| @@ -137,6 +137,10 @@ class User(Base): | |||||
| soc_link = Column(UnicodeText) | soc_link = Column(UnicodeText) | ||||
| Staff = Column(Integer, default=0) | Staff = Column(Integer, default=0) | ||||
| vote_logo = 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 | # relations | ||||
| tiers = relationship('Tiers', secondary='user_tiers_link' ) | tiers = relationship('Tiers', secondary='user_tiers_link' ) | ||||
| events = relationship('Event', secondary='user_event_link' ) | events = relationship('Event', secondary='user_event_link' ) | ||||
| @@ -13,7 +13,7 @@ | |||||
| <div class="span8"> | <div class="span8"> | ||||
| <a href="/sign/jm2l/${uprofil.my_hash}">Mon lien de connection</a> - | <a href="/sign/jm2l/${uprofil.my_hash}">Mon lien de connection</a> - | ||||
| <a href="/user/${request.user.slug}">Mon profil public</a><br> | <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 = { | DicFormA = { | ||||
| 'nom': {'PlaceHolder':u"Mon Nom", 'ContainerClass':"span6", 'next':False}, | 'nom': {'PlaceHolder':u"Mon Nom", 'ContainerClass':"span6", 'next':False}, | ||||
| @@ -61,7 +61,22 @@ DicForm2 = { | |||||
| ${helpers.DisplayRespForm(profil_form, DicFormA)} | ${helpers.DisplayRespForm(profil_form, DicFormA)} | ||||
| </div> | </div> | ||||
| <div class="span4"> | <div class="span4"> | ||||
| ${helpers.show_my_pictures(uprofil)} | ${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> | ||||
| </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" | request.response.content_type = "text/calendar" | ||||
| return cal.to_ical() | 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 -=-= | ## =-=- Here, We handle Json requests -=-= | ||||
| @view_config(route_name='users_json', renderer="json") | @view_config(route_name='users_json', renderer="json") | ||||
| def JSON_User_Request(request): | def JSON_User_Request(request): | ||||
| @@ -213,9 +250,9 @@ def JSON_TimeLine_Request(request): | |||||
| "text":"<i><span class='c1'>9ème Édition</span></i>", | "text":"<i><span class='c1'>9ème Édition</span></i>", | ||||
| "asset": | "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: | elif year==2011: | ||||