コード例 #1
0
ファイル: permissions.py プロジェクト: muescha/juliabase
def get_lab_notebooks(user):
    """Get a list of all lab notebooks the user can see.

    :param user: the user whose allowed lab notebooks should be collected

    :type user: django.contrib.auth.models.User

    :return:
      List of all lab notebooks the user is allowed to see.  Every lab book is
      represented by a dictionary with two keys, namely ``"url"`` with the url
      to the lab book, and ``"label"`` with the name of the process (starting
      lowercase).

    :rtype: list of dict mapping str to unicode
    """
    lab_notebooks = []
    for process_class, process in get_all_addable_physical_process_models().items():
        try:
            url = django.core.urlresolvers.reverse("lab_notebook_" + utils.camel_case_to_underscores(process["type"]),
                                                   kwargs={"year_and_month": ""})
        except django.core.urlresolvers.NoReverseMatch:
            pass
        else:
            if has_permission_to_view_lab_notebook(user, process_class):
                lab_notebooks.append({"label": process["label_plural"], "url": url})
    if lab_notebooks:
        lab_notebooks.sort(key=lambda process: process["label"].lower())
    return lab_notebooks
コード例 #2
0
ファイル: log_viewer.py プロジェクト: msincan/juliabase
def list(request):
    """List all crawlers and link to their log files.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    try:
        logs_whitelist = settings.CRAWLER_LOGS_WHITELIST
    except AttributeError:
        logs_whitelist = set()
    crawlers = []
    for process_class in permissions.get_all_addable_physical_process_models().keys():
        if process_class.__name__ in logs_whitelist or \
                permissions.has_permission_to_add_physical_process(request.user, process_class):
            process_class_name = camel_case_to_underscores(process_class.__name__)
            filepath = os.path.join(settings.CRAWLER_LOGS_ROOT, process_class_name + ".log")
            if os.path.exists(filepath):
                crawlers.append((process_class._meta.verbose_name_plural, process_class_name))
    crawlers.sort()
    return render(request, "samples/list_crawlers.html", {"title": _("Crawler logs"), "crawlers": crawlers})
コード例 #3
0
def list(request):
    """List all crawlers and link to their log files.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    try:
        logs_whitelist = settings.CRAWLER_LOGS_WHITELIST
    except AttributeError:
        logs_whitelist = set()
    crawlers = []
    for process_class in permissions.get_all_addable_physical_process_models(
    ).keys():
        if process_class.__name__ in logs_whitelist or \
                permissions.has_permission_to_add_physical_process(request.user, process_class):
            process_class_name = camel_case_to_underscores(
                process_class.__name__)
            filepath = os.path.join(settings.CRAWLER_LOGS_ROOT,
                                    process_class_name + ".log")
            if os.path.exists(filepath):
                crawlers.append((process_class._meta.verbose_name_plural,
                                 process_class_name))
    crawlers.sort()
    return render(request, "samples/list_crawlers.html", {
        "title": _("Crawler logs"),
        "crawlers": crawlers
    })
コード例 #4
0
ファイル: log_viewer.py プロジェクト: msincan/juliabase
def view(request, process_class_name):
    """View for log files of crawlers.

    :param request: the current HTTP Request object
    :param process_class_name: the name of the crawler whose log file is about to be
        shown

    :type request: HttpRequest
    :type process_class_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    for process_class in permissions.get_all_addable_physical_process_models().keys():
        if camel_case_to_underscores(process_class.__name__) == process_class_name:
            break
    else:
        raise Http404("Process class not found.")
    try:
        logs_whitelist = settings.CRAWLER_LOGS_WHITELIST
    except AttributeError:
        logs_whitelist = set()
    if process_class.__name__ not in logs_whitelist:
        permissions.assert_can_add_physical_process(request.user, process_class)
    assert "." not in process_class_name and "/" not in process_class_name
    filepath = os.path.join(settings.CRAWLER_LOGS_ROOT, process_class_name + ".log")
    log_content, log_timestamp = read_crawler_log(filepath)
    return render(request, "samples/log_viewer.html",
                  {"title": _("Log of crawler “{process_class_name}”").format(
                      process_class_name=process_class._meta.verbose_name_plural),
                   "log_content": log_content, "log_timestamp": log_timestamp})
コード例 #5
0
def get_lab_notebooks(user):
    """Get a list of all lab notebooks the user can see.

    :param user: the user whose allowed lab notebooks should be collected

    :type user: django.contrib.auth.models.User

    :return:
      List of all lab notebooks the user is allowed to see.  Every lab book is
      represented by a dictionary with two keys, namely ``"url"`` with the url
      to the lab book, and ``"label"`` with the name of the process (starting
      lowercase).

    :rtype: list of dict mapping str to unicode
    """
    lab_notebooks = []
    for process_class, process in get_all_addable_physical_process_models().items():
        try:
            url = django.core.urlresolvers.reverse(
                process_class._meta.app_label + ":lab_notebook_" + utils.camel_case_to_underscores(process["type"]),
                kwargs={"year_and_month": ""}, current_app=process_class._meta.app_label)
        except django.core.urlresolvers.NoReverseMatch:
            pass
        else:
            if has_permission_to_view_lab_notebook(user, process_class):
                lab_notebooks.append({"label": process["label_plural"], "url": url})
    lab_notebooks.sort(key=lambda process: process["label"].lower())
    return lab_notebooks
コード例 #6
0
ファイル: lab_notebook.py プロジェクト: msincan/juliabase
def show(request, process_name, year_and_month):
    """View for showing one month of the lab notebook for a particular
    physical process.  In ``urls.py``, you must give the entry for this view
    the name ``"lab_notebook_<camel_case_process_name>"``.

    :param request: the current HTTP Request object
    :param process_name: the class name of the model of the physical process,
        e.g. ``"LargeAreaDeposition"``
    :param year_and_month: the year and month to be displayed in the format
        ``YYYY/MM`` (the month may be single-digit)

    :type request: HttpRequest
    :type process_name: str
    :type year_and_month: str

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    process_class = get_all_models()[process_name]
    process_name = camel_case_to_underscores(process_name)
    permissions.assert_can_view_lab_notebook(request.user, process_class)
    if not year_and_month:
        try:
            timestamp = process_class.objects.latest().timestamp
        except process_class.DoesNotExist:
            timestamp = datetime.datetime.today()
        return HttpResponseSeeOther("{0}/{1}".format(timestamp.year, timestamp.month))
    year, month = parse_year_and_month(year_and_month)
    if request.method == "POST":
        year_month_form = YearMonthForm(request.POST)
        if year_month_form.is_valid():
            return HttpResponseSeeOther(django.core.urlresolvers.reverse(
                    "lab_notebook_" + process_name,
                    kwargs={"year_and_month": "{year}/{month}".format(**year_month_form.cleaned_data)}))
    else:
        year_month_form = YearMonthForm(initial={"year": year, "month": month})
    template = loader.get_template("samples/lab_notebook_" + process_name + ".html")
    template_context = RequestContext(request, process_class.get_lab_notebook_context(year, month))
    html_body = template.render(template_context)
    previous_url, next_url = get_previous_next_urls(process_name, year, month)
    try:
        export_url = django.core.urlresolvers.reverse(
            "export_lab_notebook_" + process_name,
            kwargs={"year_and_month": year_and_month}) + "?next=" + urlquote_plus(request.path)
    except django.core.urlresolvers.NoReverseMatch:
        export_url = None
    return render(request, "samples/lab_notebook.html",
                  {"title": capitalize_first_letter(_("lab notebook for {process_name}")
                                                    .format(process_name=process_class._meta.verbose_name_plural)),
                   "year": year, "month": month, "year_month": year_month_form,
                   "html_body": html_body, "previous_url": previous_url, "next_url": next_url,
                   "export_url": export_url})
コード例 #7
0
def view(request, process_class_name):
    """View for log files of crawlers.

    :param request: the current HTTP Request object
    :param process_class_name: the name of the crawler whose log file is about to be
        shown

    :type request: HttpRequest
    :type process_class_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    for process_class in permissions.get_all_addable_physical_process_models(
    ).keys():
        if camel_case_to_underscores(
                process_class.__name__) == process_class_name:
            break
    else:
        raise Http404("Process class not found.")
    try:
        logs_whitelist = settings.CRAWLER_LOGS_WHITELIST
    except AttributeError:
        logs_whitelist = set()
    if process_class.__name__ not in logs_whitelist:
        permissions.assert_can_add_physical_process(request.user,
                                                    process_class)
    assert "." not in process_class_name and "/" not in process_class_name
    filepath = os.path.join(settings.CRAWLER_LOGS_ROOT,
                            process_class_name + ".log")
    log_content, log_timestamp = read_crawler_log(filepath)
    return render(
        request, "samples/log_viewer.html", {
            "title":
            _("Log of crawler “{process_class_name}”").format(
                process_class_name=process_class._meta.verbose_name_plural),
            "log_content":
            log_content,
            "log_timestamp":
            log_timestamp
        })
コード例 #8
0
def show(request, process_name, year_and_month):
    """View for showing one month of the lab notebook for a particular
    physical process.  In ``urls.py``, you must give the entry for this view
    the name ``"lab_notebook_<camel_case_process_name>"``.

    :param request: the current HTTP Request object
    :param process_name: the class name of the model of the physical process,
        e.g. ``"LargeAreaDeposition"``
    :param year_and_month: the year and month to be displayed in the format
        ``YYYY/MM`` (the month may be single-digit)

    :type request: HttpRequest
    :type process_name: str
    :type year_and_month: str

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    process_class = get_all_models()[process_name]
    process_name = camel_case_to_underscores(process_name)
    namespace = process_class._meta.app_label
    permissions.assert_can_view_lab_notebook(request.user, process_class)
    if not year_and_month:
        try:
            timestamp = process_class.objects.latest().timestamp
        except process_class.DoesNotExist:
            timestamp = datetime.datetime.today()
        return HttpResponseSeeOther("{0}/{1}".format(timestamp.year,
                                                     timestamp.month))
    year, month = parse_year_and_month(year_and_month)
    if request.method == "POST":
        year_month_form = YearMonthForm(request.POST)
        if year_month_form.is_valid():
            return HttpResponseSeeOther(
                django.core.urlresolvers.reverse(
                    "{}:lab_notebook_{}".format(namespace, process_name),
                    kwargs={
                        "year_and_month":
                        "{year}/{month}".format(**year_month_form.cleaned_data)
                    }))
    else:
        year_month_form = YearMonthForm(initial={"year": year, "month": month})
    template = loader.get_template("samples/lab_notebook_" + process_name +
                                   ".html")
    template_context = RequestContext(
        request, process_class.get_lab_notebook_context(year, month))
    html_body = template.render(template_context.flatten())
    previous_url, next_url = get_previous_next_urls(process_name, namespace,
                                                    year, month)
    try:
        export_url = django.core.urlresolvers.reverse(
            "{}:export_lab_notebook_{}".format(namespace, process_name),
            kwargs={"year_and_month": year_and_month
                    }) + "?next=" + urlquote_plus(request.path)
    except django.core.urlresolvers.NoReverseMatch:
        export_url = None
    return render(
        request, "samples/lab_notebook.html", {
            "title":
            capitalize_first_letter(
                _("lab notebook for {process_name}").format(
                    process_name=process_class._meta.verbose_name_plural)),
            "year":
            year,
            "month":
            month,
            "year_month":
            year_month_form,
            "html_body":
            html_body,
            "previous_url":
            previous_url,
            "next_url":
            next_url,
            "export_url":
            export_url
        })
コード例 #9
0
    def physical_process(self,
                         class_name,
                         identifying_field=None,
                         url_name=None,
                         views={"add", "edit"}):
        """Add URLs for the views of the physical process `class_name`.  For the “add”
        and the “edit” view, an :samp:`edit(request, {process_class_name}_id)`
        function must exist.  In case of “add”, ``None`` is passed as the
        second parameter.  For the “custom show” view, a :samp:`show(request,
        {process_class_name}_id)` function must exist.  If there is an
        `identifying_field`, this is used for the second parameter name
        instead.  If no URL for a custom show view is requested, a default one
        is generated using a generic view function (which is mostly
        sufficient).

        :param class_name: Name of the physical process class,
            e.g. ``"ThicknessMeasurement"``.
        :param identifying_field: If applicable, name of the model field which
            serves as “poor man's” primary key.  If not given, the field name
            is derived from the model's ``JBMeta`` class, and if this fails,
            ``id`` is used.  This parameter is deprecated and will be removed
            in JuliaBase 1.2.
        :param url_name: The URL path component to be used for this process.  By
            default, this is the class name converted to underscores notation,
            with an “s” appended, e.g. ``"thickness_measurements"``.  It may
            contain slashs.
        :param views: The view functions for which URLs should be generated.
            You may choose from ``"add"``, ``"edit"``, ``"custom_show"``, and
            ``"lab_notebook"``.

        :type class_name: unicode
        :type identifying_field: unicode
        :type url_name: unicode
        :type views: set of unicode
        """
        class_name_with_underscores = camel_case_to_underscores(class_name)
        if not url_name:
            if class_name_with_underscores.endswith(("s", "x", "z")):
                url_name = class_name_with_underscores + "es"
            else:
                url_name = class_name_with_underscores + "s"
        assert not views - {"add", "edit", "custom_show", "lab_notebook"}
        normalized_id_field = identifying_field
        if not normalized_id_field:
            model = apps.get_model(self.app_label, class_name)
            try:
                normalized_id_field = model.JBMeta.identifying_field
            except AttributeError:
                normalized_id_field = class_name_with_underscores + "_id"
        if "lab_notebook" in views:
            self.url_patterns.extend([
                url(
                    r"^{}/lab_notebook/(?P<year_and_month>.*)/export/".format(
                        url_name), lab_notebook.export,
                    {"process_name": class_name},
                    "export_lab_notebook_" + class_name_with_underscores),
                url(
                    r"^{}/lab_notebook/(?P<year_and_month>.*)".format(
                        url_name), lab_notebook.show,
                    {"process_name": class_name},
                    "lab_notebook_" + class_name_with_underscores)
            ])
        if "add" in views or "edit" in views or "custom_view" in views:
            module = importlib.import_module(self.views_prefix +
                                             class_name_with_underscores)
            if "add" in views or "edit" in views:
                try:
                    edit_view_callable = module.EditView.as_view()
                except AttributeError:
                    edit_view_callable = module.edit
        if "add" in views:
            self.url_patterns.append(
                url(r"^{}/add/$".format(url_name), edit_view_callable,
                    {normalized_id_field: None},
                    "add_" + class_name_with_underscores))
        if "edit" in views:
            self.url_patterns.append(
                url(r"^{}/(?P<{}>.+)/edit/$".format(url_name,
                                                    normalized_id_field),
                    edit_view_callable,
                    name="edit_" + class_name_with_underscores))
        if "custom_show" in views:
            self.url_patterns.append(
                url(r"^{}/(?P<{}>.+)".format(url_name, normalized_id_field),
                    module.show,
                    name="show_" + class_name_with_underscores))
        else:
            self.url_patterns.append(
                url(r"^{}/(?P<process_id>.+)".format(url_name,
                                                     normalized_id_field),
                    samples.views.main.show_process,
                    {"process_name": class_name},
                    name="show_" + class_name_with_underscores))
コード例 #10
0
ファイル: urls.py プロジェクト: msincan/juliabase
    def physical_process(self, class_name, identifying_field=None, url_name=None, views={"add", "edit"}):
        """Add URLs for the views of the physical process `class_name`.  For the “add”
        and the “edit” view, an :samp:`edit(request, {process_class_name}_id)`
        function must exist.  In case of “add”, ``None`` is passed as the
        second parameter.  For the “custom show” view, a :samp:`show(request,
        {process_class_name}_id)` function must exist.  If there is an
        `identifying_field`, this is used for the second parameter name
        instead.  If no URL for a custom show view is requested, a default one
        is generated using a generic view function (which is mostly
        sufficient).

        :param class_name: Name of the physical process class,
            e.g. ``"ThicknessMeasurement"``.
        :param identifying_field: If applicable, name of the model field which
            serves as “poor man's” primary key.  If not given, the field name
            is derived from the model's ``JBMeta`` class, and if this fails,
            ``id`` is used.  This parameter is deprecated and will be removed
            in JuliaBase 1.2.
        :param url_name: The URL path component to be used for this process.  By
            default, this is the class name converted to underscores notation,
            with an “s” appended, e.g. ``"thickness_measurements"``.  It may
            contain slashs.
        :param views: The view functions for which URLs should be generated.
            You may choose from ``"add"``, ``"edit"``, ``"custom_show"``, and
            ``"lab_notebook"``.

        :type class_name: unicode
        :type identifying_field: unicode
        :type url_name: unicode
        :type views: set of unicode
        """
        class_name_with_underscores = camel_case_to_underscores(class_name)
        if not url_name:
            if class_name_with_underscores.endswith(("s", "x", "z")):
                url_name = class_name_with_underscores + "es"
            else:
                url_name = class_name_with_underscores + "s"
        assert not views - {"add", "edit", "custom_show", "lab_notebook"}
        normalized_id_field = identifying_field
        if not normalized_id_field:
            model = apps.get_model(self.app_label, class_name)
            try:
                normalized_id_field = model.JBMeta.identifying_field
            except AttributeError:
                normalized_id_field = class_name_with_underscores + "_id"
        if "lab_notebook" in views:
            self.url_patterns.extend([url(r"^{}/lab_notebook/(?P<year_and_month>.*)/export/".format(url_name),
                                          lab_notebook.export, {"process_name": class_name},
                                          "export_lab_notebook_" + class_name_with_underscores),
                                      url(r"^{}/lab_notebook/(?P<year_and_month>.*)".format(url_name),
                                          lab_notebook.show, {"process_name": class_name},
                                          "lab_notebook_" + class_name_with_underscores)])
        if "add" in views or "edit" in views or "custom_view" in views:
            module = importlib.import_module(self.views_prefix + class_name_with_underscores)
            if "add" in views or "edit" in views:
                try:
                    edit_view_callable = module.EditView.as_view()
                except AttributeError:
                    edit_view_callable = module.edit
        if "add" in views:
            self.url_patterns.append(url(r"^{}/add/$".format(url_name), edit_view_callable,
                                         {normalized_id_field: None}, "add_" + class_name_with_underscores))
        if "edit" in views:
            self.url_patterns.append(url(r"^{}/(?P<{}>.+)/edit/$".format(url_name, normalized_id_field), edit_view_callable,
                                         name="edit_" + class_name_with_underscores))
        if "custom_show" in views:
            self.url_patterns.append(url(r"^{}/(?P<{}>.+)".format(url_name, normalized_id_field), module.show,
                                         name="show_" + class_name_with_underscores))
        else:
            self.url_patterns.append(url(r"^{}/(?P<process_id>.+)".format(url_name, normalized_id_field),
                                         samples.views.main.show_process, {"process_name": class_name},
                                         name="show_" + class_name_with_underscores))
コード例 #11
0
ファイル: feed.py プロジェクト: Midnighter/juliabase
def show(request, username, user_hash):
    """View which doesn't generate an HTML page but an Atom 1.0 feed with
    current news for the user.

    The problem we have to deal with here is that the feed-reading program
    cannot login.  Therefore, it must be possible to fetch the feed without
    being logged-in.  The username is no problem, it is part of the path.
    Additionally, a secret hash (see `permissions.get_user_hash`) is appended
    to the URL in the query string.  This should be enough security for this
    purpose.

    :param request: the current HTTP Request object
    :param username: the login name of the user for whic the news should be
        delivered
    :param user_hash: the secret user hash, which works as an ersatz password
        because the feed clients can't login.

    :type request: HttpRequest
    :type username: str
    :type user_hash: str

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    user = get_object_or_404(django.contrib.auth.models.User, username=username)
    permissions.assert_can_view_feed(user_hash, user)
    feed_absolute_url = request.build_absolute_uri(django.core.urlresolvers.reverse(
        show, kwargs={"username": username, "user_hash": user_hash}))
    feed = ElementTree.Element("feed", xmlns="http://www.w3.org/2005/Atom")
    feed.attrib["xml:base"] = request.build_absolute_uri("/")
    ElementTree.SubElement(feed, "id").text = feed_absolute_url
    ElementTree.SubElement(feed, "title").text = \
        _("JuliaBase news for {user_name}").format(user_name=get_really_full_name(user))
    entries = [entry.actual_instance for entry in user.feed_entries.all()]
    if entries:
        ElementTree.SubElement(feed, "updated").text = format_timestamp(entries[0].timestamp)
    else:
        ElementTree.SubElement(feed, "updated").text = format_timestamp(datetime.datetime.now())
    author = ElementTree.SubElement(feed, "author")
    if settings.ADMINS:
        ElementTree.SubElement(author, "name").text, ElementTree.SubElement(author, "email").text = settings.ADMINS[0]
    ElementTree.SubElement(feed, "link", rel="self", href=feed_absolute_url)
    ElementTree.SubElement(feed, "generator", version=__version__).text = "JuliaBase"
    ElementTree.SubElement(feed, "icon").text = request.build_absolute_uri("/static/juliabase/juliabase_logo.png")
    only_important = user.samples_user_details.only_important_news
    for entry in entries:
        if only_important and not entry.important:
            continue
        if isinstance(entry, (models.FeedNewSamples, models.FeedMovedSamples, models.FeedCopiedMySamples,
                              models.FeedEditedSamples)):
            # Remove orphaned entries (i.e. whose samples have been deleted)
            # because they are a) phony and b) cause tracebacks.
            if entry.samples.count() == 0:
                entry.delete()
                continue
        entry_element = ElementTree.SubElement(feed, "entry")
        ElementTree.SubElement(entry_element, "id").text = \
            "tag:{0},{1}:{2}".format(request.build_absolute_uri("/").partition("//")[2][:-1],
                                     entry.timestamp.strftime("%Y-%m-%d"), entry.sha1_hash)
        metadata = entry.get_metadata()
        ElementTree.SubElement(entry_element, "title").text = metadata["title"]
        ElementTree.SubElement(entry_element, "updated").text = format_timestamp(entry.timestamp)
        author = ElementTree.SubElement(entry_element, "author")
        ElementTree.SubElement(author, "name").text = get_really_full_name(entry.originator)
        if entry.originator.email:
            ElementTree.SubElement(author, "email").text = entry.originator.email
        category = ElementTree.SubElement(
            entry_element, "category", term=metadata["category term"], label=metadata["category label"])
        if "link" in metadata:
            ElementTree.SubElement(entry_element, "link", rel="alternate", href=request.build_absolute_uri(metadata["link"]))
        template = loader.get_template("samples/" + camel_case_to_underscores(entry.__class__.__name__) + ".html")
        content = ElementTree.SubElement(entry_element, "content")
        context_dict = {"entry": entry}
        context_dict.update(entry.get_additional_template_context(user))
        content.text = template.render(Context(context_dict))
        content.attrib["type"] = "html"
#    indent(feed)
    return HttpResponse("""<?xml version="1.0"?>\n"""
                        """<?xml-stylesheet type="text/xsl" href="/static/samples/xslt/atom2html.xslt"?>\n"""
                        + ElementTree.tostring(feed, "utf-8").decode("utf-8"),
                        content_type="application/xml; charset=utf-8")
コード例 #12
0
 def __init__(self, **kwargs):
     self.model = self.model or self.form_class.Meta.model
     self.class_name = camel_case_to_underscores(self.model.__name__)
     self.template_name = "samples/edit_{}.html".format(self.class_name)
     super(ProcessWithoutSamplesView, self).__init__(**kwargs)
     self.forms = {}
コード例 #13
0
ファイル: feed.py プロジェクト: msincan/juliabase
def show(request, username, user_hash):
    """View which doesn't generate an HTML page but an Atom 1.0 feed with
    current news for the user.

    The problem we have to deal with here is that the feed-reading program
    cannot login.  Therefore, it must be possible to fetch the feed without
    being logged-in.  The username is no problem, it is part of the path.
    Additionally, a secret hash (see `permissions.get_user_hash`) is appended
    to the URL in the query string.  This should be enough security for this
    purpose.

    :param request: the current HTTP Request object
    :param username: the login name of the user for which the news should be
        delivered
    :param user_hash: the secret user hash, which works as an ersatz password
        because the feed clients can't login.

    :type request: HttpRequest
    :type username: str
    :type user_hash: str

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    user = get_object_or_404(django.contrib.auth.models.User, username=username)
    permissions.assert_can_view_feed(user_hash, user)
    feed_absolute_url = request.build_absolute_uri(django.core.urlresolvers.reverse(
        show, kwargs={"username": username, "user_hash": user_hash}))
    feed = ElementTree.Element("feed", xmlns="http://www.w3.org/2005/Atom")
    feed.attrib["xml:base"] = request.build_absolute_uri("/")
    ElementTree.SubElement(feed, "id").text = feed_absolute_url
    ElementTree.SubElement(feed, "title").text = \
        _("JuliaBase news for {user_name}").format(user_name=get_really_full_name(user))
    entries = [entry.actual_instance for entry in user.feed_entries.all()]
    if entries:
        ElementTree.SubElement(feed, "updated").text = format_timestamp(entries[0].timestamp)
    else:
        ElementTree.SubElement(feed, "updated").text = format_timestamp(datetime.datetime.now())
    author = ElementTree.SubElement(feed, "author")
    if settings.ADMINS:
        ElementTree.SubElement(author, "name").text, ElementTree.SubElement(author, "email").text = settings.ADMINS[0]
    ElementTree.SubElement(feed, "link", rel="self", href=feed_absolute_url)
    ElementTree.SubElement(feed, "generator", version=__version__).text = "JuliaBase"
    ElementTree.SubElement(feed, "icon").text = request.build_absolute_uri("/static/juliabase/juliabase_logo.png")
    only_important = user.samples_user_details.only_important_news
    for entry in entries:
        if only_important and not entry.important:
            continue
        if isinstance(entry, (models.FeedNewSamples, models.FeedMovedSamples, models.FeedCopiedMySamples,
                              models.FeedEditedSamples)):
            # Remove orphaned entries (i.e. whose samples have been deleted)
            # because they are a) phony and b) cause tracebacks.
            if entry.samples.count() == 0:
                entry.delete()
                continue
        entry_element = ElementTree.SubElement(feed, "entry")
        ElementTree.SubElement(entry_element, "id").text = \
            "tag:{0},{1}:{2}".format(request.build_absolute_uri("/").partition("//")[2][:-1],
                                     entry.timestamp.strftime("%Y-%m-%d"), entry.sha1_hash)
        metadata = entry.get_metadata()
        ElementTree.SubElement(entry_element, "title").text = metadata["title"]
        ElementTree.SubElement(entry_element, "updated").text = format_timestamp(entry.timestamp)
        author = ElementTree.SubElement(entry_element, "author")
        ElementTree.SubElement(author, "name").text = get_really_full_name(entry.originator)
        if entry.originator.email:
            ElementTree.SubElement(author, "email").text = entry.originator.email
        category = ElementTree.SubElement(
            entry_element, "category", term=metadata["category term"], label=metadata["category label"])
        if "link" in metadata:
            ElementTree.SubElement(entry_element, "link", rel="alternate", href=request.build_absolute_uri(metadata["link"]))
        template = loader.get_template("samples/" + camel_case_to_underscores(entry.__class__.__name__) + ".html")
        content = ElementTree.SubElement(entry_element, "content")
        context_dict = {"entry": entry}
        context_dict.update(entry.get_additional_template_context(user))
        content.text = template.render(Context(context_dict))
        content.attrib["type"] = "html"
#    indent(feed)
    return HttpResponse("""<?xml version="1.0"?>\n"""
                        """<?xml-stylesheet type="text/xsl" href="/static/samples/xslt/atom2html.xslt"?>\n"""
                        + ElementTree.tostring(feed, "utf-8").decode("utf-8"),
                        content_type="application/xml; charset=utf-8")
コード例 #14
0
ファイル: main.py プロジェクト: Midnighter/juliabase
def main_menu(request):
    """The main menu view.  It displays the “My Samples” list in a dynamic way, and
    the actions that depend on the specific permissions a user has.  The rest
    is served static.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    my_topics, topicless_samples = utils.build_structured_sample_list(
        request.user)
    allowed_physical_processes = permissions.get_allowed_physical_processes(
        request.user)
    lab_notebooks = []
    for process_class, process in permissions.get_all_addable_physical_process_models(
    ).items():
        try:
            url = django.core.urlresolvers.reverse(
                "lab_notebook_" + camel_case_to_underscores(process["type"]),
                kwargs={"year_and_month": ""})
        except django.core.urlresolvers.NoReverseMatch:
            pass
        else:
            if permissions.has_permission_to_view_lab_notebook(
                    request.user, process_class):
                lab_notebooks.append({
                    "label": process["label_plural"],
                    "url": url
                })
    if lab_notebooks:
        lab_notebooks.sort(key=lambda process: process["label"].lower())
    return render(
        request, "samples/main_menu.html", {
            "title":
            _("Main menu"),
            "my_topics":
            my_topics,
            "topicless_samples":
            topicless_samples,
            "add_sample_url":
            django.core.urlresolvers.reverse(settings.ADD_SAMPLES_VIEW),
            "user_hash":
            permissions.get_user_hash(request.user),
            "can_add_topic":
            permissions.has_permission_to_edit_users_topics(request.user),
            "can_edit_topics":
            any(
                permissions.has_permission_to_edit_topic(request.user, topic)
                for topic in Topic.objects.all()),
            "can_add_external_operator":
            permissions.has_permission_to_add_external_operator(request.user),
            "has_external_contacts":
            request.user.external_contacts.exists() or
            (ExternalOperator.objects.exists() and request.user.is_superuser),
            "can_rename_samples":
            request.user.has_perm("samples.rename_samples")
            or request.user.is_superuser,
            "physical_processes":
            allowed_physical_processes,
            "lab_notebooks":
            lab_notebooks
        })
コード例 #15
0
ファイル: class_views.py プロジェクト: msincan/juliabase
 def __init__(self, **kwargs):
     self.model = self.model or self.form_class.Meta.model
     self.class_name = camel_case_to_underscores(self.model.__name__)
     self.template_name = "samples/edit_{}.html".format(self.class_name)
     super(ProcessWithoutSamplesView, self).__init__(**kwargs)
     self.forms = {}