-
Notifications
You must be signed in to change notification settings - Fork 96
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
17 add timezone map #77
Conversation
If anyone would like to test this locally, the user capture script can be invoked manually with |
docker-compose.yml
Outdated
# image: | ||
# context: . | ||
# command: celery -A config beat -l debug -S django | ||
scheduler: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary when using the devserver
command, that command auto starts celery beat+worker when running locally
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh, nice. I'll drop this from the compose.
docker-compose.yml
Outdated
# image: | ||
# context: . | ||
# command: celery -A config worker -l debug | ||
workers: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, this shouldn't be necessary here. The intend of the default compose file is just for run-time services locally
@@ -0,0 +1,401 @@ | |||
const timezone_mapping = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is just vanilla JS+jquery, it's best to wrap this in an IIFE, or jquery is available put it on the document on ready handler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to do this for the small other bits of js...
pyslackers_website/slack/models.py
Outdated
@@ -7,3 +7,4 @@ class Membership(models.Model): | |||
deleted_count = models.IntegerField() | |||
bot_count = models.IntegerField() | |||
timestamp = models.DateTimeField(auto_now_add=True) | |||
tz_count_json = models.TextField(default="") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the rationale of grabbing all this is some tracking and such, should we use the postgres json type so we can query data without loading it all into application memory ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't used the postgres JSON type in django before, but I see the edit to the migration but not this model - I believe that is required for it to act as we want
}, | ||
"type": "Feature", | ||
"properties": { | ||
"popupContent": `<h3>${timezone}: ${member_count} members</h3>`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The key naming is inconsistent, is this required for the map or can we use snake_case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Camelcase is required for the map, I'll switch the other counts to camel case for consistency.
pyslackers_website/slack/tasks.py
Outdated
time_zones.append(tz) | ||
|
||
counter = Counter(time_zones) | ||
tz_count_json = dumps(dict(counter)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice usage of counter, however I would prefer to not manually dump the json and let the orm handle it. https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/fields/#jsonfield
Secondly, from what I recall with the slack API and the Django cache - it should work with the object you're caching since it's a non-complex dict
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(continued, since reviews on mobile are : 💩)
For item 2, any reason to manually dump vs allowing the cache abstraction to deal with it? One favorable reason is json vs pickle, but the context and cache accept Python types so I favor that
@@ -0,0 +1,14 @@ | |||
{% load static %} | |||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.2.0/leaflet.js"></script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be extension points in the base template to put these in the right spot (on mobile, so double check, but should be extra_script
I think).
{% load static %} | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.2.0/leaflet.js"></script> | ||
<!-- leaflet requires CSS for map applied before init --> | ||
<link rel="stylesheet" href="{% static 'css/member_map.css' %}" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also they should be an extra_links
template block
<link rel="stylesheet" href="{% static 'css/member_map.css' %}" /> | ||
|
||
<div class="ui container"> | ||
<div id='leaflet_member_map' /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quoting is inconsistent with the file, please make these double quotes like the rest
@@ -0,0 +1,6 @@ | |||
#leaflet_member_map { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't be very responsive, can the available classes from semantic work for this so it responds and collapses?
I'm out of town until tomorrow but will test it out when I'm back home. |
f20bee9
to
58b241b
Compare
Changes for all requests pushed! |
|
||
}; | ||
|
||
console.log(slack_member_tz_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug statement left around
@@ -52,6 +52,10 @@ Take note of the `client_id` and `client_secret` for each, and register them wit | |||
(.venv) $ ./manage.py createoauth2app --client-id $CLIENT_ID --client-secret $CLIENT_SECRET --provider {google,twitter} | |||
``` | |||
|
|||
### Docker Environment Backend Services | |||
|
|||
The default backend services can be run with `docker-compose up`, which will both expose ports locally as well as be available for inter-dependant links through the default docker networking (Celery -> Redis, Celery -> Postgres, etc.). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this became less-relevant since the docker-compose revert. Line#28 should cover it, though maybe this is indicating we need more detail there. In any case, I think this can be reverted
console.log(slack_member_tz_count); | ||
|
||
|
||
$(window).on('orientationchange pageshow resize', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, I'm guessing this is a leaflet nuance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, this is required for us to support the responsive UI containers.
|
||
|
||
$(window).on('orientationchange pageshow resize', function () { | ||
if (!map) buildMap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self, I'll add a js check to the build later to enforce some standards. You don't need to change this, but I intend to make braces always required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added JS linting and an .eslintrc to support failing this behaviour. I've grabbed airbnb as a default nice style guide.
pyslackers_website/slack/models.py
Outdated
@@ -7,3 +7,4 @@ class Membership(models.Model): | |||
deleted_count = models.IntegerField() | |||
bot_count = models.IntegerField() | |||
timestamp = models.DateTimeField(auto_now_add=True) | |||
tz_count_json = models.TextField(default="") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't used the postgres JSON type in django before, but I see the edit to the migration but not this model - I believe that is required for it to act as we want
}, | ||
"type": "Feature", | ||
"properties": { | ||
"popupContent": `<h3>${timezone}: ${memberCount} members</h3>`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using this does mean not supporting IE at all (which is fine in my mind), I think it's a simple enough template literal that all modern major browsers support it at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switched it out for a string concat because it's the only usage.
|
||
var features = slack_member_tz_count.map(([timezone, memberCount]) => ( | ||
{ | ||
"geometry": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't have to fix this, but I would after merge if you don't: you're mixing quotes back and forth throughout this file - generally I like to see them remain consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorted and now enforceable through linting.
onEachFeature: (feature, layer) => (layer.bindPopup(feature.properties.popupContent)), | ||
|
||
pointToLayer: function (feature, latlng) { | ||
console.log(feature.member_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
debug statement left around
</div> | ||
</div> | ||
<script type="text/javascript"> | ||
const slack_member_tz_count = {{ slack_member_tz_count | safe }}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get a bit nervous depending on a global variable to exist for a script to be able to run properly - but I don't have any great ideas other than making it an arg to an IIFE (As commented above).
I do need to validate what happens when a partial does these tags and the main template this is included into defines its own, I didn't think about that prior to recommending it. In jinja you have the super()
call, django I don't think does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code itself won't get included if we don't have this variable defined, does that fit the required constraint?
pyslackers_website/slack/views.py
Outdated
@@ -20,8 +21,10 @@ class SlackInvite(FormView): | |||
|
|||
def get_context_data(self, **kwargs): | |||
context = super().get_context_data(**kwargs) | |||
slack_member_tz_count = dumps(cache.get('slack_member_tz_count', [])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that the controller/view should be dumb and not know how this data intends to be used (I think that is a display concern strictly). I think it would be best to make a new template tag that converts a python object to JSON for the view.
Along those lines, new additions require tests - if you can add something about context I'd like to see tests that operate like the blog/tests.py
for just this new context item (I can back fill the other context I already have here).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, I was hesitant to add a new template tag for this but it's doable.
I'll check out the tests as well.
91369e6
to
1141f00
Compare
This commit adds the following features: - An enhancement to the existing celery task for gathering user information. We save a large chunk of the most common time zones for display purposes. We store a JSON record in the database so we can do historical tracking of timezone membership. - A new partial template for the Slack module. This includes some Jinja2 html templating for the Leaflet map and a JS script that incldues timezone -> coordinate mapping and the Leaflet map builder. - A new tojson tag for converting objects to json string formatting. - A new package.json and associated eslint / jsbeautifyrc for managing future javascript implementation linting. This mapping is mostly generated from the public domain tzdata's "zone1970.tab" file, converted from iso6709 format and and dropped as a static mapping inside the javascript. Fixes: Specify addon version for postgresql to 9.6 to support JSON and match our Ansible playbook version
1141f00
to
7320e76
Compare
Relevant Issue:
Implements the changes requested in #17
Description of Changes
Screenshots, if applicable
Requirements