From 380afe6a644bcfab273a1fcee0300ca9e17a1b68 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 19 May 2016 00:53:29 +0200 Subject: [PATCH 001/141] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bfda3cc..4dca078 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ python: - "3.2" - "3.3" - "3.4" + - "3.5" branches: - develop From 625e3f27aacf46dd9387d3ed24e9f4aed5b3db99 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 19 May 2016 01:31:43 +0200 Subject: [PATCH 002/141] Fix exception url --- pybooru/pybooru.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index caabbff..a5e1c2c 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -198,9 +198,10 @@ def _json_request(url, params): # Read and return JSON data return response.json() except requests.exceptions.HTTPError as err: - raise PybooruError("In _json_request", response.status_code, url) + raise PybooruError("In _json_request", response.status_code, + response.url) except requests.exceptions.Timeout as err: - raise PybooruError("Timeout! in url: {0}".format(url)) + raise PybooruError("Timeout! in url: {0}".format(response.url)) except ValueError as err: raise PybooruError("JSON Error: {0} in line {1} column {2}".format( err.msg, err.lineno, err.colno)) From 5279f5988ade3b3800d38510adf43d1c9149f723 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 20 May 2016 00:57:47 +0200 Subject: [PATCH 003/141] Start refactoring --- pybooru/api.py | 799 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 799 insertions(+) create mode 100644 pybooru/api.py diff --git a/pybooru/api.py b/pybooru/api.py new file mode 100644 index 0000000..99963ba --- /dev/null +++ b/pybooru/api.py @@ -0,0 +1,799 @@ +# -*- coding: utf-8 -*- + +"""Module contains ApiFunctions class for pybooru.""" + + +class ApiFunctions(object): + """Contains all Moebooru API calls.""" + + def posts_list(self, tags=None, limit=100, page=1): + """Get a list of posts. + + Parameters: + tags: + The tags of the posts (Default: None). + + limit: + Limit of posts. Limit is 100 posts per request (Default: 100). + + page: + The page number (Default: 1). + """ + params = {'limit': limit, 'page': page} + + if tags is not None: + params['tags'] = tags + + return self._build_request_url('posts_list', params) + + def posts_create(self, tags, file_=None, rating=None, source=None, + is_rating_locked=None, is_note_locked=None, + parent_id=None, md5=None): + """Function to create a new post. + + There are only two mandatory fields: you need to supply the tags, and + you need to supply the file, either through a multipart form or + through a source URL (Requires login)(UNTESTED). + + Parameters: + tags: + A space delimited list of tags. + + file_: + The file data encoded as a multipart form. + + rating: + The rating for the post. Can be: safe, questionable, or + explicit. + + source: + If this is a URL, Danbooru/Moebooru will download the file. + + is_rating_locked: + Set to true to prevent others from changing the rating. + + is_note_locked: + Set to true to prevent others from adding notes. + + parent_id: + The ID of the parent post. + + md5: + Supply an MD5 if you want Danbooru/Moebooru to verify the file after + uploading. If the MD5 doesn't match, the post is destroyed. + """ + params = {'post[tags]': tags} + + if source is not None or file_ is not None: + if file_ is not None: + params['post[file]'] = file_ + if source is not None: + params['post[source]'] = source + if rating is not None: + params['post[rating]'] = rating + if is_rating_locked is not None: + params['post[is_rating_locked]'] = is_rating_locked + if is_note_locked is not None: + params['post[is_note_locked]'] = is_note_locked + if parent_id is not None: + params['post[parent_id]'] = parent_id + if md5 is not None: + params['md5'] = md5 + + return self._build_request_url('posts_create', params) + else: + raise PybooruError("source or file_ is required") + + def posts_update(self, id_, tags, file_, rating, source, is_rating_locked, + is_note_locked, parent_id): + """Function update a specific post. + + Only the id_ parameter is required. Leave the other parameters blank + if you don't want to change them (Requires login)(UNESTED). + + Parameters: + id_: + The id number of the post to update (Type: INT). + + tags: + A space delimited list of tags (Type: STR). + + file_: + The file data ENCODED as a multipart form. + + rating: + The rating for the post. Can be: safe, questionable, or + explicit. + + source: + If this is a URL, Danbooru/Moebooru will download the file. + + is_rating_locked: + Set to true to prevent others from changing the rating. + + is_note_locked: + Set to true to prevent others from adding notes. + + parent_id: + The ID of the parent post. + """ + params = {'id': id_} + + if tags is not None: + params['post[tags]'] = tags + if file_ is not None: + params['post[file]'] = file_ + if rating is not None: + params['post[rating]'] = rating + if source is not None: + params['post[source]'] = source + if is_rating_locked is not None: + params['post[is_rating_locked]'] = is_rating_locked + if is_note_locked is not None: + params['post[is_note_locked]'] = is_note_locked + if parent_id is not None: + params['post[parent_id]'] = parent_id + + return self._build_request_url('posts_update', params) + + def posts_destroy(self, id_): + """Function to destroy a specific post. + + You must also be the user who uploaded the post (or you must be a + moderator) (Requires Login)(UNTESTED). + + Parameters: + id_: + The id number of the post to delete. + """ + params = {'id': id_} + response = self._build_request_url('posts_destroy', params) + return response['success'] + + def posts_revert_tags(self, id_, history_id): + """Function to reverts a post to a previous set of tags + (Requires login)(UNTESTED). + + Parameters: + id_: + The post id number to update (Type: INT). + + history_id: + The id number of the tag history. + """ + params = {'id': id_, 'history_id': history_id} + return self._build_request_url('posts_revert_tags', params) + + def posts_vote(self, id_, score): + """Action lets you vote for a post (Requires login). + + Parameters: + id_: + The post id (Type: INT). + + score: + Be can: + 0: No voted or Remove vote. + 1: Good. + 2: Great. + 3: Favorite, add post to favorites. + """ + if score <= 3: + params = {'id': id_, 'score': score} + return self._build_request_url('posts_vote', params) + else: + raise PybooruError("Value of score only can be 0, 1, 2 and 3.") + + def tags_list(self, name=None, id_=None, limit=0, page=1, order='name', + after_id=None): + """Get a list of tags. + + Parameters: + name: + The exact name of the tag. + + id_: + The id number of the tag. + + limit: + How many tags to retrieve. Setting this to 0 will return + every tag (Default value: 0). + + page: + The page number. + + order: + Can be 'date', 'name' or 'count' (Default: name). + + after_id: + Return all tags that have an id number greater than this. + """ + params = {'limit': limit, 'page': page, 'order': order} + + if id_ is not None: + params['id'] = id_ + elif name is not None: + params['name'] = name + elif after_id is not None: + params['after_id'] = after_id + return self._build_request_url('tags_list', params) + + def tags_update(self, name, tag_type, is_ambiguous): + """Action to lets you update tag (Requires login)(UNTESTED). + + Parameters: + name: + The name of the tag to update. + + tag_type: + The tag type. + General: 0. + artist: 1. + copyright: 3. + character: 4. + + is_ambiguous: + Whether or not this tag is ambiguous. Use 1 for true and 0 + for false. + """ + params = {'name': name, 'tag[tag_type]': tag_type, + 'tag[is_ambiguous]': is_ambiguous} + + return self._build_request_url('tags_update', params) + + def tags_related(self, tags, type_=None): + """Get a list of related tags. + + Parameters: + tags: + The tag names to query. + + type_: + Restrict results to this tag type. Can be general, artist, + copyright, or character (Default value: None). + """ + params = {'tags': tags} + + if type_ is not None: + params['type'] = type_ + + return self._build_request_url('tags_related', params) + + def artists_list(self, name=None, order=None, page=1): + """Get a list of artists. + + Parameters: + name: + The name (or a fragment of the name) of the artist. + + order: + Can be date or name (Default value: None). + + page: + The page number. + """ + params = {'page': page} + + if name is not None: + params['name'] = name + if order is not None: + params['order'] = order + + return self._build_request_url('artists_list', params) + + def artists_create(self, name, urls, alias, group): + """Function to create a artist (Requires login)(UNTESTED). + + Parameters: + name: + The artist's name. + + urls: + A list of URLs associated with the artist, whitespace delimited. + + alias: + The artist that this artist is an alias for. Simply enter the + alias artist's name. + + group: + The group or cicle that this artist is a member of. Simply + enter the group's name. + """ + params = {'artist[name]': name, 'artist[urls]': urls, + 'artist[alias]': alias, 'artist[group]': group} + return self._build_request_url('artists_create', params) + + def artists_update(self, id_, name=None, urls=None, alias=None, group=None): + """Function to update an artists. + + Only the id_ parameter is required. The other parameters are optional. + (Requires login)(UNTESTED). + + Parameters: + id_: + The id of thr artist to update (Type: INT). + + name: + The artist's name. + + urls: + A list of URLs associated with the artist, whitespace delimited. + + alias: + The artist that this artist is an alias for. Simply enter the + alias artist's name. + + group: + The group or cicle that this artist is a member of. Simply + enter the group's name. + """ + params = {'id': id_} + + if name is not None: + params['artist[name]'] = name + if urls is not None: + params['artist[urls]'] = urls + if alias is not None: + params['artist[alias]'] = alias + if group is not None: + params['artist[group]'] = group + + return self._build_request_url('artists_update', params) + + def artists_destroy(self, id_): + """Action to lets you remove artist (Requires login)(UNTESTED). + + Parameters: + id_: + The id of the artist to destroy (Type: INT). + """ + params = {'id': id_} + response = self._build_request_url('artists_destroy', params) + return response['success'] + + def comments_show(self, id_): + """Get a specific comment. + + Parameters: + id_: + The id number of the comment to retrieve (Type: INT). + """ + params = {'id': id_} + return self._build_request_url('comments_show', params) + + def comments_create(self, post_id, comment_body): + """Action to lets you create a comment (Requires login). + + Parameters: + post_id: + The post id number to which you are responding (Type: INT). + + comment_body: + The body of the comment. + """ + params = {'comment[post_id]': post_id, + 'comment[body]': comment_body} + response = self._build_request_url('comments_create', params) + return response['success'] + + def comments_destroy(self, id_=None): + """Remove a specific comment (Requires login). + + Parameters: + id_: + The id number of the comment to remove (Type: INT). + """ + params = {'id': id_} + response = self._build_request_url('comments_destroy', params) + return response['success'] + + def wiki_list(self, query=None, order='title', limit=100, page=1): + """Function to retrieves a list of every wiki page. + + Parameters: + query: + A word or phrase to search for (Default: None). + + order: + Can be: title, date (Default: title). + + limit: + The number of pages to retrieve (Default: 100). + + page: + The page number. + """ + params = {'order': order, 'limit': limit, 'page': page} + + if query is not None: + params['query'] = query + + return self._build_request_url('wiki_list', params) + + def wiki_create(self, title, body): + """Action to lets you create a wiki page (Requires login)(UNTESTED). + + Parameters: + title: + The title of the wiki page. + + body: + The body of the wiki page. + """ + + params = {'wiki_page[title]': str(title), 'wiki_page[body]': str(body)} + return self._build_request_url('wiki_create', params) + + def wiki_update(self, page_title, new_title, page_body): + """Action to lets you update a wiki page (Requires login)(UNTESTED). + + Parameters: + page_title: + The title of the wiki page to update. + + new_title: + The new title of the wiki page. + + page_body: + The new body of the wiki page. + """ + params = {'title': page_title, 'wiki_page[title]': new_title, + 'wiki_page[body]': page_body} + return self._build_request_url('wiki_update', params) + + def wiki_show(self, title, version=None): + """Get a specific wiki page. + + Parameters: + title: + The title of the wiki page to retrieve. + + version: + The version of the page to retrieve. + """ + params = {'title': title} + + if version is not None: + params['version'] = version + + return self._build_request_url('wiki_show', params) + + def wiki_destroy(self, title): + """Function to delete a specific wiki page (Requires login) + (Only moderators)(UNTESTED). + + Parameters: + title: + The title of the page to delete. + """ + params = {'title': title} + response = self._build_request_url('wiki_destroy', params) + return response['success'] + + def wiki_lock(self, title): + """Function to lock a specific wiki page (Requires login) + (Only moderators)(UNTESTED). + + Parameters: + title: + The title of the page to lock. + """ + params = {'title': title} + response = self._build_request_url('wiki_lock', params) + return response['success'] + + def wiki_unlock(self, title): + """Function to unlock a specific wiki page (Requires login) + (Only moderators)(UNTESTED). + + Parameters: + title: + The title of the page to unlock. + """ + params = {'title': title} + response = self._build_request_url('wiki_unlock', params) + return response['success'] + + def wiki_revert(self, title, version): + """Function to revert a specific wiki page (Requires login)(UNTESTED). + + Parameters: + title: + The title of the wiki page to update. + + version: + The version to revert to. + """ + params = {'title': title, 'version': version} + response = self._build_request_url('wiki_revert', params) + return response['success'] + + def wiki_history(self, title): + """Get history of specific wiki page. + + Parameters: + title: + The title of the wiki page to retrieve versions for. + """ + params = {'title': title} + return self._build_request_url('wiki_history', params) + + def notes_list(self, post_id=None): + """Get note list. + + Parameters: + post_id: + The post id number to retrieve notes for (Default: None) + (Type: INT). + """ + if post_id is not None: + params = {'post_id': post_id} + return self._build_request_url('notes_list', params) + else: + return self._build_request_url('notes_list') + + def notes_search(self, query): + """Search specific note. + + Parameters: + query: + A word or phrase to search for. + """ + params = {'query': query} + return self._build_request_url('notes_search', params) + + def notes_history(self, post_id=None, id_=None, limit=10, page=1): + """Get history of notes. + + Parameters: + post_id: + The post id number to retrieve note versions for. + + id_: + The note id number to retrieve versions for (Type: INT). + + limit: + How many versions to retrieve (Default: 10). + + page: + The note id number to retrieve versions for. + """ + params = {'limit': limit, 'page': page} + + if post_id is not None: + params['post_id'] = post_id + elif id_ is not None: + params['id'] = id_ + + return self._build_request_url('notes_history', params) + + def notes_revert(self, id_, version): + """Function to revert a specific note (Requires login)(UNTESTED). + + Parameters: + id_: + The note id to update (Type: INT). + + version: + The version to revert to. + """ + params = {'id': id_, 'version': version} + response = self._build_request_url('wiki_revert', params) + return response['success'] + + def notes_create_update(self, post_id, coor_x, coor_y, width, height, + is_active, body, id_=None): + """Function to create or update note (Requires login)(UNTESTED). + + Parameters: + post_id: + The post id number this note belongs to. + + coor_x: + The X coordinate of the note. + + coor_y: + The Y coordinate of the note. + + width: + The width of the note. + + height: + The height of the note. + + is_active: + Whether or not the note is visible. Set to 1 for active, 0 for + inactive. + + body: + The note message. + + id_: + If you are updating a note, this is the note id number to + update. + """ + params = {'note[post_id]': post_id, 'note[x]': coor_x, + 'note[y]': coor_y, 'note[width]': width, + 'note[height]': height, 'note[body]': body} + + if id_ is not None: + params['id'] = id_ + if is_active <= 1: + params['note[is_active]'] = is_active + else: + raise PybooruError("is_active parameters required 1 or 0") + + return self._build_request_url('notes_create_update', params) + + def users_search(self, name=None, id_=None): + """Search users. + + If you don't specify any parameters you'll get a listing of all users. + + Parameters: + name: + The name of the user. + + id_: + The id number of the user. + """ + if name is not None: + params = {'name': name} + return self._build_request_url('users_search', params) + elif id_ is not None: + params = {'id': id_} + return self._build_request_url('users_search', params) + else: + return self._build_request_url('users_search') + + def forum_list(self, parent_id=None): + """Function to get forum posts. + + If you don't specify any parameters you'll get a listing of all users. + + Parameters: + parent_id: + The parent ID number. You'll return all the responses to that + forum post. + """ + if parent_id is not None: + params = {'parent_id': parent_id} + return self._build_request_url('forum_list', params) + else: + return self._build_request_url('forum_list') + + def pools_list(self, query=None, page=1): + """Function to get pools. + + If you don't specify any parameters you'll get a list of all pools. + + Parameters: + query: + The title. + + page: + The page. + """ + params = {'page': page} + + if query is not None: + params['query'] = query + + return self._build_request_url('pools_list', params) + + def pools_posts(self, id_=None, page=1): + """Function to get pools posts. + + If you don't specify any parameters you'll get a list of all pools. + + Parameters: + id_: + The pool id number. + + page: + The page. + """ + params = {'page': page} + + if id_ is not None: + params['id'] = id_ + + return self._build_request_url('pools_posts', params) + + def pools_update(self, id_, name, is_public, description): + """Function to update a pool (Requires login)(UNTESTED). + + Parameters: + id_: + The pool id number. + + name: + The name. + + is_public: + 1 or 0, whether or not the pool is public. + + description: + A description of the pool. + """ + params = {'id': id_, 'pool[name]': name, + 'pool[description]': description} + + if is_public <= 1: + params['pool[is_public]'] = is_public + else: + raise PybooruError("is_public require 1 or 0") + + return self._build_request_url('pools_update', params) + + def pools_create(self, name, is_public, description): + """Function to create a pool (Require login)(UNTESTED). + + Parameters: + name: + The name. + + is_public: + 1 or 0, whether or not the pool is public. + + description: + A description of the pool. + """ + params = {'pool[name]': name, 'pool[description]': description} + + if is_public <= 1: + params['pool[name]'] = is_public + else: + raise PybooruError("is_public required 1 or 0") + + return self._build_request_url('pools_create', params) + + def pools_destroy(self, id_): + """Function to destroy a specific pool (Require login)(UNTESTED). + + Parameters: + id_: + The pool id number (Type: INT). + """ + params = {'id': id_} + response = self._build_request_url('pools_destroy', params) + return response['success'] + + def pools_add_post(self, pool_id, post_id): + """Function to add a post (Require login)(UNTESTED). + + Parameters: + pool_id: + The pool to add the post to. + + post_id: + The post to add. + """ + params = {'pool_id': pool_id, 'post_id': post_id} + return self._build_request_url('pools_add_post', params) + + def pools_remove_post(self, pool_id, post_id): + """Function to remove a post (Require login)(UNTESTED). + + Parameters: + pool_id: + The pool to remove the post to. + + post_id: + The post to remove. + """ + params = {'pool_id': pool_id, 'post_id': post_id} + return self._build_request_url('pools_remove_post', params) + + def favorites_list_users(self, id_): + """Function to return a list with all users who have added to favorites + a specific post. + + Parameters: + id_: + The post id (Type: INT). + """ + params = {'id': id_} + response = self._build_request_url('favorites_list_users', params) + # Return list with users + return response['favorited_users'].split(',') From cfaf5e0b60d9fcf12738135141d81ba9c96b4e3b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 20 May 2016 08:09:44 +0200 Subject: [PATCH 004/141] Testing ApiFunctionsMixin --- pybooru/api.py | 2 +- pybooru/pybooru.py | 799 +-------------------------------------------- 2 files changed, 4 insertions(+), 797 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index 99963ba..3021116 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -3,7 +3,7 @@ """Module contains ApiFunctions class for pybooru.""" -class ApiFunctions(object): +class ApiFunctionsMixin(object): """Contains all Moebooru API calls.""" def posts_list(self, tags=None, limit=100, page=1): diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index a5e1c2c..c3bf9f1 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -6,9 +6,9 @@ from __future__ import absolute_import from __future__ import unicode_literals -# pyborru exceptions imports +# pyborru imports +from .api import ApiFunctionsMixin from .exceptions import PybooruError -# pybooru resources imports from .resources import (API_BASE_URL, SITE_LIST) # requests imports @@ -21,7 +21,7 @@ import re -class Pybooru(object): +class Pybooru(ApiFunctionsMixin, object): """Pybooru main class. To initialize Pybooru, you need to specify one of these two @@ -205,796 +205,3 @@ def _json_request(url, params): except ValueError as err: raise PybooruError("JSON Error: {0} in line {1} column {2}".format( err.msg, err.lineno, err.colno)) - - def posts_list(self, tags=None, limit=100, page=1): - """Get a list of posts. - - Parameters: - tags: - The tags of the posts (Default: None). - - limit: - Limit of posts. Limit is 100 posts per request (Default: 100). - - page: - The page number (Default: 1). - """ - params = {'limit': limit, 'page': page} - - if tags is not None: - params['tags'] = tags - - return self._build_request_url('posts_list', params) - - def posts_create(self, tags, file_=None, rating=None, source=None, - is_rating_locked=None, is_note_locked=None, - parent_id=None, md5=None): - """Function to create a new post. - - There are only two mandatory fields: you need to supply the tags, and - you need to supply the file, either through a multipart form or - through a source URL (Requires login)(UNTESTED). - - Parameters: - tags: - A space delimited list of tags. - - file_: - The file data encoded as a multipart form. - - rating: - The rating for the post. Can be: safe, questionable, or - explicit. - - source: - If this is a URL, Danbooru/Moebooru will download the file. - - is_rating_locked: - Set to true to prevent others from changing the rating. - - is_note_locked: - Set to true to prevent others from adding notes. - - parent_id: - The ID of the parent post. - - md5: - Supply an MD5 if you want Danbooru/Moebooru to verify the file after - uploading. If the MD5 doesn't match, the post is destroyed. - """ - params = {'post[tags]': tags} - - if source is not None or file_ is not None: - if file_ is not None: - params['post[file]'] = file_ - if source is not None: - params['post[source]'] = source - if rating is not None: - params['post[rating]'] = rating - if is_rating_locked is not None: - params['post[is_rating_locked]'] = is_rating_locked - if is_note_locked is not None: - params['post[is_note_locked]'] = is_note_locked - if parent_id is not None: - params['post[parent_id]'] = parent_id - if md5 is not None: - params['md5'] = md5 - - return self._build_request_url('posts_create', params) - else: - raise PybooruError("source or file_ is required") - - def posts_update(self, id_, tags, file_, rating, source, is_rating_locked, - is_note_locked, parent_id): - """Function update a specific post. - - Only the id_ parameter is required. Leave the other parameters blank - if you don't want to change them (Requires login)(UNESTED). - - Parameters: - id_: - The id number of the post to update (Type: INT). - - tags: - A space delimited list of tags (Type: STR). - - file_: - The file data ENCODED as a multipart form. - - rating: - The rating for the post. Can be: safe, questionable, or - explicit. - - source: - If this is a URL, Danbooru/Moebooru will download the file. - - is_rating_locked: - Set to true to prevent others from changing the rating. - - is_note_locked: - Set to true to prevent others from adding notes. - - parent_id: - The ID of the parent post. - """ - params = {'id': id_} - - if tags is not None: - params['post[tags]'] = tags - if file_ is not None: - params['post[file]'] = file_ - if rating is not None: - params['post[rating]'] = rating - if source is not None: - params['post[source]'] = source - if is_rating_locked is not None: - params['post[is_rating_locked]'] = is_rating_locked - if is_note_locked is not None: - params['post[is_note_locked]'] = is_note_locked - if parent_id is not None: - params['post[parent_id]'] = parent_id - - return self._build_request_url('posts_update', params) - - def posts_destroy(self, id_): - """Function to destroy a specific post. - - You must also be the user who uploaded the post (or you must be a - moderator) (Requires Login)(UNTESTED). - - Parameters: - id_: - The id number of the post to delete. - """ - params = {'id': id_} - response = self._build_request_url('posts_destroy', params) - return response['success'] - - def posts_revert_tags(self, id_, history_id): - """Function to reverts a post to a previous set of tags - (Requires login)(UNTESTED). - - Parameters: - id_: - The post id number to update (Type: INT). - - history_id: - The id number of the tag history. - """ - params = {'id': id_, 'history_id': history_id} - return self._build_request_url('posts_revert_tags', params) - - def posts_vote(self, id_, score): - """Action lets you vote for a post (Requires login). - - Parameters: - id_: - The post id (Type: INT). - - score: - Be can: - 0: No voted or Remove vote. - 1: Good. - 2: Great. - 3: Favorite, add post to favorites. - """ - if score <= 3: - params = {'id': id_, 'score': score} - return self._build_request_url('posts_vote', params) - else: - raise PybooruError("Value of score only can be 0, 1, 2 and 3.") - - def tags_list(self, name=None, id_=None, limit=0, page=1, order='name', - after_id=None): - """Get a list of tags. - - Parameters: - name: - The exact name of the tag. - - id_: - The id number of the tag. - - limit: - How many tags to retrieve. Setting this to 0 will return - every tag (Default value: 0). - - page: - The page number. - - order: - Can be 'date', 'name' or 'count' (Default: name). - - after_id: - Return all tags that have an id number greater than this. - """ - params = {'limit': limit, 'page': page, 'order': order} - - if id_ is not None: - params['id'] = id_ - elif name is not None: - params['name'] = name - elif after_id is not None: - params['after_id'] = after_id - - return self._build_request_url('tags_list', params) - - def tags_update(self, name, tag_type, is_ambiguous): - """Action to lets you update tag (Requires login)(UNTESTED). - - Parameters: - name: - The name of the tag to update. - - tag_type: - The tag type. - General: 0. - artist: 1. - copyright: 3. - character: 4. - - is_ambiguous: - Whether or not this tag is ambiguous. Use 1 for true and 0 - for false. - """ - params = {'name': name, 'tag[tag_type]': tag_type, - 'tag[is_ambiguous]': is_ambiguous} - - return self._build_request_url('tags_update', params) - - def tags_related(self, tags, type_=None): - """Get a list of related tags. - - Parameters: - tags: - The tag names to query. - - type_: - Restrict results to this tag type. Can be general, artist, - copyright, or character (Default value: None). - """ - params = {'tags': tags} - - if type_ is not None: - params['type'] = type_ - - return self._build_request_url('tags_related', params) - - def artists_list(self, name=None, order=None, page=1): - """Get a list of artists. - - Parameters: - name: - The name (or a fragment of the name) of the artist. - - order: - Can be date or name (Default value: None). - - page: - The page number. - """ - params = {'page': page} - - if name is not None: - params['name'] = name - if order is not None: - params['order'] = order - - return self._build_request_url('artists_list', params) - - def artists_create(self, name, urls, alias, group): - """Function to create a artist (Requires login)(UNTESTED). - - Parameters: - name: - The artist's name. - - urls: - A list of URLs associated with the artist, whitespace delimited. - - alias: - The artist that this artist is an alias for. Simply enter the - alias artist's name. - - group: - The group or cicle that this artist is a member of. Simply - enter the group's name. - """ - params = {'artist[name]': name, 'artist[urls]': urls, - 'artist[alias]': alias, 'artist[group]': group} - return self._build_request_url('artists_create', params) - - def artists_update(self, id_, name=None, urls=None, alias=None, group=None): - """Function to update an artists. - - Only the id_ parameter is required. The other parameters are optional. - (Requires login)(UNTESTED). - - Parameters: - id_: - The id of thr artist to update (Type: INT). - - name: - The artist's name. - - urls: - A list of URLs associated with the artist, whitespace delimited. - - alias: - The artist that this artist is an alias for. Simply enter the - alias artist's name. - - group: - The group or cicle that this artist is a member of. Simply - enter the group's name. - """ - params = {'id': id_} - - if name is not None: - params['artist[name]'] = name - if urls is not None: - params['artist[urls]'] = urls - if alias is not None: - params['artist[alias]'] = alias - if group is not None: - params['artist[group]'] = group - - return self._build_request_url('artists_update', params) - - def artists_destroy(self, id_): - """Action to lets you remove artist (Requires login)(UNTESTED). - - Parameters: - id_: - The id of the artist to destroy (Type: INT). - """ - params = {'id': id_} - response = self._build_request_url('artists_destroy', params) - return response['success'] - - def comments_show(self, id_): - """Get a specific comment. - - Parameters: - id_: - The id number of the comment to retrieve (Type: INT). - """ - params = {'id': id_} - return self._build_request_url('comments_show', params) - - def comments_create(self, post_id, comment_body): - """Action to lets you create a comment (Requires login). - - Parameters: - post_id: - The post id number to which you are responding (Type: INT). - - comment_body: - The body of the comment. - """ - params = {'comment[post_id]': post_id, - 'comment[body]': comment_body} - response = self._build_request_url('comments_create', params) - return response['success'] - - def comments_destroy(self, id_=None): - """Remove a specific comment (Requires login). - - Parameters: - id_: - The id number of the comment to remove (Type: INT). - """ - params = {'id': id_} - response = self._build_request_url('comments_destroy', params) - return response['success'] - - def wiki_list(self, query=None, order='title', limit=100, page=1): - """Function to retrieves a list of every wiki page. - - Parameters: - query: - A word or phrase to search for (Default: None). - - order: - Can be: title, date (Default: title). - - limit: - The number of pages to retrieve (Default: 100). - - page: - The page number. - """ - params = {'order': order, 'limit': limit, 'page': page} - - if query is not None: - params['query'] = query - - return self._build_request_url('wiki_list', params) - - def wiki_create(self, title, body): - """Action to lets you create a wiki page (Requires login)(UNTESTED). - - Parameters: - title: - The title of the wiki page. - - body: - The body of the wiki page. - """ - - params = {'wiki_page[title]': str(title), 'wiki_page[body]': str(body)} - return self._build_request_url('wiki_create', params) - - def wiki_update(self, page_title, new_title, page_body): - """Action to lets you update a wiki page (Requires login)(UNTESTED). - - Parameters: - page_title: - The title of the wiki page to update. - - new_title: - The new title of the wiki page. - - page_body: - The new body of the wiki page. - """ - params = {'title': page_title, 'wiki_page[title]': new_title, - 'wiki_page[body]': page_body} - return self._build_request_url('wiki_update', params) - - def wiki_show(self, title, version=None): - """Get a specific wiki page. - - Parameters: - title: - The title of the wiki page to retrieve. - - version: - The version of the page to retrieve. - """ - params = {'title': title} - - if version is not None: - params['version'] = version - - return self._build_request_url('wiki_show', params) - - def wiki_destroy(self, title): - """Function to delete a specific wiki page (Requires login) - (Only moderators)(UNTESTED). - - Parameters: - title: - The title of the page to delete. - """ - params = {'title': title} - response = self._build_request_url('wiki_destroy', params) - return response['success'] - - def wiki_lock(self, title): - """Function to lock a specific wiki page (Requires login) - (Only moderators)(UNTESTED). - - Parameters: - title: - The title of the page to lock. - """ - params = {'title': title} - response = self._build_request_url('wiki_lock', params) - return response['success'] - - def wiki_unlock(self, title): - """Function to unlock a specific wiki page (Requires login) - (Only moderators)(UNTESTED). - - Parameters: - title: - The title of the page to unlock. - """ - params = {'title': title} - response = self._build_request_url('wiki_unlock', params) - return response['success'] - - def wiki_revert(self, title, version): - """Function to revert a specific wiki page (Requires login)(UNTESTED). - - Parameters: - title: - The title of the wiki page to update. - - version: - The version to revert to. - """ - params = {'title': title, 'version': version} - response = self._build_request_url('wiki_revert', params) - return response['success'] - - def wiki_history(self, title): - """Get history of specific wiki page. - - Parameters: - title: - The title of the wiki page to retrieve versions for. - """ - params = {'title': title} - return self._build_request_url('wiki_history', params) - - def notes_list(self, post_id=None): - """Get note list. - - Parameters: - post_id: - The post id number to retrieve notes for (Default: None) - (Type: INT). - """ - if post_id is not None: - params = {'post_id': post_id} - return self._build_request_url('notes_list', params) - else: - return self._build_request_url('notes_list') - - def notes_search(self, query): - """Search specific note. - - Parameters: - query: - A word or phrase to search for. - """ - params = {'query': query} - return self._build_request_url('notes_search', params) - - def notes_history(self, post_id=None, id_=None, limit=10, page=1): - """Get history of notes. - - Parameters: - post_id: - The post id number to retrieve note versions for. - - id_: - The note id number to retrieve versions for (Type: INT). - - limit: - How many versions to retrieve (Default: 10). - - page: - The note id number to retrieve versions for. - """ - params = {'limit': limit, 'page': page} - - if post_id is not None: - params['post_id'] = post_id - elif id_ is not None: - params['id'] = id_ - - return self._build_request_url('notes_history', params) - - def notes_revert(self, id_, version): - """Function to revert a specific note (Requires login)(UNTESTED). - - Parameters: - id_: - The note id to update (Type: INT). - - version: - The version to revert to. - """ - params = {'id': id_, 'version': version} - response = self._build_request_url('wiki_revert', params) - return response['success'] - - def notes_create_update(self, post_id, coor_x, coor_y, width, height, - is_active, body, id_=None): - """Function to create or update note (Requires login)(UNTESTED). - - Parameters: - post_id: - The post id number this note belongs to. - - coor_x: - The X coordinate of the note. - - coor_y: - The Y coordinate of the note. - - width: - The width of the note. - - height: - The height of the note. - - is_active: - Whether or not the note is visible. Set to 1 for active, 0 for - inactive. - - body: - The note message. - - id_: - If you are updating a note, this is the note id number to - update. - """ - params = {'note[post_id]': post_id, 'note[x]': coor_x, - 'note[y]': coor_y, 'note[width]': width, - 'note[height]': height, 'note[body]': body} - - if id_ is not None: - params['id'] = id_ - if is_active <= 1: - params['note[is_active]'] = is_active - else: - raise PybooruError("is_active parameters required 1 or 0") - - return self._build_request_url('notes_create_update', params) - - def users_search(self, name=None, id_=None): - """Search users. - - If you don't specify any parameters you'll get a listing of all users. - - Parameters: - name: - The name of the user. - - id_: - The id number of the user. - """ - if name is not None: - params = {'name': name} - return self._build_request_url('users_search', params) - elif id_ is not None: - params = {'id': id_} - return self._build_request_url('users_search', params) - else: - return self._build_request_url('users_search') - - def forum_list(self, parent_id=None): - """Function to get forum posts. - - If you don't specify any parameters you'll get a listing of all users. - - Parameters: - parent_id: - The parent ID number. You'll return all the responses to that - forum post. - """ - if parent_id is not None: - params = {'parent_id': parent_id} - return self._build_request_url('forum_list', params) - else: - return self._build_request_url('forum_list') - - def pools_list(self, query=None, page=1): - """Function to get pools. - - If you don't specify any parameters you'll get a list of all pools. - - Parameters: - query: - The title. - - page: - The page. - """ - params = {'page': page} - - if query is not None: - params['query'] = query - - return self._build_request_url('pools_list', params) - - def pools_posts(self, id_=None, page=1): - """Function to get pools posts. - - If you don't specify any parameters you'll get a list of all pools. - - Parameters: - id_: - The pool id number. - - page: - The page. - """ - params = {'page': page} - - if id_ is not None: - params['id'] = id_ - - return self._build_request_url('pools_posts', params) - - def pools_update(self, id_, name, is_public, description): - """Function to update a pool (Requires login)(UNTESTED). - - Parameters: - id_: - The pool id number. - - name: - The name. - - is_public: - 1 or 0, whether or not the pool is public. - - description: - A description of the pool. - """ - params = {'id': id_, 'pool[name]': name, - 'pool[description]': description} - - if is_public <= 1: - params['pool[is_public]'] = is_public - else: - raise PybooruError("is_public require 1 or 0") - - return self._build_request_url('pools_update', params) - - def pools_create(self, name, is_public, description): - """Function to create a pool (Require login)(UNTESTED). - - Parameters: - name: - The name. - - is_public: - 1 or 0, whether or not the pool is public. - - description: - A description of the pool. - """ - params = {'pool[name]': name, 'pool[description]': description} - - if is_public <= 1: - params['pool[name]'] = is_public - else: - raise PybooruError("is_public required 1 or 0") - - return self._build_request_url('pools_create', params) - - def pools_destroy(self, id_): - """Function to destroy a specific pool (Require login)(UNTESTED). - - Parameters: - id_: - The pool id number (Type: INT). - """ - params = {'id': id_} - response = self._build_request_url('pools_destroy', params) - return response['success'] - - def pools_add_post(self, pool_id, post_id): - """Function to add a post (Require login)(UNTESTED). - - Parameters: - pool_id: - The pool to add the post to. - - post_id: - The post to add. - """ - params = {'pool_id': pool_id, 'post_id': post_id} - return self._build_request_url('pools_add_post', params) - - def pools_remove_post(self, pool_id, post_id): - """Function to remove a post (Require login)(UNTESTED). - - Parameters: - pool_id: - The pool to remove the post to. - - post_id: - The post to remove. - """ - params = {'pool_id': pool_id, 'post_id': post_id} - return self._build_request_url('pools_remove_post', params) - - def favorites_list_users(self, id_): - """Function to return a list with all users who have added to favorites - a specific post. - - Parameters: - id_: - The post id (Type: INT). - """ - params = {'id': id_} - response = self._build_request_url('favorites_list_users', params) - # Return list with users - return response['favorited_users'].split(',') From 1c22160becd0b81e1e6cae30617608e51b713906 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 20 May 2016 09:03:24 +0200 Subject: [PATCH 005/141] Import PybooruError into api module --- pybooru/__init__.py | 12 +++++++++--- pybooru/api.py | 5 +++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pybooru/__init__.py b/pybooru/__init__.py index ffc65df..847e0ca 100644 --- a/pybooru/__init__.py +++ b/pybooru/__init__.py @@ -1,12 +1,18 @@ # -*- coding: utf-8 -*- """ -Pybooru. --------- +Pybooru +------- Pybooru is a Python library to access API of Danbooru/Moebooru based sites. - Under MIT license. + +Pybooru requires "requests" package to work. + +Pybooru modules: + pybooru -- Main module of Pybooru, contains Pybooru class. + api -- Contains all Moebooru/Danbooru API functions. + exceptions -- Manages and builds Pybooru errors messages. """ __author__ = "Daniel Luque " diff --git a/pybooru/api.py b/pybooru/api.py index 3021116..147202b 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -2,6 +2,11 @@ """Module contains ApiFunctions class for pybooru.""" +from __future__ import absolute_import +from __future__ import unicode_literals + +from .exceptions import PybooruError + class ApiFunctionsMixin(object): """Contains all Moebooru API calls.""" From bec936152f7f5055e29004acd6cca02b8bdb86dd Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 23 May 2016 21:44:19 +0200 Subject: [PATCH 006/141] Refactoring pybooru.py --- pybooru/pybooru.py | 204 ++++++++++++++++++--------------------------- 1 file changed, 83 insertions(+), 121 deletions(-) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index c3bf9f1..2f8c40f 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -1,6 +1,13 @@ # -*- coding: utf-8 -*- -"""This module contains pybooru object class.""" +"""pybooru.pybooru + +This module contains pybooru main class for access to API calls, +authentication, build urls and return JSON response. + +Classes: + Pybooru -- Main pybooru classs, define Pybooru objectself. +""" # __furute__ imports from __future__ import absolute_import @@ -11,13 +18,9 @@ from .exceptions import PybooruError from .resources import (API_BASE_URL, SITE_LIST) -# requests imports +# External imports import requests - -# hashlib imports import hashlib - -# re imports import re @@ -25,47 +28,40 @@ class Pybooru(ApiFunctionsMixin, object): """Pybooru main class. To initialize Pybooru, you need to specify one of these two - parameters: site_name or site_url. If you specify site_name, Pybooru checks - whether there is in the list of default sites (You can get list of sites in - the resources module). + parameters: 'site_name' or 'site_url'. If you specify 'site_name', Pybooru + checks whether there is in the list of default sites (You can get list + of sites in the 'resources' module). - To specify a site that isn't in list of default sites, you need use site_url - parameter. + To specify a site that isn't in list of default sites, you need use + 'site_url' parameter and specify url. Some actions may require you to log in. always specify three parameters to - log in: hash_string, username and password. Default sites has an associate - hash string. - - Init Parameters: - site_name (Type STR): - The site name in SITE_LIST, default sites. - - site_url (Type STR): - URL of based on Danbooru/Moebooru sites. - - hash_string (Type STR): - String that is hashed (required to login). - (See the API documentation of the site for more information). - - username (Type STR): - Your username of the site - (Required only for functions that modify the content). - - password (Type STR): - Your user password in plain text - (Required only for functions that modify the content). + log in: 'hash_string', 'username' and 'password'. Default sites has an + associate hash string. Attributes: site_name: Return site name. - site_url: Return URL of based danbooru/Moebooru site. + site_url: Return the URL of Danbooru/Moebooru based site. username: Return user name. password: Return password in plain text. - hash_string: Return hash_string. + hash_string: Return hash_string of the site. """ def __init__(self, site_name="", site_url="", username="", password="", hash_string=""): - + """Initialize Pybooru. + + Keyword arguments: + site_name: The site name in 'SITE_LIST', default sites. + site_url: URL of on Danbooru/Moebooru based sites. + hash_string: String that is hashed (required to login). + (See the API documentation of the site for more + information). + username: Your username of the site (Required only for functions that + modify the content). + password: Your user password in plain text (Required only for functions + that modify the content). + """ # Attributes self.site_name = site_name.lower() self.site_url = site_url.lower() @@ -74,36 +70,26 @@ def __init__(self, site_name="", site_url="", username="", password="", self.hash_string = hash_string # Validate site_name or site_url - if site_url is not "" or site_name is not "": + if site_url or site_name is not "": if site_name is not "": - self._site_name_validator(self.site_name) + self._site_name_validator() elif site_url is not "": - self._url_validator(self.site_url) + self._url_validator() else: raise PybooruError("Unexpected empty strings," - " specify parameter site_name or site_url.") - - def _site_name_validator(self, site_name): - """Function that checks the site name and get the url. + " specify parameter 'site_name' or 'site_url'.") - Parameters: - site_name (Type STR): - The name of a based Danbooru/Moebooru site. You can get list - of sites in the resources module. - """ + def _site_name_validator(self): + """Function that checks the site name and get url.""" if site_name in list(SITE_LIST.keys()): - self.site_url = SITE_LIST[site_name]['url'] + self.site_url = SITE_LIST[self.site_name]['url'] + self.hash_string = SITE_LIST[self.site_name]['hashed_string'] else: raise PybooruError( - "The site name is not valid, use the site_url parameter") - - def _url_validator(self, url): - """URL validator for site_url parameter of Pybooru. + "The site_name is not valid, specify a valid site_name") - Parameters: - url (Type STR): - The URL to validate. - """ + def _url_validator(self): + """URL validator for site_url attribute.""" # Regular expression to URL validate regex = re.compile( r'^(?:http|https)://' # Scheme only HTTP/HTTPS @@ -116,83 +102,59 @@ def _url_validator(self, url): r'(?:/?|[/?]\S+)$', re.IGNORECASE) # Validate URL - if re.match('^(?:http|https)://', url): - if re.search(regex, url): - self.site_url = url - else: - raise PybooruError("Invalid URL", url=url) + if re.match('^(?:http|https)://', self.site_url): + if not re.search(regex, self.site_url): + raise PybooruError("Invalid URL", url=self.site_url) else: - raise PybooruError("Invalid URL scheme, use HTTP or HTTPS", url=url) - - def _build_request_url(self, api_name, params=None): - """Function for build url. - - Parameters: - api_name: - The NAME of the API function. - - params (Default: None): - The parameters of the API function. - """ - if params is None: - params = {} - - # Create url - url = self.site_url + API_BASE_URL[api_name]['url'] + raise PybooruError("Invalid URL scheme, use HTTP or HTTPS", + url=self.site_url) + def _build_hash_string(self): + """Function for build password hash string.""" # Build AUTENTICATION hash_string # Check if hash_string exists - if API_BASE_URL[api_name]['required_login'] is True: - if self.site_name in list(SITE_LIST.keys()) or \ - self.hash_string is not "": - - # Check if the username and password are empty - if self.username is not "" and self.password is not "": - # Set username login parameter - params['login'] = self.username - - # Create hashed string - if self.hash_string is not "": - try: - hash_string = self.hash_string.format(self.password) - except TypeError: - raise PybooruError(r"Use \{0\} in hash_string") - else: - hash_string = SITE_LIST[self.site_name]['hashed_string'].format(self.password) - - # Set password_hash parameter - # Convert hashed_string to SHA1 and return hex string - params['password_hash'] = hashlib.sha1( # pylint: disable=E1101 - hash_string).hexdigest() - else: - raise PybooruError("Specify the username and password " - "parameter of the Pybooru object, for " - "setting password_hash attribute.") + if self.site_name in list(SITE_LIST.keys()) or \ + self.hash_string is not "": + if self.username and self.password is not "": + try: + hash_string = self.hash_string.format(self.password) + except TypeError: + raise PybooruError("Pybooru can't add 'password' " + "to 'hash_string'") + # encrypt hashed_string to SHA1 and return hexdigest string + self.hash_string = hashlib.sha1( # pylint: disable=E1101 + hash_string.encode('utf-8')).hexdigest() else: - raise PybooruError( - "Specify the hash_string parameter of the Pybooru" - " object, for the functions which require login.") - - return self._json_request(url, params) + raise PybooruError("Specify the 'username' and 'password' " + "parameters of the Pybooru object, for " + "setting 'password_hash' attribute.") + else: + raise PybooruError( + "Specify the 'hash_string' parameter of the Pybooru" + " object, for the functions that requires login.") - @staticmethod - def _json_request(url, params): - """Function to read and returning JSON response. + def _request(self, api_call, params, method='GET'): + """Function to request and returning JSON data. Parameters: - url: - API function url. - - params: - API function parameters. + api_call: API function to be called. + params: API function parameters. + method: (Defauld: GET) HTTP method 'GET' or 'POST' """ - # Header + # Build url + url = "{0}/{1}.json".format(self.site_url, api_call) + headers = {'content-type': 'application/json; charset=utf-8'} try: - # Request - response = requests.post(url, params=params, headers=headers, - timeout=60) + if method is 'GET': + response = requests.get(url, params=params, headers=headers, + timeout=60) + else: + if self.hash_string is "": + self._build_hash_string() + response = requests.post(url, params=params, headers=headers, + timeout=60) # Enable raise status error response.raise_for_status() # Read and return JSON data From 93e4b9592556158f5f569b397a4fc94f1c0e2d7a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 29 May 2016 17:00:52 +0200 Subject: [PATCH 007/141] Refactoring api.py --- provisional_test.py | 2 +- pybooru/api.py | 859 ++++++++++++++++---------------------------- pybooru/pybooru.py | 16 +- 3 files changed, 325 insertions(+), 552 deletions(-) diff --git a/provisional_test.py b/provisional_test.py index b1e70f4..d6bc815 100644 --- a/provisional_test.py +++ b/provisional_test.py @@ -4,4 +4,4 @@ # client = Pybooru(site_url='konachan.com') client = Pybooru(site_url="http://www.konachan.com") -tags = client.tags_list(None, None, 100, 0, 'date') +tags = client.tag_list(order='date') diff --git a/pybooru/api.py b/pybooru/api.py index 147202b..cd7171e 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -1,6 +1,12 @@ # -*- coding: utf-8 -*- -"""Module contains ApiFunctions class for pybooru.""" +"""pybooru.api + +This module contains all API calls of Danbooru/Moebooru for Pybooru. + +Classes: + ApiFunctionsMixin -- Contains all API calls. +""" from __future__ import absolute_import from __future__ import unicode_literals @@ -9,121 +15,90 @@ class ApiFunctionsMixin(object): - """Contains all Moebooru API calls.""" + """Contains all Danbooru/Moebooru API calls. + + API Version: 1.13.0+update.3 + doc: http://konachan.com/help/api or https://yande.re/help/api + """ - def posts_list(self, tags=None, limit=100, page=1): + def post_list(self, **params): """Get a list of posts. Parameters: - tags: - The tags of the posts (Default: None). - - limit: - Limit of posts. Limit is 100 posts per request (Default: 100). - - page: - The page number (Default: 1). + tags: The tags to search for. Any tag combination that works on the + web site will work here. This includes all the meta-tags. + limit: How many posts you want to retrieve. There is a limit of 100 + posts per request. + page: The page number. """ - params = {'limit': limit, 'page': page} + return self._request('post', params) - if tags is not None: - params['tags'] = tags - - return self._build_request_url('posts_list', params) - - def posts_create(self, tags, file_=None, rating=None, source=None, - is_rating_locked=None, is_note_locked=None, - parent_id=None, md5=None): + def post_create(self, tags, file_=None, rating=None, source=None, + rating_locked=None, note_locked=None, parent_id=None, + md5=None): """Function to create a new post. - There are only two mandatory fields: you need to supply the tags, and - you need to supply the file, either through a multipart form or - through a source URL (Requires login)(UNTESTED). - - Parameters: - tags: - A space delimited list of tags. - - file_: - The file data encoded as a multipart form. - - rating: - The rating for the post. Can be: safe, questionable, or - explicit. - - source: - If this is a URL, Danbooru/Moebooru will download the file. - - is_rating_locked: - Set to true to prevent others from changing the rating. - - is_note_locked: - Set to true to prevent others from adding notes. - - parent_id: - The ID of the parent post. - - md5: - Supply an MD5 if you want Danbooru/Moebooru to verify the file after - uploading. If the MD5 doesn't match, the post is destroyed. + There are only two mandatory fields: you need to supply the + 'post[tags]', and you need to supply the 'post[file]', either through a + multipart form or through a source URL (Requires login) (UNTESTED). + + Parameters: + tags: A space delimited list of tags. + file_: The file data encoded as a multipart form. + rating: The rating for the post. Can be: safe, questionable, + or explicit. + source: If this is a URL, Danbooru/Moebooru will download the + file. + rating_locked: Set to true to prevent others from changing + the rating. + note_locked: Set to true to prevent others from adding + notes. + parent_id: The ID of the parent post. + md5: Supply an MD5 if you want Danbooru/Moebooru to verify the file + after uploading. If the MD5 doesn't match, the post is + destroyed. """ params = {'post[tags]': tags} - - if source is not None or file_ is not None: + if file_ or source is not None: if file_ is not None: params['post[file]'] = file_ if source is not None: params['post[source]'] = source if rating is not None: params['post[rating]'] = rating - if is_rating_locked is not None: - params['post[is_rating_locked]'] = is_rating_locked - if is_note_locked is not None: - params['post[is_note_locked]'] = is_note_locked + if rating_locked is not None: + params['post[is_rating_locked]'] = rating_locked + if note_locked is not None: + params['post[is_note_locked]'] = note_locked if parent_id is not None: params['post[parent_id]'] = parent_id if md5 is not None: params['md5'] = md5 - - return self._build_request_url('posts_create', params) + return self._request('post/create', params, 'POST') else: - raise PybooruError("source or file_ is required") + raise PybooruError("'file_' or 'source' is required.") - def posts_update(self, id_, tags, file_, rating, source, is_rating_locked, - is_note_locked, parent_id): + def post_update(self, id_, tags=None, file_=None, rating=None, + source=None, rating_locked=None, note_locked=None, + parent_id=None): """Function update a specific post. - Only the id_ parameter is required. Leave the other parameters blank - if you don't want to change them (Requires login)(UNESTED). + Only the 'id_' parameter is required. Leave the other parameters blank + if you don't want to change them (Requires login). Parameters: - id_: - The id number of the post to update (Type: INT). - - tags: - A space delimited list of tags (Type: STR). - - file_: - The file data ENCODED as a multipart form. - - rating: - The rating for the post. Can be: safe, questionable, or - explicit. - - source: - If this is a URL, Danbooru/Moebooru will download the file. - - is_rating_locked: - Set to true to prevent others from changing the rating. - - is_note_locked: - Set to true to prevent others from adding notes. - - parent_id: - The ID of the parent post. + id_: The id number of the post to update. + tags: A space delimited list of tags. Specify previous tags. + file_: The file data ENCODED as a multipart form. + rating: The rating for the post. Can be: safe, questionable, or + explicit. + source: If this is a URL, Danbooru/Moebooru will download the file. + rating_locked: Set to true to prevent others from changing the + rating. + note_locked: Set to true to prevent others from adding notes. + parent_id: The ID of the parent post. """ params = {'id': id_} - if tags is not None: params['post[tags]'] = tags if file_ is not None: @@ -132,208 +107,145 @@ def posts_update(self, id_, tags, file_, rating, source, is_rating_locked, params['post[rating]'] = rating if source is not None: params['post[source]'] = source - if is_rating_locked is not None: + if rating_locked is not None: params['post[is_rating_locked]'] = is_rating_locked - if is_note_locked is not None: + if note_locked is not None: params['post[is_note_locked]'] = is_note_locked if parent_id is not None: params['post[parent_id]'] = parent_id + return self._request('post/update', params, 'POST') - return self._build_request_url('posts_update', params) - - def posts_destroy(self, id_): + def post_destroy(self, id_): """Function to destroy a specific post. You must also be the user who uploaded the post (or you must be a - moderator) (Requires Login)(UNTESTED). + moderator) (Requires Login) (UNTESTED). Parameters: - id_: - The id number of the post to delete. + id_: The id number of the post to delete. """ - params = {'id': id_} - response = self._build_request_url('posts_destroy', params) - return response['success'] + return self._request('post/destroy', {'id': id_}, 'POST') - def posts_revert_tags(self, id_, history_id): + def post_revert_tags(self, id_, history_id): """Function to reverts a post to a previous set of tags - (Requires login)(UNTESTED). + (Requires login) (UNTESTED). Parameters: - id_: - The post id number to update (Type: INT). - - history_id: - The id number of the tag history. + id_: The post id number to update. + history_id: The id number of the tag history. """ params = {'id': id_, 'history_id': history_id} - return self._build_request_url('posts_revert_tags', params) + return self._request('post/revert_tags', params, 'POST') - def posts_vote(self, id_, score): + def post_vote(self, id_, score): """Action lets you vote for a post (Requires login). Parameters: - id_: - The post id (Type: INT). - + id_: The post id. score: - Be can: - 0: No voted or Remove vote. - 1: Good. - 2: Great. - 3: Favorite, add post to favorites. + 0: No voted or Remove vote. + 1: Good. + 2: Great. + 3: Favorite, add post to favorites. """ if score <= 3: params = {'id': id_, 'score': score} - return self._build_request_url('posts_vote', params) + return self._request('post/vote', params, 'POST') else: - raise PybooruError("Value of score only can be 0, 1, 2 and 3.") + raise PybooruError("Value of 'score' only can be 0, 1, 2 or 3.") - def tags_list(self, name=None, id_=None, limit=0, page=1, order='name', - after_id=None): + def tag_list(self, **params): """Get a list of tags. Parameters: - name: - The exact name of the tag. - - id_: - The id number of the tag. - - limit: - How many tags to retrieve. Setting this to 0 will return - every tag (Default value: 0). - - page: - The page number. - - order: - Can be 'date', 'name' or 'count' (Default: name). - - after_id: - Return all tags that have an id number greater than this. + name: The exact name of the tag. + id: The id number of the tag. + limit: How many tags to retrieve. Setting this to 0 will return + every tag (Default value: 0). + page: The page number. + order: Can be 'date', 'name' or 'count'. + after_id: Return all tags that have an id number greater than this. """ - params = {'limit': limit, 'page': page, 'order': order} + return self._request('tag', params) - if id_ is not None: - params['id'] = id_ - elif name is not None: - params['name'] = name - elif after_id is not None: - params['after_id'] = after_id - return self._build_request_url('tags_list', params) - - def tags_update(self, name, tag_type, is_ambiguous): - """Action to lets you update tag (Requires login)(UNTESTED). + def tag_update(self, name=None, tag_type=None, is_ambiguous=None): + """Action to lets you update tag (Requires login) (UNTESTED). Parameters: - name: - The name of the tag to update. - + name: The name of the tag to update. tag_type: - The tag type. - General: 0. - artist: 1. - copyright: 3. - character: 4. - - is_ambiguous: - Whether or not this tag is ambiguous. Use 1 for true and 0 - for false. - """ - params = {'name': name, 'tag[tag_type]': tag_type, - 'tag[is_ambiguous]': is_ambiguous} - - return self._build_request_url('tags_update', params) - - def tags_related(self, tags, type_=None): + General: 0. + artist: 1. + copyright: 3. + character: 4. + is_ambiguous: Whether or not this tag is ambiguous. Use 1 for true + and 0 for false. + """ + params = {'name': name} + if tag_type is not None: + params['tag[tag_type]'] = tag_type + if is_ambiguous is not None: + params['tag[is_ambiguous]'] = is_ambiguous + return self._request('tag/update', params, 'POST') + + def tag_related(self, **params): """Get a list of related tags. Parameters: - tags: - The tag names to query. - - type_: - Restrict results to this tag type. Can be general, artist, - copyright, or character (Default value: None). + tags: The tag names to query. + type: Restrict results to this tag type. Can be general, artist, + copyright, or character. """ - params = {'tags': tags} + return self._request('tag/related', params) - if type_ is not None: - params['type'] = type_ - - return self._build_request_url('tags_related', params) - - def artists_list(self, name=None, order=None, page=1): + def artist_list(self, **params): """Get a list of artists. Parameters: - name: - The name (or a fragment of the name) of the artist. - - order: - Can be date or name (Default value: None). - - page: - The page number. + name: The name (or a fragment of the name) of the artist. + order: Can be date or name. + page: The page number. """ - params = {'page': page} + return self._request('artist', params) - if name is not None: - params['name'] = name - if order is not None: - params['order'] = order - - return self._build_request_url('artists_list', params) - - def artists_create(self, name, urls, alias, group): - """Function to create a artist (Requires login)(UNTESTED). + def artist_create(self, name, urls=None, alias=None, group=None): + """Function to create a artist (Requires login) (UNTESTED). Parameters: - name: - The artist's name. - - urls: - A list of URLs associated with the artist, whitespace delimited. - - alias: - The artist that this artist is an alias for. Simply enter the - alias artist's name. - - group: - The group or cicle that this artist is a member of. Simply - enter the group's name. + name: The artist's name. + urls: A list of URLs associated with the artist, whitespace + delimited. + alias: The artist that this artist is an alias for. Simply enter + the alias artist's name. + group: The group or cicle that this artist is a member of. Simply + enter the group's name. """ - params = {'artist[name]': name, 'artist[urls]': urls, - 'artist[alias]': alias, 'artist[group]': group} - return self._build_request_url('artists_create', params) + params = {'artist[name]': name} + if urls is not None: + params['artist[urls]'] = urls + if alias is not None: + params['artist[alias]'] = alias + if group is not None: + params['artist[group]'] = group + return self._request('artist/create', params, 'POST') - def artists_update(self, id_, name=None, urls=None, alias=None, group=None): + def artist_update(self, id_, name=None, urls=None, alias=None, group=None): """Function to update an artists. Only the id_ parameter is required. The other parameters are optional. - (Requires login)(UNTESTED). + (Requires login) (UNTESTED). Parameters: - id_: - The id of thr artist to update (Type: INT). - - name: - The artist's name. - - urls: - A list of URLs associated with the artist, whitespace delimited. - - alias: - The artist that this artist is an alias for. Simply enter the - alias artist's name. - - group: - The group or cicle that this artist is a member of. Simply - enter the group's name. + id_: The id of thr artist to update (Type: INT). + name: The artist's name. + urls: A list of URLs associated with the artist, whitespace + delimited. + alias: The artist that this artist is an alias for. Simply enter the + alias artist's name. + group: The group or cicle that this artist is a member of. Simply + enter the group's name. """ params = {'id': id_} - if name is not None: params['artist[name]'] = name if urls is not None: @@ -342,463 +254,324 @@ def artists_update(self, id_, name=None, urls=None, alias=None, group=None): params['artist[alias]'] = alias if group is not None: params['artist[group]'] = group + return self._request('artist/update', params, 'POST') - return self._build_request_url('artists_update', params) - - def artists_destroy(self, id_): - """Action to lets you remove artist (Requires login)(UNTESTED). + def artist_destroy(self, id_): + """Action to lets you remove artist (Requires login) (UNTESTED). Parameters: - id_: - The id of the artist to destroy (Type: INT). + id_: The id of the artist to destroy. """ - params = {'id': id_} - response = self._build_request_url('artists_destroy', params) - return response['success'] + return self._request('artist/destroy', {'id': id_}, 'POST') - def comments_show(self, id_): + def comment_show(self, id_): """Get a specific comment. Parameters: - id_: - The id number of the comment to retrieve (Type: INT). + id_: The id number of the comment to retrieve. """ - params = {'id': id_} - return self._build_request_url('comments_show', params) + return self._request('comment/show', {'id': id_}) - def comments_create(self, post_id, comment_body): + def comment_create(self, anonymous=None, post_id=None, comment_body=None): """Action to lets you create a comment (Requires login). Parameters: - post_id: - The post id number to which you are responding (Type: INT). - - comment_body: - The body of the comment. + anonymous: Set to 1 if you want to post this comment anonymously. + post_id: The post id number to which you are responding. + comment_body: The body of the comment. """ - params = {'comment[post_id]': post_id, - 'comment[body]': comment_body} - response = self._build_request_url('comments_create', params) - return response['success'] + params = {} + if post_id and comment_body is not None: + params['comment[post_id]'] = post_id + params['comment[body]'] = comment_body + if anonymous is not None: + params['comment[anonymous]'] = anonymous + return self._request('comment/create', params, 'POST') + else: + raise PybooruError("Required 'post_id' and 'comment_body' " + "parameters") - def comments_destroy(self, id_=None): + def comment_destroy(self, id_=None): """Remove a specific comment (Requires login). Parameters: - id_: - The id number of the comment to remove (Type: INT). + id_: The id number of the comment to remove. """ - params = {'id': id_} - response = self._build_request_url('comments_destroy', params) - return response['success'] + return self._request('comment/destroy', {'id': id_}, 'POST') - def wiki_list(self, query=None, order='title', limit=100, page=1): + def wiki_list(self, **params): """Function to retrieves a list of every wiki page. Parameters: - query: - A word or phrase to search for (Default: None). - - order: - Can be: title, date (Default: title). - - limit: - The number of pages to retrieve (Default: 100). - - page: - The page number. + query: A word or phrase to search for (Default: None). + order: Can be: title, date (Default: title). + limit: The number of pages to retrieve (Default: 100). + page: The page number. """ - params = {'order': order, 'limit': limit, 'page': page} - - if query is not None: - params['query'] = query - - return self._build_request_url('wiki_list', params) + return self._request('wiki', params) def wiki_create(self, title, body): - """Action to lets you create a wiki page (Requires login)(UNTESTED). + """Action to lets you create a wiki page (Requires login) (UNTESTED). Parameters: - title: - The title of the wiki page. - - body: - The body of the wiki page. + title: The title of the wiki page. + body: The body of the wiki page. """ + params = {'wiki_page[title]': title, 'wiki_page[body]': body} + return self._request('wiki/create', params, 'POST') - params = {'wiki_page[title]': str(title), 'wiki_page[body]': str(body)} - return self._build_request_url('wiki_create', params) - - def wiki_update(self, page_title, new_title, page_body): - """Action to lets you update a wiki page (Requires login)(UNTESTED). + def wiki_update(self, page_title, new_title=None, page_body=None): + """Action to lets you update a wiki page (Requires login) (UNTESTED). Parameters: - page_title: - The title of the wiki page to update. - - new_title: - The new title of the wiki page. - - page_body: - The new body of the wiki page. + page_title: The title of the wiki page to update. + new_title: The new title of the wiki page. + page_body: The new body of the wiki page. """ - params = {'title': page_title, 'wiki_page[title]': new_title, - 'wiki_page[body]': page_body} - return self._build_request_url('wiki_update', params) + params = {'title': page_title} + if new_title is not None: + params['wiki_page[title]'] = new_title + if page_body is not None: + params['wiki_page[body]'] = page_body + return self._request('wiki/update', params, 'POST') - def wiki_show(self, title, version=None): + def wiki_show(self, **params): """Get a specific wiki page. Parameters: - title: - The title of the wiki page to retrieve. - - version: - The version of the page to retrieve. + title: The title of the wiki page to retrieve. + version: The version of the page to retrieve. """ - params = {'title': title} - - if version is not None: - params['version'] = version - - return self._build_request_url('wiki_show', params) + return self._request('wiki/show', params) def wiki_destroy(self, title): """Function to delete a specific wiki page (Requires login) - (Only moderators)(UNTESTED). + (Only moderators) (UNTESTED). Parameters: - title: - The title of the page to delete. + title: The title of the page to delete. """ - params = {'title': title} - response = self._build_request_url('wiki_destroy', params) - return response['success'] + return self._request('wiki/destroy', {'title': title}, 'POST') def wiki_lock(self, title): """Function to lock a specific wiki page (Requires login) - (Only moderators)(UNTESTED). + (Only moderators) (UNTESTED). Parameters: - title: - The title of the page to lock. + title: The title of the page to lock. """ - params = {'title': title} - response = self._build_request_url('wiki_lock', params) - return response['success'] + return self._request('wiki/lock', {'title': title}, 'POST') def wiki_unlock(self, title): """Function to unlock a specific wiki page (Requires login) - (Only moderators)(UNTESTED). + (Only moderators) (UNTESTED). Parameters: - title: - The title of the page to unlock. + title: The title of the page to unlock. """ - params = {'title': title} - response = self._build_request_url('wiki_unlock', params) - return response['success'] + return self._request('wiki/unlock', {'title': title}, 'POST') def wiki_revert(self, title, version): - """Function to revert a specific wiki page (Requires login)(UNTESTED). + """Function to revert a specific wiki page (Requires login) (UNTESTED). Parameters: - title: - The title of the wiki page to update. - - version: - The version to revert to. + title: The title of the wiki page to update. + version: The version to revert to. """ params = {'title': title, 'version': version} - response = self._build_request_url('wiki_revert', params) - return response['success'] + return self._request('wiki/revert', params, 'POST') def wiki_history(self, title): """Get history of specific wiki page. Parameters: - title: - The title of the wiki page to retrieve versions for. + title: The title of the wiki page to retrieve versions for. """ - params = {'title': title} - return self._build_request_url('wiki_history', params) + return self._request('wiki/history', {'title': title}) - def notes_list(self, post_id=None): + def note_list(self, **params): """Get note list. Parameters: - post_id: - The post id number to retrieve notes for (Default: None) - (Type: INT). + post_id: The post id number to retrieve notes for. """ - if post_id is not None: - params = {'post_id': post_id} - return self._build_request_url('notes_list', params) - else: - return self._build_request_url('notes_list') + return self._request('note', params) - def notes_search(self, query): + def note_search(self, query): """Search specific note. Parameters: - query: - A word or phrase to search for. + query: A word or phrase to search for. """ - params = {'query': query} - return self._build_request_url('notes_search', params) + return self._request('note/search', {'query': query}) - def notes_history(self, post_id=None, id_=None, limit=10, page=1): + def notes_history(self, **params): """Get history of notes. Parameters: - post_id: - The post id number to retrieve note versions for. - - id_: - The note id number to retrieve versions for (Type: INT). - - limit: - How many versions to retrieve (Default: 10). - - page: - The note id number to retrieve versions for. + post_id: The post id number to retrieve note versions for. + id_: The note id number to retrieve versions for. + limit: How many versions to retrieve (Default: 10). + page: The note id number to retrieve versions for. """ - params = {'limit': limit, 'page': page} - - if post_id is not None: - params['post_id'] = post_id - elif id_ is not None: - params['id'] = id_ - - return self._build_request_url('notes_history', params) + return self._request('note/history', params) - def notes_revert(self, id_, version): - """Function to revert a specific note (Requires login)(UNTESTED). + def note_revert(self, id, version): + """Function to revert a specific note (Requires login) (UNTESTED). Parameters: - id_: - The note id to update (Type: INT). - - version: - The version to revert to. + id: The note id to update. + version: The version to revert to. """ params = {'id': id_, 'version': version} - response = self._build_request_url('wiki_revert', params) - return response['success'] - - def notes_create_update(self, post_id, coor_x, coor_y, width, height, - is_active, body, id_=None): - """Function to create or update note (Requires login)(UNTESTED). - - Parameters: - post_id: - The post id number this note belongs to. - - coor_x: - The X coordinate of the note. - - coor_y: - The Y coordinate of the note. - - width: - The width of the note. - - height: - The height of the note. - - is_active: - Whether or not the note is visible. Set to 1 for active, 0 for - inactive. - - body: - The note message. - - id_: - If you are updating a note, this is the note id number to - update. - """ - params = {'note[post_id]': post_id, 'note[x]': coor_x, - 'note[y]': coor_y, 'note[width]': width, - 'note[height]': height, 'note[body]': body} - + return self._request('note/revert', params, 'POST') + + def note_create_update(self, post_id=None, coor_x=None, coor_y=None, + width=None, height=None, is_active=None, body=None, + id_=None): + """Function to create or update note (Requires login) (UNTESTED). + + Parameters: + post_id: The post id number this note belongs to. + coor_x: The X coordinate of the note. + coor_y: The Y coordinate of the note. + width: The width of the note. + height: The height of the note. + is_active: Whether or not the note is visible. Set to 1 for + active, 0 for inactive. + body: The note message. + id_: If you are updating a note, this is the note id number to + update. + """ + params = {} if id_ is not None: params['id'] = id_ - if is_active <= 1: + if post_id is not None: + params['note[post]'] = post_id + if coor_x is not None: + params['note[x]'] = coor_x + if coor_y is not None: + params['note[y]'] = coor_y + if width is not None: + params['note[width]'] = width + if height is not None: + params['note[height]'] = height + if body is not None: + params['note[body]'] = body + if is_active is not None: params['note[is_active]'] = is_active - else: - raise PybooruError("is_active parameters required 1 or 0") + return self._request('note/update', params, 'POST') - return self._build_request_url('notes_create_update', params) - - def users_search(self, name=None, id_=None): + def user_search(self, **params): """Search users. If you don't specify any parameters you'll get a listing of all users. Parameters: - name: - The name of the user. - - id_: - The id number of the user. + id: The id number of the user. + name: The name of the user. """ - if name is not None: - params = {'name': name} - return self._build_request_url('users_search', params) - elif id_ is not None: - params = {'id': id_} - return self._build_request_url('users_search', params) - else: - return self._build_request_url('users_search') + return self._request('user', params) - def forum_list(self, parent_id=None): + def forum_list(self, **params): """Function to get forum posts. If you don't specify any parameters you'll get a listing of all users. Parameters: - parent_id: - The parent ID number. You'll return all the responses to that - forum post. + parent_id: The parent ID number. You'll return all the responses + to that forum post. """ - if parent_id is not None: - params = {'parent_id': parent_id} - return self._build_request_url('forum_list', params) - else: - return self._build_request_url('forum_list') + return self._request('forum', params) - def pools_list(self, query=None, page=1): + def pool_list(self, **params): """Function to get pools. If you don't specify any parameters you'll get a list of all pools. Parameters: - query: - The title. - - page: - The page. + query: The title. + page: The page. """ - params = {'page': page} - - if query is not None: - params['query'] = query - - return self._build_request_url('pools_list', params) + return self._request('pool', params) - def pools_posts(self, id_=None, page=1): + def pool_posts(self, **params): """Function to get pools posts. If you don't specify any parameters you'll get a list of all pools. Parameters: - id_: - The pool id number. - - page: - The page. + id: The pool id number. + page: The page. """ - params = {'page': page} + return self._request('pool/show', params) - if id_ is not None: - params['id'] = id_ - - return self._build_request_url('pools_posts', params) - - def pools_update(self, id_, name, is_public, description): - """Function to update a pool (Requires login)(UNTESTED). + def pool_update(self, id_, name=None, is_public=None, + description=None): + """Function to update a pool (Requires login) (UNTESTED). Parameters: - id_: - The pool id number. - - name: - The name. - - is_public: - 1 or 0, whether or not the pool is public. - - description: - A description of the pool. + id_: The pool id number. + name: The name. + is_public: 1 or 0, whether or not the pool is public. + description: A description of the pool. """ - params = {'id': id_, 'pool[name]': name, - 'pool[description]': description} - - if is_public <= 1: + params = {'id': id_} + if name is not None: + params['pool[name]'] = name + if is_public is not None: params['pool[is_public]'] = is_public - else: - raise PybooruError("is_public require 1 or 0") - - return self._build_request_url('pools_update', params) + if name is not None: + params['pool[name]'] = name + if description is not None: + params['pool[description]'] = description + return self._request('pool/update', params, 'POST') - def pools_create(self, name, is_public, description): + def pool_create(self, name, description, is_public): """Function to create a pool (Require login)(UNTESTED). Parameters: - name: - The name. - - is_public: - 1 or 0, whether or not the pool is public. - - description: - A description of the pool. + name: The name. + description: A description of the pool. + is_public: 1 or 0, whether or not the pool is public. """ - params = {'pool[name]': name, 'pool[description]': description} - - if is_public <= 1: - params['pool[name]'] = is_public - else: - raise PybooruError("is_public required 1 or 0") - - return self._build_request_url('pools_create', params) + params = {'pool[name]': name, 'pool[description]': description, + 'pool[name]': is_public} + return self._request('pool/create', params, 'POST') - def pools_destroy(self, id_): - """Function to destroy a specific pool (Require login)(UNTESTED). + def pool_destroy(self, id_): + """Function to destroy a specific pool (Require login) (UNTESTED). Parameters: - id_: - The pool id number (Type: INT). + id_: The pool id number. """ - params = {'id': id_} - response = self._build_request_url('pools_destroy', params) - return response['success'] + return self._request('pool/destroy', {'id': id_}, 'POST') - def pools_add_post(self, pool_id, post_id): + def pool_add_post(self, **params): """Function to add a post (Require login)(UNTESTED). Parameters: - pool_id: - The pool to add the post to. - - post_id: - The post to add. + pool_id: The pool to add the post to. + post_id: The post to add. """ - params = {'pool_id': pool_id, 'post_id': post_id} - return self._build_request_url('pools_add_post', params) + return self._request('pool/add_post', params, 'POST') - def pools_remove_post(self, pool_id, post_id): - """Function to remove a post (Require login)(UNTESTED). + def pool_remove_post(self, **params): + """Function to remove a post (Require login) (UNTESTED). Parameters: - pool_id: - The pool to remove the post to. - - post_id: - The post to remove. + pool_id: The pool to remove the post to. + post_id: The post to remove. """ - params = {'pool_id': pool_id, 'post_id': post_id} - return self._build_request_url('pools_remove_post', params) + return self._request('pool/remove_post', params, 'POST') def favorites_list_users(self, id_): """Function to return a list with all users who have added to favorites a specific post. Parameters: - id_: - The post id (Type: INT). + id_: The post id. """ - params = {'id': id_} - response = self._build_request_url('favorites_list_users', params) + response = self._request('favorite/list_users', {'id': id_}) # Return list with users return response['favorited_users'].split(',') diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 2f8c40f..496dd79 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -25,7 +25,7 @@ class Pybooru(ApiFunctionsMixin, object): - """Pybooru main class. + """Pybooru main class (inherits: pybooru.api.ApiFunctionsMixin). To initialize Pybooru, you need to specify one of these two parameters: 'site_name' or 'site_url'. If you specify 'site_name', Pybooru @@ -68,6 +68,7 @@ def __init__(self, site_name="", site_url="", username="", password="", self.username = username self.password = password self.hash_string = hash_string + self._password_hash = None # Validate site_name or site_url if site_url or site_name is not "": @@ -81,7 +82,7 @@ def __init__(self, site_name="", site_url="", username="", password="", def _site_name_validator(self): """Function that checks the site name and get url.""" - if site_name in list(SITE_LIST.keys()): + if self.site_name in list(SITE_LIST): self.site_url = SITE_LIST[self.site_name]['url'] self.hash_string = SITE_LIST[self.site_name]['hashed_string'] else: @@ -113,8 +114,7 @@ def _build_hash_string(self): """Function for build password hash string.""" # Build AUTENTICATION hash_string # Check if hash_string exists - if self.site_name in list(SITE_LIST.keys()) or \ - self.hash_string is not "": + if self.site_name in list(SITE_LIST) or self.hash_string is not "": if self.username and self.password is not "": try: hash_string = self.hash_string.format(self.password) @@ -122,7 +122,7 @@ def _build_hash_string(self): raise PybooruError("Pybooru can't add 'password' " "to 'hash_string'") # encrypt hashed_string to SHA1 and return hexdigest string - self.hash_string = hashlib.sha1( # pylint: disable=E1101 + self.password_hash = hashlib.sha1( # pylint: disable=E1101 hash_string.encode('utf-8')).hexdigest() else: raise PybooruError("Specify the 'username' and 'password' " @@ -151,12 +151,12 @@ def _request(self, api_call, params, method='GET'): response = requests.get(url, params=params, headers=headers, timeout=60) else: - if self.hash_string is "": + if self._password_hash is None: self._build_hash_string() + params['login'] = self.username + params['password_hash'] = self.password_hash response = requests.post(url, params=params, headers=headers, timeout=60) - # Enable raise status error - response.raise_for_status() # Read and return JSON data return response.json() except requests.exceptions.HTTPError as err: From d5700810945bcff117e2ab501f886b9aedb26a6d Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 29 May 2016 17:12:30 +0200 Subject: [PATCH 008/141] Fix some parameters --- pybooru/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index cd7171e..e618de6 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -79,7 +79,7 @@ def post_create(self, tags, file_=None, rating=None, source=None, raise PybooruError("'file_' or 'source' is required.") def post_update(self, id_, tags=None, file_=None, rating=None, - source=None, rating_locked=None, note_locked=None, + source=None, is_rating_locked=None, is_note_locked=None, parent_id=None): """Function update a specific post. @@ -416,7 +416,7 @@ def notes_history(self, **params): """ return self._request('note/history', params) - def note_revert(self, id, version): + def note_revert(self, id_, version): """Function to revert a specific note (Requires login) (UNTESTED). Parameters: From 464e2b9a1fd9eeeff533bb84188d409478927e0c Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 29 May 2016 17:17:35 +0200 Subject: [PATCH 009/141] Small fix --- pybooru/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index e618de6..8e9c1de 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -107,9 +107,9 @@ def post_update(self, id_, tags=None, file_=None, rating=None, params['post[rating]'] = rating if source is not None: params['post[source]'] = source - if rating_locked is not None: + if is_rating_locked is not None: params['post[is_rating_locked]'] = is_rating_locked - if note_locked is not None: + if is_note_locked is not None: params['post[is_note_locked]'] = is_note_locked if parent_id is not None: params['post[parent_id]'] = parent_id From 0e6e8c0173f91f9fbc6946cfcdb3863239ab71d4 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 29 May 2016 18:24:29 +0200 Subject: [PATCH 010/141] Fix python 2.X parameters --- pybooru/pybooru.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 496dd79..bedea00 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -147,7 +147,7 @@ def _request(self, api_call, params, method='GET'): headers = {'content-type': 'application/json; charset=utf-8'} try: - if method is 'GET': + if method == 'GET': response = requests.get(url, params=params, headers=headers, timeout=60) else: From 16088124d15716ec5d66da6a9e257afaabb8beb0 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 29 May 2016 21:43:49 +0200 Subject: [PATCH 011/141] Refactoring resources.py --- pybooru/api.py | 4 +- pybooru/pybooru.py | 2 +- pybooru/resources.py | 135 ++----------------------------------------- 3 files changed, 8 insertions(+), 133 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index 8e9c1de..8433012 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -528,7 +528,7 @@ def pool_update(self, id_, name=None, is_public=None, return self._request('pool/update', params, 'POST') def pool_create(self, name, description, is_public): - """Function to create a pool (Require login)(UNTESTED). + """Function to create a pool (Require login) (UNTESTED). Parameters: name: The name. @@ -548,7 +548,7 @@ def pool_destroy(self, id_): return self._request('pool/destroy', {'id': id_}, 'POST') def pool_add_post(self, **params): - """Function to add a post (Require login)(UNTESTED). + """Function to add a post (Require login) (UNTESTED). Parameters: pool_id: The pool to add the post to. diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index bedea00..cc3e89a 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -16,7 +16,7 @@ # pyborru imports from .api import ApiFunctionsMixin from .exceptions import PybooruError -from .resources import (API_BASE_URL, SITE_LIST) +from .resources import SITE_LIST # External imports import requests diff --git a/pybooru/resources.py b/pybooru/resources.py index 5385145..e06bd9b 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- -"""This module contains all resources for pybooru. +"""pybooru.resources -site_list: +This module contains all resources for pybooru. + +SITE_LIST: Is a dict that contains various based Danbooru/Moebooru, default sites. -api_base_url: - Is a dict that contains the urls for API functions. -http_status_codes: +HTTP_STATUS_CODES: Is a dict that contains the http status code for Danbooru/Moebooru API. """ @@ -23,131 +23,6 @@ } -# API_BASE_URL for the API functions -API_BASE_URL = { - 'posts_list': { - 'url': "/post.json", - 'required_login': False}, - 'posts_create': { - 'url': "/post/create.json", - 'required_login': True}, - 'posts_update': { - 'url': "/post/update.json", - 'required_login': True}, - 'posts_destroy': { - 'url': "/post/destroy.json", - 'required_login': True}, - 'posts_revert_tags': { - 'url': "/post/revert_tags.json", - 'required_login': True}, - 'posts_vote': { - 'url': "/post/vote.json", - 'required_login': True}, - 'tags_list': { - 'url': "/tag.json", - 'required_login': False}, - 'tags_update': { - 'url': "/tag/update.json", - 'required_login': True}, - 'tags_related': { - 'url': "/tag/related.json", - 'required_login': False}, - 'artists_list': { - 'url': "/artist.json", - 'required_login': False}, - 'artists_create': { - 'url': "/artist/create.json", - 'required_login': True}, - 'artists_update': { - 'url': "/artist/update.json", - 'required_login': True}, - 'artists_destroy': { - 'url': "/artist/destroy.json", - 'required_login': True}, - 'comments_show': { - 'url': "/comment/show.json", - 'required_login': False}, - 'comments_create': { - 'url': "/comment/create.json", - 'required_login': True}, - 'comments_destroy': { - 'url': "/comment/destroy.json", - 'required_login': True}, - 'wiki_list': { - 'url': "/wiki.json", - 'required_login': False}, - 'wiki_create': { - 'url': "/wiki/create.json", - 'required_login': True}, - 'wiki_update': { - 'url': "/wiki/update.json", - 'required_login': True}, - 'wiki_show': { - 'url': "/wiki/show.json", - 'required_login': False}, - 'wiki_destroy': { - 'url': "/wiki/destroy.json", - 'required_login': True}, - 'wiki_lock': { - 'url': "/wiki/lock.json", - 'required_login': True}, - 'wiki_unlock': { - 'url': "/wiki/unlock.json", - 'required_login': True}, - 'wiki_revert': { - 'url': "/wiki/revert.json", - 'required_login': True}, - 'wiki_history': { - 'url': "/wiki/history.json", - 'required_login': False}, - 'notes_list': { - 'url': "/note.json", - 'required_login': False}, - 'notes_search': { - 'url': "/note/search.json", - 'required_login': False}, - 'notes_history': { - 'url': "/note/history.json", - 'required_login': False}, - 'notes_revert': { - 'url': "/note/revert.json", - 'required_login': True}, - 'notes_create_update': { - 'url': "/note/update.json", - 'required_login': True}, - 'users_search': { - 'url': "/user.json", - 'required_login': False}, - 'forum_list': { - 'url': "/forum.json", - 'required_login': False}, - 'pools_list': { - 'url': "/pool.json", - 'required_login': False}, - 'pools_posts': { - 'url': "/pool/show.json", - 'required_login': False}, - 'pools_update': { - 'url': "/pool/update.json", - 'required_login': True}, - 'pools_create': { - 'url': "/pool/create.json", - 'required_login': True}, - 'pools_destroy': { - 'url': "/pool/destroy.json", - 'required_login': True}, - 'pools_add_post': { - 'url': "/pool/add_post.json", - 'required_login': True}, - 'pools_remove_post': { - 'url': "/pool/remove_post.json", - 'required_login': True}, - 'favorites_list_users': { - 'url': "/favorite/list_users.json", - 'required_login': False} - } - - # HTTP_STATUS_CODES HTTP_STATUS_CODES = { 200: ("OK", "Request was successful"), From 0c3a382e1137155bf51f60a71dfad24275720b2f Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 7 Jun 2016 16:46:08 +0200 Subject: [PATCH 012/141] Makess Pybooru use Requests as a client --- pybooru/api.py | 2 +- pybooru/pybooru.py | 36 ++++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index 8433012..0f41d4e 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -44,7 +44,7 @@ def post_create(self, tags, file_=None, rating=None, source=None, Parameters: tags: A space delimited list of tags. - file_: The file data encoded as a multipart form. + file_: The file data encoded as a multipart form. Path of content. rating: The rating for the post. Can be: safe, questionable, or explicit. source: If this is a URL, Danbooru/Moebooru will download the diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index cc3e89a..50f1cea 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -14,6 +14,7 @@ from __future__ import unicode_literals # pyborru imports +from . import __version__ from .api import ApiFunctionsMixin from .exceptions import PybooruError from .resources import SITE_LIST @@ -52,15 +53,15 @@ def __init__(self, site_name="", site_url="", username="", password="", """Initialize Pybooru. Keyword arguments: - site_name: The site name in 'SITE_LIST', default sites. - site_url: URL of on Danbooru/Moebooru based sites. - hash_string: String that is hashed (required to login). - (See the API documentation of the site for more - information). - username: Your username of the site (Required only for functions that - modify the content). - password: Your user password in plain text (Required only for functions - that modify the content). + site_name: The site name in 'SITE_LIST', default sites. + site_url: URL of on Danbooru/Moebooru based sites. + hash_string: String that is hashed (required to login). + (See the API documentation of the site for more + information). + username: Your username of the site (Required only for functions that + modify the content). + password: Your user password in plain text (Required only for + functions that modify the content). """ # Attributes self.site_name = site_name.lower() @@ -70,6 +71,12 @@ def __init__(self, site_name="", site_url="", username="", password="", self.hash_string = hash_string self._password_hash = None + # Set HTTP Client + self.client = requests.Session() + headers = {'user-agent': 'Pybooru/{}'.format(__version__), + 'content-type': 'application/json; charset=utf-8'} + self.client.headers = headers + # Validate site_name or site_url if site_url or site_name is not "": if site_name is not "": @@ -144,23 +151,20 @@ def _request(self, api_call, params, method='GET'): # Build url url = "{0}/{1}.json".format(self.site_url, api_call) - headers = {'content-type': 'application/json; charset=utf-8'} - try: if method == 'GET': - response = requests.get(url, params=params, headers=headers, - timeout=60) + response = self.client.get(url, params=params) else: if self._password_hash is None: self._build_hash_string() params['login'] = self.username params['password_hash'] = self.password_hash - response = requests.post(url, params=params, headers=headers, - timeout=60) + response = self.client.post(url, params=params) + response.raise_for_status() # Read and return JSON data return response.json() except requests.exceptions.HTTPError as err: - raise PybooruError("In _json_request", response.status_code, + raise PybooruError("In _request: ", response.status_code, response.url) except requests.exceptions.Timeout as err: raise PybooruError("Timeout! in url: {0}".format(response.url)) From 5bc9c17a1498993047f99b5a081b771e01b611cf Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 10 Jun 2016 20:54:44 +0200 Subject: [PATCH 013/141] Now Pybooru uses reqeusts.Session --- pybooru/api.py | 10 +++++----- pybooru/pybooru.py | 17 +++++++++++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index 0f41d4e..22155e1 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -61,7 +61,7 @@ def post_create(self, tags, file_=None, rating=None, source=None, params = {'post[tags]': tags} if file_ or source is not None: if file_ is not None: - params['post[file]'] = file_ + file_ = {'post[file]': open(file_, 'rb')} if source is not None: params['post[source]'] = source if rating is not None: @@ -74,7 +74,7 @@ def post_create(self, tags, file_=None, rating=None, source=None, params['post[parent_id]'] = parent_id if md5 is not None: params['md5'] = md5 - return self._request('post/create', params, 'POST') + return self._request('post/create', params, 'POST', file_) else: raise PybooruError("'file_' or 'source' is required.") @@ -102,7 +102,7 @@ def post_update(self, id_, tags=None, file_=None, rating=None, if tags is not None: params['post[tags]'] = tags if file_ is not None: - params['post[file]'] = file_ + file_ = {'post[file]': open(file_, 'rb')} if rating is not None: params['post[rating]'] = rating if source is not None: @@ -272,13 +272,13 @@ def comment_show(self, id_): """ return self._request('comment/show', {'id': id_}) - def comment_create(self, anonymous=None, post_id=None, comment_body=None): + def comment_create(self, post_id, comment_body, anonymous=None): """Action to lets you create a comment (Requires login). Parameters: - anonymous: Set to 1 if you want to post this comment anonymously. post_id: The post id number to which you are responding. comment_body: The body of the comment. + anonymous: Set to 1 if you want to post this comment anonymously. """ params = {} if post_id and comment_body is not None: diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 50f1cea..0b83a1b 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -13,7 +13,7 @@ from __future__ import absolute_import from __future__ import unicode_literals -# pyborru imports +# pybooru imports from . import __version__ from .api import ApiFunctionsMixin from .exceptions import PybooruError @@ -73,7 +73,7 @@ def __init__(self, site_name="", site_url="", username="", password="", # Set HTTP Client self.client = requests.Session() - headers = {'user-agent': 'Pybooru/{}'.format(__version__), + headers = {'user-agent': 'Pybooru/{0}'.format(__version__), 'content-type': 'application/json; charset=utf-8'} self.client.headers = headers @@ -140,13 +140,14 @@ def _build_hash_string(self): "Specify the 'hash_string' parameter of the Pybooru" " object, for the functions that requires login.") - def _request(self, api_call, params, method='GET'): + def _request(self, api_call, params, method='GET', file_=None): """Function to request and returning JSON data. Parameters: api_call: API function to be called. params: API function parameters. method: (Defauld: GET) HTTP method 'GET' or 'POST' + file_: File to upload. """ # Build url url = "{0}/{1}.json".format(self.site_url, api_call) @@ -157,16 +158,20 @@ def _request(self, api_call, params, method='GET'): else: if self._password_hash is None: self._build_hash_string() + params['login'] = self.username params['password_hash'] = self.password_hash - response = self.client.post(url, params=params) + request_args = {'data': params, 'files': file_} + + self.client.headers.update({'content-type': None}) + response = self.client.post(url, **request_args) + response.raise_for_status() - # Read and return JSON data return response.json() except requests.exceptions.HTTPError as err: raise PybooruError("In _request: ", response.status_code, response.url) - except requests.exceptions.Timeout as err: + except requests.exceptions.Timeout: raise PybooruError("Timeout! in url: {0}".format(response.url)) except ValueError as err: raise PybooruError("JSON Error: {0} in line {1} column {2}".format( From 13935ab2d17fea4cb30d32628937035881562e54 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 15 Jun 2016 20:53:51 +0200 Subject: [PATCH 014/141] Continue refactoring of api.py --- pybooru/api.py | 150 ++++++++++++++++++------------------------- pybooru/pybooru.py | 4 +- pybooru/resources.py | 1 - 3 files changed, 65 insertions(+), 90 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index 22155e1..67ba8e3 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -58,22 +58,16 @@ def post_create(self, tags, file_=None, rating=None, source=None, after uploading. If the MD5 doesn't match, the post is destroyed. """ - params = {'post[tags]': tags} if file_ or source is not None: - if file_ is not None: - file_ = {'post[file]': open(file_, 'rb')} - if source is not None: - params['post[source]'] = source - if rating is not None: - params['post[rating]'] = rating - if rating_locked is not None: - params['post[is_rating_locked]'] = rating_locked - if note_locked is not None: - params['post[is_note_locked]'] = note_locked - if parent_id is not None: - params['post[parent_id]'] = parent_id - if md5 is not None: - params['md5'] = md5 + params = { + 'post[tags]': tags, + 'post[source]': source, + 'post[rating]': rating, + 'post[is_rating_locked]': is_rating_locked, + 'post[is_note_locked]': is_note_locked, + 'post[parent_id]': parent_id, + 'md5': md5} + file_ = {'post[file]': open(file_, 'rb')} return self._request('post/create', params, 'POST', file_) else: raise PybooruError("'file_' or 'source' is required.") @@ -98,21 +92,16 @@ def post_update(self, id_, tags=None, file_=None, rating=None, note_locked: Set to true to prevent others from adding notes. parent_id: The ID of the parent post. """ - params = {'id': id_} - if tags is not None: - params['post[tags]'] = tags - if file_ is not None: - file_ = {'post[file]': open(file_, 'rb')} - if rating is not None: - params['post[rating]'] = rating - if source is not None: - params['post[source]'] = source - if is_rating_locked is not None: - params['post[is_rating_locked]'] = is_rating_locked - if is_note_locked is not None: - params['post[is_note_locked]'] = is_note_locked - if parent_id is not None: - params['post[parent_id]'] = parent_id + params = { + 'id': id_, + 'post[tags]': tags, + 'post[rating]': rating, + 'post[source]': source, + 'post[is_rating_locked]': is_rating_locked, + 'post[is_note_locked]': is_note_locked, + 'post[parent_id]': parent_id + } + file_ = {'post[file]': open(file_, 'rb')} return self._request('post/update', params, 'POST') def post_destroy(self, id_): @@ -181,11 +170,11 @@ def tag_update(self, name=None, tag_type=None, is_ambiguous=None): is_ambiguous: Whether or not this tag is ambiguous. Use 1 for true and 0 for false. """ - params = {'name': name} - if tag_type is not None: - params['tag[tag_type]'] = tag_type - if is_ambiguous is not None: - params['tag[is_ambiguous]'] = is_ambiguous + params = { + 'name': name, + 'tag[tag_type]': tag_type, + 'tag[is_ambiguous]': is_ambiguous + } return self._request('tag/update', params, 'POST') def tag_related(self, **params): @@ -220,13 +209,12 @@ def artist_create(self, name, urls=None, alias=None, group=None): group: The group or cicle that this artist is a member of. Simply enter the group's name. """ - params = {'artist[name]': name} - if urls is not None: - params['artist[urls]'] = urls - if alias is not None: - params['artist[alias]'] = alias - if group is not None: - params['artist[group]'] = group + params = { + 'artist[name]': name, + 'artist[urls]': urls, + 'artist[alias]': alias, + 'artist[group]': group + } return self._request('artist/create', params, 'POST') def artist_update(self, id_, name=None, urls=None, alias=None, group=None): @@ -245,15 +233,13 @@ def artist_update(self, id_, name=None, urls=None, alias=None, group=None): group: The group or cicle that this artist is a member of. Simply enter the group's name. """ - params = {'id': id_} - if name is not None: - params['artist[name]'] = name - if urls is not None: - params['artist[urls]'] = urls - if alias is not None: - params['artist[alias]'] = alias - if group is not None: - params['artist[group]'] = group + params = { + 'id': id_, + 'artist[name]': name, + 'artist[urls]': urls, + 'artist[alias]': alias, + 'artist[group]': group + } return self._request('artist/update', params, 'POST') def artist_destroy(self, id_): @@ -280,12 +266,12 @@ def comment_create(self, post_id, comment_body, anonymous=None): comment_body: The body of the comment. anonymous: Set to 1 if you want to post this comment anonymously. """ - params = {} if post_id and comment_body is not None: - params['comment[post_id]'] = post_id - params['comment[body]'] = comment_body - if anonymous is not None: - params['comment[anonymous]'] = anonymous + params = { + 'comment[post_id]': post_id, + 'comment[body]': comment_body, + 'comment[anonymous]': anonymous + } return self._request('comment/create', params, 'POST') else: raise PybooruError("Required 'post_id' and 'comment_body' " @@ -328,11 +314,11 @@ def wiki_update(self, page_title, new_title=None, page_body=None): new_title: The new title of the wiki page. page_body: The new body of the wiki page. """ - params = {'title': page_title} - if new_title is not None: - params['wiki_page[title]'] = new_title - if page_body is not None: - params['wiki_page[body]'] = page_body + params = { + 'title': page_title, + 'wiki_page[title]': new_title, + 'wiki_page[body]': page_body + } return self._request('wiki/update', params, 'POST') def wiki_show(self, **params): @@ -443,23 +429,16 @@ def note_create_update(self, post_id=None, coor_x=None, coor_y=None, id_: If you are updating a note, this is the note id number to update. """ - params = {} - if id_ is not None: - params['id'] = id_ - if post_id is not None: - params['note[post]'] = post_id - if coor_x is not None: - params['note[x]'] = coor_x - if coor_y is not None: - params['note[y]'] = coor_y - if width is not None: - params['note[width]'] = width - if height is not None: - params['note[height]'] = height - if body is not None: - params['note[body]'] = body - if is_active is not None: - params['note[is_active]'] = is_active + params = { + 'id': id_, + 'note[post]': post_id, + 'note[x]': coor_x, + 'note[y]': coor_y, + 'note[width]': width, + 'note[height]': height, + 'note[body]': body, + 'note[is_active]': is_active + } return self._request('note/update', params, 'POST') def user_search(self, **params): @@ -516,15 +495,12 @@ def pool_update(self, id_, name=None, is_public=None, is_public: 1 or 0, whether or not the pool is public. description: A description of the pool. """ - params = {'id': id_} - if name is not None: - params['pool[name]'] = name - if is_public is not None: - params['pool[is_public]'] = is_public - if name is not None: - params['pool[name]'] = name - if description is not None: - params['pool[description]'] = description + params = { + 'id': id_, + 'pool[name]': name, + 'pool[is_public]': is_public, + 'pool[description]': description + } return self._request('pool/update', params, 'POST') def pool_create(self, name, description, is_public): diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 0b83a1b..8433be1 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -89,7 +89,7 @@ def __init__(self, site_name="", site_url="", username="", password="", def _site_name_validator(self): """Function that checks the site name and get url.""" - if self.site_name in list(SITE_LIST): + if self.site_name in SITE_LIST: self.site_url = SITE_LIST[self.site_name]['url'] self.hash_string = SITE_LIST[self.site_name]['hashed_string'] else: @@ -121,7 +121,7 @@ def _build_hash_string(self): """Function for build password hash string.""" # Build AUTENTICATION hash_string # Check if hash_string exists - if self.site_name in list(SITE_LIST) or self.hash_string is not "": + if self.site_name in SITE_LIST or self.hash_string is not "": if self.username and self.password is not "": try: hash_string = self.hash_string.format(self.password) diff --git a/pybooru/resources.py b/pybooru/resources.py index e06bd9b..59e9197 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -16,7 +16,6 @@ 'konachan': { 'url': "http://konachan.com", 'hashed_string': "So-I-Heard-You-Like-Mupkids-?--{0}--"}, - 'yandere': { 'url': "https://yande.re", 'hashed_string': "choujin-steiner--{0}--"} From a01c81107b5c4759406a678fe982363ce9724879 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 17 Jun 2016 14:55:03 +0200 Subject: [PATCH 015/141] Refactoring exceptions.py --- pybooru/api.py | 6 +++-- pybooru/exceptions.py | 56 +++++++++++++++++++------------------------ pybooru/pybooru.py | 21 ++++++++-------- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index 67ba8e3..d0e637b 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -8,9 +8,11 @@ ApiFunctionsMixin -- Contains all API calls. """ +# __future__ imports from __future__ import absolute_import from __future__ import unicode_literals +# pybooru imports from .exceptions import PybooruError @@ -63,8 +65,8 @@ def post_create(self, tags, file_=None, rating=None, source=None, 'post[tags]': tags, 'post[source]': source, 'post[rating]': rating, - 'post[is_rating_locked]': is_rating_locked, - 'post[is_note_locked]': is_note_locked, + 'post[is_rating_locked]': rating_locked, + 'post[is_note_locked]': note_locked, 'post[parent_id]': parent_id, 'md5': md5} file_ = {'post[file]': open(file_, 'rb')} diff --git a/pybooru/exceptions.py b/pybooru/exceptions.py index 7eaee6c..8c78a44 100644 --- a/pybooru/exceptions.py +++ b/pybooru/exceptions.py @@ -1,6 +1,13 @@ # -*- coding: utf-8 -*- -"""This module contains the exceptions.""" +"""pybooru.exceptions + +This module contains Pybooru exceptions. + +Classes: + PybooruError -- Main Pybooru exception class. + PybooruHTTPError -- Manages HTTP status errors. +""" # __furute__ imports from __future__ import absolute_import @@ -11,40 +18,25 @@ class PybooruError(Exception): - """Class to return error message. - - Init Parameters: - msg: - The error message. - - http_code: - The HTTP status code. - - url: - The URL. + """Class to return Pybooru error message.""" + pass - Attributes: - msg: Return the error message. - http_code: Return the HTTP status code. - url: return the URL. - """ - def __init__(self, msg, http_code=None, url=None): - super(PybooruError, self).__init__() +class PybooruHTTPError(PybooruError): + """Class to return HTTP error message.""" - self.msg = msg - self.http_code = http_code - self.url = url + def __init__(self, msg, http_code, url): + """Initialize PybooruHTTPError. - if http_code in HTTP_STATUS_CODES and self.url is not None: - self.msg = "{0}: {1}, {2} - {3} -- URL: {4}".format(self.msg, - http_code, HTTP_STATUS_CODES[http_code][0], - HTTP_STATUS_CODES[http_code][1], self.url) + Keyword arguments:: + msg: The error message. + http_code: The HTTP status code. + url: The URL. + """ - def __str__(self): - """Function to return error message.""" - return repr(self.msg) + if http_code in HTTP_STATUS_CODES and url is not None: + msg = "{0}: {1} - {2}, {3} - URL: {4}".format(msg, http_code, + HTTP_STATUS_CODES[http_code][0], + HTTP_STATUS_CODES[http_code][1], url) - def __repr__(self): - """Function to return self.msg repr.""" - return self.msg + super(PybooruHTTPError, self).__init__(msg) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 8433be1..d313bd1 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -16,7 +16,7 @@ # pybooru imports from . import __version__ from .api import ApiFunctionsMixin -from .exceptions import PybooruError +from .exceptions import (PybooruError, PybooruHTTPError) from .resources import SITE_LIST # External imports @@ -94,7 +94,7 @@ def _site_name_validator(self): self.hash_string = SITE_LIST[self.site_name]['hashed_string'] else: raise PybooruError( - "The site_name is not valid, specify a valid site_name") + "The 'site_name' is not valid, specify a valid 'site_name'.") def _url_validator(self): """URL validator for site_url attribute.""" @@ -114,8 +114,7 @@ def _url_validator(self): if not re.search(regex, self.site_url): raise PybooruError("Invalid URL", url=self.site_url) else: - raise PybooruError("Invalid URL scheme, use HTTP or HTTPS", - url=self.site_url) + raise PybooruError("Invalid URL scheme, use HTTP or HTTPS: {0}".format(self.site_url)) def _build_hash_string(self): """Function for build password hash string.""" @@ -166,13 +165,13 @@ def _request(self, api_call, params, method='GET', file_=None): self.client.headers.update({'content-type': None}) response = self.client.post(url, **request_args) - response.raise_for_status() - return response.json() - except requests.exceptions.HTTPError as err: - raise PybooruError("In _request: ", response.status_code, - response.url) + if response.status_code is 200: + return response.json() + else: + raise PybooruHTTPError("In _request", response.status_code, + response.url) except requests.exceptions.Timeout: raise PybooruError("Timeout! in url: {0}".format(response.url)) - except ValueError as err: + except ValueError as e: raise PybooruError("JSON Error: {0} in line {1} column {2}".format( - err.msg, err.lineno, err.colno)) + e.msg, err.lineno, e.colno)) From f9665e7d7c697fa1895dc0c93d2af0a8d13ec9e6 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 19 Jun 2016 18:01:09 +0200 Subject: [PATCH 016/141] Small fix --- pybooru/api.py | 6 +++--- pybooru/exceptions.py | 6 +++--- pybooru/pybooru.py | 15 ++++++++------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index d0e637b..7af2d6a 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -230,8 +230,8 @@ def artist_update(self, id_, name=None, urls=None, alias=None, group=None): name: The artist's name. urls: A list of URLs associated with the artist, whitespace delimited. - alias: The artist that this artist is an alias for. Simply enter the - alias artist's name. + alias: The artist that this artist is an alias for. Simply enter + the alias artist's name. group: The group or cicle that this artist is a member of. Simply enter the group's name. """ @@ -514,7 +514,7 @@ def pool_create(self, name, description, is_public): is_public: 1 or 0, whether or not the pool is public. """ params = {'pool[name]': name, 'pool[description]': description, - 'pool[name]': is_public} + 'pool[is_public]': is_public} return self._request('pool/create', params, 'POST') def pool_destroy(self, id_): diff --git a/pybooru/exceptions.py b/pybooru/exceptions.py index 8c78a44..ecfeadc 100644 --- a/pybooru/exceptions.py +++ b/pybooru/exceptions.py @@ -35,8 +35,8 @@ def __init__(self, msg, http_code, url): """ if http_code in HTTP_STATUS_CODES and url is not None: - msg = "{0}: {1} - {2}, {3} - URL: {4}".format(msg, http_code, - HTTP_STATUS_CODES[http_code][0], - HTTP_STATUS_CODES[http_code][1], url) + msg = "{0}: {1} - {2}, {3} - URL: {4}".format( + msg, http_code, HTTP_STATUS_CODES[http_code][0], + HTTP_STATUS_CODES[http_code][1], url) super(PybooruHTTPError, self).__init__(msg) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index d313bd1..f5cc355 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -25,7 +25,7 @@ import re -class Pybooru(ApiFunctionsMixin, object): +class Pybooru(ApiFunctionsMixin): """Pybooru main class (inherits: pybooru.api.ApiFunctionsMixin). To initialize Pybooru, you need to specify one of these two @@ -58,8 +58,8 @@ def __init__(self, site_name="", site_url="", username="", password="", hash_string: String that is hashed (required to login). (See the API documentation of the site for more information). - username: Your username of the site (Required only for functions that - modify the content). + username: Your username of the site (Required only for functions + that modify the content). password: Your user password in plain text (Required only for functions that modify the content). """ @@ -69,7 +69,7 @@ def __init__(self, site_name="", site_url="", username="", password="", self.username = username self.password = password self.hash_string = hash_string - self._password_hash = None + self.password_hash = None # Set HTTP Client self.client = requests.Session() @@ -114,7 +114,8 @@ def _url_validator(self): if not re.search(regex, self.site_url): raise PybooruError("Invalid URL", url=self.site_url) else: - raise PybooruError("Invalid URL scheme, use HTTP or HTTPS: {0}".format(self.site_url)) + raise PybooruError("Invalid URL scheme, use HTTP " + "or HTTPS: {0}".format(self.site_url)) def _build_hash_string(self): """Function for build password hash string.""" @@ -155,7 +156,7 @@ def _request(self, api_call, params, method='GET', file_=None): if method == 'GET': response = self.client.get(url, params=params) else: - if self._password_hash is None: + if self.password_hash is None: self._build_hash_string() params['login'] = self.username @@ -174,4 +175,4 @@ def _request(self, api_call, params, method='GET', file_=None): raise PybooruError("Timeout! in url: {0}".format(response.url)) except ValueError as e: raise PybooruError("JSON Error: {0} in line {1} column {2}".format( - e.msg, err.lineno, e.colno)) + e.msg, e.lineno, e.colno)) From 88a64d3fe2925a3a466b3616289f4ec3d78414ee Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 20 Jun 2016 02:07:57 +0200 Subject: [PATCH 017/141] Inplements Pybooru.last_call --- pybooru/exceptions.py | 9 ++++----- pybooru/pybooru.py | 22 ++++++++++++++++++++-- pybooru/resources.py | 6 +++--- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/pybooru/exceptions.py b/pybooru/exceptions.py index ecfeadc..d00ab4b 100644 --- a/pybooru/exceptions.py +++ b/pybooru/exceptions.py @@ -14,7 +14,7 @@ from __future__ import unicode_literals # pybooru imports -from .resources import HTTP_STATUS_CODES +from .resources import HTTP_STATUS_CODE class PybooruError(Exception): @@ -33,10 +33,9 @@ def __init__(self, msg, http_code, url): http_code: The HTTP status code. url: The URL. """ - - if http_code in HTTP_STATUS_CODES and url is not None: + if http_code in HTTP_STATUS_CODE and url is not None: msg = "{0}: {1} - {2}, {3} - URL: {4}".format( - msg, http_code, HTTP_STATUS_CODES[http_code][0], - HTTP_STATUS_CODES[http_code][1], url) + msg, http_code, HTTP_STATUS_CODE[http_code][0], + HTTP_STATUS_CODE[http_code][1], url) super(PybooruHTTPError, self).__init__(msg) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index f5cc355..74d4a77 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -17,7 +17,7 @@ from . import __version__ from .api import ApiFunctionsMixin from .exceptions import (PybooruError, PybooruHTTPError) -from .resources import SITE_LIST +from .resources import (SITE_LIST, HTTP_STATUS_CODE) # External imports import requests @@ -46,6 +46,7 @@ class Pybooru(ApiFunctionsMixin): username: Return user name. password: Return password in plain text. hash_string: Return hash_string of the site. + last_call: Return last call. """ def __init__(self, site_name="", site_url="", username="", password="", @@ -70,6 +71,7 @@ def __init__(self, site_name="", site_url="", username="", password="", self.password = password self.hash_string = hash_string self.password_hash = None + self.last_call = {} # Set HTTP Client self.client = requests.Session() @@ -112,11 +114,19 @@ def _url_validator(self): # Validate URL if re.match('^(?:http|https)://', self.site_url): if not re.search(regex, self.site_url): - raise PybooruError("Invalid URL", url=self.site_url) + raise PybooruError("Invalid URL: {0}".format(self.site_url)) else: raise PybooruError("Invalid URL scheme, use HTTP " "or HTTPS: {0}".format(self.site_url)) + @staticmethod + def _get_status(status_code): + """Get status message.""" + if status_code in HTTP_STATUS_CODE: + return "{0}, {1}".format(*HTTP_STATUS_CODE[status_code]) + else: + return None + def _build_hash_string(self): """Function for build password hash string.""" # Build AUTENTICATION hash_string @@ -166,6 +176,14 @@ def _request(self, api_call, params, method='GET', file_=None): self.client.headers.update({'content-type': None}) response = self.client.post(url, **request_args) + self.last_call.update({ + 'API': api_call, + 'url': response.url, + 'status_code': response.status_code, + 'status': self._get_status(response.status_code), + 'headers': response.headers + }) + if response.status_code is 200: return response.json() else: diff --git a/pybooru/resources.py b/pybooru/resources.py index 59e9197..2dfcc94 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -6,7 +6,7 @@ SITE_LIST: Is a dict that contains various based Danbooru/Moebooru, default sites. -HTTP_STATUS_CODES: +HTTP_STATUS_CODE: Is a dict that contains the http status code for Danbooru/Moebooru API. """ @@ -22,8 +22,8 @@ } -# HTTP_STATUS_CODES -HTTP_STATUS_CODES = { +# HTTP_STATUS_CODE +HTTP_STATUS_CODE = { 200: ("OK", "Request was successful"), 403: ("Forbidden", "Access denied"), 404: ("Not Found", "Not found"), From 439ea576df1a6ca262819b0e8fcae03ecf90471b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 20 Jun 2016 14:18:30 +0200 Subject: [PATCH 018/141] Adds PybooruAPIError exception --- pybooru/api.py | 11 +++++------ pybooru/exceptions.py | 11 ++++++++--- pybooru/pybooru.py | 1 - 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index 7af2d6a..e29403d 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -10,10 +10,9 @@ # __future__ imports from __future__ import absolute_import -from __future__ import unicode_literals # pybooru imports -from .exceptions import PybooruError +from .exceptions import PybooruAPIError class ApiFunctionsMixin(object): @@ -72,7 +71,7 @@ def post_create(self, tags, file_=None, rating=None, source=None, file_ = {'post[file]': open(file_, 'rb')} return self._request('post/create', params, 'POST', file_) else: - raise PybooruError("'file_' or 'source' is required.") + raise PybooruAPIError("'file_' or 'source' is required.") def post_update(self, id_, tags=None, file_=None, rating=None, source=None, is_rating_locked=None, is_note_locked=None, @@ -143,7 +142,7 @@ def post_vote(self, id_, score): params = {'id': id_, 'score': score} return self._request('post/vote', params, 'POST') else: - raise PybooruError("Value of 'score' only can be 0, 1, 2 or 3.") + raise PybooruAPIError("Value of 'score' only can be 0, 1, 2 or 3.") def tag_list(self, **params): """Get a list of tags. @@ -276,8 +275,8 @@ def comment_create(self, post_id, comment_body, anonymous=None): } return self._request('comment/create', params, 'POST') else: - raise PybooruError("Required 'post_id' and 'comment_body' " - "parameters") + raise PybooruAPIError("Required 'post_id' and 'comment_body' " + "parameters") def comment_destroy(self, id_=None): """Remove a specific comment (Requires login). diff --git a/pybooru/exceptions.py b/pybooru/exceptions.py index d00ab4b..c072fa0 100644 --- a/pybooru/exceptions.py +++ b/pybooru/exceptions.py @@ -7,23 +7,23 @@ Classes: PybooruError -- Main Pybooru exception class. PybooruHTTPError -- Manages HTTP status errors. + PybooruAPIError -- Manages all API errors. """ # __furute__ imports from __future__ import absolute_import -from __future__ import unicode_literals # pybooru imports from .resources import HTTP_STATUS_CODE class PybooruError(Exception): - """Class to return Pybooru error message.""" + """Class to catch Pybooru error message.""" pass class PybooruHTTPError(PybooruError): - """Class to return HTTP error message.""" + """Class to catch HTTP error message.""" def __init__(self, msg, http_code, url): """Initialize PybooruHTTPError. @@ -39,3 +39,8 @@ def __init__(self, msg, http_code, url): HTTP_STATUS_CODE[http_code][1], url) super(PybooruHTTPError, self).__init__(msg) + + +class PybooruAPIError(PybooruError): + """Class to catch all API errors.""" + pass diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 74d4a77..f0e0f63 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -11,7 +11,6 @@ # __furute__ imports from __future__ import absolute_import -from __future__ import unicode_literals # pybooru imports from . import __version__ From e6b57b228c1e096137650ebdac4ab4c417b1299a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 20 Jun 2016 15:09:17 +0200 Subject: [PATCH 019/141] Adds support for API versioning --- pybooru/pybooru.py | 11 +++++++++-- pybooru/resources.py | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index f0e0f63..313e919 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -42,6 +42,7 @@ class Pybooru(ApiFunctionsMixin): Attributes: site_name: Return site name. site_url: Return the URL of Danbooru/Moebooru based site. + api_version: Version of Danbooru/Moebooru API. username: Return user name. password: Return password in plain text. hash_string: Return hash_string of the site. @@ -49,12 +50,13 @@ class Pybooru(ApiFunctionsMixin): """ def __init__(self, site_name="", site_url="", username="", password="", - hash_string=""): + hash_string="", api_version="1.13.0+update.3"): """Initialize Pybooru. Keyword arguments: site_name: The site name in 'SITE_LIST', default sites. site_url: URL of on Danbooru/Moebooru based sites. + api_version: Version of Danbooru/Moebooru API. hash_string: String that is hashed (required to login). (See the API documentation of the site for more information). @@ -66,6 +68,7 @@ def __init__(self, site_name="", site_url="", username="", password="", # Attributes self.site_name = site_name.lower() self.site_url = site_url.lower() + self.api_version = api_version.lower() self.username = username self.password = password self.hash_string = hash_string @@ -92,6 +95,7 @@ def _site_name_validator(self): """Function that checks the site name and get url.""" if self.site_name in SITE_LIST: self.site_url = SITE_LIST[self.site_name]['url'] + self.api_version = SITE_LIST[self.site_name]['api_version'] self.hash_string = SITE_LIST[self.site_name]['hashed_string'] else: raise PybooruError( @@ -126,6 +130,9 @@ def _get_status(status_code): else: return None + def _build_url(self, api_call): + return "{0}/{1}.json".format(self.site_url, api_call) + def _build_hash_string(self): """Function for build password hash string.""" # Build AUTENTICATION hash_string @@ -159,7 +166,7 @@ def _request(self, api_call, params, method='GET', file_=None): file_: File to upload. """ # Build url - url = "{0}/{1}.json".format(self.site_url, api_call) + url = self._build_url(api_call) try: if method == 'GET': diff --git a/pybooru/resources.py b/pybooru/resources.py index 2dfcc94..4e021d5 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -15,9 +15,11 @@ SITE_LIST = { 'konachan': { 'url': "http://konachan.com", + 'api_version': "1.13.0+update.3", 'hashed_string': "So-I-Heard-You-Like-Mupkids-?--{0}--"}, 'yandere': { 'url': "https://yande.re", + 'api_version': "1.13.0+update.3", 'hashed_string': "choujin-steiner--{0}--"} } From e781845022dd25f32767c6bce47a7273ba5bb9ab Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 20 Jun 2016 19:45:23 +0200 Subject: [PATCH 020/141] Adds 1.13.0 API support --- pybooru/api.py | 2 +- pybooru/pybooru.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pybooru/api.py b/pybooru/api.py index e29403d..3bb85e0 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -542,7 +542,7 @@ def pool_remove_post(self, **params): """ return self._request('pool/remove_post', params, 'POST') - def favorites_list_users(self, id_): + def favorite_list_users(self, id_): """Function to return a list with all users who have added to favorites a specific post. diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 313e919..e73279e 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -131,6 +131,16 @@ def _get_status(status_code): return None def _build_url(self, api_call): + """Build request url. + + Parameters: + api_call: Base API Call. + """ + if self.api_version in ('1.13.0', '1.13.0+update.1', + '1.13.0+update.2'): + if '/' not in api_call: + return "{0}/{1}/index.json".format(self.site_url, api_call) + return "{0}/{1}.json".format(self.site_url, api_call) def _build_hash_string(self): From 7ca20cc83498df4ae821db07ff38638074d44dac Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 20 Jun 2016 23:44:05 +0200 Subject: [PATCH 021/141] Fix documentation --- pybooru/__init__.py | 7 ++++--- pybooru/api.py | 43 +++++++++++++++++++++---------------------- pybooru/pybooru.py | 21 ++++++++++----------- pybooru/resources.py | 4 ++-- 4 files changed, 37 insertions(+), 38 deletions(-) diff --git a/pybooru/__init__.py b/pybooru/__init__.py index 847e0ca..fe699b9 100644 --- a/pybooru/__init__.py +++ b/pybooru/__init__.py @@ -4,20 +4,21 @@ Pybooru ------- -Pybooru is a Python library to access API of Danbooru/Moebooru based sites. +Pybooru is a Python library to access API of Moebooru based sites. Under MIT license. Pybooru requires "requests" package to work. Pybooru modules: pybooru -- Main module of Pybooru, contains Pybooru class. - api -- Contains all Moebooru/Danbooru API functions. + api -- Contains all Moebooru API functions. exceptions -- Manages and builds Pybooru errors messages. """ -__author__ = "Daniel Luque " __version__ = "3.0.1" +__license__ = "MIT" __url__ = "http://github.com/LuqueDaniel/pybooru" +__author__ = "Daniel Luque " # pybooru imports from .pybooru import Pybooru diff --git a/pybooru/api.py b/pybooru/api.py index 3bb85e0..ecd02df 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -2,7 +2,7 @@ """pybooru.api -This module contains all API calls of Danbooru/Moebooru for Pybooru. +This module contains all API calls of Moebooru for Pybooru. Classes: ApiFunctionsMixin -- Contains all API calls. @@ -16,10 +16,10 @@ class ApiFunctionsMixin(object): - """Contains all Danbooru/Moebooru API calls. + """Contains all Moebooru API calls. - API Version: 1.13.0+update.3 - doc: http://konachan.com/help/api or https://yande.re/help/api + API Version: 1.13.0+update.3 and 1.13.0 + doc: https://yande.re/help/api or http://konachan.com/help/api """ def post_list(self, **params): @@ -48,14 +48,13 @@ def post_create(self, tags, file_=None, rating=None, source=None, file_: The file data encoded as a multipart form. Path of content. rating: The rating for the post. Can be: safe, questionable, or explicit. - source: If this is a URL, Danbooru/Moebooru will download the - file. + source: If this is a URL, Moebooru will download the file. rating_locked: Set to true to prevent others from changing the rating. note_locked: Set to true to prevent others from adding notes. parent_id: The ID of the parent post. - md5: Supply an MD5 if you want Danbooru/Moebooru to verify the file + md5: Supply an MD5 if you want Moebooru to verify the file after uploading. If the MD5 doesn't match, the post is destroyed. """ @@ -87,7 +86,7 @@ def post_update(self, id_, tags=None, file_=None, rating=None, file_: The file data ENCODED as a multipart form. rating: The rating for the post. Can be: safe, questionable, or explicit. - source: If this is a URL, Danbooru/Moebooru will download the file. + source: If this is a URL, Moebooru will download the file. rating_locked: Set to true to prevent others from changing the rating. note_locked: Set to true to prevent others from adding notes. @@ -103,7 +102,7 @@ def post_update(self, id_, tags=None, file_=None, rating=None, 'post[parent_id]': parent_id } file_ = {'post[file]': open(file_, 'rb')} - return self._request('post/update', params, 'POST') + return self._request('post/update', params, 'PUT') def post_destroy(self, id_): """Function to destroy a specific post. @@ -114,7 +113,7 @@ def post_destroy(self, id_): Parameters: id_: The id number of the post to delete. """ - return self._request('post/destroy', {'id': id_}, 'POST') + return self._request('post/destroy', {'id': id_}, 'DELETE') def post_revert_tags(self, id_, history_id): """Function to reverts a post to a previous set of tags @@ -125,7 +124,7 @@ def post_revert_tags(self, id_, history_id): history_id: The id number of the tag history. """ params = {'id': id_, 'history_id': history_id} - return self._request('post/revert_tags', params, 'POST') + return self._request('post/revert_tags', params, 'PUT') def post_vote(self, id_, score): """Action lets you vote for a post (Requires login). @@ -176,7 +175,7 @@ def tag_update(self, name=None, tag_type=None, is_ambiguous=None): 'tag[tag_type]': tag_type, 'tag[is_ambiguous]': is_ambiguous } - return self._request('tag/update', params, 'POST') + return self._request('tag/update', params, 'PUT') def tag_related(self, **params): """Get a list of related tags. @@ -241,7 +240,7 @@ def artist_update(self, id_, name=None, urls=None, alias=None, group=None): 'artist[alias]': alias, 'artist[group]': group } - return self._request('artist/update', params, 'POST') + return self._request('artist/update', params, 'PUT') def artist_destroy(self, id_): """Action to lets you remove artist (Requires login) (UNTESTED). @@ -284,7 +283,7 @@ def comment_destroy(self, id_=None): Parameters: id_: The id number of the comment to remove. """ - return self._request('comment/destroy', {'id': id_}, 'POST') + return self._request('comment/destroy', {'id': id_}, 'DELETE') def wiki_list(self, **params): """Function to retrieves a list of every wiki page. @@ -320,7 +319,7 @@ def wiki_update(self, page_title, new_title=None, page_body=None): 'wiki_page[title]': new_title, 'wiki_page[body]': page_body } - return self._request('wiki/update', params, 'POST') + return self._request('wiki/update', params, 'PUT') def wiki_show(self, **params): """Get a specific wiki page. @@ -338,7 +337,7 @@ def wiki_destroy(self, title): Parameters: title: The title of the page to delete. """ - return self._request('wiki/destroy', {'title': title}, 'POST') + return self._request('wiki/destroy', {'title': title}, 'DELETE') def wiki_lock(self, title): """Function to lock a specific wiki page (Requires login) @@ -366,7 +365,7 @@ def wiki_revert(self, title, version): version: The version to revert to. """ params = {'title': title, 'version': version} - return self._request('wiki/revert', params, 'POST') + return self._request('wiki/revert', params, 'PUT') def wiki_history(self, title): """Get history of specific wiki page. @@ -411,7 +410,7 @@ def note_revert(self, id_, version): version: The version to revert to. """ params = {'id': id_, 'version': version} - return self._request('note/revert', params, 'POST') + return self._request('note/revert', params, 'PUT') def note_create_update(self, post_id=None, coor_x=None, coor_y=None, width=None, height=None, is_active=None, body=None, @@ -502,7 +501,7 @@ def pool_update(self, id_, name=None, is_public=None, 'pool[is_public]': is_public, 'pool[description]': description } - return self._request('pool/update', params, 'POST') + return self._request('pool/update', params, 'PUT') def pool_create(self, name, description, is_public): """Function to create a pool (Require login) (UNTESTED). @@ -522,7 +521,7 @@ def pool_destroy(self, id_): Parameters: id_: The pool id number. """ - return self._request('pool/destroy', {'id': id_}, 'POST') + return self._request('pool/destroy', {'id': id_}, 'DELETE') def pool_add_post(self, **params): """Function to add a post (Require login) (UNTESTED). @@ -531,7 +530,7 @@ def pool_add_post(self, **params): pool_id: The pool to add the post to. post_id: The post to add. """ - return self._request('pool/add_post', params, 'POST') + return self._request('pool/add_post', params, 'PUT') def pool_remove_post(self, **params): """Function to remove a post (Require login) (UNTESTED). @@ -540,7 +539,7 @@ def pool_remove_post(self, **params): pool_id: The pool to remove the post to. post_id: The post to remove. """ - return self._request('pool/remove_post', params, 'POST') + return self._request('pool/remove_post', params, 'PUT') def favorite_list_users(self, id_): """Function to return a list with all users who have added to favorites diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index e73279e..704b8cc 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -41,8 +41,8 @@ class Pybooru(ApiFunctionsMixin): Attributes: site_name: Return site name. - site_url: Return the URL of Danbooru/Moebooru based site. - api_version: Version of Danbooru/Moebooru API. + site_url: Return the URL of Moebooru based site. + api_version: Version of Moebooru API. username: Return user name. password: Return password in plain text. hash_string: Return hash_string of the site. @@ -55,14 +55,14 @@ def __init__(self, site_name="", site_url="", username="", password="", Keyword arguments: site_name: The site name in 'SITE_LIST', default sites. - site_url: URL of on Danbooru/Moebooru based sites. - api_version: Version of Danbooru/Moebooru API. + site_url: URL of on Moebooru based sites. + api_version: Version of Moebooru API. hash_string: String that is hashed (required to login). (See the API documentation of the site for more information). - username: Your username of the site (Required only for functions + username: Your username of the site (Required only for functions that modify the content). - password: Your user password in plain text (Required only for + password: Your user password in plain text (Required only for functions that modify the content). """ # Attributes @@ -136,8 +136,7 @@ def _build_url(self, api_call): Parameters: api_call: Base API Call. """ - if self.api_version in ('1.13.0', '1.13.0+update.1', - '1.13.0+update.2'): + if self.api_version in ('1.13.0', '1.13.0+update.1', '1.13.0+update.2'): if '/' not in api_call: return "{0}/{1}/index.json".format(self.site_url, api_call) @@ -155,7 +154,7 @@ def _build_hash_string(self): raise PybooruError("Pybooru can't add 'password' " "to 'hash_string'") # encrypt hashed_string to SHA1 and return hexdigest string - self.password_hash = hashlib.sha1( # pylint: disable=E1101 + self.password_hash = hashlib.sha1( hash_string.encode('utf-8')).hexdigest() else: raise PybooruError("Specify the 'username' and 'password' " @@ -180,7 +179,7 @@ def _request(self, api_call, params, method='GET', file_=None): try: if method == 'GET': - response = self.client.get(url, params=params) + response = self.client.request(method, url, params=params) else: if self.password_hash is None: self._build_hash_string() @@ -190,7 +189,7 @@ def _request(self, api_call, params, method='GET', file_=None): request_args = {'data': params, 'files': file_} self.client.headers.update({'content-type': None}) - response = self.client.post(url, **request_args) + response = self.client.request(method, url, **request_args) self.last_call.update({ 'API': api_call, diff --git a/pybooru/resources.py b/pybooru/resources.py index 4e021d5..623b641 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -5,9 +5,9 @@ This module contains all resources for pybooru. SITE_LIST: - Is a dict that contains various based Danbooru/Moebooru, default sites. + Is a dict that contains various based Moebooru, default sites. HTTP_STATUS_CODE: - Is a dict that contains the http status code for Danbooru/Moebooru API. + Is a dict that contains the http status code for Moebooru API. """ From 1512526352389df9922578b183e1fc334570e36c Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 20 Jun 2016 23:48:12 +0200 Subject: [PATCH 022/141] Skip Pylint error --- pybooru/pybooru.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 704b8cc..705ab52 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -154,7 +154,7 @@ def _build_hash_string(self): raise PybooruError("Pybooru can't add 'password' " "to 'hash_string'") # encrypt hashed_string to SHA1 and return hexdigest string - self.password_hash = hashlib.sha1( + self.password_hash = hashlib.sha1( # pylint: disable=E1101 hash_string.encode('utf-8')).hexdigest() else: raise PybooruError("Specify the 'username' and 'password' " From a62f4c4e4c92d695faac4fb69293903e475cb60b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 20 Jun 2016 23:55:51 +0200 Subject: [PATCH 023/141] Updated provisional_test.py --- provisional_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/provisional_test.py b/provisional_test.py index d6bc815..b288417 100644 --- a/provisional_test.py +++ b/provisional_test.py @@ -1,7 +1,11 @@ # encoding: utf-8 +from __future__ import print_function from pybooru import Pybooru # client = Pybooru(site_url='konachan.com') client = Pybooru(site_url="http://www.konachan.com") tags = client.tag_list(order='date') +print(client.last_call) +posts = client.post_list() +print(client.last_call) From b6109d52620bfbed549c0ca6544a8cb2ffcb9c9b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 7 Jul 2016 14:31:16 +0200 Subject: [PATCH 024/141] Fix post_update --- pybooru/api.py | 7 +++++-- pybooru/pybooru.py | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pybooru/api.py b/pybooru/api.py index ecd02df..c650f5f 100644 --- a/pybooru/api.py +++ b/pybooru/api.py @@ -101,8 +101,11 @@ def post_update(self, id_, tags=None, file_=None, rating=None, 'post[is_note_locked]': is_note_locked, 'post[parent_id]': parent_id } - file_ = {'post[file]': open(file_, 'rb')} - return self._request('post/update', params, 'PUT') + if file_ is not None: + file_ = {'post[file]': open(file_, 'rb')} + return self._request('post/update', params, 'PUT', file_) + else: + return self._request('post/update', params, 'PUT') def post_destroy(self, id_): """Function to destroy a specific post. diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 705ab52..2607299 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -139,7 +139,6 @@ def _build_url(self, api_call): if self.api_version in ('1.13.0', '1.13.0+update.1', '1.13.0+update.2'): if '/' not in api_call: return "{0}/{1}/index.json".format(self.site_url, api_call) - return "{0}/{1}.json".format(self.site_url, api_call) def _build_hash_string(self): From ed2b5170fb9ac6e423a8d8f54b2410c5218d111e Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 31 Aug 2016 23:33:41 +0200 Subject: [PATCH 025/141] Refactoring Pybooru base class --- pybooru/__init__.py | 2 +- pybooru/{api.py => moebooru_api.py} | 2 +- pybooru/pybooru.py | 27 +++++++++++++++++++-------- 3 files changed, 21 insertions(+), 10 deletions(-) rename pybooru/{api.py => moebooru_api.py} (99%) diff --git a/pybooru/__init__.py b/pybooru/__init__.py index fe699b9..6c4892a 100644 --- a/pybooru/__init__.py +++ b/pybooru/__init__.py @@ -21,5 +21,5 @@ __author__ = "Daniel Luque " # pybooru imports -from .pybooru import Pybooru +from .pybooru import (Moebooru, Danbooru) from .exceptions import PybooruError diff --git a/pybooru/api.py b/pybooru/moebooru_api.py similarity index 99% rename from pybooru/api.py rename to pybooru/moebooru_api.py index c650f5f..e2ce9eb 100644 --- a/pybooru/api.py +++ b/pybooru/moebooru_api.py @@ -15,7 +15,7 @@ from .exceptions import PybooruAPIError -class ApiFunctionsMixin(object): +class MoebooruApi(object): """Contains all Moebooru API calls. API Version: 1.13.0+update.3 and 1.13.0 diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 2607299..2f8c574 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -14,7 +14,7 @@ # pybooru imports from . import __version__ -from .api import ApiFunctionsMixin +from .moebooru_api import MoebooruApi from .exceptions import (PybooruError, PybooruHTTPError) from .resources import (SITE_LIST, HTTP_STATUS_CODE) @@ -24,7 +24,7 @@ import re -class Pybooru(ApiFunctionsMixin): +class Pybooru(object): """Pybooru main class (inherits: pybooru.api.ApiFunctionsMixin). To initialize Pybooru, you need to specify one of these two @@ -49,8 +49,7 @@ class Pybooru(ApiFunctionsMixin): last_call: Return last call. """ - def __init__(self, site_name="", site_url="", username="", password="", - hash_string="", api_version="1.13.0+update.3"): + def __init__(self, site_name="", site_url="", username=""): """Initialize Pybooru. Keyword arguments: @@ -68,11 +67,7 @@ def __init__(self, site_name="", site_url="", username="", password="", # Attributes self.site_name = site_name.lower() self.site_url = site_url.lower() - self.api_version = api_version.lower() self.username = username - self.password = password - self.hash_string = hash_string - self.password_hash = None self.last_call = {} # Set HTTP Client @@ -130,6 +125,17 @@ def _get_status(status_code): else: return None + +class Moebooru(Pybooru, MoebooruApi): + def __init__(self, site_name="", site_url="", username="", password="", + hash_string="", api_version="1.13.0+update.3"): + super(Moebooru, self).__init__(site_name, site_url, username) + + self.api_version = api_version.lower() + self.password = password + self.hash_string = hash_string + self.password_hash = None + def _build_url(self, api_call): """Build request url. @@ -208,3 +214,8 @@ def _request(self, api_call, params, method='GET', file_=None): except ValueError as e: raise PybooruError("JSON Error: {0} in line {1} column {2}".format( e.msg, e.lineno, e.colno)) + + +class Danbooru(Pybooru): + def __init__(self, site_name="", site_url="", username="", api_key=""): + super(Danbooru, self).__init__(site_name, site_url, username) From 7536900974ddb8f3d3d649b459ddcabcf2c1c565 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Sep 2016 00:19:02 +0200 Subject: [PATCH 026/141] Add api_danbooru.py --- pybooru/api_danbooru.py | 4 ++++ pybooru/{moebooru_api.py => api_moebooru.py} | 6 +++--- pybooru/pybooru.py | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 pybooru/api_danbooru.py rename pybooru/{moebooru_api.py => api_moebooru.py} (99%) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py new file mode 100644 index 0000000..10612f4 --- /dev/null +++ b/pybooru/api_danbooru.py @@ -0,0 +1,4 @@ +class DanbooruApi(object): + """ + """ + pass diff --git a/pybooru/moebooru_api.py b/pybooru/api_moebooru.py similarity index 99% rename from pybooru/moebooru_api.py rename to pybooru/api_moebooru.py index e2ce9eb..0850f38 100644 --- a/pybooru/moebooru_api.py +++ b/pybooru/api_moebooru.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -"""pybooru.api +"""pybooru.moebooru_api This module contains all API calls of Moebooru for Pybooru. Classes: - ApiFunctionsMixin -- Contains all API calls. + MoebooruApi -- Contains all API calls. """ # __future__ imports @@ -18,7 +18,7 @@ class MoebooruApi(object): """Contains all Moebooru API calls. - API Version: 1.13.0+update.3 and 1.13.0 + API Versions: 1.13.0+update.3 and 1.13.0 doc: https://yande.re/help/api or http://konachan.com/help/api """ diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 2f8c574..f3ce559 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -14,7 +14,8 @@ # pybooru imports from . import __version__ -from .moebooru_api import MoebooruApi +from .api_moebooru import MoebooruApi +from .api_danbooru import DanbooruApi from .exceptions import (PybooruError, PybooruHTTPError) from .resources import (SITE_LIST, HTTP_STATUS_CODE) @@ -216,6 +217,9 @@ def _request(self, api_call, params, method='GET', file_=None): e.msg, e.lineno, e.colno)) -class Danbooru(Pybooru): +class Danbooru(Pybooru, DanbooruApi): def __init__(self, site_name="", site_url="", username="", api_key=""): super(Danbooru, self).__init__(site_name, site_url, username) + + def _request(self): + pass From e8919a336c995124558e0f6180cc44f632055799 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Sep 2016 17:51:28 +0200 Subject: [PATCH 027/141] Refactoring _request method --- pybooru/pybooru.py | 80 +++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index f3ce559..631c163 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -126,6 +126,39 @@ def _get_status(status_code): else: return None + def _request(self, url, api_call, request_args, method='GET'): + """Function to request and returning JSON data. + + Parameters: + url: Base url call. + api_call: API function to be called. + request_args: All requests parameters. + method: (Defauld: GET) HTTP method 'GET' or 'POST' + """ + try: + if method != 'GET': + self.client.headers.update({'content-type': None}) + response = self.client.request(method, url, **request_args) + + self.last_call.update({ + 'API': api_call, + 'url': response.url, + 'status_code': response.status_code, + 'status': self._get_status(response.status_code), + 'headers': response.headers + }) + + if response.status_code is 200: + return response.json() + else: + raise PybooruHTTPError("In _request", response.status_code, + response.url) + except requests.exceptions.Timeout: + raise PybooruError("Timeout! in url: {0}".format(response.url)) + except ValueError as e: + raise PybooruError("JSON Error: {0} in line {1} column {2}".format( + e.msg, e.lineno, e.colno)) + class Moebooru(Pybooru, MoebooruApi): def __init__(self, site_name="", site_url="", username="", password="", @@ -171,8 +204,8 @@ def _build_hash_string(self): "Specify the 'hash_string' parameter of the Pybooru" " object, for the functions that requires login.") - def _request(self, api_call, params, method='GET', file_=None): - """Function to request and returning JSON data. + def _get(self, api_call, params, method='GET', file_=None): + """Function to preapre an API call. Parameters: api_call: API function to be called. @@ -180,46 +213,21 @@ def _request(self, api_call, params, method='GET', file_=None): method: (Defauld: GET) HTTP method 'GET' or 'POST' file_: File to upload. """ - # Build url url = self._build_url(api_call) - try: - if method == 'GET': - response = self.client.request(method, url, params=params) - else: - if self.password_hash is None: - self._build_hash_string() + if method == 'GET': + request_args = {'params': params} + else: + if self.password_hash is None: + self._build_hash_string() - params['login'] = self.username - params['password_hash'] = self.password_hash - request_args = {'data': params, 'files': file_} + params['login'] = self.username + params['password_hash'] = self.password_hash + request_args = {'data': params, 'files': file_} - self.client.headers.update({'content-type': None}) - response = self.client.request(method, url, **request_args) - - self.last_call.update({ - 'API': api_call, - 'url': response.url, - 'status_code': response.status_code, - 'status': self._get_status(response.status_code), - 'headers': response.headers - }) - - if response.status_code is 200: - return response.json() - else: - raise PybooruHTTPError("In _request", response.status_code, - response.url) - except requests.exceptions.Timeout: - raise PybooruError("Timeout! in url: {0}".format(response.url)) - except ValueError as e: - raise PybooruError("JSON Error: {0} in line {1} column {2}".format( - e.msg, e.lineno, e.colno)) + return self._request(url, api_call, request_args, method) class Danbooru(Pybooru, DanbooruApi): def __init__(self, site_name="", site_url="", username="", api_key=""): super(Danbooru, self).__init__(site_name, site_url, username) - - def _request(self): - pass From c446b94fd875881a850d263001e610a97a2bba4b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Sep 2016 18:05:58 +0200 Subject: [PATCH 028/141] Refactoring api_moebooru.py --- pybooru/api_moebooru.py | 114 ++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 0850f38..5c34932 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -23,7 +23,7 @@ class MoebooruApi(object): """ def post_list(self, **params): - """Get a list of posts. + """_get a list of posts. Parameters: tags: The tags to search for. Any tag combination that works on the @@ -32,7 +32,7 @@ def post_list(self, **params): posts per request. page: The page number. """ - return self._request('post', params) + return self._get('post', params) def post_create(self, tags, file_=None, rating=None, source=None, rating_locked=None, note_locked=None, parent_id=None, @@ -68,7 +68,7 @@ def post_create(self, tags, file_=None, rating=None, source=None, 'post[parent_id]': parent_id, 'md5': md5} file_ = {'post[file]': open(file_, 'rb')} - return self._request('post/create', params, 'POST', file_) + return self._get('post/create', params, 'POST', file_) else: raise PybooruAPIError("'file_' or 'source' is required.") @@ -103,9 +103,9 @@ def post_update(self, id_, tags=None, file_=None, rating=None, } if file_ is not None: file_ = {'post[file]': open(file_, 'rb')} - return self._request('post/update', params, 'PUT', file_) + return self._get('post/update', params, 'PUT', file_) else: - return self._request('post/update', params, 'PUT') + return self._get('post/update', params, 'PUT') def post_destroy(self, id_): """Function to destroy a specific post. @@ -116,7 +116,7 @@ def post_destroy(self, id_): Parameters: id_: The id number of the post to delete. """ - return self._request('post/destroy', {'id': id_}, 'DELETE') + return self._get('post/destroy', {'id': id_}, 'DELETE') def post_revert_tags(self, id_, history_id): """Function to reverts a post to a previous set of tags @@ -127,7 +127,7 @@ def post_revert_tags(self, id_, history_id): history_id: The id number of the tag history. """ params = {'id': id_, 'history_id': history_id} - return self._request('post/revert_tags', params, 'PUT') + return self._get('post/revert_tags', params, 'PUT') def post_vote(self, id_, score): """Action lets you vote for a post (Requires login). @@ -142,12 +142,12 @@ def post_vote(self, id_, score): """ if score <= 3: params = {'id': id_, 'score': score} - return self._request('post/vote', params, 'POST') + return self._get('post/vote', params, 'POST') else: raise PybooruAPIError("Value of 'score' only can be 0, 1, 2 or 3.") def tag_list(self, **params): - """Get a list of tags. + """_get a list of tags. Parameters: name: The exact name of the tag. @@ -158,7 +158,7 @@ def tag_list(self, **params): order: Can be 'date', 'name' or 'count'. after_id: Return all tags that have an id number greater than this. """ - return self._request('tag', params) + return self._get('tag', params) def tag_update(self, name=None, tag_type=None, is_ambiguous=None): """Action to lets you update tag (Requires login) (UNTESTED). @@ -178,27 +178,27 @@ def tag_update(self, name=None, tag_type=None, is_ambiguous=None): 'tag[tag_type]': tag_type, 'tag[is_ambiguous]': is_ambiguous } - return self._request('tag/update', params, 'PUT') + return self._get('tag/update', params, 'PUT') def tag_related(self, **params): - """Get a list of related tags. + """_get a list of related tags. Parameters: tags: The tag names to query. type: Restrict results to this tag type. Can be general, artist, copyright, or character. """ - return self._request('tag/related', params) + return self._get('tag/related', params) def artist_list(self, **params): - """Get a list of artists. + """_get a list of artists. Parameters: name: The name (or a fragment of the name) of the artist. order: Can be date or name. page: The page number. """ - return self._request('artist', params) + return self._get('artist', params) def artist_create(self, name, urls=None, alias=None, group=None): """Function to create a artist (Requires login) (UNTESTED). @@ -218,7 +218,7 @@ def artist_create(self, name, urls=None, alias=None, group=None): 'artist[alias]': alias, 'artist[group]': group } - return self._request('artist/create', params, 'POST') + return self._get('artist/create', params, 'POST') def artist_update(self, id_, name=None, urls=None, alias=None, group=None): """Function to update an artists. @@ -243,7 +243,7 @@ def artist_update(self, id_, name=None, urls=None, alias=None, group=None): 'artist[alias]': alias, 'artist[group]': group } - return self._request('artist/update', params, 'PUT') + return self._get('artist/update', params, 'PUT') def artist_destroy(self, id_): """Action to lets you remove artist (Requires login) (UNTESTED). @@ -251,15 +251,15 @@ def artist_destroy(self, id_): Parameters: id_: The id of the artist to destroy. """ - return self._request('artist/destroy', {'id': id_}, 'POST') + return self._get('artist/destroy', {'id': id_}, 'POST') def comment_show(self, id_): - """Get a specific comment. + """_get a specific comment. Parameters: id_: The id number of the comment to retrieve. """ - return self._request('comment/show', {'id': id_}) + return self._get('comment/show', {'id': id_}) def comment_create(self, post_id, comment_body, anonymous=None): """Action to lets you create a comment (Requires login). @@ -275,7 +275,7 @@ def comment_create(self, post_id, comment_body, anonymous=None): 'comment[body]': comment_body, 'comment[anonymous]': anonymous } - return self._request('comment/create', params, 'POST') + return self._get('comment/create', params, 'POST') else: raise PybooruAPIError("Required 'post_id' and 'comment_body' " "parameters") @@ -286,7 +286,7 @@ def comment_destroy(self, id_=None): Parameters: id_: The id number of the comment to remove. """ - return self._request('comment/destroy', {'id': id_}, 'DELETE') + return self._get('comment/destroy', {'id': id_}, 'DELETE') def wiki_list(self, **params): """Function to retrieves a list of every wiki page. @@ -297,7 +297,7 @@ def wiki_list(self, **params): limit: The number of pages to retrieve (Default: 100). page: The page number. """ - return self._request('wiki', params) + return self._get('wiki', params) def wiki_create(self, title, body): """Action to lets you create a wiki page (Requires login) (UNTESTED). @@ -307,7 +307,7 @@ def wiki_create(self, title, body): body: The body of the wiki page. """ params = {'wiki_page[title]': title, 'wiki_page[body]': body} - return self._request('wiki/create', params, 'POST') + return self._get('wiki/create', params, 'POST') def wiki_update(self, page_title, new_title=None, page_body=None): """Action to lets you update a wiki page (Requires login) (UNTESTED). @@ -322,16 +322,16 @@ def wiki_update(self, page_title, new_title=None, page_body=None): 'wiki_page[title]': new_title, 'wiki_page[body]': page_body } - return self._request('wiki/update', params, 'PUT') + return self._get('wiki/update', params, 'PUT') def wiki_show(self, **params): - """Get a specific wiki page. + """_get a specific wiki page. Parameters: title: The title of the wiki page to retrieve. version: The version of the page to retrieve. """ - return self._request('wiki/show', params) + return self._get('wiki/show', params) def wiki_destroy(self, title): """Function to delete a specific wiki page (Requires login) @@ -340,7 +340,7 @@ def wiki_destroy(self, title): Parameters: title: The title of the page to delete. """ - return self._request('wiki/destroy', {'title': title}, 'DELETE') + return self._get('wiki/destroy', {'title': title}, 'DELETE') def wiki_lock(self, title): """Function to lock a specific wiki page (Requires login) @@ -349,7 +349,7 @@ def wiki_lock(self, title): Parameters: title: The title of the page to lock. """ - return self._request('wiki/lock', {'title': title}, 'POST') + return self._get('wiki/lock', {'title': title}, 'POST') def wiki_unlock(self, title): """Function to unlock a specific wiki page (Requires login) @@ -358,7 +358,7 @@ def wiki_unlock(self, title): Parameters: title: The title of the page to unlock. """ - return self._request('wiki/unlock', {'title': title}, 'POST') + return self._get('wiki/unlock', {'title': title}, 'POST') def wiki_revert(self, title, version): """Function to revert a specific wiki page (Requires login) (UNTESTED). @@ -368,23 +368,23 @@ def wiki_revert(self, title, version): version: The version to revert to. """ params = {'title': title, 'version': version} - return self._request('wiki/revert', params, 'PUT') + return self._get('wiki/revert', params, 'PUT') def wiki_history(self, title): - """Get history of specific wiki page. + """_get history of specific wiki page. Parameters: title: The title of the wiki page to retrieve versions for. """ - return self._request('wiki/history', {'title': title}) + return self._get('wiki/history', {'title': title}) def note_list(self, **params): - """Get note list. + """_get note list. Parameters: post_id: The post id number to retrieve notes for. """ - return self._request('note', params) + return self._get('note', params) def note_search(self, query): """Search specific note. @@ -392,10 +392,10 @@ def note_search(self, query): Parameters: query: A word or phrase to search for. """ - return self._request('note/search', {'query': query}) + return self._get('note/search', {'query': query}) def notes_history(self, **params): - """Get history of notes. + """_get history of notes. Parameters: post_id: The post id number to retrieve note versions for. @@ -403,7 +403,7 @@ def notes_history(self, **params): limit: How many versions to retrieve (Default: 10). page: The note id number to retrieve versions for. """ - return self._request('note/history', params) + return self._get('note/history', params) def note_revert(self, id_, version): """Function to revert a specific note (Requires login) (UNTESTED). @@ -413,7 +413,7 @@ def note_revert(self, id_, version): version: The version to revert to. """ params = {'id': id_, 'version': version} - return self._request('note/revert', params, 'PUT') + return self._get('note/revert', params, 'PUT') def note_create_update(self, post_id=None, coor_x=None, coor_y=None, width=None, height=None, is_active=None, body=None, @@ -442,51 +442,51 @@ def note_create_update(self, post_id=None, coor_x=None, coor_y=None, 'note[body]': body, 'note[is_active]': is_active } - return self._request('note/update', params, 'POST') + return self._get('note/update', params, 'POST') def user_search(self, **params): """Search users. - If you don't specify any parameters you'll get a listing of all users. + If you don't specify any parameters you'll _get a listing of all users. Parameters: id: The id number of the user. name: The name of the user. """ - return self._request('user', params) + return self._get('user', params) def forum_list(self, **params): - """Function to get forum posts. + """Function to _get forum posts. - If you don't specify any parameters you'll get a listing of all users. + If you don't specify any parameters you'll _get a listing of all users. Parameters: parent_id: The parent ID number. You'll return all the responses to that forum post. """ - return self._request('forum', params) + return self._get('forum', params) def pool_list(self, **params): - """Function to get pools. + """Function to _get pools. - If you don't specify any parameters you'll get a list of all pools. + If you don't specify any parameters you'll _get a list of all pools. Parameters: query: The title. page: The page. """ - return self._request('pool', params) + return self._get('pool', params) def pool_posts(self, **params): - """Function to get pools posts. + """Function to _get pools posts. - If you don't specify any parameters you'll get a list of all pools. + If you don't specify any parameters you'll _get a list of all pools. Parameters: id: The pool id number. page: The page. """ - return self._request('pool/show', params) + return self._get('pool/show', params) def pool_update(self, id_, name=None, is_public=None, description=None): @@ -504,7 +504,7 @@ def pool_update(self, id_, name=None, is_public=None, 'pool[is_public]': is_public, 'pool[description]': description } - return self._request('pool/update', params, 'PUT') + return self._get('pool/update', params, 'PUT') def pool_create(self, name, description, is_public): """Function to create a pool (Require login) (UNTESTED). @@ -516,7 +516,7 @@ def pool_create(self, name, description, is_public): """ params = {'pool[name]': name, 'pool[description]': description, 'pool[is_public]': is_public} - return self._request('pool/create', params, 'POST') + return self._get('pool/create', params, 'POST') def pool_destroy(self, id_): """Function to destroy a specific pool (Require login) (UNTESTED). @@ -524,7 +524,7 @@ def pool_destroy(self, id_): Parameters: id_: The pool id number. """ - return self._request('pool/destroy', {'id': id_}, 'DELETE') + return self._get('pool/destroy', {'id': id_}, 'DELETE') def pool_add_post(self, **params): """Function to add a post (Require login) (UNTESTED). @@ -533,7 +533,7 @@ def pool_add_post(self, **params): pool_id: The pool to add the post to. post_id: The post to add. """ - return self._request('pool/add_post', params, 'PUT') + return self._get('pool/add_post', params, 'PUT') def pool_remove_post(self, **params): """Function to remove a post (Require login) (UNTESTED). @@ -542,7 +542,7 @@ def pool_remove_post(self, **params): pool_id: The pool to remove the post to. post_id: The post to remove. """ - return self._request('pool/remove_post', params, 'PUT') + return self._get('pool/remove_post', params, 'PUT') def favorite_list_users(self, id_): """Function to return a list with all users who have added to favorites @@ -551,6 +551,6 @@ def favorite_list_users(self, id_): Parameters: id_: The post id. """ - response = self._request('favorite/list_users', {'id': id_}) + response = self._get('favorite/list_users', {'id': id_}) # Return list with users return response['favorited_users'].split(',') From 9b3ad2efb0023edef25927b543482ff6dfba0995 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Sep 2016 22:46:06 +0200 Subject: [PATCH 029/141] Refactoring pybooru module and fix some bugs --- pybooru/__init__.py | 9 ++- pybooru/api_danbooru.py | 22 ++++++- pybooru/api_moebooru.py | 20 +++---- pybooru/danbooru.py | 41 +++++++++++++ pybooru/moebooru.py | 128 ++++++++++++++++++++++++++++++++++++++++ pybooru/pybooru.py | 115 +++--------------------------------- pybooru/resources.py | 2 +- 7 files changed, 217 insertions(+), 120 deletions(-) create mode 100644 pybooru/danbooru.py create mode 100644 pybooru/moebooru.py diff --git a/pybooru/__init__.py b/pybooru/__init__.py index 6c4892a..ed0fb82 100644 --- a/pybooru/__init__.py +++ b/pybooru/__init__.py @@ -11,8 +11,12 @@ Pybooru modules: pybooru -- Main module of Pybooru, contains Pybooru class. - api -- Contains all Moebooru API functions. + moebooru -- Contains Moebooru main class. + danbooru -- Contains Danbooru main class. + api_moebooru -- Contains all Moebooru API functions. + api_danbooru -- Contains all Danbooru API functions. exceptions -- Manages and builds Pybooru errors messages. + resources -- Contains all resources for Pybooru. """ __version__ = "3.0.1" @@ -21,5 +25,6 @@ __author__ = "Daniel Luque " # pybooru imports -from .pybooru import (Moebooru, Danbooru) +from .moebooru import Moebooru +from .danbooru import Danbooru from .exceptions import PybooruError diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 10612f4..bfa95e6 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1,4 +1,24 @@ +# -*- coding: utf-8 -*- + +"""pybooru.api_danbooru + +This module contains all API calls of Danbooru for Pybooru. + +Classes: + Danbooru -- Contains all API calls. +""" + +# __future__ imports +from __future__ import absolute_import + +# pybooru imports +from .exceptions import PybooruAPIError + + class DanbooruApi(object): - """ + """Contains all Danbooru API calls. + + API Versions: v2.105.0 + doc: https://danbooru.donmai.us/wiki_pages/43568 """ pass diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 5c34932..e6cb759 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -"""pybooru.moebooru_api +"""pybooru.api_moebooru This module contains all API calls of Moebooru for Pybooru. @@ -23,7 +23,7 @@ class MoebooruApi(object): """ def post_list(self, **params): - """_get a list of posts. + """Get a list of posts. Parameters: tags: The tags to search for. Any tag combination that works on the @@ -147,7 +147,7 @@ def post_vote(self, id_, score): raise PybooruAPIError("Value of 'score' only can be 0, 1, 2 or 3.") def tag_list(self, **params): - """_get a list of tags. + """Get a list of tags. Parameters: name: The exact name of the tag. @@ -181,7 +181,7 @@ def tag_update(self, name=None, tag_type=None, is_ambiguous=None): return self._get('tag/update', params, 'PUT') def tag_related(self, **params): - """_get a list of related tags. + """Get a list of related tags. Parameters: tags: The tag names to query. @@ -191,7 +191,7 @@ def tag_related(self, **params): return self._get('tag/related', params) def artist_list(self, **params): - """_get a list of artists. + """Get a list of artists. Parameters: name: The name (or a fragment of the name) of the artist. @@ -254,7 +254,7 @@ def artist_destroy(self, id_): return self._get('artist/destroy', {'id': id_}, 'POST') def comment_show(self, id_): - """_get a specific comment. + """Get a specific comment. Parameters: id_: The id number of the comment to retrieve. @@ -325,7 +325,7 @@ def wiki_update(self, page_title, new_title=None, page_body=None): return self._get('wiki/update', params, 'PUT') def wiki_show(self, **params): - """_get a specific wiki page. + """Get a specific wiki page. Parameters: title: The title of the wiki page to retrieve. @@ -371,7 +371,7 @@ def wiki_revert(self, title, version): return self._get('wiki/revert', params, 'PUT') def wiki_history(self, title): - """_get history of specific wiki page. + """Get history of specific wiki page. Parameters: title: The title of the wiki page to retrieve versions for. @@ -379,7 +379,7 @@ def wiki_history(self, title): return self._get('wiki/history', {'title': title}) def note_list(self, **params): - """_get note list. + """Get note list. Parameters: post_id: The post id number to retrieve notes for. @@ -395,7 +395,7 @@ def note_search(self, query): return self._get('note/search', {'query': query}) def notes_history(self, **params): - """_get history of notes. + """Get history of notes. Parameters: post_id: The post id number to retrieve note versions for. diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py new file mode 100644 index 0000000..f040cc5 --- /dev/null +++ b/pybooru/danbooru.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +"""pybooru.danbooru + +This module contains Danbooru class for access to API calls, +authentication, build url and return JSON response. + +Classes: + Danbooru -- Danbooru classs. +""" + +# Pybooru imports +from .pybooru import Pybooru +from .api_danbooru import DanbooruApi + + +class Danbooru(Pybooru, DanbooruApi): + """Danbooru class (inherits: Pybooru and DanbooruApi). + + To initialize Pybooru, you need to specify one of these two + parameters: 'site_name' or 'site_url'. If you specify 'site_name', Pybooru + checks whether there is in the list of default sites (You can get list + of sites in the 'resources' module). + + To specify a site that isn't in list of default sites, you need use + 'site_url' parameter and specify url. + + Some actions may require you to log in. always specify two parameters to + log in: 'username' and 'api_key'. Default sites has an + associate hash string. + + Attributes: + site_name: Return site name. + site_url: Return the URL of Moebooru based site. + username: Return user name. + api_key: Return API key. + last_call: Return last call. + """ + + def __init__(self, site_name="", site_url="", username="", api_key=""): + super(Danbooru, self).__init__(site_name, site_url, username) diff --git a/pybooru/moebooru.py b/pybooru/moebooru.py new file mode 100644 index 0000000..3d6a176 --- /dev/null +++ b/pybooru/moebooru.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- + +"""pybooru.moebooru + +This module contains Moebooru class for access to API calls, +authentication, build url and return JSON response. + +Classes: + Moebooru -- Moebooru classs. +""" + +# __furute__ imports +from __future__ import absolute_import + +# External imports +import hashlib + +# Pybooru imports +from .pybooru import Pybooru +from .api_moebooru import MoebooruApi +from .exceptions import PybooruError +from .resources import SITE_LIST + + +class Moebooru(Pybooru, MoebooruApi): + """Moebooru class (inherits: Pybooru and MoebooruApi). + + To initialize Pybooru, you need to specify one of these two + parameters: 'site_name' or 'site_url'. If you specify 'site_name', Pybooru + checks whether there is in the list of default sites (You can get list + of sites in the 'resources' module). + + To specify a site that isn't in list of default sites, you need use + 'site_url' parameter and specify url. + + Some actions may require you to log in. always specify three parameters to + log in: 'hash_string', 'username' and 'password'. Default sites has an + associate hash string. + + Attributes: + site_name: Return site name. + site_url: Return the URL of Moebooru based site. + api_version: Version of Moebooru API. + username: Return user name. + password: Return password in plain text. + hash_string: Return hash_string of the site. + last_call: Return last call. + """ + + def __init__(self, site_name="", site_url="", username="", password="", + hash_string="", api_version="1.13.0+update.3"): + """Initialize Moebooru. + + Keyword arguments: + site_name: The site name in 'SITE_LIST', default sites. + site_url: URL of on Moebooru based sites. + api_version: Version of Moebooru API. + hash_string: String that is hashed (required to login). + (See the API documentation of the site for more + information). + username: Your username of the site (Required only for functions + that modify the content). + password: Your user password in plain text (Required only for + functions that modify the content). + """ + super(Moebooru, self).__init__(site_name, site_url, username) + + self.api_version = api_version.lower() + self.password = password + self.password_hash = None + + def _build_url(self, api_call): + """Build request url. + + Parameters: + api_call: Base API Call. + """ + if self.api_version in ('1.13.0', '1.13.0+update.1', '1.13.0+update.2'): + if '/' not in api_call: + return "{0}/{1}/index.json".format(self.site_url, api_call) + return "{0}/{1}.json".format(self.site_url, api_call) + + def _build_hash_string(self): + """Function for build password hash string.""" + # Build AUTENTICATION hash_string + # Check if hash_string exists + if self.site_name in SITE_LIST or self.hash_string is not "": + if self.username and self.password is not "": + try: + hash_string = self.hash_string.format(self.password) + except TypeError: + raise PybooruError("Pybooru can't add 'password' " + "to 'hash_string'") + # encrypt hashed_string to SHA1 and return hexdigest string + self.password_hash = hashlib.sha1( # pylint: disable=E1101 + hash_string.encode('utf-8')).hexdigest() + else: + raise PybooruError("Specify the 'username' and 'password' " + "parameters of the Pybooru object, for " + "setting 'password_hash' attribute.") + else: + raise PybooruError( + "Specify the 'hash_string' parameter of the Pybooru" + " object, for the functions that requires login.") + + def _get(self, api_call, params, method='GET', file_=None): + """Function to preapre API call. + + Parameters: + api_call: API function to be called. + params: API function parameters. + method: (Defauld: GET) HTTP method 'GET' or 'POST' + file_: File to upload. + """ + url = self._build_url(api_call) + + if method == 'GET': + request_args = {'params': params} + else: + if self.password_hash is None: + self._build_hash_string() + + params['login'] = self.username + params['password_hash'] = self.password_hash + request_args = {'data': params, 'files': file_} + + # Do call + return self._request(url, api_call, request_args, method) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 631c163..5d806bd 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -3,50 +3,32 @@ """pybooru.pybooru This module contains pybooru main class for access to API calls, -authentication, build urls and return JSON response. +authentication and return JSON response. Classes: - Pybooru -- Main pybooru classs, define Pybooru objectself. + Pybooru -- Main pybooru classs, define Pybooru object. """ # __furute__ imports from __future__ import absolute_import +# External imports +import requests +import re + # pybooru imports from . import __version__ -from .api_moebooru import MoebooruApi -from .api_danbooru import DanbooruApi from .exceptions import (PybooruError, PybooruHTTPError) from .resources import (SITE_LIST, HTTP_STATUS_CODE) -# External imports -import requests -import hashlib -import re - class Pybooru(object): - """Pybooru main class (inherits: pybooru.api.ApiFunctionsMixin). - - To initialize Pybooru, you need to specify one of these two - parameters: 'site_name' or 'site_url'. If you specify 'site_name', Pybooru - checks whether there is in the list of default sites (You can get list - of sites in the 'resources' module). - - To specify a site that isn't in list of default sites, you need use - 'site_url' parameter and specify url. - - Some actions may require you to log in. always specify three parameters to - log in: 'hash_string', 'username' and 'password'. Default sites has an - associate hash string. + """Pybooru main class. Attributes: site_name: Return site name. - site_url: Return the URL of Moebooru based site. - api_version: Version of Moebooru API. + site_url: Return the URL of Moebooru/Danbooru based site. username: Return user name. - password: Return password in plain text. - hash_string: Return hash_string of the site. last_call: Return last call. """ @@ -55,15 +37,9 @@ def __init__(self, site_name="", site_url="", username=""): Keyword arguments: site_name: The site name in 'SITE_LIST', default sites. - site_url: URL of on Moebooru based sites. - api_version: Version of Moebooru API. - hash_string: String that is hashed (required to login). - (See the API documentation of the site for more - information). + site_url: URL of on Moebooru/Danbooru based sites. username: Your username of the site (Required only for functions that modify the content). - password: Your user password in plain text (Required only for - functions that modify the content). """ # Attributes self.site_name = site_name.lower() @@ -158,76 +134,3 @@ def _request(self, url, api_call, request_args, method='GET'): except ValueError as e: raise PybooruError("JSON Error: {0} in line {1} column {2}".format( e.msg, e.lineno, e.colno)) - - -class Moebooru(Pybooru, MoebooruApi): - def __init__(self, site_name="", site_url="", username="", password="", - hash_string="", api_version="1.13.0+update.3"): - super(Moebooru, self).__init__(site_name, site_url, username) - - self.api_version = api_version.lower() - self.password = password - self.hash_string = hash_string - self.password_hash = None - - def _build_url(self, api_call): - """Build request url. - - Parameters: - api_call: Base API Call. - """ - if self.api_version in ('1.13.0', '1.13.0+update.1', '1.13.0+update.2'): - if '/' not in api_call: - return "{0}/{1}/index.json".format(self.site_url, api_call) - return "{0}/{1}.json".format(self.site_url, api_call) - - def _build_hash_string(self): - """Function for build password hash string.""" - # Build AUTENTICATION hash_string - # Check if hash_string exists - if self.site_name in SITE_LIST or self.hash_string is not "": - if self.username and self.password is not "": - try: - hash_string = self.hash_string.format(self.password) - except TypeError: - raise PybooruError("Pybooru can't add 'password' " - "to 'hash_string'") - # encrypt hashed_string to SHA1 and return hexdigest string - self.password_hash = hashlib.sha1( # pylint: disable=E1101 - hash_string.encode('utf-8')).hexdigest() - else: - raise PybooruError("Specify the 'username' and 'password' " - "parameters of the Pybooru object, for " - "setting 'password_hash' attribute.") - else: - raise PybooruError( - "Specify the 'hash_string' parameter of the Pybooru" - " object, for the functions that requires login.") - - def _get(self, api_call, params, method='GET', file_=None): - """Function to preapre an API call. - - Parameters: - api_call: API function to be called. - params: API function parameters. - method: (Defauld: GET) HTTP method 'GET' or 'POST' - file_: File to upload. - """ - url = self._build_url(api_call) - - if method == 'GET': - request_args = {'params': params} - else: - if self.password_hash is None: - self._build_hash_string() - - params['login'] = self.username - params['password_hash'] = self.password_hash - request_args = {'data': params, 'files': file_} - - return self._request(url, api_call, request_args, method) - - -class Danbooru(Pybooru, DanbooruApi): - def __init__(self, site_name="", site_url="", username="", api_key=""): - super(Danbooru, self).__init__(site_name, site_url, username) diff --git a/pybooru/resources.py b/pybooru/resources.py index 623b641..7d5eb2b 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -2,7 +2,7 @@ """pybooru.resources -This module contains all resources for pybooru. +This module contains all resources for Pybooru. SITE_LIST: Is a dict that contains various based Moebooru, default sites. From 5ef32ff0d11dda8a94ae4bb9fda5be7a2f48524f Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 3 Sep 2016 15:13:20 +0200 Subject: [PATCH 030/141] Implement _get method of Danbooru object --- pybooru/api_danbooru.py | 1 + pybooru/danbooru.py | 16 +++++++++++++++- pybooru/pybooru.py | 7 +++++-- pybooru/resources.py | 4 +++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index bfa95e6..9c9b46a 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -21,4 +21,5 @@ class DanbooruApi(object): API Versions: v2.105.0 doc: https://danbooru.donmai.us/wiki_pages/43568 """ + pass diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index f040cc5..db947a5 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -27,7 +27,7 @@ class Danbooru(Pybooru, DanbooruApi): Some actions may require you to log in. always specify two parameters to log in: 'username' and 'api_key'. Default sites has an - associate hash string. + associate API key. Attributes: site_name: Return site name. @@ -39,3 +39,17 @@ class Danbooru(Pybooru, DanbooruApi): def __init__(self, site_name="", site_url="", username="", api_key=""): super(Danbooru, self).__init__(site_name, site_url, username) + + self.api_key = api_key + + def _get(self, api_call, params, method='GET', file_=None): + url = "{0}".format(self.site_url) + + if method == 'GET': + request_args = {'params': params} + else: + request_args = {'auth': (self.username, self.api_key), + 'data': params, 'files': file_} + + # Do call + return self.requests(url, api_call, request_args, method) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 5d806bd..d26b818 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -67,8 +67,10 @@ def _site_name_validator(self): """Function that checks the site name and get url.""" if self.site_name in SITE_LIST: self.site_url = SITE_LIST[self.site_name]['url'] - self.api_version = SITE_LIST[self.site_name]['api_version'] - self.hash_string = SITE_LIST[self.site_name]['hashed_string'] + # Only for Moebooru + if 'api_version' and 'hashed_string' in SITE_LIST[self.site_name]: + self.api_version = SITE_LIST[self.site_name]['api_version'] + self.hash_string = SITE_LIST[self.site_name]['hashed_string'] else: raise PybooruError( "The 'site_name' is not valid, specify a valid 'site_name'.") @@ -113,6 +115,7 @@ def _request(self, url, api_call, request_args, method='GET'): """ try: if method != 'GET': + # Reset content-type for data encoded as a multipart form self.client.headers.update({'content-type': None}) response = self.client.request(method, url, **request_args) diff --git a/pybooru/resources.py b/pybooru/resources.py index 7d5eb2b..d2a38b3 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -20,7 +20,9 @@ 'yandere': { 'url': "https://yande.re", 'api_version': "1.13.0+update.3", - 'hashed_string': "choujin-steiner--{0}--"} + 'hashed_string': "choujin-steiner--{0}--"}, + 'danbooru': { + 'url': "http://danbooru.donmai.us"} } From 07ab03d40705193aa4fef198bd187acab7f17fd8 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 3 Sep 2016 16:32:30 +0200 Subject: [PATCH 031/141] Danbooru: implementing post_list() --- pybooru/api_danbooru.py | 15 ++++++++++++++- pybooru/danbooru.py | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 9c9b46a..85d381f 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -22,4 +22,17 @@ class DanbooruApi(object): doc: https://danbooru.donmai.us/wiki_pages/43568 """ - pass + def post_list(self, **params): + """Get a list of posts. + + Parameters: + limit: How many posts you want to retrieve. There is a hard limit + of 100 posts per request. + page: The page number. + tags: The tags to search for. Any tag combination that works on the + web site will work here. This includes all the meta-tags. + raw: When this parameter is set the tags parameter will not be + parsed for aliased tags, metatags or multiple tags, and will + instead be parsed as a single literal tag. + """ + return self._get('posts.json', params) diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index db947a5..332f746 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -43,7 +43,7 @@ def __init__(self, site_name="", site_url="", username="", api_key=""): self.api_key = api_key def _get(self, api_call, params, method='GET', file_=None): - url = "{0}".format(self.site_url) + url = "{0}/{1}".format(self.site_url, api_call) if method == 'GET': request_args = {'params': params} @@ -52,4 +52,4 @@ def _get(self, api_call, params, method='GET', file_=None): 'data': params, 'files': file_} # Do call - return self.requests(url, api_call, request_args, method) + return self._request(url, api_call, request_args, method) From c5f2e51bdb9fe1062cdd53882ff9d57de12862a8 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 3 Sep 2016 16:40:50 +0200 Subject: [PATCH 032/141] Danbooru: implement post_show() --- pybooru/api_danbooru.py | 8 ++++++++ pybooru/danbooru.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 85d381f..9ca1dc1 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -36,3 +36,11 @@ def post_list(self, **params): instead be parsed as a single literal tag. """ return self._get('posts.json', params) + + def post_show(self, id_): + """Get a post + + Parameters: + id_: where id_ is the post id. + """ + return self._get("/posts/{0}.json".format(id_)) diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index 332f746..747326d 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -42,7 +42,7 @@ def __init__(self, site_name="", site_url="", username="", api_key=""): self.api_key = api_key - def _get(self, api_call, params, method='GET', file_=None): + def _get(self, api_call, params=None, method='GET', file_=None): url = "{0}/{1}".format(self.site_url, api_call) if method == 'GET': From 0332027faa99d2e67e7eac64f8c00a22bd3e9b03 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 3 Sep 2016 21:29:56 +0200 Subject: [PATCH 033/141] Danbooru: implement post_update() --- pybooru/api_danbooru.py | 20 ++++++++++++++++++++ pybooru/api_moebooru.py | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 9ca1dc1..6012993 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -44,3 +44,23 @@ def post_show(self, id_): id_: where id_ is the post id. """ return self._get("/posts/{0}.json".format(id_)) + + def post_update(self, id_, tag_string=None, rating=None, source=None, + parent_id=None): + """Update a specific post. + + Parameters: + id_: The id number of the post to update. + tag_string: A space delimited list of tags. + rating: The rating for the post. Can be: safe, questionable, or + explicit. + source: If this is a URL, Danbooru will download the file. + parent_id: The ID of the parent post. + """ + params = { + 'post[tag_string]': tag_string, + 'post[rating]': rating, + 'ost[source]': source, + 'post[parent_id]': parent_id + } + return self._get('/posts/{0}.json'.format(id_), params, 'PUT') diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index e6cb759..54e2665 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -75,7 +75,7 @@ def post_create(self, tags, file_=None, rating=None, source=None, def post_update(self, id_, tags=None, file_=None, rating=None, source=None, is_rating_locked=None, is_note_locked=None, parent_id=None): - """Function update a specific post. + """Update a specific post. Only the 'id_' parameter is required. Leave the other parameters blank if you don't want to change them (Requires login). From 119175d9db9d20b81acd23f2bef4fa522c59cfbc Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 3 Sep 2016 22:28:00 +0200 Subject: [PATCH 034/141] Danbooru: implement post_revert() --- pybooru/api_danbooru.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 6012993..eb76206 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -43,7 +43,7 @@ def post_show(self, id_): Parameters: id_: where id_ is the post id. """ - return self._get("/posts/{0}.json".format(id_)) + return self._get('/posts/{0}.json'.format(id_)) def post_update(self, id_, tag_string=None, rating=None, source=None, parent_id=None): @@ -64,3 +64,12 @@ def post_update(self, id_, tag_string=None, rating=None, source=None, 'post[parent_id]': parent_id } return self._get('/posts/{0}.json'.format(id_), params, 'PUT') + + def post_revert(self, id_, version_id): + """Function to reverts a post to a previous version (Requires login). + + Parameters: + version_id: REQUIRED The post version id to revert to. + """ + return self._get('/posts/{0}/revert.json'.format(id_), + {'version_id': version_id}, 'PUT') From ad0a2e45bab23cc832b5cef33fc9a4f1e47f7387 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 4 Sep 2016 14:40:39 +0200 Subject: [PATCH 035/141] Danbooru: implement post_copy_notes() --- pybooru/api_danbooru.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index eb76206..5f440a8 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -38,7 +38,7 @@ def post_list(self, **params): return self._get('posts.json', params) def post_show(self, id_): - """Get a post + """Get a post. Parameters: id_: where id_ is the post id. @@ -47,7 +47,7 @@ def post_show(self, id_): def post_update(self, id_, tag_string=None, rating=None, source=None, parent_id=None): - """Update a specific post. + """Update a specific post (Requires login). Parameters: id_: The id number of the post to update. @@ -69,7 +69,18 @@ def post_revert(self, id_, version_id): """Function to reverts a post to a previous version (Requires login). Parameters: + id_: REQUIRED post id. version_id: REQUIRED The post version id to revert to. """ return self._get('/posts/{0}/revert.json'.format(id_), {'version_id': version_id}, 'PUT') + + def post_copy_notes(self, id_, other_post_id): + """Function to copy notes (requires login). + + Parameters: + id_: Post id. + other_post_id: REQUIRED The id of the post to copy notes to. + """ + return self._get('/posts/{0}/copy_notes.json'.format(id_), + {'other_post_id': other_post_id}, 'PUT') From 28c8d1cc6df216dfe1f3bcfa3eb70bb590204613 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 4 Sep 2016 14:51:20 +0200 Subject: [PATCH 036/141] Danbooru: implement post_vote() --- pybooru/api_danbooru.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 5f440a8..378f797 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -41,7 +41,7 @@ def post_show(self, id_): """Get a post. Parameters: - id_: where id_ is the post id. + id_: REQUIRED Where id_ is the post id. """ return self._get('/posts/{0}.json'.format(id_)) @@ -50,7 +50,7 @@ def post_update(self, id_, tag_string=None, rating=None, source=None, """Update a specific post (Requires login). Parameters: - id_: The id number of the post to update. + id_: REQUIRED The id number of the post to update. tag_string: A space delimited list of tags. rating: The rating for the post. Can be: safe, questionable, or explicit. @@ -79,8 +79,19 @@ def post_copy_notes(self, id_, other_post_id): """Function to copy notes (requires login). Parameters: - id_: Post id. + id_: REQUIRED Post id. other_post_id: REQUIRED The id of the post to copy notes to. """ return self._get('/posts/{0}/copy_notes.json'.format(id_), {'other_post_id': other_post_id}, 'PUT') + + def post_vote(self, id_, score): + """Action lets you vote for a post (Requires login). + Danbooru: Post votes/create + + Parameters: + id_: REQUIRED Ppost id. + score: REQUIRED Can be: up, down. + """ + return self._get('/posts/{0}/votes.json'.format(id_), {'score': score}, + 'POST') From effc3eb6de3f066ada98610f544848d623234ba1 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 4 Sep 2016 19:40:20 +0200 Subject: [PATCH 037/141] Danbooru: implement post_flag_list() --- pybooru/api_danbooru.py | 31 +++++++++++++++++++++++++++---- pybooru/danbooru.py | 10 +++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 378f797..c3ac4e0 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -63,7 +63,8 @@ def post_update(self, id_, tag_string=None, rating=None, source=None, 'ost[source]': source, 'post[parent_id]': parent_id } - return self._get('/posts/{0}.json'.format(id_), params, 'PUT') + return self._get('/posts/{0}.json'.format(id_), params, 'PUT', + login=True) def post_revert(self, id_, version_id): """Function to reverts a post to a previous version (Requires login). @@ -73,7 +74,7 @@ def post_revert(self, id_, version_id): version_id: REQUIRED The post version id to revert to. """ return self._get('/posts/{0}/revert.json'.format(id_), - {'version_id': version_id}, 'PUT') + {'version_id': version_id}, 'PUT', login=True) def post_copy_notes(self, id_, other_post_id): """Function to copy notes (requires login). @@ -83,7 +84,7 @@ def post_copy_notes(self, id_, other_post_id): other_post_id: REQUIRED The id of the post to copy notes to. """ return self._get('/posts/{0}/copy_notes.json'.format(id_), - {'other_post_id': other_post_id}, 'PUT') + {'other_post_id': other_post_id}, 'PUT', login=True) def post_vote(self, id_, score): """Action lets you vote for a post (Requires login). @@ -94,4 +95,26 @@ def post_vote(self, id_, score): score: REQUIRED Can be: up, down. """ return self._get('/posts/{0}/votes.json'.format(id_), {'score': score}, - 'POST') + 'POST', login=True) + + def post_flag_list(self, creator_id=None, creator_name=None, post_id=None, + reason_matches=None, is_resolved=None, category=None): + """Function to flag a post (Requires login). + + Parameters: + creator_id: The user id of the flag's creator. + creator_name: The name of the flag's creator. + post_id: The post id if the flag. + reason_matches: Flag's reason. + is_resolved: + category: unapproved/banned/normal. + """ + params = { + 'search[creator_id]': creator_id, + 'search[creator_name]': creator_name, + 'search[post_id]': post_id, + 'search[reason_matches]': reason_matches, + 'search[is_resolved]': is_resolved, + 'search[category]': category + } + return self._get('post_flags.json', params, login=True) diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index 747326d..722e073 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -42,14 +42,18 @@ def __init__(self, site_name="", site_url="", username="", api_key=""): self.api_key = api_key - def _get(self, api_call, params=None, method='GET', file_=None): + def _get(self, api_call, params=None, method='GET', login=False, + file_=None): url = "{0}/{1}".format(self.site_url, api_call) if method == 'GET': request_args = {'params': params} else: - request_args = {'auth': (self.username, self.api_key), - 'data': params, 'files': file_} + request_args = {'data': params, 'files': file_} + + # Adds auth + if login is True: + request_args['auth'] = (self.username, self.api_key) # Do call return self._request(url, api_call, request_args, method) From f58a98a83fbe629c650469a01d7242723c0481f4 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sun, 4 Sep 2016 19:54:35 +0200 Subject: [PATCH 038/141] Danbooru: implement post_flag_create() --- pybooru/api_danbooru.py | 20 +++++++++++++++----- pybooru/danbooru.py | 4 ++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index c3ac4e0..bd2fa57 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -64,7 +64,7 @@ def post_update(self, id_, tag_string=None, rating=None, source=None, 'post[parent_id]': parent_id } return self._get('/posts/{0}.json'.format(id_), params, 'PUT', - login=True) + auth=True) def post_revert(self, id_, version_id): """Function to reverts a post to a previous version (Requires login). @@ -74,7 +74,7 @@ def post_revert(self, id_, version_id): version_id: REQUIRED The post version id to revert to. """ return self._get('/posts/{0}/revert.json'.format(id_), - {'version_id': version_id}, 'PUT', login=True) + {'version_id': version_id}, 'PUT', auth=True) def post_copy_notes(self, id_, other_post_id): """Function to copy notes (requires login). @@ -84,7 +84,7 @@ def post_copy_notes(self, id_, other_post_id): other_post_id: REQUIRED The id of the post to copy notes to. """ return self._get('/posts/{0}/copy_notes.json'.format(id_), - {'other_post_id': other_post_id}, 'PUT', login=True) + {'other_post_id': other_post_id}, 'PUT', auth=True) def post_vote(self, id_, score): """Action lets you vote for a post (Requires login). @@ -95,7 +95,7 @@ def post_vote(self, id_, score): score: REQUIRED Can be: up, down. """ return self._get('/posts/{0}/votes.json'.format(id_), {'score': score}, - 'POST', login=True) + 'POST', auth=True) def post_flag_list(self, creator_id=None, creator_name=None, post_id=None, reason_matches=None, is_resolved=None, category=None): @@ -117,4 +117,14 @@ def post_flag_list(self, creator_id=None, creator_name=None, post_id=None, 'search[is_resolved]': is_resolved, 'search[category]': category } - return self._get('post_flags.json', params, login=True) + return self._get('post_flags.json', params, auth=True) + + def post_flag_create(self, id_, reason): + """Function to flag a post. + + Parameters: + id_: REQUIRED The id of the flagged post. + reason: REQUIRED The reason of the flagging. + """ + params = {'post_flag[post_id]': id_, 'post_flag[reason]': reason} + return self._get('post_flags.json', params, 'POST', auth=True) diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index 722e073..0e2d04f 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -42,7 +42,7 @@ def __init__(self, site_name="", site_url="", username="", api_key=""): self.api_key = api_key - def _get(self, api_call, params=None, method='GET', login=False, + def _get(self, api_call, params=None, method='GET', auth=False, file_=None): url = "{0}/{1}".format(self.site_url, api_call) @@ -52,7 +52,7 @@ def _get(self, api_call, params=None, method='GET', login=False, request_args = {'data': params, 'files': file_} # Adds auth - if login is True: + if auth is True: request_args['auth'] = (self.username, self.api_key) # Do call From 532567bc3d213831a1ef3c2aec18dfa7b6279312 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Sep 2016 00:20:39 +0200 Subject: [PATCH 039/141] Danbooru: implement post_appeals_list() --- pybooru/api_danbooru.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index bd2fa57..ef254b1 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -128,3 +128,19 @@ def post_flag_create(self, id_, reason): """ params = {'post_flag[post_id]': id_, 'post_flag[reason]': reason} return self._get('post_flags.json', params, 'POST', auth=True) + + def post_appeals_list(self, creator_id=None, creator_name=None, + post_id=None): + """Function to return list of appeals (Requires login). + + Parameters: + creator_id: The user id of the appeal's creator. + creator_name: The name of the appeal's creator. + post_id: The post id if the appeal. + """ + params = { + 'creator_id': creator_id, + 'creator_name': creator_name, + 'post_id': post_id + } + return self._get('post_appeals.json', params, auth=True) From 912e7a3dc5ba8c3f392b62de67f88c2647033ac6 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Sep 2016 00:32:00 +0200 Subject: [PATCH 040/141] Danbooru: implement post_appeals_create() --- pybooru/api_danbooru.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index ef254b1..b98b1d1 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -144,3 +144,16 @@ def post_appeals_list(self, creator_id=None, creator_name=None, 'post_id': post_id } return self._get('post_appeals.json', params, auth=True) + + def post_appeals_create(self, id_, reason): + """Function to create appeals (Requires login). + + Parameters: + id_: REQUIRED The id of the appealed post. + reason: REQUIRED The reason of the appeal. + """ + params = { + 'post_appeal[post_id]': id_, + 'post_appeal[reason]': reason + } + return self._get('post_appeals.json', params, 'POST', auth=True) From 6fb06f3eb578425b11492f15f226f2079ec77354 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Sep 2016 19:21:18 +0200 Subject: [PATCH 041/141] Danbooru: implement upload_list() --- pybooru/api_danbooru.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index b98b1d1..cccc762 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -157,3 +157,18 @@ def post_appeals_create(self, id_, reason): 'post_appeal[reason]': reason } return self._get('post_appeals.json', params, 'POST', auth=True) + + def upload_list(self, uploader_id=None, uploader_name=None, source=None): + """Search and eturn a uploads list (Requires login). + + Parameters: + uploader_id: The id of the uploader. + uploader_name: The name of the uploader. + source The: source of the upload (exact string match). + """ + params = { + 'search[uploader_id]': uploader_id, + 'search[uploader_name]': uploader_name, + 'search[source]': source + } + return self._get('uploads.json', params, auth=True) From 7d68808843d209d46bd4c5e77ebdcbf4017532b3 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Sep 2016 19:47:04 +0200 Subject: [PATCH 042/141] Danbooru: implement upload_show() --- pybooru/api_danbooru.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index cccc762..bf888ca 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -172,3 +172,11 @@ def upload_list(self, uploader_id=None, uploader_name=None, source=None): 'search[source]': source } return self._get('uploads.json', params, auth=True) + + def upload_show(self, upload_id): + """Get a upload (Requires login). + + Parameters: + upload_id: Where upload_id is the upload id. + """ + return self._get('uploads/{0}.json'.format(upload_id), auth=True) From 942c5116cc421e69997a6413979b4f9e966280b6 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Sep 2016 21:35:39 +0200 Subject: [PATCH 043/141] Danbooru: implement upload_create() --- pybooru/api_danbooru.py | 24 ++++++++++++++++++++++++ pybooru/api_moebooru.py | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index bf888ca..e5b5b8b 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -180,3 +180,27 @@ def upload_show(self, upload_id): upload_id: Where upload_id is the upload id. """ return self._get('uploads/{0}.json'.format(upload_id), auth=True) + + def upload_create(self, tag_string, rating, file_=None, source=None, + parent_id=None): + """Function to create a new upload (Requires login). + + Parameters: + tag_string: REQUIRED The tags. + rating: REQUIRED Can be: safe, questionable, explicit. + file_: The file data encoded as a multipart form. + source: The source URL. + parent_id: The parent post id. + """ + if file_ or source is not None: + params = { + 'upload[source]': source, + 'upload[rating]': rating, + 'upload[parent_id]': parent_id, + 'upload[tag_string]': tag_string + } + file_ = {'upload[file]': open(file_, 'rb')} + return self._get('uploads.json', params, 'POST', auth=True, + file_=file_) + else: + raise PybooruAPIError("'file_' or 'source' is required.") diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 54e2665..7c78eb5 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -37,10 +37,10 @@ def post_list(self, **params): def post_create(self, tags, file_=None, rating=None, source=None, rating_locked=None, note_locked=None, parent_id=None, md5=None): - """Function to create a new post. + """Function to create a new post (Requires login). There are only two mandatory fields: you need to supply the - 'post[tags]', and you need to supply the 'post[file]', either through a + 'tags', and you need to supply the 'file_', either through a multipart form or through a source URL (Requires login) (UNTESTED). Parameters: From 5f57a70e34f8c6054582168c9a0e78d67904207a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Sep 2016 23:11:44 +0200 Subject: [PATCH 044/141] Danbooru: implement comment_list() --- pybooru/api_danbooru.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index e5b5b8b..95978ab 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -204,3 +204,35 @@ def upload_create(self, tag_string, rating, file_=None, source=None, file_=file_) else: raise PybooruAPIError("'file_' or 'source' is required.") + + def comment_list(self, group_by, body_matches=None, post_id=None, + post_tags_match=None, creator_name=None, creator_id=None, + tags=None): + """Return a list of comments. + + Parameters: + group_by: Can be 'comment', 'post'. Comment will return recent + comments. Post will return posts that have been recently + commented on. + The following work only with group_by=comment: + body_matches: Body contains the given terms. + post_id: Post id. + post_tags_match: The comment's post's tags match the + given terms. + creator_name: The name of the creator (exact match) + creator_id: The user id of the creator + The following work only with group_by=post: + tags The post's tags match the given terms. + """ + params = {'group_by': group_by} + if group_by == 'comment': + params['search[body_matches]'] = body_matches + params['search[post_id]'] = post_id + params['search[post_tags_match]'] = post_tags_match + params['search[creator_name]'] = creator_name + params['search[creator_id]'] = creator_id + elif group_by == 'post': + params['tags'] = tags + else: + raise PybooruAPIError("'group_by' must be 'comment' or post") + return self._get('comments.json', params) From ae5e2e27139c7b515bc6c97c6a30e189759206cd Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Sep 2016 16:40:04 +0200 Subject: [PATCH 045/141] Danbooru: implement comment_create() --- pybooru/api_danbooru.py | 20 ++++++++++++++++++-- pybooru/pybooru.py | 4 ++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 95978ab..f07a242 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -217,8 +217,8 @@ def comment_list(self, group_by, body_matches=None, post_id=None, The following work only with group_by=comment: body_matches: Body contains the given terms. post_id: Post id. - post_tags_match: The comment's post's tags match the - given terms. + post_tags_match: The comment's post's tags match the given + terms. creator_name: The name of the creator (exact match) creator_id: The user id of the creator The following work only with group_by=post: @@ -236,3 +236,19 @@ def comment_list(self, group_by, body_matches=None, post_id=None, else: raise PybooruAPIError("'group_by' must be 'comment' or post") return self._get('comments.json', params) + + def comment_create(self, post_id, body, do_not_bump_post=None): + """Action to lets you create a comment (Requires login). + + Parameters: + post_id: REQUIRED + body: REQUIRED + do_not_bump_post: Set to 1 if you do not want the post to be bumped + to the top of the comment listing + """ + params = { + 'comment[post_id]': post_id, + 'comment[body]': body, + 'comment[do_not_bump_post]': do_not_bump_post + } + return self._get('comments.json', params, 'POST', auth=True) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index d26b818..773c275 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -128,7 +128,7 @@ def _request(self, url, api_call, request_args, method='GET'): }) if response.status_code is 200: - return response.json() + return response.json() or True else: raise PybooruHTTPError("In _request", response.status_code, response.url) @@ -136,4 +136,4 @@ def _request(self, url, api_call, request_args, method='GET'): raise PybooruError("Timeout! in url: {0}".format(response.url)) except ValueError as e: raise PybooruError("JSON Error: {0} in line {1} column {2}".format( - e.msg, e.lineno, e.colno)) + e.msg, e.lineno, e.colno)) From 54b4df4486207a4d69bb29d119363dc67c859d7a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Sep 2016 17:04:25 +0200 Subject: [PATCH 046/141] Danbooru: implement comment_update() --- pybooru/api_danbooru.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index f07a242..82a1b99 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -241,10 +241,10 @@ def comment_create(self, post_id, body, do_not_bump_post=None): """Action to lets you create a comment (Requires login). Parameters: - post_id: REQUIRED - body: REQUIRED + post_id: REQUIRED. + body: REQUIRED. do_not_bump_post: Set to 1 if you do not want the post to be bumped - to the top of the comment listing + to the top of the comment listing. """ params = { 'comment[post_id]': post_id, @@ -252,3 +252,19 @@ def comment_create(self, post_id, body, do_not_bump_post=None): 'comment[do_not_bump_post]': do_not_bump_post } return self._get('comments.json', params, 'POST', auth=True) + + def comment_update(self, id_, body, do_not_bump_post=None): + """Function to update a comment (Requires login). + + Parameters: + id_: REQUIRED comment id. + body: REQUIRED. + do_not_bump_post: Set to 1 if you do not want the post to be bumped + to the top of the comment listing. + """ + params = { + 'comment[body]': body, + 'comment[do_not_bump_post]': do_not_bump_post + } + return self._get('comments/{0}.json'.format(id_), params, 'PUT', + auth=True) From e95de83e387637a77d343d8e32b1c34ae985c86a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Sep 2016 17:10:59 +0200 Subject: [PATCH 047/141] Danbooru: comment_show() --- pybooru/api_danbooru.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 82a1b99..5873bc5 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -268,3 +268,11 @@ def comment_update(self, id_, body, do_not_bump_post=None): } return self._get('comments/{0}.json'.format(id_), params, 'PUT', auth=True) + + def comment_show(self, id_): + """Get a specific comment. + + Parameters: + id_: The id number of the comment to retrieve. + """ + return self._get('comments/{0}.json'.format(id_)) From bd61fbe76715ad970e6c5b43b7589207a9a95bc5 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Sep 2016 17:18:41 +0200 Subject: [PATCH 048/141] Danbooru: implement comment_delete() --- pybooru/api_danbooru.py | 11 ++++++++++- pybooru/api_moebooru.py | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 5873bc5..85e5c9d 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -273,6 +273,15 @@ def comment_show(self, id_): """Get a specific comment. Parameters: - id_: The id number of the comment to retrieve. + id_: REQUIRED the id number of the comment to retrieve. """ return self._get('comments/{0}.json'.format(id_)) + + def comment_delete(self, id_): + """Remove a specific comment (Requires login). + + Parameters: + id_: REQUIRED the id number of the comment to remove. + """ + return self._get('comments/{0}.json'.format(id_), method='DELETE', + auth=True) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 7c78eb5..24afe5b 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -280,7 +280,7 @@ def comment_create(self, post_id, comment_body, anonymous=None): raise PybooruAPIError("Required 'post_id' and 'comment_body' " "parameters") - def comment_destroy(self, id_=None): + def comment_destroy(self, id_): """Remove a specific comment (Requires login). Parameters: From af1b3fb30f7e7f7cd929de2ea1af12428226d66c Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Sep 2016 00:24:00 +0200 Subject: [PATCH 049/141] Danbooru: implement favorite_list() --- pybooru/api_danbooru.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 85e5c9d..3ff5be9 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -285,3 +285,12 @@ def comment_delete(self, id_): """ return self._get('comments/{0}.json'.format(id_), method='DELETE', auth=True) + + def favorite_list(self, user_id=None): + """Return a list with favorite posts (Requires login). + + Parameters: + user_id: Which user's favorites to show. Defaults to your own if + not specified. + """ + return self._get('favorites.json', {'user_id': user_id}, auth=True) From 0f55022c65a633008839d75acf0acfe2c264b31f Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Sep 2016 00:40:52 +0200 Subject: [PATCH 050/141] Danbooru: implement favorite_add() --- pybooru/api_danbooru.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 3ff5be9..d229819 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -294,3 +294,12 @@ def favorite_list(self, user_id=None): not specified. """ return self._get('favorites.json', {'user_id': user_id}, auth=True) + + def favorite_add(self, post_id): + """Add post to favorite (Requires login). + + Parameters: + post_id: REQUIRED The post to favorite. + """ + return self._get('favorites.json', {'post_id': post_id}, 'POST', + auth=True) From 5f54d3bfdfe9919a407887b3326f5db63d307b61 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Sep 2016 00:43:53 +0200 Subject: [PATCH 051/141] Danbooru: implement favorite_remove() --- pybooru/api_danbooru.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index d229819..907c85f 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -303,3 +303,12 @@ def favorite_add(self, post_id): """ return self._get('favorites.json', {'post_id': post_id}, 'POST', auth=True) + + def favorite_remove(self, post_id): + """Remove a post from favorites (Requires login). + + Parameters: + post_id: REQUIRED where post_id is the post id. + """ + return self._get('favorites/{0}.json'.format(post_id), method='DELETE', + auth=True) From 148773dd4db505a79e2bc113bfbcbba2168162a3 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Sep 2016 11:25:39 +0200 Subject: [PATCH 052/141] Danbooru: implement dmail_list() --- pybooru/api_danbooru.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 907c85f..facc1ca 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -312,3 +312,26 @@ def favorite_remove(self, post_id): """ return self._get('favorites/{0}.json'.format(post_id), method='DELETE', auth=True) + + def dmail_list(self, message_matches=None, to_name=None, to_id=None, + from_name=None, from_id=None, read=None): + """Return list of Dmails. You can only view dmails you own + (Requires login). + + Parameters: + message_matches: The message body contains the given terms. + to_name: The recipient's name. + to_id: The recipient's user id. + from_name: The sender's name. + from_id: The sender's user id. + read: Can be: true, false. + """ + params = { + 'search[message_matches]': message_matches, + 'search[to_name]': to_name, + 'search[to_id]': to_id, + 'search[from_name]': from_name, + 'search[from_id]': from_id, + 'search[read]': read + } + return self._get('dmails.json', params, auth=True) From 7cd9341812ea3015128b0caa1d20f34dd85c1375 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Sep 2016 11:33:06 +0200 Subject: [PATCH 053/141] Danbooru: implement dmail_show() --- pybooru/api_danbooru.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index facc1ca..4fbe97c 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -335,3 +335,12 @@ def dmail_list(self, message_matches=None, to_name=None, to_id=None, 'search[read]': read } return self._get('dmails.json', params, auth=True) + + def dmail_show(self, dmail_id): + """Return a specific dmail. You can only view dmails you own + (Requires login). + + Parameters: + dmail_id: where dmail_id is the dmail id. + """ + return self._get('dmails/{0}.json'.format(dmail_id), auth=True) From bdf5d14685732a34bbc673f4dcf1305978c38584 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Sep 2016 11:38:57 +0200 Subject: [PATCH 054/141] danbooru: implement dmail_create() --- pybooru/api_danbooru.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 4fbe97c..d6e967c 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -341,6 +341,21 @@ def dmail_show(self, dmail_id): (Requires login). Parameters: - dmail_id: where dmail_id is the dmail id. + dmail_id: REQUIRED where dmail_id is the dmail id. """ return self._get('dmails/{0}.json'.format(dmail_id), auth=True) + + def dmail_create(self, to_name, title, body): + """Create a dmail (Requires login) + + Parameters: + to_name: REQUIRED the recipient's name. + title: REQUIRED the title of the message. + body: REQUIRED the body of the message. + """ + params = { + 'dmail[to_name]': to_name, + 'dmail[title]': title, + 'dmail[body]': body + } + return self._get('dmails.json', params, 'POST', auth=True) From 940c3374b556d5bad13fb8a4d679ef95e7d9cc75 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Sep 2016 11:42:36 +0200 Subject: [PATCH 055/141] Danbooru: implement dmail_delete() --- pybooru/api_danbooru.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index d6e967c..d72ed45 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -359,3 +359,12 @@ def dmail_create(self, to_name, title, body): 'dmail[body]': body } return self._get('dmails.json', params, 'POST', auth=True) + + def dmail_delete(self, dmail_id): + """Delete a dmail. You can only delete dmails you own (Requires login). + + Parameters: + dmail_id: REQUIRED where dmail_id is the dmail id. + """ + return self._get('dmails/{0}.json'.format(dmail_id), method='DELETE', + auth=True) From 47db4fa24b992675a8b4b5072b703b4bdc34575b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 26 Sep 2016 13:07:56 +0200 Subject: [PATCH 056/141] Danbooru: implement artist_list() --- pybooru/api_danbooru.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index d72ed45..55c8259 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -368,3 +368,41 @@ def dmail_delete(self, dmail_id): """ return self._get('dmails/{0}.json'.format(dmail_id), method='DELETE', auth=True) + + def artist_list(self, query=None, artist_id=None, creator_name=None, + creator_id=None, is_active=None, is_banned=None, + empty_only=None, order=None): + """Get an artist of a list of artists. + + Parameters: + query: This field has multiple uses depending on what the query + starts with: + http: Search for artist with this URL. + name: Search for artists with the given name as their base + name. + other: Search for artists with the given name in their other + names. + group: Search for artists belonging to the group with the given + name. + status:banned Search for artists that are banned. + else Search for the given name in the base name and the other + names. + artist_id: The artist id. + creator_name: + creator_id: + is_active: Can be: true, false + is_banned: Can be: true, false + empty_only: Search for artists that have 0 posts. Can be: true + order: Can be: name, updated_at. + """ + params = { + 'search[name]': query, + 'search[id]': artist_id, + 'search[creator_name]': creator_name, + 'search[creator_id]': creator_id, + 'search[is_active]': is_active, + 'search[is_banned]': is_banned, + 'search[empty_only]': empty_only, + 'search[order]': order + } + return self._get('artists.json', params) From 9ab6800cfe4e6ac3123d464bf11210288ae909d1 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 26 Sep 2016 13:13:30 +0200 Subject: [PATCH 057/141] Danbooru: implement artist_show() --- pybooru/api_danbooru.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 55c8259..c404c71 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -406,3 +406,11 @@ def artist_list(self, query=None, artist_id=None, creator_name=None, 'search[order]': order } return self._get('artists.json', params) + + def artist_show(self, artist_id): + """Return a specific artist. + + Parameters: + artist_id: REQUIRED where artist_id is the artist id. + """ + return self._get('artists/{0}.json'.format(artist_id)) From 51ebaa9a74c04658fef616e814750d049a01e99b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 26 Sep 2016 13:22:23 +0200 Subject: [PATCH 058/141] Danbooru: implement artist_create() --- pybooru/api_danbooru.py | 22 +++++++++++++++++++++- pybooru/api_moebooru.py | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index c404c71..86d16a5 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -404,7 +404,7 @@ def artist_list(self, query=None, artist_id=None, creator_name=None, 'search[is_banned]': is_banned, 'search[empty_only]': empty_only, 'search[order]': order - } + } return self._get('artists.json', params) def artist_show(self, artist_id): @@ -414,3 +414,23 @@ def artist_show(self, artist_id): artist_id: REQUIRED where artist_id is the artist id. """ return self._get('artists/{0}.json'.format(artist_id)) + + def artist_create(self, name, other_names_comma=None, group_name=None, + url_string=None): + """Function to create an artist (Requires login) (UNTESTED). + + Parameters: + name: REQUIRED. + other_names_comma: List of alternative names for this artist, comma + delimited. + group_name: The name of the group this artist belongs to. + url_string: List of URLs associated with this artist, whitespace or + newline delimited. + """ + params = { + 'artist[name]': name, + 'artist[other_names_comma]': other_names_comma, + 'artist[group_name]': group_name, + 'artist[url_string]': url_string + } + return self.get('artists.json', params, method='POST', auth=True) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 24afe5b..5417925 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -201,7 +201,7 @@ def artist_list(self, **params): return self._get('artist', params) def artist_create(self, name, urls=None, alias=None, group=None): - """Function to create a artist (Requires login) (UNTESTED). + """Function to create an artist (Requires login) (UNTESTED). Parameters: name: The artist's name. From 7ab6047de22348a2d01c8ea01fed456bc9233c76 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 26 Sep 2016 13:31:32 +0200 Subject: [PATCH 059/141] Danbooru: implement artist_update() --- pybooru/api_danbooru.py | 22 ++++++++++++++++++++++ pybooru/api_moebooru.py | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 86d16a5..d842a1a 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -434,3 +434,25 @@ def artist_create(self, name, other_names_comma=None, group_name=None, 'artist[url_string]': url_string } return self.get('artists.json', params, method='POST', auth=True) + + def artist_update(self, artist_id, name=None, other_names_comma=None, + group_name=None, url_string=None): + """Function to update artists (Requires login) (UNTESTED). + + Parameters: + artist_id: REQUIRED where artist_id is the artist id. + name: + other_names_comma: List of alternative names for this artist, comma + delimited. + group_name: The name of the group this artist belongs to. + url_string: List of URLs associated with this artist, whitespace or + newline delimited. + """ + params = { + 'artist[name]': name, + 'artist[other_names_comma]': other_names_comma, + 'artist[group_name]': group_name, + 'artist[url_string]': url_string + } + return self.get('artists/{0}.json'.format(artist_id), params, + method='PUT', auth=True) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 5417925..c79a0cc 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -221,7 +221,7 @@ def artist_create(self, name, urls=None, alias=None, group=None): return self._get('artist/create', params, 'POST') def artist_update(self, id_, name=None, urls=None, alias=None, group=None): - """Function to update an artists. + """Function to update artists (Requires Login). Only the id_ parameter is required. The other parameters are optional. (Requires login) (UNTESTED). From 994c83b0af7b6cfd8dd859c52ecfd1ce2c8d979b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 26 Sep 2016 13:35:33 +0200 Subject: [PATCH 060/141] Danbooru: implement artist_delete() --- pybooru/api_danbooru.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index d842a1a..0ef3b5b 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -454,5 +454,14 @@ def artist_update(self, artist_id, name=None, other_names_comma=None, 'artist[group_name]': group_name, 'artist[url_string]': url_string } - return self.get('artists/{0}.json'.format(artist_id), params, - method='PUT', auth=True) + return self .get('artists/{0}.json'.format(artist_id), params, + method='PUT', auth=True) + + def artist_delete(self, artist_id): + """Action to lets you delete an artist (Requires login) (UNTESTED). + + Parameters: + artist_id: where artist_id is the artist id. + """ + return self._get('artists/{0}.json'.format(artist_id), method='DELETE', + auth=True) From 6368f277e3e604fc40430978eaebbba180532dca Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 26 Sep 2016 13:39:31 +0200 Subject: [PATCH 061/141] Danbooru: implement artist_banned() --- pybooru/api_danbooru.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 0ef3b5b..c977124 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -465,3 +465,9 @@ def artist_delete(self, artist_id): """ return self._get('artists/{0}.json'.format(artist_id), method='DELETE', auth=True) + + def artist_banned(self): + """This is a shortcut for an artist listing search with + name=status:banned. + """ + return self._get('artists/banned.json') From 98ff03f82ba97434f25394f72e78afa193deffce Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 26 Sep 2016 13:46:31 +0200 Subject: [PATCH 062/141] Danbooru: implement artist_revert() --- pybooru/api_danbooru.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index c977124..c7dc92a 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -471,3 +471,14 @@ def artist_banned(self): name=status:banned. """ return self._get('artists/banned.json') + + def artist_rever(self, artist_id, version_id): + """Revert an artist (Requires login) (UNTESTED). + + Parameters: + artist_id: The artist id. + version_id: REQUIRED The artist version id to revert to. + """ + params = {'version_id': version_id} + return self._get('artists/{0}/revert.json'.format(artist_id), params, + method='PUT', auth=True) From 60af5fd37089c9e1d3aa86ce87ca000fbb58173c Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 6 Oct 2016 14:10:37 +0200 Subject: [PATCH 063/141] Danbooru: implement note_list() --- pybooru/api_danbooru.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index c7dc92a..c07940b 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -472,7 +472,7 @@ def artist_banned(self): """ return self._get('artists/banned.json') - def artist_rever(self, artist_id, version_id): + def artist_revert(self, artist_id, version_id): """Revert an artist (Requires login) (UNTESTED). Parameters: @@ -482,3 +482,25 @@ def artist_rever(self, artist_id, version_id): params = {'version_id': version_id} return self._get('artists/{0}/revert.json'.format(artist_id), params, method='PUT', auth=True) + + def note_list(self, group_by=None, body_matches=None, post_id=None, + post_tags_match=None, creator_name=None, creator_id=None): + """Return list of notes. + + Parameters: + group_by: Can be: note, post (by default post). + body_matches: The note's body matches the given terms. + post_id: A specific post. + post_tags_match: The note's post's tags match the given terms. + creator_name: The creator's name. Exact match. + creator_id: The creator's user id. + """ + params = { + 'group_by': group_by, + 'search[body_matches]': body_matches, + 'search[post_id]': post_id, + 'search[post_tags_match]': post_tags_match, + 'search[creator_name]': creator_name, + 'search[creator_id]': creator_id + } + return self._get('notes.json', params) From dedd9ed416e86a70bd831b20e238529be8894b7c Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 15 Oct 2016 18:40:17 +0200 Subject: [PATCH 064/141] Danbooru: implement note_show() --- pybooru/api_danbooru.py | 8 ++++++++ pybooru/api_moebooru.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index c07940b..ee047f1 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -504,3 +504,11 @@ def note_list(self, group_by=None, body_matches=None, post_id=None, 'search[creator_id]': creator_id } return self._get('notes.json', params) + + def note_show(self, note_id): + """Get a specific note. + + Parameters: + note_id: Where note_id is the note id. + """ + return self._get('notes/{0}.json'.format(note_id)) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index c79a0cc..ec840b9 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -394,7 +394,7 @@ def note_search(self, query): """ return self._get('note/search', {'query': query}) - def notes_history(self, **params): + def note_history(self, **params): """Get history of notes. Parameters: From cd27fd497ac34d73de7d65523994457400110522 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 15 Oct 2016 18:57:17 +0200 Subject: [PATCH 065/141] Danbooru: Implement note_create() --- pybooru/api_danbooru.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index ee047f1..3333a0a 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -512,3 +512,26 @@ def note_show(self, note_id): note_id: Where note_id is the note id. """ return self._get('notes/{0}.json'.format(note_id)) + + def note_create(self, post_id, coor_x, coor_y, width, height, body): + """Function to create a note (Requires login) (UNTESTED). + + Parameters: + post_id: REQUIRED + coor_x: REQUIRED The x coordinates of the note in pixels, with + respect to the top-left corner of the image. + coor_y: REQUIRED The y coordinates of the note in pixels, with + respect to the top-left corner of the image. + width: REQUIRED The width of the note in pixels. + height: REQUIRED The height of the note in pixels. + body: REQUIRED The body of the note. + """ + params = { + 'note[post_id]': post_id, + 'note[x]': coor_x, + 'note[y]': coor_y, + 'note[width]': width, + 'note[height]': height, + 'note[body]': body + } + return self._get('notes.json', params, method='POST', auth=True) From 245094304203896e9bd23aafe6955a94edc8e2c1 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 15 Oct 2016 19:03:41 +0200 Subject: [PATCH 066/141] Danbooru: Implements note_update() --- pybooru/api_danbooru.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 3333a0a..97ac3c4 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -476,7 +476,7 @@ def artist_revert(self, artist_id, version_id): """Revert an artist (Requires login) (UNTESTED). Parameters: - artist_id: The artist id. + artist_id: REQUIRED The artist id. version_id: REQUIRED The artist version id to revert to. """ params = {'version_id': version_id} @@ -509,7 +509,7 @@ def note_show(self, note_id): """Get a specific note. Parameters: - note_id: Where note_id is the note id. + note_id: REQUIRED Where note_id is the note id. """ return self._get('notes/{0}.json'.format(note_id)) @@ -535,3 +535,27 @@ def note_create(self, post_id, coor_x, coor_y, width, height, body): 'note[body]': body } return self._get('notes.json', params, method='POST', auth=True) + + def note_update(self, note_id, coor_x=None, coor_y=None, width=None, + height=None, body=None): + """Function to update a note (Requires login) (UNTESTED). + + Parameters: + note_id: REQUIRED Where note_id is the note id. + coor_x: REQUIRED The x coordinates of the note in pixels, with + respect to the top-left corner of the image. + coor_y: REQUIRED The y coordinates of the note in pixels, with + respect to the top-left corner of the image. + width: REQUIRED The width of the note in pixels. + height: REQUIRED The height of the note in pixels. + body: REQUIRED The body of the note. + """ + params = { + 'note[x]': coor_x, + 'note[y]': coor_y, + 'note[width]': width, + 'note[height]': height, + 'note[body]': body + } + return self._get('notes/{0}.jso'.format(note_id), params, method='PUT', + auth=True) From 0ab6eda958db821c252ba358bd67fa19bc06b91d Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 15 Oct 2016 20:59:09 +0200 Subject: [PATCH 067/141] Danbooru: implements note_delete() --- pybooru/api_danbooru.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 97ac3c4..7f22a05 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -559,3 +559,12 @@ def note_update(self, note_id, coor_x=None, coor_y=None, width=None, } return self._get('notes/{0}.jso'.format(note_id), params, method='PUT', auth=True) + + def note_delete(self, note_id): + """delete a specific note (Requires login) (UNTESTED). + + Parameters: + note_id: REQUIRED Where note_id is the note id. + """ + return self._get('notes/{0}.json'.format(note_id), method='DELETE', + auth=True) From 05e8dda45f6f4f5d13a4a9e1137c42221dbb0bff Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Sat, 15 Oct 2016 21:04:04 +0200 Subject: [PATCH 068/141] Danbooru: implements note_revert() --- pybooru/api_danbooru.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 7f22a05..d513394 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -568,3 +568,13 @@ def note_delete(self, note_id): """ return self._get('notes/{0}.json'.format(note_id), method='DELETE', auth=True) + + def note_revert(self, note_id, version_id): + """Function to revert a specific note (Requires login) (UNTESTED). + + Parameters: + note_id: REQUIRED Where note_id is the note id. + version_id: REQUIRED The note version id to revert to. + """ + return self._get('notes/{0}/revert.json'.format(note_id), + {'version_id': version_id}, method='PUT', auth=True) From bbf960d64de756557282adb7b15263e688dddd44 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 19 Oct 2016 16:38:25 +0200 Subject: [PATCH 069/141] Danbooru: Implements user_list() and user_show() --- pybooru/api_danbooru.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index d513394..194e973 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -578,3 +578,41 @@ def note_revert(self, note_id, version_id): """ return self._get('notes/{0}/revert.json'.format(note_id), {'version_id': version_id}, method='PUT', auth=True) + + def user_list(self, name=None, min_level=None, max_level=None, level=None, + user_id=None, order=None): + """Function to get a list of users or a specific user. + + Levels: + Users have a number attribute called level representing their role. + The current levels are: + + Member 20, Gold 30, Platinum 31, Builder 32, Contributor 33, + Janitor 35, Moderator 40 and Admin 50 + + Parameters: + name: Supports patterns. + min_level: Minimum level (see section on levels). + max_level: Maximum level (see section on levels). + level: Current level (see section on levels). + user_id: The user id. + order: Can be: 'name', 'post_upload_count', 'note_count', + 'post_update_count', 'date'. + """ + params = { + 'search[name]': name, + 'search[min_level]': min_level, + 'search[max_level]': max_level, + 'search[level]': level, + 'search[id]': user_id, + 'search[order]': order + } + return self._get('users.json', params) + + def user_show(self, user_id): + """Get a specific user. + + Parameters: + user_id: REQUIRED Where user_id is the user id. + """ + return self._get('users/{0}.json'.format(user_id)) From a4e1cef62311c427b2d2855137d49969e420bfef Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 11:20:23 +0200 Subject: [PATCH 070/141] Danbooru: implements post_versions() --- pybooru/api_danbooru.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 194e973..2c539c4 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -616,3 +616,21 @@ def user_show(self, user_id): user_id: REQUIRED Where user_id is the user id. """ return self._get('users/{0}.json'.format(user_id)) + + def post_versions(self, updater_name=None, updater_id=None, + post_id=None, start_id=None): + """Get list of post versions. + + Parameters: + updater_name: + updater_id: + post_id: + start_id: + """ + params = { + 'search[updater_name]': updater_name, + 'search[updater_id]': updater_id, + 'search[post_id]': post_id, + 'search[start_id]': start_id + } + return self._get('post_versions.json', params) From ead93968f28a396aea2d47bfaec0b6c4b7abe41e Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 11:28:56 +0200 Subject: [PATCH 071/141] Danbooru: implements note_versions() --- pybooru/api_danbooru.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 2c539c4..5fc44cc 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -634,3 +634,18 @@ def post_versions(self, updater_name=None, updater_id=None, 'search[start_id]': start_id } return self._get('post_versions.json', params) + + def note_versions(self, updater_id=None, post_id=None, note_id=None): + """Get list of note versions. + + Parameters: + updater_id: + post_id: + note_id: + """ + params = { + 'search[updater_id]': updater_id, + 'search[post_id]': post_id, + 'search[note_id]': note_id + } + return self._get('note_versions.json', params) From c891ce57273f3192b99296dda2130c6a94e966c1 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 11:47:55 +0200 Subject: [PATCH 072/141] Danbooru: implements artist_version() --- pybooru/api_danbooru.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 5fc44cc..1100dcc 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -649,3 +649,25 @@ def note_versions(self, updater_id=None, post_id=None, note_id=None): 'search[note_id]': note_id } return self._get('note_versions.json', params) + + def artist_version(self, name=None, updater_id=None, artist_id=None, + is_active=None, is_banned=None, order=None): + """Get list of artist versions. + + Parameters: + name: + updater_id: + artist_id: + is_active: Can be: true, false. + is_banned: Can be: true, false. + order: Can be: name, date. + """ + params = { + 'search[name]': name, + 'search[updater_id]': updater_id, + 'search[artist_id]': artist_id, + 'search[is_active]': is_active, + 'search[is_banned]': is_banned, + 'search[order]': order + } + return self._get('artist_versions.json', params) From d99aa1b3b3e646e2c4ca9b8125c5d3ba0c44a09c Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 12:10:22 +0200 Subject: [PATCH 073/141] Danbooru: implements pools_list() --- pybooru/api_danbooru.py | 25 +++++++++++++++++++++++++ pybooru/api_moebooru.py | 16 ++++++++-------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 1100dcc..490462a 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -671,3 +671,28 @@ def artist_version(self, name=None, updater_id=None, artist_id=None, 'search[order]': order } return self._get('artist_versions.json', params) + + def pools_list(self, name_matches=None, description_matches=None, + creator_name=None, creator_id=None, is_active=None, + order=None, category=None): + """Get a list of pools. + + Parameters: + name_matches: + description_matches: + creator_name: + creator_id: + is_active: Can be: true, false. + order: Can be: name, created_at, post_count, date. + category: Can be: series, collection + """ + params = { + 'search[name_matches]': name_matches, + 'search[description_matches]': description_matches, + 'search[creator_name]': creator_name, + 'search[creator_id]': creator_id, + 'search[is_active]': is_active, + 'search[order]': order, + 'search[category]': category + } + return self._get('pools.json', params) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index ec840b9..4baa246 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -466,8 +466,8 @@ def forum_list(self, **params): """ return self._get('forum', params) - def pool_list(self, **params): - """Function to _get pools. + def poosl_list(self, **params): + """Function to get pools. If you don't specify any parameters you'll _get a list of all pools. @@ -477,7 +477,7 @@ def pool_list(self, **params): """ return self._get('pool', params) - def pool_posts(self, **params): + def pools_posts(self, **params): """Function to _get pools posts. If you don't specify any parameters you'll _get a list of all pools. @@ -488,7 +488,7 @@ def pool_posts(self, **params): """ return self._get('pool/show', params) - def pool_update(self, id_, name=None, is_public=None, + def pools_update(self, id_, name=None, is_public=None, description=None): """Function to update a pool (Requires login) (UNTESTED). @@ -506,7 +506,7 @@ def pool_update(self, id_, name=None, is_public=None, } return self._get('pool/update', params, 'PUT') - def pool_create(self, name, description, is_public): + def pools_create(self, name, description, is_public): """Function to create a pool (Require login) (UNTESTED). Parameters: @@ -518,7 +518,7 @@ def pool_create(self, name, description, is_public): 'pool[is_public]': is_public} return self._get('pool/create', params, 'POST') - def pool_destroy(self, id_): + def pools_destroy(self, id_): """Function to destroy a specific pool (Require login) (UNTESTED). Parameters: @@ -526,7 +526,7 @@ def pool_destroy(self, id_): """ return self._get('pool/destroy', {'id': id_}, 'DELETE') - def pool_add_post(self, **params): + def pools_add_post(self, **params): """Function to add a post (Require login) (UNTESTED). Parameters: @@ -535,7 +535,7 @@ def pool_add_post(self, **params): """ return self._get('pool/add_post', params, 'PUT') - def pool_remove_post(self, **params): + def pools_remove_post(self, **params): """Function to remove a post (Require login) (UNTESTED). Parameters: From 119b5f4eb219e0cec0a60bf827599a700b70df0a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 12:19:05 +0200 Subject: [PATCH 074/141] Danbooru: implements pools_show() --- pybooru/api_danbooru.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 490462a..057f7b3 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -696,3 +696,11 @@ def pools_list(self, name_matches=None, description_matches=None, 'search[category]': category } return self._get('pools.json', params) + + def pools_show(self, pool_id): + """Get a specific pool. + + Parameters: + pool_id: REQUIRED Where pool_id is the pool id. + """ + return self._get('pools/{0}.json'.format(pool_id)) From 280b05a892e7683f7ca6b529c8052b44292e485b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 12:28:57 +0200 Subject: [PATCH 075/141] Danbooru: implements pools_create() --- pybooru/api_danbooru.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 057f7b3..ff801cb 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -704,3 +704,18 @@ def pools_show(self, pool_id): pool_id: REQUIRED Where pool_id is the pool id. """ return self._get('pools/{0}.json'.format(pool_id)) + + def pools_create(self, name, description, category): + """Function to create a pool (Requires login) (UNTESTED). + + Parameters: + name: REQUIRED. + description: REQUIRED. + category: Can be: series, collection. + """ + params = { + 'pool[name]': name, + 'pool[description]': description, + 'pool[category]': category + } + return self._get('pools.json', params, method='POST', auth=True) From 905b1c2ad3cfafba5de0a4c00c2fdcab411d1f9a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 19:30:05 +0200 Subject: [PATCH 076/141] Danbooru: implements pool_update() --- pybooru/api_danbooru.py | 28 +++++++++++++++++++++++++--- pybooru/api_moebooru.py | 14 +++++++------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index ff801cb..ab6dde6 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -672,7 +672,7 @@ def artist_version(self, name=None, updater_id=None, artist_id=None, } return self._get('artist_versions.json', params) - def pools_list(self, name_matches=None, description_matches=None, + def pool_list(self, name_matches=None, description_matches=None, creator_name=None, creator_id=None, is_active=None, order=None, category=None): """Get a list of pools. @@ -697,7 +697,7 @@ def pools_list(self, name_matches=None, description_matches=None, } return self._get('pools.json', params) - def pools_show(self, pool_id): + def pool_show(self, pool_id): """Get a specific pool. Parameters: @@ -705,7 +705,7 @@ def pools_show(self, pool_id): """ return self._get('pools/{0}.json'.format(pool_id)) - def pools_create(self, name, description, category): + def pool_create(self, name, description, category): """Function to create a pool (Requires login) (UNTESTED). Parameters: @@ -719,3 +719,25 @@ def pools_create(self, name, description, category): 'pool[category]': category } return self._get('pools.json', params, method='POST', auth=True) + + def pool_update(self, pool_id, name=None, description=None, post_ids=None, + is_active=None, category=None): + """Update a pool (Requires login) (UNTESTED). + + Parameters: + pool_id: REQUIRED Where pool_id is the pool id. + name: + description: + post_ids: List of space delimited post ids. + is_active: Can be: 1, 0 + category: Can be: series, collection + """ + params = { + 'pool[name]': name, + 'pool[description]': description, + 'pool[post_ids]': post_ids, + 'pool[is_active]': is_active, + 'pool[category]': category + } + return self._get('pools/{0}.json'.format(pool_id), params, + method='PUT', auth=True) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 4baa246..9590a61 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -466,7 +466,7 @@ def forum_list(self, **params): """ return self._get('forum', params) - def poosl_list(self, **params): + def pool_list(self, **params): """Function to get pools. If you don't specify any parameters you'll _get a list of all pools. @@ -477,7 +477,7 @@ def poosl_list(self, **params): """ return self._get('pool', params) - def pools_posts(self, **params): + def pool_posts(self, **params): """Function to _get pools posts. If you don't specify any parameters you'll _get a list of all pools. @@ -488,7 +488,7 @@ def pools_posts(self, **params): """ return self._get('pool/show', params) - def pools_update(self, id_, name=None, is_public=None, + def pool_update(self, id_, name=None, is_public=None, description=None): """Function to update a pool (Requires login) (UNTESTED). @@ -506,7 +506,7 @@ def pools_update(self, id_, name=None, is_public=None, } return self._get('pool/update', params, 'PUT') - def pools_create(self, name, description, is_public): + def pool_create(self, name, description, is_public): """Function to create a pool (Require login) (UNTESTED). Parameters: @@ -518,7 +518,7 @@ def pools_create(self, name, description, is_public): 'pool[is_public]': is_public} return self._get('pool/create', params, 'POST') - def pools_destroy(self, id_): + def pool_destroy(self, id_): """Function to destroy a specific pool (Require login) (UNTESTED). Parameters: @@ -526,7 +526,7 @@ def pools_destroy(self, id_): """ return self._get('pool/destroy', {'id': id_}, 'DELETE') - def pools_add_post(self, **params): + def pool_add_post(self, **params): """Function to add a post (Require login) (UNTESTED). Parameters: @@ -535,7 +535,7 @@ def pools_add_post(self, **params): """ return self._get('pool/add_post', params, 'PUT') - def pools_remove_post(self, **params): + def pool_remove_post(self, **params): """Function to remove a post (Require login) (UNTESTED). Parameters: From a1b8319f774b532d1a0739ed0c4959189660cc3d Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 19:35:35 +0200 Subject: [PATCH 077/141] Danbooru: implements pool_delete() --- pybooru/api_danbooru.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index ab6dde6..b24c323 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -741,3 +741,12 @@ def pool_update(self, pool_id, name=None, description=None, post_ids=None, } return self._get('pools/{0}.json'.format(pool_id), params, method='PUT', auth=True) + + def pool_delete(self, pool_id): + """Delete a pool (Requires login) (UNTESTED). + + Parameters: + pool_id: REQUIRED Where pool_id is the pool id. + """ + return self._get('pools/{0}.json'.format(pool_id), method='DELETE', + auth=True) From eeb629cd11d130c98875d4b781187d34797bd027 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 19:47:04 +0200 Subject: [PATCH 078/141] Danbooru: implements pool_undelete() --- pybooru/api_danbooru.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index b24c323..48a3024 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -750,3 +750,12 @@ def pool_delete(self, pool_id): """ return self._get('pools/{0}.json'.format(pool_id), method='DELETE', auth=True) + + def pool_undelete(self, pool_id): + """Undelete a specific poool (Requires login) (UNTESTED). + + Parameters: + pool_id: REQUIRED Where pool_id is the pool id. + """ + return self._get('pools/{0}/undelete.json'.format(pool_id), + method='POST', auth=True) From 4020c3e54e79493bc968cef501be24d2857a9528 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 19:48:43 +0200 Subject: [PATCH 079/141] Danbooru: implements pool_revert() --- pybooru/api_danbooru.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 48a3024..639fba9 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -759,3 +759,14 @@ def pool_undelete(self, pool_id): """ return self._get('pools/{0}/undelete.json'.format(pool_id), method='POST', auth=True) + + def pool_revert(self, pool_id, version_id): + """Function to revert a specific pool (Requires login) (UNTESTED). + + Parameters: + pool_id: REQUIRED Where pool_id is the pool id. + version_id: REQUIRED. + """ + params = {'version_id': version_id} + return self._get('pools/{0}/revert.json'.format(pool_id), params, + method='PUT', auth=True) From fb4c4ba9ba06b860e41825a2f7cd6d67bf5833a6 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 19:58:04 +0200 Subject: [PATCH 080/141] Danbooru: implements pool_versions() --- pybooru/api_danbooru.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 639fba9..ab3bc57 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -673,8 +673,8 @@ def artist_version(self, name=None, updater_id=None, artist_id=None, return self._get('artist_versions.json', params) def pool_list(self, name_matches=None, description_matches=None, - creator_name=None, creator_id=None, is_active=None, - order=None, category=None): + creator_name=None, creator_id=None, is_active=None, + order=None, category=None): """Get a list of pools. Parameters: @@ -770,3 +770,18 @@ def pool_revert(self, pool_id, version_id): params = {'version_id': version_id} return self._get('pools/{0}/revert.json'.format(pool_id), params, method='PUT', auth=True) + + def pool_versions(self, updater_id=None, updater_name=None, pool_id=None): + """Get list of pool versions. + + Parameters: + updater_id: + updater_name: + pool_id: + """ + params = { + 'search[updater_id]': updater_id, + 'search[updater_name]': updater_name, + 'search[pool_id]': pool_id + } + return self._get('pool_versions.json', params) From 2c0eb86b79e8d86705a3149825d436e4cabceb15 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 20:14:01 +0200 Subject: [PATCH 081/141] Danbooru: implements tag_list() --- pybooru/api_danbooru.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index ab3bc57..91191b9 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -785,3 +785,30 @@ def pool_versions(self, updater_id=None, updater_name=None, pool_id=None): 'search[pool_id]': pool_id } return self._get('pool_versions.json', params) + + def tag_list(self, name_matches=None, category=None, hide_empty=None, + order=None, has_wiki=None, name=None): + """Get a list of tags. + + Parameters: + name_matches: + category: Can be: 0, 1, 3, 4 (general, artist, copyright, + character respectively) + hide_empty: Can be: yes, no. Excludes tags with 0 posts + when "yes". + order: Can be: name, date, count + has_wiki: Can be: yes, no + name: Allows searching for multiple tags with exact given + names, separated by commas. e.g. + search[name]=touhou,original,k-on! would return the + three listed tags. + """ + params = { + 'search[name_matches]': name_matches, + 'search[category]': category, + 'search[hide_empty]': hide_empty, + 'search[order]': order, + 'search[has_wiki]': has_wiki, + 'search[name]': name + } + return self._get('tags.json', params) From 014d353a2049f9762c1c0a16fa0f1f189a00f19b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 20:27:16 +0200 Subject: [PATCH 082/141] Danbooru: implements tag_aliases() --- pybooru/api_danbooru.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 91191b9..c73115a 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -812,3 +812,19 @@ def tag_list(self, name_matches=None, category=None, hide_empty=None, 'search[name]': name } return self._get('tags.json', params) + + def tag_aliases(self, name_matches=None, antecedent_name=None, + tag_id=None): + """Get tags aliasses. + + Parameters: + name_matches: Match antecedent or consequent name. + antecedent_name: Match antecedent name (exact match). + tag_id: The tag alias id. + """ + params = { + 'search[name_matches]': name_matches, + 'search[antecedent_name]': antecedent_name, + 'search[id]': tag_id + } + return self._get('tag_aliases.json', params) From 42d8538e0d949ac3e2d59b3084a33f43b4426e4c Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 20:35:49 +0200 Subject: [PATCH 083/141] Danbooru: implements tag_implications() --- pybooru/api_danbooru.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index c73115a..d935c52 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -815,7 +815,7 @@ def tag_list(self, name_matches=None, category=None, hide_empty=None, def tag_aliases(self, name_matches=None, antecedent_name=None, tag_id=None): - """Get tags aliasses. + """Get tags aliases. Parameters: name_matches: Match antecedent or consequent name. @@ -828,3 +828,19 @@ def tag_aliases(self, name_matches=None, antecedent_name=None, 'search[id]': tag_id } return self._get('tag_aliases.json', params) + + def tag_implications(self, name_matches=None, antecedent_name=None, + tag_id=None): + """Get tags implications. + + Parameters: + name_matches: Match antecedent or consequent name. + antecedent_name: Match antecedent name (exact match). + tag_id: The tag implication id. + """ + params = { + 'search[name_matches]': name_matches, + 'search[antecedent_name]': antecedent_name, + 'search[id]': tag_id + } + return self._get('tag_implications.json', params) From 9489bcb10159e40eb0412c30ee711fdf5d14d28b Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 20 Oct 2016 20:47:23 +0200 Subject: [PATCH 084/141] Danbooru implements tag_related() --- pybooru/api_danbooru.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index d935c52..f266461 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -844,3 +844,14 @@ def tag_implications(self, name_matches=None, antecedent_name=None, 'search[id]': tag_id } return self._get('tag_implications.json', params) + + def tag_related(self, query, category=None): + """Get related tags. + + Parameters: + query: REQUIRED The tag to find the related tags for. + category: If specified, show only tags of a specific category. + Can be: General 0, Artist 1, Copyright 3 and Character 4. + """ + params = {'query': query, 'category': category} + return self._get('related_tag.json', params) From 7d85c5eb38b5967b2fcb1c24d5cd1af7aa8869d1 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 21 Oct 2016 16:50:48 +0200 Subject: [PATCH 085/141] Danbooru: implements wiki_list() --- pybooru/api_danbooru.py | 22 ++++++++++++++++++++++ pybooru/pybooru.py | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index f266461..7e63d9c 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -855,3 +855,25 @@ def tag_related(self, query, category=None): """ params = {'query': query, 'category': category} return self._get('related_tag.json', params) + + def wiki_list(self, title=None, creator_id=None, body_matches=None, + other_names_match=None, creator_name=None, order=None): + """Function to retrieves a list of every wiki page. + + Parameters: + title: + creator_id: + body_matches: + other_names_match: + creator_name: + order: Can be: date, title. + """ + params = { + 'search[title]': title, + 'search[creator_id]': creator_id, + 'search[body_matches]': body_matches, + 'search[other_names_match]': other_names_match, + 'search[creator_name]': creator_name, + 'search[order]': order + } + return self._get('wiki_pages.json', params) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 773c275..07c5eed 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -128,7 +128,7 @@ def _request(self, url, api_call, request_args, method='GET'): }) if response.status_code is 200: - return response.json() or True + return response.json() else: raise PybooruHTTPError("In _request", response.status_code, response.url) From 540d2e8823ec7c07fbbc139ee387f87b50e6a038 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 21 Oct 2016 16:57:34 +0200 Subject: [PATCH 086/141] Danbooru: implements wiki_show() --- pybooru/api_danbooru.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 7e63d9c..63168da 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -877,3 +877,11 @@ def wiki_list(self, title=None, creator_id=None, body_matches=None, 'search[order]': order } return self._get('wiki_pages.json', params) + + def wiki_show(self, page_id): + """Retrieve a specific page of the wiki. + + Parameters: + page_id: REQUIRED Where page_id is the wiki page id. + """ + return self._get('wiki_pages/{0}.json'.format(page_id)) From 23786faf9a4768ae2d65824805244e008a273520 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 21 Oct 2016 17:08:22 +0200 Subject: [PATCH 087/141] Danbooru: implements wiki_create() --- pybooru/api_danbooru.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 63168da..67197cb 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -875,7 +875,7 @@ def wiki_list(self, title=None, creator_id=None, body_matches=None, 'search[other_names_match]': other_names_match, 'search[creator_name]': creator_name, 'search[order]': order - } + } return self._get('wiki_pages.json', params) def wiki_show(self, page_id): @@ -885,3 +885,18 @@ def wiki_show(self, page_id): page_id: REQUIRED Where page_id is the wiki page id. """ return self._get('wiki_pages/{0}.json'.format(page_id)) + + def wiki_create(self, title, body, other_names=None): + """Action to lets you create a wiki page (Requires login) (UNTESTED). + + Parameters: + title: REQUIRED + body: REQUIRED + other_names: + """ + params = { + 'wiki_page[title]': title, + 'wiki_page[body]': body, + 'wiki_page[other_names]': other_names + } + return self._get('wiki_pages.json', params, method='POST', auth=True) From a7cad5891fc13a414c91b125b2324f3ab61f01ba Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 21 Oct 2016 17:09:04 +0200 Subject: [PATCH 088/141] Danbooru: implements wiki_update() --- pybooru/api_danbooru.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 67197cb..90ae29c 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -900,3 +900,20 @@ def wiki_create(self, title, body, other_names=None): 'wiki_page[other_names]': other_names } return self._get('wiki_pages.json', params, method='POST', auth=True) + + def wiki_update(self, page_id, title=None, body=None, other_names=None): + """Action to lets you update a wiki page (Requires login) (UNTESTED). + + Parameters: + page_id: REQURIED Whre page_id is the wiki page id. + title: + body: + other_names: + """ + params = { + 'wiki_page[title]': title, + 'wiki_page[body]': body, + 'wiki_page[other_names]': other_names + } + return self._get('wiki_pages/{0}.json'.format(page_id), params, + method='PUT', auth=True) From 2bd8b548bbbd67d8eafc7b9a163f23c4355165be Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 21 Oct 2016 17:14:08 +0200 Subject: [PATCH 089/141] Danbooru: implements wiki_revert() --- pybooru/api_danbooru.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 90ae29c..73da126 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -890,8 +890,8 @@ def wiki_create(self, title, body, other_names=None): """Action to lets you create a wiki page (Requires login) (UNTESTED). Parameters: - title: REQUIRED - body: REQUIRED + title: REQUIRED. + body: REQUIRED. other_names: """ params = { @@ -917,3 +917,13 @@ def wiki_update(self, page_id, title=None, body=None, other_names=None): } return self._get('wiki_pages/{0}.json'.format(page_id), params, method='PUT', auth=True) + + def wiki_revert(self, page_id, version_id): + """Revert page to a previeous version. + + Parameters: + page_id: REQUIRED Where page_id is the wiki page id. + version_id REQUIRED. + """ + return self._get('wiki_pages/{0}/revert.json'.format(page_id), + {'version_id': version_id}, method='PUT', auth=True) From 6cb820749bf148047222bad0ea90a2ff577ef15d Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 21 Oct 2016 17:36:41 +0200 Subject: [PATCH 090/141] Danbooru: implements forum_topics_list() --- pybooru/api_danbooru.py | 19 ++++++++++++++++++- pybooru/api_moebooru.py | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 73da126..381666c 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -919,7 +919,7 @@ def wiki_update(self, page_id, title=None, body=None, other_names=None): method='PUT', auth=True) def wiki_revert(self, page_id, version_id): - """Revert page to a previeous version. + """Revert page to a previeous version (Requires login) (UNTESTED). Parameters: page_id: REQUIRED Where page_id is the wiki page id. @@ -927,3 +927,20 @@ def wiki_revert(self, page_id, version_id): """ return self._get('wiki_pages/{0}/revert.json'.format(page_id), {'version_id': version_id}, method='PUT', auth=True) + + def forum_topics_list(self, title_matches=None, title=None, + category_id=None): + """Function to get forum topics. + + Parameters: + title_matches: Search body for the given terms. + title: Exact title match. + category_id: Can be: 0, 1, 2 (General, Tags, Bugs & Features + respectively) + """ + params = { + 'search[title_matches]': title_matches, + 'search[title]': title, + 'search[category_id]': category_id + } + return self._get('forum_topics.json', params) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 9590a61..9afb8e9 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -456,7 +456,7 @@ def user_search(self, **params): return self._get('user', params) def forum_list(self, **params): - """Function to _get forum posts. + """Function to get forum posts. If you don't specify any parameters you'll _get a listing of all users. From b0538ddb8a5c4fe082b0af76eff3c351fe79fa4d Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 21 Oct 2016 17:50:11 +0200 Subject: [PATCH 091/141] Danbooru: implements forum_topic_show() --- pybooru/api_danbooru.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 381666c..80613e8 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -928,8 +928,8 @@ def wiki_revert(self, page_id, version_id): return self._get('wiki_pages/{0}/revert.json'.format(page_id), {'version_id': version_id}, method='PUT', auth=True) - def forum_topics_list(self, title_matches=None, title=None, - category_id=None): + def forum_topic_list(self, title_matches=None, title=None, + category_id=None): """Function to get forum topics. Parameters: @@ -944,3 +944,11 @@ def forum_topics_list(self, title_matches=None, title=None, 'search[category_id]': category_id } return self._get('forum_topics.json', params) + + def forum_topic_show(self, topic_id): + """Retrieve a specific forum topic. + + Parameters: + topic_id: REQUIRED Where topic_id is the forum topic id. + """ + return self._get('forum_topics/{0}.json'.format(topic_id)) From c2df48c85443a6969cebc97ab78a6c76e7cb6853 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 16:52:04 +0100 Subject: [PATCH 092/141] Danbooru: implement forum_topic_create() --- pybooru/api_danbooru.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 80613e8..654c0b7 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -952,3 +952,19 @@ def forum_topic_show(self, topic_id): topic_id: REQUIRED Where topic_id is the forum topic id. """ return self._get('forum_topics/{0}.json'.format(topic_id)) + + def forum_topic_create(self, title, body, category): + """Function to create topic (Requires login) (UNTESTED). + + Parameters: + title: topic title. + body: Message of the initial post. + category: Can be: 0, 1, 2 (General, Tags, Bugs & Features + respectively). + """ + params = { + 'forum_topic[title]': title, + 'forum_topic[original_post_attributes][body]': body, + 'forum_topic[category_id]': category + } + return self._get('forum_topics.json', params, method='POST', auth=True) From 7e99d64c2097323f07a1f2f1982bd88ff070c152 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 17:24:30 +0100 Subject: [PATCH 093/141] Fix Danbooru username and api_key check --- pybooru/danbooru.py | 10 ++++++++-- pybooru/moebooru.py | 3 ++- pybooru/pybooru.py | 5 +++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index 0e2d04f..ec5d128 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -12,6 +12,7 @@ # Pybooru imports from .pybooru import Pybooru from .api_danbooru import DanbooruApi +from .exceptions import PybooruError class Danbooru(Pybooru, DanbooruApi): @@ -40,7 +41,8 @@ class Danbooru(Pybooru, DanbooruApi): def __init__(self, site_name="", site_url="", username="", api_key=""): super(Danbooru, self).__init__(site_name, site_url, username) - self.api_key = api_key + if api_key is not "": + self.api_key = api_key def _get(self, api_call, params=None, method='GET', auth=False, file_=None): @@ -53,7 +55,11 @@ def _get(self, api_call, params=None, method='GET', auth=False, # Adds auth if auth is True: - request_args['auth'] = (self.username, self.api_key) + try: + request_args['auth'] = (self.username, self.api_key) + except AttributeError: + raise PybooruError("'username' and 'api_key' attribute of \ + Danbooru are required.") # Do call return self._request(url, api_call, request_args, method) diff --git a/pybooru/moebooru.py b/pybooru/moebooru.py index 3d6a176..569bd64 100644 --- a/pybooru/moebooru.py +++ b/pybooru/moebooru.py @@ -66,7 +66,8 @@ def __init__(self, site_name="", site_url="", username="", password="", super(Moebooru, self).__init__(site_name, site_url, username) self.api_version = api_version.lower() - self.password = password + if password is not "": + self.password = password self.password_hash = None def _build_url(self, api_call): diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 07c5eed..53f4afe 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -39,12 +39,13 @@ def __init__(self, site_name="", site_url="", username=""): site_name: The site name in 'SITE_LIST', default sites. site_url: URL of on Moebooru/Danbooru based sites. username: Your username of the site (Required only for functions - that modify the content). + that modify the content). """ # Attributes self.site_name = site_name.lower() self.site_url = site_url.lower() - self.username = username + if username is not "": + self.username = username self.last_call = {} # Set HTTP Client From 6dd47cecc868dc455f043403d668b1e45fb784a8 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 17:35:24 +0100 Subject: [PATCH 094/141] Danbooru: implement forum_topic_update() --- pybooru/api_danbooru.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 654c0b7..0376eff 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -953,7 +953,7 @@ def forum_topic_show(self, topic_id): """ return self._get('forum_topics/{0}.json'.format(topic_id)) - def forum_topic_create(self, title, body, category): + def forum_topic_create(self, title, body, category=None): """Function to create topic (Requires login) (UNTESTED). Parameters: @@ -968,3 +968,18 @@ def forum_topic_create(self, title, body, category): 'forum_topic[category_id]': category } return self._get('forum_topics.json', params, method='POST', auth=True) + + def forum_topic_update(self, topic_id, title=None, category=None): + """Update a specific topic (Login Requires) (UNTESTED). + + Parameters: + title: Topic title. + category: Can be: 0, 1, 2 (General, Tags, Bugs & Features + respectively) + """ + params = { + 'forum_topic[title]': title, + 'forum_topic[category_id]': category + } + return self._get('forum_topics/{0}.json'.format(topic_id), params, + method='PUT', auth=True) From 622de3722f918c384ca3c59171c084d26627a7ea Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 17:44:58 +0100 Subject: [PATCH 095/141] Danbooru: Implement forum_topic_delete() --- pybooru/api_danbooru.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 0376eff..edc7651 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -973,6 +973,7 @@ def forum_topic_update(self, topic_id, title=None, category=None): """Update a specific topic (Login Requires) (UNTESTED). Parameters: + topic_id: REQUIRED Where topic_id is the topic id. title: Topic title. category: Can be: 0, 1, 2 (General, Tags, Bugs & Features respectively) @@ -983,3 +984,12 @@ def forum_topic_update(self, topic_id, title=None, category=None): } return self._get('forum_topics/{0}.json'.format(topic_id), params, method='PUT', auth=True) + + def forum_topic_delete(self, topic_id): + """Delete a topic (Login Requires) (Moderator+) (UNTESTED). + + Parameters: + topic_id: REQUIRED Where topic_id is the topic id. + """ + return self._get('forum_topics/{0}.json'.format(topic_id), + method='DELETE', auth=True) From 4c6bcc14ef8c70ae771fe56302c048ff07a51fc4 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 17:49:10 +0100 Subject: [PATCH 096/141] Danbooru: Implement forum_topic_undelete() --- pybooru/api_danbooru.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index edc7651..ce3a71c 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -973,7 +973,7 @@ def forum_topic_update(self, topic_id, title=None, category=None): """Update a specific topic (Login Requires) (UNTESTED). Parameters: - topic_id: REQUIRED Where topic_id is the topic id. + topic_id: REQUIRED .ñWhere topic_id is the topic id. title: Topic title. category: Can be: 0, 1, 2 (General, Tags, Bugs & Features respectively) @@ -993,3 +993,12 @@ def forum_topic_delete(self, topic_id): """ return self._get('forum_topics/{0}.json'.format(topic_id), method='DELETE', auth=True) + + def forum_topic_undelete(self, topic_id): + """Un delete a topic (Login requries) (Moderator+) (UNTESTED). + + Parameters: + topic_id: REQUIRED Where topic_id is the topic id. + """ + return self._get('forum_topics/{0}/undelete.json'.format(topic_id), + method='POST', auth=True) From 86dc92dc6cffc7755cb5e575f4876cda394d9332 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 18:12:39 +0100 Subject: [PATCH 097/141] Danbooru: Implement artist_commentary_list() --- pybooru/api_danbooru.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index ce3a71c..79eefb8 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1002,3 +1002,25 @@ def forum_topic_undelete(self, topic_id): """ return self._get('forum_topics/{0}/undelete.json'.format(topic_id), method='POST', auth=True) + + def artist_commentary_list(self, text_matches=None, post_id=None, + post_tags_match=None, original_present=None, + translated_present=None): + """list artist commentary. + + Parameters: + text_matches: + post_id: + post_tags_match: The commentary's post's tags match the given + terms. Meta-tags not supported. + original_present: Can be: yes, no + translated_present: Can be: yes, no + """ + params = { + 'search[text_matches]': text_matches, + 'search[post_id]': post_id, + 'search[post_tags_match]': post_tags_match, + 'search[original_present]': original_present, + 'search[translated_present]': translated_present + } + return self._get('artist_commentaries.json', params) From a295538b7090a82244d92f301862f665f62419dc Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 18:27:05 +0100 Subject: [PATCH 098/141] Danbooru: Implement artist_commentary_create_update() --- pybooru/api_danbooru.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 79eefb8..1048154 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1024,3 +1024,25 @@ def artist_commentary_list(self, text_matches=None, post_id=None, 'search[translated_present]': translated_present } return self._get('artist_commentaries.json', params) + + def artist_commentary_create_update(self, post_id, original_title, + original_description, translated_title, + translated_description): + """Create or update artist commentary (Login requires) (UNTESTED). + + Parameters: + post_id: REQUIRED. + original_title: + original_description: + translated_title: + translated_description: + """ + params = { + 'artist_commentary[post_id]': post_id, + 'artist_commentary[original_title]': original_title, + 'artist_commentary[original_description]': original_description, + 'artist_commentary[translated_title]': translated_title, + 'artist_commentary[translated_description]': translated_description + } + return self._get('artist_commentaries/create_or_update.json', params, + method='POST', auth=True) From f344fd40baac0e05f470b15effb7576a91e424b3 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 18:35:17 +0100 Subject: [PATCH 099/141] Danbooru: Implement artist_commentary_revert() --- pybooru/api_danbooru.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 1048154..71183c9 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1028,7 +1028,7 @@ def artist_commentary_list(self, text_matches=None, post_id=None, def artist_commentary_create_update(self, post_id, original_title, original_description, translated_title, translated_description): - """Create or update artist commentary (Login requires) (UNTESTED). + """Create or update artist commentary (Requires login) (UNTESTED). Parameters: post_id: REQUIRED. @@ -1046,3 +1046,14 @@ def artist_commentary_create_update(self, post_id, original_title, } return self._get('artist_commentaries/create_or_update.json', params, method='POST', auth=True) + + def artist_commentary_revert(self, id_, version_id): + """Revert artist commentary (Requires login) (UNTESTED). + + Parameters: + id_: REQUIRED The artist commentary id. + version_id: REQUIRED The artist commentary version id to revert to. + """ + params = {'version_id': version_id} + return self._get('artist_commentaries/{0}/revert.json'.format(id_), + params, method='PUT', auth=True) From 9c5a7799394a21a49e23992f517beb761a54ec7e Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 18:47:01 +0100 Subject: [PATCH 100/141] Danbooru: Implement artist_commentary_version() --- pybooru/api_danbooru.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 71183c9..4e100b0 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1057,3 +1057,16 @@ def artist_commentary_revert(self, id_, version_id): params = {'version_id': version_id} return self._get('artist_commentaries/{0}/revert.json'.format(id_), params, method='PUT', auth=True) + + def artist_commentary_version(self, post_id, updater_id): + """Return list of artist commentary versions. + + Parameters: + updater_id: REQUIRED. + post_id: REQUIRED. + """ + params = { + 'search[updater_id]': updater_id, + 'search[post_id]': post_id + } + return self._get('artist_commentary_versions.json', params) From 9114ed02ce9f3d3156a1d763950780379c812cef Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 19:02:09 +0100 Subject: [PATCH 101/141] Danbooru: Implement wiki_versions_list() --- pybooru/api_danbooru.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 4e100b0..c1b51e7 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -650,8 +650,8 @@ def note_versions(self, updater_id=None, post_id=None, note_id=None): } return self._get('note_versions.json', params) - def artist_version(self, name=None, updater_id=None, artist_id=None, - is_active=None, is_banned=None, order=None): + def artist_versions(self, name=None, updater_id=None, artist_id=None, + is_active=None, is_banned=None, order=None): """Get list of artist versions. Parameters: @@ -1058,7 +1058,7 @@ def artist_commentary_revert(self, id_, version_id): return self._get('artist_commentaries/{0}/revert.json'.format(id_), params, method='PUT', auth=True) - def artist_commentary_version(self, post_id, updater_id): + def artist_commentary_versions(self, post_id, updater_id): """Return list of artist commentary versions. Parameters: @@ -1070,3 +1070,25 @@ def artist_commentary_version(self, post_id, updater_id): 'search[post_id]': post_id } return self._get('artist_commentary_versions.json', params) + + def wiki_versions(self, wiki_page_id, updater_id): + """Return a list of wiki page version. + + Parameters: + updater_id: REQUIRED. + wiki_page_id: REQUIRED. + """ + params = { + 'earch[updater_id]': updater_id, + 'search[wiki_page_id]': wiki_page_id + } + return self._get('wiki_page_versions.json', params) + + def wiki_versions_show(self, wiki_page_id): + """Return a specific wiki page version. + + Parameters: + wiki_page_id: REQUIRED Where wiki_page_id is the wiki page version + id. + """ + return self._get('wiki_page_versions/{0}.json'.format(wiki_page_id)) From 225873d9da5d903f653cdea70bb8edd7cdedb2d3 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 19:17:59 +0100 Subject: [PATCH 102/141] Danbooru: Implement forum_post_list() --- pybooru/api_danbooru.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index c1b51e7..ba65634 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1092,3 +1092,27 @@ def wiki_versions_show(self, wiki_page_id): id. """ return self._get('wiki_page_versions/{0}.json'.format(wiki_page_id)) + + def forum_post_list(self, creator_id=None, creator_name=None, + topic_id=None, topic_title_matches=None, + topic_category_id=None, body_matches=None): + """Return a list of forum posts. + + Parameters: + creator_id: + creator_name: + topic_id: + topic_title_matches: + topic_category_id: Can be: 0, 1, 2 (General, Tags, Bugs & Features + respectively) + body_matches: + """ + params = { + 'search[creator_id]': creator_id, + 'search[creator_name]': creator_name, + 'search[topic_id]': topic_id, + 'search[topic_title_matches]': topic_title_matches, + 'search[topic_category_id]': topic_category_id, + 'search[body_matches]': body_matches + } + return self._get('forum_posts.json', params) From 9e0374e9816f74987cf50d8ecc1a1ba31603aaab Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 19:29:24 +0100 Subject: [PATCH 103/141] Danbooru: Implement forum_post_create() --- pybooru/api_danbooru.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index ba65634..2539f2c 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1116,3 +1116,16 @@ def forum_post_list(self, creator_id=None, creator_name=None, 'search[body_matches]': body_matches } return self._get('forum_posts.json', params) + + def forum_post_create(self, topic_id, body): + """Create a forum post (Requires login). + + Parameters: + topic_id: + body: + """ + params = { + 'forum_post[topic_id]': topic_id, + 'forum_post[body]': body + } + return self._get('forum_posts.json', params, method='POST', auth=True) From 6a8b17656db82a49e3e93caf4e4f2767c347ed49 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Tue, 29 Nov 2016 19:39:08 +0100 Subject: [PATCH 104/141] Danbooru: Implement forum_post_update() --- pybooru/api_danbooru.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 2539f2c..2fb1088 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1129,3 +1129,14 @@ def forum_post_create(self, topic_id, body): 'forum_post[body]': body } return self._get('forum_posts.json', params, method='POST', auth=True) + + def forum_post_update(self, topic_id, body): + """Update a specific forum post (Requries login) (UNTESTED). + + Parameters: + post_id: REQUIRED Forum topic id. + body: REQUIRED. + """ + params = {'forum_post[body]': body} + return self._get('forum_posts/{0}.json'.format(topic_id), params, + method='PUT', auth=True) From d65cabb414d3c3a3f575efb4663144e8d32f5b36 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 11:40:38 +0100 Subject: [PATCH 105/141] Danbooru: Implement forum_post_delete() --- pybooru/api_danbooru.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 2fb1088..f356cab 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1121,8 +1121,8 @@ def forum_post_create(self, topic_id, body): """Create a forum post (Requires login). Parameters: - topic_id: - body: + topic_id: REQUIRED. + body: REQUIRED. """ params = { 'forum_post[topic_id]': topic_id, @@ -1131,7 +1131,7 @@ def forum_post_create(self, topic_id, body): return self._get('forum_posts.json', params, method='POST', auth=True) def forum_post_update(self, topic_id, body): - """Update a specific forum post (Requries login) (UNTESTED). + """Update a specific forum post (Requries login)(Moderator+)(UNTESTED). Parameters: post_id: REQUIRED Forum topic id. @@ -1140,3 +1140,12 @@ def forum_post_update(self, topic_id, body): params = {'forum_post[body]': body} return self._get('forum_posts/{0}.json'.format(topic_id), params, method='PUT', auth=True) + + def forum_post_delete(self, post_id): + """Delete a specific forum post (Requires login)(Moderator+)(UNTESTED). + + Parameters: + post_id: REQUIRED forum post id. + """ + return self._get('forum_posts/{0}.json'.format(post_id), + method='DELETE', auth=True) From e71c853ed6f1ea2a39040a4ece270f7a4b1719c2 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 11:45:30 +0100 Subject: [PATCH 106/141] Danbooru: implement forum_post_undelete() --- pybooru/api_danbooru.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index f356cab..ba9c53e 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -1149,3 +1149,13 @@ def forum_post_delete(self, post_id): """ return self._get('forum_posts/{0}.json'.format(post_id), method='DELETE', auth=True) + + def forum_post_undelete(self, post_id): + """Undelete a specific forum post (Requires login) (Moderator+) + (UNTESTED). + + Parameters: + post_id: REQUIRED forum post id. + """ + return self._get('forum_posts/{0}/undelete.json'.format(post_id), + method='POST', auth=True) From 1f29842e540b81101bae2095958df10d288cff42 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 12:56:37 +0100 Subject: [PATCH 107/141] Fix typo --- pybooru/api_danbooru.py | 307 ++++++++++++++++++++-------------------- 1 file changed, 152 insertions(+), 155 deletions(-) diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index ba9c53e..a6ce941 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -18,7 +18,7 @@ class DanbooruApi(object): """Contains all Danbooru API calls. - API Versions: v2.105.0 + API Version: v2.105.0 (77e06b6) doc: https://danbooru.donmai.us/wiki_pages/43568 """ @@ -88,7 +88,7 @@ def post_copy_notes(self, id_, other_post_id): def post_vote(self, id_, score): """Action lets you vote for a post (Requires login). - Danbooru: Post votes/create + Danbooru: Post votes/create. Parameters: id_: REQUIRED Ppost id. @@ -152,11 +152,26 @@ def post_appeals_create(self, id_, reason): id_: REQUIRED The id of the appealed post. reason: REQUIRED The reason of the appeal. """ + params = {'post_appeal[post_id]': id_, 'post_appeal[reason]': reason} + return self._get('post_appeals.json', params, 'POST', auth=True) + + def post_versions(self, updater_name=None, updater_id=None, + post_id=None, start_id=None): + """Get list of post versions. + + Parameters: + updater_name: + updater_id: + post_id: + start_id: + """ params = { - 'post_appeal[post_id]': id_, - 'post_appeal[reason]': reason + 'search[updater_name]': updater_name, + 'search[updater_id]': updater_id, + 'search[post_id]': post_id, + 'search[start_id]': start_id } - return self._get('post_appeals.json', params, 'POST', auth=True) + return self._get('post_versions.json', params) def upload_list(self, uploader_id=None, uploader_name=None, source=None): """Search and eturn a uploads list (Requires login). @@ -269,22 +284,22 @@ def comment_update(self, id_, body, do_not_bump_post=None): return self._get('comments/{0}.json'.format(id_), params, 'PUT', auth=True) - def comment_show(self, id_): + def comment_show(self, comment_id): """Get a specific comment. Parameters: id_: REQUIRED the id number of the comment to retrieve. """ - return self._get('comments/{0}.json'.format(id_)) + return self._get('comments/{0}.json'.format(comment_id)) - def comment_delete(self, id_): + def comment_delete(self, comment_id): """Remove a specific comment (Requires login). Parameters: id_: REQUIRED the id number of the comment to remove. """ - return self._get('comments/{0}.json'.format(id_), method='DELETE', - auth=True) + return self._get('comments/{0}.json'.format(comment_id), + method='DELETE', auth=True) def favorite_list(self, user_id=None): """Return a list with favorite posts (Requires login). @@ -483,6 +498,96 @@ def artist_revert(self, artist_id, version_id): return self._get('artists/{0}/revert.json'.format(artist_id), params, method='PUT', auth=True) + def artist_versions(self, name=None, updater_id=None, artist_id=None, + is_active=None, is_banned=None, order=None): + """Get list of artist versions. + + Parameters: + name: + updater_id: + artist_id: + is_active: Can be: true, false. + is_banned: Can be: true, false. + order: Can be: name, date. + """ + params = { + 'search[name]': name, + 'search[updater_id]': updater_id, + 'search[artist_id]': artist_id, + 'search[is_active]': is_active, + 'search[is_banned]': is_banned, + 'search[order]': order + } + return self._get('artist_versions.json', params) + + def artist_commentary_list(self, text_matches=None, post_id=None, + post_tags_match=None, original_present=None, + translated_present=None): + """list artist commentary. + + Parameters: + text_matches: + post_id: + post_tags_match: The commentary's post's tags match the given + terms. Meta-tags not supported. + original_present: Can be: yes, no + translated_present: Can be: yes, no + """ + params = { + 'search[text_matches]': text_matches, + 'search[post_id]': post_id, + 'search[post_tags_match]': post_tags_match, + 'search[original_present]': original_present, + 'search[translated_present]': translated_present + } + return self._get('artist_commentaries.json', params) + + def artist_commentary_create_update(self, post_id, original_title, + original_description, translated_title, + translated_description): + """Create or update artist commentary (Requires login) (UNTESTED). + + Parameters: + post_id: REQUIRED. + original_title: + original_description: + translated_title: + translated_description: + """ + params = { + 'artist_commentary[post_id]': post_id, + 'artist_commentary[original_title]': original_title, + 'artist_commentary[original_description]': original_description, + 'artist_commentary[translated_title]': translated_title, + 'artist_commentary[translated_description]': translated_description + } + return self._get('artist_commentaries/create_or_update.json', params, + method='POST', auth=True) + + def artist_commentary_revert(self, id_, version_id): + """Revert artist commentary (Requires login) (UNTESTED). + + Parameters: + id_: REQUIRED The artist commentary id. + version_id: REQUIRED The artist commentary version id to revert to. + """ + params = {'version_id': version_id} + return self._get('artist_commentaries/{0}/revert.json'.format(id_), + params, method='PUT', auth=True) + + def artist_commentary_versions(self, post_id, updater_id): + """Return list of artist commentary versions. + + Parameters: + updater_id: REQUIRED. + post_id: REQUIRED. + """ + params = { + 'search[updater_id]': updater_id, + 'search[post_id]': post_id + } + return self._get('artist_commentary_versions.json', params) + def note_list(self, group_by=None, body_matches=None, post_id=None, post_tags_match=None, creator_name=None, creator_id=None): """Return list of notes. @@ -579,6 +684,21 @@ def note_revert(self, note_id, version_id): return self._get('notes/{0}/revert.json'.format(note_id), {'version_id': version_id}, method='PUT', auth=True) + def note_versions(self, updater_id=None, post_id=None, note_id=None): + """Get list of note versions. + + Parameters: + updater_id: + post_id: + note_id: + """ + params = { + 'search[updater_id]': updater_id, + 'search[post_id]': post_id, + 'search[note_id]': note_id + } + return self._get('note_versions.json', params) + def user_list(self, name=None, min_level=None, max_level=None, level=None, user_id=None, order=None): """Function to get a list of users or a specific user. @@ -617,61 +737,6 @@ def user_show(self, user_id): """ return self._get('users/{0}.json'.format(user_id)) - def post_versions(self, updater_name=None, updater_id=None, - post_id=None, start_id=None): - """Get list of post versions. - - Parameters: - updater_name: - updater_id: - post_id: - start_id: - """ - params = { - 'search[updater_name]': updater_name, - 'search[updater_id]': updater_id, - 'search[post_id]': post_id, - 'search[start_id]': start_id - } - return self._get('post_versions.json', params) - - def note_versions(self, updater_id=None, post_id=None, note_id=None): - """Get list of note versions. - - Parameters: - updater_id: - post_id: - note_id: - """ - params = { - 'search[updater_id]': updater_id, - 'search[post_id]': post_id, - 'search[note_id]': note_id - } - return self._get('note_versions.json', params) - - def artist_versions(self, name=None, updater_id=None, artist_id=None, - is_active=None, is_banned=None, order=None): - """Get list of artist versions. - - Parameters: - name: - updater_id: - artist_id: - is_active: Can be: true, false. - is_banned: Can be: true, false. - order: Can be: name, date. - """ - params = { - 'search[name]': name, - 'search[updater_id]': updater_id, - 'search[artist_id]': artist_id, - 'search[is_active]': is_active, - 'search[is_banned]': is_banned, - 'search[order]': order - } - return self._get('artist_versions.json', params) - def pool_list(self, name_matches=None, description_matches=None, creator_name=None, creator_id=None, is_active=None, order=None, category=None): @@ -928,6 +993,28 @@ def wiki_revert(self, page_id, version_id): return self._get('wiki_pages/{0}/revert.json'.format(page_id), {'version_id': version_id}, method='PUT', auth=True) + def wiki_versions(self, wiki_page_id, updater_id): + """Return a list of wiki page version. + + Parameters: + updater_id: REQUIRED. + wiki_page_id: REQUIRED. + """ + params = { + 'earch[updater_id]': updater_id, + 'search[wiki_page_id]': wiki_page_id + } + return self._get('wiki_page_versions.json', params) + + def wiki_versions_show(self, wiki_page_id): + """Return a specific wiki page version. + + Parameters: + wiki_page_id: REQUIRED Where wiki_page_id is the wiki page version + id. + """ + return self._get('wiki_page_versions/{0}.json'.format(wiki_page_id)) + def forum_topic_list(self, title_matches=None, title=None, category_id=None): """Function to get forum topics. @@ -1003,96 +1090,6 @@ def forum_topic_undelete(self, topic_id): return self._get('forum_topics/{0}/undelete.json'.format(topic_id), method='POST', auth=True) - def artist_commentary_list(self, text_matches=None, post_id=None, - post_tags_match=None, original_present=None, - translated_present=None): - """list artist commentary. - - Parameters: - text_matches: - post_id: - post_tags_match: The commentary's post's tags match the given - terms. Meta-tags not supported. - original_present: Can be: yes, no - translated_present: Can be: yes, no - """ - params = { - 'search[text_matches]': text_matches, - 'search[post_id]': post_id, - 'search[post_tags_match]': post_tags_match, - 'search[original_present]': original_present, - 'search[translated_present]': translated_present - } - return self._get('artist_commentaries.json', params) - - def artist_commentary_create_update(self, post_id, original_title, - original_description, translated_title, - translated_description): - """Create or update artist commentary (Requires login) (UNTESTED). - - Parameters: - post_id: REQUIRED. - original_title: - original_description: - translated_title: - translated_description: - """ - params = { - 'artist_commentary[post_id]': post_id, - 'artist_commentary[original_title]': original_title, - 'artist_commentary[original_description]': original_description, - 'artist_commentary[translated_title]': translated_title, - 'artist_commentary[translated_description]': translated_description - } - return self._get('artist_commentaries/create_or_update.json', params, - method='POST', auth=True) - - def artist_commentary_revert(self, id_, version_id): - """Revert artist commentary (Requires login) (UNTESTED). - - Parameters: - id_: REQUIRED The artist commentary id. - version_id: REQUIRED The artist commentary version id to revert to. - """ - params = {'version_id': version_id} - return self._get('artist_commentaries/{0}/revert.json'.format(id_), - params, method='PUT', auth=True) - - def artist_commentary_versions(self, post_id, updater_id): - """Return list of artist commentary versions. - - Parameters: - updater_id: REQUIRED. - post_id: REQUIRED. - """ - params = { - 'search[updater_id]': updater_id, - 'search[post_id]': post_id - } - return self._get('artist_commentary_versions.json', params) - - def wiki_versions(self, wiki_page_id, updater_id): - """Return a list of wiki page version. - - Parameters: - updater_id: REQUIRED. - wiki_page_id: REQUIRED. - """ - params = { - 'earch[updater_id]': updater_id, - 'search[wiki_page_id]': wiki_page_id - } - return self._get('wiki_page_versions.json', params) - - def wiki_versions_show(self, wiki_page_id): - """Return a specific wiki page version. - - Parameters: - wiki_page_id: REQUIRED Where wiki_page_id is the wiki page version - id. - """ - return self._get('wiki_page_versions/{0}.json'.format(wiki_page_id)) - def forum_post_list(self, creator_id=None, creator_name=None, topic_id=None, topic_title_matches=None, topic_category_id=None, body_matches=None): From cfb7e2c7d1b25320dd38452380f64f309e4ed9d0 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 13:05:52 +0100 Subject: [PATCH 108/141] pybooru.py: change imports order --- pybooru/pybooru.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index 53f4afe..d306c99 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -13,8 +13,8 @@ from __future__ import absolute_import # External imports -import requests import re +import requests # pybooru imports from . import __version__ From 35cea5cf6dfd068dd099fbd2cc608a6dcf931f94 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 13:35:47 +0100 Subject: [PATCH 109/141] Change provisional_test.py --- provisional_test.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/provisional_test.py b/provisional_test.py index b288417..73275af 100644 --- a/provisional_test.py +++ b/provisional_test.py @@ -1,11 +1,18 @@ # encoding: utf-8 from __future__ import print_function -from pybooru import Pybooru +from pybooru import Danbooru +from pybooru import Moebooru -# client = Pybooru(site_url='konachan.com') -client = Pybooru(site_url="http://www.konachan.com") +konachan = Moebooru("konachan") -tags = client.tag_list(order='date') -print(client.last_call) -posts = client.post_list() -print(client.last_call) +kona_tags = konachan.tag_list(order='date') +print(konachan.last_call) +kona_post = konachan.post_list() +print(konachan.last_call) + +danbooru = Danbooru('danbooru') + +dan_tags = danbooru.tag_list(order='name') +print(danbooru.last_call) +dan_post = danbooru.post_list(tags="computer") +print(danbooru.last_call) From f2ff88413f02a4b5d080c2d317b68a20def2f212 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 14:11:19 +0100 Subject: [PATCH 110/141] Update .pylintrc --- .pylintrc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.pylintrc b/.pylintrc index 9c2648e..2679d1a 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,4 +1,7 @@ # Pylint config file +[TYPECHECK] +generated-members=objects + [REPORTS] -msg-template="{path}:{line}:{column} - [{msg_id} in {obj}]: ({symbol}), {msg} +msg-template={path}:{line}:{column} - [{msg_id} in {obj}]: ({symbol}), {msg} From 41b21399cd78868cb8e95a67b022678359eb0819 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 14:17:13 +0100 Subject: [PATCH 111/141] Travis: updated --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4dca078..7dcd49f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,6 @@ before_script: script: # Run pylint - - pylint --errors-only --rcfile=".pylintrc" pybooru/ + - pylint --errors-only --rcfile=.pylintrc pybooru/ # Run test script, but at the moment is a provisional test - python provisional_test.py From 8b8d5ba884227dca31e6c24f6470dd6dfffcc36c Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 16:00:18 +0100 Subject: [PATCH 112/141] Change class name --- .travis.yml | 10 ++++------ pybooru/api_danbooru.py | 2 +- pybooru/api_moebooru.py | 2 +- pybooru/danbooru.py | 4 ++-- pybooru/moebooru.py | 4 ++-- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7dcd49f..6b795d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,17 +19,15 @@ branches: - master install: - # Install pylint - - sudo apt-get install pylint - # Install requests - - pip install requests + # Install requests and pylint + - pip install requests pylint before_script: # Remove python binari files - rm --recursive --force --verbose *.py[cod] - -script: # Run pylint - pylint --errors-only --rcfile=.pylintrc pybooru/ + +script: # Run test script, but at the moment is a provisional test - python provisional_test.py diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index a6ce941..83b9a5b 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -15,7 +15,7 @@ from .exceptions import PybooruAPIError -class DanbooruApi(object): +class DanbooruApi_Mixin(object): """Contains all Danbooru API calls. API Version: v2.105.0 (77e06b6) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 9afb8e9..75d1a39 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -15,7 +15,7 @@ from .exceptions import PybooruAPIError -class MoebooruApi(object): +class MoebooruApi_Mixin(object): """Contains all Moebooru API calls. API Versions: 1.13.0+update.3 and 1.13.0 diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index ec5d128..f8765ef 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -11,11 +11,11 @@ # Pybooru imports from .pybooru import Pybooru -from .api_danbooru import DanbooruApi +from .api_danbooru import DanbooruApi_Mixin from .exceptions import PybooruError -class Danbooru(Pybooru, DanbooruApi): +class Danbooru(Pybooru, DanbooruApi_Mixin): """Danbooru class (inherits: Pybooru and DanbooruApi). To initialize Pybooru, you need to specify one of these two diff --git a/pybooru/moebooru.py b/pybooru/moebooru.py index 569bd64..3b253c4 100644 --- a/pybooru/moebooru.py +++ b/pybooru/moebooru.py @@ -17,12 +17,12 @@ # Pybooru imports from .pybooru import Pybooru -from .api_moebooru import MoebooruApi +from .api_moebooru import MoebooruApi_Mixin from .exceptions import PybooruError from .resources import SITE_LIST -class Moebooru(Pybooru, MoebooruApi): +class Moebooru(Pybooru, MoebooruApi_Mixin): """Moebooru class (inherits: Pybooru and MoebooruApi). To initialize Pybooru, you need to specify one of these two From 01d15dc1654e2f249cdcb7933a3df4f2dc64c881 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 16:05:59 +0100 Subject: [PATCH 113/141] Change pylint installation with Travis --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6b795d6..0347314 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,8 +19,11 @@ branches: - master install: - # Install requests and pylint - - pip install requests pylint + # Install requests + - pip install requests + + # Install pylint + - sudo apt-get install pylint before_script: # Remove python binari files From e369e40bd25c5f330af8fefb914794ed228242e6 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 30 Nov 2016 16:42:56 +0100 Subject: [PATCH 114/141] End of Python 3.2 support --- .travis.yml | 1 - README.md | 2 +- setup.py | 6 +++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0347314..7e20e2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ language: python python: - "2.6" - "2.7" - - "3.2" - "3.3" - "3.4" - "3.5" diff --git a/README.md b/README.md index 210b291..fb41284 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ - Licensed under: **MIT License** ## Dependencies. -- Python: >= 2.6 or Python: >= 3 +- Python: >= 2.6 or Python: >= 3.3 - [requests.](http://docs.python-requests.org/en/latest/) ## Installation diff --git a/setup.py b/setup.py index 31e1335..23376d8 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,8 @@ name="Pybooru", version=pybooru.__version__, author=pybooru.__author__, - description="Pybooru is a Python library to access API of Danbooru/Moebooru based sites.", + description="Pybooru is a Python library to access API of Danbooru/Moebooru \ + based sites.", long_description=long_description, author_email="danielluque14@gmail.com", url="https://github.com/LuqueDaniel/pybooru", @@ -29,6 +30,9 @@ "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Topic :: Software Development :: Libraries :: Python Modules", From d25f2915abf3b53a19209ed17cbad2357269b900 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Dec 2016 15:01:59 +0100 Subject: [PATCH 115/141] Gitignore: test.json --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 75adbe0..5909fe0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ __pycache__ # ignore test file pro.py +test.json # build/dist files build/ From c359825190cdf91efc81833d3fb08dd8e52088bc Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Dec 2016 15:13:53 +0100 Subject: [PATCH 116/141] Change package docstring --- pybooru/__init__.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pybooru/__init__.py b/pybooru/__init__.py index ed0fb82..a0e611b 100644 --- a/pybooru/__init__.py +++ b/pybooru/__init__.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- - """ Pybooru ------- -Pybooru is a Python library to access API of Moebooru based sites. +Pybooru is a API client written in Python for Danbooru and Moebooru based sites. Under MIT license. Pybooru requires "requests" package to work. @@ -19,10 +18,10 @@ resources -- Contains all resources for Pybooru. """ -__version__ = "3.0.1" +__version__ = "4.0.0" __license__ = "MIT" -__url__ = "http://github.com/LuqueDaniel/pybooru" -__author__ = "Daniel Luque " +__source_url__ = "http://github.com/LuqueDaniel/pybooru" +__author__ = "Daniel Luque " # pybooru imports from .moebooru import Moebooru From 3112fcf798d2eb26d46404e798143c91e2d77a90 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Dec 2016 16:46:06 +0100 Subject: [PATCH 117/141] api_danbooru.py: change some var names --- pybooru/__init__.py | 1 + pybooru/api_danbooru.py | 80 +++++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/pybooru/__init__.py b/pybooru/__init__.py index a0e611b..5790ca8 100644 --- a/pybooru/__init__.py +++ b/pybooru/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + """ Pybooru ------- diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 83b9a5b..3aa305b 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -2,10 +2,10 @@ """pybooru.api_danbooru -This module contains all API calls of Danbooru for Pybooru. +This module contains all API calls of Danbooru. Classes: - Danbooru -- Contains all API calls. + DanbooruApi_Mixin -- Contains all API calls. """ # __future__ imports @@ -37,20 +37,20 @@ def post_list(self, **params): """ return self._get('posts.json', params) - def post_show(self, id_): + def post_show(self, post_id): """Get a post. Parameters: - id_: REQUIRED Where id_ is the post id. + post_id: REQUIRED Where post_id is the post id. """ - return self._get('/posts/{0}.json'.format(id_)) + return self._get('/posts/{0}.json'.format(post_id)) - def post_update(self, id_, tag_string=None, rating=None, source=None, + def post_update(self, post_id, tag_string=None, rating=None, source=None, parent_id=None): """Update a specific post (Requires login). Parameters: - id_: REQUIRED The id number of the post to update. + post_id: REQUIRED The id number of the post to update. tag_string: A space delimited list of tags. rating: The rating for the post. Can be: safe, questionable, or explicit. @@ -63,39 +63,39 @@ def post_update(self, id_, tag_string=None, rating=None, source=None, 'ost[source]': source, 'post[parent_id]': parent_id } - return self._get('/posts/{0}.json'.format(id_), params, 'PUT', + return self._get('/posts/{0}.json'.format(post_id), params, 'PUT', auth=True) - def post_revert(self, id_, version_id): + def post_revert(self, post_id, version_id): """Function to reverts a post to a previous version (Requires login). Parameters: - id_: REQUIRED post id. + post_id: REQUIRED post id. version_id: REQUIRED The post version id to revert to. """ - return self._get('/posts/{0}/revert.json'.format(id_), + return self._get('/posts/{0}/revert.json'.format(post_id), {'version_id': version_id}, 'PUT', auth=True) - def post_copy_notes(self, id_, other_post_id): + def post_copy_notes(self, post_id, other_post_id): """Function to copy notes (requires login). Parameters: - id_: REQUIRED Post id. + post_id: REQUIRED Post id. other_post_id: REQUIRED The id of the post to copy notes to. """ - return self._get('/posts/{0}/copy_notes.json'.format(id_), + return self._get('/posts/{0}/copy_notes.json'.format(post_id), {'other_post_id': other_post_id}, 'PUT', auth=True) - def post_vote(self, id_, score): + def post_vote(self, post_id, score): """Action lets you vote for a post (Requires login). Danbooru: Post votes/create. Parameters: - id_: REQUIRED Ppost id. + post_id: REQUIRED Ppost id. score: REQUIRED Can be: up, down. """ - return self._get('/posts/{0}/votes.json'.format(id_), {'score': score}, - 'POST', auth=True) + return self._get('/posts/{0}/votes.json'.format(post_id), + {'score': score}, 'POST', auth=True) def post_flag_list(self, creator_id=None, creator_name=None, post_id=None, reason_matches=None, is_resolved=None, category=None): @@ -119,14 +119,14 @@ def post_flag_list(self, creator_id=None, creator_name=None, post_id=None, } return self._get('post_flags.json', params, auth=True) - def post_flag_create(self, id_, reason): + def post_flag_create(self, post_id, reason): """Function to flag a post. Parameters: - id_: REQUIRED The id of the flagged post. + post_id: REQUIRED The id of the flagged post. reason: REQUIRED The reason of the flagging. """ - params = {'post_flag[post_id]': id_, 'post_flag[reason]': reason} + params = {'post_flag[post_id]': post_id, 'post_flag[reason]': reason} return self._get('post_flags.json', params, 'POST', auth=True) def post_appeals_list(self, creator_id=None, creator_name=None, @@ -145,14 +145,15 @@ def post_appeals_list(self, creator_id=None, creator_name=None, } return self._get('post_appeals.json', params, auth=True) - def post_appeals_create(self, id_, reason): + def post_appeals_create(self, post_id, reason): """Function to create appeals (Requires login). Parameters: - id_: REQUIRED The id of the appealed post. + post_id: REQUIRED The id of the appealed post. reason: REQUIRED The reason of the appeal. """ - params = {'post_appeal[post_id]': id_, 'post_appeal[reason]': reason} + params = {'post_appeal[post_id]': post_id, + 'post_appeal[reason]': reason} return self._get('post_appeals.json', params, 'POST', auth=True) def post_versions(self, updater_name=None, updater_id=None, @@ -268,11 +269,11 @@ def comment_create(self, post_id, body, do_not_bump_post=None): } return self._get('comments.json', params, 'POST', auth=True) - def comment_update(self, id_, body, do_not_bump_post=None): + def comment_update(self, comment_id, body, do_not_bump_post=None): """Function to update a comment (Requires login). Parameters: - id_: REQUIRED comment id. + comment_id: REQUIRED comment id. body: REQUIRED. do_not_bump_post: Set to 1 if you do not want the post to be bumped to the top of the comment listing. @@ -281,14 +282,14 @@ def comment_update(self, id_, body, do_not_bump_post=None): 'comment[body]': body, 'comment[do_not_bump_post]': do_not_bump_post } - return self._get('comments/{0}.json'.format(id_), params, 'PUT', + return self._get('comments/{0}.json'.format(comment_id), params, 'PUT', auth=True) def comment_show(self, comment_id): """Get a specific comment. Parameters: - id_: REQUIRED the id number of the comment to retrieve. + comment_id: REQUIRED the id number of the comment to retrieve. """ return self._get('comments/{0}.json'.format(comment_id)) @@ -296,7 +297,7 @@ def comment_delete(self, comment_id): """Remove a specific comment (Requires login). Parameters: - id_: REQUIRED the id number of the comment to remove. + comment_id: REQUIRED the id number of the comment to remove. """ return self._get('comments/{0}.json'.format(comment_id), method='DELETE', auth=True) @@ -943,13 +944,13 @@ def wiki_list(self, title=None, creator_id=None, body_matches=None, } return self._get('wiki_pages.json', params) - def wiki_show(self, page_id): + def wiki_show(self, wiki_page_id): """Retrieve a specific page of the wiki. Parameters: - page_id: REQUIRED Where page_id is the wiki page id. + wiki_page_id: REQUIRED Where page_id is the wiki page id. """ - return self._get('wiki_pages/{0}.json'.format(page_id)) + return self._get('wiki_pages/{0}.json'.format(wiki_page_id)) def wiki_create(self, title, body, other_names=None): """Action to lets you create a wiki page (Requires login) (UNTESTED). @@ -966,11 +967,12 @@ def wiki_create(self, title, body, other_names=None): } return self._get('wiki_pages.json', params, method='POST', auth=True) - def wiki_update(self, page_id, title=None, body=None, other_names=None): + def wiki_update(self, wiki_page_id, title=None, body=None, + other_names=None): """Action to lets you update a wiki page (Requires login) (UNTESTED). Parameters: - page_id: REQURIED Whre page_id is the wiki page id. + wiki_page_id: REQURIED Whre page_id is the wiki page id. title: body: other_names: @@ -980,25 +982,25 @@ def wiki_update(self, page_id, title=None, body=None, other_names=None): 'wiki_page[body]': body, 'wiki_page[other_names]': other_names } - return self._get('wiki_pages/{0}.json'.format(page_id), params, + return self._get('wiki_pages/{0}.json'.format(wiki_page_id), params, method='PUT', auth=True) - def wiki_revert(self, page_id, version_id): + def wiki_revert(self, wiki_page_id, version_id): """Revert page to a previeous version (Requires login) (UNTESTED). Parameters: - page_id: REQUIRED Where page_id is the wiki page id. + wiki_page_id: REQUIRED Where page_id is the wiki page id. version_id REQUIRED. """ - return self._get('wiki_pages/{0}/revert.json'.format(page_id), + return self._get('wiki_pages/{0}/revert.json'.format(wiki_page_id), {'version_id': version_id}, method='PUT', auth=True) def wiki_versions(self, wiki_page_id, updater_id): """Return a list of wiki page version. Parameters: - updater_id: REQUIRED. wiki_page_id: REQUIRED. + updater_id: REQUIRED. """ params = { 'earch[updater_id]': updater_id, From 31affd0e01fd4db6b1c8328e11c3baa1674573f5 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Dec 2016 17:05:42 +0100 Subject: [PATCH 118/141] api_moebooru.py: Change some var names --- pybooru/api_moebooru.py | 95 +++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 75d1a39..8de38c8 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -2,10 +2,10 @@ """pybooru.api_moebooru -This module contains all API calls of Moebooru for Pybooru. +This module contains all API calls of Moebooru. Classes: - MoebooruApi -- Contains all API calls. + MoebooruApi_Mixin -- Contains all API calls. """ # __future__ imports @@ -72,16 +72,16 @@ def post_create(self, tags, file_=None, rating=None, source=None, else: raise PybooruAPIError("'file_' or 'source' is required.") - def post_update(self, id_, tags=None, file_=None, rating=None, + def post_update(self, post_id, tags=None, file_=None, rating=None, source=None, is_rating_locked=None, is_note_locked=None, parent_id=None): """Update a specific post. - Only the 'id_' parameter is required. Leave the other parameters blank - if you don't want to change them (Requires login). + Only the 'post_id' parameter is required. Leave the other parameters + blank if you don't want to change them (Requires login). Parameters: - id_: The id number of the post to update. + post_id: The id number of the post to update. tags: A space delimited list of tags. Specify previous tags. file_: The file data ENCODED as a multipart form. rating: The rating for the post. Can be: safe, questionable, or @@ -93,7 +93,7 @@ def post_update(self, id_, tags=None, file_=None, rating=None, parent_id: The ID of the parent post. """ params = { - 'id': id_, + 'id': post_id, 'post[tags]': tags, 'post[rating]': rating, 'post[source]': source, @@ -107,33 +107,33 @@ def post_update(self, id_, tags=None, file_=None, rating=None, else: return self._get('post/update', params, 'PUT') - def post_destroy(self, id_): + def post_destroy(self, post_id): """Function to destroy a specific post. You must also be the user who uploaded the post (or you must be a moderator) (Requires Login) (UNTESTED). Parameters: - id_: The id number of the post to delete. + Post_id: The id number of the post to delete. """ - return self._get('post/destroy', {'id': id_}, 'DELETE') + return self._get('post/destroy', {'id': post_id}, 'DELETE') - def post_revert_tags(self, id_, history_id): + def post_revert_tags(self, post_id, history_id): """Function to reverts a post to a previous set of tags (Requires login) (UNTESTED). Parameters: - id_: The post id number to update. + post_id: The post id number to update. history_id: The id number of the tag history. """ - params = {'id': id_, 'history_id': history_id} + params = {'id': post_id, 'history_id': history_id} return self._get('post/revert_tags', params, 'PUT') - def post_vote(self, id_, score): + def post_vote(self, post_id, score): """Action lets you vote for a post (Requires login). Parameters: - id_: The post id. + post_id: The post id. score: 0: No voted or Remove vote. 1: Good. @@ -141,7 +141,7 @@ def post_vote(self, id_, score): 3: Favorite, add post to favorites. """ if score <= 3: - params = {'id': id_, 'score': score} + params = {'id': post_id, 'score': score} return self._get('post/vote', params, 'POST') else: raise PybooruAPIError("Value of 'score' only can be 0, 1, 2 or 3.") @@ -220,14 +220,15 @@ def artist_create(self, name, urls=None, alias=None, group=None): } return self._get('artist/create', params, 'POST') - def artist_update(self, id_, name=None, urls=None, alias=None, group=None): + def artist_update(self, artist_id, name=None, urls=None, alias=None, + group=None): """Function to update artists (Requires Login). - Only the id_ parameter is required. The other parameters are optional. - (Requires login) (UNTESTED). + Only the artist_id parameter is required. The other parameters are + optional. (Requires login) (UNTESTED). Parameters: - id_: The id of thr artist to update (Type: INT). + artist_id: The id of thr artist to update (Type: INT). name: The artist's name. urls: A list of URLs associated with the artist, whitespace delimited. @@ -237,7 +238,7 @@ def artist_update(self, id_, name=None, urls=None, alias=None, group=None): enter the group's name. """ params = { - 'id': id_, + 'id': artist_id, 'artist[name]': name, 'artist[urls]': urls, 'artist[alias]': alias, @@ -245,21 +246,21 @@ def artist_update(self, id_, name=None, urls=None, alias=None, group=None): } return self._get('artist/update', params, 'PUT') - def artist_destroy(self, id_): + def artist_destroy(self, artist_id): """Action to lets you remove artist (Requires login) (UNTESTED). Parameters: - id_: The id of the artist to destroy. + artist_id: The id of the artist to destroy. """ - return self._get('artist/destroy', {'id': id_}, 'POST') + return self._get('artist/destroy', {'id': artist_id}, 'POST') - def comment_show(self, id_): + def comment_show(self, comment_id): """Get a specific comment. Parameters: - id_: The id number of the comment to retrieve. + comment_id: The id number of the comment to retrieve. """ - return self._get('comment/show', {'id': id_}) + return self._get('comment/show', {'id': comment_id}) def comment_create(self, post_id, comment_body, anonymous=None): """Action to lets you create a comment (Requires login). @@ -280,13 +281,13 @@ def comment_create(self, post_id, comment_body, anonymous=None): raise PybooruAPIError("Required 'post_id' and 'comment_body' " "parameters") - def comment_destroy(self, id_): + def comment_destroy(self, comment_id): """Remove a specific comment (Requires login). Parameters: - id_: The id number of the comment to remove. + comment_id: The id number of the comment to remove. """ - return self._get('comment/destroy', {'id': id_}, 'DELETE') + return self._get('comment/destroy', {'id': comment_id}, 'DELETE') def wiki_list(self, **params): """Function to retrieves a list of every wiki page. @@ -399,25 +400,25 @@ def note_history(self, **params): Parameters: post_id: The post id number to retrieve note versions for. - id_: The note id number to retrieve versions for. + id: The note id number to retrieve versions for. limit: How many versions to retrieve (Default: 10). page: The note id number to retrieve versions for. """ return self._get('note/history', params) - def note_revert(self, id_, version): + def note_revert(self, note_id, version): """Function to revert a specific note (Requires login) (UNTESTED). Parameters: - id: The note id to update. + note_id: The note id to update. version: The version to revert to. """ - params = {'id': id_, 'version': version} + params = {'id': note_id, 'version': version} return self._get('note/revert', params, 'PUT') def note_create_update(self, post_id=None, coor_x=None, coor_y=None, width=None, height=None, is_active=None, body=None, - id_=None): + note_id=None): """Function to create or update note (Requires login) (UNTESTED). Parameters: @@ -429,11 +430,11 @@ def note_create_update(self, post_id=None, coor_x=None, coor_y=None, is_active: Whether or not the note is visible. Set to 1 for active, 0 for inactive. body: The note message. - id_: If you are updating a note, this is the note id number to - update. + note_id: If you are updating a note, this is the note id number to + update. """ params = { - 'id': id_, + 'id': note_id, 'note[post]': post_id, 'note[x]': coor_x, 'note[y]': coor_y, @@ -488,18 +489,18 @@ def pool_posts(self, **params): """ return self._get('pool/show', params) - def pool_update(self, id_, name=None, is_public=None, + def pool_update(self, pool_id, name=None, is_public=None, description=None): """Function to update a pool (Requires login) (UNTESTED). Parameters: - id_: The pool id number. + pool_id: The pool id number. name: The name. is_public: 1 or 0, whether or not the pool is public. description: A description of the pool. """ params = { - 'id': id_, + 'id': pool_id, 'pool[name]': name, 'pool[is_public]': is_public, 'pool[description]': description @@ -518,13 +519,13 @@ def pool_create(self, name, description, is_public): 'pool[is_public]': is_public} return self._get('pool/create', params, 'POST') - def pool_destroy(self, id_): + def pool_destroy(self, pool_id): """Function to destroy a specific pool (Require login) (UNTESTED). Parameters: - id_: The pool id number. + pool_id: The pool id number. """ - return self._get('pool/destroy', {'id': id_}, 'DELETE') + return self._get('pool/destroy', {'id': pool_id}, 'DELETE') def pool_add_post(self, **params): """Function to add a post (Require login) (UNTESTED). @@ -544,13 +545,13 @@ def pool_remove_post(self, **params): """ return self._get('pool/remove_post', params, 'PUT') - def favorite_list_users(self, id_): + def favorite_list_users(self, post_id): """Function to return a list with all users who have added to favorites a specific post. Parameters: - id_: The post id. + post_id: The post id. """ - response = self._get('favorite/list_users', {'id': id_}) + response = self._get('favorite/list_users', {'id': post_id}) # Return list with users return response['favorited_users'].split(',') From 3cef4198389b2703dd5b03cdf9907ee5d70a2e2e Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Dec 2016 18:36:44 +0100 Subject: [PATCH 119/141] Danbooru: added missing docstrings --- pybooru/danbooru.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index f8765ef..0d5e656 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -2,11 +2,11 @@ """pybooru.danbooru -This module contains Danbooru class for access to API calls, -authentication, build url and return JSON response. +This module contains Danbooru class for access to API calls, authentication, +build url and return JSON response. Classes: - Danbooru -- Danbooru classs. + Danbooru -- Danbooru main classs. """ # Pybooru imports @@ -16,7 +16,7 @@ class Danbooru(Pybooru, DanbooruApi_Mixin): - """Danbooru class (inherits: Pybooru and DanbooruApi). + """Danbooru class (inherits: Pybooru and DanbooruApi_Mixin). To initialize Pybooru, you need to specify one of these two parameters: 'site_name' or 'site_url'. If you specify 'site_name', Pybooru @@ -27,8 +27,7 @@ class Danbooru(Pybooru, DanbooruApi_Mixin): 'site_url' parameter and specify url. Some actions may require you to log in. always specify two parameters to - log in: 'username' and 'api_key'. Default sites has an - associate API key. + log in: 'username' and 'api_key'. Attributes: site_name: Return site name. @@ -39,6 +38,16 @@ class Danbooru(Pybooru, DanbooruApi_Mixin): """ def __init__(self, site_name="", site_url="", username="", api_key=""): + """Initialize Danbooru. + + Keyword arguments: + site_name: The site name in 'SITE_LIST', default sites. + site_url: URL of on Moebooru based sites. + username: Your username of the site (Required only for functions + that modify the content). + api_key: Your api key of the site (Required only for + functions that modify the content). + """ super(Danbooru, self).__init__(site_name, site_url, username) if api_key is not "": @@ -46,6 +55,14 @@ def __init__(self, site_name="", site_url="", username="", api_key=""): def _get(self, api_call, params=None, method='GET', auth=False, file_=None): + """Function to preapre API call. + + Parameters: + api_call: API function to be called. + params: API function parameters. + method: (Defauld: GET) HTTP method (GET, POST, PUT or DELETE) + file_: File to upload (only in uploads). + """ url = "{0}/{1}".format(self.site_url, api_call) if method == 'GET': From 156271013e80970839225f629d0d50e84452729a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Dec 2016 20:45:25 +0100 Subject: [PATCH 120/141] Exceptions: add new exceptions code --- pybooru/danbooru.py | 2 +- pybooru/exceptions.py | 3 +-- pybooru/pybooru.py | 2 +- pybooru/resources.py | 3 +++ 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index 0d5e656..b0bd688 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -61,7 +61,7 @@ def _get(self, api_call, params=None, method='GET', auth=False, api_call: API function to be called. params: API function parameters. method: (Defauld: GET) HTTP method (GET, POST, PUT or DELETE) - file_: File to upload (only in uploads). + file_: File to upload (only uploads). """ url = "{0}/{1}".format(self.site_url, api_call) diff --git a/pybooru/exceptions.py b/pybooru/exceptions.py index c072fa0..9ef070c 100644 --- a/pybooru/exceptions.py +++ b/pybooru/exceptions.py @@ -33,13 +33,12 @@ def __init__(self, msg, http_code, url): http_code: The HTTP status code. url: The URL. """ + super(PybooruHTTPError, self).__init__(msg, http_code, url) if http_code in HTTP_STATUS_CODE and url is not None: msg = "{0}: {1} - {2}, {3} - URL: {4}".format( msg, http_code, HTTP_STATUS_CODE[http_code][0], HTTP_STATUS_CODE[http_code][1], url) - super(PybooruHTTPError, self).__init__(msg) - class PybooruAPIError(PybooruError): """Class to catch all API errors.""" diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index d306c99..c8915a2 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -128,7 +128,7 @@ def _request(self, url, api_call, request_args, method='GET'): 'headers': response.headers }) - if response.status_code is 200: + if response.status_code in (200, 201, 202, 204): return response.json() else: raise PybooruHTTPError("In _request", response.status_code, diff --git a/pybooru/resources.py b/pybooru/resources.py index d2a38b3..6d15dd5 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -29,6 +29,9 @@ # HTTP_STATUS_CODE HTTP_STATUS_CODE = { 200: ("OK", "Request was successful"), + 400: ("Bad request", "The server cannot or will not process the request"), + 401: ("Unauthorized", "Authentication is required and has failed or has \ + not yet been provided."), 403: ("Forbidden", "Access denied"), 404: ("Not Found", "Not found"), 420: ("Invalid Record", "Record could not be saved"), From 3f88a474b94623b80297b4d597ed5db08516d22d Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 1 Dec 2016 22:14:01 +0100 Subject: [PATCH 121/141] Fix documentation --- pybooru/moebooru.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pybooru/moebooru.py b/pybooru/moebooru.py index 3b253c4..a7b7b80 100644 --- a/pybooru/moebooru.py +++ b/pybooru/moebooru.py @@ -23,7 +23,7 @@ class Moebooru(Pybooru, MoebooruApi_Mixin): - """Moebooru class (inherits: Pybooru and MoebooruApi). + """Moebooru class (inherits: Pybooru and MoebooruApi_Mixin). To initialize Pybooru, you need to specify one of these two parameters: 'site_name' or 'site_url'. If you specify 'site_name', Pybooru @@ -121,6 +121,7 @@ def _get(self, api_call, params, method='GET', file_=None): if self.password_hash is None: self._build_hash_string() + # Set login params['login'] = self.username params['password_hash'] = self.password_hash request_args = {'data': params, 'files': file_} From 5b35ab01eb2d43d0b3e93e9ddb9faf4e831c4be6 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 2 Dec 2016 23:02:19 +0100 Subject: [PATCH 122/141] Distribute: refactoring setup.py and adds MANIFEST.in --- .travis.yml | 2 +- setup.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7e20e2a..7820664 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ branches: install: # Install requests - - pip install requests + - pip install -r requirements.txt # Install pylint - sudo apt-get install pylint diff --git a/setup.py b/setup.py index 23376d8..beee7a9 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ # -*- coding utf-8 -*- -#!/usr/bin/env python +# !/usr/bin/env python # setuptools imports from setuptools import setup @@ -9,6 +9,7 @@ import pybooru +# Read description file with open('README.rst', 'r') as f: long_description = f.read() @@ -17,13 +18,16 @@ name="Pybooru", version=pybooru.__version__, author=pybooru.__author__, - description="Pybooru is a Python library to access API of Danbooru/Moebooru \ - based sites.", + description="Pybooru is a Python package to access to the API of Danbooru/Moebooru based sites.", long_description=long_description, author_email="danielluque14@gmail.com", url="https://github.com/LuqueDaniel/pybooru", license="MIT License", - keywords="Pybooru moebooru danbooru API", + keywords="Pybooru moebooru danbooru API client", + packages=find_packages(), + platforms=['any'], + install_requires=['requests'], + include_package_data=True, classifiers=[ "Development Status :: 5 - Production/Stable", "Programming Language :: Python", @@ -38,8 +42,4 @@ "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Internet" ], - platforms=['any'], - install_requires=['requests'], - packages=find_packages(), - include_package_data=True, ) From 4d2178626189be2742192887ca6d37dc8b8cbd12 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 2 Dec 2016 23:02:49 +0100 Subject: [PATCH 123/141] Distribute: refactoring setup.py and adds MANIFEST.in --- MANIFEST.in | 1 + requirements.txt | 1 + 2 files changed, 2 insertions(+) create mode 100644 MANIFEST.in create mode 100644 requirements.txt diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..22fad36 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include README.md changelog.md LICENSE requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f229360 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +requests From df3a1ee06f3e45d954546abe4a0c28bb019b51a5 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Dec 2016 21:33:24 +0100 Subject: [PATCH 124/141] Fix typo --- pybooru/danbooru.py | 4 ++-- pybooru/exceptions.py | 2 +- pybooru/moebooru.py | 4 ++-- pybooru/pybooru.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index b0bd688..167fe97 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -10,12 +10,12 @@ """ # Pybooru imports -from .pybooru import Pybooru +from .pybooru import _Pybooru from .api_danbooru import DanbooruApi_Mixin from .exceptions import PybooruError -class Danbooru(Pybooru, DanbooruApi_Mixin): +class Danbooru(_Pybooru, DanbooruApi_Mixin): """Danbooru class (inherits: Pybooru and DanbooruApi_Mixin). To initialize Pybooru, you need to specify one of these two diff --git a/pybooru/exceptions.py b/pybooru/exceptions.py index 9ef070c..55984f8 100644 --- a/pybooru/exceptions.py +++ b/pybooru/exceptions.py @@ -28,7 +28,7 @@ class PybooruHTTPError(PybooruError): def __init__(self, msg, http_code, url): """Initialize PybooruHTTPError. - Keyword arguments:: + Keyword arguments: msg: The error message. http_code: The HTTP status code. url: The URL. diff --git a/pybooru/moebooru.py b/pybooru/moebooru.py index a7b7b80..b77cc9f 100644 --- a/pybooru/moebooru.py +++ b/pybooru/moebooru.py @@ -16,13 +16,13 @@ import hashlib # Pybooru imports -from .pybooru import Pybooru +from .pybooru import _Pybooru from .api_moebooru import MoebooruApi_Mixin from .exceptions import PybooruError from .resources import SITE_LIST -class Moebooru(Pybooru, MoebooruApi_Mixin): +class Moebooru(_Pybooru, MoebooruApi_Mixin): """Moebooru class (inherits: Pybooru and MoebooruApi_Mixin). To initialize Pybooru, you need to specify one of these two diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index c8915a2..bc2f3ac 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -6,7 +6,7 @@ authentication and return JSON response. Classes: - Pybooru -- Main pybooru classs, define Pybooru object. + _Pybooru -- Main pybooru classs, define Pybooru object and do requests. """ # __furute__ imports @@ -22,7 +22,7 @@ from .resources import (SITE_LIST, HTTP_STATUS_CODE) -class Pybooru(object): +class _Pybooru(object): """Pybooru main class. Attributes: From a700e9d4036fb174f3fe3127755724b06989978a Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Dec 2016 21:56:17 +0100 Subject: [PATCH 125/141] Update moebooru examples --- examples/login_example.py | 7 ------- examples/{ => moebooru}/list_tags.py | 7 +++---- examples/moebooru/login_example.py | 7 +++++++ examples/moebooru/more_examples.py | 20 +++++++++++++++++++ examples/{ => moebooru}/posts_img_url.py | 7 +++---- examples/{ => moebooru}/wiki_msg.py | 7 +++---- examples/more_examples.py | 25 ------------------------ 7 files changed, 36 insertions(+), 44 deletions(-) delete mode 100644 examples/login_example.py rename examples/{ => moebooru}/list_tags.py (57%) create mode 100644 examples/moebooru/login_example.py create mode 100644 examples/moebooru/more_examples.py rename examples/{ => moebooru}/posts_img_url.py (55%) rename examples/{ => moebooru}/wiki_msg.py (50%) delete mode 100644 examples/more_examples.py diff --git a/examples/login_example.py b/examples/login_example.py deleted file mode 100644 index f86862b..0000000 --- a/examples/login_example.py +++ /dev/null @@ -1,7 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals -from pybooru import Pybooru - -client = Pybooru('Konachan', username='your-username', password='your-password') - -client.comments_create(post_id=id, comment_body='Comment content') diff --git a/examples/list_tags.py b/examples/moebooru/list_tags.py similarity index 57% rename from examples/list_tags.py rename to examples/moebooru/list_tags.py index 84bf560..639908c 100644 --- a/examples/list_tags.py +++ b/examples/moebooru/list_tags.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from pybooru import Pybooru +from pybooru import Moebooru -client = Pybooru('Konachan') - -tags = client.tags_list(None, None, 100, 0, 'date') +client = Moebooru('Konachan') +tags = client.tag_list(order='name') for tag in tags: print("Nombre: {0} ----- {1}".format(tag['name'], tag['type'])) diff --git a/examples/moebooru/login_example.py b/examples/moebooru/login_example.py new file mode 100644 index 0000000..e728858 --- /dev/null +++ b/examples/moebooru/login_example.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from pybooru import Moebooru + +# replace login information +client = Moebooru('Konachan', username='your-username', password='your-password') +client.comment_create(post_id=id, comment_body='Comment content') diff --git a/examples/moebooru/more_examples.py b/examples/moebooru/more_examples.py new file mode 100644 index 0000000..ca5bef7 --- /dev/null +++ b/examples/moebooru/more_examples.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from pybooru import Moebooru + +client = Moebooru(site_name='Konachan') + +# notes = client.note_list() +# print(notes) + +# wiki = client.wiki_list(query='nice', order='date') +# for msg in wiki: +# print("Mensaje: {0}".format(msg['body'])) + +# posts = client.post_list(tags='blue_eyes', limit=2) +# for post in posts: +# print("URL imagen: {0}".format(post['file_url'])) + +# tags = client.tag_list() +# for tag in tags: +# print("Nombre: {0} ----- {1}".format(tag['name'], tag['type'])) diff --git a/examples/posts_img_url.py b/examples/moebooru/posts_img_url.py similarity index 55% rename from examples/posts_img_url.py rename to examples/moebooru/posts_img_url.py index 7e8e92a..d22a9a9 100644 --- a/examples/posts_img_url.py +++ b/examples/moebooru/posts_img_url.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from pybooru import Pybooru +from pybooru import Moebooru -client = Pybooru('Konachan') - -posts = client.posts_list('blue_eyes', 10) +client = Moebooru('Konachan') +posts = client.post_list(tags='blue_eyes', limit=10) for post in posts: print("URL imagen: {0}".format(post['file_url'])) diff --git a/examples/wiki_msg.py b/examples/moebooru/wiki_msg.py similarity index 50% rename from examples/wiki_msg.py rename to examples/moebooru/wiki_msg.py index 956c667..6af9bf3 100644 --- a/examples/wiki_msg.py +++ b/examples/moebooru/wiki_msg.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from pybooru import Pybooru +from pybooru import Moebooru -client = Pybooru('yandere') - -wiki = client.wiki_list('nice', 'date', 2, 1) +client = Moebooru('yandere') +wiki = client.wiki_list(query='nice', order='date', limit=2, page=1) for msg in wiki: print("Mensaje: {0}".format(msg['body'])) diff --git a/examples/more_examples.py b/examples/more_examples.py deleted file mode 100644 index 4ea29f1..0000000 --- a/examples/more_examples.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals -from pybooru import Pybooru - -client = Pybooru(siteName='Konachan') - -#notes = client.notes_list() - -#print(notes) - -#wiki = client.wiki_list('nice', 'date', 2, 1) - -#for msg in wiki: -# print("Mensaje: {0}".format(msg['body'])) - -#posts = client.posts_list('blue_eyes', 2, 0) - -#for post in posts: -# print("URL imagen: {0}".format(post['file_url'])) - -#tags = client.tags_list(None, None, 100, 0, 'date') - -#print tags -#for tag in tags: -# print("Nombre: {0} ----- {1}".format(tag['name'], tag['type'])) From 52fb557732b78db83bd5dfbd284678e15d763926 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Dec 2016 23:38:46 +0100 Subject: [PATCH 126/141] Create tools folders --- .gitignore | 2 ++ .travis.yml | 4 ++-- clean_pycs.sh | 3 --- tools/remove_binary.bat | 3 +++ tools/remove_binary.sh | 7 +++++++ 5 files changed, 14 insertions(+), 5 deletions(-) delete mode 100755 clean_pycs.sh create mode 100644 tools/remove_binary.bat create mode 100644 tools/remove_binary.sh diff --git a/.gitignore b/.gitignore index 5909fe0..a5afc51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ # Ignore files .pyc *.pyc +*.pyo +*.pyd *.egg-info __pycache__ diff --git a/.travis.yml b/.travis.yml index 7820664..f913c24 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,8 @@ install: - sudo apt-get install pylint before_script: - # Remove python binari files - - rm --recursive --force --verbose *.py[cod] + # Remove python binary files + - ./tools/remove_binary.sh # Run pylint - pylint --errors-only --rcfile=.pylintrc pybooru/ diff --git a/clean_pycs.sh b/clean_pycs.sh deleted file mode 100755 index fb6ed8d..0000000 --- a/clean_pycs.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -find . -iname '*.pyc' -delete diff --git a/tools/remove_binary.bat b/tools/remove_binary.bat new file mode 100644 index 0000000..c780bf5 --- /dev/null +++ b/tools/remove_binary.bat @@ -0,0 +1,3 @@ +DEL /S .\*.pyc + +RD /S /Q .\pybooru\__pycache__ diff --git a/tools/remove_binary.sh b/tools/remove_binary.sh new file mode 100644 index 0000000..96ee240 --- /dev/null +++ b/tools/remove_binary.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Remove binary files +find . -iname '*.py[cod]' -delete + +# Remove __pycache__ Py3k +rm --recursive --force --verbose pybooru/__pycache__ From e7b773f5b8356cee580fcd7f4b96f98ea38148ff Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Dec 2016 23:41:10 +0100 Subject: [PATCH 127/141] Try to fix build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f913c24..5db5670 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ install: before_script: # Remove python binary files - - ./tools/remove_binary.sh + - sudo ./tools/remove_binary.sh # Run pylint - pylint --errors-only --rcfile=.pylintrc pybooru/ From 0b317ca6d24a1f0164026228020682af88332f4e Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Mon, 5 Dec 2016 23:44:32 +0100 Subject: [PATCH 128/141] Revert changes --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5db5670..13879e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,8 @@ install: before_script: # Remove python binary files - - sudo ./tools/remove_binary.sh + - rm --recursive --force --verbose *.py[cod] + - rm --recursive --force --verbose pybooru/__pycache__ # Run pylint - pylint --errors-only --rcfile=.pylintrc pybooru/ From ac6b4652a2477c7c77e3fcd43a35bccb56a46713 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Dec 2016 10:49:17 +0100 Subject: [PATCH 129/141] Adds new HTTP status code Adds HTTP status code (201, 202 and 204) --- pybooru/resources.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pybooru/resources.py b/pybooru/resources.py index 6d15dd5..3f6d5e9 100644 --- a/pybooru/resources.py +++ b/pybooru/resources.py @@ -29,6 +29,12 @@ # HTTP_STATUS_CODE HTTP_STATUS_CODE = { 200: ("OK", "Request was successful"), + 201: ("Created" "The request has been fulfilled, resulting in the creation \ + of a new resource"), + 202: ("Accepted", "The request has been accepted for processing, but the \ + processing has not been completed."), + 204: ("No Content", "The server successfully processed the request and is \ + not returning any content."), 400: ("Bad request", "The server cannot or will not process the request"), 401: ("Unauthorized", "Authentication is required and has failed or has \ not yet been provided."), From a3d1655f9df131d26cedfe6f1c9a6a2a0e0a3970 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Dec 2016 11:49:10 +0100 Subject: [PATCH 130/141] Adds Danbooru examples Adds Danbooru examples and fix some typos of Moebooru examples. --- examples/danbooru/list_tags.py | 9 +++++++++ examples/danbooru/login_example.py | 8 ++++++++ examples/danbooru/post_img_path.py | 9 +++++++++ examples/danbooru/wiki_msg.py | 9 +++++++++ examples/moebooru/list_tags.py | 2 +- examples/moebooru/login_example.py | 2 ++ examples/moebooru/more_examples.py | 6 +++--- examples/moebooru/posts_img_url.py | 2 +- examples/moebooru/wiki_msg.py | 2 +- 9 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 examples/danbooru/list_tags.py create mode 100644 examples/danbooru/login_example.py create mode 100644 examples/danbooru/post_img_path.py create mode 100644 examples/danbooru/wiki_msg.py diff --git a/examples/danbooru/list_tags.py b/examples/danbooru/list_tags.py new file mode 100644 index 0000000..de62d03 --- /dev/null +++ b/examples/danbooru/list_tags.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from pybooru import Danbooru + +client = Danbooru('danbooru') +tags = client.tag_list(order='date') + +for tag in tags: + print("Tag: {0} ----- {1}".format(tag['name'], tag['category'])) diff --git a/examples/danbooru/login_example.py b/examples/danbooru/login_example.py new file mode 100644 index 0000000..fd5f6b7 --- /dev/null +++ b/examples/danbooru/login_example.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from pybooru import Danbooru + +client = Danbooru('danbooru', username='your-username', api_key='yout-api_key') +response = client.comment_create(post_id=id, body='your comment') + +print(client.last_call) diff --git a/examples/danbooru/post_img_path.py b/examples/danbooru/post_img_path.py new file mode 100644 index 0000000..5fb45d3 --- /dev/null +++ b/examples/danbooru/post_img_path.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from pybooru import Danbooru + +client = Danbooru('danbooru') +posts = client.post_list(tags='blue_eyes', limit=5) + +for post in posts: + print("Image path: {0}".format(post['file_url'])) diff --git a/examples/danbooru/wiki_msg.py b/examples/danbooru/wiki_msg.py new file mode 100644 index 0000000..e9564f6 --- /dev/null +++ b/examples/danbooru/wiki_msg.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from pybooru import Moebooru + +client = Moebooru('yandere') +wiki = client.wiki_list(body_matches='great', order='date') + +for page in wiki: + print("Message: {0}".format(page['body'])) diff --git a/examples/moebooru/list_tags.py b/examples/moebooru/list_tags.py index 639908c..2d8a0c7 100644 --- a/examples/moebooru/list_tags.py +++ b/examples/moebooru/list_tags.py @@ -6,4 +6,4 @@ tags = client.tag_list(order='name') for tag in tags: - print("Nombre: {0} ----- {1}".format(tag['name'], tag['type'])) + print("Tag: {0} ----- {1}".format(tag['name'], tag['type'])) diff --git a/examples/moebooru/login_example.py b/examples/moebooru/login_example.py index e728858..3add5c6 100644 --- a/examples/moebooru/login_example.py +++ b/examples/moebooru/login_example.py @@ -5,3 +5,5 @@ # replace login information client = Moebooru('Konachan', username='your-username', password='your-password') client.comment_create(post_id=id, comment_body='Comment content') + +print(client.last_call) diff --git a/examples/moebooru/more_examples.py b/examples/moebooru/more_examples.py index ca5bef7..43ee49c 100644 --- a/examples/moebooru/more_examples.py +++ b/examples/moebooru/more_examples.py @@ -9,12 +9,12 @@ # wiki = client.wiki_list(query='nice', order='date') # for msg in wiki: -# print("Mensaje: {0}".format(msg['body'])) +# print("Message: {0}".format(msg['body'])) # posts = client.post_list(tags='blue_eyes', limit=2) # for post in posts: -# print("URL imagen: {0}".format(post['file_url'])) +# print("Image URL: {0}".format(post['file_url'])) # tags = client.tag_list() # for tag in tags: -# print("Nombre: {0} ----- {1}".format(tag['name'], tag['type'])) +# print("Tag: {0} ----- {1}".format(tag['name'], tag['type'])) diff --git a/examples/moebooru/posts_img_url.py b/examples/moebooru/posts_img_url.py index d22a9a9..d708c35 100644 --- a/examples/moebooru/posts_img_url.py +++ b/examples/moebooru/posts_img_url.py @@ -6,4 +6,4 @@ posts = client.post_list(tags='blue_eyes', limit=10) for post in posts: - print("URL imagen: {0}".format(post['file_url'])) + print("URL image: {0}".format(post['file_url'])) diff --git a/examples/moebooru/wiki_msg.py b/examples/moebooru/wiki_msg.py index 6af9bf3..8ea1887 100644 --- a/examples/moebooru/wiki_msg.py +++ b/examples/moebooru/wiki_msg.py @@ -6,4 +6,4 @@ wiki = client.wiki_list(query='nice', order='date', limit=2, page=1) for msg in wiki: - print("Mensaje: {0}".format(msg['body'])) + print("Message: {0}".format(msg['body'])) From 462b72cf99f9d21d6219cbfbb23b3f37a28dad41 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Dec 2016 14:08:22 +0100 Subject: [PATCH 131/141] Update README.md and README.rst Update README.md and README.rst (Description, examples, badges, installation process etc). Also updated setup.cfg for build wheels. --- README.md | 68 ++++++++++++++++++++++++++++++++---------------------- README.rst | 23 +++++++++--------- setup.cfg | 2 +- 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index fb41284..98cd327 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# Pybooru - Library for Danbooru/Moebooru API. -[![Build Status](https://travis-ci.org/LuqueDaniel/pybooru.svg?branch=master)](https://travis-ci.org/LuqueDaniel/pybooru) +# Pybooru - Package for Danbooru/Moebooru API. +[![Build Status](https://travis-ci.org/LuqueDaniel/pybooru.svg?branch=master)](https://travis-ci.org/LuqueDaniel/pybooru) [![PyPI](https://img.shields.io/pypi/status/Pybooru.svg?style=flat-square)](https://pypi.python.org/pypi/Pybooru/) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/LuqueDaniel/pybooru/master/LICENSE) -**Pybooru** is a Python library to access API of Danbooru/Moebooru based sites. +**Pybooru** is a Python package to access to the API of Danbooru/Moebooru based sites. -- Version: **3.0.1** +- Version: **4.0.0** - Licensed under: **MIT License** ## Dependencies. - Python: >= 2.6 or Python: >= 3.3 -- [requests.](http://docs.python-requests.org/en/latest/) +- [requests](http://docs.python-requests.org/en/latest/) ## Installation ### from Python Package Index (Pypi) @@ -16,54 +16,68 @@ Pypi - Python Package Index: [Pybooru on Pypi.](https://pypi.python.org/pypi/Pybooru/) ```bash -sudo pip install Pybooru -``` -or -```bash -sudo easy_install Pybooru +pip install --user Pybooru ``` ### Manual installation ```bash git clone git://github.com/luquedaniel/pybooru.git cd pybooru +pip install --user -r requirements.txt sudo python setup.py build -sudo python setup.py install +python setup.py install ``` ## Examples of use -```python -from pybooru import Pybooru +See [More examples.](https://github.com/LuqueDaniel/pybooru/tree/master/examples) -client = Pybooru('Konachan') +### Danbooru +```python +from pybooru import Danbooru -artists = client.artists('ma') +client = Danbooru('danbooru') +artists = client.artist_list('ma') for artist in artists: print("Name: {0}".format(artist['name'])) ``` -### Login example -#### Default sites +#### Login example ```python -from pybooru import Pybooru +from pybooru import Danbooru -client = Pybooru('Konachan', username='your-username', password='your-password') - -client.comments_create(post_id=id, comment_body='Comment content') +client = Danbooru('danbooru', username='your-username', api_key='your-apikey') +client.comment_create(post_id=id, body='Comment content') ``` -#### Other sites +### Moebooru ```python -from pybooru import Pybooru +from pybooru import Moebooru + +client = Moebooru('konachan') +artists = client.artist_list(name='neko') + +for artist in artists: + print("Name: {0}".format(artist['name'])) +``` -client = Pybooru('konachan.com', username='your-username', password='your-password', - hashString='So-I-Heard-You-Like-Mupkids-?--{0}--') +#### Login example +##### Default sites +```python +from pybooru import Moebooru -client.comments_create(post_id=id, comment_body='Comment content') +client = Moebooru('konachan', username='your-username', password='your-password') +client.comment_create(post_id=id, comment_body='Comment content') ``` -[More examples.](https://github.com/LuqueDaniel/pybooru/tree/master/examples) +##### Not default sites +```python +from pybooru import Moebooru + +client = Moebooru('konachan.com', username='your-username', password='your-password', + hash_string='So-I-Heard-You-Like-Mupkids-?--{0}--') +client.comment_create(post_id=id, comment_body='Comment content') +``` ## CI Report - https://travis-ci.org/LuqueDaniel/pybooru diff --git a/README.rst b/README.rst index 6400917..04cb977 100644 --- a/README.rst +++ b/README.rst @@ -1,27 +1,26 @@ -Pybooru - Library for Danbooru/Moebooru API. +Pybooru - Package for Danbooru/Moebooru API. ============================================ -.. image:: https://travis-ci.org/LuqueDaniel/pybooru.svg?branch=master - :target: https://travis-ci.org/LuqueDaniel/pybooru - -Pybooru is a Python library to access API of Danbooru/Moebooru based sites. +.. image:: https://img.shields.io/pypi/v/Pybooru.svg?style=flat-square :target: +.. image:: https://img.shields.io/pypi/status/Pybooru.svg?style=flat-square :target: +.. image:: https://img.shields.io/pypi/l/Pybooru.svg?style=flat-square :target: https://raw.githubusercontent.com/LuqueDaniel/pybooru/master/LICENSE +.. image:: https://img.shields.io/pypi/wheel/Pybooru.svg?style=flat-square :target: +.. image:: https://img.shields.io/pypi/format/Pybooru.svg?style=flat-square :target: Licensed under: **MIT License**. Examples of use --------------- .. code-block:: python + from pybooru import Danbooru - from pybooru import Pybooru - - client = Pybooru('Konachan') - - artists = client.artists('ma') + client = Danbooru('danbooru') + artists = client.artist_list('ma') for artist in artists: print("Name: {0}".format(artist['name'])) - .. +.. -See more examples: https://github.com/LuqueDaniel/pybooru/tree/develop/examples +See more examples of Danbooru and Moebooru: https://github.com/LuqueDaniel/pybooru/tree/develop/examples Changelog --------- diff --git a/setup.cfg b/setup.cfg index 5e40900..2a9acf1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,2 @@ -[wheel] +[bdist_wheel] universal = 1 From 38bcf354f374035cdd000f3b05ee2293b9f525b6 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Dec 2016 14:59:16 +0100 Subject: [PATCH 132/141] Setup documentation (Sphinx) Create the Sphinx documentation base structure --- README.rst | 1 + docs/Makefile | 20 ++++++ docs/make.bat | 36 ++++++++++ docs/source/conf.py | 158 ++++++++++++++++++++++++++++++++++++++++++ docs/source/index.rst | 20 ++++++ 5 files changed, 235 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst diff --git a/README.rst b/README.rst index 04cb977..d97f7d3 100644 --- a/README.rst +++ b/README.rst @@ -6,6 +6,7 @@ Pybooru - Package for Danbooru/Moebooru API. .. image:: https://img.shields.io/pypi/wheel/Pybooru.svg?style=flat-square :target: .. image:: https://img.shields.io/pypi/format/Pybooru.svg?style=flat-square :target: + Licensed under: **MIT License**. Examples of use diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..0b3ab3a --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = Pybooru +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..4d28340 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build +set SPHINXPROJ=Pybooru + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..8aaf0ad --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Pybooru documentation build configuration file, created by +# sphinx-quickstart on Wed Dec 7 14:53:54 2016. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', + 'sphinx.ext.mathjax'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'Pybooru' +copyright = '2016, Daniel Luque' +author = 'Daniel Luque' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '' +# The full version, including alpha/beta/rc tags. +release = '' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Pyboorudoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'Pybooru.tex', 'Pybooru Documentation', + 'Daniel Luque', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'pybooru', 'Pybooru Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'Pybooru', 'Pybooru Documentation', + author, 'Pybooru', 'One line description of project.', + 'Miscellaneous'), +] + + + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..20c7e07 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,20 @@ +.. Pybooru documentation master file, created by + sphinx-quickstart on Wed Dec 7 14:53:54 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Pybooru's documentation! +=================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` From ca88aea3aef1bd96957dcbac4133cde4f287a4b0 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Dec 2016 16:41:08 +0100 Subject: [PATCH 133/141] Docs: change html_theme Docs: change html_theme to use sphinx_rtd_theme for Read the Docs. --- docs/source/conf.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 8aaf0ad..d629c53 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -84,7 +84,9 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +# Use Read the Docs theme +import sphinx_rtd_theme +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -153,6 +155,3 @@ author, 'Pybooru', 'One line description of project.', 'Miscellaneous'), ] - - - From b0608a0f5725fde200015b0fc7b1e0ea8564dac8 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Dec 2016 23:41:02 +0100 Subject: [PATCH 134/141] Docs: adds quick_start_guide.rst Adds quick_start_guide.rst --- README.rst | 2 +- docs/source/quick_start_guide.rst | 113 ++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 docs/source/quick_start_guide.rst diff --git a/README.rst b/README.rst index d97f7d3..df11195 100644 --- a/README.rst +++ b/README.rst @@ -21,7 +21,7 @@ Examples of use print("Name: {0}".format(artist['name'])) .. -See more examples of Danbooru and Moebooru: https://github.com/LuqueDaniel/pybooru/tree/develop/examples +See more examples of `Danbooru `_ and `Moebooru `_. Changelog --------- diff --git a/docs/source/quick_start_guide.rst b/docs/source/quick_start_guide.rst new file mode 100644 index 0000000..93b5b2a --- /dev/null +++ b/docs/source/quick_start_guide.rst @@ -0,0 +1,113 @@ +Quick Start Guide +================= + +Features +-------- + +- Support Danbooru API. +- Support Moebooru API. +- Defult site list. +- JSON responses. + +Installation +------------ + +You can download and install Pybooru from `Pypi `_ + +.. code-block:: bash + + pip install --user Pybooru +.. + +Install from source +------------------- + +.. code-block:: bash + + git clone git://github.com/luquedaniel/pybooru.git + cd pybooru + pip install --user -r requirements.txt + sudo python setup.py build + python setup.py install +.. + +Example of use with Danbooru +---------------------------- + +.. code-block:: python + + from pybooru import Danbooru + + client = Danbooru('danbooru') + artists = client.artist_list('ma') + + for artist in artists: + print("Name: {0}".format(artist['name'])) +.. + +login (only for functions that **requires login**): + +You can pass two parameters to authenticate: "username" and "api_key". You can see your API key in your profile. + +Example: + +.. code-block:: python + + from pybooru import Danbooru + + client = Danbooru('danbooru', username='your-username', api_key='your-apikey') + client.comment_create(post_id=id, body='Comment content') +.. + +Example of use with Moebooru +---------------------------- + +.. code-block:: python + + from pybooru import Moebooru + + client = Moebooru('konachan') + artists = client.artist_list(name='ma') + + for artist in artists: + print("Name: {0}".format(artist['name'])) +.. + +Some functions may require you to authenticate: + +- **username**: your site username. +- **password**: your password in plain text. +- **hash_string** (requires only for sites that isn't in default site list): a string to be hashed with your password. + +Example using default sites: + +.. code-block:: python + + from pybooru import Moebooru + + client = Moebooru('konachan', username='your-username', password='your-password') + client.comment_create(post_id=id, comment_body='Comment content') +.. + +Example using not default sites: + +.. code-block:: python + + from pybooru import Moebooru + + client = Moebooru('konachan.com', username='your-username', password='your-password', + hash_string='So-I-Heard-You-Like-Mupkids-?--{0}--') + client.comment_create(post_id=id, comment_body='Comment content') +.. + + +See more examples of `Danbooru `_ and `Moebooru `_. + +Default sites list +------------------ + +Pybooru has a list of default sites that allow you to use Pybooru without "site_url" argument: + +- konchan (`Konachan `_) +- yandere (`Yande.re `_) +- danbooru (`Danbooru `_) From fd98857bedb7e1e84f27086aec1210608b84bbd1 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Wed, 7 Dec 2016 23:41:51 +0100 Subject: [PATCH 135/141] Docs: update index.rst --- docs/source/index.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/source/index.rst b/docs/source/index.rst index 20c7e07..38af724 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,10 +6,23 @@ Welcome to Pybooru's documentation! =================================== +**Pybooru** is a Python package to access to the API of Danbooru/Moebooru based sites. + +- Version: **4.0.0**. +- Licensed under: **MIT License**. + +Dependencies +------------ + +- Python: >= 2.6 or Python: >= 3.3 +- requests + + .. toctree:: :maxdepth: 2 :caption: Contents: + quick_start_guide Indices and tables From aa2b131a2f650ce249cdc7c6dc595baa432ad12f Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Dec 2016 17:44:42 +0100 Subject: [PATCH 136/141] Docs: api_danbooru.rst - Adapt Danbooru API docstring to sphinx. - Adds api_danbooru.rst - Order by source - Update index.rst and quick_start_guide.rst --- docs/source/api_danbooru.rst | 6 + docs/source/conf.py | 3 + docs/source/index.rst | 7 +- docs/source/quick_start_guide.rst | 1 + pybooru/api_danbooru.py | 561 +++++++++++++++--------------- 5 files changed, 300 insertions(+), 278 deletions(-) create mode 100644 docs/source/api_danbooru.rst diff --git a/docs/source/api_danbooru.rst b/docs/source/api_danbooru.rst new file mode 100644 index 0000000..20db4b0 --- /dev/null +++ b/docs/source/api_danbooru.rst @@ -0,0 +1,6 @@ +Danbooru API Reference +====================== + +.. automodule:: pybooru.api_danbooru + :show-inheritance: + :members: diff --git a/docs/source/conf.py b/docs/source/conf.py index d629c53..82d1071 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -155,3 +155,6 @@ author, 'Pybooru', 'One line description of project.', 'Miscellaneous'), ] + +# Order autodoc by source +autodoc_member_order = 'bysource' diff --git a/docs/source/index.rst b/docs/source/index.rst index 38af724..cb21d84 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -8,13 +8,13 @@ Welcome to Pybooru's documentation! **Pybooru** is a Python package to access to the API of Danbooru/Moebooru based sites. -- Version: **4.0.0**. -- Licensed under: **MIT License**. +- Version: **4.0.0** +- Licensed under: **MIT License** +- Python: >= 2.6 or Python: >= 3.3 Dependencies ------------ -- Python: >= 2.6 or Python: >= 3.3 - requests @@ -23,6 +23,7 @@ Dependencies :caption: Contents: quick_start_guide + api_danbooru Indices and tables diff --git a/docs/source/quick_start_guide.rst b/docs/source/quick_start_guide.rst index 93b5b2a..e11f93b 100644 --- a/docs/source/quick_start_guide.rst +++ b/docs/source/quick_start_guide.rst @@ -8,6 +8,7 @@ Features - Support Moebooru API. - Defult site list. - JSON responses. +- Custom user-agent. Installation ------------ diff --git a/pybooru/api_danbooru.py b/pybooru/api_danbooru.py index 3aa305b..7d7f605 100644 --- a/pybooru/api_danbooru.py +++ b/pybooru/api_danbooru.py @@ -18,22 +18,23 @@ class DanbooruApi_Mixin(object): """Contains all Danbooru API calls. - API Version: v2.105.0 (77e06b6) - doc: https://danbooru.donmai.us/wiki_pages/43568 + * API Version: v2.105.0 (77e06b6) + * Doc: https://danbooru.donmai.us/wiki_pages/43568 """ def post_list(self, **params): """Get a list of posts. Parameters: - limit: How many posts you want to retrieve. There is a hard limit - of 100 posts per request. - page: The page number. - tags: The tags to search for. Any tag combination that works on the - web site will work here. This includes all the meta-tags. - raw: When this parameter is set the tags parameter will not be - parsed for aliased tags, metatags or multiple tags, and will - instead be parsed as a single literal tag. + :param limit: How many posts you want to retrieve. There is a hard + limit of 100 posts per request. + :param page: The page number. + :param tags: The tags to search for. Any tag combination that works + on the web site will work here. This includes all the + meta-tags. + :param raw: When this parameter is set the tags parameter will not + be parsed for aliased tags, metatags or multiple tags, + and will instead be parsed as a single literal tag. """ return self._get('posts.json', params) @@ -41,7 +42,7 @@ def post_show(self, post_id): """Get a post. Parameters: - post_id: REQUIRED Where post_id is the post id. + :param post_id: REQUIRED Where post_id is the post id. """ return self._get('/posts/{0}.json'.format(post_id)) @@ -50,12 +51,12 @@ def post_update(self, post_id, tag_string=None, rating=None, source=None, """Update a specific post (Requires login). Parameters: - post_id: REQUIRED The id number of the post to update. - tag_string: A space delimited list of tags. - rating: The rating for the post. Can be: safe, questionable, or - explicit. - source: If this is a URL, Danbooru will download the file. - parent_id: The ID of the parent post. + :param post_id: REQUIRED The id number of the post to update. + :param tag_string: A space delimited list of tags. + :param rating: The rating for the post. Can be: safe, questionable, + or explicit. + :param source: If this is a URL, Danbooru will download the file. + :param parent_id: The ID of the parent post. """ params = { 'post[tag_string]': tag_string, @@ -70,8 +71,8 @@ def post_revert(self, post_id, version_id): """Function to reverts a post to a previous version (Requires login). Parameters: - post_id: REQUIRED post id. - version_id: REQUIRED The post version id to revert to. + :param post_id: REQUIRED post id. + :param version_id: REQUIRED The post version id to revert to. """ return self._get('/posts/{0}/revert.json'.format(post_id), {'version_id': version_id}, 'PUT', auth=True) @@ -80,8 +81,8 @@ def post_copy_notes(self, post_id, other_post_id): """Function to copy notes (requires login). Parameters: - post_id: REQUIRED Post id. - other_post_id: REQUIRED The id of the post to copy notes to. + :param post_id: REQUIRED Post id. + :param other_post_id: REQUIRED The id of the post to copy notes to. """ return self._get('/posts/{0}/copy_notes.json'.format(post_id), {'other_post_id': other_post_id}, 'PUT', auth=True) @@ -91,8 +92,8 @@ def post_vote(self, post_id, score): Danbooru: Post votes/create. Parameters: - post_id: REQUIRED Ppost id. - score: REQUIRED Can be: up, down. + :param post_id: REQUIRED Ppost id. + :param score: REQUIRED Can be: up, down. """ return self._get('/posts/{0}/votes.json'.format(post_id), {'score': score}, 'POST', auth=True) @@ -102,12 +103,12 @@ def post_flag_list(self, creator_id=None, creator_name=None, post_id=None, """Function to flag a post (Requires login). Parameters: - creator_id: The user id of the flag's creator. - creator_name: The name of the flag's creator. - post_id: The post id if the flag. - reason_matches: Flag's reason. - is_resolved: - category: unapproved/banned/normal. + :param creator_id: The user id of the flag's creator. + :param creator_name: The name of the flag's creator. + :param post_id: The post id if the flag. + :param reason_matches: Flag's reason. + :param is_resolved: Can be 1 or 0. + :param category: unapproved/banned/normal. """ params = { 'search[creator_id]': creator_id, @@ -123,8 +124,8 @@ def post_flag_create(self, post_id, reason): """Function to flag a post. Parameters: - post_id: REQUIRED The id of the flagged post. - reason: REQUIRED The reason of the flagging. + :param post_id: REQUIRED The id of the flagged post. + :param reason: REQUIRED The reason of the flagging. """ params = {'post_flag[post_id]': post_id, 'post_flag[reason]': reason} return self._get('post_flags.json', params, 'POST', auth=True) @@ -134,9 +135,9 @@ def post_appeals_list(self, creator_id=None, creator_name=None, """Function to return list of appeals (Requires login). Parameters: - creator_id: The user id of the appeal's creator. - creator_name: The name of the appeal's creator. - post_id: The post id if the appeal. + :param creator_id: The user id of the appeal's creator. + :param creator_name: The name of the appeal's creator. + :param post_id: The post id if the appeal. """ params = { 'creator_id': creator_id, @@ -149,8 +150,8 @@ def post_appeals_create(self, post_id, reason): """Function to create appeals (Requires login). Parameters: - post_id: REQUIRED The id of the appealed post. - reason: REQUIRED The reason of the appeal. + :param post_id: REQUIRED The id of the appealed post. + :param reason: REQUIRED The reason of the appeal. """ params = {'post_appeal[post_id]': post_id, 'post_appeal[reason]': reason} @@ -161,10 +162,10 @@ def post_versions(self, updater_name=None, updater_id=None, """Get list of post versions. Parameters: - updater_name: - updater_id: - post_id: - start_id: + :param updater_name: + :param updater_id: + :param post_id: + :param start_id: """ params = { 'search[updater_name]': updater_name, @@ -178,9 +179,9 @@ def upload_list(self, uploader_id=None, uploader_name=None, source=None): """Search and eturn a uploads list (Requires login). Parameters: - uploader_id: The id of the uploader. - uploader_name: The name of the uploader. - source The: source of the upload (exact string match). + :param uploader_id: The id of the uploader. + :param uploader_name: The name of the uploader. + :param source: The source of the upload (exact string match). """ params = { 'search[uploader_id]': uploader_id, @@ -193,7 +194,7 @@ def upload_show(self, upload_id): """Get a upload (Requires login). Parameters: - upload_id: Where upload_id is the upload id. + :param upload_id: Where upload_id is the upload id. """ return self._get('uploads/{0}.json'.format(upload_id), auth=True) @@ -202,11 +203,11 @@ def upload_create(self, tag_string, rating, file_=None, source=None, """Function to create a new upload (Requires login). Parameters: - tag_string: REQUIRED The tags. - rating: REQUIRED Can be: safe, questionable, explicit. - file_: The file data encoded as a multipart form. - source: The source URL. - parent_id: The parent post id. + :param tag_string: REQUIRED The tags. + :param rating: REQUIRED Can be: safe, questionable, explicit. + :param file_: The file data encoded as a multipart form. + :param source: The source URL. + :param parent_id: The parent post id. """ if file_ or source is not None: params = { @@ -227,18 +228,19 @@ def comment_list(self, group_by, body_matches=None, post_id=None, """Return a list of comments. Parameters: - group_by: Can be 'comment', 'post'. Comment will return recent - comments. Post will return posts that have been recently - commented on. - The following work only with group_by=comment: - body_matches: Body contains the given terms. - post_id: Post id. - post_tags_match: The comment's post's tags match the given - terms. - creator_name: The name of the creator (exact match) - creator_id: The user id of the creator - The following work only with group_by=post: - tags The post's tags match the given terms. + :param group_by: + Can be 'comment', 'post'. Comment will return recent comments. + Post will return posts that have been recently commented on. + + :param group_by=comment: + :param body_matches: Body contains the given terms. + :param post_id: Post id. + :param post_tags_match: The comment's post's tags match + the given terms. + :param group_by=post: + :param tags: The post's tags match the given terms. + :param creator_name: The name of the creator (exact match) + :param creator_id: The user id of the creator """ params = {'group_by': group_by} if group_by == 'comment': @@ -257,10 +259,10 @@ def comment_create(self, post_id, body, do_not_bump_post=None): """Action to lets you create a comment (Requires login). Parameters: - post_id: REQUIRED. - body: REQUIRED. - do_not_bump_post: Set to 1 if you do not want the post to be bumped - to the top of the comment listing. + :param post_id: REQUIRED. + :param body: REQUIRED. + :param do_not_bump_post: Set to 1 if you do not want the post to be + bumped to the top of the comment listing. """ params = { 'comment[post_id]': post_id, @@ -273,10 +275,10 @@ def comment_update(self, comment_id, body, do_not_bump_post=None): """Function to update a comment (Requires login). Parameters: - comment_id: REQUIRED comment id. - body: REQUIRED. - do_not_bump_post: Set to 1 if you do not want the post to be bumped - to the top of the comment listing. + :param comment_id: REQUIRED comment id. + :param body: REQUIRED. + :param do_not_bump_post: Set to 1 if you do not want the post to be + bumped to the top of the comment listing. """ params = { 'comment[body]': body, @@ -289,7 +291,8 @@ def comment_show(self, comment_id): """Get a specific comment. Parameters: - comment_id: REQUIRED the id number of the comment to retrieve. + :param comment_id: REQUIRED the id number of the comment to + retrieve. """ return self._get('comments/{0}.json'.format(comment_id)) @@ -297,7 +300,7 @@ def comment_delete(self, comment_id): """Remove a specific comment (Requires login). Parameters: - comment_id: REQUIRED the id number of the comment to remove. + :param comment_id: REQUIRED the id number of the comment to remove. """ return self._get('comments/{0}.json'.format(comment_id), method='DELETE', auth=True) @@ -306,8 +309,8 @@ def favorite_list(self, user_id=None): """Return a list with favorite posts (Requires login). Parameters: - user_id: Which user's favorites to show. Defaults to your own if - not specified. + :param user_id: Which user's favorites to show. Defaults to your + own if not specified. """ return self._get('favorites.json', {'user_id': user_id}, auth=True) @@ -315,7 +318,7 @@ def favorite_add(self, post_id): """Add post to favorite (Requires login). Parameters: - post_id: REQUIRED The post to favorite. + :param post_id: REQUIRED The post to favorite. """ return self._get('favorites.json', {'post_id': post_id}, 'POST', auth=True) @@ -324,7 +327,7 @@ def favorite_remove(self, post_id): """Remove a post from favorites (Requires login). Parameters: - post_id: REQUIRED where post_id is the post id. + :param post_id: REQUIRED where post_id is the post id. """ return self._get('favorites/{0}.json'.format(post_id), method='DELETE', auth=True) @@ -335,12 +338,12 @@ def dmail_list(self, message_matches=None, to_name=None, to_id=None, (Requires login). Parameters: - message_matches: The message body contains the given terms. - to_name: The recipient's name. - to_id: The recipient's user id. - from_name: The sender's name. - from_id: The sender's user id. - read: Can be: true, false. + :param message_matches: The message body contains the given terms. + :param to_name: The recipient's name. + :param to_id: The recipient's user id. + :param from_name: The sender's name. + :param from_id: The sender's user id. + :param read: Can be: true, false. """ params = { 'search[message_matches]': message_matches, @@ -357,7 +360,7 @@ def dmail_show(self, dmail_id): (Requires login). Parameters: - dmail_id: REQUIRED where dmail_id is the dmail id. + :param dmail_id: REQUIRED where dmail_id is the dmail id. """ return self._get('dmails/{0}.json'.format(dmail_id), auth=True) @@ -365,9 +368,9 @@ def dmail_create(self, to_name, title, body): """Create a dmail (Requires login) Parameters: - to_name: REQUIRED the recipient's name. - title: REQUIRED the title of the message. - body: REQUIRED the body of the message. + :param to_name: REQUIRED the recipient's name. + :param title: REQUIRED the title of the message. + :param body: REQUIRED the body of the message. """ params = { 'dmail[to_name]': to_name, @@ -380,7 +383,7 @@ def dmail_delete(self, dmail_id): """Delete a dmail. You can only delete dmails you own (Requires login). Parameters: - dmail_id: REQUIRED where dmail_id is the dmail id. + :param dmail_id: REQUIRED where dmail_id is the dmail id. """ return self._get('dmails/{0}.json'.format(dmail_id), method='DELETE', auth=True) @@ -391,25 +394,31 @@ def artist_list(self, query=None, artist_id=None, creator_name=None, """Get an artist of a list of artists. Parameters: - query: This field has multiple uses depending on what the query - starts with: - http: Search for artist with this URL. - name: Search for artists with the given name as their base - name. - other: Search for artists with the given name in their other - names. - group: Search for artists belonging to the group with the given - name. - status:banned Search for artists that are banned. - else Search for the given name in the base name and the other - names. - artist_id: The artist id. - creator_name: - creator_id: - is_active: Can be: true, false - is_banned: Can be: true, false - empty_only: Search for artists that have 0 posts. Can be: true - order: Can be: name, updated_at. + :param query: + This field has multiple uses depending on what the query starts + with: + + 'http:desired_url': + Search for artist with this URL. + 'name:desired_url': + Search for artists with the given name as their base name. + 'other:other_name': + Search for artists with the given name in their other + names. + 'group:group_name': + Search for artists belonging to the group with the given + name. + 'status:banned': + Search for artists that are banned. else Search for the + given name in the base name and the other names. + :param artist_id: The artist id. + :param creator_name: Exact creator name. + :param creator_id: Artist creator id. + :param is_active: Can be: true, false + :param is_banned: Can be: true, false + :param empty_only: Search for artists that have 0 posts. Can be: + true + :param order: Can be: name, updated_at. """ params = { 'search[name]': query, @@ -427,7 +436,7 @@ def artist_show(self, artist_id): """Return a specific artist. Parameters: - artist_id: REQUIRED where artist_id is the artist id. + :param artist_id:param : REQUIRED where artist_id is the artist id. """ return self._get('artists/{0}.json'.format(artist_id)) @@ -436,12 +445,12 @@ def artist_create(self, name, other_names_comma=None, group_name=None, """Function to create an artist (Requires login) (UNTESTED). Parameters: - name: REQUIRED. - other_names_comma: List of alternative names for this artist, comma - delimited. - group_name: The name of the group this artist belongs to. - url_string: List of URLs associated with this artist, whitespace or - newline delimited. + :param name: REQUIRED. + :param other_names_comma: List of alternative names for this + artist, comma delimited. + :param group_name: The name of the group this artist belongs to. + :param url_string: List of URLs associated with this artist, + whitespace or newline delimited. """ params = { 'artist[name]': name, @@ -456,13 +465,13 @@ def artist_update(self, artist_id, name=None, other_names_comma=None, """Function to update artists (Requires login) (UNTESTED). Parameters: - artist_id: REQUIRED where artist_id is the artist id. - name: - other_names_comma: List of alternative names for this artist, comma - delimited. - group_name: The name of the group this artist belongs to. - url_string: List of URLs associated with this artist, whitespace or - newline delimited. + :param artist_id: REQUIRED where artist_id is the artist id. + :param name: + :param other_names_comma: List of alternative names for this + artist, comma delimited. + :param group_name: The name of the group this artist belongs to. + :param url_string: List of URLs associated with this artist, + whitespace or newline delimited. """ params = { 'artist[name]': name, @@ -477,23 +486,22 @@ def artist_delete(self, artist_id): """Action to lets you delete an artist (Requires login) (UNTESTED). Parameters: - artist_id: where artist_id is the artist id. + :param artist_id: where artist_id is the artist id. """ return self._get('artists/{0}.json'.format(artist_id), method='DELETE', auth=True) def artist_banned(self): """This is a shortcut for an artist listing search with - name=status:banned. - """ + name=status:banned.:param """ return self._get('artists/banned.json') def artist_revert(self, artist_id, version_id): """Revert an artist (Requires login) (UNTESTED). Parameters: - artist_id: REQUIRED The artist id. - version_id: REQUIRED The artist version id to revert to. + :param artist_id: REQUIRED The artist id. + :param version_id: REQUIRED The artist version id to revert to. """ params = {'version_id': version_id} return self._get('artists/{0}/revert.json'.format(artist_id), params, @@ -504,12 +512,12 @@ def artist_versions(self, name=None, updater_id=None, artist_id=None, """Get list of artist versions. Parameters: - name: - updater_id: - artist_id: - is_active: Can be: true, false. - is_banned: Can be: true, false. - order: Can be: name, date. + :param name: + :param updater_id: + :param artist_id: + :param is_active: Can be: true, false. + :param is_banned: Can be: true, false. + :param order: Can be: name, date. """ params = { 'search[name]': name, @@ -527,12 +535,12 @@ def artist_commentary_list(self, text_matches=None, post_id=None, """list artist commentary. Parameters: - text_matches: - post_id: - post_tags_match: The commentary's post's tags match the given - terms. Meta-tags not supported. - original_present: Can be: yes, no - translated_present: Can be: yes, no + :param text_matches: + :param post_id: + :param post_tags_match: The commentary's post's tags match the + giventerms. Meta-tags not supported. + :param original_present: Can be: yes, no. + :param translated_present: Can be: yes, no. """ params = { 'search[text_matches]': text_matches, @@ -549,11 +557,11 @@ def artist_commentary_create_update(self, post_id, original_title, """Create or update artist commentary (Requires login) (UNTESTED). Parameters: - post_id: REQUIRED. - original_title: - original_description: - translated_title: - translated_description: + :param post_id: REQUIRED. + :param original_title: + :param original_description: + :param translated_title: + :param translated_description: """ params = { 'artist_commentary[post_id]': post_id, @@ -569,8 +577,9 @@ def artist_commentary_revert(self, id_, version_id): """Revert artist commentary (Requires login) (UNTESTED). Parameters: - id_: REQUIRED The artist commentary id. - version_id: REQUIRED The artist commentary version id to revert to. + :param id_: REQUIRED The artist commentary id. + :param version_id: REQUIRED The artist commentary version id to + revert to. """ params = {'version_id': version_id} return self._get('artist_commentaries/{0}/revert.json'.format(id_), @@ -580,8 +589,8 @@ def artist_commentary_versions(self, post_id, updater_id): """Return list of artist commentary versions. Parameters: - updater_id: REQUIRED. - post_id: REQUIRED. + :param updater_id: REQUIRED. + :param post_id: REQUIRED. """ params = { 'search[updater_id]': updater_id, @@ -594,12 +603,13 @@ def note_list(self, group_by=None, body_matches=None, post_id=None, """Return list of notes. Parameters: - group_by: Can be: note, post (by default post). - body_matches: The note's body matches the given terms. - post_id: A specific post. - post_tags_match: The note's post's tags match the given terms. - creator_name: The creator's name. Exact match. - creator_id: The creator's user id. + :param group_by: Can be: note, post (by default post). + :param body_matches: The note's body matches the given terms. + :param post_id: A specific post. + :param post_tags_match: The note's post's tags match the given + terms. + :param creator_name: The creator's name. Exact match. + :param creator_id: The creator's user id. """ params = { 'group_by': group_by, @@ -615,7 +625,7 @@ def note_show(self, note_id): """Get a specific note. Parameters: - note_id: REQUIRED Where note_id is the note id. + :param :param note_id: REQUIRED Where note_id is the note id. """ return self._get('notes/{0}.json'.format(note_id)) @@ -623,14 +633,14 @@ def note_create(self, post_id, coor_x, coor_y, width, height, body): """Function to create a note (Requires login) (UNTESTED). Parameters: - post_id: REQUIRED - coor_x: REQUIRED The x coordinates of the note in pixels, with - respect to the top-left corner of the image. - coor_y: REQUIRED The y coordinates of the note in pixels, with - respect to the top-left corner of the image. - width: REQUIRED The width of the note in pixels. - height: REQUIRED The height of the note in pixels. - body: REQUIRED The body of the note. + :param post_id: REQUIRED + :param coor_x: REQUIRED The x coordinates of the note in pixels, + with respect to the top-left corner of the image. + :param coor_y: REQUIRED The y coordinates of the note in pixels, + with respect to the top-left corner of the image. + :param width: REQUIRED The width of the note in pixels. + :param height: REQUIRED The height of the note in pixels. + :param body: REQUIRED The body of the note. """ params = { 'note[post_id]': post_id, @@ -647,14 +657,14 @@ def note_update(self, note_id, coor_x=None, coor_y=None, width=None, """Function to update a note (Requires login) (UNTESTED). Parameters: - note_id: REQUIRED Where note_id is the note id. - coor_x: REQUIRED The x coordinates of the note in pixels, with - respect to the top-left corner of the image. - coor_y: REQUIRED The y coordinates of the note in pixels, with - respect to the top-left corner of the image. - width: REQUIRED The width of the note in pixels. - height: REQUIRED The height of the note in pixels. - body: REQUIRED The body of the note. + :param note_id: REQUIRED Where note_id is the note id. + :param coor_x: REQUIRED The x coordinates of the note in pixels, + with respect to the top-left corner of the image. + :param coor_y: REQUIRED The y coordinates of the note in pixels, + with respect to the top-left corner of the image. + :param width: REQUIRED The width of the note in pixels. + :param height: REQUIRED The height of the note in pixels. + :param body: REQUIRED The body of the note. """ params = { 'note[x]': coor_x, @@ -670,7 +680,7 @@ def note_delete(self, note_id): """delete a specific note (Requires login) (UNTESTED). Parameters: - note_id: REQUIRED Where note_id is the note id. + :param note_id: REQUIRED Where note_id is the note id. """ return self._get('notes/{0}.json'.format(note_id), method='DELETE', auth=True) @@ -679,8 +689,8 @@ def note_revert(self, note_id, version_id): """Function to revert a specific note (Requires login) (UNTESTED). Parameters: - note_id: REQUIRED Where note_id is the note id. - version_id: REQUIRED The note version id to revert to. + :param note_id: REQUIRED Where note_id is the note id. + :param version_id: REQUIRED The note version id to revert to. """ return self._get('notes/{0}/revert.json'.format(note_id), {'version_id': version_id}, method='PUT', auth=True) @@ -689,9 +699,9 @@ def note_versions(self, updater_id=None, post_id=None, note_id=None): """Get list of note versions. Parameters: - updater_id: - post_id: - note_id: + :param updater_id: + :param post_id: + :param note_id: """ params = { 'search[updater_id]': updater_id, @@ -709,16 +719,16 @@ def user_list(self, name=None, min_level=None, max_level=None, level=None, The current levels are: Member 20, Gold 30, Platinum 31, Builder 32, Contributor 33, - Janitor 35, Moderator 40 and Admin 50 + Janitor 35, Moderator 40 and Admin 50. Parameters: - name: Supports patterns. - min_level: Minimum level (see section on levels). - max_level: Maximum level (see section on levels). - level: Current level (see section on levels). - user_id: The user id. - order: Can be: 'name', 'post_upload_count', 'note_count', - 'post_update_count', 'date'. + :param name: Supports patterns. + :param min_level: Minimum level (see section on levels). + :param max_level: Maximum level (see section on levels). + :param level: Current level (see section on levels). + :param user_id: The user id. + :param order: Can be: 'name', 'post_upload_count', 'note_count', + 'post_update_count', 'date'. """ params = { 'search[name]': name, @@ -734,7 +744,7 @@ def user_show(self, user_id): """Get a specific user. Parameters: - user_id: REQUIRED Where user_id is the user id. + :param user_id: REQUIRED Where user_id is the user id. """ return self._get('users/{0}.json'.format(user_id)) @@ -744,13 +754,13 @@ def pool_list(self, name_matches=None, description_matches=None, """Get a list of pools. Parameters: - name_matches: - description_matches: - creator_name: - creator_id: - is_active: Can be: true, false. - order: Can be: name, created_at, post_count, date. - category: Can be: series, collection + :param name_matches: + :param description_matches: + :param creator_name: + :param creator_id: + :param is_active: Can be: true, false. + :param order: Can be: name, created_at, post_count, date. + :param category: Can be: series, collection """ params = { 'search[name_matches]': name_matches, @@ -767,7 +777,7 @@ def pool_show(self, pool_id): """Get a specific pool. Parameters: - pool_id: REQUIRED Where pool_id is the pool id. + :param pool_id: REQUIRED Where pool_id is the pool id. """ return self._get('pools/{0}.json'.format(pool_id)) @@ -775,9 +785,9 @@ def pool_create(self, name, description, category): """Function to create a pool (Requires login) (UNTESTED). Parameters: - name: REQUIRED. - description: REQUIRED. - category: Can be: series, collection. + :param name: REQUIRED. + :param description: REQUIRED. + :param category: Can be: series, collection. """ params = { 'pool[name]': name, @@ -791,12 +801,12 @@ def pool_update(self, pool_id, name=None, description=None, post_ids=None, """Update a pool (Requires login) (UNTESTED). Parameters: - pool_id: REQUIRED Where pool_id is the pool id. - name: - description: - post_ids: List of space delimited post ids. - is_active: Can be: 1, 0 - category: Can be: series, collection + :param pool_id: REQUIRED Where pool_id is the pool id. + :param name: + :param description: + :param post_ids: List of space delimited post ids. + :param is_active: Can be: 1, 0 + :param category: Can be: series, collection """ params = { 'pool[name]': name, @@ -812,7 +822,7 @@ def pool_delete(self, pool_id): """Delete a pool (Requires login) (UNTESTED). Parameters: - pool_id: REQUIRED Where pool_id is the pool id. + :param pool_id: REQUIRED Where pool_id is the pool id. """ return self._get('pools/{0}.json'.format(pool_id), method='DELETE', auth=True) @@ -821,7 +831,7 @@ def pool_undelete(self, pool_id): """Undelete a specific poool (Requires login) (UNTESTED). Parameters: - pool_id: REQUIRED Where pool_id is the pool id. + :param pool_id: REQUIRED Where pool_id is the pool id. """ return self._get('pools/{0}/undelete.json'.format(pool_id), method='POST', auth=True) @@ -830,8 +840,8 @@ def pool_revert(self, pool_id, version_id): """Function to revert a specific pool (Requires login) (UNTESTED). Parameters: - pool_id: REQUIRED Where pool_id is the pool id. - version_id: REQUIRED. + :param pool_id: REQUIRED Where pool_id is the pool id. + :param version_id: REQUIRED. """ params = {'version_id': version_id} return self._get('pools/{0}/revert.json'.format(pool_id), params, @@ -841,9 +851,9 @@ def pool_versions(self, updater_id=None, updater_name=None, pool_id=None): """Get list of pool versions. Parameters: - updater_id: - updater_name: - pool_id: + :param updater_id: + :param updater_name: + :param pool_id: """ params = { 'search[updater_id]': updater_id, @@ -857,17 +867,17 @@ def tag_list(self, name_matches=None, category=None, hide_empty=None, """Get a list of tags. Parameters: - name_matches: - category: Can be: 0, 1, 3, 4 (general, artist, copyright, - character respectively) - hide_empty: Can be: yes, no. Excludes tags with 0 posts - when "yes". - order: Can be: name, date, count - has_wiki: Can be: yes, no - name: Allows searching for multiple tags with exact given - names, separated by commas. e.g. - search[name]=touhou,original,k-on! would return the - three listed tags. + :param name_matches: + :param category: Can be: 0, 1, 3, 4 (general, artist, copyright, + character respectively) + :param hide_empty: Can be: yes, no. Excludes tags with 0 posts + when "yes". + :param order: Can be: name, date, count + :param has_wiki: Can be: yes, no + :param name: Allows searching for multiple tags with exact given + names, separated by commas. e.g. + search[name]=touhou,original,k-on! would return the + three listed tags. """ params = { 'search[name_matches]': name_matches, @@ -884,9 +894,9 @@ def tag_aliases(self, name_matches=None, antecedent_name=None, """Get tags aliases. Parameters: - name_matches: Match antecedent or consequent name. - antecedent_name: Match antecedent name (exact match). - tag_id: The tag alias id. + :param name_matches: Match antecedent or consequent name. + :param antecedent_name: Match antecedent name (exact match). + :param tag_id: The tag alias id. """ params = { 'search[name_matches]': name_matches, @@ -900,9 +910,9 @@ def tag_implications(self, name_matches=None, antecedent_name=None, """Get tags implications. Parameters: - name_matches: Match antecedent or consequent name. - antecedent_name: Match antecedent name (exact match). - tag_id: The tag implication id. + :param name_matches: Match antecedent or consequent name. + :param antecedent_name: Match antecedent name (exact match). + :param tag_id: The tag implication id. """ params = { 'search[name_matches]': name_matches, @@ -915,9 +925,10 @@ def tag_related(self, query, category=None): """Get related tags. Parameters: - query: REQUIRED The tag to find the related tags for. - category: If specified, show only tags of a specific category. - Can be: General 0, Artist 1, Copyright 3 and Character 4. + :param query: REQUIRED The tag to find the related tags for. + :param category: If specified, show only tags of a specific + category. Can be: General 0, Artist 1, Copyright + 3 and Character 4. """ params = {'query': query, 'category': category} return self._get('related_tag.json', params) @@ -927,12 +938,12 @@ def wiki_list(self, title=None, creator_id=None, body_matches=None, """Function to retrieves a list of every wiki page. Parameters: - title: - creator_id: - body_matches: - other_names_match: - creator_name: - order: Can be: date, title. + :param title: + :param creator_id: + :param body_matches: + :param other_names_match: + :param creator_name: + :param order: Can be: date, title. """ params = { 'search[title]': title, @@ -948,7 +959,7 @@ def wiki_show(self, wiki_page_id): """Retrieve a specific page of the wiki. Parameters: - wiki_page_id: REQUIRED Where page_id is the wiki page id. + :param wiki_page_id: REQUIRED Where page_id is the wiki page id. """ return self._get('wiki_pages/{0}.json'.format(wiki_page_id)) @@ -956,9 +967,9 @@ def wiki_create(self, title, body, other_names=None): """Action to lets you create a wiki page (Requires login) (UNTESTED). Parameters: - title: REQUIRED. - body: REQUIRED. - other_names: + :param title: REQUIRED. + :param body: REQUIRED. + :param other_names: """ params = { 'wiki_page[title]': title, @@ -972,10 +983,10 @@ def wiki_update(self, wiki_page_id, title=None, body=None, """Action to lets you update a wiki page (Requires login) (UNTESTED). Parameters: - wiki_page_id: REQURIED Whre page_id is the wiki page id. - title: - body: - other_names: + :param wiki_page_id: REQURIED Whre page_id is the wiki page id. + :param title: + :param body: + :param other_names: """ params = { 'wiki_page[title]': title, @@ -989,8 +1000,8 @@ def wiki_revert(self, wiki_page_id, version_id): """Revert page to a previeous version (Requires login) (UNTESTED). Parameters: - wiki_page_id: REQUIRED Where page_id is the wiki page id. - version_id REQUIRED. + :param wiki_page_id: REQUIRED Where page_id is the wiki page id. + :param version_id: REQUIRED. """ return self._get('wiki_pages/{0}/revert.json'.format(wiki_page_id), {'version_id': version_id}, method='PUT', auth=True) @@ -999,8 +1010,8 @@ def wiki_versions(self, wiki_page_id, updater_id): """Return a list of wiki page version. Parameters: - wiki_page_id: REQUIRED. - updater_id: REQUIRED. + :param wiki_page_id: REQUIRED. + :param updater_id: REQUIRED. """ params = { 'earch[updater_id]': updater_id, @@ -1012,8 +1023,8 @@ def wiki_versions_show(self, wiki_page_id): """Return a specific wiki page version. Parameters: - wiki_page_id: REQUIRED Where wiki_page_id is the wiki page version - id. + :param wiki_page_id: REQUIRED Where wiki_page_id is the wiki page + version id. """ return self._get('wiki_page_versions/{0}.json'.format(wiki_page_id)) @@ -1022,10 +1033,10 @@ def forum_topic_list(self, title_matches=None, title=None, """Function to get forum topics. Parameters: - title_matches: Search body for the given terms. - title: Exact title match. - category_id: Can be: 0, 1, 2 (General, Tags, Bugs & Features - respectively) + :param title_matches: Search body for the given terms. + :param title: Exact title match. + :param category_id: Can be: 0, 1, 2 (General, Tags, Bugs & Features + respectively) """ params = { 'search[title_matches]': title_matches, @@ -1038,7 +1049,7 @@ def forum_topic_show(self, topic_id): """Retrieve a specific forum topic. Parameters: - topic_id: REQUIRED Where topic_id is the forum topic id. + :param topic_id: REQUIRED Where topic_id is the forum topic id. """ return self._get('forum_topics/{0}.json'.format(topic_id)) @@ -1046,10 +1057,10 @@ def forum_topic_create(self, title, body, category=None): """Function to create topic (Requires login) (UNTESTED). Parameters: - title: topic title. - body: Message of the initial post. - category: Can be: 0, 1, 2 (General, Tags, Bugs & Features - respectively). + :param title: topic title. + :param body: Message of the initial post. + :param category: Can be: 0, 1, 2 (General, Tags, Bugs & Features + respectively). """ params = { 'forum_topic[title]': title, @@ -1062,10 +1073,10 @@ def forum_topic_update(self, topic_id, title=None, category=None): """Update a specific topic (Login Requires) (UNTESTED). Parameters: - topic_id: REQUIRED .ñWhere topic_id is the topic id. - title: Topic title. - category: Can be: 0, 1, 2 (General, Tags, Bugs & Features - respectively) + :param topic_id: REQUIRED .ñWhere topic_id is the topic id. + :param title: Topic title. + :param category: Can be: 0, 1, 2 (General, Tags, Bugs & Features + respectively) """ params = { 'forum_topic[title]': title, @@ -1078,7 +1089,7 @@ def forum_topic_delete(self, topic_id): """Delete a topic (Login Requires) (Moderator+) (UNTESTED). Parameters: - topic_id: REQUIRED Where topic_id is the topic id. + :param topic_id: REQUIRED Where topic_id is the topic id. """ return self._get('forum_topics/{0}.json'.format(topic_id), method='DELETE', auth=True) @@ -1087,7 +1098,7 @@ def forum_topic_undelete(self, topic_id): """Un delete a topic (Login requries) (Moderator+) (UNTESTED). Parameters: - topic_id: REQUIRED Where topic_id is the topic id. + :param topic_id: REQUIRED Where topic_id is the topic id. """ return self._get('forum_topics/{0}/undelete.json'.format(topic_id), method='POST', auth=True) @@ -1098,13 +1109,13 @@ def forum_post_list(self, creator_id=None, creator_name=None, """Return a list of forum posts. Parameters: - creator_id: - creator_name: - topic_id: - topic_title_matches: - topic_category_id: Can be: 0, 1, 2 (General, Tags, Bugs & Features - respectively) - body_matches: + :param creator_id: + :param creator_name: + :param topic_id: + :param topic_title_matches: + :param topic_category_id: Can be: 0, 1, 2 (General, Tags, Bugs & + Features respectively) + :param body_matches: """ params = { 'search[creator_id]': creator_id, @@ -1120,8 +1131,8 @@ def forum_post_create(self, topic_id, body): """Create a forum post (Requires login). Parameters: - topic_id: REQUIRED. - body: REQUIRED. + :param topic_id: REQUIRED. + :param body: REQUIRED. """ params = { 'forum_post[topic_id]': topic_id, @@ -1133,8 +1144,8 @@ def forum_post_update(self, topic_id, body): """Update a specific forum post (Requries login)(Moderator+)(UNTESTED). Parameters: - post_id: REQUIRED Forum topic id. - body: REQUIRED. + :param post_id: REQUIRED Forum topic id. + :param body: REQUIRED. """ params = {'forum_post[body]': body} return self._get('forum_posts/{0}.json'.format(topic_id), params, @@ -1144,7 +1155,7 @@ def forum_post_delete(self, post_id): """Delete a specific forum post (Requires login)(Moderator+)(UNTESTED). Parameters: - post_id: REQUIRED forum post id. + :param post_id: REQUIRED forum post id. """ return self._get('forum_posts/{0}.json'.format(post_id), method='DELETE', auth=True) @@ -1154,7 +1165,7 @@ def forum_post_undelete(self, post_id): (UNTESTED). Parameters: - post_id: REQUIRED forum post id. + :param post_id: REQUIRED forum post id. """ return self._get('forum_posts/{0}/undelete.json'.format(post_id), method='POST', auth=True) From fef57320cd596611ab8c436b51dc168ea9267ced Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Dec 2016 18:24:22 +0100 Subject: [PATCH 137/141] Docs: Adds api_moebooru.rst - Adds api_moebooru.rst - Adds preview_documentation.bat script - Adapt api_moebooru.py docstring to sphinx - Update index.rst --- docs/source/api_moebooru.rst | 6 + docs/source/index.rst | 1 + pybooru/api_moebooru.py | 279 ++++++++++++++++---------------- tools/preview_documentation.bat | 7 + 4 files changed, 156 insertions(+), 137 deletions(-) create mode 100644 docs/source/api_moebooru.rst create mode 100644 tools/preview_documentation.bat diff --git a/docs/source/api_moebooru.rst b/docs/source/api_moebooru.rst new file mode 100644 index 0000000..4a95f60 --- /dev/null +++ b/docs/source/api_moebooru.rst @@ -0,0 +1,6 @@ +Moebooru API Reference +====================== + +.. automodule:: pybooru.api_moebooru + :show-inheritance: + :members: diff --git a/docs/source/index.rst b/docs/source/index.rst index cb21d84..9de7be5 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -24,6 +24,7 @@ Dependencies quick_start_guide api_danbooru + api_moebooru Indices and tables diff --git a/pybooru/api_moebooru.py b/pybooru/api_moebooru.py index 8de38c8..10a1e32 100644 --- a/pybooru/api_moebooru.py +++ b/pybooru/api_moebooru.py @@ -18,19 +18,20 @@ class MoebooruApi_Mixin(object): """Contains all Moebooru API calls. - API Versions: 1.13.0+update.3 and 1.13.0 - doc: https://yande.re/help/api or http://konachan.com/help/api + * API Versions: 1.13.0+update.3 and 1.13.0 + * doc: https://yande.re/help/api or http://konachan.com/help/api """ def post_list(self, **params): """Get a list of posts. Parameters: - tags: The tags to search for. Any tag combination that works on the - web site will work here. This includes all the meta-tags. - limit: How many posts you want to retrieve. There is a limit of 100 - posts per request. - page: The page number. + :param tags: The tags to search for. Any tag combination that works + on the web site will work here. This includes all the + meta-tags. + :param limit: How many posts you want to retrieve. There is a limit + of 100:param posts per request. + :param page: The page number. """ return self._get('post', params) @@ -44,19 +45,20 @@ def post_create(self, tags, file_=None, rating=None, source=None, multipart form or through a source URL (Requires login) (UNTESTED). Parameters: - tags: A space delimited list of tags. - file_: The file data encoded as a multipart form. Path of content. - rating: The rating for the post. Can be: safe, questionable, - or explicit. - source: If this is a URL, Moebooru will download the file. - rating_locked: Set to true to prevent others from changing - the rating. - note_locked: Set to true to prevent others from adding - notes. - parent_id: The ID of the parent post. - md5: Supply an MD5 if you want Moebooru to verify the file - after uploading. If the MD5 doesn't match, the post is - destroyed. + :param tags: A space delimited list of tags. + :param file_: The file data encoded as a multipart form. Path of + content. + :param rating: The rating for the post. Can be: safe, questionable, + or explicit. + :param source: If this is a URL, Moebooru will download the file. + :param rating_locked: Set to true to prevent others from changing + the rating. + :param note_locked: Set to true to prevent others from adding + notes. + :param parent_id: The ID of the parent post. + :param md5: Supply an MD5 if you want Moebooru to verify the file + after uploading. If the MD5 doesn't match, the post is + destroyed. """ if file_ or source is not None: params = { @@ -81,16 +83,17 @@ def post_update(self, post_id, tags=None, file_=None, rating=None, blank if you don't want to change them (Requires login). Parameters: - post_id: The id number of the post to update. - tags: A space delimited list of tags. Specify previous tags. - file_: The file data ENCODED as a multipart form. - rating: The rating for the post. Can be: safe, questionable, or - explicit. - source: If this is a URL, Moebooru will download the file. - rating_locked: Set to true to prevent others from changing the - rating. - note_locked: Set to true to prevent others from adding notes. - parent_id: The ID of the parent post. + :param post_id: The id number of the post to update. + :param tags: A space delimited list of tags. Specify previous tags. + :param file_: The file data ENCODED as a multipart form. + :param rating: The rating for the post. Can be: safe, questionable, + or explicit. + :param source: If this is a URL, Moebooru will download the file. + :param rating_locked: Set to true to prevent others from changing + the rating. + :param note_locked: Set to true to prevent others from adding + notes. + :param parent_id: The ID of the parent post. """ params = { 'id': post_id, @@ -114,7 +117,7 @@ def post_destroy(self, post_id): moderator) (Requires Login) (UNTESTED). Parameters: - Post_id: The id number of the post to delete. + :param Post_id: The id number of the post to delete. """ return self._get('post/destroy', {'id': post_id}, 'DELETE') @@ -123,8 +126,8 @@ def post_revert_tags(self, post_id, history_id): (Requires login) (UNTESTED). Parameters: - post_id: The post id number to update. - history_id: The id number of the tag history. + :param post_id: The post id number to update. + :param history_id: The id number of the tag history. """ params = {'id': post_id, 'history_id': history_id} return self._get('post/revert_tags', params, 'PUT') @@ -133,12 +136,12 @@ def post_vote(self, post_id, score): """Action lets you vote for a post (Requires login). Parameters: - post_id: The post id. - score: - 0: No voted or Remove vote. - 1: Good. - 2: Great. - 3: Favorite, add post to favorites. + :param post_id: The post id. + :param score: + * 0: No voted or Remove vote. + * 1: Good. + * 2: Great. + * 3: Favorite, add post to favorites. """ if score <= 3: params = {'id': post_id, 'score': score} @@ -150,13 +153,14 @@ def tag_list(self, **params): """Get a list of tags. Parameters: - name: The exact name of the tag. - id: The id number of the tag. - limit: How many tags to retrieve. Setting this to 0 will return - every tag (Default value: 0). - page: The page number. - order: Can be 'date', 'name' or 'count'. - after_id: Return all tags that have an id number greater than this. + :param name: The exact name of the tag. + :param id: The id number of the tag. + :param limit: How many tags to retrieve. Setting this to 0 will + return every tag (Default value: 0). + :param page: The page number. + :param order: Can be 'date', 'name' or 'count'. + :param after_id: Return all tags that have an id number greater + than this. """ return self._get('tag', params) @@ -164,14 +168,14 @@ def tag_update(self, name=None, tag_type=None, is_ambiguous=None): """Action to lets you update tag (Requires login) (UNTESTED). Parameters: - name: The name of the tag to update. - tag_type: - General: 0. - artist: 1. - copyright: 3. - character: 4. - is_ambiguous: Whether or not this tag is ambiguous. Use 1 for true - and 0 for false. + :param name: The name of the tag to update. + :param tag_type: + * General: 0. + * artist: 1. + * copyright: 3. + * character: 4. + :param is_ambiguous: Whether or not this tag is ambiguous. Use 1 + for true and 0 for false. """ params = { 'name': name, @@ -184,9 +188,9 @@ def tag_related(self, **params): """Get a list of related tags. Parameters: - tags: The tag names to query. - type: Restrict results to this tag type. Can be general, artist, - copyright, or character. + :param tags: The tag names to query. + :param type: Restrict results to this tag type. Can be general, + artist, copyright, or character. """ return self._get('tag/related', params) @@ -194,9 +198,9 @@ def artist_list(self, **params): """Get a list of artists. Parameters: - name: The name (or a fragment of the name) of the artist. - order: Can be date or name. - page: The page number. + :param name: The name (or a fragment of the name) of the artist. + :param order: Can be date or name. + :param page: The page number. """ return self._get('artist', params) @@ -204,13 +208,13 @@ def artist_create(self, name, urls=None, alias=None, group=None): """Function to create an artist (Requires login) (UNTESTED). Parameters: - name: The artist's name. - urls: A list of URLs associated with the artist, whitespace - delimited. - alias: The artist that this artist is an alias for. Simply enter - the alias artist's name. - group: The group or cicle that this artist is a member of. Simply - enter the group's name. + :param name: The artist's name. + :param urls: A list of URLs associated with the artist, whitespace + delimited. + :param alias: The artist that this artist is an alias for. Simply + enter the alias artist's name. + :param group: The group or cicle that this artist is a member of. + Simply:param enter the group's name. """ params = { 'artist[name]': name, @@ -228,14 +232,14 @@ def artist_update(self, artist_id, name=None, urls=None, alias=None, optional. (Requires login) (UNTESTED). Parameters: - artist_id: The id of thr artist to update (Type: INT). - name: The artist's name. - urls: A list of URLs associated with the artist, whitespace - delimited. - alias: The artist that this artist is an alias for. Simply enter - the alias artist's name. - group: The group or cicle that this artist is a member of. Simply - enter the group's name. + :param artist_id: The id of thr artist to update (Type: INT). + :param name: The artist's name. + :param urls: A list of URLs associated with the artist, whitespace + delimited. + :param alias: The artist that this artist is an alias for. Simply + enter the alias artist's name. + :param group: The group or cicle that this artist is a member of. + Simply enter the group's name. """ params = { 'id': artist_id, @@ -250,7 +254,7 @@ def artist_destroy(self, artist_id): """Action to lets you remove artist (Requires login) (UNTESTED). Parameters: - artist_id: The id of the artist to destroy. + :param artist_id: The id of the artist to destroy. """ return self._get('artist/destroy', {'id': artist_id}, 'POST') @@ -258,7 +262,7 @@ def comment_show(self, comment_id): """Get a specific comment. Parameters: - comment_id: The id number of the comment to retrieve. + :param :param comment_id: The id number of the comment to retrieve. """ return self._get('comment/show', {'id': comment_id}) @@ -266,9 +270,10 @@ def comment_create(self, post_id, comment_body, anonymous=None): """Action to lets you create a comment (Requires login). Parameters: - post_id: The post id number to which you are responding. - comment_body: The body of the comment. - anonymous: Set to 1 if you want to post this comment anonymously. + :param post_id: The post id number to which you are responding. + :param comment_body: The body of the comment. + :param anonymous: Set to 1 if you want to post this comment + anonymously. """ if post_id and comment_body is not None: params = { @@ -285,7 +290,7 @@ def comment_destroy(self, comment_id): """Remove a specific comment (Requires login). Parameters: - comment_id: The id number of the comment to remove. + :param comment_id: The id number of the comment to remove. """ return self._get('comment/destroy', {'id': comment_id}, 'DELETE') @@ -293,10 +298,10 @@ def wiki_list(self, **params): """Function to retrieves a list of every wiki page. Parameters: - query: A word or phrase to search for (Default: None). - order: Can be: title, date (Default: title). - limit: The number of pages to retrieve (Default: 100). - page: The page number. + :param query: A word or phrase to search for (Default: None). + :param order: Can be: title, date (Default: title). + :param limit: The number of pages to retrieve (Default: 100). + :param page: The page number. """ return self._get('wiki', params) @@ -304,8 +309,8 @@ def wiki_create(self, title, body): """Action to lets you create a wiki page (Requires login) (UNTESTED). Parameters: - title: The title of the wiki page. - body: The body of the wiki page. + :param title: The title of the wiki page. + :param body: The body of the wiki page. """ params = {'wiki_page[title]': title, 'wiki_page[body]': body} return self._get('wiki/create', params, 'POST') @@ -314,9 +319,9 @@ def wiki_update(self, page_title, new_title=None, page_body=None): """Action to lets you update a wiki page (Requires login) (UNTESTED). Parameters: - page_title: The title of the wiki page to update. - new_title: The new title of the wiki page. - page_body: The new body of the wiki page. + :param page_title: The title of the wiki page to update. + :param new_title: The new title of the wiki page. + :param page_body: The new body of the wiki page. """ params = { 'title': page_title, @@ -329,8 +334,8 @@ def wiki_show(self, **params): """Get a specific wiki page. Parameters: - title: The title of the wiki page to retrieve. - version: The version of the page to retrieve. + :param title: The title of the wiki page to retrieve. + :param version: The version of the page to retrieve. """ return self._get('wiki/show', params) @@ -339,7 +344,7 @@ def wiki_destroy(self, title): (Only moderators) (UNTESTED). Parameters: - title: The title of the page to delete. + :param title: The title of the page to delete. """ return self._get('wiki/destroy', {'title': title}, 'DELETE') @@ -348,7 +353,7 @@ def wiki_lock(self, title): (Only moderators) (UNTESTED). Parameters: - title: The title of the page to lock. + :param title: The title of the page to lock. """ return self._get('wiki/lock', {'title': title}, 'POST') @@ -357,7 +362,7 @@ def wiki_unlock(self, title): (Only moderators) (UNTESTED). Parameters: - title: The title of the page to unlock. + :param title: The title of the page to unlock. """ return self._get('wiki/unlock', {'title': title}, 'POST') @@ -365,8 +370,8 @@ def wiki_revert(self, title, version): """Function to revert a specific wiki page (Requires login) (UNTESTED). Parameters: - title: The title of the wiki page to update. - version: The version to revert to. + :param title: The title of the wiki page to update. + :param version: The version to revert to. """ params = {'title': title, 'version': version} return self._get('wiki/revert', params, 'PUT') @@ -375,7 +380,7 @@ def wiki_history(self, title): """Get history of specific wiki page. Parameters: - title: The title of the wiki page to retrieve versions for. + :param title: The title of the wiki page to retrieve versions for. """ return self._get('wiki/history', {'title': title}) @@ -383,7 +388,7 @@ def note_list(self, **params): """Get note list. Parameters: - post_id: The post id number to retrieve notes for. + :param post_id: The post id number to retrieve notes for. """ return self._get('note', params) @@ -391,7 +396,7 @@ def note_search(self, query): """Search specific note. Parameters: - query: A word or phrase to search for. + :param query: A word or phrase to search for. """ return self._get('note/search', {'query': query}) @@ -399,10 +404,10 @@ def note_history(self, **params): """Get history of notes. Parameters: - post_id: The post id number to retrieve note versions for. - id: The note id number to retrieve versions for. - limit: How many versions to retrieve (Default: 10). - page: The note id number to retrieve versions for. + :param post_id: The post id number to retrieve note versions for. + :param id: The note id number to retrieve versions for. + :param limit: How many versions to retrieve (Default: 10). + :param page: The note id number to retrieve versions for. """ return self._get('note/history', params) @@ -410,8 +415,8 @@ def note_revert(self, note_id, version): """Function to revert a specific note (Requires login) (UNTESTED). Parameters: - note_id: The note id to update. - version: The version to revert to. + :param note_id: The note id to update. + :param version: The version to revert to. """ params = {'id': note_id, 'version': version} return self._get('note/revert', params, 'PUT') @@ -422,16 +427,16 @@ def note_create_update(self, post_id=None, coor_x=None, coor_y=None, """Function to create or update note (Requires login) (UNTESTED). Parameters: - post_id: The post id number this note belongs to. - coor_x: The X coordinate of the note. - coor_y: The Y coordinate of the note. - width: The width of the note. - height: The height of the note. - is_active: Whether or not the note is visible. Set to 1 for - active, 0 for inactive. - body: The note message. - note_id: If you are updating a note, this is the note id number to - update. + :param post_id: The post id number this note belongs to. + :param coor_x: The X coordinate of the note. + :param coor_y: The Y coordinate of the note. + :param width: The width of the note. + :param height: The height of the note. + :param is_active: Whether or not the note is visible. Set to 1 for + active, 0 for inactive. + :param body: The note message. + :param note_id: If you are updating a note, this is the note id + number to update. """ params = { 'id': note_id, @@ -451,8 +456,8 @@ def user_search(self, **params): If you don't specify any parameters you'll _get a listing of all users. Parameters: - id: The id number of the user. - name: The name of the user. + :param id: The id number of the user. + :param name: The name of the user. """ return self._get('user', params) @@ -462,8 +467,8 @@ def forum_list(self, **params): If you don't specify any parameters you'll _get a listing of all users. Parameters: - parent_id: The parent ID number. You'll return all the responses - to that forum post. + :param parent_id: The parent ID number. You'll return all the + responses to that forum post. """ return self._get('forum', params) @@ -473,8 +478,8 @@ def pool_list(self, **params): If you don't specify any parameters you'll _get a list of all pools. Parameters: - query: The title. - page: The page. + :param query: The title. + :param page: The page. """ return self._get('pool', params) @@ -484,8 +489,8 @@ def pool_posts(self, **params): If you don't specify any parameters you'll _get a list of all pools. Parameters: - id: The pool id number. - page: The page. + :param id: The pool id number. + :param page: The page. """ return self._get('pool/show', params) @@ -494,10 +499,10 @@ def pool_update(self, pool_id, name=None, is_public=None, """Function to update a pool (Requires login) (UNTESTED). Parameters: - pool_id: The pool id number. - name: The name. - is_public: 1 or 0, whether or not the pool is public. - description: A description of the pool. + :param pool_id: The pool id number. + :param name: The name. + :param is_public: 1 or 0, whether or not the pool is public. + :param description: A description of the pool. """ params = { 'id': pool_id, @@ -511,9 +516,9 @@ def pool_create(self, name, description, is_public): """Function to create a pool (Require login) (UNTESTED). Parameters: - name: The name. - description: A description of the pool. - is_public: 1 or 0, whether or not the pool is public. + :param name: The name. + :param description: A description of the pool. + :param is_public: 1 or 0, whether or not the pool is public. """ params = {'pool[name]': name, 'pool[description]': description, 'pool[is_public]': is_public} @@ -523,7 +528,7 @@ def pool_destroy(self, pool_id): """Function to destroy a specific pool (Require login) (UNTESTED). Parameters: - pool_id: The pool id number. + :param pool_id: The pool id number. """ return self._get('pool/destroy', {'id': pool_id}, 'DELETE') @@ -531,8 +536,8 @@ def pool_add_post(self, **params): """Function to add a post (Require login) (UNTESTED). Parameters: - pool_id: The pool to add the post to. - post_id: The post to add. + :param pool_id: The pool to add the post to. + :param post_id: The post to add. """ return self._get('pool/add_post', params, 'PUT') @@ -540,8 +545,8 @@ def pool_remove_post(self, **params): """Function to remove a post (Require login) (UNTESTED). Parameters: - pool_id: The pool to remove the post to. - post_id: The post to remove. + :param pool_id: The pool to remove the post to. + :param post_id: The post to remove. """ return self._get('pool/remove_post', params, 'PUT') @@ -550,7 +555,7 @@ def favorite_list_users(self, post_id): a specific post. Parameters: - post_id: The post id. + :param post_id: The post id. """ response = self._get('favorite/list_users', {'id': post_id}) # Return list with users diff --git a/tools/preview_documentation.bat b/tools/preview_documentation.bat new file mode 100644 index 0000000..c6fc09d --- /dev/null +++ b/tools/preview_documentation.bat @@ -0,0 +1,7 @@ +@echo off + +cd docs +call .\make.bat html +cd build\html +call python -m http.server 80 +cd ..\..\..\ From b0af7f689269773819b8c21b59f31a022cfbae10 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Dec 2016 21:30:59 +0100 Subject: [PATCH 138/141] Docs: adds pybooru.rst - Update index.rst - Adds pybooru.rst (contains all references for pybooru, exceptions and resources) - Adapt docstrings of pybooru, exceptions and resources to Sphinx --- docs/source/index.rst | 1 + docs/source/pybooru.rst | 29 +++++++++++++++++++++++++++++ pybooru/exceptions.py | 6 +++--- pybooru/pybooru.py | 29 ++++++++++++++++------------- 4 files changed, 49 insertions(+), 16 deletions(-) create mode 100644 docs/source/pybooru.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 9de7be5..5d93f2e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -25,6 +25,7 @@ Dependencies quick_start_guide api_danbooru api_moebooru + pybooru Indices and tables diff --git a/docs/source/pybooru.rst b/docs/source/pybooru.rst new file mode 100644 index 0000000..63f855d --- /dev/null +++ b/docs/source/pybooru.rst @@ -0,0 +1,29 @@ +Pybooru Reference +====================== + +Pybooru +------- + +.. automodule:: pybooru.pybooru + :show-inheritance: + :members: + :private-members: + :special-members: + +Exceptions +---------- + +.. automodule:: pybooru.exceptions + :show-inheritance: + :members: + :private-members: + :special-members: + +Resources +--------- + +.. automodule:: pybooru.resources + :show-inheritance: + :members: + :private-members: + :special-members: diff --git a/pybooru/exceptions.py b/pybooru/exceptions.py index 55984f8..8e7202a 100644 --- a/pybooru/exceptions.py +++ b/pybooru/exceptions.py @@ -29,9 +29,9 @@ def __init__(self, msg, http_code, url): """Initialize PybooruHTTPError. Keyword arguments: - msg: The error message. - http_code: The HTTP status code. - url: The URL. + :param msg: The error message. + :param http_code: The HTTP status code. + :param url: The URL. """ super(PybooruHTTPError, self).__init__(msg, http_code, url) if http_code in HTTP_STATUS_CODE and url is not None: diff --git a/pybooru/pybooru.py b/pybooru/pybooru.py index bc2f3ac..03162e4 100644 --- a/pybooru/pybooru.py +++ b/pybooru/pybooru.py @@ -26,20 +26,20 @@ class _Pybooru(object): """Pybooru main class. Attributes: - site_name: Return site name. - site_url: Return the URL of Moebooru/Danbooru based site. - username: Return user name. - last_call: Return last call. + :var site_name: Return site name. + :var site_url: Return the URL of Moebooru/Danbooru based site. + :var username: Return user name. + :var last_call: Return last call. """ def __init__(self, site_name="", site_url="", username=""): """Initialize Pybooru. Keyword arguments: - site_name: The site name in 'SITE_LIST', default sites. - site_url: URL of on Moebooru/Danbooru based sites. - username: Your username of the site (Required only for functions - that modify the content). + :param site_name: The site name in 'SITE_LIST', default sites. + :param site_url: URL of on Moebooru/Danbooru based sites. + :param username: Your username of the site (Required only for + functions that modify the content). """ # Attributes self.site_name = site_name.lower() @@ -99,7 +99,7 @@ def _url_validator(self): @staticmethod def _get_status(status_code): - """Get status message.""" + """Get status message for status code""" if status_code in HTTP_STATUS_CODE: return "{0}, {1}".format(*HTTP_STATUS_CODE[status_code]) else: @@ -109,10 +109,13 @@ def _request(self, url, api_call, request_args, method='GET'): """Function to request and returning JSON data. Parameters: - url: Base url call. - api_call: API function to be called. - request_args: All requests parameters. - method: (Defauld: GET) HTTP method 'GET' or 'POST' + :param url: Base url call. + :param api_call: API function to be called. + :param request_args: All requests parameters. + :param method: (Defauld: GET) HTTP method 'GET' or 'POST' + + :raises requests.exceptions.Timeout: When HTTP Timeout. + :raises ValueError: When can't decode JSON response. """ try: if method != 'GET': From 6019d84f5816cc93c704fb644921c75e988f001f Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Dec 2016 21:57:12 +0100 Subject: [PATCH 139/141] Docs: adds danbooru.rst and moebooru.rst - Adds danbooru.rst and moebooru.rst - Update index.rst - Adapt docstrings of danbooru and moeboor to sphinx - update quick_start_guide.rst --- docs/source/danbooru.rst | 8 ++++++ docs/source/index.rst | 12 +++------ docs/source/moebooru.rst | 8 ++++++ docs/source/quick_start_guide.rst | 4 +-- pybooru/danbooru.py | 33 ++++++++++++----------- pybooru/exceptions.py | 6 ++--- pybooru/moebooru.py | 44 +++++++++++++++---------------- 7 files changed, 64 insertions(+), 51 deletions(-) create mode 100644 docs/source/danbooru.rst create mode 100644 docs/source/moebooru.rst diff --git a/docs/source/danbooru.rst b/docs/source/danbooru.rst new file mode 100644 index 0000000..fd22c2d --- /dev/null +++ b/docs/source/danbooru.rst @@ -0,0 +1,8 @@ +Danbooru Reference +================== + +.. automodule:: pybooru.danbooru + :show-inheritance: + :members: + :private-members: + :special-members: diff --git a/docs/source/index.rst b/docs/source/index.rst index 5d93f2e..7490973 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,7 +15,7 @@ Welcome to Pybooru's documentation! Dependencies ------------ -- requests +- `requests `_ .. toctree:: @@ -23,14 +23,8 @@ Dependencies :caption: Contents: quick_start_guide + danbooru api_danbooru + moebooru api_moebooru pybooru - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/source/moebooru.rst b/docs/source/moebooru.rst new file mode 100644 index 0000000..cbc4ffb --- /dev/null +++ b/docs/source/moebooru.rst @@ -0,0 +1,8 @@ +Moebooru Reference +================== + +.. automodule:: pybooru.moebooru + :show-inheritance: + :members: + :private-members: + :special-members: diff --git a/docs/source/quick_start_guide.rst b/docs/source/quick_start_guide.rst index e11f93b..5423492 100644 --- a/docs/source/quick_start_guide.rst +++ b/docs/source/quick_start_guide.rst @@ -4,8 +4,8 @@ Quick Start Guide Features -------- -- Support Danbooru API. -- Support Moebooru API. +- Support Danbooru API (version: 2.105.0 - 77e06b6). +- Support Moebooru API (version: 1.13.0+update.3). - Defult site list. - JSON responses. - Custom user-agent. diff --git a/pybooru/danbooru.py b/pybooru/danbooru.py index 167fe97..8e05574 100644 --- a/pybooru/danbooru.py +++ b/pybooru/danbooru.py @@ -30,23 +30,23 @@ class Danbooru(_Pybooru, DanbooruApi_Mixin): log in: 'username' and 'api_key'. Attributes: - site_name: Return site name. - site_url: Return the URL of Moebooru based site. - username: Return user name. - api_key: Return API key. - last_call: Return last call. + :var site_name: Return site name. + :var site_url: Return the URL of Moebooru based site. + :var username: Return user name. + :var api_key: Return API key. + :var last_call: Return last call. """ def __init__(self, site_name="", site_url="", username="", api_key=""): """Initialize Danbooru. Keyword arguments: - site_name: The site name in 'SITE_LIST', default sites. - site_url: URL of on Moebooru based sites. - username: Your username of the site (Required only for functions - that modify the content). - api_key: Your api key of the site (Required only for - functions that modify the content). + :param site_name: The site name in 'SITE_LIST', default sites. + :param site_url: URL of on Moebooru based sites. + :param username: Your username of the site (Required only for + functions that modify the content). + :param api_key: Your api key of the site (Required only for + functions that modify the content). """ super(Danbooru, self).__init__(site_name, site_url, username) @@ -58,10 +58,13 @@ def _get(self, api_call, params=None, method='GET', auth=False, """Function to preapre API call. Parameters: - api_call: API function to be called. - params: API function parameters. - method: (Defauld: GET) HTTP method (GET, POST, PUT or DELETE) - file_: File to upload (only uploads). + :param api_call: API function to be called. + :param params: API function parameters. + :param method: (Defauld: GET) HTTP method (GET, POST, PUT or + DELETE) + :param file_: File to upload (only uploads). + + :raise AttributeError: When 'username' or 'api_key' are not set. """ url = "{0}/{1}".format(self.site_url, api_call) diff --git a/pybooru/exceptions.py b/pybooru/exceptions.py index 8e7202a..c9f03ab 100644 --- a/pybooru/exceptions.py +++ b/pybooru/exceptions.py @@ -5,9 +5,9 @@ This module contains Pybooru exceptions. Classes: - PybooruError -- Main Pybooru exception class. - PybooruHTTPError -- Manages HTTP status errors. - PybooruAPIError -- Manages all API errors. + * PybooruError -- Main Pybooru exception class. + * PybooruHTTPError -- Manages HTTP status errors. + * PybooruAPIError -- Manages all API errors. """ # __furute__ imports diff --git a/pybooru/moebooru.py b/pybooru/moebooru.py index b77cc9f..c040fb3 100644 --- a/pybooru/moebooru.py +++ b/pybooru/moebooru.py @@ -38,13 +38,13 @@ class Moebooru(_Pybooru, MoebooruApi_Mixin): associate hash string. Attributes: - site_name: Return site name. - site_url: Return the URL of Moebooru based site. - api_version: Version of Moebooru API. - username: Return user name. - password: Return password in plain text. - hash_string: Return hash_string of the site. - last_call: Return last call. + :var site_name: Return site name. + :var site_url: Return the URL of Moebooru based site. + :var api_version: Version of Moebooru API. + :var username: Return user name. + :var password: Return password in plain text. + :var hash_string: Return hash_string of the site. + :var last_call: Return last call. """ def __init__(self, site_name="", site_url="", username="", password="", @@ -52,16 +52,16 @@ def __init__(self, site_name="", site_url="", username="", password="", """Initialize Moebooru. Keyword arguments: - site_name: The site name in 'SITE_LIST', default sites. - site_url: URL of on Moebooru based sites. - api_version: Version of Moebooru API. - hash_string: String that is hashed (required to login). - (See the API documentation of the site for more - information). - username: Your username of the site (Required only for functions - that modify the content). - password: Your user password in plain text (Required only for - functions that modify the content). + :param site_name: The site name in 'SITE_LIST', default sites. + :param site_url: URL of on Moebooru based sites. + :param api_version: Version of Moebooru API. + :param hash_string: String that is hashed (required to login). + (See the API documentation of the site for more + information). + :param username: Your username of the site (Required only for + functions that modify the content). + :param password: Your user password in plain text (Required only + for functions that modify the content). """ super(Moebooru, self).__init__(site_name, site_url, username) @@ -74,7 +74,7 @@ def _build_url(self, api_call): """Build request url. Parameters: - api_call: Base API Call. + :param api_call: Base API Call. """ if self.api_version in ('1.13.0', '1.13.0+update.1', '1.13.0+update.2'): if '/' not in api_call: @@ -108,10 +108,10 @@ def _get(self, api_call, params, method='GET', file_=None): """Function to preapre API call. Parameters: - api_call: API function to be called. - params: API function parameters. - method: (Defauld: GET) HTTP method 'GET' or 'POST' - file_: File to upload. + :param api_call: API function to be called. + :param params: API function parameters. + :param method: (Defauld: GET) HTTP method 'GET' or 'POST' + :param file_: File to upload. """ url = self._build_url(api_call) From 3219001cf5af2148fdb91537044a9f8dccf23b7e Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Thu, 8 Dec 2016 22:04:44 +0100 Subject: [PATCH 140/141] Docs: update index.rst Adds license and changelog. --- docs/source/index.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index 7490973..01c9182 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -9,7 +9,7 @@ Welcome to Pybooru's documentation! **Pybooru** is a Python package to access to the API of Danbooru/Moebooru based sites. - Version: **4.0.0** -- Licensed under: **MIT License** +- Licensed under: `MIT License `_ - Python: >= 2.6 or Python: >= 3.3 Dependencies @@ -28,3 +28,8 @@ Dependencies moebooru api_moebooru pybooru + +Changelog +--------- + +`Changelog `_ From c81cc94bee1d1bcbcea798dee734e94b7d0b2ab9 Mon Sep 17 00:00:00 2001 From: Daniel Luque Date: Fri, 9 Dec 2016 12:03:58 +0100 Subject: [PATCH 141/141] Update changelog.md Adds new version 4.0.0 --- LICENSE | 2 +- README.md | 8 +++++++- README.rst | 4 ++++ changelog.md | 15 +++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 66f504b..86ae240 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2012 - 2015 - Daniel Luque +Copyright (c) 2012 - 2016 - Daniel Luque Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.md b/README.md index 98cd327..45ca0ac 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # Pybooru - Package for Danbooru/Moebooru API. -[![Build Status](https://travis-ci.org/LuqueDaniel/pybooru.svg?branch=master)](https://travis-ci.org/LuqueDaniel/pybooru) [![PyPI](https://img.shields.io/pypi/status/Pybooru.svg?style=flat-square)](https://pypi.python.org/pypi/Pybooru/) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/LuqueDaniel/pybooru/master/LICENSE) +[![PyPI](https://img.shields.io/pypi/v/Pybooru.svg?style=flat-square)](https://pypi.python.org/pypi/Pybooru/) +[![Build Status](https://travis-ci.org/LuqueDaniel/pybooru.svg?branch=master)](https://travis-ci.org/LuqueDaniel/pybooru) [![PyPI](https://img.shields.io/pypi/status/Pybooru.svg?style=flat-square)](https://pypi.python.org/pypi/Pybooru/) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/LuqueDaniel/pybooru/master/LICENSE) +[![Documentation Status](https://readthedocs.org/projects/pybooru/badge/?version=stable)](http://pybooru.readthedocs.io/en/stable/?badge=stable) **Pybooru** is a Python package to access to the API of Danbooru/Moebooru based sites. @@ -79,6 +82,9 @@ client = Moebooru('konachan.com', username='your-username', password='your-passw client.comment_create(post_id=id, comment_body='Comment content') ``` +## Documentation +You can consult the documentation on **[Read the Docs](http://pybooru.readthedocs.io/en/stable/)** + ## CI Report - https://travis-ci.org/LuqueDaniel/pybooru diff --git a/README.rst b/README.rst index df11195..6436784 100644 --- a/README.rst +++ b/README.rst @@ -23,6 +23,10 @@ Examples of use See more examples of `Danbooru `_ and `Moebooru `_. +Documentation +------------- +You can consult the documentation on `Read the Docs `_ + Changelog --------- - https://github.com/LuqueDaniel/pybooru/blob/master/changelog.md diff --git a/changelog.md b/changelog.md index 4b9611b..2c2f7bc 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,20 @@ # Pybooru - Changelog +## Pybooru 4.0.0 - (12/09/2016) +- Added support to Danbooru. +- Now Danbooru and Moebooru are two separed classes. +- Pybooru has been refactored. +- Moebooru (only): added support for API versioning. +- Added PybooruAPIError exception. +- Added **last_call** attribute to Danbooru and Moebooru to store last request information. +- Examples has been updated. +- Added **[documentation](http://pybooru.readthedocs.io/en/stable/)** to Pybooru (with Sphinx). +- Added some tools for Pybooru (tools folder) +- Refactored setup.py. +- End of Python 3.2.x support. +- Fixed parameter comparison (python 2.X only) +- In this version there's a nice amount of improvements. + ## Pybooru 3.0.1 - (01/13/2015) - Minors changes