Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Multiple fixes for hnofficehours #28

Open
wants to merge 13 commits into from

2 participants

@apenwarr
Collaborator

Hi,

I skimmed the comments on HN and also found some bugs of my own. I had a bit of time today so I blew through the most critically broken stuff, including the "upcoming office hours" list being full of lies.

I also changed the calendar so your start and end date has to be on the same day, which is much more user friendly. Recurrences exist to cover multi-day availability.

Hope you like it.

Have fun,

Avery

apenwarr added some commits
@apenwarr apenwarr manage.py: make executable.
So we can do "./manage.py runserver" instead of "python manage.py
runserver" if we're lazy.
e13d833
@apenwarr apenwarr apps/search/views.py: backwards compatibility for python 2.5.
"except xx as yy" required python 2.6 or newer.
cdf2979
@apenwarr apenwarr .gitignore: ignore *~ files generated by some editors. 2dc8a2a
@apenwarr apenwarr settings.py: make a note to help people find which packages are requi…
…red.
4a64cb8
@apenwarr apenwarr In "Upcoming Office Hours", use the occurrence date, not the start date.
occurrence.event.start is the start of the recurrence *series*.  We want the
current individual event, which is occurrence.start.
20fecdf
@apenwarr apenwarr Upcoming Office Hours: only print the first occurrence per person.
If you want more occurrences for that person, you can click their name.
091904b
@apenwarr apenwarr If an office hour entry is all in one day, show the date only once. 20d5ce4
@apenwarr apenwarr datepicker: set a minimum date, and let the user select the month. c6d30e2
@apenwarr apenwarr Get rid of a male-presumptive pronoun.
(as complained about in HN comments)
0da86a0
@apenwarr apenwarr Timezone selector: sort by GMT offset and *then* name, not just name.
It's a lot easier to find your timezone name this way if you already know
your offset.
abcdc99
@apenwarr apenwarr apps/profiles/urls: fix a crash for usernames with dashes and dots.
urls.py was using \w+, which isn't flexible enough.
78bb4fc
@apenwarr apenwarr Add missing media files from the jquery-ui theme.
The most notable improvements are:

- no more django errors about missing files (especially on the "add office
  hours" page).

- the calendar actually has forward/back month buttons now.
3e1ef63
@apenwarr apenwarr View profile page: hyperlink back to the user's HN profile. 85f7e7d
@bitemyapp
Collaborator

Did anyone merge this in? I just noticed this and didn't know if ezl took care of this or not.

@apenwarr
Collaborator

Nobody has merged it. This project seems fairly dead.

@bitemyapp
Collaborator

Let me get in touch with ezl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 28, 2010
  1. @apenwarr

    manage.py: make executable.

    apenwarr authored
    So we can do "./manage.py runserver" instead of "python manage.py
    runserver" if we're lazy.
  2. @apenwarr

    apps/search/views.py: backwards compatibility for python 2.5.

    apenwarr authored
    "except xx as yy" required python 2.6 or newer.
  3. @apenwarr
  4. @apenwarr
  5. @apenwarr

    In "Upcoming Office Hours", use the occurrence date, not the start date.

    apenwarr authored
    occurrence.event.start is the start of the recurrence *series*.  We want the
    current individual event, which is occurrence.start.
  6. @apenwarr

    Upcoming Office Hours: only print the first occurrence per person.

    apenwarr authored
    If you want more occurrences for that person, you can click their name.
  7. @apenwarr
  8. @apenwarr
  9. @apenwarr

    Get rid of a male-presumptive pronoun.

    apenwarr authored
    (as complained about in HN comments)
  10. @apenwarr

    Timezone selector: sort by GMT offset and *then* name, not just name.

    apenwarr authored
    It's a lot easier to find your timezone name this way if you already know
    your offset.
  11. @apenwarr

    apps/profiles/urls: fix a crash for usernames with dashes and dots.

    apenwarr authored
    urls.py was using \w+, which isn't flexible enough.
  12. @apenwarr

    Add missing media files from the jquery-ui theme.

    apenwarr authored
    The most notable improvements are:
    
    - no more django errors about missing files (especially on the "add office
      hours" page).
    
    - the calendar actually has forward/back month buttons now.
  13. @apenwarr
This page is out of date. Refresh to see the latest.
Showing with 48 additions and 13 deletions.
  1. +1 −0  .gitignore
  2. +3 −2 apps/profiles/models.py
  3. +2 −2 apps/profiles/urls.py
  4. +2 −2 apps/search/views.py
  5. 0  manage.py
  6. BIN  media/schedule/css/images/ui-bg_flat_30_cccccc_40x100.png
  7. BIN  media/schedule/css/images/ui-bg_flat_50_5c5c5c_40x100.png
  8. BIN  media/schedule/css/images/ui-bg_glass_20_555555_1x400.png
  9. BIN  media/schedule/css/images/ui-bg_glass_40_0078a3_1x400.png
  10. BIN  media/schedule/css/images/ui-bg_glass_40_ffc73d_1x400.png
  11. BIN  media/schedule/css/images/ui-bg_gloss-wave_25_333333_500x100.png
  12. BIN  media/schedule/css/images/ui-bg_highlight-soft_80_eeeeee_1x100.png
  13. BIN  media/schedule/css/images/ui-bg_inset-soft_25_000000_1x100.png
  14. BIN  media/schedule/css/images/ui-bg_inset-soft_30_f58400_1x100.png
  15. BIN  media/schedule/css/images/ui-icons_222222_256x240.png
  16. BIN  media/schedule/css/images/ui-icons_4b8e0b_256x240.png
  17. BIN  media/schedule/css/images/ui-icons_a83300_256x240.png
  18. BIN  media/schedule/css/images/ui-icons_cccccc_256x240.png
  19. BIN  media/schedule/css/images/ui-icons_ffffff_256x240.png
  20. +9 −0 media/schedule/css/jquery.tooltip.css
  21. +1 −1  settings.py
  22. +1 −1  settings_local.copy
  23. +3 −1 templates/profiles/view_profile.html
  24. +10 −2 templates/schedule/event_form_base.html
  25. +7 −1 templates/upcoming_office_hour.html
  26. +9 −1 views.py
View
1  .gitignore
@@ -2,3 +2,4 @@ settings_local.py
*.sqlite3
pip-log.txt
*.pyc
+*~
View
5 apps/profiles/models.py
@@ -4,6 +4,7 @@
from tagging.fields import TagField
from tagging.models import Tag
from tagging_autocomplete.models import TagAutocompleteField
+from timezones.zones import PRETTY_TIMEZONE_CHOICES
from timezones.fields import TimeZoneField
class Profile(models.Model):
@@ -13,8 +14,8 @@ class Profile(models.Model):
gchat = models.CharField("Google Chat", max_length=20, null=True, blank=True)
phone = models.CharField("Phone number", max_length=20, null=True, blank=True)
is_available = models.BooleanField("Available now")
- timezone = TimeZoneField()
-
+ timezone = TimeZoneField(choices=sorted(PRETTY_TIMEZONE_CHOICES,
+ key=lambda x: (int(x[1][4:9]), x[1])))
skills = models.ManyToManyField('Skill', blank=True)
def __unicode__(self):
return unicode(self.user)
View
4 apps/profiles/urls.py
@@ -7,8 +7,8 @@
name='ajax_toggle_availability'),
url(r'^set_availability/(?P<set_status>\d)/$', 'set_availability',
name='set_availability'),
- url(r'^skills/(?P<skill>\w+)/$', 'list_profiles_by_skill',
+ url(r'^skills/(?P<skill>[-.\w]+)/$', 'list_profiles_by_skill',
name='list_profiles_by_skill'),
- url(r'^(?P<username>\w+)/$', 'view_profile', name='view_profile'),
+ url(r'^(?P<username>[-.\w]+)/$', 'view_profile', name='view_profile'),
url(r'^(?P<profile_id>\d+)/skill/(?P<skill_id>\d+)/(?P<verb>\w+)/$', 'ajax_view', name='ajax-view'),
)
View
4 apps/search/views.py
@@ -14,12 +14,12 @@ def search(request):
try:
qs = [list(chain(*[skill.profile_set.all() for skill in Skill.objects.filter(name__contains=tag_clean(qry))])) for qry in query_list]
results = list(set(qs[0]).intersection(*qs))
- except Exception as e:
+ except Exception, e:
results = None
else:
try:
results = list(chain(Skill.objects.get(name__contains=query_list[0]).profile_set.all()))
- except Exception as e:
+ except Exception, e:
if e.__class__ == Skill.MultipleObjectsReturned:
results = list(chain(*[skill.profile_set.all() for skill in Skill.objects.filter(name__contains=query_list[0])]))
else:
View
0  manage.py 100644 → 100755
File mode changed
View
BIN  media/schedule/css/images/ui-bg_flat_30_cccccc_40x100.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-bg_flat_50_5c5c5c_40x100.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-bg_glass_20_555555_1x400.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-bg_glass_40_0078a3_1x400.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-bg_glass_40_ffc73d_1x400.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-bg_gloss-wave_25_333333_500x100.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-bg_highlight-soft_80_eeeeee_1x100.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-bg_inset-soft_25_000000_1x100.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-bg_inset-soft_30_f58400_1x100.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-icons_222222_256x240.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-icons_4b8e0b_256x240.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-icons_a83300_256x240.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-icons_cccccc_256x240.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  media/schedule/css/images/ui-icons_ffffff_256x240.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
9 media/schedule/css/jquery.tooltip.css
@@ -0,0 +1,9 @@
+#tooltip {
+ position: absolute;
+ z-index: 3000;
+ border: 1px solid #111;
+ background-color: #eee;
+ padding: 5px;
+ opacity: 0.85;
+}
+#tooltip h3, #tooltip div { margin: 0; }
View
2  settings.py
@@ -106,7 +106,7 @@
# Uncomment the next line to enable the admin:
'django.contrib.admin',
- # third-party apps:
+ # third-party apps: (see deploy/requirements.txt)
'ajax_select',
'django_extensions',
'schedule',
View
2  settings_local.copy
@@ -40,7 +40,7 @@ INSTALLED_APPS = (
# Uncomment the next line to enable the admin:
'django.contrib.admin',
- # third-party apps:
+ # third-party apps: (see deploy/requirements.txt)
'ajax_select',
'django_extensions',
'schedule',
View
4 templates/profiles/view_profile.html
@@ -21,6 +21,8 @@
</h1>
{% if display_full_profile %}
{% with user.get_profile as profile %}
+ <p><label>hn profile:</label> <a
+ href="http://news.ycombinator.com/user?id={{ user.username }}">{{ user.username }}</a></p>
<p><label>skype:</label> {{ profile.skype }}
{% if profile.skype %}
<a class="skype" href="skype:{{ profile.skype }}?call"><img src="http://mystatus.skype.com/bigclassic/{{ profile.skype }}" style="border: none;" width="182" height="44" alt="My status" /></a>
@@ -40,7 +42,7 @@
{% for skill in user.get_profile.skills.all %}
<li>{{ skill }}</li>
{% empty %}
- <li>{{ user.username }} has not listed his skills</li>
+ <li>{{ user.username }} has not listed any skills</li>
{% endfor %}
</ul>
<br />
View
12 templates/schedule/event_form_base.html
@@ -7,12 +7,20 @@
$(function() {
$("#id_start_0").datepicker({
dateFormat: $.datepicker.ATOM,
+ changeMonth: true,
+ changeYear: true,
+ minDate: new Date(),
onSelect: function(dateText,inst){ $("#id_end_0").val(dateText); } // automagically set end to the same date
});
- $("#id_end_0").datepicker({dateFormat: $.datepicker.ATOM});
+ $("#id_end_0").css({visibility: "hidden"});
$("#id_start_1").timePicker();
$("#id_end_1").timePicker();
- $("#id_end_recurring_period").datepicker({dateFormat: $.datepicker.ATOM});
+ $("#id_end_recurring_period").datepicker({
+ dateFormat: $.datepicker.ATOM,
+ changeMonth: true,
+ changeYear: true,
+ minDate: new Date()
+ });
var oldTime = $.timePicker("#id_start_1").getTime();
$("#id_start_1").change(function() {
if ($("#id_end_1").val()) { // Only update when second input has a value.
View
8 templates/upcoming_office_hour.html
@@ -2,7 +2,13 @@
<div>
{% with office_hour.event.creator as user %}
<h3><a href="{% url view_profile user.username %}"><em>{{ user.username }}</em></a></h3>
- <p>From {{ office_hour.event.start }} to {{ office_hour.event.end }}</p>
+ {% if office_hour.start.date == office_hour.end.date %}
+ <p>{{ office_hour.start.date }}
+ from {{ office_hour.start.time }}
+ to {{ office_hour.end.time }}</p>
+ {% else %}
+ <p>From {{ office_hour.start }} to {{ office_hour.end }}</p>
+ {% endif %}
<ul class="skill"><li>{{ user.get_profile.skills.all|join:"</li><li>" }}</li></ul>
{% endwith %}
</div>
View
10 views.py
@@ -23,7 +23,15 @@ def site_index(request, template_name='index.html'):
users = set(list(users_available_now) + users_holding_office_hours_now)
future = Period(events=events, start=datetime.now(),
end=datetime.now() + timedelta(days=MAX_FUTURE_DAYS))
- upcoming_office_hours = future.get_occurrences()
+ upcoming_office_hours = []
+ already_saw = {}
+ for i in future.get_occurrences():
+ if len(upcoming_office_hours) >= MAX_FUTURE_OFFICE_HOURS:
+ break
+ if already_saw.get(i.event.creator):
+ continue
+ upcoming_office_hours.append(i)
+ already_saw[i.event.creator] = 1
upcoming_office_hours = upcoming_office_hours[:MAX_FUTURE_OFFICE_HOURS]
return direct_to_template(request, template_name, locals())
Something went wrong with that request. Please try again.