Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7898ff3ff1 | |||
| 9709744b33 | |||
| 22e236a009 | |||
| 0857a9cfe7 | |||
| 30e2068b4d | |||
| 227924f098 | |||
| 201ff3d717 | |||
| 393422f964 | |||
| d9e0af7e59 | |||
| 227c3fb469 | |||
| 0378a38d87 | |||
| 5c12e06e58 | |||
| 27363e5fa7 | |||
| 8be16c34ff | |||
| 8971629bcb | |||
| 7e237c6b68 | |||
| 062904fd2a |
@@ -5,11 +5,11 @@ on: [ push, pull_request ]
|
||||
jobs:
|
||||
test:
|
||||
|
||||
name: Test on Python ${{ matrix.py_version }}
|
||||
name: Test on Python ${{ matrix.python-version }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [ "3.7", "3.8", "3.9", "3.10" ]
|
||||
python-version: [ "3.7", "3.8", "3.9", "3.10", "3.11" ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
@@ -36,3 +36,9 @@ coverage.xml
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# Pyenv
|
||||
.python-version
|
||||
|
||||
# PyCharm
|
||||
.idea
|
||||
|
||||
@@ -12,3 +12,4 @@ Karl Goetz
|
||||
Alex Kerney
|
||||
Gustav <https://github.com/dkgv>
|
||||
Sebastian2023 <https://github.com/Sebastian2023>
|
||||
Dominik George <https://github.com/Natureshadow>
|
||||
+1
-1
@@ -43,7 +43,7 @@ Or it's slightly faster cousin `detox
|
||||
|
||||
Alternatively, you can run the self test with the following commands::
|
||||
|
||||
pip install -r requirements.dev.txt
|
||||
pip install -r requirements.txt
|
||||
pip install -e .
|
||||
python setup.py test
|
||||
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
Release history
|
||||
===============
|
||||
|
||||
1.3.0
|
||||
-----
|
||||
|
||||
- Add fix for handling global Discourse timeouts
|
||||
- Add group owners
|
||||
- Update API for add_group_owner
|
||||
|
||||
1.2.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ version = attr: pydiscourse.__version__
|
||||
author = "Marc Sibson and contributors"
|
||||
author_email = "ben@benlopatin.com"
|
||||
license = "MIT"
|
||||
url = "https://github.com/bennylope/pydiscourse"
|
||||
url = https://github.com/bennylope/pydiscourse
|
||||
description = "A Python library for the Discourse API"
|
||||
long_description = file: README.rst, HISTORY.rst
|
||||
platforms =
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
"""Python client for the Discourse API."""
|
||||
|
||||
__version__ = "1.2.0"
|
||||
__version__ = "1.3.0"
|
||||
|
||||
from pydiscourse.client import DiscourseClient
|
||||
|
||||
|
||||
+52
-11
@@ -649,6 +649,21 @@ class DiscourseClient(object):
|
||||
kwargs["post_ids[]"] = post_ids
|
||||
return self._get("/t/{0}/posts.json".format(topic_id), **kwargs)
|
||||
|
||||
def latest_posts(self, before=None, **kwargs):
|
||||
"""
|
||||
List latest posts across topics
|
||||
|
||||
Args:
|
||||
before: Load posts with an id lower than this value. Useful for pagination.
|
||||
**kwargs:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
if before:
|
||||
kwargs["before"] = before
|
||||
return self._get("/posts.json", **kwargs)
|
||||
|
||||
def topic_timings(self, topic_id, time, timings={}, **kwargs):
|
||||
"""
|
||||
Set time spent reading a post
|
||||
@@ -1119,7 +1134,24 @@ class DiscourseClient(object):
|
||||
|
||||
"""
|
||||
return self._put(
|
||||
"/admin/groups/{0}/owners.json".format(groupid), usernames=username
|
||||
"/admin/groups/{0}/owners.json".format(groupid), **{"group[usernames]": username}
|
||||
)
|
||||
|
||||
def add_group_owners(self, groupid, usernames):
|
||||
"""
|
||||
Add a list of owners to a group by usernames
|
||||
|
||||
Args:
|
||||
groupid: the ID of the group
|
||||
username: the list of new owner usernames
|
||||
|
||||
Returns:
|
||||
JSON API response
|
||||
|
||||
"""
|
||||
usernames = ",".join(usernames)
|
||||
return self._put(
|
||||
"/admin/groups/{0}/owners.json".format(groupid), **{"group[usernames]": usernames}
|
||||
)
|
||||
|
||||
def delete_group_owner(self, groupid, userid):
|
||||
@@ -1544,20 +1576,29 @@ class DiscourseClient(object):
|
||||
if 400 <= response.status_code < 500:
|
||||
if 429 == response.status_code:
|
||||
# This codepath relies on wait_seconds from Discourse v2.0.0.beta3 / v1.9.3 or higher.
|
||||
rj = response.json()
|
||||
wait_delay = (
|
||||
retry_backoff + rj["extras"]["wait_seconds"]
|
||||
) # how long to back off for.
|
||||
content_type = response.headers.get("Content-Type")
|
||||
if content_type is not None and "application/json" in content_type:
|
||||
ret = response.json()
|
||||
wait_delay = (
|
||||
retry_backoff + ret["extras"]["wait_seconds"]
|
||||
) # how long to back off for.
|
||||
else:
|
||||
# We got an early 429 error without a proper JSON body
|
||||
ret = response.content
|
||||
wait_delay = retry_backoff + 10
|
||||
|
||||
limit_name = response.headers.get(
|
||||
"Discourse-Rate-Limit-Error-Code", "<unknown>")
|
||||
|
||||
log.info(
|
||||
"We have been rate limited (limit: {2}) and will wait {0} seconds ({1} retries left)".format(
|
||||
wait_delay, retry_count, limit_name
|
||||
)
|
||||
)
|
||||
if retry_count > 1:
|
||||
time.sleep(wait_delay)
|
||||
retry_count -= 1
|
||||
log.info(
|
||||
"We have been rate limited and waited {0} seconds ({1} retries left)".format(
|
||||
wait_delay, retry_count
|
||||
)
|
||||
)
|
||||
log.debug("API returned {0}".format(rj))
|
||||
log.debug("API returned {0}".format(ret))
|
||||
continue
|
||||
else:
|
||||
raise DiscourseClientError(msg, response=response)
|
||||
|
||||
@@ -182,6 +182,11 @@ class TestTopics(ClientBaseTestCase):
|
||||
@mock.patch("pydiscourse.client.requests.request")
|
||||
class MiscellaneousTests(ClientBaseTestCase):
|
||||
|
||||
def test_latest_posts(self, request):
|
||||
prepare_response(request)
|
||||
r = self.client.latest_posts(before=54321)
|
||||
self.assertRequestCalled(request, "GET", "/posts.json", before=54321)
|
||||
|
||||
def test_search(self, request):
|
||||
prepare_response(request)
|
||||
self.client.search("needle")
|
||||
|
||||
Reference in New Issue
Block a user