| # Copyright 2014 the Melange authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| """Mapreduce converting SOCOrganization to Organization model.""" |
| |
| import logging |
| |
| from melange.appengine import django_setup |
| django_setup.setup_environment() |
| |
| from google.appengine.ext import ndb |
| |
| from melange.appengine import db as melange_db |
| from melange.models import organization as org_model |
| from melange.models import survey as survey_model |
| |
| # This MapReduce requires these models to have been imported. |
| # pylint: disable=unused-import |
| from melange.models.connection import Connection |
| from melange.models.profile import Profile |
| from summerofcode.models.organization import SOCOrganization |
| # pylint: enable=unused-import |
| |
| |
| def _hasSOCOrganizationKind(org_key): |
| """Returns True if the specified key has 'SOCOrganization' kind. |
| |
| Args: |
| org_key: ndb.Key of Organization entity. |
| |
| Returns: |
| True, if kind of the specified key equals 'SOCOrganization'. Otherwise, |
| False. |
| """ |
| return org_key.kind() == 'SOCOrganization' |
| |
| |
| def _getNewKey(org_key): |
| """Returns Organization key corresponding to the specified SOCOrganization. |
| |
| Args: |
| org_key: ndb.Key of SOCOrganization entity. |
| |
| Returns: |
| ndb.Key whose kind is Organization and id equals to the id of the specified |
| key. |
| """ |
| return ndb.Key('Organization', org_key.id()) |
| |
| |
| def convertOrganization(org_key): |
| """Converts the specified organization by creating org_model.Organization |
| entity that has the same properties. |
| |
| Args: |
| org_key: ndb.Key of SOCOrganization entity. |
| """ |
| org_key = ndb.Key.from_old_key(org_key) |
| org = org_key.get() |
| |
| to_put = [] |
| |
| properties = melange_db.toDict(org, exclude_computed=True) |
| new_org = org_model.Organization(id=org_key.id(), **properties) |
| |
| for key in org.to_dict().iterkeys(): |
| # NOTE: for some reason, some existing organization entities have logo_image |
| # property. It is returned by to_dict() and _properties. However, this |
| # field is not supported by Organization model anymore, so accessing it |
| # would raise an error |
| if key == 'logo_image': |
| continue |
| elif key not in new_org.to_dict().keys(): |
| logging.error( |
| 'Something went from for organization %s. Property %s does not ' |
| 'exist in the converted organization.', org_key, key) |
| return |
| elif new_org.to_dict()[key] != org.to_dict()[key]: |
| logging.error( |
| 'Something went wrong for organization %s. Property %s does not ' |
| 'equal: %s != %s.', org_key, key, new_org.to_dict()[key], |
| org.to_dict()[key]) |
| return |
| else: |
| to_put.append(new_org) |
| |
| # find survey response corresponding to the old organization kind |
| app_response = survey_model.SurveyResponse.query(ancestor=org_key).get() |
| if not app_response: |
| pass |
| # logging.warning( |
| # 'Survey response does not exist for organization %s', org_key) |
| else: |
| properties = melange_db.toDict(app_response, exclude_computed=True) |
| new_response = survey_model.SurveyResponse(parent=new_org.key, **properties) |
| to_put.append(new_response) |
| |
| # find organization messages corresponding to the old organization kind |
| org_messages = org_model.OrganizationMessages.query(ancestor=org_key).get() |
| if not org_messages: |
| logging.warning( |
| 'Organization messages not found for organization %s', org_key) |
| else: |
| properties = melange_db.toDict(org_messages, exclude_computed=True) |
| new_messages = org_model.OrganizationMessages( |
| parent=new_org.key, **properties) |
| to_put.append(new_messages) |
| |
| @ndb.transactional |
| def txn(): |
| ndb.put_multi(to_put) |
| txn() |
| |
| |
| @ndb.transactional |
| def convertConnection(connection_key): |
| """Converts the specified connection by updating references so that they |
| points to 'Organization' model instead of 'SOCOrganization'. |
| |
| Args: |
| connection_key: ndb.Key of Connection entity. |
| """ |
| connection = ndb.Key.from_old_key(connection_key).get() |
| if connection.organization.kind() == 'SOCOrganization': |
| connection.organization = _getNewKey(connection.organization) |
| connection.put() |
| |
| |
| @ndb.transactional |
| def convertProposal(proposal_key): |
| """Converts the specified proposal by updating references so that they |
| points to 'Organization' model instead of 'SOCOrganization'. |
| |
| Args: |
| proposal_key: ndb.Key of Proposal entity. |
| """ |
| proposal = ndb.Key.from_old_key(proposal_key).get() |
| if proposal.organization.kind() == 'SOCOrganization': |
| proposal.organization = _getNewKey(proposal.organization) |
| proposal.put() |
| |
| |
| @ndb.transactional |
| def convertProject(project_key): |
| """Converts the specified project by updating references so that they |
| points to 'Organization' model instead of 'SOCOrganization'. |
| |
| Args: |
| project_key: ndb.Key of Project entity. |
| """ |
| project = ndb.Key.from_old_key(project_key).get() |
| if not project.organization: |
| logging.error('No organization for project: %s', project_key) |
| elif project.organization.kind() == 'SOCOrganization': |
| project.organization = _getNewKey(project.organization) |
| project.put() |
| |
| |
| @ndb.transactional |
| def convertProfile(profile_key): |
| """Converts the specified profile by updating references so that they |
| points to 'Organization' model instead of 'SOCOrganization'. |
| |
| Args: |
| profile_key: ndb.Key of Profile entity. |
| """ |
| profile = ndb.Key.from_old_key(profile_key).get() |
| do_put = False |
| |
| mentor_for = [] |
| for org_key in profile.mentor_for: |
| if _hasSOCOrganizationKind(org_key): |
| mentor_for.append(_getNewKey(org_key)) |
| do_put = True |
| else: |
| mentor_for.append(org_key) |
| profile.mentor_for = mentor_for |
| |
| admin_for = [] |
| for org_key in profile.admin_for: |
| if _hasSOCOrganizationKind(org_key): |
| admin_for.append(_getNewKey(org_key)) |
| do_put = True |
| else: |
| admin_for.append(org_key) |
| profile.admin_for = admin_for |
| |
| rejected_for = [] |
| for org_key in profile.rejected_for: |
| if _hasSOCOrganizationKind(org_key): |
| rejected_for.append(_getNewKey(org_key)) |
| do_put = True |
| else: |
| rejected_for.append(org_key) |
| profile.rejected_for = rejected_for |
| |
| if profile.is_student: |
| project_for_orgs = [] |
| for org_key in profile.student_data.project_for_orgs: |
| if _hasSOCOrganizationKind(org_key): |
| project_for_orgs.append(_getNewKey(org_key)) |
| do_put = True |
| else: |
| project_for_orgs.append(org_key) |
| profile.student_data.project_for_orgs = project_for_orgs |
| |
| if do_put: |
| profile.put() |