Changeset View
Changeset View
Standalone View
Standalone View
swh/web/api/views/content.py
# Copyright (C) 2015-2022 The Software Heritage developers | # Copyright (C) 2015-2022 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU Affero General Public License version 3, or any later version | # License: GNU Affero General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import functools | import functools | ||||
import io | |||||
from typing import Optional | from typing import Optional | ||||
from django.http import HttpResponse | from django.http import FileResponse | ||||
from rest_framework.request import Request | from rest_framework.request import Request | ||||
from swh.web.api import utils | from swh.web.api import utils | ||||
from swh.web.api.apidoc import api_doc, format_docstring | from swh.web.api.apidoc import api_doc, format_docstring | ||||
from swh.web.api.apiurls import api_route | from swh.web.api.apiurls import api_route | ||||
from swh.web.api.views.utils import api_lookup | from swh.web.api.views.utils import api_lookup | ||||
from swh.web.common import archive | from swh.web.common import archive | ||||
from swh.web.common.exc import NotFoundExc | from swh.web.common.exc import NotFoundExc | ||||
▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | .. http:get:: /api/1/content/[(hash_type):](hash)/raw/ | ||||
:statuscode 404: requested content can not be found in the archive | :statuscode 404: requested content can not be found in the archive | ||||
**Example:** | **Example:** | ||||
.. parsed-literal:: | .. parsed-literal:: | ||||
:swh_web_api:`content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/raw/` | :swh_web_api:`content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/raw/` | ||||
""" | """ | ||||
def generate(content): | |||||
yield content["data"] | |||||
content_raw = archive.lookup_content_raw(q) | content_raw = archive.lookup_content_raw(q) | ||||
if not content_raw: | if not content_raw: | ||||
raise NotFoundExc("Content %s is not found." % q) | raise NotFoundExc("Content %s is not found." % q) | ||||
filename = request.query_params.get("filename") | filename = request.query_params.get("filename") | ||||
if not filename: | if not filename: | ||||
filename = "content_%s_raw" % q.replace(":", "_") | filename = "content_%s_raw" % q.replace(":", "_") | ||||
response = HttpResponse( | return FileResponse( | ||||
generate(content_raw), content_type="application/octet-stream" | io.BytesIO(content_raw["data"]), # not copied, as this is never modified | ||||
filename=filename, | |||||
content_type="application/octet-stream", | |||||
as_attachment=True, | |||||
) | ) | ||||
response["Content-disposition"] = "attachment; filename=%s" % filename | |||||
return response | |||||
@api_route(r"/content/symbol/(?P<q>.+)/", "api-1-content-symbol") | @api_route(r"/content/symbol/(?P<q>.+)/", "api-1-content-symbol") | ||||
@api_doc("/content/symbol/", tags=["hidden"]) | @api_doc("/content/symbol/", tags=["hidden"]) | ||||
def api_content_symbol(request: Request, q: str): | def api_content_symbol(request: Request, q: str): | ||||
"""Search content objects by `Ctags <http://ctags.sourceforge.net/>`_-style | """Search content objects by `Ctags <http://ctags.sourceforge.net/>`_-style | ||||
symbol (e.g., function name, data type, method, ...). | symbol (e.g., function name, data type, method, ...). | ||||
▲ Show 20 Lines • Show All 165 Lines • Show Last 20 Lines |