diff --git a/.gitignore b/.gitignore
index 162fc7155..fb3961a90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,8 @@
-tags
-.coverage
-*.pyc
*~
+*.egg
+*.pyc
+.coverage
+*.egg-info/
_build/
build/
dist/
-reddit.egg-info/
diff --git a/MANIFEST.in b/MANIFEST.in
index 509fe7043..7bad66981 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,2 @@
include COPYING
-include reddit/*.cfg
+include praw/praw.ini
diff --git a/deploy.sh b/deploy.sh
index 5902e1310..3f94dac0c 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -12,7 +12,7 @@ if [ $lines -ne 2 ]; then
exit 1
fi
-version=$(python -c "import reddit; print reddit.__version__")
+version=$(python -c "import praw; print praw.__version__")
read -p "Do you want to deploy $version? [y/n] " input
case $input in
diff --git a/lint.sh b/lint.sh
index e58431c0f..6a9b40ff4 100755
--- a/lint.sh
+++ b/lint.sh
@@ -3,7 +3,7 @@
dir=$(dirname $0)
# pep8
-output=$(find $dir/reddit -name [A-Za-z_]\*.py -exec pep8 {} \;)
+output=$(find $dir/praw -name [A-Za-z_]\*.py -exec pep8 {} \;)
if [ -n "$output" ]; then
echo "---pep8---"
echo -e "$output"
@@ -11,13 +11,13 @@ if [ -n "$output" ]; then
fi
# pylint
-output=$(pylint --rcfile=$dir/.pylintrc $dir/reddit 2> /dev/null)
+output=$(pylint --rcfile=$dir/.pylintrc $dir/praw 2> /dev/null)
if [ -n "$output" ]; then
echo "--pylint--"
echo -e "$output"
fi
echo "---pyflakes---"
-find $dir/reddit -name [A-Za-z_]\*.py -exec pyflakes {} \;
+find $dir/praw -name [A-Za-z_]\*.py -exec pyflakes {} \;
exit 0
\ No newline at end of file
diff --git a/praw/__init__.py b/praw/__init__.py
index 0f4ec5bb2..969e41d40 100644
--- a/praw/__init__.py
+++ b/praw/__init__.py
@@ -1,19 +1,18 @@
-# This file is part of reddit_api.
+# This file is part of PRAW.
#
-# reddit_api is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# PRAW is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
#
-# reddit_api is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# PRAW is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with reddit_api. If not, see .
+# You should have received a copy of the GNU General Public License along with
+# PRAW. If not, see .
-import reddit.backport # pylint: disable-msg=W0611
+from . import backport # pylint: disable-msg=W0611
from six.moves import (HTTPCookieProcessor, HTTPError, build_opener,
http_cookiejar, http_client, urljoin)
@@ -22,15 +21,15 @@
import platform
import six
import sys
-import warnings
+from warnings import warn_explicit
-import reddit.decorators
-import reddit.errors
-import reddit.helpers
-import reddit.objects
-from reddit.settings import CONFIG
+from . import decorators
+from . import errors
+from . import helpers
+from . import objects
+from .settings import CONFIG
-__version__ = '1.4.0'
+__version__ = '1.0dev'
UA_STRING = '%%s PRAW/%s Python/%s %s' % (__version__,
sys.version.split()[0],
platform.platform(True))
@@ -103,16 +102,16 @@ def __init__(self, site_name):
else:
self._ssl_url = None
self.api_request_delay = float(obj['api_request_delay'])
- self.by_kind = {obj['comment_kind']: reddit.objects.Comment,
- obj['message_kind']: reddit.objects.Message,
- obj['redditor_kind']: reddit.objects.Redditor,
- obj['submission_kind']: reddit.objects.Submission,
- obj['subreddit_kind']: reddit.objects.Subreddit,
- 'more': reddit.objects.MoreComments,
- 'UserList': reddit.objects.UserList}
+ self.by_kind = {obj['comment_kind']: objects.Comment,
+ obj['message_kind']: objects.Message,
+ obj['redditor_kind']: objects.Redditor,
+ obj['submission_kind']: objects.Submission,
+ obj['subreddit_kind']: objects.Subreddit,
+ 'more': objects.MoreComments,
+ 'UserList': objects.UserList}
self.by_object = dict((value, key) for (key, value) in
six.iteritems(self.by_kind))
- self.by_object[reddit.objects.LoggedInRedditor] = obj['redditor_kind']
+ self.by_object[objects.LoggedInRedditor] = obj['redditor_kind']
self.cache_timeout = float(obj['cache_timeout'])
self.comment_limit = int(obj['comment_limit'])
self.comment_sort = obj['comment_sort']
@@ -142,7 +141,7 @@ def short_domain(self):
if self._short_domain:
return self._short_domain
else:
- raise reddit.errors.ClientException('No short domain specified.')
+ raise errors.ClientException('No short domain specified.')
class BaseReddit(object):
@@ -186,8 +185,8 @@ def _request(self, page_url, params=None, url_data=None, timeout=None):
remaining_attempts = 3
while True:
try:
- return reddit.helpers._request(self, page_url, params,
- url_data, timeout)
+ return helpers._request(self, page_url, params,
+ url_data, timeout)
except HTTPError as error:
remaining_attempts -= 1
if (error.code not in self.RETRY_CODES or
@@ -208,8 +207,8 @@ def _json_reddit_objecter(self, json_data):
except KeyError:
if 'json' in json_data:
if len(json_data) != 1:
- warnings.warn_explicit('Unknown object type: %s' %
- json_data, UserWarning, '', 0)
+ warn_explicit('Unknown object type: %s' %
+ json_data, UserWarning, '', 0)
return json_data['json']
else:
return object_class.from_api_response(self, json_data['data'])
@@ -218,7 +217,7 @@ def _json_reddit_objecter(self, json_data):
def get_content(self, page_url, limit=0, url_data=None, place_holder=None,
root_field='data', thing_field='children',
after_field='after'):
- """A generator method to return Reddit content from a URL. Starts at
+ """A generator method to return reddit content from a URL. Starts at
the initial page_url, and fetches content using the `after` JSON data
until `limit` entries have been fetched, or the `place_holder` has been
reached.
@@ -239,9 +238,9 @@ def get_content(self, page_url, limit=0, url_data=None, place_holder=None,
contains the list of things. Most objects use 'children'.
:param after_field: indicates the field which holds the after item
element
- :type place_holder: a string corresponding to a Reddit content id, e.g.
+ :type place_holder: a string corresponding to a reddit content id, e.g.
't3_asdfasdf'
- :returns: a list of Reddit content, of type Subreddit, Comment,
+ :returns: a list of reddit content, of type Subreddit, Comment,
Submission or user flair.
"""
content_found = 0
@@ -276,7 +275,7 @@ def get_content(self, page_url, limit=0, url_data=None, place_holder=None,
else:
return
- @reddit.decorators.parse_api_json_response
+ @decorators.parse_api_json_response
def request_json(self, page_url, params=None, url_data=None,
as_objects=True):
"""Gets the JSON processed from a page. Takes the same parameters as
@@ -286,7 +285,7 @@ def request_json(self, page_url, params=None, url_data=None,
:param page_url
:param params
:param url_data
- :param as_objects: Whether to return constructed Reddit objects or the
+ :param as_objects: Whether to return constructed reddit objects or the
raw json dict.
:returns: JSON processed page
"""
@@ -303,7 +302,7 @@ class SubredditExtension(BaseReddit):
def __init__(self, *args, **kwargs):
super(SubredditExtension, self).__init__(*args, **kwargs)
- @reddit.decorators.require_login
+ @decorators.require_login
def _subscribe(self, sr_id=None, sr_name=None, unsubscribe=False):
"""Perform the (un)subscribe to the given subreddit.
@@ -320,11 +319,11 @@ def _subscribe(self, sr_id=None, sr_name=None, unsubscribe=False):
response = self.request_json(self.config['subscribe'], params)
# pylint: disable-msg=E1101,W0212
- reddit.helpers._request.evict([self.config['my_reddits']])
+ helpers._request.evict([self.config['my_reddits']])
return response
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def add_flair_template(self, subreddit, text='', css_class='',
text_editable=False, is_link=False):
"""Adds a flair template to the given subreddit."""
@@ -335,16 +334,16 @@ def add_flair_template(self, subreddit, text='', css_class='',
'flair_type': 'LINK_FLAIR' if is_link else 'USER_FLAIR'}
return self.request_json(self.config['flairtemplate'], params)
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def clear_flair_templates(self, subreddit, is_link=False):
"""Clear flair templates for the given subreddit."""
params = {'r': six.text_type(subreddit),
'flair_type': 'LINK_FLAIR' if is_link else 'USER_FLAIR'}
return self.request_json(self.config['clearflairtemplates'], params)
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def flair_list(self, subreddit, limit=None):
"""Get flair list for the given subreddit.
@@ -355,29 +354,29 @@ def flair_list(self, subreddit, limit=None):
limit=limit, root_field=None,
thing_field='users', after_field='next')
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def get_banned(self, subreddit):
"""Get the list of banned users for the given subreddit."""
return self.request_json(self.config['banned'] %
six.text_type(subreddit))
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def get_settings(self, subreddit):
"""Get the settings for the given subreddit."""
return self.request_json(self.config['subreddit_settings'] %
six.text_type(subreddit))['data']
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def get_contributors(self, subreddit):
"""Get the list of contributors for the given subreddit."""
return self.request_json(self.config['contributors'] %
six.text_type(subreddit))
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def get_flair(self, subreddit, redditor):
"""Gets the flair for a user on the given subreddit."""
url_data = {'name': six.text_type(redditor)}
@@ -385,44 +384,44 @@ def get_flair(self, subreddit, redditor):
six.text_type(subreddit), url_data=url_data)
return data['users'][0]
- @reddit.decorators.require_login
+ @decorators.require_login
def get_moderators(self, subreddit):
"""Get the list of moderators for the given subreddit."""
return self.request_json(self.config['moderators'] %
six.text_type(subreddit))
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def get_modqueue(self, subreddit='mod', limit=None):
"""Get the mod-queue for the given subreddit."""
return self.get_content(self.config['modqueue'] %
six.text_type(subreddit),
limit=limit)
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def get_reports(self, subreddit='mod', limit=None):
"""Get the list of reported submissions for the given subreddit."""
return self.get_content(self.config['reports'] %
six.text_type(subreddit),
limit=limit)
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def get_spam(self, subreddit='mod', limit=None):
"""Get the list of spam-filtered items for the given subreddit."""
return self.get_content(self.config['spam'] % six.text_type(subreddit),
limit=limit)
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def get_stylesheet(self, subreddit):
"""Get the stylesheet and associated images for the given subreddit."""
return self.request_json(self.config['stylesheet'] %
six.text_type(subreddit))['data']
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def set_flair(self, subreddit, item, flair_text='', flair_css_class=''):
"""Set flair for the user in the given subreddit.
@@ -432,7 +431,7 @@ def set_flair(self, subreddit, item, flair_text='', flair_css_class=''):
params = {'r': six.text_type(subreddit),
'text': flair_text or '',
'css_class': flair_css_class or ''}
- if isinstance(item, reddit.objects.Submission):
+ if isinstance(item, objects.Submission):
params['link'] = item.content_id
evict = item.permalink
else:
@@ -440,11 +439,11 @@ def set_flair(self, subreddit, item, flair_text='', flair_css_class=''):
evict = self.config['flairlist'] % six.text_type(subreddit)
response = self.request_json(self.config['flair'], params)
# pylint: disable-msg=E1101,W0212
- reddit.helpers._request.evict([evict])
+ helpers._request.evict([evict])
return response
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def set_flair_csv(self, subreddit, flair_mapping):
"""Set flair for a group of users in the given subreddit.
@@ -454,13 +453,13 @@ def set_flair_csv(self, subreddit, flair_mapping):
flair_css_class: the flair css class for the user (optional)
"""
if not flair_mapping:
- raise reddit.errors.ClientException('flair_mapping must be set')
+ raise errors.ClientException('flair_mapping must be set')
item_order = ['user', 'flair_text', 'flair_css_class']
lines = []
for mapping in flair_mapping:
if 'user' not in mapping:
- raise reddit.errors.ClientException('flair_mapping must '
- 'contain `user` key')
+ raise errors.ClientException('flair_mapping must '
+ 'contain `user` key')
lines.append(','.join([mapping.get(x, '') for x in item_order]))
response = []
while len(lines):
@@ -470,11 +469,11 @@ def set_flair_csv(self, subreddit, flair_mapping):
lines = lines[100:]
stale_url = self.config['flairlist'] % six.text_type(subreddit)
# pylint: disable-msg=E1101,W0212
- reddit.helpers._request.evict([stale_url])
+ helpers._request.evict([stale_url])
return response
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def set_settings(self, subreddit, title, public_description='',
description='', language='en', subreddit_type='public',
content_options='any', over_18=False, default_set=True,
@@ -500,12 +499,12 @@ def bool_str(item):
'domain_sidebar': bool_str(domain_sidebar),
'header-title': header_hover_text or ''}
# pylint: disable-msg=E1101,W0212
- reddit.helpers._request.evict([self.config['subreddit_settings'] %
- six.text_type(subreddit)])
+ helpers._request.evict([self.config['subreddit_settings'] %
+ six.text_type(subreddit)])
return self.request_json(self.config['site_admin'], params)
- @reddit.decorators.require_login
- @reddit.decorators.require_moderator
+ @decorators.require_login
+ @decorators.require_moderator
def set_stylesheet(self, subreddit, stylesheet):
"""Set stylesheet for the given subreddit."""
params = {'r': six.text_type(subreddit),
@@ -513,8 +512,8 @@ def set_stylesheet(self, subreddit, stylesheet):
'op': 'save'} # Options: save / preview
return self.request_json(self.config['subreddit_css'], params)
- @reddit.decorators.require_login
- @reddit.decorators.RequireCaptcha
+ @decorators.require_login
+ @decorators.RequireCaptcha
def submit(self, subreddit, title, text=None, url=None, captcha=None):
"""
Submit a new link to the given subreddit.
@@ -562,28 +561,27 @@ class LoggedInExtension(BaseReddit):
def __init__(self, *args, **kwargs):
super(LoggedInExtension, self).__init__(*args, **kwargs)
- @reddit.decorators.require_login
+ @decorators.require_login
def _add_comment(self, thing_id, text):
"""Comment on the given thing with the given text."""
params = {'thing_id': thing_id,
'text': text}
data = self.request_json(self.config['comment'], params)
- # REDDIT: Reddit's end should only ever return a single comment
+ # REDDIT: reddit's end should only ever return a single comment
return data['data']['things'][0]
- @reddit.decorators.require_login
+ @decorators.require_login
def _mark_as_read(self, thing_ids, unread=False):
""" Marks each of the supplied thing_ids as (un)read."""
params = {'id': ','.join(thing_ids)}
key = 'unread_message' if unread else 'read_message'
response = self.request_json(self.config[key], params)
urls = [self.config[x] for x in ['inbox', 'moderator', 'unread']]
- # pylint: disable-msg=E1101,W0212
- reddit.helpers._request.evict(urls)
+ helpers._request.evict(urls) # pylint: disable-msg=E1101,W0212
return response
- @reddit.decorators.require_login
- @reddit.decorators.RequireCaptcha
+ @decorators.require_login
+ @decorators.RequireCaptcha
def compose_message(self, recipient, subject, message, captcha=None):
"""Send a message to another redditor or a subreddit.
@@ -591,7 +589,7 @@ def compose_message(self, recipient, subject, message, captcha=None):
either be a subreddit object or the subreddit name needs to be prefixed
with either '/r/' or '#'.
"""
- if isinstance(recipient, reddit.objects.Subreddit):
+ if isinstance(recipient, objects.Subreddit):
recipient = '/r/%s' % six.text_type(recipient)
else:
recipient = six.text_type(recipient)
@@ -603,10 +601,10 @@ def compose_message(self, recipient, subject, message, captcha=None):
params.update(captcha)
response = self.request_json(self.config['compose'], params)
# pylint: disable-msg=E1101,W0212
- reddit.helpers._request.evict([self.config['sent']])
+ helpers._request.evict([self.config['sent']])
return response
- @reddit.decorators.require_login
+ @decorators.require_login
def create_subreddit(self, name, title, description='', language='en',
subreddit_type='public', content_options='any',
over_18=False, default_set=True, show_media=False,
@@ -625,16 +623,16 @@ def create_subreddit(self, name, title, description='', language='en',
return self.request_json(self.config['site_admin'], params)
def get_redditor(self, user_name, *args, **kwargs):
- """Returns a Redditor class for the user_name specified."""
- return reddit.objects.Redditor(self, user_name, *args, **kwargs)
+ """Returns a Redditor instance for the user_name specified."""
+ return objects.Redditor(self, user_name, *args, **kwargs)
- @reddit.decorators.require_login
+ @decorators.require_login
def get_saved_links(self, limit=0):
"""Return a listing of the logged-in user's saved links."""
return self.get_content(self.config['saved'], limit=limit)
def login(self, username=None, password=None):
- """Login to Reddit.
+ """Login to a reddit site.
If no user or password is provided, the settings file will be checked,
and finally the user will be prompted with raw_input and
@@ -661,7 +659,7 @@ def login(self, username=None, password=None):
response = self.request_json(self.config['login'] % user, params)
self.modhash = response['data']['modhash']
self.user = self.get_redditor(user)
- self.user.__class__ = reddit.objects.LoggedInRedditor
+ self.user.__class__ = objects.LoggedInRedditor
class Reddit(LoggedInExtension, # pylint: disable-msg=R0904
@@ -669,7 +667,7 @@ class Reddit(LoggedInExtension, # pylint: disable-msg=R0904
def __init__(self, *args, **kwargs):
super(Reddit, self).__init__(*args, **kwargs)
- @reddit.decorators.RequireCaptcha
+ @decorators.RequireCaptcha
def create_redditor(self, user_name, password, email='', captcha=None):
"""Register a new user."""
params = {'email': email,
@@ -696,11 +694,11 @@ def get_submission(self, url=None, submission_id=None):
raise TypeError('One (and only one) of id or url is required!')
if submission_id:
url = urljoin(self.config['comments'], submission_id)
- return reddit.objects.Submission.get_info(self, url)
+ return objects.Submission.get_info(self, url)
def get_subreddit(self, subreddit_name, *args, **kwargs):
"""Returns a Subreddit object for the subreddit_name specified."""
- return reddit.objects.Subreddit(self, subreddit_name, *args, **kwargs)
+ return objects.Subreddit(self, subreddit_name, *args, **kwargs)
def info(self, url=None, thing_id=None, limit=0):
"""
@@ -718,7 +716,7 @@ def info(self, url=None, thing_id=None, limit=0):
msg = ('It looks like you may be trying to get the info of a '
'self or internal link. This probably will not return '
'any useful results!')
- warnings.warn_explicit(msg, UserWarning, '', 0)
+ warn_explicit(msg, UserWarning, '', 0)
else:
url_data = {'id': thing_id}
return self.get_content(self.config['info'], url_data=url_data,
@@ -743,7 +741,7 @@ def search_reddit_names(self, query):
results = self.request_json(self.config['search_reddit_names'], params)
return [self.get_subreddit(name) for name in results['names']]
- @reddit.decorators.RequireCaptcha
+ @decorators.RequireCaptcha
def send_feedback(self, name, email, message, reason='feedback',
captcha=None):
"""
diff --git a/praw/backport.py b/praw/backport.py
index 080f27fdc..793ba9236 100644
--- a/praw/backport.py
+++ b/praw/backport.py
@@ -1,17 +1,16 @@
-# This file is part of reddit_api.
+# This file is part of PRAW.
#
-# reddit_api is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# PRAW is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
#
-# reddit_api is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# PRAW is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with reddit_api. If not, see .
+# You should have received a copy of the GNU General Public License along with
+# PRAW. If not, see .
from six import MovedAttribute, add_move
diff --git a/praw/decorators.py b/praw/decorators.py
index 657be682b..ddfe71c2b 100644
--- a/praw/decorators.py
+++ b/praw/decorators.py
@@ -1,19 +1,18 @@
-# This file is part of reddit_api.
+# This file is part of PRAW.
#
-# reddit_api is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# PRAW is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
#
-# reddit_api is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# PRAW is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with reddit_api. If not, see .
+# You should have received a copy of the GNU General Public License along with
+# PRAW. If not, see .
-import reddit.backport # pylint: disable-msg=W0611
+from . import backport # pylint: disable-msg=W0611
import six
import sys
@@ -22,7 +21,7 @@
from functools import wraps
from six.moves import urljoin
-from reddit import errors
+from . import errors
class Memoize(object):
@@ -153,9 +152,9 @@ def function_wrapper(self, *args, **kwargs):
def parse_api_json_response(function): # pylint: disable-msg=R0912
- """Decorator to look at the Reddit API response to an API POST request like
- vote, subscribe, login, etc. Basically, it just looks for certain errors in
- the return string. If it doesn't find one, then it just returns True.
+ """Decorator to look at the response to an API POST request like vote,
+ subscribe, login, etc. Basically, it just looks for certain errors in the
+ return string. If it doesn't find one, then it just returns True.
"""
@wraps(function)
def error_checked_function(self, *args, **kwargs):
@@ -229,5 +228,5 @@ def moderator_required_function(self, subreddit, *args, **kwargs):
# Avoid circular import: http://effbot.org/zone/import-confusion.htm
-from reddit.objects import RedditContentObject
-from reddit.helpers import _request
+from .objects import RedditContentObject
+from .helpers import _request
diff --git a/praw/errors.py b/praw/errors.py
index 50dc4f4c8..a2ac9ae45 100644
--- a/praw/errors.py
+++ b/praw/errors.py
@@ -1,17 +1,16 @@
-# This file is part of reddit_api.
+# This file is part of PRAW.
#
-# reddit_api is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# PRAW is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
#
-# reddit_api is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# PRAW is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with reddit_api. If not, see .
+# You should have received a copy of the GNU General Public License along with
+# PRAW. If not, see .
import inspect
import six
diff --git a/praw/helpers.py b/praw/helpers.py
index 60d3d41c3..87e7dbe80 100644
--- a/praw/helpers.py
+++ b/praw/helpers.py
@@ -1,22 +1,22 @@
-# This file is part of reddit_api.
+# This file is part of PRAW.
#
-# reddit_api is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# PRAW is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
#
-# reddit_api is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# PRAW is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with reddit_api. If not, see .
+# You should have received a copy of the GNU General Public License along with
+# PRAW. If not, see .
+
+from . import backport # pylint: disable-msg=W0611
-import reddit.backport # pylint: disable-msg=W0611
import six
from six.moves import Request, quote, urlencode, urljoin
-from reddit.decorators import Memoize, SleepAfter, require_login
+from .decorators import Memoize, SleepAfter, require_login
def _get_section(subpath=''):
@@ -38,8 +38,7 @@ def _section(self, sort='new', time='all', *args, **kw):
def _get_sorter(subpath='', **defaults):
"""
- Used by the Reddit Page classes to generate each of the currently supported
- sorts (hot, top, new, best).
+ Used to generate the various Submission listings.
"""
def _sorted(self, *args, **kw):
if 'url_data' in kw and kw['url_data']:
diff --git a/praw/objects.py b/praw/objects.py
index 200d2ac61..b1c640368 100644
--- a/praw/objects.py
+++ b/praw/objects.py
@@ -1,28 +1,27 @@
-# This file is part of reddit_api.
+# This file is part of PRAW.
#
-# reddit_api is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# PRAW is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
#
-# reddit_api is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# PRAW is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with reddit_api. If not, see .
+# You should have received a copy of the GNU General Public License along with
+# PRAW. If not, see .
-import reddit.backport # pylint: disable-msg=W0611
+from . import backport # pylint: disable-msg=W0611
import six
import warnings
from six.moves import urljoin
-from reddit.decorators import limit_chars, require_login
-from reddit.errors import ClientException
-from reddit.helpers import (_get_section, _get_sorter, _modify_relationship,
- _request)
+from .decorators import limit_chars, require_login
+from .errors import ClientException
+from .helpers import (_get_section, _get_sorter, _modify_relationship,
+ _request)
REDDITOR_KEYS = ('approved_by', 'author', 'banned_by', 'redditor')
@@ -165,7 +164,7 @@ def edit(self, text):
response = self.reddit_session.request_json(url, params)
# pylint: disable-msg=E1101
_request.evict([self.reddit_session.config['user']])
- # REDDIT: Reddit's end should only ever return a single comment
+ # REDDIT: reddit's end should only ever return a single comment
return response['data']['things'][0]
@@ -193,13 +192,13 @@ def reply(self, text):
class Messageable(RedditContentObject):
- """Interface for Reddit content objects that can be messaged."""
+ """Interface for RedditContentObjects that can be messaged."""
def compose_message(self, subject, message):
return self.reddit_session.compose_message(self, subject, message)
class Reportable(RedditContentObject):
- """Interface for Reddit content objects that can be reported."""
+ """Interface for RedditContentObjects that can be reported."""
@require_login
def report(self):
url = self.reddit_session.config['report']
@@ -211,7 +210,7 @@ def report(self):
class Saveable(RedditContentObject):
- """Interface for Reddit content objects that can be saved."""
+ """Interface for RedditContentObjects that can be saved."""
@require_login
def save(self, unsave=False):
"""If logged in, save the content."""
@@ -228,7 +227,7 @@ def unsave(self):
class Voteable(RedditContentObject):
- """Interface for Reddit content objects that can be voted on."""
+ """Interface for RedditContentObjects that can be voted on."""
def clear_vote(self):
return self.vote()
@@ -354,7 +353,7 @@ def comments(self, update=True):
class Redditor(Messageable):
- """A class for Redditor methods."""
+ """A class representing the users of reddit."""
get_overview = _get_section('')
get_comments = _get_section('comments')
get_submitted = _get_section('submitted')
@@ -403,7 +402,7 @@ def unfriend(self):
class LoggedInRedditor(Redditor):
- """A class for a currently logged in redditor"""
+ """A class for a currently logged in Redditor"""
@require_login
def get_inbox(self, limit=0):
"""Return a generator for inbox messages."""
@@ -443,7 +442,7 @@ def my_reddits(self, limit=0):
class Submission(Approvable, Deletable, Distinguishable, Editable, Reportable,
Saveable, Voteable):
- """A class for submissions to Reddit."""
+ """A class for submissions to reddit."""
@staticmethod
def get_info(reddit_session, url, comments_only=False):
url_data = {}
@@ -771,7 +770,7 @@ class UserList(RedditContentObject):
def __init__(self, reddit_session, json_dict=None, fetch=False):
super(UserList, self).__init__(reddit_session, json_dict, fetch)
- # HACK: Convert children to RedditorObjects
+ # HACK: Convert children to Redditor instances
for i in range(len(self.children)):
tmp = self.children[i]
redditor = Redditor(reddit_session, tmp['name'], fetch=False)
diff --git a/praw/settings.py b/praw/settings.py
index 39dba8b51..98fcf6658 100644
--- a/praw/settings.py
+++ b/praw/settings.py
@@ -1,23 +1,23 @@
-# This file is part of reddit_api.
+# This file is part of PRAW.
#
-# reddit_api is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# PRAW is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
#
-# reddit_api is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# PRAW is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with reddit_api. If not, see .
+# You should have received a copy of the GNU General Public License along with
+# PRAW. If not, see .
-import reddit.backport # pylint: disable-msg=W0611
+from . import backport # pylint: disable-msg=W0611
import os
import sys
from six.moves import configparser
+from warnings import warn_explicit
def _load_configuration():
@@ -29,9 +29,9 @@ def _load_configuration():
os_config_path = os.environ['XDG_CONFIG_HOME']
else: # Legacy Linux
os_config_path = os.path.join(os.environ['HOME'], '.config')
- locations = [os.path.join(module_dir, 'reddit_api.cfg'),
- os.path.join(os_config_path, 'reddit_api', 'reddit_api.cfg'),
- 'reddit_api.cfg']
+ locations = [os.path.join(module_dir, 'praw.ini'),
+ os.path.join(os_config_path, 'praw.ini'),
+ 'praw.ini']
if not config.read(locations):
raise Exception('Could not find config file in any of: %s' % locations)
return config
diff --git a/praw/tests.py b/praw/tests.py
index e4fde4e5b..721877558 100755
--- a/praw/tests.py
+++ b/praw/tests.py
@@ -1,24 +1,23 @@
#!/usr/bin/env python
-# This file is part of reddit_api.
+# This file is part of PRAW.
#
-# reddit_api is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# PRAW is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
#
-# reddit_api is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# PRAW is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License
-# along with reddit_api. If not, see .
+# You should have received a copy of the GNU General Public License along with
+# PRAW. If not, see .
# pylint: disable-msg=C0103, R0903, R0904, W0201
from __future__ import unicode_literals
-import reddit.backport # pylint: disable-msg=W0611
+from . import backport # pylint: disable-msg=W0611
import random
import unittest
@@ -27,8 +26,8 @@
from six import advance_iterator as six_next, text_type
from six.moves import HTTPError, URLError, urljoin
-from reddit import Reddit, errors, helpers
-from reddit.objects import Comment, LoggedInRedditor, Message, MoreComments
+from . import Reddit, errors, helpers
+from .objects import Comment, LoggedInRedditor, Message, MoreComments
USER_AGENT = 'PRAW_test_suite'
diff --git a/setup.py b/setup.py
index 28638253a..f9743a8e5 100644
--- a/setup.py
+++ b/setup.py
@@ -1,25 +1,30 @@
-import re
+import os, re
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
+PACKAGE_NAME = 'praw'
-version = re.search("__version__ = '([^']+)'",
- open('reddit/__init__.py').read()).group(1)
+HERE = os.path.abspath(os.path.dirname(__file__))
+INIT = open(os.path.join(HERE, PACKAGE_NAME, '__init__.py')).read()
+README = open(os.path.join(HERE, 'README.md')).read()
+
+VERSION = re.search("__version__ = '([^']+)'", INIT).group(1)
setup(
- name='reddit',
- version=version,
+ name=PACKAGE_NAME,
+ version=VERSION,
author='Timothy Mellor',
author_email='timothy.mellor+pip@gmail.com',
maintainer='Bryce Boe',
maintainer_email='bbzbryce@gmail.com',
- url='https://github.com/mellort/reddit_api',
- description='A wrapper for the Reddit API',
- long_description=('Please see the `documentation on github '
- '`_.'),
+ url='http://python-reddit-api-wrapper.readthedocs.org/',
+ description=('PRAW, an acronym for "Python Reddit API Wrapper", is a '
+ 'python package that allows for simple access to '
+ 'reddit\'s API.'),
+ long_description=README,
classifiers=['Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Intended Audience :: Developers',
@@ -31,7 +36,9 @@
'Programming Language :: Python :: 3.2',
'Topic :: Utilities'],
license='GPLv3',
- keywords=['api', 'reddit'],
- packages=['reddit'],
- package_data={'': ['COPYING'], 'reddit': ['*.cfg']},
- install_requires=['six'])
+ keywords='reddit api wrapper',
+ packages=[PACKAGE_NAME],
+ package_data={'': ['COPYING'], PACKAGE_NAME: ['*.ini']},
+ install_requires=['six'],
+ test_suite='praw',
+ )