def __init__(self, request, objects): items_per_page = settings.DEFAULT_ITEMS_PER_PAGE if is_authenticated(request.user): items_per_page = request.user.profile.items_per_page super(Paginator, self).__init__(objects, items_per_page) try: page_no = int(request.GET.get('page', 1)) self.current_page = self.page(int(page_no)) except ValueError: page_no = 1 self.current_page = self.page(page_no) except paginator.EmptyPage: if page_no < 1: page_no = 1 else: page_no = self.num_pages self.current_page = self.page(page_no) self.leading_set = self.trailing_set = [] pages = self.num_pages if pages <= LEADING_PAGE_RANGE_DISPLAYED: adjacent_start = 1 adjacent_end = pages + 1 elif page_no < LEADING_PAGE_RANGE: adjacent_start = 1 adjacent_end = LEADING_PAGE_RANGE_DISPLAYED + 1 self.leading_set = [ n + pages for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1) ] elif page_no >= pages - TRAILING_PAGE_RANGE: adjacent_start = pages - TRAILING_PAGE_RANGE_DISPLAYED + 1 adjacent_end = pages + 1 self.trailing_set = [ n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE) ] else: adjacent_start = page_no - ADJACENT_PAGES adjacent_end = page_no + ADJACENT_PAGES + 1 self.leading_set = [ n + pages for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1) ] self.trailing_set = [ n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE) ] self.adjacent_set = [ n for n in range(adjacent_start, adjacent_end) if n > 0 and n <= pages ] self.leading_set.reverse() self.long_page = len( self.current_page.object_list) >= LONG_PAGE_THRESHOLD
def is_editable(self, user): if not is_authenticated(user): return False if user in [self.submitter.user, self.delegate]: return True return self.project.is_editable(user)
def patch_list(request, project_id): project = get_object_or_404(Project, linkname=project_id) context = generic_list(request, project, 'patch-list', view_args={'project_id': project.linkname}) if is_authenticated(request.user): context['bundles'] = Bundle.objects.filter(owner=request.user) return render(request, 'patchwork/list.html', context)
def get_queryset(self): if is_authenticated(self.request.user): bundle_filter = Q(owner=self.request.user) | Q(public=True) else: bundle_filter = Q(public=True) return Bundle.objects\ .filter(bundle_filter)\ .prefetch_related('patches',)\ .select_related('owner', 'project')
def __init__(self, request, objects): items_per_page = settings.DEFAULT_ITEMS_PER_PAGE if is_authenticated(request.user): items_per_page = request.user.profile.items_per_page super(Paginator, self).__init__(objects, items_per_page) try: page_no = int(request.GET.get('page', 1)) self.current_page = self.page(int(page_no)) except ValueError: page_no = 1 self.current_page = self.page(page_no) except paginator.EmptyPage: if page_no < 1: page_no = 1 else: page_no = self.num_pages self.current_page = self.page(page_no) self.leading_set = self.trailing_set = [] pages = self.num_pages if pages <= LEADING_PAGE_RANGE_DISPLAYED: adjacent_start = 1 adjacent_end = pages + 1 elif page_no < LEADING_PAGE_RANGE: adjacent_start = 1 adjacent_end = LEADING_PAGE_RANGE_DISPLAYED + 1 self.leading_set = [n + pages for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)] elif page_no >= pages - TRAILING_PAGE_RANGE: adjacent_start = pages - TRAILING_PAGE_RANGE_DISPLAYED + 1 adjacent_end = pages + 1 self.trailing_set = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)] else: adjacent_start = page_no - ADJACENT_PAGES adjacent_end = page_no + ADJACENT_PAGES + 1 self.leading_set = [n + pages for n in range(0, -NUM_PAGES_OUTSIDE_RANGE, -1)] self.trailing_set = [n + 1 for n in range(0, NUM_PAGES_OUTSIDE_RANGE)] self.adjacent_set = [n for n in range(adjacent_start, adjacent_end) if n > 0 and n <= pages] self.leading_set.reverse() self.long_page = len( self.current_page.object_list) >= LONG_PAGE_THRESHOLD
def is_editable(self, user): if not is_authenticated(user): return False return self in user.profile.maintainer_projects.all()
def patch_detail(request, patch_id): # redirect to cover letters where necessary try: patch = get_object_or_404(Patch, id=patch_id) except Http404 as exc: submissions = Submission.objects.filter(id=patch_id) if submissions: return HttpResponseRedirect( reverse('cover-detail', kwargs={'cover_id': patch_id})) raise exc editable = patch.is_editable(request.user) context = {'project': patch.project} form = None createbundleform = None if editable: form = PatchForm(instance=patch) if is_authenticated(request.user): createbundleform = CreateBundleForm() if request.method == 'POST': action = request.POST.get('action', None) if action: action = action.lower() if action == 'createbundle': bundle = Bundle(owner=request.user, project=patch.project) createbundleform = CreateBundleForm(instance=bundle, data=request.POST) if createbundleform.is_valid(): createbundleform.save() bundle.append_patch(patch) bundle.save() createbundleform = CreateBundleForm() messages.success(request, 'Bundle %s created' % bundle.name) elif action == 'addtobundle': bundle = get_object_or_404(Bundle, id=request.POST.get('bundle_id')) if bundle.append_patch(patch): messages.success( request, 'Patch "%s" added to bundle "%s"' % (patch.name, bundle.name)) else: messages.error( request, 'Failed to add patch "%s" to bundle "%s": ' 'patch is already in bundle' % (patch.name, bundle.name)) # all other actions require edit privs elif not editable: return HttpResponseForbidden() elif action is None: form = PatchForm(data=request.POST, instance=patch) if form.is_valid(): form.save() messages.success(request, 'Patch updated') if is_authenticated(request.user): context['bundles'] = Bundle.objects.filter(owner=request.user) context['submission'] = patch context['patchform'] = form context['createbundleform'] = createbundleform context['project'] = patch.project return render(request, 'patchwork/submission.html', context)
def patch_detail(request, patch_id): # redirect to cover letters where necessary try: patch = get_object_or_404(Patch, id=patch_id) except Http404 as exc: submissions = Submission.objects.filter(id=patch_id) if submissions: return HttpResponseRedirect( reverse('cover-detail', kwargs={'cover_id': patch_id})) raise exc editable = patch.is_editable(request.user) context = { 'project': patch.project } form = None createbundleform = None if editable: form = PatchForm(instance=patch) if is_authenticated(request.user): createbundleform = CreateBundleForm() if request.method == 'POST': action = request.POST.get('action', None) if action: action = action.lower() if action == 'createbundle': bundle = Bundle(owner=request.user, project=patch.project) createbundleform = CreateBundleForm(instance=bundle, data=request.POST) if createbundleform.is_valid(): createbundleform.save() bundle.append_patch(patch) bundle.save() createbundleform = CreateBundleForm() messages.success(request, 'Bundle %s created' % bundle.name) elif action == 'addtobundle': bundle = get_object_or_404( Bundle, id=request.POST.get('bundle_id')) if bundle.append_patch(patch): messages.success(request, 'Patch "%s" added to bundle "%s"' % ( patch.name, bundle.name)) else: messages.error(request, 'Failed to add patch "%s" to bundle "%s": ' 'patch is already in bundle' % ( patch.name, bundle.name)) # all other actions require edit privs elif not editable: return HttpResponseForbidden() elif action is None: form = PatchForm(data=request.POST, instance=patch) if form.is_valid(): form.save() messages.success(request, 'Patch updated') if is_authenticated(request.user): context['bundles'] = Bundle.objects.filter(owner=request.user) context['submission'] = patch context['patchform'] = form context['createbundleform'] = createbundleform context['project'] = patch.project return render(request, 'patchwork/submission.html', context)
def generic_list(request, project, view, view_args=None, filter_settings=None, patches=None, editable_order=False): if not filter_settings: filter_settings = [] filters = Filters(request) context = { 'project': project, 'projects': Project.objects.all(), 'filters': filters, } # pagination params = filters.params() for param in ['order', 'page']: data = {} if request.method == 'GET': data = request.GET elif request.method == 'POST': data = request.POST value = data.get(param, None) if value: params.append((param, value)) data = {} if request.method == 'GET': data = request.GET elif request.method == 'POST': data = request.POST order = Order(data.get('order'), editable=editable_order) context.update({ 'order': order, 'list_view': { 'view': view, 'view_params': view_args or {}, 'params': params } }) # form processing # Explicitly set data to None because request.POST will be an empty dict # when the form is not submitted, but passing a non-None data argument to # a forms.Form will make it bound and we don't want that to happen unless # there's been a form submission. if request.method != 'POST': data = None user = request.user properties_form = None if is_authenticated(user): # we only pass the post data to the MultiplePatchForm if that was # the actual form submitted data_tmp = None if data and data.get('form', '') == 'patchlistform': data_tmp = data properties_form = MultiplePatchForm(project, data=data_tmp) if request.method == 'POST' and data.get('form') == 'patchlistform': action = data.get('action', '').lower() # special case: the user may have hit enter in the 'create bundle' # text field, so if non-empty, assume the create action: if data.get('bundle_name', False): action = 'create' ps = Patch.objects.filter(id__in=get_patch_ids(data)) if action in bundle_actions: errors = set_bundle(request, project, action, data, ps, context) elif properties_form and action == properties_form.action: errors = process_multiplepatch_form(request, properties_form, action, ps, context) else: errors = [] if errors: context['errors'] = errors for (filterclass, setting) in filter_settings: if isinstance(setting, dict): context['filters'].set_status(filterclass, **setting) elif isinstance(setting, list): context['filters'].set_status(filterclass, *setting) else: context['filters'].set_status(filterclass, setting) if patches is None: patches = Patch.objects.filter(project=project) # annotate with tag counts patches = patches.with_tag_counts(project) patches = context['filters'].apply(patches) if not editable_order: patches = order.apply(patches) # we don't need the content, diff or headers for a list; they're text # fields that can potentially contain a lot of data patches = patches.defer('content', 'diff', 'headers') # but we will need to follow the state and submitter relations for # rendering the list template patches = patches.select_related('state', 'submitter', 'delegate') # we also need checks and series patches = patches.prefetch_related('check_set', 'series') paginator = Paginator(request, patches) context.update({ 'page': paginator.current_page, 'patchform': properties_form, 'project': project, 'order': order, }) return context
def generic_list(request, project, view, view_args=None, filter_settings=None, patches=None, editable_order=False): if not filter_settings: filter_settings = [] filters = Filters(request) context = { 'project': project, 'projects': Project.objects.all(), 'filters': filters, } # pagination params = filters.params() for param in ['order', 'page']: data = {} if request.method == 'GET': data = request.GET elif request.method == 'POST': data = request.POST value = data.get(param, None) if value: params.append((param, value)) data = {} if request.method == 'GET': data = request.GET elif request.method == 'POST': data = request.POST order = Order(data.get('order'), editable=editable_order) context.update({ 'order': order, 'list_view': { 'view': view, 'view_params': view_args or {}, 'params': params }}) # form processing # Explicitly set data to None because request.POST will be an empty dict # when the form is not submitted, but passing a non-None data argument to # a forms.Form will make it bound and we don't want that to happen unless # there's been a form submission. if request.method != 'POST': data = None user = request.user properties_form = None if is_authenticated(user): # we only pass the post data to the MultiplePatchForm if that was # the actual form submitted data_tmp = None if data and data.get('form', '') == 'patchlistform': data_tmp = data properties_form = MultiplePatchForm(project, data=data_tmp) if request.method == 'POST' and data.get('form') == 'patchlistform': action = data.get('action', '').lower() # special case: the user may have hit enter in the 'create bundle' # text field, so if non-empty, assume the create action: if data.get('bundle_name', False): action = 'create' ps = Patch.objects.filter(id__in=get_patch_ids(data)) if action in bundle_actions: errors = set_bundle(request, project, action, data, ps, context) elif properties_form and action == properties_form.action: errors = process_multiplepatch_form(request, properties_form, action, ps, context) else: errors = [] if errors: context['errors'] = errors for (filterclass, setting) in filter_settings: if isinstance(setting, dict): context['filters'].set_status(filterclass, **setting) elif isinstance(setting, list): context['filters'].set_status(filterclass, *setting) else: context['filters'].set_status(filterclass, setting) if patches is None: patches = Patch.objects.filter(project=project) # annotate with tag counts patches = patches.with_tag_counts(project) patches = context['filters'].apply(patches) if not editable_order: patches = order.apply(patches) # we don't need the content, diff or headers for a list; they're text # fields that can potentially contain a lot of data patches = patches.defer('content', 'diff', 'headers') # but we will need to follow the state and submitter relations for # rendering the list template patches = patches.select_related('state', 'submitter', 'delegate') # we also need checks and series patches = patches.prefetch_related('check_set', 'series') paginator = Paginator(request, patches) context.update({ 'page': paginator.current_page, 'patchform': properties_form, 'project': project, 'order': order, }) return context