<commit_before># -*- coding: utf-8 -*-

import logging
import operator
import httplib
import httplib as http
import os

from dateutil.parser import parse as parse_date

from flask import request
from modularodm.exceptions import ValidationError, NoResultsFound
from modularodm import Q

from framework import sentry
from framework.auth import utils as auth_utils
from framework.auth.decorators import collect_auth
from framework.auth.decorators import must_be_logged_in
from framework.auth.exceptions import ChangePasswordError
from framework.auth.views import send_confirm_email
from framework.exceptions import HTTPError
from framework.flask import redirect  # VOL-aware redirect
from framework.status import push_status_message

from website import mails
from website import mailchimp_utils
from website import settings
from website.models import User
from website.models import ApiKey
from website.profile import utils as profile_utils
from website.util import web_url_for, paths
from website.util.sanitize import escape_html
from website.util.sanitize import strip_html
from website.views import _render_nodes


logger = logging.getLogger(__name__)


def get_public_projects(uid=None, user=None):
    user = user or User.load(uid)
    return _render_nodes([
        node
        for node in user.node__contributed
        if node.category == 'project'
        and node.is_public
        and not node.is_registration
        and not node.is_deleted
    ])


def get_public_components(uid=None, user=None):
    user = user or User.load(uid)
    return _render_nodes([
        node
        for node in user.node__contributed
        if node.category != 'project'
        and node.is_public
        and not node.is_registration
        and not node.is_deleted
    ])


@must_be_logged_in
def current_user_gravatar(size=None, **kwargs):
    user_id = kwargs['auth'].user._id
    return get_gravatar(user_id, size=size)


def get_gravatar(uid, size=None):
    return {'gravatar_url': profile_utils.get_gravatar(User.load(uid), size=size)}


def date_or_none(date):
    try:
        return parse_date(date)
    except Exception as error:
        logger.exception(error)
        return None


@must_be_logged_in
def update_user(auth):
    """Update the logged-in user's profile."""

    # trust the decorator to handle auth
    user = auth.user

    data = request.get_json()

    # TODO: Expand this to support other user attributes

    ##########
    # Emails #
    ##########

    if 'emails' in data:
        # removals
        removed_emails = [
            each
            for each in user.emails + user.unconfirmed_emails
            if each not in [x['address'].strip().lower()
                            for x in data['emails']]
        ]

        for address in removed_emails:
            if address in user.emails:
                user.remove_email(address)
            elif address in user.unconfirmed_emails:
                user.remove_unconfirmed_email(address)
            else:
                raise HTTPError(httplib.FORBIDDEN)

        # additions
        added_emails = [
            each['address'].strip().lower()
            for each in data['emails']
            if each['address'].strip().lower() not in user.emails
            and each['address'].strip().lower() not in user.unconfirmed_emails
        ]

        for address in added_emails:
            try:
                user.add_unconfirmed_email(address)
            except (ValidationError, ValueError):
                continue

            # TODO: This setting is now named incorrectly.
            if settings.CONFIRM_REGISTRATIONS_BY_EMAIL:
                send_confirm_email(user, email=address)

        ############
        # Username #
        ############

        # get the first email that is set to primary and has an address
        primary_email = next(
            (
                each for each in data['emails']
                # email is primary
                if each.get('primary')<commit_msg>fix the delete account author check logic<commit_after># -*- coding: utf-8 -*-

import logging
import operator
import httplib
import httplib as http
import os

from dateutil.parser import parse as parse_date

from flask import request
from modularodm.exceptions import ValidationError, NoResultsFound
from modularodm import Q

from framework import sentry
from framework.auth import utils as auth_utils
from framework.auth.decorators import collect_auth
from framework.auth.decorators import must_be_logged_in
from framework.auth.exceptions import ChangePasswordError
from framework.auth.views import send_confirm_email
from framework.exceptions import HTTPError
from framework.flask import redirect  # VOL-aware redirect
from framework.status import push_status_message

from website import mails
from website import mailchimp_utils
from website import settings
from website.models import User
from website.models import ApiKey
from website.profile import utils as profile_utils
from website.util import web_url_for, paths
from website.util.sanitize import escape_html
from website.util.sanitize import strip_html
from website.views import _render_nodes


logger = logging.getLogger(__name__)


def get_public_projects(uid=None, user=None):
    user = user or User.load(uid)
    return _render_nodes([
        node
        for node in user.node__contributed
        if node.category == 'project'
        and node.is_public
        and not node.is_registration
        and not node.is_deleted
    ])


def get_public_components(uid=None, user=None):
    user = user or User.load(uid)
    return _render_nodes([
        node
        for node in user.node__contributed
        if node.category != 'project'
        and node.is_public
        and not node.is_registration
        and not node.is_deleted
    ])


@must_be_logged_in
def current_user_gravatar(size=None, **kwargs):
    user_id = kwargs['auth'].user._id
    return get_gravatar(user_id, size=size)


def get_gravatar(uid, size=None):
    return {'gravatar_url': profile_utils.get_gravatar(User.load(uid), size=size)}


def date_or_none(date):
    try:
        return parse_date(date)
    except Exception as error:
        logger.exception(error)
        return None


@must_be_logged_in
def update_user(auth):
    """Update the logged-in user's profile."""

    # trust the decorator to handle auth
    user = auth.user

    data = request.get_json()

    # TODO: Expand this to support other user attributes

    ##########
    # Emails #
    ##########

    if 'emails' in data:
        # removals
        removed_emails = [
            each
            for each in user.emails + user.unconfirmed_emails
            if each not in [x['address'].strip().lower()
                            for x in data['emails']]
        ]

        #currently we only allow delete one email address at a time
        #if there are more than one emails deleted, this should be an error
        if len(removed_emails) > 1:
            raise HTTPError(httplib.FORBIDDEN)

        for address in removed_emails:
            if address in user.emails:
                user.remove_email(address)
            user.remove_unconfirmed_email(address)


        # additions
        added_emails = [
            each['address'].strip().lower()
            for each in data['emails']
            if each['address'].strip().lower() not in user.emails
            and each['address'].strip().lower() not in user.unconfirmed_emails
        ]

        for address in added_emails:
            try:
                user.add_unconfirmed_email(address)
            except (ValidationError, ValueError):
                continue

            # TODO: This setting is now named incorrectly.
            if settings.CONFIRM_REGISTRATIONS_BY_EMAIL:
                send_confirm_email(user, email=address)

        ############
        # Username #
        ############

        # get the first email that is set to primary and has an address
        primary_email = next(
            (
                each for each in data['emails']
                # email is primary
                if each.get('primary')
{'fraction_non_alphanumeric': 0.07897650387501538, 'fraction_numerical': 0.0003690490835281092, 'mean_word_length': 2.589403973509934, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '1041448', 'n_tokens_mistral': 2271, 'n_tokens_neox': 2198, 'n_words': 679}