-
-
-
reviewboard/accounts/managers.py (Diff revision 1) Docstrings should be in the form:
"""One-line summary."""or:
"""One-line summary.
Multi-line description.
""" -
-
-
reviewboard/accounts/managers.py (Diff revision 1) You can combine these logic to something like:
if not interesting: if id_str == ''.join(reversed(id_str)): context['palindrome'] = True review_request.extra_data['has_trophy_case'] = 'true' else: context.pop() return ""
-
-
-
-
reviewboard/reviews/templatetags/reviewtags.py (Diff revision 1) Might be better to name this 'has_trophy' or 'has_trophy_assigned'.
-
reviewboard/reviews/templatetags/reviewtags.py (Diff revision 1) Same thing about docstrings as before.
-
reviewboard/reviews/templatetags/reviewtags.py (Diff revision 1) Comments shouldn't span across conditions. It's better if you combine and put them before the opening if statement.
-
[Non-WIP] Add logic for computing and checking for trophies.
Review Request #4857 — Created Oct. 28, 2013 and submitted
Add functionality for trophy to be awarded to a user.
The trophy will be associated with the user, review request, and maybe a local site. It will be added to the database, and displayed on the review request page. Also added functionality for a subclass of TrophyType to be registered as a trophy. However, more work is needed to allow for importing trophies via extensions.
All unit tests pass. Checked with review requests 1000, 1001, and 3 and trophies were displayed correctly (or not at all). Also tested with a new database, filled with the fill-database script. Tested with review request ID's 1000, 10000, 1001, 2222, and 3. Appropriate trophies (or none at all) were awarded. The trophies' existence in the database was manually confirmed.
Description | From | Last Updated |
---|---|---|
This should be removed. We don't use these in Review Board, as a file will typically be modified and maybe … |
|
|
Blank line between these. Imports should be separated in upwards of 3 groups, as: Built-in Python modules. Third-party modules (those … |
|
|
Two blank lines here. Also, you wouldn't put parens around the import unless the imports flow over several lines. |
|
|
Unnecessary blank line. |
ED edwlee | |
Docstrings should be in the form: """One-line summary.""" or: """One-line summary. Multi-line description. """ |
ED edwlee | |
Comments should have sentence capitalization, and generally end with a period. Same with other comments in the file. |
|
|
iftrophy shouldn't be the central point here for determining if there's a trophy for something. All logic around trophies should … |
|
|
Call this display_id or something. id is a reserved word in Python. |
|
|
You can do 'if not id or id < 1000'. |
ED edwlee | |
Should be False, not 'false'. Also, you're setting this, but never saving the review request. When you save, you'll want … |
|
|
Too many blank lines. |
ED edwlee | |
You can combine these logic to something like: if not interesting: if id_str == ''.join(reversed(id_str)): context['palindrome'] = True review_request.extra_data['has_trophy_case'] = … |
ED edwlee | |
True, not 'true'. Same comment about saving and about the structure. |
|
|
Blank line between these. |
|
|
This class is missing a docstring, and missing an objects = TrophyManager to associate with the manager. |
|
|
type is a reserved word. |
|
|
Imports should be sorted alphabetically. |
ED edwlee | |
This doesn't seem right... You're overriding what extra_data is. I gather you're trying to create this field with a default … |
|
|
Too many blank lines. |
ED edwlee | |
Same comment about sentence capitalization. This comment is very narrow, width-wise. You can fit more on a line. |
|
|
What you want is: Trophy.objects.compute_trophies(self) |
|
|
You don't need to pass in self as an argument. |
ED edwlee | |
Might be better to name this 'has_trophy' or 'has_trophy_assigned'. |
ED edwlee | |
Same thing about docstrings as before. |
ED edwlee | |
Comments shouldn't span across conditions. It's better if you combine and put them before the opening if statement. |
ED edwlee | |
Too many blank lines. |
ED edwlee | |
This comment isn't particularly useful. |
|
|
Because this is in the manager, "self.model.objects" is the same as "self", so this can be simplified: for trophy in … |
|
|
Trailing whitespace. |
|
|
Please wrap this line to 80 columns. |
|
|
To help with the unicode work I'm doing right now, can you change str to unicode here? |
|
|
It might be nice to use a regular expression here instead of string multiplication + comparison. Something like this: if … |
|
|
Add a space between "#" and "Create" |
|
|
You shouldn't need to do this. Because of the way foreign keys work in django, review_request.local_site will resolve to be … |
|
|
You already have the review request object (it was passed into your method). |
|
|
Accessing review_request.submitter will give you the User object directly. What your code does is fetches the user object, calls its … |
|
|
With the above changes for foreign keys, this line might look like this: trophy = self.model(category=trophy_category, review_request=review_request, local_site=review_request.local_site, user=review_request.submitter) |
|
|
Remove the space between """ and Testing |
|
|
Same here. |
|
|
You'll need to make an evolution for this, since you're adding a field to an existing model. We'll also probably … |
|
|
Generally when using the 're' module, the entire module is imported, and then calls are made to re.match(). It's not … |
|
|
Don't delete this line. |
|
|
This code should move into the individual TrophyType subclasses, which should have a method that takes in a ReviewRequest, and … |
|
|
Why did you rename this to "trophy_bean_list"??? What is a trophy bean? |
|
|
It looks like you copied code from the scmtools (line 266 still says _scmtool_class), which works differently from the Review … |
|
|
We should include the trophy category in the subclasses here, and add a class method to get the right subclass … |
|
|
This is a start, but you'll also need some code to register your built-in trophy types. Something like this: from … |
|
|
Leftover debug code. |
|
|
Leftover debug code. |
|
|
This could be shortened: review_request.extra_data['has_trophy_case'] = \ bool(calculated_trophy_types) |
|
|
You don't need to say "is True", you can just say if review_request['has_trophy_case']: and it will check for truthiness. |
|
|
This should just be "else:" instead of elif. |
|
|
TrophyType.get_type() already returns None if it doesn't find anything, so you can just return TrophyType.get_type(self.category) here. |
|
|
The trophy_id field isn't used anywhere, and if we ever have trophies that come from multiple people, it's going to … |
|
|
Can we do localization here? Something like this: from django.utils.translation import ugettext_lazy _ ... def get_display_text(self, trophy): ... return _('%(user)s … |
|
|
Can we wrap the title in _() ? |
|
|
We should change the title of this to be _('Fish Trophy') |
|
|
This line is too long. Can we wrap it? if (review_request.display_id >= 1000 and id_str == ''.join(reversed(id_str)): |
|
|
Can we add a get_display_text method here that says "XXX got a fish trophy!"? |
|
|
Probably the next step here is to make the template tag iterate through the awarded trophies and have them insert … |
|
|
We might as well let the database do the work here even in the empty case. You're also doing a … |
|
|
The Trophy.get_display_text doesn't take in any additional parameters (the one "self" parameter is provided for you because it's a bound … |
|
|
You could use a list comprehension here, too: return [trophy_model.get_trophy_type()() for trophy_model in trophy_models] |
|
|
Instead of using .count() == 0, you can use .empty(), which is a more efficient database query. |
|
|
You could combine these lines: return (review_request.display_id >= 1000 and re.match(r'^[1-9]0+$', id_str)) |
|
|
Can we change the title here to "Fish Trophy"? A lot of our amusement from this comes from it being … |
|
|
This line is slightly misaligned. |
|
|
You could combine these lines together. |
|
|
This line is indented too far. It should be either aligned exactly or indented 4 spaces compared to "review_request" on … |
|
|
You could just move the call to trophy.user.get_full_name into the dict definition and make this 1 line shorter. |
|
|
Docstrings should be in the form of: """One-line summary. Multi-line description. """ |
|
|
Blank line before this. |
|
|
Blank line before this. |
|
|
Preferably call this trophies and not trophy_models. |
|
|
You can actually simplify this in a nice Pythonic way by doing: trophies = [ self.model.create(...) for trophy_type in calculated_trophy_types … |
|
|
Blank line before this. |
|
|
Instead of creating and then saving, you can do: trophy = self.model.create(<params here>) Also, best to name this trophy and … |
|
|
Blank line between these. It's good being able to see where block statements begin/end when they cause indentation changes. |
|
|
The point of the entry is to know whether or not we have to calculate again, so I think we … |
|
|
get_trophies I wouldn't use "model" everywhere. It's just not our convention. The "model" is the class definition and its schema, … |
|
|
"any possible" is not clear, and "This function" isn't really useful. I'd say something like: """Returns a list of trophies … |
|
|
This function seems pointless. Callers should just call the right thing on the trophy itself. |
|
|
One-line summary, multi-line description. Cannot wrap or exceed a total of 79 characters for the line. A good way of … |
|
|
You can put review_request as a parameter to this, instead of pulling from kwargs. kwargs is just a representation of … |
|
|
Blank line before this. |
|
|
It isn't correct to call functions in a class definition. Any setup should happen in the setUp function for a … |
|
|
Please be sure to use the same format for these test docstrings that we use elsewhere in the codebase. |
|
|
No need to pop. Just compare with trophies[0] below. Same in other functions. |
|
|
Two blank lines. |
|
|
This and all other classes in this file are missing a docstring. |
|
|
I'd maybe rename this for_category. |
|
|
You should explicitly return None at the end if nothing matches, and then be sure to handle that in all … |
|
|
This looks to be exceeding 79 characters. Wrap the parameters to the following line after __init__. |
|
|
Same comment about wrapping. |
|
|
Should have a trailing comma. |
|
|
Two blank lines. |
|
|
We wrote @blocktag to prevent having to create these nodes. It does all this for you. Your entire template tag … |
|
|
"for a given" What do you mean by "instantiating existing and imported trophies?" I don't really see where it's doing … |
|
|
I think we want to unconditionally set this, since any review request without a trophy will otherwise have these calculations … |
|
|
This is duplicating the conditional above in compute_trophies. I think instead, we should either have compute_trophies not return existing trophies, … |
|
|
No blank line here. |
|
|
Nit - remove this blank line. |
|
|
In our other models, we put objects below the list of fields, with a blank line on either side. |
|
|
We should cache the result of this locally, like Tool.get_scmtool_class does. |
|
|
Should only call get_trophy_type once. Also, this function is missing a result when it can't find a valid TrophyType. However, … |
|
|
I'd just call this TrophyTests. There's not really a trophy "case" anywhere. We're just testing trophies. |
|
|
Likewise, we're awarding a trophy, not a trophy case. |
|
|
I'm really not understanding how these two tests are different. I assume when create_review_request is called, and the review requests … |
|
|
The """ should be all on one line for unit tests. Same with the others. |
|
|
calculated_trophies should be True already, since we published. You should instead be asserting that calculated_trophies is True. |
|
|
I'm really not sure why these calculated_trophies extra_data things are being set manually here... same below. |
|
|
Same as above. I don't see how these tests are different. |
|
|
I think we need from future import unicode_literals in every new file, right? |
|
|
This represents a type of a trophy, not an imported trophy. |
|
|
This should be image_url. |
|
|
To simplify this a bit, you can do: return _trophy_types.get(category, UnknownTrophy) |
|
|
"if the review request ID" |
|
|
It's registering a TrophyType subclass. |
|
|
"a type of trophy" |
|
|
_register_trophies itself should be safe-guarding here, like with HostingServices and stuff. Callers should be able to call _register_trophies multiple times … |
|
|
These aren't hosting services ;) |
|
|
"type of trophy" |
|
|
"TrophyType" |
|
|
"TrophyType" |
|
|
Missing the __future__ import discussed at the meeting. You can copy/paste it from other files in this directory. |
|
|
Blank line before this. |
|
|
This looks like the perfect use case for a template. Maybe I missed something, but why can't we use a … |
|
|
For readability, can you termiante strings after the \n? Actually, a better way to do things is to build a … |
|
|
If you use single quotes for the string, you won't need to escape the double quotes. It's also better to … |
|
|
Blank line before this. |
|
-
-
reviewboard/accounts/managers.py (Diff revision 1) This should be removed. We don't use these in Review Board, as a file will typically be modified and maybe partially rewritten by many people over its lifetime.
-
reviewboard/accounts/managers.py (Diff revision 1) Blank line between these. Imports should be separated in upwards of 3 groups, as:
- Built-in Python modules.
- Third-party modules (those outside the project, like django)
- Modules within the project.
-
reviewboard/accounts/managers.py (Diff revision 1) Two blank lines here.
Also, you wouldn't put parens around the import unless the imports flow over several lines.
-
reviewboard/accounts/managers.py (Diff revision 1) Comments should have sentence capitalization, and generally end with a period.
Same with other comments in the file.
-
reviewboard/accounts/managers.py (Diff revision 1) iftrophy shouldn't be the central point here for determining if there's a trophy for something. All logic around trophies should exist in this class, not in templatetags anywhere.
Since iftrophy is really trivial, and special-cased to this function's usage, that logic should just move directly into here.
-
reviewboard/accounts/managers.py (Diff revision 1) Call this display_id or something.
id
is a reserved word in Python. -
reviewboard/accounts/managers.py (Diff revision 1) Should be
False
, not'false'
.Also, you're setting this, but never saving the review request.
When you save, you'll want to do:
review_request.save(update_fields=['extra_data'])
That'll ensure that we write only what's necessary here, and won't risk stomping on other fields.
Also, this code should be structured o that we only ever set has_trophy_case once, to the computed value based on the logic in this function, and save it once.
-
reviewboard/accounts/managers.py (Diff revision 1) From your pastie, I know that you've removing context and stuff from this function, which is great. That's exactly what you want to do.
This function should also, by the end of the project, not directly calculate these types of trophies. Instead, it should interface with pluggable trophy classes that calculate trophies for the review request, so that we can extend the trophy types via plugins. That can go in after this, though.
-
reviewboard/accounts/managers.py (Diff revision 1) True
, not'true'
.Same comment about saving and about the structure.
-
-
reviewboard/accounts/models.py (Diff revision 1) This class is missing a docstring, and missing an
objects = TrophyManager
to associate with the manager. -
-
reviewboard/reviews/models.py (Diff revision 1) This doesn't seem right... You're overriding what
extra_data
is.I gather you're trying to create this field with a default value in it. You shouldn't create default value in any
extra_data
. Instead, you should just check for the existence of a key inextra_data
, and make decisions based on that. You can do so with:if `has_trophy_case` in review_request.extra_data:
-
reviewboard/reviews/models.py (Diff revision 1) Same comment about sentence capitalization.
This comment is very narrow, width-wise. You can fit more on a line.
-
reviewboard/reviews/models.py (Diff revision 1) What you want is:
Trophy.objects.compute_trophies(self)
Description: |
|
||||||
---|---|---|---|---|---|---|---|
Testing Done: |
|
||||||
Diff: |
Revision 2 (+102 -2) |
Change Summary:
Fix an issue in tests.py. Change the way the compute_trophy method is called.
Diff: |
Revision 3 (+105 -1) |
---|
Change Summary:
The logic for creating a trophy and assigning it to a review request is complete. Unit tests pass.
Testing Done: |
|
||||||
---|---|---|---|---|---|---|---|
Diff: |
Revision 5 (+103 -3) |
-
-
-
reviewboard/accounts/managers.py (Diff revision 5) Because this is in the manager, "self.model.objects" is the same as "self", so this can be simplified:
for trophy in self.filter(review_request=display_id):
You could even replace this with a list constructor:
existing_trophies = list(self.filter(review_request=display_id))
-
-
-
reviewboard/accounts/managers.py (Diff revision 5) To help with the unicode work I'm doing right now, can you change
str
tounicode
here? -
reviewboard/accounts/managers.py (Diff revision 5) It might be nice to use a regular expression here instead of string multiplication + comparison. Something like this:
if re.match(r'^[1-9]0+$', id_str): # do stuff
-
-
reviewboard/accounts/managers.py (Diff revision 5) You shouldn't need to do this. Because of the way foreign keys work in django,
review_request.local_site
will resolve to be either theLocalSite
object orNone
-
reviewboard/accounts/managers.py (Diff revision 5) You already have the review request object (it was passed into your method).
-
reviewboard/accounts/managers.py (Diff revision 5) Accessing review_request.submitter will give you the User object directly. What your code does is fetches the user object, calls its
__str__
method (coercing to string), which returns the username, then queries for that username again.Since you only use this once, might as well do it inline. Will show below.
-
reviewboard/accounts/managers.py (Diff revision 5) With the above changes for foreign keys, this line might look like this:
trophy = self.model(category=trophy_category, review_request=review_request, local_site=review_request.local_site, user=review_request.submitter)
-
-
-
reviewboard/reviews/models.py (Diff revision 5) You'll need to make an evolution for this, since you're adding a field to an existing model.
We'll also probably want to have an IRC discussion at some point about how this field should work with drafts.
Change Summary:
Create an evolution for the extra_data field in ReviewRequest as well as other WIP changes for the trophy case.
Diff: |
Revision 6 (+105 -3) |
---|
-
This is looking pretty good! Just a couple trivial comments on code style.
-
reviewboard/accounts/managers.py (Diff revision 6) Generally when using the 're' module, the entire module is imported, and then calls are made to
re.match()
. It's not incorrect to do it this way, but I think the other way is more conventional. -
Change Summary:
Make changes in order to connect to frontend.
Change Summary:
Add trophy registration.
Diff: |
Revision 9 (+228 -11)
|
---|
Change Summary:
Fix variable name
Diff: |
Revision 10 (+228 -11)
|
---|
-
-
reviewboard/accounts/managers.py (Diff revision 9) This code should move into the individual TrophyType subclasses, which should have a method that takes in a ReviewRequest, and we should iterate over the TrophyTypes to have them each run their own calculation.
-
reviewboard/accounts/managers.py (Diff revision 9) Why did you rename this to "trophy_bean_list"??? What is a trophy bean?
-
reviewboard/accounts/models.py (Diff revision 9) It looks like you copied code from the scmtools (line 266 still says
_scmtool_class
), which works differently from the Review UI registration pattern.If you make the changes I suggested below to the TrophyType code, this becomes very simple:
def get_trophy_type(self): trophy_type = TrophyType.get_type(self.category)
Note that it's possible that the trophy_type might be None, in which case we'd probably want to hide it from view.
-
reviewboard/accounts/trophies.py (Diff revision 9) We should include the trophy category in the subclasses here, and add a class method to get the right subclass based on a category name.
Something like this:
class TrophyType: ... (keep the stuff you have) ... @classmethod def get_type(cls, category): for trophy_type in _trophy_types: if trophy_type.category == category: return trophy_type class MilestoneTrophy(TrophyType): category = 'milestone' def __init__(self, received_date): ... ...
-
reviewboard/accounts/trophies.py (Diff revision 9) This is a start, but you'll also need some code to register your built-in trophy types. Something like this:
from reviewboard.signals import initializing def _register_trophies(**kwargs): register_trophy(MilestoneTrophy) register_trophy(PalindromeTrophy) initializing.connect(_register_trophies)
Change Summary:
Add improvements for computing trophies.
Diff: |
Revision 11 (+251 -11)
|
---|
Change Summary:
Update TrophyManager to work with TrophyType.
Diff: |
Revision 12 (+239 -11)
|
---|
-
-
-
-
reviewboard/accounts/managers.py (Diff revision 12) This could be shortened:
review_request.extra_data['has_trophy_case'] = \ bool(calculated_trophy_types)
-
reviewboard/accounts/managers.py (Diff revision 12) You don't need to say "is True", you can just say
if review_request['has_trophy_case']:
and it will check for truthiness. -
-
reviewboard/accounts/models.py (Diff revision 12) TrophyType.get_type() already returns None if it doesn't find anything, so you can just
return TrophyType.get_type(self.category)
here. -
reviewboard/accounts/trophies.py (Diff revision 12) The
trophy_id
field isn't used anywhere, and if we ever have trophies that come from multiple people, it's going to be hard to keep these unique. I think you should just remove it. -
reviewboard/accounts/trophies.py (Diff revision 12) Can we do localization here? Something like this:
from django.utils.translation import ugettext_lazy _ ... def get_display_text(self, trophy): ... return _('%(user)s got review request #%(id)!') % { 'user': full_name, 'id': review_request_id, }
-
-
reviewboard/accounts/trophies.py (Diff revision 12) We should change the title of this to be
_('Fish Trophy')
-
reviewboard/accounts/trophies.py (Diff revision 12) This line is too long. Can we wrap it?
if (review_request.display_id >= 1000 and id_str == ''.join(reversed(id_str)):
-
reviewboard/accounts/trophies.py (Diff revision 12) Can we add a
get_display_text
method here that says "XXX got a fish trophy!"? -
reviewboard/templates/reviews/trophy_box.html (Diff revision 12) Probably the next step here is to make the template tag iterate through the awarded trophies and have them insert their own HTML instead of having the hard-coded stuff in here.
Change Summary:
Refactor according to reviews. Update unit tests.
Testing Done: |
|
||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Diff: |
Revision 13 (+253 -11)
|
Change Summary:
Add object as superclass of TrophyType.
Diff: |
Revision 14 (+250 -11)
|
---|
Change Summary:
Fix so that unit tests pass.
Testing Done: |
|
||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Diff: |
Revision 15 (+252 -11)
|
Change Summary:
Modify TrophyManager to return Trophy models rather than TrophyTypes.
Diff: |
Revision 16 (+252 -11)
|
---|
Change Summary:
Add display_trophies method to TrophyManager.
Diff: |
Revision 17 (+258 -11)
|
---|
Change Summary:
Add method to TrophyManager to return TrophyTypes.
Diff: |
Revision 18 (+268 -11)
|
---|
-
-
reviewboard/accounts/managers.py (Diff revision 18) We might as well let the database do the work here even in the empty case. You're also doing a weird lookup with display_id in there when the foreign key will give you the related object directly:
if 'has_trophy_case' in review_request.extra_data: return list(self.filter(review_request=review_request))
-
reviewboard/accounts/managers.py (Diff revision 18) The Trophy.get_display_text doesn't take in any additional parameters (the one "self" parameter is provided for you because it's a bound method).
This would also be a convenient place to use a list comprehension:
return [trophy_model.get_display_text() for trophy_model in trophy_models]
-
reviewboard/accounts/managers.py (Diff revision 18) You could use a list comprehension here, too:
return [trophy_model.get_trophy_type()() for trophy_model in trophy_models]
-
reviewboard/accounts/models.py (Diff revision 18) Instead of using
.count() == 0
, you can use.empty()
, which is a more efficient database query. -
reviewboard/accounts/trophies.py (Diff revision 18) You could combine these lines:
return (review_request.display_id >= 1000 and re.match(r'^[1-9]0+$', id_str))
-
reviewboard/accounts/trophies.py (Diff revision 18) Can we change the title here to "Fish Trophy"? A lot of our amusement from this comes from it being a bit of a mystery.
-
-
-
reviewboard/accounts/trophies.py (Diff revision 18) This line is indented too far. It should be either aligned exactly or indented 4 spaces compared to "review_request" on the previous line.
-
reviewboard/accounts/trophies.py (Diff revision 18) You could just move the call to trophy.user.get_full_name into the dict definition and make this 1 line shorter.
Change Summary:
Refactor.
Diff: |
Revision 19 (+250 -11)
|
---|
Change Summary:
Modify template to display trophy on review request page.
Diff: |
Revision 20 (+258 -11)
|
---|
Change Summary:
Impove TrophyNode class. Add unit test.
Testing Done: |
|
||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Diff: |
Revision 21 (+271 -11)
|
Change Summary:
Modify get_trophy_types() to take a list of trophy models rather than a review request.
Testing Done: |
|
||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Diff: |
Revision 22 (+263 -11)
|
Change Summary:
Add new unit tests.
Diff: |
Revision 23 (+302 -11)
|
---|
Change Summary:
Possible trophies are displayed on the review request page.
Summary: |
|
||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Testing Done: |
|
||||||||||||||||||
Diff: |
Revision 24 (+305 -11)
|
Change Summary:
Refactor. Get rid of unused TrophyManager methods.
Diff: |
Revision 25 (+295 -15)
|
---|
Change Summary:
Add testing information
Testing Done: |
|
---|
-
-
reviewboard/accounts/managers.py (Diff revision 25) Docstrings should be in the form of:
"""One-line summary. Multi-line description. """
-
-
-
reviewboard/accounts/managers.py (Diff revision 25) Preferably call this
trophies
and nottrophy_models
. -
reviewboard/accounts/managers.py (Diff revision 25) You can actually simplify this in a nice Pythonic way by doing:
trophies = [ self.model.create(...) for trophy_type in calculated_trophy_types ]
-
-
reviewboard/accounts/managers.py (Diff revision 25) Instead of creating and then saving, you can do:
trophy = self.model.create(<params here>)
Also, best to name this
trophy
and nottrophy_model
. -
reviewboard/accounts/managers.py (Diff revision 25) Blank line between these.
It's good being able to see where block statements begin/end when they cause indentation changes.
-
reviewboard/accounts/managers.py (Diff revision 25) The point of the entry is to know whether or not we have to calculate again, so I think we want this to always be
True
.I don't think
has_trophy_case
properly conveys what this is.calculated_trophies
is more correct.Also, this function should simply return right away if this is already
True
, so we don't repeat all this. -
reviewboard/accounts/managers.py (Diff revision 25) get_trophies
I wouldn't use "model" everywhere. It's just not our convention. The "model" is the class definition and its schema, but things interacting with it are just dealing with it as what it is. A representation of a trophy, not a DB model.
-
reviewboard/accounts/managers.py (Diff revision 25) "any possible" is not clear, and "This function" isn't really useful. I'd say something like:
"""Returns a list of trophies fo a review request."""
-
reviewboard/accounts/managers.py (Diff revision 25) This function seems pointless. Callers should just call the right thing on the trophy itself.
-
reviewboard/accounts/models.py (Diff revision 25) One-line summary, multi-line description. Cannot wrap or exceed a total of 79 characters for the line.
A good way of approaching these is not to think about what it's technically doing (like here, what it's attached to), but by what it is.
"A trophy represents an achievement given to the user.", and then go into details in the description.
-
reviewboard/accounts/models.py (Diff revision 25) You can put
review_request
as a parameter to this, instead of pulling fromkwargs
.kwargs
is just a representation of all parameters passed to a function by keyword.Also, given that this function is internal, it's best to prefix it with a
_
. -
-
reviewboard/accounts/tests.py (Diff revision 25) It isn't correct to call functions in a class definition. Any setup should happen in the
setUp
function for a test suite.You shouldn't even need to register these. It should happen automatically when you fetch trophy types, right?
-
reviewboard/accounts/tests.py (Diff revision 25) Please be sure to use the same format for these test docstrings that we use elsewhere in the codebase.
-
reviewboard/accounts/tests.py (Diff revision 25) No need to pop. Just compare with
trophies[0]
below.Same in other functions.
-
-
reviewboard/accounts/trophies.py (Diff revision 25) This and all other classes in this file are missing a docstring.
-
-
reviewboard/accounts/trophies.py (Diff revision 25) You should explicitly return
None
at the end if nothing matches, and then be sure to handle that in all call sites appropriately. -
reviewboard/accounts/trophies.py (Diff revision 25) This looks to be exceeding 79 characters. Wrap the parameters to the following line after
__init__
. -
-
-
-
reviewboard/reviews/templatetags/reviewtags.py (Diff revision 25) We wrote
@blocktag
to prevent having to create these nodes. It does all this for you. Your entire template tag should be very similar toifneatnumber
.You also shouldn't hard-code HTML in a template tag. You should be doing exactly what
ifneatnumber
is doing. Passing in context, and letting the template render it how it chooses.
Change Summary:
Refactor and make changes according to reviews.
Diff: |
Revision 26 (+359 -15)
|
---|
Change Summary:
Refactor.
Diff: |
Revision 27 (+359 -15)
|
---|
-
-
reviewboard/accounts/managers.py (Diff revision 27) "for a given"
What do you mean by "instantiating existing and imported trophies?" I don't really see where it's doing that. It looks instead like it's computing trophies by looping through all registered trophy types and seeing if any apply to the review request.
-
reviewboard/accounts/managers.py (Diff revision 27) I think we want to unconditionally set this, since any review request without a trophy will otherwise have these calculations done every time. Having no trophies set is a valid result of calculating trophies.
-
reviewboard/accounts/managers.py (Diff revision 27) This is duplicating the conditional above in
compute_trophies
. I think instead, we should either havecompute_trophies
not return existing trophies, or we should have this just callcompute_trophies
internally. Probably the latter. -
-
reviewboard/accounts/models.py (Diff revision 27) In our other models, we put
objects
below the list of fields, with a blank line on either side. -
reviewboard/accounts/models.py (Diff revision 27) We should cache the result of this locally, like
Tool.get_scmtool_class
does. -
reviewboard/accounts/models.py (Diff revision 27) Should only call
get_trophy_type
once.Also, this function is missing a result when it can't find a valid
TrophyType
. However, I'm not sure if that's possible anymore, withUnknownTrophy
. Maybe we should unconditionally callget_display_text
now? -
reviewboard/accounts/tests.py (Diff revision 27) I'd just call this
TrophyTests
.There's not really a trophy "case" anywhere. We're just testing trophies.
-
reviewboard/accounts/tests.py (Diff revision 27) Likewise, we're awarding a trophy, not a trophy case.
-
reviewboard/accounts/tests.py (Diff revision 27) The
"""
should be all on one line for unit tests.Same with the others.
-
reviewboard/accounts/tests.py (Diff revision 27) calculated_trophies
should beTrue
already, since we published. You should instead be asserting thatcalculated_trophies
isTrue
. -
reviewboard/accounts/trophies.py (Diff revision 27) This represents a type of a trophy, not an imported trophy.
-
-
-
-
-
reviewboard/accounts/trophies.py (Diff revision 27) _register_trophies
itself should be safe-guarding here, like with HostingServices and stuff. Callers should be able to call_register_trophies
multiple times without problems. -
-
-
-
-
reviewboard/reviews/evolutions/review_request_extra_data.py (Diff revision 27) Missing the
__future__
import discussed at the meeting. You can copy/paste it from other files in this directory. -
-
reviewboard/reviews/templatetags/reviewtags.py (Diff revision 27) For readability, can you termiante strings after the
\n
?Actually, a better way to do things is to build a list of string lines, instead of one big string. It's faster, and you can structure your code here in terms of lines.
So:
lines = [] ... lines.append('<div class="...">') ... return '\n'.join(lines)
-
reviewboard/reviews/templatetags/reviewtags.py (Diff revision 27) If you use single quotes for the string, you won't need to escape the double quotes.
It's also better to put the indentation at the beginning of the line for that string, to help see the visual structure, instead of right after the
\n
-
-
-
-
reviewboard/accounts/tests.py (Diff revision 27) I'm really not understanding how these two tests are different. I assume when create_review_request is called, and the review requests are published, the _call_compute_trophies function is going to be called, which will set calculated_trophies once its done computing.
So I don't really know what this "without initial trophy case" test is testing.
-
reviewboard/accounts/tests.py (Diff revision 27) I'm really not sure why these calculated_trophies extra_data things are being set manually here... same below.
-
reviewboard/accounts/tests.py (Diff revision 27) Same as above. I don't see how these tests are different.
-
reviewboard/accounts/trophies.py (Diff revision 27) I think we need from future import unicode_literals in every new file, right?
-
reviewboard/reviews/templatetags/reviewtags.py (Diff revision 27) This looks like the perfect use case for a template. Maybe I missed something, but why can't we use a template?
Change Summary:
Refactor. Make changes according to reviews.
Diff: |
Revision 28 (+345 -15)
|
---|
-
This looks great! One small nifty trick you can do to save a couple lines.
-
reviewboard/accounts/trophies.py (Diff revisions 27 - 28) To simplify this a bit, you can do:
return _trophy_types.get(category, UnknownTrophy)
Change Summary:
Refactor.
Description: |
|
||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Testing Done: |
|
||||||||||||||||||
Diff: |
Revision 29 (+342 -15)
|