-
Notifications
You must be signed in to change notification settings - Fork 45
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
activity: Make activity page with graphs on issues #27
Conversation
activity/scraper.py
Outdated
import datetime | ||
from dateutil import parser, relativedelta | ||
|
||
issuesurl = "https://coala.github.io/gh-board/issues.json" |
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 line contains the keyword 'coala'.
Origin: KeywordBear, Section: generalization
.
activity/index.html
Outdated
<html> | ||
|
||
<head> | ||
<title>Coala Community Activity</title> |
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 line contains the keyword 'Coala'.
Origin: KeywordBear, Section: generalization
.
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.
So, should I remove the word 'coala' or what?
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.
We don't allow "coala" here, the organization name must be dynamic.
By the way, coala is always written with lower case 'c', but in this repo, it's should be removed altogether.
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.
We can keep this as Organization Community Activity
for now, later after the model patch, this can be made dynamic.
Same for wherever you've used coala
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.
@Monal5031 okay I’ll do that, but I can’t remove it from the issuesurl since that’s a url to fetch data from? Should I add that to ignored files?
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.
# Ignore KeywordBear
activity/index.html
Outdated
</head> | ||
|
||
<body> | ||
<h1>Coala Activity</h1> |
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 line contains the keyword 'Coala'.
Origin: KeywordBear, Section: generalization
.
activity/index.html
Outdated
responsive: true, | ||
title: { | ||
display: true, | ||
text: 'Coala Community Activity' |
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 line contains the keyword 'Coala'.
Origin: KeywordBear, Section: generalization
.
activity/scraper.py
Outdated
def diff_week(d1, d2): | ||
monday1 = (d1 - datetime.timedelta(days=d1.weekday())) | ||
monday2 = (d2 - datetime.timedelta(days=d2.weekday())) | ||
return (monday1 - monday2).days / 7 |
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.
Though I am not sure about this. I think this would be rather // 7
. We need the floor value for the number of weeks right.
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.
Monday1-monday2 is guaranteed to be a multiple of 7. Since, it’s a difference in Monday’s of different weeks...
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.
Then maybe return ((d1-d2).days)//7
would be more simple.
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 purpose behind doing it this way is to make sure weeks are counted starting from Monday. So if the data is scraped on a Thursday, the current week is Monday-Thursday, and not previous Friday-Thursday, since it doesn’t make much sense mentally to have weeks not start from Monday, and also, it maintains consistency with other options(for example, year counts a month partially if it hasn’t ended yet)
What the code does is basically calculate the number of Mondays between the two dates, which is when regular calendar week changes.
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've left a comment in the code now to be clear(er) about this for future readers.
.travis.yml
Outdated
@@ -17,4 +17,9 @@ after_success: | |||
- mkdir _site public | |||
- python manage.py collectstatic --noinput | |||
- python manage.py distill-local public --force | |||
- mkdir public/activity | |||
- python activity/scraper.py |
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.
Move all of this before the django stuff.
Then the json could be loaded by djanjo, but more importantly the static components should all be managed by djanjo's asset system. (e.g. there are django addons that do cache busting)
activity/index.html
Outdated
var labels = []; | ||
var myChart; | ||
|
||
function updateChart() { |
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 should also be in static JS files, so they can be linted.
pass the document elements into the functions.
activity/scraper.py
Outdated
from dateutil import parser, relativedelta | ||
|
||
# URL to grab all issues from | ||
issuesurl = "https://coala.github.io/gh-board/issues.json" # Ignore KeywordBear |
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.
activity/scraper.py
Outdated
return (d1-d2).days | ||
|
||
# Get labels for each option | ||
month_labels = [] |
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 want the python std calendar
library, which is unfortunately not well known (and will be necessary if we add i18n).
Also move 80% of the remaining code into a class, even if it isnt well designed, because a class will force you to do some basic design, and then the indent levels will be correct , and it is easier to shuffle code around after that has been done.
activity/scraper.py
Outdated
if issue["state"] == "closed": | ||
data["week"]["closed"][dys] += 1 | ||
|
||
print(data) |
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.
hmm
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.
Printed for logging purposes currently, the rest of the codebase doesn't appear to use proper logging so I just printed it to console too :P
activity/scraper.py
Outdated
data["week"]["closed"][dys] += 1 | ||
|
||
print(data) | ||
with open('activity/data.json', 'w') as fp: |
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.
os.sep
, for proper cross platform support.
unack 0f2b4a2 |
static/charts.js
Outdated
function setChart(labels, openedData, closedData, type) { | ||
var ctx = document.getElementById("canvas"); | ||
|
||
curChart = new Chart(ctx, { |
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.
'Chart' is not defined.
Origin: JSHintBear, Section: javascript
.
static/charts.js
Outdated
function updateChart(type) { | ||
if(curChart){ curChart.destroy(); } | ||
|
||
$.getJSON({ |
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.
'$' is not defined.
Origin: JSHintBear, Section: javascript
.
static/charts.js
Outdated
function setChart(labels, openedData, closedData, type) { | ||
var ctx = document.getElementById("canvas"); | ||
|
||
curChart = new Chart(ctx, { |
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.
'Chart' is not defined.
Origin: JSHintBear, Section: javascript
.
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 a way to tell JSHintBear (or configure jshint) to ignore Chart
.
static/charts.js
Outdated
function updateChart(type) { | ||
if(curChart){ curChart.destroy(); } | ||
|
||
$.getJSON({ |
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.
'$' is not defined.
Origin: JSHintBear, Section: javascript
.
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 think you need to configure JSHintBear to accept JQuery's $
.
.travis.yml
Outdated
@@ -3,6 +3,7 @@ python: 3.6 | |||
|
|||
env: | |||
global: | |||
- ORG_NAME: "coala" |
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.
Not allowed to put the word coala anywhere in this repo; it must work dynamically; when forked to a different org, it must derive the org. I've also now created #29 for the existing use of coala
in this file.
activity/scraper.py
Outdated
print(real_data) | ||
with open('static' + os.sep + 'activity-data.json', 'w') as fp: | ||
json.dump(real_data, fp) | ||
|
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.
EOL problem here.
static/charts.js
Outdated
function updateChart(type) { | ||
if(curChart){ curChart.destroy(); } | ||
|
||
$.getJSON({ |
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 think you need to configure JSHintBear to accept JQuery's $
.
static/charts.js
Outdated
function setChart(labels, openedData, closedData, type) { | ||
var ctx = document.getElementById("canvas"); | ||
|
||
curChart = new Chart(ctx, { |
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 a way to tell JSHintBear (or configure jshint) to ignore Chart
.
Comment on ddf9751, file static/charts.js, line 61. '$' is not defined. Origin: JSHintBear, Section: |
Comment on ddf9751, file static/charts.js, line 6. 'Chart' is not defined. Origin: JSHintBear, Section: |
Comment on ddf9751, file static/charts.js, line 61. '$' is not defined. Origin: JSHintBear, Section: |
static/charts.js
Outdated
function setChart(labels, openedData, closedData, type) { | ||
var ctx = document.getElementById("canvas"); | ||
|
||
curChart = new Chart(ctx, { // Ignore JSHintBear |
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 should be able to add Chart
and $
to the globals by adding this to the top of the file:
/* globals $, Chart */
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.
Thanks, worked like a charm. :)
regex="github.com/[a-z0-9A-Z]*" | ||
git config -l | grep -o "$regex" | while read -r line ; do | ||
echo "${line:11}" | xargs echo -n > org_name.txt | ||
done |
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.
newline here please.
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.
fixed.
activity/index.html
Outdated
|
||
<body> | ||
<h1>Community Activity</h1> | ||
<script>loadTimeElements()</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.
Why not put it inside the same script tag below?
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.
Actually, this is a remain of when I was serving the page using django. It's no longer possible to display the time stamp(since it's not generated via django)
I think I'll just remove this for now.
activity/index.html
Outdated
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.js"></script> | ||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> | ||
<script src="/static/timeago.js"></script> | ||
<script src="/static/charts.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.
All of the <script>
tag can be inside the body (below the content) so it doesn't block content.
updateChart()
is called after the content anyway, so it doesn't matter.
activity/index.html
Outdated
<head> | ||
<title>Community Activity</title> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.js"></script> | ||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.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.
Is jquery 3 not compatible with Chart.js?
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.
Wasn't using it because it fails silently on getJSON
errors(and I need logging), will change.
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 it's .fail()
in jQuery 3
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.
yep, changing.
static/charts.js
Outdated
}, | ||
error: function(error_data) { | ||
console.log("error"); | ||
console.log(error_data); |
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.
console.error
is a bit accurate.
static/charts.js
Outdated
if(curChart){ curChart.destroy(); } | ||
|
||
$.getJSON({ | ||
url: "/static/activity-data.json", |
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 can use the url directly $.getJSON("/static/activity-data.json")
and have a callback as the second argument or .done()
and .fail()
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.
^ But it's optional.
|
||
regex="github.com/[a-z0-9A-Z]*" | ||
git config -l | grep -o "$regex" | while read -r line ; do | ||
echo "${line:11}" | xargs echo -n > org_name.txt |
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 think we prefer two indents by default for shell. Maybe see what ShellCheckBear says ;-)
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.
Seems not, .ci/deploy.sh uses 4 as well.
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.
that was a horribly rushed script I mostly copied from other sources and fixed up; without code review; naughty me.
https://github.com/coala/coala-bears/blob/master/.ci/deps.sh
https://github.com/coala/coala/blob/master/.misc/deps.sh
(and others in those directories)
We dont run code linting on them yet. I've created coala/coala#4952 for that. (I'll publish a backlog of new tasks tomorrow)
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 script is so small it doesnt matter; you are right we dont have a convention yet, so you dont need to update this patch to follow a non-existent coding standard)
This is just a comment. When I check ChartJS, it does not need jQuery. You need to stop using jQuery only for fetching things in the future :P For now I think it's ok since we're probably gonna need it for anything else, esp. DOM modification, |
@blazeu I'm currently also using |
static/charts.js
Outdated
$.getJSON("/static/activity-data.json", | ||
function(data) { | ||
var labels = data.year.labels; | ||
var openedData = data.year.opened; |
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.
L65 and 66 are not needed right, its getting overwritten later inside if else anyway
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.
Fixed.
activity/scraper.py
Outdated
from dateutil import parser, relativedelta | ||
|
||
class Scraper(): | ||
''' |
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.
"""
for docstrings.
activity/scraper.py
Outdated
''' | ||
|
||
# Count of months/weeks/days respectively to be scraped in past. | ||
month_count = 12 |
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 am 99% sure these constants can be obtained from calendar
. If not, they should be CONSTANTS at the top of the module.
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.
hmm, I chose these constants randomly myself. They're not representative of anything, just a number I think is good for display.(so no calendar use here)
activity/scraper.py
Outdated
|
||
# Process labels for each option | ||
for x in range(self.month_count-1, -1, -1): | ||
self.data["year"]["labels"].append(calendar.month_name[(self.date - relativedelta.relativedelta(months=x)).month]) |
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.
line length; please ensure this is being linted.
activity/scraper.py
Outdated
|
||
# Initialise data dicts | ||
self.data = { | ||
"year" : { |
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.
prefer single quotes in code.
|
||
def get_data(self): | ||
""" | ||
Get data |
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.
return type
activity/scraper.py
Outdated
# URL to grab all issues from | ||
org_name = open('org_name.txt').readline() | ||
|
||
issuesurl = "http://" + org_name + ".github.io/gh-board/issues.json" |
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.
issues_url
Make bash script to automatically determine the org the repo is for. Uses git config info. Stores org's name to org_name.txt in running folder. Fixes #29 partially
Makes class Scraper to scrape http://coala.github.io/gh-board/issues.json or similar file into a JSON containing only the statistics required. Stores file at "static/activity-data.json" Closes #25
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.
2 spaces for JS is the decision
Make activity/index.html to display the data, and static/charts.js for constructing the charts. Uses scraped file `static/activity-data.json`. Closes #25
ack 6b69490 |
When the issue data JSON is missing, an exception should occur then, instead of when failing to load the JSON. Related to coala#27
Use templates for static content, including new basic front page. Also remove unnecessary auth processor. Related to coala#27
Build scraper that scrapes issues.json from gh-board and produces a JSON file just containing stats. This JSON file is used for displaying a static page with graphs, which can be toggled from a dropdown to display past year/month or week's data.
Example page:
I haven't worked with Django before, so please let me know if something is wrong, or there are better ways to do what I do.I've since removed all uses of Django, and am deploying it individually since I couldn't get it to work with the rest of the codebase neatly(getting some errors, although it worked fine individually)The data is processed in python, and not directly in frontend to prevent browser overload(issues.json is > 27 MB)
Closes #25
TODO: Once all changes are approved, make orderly commits with proper fragmentation, description etc.(done)