<commit_before>import re

from lxml import html

from . import helpers
from . import util
from .messaging import MailboxFetcher
from .objects import Profile, Question, Session
from .search import search
from .xpath import XPathBuilder


class User(object):
    """
    Represent an OKCupid user. Username and password are only optional
    if you have already filled in your username and password in
    settings.py.
    Parameters
    ----------
    username : str, optional
        The username for your OKCupid account.
    password : str, optional
        The password for your OKCupid account.
    Raises
    ----------
    AuthenticationError
        If you are unable to login with the username and password
        provided.
    """

    @classmethod
    def with_credentials(cls, username, password):
        return cls(Session.login(username, password))

    def __init__(self, session=None):
        self._session = session or Session.login()
        profile_response = self._session.get('https://www.okcupid.com/profile')
        self._profile_tree = html.fromstring(profile_response.content.decode('utf8'))
        self.age, self.gender, self.orientation, self.status, self.location = helpers.get_additional_info(self._profile_tree)
        self.authcode = re.search('var AUTHCODE = "(.*?)";', profile_response.text).group(1)

        self.username = helpers.get_my_username(self._profile_tree)
        self.questions = []
        self.visitors = []

    @util.cached_property
    def inbox(self):
        return list(MailboxFetcher(self._session, 1).get_threads())

    @util.cached_property
    def outbox(self):
        return list(MailboxFetcher(self._session, 2).get_threads())

    @util.cached_property
    def drafts(self):
        return list(MailboxFetcher(self._session, 4).get_threads())

    def force_refresh(self, inbox_name='inbox'):
        del self.__dict__[inbox_name]
        return getattr(self, inbox_name)

    def update_essay(self, essay_id, essay_body):
        form_data = {
            "essay_id": essay_id,
            "essay_body": essay_body,
            "authcode": self.authcode,
            "okc_api": 1
        }
        self._session.post('https://www.okcupid.com/profileedit2', data=form_data)

    def message(self, username, message_text):
        """
        Send a message to the username specified.
        Parameters
        ----------
        username : str or Profile
            Username of the profile that is being messaged.
        message_text : str
            Text body of the message.
        """
        threadid = ''
        if isinstance(username, Profile):
            username == username.name
        for thread in self.inbox[::-1]: # reverse, find most recent messages first
            if thread.sender.lower() == username.lower():
                threadid = thread.threadid
                break
        get_messages = self._session.get('http://www.okcupid.com/messages')
        inbox_tree = html.fromstring(get_messages.content.decode('utf8'))
        authcode = helpers.get_authcode(inbox_tree)
        msg_data = {
            'ajax': '1',
            'sendmsg': '1',
            'r1': username,
            'body': message_text,
            'threadid': threadid,
            'authcode': authcode,
            'reply': '1',
        }
        return self._session.post('http://www.okcupid.com/mailbox', data=msg_data)

    def search(self, **kwargs):
        kwargs.setdefault('gender', self.gender[0])
        kwargs.setdefault('looking_for', helpers.get_looking_for(self.gender, self.orientation))
        kwargs.setdefault('location', self.location)
        kwargs.setdefault('radius', 25)
        return search(self._session, **kwargs)

    def visit(self, username, update_pics=False):<commit_msg>Simpler authcode retrieval.<commit_after>import re

from lxml import html

from . import helpers
from . import util
from .messaging import MailboxFetcher
from .objects import Profile, Question, Session
from .search import search
from .xpath import XPathBuilder


class User(object):
    """
    Represent an OKCupid user. Username and password are only optional
    if you have already filled in your username and password in
    settings.py.
    Parameters
    ----------
    username : str, optional
        The username for your OKCupid account.
    password : str, optional
        The password for your OKCupid account.
    Raises
    ----------
    AuthenticationError
        If you are unable to login with the username and password
        provided.
    """

    @classmethod
    def with_credentials(cls, username, password):
        return cls(Session.login(username, password))

    def __init__(self, session=None):
        self._session = session or Session.login()
        profile_response = self._session.get('https://www.okcupid.com/profile')
        self._profile_tree = html.fromstring(profile_response.content.decode('utf8'))
        self.age, self.gender, self.orientation, self.status, self.location = helpers.get_additional_info(self._profile_tree)
        self.authcode = re.search('var AUTHCODE = "(.*?)";', profile_response.text).group(1)

        self.username = helpers.get_my_username(self._profile_tree)
        self.questions = []
        self.visitors = []

    @util.cached_property
    def inbox(self):
        return list(MailboxFetcher(self._session, 1).get_threads())

    @util.cached_property
    def outbox(self):
        return list(MailboxFetcher(self._session, 2).get_threads())

    @util.cached_property
    def drafts(self):
        return list(MailboxFetcher(self._session, 4).get_threads())

    def force_refresh(self, inbox_name='inbox'):
        del self.__dict__[inbox_name]
        return getattr(self, inbox_name)

    def update_essay(self, essay_id, essay_body):
        form_data = {
            "essay_id": essay_id,
            "essay_body": essay_body,
            "authcode": self.authcode,
            "okc_api": 1
        }
        self._session.post('https://www.okcupid.com/profileedit2', data=form_data)

    def message(self, username, message_text):
        """
        Send a message to the username specified.
        Parameters
        ----------
        username : str or Profile
            Username of the profile that is being messaged.
        message_text : str
            Text body of the message.
        """
        threadid = ''
        if isinstance(username, Profile):
            username == username.name
        for thread in self.inbox[::-1]: # reverse, find most recent messages first
            if thread.correspondent.lower() == username.lower():
                threadid = thread.threadid
                break
        msg_data = {
            'ajax': '1',
            'sendmsg': '1',
            'r1': username,
            'body': message_text,
            'threadid': threadid,
            'authcode': self.authcode,
            'reply': '1',
        }
        return self._session.post('http://www.okcupid.com/mailbox', data=msg_data)

    def search(self, **kwargs):
        kwargs.setdefault('gender', self.gender[0])
        kwargs.setdefault('looking_for', helpers.get_looking_for(self.gender, self.orientation))
        kwargs.setdefault('location', self.location)
        kwargs.setdefault('radius', 25)
        return search(self._session, **kwargs)

    def visit(self, username, update_pics=False):
{'fraction_non_alphanumeric': 0.11172806067172264, 'fraction_numerical': 0.004198266522210184, 'mean_word_length': 2.4428904428904428, 'pattern_counts': {'":': 8, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 7, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '599666', 'n_tokens_mistral': 2093, 'n_tokens_neox': 2041, 'n_words': 509}