<commit_before># This file is part of reddit_api.
# 
# 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.
#
# 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.
# 
# You should have received a copy of the GNU General Public License
# along with reddit_api.  If not, see <http://www.gnu.org/licenses/>.

from settings import WAIT_BETWEEN_CALL_TIME 
from urls import urls
from functools import wraps
import time

class require_captcha(object):
    """
    Decorator for methods that require captchas.
    """
    URL = urls["new_captcha"]
    VIEW_URL = urls["view_captcha"]

    def __init__(self, func):
        wraps(func)(self)
        self.func = func
        self.captcha_id = None
        self.captcha = None

    def __get__(self, obj, type=None):
        if obj is None:
            return self
        return self.__class__(self.func.__get__(obj, type))

    def __call__(self, *args, **kwargs):
        # use the captcha passed in if given, otherwise get one
        self.captcha_id, self.captcha = kwargs.get("captcha",
                                                   self.get_captcha())
        result = self.func(*args, **kwargs)
        result.update(self.captcha_as_dict)
        return result

    @property
    def captcha_as_dict(self):
        return {"iden" : self.captcha_id,
                "captcha" : self.captcha}

    @property
    def captcha_url(self):
        if self.captcha_id:
            return urljoin(self.VIEW_URL, self.captcha_id + ".png")

    def get_captcha(self):
        data = Reddit()._request_json(self.URL, {"renderstyle" : "html"})
        # TODO: fix this, it kills kittens
        self.captcha_id = data["jquery"][-1][-1][-1]
        print "Captcha URL: " + self.captcha_url
        self.captcha = raw_input("Captcha: ")
        return self.captcha_id, self.captcha

def require_login(func):
    """A decorator to ensure that a user has logged in before calling the
    function."""
    @wraps(func)
    def login_reqd_func(self, *args, **kwargs):
        try:
            user = self.user
        except AttributeError:
            user = self.reddit_session.user

        if user is None:
            raise NotLoggedInException()
        else:
            return func(self, *args, **kwargs)
    return login_reqd_func

class sleep_after(object):
    """
    A decorator to add to API functions that shouldn't be called too
    rapidly, in order to be nice to the reddit server.

    Every function wrapped with this decorator will use a collective
    last_call_time attribute, so that collectively any one of the funcs won't<commit_msg>Updated decorate so captcha works for sending messages<commit_after># This file is part of reddit_api.
# 
# 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.
#
# 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.
# 
# You should have received a copy of the GNU General Public License
# along with reddit_api.  If not, see <http://www.gnu.org/licenses/>.

from settings import WAIT_BETWEEN_CALL_TIME 
from urls import urls
from functools import wraps
from urlparse import urljoin
import time

class require_captcha(object):
    """
    Decorator for methods that require captchas.
    """
    URL = urls["new_captcha"]
    VIEW_URL = urls["view_captcha"]

    def __init__(self, func):
        wraps(func)(self)
        self.func = func
        self.captcha_id = None
        self.captcha = None

    def __get__(self, obj, type=None):
        if obj is None:
            return self
        return self.__class__(self.func.__get__(obj, type))

    def __call__(self, caller, *args, **kwargs):
        # use the captcha passed in if given, otherwise get one
        self.captcha_id, self.captcha = kwargs.get("captcha",
                                                   self.get_captcha(caller))
        result = self.func(caller, *args, **kwargs)
        result.update(self.captcha_as_dict)
        return result

    @property
    def captcha_as_dict(self):
        return {"iden" : self.captcha_id,
                "captcha" : self.captcha}

    @property
    def captcha_url(self):
        if self.captcha_id:
            return urljoin(self.VIEW_URL, self.captcha_id + ".png")

    def get_captcha(self, caller):
        data = caller._request_json(self.URL, {"renderstyle" : "html"})
        # TODO: fix this, it kills kittens
        self.captcha_id = data["jquery"][-1][-1][-1]
        print "Captcha URL: " + self.captcha_url
        self.captcha = raw_input("Captcha: ")
        return self.captcha_id, self.captcha

def require_login(func):
    """A decorator to ensure that a user has logged in before calling the
    function."""
    @wraps(func)
    def login_reqd_func(self, *args, **kwargs):
        try:
            user = self.user
        except AttributeError:
            user = self.reddit_session.user

        if user is None:
            raise NotLoggedInException()
        else:
            return func(self, *args, **kwargs)
    return login_reqd_func

class sleep_after(object):
    """
    A decorator to add to API functions that shouldn't be called too
    rapidly, in order to be nice to the reddit server.

    Every function wrapped with this decorator will use a collective
    last_call_time attribute, so that collectively any one of the funcs won't
{'fraction_non_alphanumeric': 0.08496190791652865, 'fraction_numerical': 0.001324942033786022, 'mean_word_length': 2.6577831617201695, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '471077', 'n_tokens_mistral': 1785, 'n_tokens_neox': 1732, 'n_words': 617}