def test_split_filter(self): ok, ko = split_filter((lambda x: x % 2), range(5)) self.assertEqual([1, 3], ok) self.assertEqual([0, 2, 4], ko) ok, ko = split_filter((lambda x: 'k' in x), ['Naruto', 'Sasuke', 'Sakura', 'Kakashi']) self.assertEqual(['Sasuke', 'Sakura', 'Kakashi'], ok) self.assertEqual(['Naruto'], ko)
def _build_section_matches(self, instance): """Build a dict that is the correspondence between PollFormSection & clone or PollReplySection instances. """ instance_classname = instance.__class__.__name__ if instance_classname == 'PollForm': create_section = partial(PollFormSection.objects.create, pform=instance) elif instance_classname == 'PollReply': from .poll_reply import PollReplySection create_section = partial(PollReplySection.objects.create, preply=instance) matches = {} # id = ID of PollFormSection instance ; # value = corresponding PollReplySection or PollFormSection instance fsections = [*self.sections.all()] parents = [None] # set ?? # At each loop, we take a level of PollFormSection (root, then their # children, then the children of children etc...), and we create for each # PollFormSection the corresponding PollFormSection or PollReplySection. while fsections: children, fsections = split_filter((lambda section: section.parent in parents), fsections) matches.update((child.id, create_section(name=child.name, body=child.body, order=child.order, parent=matches.get(child.parent_id), ) ) for child in children ) parents = children return matches
def form_gather_blocks_for_layout(form_blocks): sections = [] i = 0 form_blocks = [*form_blocks] length = len(form_blocks) while i < length: block = form_blocks[i] if block.layout == LAYOUT_REGULAR: regular_section = [block] i += 1 while i < length and form_blocks[i].layout == LAYOUT_REGULAR: regular_section.append(form_blocks[i]) i += 1 sections.append(('regular', regular_section)) else: # LAYOUT_DUAL_FIRST, LAYOUT_DUAL_SECOND dual_section = [block] i += 1 while i < length and form_blocks[i].layout != LAYOUT_REGULAR: dual_section.append(form_blocks[i]) i += 1 sections.append(( 'dual', split_filter( lambda b: b.layout == LAYOUT_DUAL_FIRST, dual_section, ), )) return sections
def portal(request): user = request.user now_val = localtime(now()) def build_dt(h, m, s): return datetime( year=now_val.year, month=now_val.month, day=now_val.day, hour=h, minute=m, second=s, tzinfo=now_val.tzinfo, ) activities = EntityCredentials.filter( user, Activity.objects.filter( is_deleted=False, relations__type=act_constants.REL_OBJ_PART_2_ACTIVITY, relations__object_entity=user.linked_contact, start__range=( build_dt(0, 0, 0), build_dt(23, 59, 59), ), ).exclude(status__in=( act_constants.STATUS_DONE, act_constants.STATUS_CANCELLED, ), ).order_by('start')) # TODO: an activity which starts before now, & ends before now too, with status != PROGRESS # -> should it be displayed in this hot_activities (or in today_activities) ???? # NB: FLOATING_TIME activities will naturally be the first activities in # 'today_activities' as we want (they are ordered by start, and NARROW # activities which start at 0h00 will be in 'hot_activities'). hot_activities, today_activities = split_filter( lambda a: a.floating_type == act_constants.NARROW and (a.status_id == act_constants.STATUS_IN_PROGRESS or a.start < now_val), activities) # TODO: populate participants (regroup queries for Relation + real entities) ?? used_worked_hours = frozenset( localtime(a.start).hour for a in today_activities if a.floating_type == act_constants.NARROW) shortcuts_map = [(hour, hour in used_worked_hours) for hour in range(WORKED_HOURS[0], WORKED_HOURS[1] + 1)] return render( request, 'mobile/index.html', { 'hot_activities': hot_activities, 'today_activities': today_activities, 'shortcuts_map': shortcuts_map, }, )
def _delete_instances(self, models, verbosity): if verbosity > 1: self.stdout.write('Processing deletion...\n') # TODO: implement a True dependencies solver ?? # NB: we delete first the entities models because it will probably # avoid major dependencies problems. models_info = [ (model, True) # True means 'First deletion trial" for model in chain( *split_filter(lambda m: issubclass(m, CremeEntity), models)) ] while True: errors = LimitedList(MAX_ERRORS) next_models_info = [] progress = False for model, first_trial in models_info: count = model.objects.count() if not count: if verbosity: self.stdout.write( 'No "{}" instance to delete.\n'.format( model.__name__)) continue if verbosity: self.stdout.write( 'Trying to flush "{model}" ({count}{adj} instances)...\n' .format( model=model.__name__, count=count, adj='' if first_trial else ' remaining', )) if issubclass(model, CremeEntity): pre_delete = lambda i: i.relations.filter(type__is_internal =False).delete() else: pre_delete = lambda i: None local_errors = False for instance in model.objects.all(): try: pre_delete(instance) instance.delete() except Exception as e: local_errors = True errors.append((instance, str(e))) else: progress = True if local_errors: next_models_info.append((model, False)) elif verbosity: self.stdout.write( ' [OK] All instances have been deleted.', # self.style.MIGRATE_SUCCESS, self.style.SUCCESS, ) if not next_models_info: return if not progress: extra_errors = max(0, len(errors) - errors.max_size) raise CommandError( u'[KO] Cannot flush all instances: aborting.\n' u'{errors}\n{extra_errors}' u'Please delete the problematic instances ' u'manually before re-run this command.'.format( errors=u'\n'.join( u'- Cannot delete "{obj}" (id={id}) (original error: {error})' .format( obj=obj, id=obj.id, error=error, ) for obj, error in errors), extra_errors='({} extra error(s))\n'.format( extra_errors) if extra_errors else '', )) models_info = next_models_info