Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8aa3523

Browse files
committedJul 9, 2018
Update and include more apps to yapf
1 parent e5298bf commit 8aa3523

20 files changed

+194
-572
lines changed
 

‎.pre-commit-config.yaml

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,4 @@
11
repos:
2-
- repo: git://github.com/pre-commit/mirrors-isort
3-
sha: 'v4.3.3'
4-
hooks:
5-
- id: isort
6-
args:
7-
- --recursive
8-
- --settings-path
9-
- ./setup.cfg
10-
- .
112
- repo: local
123
hooks:
134
- id: eslint
@@ -29,4 +20,13 @@ repos:
2920
language: python
3021
entry: yapf
3122
files: \.py$
32-
args: [-r, -e, "app/**/migrations/", app/dataviz/, app/app/, app/enssubdomain/]
23+
args: ["-i", "-r", "-e", "app/**/migrations/", "-p", "app/app/", "app/avatar/", "app/credits/", "app/dataviz/", "app/enssubdomain/", "app/ethos/", "app/github/"]
24+
- repo: git://github.com/pre-commit/mirrors-isort
25+
sha: 'v4.3.4'
26+
hooks:
27+
- id: isort
28+
args:
29+
- --recursive
30+
- --settings-path
31+
- ./setup.cfg
32+
- .

‎.stickler.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ files:
1717
- 'docs'
1818
- 'node_modules/*'
1919
- 'requirements'
20-
- '**/migrations/*.py'
20+
- 'app/**/migrations/*.py'
2121
fixers:
2222
enable: false

‎Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fix-stylelint: ## Run stylelint --fix against the project directory. Requires no
2626
@npm run stylelint:fix
2727

2828
fix-yapf: ## Run yapf against any included or newly introduced Python code.
29-
@docker-compose exec web yapf -i -r -e "app/**/migrations/*.py" -p app/dataviz/ app/app/ app/enssubdomain/ app/avatar/
29+
@docker-compose exec web yapf -i -r -e "app/**/migrations/*.py" -p app/app/ app/avatar/ app/credits/ app/dataviz/ app/enssubdomain/ app/ethos/ app/github/
3030

3131
fix: fix-eslint fix-stylelint fix-isort fix-yapf ## Attempt to run all fixes against the project directory.
3232

‎app/app/settings.py

+43-127
Original file line numberDiff line numberDiff line change
@@ -53,60 +53,22 @@
5353

5454
# Application definition
5555
INSTALLED_APPS = [
56-
'corsheaders',
57-
'django.contrib.admin',
58-
'django.contrib.auth',
59-
'django.contrib.contenttypes',
60-
'django.contrib.sessions',
61-
'django.contrib.messages',
62-
'whitenoise.runserver_nostatic',
63-
'django.contrib.staticfiles',
64-
'storages',
65-
'social_django',
66-
'cookielaw',
67-
'django.contrib.humanize',
68-
'django.contrib.sitemaps',
69-
'django.contrib.sites',
70-
'django_extensions',
71-
'easy_thumbnails',
72-
'app',
73-
'avatar',
74-
'retail',
75-
'rest_framework',
76-
'bootstrap3',
77-
'marketing',
78-
'economy',
79-
'dashboard',
80-
'enssubdomain',
81-
'faucet',
82-
'tdi',
83-
'gas',
84-
'github',
85-
'legacy',
86-
'chartit',
87-
'email_obfuscator',
88-
'linkshortener',
89-
'credits',
90-
'gitcoinbot',
91-
'external_bounties',
92-
'dataviz',
93-
'ethos',
56+
'corsheaders', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes',
57+
'django.contrib.sessions', 'django.contrib.messages', 'whitenoise.runserver_nostatic', 'django.contrib.staticfiles',
58+
'storages', 'social_django', 'cookielaw', 'django.contrib.humanize', 'django.contrib.sitemaps',
59+
'django.contrib.sites', 'django_extensions', 'easy_thumbnails', 'app', 'avatar', 'retail', 'rest_framework',
60+
'bootstrap3', 'marketing', 'economy', 'dashboard', 'enssubdomain', 'faucet', 'tdi', 'gas', 'github', 'legacy',
61+
'chartit', 'email_obfuscator', 'linkshortener', 'credits', 'gitcoinbot', 'external_bounties', 'dataviz', 'ethos',
9462
'impersonate',
9563
]
9664

9765
MIDDLEWARE = [
98-
'corsheaders.middleware.CorsMiddleware',
99-
'django.middleware.security.SecurityMiddleware',
100-
'whitenoise.middleware.WhiteNoiseMiddleware',
101-
'django.contrib.sessions.middleware.SessionMiddleware',
102-
'django.middleware.locale.LocaleMiddleware',
103-
'django.middleware.common.CommonMiddleware',
104-
'django.middleware.csrf.CsrfViewMiddleware',
105-
'django.contrib.auth.middleware.AuthenticationMiddleware',
106-
'django.contrib.messages.middleware.MessageMiddleware',
107-
'django.middleware.clickjacking.XFrameOptionsMiddleware',
108-
'ratelimit.middleware.RatelimitMiddleware',
109-
'social_django.middleware.SocialAuthExceptionMiddleware',
66+
'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware',
67+
'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
68+
'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware',
69+
'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
70+
'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
71+
'ratelimit.middleware.RatelimitMiddleware', 'social_django.middleware.SocialAuthExceptionMiddleware',
11072
'impersonate.middleware.ImpersonateMiddleware',
11173
]
11274

@@ -119,28 +81,19 @@
11981
'django.contrib.auth.backends.ModelBackend',
12082
)
12183

122-
TEMPLATES = [
123-
{
124-
'BACKEND': 'django.template.backends.django.DjangoTemplates',
125-
'DIRS': [
126-
'retail/templates/',
127-
'external_bounties/templates/',
128-
'dataviz/templates',
84+
TEMPLATES = [{
85+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
86+
'DIRS': ['retail/templates/', 'external_bounties/templates/', 'dataviz/templates', ],
87+
'APP_DIRS': True,
88+
'OPTIONS': {
89+
'context_processors': [
90+
'django.template.context_processors.debug', 'django.template.context_processors.request',
91+
'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages',
92+
'app.context.insert_settings', 'social_django.context_processors.backends',
93+
'social_django.context_processors.login_redirect',
12994
],
130-
'APP_DIRS': True,
131-
'OPTIONS': {
132-
'context_processors': [
133-
'django.template.context_processors.debug',
134-
'django.template.context_processors.request',
135-
'django.contrib.auth.context_processors.auth',
136-
'django.contrib.messages.context_processors.messages',
137-
'app.context.insert_settings',
138-
'social_django.context_processors.backends',
139-
'social_django.context_processors.login_redirect',
140-
],
141-
},
14295
},
143-
]
96+
}, ]
14497

14598
SITE_ID = env.int('SITE_ID', default=1)
14699
WSGI_APPLICATION = env('WSGI_APPLICATION', default='app.wsgi.application')
@@ -151,20 +104,15 @@
151104

152105
# Password validation
153106
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
154-
AUTH_PASSWORD_VALIDATORS = [
155-
{
156-
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
157-
},
158-
{
159-
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
160-
},
161-
{
162-
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
163-
},
164-
{
165-
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
166-
},
167-
]
107+
AUTH_PASSWORD_VALIDATORS = [{
108+
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
109+
}, {
110+
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
111+
}, {
112+
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
113+
}, {
114+
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
115+
}, ]
168116

169117
REST_FRAMEWORK = {
170118
# Use Django's standard `django.contrib.auth` permissions,
@@ -323,22 +271,13 @@
323271
SOCIAL_AUTH_GITHUB_SECRET = GITHUB_CLIENT_SECRET
324272
SOCIAL_AUTH_POSTGRES_JSONFIELD = True
325273
SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ['username', 'first_name', 'last_name', 'email']
326-
SOCIAL_AUTH_GITHUB_SCOPE = [
327-
'read:public_repo',
328-
'read:user',
329-
'user:email',
330-
]
274+
SOCIAL_AUTH_GITHUB_SCOPE = ['read:public_repo', 'read:user', 'user:email', ]
331275

332276
SOCIAL_AUTH_PIPELINE = (
333-
'social_core.pipeline.social_auth.social_details',
334-
'social_core.pipeline.social_auth.social_uid',
335-
'social_core.pipeline.social_auth.auth_allowed',
336-
'social_core.pipeline.social_auth.social_user',
337-
'social_core.pipeline.user.get_username',
338-
'social_core.pipeline.user.create_user',
339-
'app.pipeline.save_profile',
340-
'social_core.pipeline.social_auth.associate_user',
341-
'social_core.pipeline.social_auth.load_extra_data',
277+
'social_core.pipeline.social_auth.social_details', 'social_core.pipeline.social_auth.social_uid',
278+
'social_core.pipeline.social_auth.auth_allowed', 'social_core.pipeline.social_auth.social_user',
279+
'social_core.pipeline.user.get_username', 'social_core.pipeline.user.create_user', 'app.pipeline.save_profile',
280+
'social_core.pipeline.social_auth.associate_user', 'social_core.pipeline.social_auth.load_extra_data',
342281
'social_core.pipeline.user.user_details',
343282
)
344283

@@ -391,10 +330,7 @@
391330
env('GA_AUTH_PROVIDER_X509_CERT_URL', default='https://www.googleapis.com/oauth2/v1/certs'),
392331
'client_x509_cert_url': env('GA_CLIENT_X509_CERT_URL', default='')
393332
}
394-
HOTJAR_CONFIG = {
395-
'hjid': env.int('HOTJAR_ID', default=0),
396-
'hjsv': env.int('HOTJAR_SV', default=0),
397-
}
333+
HOTJAR_CONFIG = {'hjid': env.int('HOTJAR_ID', default=0), 'hjsv': env.int('HOTJAR_SV', default=0), }
398334

399335
# Rollbar - https://rollbar.com/docs/notifier/pyrollbar/#django
400336
ROLLBAR_CLIENT_TOKEN = env('ROLLBAR_CLIENT_TOKEN', default='') # post_client_item
@@ -411,28 +347,10 @@
411347
'capture_ip': 'anonymize',
412348
'capture_username': True,
413349
'scrub_fields': [
414-
'pw',
415-
'passwd',
416-
'password',
417-
'secret',
418-
'confirm_password',
419-
'confirmPassword',
420-
'password_confirmation',
421-
'passwordConfirmation',
422-
'access_token',
423-
'accessToken',
424-
'auth',
425-
'authentication',
426-
'github_access_token',
427-
'github_client_secret',
428-
'secret_key',
429-
'twitter_access_token',
430-
'twitter_access_secret',
431-
'twitter_consumer_secret',
432-
'mixpanel_token',
433-
'slack_verification_token',
434-
'redirect_state',
435-
'slack_token',
350+
'pw', 'passwd', 'password', 'secret', 'confirm_password', 'confirmPassword', 'password_confirmation',
351+
'passwordConfirmation', 'access_token', 'accessToken', 'auth', 'authentication', 'github_access_token',
352+
'github_client_secret', 'secret_key', 'twitter_access_token', 'twitter_access_secret',
353+
'twitter_consumer_secret', 'mixpanel_token', 'slack_verification_token', 'redirect_state', 'slack_token',
436354
'priv_key',
437355
],
438356
}
@@ -448,9 +366,7 @@
448366
rollbar.init(**ROLLBAR)
449367

450368
# List of github usernames to not count as comments on an issue
451-
IGNORE_COMMENTS_FROM = [
452-
'gitcoinbot',
453-
]
369+
IGNORE_COMMENTS_FROM = ['gitcoinbot', ]
454370

455371
# optional: only needed if you run the activity-report management command
456372
AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID', default='')

‎app/app/sitemaps.py

+3-23
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,9 @@ class StaticViewSitemap(sitemaps.Sitemap):
1313

1414
def items(self):
1515
return [
16-
'dashboard',
17-
'new_funding',
18-
'fulfill_bounty',
19-
'process_funding',
20-
'funding_details',
21-
'tip',
22-
'terms',
23-
'privacy',
24-
'cookie',
25-
'prirp',
26-
'apitos',
27-
'about',
28-
'index',
29-
'help',
30-
'whitepaper',
31-
'whitepaper_access',
32-
'_leaderboard',
33-
'ios',
34-
'faucet',
35-
'mission',
36-
'slack',
37-
'universe_index',
38-
'results',
16+
'dashboard', 'new_funding', 'fulfill_bounty', 'process_funding', 'funding_details', 'tip', 'terms',
17+
'privacy', 'cookie', 'prirp', 'apitos', 'about', 'index', 'help', 'whitepaper', 'whitepaper_access',
18+
'_leaderboard', 'ios', 'faucet', 'mission', 'slack', 'universe_index', 'results',
3919
]
4020

4121
def location(self, item):

‎app/app/utils.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,7 @@ def sync_profile(handle, user=None, hide_profile=True):
122122
rollbar.report_message('Failed to fetch github username', 'warning', extra_data=data)
123123
return None
124124

125-
defaults = {
126-
'last_sync_date': timezone.now(),
127-
'data': data,
128-
'hide_profile': hide_profile,
129-
}
125+
defaults = {'last_sync_date': timezone.now(), 'data': data, 'hide_profile': hide_profile, }
130126

131127
if user and isinstance(user, User):
132128
defaults['user'] = user

‎app/avatar/admin.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ class AvatarAdmin(GeneralAdmin):
4545
ordering = ['-id']
4646
fields = ['config', 'use_github_avatar', 'svg_asset', 'png_asset', 'created_on', 'modified_on']
4747
readonly_fields = ['svg_asset', 'png_asset', 'created_on', 'modified_on']
48-
inlines = [
49-
ProfileInline,
50-
]
48+
inlines = [ProfileInline, ]
5149

5250
def svg_asset(self, instance):
5351
"""Define the avatar SVG tag to be displayed in the admin."""

‎app/avatar/urls.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,4 @@
2323
from .views import avatar, save_avatar
2424

2525
app_name = 'avatar'
26-
urlpatterns = [
27-
re_path(r'^view', avatar, name='view_avatar'),
28-
re_path(r'^save', save_avatar, name='save_avatar'),
29-
]
26+
urlpatterns = [re_path(r'^view', avatar, name='view_avatar'), re_path(r'^save', save_avatar, name='save_avatar'), ]

‎app/avatar/utils.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,7 @@ def build_avatar_svg(svg_path='avatar.svg', line_color='#781623', icon_size=None
217217

218218
# Build the list of avatar components
219219
components = [
220-
icon_width,
221-
icon_height,
220+
icon_width, icon_height,
222221
Line([(0, icon_height / 2), (icon_width, icon_height / 2)],
223222
width=f'{icon_height}px',
224223
color=payload.get('background_color')),
@@ -270,10 +269,7 @@ def handle_avatar_payload(request):
270269
for k, v in body.items():
271270
if v and k in valid_component_keys:
272271
component_type, svg_asset = v.lstrip('v2/images/avatar/').split('/')
273-
avatar_dict[k] = {
274-
'component_type': component_type,
275-
'svg_asset': svg_asset,
276-
}
272+
avatar_dict[k] = {'component_type': component_type, 'svg_asset': svg_asset, }
277273
elif v and k in valid_color_keys:
278274
avatar_dict[k] = v
279275
return avatar_dict

‎app/dataviz/d3_views.py

+7-41
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,7 @@ def viz_spiral(request, key='email_open'):
123123
stats = Stat.objects.filter(created_on__hour=1)
124124
type_options = stats.distinct('key').values_list('key', flat=True)
125125
stats = stats.filter(key=key).order_by('created_on')
126-
params = {
127-
'stats': stats,
128-
'key': key,
129-
'page_route': 'spiral',
130-
'type_options': type_options,
131-
'viz_type': key,
132-
}
126+
params = {'stats': stats, 'key': key, 'page_route': 'spiral', 'type_options': type_options, 'viz_type': key, }
133127
return TemplateResponse(request, 'dataviz/spiral.html', params)
134128

135129

@@ -169,12 +163,7 @@ def viz_chord(request, key='bounties_paid'):
169163
output = "\n".join(output_rows)
170164
return HttpResponse(output)
171165

172-
params = {
173-
'key': key,
174-
'page_route': 'spiral',
175-
'type_options': type_options,
176-
'viz_type': key,
177-
}
166+
params = {'key': key, 'page_route': 'spiral', 'type_options': type_options, 'viz_type': key, }
178167
return TemplateResponse(request, 'dataviz/chord.html', params)
179168

180169

@@ -225,12 +214,7 @@ def viz_steamgraph(request, key='open'):
225214
output = "\n".join(output_rows)
226215
return HttpResponse(output)
227216

228-
params = {
229-
'key': key,
230-
'page_route': 'steamgraph',
231-
'type_options': type_options,
232-
'viz_type': key,
233-
}
217+
params = {'key': key, 'page_route': 'steamgraph', 'type_options': type_options, 'viz_type': key, }
234218
return TemplateResponse(request, 'dataviz/steamgraph.html', params)
235219

236220

@@ -287,13 +271,7 @@ def viz_heatmap(request, key='email_open', template='heatmap'):
287271

288272
output = "\n".join(output_rows)
289273
return HttpResponse(output)
290-
params = {
291-
'stats': stats,
292-
'key': key,
293-
'page_route': template,
294-
'type_options': type_options,
295-
'viz_type': key,
296-
}
274+
params = {'stats': stats, 'key': key, 'page_route': template, 'type_options': type_options, 'viz_type': key, }
297275
return TemplateResponse(request, f'dataviz/{template}.html', params)
298276

299277

@@ -333,9 +311,7 @@ def data_viz_helper_merge_json_trees(output):
333311
dict: The merged data dictionary.
334312
335313
"""
336-
new_output = {
337-
'name': output['name'],
338-
}
314+
new_output = {'name': output['name'], }
339315
if not output.get('children'):
340316
new_output['size'] = output['size']
341317
return new_output
@@ -401,12 +377,7 @@ def viz_sunburst(request, visual_type, template='sunburst'):
401377
TemplateResponse: If data param not provided, return the populated data visualization template.
402378
403379
"""
404-
visual_type_options = [
405-
'status_progression',
406-
'repos',
407-
'fulfillers',
408-
'funders',
409-
]
380+
visual_type_options = ['status_progression', 'repos', 'fulfillers', 'funders', ]
410381
if visual_type not in visual_type_options:
411382
visual_type = visual_type_options[0]
412383

@@ -733,12 +704,7 @@ def viz_scatterplot_helper(request, key='hourly_rate', template='dataviz/scatter
733704
username = bf.bounty.org_name
734705
if hide_usernames:
735706
username = "repo: " + helper_hide_pii(username.lower(), 1)
736-
row = [
737-
str(bf.bounty.hourly_rate),
738-
str((timezone.now() - bf.accepted_on).days),
739-
username,
740-
str(weight),
741-
]
707+
row = [str(bf.bounty.hourly_rate), str((timezone.now() - bf.accepted_on).days), username, str(weight), ]
742708
if bf.bounty.hourly_rate:
743709
rows.append(row)
744710
except Exception:

‎app/dataviz/views.py

+37-90
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,16 @@ def stats(request):
5858
_filters = ['slack', 'email', 'whitepaper', 'twitter']
5959
types = filter_types(types, _filters)
6060
if _filter == 'user_skills':
61-
_filters = [
62-
'subscribers_with_skill_',
63-
]
61+
_filters = ['subscribers_with_skill_', ]
6462
types = filter_types(types, _filters)
6563
if _filter == 'bounty_skills':
66-
_filters = [
67-
'bounties_with_skill_',
68-
]
64+
_filters = ['bounties_with_skill_', ]
6965
types = filter_types(types, _filters)
7066
if _filter == 'KPI':
7167
_filters = []
7268
types = [
73-
'email_subscribers_active',
74-
'joe_dominance_index_30_value',
75-
'bounties_value',
76-
'bounties_done_value',
77-
'bounties_hourly_rate_inusd_last_24_hours',
78-
'bounties_open_total',
79-
'slack_users_active',
69+
'email_subscribers_active', 'joe_dominance_index_30_value', 'bounties_value', 'bounties_done_value',
70+
'bounties_hourly_rate_inusd_last_24_hours', 'bounties_open_total', 'slack_users_active',
8071
'twitter_followers',
8172
]
8273

@@ -165,9 +156,7 @@ def cohort_helper_num(inner_start_time, inner_end_time, data_source, users):
165156
if 'profile' in data_source:
166157
if data_source == 'profile-githubinteraction':
167158
num = GithubEvent.objects.filter(
168-
profile__in=users,
169-
created_on__gte=inner_start_time,
170-
created_on__lt=inner_end_time,
159+
profile__in=users, created_on__gte=inner_start_time, created_on__lt=inner_end_time,
171160
).distinct('profile').count()
172161
else:
173162
event = 'start_work'
@@ -176,17 +165,11 @@ def cohort_helper_num(inner_start_time, inner_end_time, data_source, users):
176165
if data_source == 'profile-new_bounty':
177166
event = 'new_bounty'
178167
num = UserAction.objects.filter(
179-
profile__in=users,
180-
created_on__gte=inner_start_time,
181-
created_on__lt=inner_end_time,
182-
action=event,
168+
profile__in=users, created_on__gte=inner_start_time, created_on__lt=inner_end_time, action=event,
183169
).distinct('profile').count()
184170
elif data_source == 'slack-online':
185171
num = SlackPresence.objects.filter(
186-
slackuser__in=users,
187-
created_on__gte=inner_start_time,
188-
created_on__lt=inner_end_time,
189-
status='active',
172+
slackuser__in=users, created_on__gte=inner_start_time, created_on__lt=inner_end_time, status='active',
190173
).distinct('slackuser').count()
191174
else:
192175
event = data_source.split('-')[1]
@@ -227,11 +210,7 @@ def cohort(request):
227210
inner_end_time = timezone.now() - timezone.timedelta(**cohort_helper_timedelta(k - 1, period_size))
228211
num = cohort_helper_num(inner_start_time, inner_end_time, data_source, users)
229212
pct = round(num / num_entries, 2) if num_entries else 0
230-
usage_by_time_period[k] = {
231-
'num': num,
232-
'pct_float': pct,
233-
'pct_int': int(pct * 100),
234-
}
213+
usage_by_time_period[k] = {'num': num, 'pct_float': pct, 'pct_int': int(pct * 100), }
235214
cohorts[i] = {
236215
'num': num_entries,
237216
'start_time': start_time,
@@ -287,63 +266,34 @@ def funnel(request):
287266

288267
weekly_source = Stat.objects.filter(created_on__hour=1, created_on__week_day=1).order_by('-created_on')
289268
daily_source = Stat.objects.filter(created_on__hour=1).order_by('-created_on')
290-
funnels = [
291-
{
292-
'title': 'web => bounties_posted => bounties_fulfilled',
293-
'keys': [
294-
'sessions',
295-
'bounties_alltime',
296-
'bounties_fulfilled',
297-
],
298-
'data': []
299-
},
300-
{
301-
'title': 'web => bounties_posted => bounties_fulfilled (detail)',
302-
'keys': [
303-
'sessions',
304-
'bounties_alltime',
305-
'bounties_started_total',
306-
'bounties_submitted_total',
307-
'bounties_done_total',
308-
'bounties_expired_total',
309-
'bounties_cancelled_total',
310-
],
311-
'data': []
312-
},
313-
{
314-
'title': 'web session => email_subscribers',
315-
'keys': [
316-
'sessions',
317-
'email_subscribers',
318-
],
319-
'data': []
320-
},
321-
{
322-
'title': 'web session => slack',
323-
'keys': [
324-
'sessions',
325-
'slack_users',
326-
],
327-
'data': []
328-
},
329-
{
330-
'title': 'web session => create dev grant',
331-
'keys': [
332-
'sessions',
333-
'dev_grant',
334-
],
335-
'data': []
336-
},
337-
{
338-
'title': 'email funnel',
339-
'keys': [
340-
'email_processed',
341-
'email_open',
342-
'email_click',
343-
],
344-
'data': []
345-
},
346-
]
269+
funnels = [{
270+
'title': 'web => bounties_posted => bounties_fulfilled',
271+
'keys': ['sessions', 'bounties_alltime', 'bounties_fulfilled', ],
272+
'data': []
273+
}, {
274+
'title': 'web => bounties_posted => bounties_fulfilled (detail)',
275+
'keys': [
276+
'sessions', 'bounties_alltime', 'bounties_started_total', 'bounties_submitted_total', 'bounties_done_total',
277+
'bounties_expired_total', 'bounties_cancelled_total',
278+
],
279+
'data': []
280+
}, {
281+
'title': 'web session => email_subscribers',
282+
'keys': ['sessions', 'email_subscribers', ],
283+
'data': []
284+
}, {
285+
'title': 'web session => slack',
286+
'keys': ['sessions', 'slack_users', ],
287+
'data': []
288+
}, {
289+
'title': 'web session => create dev grant',
290+
'keys': ['sessions', 'dev_grant', ],
291+
'data': []
292+
}, {
293+
'title': 'email funnel',
294+
'keys': ['email_processed', 'email_open', 'email_click', ],
295+
'data': []
296+
}, ]
347297

348298
for funnel in range(0, len(funnels)):
349299
keys = funnels[funnel]['keys']
@@ -380,8 +330,5 @@ def funnel(request):
380330
except Exception as e:
381331
print(key, k, e)
382332

383-
params = {
384-
'title': "Funnel Analysis",
385-
'funnels': funnels,
386-
}
333+
params = {'title': "Funnel Analysis", 'funnels': funnels, }
387334
return TemplateResponse(request, 'funnel.html', params)

‎app/enssubdomain/views.py

+7-27
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ def get_gas_price(gas_multiplier=1.101):
5757

5858

5959
def handle_default_response(request, github_handle):
60-
params = {
61-
'github_handle': github_handle,
62-
'ens_domain': settings.ENS_TLD,
63-
}
60+
params = {'github_handle': github_handle, 'ens_domain': settings.ENS_TLD, }
6461
return TemplateResponse(request, 'ens/ens_register.html', params)
6562

6663

@@ -119,14 +116,8 @@ def set_resolver(signer, github_handle, nonce, gas_multiplier=1.101):
119116
'gasPrice': Web3.toHex(int(float(gas_price))),
120117
}
121118

122-
ens_contract = w3.eth.contract(
123-
address=ENS_MAINNET_ADDR,
124-
abi=ens_abi,
125-
)
126-
txn = ens_contract.functions.setResolver(
127-
dot_eth_namehash(subdomain),
128-
resolver_addr,
129-
).buildTransaction(transaction)
119+
ens_contract = w3.eth.contract(address=ENS_MAINNET_ADDR, abi=ens_abi, )
120+
txn = ens_contract.functions.setResolver(dot_eth_namehash(subdomain), resolver_addr, ).buildTransaction(transaction)
130121
signed_txn = w3.eth.account.signTransaction(txn, private_key=settings.ENS_PRIVATE_KEY)
131122
try:
132123
txn_hash = convert_txn(w3.eth.sendRawTransaction(signed_txn.rawTransaction))
@@ -152,15 +143,10 @@ def set_owner(signer, github_handle, nonce, gas_multiplier=1.101):
152143
'gasPrice': Web3.toHex(int(float(gas_price))),
153144
}
154145

155-
ens_contract = w3.eth.contract(
156-
address=ENS_MAINNET_ADDR,
157-
abi=ens_abi,
158-
)
146+
ens_contract = w3.eth.contract(address=ENS_MAINNET_ADDR, abi=ens_abi, )
159147

160148
txn = ens_contract.functions.setSubnodeOwner(
161-
dot_eth_namehash(owned),
162-
label_to_hash(label),
163-
Web3.toChecksumAddress(settings.ENS_OWNER_ACCOUNT),
149+
dot_eth_namehash(owned), label_to_hash(label), Web3.toChecksumAddress(settings.ENS_OWNER_ACCOUNT),
164150
).buildTransaction(transaction)
165151
signed_txn = w3.eth.account.signTransaction(txn, private_key=settings.ENS_PRIVATE_KEY)
166152
try:
@@ -188,14 +174,8 @@ def set_address_at_resolver(signer, github_handle, nonce, gas_multiplier=1.101):
188174
'gasPrice': Web3.toHex(int(float(gas_price))),
189175
}
190176

191-
resolver_contract = w3.eth.contract(
192-
address=resolver_addr,
193-
abi=resolver_abi,
194-
)
195-
txn = resolver_contract.functions.setAddr(
196-
dot_eth_namehash(subdomain),
197-
signer,
198-
).buildTransaction(transaction)
177+
resolver_contract = w3.eth.contract(address=resolver_addr, abi=resolver_abi, )
178+
txn = resolver_contract.functions.setAddr(dot_eth_namehash(subdomain), signer, ).buildTransaction(transaction)
199179
signed_txn = w3.eth.account.signTransaction(txn, private_key=settings.ENS_PRIVATE_KEY)
200180
try:
201181
txn_hash = convert_txn(w3.eth.sendRawTransaction(signed_txn.rawTransaction))

‎app/ethos/management/commands/generate_ethos_hop.py

+19-117
Original file line numberDiff line numberDiff line change
@@ -30,120 +30,25 @@
3030
logging.getLogger("requests").setLevel(logging.WARNING)
3131
logging.getLogger("urllib3").setLevel(logging.WARNING)
3232

33-
3433
twitter_usernames = [
35-
'eswara_sai',
36-
'owocki',
37-
'mbeacom',
38-
'mitch_kosowski',
39-
'vishesh04',
40-
'abhiram383',
41-
'EthOS_ERC20',
42-
'thelostone_mc',
43-
'rajat100493',
44-
'vsinghdothings'
45-
'MiccomServices5',
46-
'bdosari',
47-
'knowerlittle',
48-
'JPasintSHC',
49-
'savils',
50-
'elmerm',
51-
'ILovePythonMore',
52-
'icoexplorer',
53-
'HanimMYusof',
54-
'GWierzowiecki',
55-
'bohendo',
56-
'bigc1745',
57-
'stojce',
58-
'jeffesquivels',
59-
'QuikNode',
60-
'e3amn2l',
61-
'asinghchrony',
62-
'hiimmox',
63-
'c_t_ogden',
64-
'theycallmeken',
65-
'Danteintheloop',
66-
'AugurProject',
67-
'misterpikul',
68-
'sincibx',
69-
'gats8y',
70-
'scryptomagna',
71-
'iMichaelTen',
72-
'_hydeenoble',
73-
'jhselvik',
74-
'SUCCULENTS__',
75-
'SamyakJ04711116',
76-
'MarkTomsu',
77-
'freezing_point',
78-
'dangguillen',
79-
'rickmanelius',
80-
'LElkan',
81-
'cattron313',
82-
'Beezel_Bug',
83-
'kevinwucodes',
84-
'X11Spain',
85-
'occhiphaura',
86-
'2GatherUs',
87-
'jakrabbit',
88-
'RVNCoin',
89-
'BertBoeiend',
90-
'illbeanywhere',
91-
'adeloveh1',
92-
'EdgarTwit1',
93-
'ResetDavid',
94-
'allkindzzz',
95-
'planetary_dev',
96-
'Tom_Wolters',
97-
'Petru_Catana',
98-
'i_instances',
99-
'azeemansar',
100-
'tomazy',
101-
'brendanboyle87',
102-
'jaronrayhinds',
103-
'matthewholey',
104-
'kuriyamaPG',
105-
'evandroguedes',
106-
'matmeth_',
107-
'TuanAnh1011',
108-
'irpansy09096981',
109-
'MohammedAziz90',
110-
'live_s_s',
111-
'gregsantos',
112-
'CodeManDeluxe',
113-
'pro_webhosting',
114-
'randal_olson',
115-
'lvl_jesse',
116-
'kristofer_done',
117-
'breadboardkill',
118-
'Teo_Blockerz',
119-
'palash2504',
120-
'hedgehogy',
121-
'dredense',
122-
'kokossmoss',
123-
'sogasg',
124-
'artesesan',
125-
'scsab',
126-
'jenmacchiarelli',
127-
'yarrumretep',
128-
'keithtmccartney',
129-
'Cryptoscillator',
130-
'MillerApps',
131-
'5kyn0d3',
132-
'Mitch_Kosowski',
133-
'LamsonScribner',
134-
'mbeacom',
135-
'moneyfordogfood',
136-
'michelgotta',
137-
'vietlq',
138-
'Ruski93',
139-
'Skip_Carlson',
140-
'jakerockland',
141-
'NukeManDan',
142-
'MatthewLilley',
143-
'tylertommy21',
144-
'kelvin60429',
145-
'GetGitcoin',
146-
'owocki']
34+
'eswara_sai', 'owocki', 'mbeacom', 'mitch_kosowski', 'vishesh04', 'abhiram383', 'EthOS_ERC20', 'thelostone_mc',
35+
'rajat100493', 'vsinghdothings'
36+
'MiccomServices5', 'bdosari', 'knowerlittle', 'JPasintSHC', 'savils', 'elmerm', 'ILovePythonMore', 'icoexplorer',
37+
'HanimMYusof', 'GWierzowiecki', 'bohendo', 'bigc1745', 'stojce', 'jeffesquivels', 'QuikNode', 'e3amn2l',
38+
'asinghchrony', 'hiimmox', 'c_t_ogden', 'theycallmeken', 'Danteintheloop', 'AugurProject', 'misterpikul', 'sincibx',
39+
'gats8y', 'scryptomagna', 'iMichaelTen', '_hydeenoble', 'jhselvik', 'SUCCULENTS__', 'SamyakJ04711116', 'MarkTomsu',
40+
'freezing_point', 'dangguillen', 'rickmanelius', 'LElkan', 'cattron313', 'Beezel_Bug', 'kevinwucodes', 'X11Spain',
41+
'occhiphaura', '2GatherUs', 'jakrabbit', 'RVNCoin', 'BertBoeiend', 'illbeanywhere', 'adeloveh1', 'EdgarTwit1',
42+
'ResetDavid', 'allkindzzz', 'planetary_dev', 'Tom_Wolters', 'Petru_Catana', 'i_instances', 'azeemansar', 'tomazy',
43+
'brendanboyle87', 'jaronrayhinds', 'matthewholey', 'kuriyamaPG', 'evandroguedes', 'matmeth_', 'TuanAnh1011',
44+
'irpansy09096981', 'MohammedAziz90', 'live_s_s', 'gregsantos', 'CodeManDeluxe', 'pro_webhosting', 'randal_olson',
45+
'lvl_jesse', 'kristofer_done', 'breadboardkill', 'Teo_Blockerz', 'palash2504', 'hedgehogy', 'dredense',
46+
'kokossmoss', 'sogasg', 'artesesan', 'scsab', 'jenmacchiarelli', 'yarrumretep', 'keithtmccartney',
47+
'Cryptoscillator', 'MillerApps', '5kyn0d3', 'Mitch_Kosowski', 'LamsonScribner', 'mbeacom', 'moneyfordogfood',
48+
'michelgotta', 'vietlq', 'Ruski93', 'Skip_Carlson', 'jakerockland', 'NukeManDan', 'MatthewLilley', 'tylertommy21',
49+
'kelvin60429', 'GetGitcoin', 'owocki'
50+
]
51+
14752
# create more with
14853
# followers = api.GetFollowers(count=200)
14954
# [follower.screen_name for follower in followers]
@@ -178,10 +83,7 @@ def handle(self, *args, **options):
17883
previous_hop = None
17984

18085
Hop.objects.create(
181-
twitter_profile=twitter_profile,
182-
shortcode=shortcode,
183-
previous_hop=previous_hop,
184-
ip='127.0.0.1'
86+
twitter_profile=twitter_profile, shortcode=shortcode, previous_hop=previous_hop, ip='127.0.0.1'
18587
)
18688
# TODO: Build the graph for each hop.
18789
# hop.build_graph(latest=False)

‎app/ethos/management/commands/reminder_users.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,16 @@
2525
from ethos.models import Hop, ShortCode, TwitterProfile
2626
from ethos.utils import get_twitter_api
2727

28-
already_sent = ['132','Munair','134','kauri_io','138','Jbschweitzer','139','Kavitagupta19','133','matrick','135','heyomarks','135','Consensys','134','craastad','132','owocki','140','ferrarijetpack','138','Somemikesena','135','leahfeuer','137','saintkamini','134','simondlr','138','elise_ransom','132','namdar','131','Gnsps','132','ThessyMehrain','Ezelby','Owocki','Kamescg', 'bsmokes_', 'Untra', 'tokenfoundry', 'everett_muzzy', 'Vladzamfir']
28+
already_sent = [
29+
'132', 'Munair', '134', 'kauri_io', '138', 'Jbschweitzer', '139', 'Kavitagupta19', '133', 'matrick', '135',
30+
'heyomarks', '135', 'Consensys', '134', 'craastad', '132', 'owocki', '140', 'ferrarijetpack', '138', 'Somemikesena',
31+
'135', 'leahfeuer', '137', 'saintkamini', '134', 'simondlr', '138', 'elise_ransom', '132', 'namdar', '131', 'Gnsps',
32+
'132', 'ThessyMehrain', 'Ezelby', 'Owocki', 'Kamescg', 'bsmokes_', 'Untra', 'tokenfoundry', 'everett_muzzy',
33+
'Vladzamfir'
34+
]
2935
already_sent = [ele.lower() for ele in already_sent]
3036

37+
3138
class Command(BaseCommand):
3239
"""Define the management command to generate Ethos reminder tweets."""
3340

@@ -49,7 +56,9 @@ def handle(self, *args, **options):
4956
if options['live']:
5057
twitter_api = get_twitter_api()
5158
try:
52-
twitter_api.PostUpdate(tweet, media='https://cdn-images-1.medium.com/max/1440/1*gAG6JvDK-Al_c1xEn1VHpA.jpeg')
59+
twitter_api.PostUpdate(
60+
tweet, media='https://cdn-images-1.medium.com/max/1440/1*gAG6JvDK-Al_c1xEn1VHpA.jpeg'
61+
)
5362
except Exception as e:
5463
print(e)
5564
time.sleep(10)

‎app/ethos/models.py

+12-19
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,14 @@ class Meta:
8686
black = (0, 0, 0, 0)
8787
grey = (122, 122, 122, 0)
8888
size = (1000, 1000)
89-
center = (int(size[0]/2), int(size[1]/2))
89+
center = (int(size[0] / 2), int(size[1] / 2))
9090
font = 'assets/v2/fonts/futura/FuturaStd-Medium.otf'
9191

9292
# Model variables
9393
ip = models.GenericIPAddressField(protocol='IPv4', blank=True, null=True)
9494
twitter_profile = models.ForeignKey(
95-
'ethos.TwitterProfile', on_delete=models.SET_NULL, null=True, related_name='hops')
95+
'ethos.TwitterProfile', on_delete=models.SET_NULL, null=True, related_name='hops'
96+
)
9697
txid = models.CharField(max_length=255, default='', blank=True)
9798
web3_address = models.CharField(max_length=255, blank=True)
9899
previous_hop = models.ForeignKey("self", on_delete=models.SET_NULL, blank=True, null=True)
@@ -125,16 +126,15 @@ def add_edge(self, img, loc, width=3):
125126
draw.line(loc, fill=self.grey, width=width)
126127
return img
127128

128-
def add_node_helper(self, img, name, loc, node_image=None, size=30, font='',
129-
font_size=12):
129+
def add_node_helper(self, img, name, loc, node_image=None, size=30, font='', font_size=12):
130130
font = font or self.font
131131
x, y = loc
132132
font = ImageFont.truetype(font, font_size, encoding="unic")
133133
draw = ImageDraw.Draw(img)
134-
x0 = x - int((size/2))
135-
x1 = x + int((size/2))
136-
y0 = y - int((size/2))
137-
y1 = y + int((size/2))
134+
x0 = x - int((size / 2))
135+
x1 = x + int((size / 2))
136+
y0 = y - int((size / 2))
137+
y1 = y + int((size / 2))
138138
loc = [x0, y0, x1, y1]
139139

140140
if not node_image:
@@ -161,7 +161,7 @@ def edge_size(self):
161161
if previous_hop:
162162
edge_size += previous_hop.edge_size()
163163

164-
time_lapsed = round((self.created_on - previous_hop.created_on).total_seconds()/60) if previous_hop else 100
164+
time_lapsed = round((self.created_on - previous_hop.created_on).total_seconds() / 60) if previous_hop else 100
165165
this_edge_size = 0
166166
if 0 < time_lapsed < 30:
167167
this_edge_size = time_lapsed * 10
@@ -173,7 +173,6 @@ def edge_size(self):
173173
edge_size += this_edge_size
174174
return edge_size
175175

176-
177176
def draw_hop(self, img):
178177
node_image = None
179178
increment = self.increment()
@@ -198,8 +197,7 @@ def draw_hop(self, img):
198197

199198
return img
200199

201-
def build_graph(self, save=True, root_node='Genesis', size=None,
202-
background_color=None, latest=True):
200+
def build_graph(self, save=True, root_node='Genesis', size=None, background_color=None, latest=True):
203201
"""Build the Hop graph."""
204202

205203
file_system_cache_file = f"assets/tmp/{self.pk}.gif"
@@ -246,13 +244,8 @@ def build_gif(self):
246244
class TwitterProfile(SuperModel):
247245
"""Define the Twitter Profile."""
248246

249-
profile_picture = ThumbnailerImageField(
250-
upload_to='ethos/twitter_profiles/',
251-
blank=True,
252-
null=True,
253-
max_length=255)
254-
node_image = models.ImageField(
255-
upload_to='ethos/node_images/', blank=True, null=True, max_length=255)
247+
profile_picture = ThumbnailerImageField(upload_to='ethos/twitter_profiles/', blank=True, null=True, max_length=255)
248+
node_image = models.ImageField(upload_to='ethos/node_images/', blank=True, null=True, max_length=255)
256249
username = models.CharField(max_length=255)
257250

258251
class Meta:

‎app/ethos/views.py

+7-18
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@
8484
'"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],'
8585
'"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from",'
8686
'"type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value",'
87-
'"type":"uint256"}],"name":"Transfer","type":"event"}]')
87+
'"type":"uint256"}],"name":"Transfer","type":"event"}]'
88+
)
8889

8990
# Instantiate EthOS contract
9091
try:
@@ -155,7 +156,7 @@ def redeem_coin(request, shortcode):
155156

156157
twitter_profile, __ = TwitterProfile.objects.prefetch_related('hops').get_or_create(username=username)
157158
ethos = ShortCode.objects.get(shortcode=shortcode)
158-
previous_hop = None
159+
previous_hop = None
159160

160161
if address:
161162
address = Web3.toChecksumAddress(address)
@@ -176,7 +177,7 @@ def redeem_coin(request, shortcode):
176177

177178
previous_hop = Hop.objects.select_related('shortcode').filter(shortcode=ethos).order_by('-id').first()
178179
if previous_hop:
179-
time_lapsed = round((timezone.now() - previous_hop.created_on).total_seconds()/60)
180+
time_lapsed = round((timezone.now() - previous_hop.created_on).total_seconds() / 60)
180181
n = 5
181182

182183
if time_lapsed < 25:
@@ -191,12 +192,7 @@ def redeem_coin(request, shortcode):
191192
signed = w3.eth.account.signTransaction(tx, settings.ETHOS_ACCOUNT_PRIVATE_KEY)
192193
message = w3.eth.sendRawTransaction(signed.rawTransaction).hex()
193194

194-
hop = Hop(
195-
shortcode=ethos,
196-
ip=get_ip(request),
197-
created_on=timezone.now(),
198-
twitter_profile=twitter_profile,
199-
)
195+
hop = Hop(shortcode=ethos, ip=get_ip(request), created_on=timezone.now(), twitter_profile=twitter_profile, )
200196
if message and message.startswith('0x'):
201197
hop.txid = message
202198
if address and address.startswith('0x'):
@@ -240,10 +236,7 @@ def redeem_coin(request, shortcode):
240236
message = str(e)
241237

242238
# API Response
243-
response = {
244-
'status': status,
245-
'message': message,
246-
}
239+
response = {'status': status, 'message': message, }
247240

248241
if status == 'OK':
249242
response['num_scans'] = num_scans
@@ -257,10 +250,6 @@ def redeem_coin(request, shortcode):
257250
except ShortCode.DoesNotExist:
258251
raise Http404
259252

260-
params = {
261-
'class': 'redeem',
262-
'title': _('EthOS Coin'),
263-
'hide_send_tip': True
264-
}
253+
params = {'class': 'redeem', 'title': _('EthOS Coin'), 'hide_send_tip': True}
265254

266255
return TemplateResponse(request, 'redeem_ethos.html', params)

‎app/github/tests/test_utils.py

+9-33
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,8 @@ def test_get_github_user_token(self):
119119
}
120120
params = urlencode(params, quote_via=quote_plus)
121121
url = settings.GITHUB_TOKEN_URL + '?' + params
122-
responses.add(responses.GET, settings.GITHUB_TOKEN_URL,
123-
json=data, headers=JSON_HEADER, status=200)
124-
responses.add(responses.GET, settings.GITHUB_TOKEN_URL,
125-
json={}, headers=JSON_HEADER, status=200)
122+
responses.add(responses.GET, settings.GITHUB_TOKEN_URL, json=data, headers=JSON_HEADER, status=200)
123+
responses.add(responses.GET, settings.GITHUB_TOKEN_URL, json={}, headers=JSON_HEADER, status=200)
126124
result = get_github_user_token(self.callback_code)
127125
result_no_token = get_github_user_token(self.callback_code)
128126

@@ -136,8 +134,7 @@ def test_get_github_user_data(self):
136134
"""Test the github utility get_github_user_data method."""
137135
headers = dict({'Authorization': f'token {self.user_oauth_token}'}, **JSON_HEADER)
138136
data = {'login': 'gitcoin'}
139-
responses.add(responses.GET, 'https://api.github.com/user',
140-
json=data, headers=headers, status=200)
137+
responses.add(responses.GET, 'https://api.github.com/user', json=data, headers=headers, status=200)
141138
result = get_github_user_data(self.user_oauth_token)
142139

143140
assert result == data
@@ -147,8 +144,7 @@ def test_get_github_user_data_failure(self):
147144
"""Test the github utility get_github_user_data method."""
148145
headers = dict({'Authorization': f'token {self.user_oauth_token}'}, **JSON_HEADER)
149146
data = {'login': 'gitcoin'}
150-
responses.add(responses.GET, 'https://api.github.com/user',
151-
json=data, headers=headers, status=404)
147+
responses.add(responses.GET, 'https://api.github.com/user', json=data, headers=headers, status=404)
152148
result = get_github_user_data(self.user_oauth_token)
153149

154150
assert result == {}
@@ -173,10 +169,7 @@ def test_is_github_token_valid(self):
173169
@responses.activate
174170
def test_get_github_primary_email(self):
175171
"""Test the github utility get_github_primary_email method."""
176-
data = [
177-
{'primary': True, 'email': 'test@gitcoin.co'},
178-
{'email': 'test2@gitcoin.co'}
179-
]
172+
data = [{'primary': True, 'email': 'test@gitcoin.co'}, {'email': 'test2@gitcoin.co'}]
180173
url = 'https://api.github.com/user/emails'
181174
responses.add(responses.GET, url, json=data, headers=HEADERS, status=200)
182175
responses.add(responses.GET, url, json=data, headers=HEADERS, status=404)
@@ -190,11 +183,7 @@ def test_get_github_primary_email(self):
190183
def test_get_github_emails(self):
191184
"""Test the github utility get_github_emails method."""
192185
headers = dict({'Authorization': f'token {self.user_oauth_token}'}, **JSON_HEADER)
193-
data = [
194-
{'email': 'test@gitcoin.co'},
195-
{'email': 'test2@gitcoin.co'},
196-
{'email': 'testing@noreply.github.com'}
197-
]
186+
data = [{'email': 'test@gitcoin.co'}, {'email': 'test2@gitcoin.co'}, {'email': 'testing@noreply.github.com'}]
198187
url = 'https://api.github.com/user/emails'
199188
responses.add(responses.GET, url, json=data, headers=headers, status=200)
200189
responses.add(responses.GET, url, json=data, headers=headers, status=404)
@@ -208,11 +197,7 @@ def test_get_github_emails(self):
208197
@responses.activate
209198
def test_get_issue_comments(self):
210199
"""Test the github utility get_issue_comments method."""
211-
params = {
212-
'sort': 'created',
213-
'direction': 'desc',
214-
'per_page': 100,
215-
}
200+
params = {'sort': 'created', 'direction': 'desc', 'per_page': 100, }
216201
params = urlencode(params, quote_via=quote_plus)
217202
owner = 'gitcoinco'
218203
repo = 'web'
@@ -225,11 +210,7 @@ def test_get_issue_comments(self):
225210
@responses.activate
226211
def test_get_issue_comments_issue(self):
227212
"""Test the github utility get_issue_comments_issue method."""
228-
params = {
229-
'sort': 'created',
230-
'direction': 'desc',
231-
'per_page': 100,
232-
}
213+
params = {'sort': 'created', 'direction': 'desc', 'per_page': 100, }
233214
params = urlencode(params, quote_via=quote_plus)
234215
owner = 'gitcoinco'
235216
repo = 'web'
@@ -244,12 +225,7 @@ def test_get_issue_comments_issue(self):
244225
@responses.activate
245226
def test_get_issue_timeline_events(self):
246227
"""Test the github utility get_issue_timeline_events method."""
247-
params = {
248-
'sort': 'created',
249-
'direction': 'desc',
250-
'per_page': 100,
251-
'page': 1
252-
}
228+
params = {'sort': 'created', 'direction': 'desc', 'per_page': 100, 'page': 1}
253229
params = urlencode(params, quote_via=quote_plus)
254230
owner = 'gitcoinco'
255231
repo = 'web'

‎app/github/utils.py

+20-44
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,7 @@
3737
BASE_URI = settings.BASE_URL.rstrip('/')
3838
HEADERS = {'Accept': 'application/vnd.github.squirrel-girl-preview'}
3939
V3HEADERS = {'Accept': 'application/vnd.github.v3.text-match+json'}
40-
JSON_HEADER = {
41-
'Accept': 'application/json',
42-
'User-Agent': settings.GITHUB_APP_NAME,
43-
'Origin': settings.BASE_URL
44-
}
40+
JSON_HEADER = {'Accept': 'application/json', 'User-Agent': settings.GITHUB_APP_NAME, 'Origin': settings.BASE_URL}
4541
TIMELINE_HEADERS = {'Accept': 'application/vnd.github.mockingbird-preview'}
4642
TOKEN_URL = '{api_url}/applications/{client_id}/tokens/{oauth_token}'
4743

@@ -85,10 +81,7 @@ def check_github(profile):
8581

8682
def search_github(q):
8783

88-
params = (
89-
('q', q),
90-
('sort', 'updated'),
91-
)
84+
params = (('q', q), ('sort', 'updated'), )
9285
response = requests.get('https://api.github.com/search/users', headers=HEADERS, params=params)
9386
return response.json()
9487

@@ -199,15 +192,10 @@ def get_auth_url(redirect_uri='/'):
199192

200193
def get_github_user_token(code, **kwargs):
201194
"""Get the Github authorization token."""
202-
_params = {
203-
'code': code,
204-
'client_id': settings.GITHUB_CLIENT_ID,
205-
'client_secret': settings.GITHUB_CLIENT_SECRET
206-
}
195+
_params = {'code': code, 'client_id': settings.GITHUB_CLIENT_ID, 'client_secret': settings.GITHUB_CLIENT_SECRET}
207196
# Add additional parameters to the request paramaters.
208197
_params.update(kwargs)
209-
response = requests.get(
210-
settings.GITHUB_TOKEN_URL, headers=JSON_HEADER, params=_params)
198+
response = requests.get(settings.GITHUB_TOKEN_URL, headers=JSON_HEADER, params=_params)
211199
response = response.json()
212200
scope = response.get('scope', None)
213201
if scope:
@@ -289,13 +277,9 @@ def search(query):
289277
request.Response: The github search response.
290278
291279
"""
292-
params = (
293-
('q', query),
294-
('sort', 'updated'),
295-
)
280+
params = (('q', query), ('sort', 'updated'), )
296281

297-
response = requests.get('https://api.github.com/search/users',
298-
auth=_AUTH, headers=V3HEADERS, params=params)
282+
response = requests.get('https://api.github.com/search/users', auth=_AUTH, headers=V3HEADERS, params=params)
299283
return response.json()
300284

301285

@@ -331,13 +315,7 @@ def get_issue_comments(owner, repo, issue=None, comment_id=None):
331315

332316
def get_issues(owner, repo, page=1, state='open'):
333317
"""Get the open issues on a respository."""
334-
params = {
335-
'state': state,
336-
'sort': 'created',
337-
'direction': 'desc',
338-
'page': page,
339-
'per_page': 100,
340-
}
318+
params = {'state': state, 'sort': 'created', 'direction': 'desc', 'page': page, 'per_page': 100, }
341319
url = f'https://api.github.com/repos/{owner}/{repo}/issues'
342320

343321
response = requests.get(url, auth=_AUTH, headers=HEADERS, params=params)
@@ -359,12 +337,7 @@ def get_issue_timeline_events(owner, repo, issue, page=1):
359337
Returns:
360338
requests.Response: The GitHub timeline response.
361339
"""
362-
params = {
363-
'sort': 'created',
364-
'direction': 'desc',
365-
'per_page': 100,
366-
'page': page,
367-
}
340+
params = {'sort': 'created', 'direction': 'desc', 'per_page': 100, 'page': page, }
368341
url = f'https://api.github.com/repos/{owner}/{repo}/issues/{issue}/timeline'
369342
# Set special header to access timeline preview api
370343
response = requests.get(url, auth=_AUTH, headers=TIMELINE_HEADERS, params=params)
@@ -373,10 +346,7 @@ def get_issue_timeline_events(owner, repo, issue, page=1):
373346

374347

375348
def get_interested_actions(github_url, username, email=''):
376-
activity_event_types = [
377-
'commented', 'cross-referenced', 'merged', 'referenced',
378-
'review_requested',
379-
]
349+
activity_event_types = ['commented', 'cross-referenced', 'merged', 'referenced', 'review_requested', ]
380350

381351
owner = org_name(github_url)
382352
repo = repo_name(github_url)
@@ -460,9 +430,14 @@ def patch_issue_comment(comment_id, owner, repo, comment):
460430
if response.status_code == 200:
461431
return response.json()
462432
rollbar.report_message(
463-
'Github issue comment patch returned non-200 status code', 'warning',
433+
'Github issue comment patch returned non-200 status code',
434+
'warning',
464435
request=response.request,
465-
extra_data={'status_code': response.status_code, 'reason': response.reason})
436+
extra_data={
437+
'status_code': response.status_code,
438+
'reason': response.reason
439+
}
440+
)
466441
return {}
467442

468443

@@ -473,16 +448,17 @@ def delete_issue_comment(comment_id, owner, repo):
473448
response = requests.delete(url, auth=_AUTH)
474449
return response.json()
475450
except ValueError:
476-
logger.error(f"could not delete issue comment because JSON response could not be decoded: {comment_id}, {owner}, {repo}. {response.status_code}, {response.text} ")
451+
logger.error(
452+
f"could not delete issue comment because JSON response could not be decoded: {comment_id}, {owner}, {repo}. {response.status_code}, {response.text} "
453+
)
477454
except Exception:
478455
return {}
479456

480457

481458
def post_issue_comment_reaction(owner, repo, comment_id, content):
482459
"""React to an issue comment."""
483460
url = f'https://api.github.com/repos/{owner}/{repo}/issues/comments/{comment_id}/reactions'
484-
response = requests.post(
485-
url, data=json.dumps({'content': content}), auth=_AUTH, headers=HEADERS)
461+
response = requests.post(url, data=json.dumps({'content': content}), auth=_AUTH, headers=HEADERS)
486462
return response.json()
487463

488464

‎requirements/test.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ isort
1010
responses
1111
requests_mock
1212
django-test-plus
13-
yapf
13+
git+https://github.com/google/yapf.git#egg=yapf

‎setup.cfg

+1
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,4 @@ ALLOW_MULTILINE_LAMBDAS = true
8383
BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF = true
8484
INDENT_DICTIONARY_VALUE = true
8585
SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN = true
86+
DISABLE_ENDING_COMMA_HEURISTIC = true

0 commit comments

Comments
 (0)
Please sign in to comment.