Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New timetable load #215

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
19 changes: 19 additions & 0 deletions pyconbalkan/core/static/css/components/person.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,31 @@

.presentation__talk {
color: #343C3E;

}

.presentation__workshop {
color: #666;
}

.presentation__keynote,
.presentation__talk,
.presentation__workshop {
padding-left: 1em;
}

.cat-session {
border: 1px solid;
border-radius: 2px;
width: 3em;
text-align: center;
color: #3aaee2;
font-size: 14px;
font-weight: 700;
float:left;
margin-top: 1.3em;
}

.speaker,
.organizer,
.sponsor {
Expand Down
56 changes: 56 additions & 0 deletions pyconbalkan/core/static/css/components/timetable.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,59 @@
#dates-wrapper {
text-align: center;
}

.day-select {
border: 1px solid #343C3E;
border-radius: 6px;
background: white;
font-size: 16px;
padding: 6px;
text-decoration: none;
margin: 1em;
}

.day-select:focus {outline:0;}

.day-select:active,
.day-select:hover,
.selected-day {
background: #27aae1;
color: white;
border: 1px solid transparent;
}

/*.room-timeline {*/
/* width: 1800px !important;*/
/* overflow: hidden !important;*/
/*}*/

.timetable .time-entry {
background-color: #27aae1 !important;
border: 1px solid #efefef !important;
text-decoration: none;
font-size: 14px;
}

.timetable .time-entry:hover {
background-color: #343c3e !important;
}

.timetable>section>header li {
width: 115px !important;
}

.timetable ul.room-timeline li:before {
background-image: unset !important;
}

.timetable ul.room-timeline li:after {
background-size: 112px auto !important
}

.timetable ul.room-timeline li .time-entry {
height: 140px;
}

.presentation {
display: flex;
margin: 15px 0;
Expand Down
1 change: 1 addition & 0 deletions pyconbalkan/core/static/css/timetablejs.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 1 addition & 7 deletions pyconbalkan/core/static/js/timetable.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions pyconbalkan/speaker/templates/speaker.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,22 @@ <h4 class="speaker__job"> {{ speaker.job }} {% if speaker.company %}- {{ speaker
{% for conference, presentations in conf.items %}
<h2>PyCon Balkan {{ conference }} Talks</h2>
{% for presentation in presentations %}
<div class="{{ presentation.get_type_display|lower }}__wrapper">
MaliRobot marked this conversation as resolved.
Show resolved Hide resolved
<a style="text-decoration: none" href="#talk-{{ presentation.slugify }}" name="talk-{{ presentation.slugify }}">
<h3 class="speaker__presentation presentation__{{ speaker.preffered_talk_type }}">{{ presentation.title }}</h3>
</a>
{% if presentation.type == 5 %} {# Keynote talk #}
<div class="keynote__wrapper">
<h3 class="speaker__presentation presentation__{{ speaker.preffered_talk_type }}">{{ presentation.title }}</h3>
<p>{{ presentation.description|markdownify }}</p>
</div>
{% elif presentation.type == 10 %} {# Normal talk #}
<div class="talk__wrapper">
<h3 class="speaker__presentation presentation__{{ speaker.preffered_talk_type }}">{{ presentation.title }}</h3>
<p>{{ presentation.description|markdownify }}</p>
</div>
{% elif presentation.type == 15 %} {# Workshop #}
<div class="workshop__wrapper">
<h3 class="speaker__presentation presentation__{{ speaker.preffered_talk_type }}">{{ presentation.title }}</h3>
<p>{{ presentation.description|markdownify }}</p>
</div>
{% endif %}
<div class="speaker__tags">
{% for tag in presentation.tags.all %}
<div class="speaker__presentation__tag">{{ tag }}</div>
Expand Down
97 changes: 47 additions & 50 deletions pyconbalkan/timetable/management/commands/load_timetable.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
from pyconbalkan.speaker.models import Speaker
from pyconbalkan.timetable.models import Presentation, Room, Slot

from django.core.exceptions import ObjectDoesNotExist

ALL_DATA_URL = "https://sessionize.com/api/v2/fwv5aino/view/All"


class Command(BaseCommand):
help = 'Closes the specified poll for voting'
help = 'Import data from sessionize'

def add_arguments(self, parser):
pass
Expand All @@ -24,79 +26,74 @@ def add_arguments(self, parser):

def handle(self, *args, **options):
conference = Conference.objects.get(year=options['year'])
_cant_find = []

data = requests.get(options['data_url']).json()

questions = data['questions']
categories = data['categories']
rooms = data['rooms']
sessions = data['sessions']
speakers = data['speakers']

# Sync rooms
types = categories[0]['items']
types = {x['id']:x['name'] for x in types}

Presentation.objects.filter(conference=conference).delete()
Room.objects.filter(conference=conference).delete()
Slot.objects.filter(conference=conference).delete()
all_presentations_this_year = list(Presentation.objects.filter(conference=conference).values_list("id", "title"))

for room in rooms:
Room.objects.create(
Room.objects.get_or_create(
pk=room['id'],
conference=conference,
name=room['name'],
sort_order=room['sort']
)


# Make speaker dict
speakers = {}
for _ in data['speakers']:
first_name = _.pop('firstName')
last_name = _.pop('lastName')
speakers[f"{first_name} {last_name}"] = _

for speaker in speakers.values():
for i, session in enumerate(speaker['sessions']):
speaker['sessions'][i] = list(filter(lambda _: int(_['id']) == session, data['sessions']))[0]
for session in sessions:
speaker_id = session['speakers'][0]
speaker = self.get_speaker(speaker_id, speakers)

# Attach Speaker obj from DB
speakers_qs = Speaker.objects.all().prefetch_related(
Prefetch(
"presentations",
queryset=Presentation.objects.filter(active=True, conference=conference).order_by("type")
if speaker == None:
print(speaker_id, 'Not found')
else:
speaker = speaker.id

presentation, created = Presentation.objects.get_or_create(
pk=session['id'],
active=False,
title=session['title'],
description=session['description'],
type=Presentation.PRESENTATION_TYPE_REVERSE[types[session['categoryItems'][0]]],
speaker_id=speaker,
conference_id=conference.id,
)
)

_cant_find = []
for speaker in speakers_qs:
if not any(speaker.presentations.all()):
continue

r = list(fuzzyfinder(speaker.full_name, speakers.keys()))
if not any(r):
_cant_find.append(speaker)
continue
speakers[r[0]]["model_speaker"] = speaker
speaker = speakers[r[0]]

for _ in speaker['sessions']:
r = list(fuzzyfinder(_['title'], list(zip(*all_presentations_this_year))[1]))
if not any(r):
_cant_find.append(_)


try:
presentation = Presentation.objects.get(title__icontains=_['title'])
except Presentation.DoesNotExist:
_cant_find.append(_)
# TODO NEXT YEAR MAYBE, GET TZ FROM CONFERENCE OBJECT ?!
Slot.objects.create(
from_date=timezone.make_aware(datetime.strptime(_['startsAt'], "%Y-%m-%dT%H:%M:%S")),
to_date=timezone.make_aware(datetime.strptime(_['endsAt'], "%Y-%m-%dT%H:%M:%S")),
talk=presentation,
room=Room.objects.get(pk=_['roomId']),
conference=conference
)
start = timezone.make_aware(datetime.strptime(session['startsAt'], "%Y-%m-%dT%H:%M:%S"))
end = timezone.make_aware(datetime.strptime(session['endsAt'], "%Y-%m-%dT%H:%M:%S"))
Slot.objects.get_or_create(
active=False,
from_date=start,
to_date=end,
room_id=session['roomId'],
talk_id=presentation.id,
conference_id=conference.id,
)

if any(_cant_find):
if options['force']:
print(_cant_find)
else:
raise Exception("Had problems with the following", _cant_find)

def get_speaker(self, speaker_id, speakers):
for speaker in speakers:
if speaker['id'] == speaker_id:
full_name = " ".join(speaker['fullName'].split())
try:
return Speaker.objects.get(full_name=full_name)
except ObjectDoesNotExist:
return None
return None
11 changes: 11 additions & 0 deletions pyconbalkan/timetable/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ class Presentation(AbstractConference, ActiveModel):
(KEYNOTE, 'Keynote'),
)

PRESENTATION_TYPE_REVERSE = {
'Talk': TALK,
'Workshop': WORKSHOP,
'Keynote': KEYNOTE
}

title = models.CharField(null=True, blank=True, max_length=100)
description = MarkdownxField(null=True, blank=True)
type = models.IntegerField(choices=PRESENTATION_TYPE, default=TALK)
Expand All @@ -30,6 +36,11 @@ class Presentation(AbstractConference, ActiveModel):
def slugify(self):
return slugify(self.title)

@property
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, this method should be on the speaker model, not here !

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but you need it as well here, check how url is formed: /speaker/alex-plugaru/#talk-scaling-flask-and-celery
I mean I don't know if we want to use it, but it's here for different purpose.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so what blocks you from saying session.speaker.slugify, why do you need to call session.slugify_speaker?

def slugify_speaker(self):
if self.speaker:
return slugify(self.speaker.name)

def __str__(self):
return '[{}] {}'.format(self.get_type_display(), self.title)

Expand Down
Loading