From 11d62aa3a5fc8cd196a7c3a3f6cbb736d0d0b3d1 Mon Sep 17 00:00:00 2001 From: Nicolas Martignole Date: Mon, 11 Apr 2016 10:42:49 +0200 Subject: [PATCH 1/6] bug(publisher): Fixed bug on all Speakers Web page --- app/controllers/Publisher.scala | 35 ++++++++++++++++++++------------- app/controllers/RestAPI.scala | 3 ++- public/dvfr2015/dvfr2015.css | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/app/controllers/Publisher.scala b/app/controllers/Publisher.scala index 5bec82a98..3b2175644 100644 --- a/app/controllers/Publisher.scala +++ b/app/controllers/Publisher.scala @@ -25,7 +25,7 @@ package controllers import akka.util.Crypt import library.search.ElasticSearch -import library.{LogURL, SendQuestionToSpeaker, ZapActor} +import library.{LogURL, ZapActor} import models._ import play.api.cache.Cache import play.api.data.Form @@ -36,14 +36,14 @@ import play.api.mvc._ /** - * Publisher is the controller responsible for the Web content of your conference Program. - * Created by nicolas on 12/02/2014. - */ + * Publisher is the controller responsible for the Web content of your conference Program. + * Created by nicolas on 12/02/2014. + */ object Publisher extends Controller { def homePublisher = Action { implicit request => val result = views.html.Publisher.homePublisher() - val etag = Crypt.md5(result.toString()+"dvx").toString + val etag = Crypt.md5(result.toString() + "dvx").toString val maybeETag = request.headers.get(IF_NONE_MATCH) maybeETag match { @@ -54,16 +54,23 @@ object Publisher extends Controller { def showAllSpeakers = Action { implicit request => - import play.api.Play.current - val speakers = Cache.getOrElse[List[Speaker]]("allSpeakersWithAcceptedTerms", 600) { - Speaker.allSpeakersWithAcceptedTerms() - } - val etag = speakers.hashCode().toString + "_2" - val maybeETag = request.headers.get(IF_NONE_MATCH) - maybeETag match { - case Some(oldEtag) if oldEtag == etag => NotModified - case other => Ok(views.html.Publisher.showAllSpeakers(speakers)).withHeaders(ETAG -> etag) + + // First load published slots + val publishedConf = ScheduleConfiguration.loadAllPublishedSlots().filter(_.proposal.isDefined) + val allSpeakersIDs = publishedConf.flatMap(_.proposal.get.allSpeakerUUIDs).toSet + val etag = allSpeakersIDs.hashCode.toString + + request.headers.get(IF_NONE_MATCH) match { + case Some(tag) if tag == etag => + NotModified + + case other => + val onlySpeakersThatAcceptedTerms: Set[String] = allSpeakersIDs.filterNot(uuid => Speaker.needsToAccept(uuid)) + val speakers = Speaker.loadSpeakersFromSpeakerIDs(onlySpeakersThatAcceptedTerms) + Ok(views.html.Publisher.showAllSpeakers(speakers)).withHeaders(ETAG -> etag) + } + } def showSpeakerByName(name: String) = Action { diff --git a/app/controllers/RestAPI.scala b/app/controllers/RestAPI.scala index 837644a15..e261646c9 100644 --- a/app/controllers/RestAPI.scala +++ b/app/controllers/RestAPI.scala @@ -151,7 +151,8 @@ object RestAPI extends Controller { )) ) ) - Ok(jsonObject).as(JSON).withHeaders(ETAG -> etag, "Links" -> ("<" + routes.RestAPI.profile("conference").absoluteURL().toString + ">; rel=\"profile\"")) + Ok(jsonObject).as(JSON).withHeaders(ETAG -> etag, + "Links" -> ("<" + routes.RestAPI.profile("conference").absoluteURL() + ">; rel=\"profile\"")) } } }.getOrElse(NotFound("Conference not found")) diff --git a/public/dvfr2015/dvfr2015.css b/public/dvfr2015/dvfr2015.css index eccedea52..13d269d17 100644 --- a/public/dvfr2015/dvfr2015.css +++ b/public/dvfr2015/dvfr2015.css @@ -20003,7 +20003,7 @@ Main Top Section - Image Page -ms-transform: skew(-20deg, 0); transform: skew(-20deg, 0); position: absolute; - width: 64%; + width: 75%; height: 100%; left: 210px; z-index: 1; From 4e5ca94082d7cad43aacd4f7897b09b101ab2e55 Mon Sep 17 00:00:00 2001 From: Nicolas Martignole Date: Mon, 11 Apr 2016 16:32:31 +0200 Subject: [PATCH 2/6] feat(paperGuide): Added a simple controller to export the agenda as CSV --- app/controllers/PaperGuide.scala | 154 +++++++++++++++++++++++++++++++ conf/routes | 3 + 2 files changed, 157 insertions(+) create mode 100644 app/controllers/PaperGuide.scala diff --git a/app/controllers/PaperGuide.scala b/app/controllers/PaperGuide.scala new file mode 100644 index 000000000..56bece3cf --- /dev/null +++ b/app/controllers/PaperGuide.scala @@ -0,0 +1,154 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2013 Association du Paris Java User Group. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package controllers + +import java.io.{PrintWriter, File} + +import models.{Speaker, Slot, ConferenceDescriptor, ScheduleConfiguration} +import org.apache.commons.lang3.StringEscapeUtils +import play.api.i18n.Messages + +/** + * Simple controller used to export the whole program as a CSV file. + * Practical if you want to print the schedule. + * + * @author created by N.Martignole, Innoteria, on 11/04/16. + */ +object PaperGuide extends SecureCFPController { + + def exportProgram() = SecuredAction(IsMemberOf("cfp")) { + implicit request: SecuredRequest[play.api.mvc.AnyContent] => + implicit val context = scala.concurrent.ExecutionContext.Implicits.global + + + val allScheduledConf: List[ScheduleConfiguration] = for (confType <- ConferenceDescriptor.ConferenceProposalTypes.ALL; + scheduleId <- ScheduleConfiguration.getPublishedSchedule(confType.id); + scheduledConf <- ScheduleConfiguration.loadScheduledConfiguration(scheduleId) + ) yield scheduledConf + + val file = new File("./target/guide", "DEVOXX_" + allScheduledConf.hashCode() + ".csv") + val writer = new PrintWriter(file, "MacRoman") // !!! ENCODING !!! + writer.println("id,name,day,from,to,roomName,proposalId,proposalTitle,proposalLang,track,speakerName,secSpeakerName,thirdSpeaker,fourthSpeaker") + + allScheduledConf.foreach { + scheduleConf: ScheduleConfiguration => + scheduleConf.slots.foreach { + slot: Slot => + writer.print(slot.id) + writer.print(",") + writer.print(slot.name) + writer.print(",") + writer.print(slot.day) + writer.print(",") + writer.print(slot.from.toString("HH:mm")) + writer.print(",") + writer.print(slot.to.toString("HH:mm")) + writer.print(",") + writer.print(slot.room.name) + writer.print(",") + slot.proposal.map { + proposal => + writer.print(proposal.id) + writer.print(",") + writer.print(StringEscapeUtils.escapeCsv(proposal.title)) + writer.print(",") + writer.print(proposal.lang) + writer.print(",") + writer.print(StringEscapeUtils.escapeCsv(Messages(proposal.track.label))) + writer.print(",") + + Speaker.findByUUID(proposal.mainSpeaker).map { + speaker: Speaker => + writer.print(StringEscapeUtils.escapeCsv(speaker.cleanName)) + writer.print(",") + }.getOrElse(writer.print(",,")) + + proposal.secondarySpeaker.map { + secSpeaker => + Speaker.findByUUID(secSpeaker).map { + s: Speaker => + writer.print(StringEscapeUtils.escapeCsv(s.cleanName)) + writer.print(",") + }.getOrElse(writer.print(",,")) + }.getOrElse(writer.print(",,")) + + proposal.otherSpeakers.size match { + case 0 => writer.print(",,,,") + case 1 => { + proposal.otherSpeakers.map { + otherSpeakerId => + Speaker.findByUUID(otherSpeakerId).map { + s2: Speaker => + writer.print(StringEscapeUtils.escapeCsv(s2.cleanName)) + writer.print(",") + }.getOrElse(writer.print(",,")) + } + writer.print(",,") + } + case 2 => { + proposal.otherSpeakers.map { + otherSpeakerId => + Speaker.findByUUID(otherSpeakerId).map { + s2: Speaker => + writer.print(StringEscapeUtils.escapeCsv(s2.cleanName)) + writer.print(",") + }.getOrElse(writer.print(",,")) + } + } + case 3 => { + proposal.otherSpeakers.map { + otherSpeakerId => + Speaker.findByUUID(otherSpeakerId).map { + s2: Speaker => + writer.print(StringEscapeUtils.escapeCsv(s2.cleanName)) + writer.print(",") + }.getOrElse(writer.print(",,")) + } + } + case 4 => { + proposal.otherSpeakers.map { + otherSpeakerId => + Speaker.findByUUID(otherSpeakerId).map { + s2: Speaker => + writer.print(StringEscapeUtils.escapeCsv(s2.cleanName)) + writer.print(",") + }.getOrElse(writer.print(",,")) + } + } + } + + }.getOrElse { + writer.print(",,,,,,,") + } + writer.println("") + + } + } + writer.close() + + Ok("Done - Check target CFP folder") + + } + +} diff --git a/conf/routes b/conf/routes index 6e355d516..2b4ece411 100644 --- a/conf/routes +++ b/conf/routes @@ -159,6 +159,9 @@ GET /ar/doMassRefuseAndRedirect # For Fun, it works only if you have Elastic Search GET /cloudtags controllers.CallForPaper.cloudTags() +# For Paper guide +GET /guide/exported controllers.PaperGuide.exportProgram() + # Content Publisher # If you plan to use the CFP for your program, you can adapt the URLs below # Please, do not try to propose a configurable system here, as each Conference has its own URLs From 42f5d6641a99774ff65b24bb1461d5166aa61db3 Mon Sep 17 00:00:00 2001 From: Nicolas Martignole Date: Mon, 11 Apr 2016 16:50:30 +0200 Subject: [PATCH 3/6] feat(program): export to CSV the full program --- app/controllers/PaperGuide.scala | 59 +++++++------------------------- 1 file changed, 13 insertions(+), 46 deletions(-) diff --git a/app/controllers/PaperGuide.scala b/app/controllers/PaperGuide.scala index 56bece3cf..88e66c153 100644 --- a/app/controllers/PaperGuide.scala +++ b/app/controllers/PaperGuide.scala @@ -47,9 +47,10 @@ object PaperGuide extends SecureCFPController { scheduledConf <- ScheduleConfiguration.loadScheduledConfiguration(scheduleId) ) yield scheduledConf - val file = new File("./target/guide", "DEVOXX_" + allScheduledConf.hashCode() + ".csv") + val file = new File("./target", "DEVOXX_UTF8_" + allScheduledConf.hashCode() + ".csv") val writer = new PrintWriter(file, "MacRoman") // !!! ENCODING !!! - writer.println("id,name,day,from,to,roomName,proposalId,proposalTitle,proposalLang,track,speakerName,secSpeakerName,thirdSpeaker,fourthSpeaker") +// val writer = new PrintWriter(file, "UTF-8") + writer.println("id,name,day,from,to,roomName,proposalId,proposalTitle,proposalLang,track,firstSpeaker,secondarySpeaker,thirdSpeaker,fourthSpeaker,fifthSpeaker") allScheduledConf.foreach { scheduleConf: ScheduleConfiguration => @@ -93,53 +94,19 @@ object PaperGuide extends SecureCFPController { }.getOrElse(writer.print(",,")) }.getOrElse(writer.print(",,")) - proposal.otherSpeakers.size match { - case 0 => writer.print(",,,,") - case 1 => { - proposal.otherSpeakers.map { - otherSpeakerId => - Speaker.findByUUID(otherSpeakerId).map { - s2: Speaker => - writer.print(StringEscapeUtils.escapeCsv(s2.cleanName)) - writer.print(",") - }.getOrElse(writer.print(",,")) - } - writer.print(",,") - } - case 2 => { - proposal.otherSpeakers.map { - otherSpeakerId => - Speaker.findByUUID(otherSpeakerId).map { - s2: Speaker => - writer.print(StringEscapeUtils.escapeCsv(s2.cleanName)) - writer.print(",") - }.getOrElse(writer.print(",,")) - } - } - case 3 => { - proposal.otherSpeakers.map { - otherSpeakerId => - Speaker.findByUUID(otherSpeakerId).map { - s2: Speaker => - writer.print(StringEscapeUtils.escapeCsv(s2.cleanName)) - writer.print(",") - }.getOrElse(writer.print(",,")) - } - } - case 4 => { - proposal.otherSpeakers.map { - otherSpeakerId => - Speaker.findByUUID(otherSpeakerId).map { - s2: Speaker => - writer.print(StringEscapeUtils.escapeCsv(s2.cleanName)) - writer.print(",") - }.getOrElse(writer.print(",,")) - } - } + val otherSpeakersNames = proposal.otherSpeakers.map{ + id:String=> + Speaker.findByUUID(id).map{s=> + StringEscapeUtils.escapeCsv(s.cleanName) + "," + }.getOrElse(",,") } + val paddedToSixSpeakers = otherSpeakersNames.padTo(6,",") + + paddedToSixSpeakers.foreach{token=>writer.print(token)} + }.getOrElse { - writer.print(",,,,,,,") + writer.print(",,,,,,,,") } writer.println("") From a0bd3a53208a5eb499d46938f9b42f92a7be727b Mon Sep 17 00:00:00 2001 From: Nicolas Martignole Date: Fri, 15 Apr 2016 10:48:43 +0200 Subject: [PATCH 4/6] specific to Devoxx France 2016 --- app/controllers/Publisher.scala | 15 ++-- app/models/ConferenceDescriptor.scala | 2 + app/models/Slot.scala | 43 ++++++++++-- .../Publisher/showAgendaByConfType.scala.html | 48 +++++-------- app/views/Publisher/showOneDay.scala.html | 70 +++++++++---------- .../tags/publisher/renderFavorite.scala.html | 1 - .../tags/publisher/renderOneDay.scala.html | 12 ++++ .../tags/publisher/tagRenderRow.scala.html | 41 +++++++---- conf/messages | 1 + conf/messages.fr | 3 +- 10 files changed, 138 insertions(+), 98 deletions(-) create mode 100644 app/views/tags/publisher/renderOneDay.scala.html diff --git a/app/controllers/Publisher.scala b/app/controllers/Publisher.scala index 3b2175644..4339bde25 100644 --- a/app/controllers/Publisher.scala +++ b/app/controllers/Publisher.scala @@ -133,40 +133,40 @@ object Publisher extends Controller { maybeScheduledConfiguration match { case Some(slotConfig) if day == null => { val updatedConf = slotConfig.copy(slots = slotConfig.slots) - Ok(views.html.Publisher.showAgendaByConfType(updatedConf, confType, "wednesday")) + Ok(views.html.Publisher.showAgendaByConfType(updatedConf.slots, confType, "wednesday")) } case Some(slotConfig) if day == "monday" => { val updatedConf = slotConfig.copy(slots = slotConfig.slots.filter(_.day == "monday") , timeSlots = slotConfig.timeSlots.filter(_.start.getDayOfWeek == 1)) - Ok(views.html.Publisher.showAgendaByConfType(updatedConf, confType, "monday")) + Ok(views.html.Publisher.showAgendaByConfType(updatedConf.slots, confType, "monday")) } case Some(slotConfig) if day == "tuesday" => { val updatedConf = slotConfig.copy( slots = slotConfig.slots.filter(_.day == "tuesday") , timeSlots = slotConfig.timeSlots.filter(_.start.getDayOfWeek == 2) ) - Ok(views.html.Publisher.showAgendaByConfType(updatedConf, confType, "tuesday")) + Ok(views.html.Publisher.showAgendaByConfType(updatedConf.slots, confType, "tuesday")) } case Some(slotConfig) if day == "wednesday" => { val updatedConf = slotConfig.copy( slots = slotConfig.slots.filter(_.day == "wednesday") , timeSlots = slotConfig.timeSlots.filter(_.start.getDayOfWeek == 3) ) - Ok(views.html.Publisher.showAgendaByConfType(updatedConf, confType, "wednesday")) + Ok(views.html.Publisher.showAgendaByConfType(updatedConf.slots, confType, "wednesday")) } case Some(slotConfig) if day == "thursday" => { val updatedConf = slotConfig.copy( slots = slotConfig.slots.filter(_.day == "thursday") , timeSlots = slotConfig.timeSlots.filter(_.start.getDayOfWeek == 4) ) - Ok(views.html.Publisher.showAgendaByConfType(updatedConf, confType, "thursday")) + Ok(views.html.Publisher.showAgendaByConfType(updatedConf.slots, confType, "thursday")) } case Some(slotConfig) if day == "friday" => { val updatedConf = slotConfig.copy( slots = slotConfig.slots.filter(_.day == "friday") , timeSlots = slotConfig.timeSlots.filter(_.start.getDayOfWeek == 5) ) - Ok(views.html.Publisher.showAgendaByConfType(updatedConf, confType, "friday")) + Ok(views.html.Publisher.showAgendaByConfType(updatedConf.slots, confType, "friday")) } case None => NotFound(views.html.Publisher.agendaNotYetPublished()) @@ -176,9 +176,8 @@ object Publisher extends Controller { def showByDay(day: String) = Action { implicit request => - def _showDay(slots: List[Slot], day: String) = { - val rooms = slots.groupBy(_.room).keys.toList.sortBy(_.id) + val rooms = slots.groupBy(_.room).keys.toList val allSlots = ScheduleConfiguration.getPublishedScheduleByDay(day) Ok(views.html.Publisher.showOneDay(allSlots, rooms, day)) } diff --git a/app/models/ConferenceDescriptor.scala b/app/models/ConferenceDescriptor.scala index 6780fa5ac..45f25582f 100644 --- a/app/models/ConferenceDescriptor.scala +++ b/app/models/ConferenceDescriptor.scala @@ -212,6 +212,8 @@ object ConferenceDescriptor { // Tip : I use the ID to sort-by on the view per day... So if the exhibition floor id is "aaa" it will be // the first column on the HTML Table + + // Do not change the ID's once the program is published val HALL_EXPO = Room("a_hall", "Exhibition floor", 2300, "special", "") val HALL_A = Room("x_hall_a", "Open Data Camp", 100, "special", "") diff --git a/app/models/Slot.scala b/app/models/Slot.scala index db42e4d1b..c2c74ab7f 100644 --- a/app/models/Slot.scala +++ b/app/models/Slot.scala @@ -25,8 +25,6 @@ package models import org.joda.time.DateTime import play.api.libs.json.Json -import play.api.libs.json._ -import play.api.libs.functional.syntax._ /** * Time slots and Room are defined as static file. @@ -38,8 +36,6 @@ import play.api.libs.functional.syntax._ case class Room(id: String, name: String, capacity: Int, setup: String, recorded:String) extends Ordered[Room] { - import scala.math.Ordered.orderingToOrdered - def index: Int = { val regexp = "[\\D\\s]+(\\d+)".r id match { @@ -48,7 +44,17 @@ case class Room(id: String, name: String, capacity: Int, setup: String, recorded } } - def compare(that: Room): Int = (this.id.substring(0, 3), this.index) compare(that.id.substring(0, 3), that.index) + def compare(that: Room): Int = { + // TODO a virer apres Devoxx FR 2016 + // Hack for Devoxx France => I cannot change the Room IDs so I fix the order in an IndexedSeq here + if(Room.fixedOrderForRoom.indexOf(this.id) < Room.fixedOrderForRoom.indexOf(that.id)){ + return -1 + } +if(Room.fixedOrderForRoom.indexOf(this.id) > Room.fixedOrderForRoom.indexOf(that.id)){ + return 1 + } + return 0 + } } object Room { @@ -62,6 +68,33 @@ object Room { ConferenceDescriptor.ConferenceRooms.allRooms.find(r => r.id == roomId).getOrElse(OTHER) } + // TODO à virer apres Devoxx FR 2016 + val fixedOrderForRoom = IndexedSeq("a_hall", + "b_amphi", + "c_maillot", + "d_par241", + "f_neu251", + "e_neu252", + "par242AB", + "par242A", + "par242AT", + "par242B", + "par242BT", + "par243", + "neu253", + "neu253_t", + "par243_t", + "par201", + "par202_203", + "par204", + "par221M-222M", + "par224M-225M", + "neu_232_232", + "neu_234_235", + "neu_212_213", + "x_hall_a" + ) + } case class SlotBreak(id: String, nameEN: String, nameFR: String, room: Room) diff --git a/app/views/Publisher/showAgendaByConfType.scala.html b/app/views/Publisher/showAgendaByConfType.scala.html index ceeba8a6d..f3123d858 100644 --- a/app/views/Publisher/showAgendaByConfType.scala.html +++ b/app/views/Publisher/showAgendaByConfType.scala.html @@ -1,7 +1,7 @@ -@(schedule: ScheduleConfiguration, talkType: String, day: String)(implicit lang: Lang, flash: Flash, req: RequestHeader) -@import org.joda.time.DateTimeZone +@(slots: List[Slot], talkType: String, day: String)(implicit lang: Lang, flash: Flash, req: RequestHeader) + @import org.joda.time.DateTimeZone - @views.html.Publisher.devoxxFR2016(Messages("agenda-" + talkType),Some(s"Agenda for Devoxx FR 2016 for $day"+Messages("day-" + day))) { + @views.html.Publisher.devoxxFR2016(Messages("agenda-" + talkType), Some(s"Agenda for Devoxx FR 2016 for $day" + Messages("day-" + day))) {

@Messages(talkType), @Messages("day-" + day)

@Messages(talkType), @Messages("day-" + day)

- - @schedule.slots.groupBy(_.room).keys.toList.sorted.map { room: Room => + + @slots.groupBy(_.room).keys.toList.sorted.map { room: Room => } - @if(day.toLowerCase=="thursday" && talkType.toLowerCase=="conf" ){ + @if(day.toLowerCase == "thursday" && talkType.toLowerCase == "conf") { } - @if(day.toLowerCase=="friday" && talkType.toLowerCase=="conf" ){ + @if(day.toLowerCase == "friday" && talkType.toLowerCase == "conf") { } - @schedule.slots.groupBy(_.from).toList.sortBy(_._1.toDate.getTime).map { case (time: org.joda.time.DateTime, slots) => + @slots.groupBy(_.from.getMillis).toList.sortWith(_._1 < _._1).map { case (_, subSlots) => - @slots.sortBy(_.room).zipWithIndex.map { case(slot,index) => - - + @subSlots.groupBy(_.room).keys.toList.sorted.map { room: Room => + @tags.publisher.tagRenderRow(subSlots, room, 17) } } - - @schedule.slots.groupBy(_.room).keys.toList.sorted.map { room: Room => - + + @slots.groupBy(_.room).keys.toList.sorted.map { roomName: Room => + }
Salle @Messages("publisher.room")@room.name
09:00 - 11:00 Keynotes dès 9h précise
- Le programme détaillé sera publié ultérieurement. Accueil + Petit-déjeuner dès 7h30
- + Accueil + Petit-déjeuner dès 7h30
09:30 - 11:00 Keynotes 9h30
- Le programme détaillé sera publié ultérieurement.
- @time.toDateTime(DateTimeZone.forID("Europe/Brussels")).toString("HH:mm") - @slots.head.to.toDateTime(DateTimeZone.forID("Europe/Brussels")).toString("HH:mm") + @subSlots.head.from.toDateTime(DateTimeZone.forID("Europe/Brussels")).toString("HH:mm") + - @subSlots.head.to.toDateTime(DateTimeZone.forID("Europe/Brussels")).toString("HH:mm") - @slot.proposal.map { p: Proposal => - @tags.publisher.renderIconForTrack(p.track) @Messages(p.track.label) - @tags.publisher.renderFavorite(p.id) - @p.title - @p.allSpeakerUUIDs.map { speakerUUID => - @tags.publisher.renderSpeaker(speakerUUID) - } - - - } - @if(slot.proposal.isEmpty && slot.break.isEmpty ){ - Pas encore programmé - } -
Salle@room.name @Messages("publisher.room")@roomName.name
diff --git a/app/views/Publisher/showOneDay.scala.html b/app/views/Publisher/showOneDay.scala.html index f987dc419..67b54eb4a 100644 --- a/app/views/Publisher/showOneDay.scala.html +++ b/app/views/Publisher/showOneDay.scala.html @@ -1,46 +1,40 @@ @(slots: List[Slot], rooms: List[Room], day: String)(implicit lang: Lang, req: RequestHeader) @import org.joda.time.DateTimeZone -@views.html.Publisher.devoxxFR2016(Messages(s"sw.show.$day")) { - - -
- - - - @rooms.sorted.map { roomName: Room => - - } + + @views.html.Publisher.devoxxFR2016(Messages(s"sw.show.$day")) { + + +
+
Room@roomName.name
+ + + @slots.groupBy(_.room).keys.toList.sorted.map { roomName: Room => + + } - @slots.groupBy(s=> s.from.getMillis).toList.sortWith(_._1 < _._1).map { case (_, subSlots) => - - - @rooms.map { room => - @tags.publisher.tagRenderRow(subSlots,room,rooms.size) - } - - } - - - - @slots.groupBy(_.room).keys.toList.sorted.map { roomName: Room => - + @slots.groupBy(s => s.from.getMillis).toList.sortWith(_._1 < _._1).map { case (_, subSlots) => + @tags.publisher.renderOneDay(subSlots,slots,rooms) } - -
@Messages("publisher.room")@roomName.name
- @subSlots.head.from.toDateTime(DateTimeZone.forID("Europe/Brussels")).toString("HH:mm") - @subSlots.head.to.toDateTime(DateTimeZone.forID("Europe/Brussels")).toString("HH:mm") -
Room@roomName.name
+ + + @Messages("publisher.room") + @slots.groupBy(_.room).keys.toList.sorted.map { roomName: Room => + @roomName.name + } + + -
-} \ No newline at end of file +
+ } \ No newline at end of file diff --git a/app/views/tags/publisher/renderFavorite.scala.html b/app/views/tags/publisher/renderFavorite.scala.html index 440885ddf..02d9122f0 100644 --- a/app/views/tags/publisher/renderFavorite.scala.html +++ b/app/views/tags/publisher/renderFavorite.scala.html @@ -3,7 +3,6 @@ @defining(UserCFPController.findAuthenticator) { maybeUuid:Option[String] => @maybeUuid.map { uuid:String => @if(FavoriteTalk.isFavByThisUser(proposalId = proposalId, webuserId = uuid)) { - } else { diff --git a/app/views/tags/publisher/renderOneDay.scala.html b/app/views/tags/publisher/renderOneDay.scala.html new file mode 100644 index 000000000..4768693a1 --- /dev/null +++ b/app/views/tags/publisher/renderOneDay.scala.html @@ -0,0 +1,12 @@ +@(subSlots:List[Slot], slots:List[Slot], rooms:List[Room])(implicit req:RequestHeader) +@import org.joda.time.DateTimeZone + + + + @subSlots.head.from.toDateTime(DateTimeZone.forID("Europe/Brussels")).toString("HH:mm") + - @subSlots.head.to.toDateTime(DateTimeZone.forID("Europe/Brussels")).toString("HH:mm") + +@slots.groupBy(_.room).keys.toList.sorted.map { room: Room => + @tags.publisher.tagRenderRow(subSlots, room, rooms.size) +} + \ No newline at end of file diff --git a/app/views/tags/publisher/tagRenderRow.scala.html b/app/views/tags/publisher/tagRenderRow.scala.html index 7969cef9e..895ec2149 100644 --- a/app/views/tags/publisher/tagRenderRow.scala.html +++ b/app/views/tags/publisher/tagRenderRow.scala.html @@ -1,24 +1,39 @@ -@(subSlots: List[Slot], room: Room, roomSize: Int)(implicit req:RequestHeader) +@(subSlots: List[Slot], room: Room, roomSize: Int)(implicit req: RequestHeader) @subSlots.filter(_.room.id == room.id).map { zeSlot: Slot => @zeSlot.proposal.map { p: Proposal => - - @Messages(p.talkType.id) - @tags.publisher.renderIconForTrack(p.track) @Messages(p.track.label) @tags.publisher.renderFavorite(p.id) - @p.title - @p.allSpeakerUUIDs.map { speakerUUID => - @tags.publisher.renderSpeaker(speakerUUID) - } - + + @if(p.talkType == ConferenceDescriptor.ConferenceProposalTypes.KEY) { + + @Messages(p.talkType.id) (retransmission en salle Maillot, Neuilly 252-AB et Paris 242-AB) +

@p.title

+ @p.allSpeakerUUIDs.map { speakerUUID => + @tags.publisher.renderSpeaker(speakerUUID,true) + } + @tags.publisher.renderFavorite(p.id) + + } else { + + @Messages(p.talkType.id) + @tags.publisher.renderIconForTrack(p.track) + @p.title + @p.allSpeakerUUIDs.map { speakerUUID => + @tags.publisher.renderSpeaker(speakerUUID) + } + @tags.publisher.renderFavorite(p.id) + + } + + } @if(zeSlot.break.isDefined) { - @Messages("tagRenderRow-"+zeSlot.break.get.id) + @Messages("tagRenderRow-" + zeSlot.break.get.id) } - @if(zeSlot.notAllocated) { - TBA - } + @if(zeSlot.notAllocated) { + TBA + } } @if(!subSlots.exists(_.room.id == room.id)) { diff --git a/conf/messages b/conf/messages index 50a051511..0d17bd72e 100644 --- a/conf/messages +++ b/conf/messages @@ -809,3 +809,4 @@ cfpadmin.toreview={0} proposal(s) to review cfpAdmin.showWhenCreated=Submitted to the CFP on {0} publisher.showMore=See proposal details +publisher.room=Room \ No newline at end of file diff --git a/conf/messages.fr b/conf/messages.fr index 768576041..e9060a8cb 100644 --- a/conf/messages.fr +++ b/conf/messages.fr @@ -762,4 +762,5 @@ noPasswordHere=Le site du CFP ne vous permet pas de configurer un mot de passe, cfpadmin.toreview={0} sujet(s) à noter cfpAdmin.showWhenCreated=Sujet soumis par le speaker sur le CFP le {0} -publisher.showMore=Voir la description \ No newline at end of file +publisher.showMore=Voir la description +publisher.room=Salle \ No newline at end of file From e845f46f6204c76bb38c32d45fd0fd52a267eecd Mon Sep 17 00:00:00 2001 From: Nicolas Martignole Date: Fri, 15 Apr 2016 11:08:49 +0200 Subject: [PATCH 5/6] Devoxx FR 2016 only --- app/models/ConferenceDescriptor.scala | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/app/models/ConferenceDescriptor.scala b/app/models/ConferenceDescriptor.scala index 45f25582f..e212d96a3 100644 --- a/app/models/ConferenceDescriptor.scala +++ b/app/models/ConferenceDescriptor.scala @@ -461,23 +461,17 @@ object ConferenceDescriptor { val keynoteThursdaySlot2 = ConferenceRooms.keynoteRoom.map { r2 => SlotBuilder(ConferenceProposalTypes.KEY.id, "thursday", - new DateTime("2016-04-21T09:40:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), - new DateTime("2016-04-21T10:00:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), r2) + new DateTime("2016-04-21T09:45:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), + new DateTime("2016-04-21T10:05:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), r2) } val keynoteThursdaySlot3 = ConferenceRooms.keynoteRoom.map { r3 => SlotBuilder(ConferenceProposalTypes.KEY.id, "thursday", - new DateTime("2016-04-21T10:05:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), - new DateTime("2016-04-21T10:25:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), r3) - } - val keynoteThursdaySlot4 = ConferenceRooms.keynoteRoom.map { - r4 => - SlotBuilder(ConferenceProposalTypes.KEY.id, "thursday", - new DateTime("2016-04-21T10:25:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), - new DateTime("2016-04-21T10:45:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), r4) + new DateTime("2016-04-21T10:10:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), + new DateTime("2016-04-21T10:30:00.000+02:00").toDateTime(DateTimeZone.forID("Europe/Paris")), r3) } - keynoteThursdayWelcome ++keynoteThursdaySlot1 ++ keynoteThursdaySlot2 ++ keynoteThursdaySlot3 ++ keynoteThursdaySlot4 + keynoteThursdayWelcome ++keynoteThursdaySlot1 ++ keynoteThursdaySlot2 ++ keynoteThursdaySlot3 } val keynoteSlotsFriday: List[Slot] = { From 44b3731e78fcaf143038aeb1753e4a15d29ecf5c Mon Sep 17 00:00:00 2001 From: Nicolas Martignole Date: Sun, 8 May 2016 10:02:42 +0200 Subject: [PATCH 6/6] last commit during Devoxx FR 2016 --- .../allSpeakersWithAcceptedTalksAndBadge.scala.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/CFPAdmin/allSpeakersWithAcceptedTalksAndBadge.scala.html b/app/views/CFPAdmin/allSpeakersWithAcceptedTalksAndBadge.scala.html index 190784019..c18b196e8 100644 --- a/app/views/CFPAdmin/allSpeakersWithAcceptedTalksAndBadge.scala.html +++ b/app/views/CFPAdmin/allSpeakersWithAcceptedTalksAndBadge.scala.html @@ -1,4 +1,4 @@ -@(proposals: List[(Speaker, Iterable[Proposal])])(implicit lang: Lang, flash: Flash, req: RequestHeader) +@(speakersAndProposals: List[(Speaker, Iterable[Proposal])])(implicit lang: Lang, flash: Flash, req: RequestHeader) @main("CFP Speakers") {
@@ -24,8 +24,9 @@

CFP Admin

All speakers with a badge

Primary or secondary speaker, with a speaker badge + CFP or Red Coat not included No Quickies or B.O.F - @proposals.size speakers + @speakersAndProposals.size speakers
-        @proposals.sortBy(_._1.name.map(_.capitalize)).map{case(speaker,props)=>
-@speaker.name.get.head.toString;@speaker.name.map(_.toUpperCase);@speaker.firstName.get;@speaker.email;@speaker.company.getOrElse("");@speaker.twitter.getOrElse("") }
+        @speakersAndProposals.sortBy(_._1.name.map(_.capitalize)).map{case(speaker,props)=>
+"@speaker.name.get.head.toString","@speaker.name.map(_.toUpperCase)","@speaker.firstName.get","@speaker.email.trim","@speaker.company.getOrElse("")","@speaker.cleanTwitter.map(_.drop(1))" }