def display_object_lifecycle(request, obj_type, obj_ref, obj_revi): """ Lifecycle data of the given object (a part or a document). :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/lifecycle/[apply/]` .. include:: views_params.txt POST requests must have a "demote", "promote", "publish" or "unpublish" key and must validate the :class:`.ConfirmPasswordForm` form. If the form is valid, the object is promoted, demoted, published, unpublished according to the request. **Template:** :file:`lifecycle.html` **Context:** ``RequestContext`` ``action`` Only for unsuccessful POST requests. Name of the action ("demote" or "promote") that the user tries to do. """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if obj.is_cancelled: return r2r("lifecycle_cancelled.html", ctx, request) if request.method == 'POST': password_form = forms.ConfirmPasswordForm(request.user, request.POST) actions = (("demote", obj.demote), ("promote", obj.approve_promotion), ("discard", obj.discard_approvals), ("publish", obj.publish), ("unpublish", obj.unpublish), ("cancel", obj.safe_cancel), ) if obj.is_part: actions += (("promote_assembly", obj.promote_assembly),) if password_form.is_valid(): for action_name, method in actions: if action_name in request.POST: method() if 'cancel' in request.POST: message = _(u"The %(object_type)s has been successfully cancelled." % dict(object_type=obj_type)) messages.info(request, message) elif 'promote' in request.POST: message = _(u"The %(object_type)s has been successfully promoted." % dict(object_type=obj_type)) messages.info(request, message) break return HttpResponseRedirect("..") for action_name, method in actions: if action_name in request.POST: ctx["action"] = action_name break else: password_form = forms.ConfirmPasswordForm(request.user) ctx['password_form'] = password_form ctx['in_group'] = obj.check_in_group(request.user, raise_=False) ctx.update(get_management_data(obj, request.user)) ctx.update(get_lifecycle_data(obj)) return r2r('lifecycle.html', ctx, request)
def import_csv_init(request, target="csv"): """ Manage page to import a csv file. """ if not request.user.profile.is_contributor: raise PermissionError("You are not a contributor.") obj, ctx = get_generic_data(request) if request.method == "POST": csv_form = forms.CSVForm(request.POST, request.FILES) if csv_form.is_valid(): f = request.FILES["file"] prefix = "openplmcsv" + request.user.username tmp = tempfile.NamedTemporaryFile(prefix=prefix, delete=False) for chunk in f.chunks(): tmp.write(chunk) name = os.path.split(tmp.name)[1][len(prefix):] tmp.close() encoding = csv_form.cleaned_data["encoding"] return HttpResponseRedirect("/import/%s/%s/%s/" % (target, name, encoding)) else: csv_form = forms.CSVForm() ctx["csv_form"] = csv_form ctx["step"] = 1 ctx["target"] = target return r2r("import/csv.html", ctx, request)
def alternates(request, obj_type, obj_ref, obj_revi): obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) ctx.update({ "current_page": "alternates", "alternates": obj.get_alternates(), }) return r2r('parts/alternates.html', ctx, request)
def display_object_attributes(request, obj_type, obj_ref, obj_revi): """ Attributes view of the given object. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/attributes/` .. include:: views_params.txt **Template:** :file:`attribute.html` **Context:** ``RequestContext`` ``object_attributes`` list of tuples(verbose attribute name, value) """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) object_attributes = render_attributes(obj, obj.attributes) ctx["is_contributor"] = obj._user.profile.is_contributor ctx.update({'current_page' : 'attributes', 'object_attributes' : object_attributes}) if isinstance(obj.object, models.PLMObject): if obj.is_part: ctx["attach"] = (obj, "attach_doc") ctx["link_creation_action"] = u"%sdoc-cad/add/" % obj.plmobject_url elif obj.is_document: ctx["attach"] = (obj, "attach_part") ctx["link_creation_action"] = u"%sparts/add/" % obj.plmobject_url return r2r('attributes.html', ctx, request)
def display_files(request, client, obj_type, obj_ref, obj_revi): """ Files page of a GoogleDocument. """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "files"): raise TypeError() try: entry = client.get_resource_by_id(obj.resource_id) edit_uri = "" if entry is not None: for link in entry.link: if link.rel == 'alternate': edit_uri = link.href break uri = client._get_download_uri(entry.content.src) ctx.update({ 'resource': obj.resource_id.split(":", 1)[-1], 'download_uri': uri, 'edit_uri': edit_uri, 'error': False, }) else: ctx["error"] = True except gdata.client.RequestError: ctx['error'] = True ctx['current_page'] = 'files' return r2r('gdoc_files.html', ctx, request)
def change_user_password(request, obj_ref): """ Manage html page for the modification of the selected :class:`~django.contrib.auth.models.User` password. It computes a context dictionary based on :param request: :class:`django.http.QueryDict` :param obj_ref: :attr:`~django.contrib.auth.models.User.username` :return: a :class:`django.http.HttpResponse` """ if request.user.username == 'test': return HttpResponseRedirect("/user/%s/attributes/" % request.user) obj, ctx = get_generic_data(request, "User", obj_ref) if obj.object != request.user: raise PermissionError("You are not the user") if request.method == 'POST' and request.POST: modification_form = PasswordChangeForm(obj, request.POST) if modification_form.is_valid(): obj.set_password(modification_form.cleaned_data['new_password2']) obj.save() messages.info(request, _(u"Your password has been modified successfully.")) return HttpResponseRedirect("/user/%s/" % obj.username) else: modification_form = PasswordChangeForm(obj) ctx["modification_form"] = modification_form return r2r('users/password.html', ctx, request)
def change_user_password(request, obj_ref): """ Manage html page for the modification of the selected :class:`~django.contrib.auth.models.User` password. It computes a context dictionary based on :param request: :class:`django.http.QueryDict` :param obj_ref: :attr:`~django.contrib.auth.models.User.username` :return: a :class:`django.http.HttpResponse` """ if request.user.username=='test': return HttpResponseRedirect("/user/%s/attributes/" % request.user) obj, ctx = get_generic_data(request, "User", obj_ref) if obj.object != request.user: raise PermissionError("You are not the user") if request.method == 'POST' and request.POST: modification_form = PasswordChangeForm(obj, request.POST) if modification_form.is_valid(): obj.set_password(modification_form.cleaned_data['new_password2']) obj.save() messages.info(request, _(u"Your password has been modified successfully.")) return HttpResponseRedirect("/user/%s/" % obj.username) else: modification_form = PasswordChangeForm(obj) ctx["modification_form"] = modification_form return r2r('users/password.html', ctx, request)
def display_userbadges(request, obj_type, obj_ref, obj_revi): """ Badge tab in user view. :url: :samp:`/user/{{username}}/badges` **Template:** :file:`users/badges_overview.html` **Context:** ``RequestContext`` ``badges`` List of badges won by the user ``current_page`` name of the tab """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) badges = Badge.objects.active().filter(user=obj.object).order_by("level") ctx.update({ 'current_page' : 'badges', 'badges' : badges, }) return r2r("user/badges_overview.html", ctx, request)
def ajax_logs(request, obj_type, obj_ref, obj_revi): """ Ajax Logs page of a SubversionRepository. """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) ctx["error"] = False try: revision = parse_revision(obj.svn_revision) uri = obj.repository_uri if uri.startswith("file://") or uri.startswith("/"): raise ValueError() client = pysvn.Client() if not client.is_url(uri): raise ValueError() # parse uri and set credentials if given parts = urlparse.urlparse(uri) if parts.username and parts.password: client.callback_get_login = lambda *args: (True, parts.username, parts.password, True) logs = client.log(uri, limit=20, revision_start=revision) for log in logs: log["date"] = datetime.datetime.fromtimestamp(log["date"]) log["day"] = get_day(log) ctx["logs"] = logs except (ValueError, pysvn.ClientError): ctx["error"] = True ctx['current_page'] = 'logs' return r2r('ajax_logs.html', ctx, request)
def logs(request, obj_type, obj_ref, obj_revi): """ Logs page of a SubversionRepository. """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) ctx['current_page'] = 'logs' return r2r('logs.html', ctx, request)
def display_object_attributes(request, obj_type, obj_ref, obj_revi): """ Attributes view of the given object. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/attributes/` .. include:: views_params.txt **Template:** :file:`attribute.html` **Context:** ``RequestContext`` ``object_attributes`` list of tuples(verbose attribute name, value) """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) object_attributes = render_attributes(obj, obj.attributes) ctx["is_contributor"] = obj._user.profile.is_contributor ctx.update({ 'current_page': 'attributes', 'object_attributes': object_attributes }) if isinstance(obj.object, models.PLMObject): if obj.is_part: ctx["attach"] = (obj, "attach_doc") ctx["link_creation_action"] = u"%sdoc-cad/add/" % obj.plmobject_url elif obj.is_document: ctx["attach"] = (obj, "attach_part") ctx["link_creation_action"] = u"%sparts/add/" % obj.plmobject_url return r2r('attributes.html', ctx, request)
def display_files(request, obj_type, obj_ref, obj_revi): """ Files page of a SubversionRepository. """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) ctx['current_page'] = 'files' return r2r('subversion_files.html', ctx, request)
def display_URLDoc(request, obj_type, obj_ref, obj_revi): obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) ctx.update({ 'current_page': 'content', }) return r2r('content.html', ctx, request)
def display_files(request, client, obj_type, obj_ref, obj_revi): """ Files page of a GoogleDocument. """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "files"): raise TypeError() try: entry = client.get_resource_by_id(obj.resource_id) edit_uri = "" if entry is not None: for link in entry.link: if link.rel == 'alternate': edit_uri = link.href break uri = client._get_download_uri(entry.content.src) ctx.update({ 'resource' : obj.resource_id.split(":", 1)[-1], 'download_uri' : uri, 'edit_uri' : edit_uri, 'error' : False, }) else: ctx["error"] = True except gdata.client.RequestError: ctx['error'] = True ctx['current_page'] = 'files' return r2r('gdoc_files.html', ctx, request)
def alternates(request, obj_type, obj_ref, obj_revi): obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) ctx.update({ "current_page" : "alternates", "alternates" : obj.get_alternates(), }) return r2r('parts/alternates.html', ctx, request)
def compare_bom(request, obj_type, obj_ref, obj_revi): obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "get_children"): return HttpResponseBadRequest("object must be a part") date = date2 = None level = "first" state = "all" show_documents = show_alternates = False compact = True now = timezone.now() if request.GET: cmp_form = forms.CompareBOMForm(request.GET) if cmp_form.is_valid(): date = cmp_form.cleaned_data["date"] date2 = cmp_form.cleaned_data["date2"] level = cmp_form.cleaned_data["level"] state = cmp_form.cleaned_data["state"] show_documents = cmp_form.cleaned_data["show_documents"] show_alternates = cmp_form.cleaned_data["show_documents"] compact = cmp_form.cleaned_data.get("compact", compact) else: initial = {"date" : now, "date2" : now, "level" : "first", "state" : "all", "compact" : compact, } cmp_form = forms.CompareBOMForm(initial=initial) ctx.update(obj.cmp_bom(date, date2, level, state, show_documents, show_alternates)) ctx.update({'current_page' : 'BOM-child', "cmp_form" : cmp_form, 'compact' : compact, 'date1' : date or now, 'date2' : date2 or now, }) return r2r('parts/bom_diff.html', ctx, request)
def overview(request, extra_context={}): """ Badges view : display all badges available in OpenPLM :url: :samp:`/badges/` **Template:** :file:`badges/overview.html` **Context:** ``RequestContext`` ``badges`` List of all badges available ``object_type`` Name of the page """ obj, ctx = get_generic_data(request, search=False) badges = Badge.objects.active().order_by("level") ctx.update(extra_context) ctx["badges"] = badges ctx["object_type"] = _("Badges") return r2r("badges/overview.html", ctx, request)
def display_page(request, obj_type, obj_ref, obj_revi): """ Files page of a :class:`.Page`. """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) ctx['current_page'] = 'page' return r2r('richpage/page.html', ctx, request)
def display_userbadges(request, obj_type, obj_ref, obj_revi): """ Badge tab in user view. :url: :samp:`/user/{{username}}/badges` **Template:** :file:`users/badges_overview.html` **Context:** ``RequestContext`` ``badges`` List of badges won by the user ``current_page`` name of the tab """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) badges = Badge.objects.active().filter(user=obj.object).order_by("level") ctx.update({ 'current_page': 'badges', 'badges': badges, }) return r2r("user/badges_overview.html", ctx, request)
def overview(request, extra_context={}): """ Badges view : display all badges available in OpenPLM :url: :samp:`/badges/` **Template:** :file:`badges/overview.html` **Context:** ``RequestContext`` ``badges`` List of all badges available ``object_type`` Name of the page """ obj, ctx = get_generic_data(request, search=False) badges = Badge.objects.active().order_by("level") ctx.update(extra_context) ctx["badges"]=badges ctx["object_type"]=_("Badges") return r2r("badges/overview.html",ctx,request)
def add_child(request, obj_type, obj_ref, obj_revi): """ View to add a child to a part. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/bom-child/add/` .. include:: views_params.txt **Template:** :file:`parts/bom_add.html` **Context:** ``RequestContext`` ``add_child_form`` a form to add a child (:class:`.AddChildForm`) ``link`` :class:`.ParentChildLink` being replaced ``link_creation`` Set to True ``attach`` set to (*obj*, "add_child") """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi, load_all=True) if request.method == "POST" and request.POST: add_child_form = forms.AddChildForm(obj.object, request.POST) if add_child_form.is_valid(): child_obj = get_obj_from_form(add_child_form, request.user) obj.add_child(child_obj, add_child_form.cleaned_data["quantity"], add_child_form.cleaned_data["order"], add_child_form.cleaned_data["unit"], **add_child_form.extensions) return HttpResponseRedirect(obj.plmobject_url + "BOM-child/") else: if "type" in request.GET and request.GET["type"] in models.get_all_parts(): # use GET params only if they seems valid initial = request.GET else: initial = None add_child_form = forms.AddChildForm(obj.object, initial=initial) ctx['current_page'] = 'BOM-child' if ctx["results"]: obj.precompute_can_add_child2() orders = list(obj.parentchildlink_parent.values_list('order', flat=True)) initial_order = max(orders) + 10 if orders else 10 ctx['order'] = initial_order ctx.update({'link_creation': True, 'add_child_form': add_child_form, 'attach' : (obj, "add_child")}) return r2r('parts/bom_add.html', ctx, request)
def add_management(request, obj_type, obj_ref, obj_revi, reader=False, level=None): """ View to add a manager (notified user or restricted reader). :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/management/add/` or :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/management/add-reader/` .. include:: views_params.txt :param reader: True to add a restricted reader instead of a notified user **Template:** :file:`management_replace.html` **Context:** ``RequestContext`` ``replace_manager_form`` a form to select the new manager (a user) ``link_creation`` Set to True ``role`` role of the new user (:const:`.ROLE_NOTIFIED` or :const:`.ROLE_READER`) ``attach`` set to (*obj*, :samp:`"add_{role}"`) """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if level is None: role = models.ROLE_READER if reader else models.ROLE_NOTIFIED else: role = level_to_sign_str(int(level)) if request.method == "POST": add_management_form = forms.SelectUserForm(request.POST) if add_management_form.is_valid(): if add_management_form.cleaned_data["type"] == "User": user_obj = get_obj_from_form(add_management_form, request.user) obj.set_role(user_obj.object, role) message = _(u"Role %(add_role)s granted." % dict(add_role=role)) messages.info(request, message) return HttpResponseRedirect("../../lifecycle/") else: add_management_form = forms.SelectUserForm() ctx.update({'current_page':'lifecycle', 'replace_manager_form': add_management_form, 'link_creation': True, 'role' : role, "attach" : (obj, "add_" + role)}) return r2r('management_replace.html', ctx, request)
def plmobjects(request, obj_ref): obj, ctx = bv.get_generic_data(request, "ECR", obj_ref, "-") objects = models.PLMObject.objects.filter( id__in=obj.plmobjects.now().values_list("plmobject", flat=True)) objects = objects.select_related("state", "lifecycle") ctx.update(get_pagination(request, objects, "object")) ctx["current_page"] = "part-doc-cads" ctx["detach_objects"] = obj.is_editable and ctx["is_owner"] return r2r("ecrs/plmobjects.html", ctx, request)
def display_groups(request, obj_ref): """ View of the *groups* page of a user. """ obj, ctx = get_generic_data(request, "User", obj_ref) ctx["groups"] = models.GroupInfo.objects.filter(id__in=obj.groups.all())\ .order_by("name") ctx['current_page'] = 'groups' return r2r("users/groups.html", ctx, request)
def attributes(request, obj_ref, obj_revi): """Custom attributes page """ obj_type = "Bicycle" obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) object_attributes = [] for attr in obj.attributes: item = obj.get_verbose_name(attr) + ":" # <- this is our small modification object_attributes.append((item, getattr(obj, attr))) ctx.update({"current_page": "attributes", "object_attributes": object_attributes}) return r2r("attributes.html", ctx, request)
def display_plmobjects(request, obj_ref): """ View of the *objects* page of a group. """ obj, ctx = get_generic_data(request, "Group", obj_ref) objects = obj.plmobject_group.exclude_cancelled() ctx.update(get_pagination(request, objects, "object")) ctx['current_page'] = 'objects' return r2r("groups/objects.html", ctx, request)
def replace_management(request, obj_type, obj_ref, obj_revi, link_id): """ View to replace a manager (owner, signer, reader...) by another one. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/management/replace/{link_id}/` .. include:: views_params.txt :param link_id: id of the :class:`.PLMObjectUserLink` being replaced **Template:** :file:`management_replace.html` **Context:** ``RequestContext`` ``replace_manager_form`` a form to select the new manager (a user) ``link_creation`` Set to True ``role`` role of the link being replace ``attach`` set to (*obj*, :samp:`"add_{role}"`) """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) link = obj.users.now().get(id=int(link_id)) if request.method == "POST": replace_manager_form = forms.SelectUserForm(request.POST) if replace_manager_form.is_valid(): if replace_manager_form.cleaned_data["type"] == "User": user_obj = get_obj_from_form(replace_manager_form, request.user) if link.role.startswith(models.ROLE_SIGN): obj.replace_signer(link.user, user_obj.object, link.role) else: obj.set_role(user_obj.object, link.role) if link.role == models.ROLE_NOTIFIED: obj.remove_notified(link.user) elif link.role == models.ROLE_READER: obj.remove_reader(link.user) return HttpResponseRedirect("../../../lifecycle/") else: replace_manager_form = forms.SelectUserForm() ctx.update({'current_page':'lifecycle', 'replace_manager_form': replace_manager_form, 'link_creation': True, 'role' : link.role, 'attach' : (obj, "add_" + link.role)}) return r2r('management_replace.html', ctx, request)
def attributes(request, obj_ref, obj_revi): """Custom attributes page """ obj_type = "Bicycle" obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) object_attributes = [] for attr in obj.attributes: item = obj.get_verbose_name(attr) + ":" # <- this is our small modification object_attributes.append((item, getattr(obj, attr))) ctx.update({'current_page':'attributes', 'object_attributes': object_attributes}) return r2r('attributes.html', ctx, request)
def upload_and_create(request, obj_ref): obj, ctx = get_generic_data(request) if not obj.profile.is_contributor: raise ValueError("You are not a contributor") if request.method == "POST": if request.FILES: # from a browser where js is disabled return add_file(request, "User", obj.username, "-") add_file_form = forms.AddFileForm() ctx.update({"add_file_form": add_file_form, "object_reference": "-", "object_type": _("Upload")}) return r2r("users/files.html", ctx, request)
def display_doc_cad(request, obj_type, obj_ref, obj_revi): """ Attached documents view. That view displays the documents attached to the selected object that must be a part. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/doc-cad/` .. include:: views_params.txt **Template:** :file:`parts/doccad.html` **Context:** ``RequestContext`` ``documents`` a queryset of :class:`.DocumentPartLink` bound to the part ``archive_formats`` list of available archive formats ``docs_formset`` a formset to detach documents ``forms`` a dictionary (link_id -> form) to get the form related to a link (a document may not be "detachable") """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "get_attached_documents"): return HttpResponseBadRequest("object must be a part") if request.method == "POST": formset = forms.get_doc_cad_formset(obj, request.POST) if formset.is_valid(): obj.update_doc_cad(formset) return HttpResponseRedirect(".") else: formset = forms.get_doc_cad_formset(obj) dforms = dict((form.instance.id, form) for form in formset.forms) documents = obj.get_attached_documents() ctx.update({ 'current_page': 'doc-cad', 'documents': documents, 'forms': dforms, 'archive_formats': ARCHIVE_FORMATS, 'docs_formset': formset, }) ctx.update(get_id_card_data([d.document.id for d in documents])) return r2r('parts/doccad.html', ctx, request)
def import_csv_apply(request, target, filename, encoding): """ View that display a preview of an uploaded csv file. """ obj, ctx = get_generic_data(request) if not request.user.profile.is_contributor: raise PermissionError("You are not a contributor.") ctx["encoding_error"] = False ctx["io_error"] = False Importer = csvimport.IMPORTERS[target] Formset = forms.get_headers_formset(Importer) try: path = os.path.join(tempfile.gettempdir(), "openplmcsv" + request.user.username + filename) with open(path, "rb") as csv_file: importer = Importer(csv_file, request.user, encoding) preview = importer.get_preview() if request.method == "POST": headers_formset = Formset(request.POST) if headers_formset.is_valid(): headers = headers_formset.headers try: with open(path, "rb") as csv_file: importer = Importer(csv_file, request.user, encoding) importer.import_csv(headers) except csvimport.CSVImportError as exc: ctx["errors"] = exc.errors.iteritems() else: os.remove(path) return HttpResponseRedirect("/import/done/") else: initial = [{ "header": header } for header in preview.guessed_headers] headers_formset = Formset(initial=initial) ctx.update({ "preview": preview, "preview_data": itertools.izip((f["header"] for f in headers_formset.forms), preview.headers, *preview.rows), "headers_formset": headers_formset, }) except UnicodeError: ctx["encoding_error"] = True except (IOError, csv.Error): ctx["io_error"] = True ctx["has_critical_error"] = ctx["io_error"] or ctx["encoding_error"] \ or "errors" in ctx ctx["csv_form"] = forms.CSVForm(initial={"encoding": encoding}) ctx["step"] = 2 ctx["target"] = target return r2r("import/csv.html", ctx, request)
def edit_content(request, obj_type, obj_ref, obj_revi): obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if request.method == "POST": form = PageForm(request.POST) if form.is_valid(): obj.edit_content(form.cleaned_data["page_content"]) return HttpResponseRedirect("../page/") else: form = PageForm(initial={"page_content": obj.page_content}) ctx["form"] = form ctx['current_page'] = 'page' return r2r('richpage/edit_content.html', ctx, request)
def edit_children(request, obj_type, obj_ref, obj_revi): """ View to edit a BOM. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/bom-child/edit/` .. include:: views_params.txt **Template:** :file:`parts/bom_edit.html` **Context:** ``RequestContext`` ``children_formset`` a formset to edit the BOM ``extra_columns`` a list of extra columns that are displayed ``extra_fields`` a list of extra fields that are editable """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "get_children"): return HttpResponseBadRequest("object must be a part") if request.method == "POST": formset = forms.get_children_formset(obj, request.POST) if formset.is_valid(): obj.update_children(formset) return HttpResponseRedirect("..") else: formset = forms.get_children_formset(obj) extra_columns = [] extra_fields = [] for PCLE in models.get_PCLEs(obj.object): fields = PCLE.get_visible_fields() if fields: extra_columns.extend( (f, PCLE._meta.get_field(f).verbose_name) for f in fields) prefix = PCLE._meta.module_name extra_fields.extend('%s_%s' % (prefix, f) for f in fields) ctx.update({ 'current_page': 'BOM-child', 'extra_columns': extra_columns, 'extra_fields': extra_fields, 'children_formset': formset, }) return r2r('parts/bom_edit.html', ctx, request)
def display_doc_cad(request, obj_type, obj_ref, obj_revi): """ Attached documents view. That view displays the documents attached to the selected object that must be a part. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/doc-cad/` .. include:: views_params.txt **Template:** :file:`parts/doccad.html` **Context:** ``RequestContext`` ``documents`` a queryset of :class:`.DocumentPartLink` bound to the part ``archive_formats`` list of available archive formats ``docs_formset`` a formset to detach documents ``forms`` a dictionary (link_id -> form) to get the form related to a link (a document may not be "detachable") """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "get_attached_documents"): return HttpResponseBadRequest("object must be a part") if request.method == "POST": formset = forms.get_doc_cad_formset(obj, request.POST) if formset.is_valid(): obj.update_doc_cad(formset) return HttpResponseRedirect(".") else: formset = forms.get_doc_cad_formset(obj) dforms = dict((form.instance.id, form) for form in formset.forms) documents = obj.get_attached_documents() ctx.update({'current_page':'doc-cad', 'documents': documents, 'forms' : dforms, 'archive_formats' : ARCHIVE_FORMATS, 'docs_formset': formset, }) ctx.update(get_id_card_data([d.document.id for d in documents])) return r2r('parts/doccad.html', ctx, request)
def display_files(request, obj_type, obj_ref, obj_revi): """ Files view. That view displays files of the given document. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/files/` .. include:: views_params.txt **Template:** :file:`documents/files.html` **Context:** ``RequestContext`` ``file_formset`` a formset to remove files ``archive_formats`` list of available archive formats ``add_file_form`` form to add a file """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "files"): return HttpResponseBadRequest("object must be a document") if request.method == "POST": if request.FILES: # from a browser where js is disabled return add_file(request, obj_type, obj_ref, obj_revi) formset = forms.get_file_formset(obj, request.POST) if formset.is_valid(): obj.update_file(formset) return HttpResponseRedirect(".") else: formset = forms.get_file_formset(obj) add_file_form = forms.AddFileForm() ctx.update( { "current_page": "files", "file_formset": formset, "archive_formats": ARCHIVE_FORMATS, "deprecated_files": obj.deprecated_files.filter(last_revision__isnull=True), "add_file_form": add_file_form, } ) return r2r("documents/files.html", ctx, request)
def navigate(request, obj_type, obj_ref, obj_revi): """ Manage html page which displays a graphical picture the different links between :class:`~django.contrib.auth.models.User` and :class:`.models.PLMObject`. This function uses Graphviz (http://graphviz.org/). Some filters let user defines which type of links he/she wants to display. It computes a context dictionary based on .. include:: views_params.txt """ ctx = get_navigate_data(request, obj_type, obj_ref, obj_revi) ctx["edges"] = json.dumps(ctx["edges"]) return r2r('navigate.html', ctx, request)
def edit_children(request, obj_type, obj_ref, obj_revi): """ View to edit a BOM. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/bom-child/edit/` .. include:: views_params.txt **Template:** :file:`parts/bom_edit.html` **Context:** ``RequestContext`` ``children_formset`` a formset to edit the BOM ``extra_columns`` a list of extra columns that are displayed ``extra_fields`` a list of extra fields that are editable """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "get_children"): return HttpResponseBadRequest("object must be a part") if request.method == "POST": formset = forms.get_children_formset(obj, request.POST) if formset.is_valid(): obj.update_children(formset) return HttpResponseRedirect("..") else: formset = forms.get_children_formset(obj) extra_columns = [] extra_fields = [] for PCLE in models.get_PCLEs(obj.object): fields = PCLE.get_visible_fields() if fields: extra_columns.extend((f, PCLE._meta.get_field(f).verbose_name) for f in fields) prefix = PCLE._meta.module_name extra_fields.extend('%s_%s' % (prefix, f) for f in fields) ctx.update({'current_page':'BOM-child', 'extra_columns' : extra_columns, 'extra_fields' : extra_fields, 'children_formset': formset, }) return r2r('parts/bom_edit.html', ctx, request)
def delegate(request, obj_ref, role, sign_level): """ Manage html page for delegations modification of the selected :class:`~django.contrib.auth.models.User`. It computes a context dictionary based on :param request: :class:`django.http.QueryDict` :param obj_type: :class:`~django.contrib.auth.models.User` :type obj_ref: str :param role: :attr:`.DelegationLink.role` if role is not "sign" :type role: str :param sign_level: used for :attr:`.DelegationLink.role` if role is "sign" :type sign_level: str :return: a :class:`django.http.HttpResponse` """ obj, ctx = get_generic_data(request, "User", obj_ref) if request.method == "POST": delegation_form = forms.SelectUserForm(request.POST) if delegation_form.is_valid(): if delegation_form.cleaned_data["type"] == "User": user_obj = get_obj_from_form(delegation_form, request.user) if role == "notified" or role == "owner": obj.delegate(user_obj.object, role) return HttpResponseRedirect("../..") elif role == "sign": if sign_level == "all": obj.delegate(user_obj.object, "sign*") return HttpResponseRedirect("../../..") elif sign_level.isdigit(): obj.delegate(user_obj.object, level_to_sign_str(int(sign_level) - 1)) return HttpResponseRedirect("../../..") else: delegation_form = forms.SelectUserForm() if role == 'sign': if sign_level.isdigit(): role = _("signer level") + " " + str(sign_level) else: role = _("signer all levels") elif role == "notified": role = _("notified") ctx.update({ 'current_page': 'delegation', 'replace_manager_form': delegation_form, 'link_creation': True, 'attach': (obj, "delegate"), 'role': role }) return r2r('management_replace.html', ctx, request)
def add_alternate(request, obj_type, obj_ref, obj_revi): obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if request.POST: add_part_form = forms.AddPartForm(request.POST) if add_part_form.is_valid(): part_obj = get_obj_from_form(add_part_form, request.user) obj.add_alternate(part_obj) return HttpResponseRedirect(obj.plmobject_url + "alternates/") else: add_part_form = forms.AddPartForm() ctx.update({'link_creation': True, 'add_part_form': add_part_form, 'attach' : (obj, "add_alternate") }) return r2r('parts/alternates_add.html', ctx, request)
def replace_child(request, obj_type, obj_ref, obj_revi, link_id): """ View to replace a child by another one. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/bom-child/replace/{link_id}/` .. include:: views_params.txt :param link_id: id of the :class:`.ParentChildLink` being replaced **Template:** :file:`parts/bom_replace.html` **Context:** ``RequestContext`` ``replace_child_form`` a form to select the replacement part ``link`` :class:`.ParentChildLink` being replaced ``link_creation`` Set to True ``attach`` set to (*obj*, "add_child") """ link_id = int(link_id) obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi, load_all=True) link = models.ParentChildLink.objects.get(id=link_id) if request.method == "POST": form = forms.AddPartForm(request.POST) if form.is_valid(): obj.replace_child(link, get_obj_from_form(form, request.user)) return HttpResponseRedirect("../..") else: form = forms.AddPartForm() if ctx["results"]: obj.precompute_can_add_child2() ctx["replace_child_form"] = form ctx["link"] = link ctx["attach"] = (obj, "add_child") ctx["link_creation"] = True return r2r("parts/bom_replace.html", ctx, request)
def display_files(request, obj_type, obj_ref, obj_revi): """ Files view. That view displays files of the given document. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/files/` .. include:: views_params.txt **Template:** :file:`documents/files.html` **Context:** ``RequestContext`` ``file_formset`` a formset to remove files ``archive_formats`` list of available archive formats ``add_file_form`` form to add a file """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "files"): return HttpResponseBadRequest("object must be a document") if request.method == "POST": if request.FILES: # from a browser where js is disabled return add_file(request, obj_type, obj_ref, obj_revi) formset = forms.get_file_formset(obj, request.POST) if formset.is_valid(): obj.update_file(formset) return HttpResponseRedirect(".") else: formset = forms.get_file_formset(obj) add_file_form = forms.AddFileForm() ctx.update({'current_page':'files', 'file_formset': formset, 'archive_formats' : ARCHIVE_FORMATS, 'deprecated_files' : obj.deprecated_files.filter(last_revision__isnull=True), 'add_file_form': add_file_form, }) return r2r('documents/files.html', ctx, request)
def import_csv_apply(request, target, filename, encoding): """ View that display a preview of an uploaded csv file. """ obj, ctx = get_generic_data(request) if not request.user.profile.is_contributor: raise PermissionError("You are not a contributor.") ctx["encoding_error"] = False ctx["io_error"] = False Importer = csvimport.IMPORTERS[target] Formset = forms.get_headers_formset(Importer) try: path = os.path.join(tempfile.gettempdir(), "openplmcsv" + request.user.username + filename) with open(path, "rb") as csv_file: importer = Importer(csv_file, request.user, encoding) preview = importer.get_preview() if request.method == "POST": headers_formset = Formset(request.POST) if headers_formset.is_valid(): headers = headers_formset.headers try: with open(path, "rb") as csv_file: importer = Importer(csv_file, request.user, encoding) importer.import_csv(headers) except csvimport.CSVImportError as exc: ctx["errors"] = exc.errors.iteritems() else: os.remove(path) return HttpResponseRedirect("/import/done/") else: initial = [{"header": header} for header in preview.guessed_headers] headers_formset = Formset(initial=initial) ctx.update({ "preview" : preview, "preview_data" : itertools.izip((f["header"] for f in headers_formset.forms), preview.headers, *preview.rows), "headers_formset" : headers_formset, }) except UnicodeError: ctx["encoding_error"] = True except (IOError, csv.Error): ctx["io_error"] = True ctx["has_critical_error"] = ctx["io_error"] or ctx["encoding_error"] \ or "errors" in ctx ctx["csv_form"] = forms.CSVForm(initial={"encoding" : encoding}) ctx["step"] = 2 ctx["target"] = target return r2r("import/csv.html", ctx, request)
def group_ask_to_join(request, obj_ref): """ View of the *user join* page of a group """ obj, ctx = get_generic_data(request, "Group", obj_ref) if request.method == "POST": obj.ask_to_join() msg = _("Invitation asked to %(name)s") % {"name": obj.owner.get_full_name()} messages.info(request, msg) return HttpResponseRedirect("..") ctx["ask_form"] = "" ctx['current_page'] = 'users' ctx['in_group'] = request.user.groups.filter(id=obj.id).exists() return r2r("groups/ask_to_join.html", ctx, request)
def upload_and_create(request, obj_ref): obj, ctx = get_generic_data(request) if not obj.profile.is_contributor: raise ValueError("You are not a contributor") if request.method == "POST": if request.FILES: # from a browser where js is disabled return add_file(request, "User", obj.username, "-") add_file_form = forms.AddFileForm() ctx.update({ 'add_file_form': add_file_form, 'object_reference': "-", 'object_type': _("Upload"), }) return r2r('users/files.html', ctx, request)
def delegate(request, obj_ref, role, sign_level): """ Manage html page for delegations modification of the selected :class:`~django.contrib.auth.models.User`. It computes a context dictionary based on :param request: :class:`django.http.QueryDict` :param obj_type: :class:`~django.contrib.auth.models.User` :type obj_ref: str :param role: :attr:`.DelegationLink.role` if role is not "sign" :type role: str :param sign_level: used for :attr:`.DelegationLink.role` if role is "sign" :type sign_level: str :return: a :class:`django.http.HttpResponse` """ obj, ctx = get_generic_data(request, "User", obj_ref) if request.method == "POST": delegation_form = forms.SelectUserForm(request.POST) if delegation_form.is_valid(): if delegation_form.cleaned_data["type"] == "User": user_obj = get_obj_from_form(delegation_form, request.user) if role == "notified" or role == "owner": obj.delegate(user_obj.object, role) return HttpResponseRedirect("../..") elif role == "sign": if sign_level == "all": obj.delegate(user_obj.object, "sign*") return HttpResponseRedirect("../../..") elif sign_level.isdigit(): obj.delegate(user_obj.object, level_to_sign_str(int(sign_level)-1)) return HttpResponseRedirect("../../..") else: delegation_form = forms.SelectUserForm() if role == 'sign': if sign_level.isdigit(): role = _("signer level") + " " + str(sign_level) else: role = _("signer all levels") elif role == "notified": role = _("notified") ctx.update({'current_page':'delegation', 'replace_manager_form': delegation_form, 'link_creation': True, 'attach' : (obj, "delegate"), 'role': role}) return r2r('management_replace.html', ctx, request)
def display_parts(request, obj_type, obj_ref, obj_revi): """ Attached parts view. That view displays the parts attached to the selected object that must be a document. :url: :samp:`/object/{obj_type}/{obj_ref}/{obj_revi}/parts/` .. include:: views_params.txt **Template:** :file:`documents/parts.html` **Context:** ``RequestContext`` ``parts`` a queryset of :class:`.DocumentPartLink` bound to the document ``parts_formset`` a formset to detach parts ``forms`` a dictionary (link_id -> form) to get the form related to a link (a part may not be "detachable") """ obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if not hasattr(obj, "get_attached_parts"): return HttpResponseBadRequest("object must be a document") if request.method == "POST": formset = forms.get_rel_part_formset(obj, request.POST) if formset.is_valid(): obj.update_rel_part(formset) return HttpResponseRedirect(".") else: formset = forms.get_rel_part_formset(obj) rforms = dict((form.instance.id, form) for form in formset.forms) parts = obj.get_attached_parts() ctx.update({'current_page':'parts', 'parts': parts, 'forms' : rforms, 'parts_formset': formset}) if request.session.get("as_table"): ctx.update(get_id_card_data([p.id for p in parts])) return r2r('documents/parts.html', ctx, request)
def add_alternate(request, obj_type, obj_ref, obj_revi): obj, ctx = get_generic_data(request, obj_type, obj_ref, obj_revi) if request.POST: add_part_form = forms.AddPartForm(request.POST) if add_part_form.is_valid(): part_obj = get_obj_from_form(add_part_form, request.user) obj.add_alternate(part_obj) return HttpResponseRedirect(obj.plmobject_url + "alternates/") else: add_part_form = forms.AddPartForm() ctx.update({ 'link_creation': True, 'add_part_form': add_part_form, 'attach': (obj, "add_alternate") }) return r2r('parts/alternates_add.html', ctx, request)
def group_ask_to_join(request, obj_ref): """ View of the *user join* page of a group """ obj, ctx = get_generic_data(request, "Group", obj_ref) if request.method == "POST": obj.ask_to_join() msg = _("Invitation asked to %(name)s") % { "name": obj.owner.get_full_name() } messages.info(request, msg) return HttpResponseRedirect("..") ctx["ask_form"] = "" ctx['current_page'] = 'users' ctx['in_group'] = request.user.groups.filter(id=obj.id).exists() return r2r("groups/ask_to_join.html", ctx, request)