Add API for reviews

This commit is contained in:
rubenwardy 2021-11-24 16:33:37 +00:00
parent d0741fde6e
commit 4f69dd8d32
3 changed files with 73 additions and 1 deletions

@ -20,7 +20,8 @@ from sqlalchemy.sql.expression import func
from app import csrf from app import csrf
from app.markdown import render_markdown from app.markdown import render_markdown
from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, \
MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview
from app.querybuilder import QueryBuilder from app.querybuilder import QueryBuilder
from app.utils import is_package_page, get_int_or_abort from app.utils import is_package_page, get_int_or_abort
from . import bp from . import bp
@ -362,6 +363,21 @@ def order_screenshots(token: APIToken, package: Package):
return api_order_screenshots(token, package, request.json) return api_order_screenshots(token, package, request.json)
@bp.route("/api/packages/<author>/<name>/reviews/")
@is_package_page
@cors_allowed
def list_reviews(package):
reviews = package.reviews
return jsonify([review.getAsDictionary() for review in reviews])
@bp.route("/api/reviews/")
@cors_allowed
def list_all_reviews():
reviews = PackageReview.query.all()
return jsonify([review.getAsDictionary(True) for review in reviews])
@bp.route("/api/scores/") @bp.route("/api/scores/")
@cors_allowed @cors_allowed
def package_scores(): def package_scores():

@ -210,6 +210,42 @@ curl -X POST https://content.minetest.net/api/packages/username/name/screenshots
``` ```
## Reviews
* GET `/api/packages/<username></<name>/releases/` (List)
* Returns array of review dictionaries with keys:
* `user`: dictionary with `display_name` and `username`.
* `title`: review title
* `comment`: the text
* `is_positive`: boolean
* `created_at`: iso timestamp
* `votes`: dictionary with `helpful` and `unhelpful`,
* GET `/api/reviews/` (List)
* Above, but for all packages.
* Each review has a `package` dictionary with `type`, `author` and `name`
Example:
```json
[
{
"comment": "This is a really good mod!",
"created_at": "2021-11-24T16:18:33.764084",
"is_positive": true,
"title": "Really good",
"user": {
"display_name": "rubenwardy",
"username": "rubenwardy"
},
"votes": {
"helpful": 0,
"unhelpful": 0
}
}
]
```
## Topics ## Topics
* GET `/api/topics/` ([View](/api/topics/)): Supports [Package Queries](#package-queries), and the following two options: * GET `/api/topics/` ([View](/api/topics/)): Supports [Package Queries](#package-queries), and the following two options:

@ -168,6 +168,26 @@ class PackageReview(db.Model):
user_vote = next(filter(lambda vote: vote.user == current_user, votes), None) user_vote = next(filter(lambda vote: vote.user == current_user, votes), None)
return pos, neg, user_vote.is_positive if user_vote else None return pos, neg, user_vote.is_positive if user_vote else None
def getAsDictionary(self, include_package=False):
pos, neg, _user = self.get_totals()
ret = {
"is_positive": self.recommends,
"user": {
"username": self.author.username,
"display_name": self.author.display_name,
},
"created_at": self.created_at.isoformat(),
"votes": {
"helpful": pos,
"unhelpful": neg,
},
"title": self.thread.title,
"comment": self.thread.replies[0].comment,
}
if include_package:
ret["package"] = self.package.getAsDictionaryKey()
return ret
def asSign(self): def asSign(self):
return 1 if self.recommends else -1 return 1 if self.recommends else -1