def linked_object(self): """Returns the linked object.""" from MaKaC.conference import CategoryManager, ConferenceHolder if self.link_type == LinkType.category: return CategoryManager().getById(self.category_id, True) event = ConferenceHolder().getById(self.event_id, True) if event is None: return None if self.link_type == LinkType.event: return event elif self.link_type == LinkType.session: return event.getSessionById(self.session_id) elif self.link_type == LinkType.contribution: return event.getContributionById(self.contribution_id) elif self.link_type == LinkType.subcontribution: contribution = event.getContributionById(self.contribution_id) if contribution is None: return None return contribution.getSubContributionById(self.subcontribution_id)
def linked_object(self): """Returns the linked object.""" from MaKaC.conference import CategoryManager, ConferenceHolder if self.link_type == LinkType.category: return CategoryManager().getById(self.category_id, True) event = ConferenceHolder().getById(self.event_id, True) if event is None: return None if self.link_type == LinkType.event: return event elif self.link_type == LinkType.session: return event.getSessionById(self.session_id) elif self.link_type == LinkType.contribution: return event.getContributionById(self.contribution_id) elif self.link_type == LinkType.subcontribution: contribution = event.getContributionById(self.contribution_id) if contribution is None: return None return contribution.getSubContributionById(self.subcontribution_id)
def get_object_from_args(args=None): """Retrieves an event object from request arguments. This utility is meant to be used in cases where the same controller can deal with objects attached to various parts of an event which use different URLs to indicate which object to use. :param args: The request arguments. If unspecified, ``request.view_args`` is used. :return: An ``(object_type, event, object)`` tuple. The event is always the :class:`Conference` associated with the object. The object may be a `Conference`, `Session`, `Contribution` or `SubContribution`. If the object does not exist, ``(object_type, None, None)`` is returned. """ from MaKaC.conference import ConferenceHolder if args is None: args = request.view_args object_type = args['object_type'] event = ConferenceHolder().getById(args['confId'], True) obj = None if event is None: obj = None elif object_type == 'event': obj = event elif object_type == 'session': obj = event.getSessionById(args['sessionId']) elif object_type == 'contribution': obj = event.getContributionById(args['contribId']) elif object_type == 'subcontribution': contrib = event.getContributionById(args['contribId']) if contrib is not None: obj = contrib.getSubContributionById(args['subContId']) else: raise ValueError('Unexpected object type: {}'.format(object_type)) if obj is not None: return object_type, event, obj else: return object_type, None, None
def resolveHierarchicalId(objId): """ Gets an object from its Id (unless it doesn't exist, in which case it returns None """ from MaKaC.conference import ConferenceHolder m = re.match(r'(\w+)(?:\.(s?)(\w+))?(?:\.(\w+))?', objId) # If the expression doesn't match at all, return if not m or not m.groups()[0]: return None try: m = m.groups() conference = ConferenceHolder().getById(m[0]) if m[1]: # session id specified - session or slot session = conference.getSessionById(m[2]) if m[3]: # session slot: 1234.s12.1 return session.getSlotById(m[3]) else: # session: 1234.s12 return session else: if m[2]: # second token is not a session id # (either contribution or subcontribution) contribution = conference.getContributionById(m[2]) if m[3]: # subcontribution: 1234.12.1 return contribution.getSubContributionById(m[3]) else: # contribution: 1234.12 return contribution else: # there's not second token # it's definitely a conference return conference except errors.MaKaCError: return None
def resolveHierarchicalId(objId): """ Gets an object from its Id (unless it doesn't exist, in which case it returns None """ from MaKaC.conference import ConferenceHolder m = re.match(r'(\w+)(?:\.(s?)(\w+))?(?:\.(\w+))?', objId) # If the expression doesn't match at all, return if not m or not m.groups()[0]: return None try: m = m.groups() conference = ConferenceHolder().getById(m[0]) if m[1]: # session id specified - session or slot session = conference.getSessionById(m[2]) if m[3]: # session slot: 1234.s12.1 return session.getSlotById(m[3]) else: # session: 1234.s12 return session else: if m[2]: # second token is not a session id # (either contribution or subcontribution) contribution = conference.getContributionById(m[2]) if m[3]: # subcontribution: 1234.12.1 return contribution.getSubContributionById(m[3]) else: # contribution: 1234.12 return contribution else: # there's not second token # it's definitely a conference return conference except errors.MaKaCError: return None
def split_avatars(file): """Step 2: Split the merged avatars - run this on the POST-MERGE database""" data = json.load(file) if len(data) != 2: echo('Invalid data: Expected two items, found {}'.format(len(data))) raise click.Abort() avatars = [AvatarHolder().getById(x['id']) for x in data] if avatars.count(None) != 1: echo( 'Expected exactly one unreferenced avatar, got {}'.format(avatars)) raise click.Abort() if avatars[0] is None: orig = avatars[1] orig_data = data[1] merged_data = data[0] else: orig = avatars[0] orig_data = data[0] merged_data = data[1] merged = [av for av in orig._mergeFrom if av.getId() == merged_data['id']] if len(merged) != 1: echo("Avatars don't seem to be merged into each other") raise click.Abort() merged = merged[0] if merged not in orig._mergeFrom or merged._mergeTo != orig: echo("Avatars don't seem to be merged into each other") raise click.Abort() # Remove merge references orig._mergeFrom.remove(merged) merged._mergeTo = None # Clean secondary emails orig.setSecondaryEmails(orig_data['secondary_emails']) merged.setSecondaryEmails(merged_data['secondary_emails']) # Clean identities for identity in merged.getIdentityList(create_identities=True): orig.removeIdentity(identity) identity.setUser(merged) # Re-index the avatars # noinspection PyCallByClass ObjectHolder.add(AvatarHolder(), merged) for index in {'organisation', 'email', 'name', 'surName', 'status'}: IndexesHolder().getById(index).unindexUser(orig) IndexesHolder().getById(index).indexUser(orig) IndexesHolder().getById(index).indexUser(merged) # Restore links for the merged avatar for key, links in merged_data['links'].iteritems(): objtype, role = key.split('.') for link in links: # TODO: Add extra items here as necessary (use show_links to check if anything is missing)! if objtype == 'conference': event = ConferenceHolder().getById(link, quiet=True) if event is None: echo('Event not found: {}'.format(link)) continue if event not in set(orig.linkedTo[objtype][role]): echo('{!r} not linked to avatar via {}'.format(event, key)) continue if role == 'access': event.revokeAccess(orig) event.grantAccess(merged) else: echo('Unexpected link type: {}'.format(key)) raise click.Abort() # print 'Updated {} - {!r}'.format(key, event) elif objtype == 'contribution': event_id, contrib_id = link event = ConferenceHolder().getById(event_id) if event is None: echo('Event not found: {}'.format(event_id)) continue contrib = event.getContributionById(contrib_id) if contrib is None: echo('Contrib not found: {}.{}'.format( event_id, contrib_id)) continue if contrib not in set(orig.linkedTo[objtype][role]): echo('{} not linked to avatar via {}'.format(contrib, key)) continue if role == 'submission': contrib.revokeSubmission(orig) contrib.grantSubmission(merged) elif role == 'manager': contrib.revokeModification(orig) contrib.grantModification(merged) else: echo('Unexpected link type: {}'.format(key)) raise click.Abort() # print 'Updated {} - {}'.format(key, contrib) else: # This results in inconsistent data in redis, but since we flush the redis # links after a successful merge, that's not an issue. Also, we only reach # this branch if someone is using different versions of this script... echo('Unexpected link type: {}'.format(key)) raise click.Abort() if not click.confirm('Do you want to commit the changes now?'): transaction.abort( ) # not really necessary, but let's stay on the safe side raise click.Abort() transaction.commit() # Refresh redis links avatar_links.delete_avatar(orig) avatar_links.delete_avatar(merged) avatar_links.init_links(orig) avatar_links.init_links(merged) # Delete suggestions suggestions.delete_avatar(orig) suggestions.delete_avatar(merged)
def split_avatars(file): """Step 2: Split the merged avatars - run this on the POST-MERGE database""" data = json.load(file) if len(data) != 2: echo('Invalid data: Expected two items, found {}'.format(len(data))) raise click.Abort() avatars = [AvatarHolder().getById(x['id']) for x in data] if avatars.count(None) != 1: echo('Expected exactly one unreferenced avatar, got {}'.format(avatars)) raise click.Abort() if avatars[0] is None: orig = avatars[1] orig_data = data[1] merged_data = data[0] else: orig = avatars[0] orig_data = data[0] merged_data = data[1] merged = [av for av in orig._mergeFrom if av.getId() == merged_data['id']] if len(merged) != 1: echo("Avatars don't seem to be merged into each other") raise click.Abort() merged = merged[0] if merged not in orig._mergeFrom or merged._mergeTo != orig: echo("Avatars don't seem to be merged into each other") raise click.Abort() # Remove merge references orig._mergeFrom.remove(merged) merged._mergeTo = None # Clean secondary emails orig.setSecondaryEmails(orig_data['secondary_emails']) merged.setSecondaryEmails(merged_data['secondary_emails']) # Clean identities for identity in merged.getIdentityList(create_identities=True): orig.removeIdentity(identity) identity.setUser(merged) # Re-index the avatars # noinspection PyCallByClass ObjectHolder.add(AvatarHolder(), merged) for index in {'organisation', 'email', 'name', 'surName', 'status'}: IndexesHolder().getById(index).unindexUser(orig) IndexesHolder().getById(index).indexUser(orig) IndexesHolder().getById(index).indexUser(merged) # Restore links for the merged avatar for key, links in merged_data['links'].iteritems(): objtype, role = key.split('.') for link in links: # TODO: Add extra items here as necessary (use show_links to check if anything is missing)! if objtype == 'conference': event = ConferenceHolder().getById(link, quiet=True) if event is None: echo('Event not found: {}'.format(link)) continue if event not in set(orig.linkedTo[objtype][role]): echo('{!r} not linked to avatar via {}'.format(event, key)) continue if role == 'access': event.revokeAccess(orig) event.grantAccess(merged) else: echo('Unexpected link type: {}'.format(key)) raise click.Abort() # print 'Updated {} - {!r}'.format(key, event) elif objtype == 'contribution': event_id, contrib_id = link event = ConferenceHolder().getById(event_id) if event is None: echo('Event not found: {}'.format(event_id)) continue contrib = event.getContributionById(contrib_id) if contrib is None: echo('Contrib not found: {}.{}'.format(event_id, contrib_id)) continue if contrib not in set(orig.linkedTo[objtype][role]): echo('{} not linked to avatar via {}'.format(contrib, key)) continue if role == 'submission': contrib.revokeSubmission(orig) contrib.grantSubmission(merged) elif role == 'manager': contrib.revokeModification(orig) contrib.grantModification(merged) else: echo('Unexpected link type: {}'.format(key)) raise click.Abort() # print 'Updated {} - {}'.format(key, contrib) else: # This results in inconsistent data in redis, but since we flush the redis # links after a successful merge, that's not an issue. Also, we only reach # this branch if someone is using different versions of this script... echo('Unexpected link type: {}'.format(key)) raise click.Abort() if not click.confirm('Do you want to commit the changes now?'): transaction.abort() # not really necessary, but let's stay on the safe side raise click.Abort() transaction.commit() # Refresh redis links avatar_links.delete_avatar(orig) avatar_links.delete_avatar(merged) avatar_links.init_links(orig) avatar_links.init_links(merged) # Delete suggestions suggestions.delete_avatar(orig) suggestions.delete_avatar(merged)
def findZombies(fix=False,fromDate=None): dbi = DBMgr.getInstance() dbi.startRequest() pubConfIdx = IndexesHolder().getIndex('OAIDeletedConferenceModificationDate') prvConfIdx = IndexesHolder().getIndex('OAIDeletedPrivateConferenceModificationDate') pubContIdx = IndexesHolder().getIndex('OAIDeletedContributionModificationDate') prvContIdx = IndexesHolder().getIndex('OAIDeletedPrivateContributionModificationDate') zombies = [] doh = DeletedObjectHolder() for obj in doh.getList(): isZombie = False rec = None if obj._objClass == Conference: try: rec = ConferenceHolder().getById(obj.getId()) isZombie = True except: continue elif obj._objClass == Contribution or obj._objClass == AcceptedContribution: try: conference = ConferenceHolder().getById(obj.confId) except: continue rec = conference.getContributionById(obj.contribId) isZombie = (rec != None) elif obj._objClass == SubContribution: try: conference = ConferenceHolder().getById(obj.confId) except: continue contrib = conference.getContributionById(obj.contribId) if not contrib: continue rec = contrib.getSubContributionById(obj.subContribId) isZombie = (rec != None) if isZombie: print "-- ZOMBIE %s" % prettyPrint(rec) zombies.append(obj) if fix: for z in zombies: dbi.sync() pubConfIdx.unindexElement(z) prvConfIdx.unindexElement(z) pubContIdx.unindexElement(z) prvContIdx.unindexElement(z) id = z.getId() doh.remove(z) dbi.commit() print "-- FIXED %s " % id dbi.endRequest() print "\n Total of %s zombie records found" % len(zombies) return zombies
def findZombies(fix=False, fromDate=None): dbi = DBMgr.getInstance() dbi.startRequest() pubConfIdx = IndexesHolder().getIndex( 'OAIDeletedConferenceModificationDate') prvConfIdx = IndexesHolder().getIndex( 'OAIDeletedPrivateConferenceModificationDate') pubContIdx = IndexesHolder().getIndex( 'OAIDeletedContributionModificationDate') prvContIdx = IndexesHolder().getIndex( 'OAIDeletedPrivateContributionModificationDate') zombies = [] doh = DeletedObjectHolder() for obj in doh.getList(): isZombie = False rec = None if obj._objClass == Conference: try: rec = ConferenceHolder().getById(obj.getId()) isZombie = True except: continue elif obj._objClass == Contribution or obj._objClass == AcceptedContribution: try: conference = ConferenceHolder().getById(obj.confId) except: continue rec = conference.getContributionById(obj.contribId) isZombie = (rec != None) elif obj._objClass == SubContribution: try: conference = ConferenceHolder().getById(obj.confId) except: continue contrib = conference.getContributionById(obj.contribId) if not contrib: continue rec = contrib.getSubContributionById(obj.subContribId) isZombie = (rec != None) if isZombie: print "-- ZOMBIE %s" % prettyPrint(rec) zombies.append(obj) if fix: for z in zombies: dbi.sync() pubConfIdx.unindexElement(z) prvConfIdx.unindexElement(z) pubContIdx.unindexElement(z) prvContIdx.unindexElement(z) id = z.getId() doh.remove(z) dbi.commit() print "-- FIXED %s " % id dbi.endRequest() print "\n Total of %s zombie records found" % len(zombies) return zombies