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

add Opera Add-ons support #990

Closed
wants to merge 8 commits into from
Closed

add Opera Add-ons support #990

wants to merge 8 commits into from

Conversation

perceptron8
Copy link

resolves #827

@perceptron8
Copy link
Author

Don't merge yet, please. I'm going to switch from html-soup to cheerio. I didn't know such lib exists.

@Daniel15 Daniel15 added the service-badge New or updated service badge label May 16, 2017
@Daniel15
Copy link
Member

Please let us know when this is ready for review :)

@perceptron8
Copy link
Author

It is already! :)

@perceptron8
Copy link
Author

Now it's even more ready.

@timbru31
Copy link

Nice, one step further to unified browser extensions 🎉

@perceptron8
Copy link
Author

@Daniel15 Please let me know when you are ready for review.

@Daniel15
Copy link
Member

Daniel15 commented Jun 5, 2017

Sorry for the delay, I've been pretty busy recently :( I'll try to view this soon, but someone else may get to it before I do.

Copy link
Member

@Daniel15 Daniel15 left a comment

Choose a reason for hiding this comment

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

Sorry for the delay!

server.js Outdated
try {
const cheerio = require('cheerio');
const $ = cheerio.load(buffer);
const version = $('section.about > dl > dd').eq(2).text();
Copy link
Member

Choose a reason for hiding this comment

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

This seems very unmaintainable and will break if Opera ever change their HTML even slightly. Do Opera not have an API for retrieving this data?

Copy link
Member

Choose a reason for hiding this comment

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

Something as simple as Opera switching the order of the fields in the "about the extension" section (for example, displaying "size" above "version") will break this. If you really do need to parse the HTML, it might be worth making it smarter (eg. look for the <dt> containing "Version" and then look in the <dd> directly after that)

I'd suggest pulling this out into a separate utility module (eg. lib/parseOperaExtensionPage.js) rather than putting all the code in here.

server.js Outdated
case 'rating-count':
badgeData.text[0] = data.label || 'rating-count';
badgeData.text[1] = metric(reviewCount) + ' total';
badgeData.colorscheme = floorCountColor(reviewCount, 5, 50, 500);
Copy link
Member

Choose a reason for hiding this comment

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

A lot of this code looks like it was copied and pasted from the Chrome web store implementation. Instead of copying and pasting it, could you pull it out into a reusable utility function?

@Daniel15
Copy link
Member

Please also add test cases for this. See https://github.com/badges/shields/tree/master/service-tests for instructions on how to write tests.

@perceptron8
Copy link
Author

@Daniel15 Thanks you for your comments. Give me some time, please.

@Daniel15
Copy link
Member

No worries, feel free to take as long as you like! No pressure 😄

@perceptron8
Copy link
Author

This seems very unmaintainable and will break if Opera ever change their HTML even slightly. Do Opera not have an API for retrieving this data?

There is no public API for Opera Add-ons, neither for Chrome Web Store.

Something as simple as Opera switching the order of the fields in the "about the extension" section (for example, displaying "size" above "version") will break this. If you really do need to parse the HTML, it might be worth making it smarter.

No need to worry. Tests will catch that. It's much more likely that store's layout changes completely than "size" goes above "version".

Please also add test cases for this.

Done.

I'd suggest pulling this out into a separate utility module (eg. lib/parseOperaExtensionPage.js) rather than putting all the code in here.

Parsing is just 4 lines of code. There's much more ceremony with badge construction: that's what should be improved in the first place. I'll be happy to take care of opera and chrome modules as soon as server.js becomes modular (in the sense of #948 and #963).

I did, however, some refactoring in color- and text-formatters. It was painful to replace all versionFormatter() calls but someone had to do this.

while (stars.length < rating) { stars += '★'; }
while (stars.length < 5) { stars += '☆'; }
return stars;
assert(rating >= 0);
Copy link
Member

Choose a reason for hiding this comment

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

What happens at runtime if the assertion fails?

Copy link
Author

@perceptron8 perceptron8 Jul 10, 2017

Choose a reason for hiding this comment

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

An AssertionError is thrown with a default message. No one should invoke this method with negative number. An exception signals function caller a mistake. It's fail-fast vs return garbage in / gargage out.

Copy link
Author

Choose a reason for hiding this comment

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

Also note that rounding changed from Math.ceil (implicit) to Math.round (explicit), so starRating(1.01) gives ★☆☆☆☆ instead of ★★☆☆☆.

@@ -32,6 +33,7 @@
"pdfkit": "~0.8.0",
"redis": "~2.6.2",
"request": "~2.81.0",
"request-promise": "~4.2.1",
Copy link
Member

Choose a reason for hiding this comment

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

Are you using this?

Copy link
Author

Choose a reason for hiding this comment

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

@paulmelnikow
Copy link
Member

@espadrine has argued against parsing on the server because it's resource intensive. We've said no to badges like these before, and asked that contributors approach the vendor and ask them to create an API.

This PR has a bunch of unrelated changes / refactoring. Could those be cherry-picked into a new PR?

@perceptron8
Copy link
Author

@paulmelnikow You also said yes to badges like this before, so I don't understand why this is so problematic now and it wasn't in case of Firefox and Chrome. After nearly 11 months I have no expectations really, but - at least be fair.

As for the question, I'll be happy to see that versionFormatter() is gone forever. Be my guest. Pick whatever you want.

@paulmelnikow
Copy link
Member

As far as I know I haven't merged a badge that parses web pages. I did not realize the Chrome badge used a library that uses cheerio.

I don't have a problem with it from a maintainability perspective, as integration tests can catch the problem, with the caveat that our deploy cycles can be a bit long. If there's not a performance problem I am okay with it.

@Daniel15 it sounds like you are okay with it too. @espadrine what do you think?

@paulmelnikow
Copy link
Member

I know you're frustrated about this. I apologize. There's not much else I can say, other than this (from #358 (comment)):

We need more capacity, or confidence we can buy more capacity, before we add more scrapers.

Our OpenCollective is now open, which means we can start to collect $10 donations toward this fund. If you wanted an answer to "what can you do to make this happen," it's to spread that message, far and wide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
service-badge New or updated service badge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Opera Add-ons
4 participants