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

CB-244: Frontend for the rating system #138

Merged
merged 40 commits into from Sep 5, 2017

Conversation

breakbuidl
Copy link
Contributor

Basic functionality for different types of review is up and running. Styling along with some other minor changes are to be done.

Copy link
Contributor

@gentlecat gentlecat left a comment

Choose a reason for hiding this comment

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

Rating selection doesn't show up for me for some reason.

self.message = message

def __call__(self, form, field):
if not field.data and not form.rating.data:
Copy link
Contributor

Choose a reason for hiding this comment

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

Accessing other fields in a validator doesn't seem right. Form class uses a validate method which you can override and check that either text or rating are present. Make sure to call original method with super().validate().

@@ -124,3 +125,7 @@
</div>
</div>
{% endblock %}

{% block scripts %}
<script src="{{ get_static_path('scripts/rating1.js') }}" type="text/javascript"></script>
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it supposed to be rating.js?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, a typo.

@@ -124,3 +125,7 @@
</div>
</div>
{% endblock %}

{% block scripts %}
Copy link
Contributor

Choose a reason for hiding this comment

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

Make sure to call super() when defining a scripts block.

@@ -108,4 +114,5 @@
});
});
</script>
<script src="{{ get_static_path('scripts/rating.js') }}" type="text/javascript"></script>
Copy link
Contributor

Choose a reason for hiding this comment

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

JS files shouldn't be accessed directly. The way we do it here now is by building JS files in gulpfile.js and referencing them like this: <script src="{{ get_static_path('rating.js') }}"></script>. That way you can easily use React, jQuery, etc. in your scripts.

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 ratingBundle in gulpfile.js

@@ -211,8 +214,10 @@ def create():
return redirect(url_for('user.reviews', user_id=current_user.id))

is_draft = form.state.data == 'draft'
if not form.text.data:
Copy link
Contributor

Choose a reason for hiding this comment

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

What values would these be?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TextAreaField in wtforms returns an empty string when no input is provided. So, it must be changed to None before inserted into the database.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you make a comment noting this? Or, even better, just compare to an empty string.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same in another case below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -16,7 +16,15 @@ def __call__(self, form, field):
if form.state.data == "draft":
return
l = len(field.data) if field.data else 0
if l < self.min or self.max != -1 and l > self.max:
if (l < self.min or self.max != -1 and l > self.max) and (l != 0):
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain what this change does? I even forgot how the original check works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally it checked whether the length is between min and max and max is not -1. I added the check for not zero so that error is not raised when its empty. I am gonna remove it because the in- built Optional() validator works better.

@breakbuidl breakbuidl force-pushed the cb-244/frontend branch 2 times, most recently from 9071c6d to 61f3c09 Compare August 7, 2017 22:15
Copy link
Contributor

@gentlecat gentlecat left a comment

Choose a reason for hiding this comment

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

Haven't tried using this yet, having some issues with Docker.

Is the rating code from some library or did you implement it yourself?

if not super(ReviewEditForm, self).validate():
return False
if not self.text.data and not self.rating.data:
message = "Please provide at least one of text or rating for this review."
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the message have to be in a separate variable?

Copy link
Member

Choose a reason for hiding this comment

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

The message isn't entirely grammatical. I suggest "Please provide some text or a rating for this review."

@@ -0,0 +1,157 @@
(function ($) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain why this is necessary here? Sorry, I'm not that good at JS.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It provides closure.

(function ($) {
'use strict';

var clearClass = 'rating-clear',
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's just let by default now unless var is actually needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since there's a closure, so the global environment won't be polluted and the code has been taken from a plugin, I think its wise to let it be the way author wrote it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Don't be afraid to modify a library code if it can be improved or adjusted for the way we use it. Not every library published on the internet is perfect. :)

this.highlight($input.val());
};

Rating.VERSION = '0.4.0';
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this version?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its plugin version. I will remove it.


user_all_reviews, review_count = db_review.list_reviews(user_id=review["user_id"], sort="random", exclude=[review["id"]]) # pylint: disable=unused-variable
other_reviews = user_all_reviews[:3]
return render_template('review/entity/%s.html' % review["entity_type"], review=review, spotify_mappings=spotify_mappings, soundcloud_url=soundcloud_url, vote=vote, other_reviews=other_reviews)
rating_titles = {20: "Terrible", 40: "Bad", 60: "Average", 80: "Good", 100: "Extradordinary"}
Copy link
Contributor

Choose a reason for hiding this comment

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

These strings should be wrapped in gettext.


Rating.DEFAULTS = DEFAULTS;

Rating.prototype = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to use Classes here?

@@ -25,9 +25,17 @@
{% endif %}
</em>
{% endif %}
<br>
<br>
Copy link
Contributor

Choose a reason for hiding this comment

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

It's better to use CSS instead of adding line breaks for spacing.

Copy link
Contributor

@gentlecat gentlecat left a comment

Choose a reason for hiding this comment

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

Just tried using it. Seems to be working.

A few issues I noticed so far:

  • There's now a weird margin before rating stars:
    screenshot 2017-08-10 17 24 08
  • I don't think titles for ratings are necessary.
  • Stars should be displayed a bit more prominently (perhaps make them slightly larger).
  • It's unnecessary to display a language when review is rating-only.
  • In the editor it's unclear that rating is unnecessary or that review might just have a rating without text. This should be made a bit more clear. Perhaps add a note.

@@ -0,0 +1,157 @@
(function ($) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't recommend forking external libraries, but I can't say much else without knowing to what extent you've modified this. Can you please link to the original source code?

If we fork this, the file must include a copyright and license attached.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Original source - https://github.com/javiertoledo/bootstrap-rating-input
I used this plugin because suited our needs the best with a few modifications. Can you please tell why are you skeptical of this kinda thing. And yes I will add the copyright.

There are lot of other options. Can you please have a look at this quite comprehensive list https://github.com/dandv/comparisons/blob/master/star-rating-widgets.md and let me know what you have in mind.

Copy link
Member

Choose a reason for hiding this comment

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

It's more code we have to test (the modifications we make) and maintain (we don't have a lot of resources).

If any bug fixes are made upstream, we have to manually merge them into our fork, instead of just bumping the version in package.json.

It doesn't look like you've made that many modifications: https://gist.github.com/mwiencek/838e5abd016ce6627c23ba47befe2d2d

You don't need to fork the code to modify DEFAULTS. You can mutate it externally through $.fn.rating.Constructor.DEFAULTS.

For the rest, why not just submit a patch upstream to support what you're doing? That way other people benefit, and we don't have to maintain our own fork.

Copy link
Member

Choose a reason for hiding this comment

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

That's just my opinion, but I don't have much stake in this. :) Fork the code if you think that's a good idea.

Copy link
Contributor

Choose a reason for hiding this comment

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

If it's possible to just make it a dependency and modify defaults externally, I'd also prefer to do that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am trying do that and also looking for some other plugin which might be more suitable.

Copy link
Contributor

Choose a reason for hiding this comment

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

There's less than a week left for the official GSoC coding period, so I'd suggest to avoid doing very time consuming tasks such as evaluating different libraries. If this one works well enough then the only thing we need to do is clean up the code to meet our requirements and move on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I decided for this plugin after a lot of searching and still didn't find any other which is more suitable. I have updated the package file and working on the required changes. Will let you know at the earliest if I face any problems.

@breakbuidl
Copy link
Contributor Author

Understood. Will make proper commits from now on.

Copy link
Contributor

@gentlecat gentlecat left a comment

Choose a reason for hiding this comment

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

It looks like there's a conflict in the package.json file. This should be rebased on top of the latest commit in master.

$('.glyphicon-remove-circle').hover(function() {
$(this).css('color', 'red');
}, function() {
$(this).css('color', '#808080');
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not do this in the style definitions (Less files) that we already have?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should this go in main.less or theme/glyphicons.less?

Copy link
Contributor

Choose a reason for hiding this comment

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

Stuff in theme shouldn't really be modified, so I'd say main.less.

@breakbuidl
Copy link
Contributor Author

breakbuidl commented Aug 18, 2017

Please don't mind the merge and conflicts commits. Ran into some trouble.
Also, I can't resolve PyLint R0912 (too many branches). The functions which have this warning are quite large.

@gentlecat
Copy link
Contributor

The functions which have this warning are quite large.

Well, that's not good. One way to fix this would be to extract some of the operations that are done in them into separate functions.

@gentlecat
Copy link
Contributor

You can also add an ignore for this check on the functions and add a TODO comment saying that it needs improvement.

@breakbuidl breakbuidl force-pushed the cb-244/frontend branch 3 times, most recently from 6093314 to f44e56b Compare August 19, 2017 08:28
Copy link
Contributor

@gentlecat gentlecat left a comment

Choose a reason for hiding this comment

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

I get this exception when I open a homepage when there's a review without text:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/werkzeug/wsgi.py", line 660, in __call__
    return app(environ, start_response)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/code/critiquebrainz/frontend/views/index.py", line 19, in index
    preview = markdown(review['text'], safe_mode="escape")
  File "/usr/local/lib/python3.6/site-packages/markdown/__init__.py", line 494, in markdown
    return md.convert(text)
  File "/usr/local/lib/python3.6/site-packages/markdown/__init__.py", line 355, in convert
    if not source.strip():
AttributeError: 'NoneType' object has no attribute 'strip'

@gentlecat
Copy link
Contributor

Another one:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/werkzeug/wsgi.py", line 660, in __call__
    return app(environ, start_response)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.6/site-packages/flask_login/utils.py", line 228, in decorated_view
    return func(*args, **kwargs)
  File "/code/critiquebrainz/frontend/views/review.py", line 304, in edit
    form.rating.data = review["rating"] // 20
TypeError: unsupported operand type(s) for //: 'NoneType' and 'int'

@gentlecat
Copy link
Contributor

I can create a review with 0 stars. Is it possible to do that in the MusicBrainz UI?

@breakbuidl
Copy link
Contributor Author

breakbuidl commented Aug 20, 2017

I get this exception when I open a homepage when there's a review without text:

Can you please check if you have included changes from #147 and the cache is clear? Because it works perfectly fine for me.

@breakbuidl
Copy link
Contributor Author

breakbuidl commented Aug 20, 2017

Another one:

Resolved this

I can create a review with 0 stars. Is it possible to do that in the MusicBrainz UI?

No, one cannot rate 0 with MusicBrainz UI. And, creating a review with 0 stars is equal to 'Not rated'. So, rating will be NULL in this case.

@gentlecat
Copy link
Contributor

Can you please check if you have included changes from #147 and the cache is clear? Because it works perfectly fine for me.

OK, seems to be working with latest changes now. But it might still be worth checking if there's any text before trying to convert it.

Copy link
Contributor

@gentlecat gentlecat left a comment

Choose a reason for hiding this comment

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

Looks a lot better now, good job. There are a few things that need to be cleaned up.

<i class="glyphicon glyphicon-star"></i>
<span style="font-size: 16px;">{{ avg_rating.rating }}</span><em class="text-muted">/5 based on {{ avg_rating.count }} ratings</em>
</p>
{% endif %}
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like this part is the same among all templates. It would be a good idea to make it a macro.

avg_rating = db_avg_rating.get(place['id'], "place")
avg_rating["rating"] = round(avg_rating["rating"] / 20, 1)
except db_exceptions.NoDataFoundException:
avg_rating = None
Copy link
Contributor

Choose a reason for hiding this comment

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

This part of code is also almost the same among different views. Can it be moved into one function that does average rating retrieval?

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 views/avg_rating for this purpose.

@@ -58,6 +59,8 @@ def browse():
page=page, limit=limit, count=count, entity_type=entity_type)


# TODO : Refactor this function to remove PyLint warning.
Copy link
Contributor

Choose a reason for hiding this comment

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

In CB code we put an identifier next to a TODO comment to know who to ask if more details are needed. So something like

# TODO(psolanki): Refactor this function to remove PyLint warning.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same in the comment below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will keep this in mind next time.


user_all_reviews, review_count = db_review.list_reviews( # pylint: disable=unused-variable
user_id=review["user_id"],
sort="random",
exclude=[review["id"]],
)
other_reviews = user_all_reviews[:3]
if review["rating"] is not None:
review["rating"] //= 20
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this conversion be done within the db package? That way users of these functions don't have to worry about converting the values, they'd just use 1-5 scale.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm still interested in a fix for this. Conversion from 5-star to 100 should be done within the db package. Modules that use it don't need to know about how ratings are stored. It's about making the interface less complex and easier to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have proposed these changes - javiertoledo/bootstrap-rating-input#61
If this gets merged then there won't be any need for converting ratings to different scales anywhere.

Copy link
Contributor

@gentlecat gentlecat Aug 21, 2017

Choose a reason for hiding this comment

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

That's great, but this is what we have now and the interface is not very well designed.

</div>
{% endif %}
{% if review.text %}
<!-- Used to display only-text review properly -->
Copy link
Contributor

Choose a reason for hiding this comment

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

What is used? Not sure if I understand what issue you are trying to solve there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is used for proper spacing above text when star icons are not present.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, but this should be simplified in the future.

@gentlecat
Copy link
Contributor

Please don't mind the merge and conflicts commits. Ran into some trouble.

You can use git rebase -i origin/master on your branch to sync the changes quicker and cleaner. Let us know if you have any questions about that.

@@ -93,10 +94,8 @@ <h4 style="margin-bottom:0;">{{ _('Reviews') }}</h4>
<div class="col-md-3">
<h4>{{ _('Place information') }}</h4>
{% if avg_rating %}
Copy link
Contributor

Choose a reason for hiding this comment

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

This checking can also be moved inside the show_avg_rating macro. And simply pass avg_rating to it. Make usage as simple as possible.

import critiquebrainz.db.avg_rating as db_avg_rating
import critiquebrainz.db.exceptions as db_exceptions

def get(entity_id, entity_type):
Copy link
Contributor

Choose a reason for hiding this comment

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

It would probably be better to just put this into __init__.py of the frontend.views package instead of creating a new module just for one utility function. I think it's expected that modules in views contain actual views.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Move the function to __init__.py


user_all_reviews, review_count = db_review.list_reviews( # pylint: disable=unused-variable
user_id=review["user_id"],
sort="random",
exclude=[review["id"]],
)
other_reviews = user_all_reviews[:3]
if review["rating"] is not None:
review["rating"] //= 20
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm still interested in a fix for this. Conversion from 5-star to 100 should be done within the db package. Modules that use it don't need to know about how ratings are stored. It's about making the interface less complex and easier to use.

<form id="review-editor" method="POST" class="form-horizontal" role="form">
{{ form.hidden_tag() }}
<div class="form-group">
<label class="col-sm-2" for="rating">{{ _('Rating for the review:') }}</label>
Copy link
Contributor

Choose a reason for hiding this comment

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

for the review part can be removed since it's pretty obvious what the rating is for.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed it and changed the column grid accordingly.

</div>
{% endif %}
{% if review.text %}
<!-- Used to display only-text review properly -->
Copy link
Contributor

Choose a reason for hiding this comment

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

OK, but this should be simplified in the future.

@@ -92,6 +93,11 @@ <h4 style="margin-bottom:0;">{{ _('Reviews') }}</h4>

<div class="col-md-3">
<h4>{{ _('Place information') }}</h4>
{% if avg_rating %}
<p>
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the <p> for here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is needed to maintain the spacing format.

Copy link
Contributor

Choose a reason for hiding this comment

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

You should use CSS for this.

Copy link
Contributor Author

@breakbuidl breakbuidl Sep 3, 2017

Choose a reason for hiding this comment

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

IMO, CSS isn't necessary here. Other elements in this column (in event and release_group) also use <p>, so we get perfectly formatted column without any use of CSS and by using mere <p>.

Copy link
Contributor

@gentlecat gentlecat Sep 3, 2017

Choose a reason for hiding this comment

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

There are plenty of places that are not implemented correctly. The goal is to make the code better, not to keep using bad practices. When other code has been written it wasn't reviewed properly.

<p> is supposed to represent a paragraph of text, which doesn't seem to apply here.


{% macro show_avg_rating(rating, count) %}
<i class="glyphicon glyphicon-star"></i>
<span style="font-size: 16px;">{{ rating }}</span><em class="text-muted">/5 {{ _('based on') }} {{ count }} {{ _('ratings') }}</em>
Copy link
Contributor

Choose a reason for hiding this comment

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

Split long lines, if necessary:

<span style="font-size: 16px;">{{ rating }}</span>
<em class="text-muted">/5 {{ _('based on') }} {{ count }} {{ _('ratings') }}</em>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its intentional. Splitting them will create an extra space.


{% macro show_avg_rating(rating, count) %}
<i class="glyphicon glyphicon-star"></i>
<span style="font-size: 16px;">{{ rating }}</span><em class="text-muted">/5 {{ _('based on') }} {{ count }} {{ _('ratings') }}</em>
Copy link
Contributor

Choose a reason for hiding this comment

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

{{ _('based on') }} {{ count }} {{ _('ratings') }} should be combined into one localisable string. It can be a bad idea that the order of words would be the same in all languages.

_('based on %(number)s ratings', number=count)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Combined into one.

@breakbuidl
Copy link
Contributor Author

There are 4 new commits containing the requested changes and 4 commits at the base are part of db/rating_scale.

@gentlecat gentlecat changed the title CB-244: Rating system (Frontend) CB-244: Frontend for the rating system Sep 3, 2017
{{ _('<a href="%(link)s">Sign in</a> to rate this review', link=url_for('login.index', next=url_for('review.entity', id=review.id))) }}
</div>
{% else %}
<div class="col-md-5"></div>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why keep this duplicate block definition around? It might be better to just move the condition inside it.

import critiquebrainz.db.exceptions as db_exceptions

def get_avg_rating(entity_id, entity_type):
"""Retrieve avg_rating and convert rating on a scale 1-5."""
Copy link
Contributor

Choose a reason for hiding this comment

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

What's avg_rating? Average rating? There's no need to literally use variable names in docstrings.

except db_exceptions.NoDataFoundException:
avg_rating = None

return avg_rating
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of assigning a variable why not just directly return values?

@gentlecat gentlecat merged commit 078cbc2 into metabrainz:master Sep 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants