import logging
import time
from .profile import Profile
from .question import Questions
log = logging.getLogger(__name__)
[docs]class Copy(object):
"""Copy photos, essays and other attributes from one profile to another."""
copy_methods = ['photos', 'essays', 'looking_for', 'details', 'questions']
[docs] def __init__(self, source_profile_or_user, dest_user):
"""
:param source_profile_or_user: A :class:`~okcupyd.user.User` or
:class:`~okcupyd.profile.Profile` object
from which to copy attributes.
:meth:`~.Copy.questions` will not
will not preserve the importance of
copied questions if a
:class:`~okcupyd.profile.Profile`
instance is provided.
:param dest_user: A :class:`~okcupyd.user.User` to which data will be
copied
"""
if isinstance(source_profile_or_user, Profile):
self.source_profile = source_profile_or_user
self.source_user = None
else:
self.source_user = source_profile_or_user
self.source_profile = self.source_user.profile
self.dest_user = dest_user
[docs] def questions(self):
"""Copy questions to the destination user. When this class was
initialized with a :class:`~okcupyd.profile.Profile`, this will
delete any existing questions answers on the destination account.
"""
if self.source_user:
return self._copy_questions_from_user()
else:
return self._copy_questions_from_profile()
def _copy_questions_from_user(self):
dest_questions = self.dest_user.questions
for key, importance in Questions.importance_name_to_number.items():
questions = getattr(self.source_user.questions, key)
for question in questions:
log.debug(
dest_questions.respond_from_user_question(
question,
importance
).content
)
def _copy_questions_from_profile(self):
# Answer all of the questions that the source user has answered.
# So that we can see their answers
for question in self.source_profile.questions:
log.debug(u'Answering {0}: {1} to see {2}\'s answer'.format(
question.id, question.text, self.source_profile.username
))
if not question.answered:
self.dest_user.questions.respond(question.id, [1], [1], 3)
# Load all of their questions. We use a new question fetchable because
# the one that lives on the profile has been accessed and has cached
# data.
source_questions = self.source_profile.question_fetchable()[:]
log.debug(u'Copying {0} questions from {1} to {2}'.format(
len(source_questions),
self.source_profile.username,
self.dest_user.username
))
id_to_user_question = {question.id: question
for question in self.dest_user.profile.questions}
self.dest_user.questions.clear()
while True:
log.debug(u'Sleeping to wait for questions to clear')
time.sleep(5)
try:
question = self.dest_user.profile.question_fetchable()[0]
except IndexError:
break
else:
log.debug(u'Destination user still has question {0}'.format(
question.text
))
for question in source_questions:
try:
user_question = id_to_user_question[question.id]
except KeyError:
log.debug(u'No user question found for {0}: {1}'.format(
question.id, question.text
))
else:
log.debug(u'Answering {0}: {1}'.format(
question.id, question.text
))
self.dest_user.questions.respond_from_question(question,
user_question, 3)
[docs] def photos(self):
"""Copy photos to the destination user."""
# Reverse because pictures appear in inverse chronological order.
for photo_info in self.dest_user.profile.photo_infos:
self.dest_user.photo.delete(photo_info)
return [self.dest_user.photo.upload_and_confirm(info)
for info in reversed(self.source_profile.photo_infos)]
[docs] def essays(self):
"""Copy essays from the source profile to the destination profile."""
for essay_name in self.dest_user.profile.essays.essay_names:
setattr(self.dest_user.profile.essays, essay_name,
getattr(self.source_profile.essays, essay_name))
[docs] def looking_for(self):
"""Copy looking for attributes from the source profile to the
destination profile.
"""
looking_for = self.source_profile.looking_for
return self.dest_user.profile.looking_for.update(
gentation=looking_for.gentation,
single=looking_for.single,
near_me=looking_for.near_me,
kinds=looking_for.kinds,
ages=looking_for.ages
)
[docs] def details(self):
"""Copy details from the source profile to the destination profile."""
return self.dest_user.profile.details.convert_and_update(
self.source_profile.details.as_dict
)
[docs] def all(self):
"""Invoke all of :meth:`~.Copy.questions`, :meth:`~.Copy.details`,
:meth:`~.Copy.essays`, :meth:`~.Copy.photos`, :meth:`~.Copy.looking_for`
"""
for method_name in self.copy_methods:
getattr(self, method_name)()