Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

WIP: Stats email v2 #1311

Merged
merged 17 commits into from
Jul 24, 2018
Merged

WIP: Stats email v2 #1311

merged 17 commits into from
Jul 24, 2018

Conversation

oogetyboogety
Copy link
Contributor

@oogetyboogety oogetyboogety commented May 30, 2018

Description
Checklist
  • linter status: 100% pass
  • changes don't break existing behavior
  • commit message follows commit guidelines
Affected core subsystem(s)
Testing
Refers/Fixes

@oogetyboogety
Copy link
Contributor Author

@owocki This just need the hardcoded text to be localized. Otherwise, this should be finished, unless there are CSS changes to be included?

@@ -1065,6 +1082,175 @@ def stats(self):
(success_rate, 'Success Rate'),
]

@property

Choose a reason for hiding this comment

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

C901 'Profile.get_quarterly_stats' is too complex (17)

for bounty in funded_bounties:
hourly_rate = bounty.hourly_rate
if hourly_rate:
total_funded_hourly_rate += bounty.hourly_rate

Choose a reason for hiding this comment

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

W291 trailing whitespace

hourly_rate_bounties_counted += 1
funded_bounty_fulfillments = []
for bounty in funded_bounties:
fulfillments = bounty.fulfillments.filter(accepted=True)

Choose a reason for hiding this comment

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

E111 indentation is not a multiple of four

funded_bounty_fulfillments = []
for bounty in funded_bounties:
fulfillments = bounty.fulfillments.filter(accepted=True)
for fulfillment in fulfillments:

Choose a reason for hiding this comment

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

E111 indentation is not a multiple of four

fulfillments = bounty.fulfillments.filter(accepted=True)
for fulfillment in fulfillments:
if isinstance(fulfillment, BountyFulfillment):
funded_bounty_fulfillments.append(fulfillment)

Choose a reason for hiding this comment

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

E111 indentation is not a multiple of four
W291 trailing whitespace

print("-----" * 100)
print(html)
print("-----" * 100)
from_email = settings.PERSONAL_CONTACT_EMAIL

Choose a reason for hiding this comment

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

F841 local variable 'from_email' is assigned to but never used

print("-----" * 100)
from_email = settings.PERSONAL_CONTACT_EMAIL

#if not should_suppress_notification_email(to_email, 'roundup'):

Choose a reason for hiding this comment

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

E265 block comment should start with '# '

from_email = settings.PERSONAL_CONTACT_EMAIL

#if not should_suppress_notification_email(to_email, 'roundup'):
#send_mail(from_email, to_email, subject, text, html, from_name="Kevin Owocki (Gitcoin.co)")

Choose a reason for hiding this comment

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

E116 unexpected indentation (comment)
E265 block comment should start with '# '


platform_wide_stats = get_platform_wide_stats()

<<<<<<< HEAD

Choose a reason for hiding this comment

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

E305 expected 2 blank lines after class or function definition, found 1
E999 SyntaxError: invalid syntax
E227 missing whitespace around bitwise or shift operator
E225 missing whitespace around operator

platform_wide_stats = get_platform_wide_stats()

<<<<<<< HEAD
for counter, to_email in enumerate(email_list):

Choose a reason for hiding this comment

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

E113 unexpected indentation

@@ -323,6 +323,33 @@ def new_match(to_emails, bounty, github_username):
translation.activate(cur_language)


def quarterly_stats(to_emails=None):
if not platform_wide_stats:

Choose a reason for hiding this comment

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

F821 undefined name 'platform_wide_stats'

print("-----" * 100)
print(html)
print("-----" * 100)
from_email = settings.PERSONAL_CONTACT_EMAIL

Choose a reason for hiding this comment

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

F841 local variable 'from_email' is assigned to but never used

along with this program. If not, see <http://www.gnu.org/licenses/>.

'''
import logging

Choose a reason for hiding this comment

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

F401 'logging' imported but unused

'user_total_earned_eth': Total earnings of user in ETH.
'user_total_earned_usd': Total earnings of user in USD.
'user_total_funded_usd': Total value of bounties funded by the user on bounties in done status in USD
'user_total_funded_hours': Total hours input by the developers on the fulfillment of bounties created by the user in USD

Choose a reason for hiding this comment

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

E501 line too long (132 > 120 characters)

'user_active_in_last_quarter': bool, if the user was active in last quarter
'user_no_of_languages': No of languages user used while working on bounties.
'user_languages': Languages that were used in bounties that were worked on.
'relevant_bounties': a list of Bounty(s) that would match the skillset input by the user into the Match tab of their settings

Choose a reason for hiding this comment

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

E501 line too long (137 > 120 characters)

user_funded_bounty_developers.append('@' + fulfillment.fulfiller_github_username.lstrip('@'))
user_funded_bounty_developers = [*{*user_funded_bounty_developers}]
if funded_fulfillments_with_hours_counted:
avg_hourly_rate_per_funded_bounty = float(total_funded_hourly_rate) / float(funded_fulfillments_with_hours_counted)

Choose a reason for hiding this comment

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

E501 line too long (131 > 120 characters)

@oogetyboogety oogetyboogety changed the title WIP Stats email v2 Stats email v2 Jun 1, 2018
@oogetyboogety
Copy link
Contributor Author

funder_email

@thelostone-mc
Copy link
Member

Ah looks like something went wrong during your rebase. This PR has commits pushed in by other folks ! Could you cherry-pick them and ensure the PR just has your commits ? ^_^

user_active_in_last_quarter = False
user_fulfilled_bounties = False
user_funded_bounties = False
last_quarter = datetime.now() - timedelta(days=90)

Choose a reason for hiding this comment

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

F821 undefined name 'timedelta'

@oogetyboogety
Copy link
Contributor Author

@thelostone-mc Done! Thanks, please provide any further instructions I can complete to get this merged!

Thanks again

@@ -1194,6 +1194,187 @@ def get_quarterly_stats(self):
'user_languages': user_languages
}

@property

Choose a reason for hiding this comment

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

C901 'Profile.get_quarterly_stats' is too complex (17)
F811 redefinition of unused 'get_quarterly_stats' from line 1122

@codecov
Copy link

codecov bot commented Jun 3, 2018

Codecov Report

Merging #1311 into master will decrease coverage by 1.19%.
The diff coverage is 29.68%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #1311     +/-   ##
=========================================
- Coverage   30.63%   29.44%   -1.2%     
=========================================
  Files         124      132      +8     
  Lines        8783     9847   +1064     
  Branches     1141     1284    +143     
=========================================
+ Hits         2691     2899    +208     
- Misses       5984     6842    +858     
+ Partials      108      106      -2
Impacted Files Coverage Δ
app/retail/emails.py 20.79% <100%> (-2.12%) ⬇️
app/dashboard/models.py 52.51% <28.57%> (-3.07%) ⬇️
app/gas/utils.py 70.96% <0%> (-13.65%) ⬇️
app/retail/utils.py 15.19% <0%> (-6.55%) ⬇️
app/app/urls.py 89.74% <0%> (-4.55%) ⬇️
app/app/sitemaps.py 68.62% <0%> (-3.88%) ⬇️
app/dashboard/signals.py 54.54% <0%> (-3.79%) ⬇️
app/dashboard/router.py 31.42% <0%> (-3.31%) ⬇️
app/app/settings.py 80.43% <0%> (-2.72%) ⬇️
... and 35 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c23fccc...083d5ce. Read the comment docs.

@@ -1127,22 +1090,97 @@ def get_quarterly_stats(self):
dict : containing the following information
'user_total_earned_eth': Total earnings of user in ETH.
'user_total_earned_usd': Total earnings of user in USD.
'user_fulfilled_bounties_count': Total bounties fulfilled by user.
'user_total_funded_usd': Total value of bounties funded by the user on bounties in done status in USD
'user_total_funded_hours': Total hours input by the developers on the fulfillment of bounties created by the user in USD

Choose a reason for hiding this comment

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

E501 line too long (132 > 120 characters)

Copy link
Contributor

Choose a reason for hiding this comment

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

^

'user_active_in_last_quarter': bool, if the user was active in last quarter
'user_no_of_languages': No of languages user used while working on bounties.
'user_languages': Languages that were used in bounties that were worked on.
'relevant_bounties': a list of Bounty(s) that would match the skillset input by the user into the Match tab of their settings

Choose a reason for hiding this comment

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

E501 line too long (137 > 120 characters)

Copy link
Contributor

Choose a reason for hiding this comment

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

^

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no recommendation on https://www.python.org/dev/peps/pep-0257/, could you advise

@@ -1743,6 +1591,9 @@ def i18n_description(self):
def i18n_link_copy(self):
return _(self.link_copy)

def __str__(self):

Choose a reason for hiding this comment

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

F811 redefinition of unused 'str' from line 1545

@owocki
Copy link
Contributor

owocki commented Jun 5, 2018

looking at this now

last_quarter = datetime.now() - timedelta(days=90)
bounties = self.bounties.filter(modified_on__gte=last_quarter)
fulfilled_bounties = [
bounty for bounty in bounties if bounty.is_hunter(self.handle) and bounty.status == 'done'
]
fulfilled_bounties_count = len(fulfilled_bounties)
funded_bounties = [
bounty for bounty in bounties if bounty.is_funder(self.handle)
Copy link
Contributor

Choose a reason for hiding this comment

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

is any of this data STUBBed out? are you unsure of any of the calcs you did? if so, mind throwing a few TODOs in there for us to work through?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added TODOs

relevant_bounties = Bounty.objects.none()
for keyword in user_coding_languages:
relevant_bounties = relevant_bounties.union(potential_bounties.filter(
network='rinkeby',
Copy link
Contributor

Choose a reason for hiding this comment

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

should not hardcode this network

@owocki
Copy link
Contributor

owocki commented Jun 5, 2018

over all looking good! heres my testing notes

  1. double @ signs on this module http://bits.owocki.com/3Y0b100V2W28/Screen%20Shot%202018-06-04%20at%206.10.39%20PM.png
  2. rounding http://bits.owocki.com/1o2b0D3H0J2d/Screen%20Shot%202018-06-04%20at%206.11.18%20PM.png

could you post screenshots from each of the personas pls? that'll make testing/QA easier for everyone else

cc @mbeacom @thelostone-mc in case anyone else wants to QA too

user_funded_bounty_developers.append(fulfillment.fulfiller_github_username.lstrip('@'))
user_funded_bounty_developers = [*{*user_funded_bounty_developers}]
if funded_fulfillments_with_hours_counted:
avg_hourly_rate_per_funded_bounty = float(total_funded_hourly_rate) / float(funded_fulfillments_with_hours_counted)

Choose a reason for hiding this comment

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

E501 line too long (131 > 120 characters)

Copy link
Contributor

Choose a reason for hiding this comment

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

^

for bounty in funded_bounties
])
total_funded_hourly_rate = float(0)
#TODO: Explain to the user that we only counted Bounties that developers entered # of hours worked on

Choose a reason for hiding this comment

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

E265 block comment should start with '# '

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need us to finish the BE for these TODOs?

Copy link
Contributor

Choose a reason for hiding this comment

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

i just resolved this TODO

hourly_rate_bounties_counted += 1
funded_bounty_fulfillments = []
for bounty in funded_bounties:
#TODO: Check that all bounty fulfillments have acceptance and that there are no bounties that have skipped the Acceptance in fulfillment step of workflow

Choose a reason for hiding this comment

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

E265 block comment should start with '# '
E501 line too long (169 > 120 characters)

avg_hourly_rate_per_funded_bounty = 0
avg_hours_per_funded_bounty = 0
funded_fulfilled_bounties = [
#TODO: Change this to check for terminal statuses instead?

Choose a reason for hiding this comment

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

E265 block comment should start with '# '

current_bounty=True,
metadata__icontains=keyword,
idx_status__in=['open'],
#TODO: Identify the random sampling method used, see if it sending mass emails becomes slow

Choose a reason for hiding this comment

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

E265 block comment should start with '# '

metadata__icontains=keyword,
idx_status__in=['open'],
#TODO: Identify the random sampling method used, see if it sending mass emails becomes slow
).order_by('?')

Choose a reason for hiding this comment

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

W291 trailing whitespace

Copy link
Contributor

Choose a reason for hiding this comment

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

^

@oogetyboogety
Copy link
Contributor Author

@owocki Done, please review!

@mbeacom mbeacom changed the title Stats email v2 WIP: Stats email v2 Jun 7, 2018
@ghost ghost assigned owocki Jun 13, 2018
@@ -1127,22 +1127,97 @@ def get_quarterly_stats(self):
dict : containing the following information
'user_total_earned_eth': Total earnings of user in ETH.
'user_total_earned_usd': Total earnings of user in USD.
'user_fulfilled_bounties_count': Total bounties fulfilled by user.
'user_total_funded_usd': Total value of bounties funded by the user on bounties in done status in USD
'user_total_funded_hours': Total hours input by the developers on the fulfillment of bounties created by the user in USD

Choose a reason for hiding this comment

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

E501 line too long (132 > 120 characters)

'user_active_in_last_quarter': bool, if the user was active in last quarter
'user_no_of_languages': No of languages user used while working on bounties.
'user_languages': Languages that were used in bounties that were worked on.
'relevant_bounties': a list of Bounty(s) that would match the skillset input by the user into the Match tab of their settings

Choose a reason for hiding this comment

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

E501 line too long (137 > 120 characters)

user_funded_bounty_developers.append(fulfillment.fulfiller_github_username.lstrip('@'))
user_funded_bounty_developers = [*{*user_funded_bounty_developers}]
if funded_fulfillments_with_hours_counted:
avg_hourly_rate_per_funded_bounty = float(total_funded_hourly_rate) / float(funded_fulfillments_with_hours_counted)

Choose a reason for hiding this comment

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

E501 line too long (131 > 120 characters)

current_bounty=True,
metadata__icontains=keyword,
idx_status__in=['open'],
).order_by('?')

Choose a reason for hiding this comment

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

W291 trailing whitespace

owocki
owocki previously approved these changes Jun 13, 2018
Copy link
Contributor

@owocki owocki left a comment

Choose a reason for hiding this comment

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

just tested this and pushed up a few commits. this has my 👍 after you resolve @mbeacom 's concerns @oogetyboogety !

@@ -1127,22 +1127,97 @@ def get_quarterly_stats(self):
dict : containing the following information
'user_total_earned_eth': Total earnings of user in ETH.
'user_total_earned_usd': Total earnings of user in USD.
'user_fulfilled_bounties_count': Total bounties fulfilled by user.
'user_total_funded_usd': Total value of bounties funded by the user on bounties in done status in USD
'user_total_funded_hours': Total hours input by the developers on the fulfillment of bounties created by the user in USD

Choose a reason for hiding this comment

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

E501 line too long (132 > 120 characters)

'user_active_in_last_quarter': bool, if the user was active in last quarter
'user_no_of_languages': No of languages user used while working on bounties.
'user_languages': Languages that were used in bounties that were worked on.
'relevant_bounties': a list of Bounty(s) that would match the skillset input by the user into the Match tab of their settings

Choose a reason for hiding this comment

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

E501 line too long (137 > 120 characters)

user_funded_bounty_developers.append(fulfillment.fulfiller_github_username.lstrip('@'))
user_funded_bounty_developers = [*{*user_funded_bounty_developers}]
if funded_fulfillments_with_hours_counted:
avg_hourly_rate_per_funded_bounty = float(total_funded_hourly_rate) / float(funded_fulfillments_with_hours_counted)

Choose a reason for hiding this comment

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

E501 line too long (131 > 120 characters)

@@ -1127,22 +1127,95 @@ def get_quarterly_stats(self):
dict : containing the following information
'user_total_earned_eth': Total earnings of user in ETH.
'user_total_earned_usd': Total earnings of user in USD.
'user_fulfilled_bounties_count': Total bounties fulfilled by user.
'user_total_funded_usd': Total value of bounties funded by the user on bounties in done status in USD
'user_total_funded_hours': Total hours input by the developers on the fulfillment of bounties created by the user in USD

Choose a reason for hiding this comment

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

E501 line too long (132 > 120 characters)

'user_active_in_last_quarter': bool, if the user was active in last quarter
'user_no_of_languages': No of languages user used while working on bounties.
'user_languages': Languages that were used in bounties that were worked on.
'relevant_bounties': a list of Bounty(s) that would match the skillset input by the user into the Match tab of their settings

Choose a reason for hiding this comment

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

E501 line too long (137 > 120 characters)

avg_hourly_rate_per_funded_bounty = \
float(total_funded_hourly_rate) / float(funded_fulfillments_with_hours_counted)
avg_hours_per_funded_bounty = \
float(total_funded_hours) / float(funded_fulfillments_with_hours_counted)

Choose a reason for hiding this comment

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

E127 continuation line over-indented for visual indent

@@ -1127,22 +1127,95 @@ def get_quarterly_stats(self):
dict : containing the following information
'user_total_earned_eth': Total earnings of user in ETH.
'user_total_earned_usd': Total earnings of user in USD.
'user_fulfilled_bounties_count': Total bounties fulfilled by user.
'user_total_funded_usd': Total value of bounties funded by the user on bounties in done status in USD
'user_total_funded_hours': Total hours input by the developers on the fulfillment of bounties created by the user in USD

Choose a reason for hiding this comment

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

E501 line too long (132 > 120 characters)

'user_active_in_last_quarter': bool, if the user was active in last quarter
'user_no_of_languages': No of languages user used while working on bounties.
'user_languages': Languages that were used in bounties that were worked on.
'relevant_bounties': a list of Bounty(s) that would match the skillset input by the user into the Match tab of their settings

Choose a reason for hiding this comment

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

E501 line too long (137 > 120 characters)

@oogetyboogety
Copy link
Contributor Author

@owocki @mbeacom Fixed most of the review comments, can you look over once more

@mbeacom
Copy link
Contributor

mbeacom commented Jun 25, 2018

@oogetyboogety Would you mind posting screenshots or gifs for these changes?

@owocki
Copy link
Contributor

owocki commented Jul 3, 2018

@oogetyboogety we are keen to move fowrward on this since its now Q3! let us know what you think of @mbeacom 's question above

@oogetyboogety
Copy link
Contributor Author

@owocki I'll get those wrapped up and uploaded today!

…of passing the whole array for total_funded_usd
@@ -1127,22 +1127,95 @@ def get_quarterly_stats(self):
dict : containing the following information
'user_total_earned_eth': Total earnings of user in ETH.
'user_total_earned_usd': Total earnings of user in USD.
'user_fulfilled_bounties_count': Total bounties fulfilled by user.
'user_total_funded_usd': Total value of bounties funded by the user on bounties in done status in USD
'user_total_funded_hours': Total hours input by the developers on the fulfillment of bounties created by the user in USD

Choose a reason for hiding this comment

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

E501 line too long (132 > 120 characters)

'user_active_in_last_quarter': bool, if the user was active in last quarter
'user_no_of_languages': No of languages user used while working on bounties.
'user_languages': Languages that were used in bounties that were worked on.
'relevant_bounties': a list of Bounty(s) that would match the skillset input by the user into the Match tab of their settings

Choose a reason for hiding this comment

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

E501 line too long (137 > 120 characters)

@oogetyboogety
Copy link
Contributor Author

owocki_rinkeby3
owocki_rinkeby2
owocki_rinkeby
gitcointestdeveloper2

@@ -1127,22 +1127,95 @@ def get_quarterly_stats(self):
dict : containing the following information
'user_total_earned_eth': Total earnings of user in ETH.
'user_total_earned_usd': Total earnings of user in USD.
'user_fulfilled_bounties_count': Total bounties fulfilled by user.
'user_total_funded_usd': Total value of bounties funded by the user on bounties in done status in USD
'user_total_funded_hours': Total hours input by the developers on the fulfillment of bounties created by the user in USD

Choose a reason for hiding this comment

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

E501 line too long (132 > 120 characters)

'user_active_in_last_quarter': bool, if the user was active in last quarter
'user_no_of_languages': No of languages user used while working on bounties.
'user_languages': Languages that were used in bounties that were worked on.
'relevant_bounties': a list of Bounty(s) that would match the skillset input by the user into the Match tab of their settings

Choose a reason for hiding this comment

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

E501 line too long (137 > 120 characters)

@owocki
Copy link
Contributor

owocki commented Jul 24, 2018

these look really good!

@owocki owocki merged commit 19b3693 into gitcoinco:master Jul 24, 2018
@ghost ghost removed the in progress label Jul 24, 2018
@owocki
Copy link
Contributor

owocki commented Jul 24, 2018

@oogetyboogety can u pls request payout via the gitcoin bounty?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants