diff --git a/docs/conf.py b/docs/conf.py index 6aeb9dd9..3149243b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,7 +1,15 @@ -import os +# flake8: noqa + import django +import os + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'swh.web.settings.development') -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "swh.web.settings.development") django.setup() -from swh.docs.sphinx.conf import * # NoQA +import swh.docs.sphinx.conf as sphinx_conf + +from swh.web.doc_config import customize_sphinx_conf +customize_sphinx_conf(sphinx_conf) + +from swh.docs.sphinx.conf import * diff --git a/docs/index.rst b/docs/index.rst index 12eac056..798d3aad 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,17 +1,19 @@ Software Heritage Web Applications - Development Documentation =============================================================== .. toctree:: :maxdepth: 2 :caption: Contents: dev-info.md - uri-scheme + uri-scheme-api + uri-scheme-browse Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` + diff --git a/docs/uri-scheme-api-content.rst b/docs/uri-scheme-api-content.rst new file mode 100644 index 00000000..2779f22b --- /dev/null +++ b/docs/uri-scheme-api-content.rst @@ -0,0 +1,275 @@ +Content +------- + +.. http:get:: /api/1/content/[(hash_type):](hash)/ + + Get information about a content (aka a "blob") object. + In the SWH archive, a content object is identified based on checksum + values computed using various hashing algorithms. + + :param string hash_type: optional parameter specifying which hashing algorithm has been used + to compute the content checksum. It can be either *sha1*, *sha1_git*, *sha256* + or *blake2s256*. If that parameter is not provided, it is assumed that the + hashing algorithm used is *sha1*. + :param string hash: hexadecimal representation of the checksum value computed with + the specified hashing algorithm. + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :>json object checksums: object holding the computed checksum values for the requested content + :>json string data_url: link to :http:get:`/api/1/content/[(hash_type):](hash)/raw/` + for downloading the content raw bytes + :>json string filetype_url: link to :http:get:`/api/1/content/[(hash_type):](hash)/filetype/` + for getting information about the content MIME type + :>json string language_url: link to :http:get:`/api/1/content/[(hash_type):](hash)/language/` + for getting information about the programming language used in the content + :>json number length: length of the content in bytes + :>json string license_url: link to :http:get:`/api/1/content/[(hash_type):](hash)/license/` + for getting information about the license of the content + + :statuscode 200: no error + :statuscode 400: an invalid *hash_type* or *hash* has been provided + :statuscode 404: requested content can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`content/sha1_git:fe95a46679d128ff167b7c55df5d02356c5a1ae1/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "checksums": { + "blake2s256": "791e07fcea240ade6dccd0a9309141673c31242cae9c237cf3855e151abc78e9", + "sha1": "dc2830a9e72f23c1dfebef4413003221baa5fb62", + "sha1_git": "fe95a46679d128ff167b7c55df5d02356c5a1ae1", + "sha256": "b5c7fe0536f44ef60c8780b6065d30bca74a5cd06d78a4a71ba1ad064770f0c9" + }, + "data_url": "/api/1/content/sha1_git:fe95a46679d128ff167b7c55df5d02356c5a1ae1/raw/", + "filetype_url": "/api/1/content/sha1_git:fe95a46679d128ff167b7c55df5d02356c5a1ae1/filetype/", + "language_url": "/api/1/content/sha1_git:fe95a46679d128ff167b7c55df5d02356c5a1ae1/language/", + "length": 151810, + "license_url": "/api/1/content/sha1_git:fe95a46679d128ff167b7c55df5d02356c5a1ae1/license/", + "status": "visible" + } + +.. http:get:: /api/1/content/[(hash_type):](hash)/raw/ + + Get the raw content of a content object (aka a "blob"), as a byte sequence. + + :param string hash_type: optional parameter specifying which hashing algorithm has been used + to compute the content checksum. It can be either *sha1*, *sha1_git*, *sha256* + or *blake2s256*. If that parameter is not provided, it is assumed that the + hashing algorithm used is *sha1*. + :param string hash: hexadecimal representation of the checksum value computed with + the specified hashing algorithm. + :query string filename: if provided, the downloaded content will get that filename + + :resheader Content-Type: application/octet-stream + + :statuscode 200: no error + :statuscode 400: an invalid *hash_type* or *hash* has been provided + :statuscode 404: requested content can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/raw/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-disposition: attachment; filename=content_sha1_dc2830a9e72f23c1dfebef4413003221baa5fb62_raw + Content-Type: application/octet-stream + + /* 'dir', 'vdir' and 'ls' directory listing programs for GNU. + Copyright (C) 1985-2015 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + + ... + +.. http:get:: /api/1/content/[(hash_type):](hash)/filetype/ + + Get information about the detected MIME type of a content object. + + :param string hash_type: optional parameter specifying which hashing algorithm has been used + to compute the content checksum. It can be either *sha1*, *sha1_git*, *sha256* + or *blake2s256*. If that parameter is not provided, it is assumed that the + hashing algorithm used is *sha1*. + :param string hash: hexadecimal representation of the checksum value computed with + the specified hashing algorithm. + + :>json object content_url: link to :http:get:`/api/1/content/[(hash_type):](hash)/` for + getting information about the content + :>json string encoding: the detected content encoding + :>json string id: the *sha1* identifier of the content + :>json string mimetype: the detected MIME type of the content + :>json object tool: information about the tool used to detect the content filetype + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :statuscode 200: no error + :statuscode 400: an invalid *hash_type* or *hash* has been provided + :statuscode 404: requested content can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/filetype/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "content_url": "/api/1/content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/", + "encoding": "us-ascii", + "id": "dc2830a9e72f23c1dfebef4413003221baa5fb62", + "mimetype": "text/x-c", + "tool": { + "configuration": { + "command_line": "file --mime " + }, + "id": 7, + "name": "file", + "version": "5.22" + } + } + +.. http:get:: /api/1/content/[(hash_type):](hash)/language/ + + Get information about the programming language used in a content object. + + :param string hash_type: optional parameter specifying which hashing algorithm has been used + to compute the content checksum. It can be either *sha1*, *sha1_git*, *sha256* + or *blake2s256*. If that parameter is not provided, it is assumed that the + hashing algorithm used is *sha1*. + :param string hash: hexadecimal representation of the checksum value computed with + the specified hashing algorithm. + + :>json object content_url: link to :http:get:`/api/1/content/[(hash_type):](hash)/` for + getting information about the content + :>json string id: the *sha1* identifier of the content + :>json string lang: the detected programming language if any + :>json object tool: information about the tool used to detect the programming language + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :statuscode 200: no error + :statuscode 400: an invalid *hash_type* or *hash* has been provided + :statuscode 404: requested content can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/language/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "content_url": "/api/1/content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/", + "id": "dc2830a9e72f23c1dfebef4413003221baa5fb62", + "lang": "c", + "tool": { + "configuration": { + "debian-package": "python3-pygments", + "max_content_size": 10240, + "type": "library" + }, + "id": 8, + "name": "pygments", + "version": "2.0.1+dfsg-1.1+deb8u1" + } + } + + +.. http:get:: /api/1/content/[(hash_type):](hash)/license/ + + Get information about the license of a content object. + + :param string hash_type: optional parameter specifying which hashing algorithm has been used + to compute the content checksum. It can be either *sha1*, *sha1_git*, *sha256* + or *blake2s256*. If that parameter is not provided, it is assumed that the + hashing algorithm used is *sha1*. + :param string hash: hexadecimal representation of the checksum value computed with + the specified hashing algorithm. + + :>json object content_url: link to :http:get:`/api/1/content/[(hash_type):](hash)/` for + getting information about the content + :>json string id: the *sha1* identifier of the content + :>json array licenses: array of strings containing the detected license names if any + :>json object tool: information about the tool used to detect the license + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :statuscode 200: no error + :statuscode 400: an invalid *hash_type* or *hash* has been provided + :statuscode 404: requested content can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/license/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "content_url": "/api/1/content/sha1:dc2830a9e72f23c1dfebef4413003221baa5fb62/", + "id": "dc2830a9e72f23c1dfebef4413003221baa5fb62", + "licenses": [ + "GPL-3.0+" + ], + "tool": { + "configuration": { + "command_line": "nomossa " + }, + "id": 1, + "name": "nomos", + "version": "3.1.0rc2-31-ga2cbb8c" + } + } diff --git a/docs/uri-scheme-api-directory.rst b/docs/uri-scheme-api-directory.rst new file mode 100644 index 00000000..7d7d37bd --- /dev/null +++ b/docs/uri-scheme-api-directory.rst @@ -0,0 +1,85 @@ +Directory +--------- + +.. http:get:: /api/1/directory/(sha1_git)/[(path)/] + + Get information about directory objects. + Directories are identified by *sha1* checksums, compatible with Git directory identifiers. + See :func:`swh.model.identifiers.directory_identifier` in our data model module for details + about how they are computed. + + When given only a directory identifier, this endpoint returns information about the directory itself, + returning its content (usually a list of directory entries). When given a directory identifier and a + path, this endpoint returns information about the directory entry pointed by the relative path, + starting path resolution from the given directory. + + :param string sha1_git: hexadecimal representation of the directory *sha1_git* identifier + :param string path: optional parameter to get information about the directory entry + pointed by that relative path + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :>json object checksums: object holding the computed checksum values for a directory entry + (only for file entries) + :>json string dir_id: *sha1_git* identifier of the requested directory + :>json number length: length of a directory entry in bytes (only for file entries) + for getting information about the content MIME type + :>json string name: the directory entry name + :>json number perms: permissions for the directory entry + :>json string target: *sha1_git* identifier of the directory entry + :>json string target_url: link to :http:get:`/api/1/content/[(hash_type):](hash)/` + or :http:get:`/api/1/directory/(sha1_git)/[(path)/]` depending on the directory entry type + :>json string type: the type of the directory entry, can be either *dir*, *file* or *rev* + + :statuscode 200: no error + :statuscode 400: an invalid *hash_type* or *hash* has been provided + :statuscode 404: requested directory can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`directory/977fc4b98c0e85816348cebd3b12026407c368b6/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + [ + { + "checksums": { + "sha1": "e2d79ae437210941840f49966497cc348c7e817f", + "sha1_git": "58471109208922c9ee8c4b06135725f03ed16814", + "sha256": "2b7001f4819e898776b45b2fa3411018b7bc24e38afbb351691c32508eb2ae5d" + }, + "dir_id": "977fc4b98c0e85816348cebd3b12026407c368b6", + "length": 582, + "name": ".bzrignore", + "perms": 33188, + "status": "visible", + "target": "58471109208922c9ee8c4b06135725f03ed16814", + "target_url": "/api/1/content/sha1_git:58471109208922c9ee8c4b06135725f03ed16814/", + "type": "file" + }, + { + "checksums": { + "sha1": "f47aabb47381119cf72add7633bc095ca2cd030d", + "sha1_git": "2106da61725973b81a63a817ec6f245706af4353", + "sha256": "4f0475fac23bcd3ebceceecffb0d4facc5a413f6d9a0287185fb75638b8e9c69" + }, + "dir_id": "977fc4b98c0e85816348cebd3b12026407c368b6", + "length": 453, + "name": ".codecov.yml", + "perms": 33188, + "status": "visible", + "target": "2106da61725973b81a63a817ec6f245706af4353", + "target_url": "/api/1/content/sha1_git:2106da61725973b81a63a817ec6f245706af4353/", + "type": "file" + }, + + ] diff --git a/docs/uri-scheme-api-origin.rst b/docs/uri-scheme-api-origin.rst new file mode 100644 index 00000000..6ac98f79 --- /dev/null +++ b/docs/uri-scheme-api-origin.rst @@ -0,0 +1,210 @@ +Origin +------ + +Information +^^^^^^^^^^^ + +.. http:get:: /api/1/origin/(origin_id)/ + + Get information about a software origin from its unique (but otherwise meaningless) + identifier. + + :param int origin_id: a SWH origin identifier + + :>json number id: the origin unique identifier + :>json string origin_visits_url: link to in order to get information about the SWH + visits for that origin + :>json string type: the type of software origin (*git*, *svn*, *hg*, *deb*, *ftp*, ...) + :>json string url: the origin canonical url + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`origin/1/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "id": 1, + "origin_visits_url": "/api/1/origin/1/visits/", + "type": "git", + "url": "https://github.com/hylang/hy" + } + +.. http:get:: /api/1/origin/(origin_type)/url/(origin_url)/ + + Get information about a software origin from its type and canonical url. + + :param string origin_type: the origin type (*git*, *svn*, *hg*, *deb*, *ftp*, ...) + :param string origin_url: the origin url + + :>json number id: the origin unique identifier + :>json string origin_visits_url: link to in order to get information about the SWH + visits for that origin + :>json string type: the type of software origin (*git*, *svn*, *hg*, *deb*, *ftp*, ...) + :>json string url: the origin canonical url + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`origin/git/url/https://github.com/python/cpython/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "id": 13706355, + "origin_visits_url": "/api/1/origin/13706355/visits/", + "type": "git", + "url": "https://github.com/python/cpython" + } + +Visits +^^^^^^ + +.. http:get:: /api/1/origin/(origin_id)/visits/ + + Get information about all visits of a software origin. + + :param int origin_id: a SWH origin identifier + :query int per_page: specify the number of visits to list, for pagination purposes + :query int last_visit: visit to start listing from, for pagination purposes + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + :resheader Link: indicates that a subsequent result page is available and contains + the url pointing to it + + :>json string date: ISO representation of the visit date (in UTC) + :>json number id: the unique identifier of the origin + :>json string origin_visit_url: link to :http:get:`/api/1/origin/(origin_id)/visit/(visit_id)/` + in order to get information about the visit + :>json string status: status of the visit (either *full*, *partial* or *ongoing*) + :>json number visit: the unique identifier of the visit + + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`origin/1/visits/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Link: ; rel="next" + Content-Type: application/json + + [ + { + "date": "2015-08-04T22:26:14.804009+00:00", + "origin": 1, + "origin_visit_url": "/api/1/origin/1/visit/1/", + "status": "full", + "visit": 1 + }, + { + "date": "2016-02-22T16:56:16.725068+00:00", + "metadata": {}, + "origin": 1, + "origin_visit_url": "/api/1/origin/1/visit/2/", + "status": "full", + "visit": 2 + }, + ] + +.. http:get:: /api/1/origin/(origin_id)/visit/(visit_id)/ + + Get information about a specific visit of a software origin. + + :param int origin_id: a SWH origin identifier + :param int visit_id: a visit identifier + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :>json string date: ISO representation of the visit date (in UTC) + :>json object occurrences: object containing all branches associated to the origin found + during the visit, for each of them the associated SWH revision id is given but also + a link to in order to get information about it + :>json number origin: the origin unique identifier + :>json string origin_url: link to get information about the origin + :>json string status: status of the visit (either *full*, *partial* or *ongoing*) + :>json number visit: the unique identifier of the visit + + :statuscode 200: no error + :statuscode 404: requested origin or visit can not be found in the SWH archive + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`origin/1500/visit/1/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "date": "2015-08-23T17:48:46.800813+00:00", + "occurrences": { + "refs/heads/master": { + "target": "83c20a6a63a7ebc1a549d367bc07a61b926cecf3", + "target_type": "revision", + "target_url": "/api/1/revision/83c20a6a63a7ebc1a549d367bc07a61b926cecf3/" + }, + "refs/heads/wiki": { + "target": "71f667aeb5d02562f2fa0941ad91df69c474ff3b", + "target_type": "revision", + "target_url": "/api/1/revision/71f667aeb5d02562f2fa0941ad91df69c474ff3b/" + }, + "refs/tags/dpkt-1.6": { + "target": "7fc0fd582812af36064d1c85fe51e33227920479", + "target_type": "revision", + "target_url": "/api/1/revision/7fc0fd582812af36064d1c85fe51e33227920479/" + }, + "refs/tags/dpkt-1.7": { + "target": "0c9dbfbc0974ec8ac1d8253aa1092366a03633a8", + "target_type": "revision", + "target_url": "/api/1/revision/0c9dbfbc0974ec8ac1d8253aa1092366a03633a8/" + } + }, + "origin": 1500, + "origin_url": "/api/1/origin/1500/", + "status": "full", + "visit": 1 + } diff --git a/docs/uri-scheme-api-stat.rst b/docs/uri-scheme-api-stat.rst new file mode 100644 index 00000000..4e2057af --- /dev/null +++ b/docs/uri-scheme-api-stat.rst @@ -0,0 +1,65 @@ +Archive statistics +------------------ + +.. http:get:: /api/1/stat/counters + + Get statistics about the content of the archive. + + :>json number content: current number of content objects (aka files) in the SWH archive + :>json number directory: current number of directory objects in the SWH archive + :>json number directory_entry_dir: current number of SWH directory entries + pointing to others SWH directories in the SWH archive + :>json number directory_entry_file: current number of SWH directory entries + pointing to SWH content objects in the SWH archive + :>json number directory_entry_rev: current number of SWH directory entries + pointing to SWH revision objects (e.g. git submodules) in the SWH archive + :>json number entity: current number of SWH entities (a SWH entity is either + a *group_of_entities*, a *group_of_persons*, a *project*, a *person*, an *organization*, + or a *hosting* service) in the SWH archive + :>json number occurrence: current number of SWH occurences (an occurrence may be assimilated + to a branch found during a SWH crawl of a repository) in the SWH archive + :>json number origin: current number of SWH origins (an origin is a "place" where code + source can be found, e.g. a git repository, a tarball, ...) in the SWH archive + :>json number person: current number of SWH persons (code source authors or commiters) + in the SWH archive + :>json number release: current number of SWH releases objects in the SWH archive + :>json number revision: current number of SWH revision objects (aka commits) in the SWH archive + :>json number skipped_content: current number of content objects (aka files) which where + not inserted in the SWH archive + + :reqheader Accept: the response content type depends on :mailheader:`Accept` header: + either *application/json* (default) or *application/yaml* + :resheader Content-Type: this depends on :mailheader:`Accept` header of request + + :statuscode 200: no error + + **Request**: + + .. parsed-literal:: + + $ curl -i :swh_web_api:`stat/counters/` + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + { + "content": 3837301367, + "directory": 3385342732, + "directory_entry_dir": 2696063206, + "directory_entry_file": 3969668591, + "directory_entry_rev": 8201450, + "entity": 7101551, + "entity_history": 7148571, + "occurrence": 538691292, + "occurrence_history": 554791126, + "origin": 65642044, + "person": 17211993, + "release": 6666960, + "revision": 879725958, + "revision_history": 908684112, + "skipped_content": 19383 + } diff --git a/docs/uri-scheme-api.rst b/docs/uri-scheme-api.rst new file mode 100644 index 00000000..5567e5e4 --- /dev/null +++ b/docs/uri-scheme-api.rst @@ -0,0 +1,15 @@ +.. _swh-web-api-urls: + +SWH Web API URLs +================ + +.. include:: uri-scheme-api-content.rst + +.. include:: uri-scheme-api-directory.rst + +.. include:: uri-scheme-api-origin.rst + +.. include:: uri-scheme-api-stat.rst + + + diff --git a/docs/uri-scheme-browse-content.rst b/docs/uri-scheme-browse-content.rst new file mode 100644 index 00000000..237fa301 --- /dev/null +++ b/docs/uri-scheme-browse-content.rst @@ -0,0 +1,83 @@ +Content +^^^^^^^ + +.. http:get:: /browse/content/[(algo_hash):](hash)/ + + HTML view that displays a SWH content identified by its hash value. + + If the content to display is textual, it will be highlighted client-side + if possible using highlightjs_. In order for that operation to be + performed, a programming language must first be associated to the content. + The following procedure is used in order to find the language: + + 1) First try to find a language from the content filename + (provided as query parameter when navigating from a directory view). + + 2) If no language has been found from the filename, + try to find one from the content mime type. + The mime type is retrieved from the content metadata stored + in the SWH archive or is computed server-side using Python + magic module. + + When that view is called in the context of a navigation coming from + a directory view, a breadcrumb will be displayed on top of the rendered + content in order to easily navigate up to the associated root directory. + In that case, the path query parameter will be used and filled with the path + of the file relative to the root directory. + + :param string algo_hash: optional parameter to indicate the algorithm used + to compute the content checksum (can be either *sha1*, + *sha1_git*, *sha256* or *blake2s256*, default to *sha1*) + :param string hash: hexadecimal representation for the checksum from which + to retrieve the associated content in the SWH archive + :query string path: describe the path of the content relative to a root + directory (used to add context aware navigation links when navigating + from a directory view) + :statuscode 200: no error + :statuscode 400: an invalid query string has been provided + :statuscode 404: requested content can not be found in the SWH archive + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`content/sha1_git:f5d0b39a0cdddb91a31a537052b7d8d31a4aa79f/` + :swh_web_browse:`content/blake2s256:1cc1e3124957c9be8a454c58e92eb925cf4aa9823984bd01451c5b7e0fee99d1/` + :swh_web_browse:`content/sha1:1cb1447c1c7ddc1b03eac88398e40bd914d46b62/` + :swh_web_browse:`content/sha256:8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903/` + +.. http:get:: /browse/content/[(algo_hash):](hash)/raw/ + + HTML view that produces a raw display of a SWH content identified by its hash value. + + The behaviour of that view depends on the mime type of the requested content. + If the mime type is from the text family, the view will return a response whose + content type is 'text/plain' that will be rendered by the browser. Otherwise, + the view will return a response whose content type is 'application/octet-stream' + and the browser will then offer to download the file. + + In the context of a navigation coming from a directory view, the filename query + parameter will be used in order to provide the real name of the file when + one wants to save it locally. + + :param string algo_hash: optionnal parameter to indicate the algorithm used + to compute the content checksum (can be either *sha1*, + *sha1_git*, *sha256* or *blake2s256*, default to *sha1*) + :param string hash: hexadecimal representation for the checksum from which + to retrieve the associated content in the SWH archive + :query string filename: indicate the name of the file holding the requested + content (used when one wants to save the content to a local file) + :statuscode 200: no error + :statuscode 400: an invalid query string has been provided + :statuscode 404: requested content can not be found in the SWH archive + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`content/sha1_git:f5d0b39a0cdddb91a31a537052b7d8d31a4aa79f/raw/?filename=LICENSE` + :swh_web_browse:`content/blake2s256:1cc1e3124957c9be8a454c58e92eb925cf4aa9823984bd01451c5b7e0fee99d1/raw/?filename=MAINTAINERS` + :swh_web_browse:`content/sha1:1cb1447c1c7ddc1b03eac88398e40bd914d46b62/raw/` + :swh_web_browse:`content/sha256:8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903/raw/?filename=COPYING` + +.. _highlightjs: https://highlightjs.org/ \ No newline at end of file diff --git a/docs/uri-scheme-browse-directory.rst b/docs/uri-scheme-browse-directory.rst new file mode 100644 index 00000000..a7aa54a6 --- /dev/null +++ b/docs/uri-scheme-browse-directory.rst @@ -0,0 +1,31 @@ +Directory +^^^^^^^^^ + +.. http:get:: /browse/directory/(sha1_git)/[(path)/] + + HTML view for browsing the content of a SWH directory reachable from + the provided root one (including itself) identified by its `sha1_git` value. + + The content of the directory is first sorted in lexicographical order + and the sub-directories are displayed before the regular files. + + The view enables to navigate from the requested directory to + directories reachable from it in a recursive way but also + up to the root directory. + A breadcrumb located in the top part of the view allows + to keep track of the paths navigated so far. + + :param string sha1_git: hexadecimal representation for the *sha1_git* identifier + of the directory to browse + :param string path: optional parameter used to specify the path of a directory + reachable from the provided root one + :statuscode 200: no error + :statuscode 400: an invalid *sha1_git* value has been provided + :statuscode 404: requested directory can not be found in the SWH archive + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`directory/977fc4b98c0e85816348cebd3b12026407c368b6/` + :swh_web_browse:`directory/9650ed370c0330d2cd2b6fd1e9febf649ffe538d/kernel/sched/` diff --git a/docs/uri-scheme-browse-origin.rst b/docs/uri-scheme-browse-origin.rst new file mode 100644 index 00000000..752b42a0 --- /dev/null +++ b/docs/uri-scheme-browse-origin.rst @@ -0,0 +1,481 @@ +Origin +^^^^^^ + +Origin metadata +""""""""""""""" + +.. http:get:: /browse/origin/(origin_id)/ + + HTML view that displays a SWH origin identified by its id. + + The view displays the origin metadata and contains links + for browsing its directories and contents for each SWH visit. + + :param int origin_id: the id of a SWH origin + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/2/` + :swh_web_browse:`origin/13706355/` + +.. http:get:: /browse/origin/(origin_type)/url/(origin_url)/ + + HTML view that displays a SWH origin identified by its type and url. + + The view displays the origin metadata and contains links + for browsing its directories and contents for each SWH visit. + + :param string origin_type: the type of the SWH origin (*git*, *svn*, ...) + :param string origin_url: the url of the origin (e.g. https://github.com///) + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/git/url/https://github.com/torvalds/linux/` + :swh_web_browse:`origin/git/url/https://github.com/python/cpython/` + +Origin directory +"""""""""""""""" + +.. http:get:: /browse/origin/(origin_id)/directory/[(path)/] + + HTML view for browsing the content of a directory reachable from the root directory + (including itself) associated to the latest visit of a SWH origin. + + The content of the directory is first sorted in lexicographical order + and the sub-directories are displayed before the regular files. + + The view enables to navigate from the requested directory to + directories reachable from it in a recursive way but also + up to the origin root directory. + A breadcrumb located in the top part of the view allows + to keep track of the paths navigated so far. + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the directory + content can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :param string path: optional parameter used to specify the path of a directory + reachable from the origin root one + :query string branch: specify the origin branch from which + to retrieve the directory + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the directory + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + or the provided path does not exist from the origin root directory + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/2/directory/` + :swh_web_browse:`origin/2/directory/net/ethernet/` + :swh_web_browse:`origin/13706355/directory/` + :swh_web_browse:`origin/13706355/directory/Python/` + :swh_web_browse:`origin/13706355/directory/?branch=refs/heads/2.7` + +.. http:get:: /browse/origin/(origin_id)/visit/(visit_id)/directory/[(path)/] + + HTML view for browsing the content of a directory reachable from the root directory + (including itself) associated to a specific visit (identified by its id) of a SWH origin. + + The content of the directory is first sorted in lexicographical order + and the sub-directories are displayed before the regular files. + + The view enables to navigate from the requested directory to + directories reachable from it in a recursive way but also + up to the origin root directory. + A breadcrumb located in the top part of the view allows + to keep track of the paths navigated so far. + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the directory + content can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :param int visit_id: the id of the origin visit + :param string path: optional parameter used to specify the path of a directory + reachable from the origin root one + :query string branch: specify the origin branch from which + to retrieve the directory + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the directory + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive, + requested visit id does not exist or the provided path does + not exist from the origin root directory + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/2/visit/2/directory/` + :swh_web_browse:`origin/2/visit/2/directory/net/ethernet/` + :swh_web_browse:`origin/13706355/visit/1/directory/` + :swh_web_browse:`origin/13706355/visit/1/directory/Python/` + :swh_web_browse:`origin/13706355/visit/1/directory/?branch=refs/heads/2.7` + +.. http:get:: /browse/origin/(origin_id)/ts/(timestamp)/directory/[(path)/] + + HTML view for browsing the content of a directory reachable from the root directory + (including itself) associated to a specific visit (identified by its timestamp) of a SWH origin. + + The content of the directory is first sorted in lexicographical order + and the sub-directories are displayed before the regular files. + + The view enables to navigate from the requested directory to + directories reachable from it in a recursive way but also + up to the origin root directory. + A breadcrumb located in the top part of the view allows + to keep track of the paths navigated so far. + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the directory + content can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :param int timestamp: the Unix timestamp of the origin visit + :param path: optional parameter used to specify the path of a directory + reachable from the origin root one + :type path: string + :query string branch: specify the origin branch from which + to retrieve the directory + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the directory + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive, + requested visit timestamp does not exist or the provided path does + not exist from the origin root directory + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/2/ts/1493926809/directory/` + :swh_web_browse:`origin/2/ts/1493926809/directory/net/ethernet/` + :swh_web_browse:`origin/13706355/ts/1474620651/directory/` + :swh_web_browse:`origin/13706355/ts/1474620651/directory/Python/` + :swh_web_browse:`origin/13706355/ts/1474620651/directory/?branch=refs/heads/2.7` + + + +Origin content +"""""""""""""" + +.. http:get:: /browse/origin/(origin_id)/content/(path)/ + + HTML view that produces a display of a SWH content + associated to the latest visit of a SWH origin. + + If the content to display is textual, it will be highlighted client-side + if possible using highlightjs_. In order for that operation to be + performed, a programming language must first be associated to the content. + The following procedure is used in order to find the language: + + 1) First try to find a language from the content filename + + 2) If no language has been found from the filename, + try to find one from the content mime type. + The mime type is retrieved from the content metadata stored + in the SWH archive or is computed server-side using Python + magic module. + + The view displays a breadcrumb on top of the rendered + content in order to easily navigate up to the origin root directory. + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the content + can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :param string path: path of a content reachable from the origin root directory + :query string branch: specify the origin branch from which + to retrieve the content + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the content + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive, + or the provided content path does not exist from the origin root directory + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/723566/content/git.c/` + :swh_web_browse:`origin/16297443/content/js/src/json.cpp/` + :swh_web_browse:`origin/723566/content/git.c/?branch=refs/heads/next` + +.. http:get:: /browse/origin/(origin_id)/visit/(visit_id)/content/(path)/ + + HTML view that produces a display of a SWH content + associated to a specific visit (identified by its id) of a SWH origin. + + If the content to display is textual, it will be highlighted client-side + if possible using highlightjs_. In order for that operation to be + performed, a programming language must first be associated to the content. + The following procedure is used in order to find the language: + + 1) First try to find a language from the content filename + + 2) If no language has been found from the filename, + try to find one from the content mime type. + The mime type is retrieved from the content metadata stored + in the SWH archive or is computed server-side using Python + magic module. + + The view displays a breadcrumb on top of the rendered + content in order to easily navigate up to the origin root directory. + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the content + can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :param int visit_id: the id of the origin visit + :param string path: path of a content reachable from the origin root directory + :query string branch: specify the origin branch from which + to retrieve the content + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the content + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive, + requested visit id does not exist or the provided content path does + not exist from the origin root directory + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/723566/visit/1/content/git.c/` + :swh_web_browse:`origin/16297443/visit/3/content/js/src/json.cpp/` + :swh_web_browse:`origin/723566/visit/1/content/git.c/?branch=refs/heads/next` + +.. http:get:: /browse/origin/(origin_id)/ts/(timestamp)/content/(path)/ + + HTML view that produces a display of a SWH content + associated to a specific visit (identified by its timestamp) of a SWH origin. + + If the content to display is textual, it will be highlighted client-side + if possible using highlightjs_. In order for that operation to be + performed, a programming language must first be associated to the content. + The following procedure is used in order to find the language: + + 1) First try to find a language from the content filename + + 2) If no language has been found from the filename, + try to find one from the content mime type. + The mime type is retrieved from the content metadata stored + in the SWH archive or is computed server-side using Python + magic module. + + The view displays a breadcrumb on top of the rendered + content in order to easily navigate up to the origin root directory. + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the content + can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :param int timestamp: the Unix timestamp of the origin visit + :param string path: path of a content reachable from the origin root directory + :query string branch: specify the origin branch from which + to retrieve the content + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the content + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive, + requested visit timestamp does not exist or the provided content path does + not exist from the origin root directory + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/723566/ts/1473933564/content/git.c/` + :swh_web_browse:`origin/16297443/ts/1490126182/content/js/src/json.cpp/` + :swh_web_browse:`origin/723566/ts/1473933564/content/git.c/?branch=refs/heads/next` + +Origin history +"""""""""""""" + +.. http:get:: /browse/origin/(origin_id)/log/ + + HTML view that produces a display of revisions history heading + to the last revision found during the latest visit of a SWH origin. + In other words, it shows the commit log associated to the latest + visit of a SWH origin. + + The following data are displayed for each log entry: + + * author of the revision + * link to the revision metadata + * message associated the revision + * date of the revision + * link to browse the associated source tree in the origin context + + N log entries are displayed per page (default is 20). In order to navigate + in a large history, two buttons are present at the bottom of the view: + + * *Newer*: fetch and display if available the N more recent log entries + than the ones currently displayed + * *Older*: fetch and display if available the N older log entries + than the ones currently displayed + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the content + can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :query string revs_breadcrumb: used internally to store + the navigation breadcrumbs (i.e. the list of descendant revisions + visited so far). It must be a string in the form + "[//.../]" where rev_i corresponds to a + revision sha1_git. + :query int per_page: the number of log entries to display per page + (default is 20, max is 50) + :query string branch: specify the origin branch from which + to retrieve the commit log + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the commit log + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/12215444/log/` + :swh_web_browse:`origin/2081083/log/` + :swh_web_browse:`origin/12081083/log/?branch=refs/heads/release` + +.. http:get:: /browse/origin/(origin_id)/visit/(visit_id)/log/ + + HTML view that produces a display of revisions history heading + to the last revision found during a specific visit of a SWH origin. + In other words, it shows the commit log associated to a specific + visit of a SWH origin. + + The following data are displayed for each log entry: + + * author of the revision + * link to the revision metadata + * message associated the revision + * date of the revision + * link to browse the associated source tree in the origin context + + N log entries are displayed per page (default is 20). In order to navigate + in a large history, two buttons are present at the bottom of the view: + + * *Newer*: fetch and display if available the N more recent log entries + than the ones currently displayed + * *Older*: fetch and display if available the N older log entries + than the ones currently displayed + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the content + can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :param int visit_id: the id of the origin visit + :query string revs_breadcrumb: used internally to store + the navigation breadcrumbs (i.e. the list of descendant revisions + visited so far). It must be a string in the form + "[//.../]" where rev_i corresponds to a + revision sha1_git. + :query int per_page: the number of log entries to display per page + (default is 20, max is 50) + :query string branch: specify the origin branch from which + to retrieve the commit log + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the commit log + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/12215444/visit/2/log/` + :swh_web_browse:`origin/12081083/visit/10/log/` + :swh_web_browse:`origin/12081083/visit/10/log/?branch=refs/heads/release` + +.. http:get:: /browse/origin/(origin_id)/ts/(timestamp)/log/ + + HTML view that produces a display of revisions history heading + to the last revision found during a specific visit (identified by its + timestamp) of a SWH origin. + In other words, it shows the commit log associated to a specific + visit (identified by its timestamp) of a SWH origin. + + The following data are displayed for each log entry: + + * author of the revision + * link to the revision metadata + * message associated the revision + * date of the revision + * link to browse the associated source tree in the origin context + + N log entries are displayed per page (default is 20). In order to navigate + in a large history, two buttons are present at the bottom of the view: + + * *Newer*: fetch and display if available the N more recent log entries + than the ones currently displayed + * *Older*: fetch and display if available the N older log entries + than the ones currently displayed + + The view also enables to easily switch between the origin branches + through a dropdown menu. + + The origin branch (default to master) from which to retrieve the content + can also be specified by using the branch query parameter. + + :param int origin_id: the id of a SWH origin + :param int timestamp: the Unix timestamp of the origin visit + :query string revs_breadcrumb: used internally to store + the navigation breadcrumbs (i.e. the list of descendant revisions + visited so far). It must be a string in the form + "[//.../]" where rev_i corresponds to a + revision sha1_git. + :query int per_page: the number of log entries to display per page + (default is 20, max is 50) + :query string branch: specify the origin branch from which + to retrieve the commit log + :query string revision: specify the origin revision, identified by the hexadecimal + representation of its *sha1_git* value, from which to retrieve the commit log + :statuscode 200: no error + :statuscode 404: requested origin can not be found in the SWH archive + + **Examples**: + + .. parsed-literal:: + + :swh_web_browse:`origin/12215444/ts/1459651262/log/` + :swh_web_browse:`origin/12081083/ts/1438116814/log/` + :swh_web_browse:`origin/12081083/ts/1438116814/log/?branch=refs/heads/release` + +.. _highlightjs: https://highlightjs.org/ diff --git a/docs/uri-scheme-browse-person.rst b/docs/uri-scheme-browse-person.rst new file mode 100644 index 00000000..a64a25e6 --- /dev/null +++ b/docs/uri-scheme-browse-person.rst @@ -0,0 +1,10 @@ +Person +^^^^^^ + +.. http:get:: /browse/person/(person_id)/ + + HTML view that displays information regarding a SWH person. + + :param int person_id: the id of a SWH person + :statuscode 200: no error + :statuscode 404: requested person can not be found in the SWH archive diff --git a/docs/uri-scheme-browse-revision.rst b/docs/uri-scheme-browse-revision.rst new file mode 100644 index 00000000..9990ccd8 --- /dev/null +++ b/docs/uri-scheme-browse-revision.rst @@ -0,0 +1,60 @@ +Revision +^^^^^^^^ + +.. http:get:: /browse/revision/(sha1_git)/ + + HTML view that displays the metadata associated to a SWH revision. + It notably shows the revision date and message but also offers + links to get more details on: + + * the author + * the committer + * the directory that revision points to + * the history log reachable from that revision + + :param string sha1_git: hexadecimal representation for the *sha1_git* + identifier of a SWH revision + :statuscode 200: no error + :statuscode 404: requested revision can not be found in the SWH archive + + .. parsed-literal:: + + :swh_web_browse:`revision/f1b94134a4b879bc55c3dacdb496690c8ebdc03f/` + :swh_web_browse:`revision/d1aa2b3f607b35dc5dbf613b2334b6d243ec2bda/` + +.. http:get:: /browse/revision/(sha1_git)/log/ + + HTML view that displays the list of revisions heading to + a given one. In other words, it shows a commit log. + The following data are displayed for each log entry: + + * author of the revision + * link to the revision metadata + * message associated to the revision + * date of the revision + * link to browse the associated source tree + + N log entries are displayed per page (default is 20). In order to navigate + in a large history, two buttons are present at the bottom of the view: + + * *Newer*: fetch and display if available the N more recent log entries + than the ones currently displayed + * *Older*: fetch and display if available the N older log entries + than the ones currently displayed + + :param string sha1_git: hexadecimal representation for the *sha1_git* + identifier of a SWH revision + :query string revs_breadcrumb: used internally to store + the navigation breadcrumbs (i.e. the list of descendant revisions + visited so far). It must be a string in the form + "[//.../]" where rev_i corresponds to a + revision sha1_git. + :query int per_page: the number of log entries to display per page + (default is 20, max is 50) + :statuscode 200: no error + :statuscode 404: requested revision can not be found in the SWH archive + + .. parsed-literal:: + + :swh_web_browse:`revision/f1b94134a4b879bc55c3dacdb496690c8ebdc03f/log/` + :swh_web_browse:`revision/d1aa2b3f607b35dc5dbf613b2334b6d243ec2bda/log/` \ No newline at end of file diff --git a/docs/uri-scheme-browse.rst b/docs/uri-scheme-browse.rst new file mode 100644 index 00000000..ed2fc260 --- /dev/null +++ b/docs/uri-scheme-browse.rst @@ -0,0 +1,105 @@ +URI scheme for SWH Web Browse application +========================================= + +This web application aims to provide HTML views to easily navigate in the SWH archive, +thus it needs to be reached from a web browser. +If you intend to query the SWH archive programmatically through any HTTP client, +please refer to the :ref:`swh-web-api-urls` section instead. + +Context-independent browsing +---------------------------- + +Context-independent URLs provide information about SWH objects (e.g., +revisions, directories, contents, person, ...), independently of the +contexts where they have been found (e.g., specific repositories, +branches, commits, ...). + +The following endpoints are the same of the API case (see below), and +just render the corresponding information for user consumption. Where +hyperlinks are created, they always point to other context-independent +user URLs: + + * :http:get:`/browse/content/[(algo_hash):](hash)/`: Display a content + * :http:get:`/browse/content/[(algo_hash):](hash)/raw/`: Get / Download content data + * :http:get:`/browse/directory/(sha1_git)/[(path)/]`: Browse the content of a directory + * :http:get:`/browse/origin/(origin_id)/`: Information on origin + * :http:get:`/browse/person/(person_id)/`: Information on person + * :http:get:`/browse/revision/(sha1_git)/`: Browse revision + * :http:get:`/browse/revision/(sha1_git)/log/`: Browse history log heading to revision + +Context-dependent browsing +-------------------------- + +Context-dependent URLs provide information about SWH objects, limited to +specific contexts where the objects have been found. + +For instance, instead of having to specify a (root) revision by *sha1_git*, users might want to +specify a place and a time. In SWH a "place" is an origin, with an optional +branch name; a "time" is a timestamp at which some place has been observed by +SWH crawlers. + +Wherever a revision context is expected in a path (i.e., a +**/browse/revision/(sha1_git)/** path fragment) we can put in its stead a path fragment +of the form /origin/[/branch/][/ts//]. Such a +fragment is resolved, internally by the SWH archive, to a SHA1_GIT as follows: + +- [if is absent] look for the most recent crawl of origin +- [if is given] look for the most recent crawl of origin + whose timestamp is <= +- [if is given] look for the branch +- [if is absent] look for branch "master" +- return the pointed by the chosen branch + +The already mentioned URLs for revision contexts can therefore be alternatively +specified by users as: + +* /revision/origin/[/branch/][/ts/]/ +* /revision/origin/[/branch/][/ts/]/history// +* /revision/origin/[/branch/][/ts/]/directory/[] +* /revision/origin/[/branch/][/ts/]/history//directory/[] + +Typing: + +- s are given as integer identifiers, pointing into the origin table. + There will be separate mechanisms for finding origins by other means (e.g., + URLs, metadata, etc). Once an origin is found, it can be used by ID into the + above URL schemes + +- names are given as per the corresponding VCS (e.g., Git) and might + therefore contains characters that are either invalid in URLs, or that might + make the above URL schemes ambiguous (e.g., '/'). All those characters will + need to be URL-escaped. (e.g., '/' will become '%2F') + +- s are given in a format as liberal as possible, to uphold the + principle of least surprise. At the very minimum it should be possible to + enter timestamps as: + + - ISO 8601 timestamps (see for instance the output of `date -I`, `date -Is`) + - YYYY[MM[DD[HH[MM[SS]]]]] ad-hoc format + + Implementation proposal: use Python dateutil's parser and be done with it + https://dateutil.readthedocs.org/en/latest/parser.html . Note: that dateutil + does *not* allow to use classical UNIX timestamps expressed as seconds since + the epoch (i.e., `date +%s` output). We will need to single case them. + + The same escaping considerations given for apply. + +Notes: + +- Differently from , s are still specified as SHA1 and + cannot be specified a origin/branch/ts triples. This is to preserve some URL + sanity. + + +SWH Browse Urls +--------------- + +.. include:: uri-scheme-browse-content.rst + +.. include:: uri-scheme-browse-directory.rst + +.. include:: uri-scheme-browse-origin.rst + +.. include:: uri-scheme-browse-person.rst + +.. include:: uri-scheme-browse-revision.rst diff --git a/docs/uri-scheme.rst b/docs/uri-scheme.rst deleted file mode 100644 index 282b3fa4..00000000 --- a/docs/uri-scheme.rst +++ /dev/null @@ -1,685 +0,0 @@ -URI scheme for SWH Web applications -=================================== - -SWH Browse Urls ---------------- - -This web application aims to provide HTML views to easily navigate in the SWH archive, -thus it needs to be reached from a web browser. -If you intend to query the SWH archive programmatically through any HTTP client, -please refer to the `SWH Web API URLs`_ instead. - -Content -^^^^^^^ - -.. http:get:: /browse/content/[(algo_hash):](hash)/ - - HTML view that displays a SWH content identified by its hash value. - - If the content to display is textual, it will be highlighted client-side - if possible using highlightjs_. In order for that operation to be - performed, a programming language must first be associated to the content. - The following procedure is used in order to find the language: - - 1) First try to find a language from the content filename - (provided as query parameter when navigating from a directory view). - - 2) If no language has been found from the filename, - try to find one from the content mime type. - The mime type is retrieved from the content metadata stored - in the SWH archive or is computed server-side using Python - magic module. - - When that view is called in the context of a navigation coming from - a directory view, a breadcrumb will be displayed on top of the rendered - content in order to easily navigate up to the associated root directory. - In that case, the path query parameter will be used and filled with the path - of the file relative to the root directory. - - :param algo_hash: optionnal parameter to indicate the algorithm used - to compute the content checksum (default to *sha1*) - :type algo_hash: a string identifying the hashing algorithm (either *sha1*, - *sha1_git*, *sha256* or *blake2s256*) - :param hash: the checksum from which to retrieve the associated content in - the SWH archive - :type hash: hexadecimal representation of the hash value - :query path: optionnal parameter used to describe the path of the content - relative to a root directory (used to add context aware navigation links - when navigating from a directory view) - :statuscode 200: no error - :statuscode 400: an invalid query string has been provided - :statuscode 404: requested content can not be found in the SWH archive - -.. http:get:: /browse/content/[(algo_hash):](hash)/raw/ - - HTML view that produces a raw display of a SWH content identified by its hash value. - - The behaviour of that view depends on the mime type of the requested content. - If the mime type is from the text family, the view will return a response whose - content type is 'text/plain' that will be rendered by the browser. Otherwise, - the view will return a response whose content type is 'application/octet-stream' - and the browser will then offer to download the file. - - In the context of a navigation coming from a directory view, the filename query - parameter will be used in order to provide the real name of the file when - one wants to save it locally. - - :param algo_hash: optionnal parameter to indicate the algorithm used - to compute the content checksum (default to *sha1*) - :type algo_hash: a string identifying the hashing algorithm (either *sha1*, - *sha1_git*, *sha256* or *blake2s256*) - :param hash: the checksum from which to retrieve the associated content in - the SWH archive - :type hash: hexadecimal representation of the hash value - :query filename: optionnal parameter used to indicate the name of the file - holding the requested content (used when one wants to save the content - to a local file) - :statuscode 200: no error - :statuscode 400: an invalid query string has been provided - :statuscode 404: requested content can not be found in the SWH archive - -Directory -^^^^^^^^^ - -.. http:get:: /browse/directory/(sha1_git)/ - - HTML view for browsing the content of a SWH directory identified - by its `sha1_git` value. - - The content of the directory is first sorted in lexicographical order - and the sub-directories are displayed before the regular files. - - The view enables to navigate from the provided root directory to - directories reachable from it in a recursive way. - A breadcrumb located in the top part of the view allows - to keep track of the paths navigated so far. - - :param sha1_git: the `sha1_git` identifier of the directory to browse - :type sha1_git: hexadecimal representation of that hash value - :statuscode 200: no error - :statuscode 400: an invalid `sha1_git` value has been provided - :statuscode 404: requested directory can not be found in the SWH archive - - -.. http:get:: /browse/directory/(sha1_git)/(path)/ - - HTML view for browsing the content of a SWH directory reachable from - the provided root one identified by its `sha1_git` value. - - The content of the directory is first sorted in lexicographical order - and the sub-directories are displayed before the regular files. - - The view enables to navigate from the requested directory to - directories reachable from it in a recursive way but also - up to the root directory. - A breadcrumb located in the top part of the view allows - to keep track of the paths navigated so far. - - :param sha1_git: the `sha1_git` identifier of the directory to browse - :type sha1_git: hexadecimal representation of that hash value - :param path: path of a directory reachable from the provided root one - :type path: string - :statuscode 200: no error - :statuscode 400: an invalid `sha1_git` value has been provided - :statuscode 404: requested directory can not be found in the SWH archive - -Origin -^^^^^^ - -Origin metadata -""""""""""""""" - -.. http:get:: /browse/origin/(origin_id)/ - - HTML view that displays a SWH origin identified by its id. - - The view displays the origin metadata and contains links - for browsing its directories and contents for each SWH visit. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - -.. http:get:: /browse/origin/(origin_type)/url/(origin_url)/ - - HTML view that displays a SWH origin identified by its type and url. - - The view displays the origin metadata and contains links - for browsing its directories and contents for each SWH visit. - - :param origin_type: the type of the SWH origin (*git*, *svn*, ...) - :type origin_type: string - :param origin_url: the url of the origin (e.g. https://github.com///) - :type origin_url: string - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - -Origin directory -"""""""""""""""" - -.. http:get:: /browse/origin/(origin_id)/directory/ - - HTML view for browsing the content of the root directory associated - to the latest visit of a SWH origin. - - The content of the directory is first sorted in lexicographical order - and the sub-directories are displayed before the regular files. - - The view enables to navigate from the origin root directory to - directories reachable from it in a recursive way. - A breadcrumb located in the top part of the view allows - to keep track of the paths navigated so far. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the directory - content can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :query branch: optional query parameter to specify the origin branch - from which to retrieve the directory - :query revision: optional query parameter to specify the origin revision - from which to retrieve the directory - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - -.. http:get:: /browse/origin/(origin_id)/directory/(path)/ - - HTML view for browsing the content of a directory reachable from the root directory - associated to the latest visit of a SWH origin. - - The content of the directory is first sorted in lexicographical order - and the sub-directories are displayed before the regular files. - - The view enables to navigate from the requested directory to - directories reachable from it in a recursive way but also - up to the origin root directory. - A breadcrumb located in the top part of the view allows - to keep track of the paths navigated so far. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the directory - content can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param path: path of a directory reachable from the origin root one - :type path: string - :query branch: optional query parameter to specify the origin branch - from which to retrieve the directory - :query revision: optional query parameter to specify the origin revision - from which to retrieve the directory - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - or the provided path does not exist from the origin root directory - -.. http:get:: /browse/origin/(origin_id)/visit/(visit_id)/directory/ - - HTML view for browsing the content of the root directory - associated to a specific visit (identified by its id) of a SWH origin. - - The content of the directory is first sorted in lexicographical order - and the sub-directories are displayed before the regular files. - - The view enables to navigate from the origin root directory to - directories reachable from it in a recursive way. - A breadcrumb located in the top part of the view allows - to keep track of the paths navigated so far. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the directory - content can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param visit_id: the id of the origin visit - :type visit_id: int - :query branch: optional query parameter to specify the origin branch - from which to retrieve the directory - :query revision: optional query parameter to specify the origin revision - from which to retrieve the directory - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - or requested visit id does not exist - -.. http:get:: /browse/origin/(origin_id)/visit/(visit_id)/directory/(path)/ - - HTML view for browsing the content of a directory reachable from the root directory - associated to a specific visit (identified by its id) of a SWH origin. - - The content of the directory is first sorted in lexicographical order - and the sub-directories are displayed before the regular files. - - The view enables to navigate from the requested directory to - directories reachable from it in a recursive way but also - up to the origin root directory. - A breadcrumb located in the top part of the view allows - to keep track of the paths navigated so far. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the directory - content can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param visit_id: the id of the origin visit - :type visit_id: int - :param path: path of a directory reachable from the origin root one - :type path: string - :query branch: optional query parameter to specify the origin branch - from which to retrieve the directory - :query revision: optional query parameter to specify the origin revision - from which to retrieve the directory - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive, - requested visit id does not exist or the provided path does - not exist from the origin root directory - -.. http:get:: /browse/origin/(origin_id)/ts/(ts)/directory/ - - HTML view for browsing the content of the root directory - associated to a specific visit (identified by its timestamp) of a SWH origin. - - The content of the directory is first sorted in lexicographical order - and the sub-directories are displayed before the regular files. - - The view enables to navigate from the origin root directory to - directories reachable from it in a recursive way. - A breadcrumb located in the top part of the view allows - to keep track of the paths navigated so far. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the directory - content can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param ts: the timestamp of the origin visit - :type ts: Unix timestamp - :query branch: optional query parameter to specify the origin branch - from which to retrieve the directory - :query revision: optional query parameter to specify the origin revision - from which to retrieve the directory - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - or requested visit timestamp does not exist - -.. http:get:: /browse/origin/(origin_id)/ts/(ts)/directory/(path)/ - - HTML view for browsing the content of a directory reachable from the root directory - associated to a specific visit (identified by its timestamp) of a SWH origin. - - The content of the directory is first sorted in lexicographical order - and the sub-directories are displayed before the regular files. - - The view enables to navigate from the requested directory to - directories reachable from it in a recursive way but also - up to the origin root directory. - A breadcrumb located in the top part of the view allows - to keep track of the paths navigated so far. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the directory - content can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param ts: the timestamp of the origin visit - :type ts: Unix timestamp - :param path: path of a directory reachable from the origin root one - :type path: string - :query branch: optional query parameter to specify the origin branch - from which to retrieve the directory - :query revision: optional query parameter to specify the origin revision - from which to retrieve the directory - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive, - requested visit timestamp does not exist or the provided path does - not exist from the origin root directory - -Origin content -"""""""""""""" - -.. http:get:: /browse/origin/(origin_id)/content/(path)/ - - HTML view that produces a display of a SWH content - associated to the latest visit of a SWH origin. - - If the content to display is textual, it will be highlighted client-side - if possible using highlightjs_. In order for that operation to be - performed, a programming language must first be associated to the content. - The following procedure is used in order to find the language: - - 1) First try to find a language from the content filename - - 2) If no language has been found from the filename, - try to find one from the content mime type. - The mime type is retrieved from the content metadata stored - in the SWH archive or is computed server-side using Python - magic module. - - The view displays a breadcrumb on top of the rendered - content in order to easily navigate up to the origin root directory. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the content - can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param path: path of a content reachable from the origin root directory - :type path: string - :query branch: optional query parameter to specify the origin branch - from which to retrieve the content - :query revision: optional query parameter to specify the origin revision - from which to retrieve the content - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive, - or the provided content path does not exist from the origin root directory - -.. http:get:: /browse/origin/(origin_id)/visit/(visit_id)/content/(path)/ - - HTML view that produces a display of a SWH content - associated to a specific visit (identified by its id) of a SWH origin. - - If the content to display is textual, it will be highlighted client-side - if possible using highlightjs_. In order for that operation to be - performed, a programming language must first be associated to the content. - The following procedure is used in order to find the language: - - 1) First try to find a language from the content filename - - 2) If no language has been found from the filename, - try to find one from the content mime type. - The mime type is retrieved from the content metadata stored - in the SWH archive or is computed server-side using Python - magic module. - - The view displays a breadcrumb on top of the rendered - content in order to easily navigate up to the origin root directory. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the content - can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param visit_id: the id of the origin visit - :type visit_id: int - :param path: path of a content reachable from the origin root directory - :type path: string - :query branch: optional query parameter to specify the origin branch - from which to retrieve the content - :query revision: optional query parameter to specify the origin revision - from which to retrieve the content - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive, - requested visit id does not exist or the provided content path does - not exist from the origin root directory - -.. http:get:: /browse/origin/(origin_id)/ts/(ts)/content/(path)/ - - HTML view that produces a display of a SWH content - associated to a specific visit (identified by its timestamp) of a SWH origin. - - If the content to display is textual, it will be highlighted client-side - if possible using highlightjs_. In order for that operation to be - performed, a programming language must first be associated to the content. - The following procedure is used in order to find the language: - - 1) First try to find a language from the content filename - - 2) If no language has been found from the filename, - try to find one from the content mime type. - The mime type is retrieved from the content metadata stored - in the SWH archive or is computed server-side using Python - magic module. - - The view displays a breadcrumb on top of the rendered - content in order to easily navigate up to the origin root directory. - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the content - can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param ts: the timestamp of the origin visit - :type ts: Unix timestamp - :param path: path of a content reachable from the origin root directory - :type path: string - :query branch: optional query parameter to specify the origin branch - from which to retrieve the content - :query revision: optional query parameter to specify the origin revision - from which to retrieve the content - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive, - requested visit timestamp does not exist or the provided content path does - not exist from the origin root directory - -Origin history -"""""""""""""" - -.. http:get:: /browse/origin/(origin_id)/log/ - - HTML view that produces a display of revisions history heading - to the last revision found during the latest visit of a SWH origin. - In other words, it shows the commit log associated to the latest - visit of a SWH origin. - - The following data are displayed for each log entry: - - * author of the revision - * link to the revision metadata - * message associated the revision - * date of the revision - * link to browse the associated source tree in the origin context - - N log entries are displayed per page (default is 20). In order to navigate - in a large history, two buttons are present at the bottom of the view: - - * *Newer*: fetch and display if available the N more recent log entries - than the ones currently displayed - * *Older*: fetch and display if available the N older log entries - than the ones currently displayed - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the content - can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :query revs_breadcrumb: query parameter used internally to store - the navigation breadcrumbs (i.e. the list of descendant revisions - visited so far). It must be a string in the form - "[//.../]" - :query per_page: the number of log entries to display per page - (default is 20, max is 50) - :query branch: optional query parameter to specify the origin branch - from which to retrieve the commit log - :query revision: optional query parameter to specify the origin revision - from which to retrieve the commit log - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - -.. http:get:: /browse/origin/(origin_id)/visit/(visit_id)/log/ - - HTML view that produces a display of revisions history heading - to the last revision found during a specific visit of a SWH origin. - In other words, it shows the commit log associated to a specific - visit of a SWH origin. - - The following data are displayed for each log entry: - - * author of the revision - * link to the revision metadata - * message associated the revision - * date of the revision - * link to browse the associated source tree in the origin context - - N log entries are displayed per page (default is 20). In order to navigate - in a large history, two buttons are present at the bottom of the view: - - * *Newer*: fetch and display if available the N more recent log entries - than the ones currently displayed - * *Older*: fetch and display if available the N older log entries - than the ones currently displayed - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the content - can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param visit_id: the id of the origin visit - :type visit_id: int - :query revs_breadcrumb: query parameter used internally to store - the navigation breadcrumbs (i.e. the list of descendant revisions - visited so far). It must be a string in the form - "[//.../]" - :query per_page: the number of log entries to display per page - (default is 20, max is 50) - :query branch: optional query parameter to specify the origin branch - from which to retrieve the commit log - :query revision: optional query parameter to specify the origin revision - from which to retrieve the commit log - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - -.. http:get:: /browse/origin/(origin_id)/ts/(ts)/log/ - - HTML view that produces a display of revisions history heading - to the last revision found during a specific visit (identified by its - timestamp) of a SWH origin. - In other words, it shows the commit log associated to a specific - visit (identified by its timestamp) of a SWH origin. - - The following data are displayed for each log entry: - - * author of the revision - * link to the revision metadata - * message associated the revision - * date of the revision - * link to browse the associated source tree in the origin context - - N log entries are displayed per page (default is 20). In order to navigate - in a large history, two buttons are present at the bottom of the view: - - * *Newer*: fetch and display if available the N more recent log entries - than the ones currently displayed - * *Older*: fetch and display if available the N older log entries - than the ones currently displayed - - The view also enables to easily switch between the origin branches - through a dropdown menu. - - The origin branch (default to master) from which to retrieve the content - can also be specified by using the branch query parameter. - - :param origin_id: the id of a SWH origin - :type origin_id: int - :param ts: the timestamp of the origin visit - :type ts: Unix timestamp - :query revs_breadcrumb: query parameter used internally to store - the navigation breadcrumbs (i.e. the list of descendant revisions - visited so far). It must be a string in the form - "[//.../]" - :query per_page: the number of log entries to display per page - (default is 20, max is 50) - :query branch: optional query parameter to specify the origin branch - from which to retrieve the commit log - :query revision: optional query parameter to specify the origin revision - from which to retrieve the commit log - :statuscode 200: no error - :statuscode 404: requested origin can not be found in the SWH archive - -Person -^^^^^^ - -.. http:get:: /browse/person/(person_id)/ - - HTML view that displays information regarding a SWH person. - - :param person_id: the id of a SWH person - :type origin_id: int - :statuscode 200: no error - :statuscode 404: requested person can not be found in the SWH archive - -Revision -^^^^^^^^ - -.. http:get:: /browse/revision/(revision_id)/ - - HTML view that displays the metadata associated to a SWH revision. - It notably shows the revision date and message but also offers - links to get more details on: - - * the author - * the committer - * the directory that revision points to - * the history log reachable from that revision - - :param revision_id: the sha1_git identifier of a SWH revision - :type revision_id: hexadecimal representation of that hash value - :statuscode 200: no error - :statuscode 404: requested revision can not be found in the SWH archive - -.. http:get:: /browse/revision/(revision_id)/log/ - - HTML view that displays the list of revisions heading to - a given one. In other words, it shows a commit log. - The following data are displayed for each log entry: - - * author of the revision - * link to the revision metadata - * message associated to the revision - * date of the revision - * link to browse the associated source tree - - N log entries are displayed per page (default is 20). In order to navigate - in a large history, two buttons are present at the bottom of the view: - - * *Newer*: fetch and display if available the N more recent log entries - than the ones currently displayed - * *Older*: fetch and display if available the N older log entries - than the ones currently displayed - - :param revision_id: the sha1_git identifier of a SWH revision - :type revision_id: hexadecimal representation of that hash value - :query revs_breadcrumb: query parameter used internally to store - the navigation breadcrumbs (i.e. the list of descendant revisions - visited so far). It must be a string in the form - "[//.../]" - :query per_page: the number of log entries to display per page - (default is 20, max is 50) - :statuscode 200: no error - :statuscode 404: requested revision can not be found in the SWH archive - - -SWH Web API URLs ----------------- - -.. _highlightjs: https://highlightjs.org/ \ No newline at end of file diff --git a/swh/web/browse/views/directory.py b/swh/web/browse/views/directory.py index 14298df7..cdf06bc7 100644 --- a/swh/web/browse/views/directory.py +++ b/swh/web/browse/views/directory.py @@ -1,83 +1,80 @@ # Copyright (C) 2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information from django.shortcuts import render from swh.web.common import service from swh.web.common.utils import reverse from swh.web.common.exc import handle_view_exception from swh.web.browse.utils import ( gen_path_info, get_directory_entries ) from swh.web.browse.browseurls import browse_route @browse_route(r'directory/(?P[0-9a-f]+)/', r'directory/(?P[0-9a-f]+)/(?P.+)/', view_name='browse-directory') def directory_browse(request, sha1_git, path=None): """Django view for browsing the content of a SWH directory identified by its sha1_git value. - The url scheme that points to it is the following: - - * :http:get:`/browse/directory/(sha1_git)/` - * :http:get:`/browse/directory/(sha1_git)/(path)/` + The url that points to it is :http:get:`/browse/directory/(sha1_git)/[(path)/]` Args: request: input django http request sha1_git: swh sha1_git identifer of the directory to browse path: optionnal path parameter used to navigate in directories reachable from the provided root one Returns: The HTML rendering for the content of the provided directory. - """ + """ # noqa root_sha1_git = sha1_git try: if path: dir_info = service.lookup_directory_with_path(sha1_git, path) sha1_git = dir_info['target'] dirs, files = get_directory_entries(sha1_git) except Exception as exc: return handle_view_exception(exc) path_info = gen_path_info(path) breadcrumbs = [] breadcrumbs.append({'name': root_sha1_git[:7], 'url': reverse('browse-directory', kwargs={'sha1_git': root_sha1_git})}) for pi in path_info: breadcrumbs.append({'name': pi['name'], 'url': reverse('browse-directory', kwargs={'sha1_git': root_sha1_git, 'path': pi['path']})}) path = '' if path is None else (path + '/') for d in dirs: d['url'] = reverse('browse-directory', kwargs={'sha1_git': root_sha1_git, 'path': path + d['name']}) for f in files: query_string = 'sha1_git:' + f['target'] f['url'] = reverse('browse-content', kwargs={'query_string': query_string}, query_params={'path': root_sha1_git + '/' + path + f['name']}) return render(request, 'directory.html', {'dir_sha1_git': sha1_git, 'dirs': dirs, 'files': files, 'breadcrumbs': breadcrumbs, 'branches': None, 'branch': None, 'top_right_link': None, 'top_right_link_text': None}) diff --git a/swh/web/browse/views/origin.py b/swh/web/browse/views/origin.py index a2f028d8..669b30b2 100644 --- a/swh/web/browse/views/origin.py +++ b/swh/web/browse/views/origin.py @@ -1,503 +1,501 @@ # Copyright (C) 2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information import dateutil from django.shortcuts import render from swh.web.common import service from swh.web.common.utils import reverse, format_utc_iso_date from swh.web.common.exc import NotFoundExc, handle_view_exception from swh.web.browse.utils import ( get_origin_visits, get_origin_visit_branches, gen_path_info, get_directory_entries, request_content, prepare_content_for_display, gen_link, prepare_revision_log_for_display ) from swh.web.browse.browseurls import browse_route @browse_route(r'origin/(?P[0-9]+)/', r'origin/(?P[a-z]+)/url/(?P.+)/', view_name='browse-origin') def origin_browse(request, origin_id=None, origin_type=None, origin_url=None): """Django view that produces an HTML display of a swh origin identified by its id or its url. - The url scheme that points to it is the following: - - * :http:get:`/browse/origin/(origin_id)/` - * :http:get:`/browse/origin/(origin_id)/directory/` + The url scheme that points to it is :http:get:`/browse/origin/(origin_id)/`. Args: request: input django http request origin_id: a swh origin id origin_type: type of origin (git, svn, ...) origin_url: url of the origin (e.g. https://github.com//) Returns: The HMTL rendering for the metadata of the provided origin. - """ + """ # noqa try: if origin_id: origin_request_params = { 'id': origin_id, } else: origin_request_params = { 'type': origin_type, 'url': origin_url } origin_info = service.lookup_origin(origin_request_params) origin_id = origin_info['id'] origin_visits = get_origin_visits(origin_id) except Exception as exc: return handle_view_exception(exc) origin_info['last swh visit browse url'] = \ reverse('browse-origin-directory', kwargs={'origin_id': origin_id}) origin_visits_data = [] for visit in origin_visits: visit_date = dateutil.parser.parse(visit['date']) visit['date'] = format_utc_iso_date(visit['date']) visit['browse_url'] = reverse('browse-origin-directory', kwargs={'origin_id': origin_id, 'visit_id': visit['visit']}) origin_visits_data.append( {'date': visit_date.timestamp()}) return render(request, 'origin.html', {'origin': origin_info, 'origin_visits_data': origin_visits_data, 'visits': origin_visits, 'browse_url_base': '/browse/origin/%s/' % origin_id}) def _get_origin_branches_and_url_args(origin_id, visit_id, ts): if not visit_id and ts: branches = get_origin_visit_branches(origin_id, visit_ts=ts) url_args = {'origin_id': origin_id, - 'ts': ts} + 'timestamp': ts} else: branches = get_origin_visit_branches(origin_id, visit_id) url_args = {'origin_id': origin_id, 'visit_id': visit_id} return branches, url_args def _raise_exception_if_branch_not_found(origin_id, visit_id, ts, branch): if visit_id: raise NotFoundExc('Branch %s associated to visit with' ' id %s for origin with id %s' ' not found!' % (branch, visit_id, origin_id)) else: raise NotFoundExc('Branch %s associated to visit with' ' timestamp %s for origin with id %s' ' not found!' % (branch, ts, origin_id)) @browse_route(r'origin/(?P[0-9]+)/directory/', r'origin/(?P[0-9]+)/directory/(?P.+)/', r'origin/(?P[0-9]+)/visit/(?P[0-9]+)/directory/', # noqa r'origin/(?P[0-9]+)/visit/(?P[0-9]+)/directory/(?P.+)/', # noqa - r'origin/(?P[0-9]+)/ts/(?P[0-9]+)/directory/', - r'origin/(?P[0-9]+)/ts/(?P[0-9]+)/directory/(?P.+)/', # noqa + r'origin/(?P[0-9]+)/ts/(?P[0-9]+)/directory/', # noqa + r'origin/(?P[0-9]+)/ts/(?P[0-9]+)/directory/(?P.+)/', # noqa view_name='browse-origin-directory') def origin_directory_browse(request, origin_id, visit_id=None, - ts=None, path=None): + timestamp=None, path=None): """Django view for browsing the content of a swh directory associated to an origin for a given visit. The url scheme that points to it is the following: - * :http:get:`/browse/origin/(origin_id)/directory/` - * :http:get:`/browse/origin/(origin_id)/directory/(path)/` - * :http:get:`/browse/origin/(origin_id)/visit/(visit_id)/directory/` - * :http:get:`/browse/origin/(origin_id)/visit/(visit_id)/directory/(path)/` - * :http:get:`/browse/origin/(origin_id)/ts/(ts)/directory/` - * :http:get:`/browse/origin/(origin_id)/ts/(ts)/directory/(path)/` + * :http:get:`/browse/origin/(origin_id)/directory/[(path)/]` + * :http:get:`/browse/origin/(origin_id)/visit/(visit_id)/directory/[(path)/]` + * :http:get:`/browse/origin/(origin_id)/ts/(timestamp)/directory/[(path)/]` Args: request: input django http request origin_id: a swh origin id visit_id: optionnal visit id parameter (the last one will be used by default) - ts: optionnal visit timestamp parameter + timestamp: optionnal visit timestamp parameter (the last one will be used by default) path: optionnal path parameter used to navigate in directories reachable from the origin root one branch: optionnal query parameter that specifies the origin branch from which to retrieve the directory revision: optional query parameter to specify the origin revision from which to retrieve the directory Returns: The HTML rendering for the content of the directory associated to the provided origin and visit. """ # noqa try: - if not visit_id and not ts: + if not visit_id and not timestamp: origin_visits = get_origin_visits(origin_id) return origin_directory_browse(request, origin_id, origin_visits[-1]['visit'], path=path) branches, url_args = _get_origin_branches_and_url_args(origin_id, - visit_id, ts) + visit_id, + timestamp) for b in branches: branch_url_args = dict(url_args) if path: b['path'] = path branch_url_args['path'] = path b['url'] = reverse('browse-origin-directory', kwargs=branch_url_args, query_params={'branch': b['name']}) revision_id = request.GET.get('revision', None) if revision_id: revision = service.lookup_revision(revision_id) root_sha1_git = revision['directory'] branches.append({'name': revision_id, 'revision': revision_id, 'directory': root_sha1_git}) branch = revision_id else: branch = request.GET.get('branch', 'master') filtered_branches = [b for b in branches if branch in b['name']] if len(filtered_branches) > 0: root_sha1_git = filtered_branches[0]['directory'] branch = filtered_branches[0]['name'] else: - _raise_exception_if_branch_not_found(origin_id, visit_id, ts, - branch) + _raise_exception_if_branch_not_found(origin_id, visit_id, + timestamp, branch) sha1_git = root_sha1_git if path: dir_info = service.lookup_directory_with_path(root_sha1_git, path) sha1_git = dir_info['target'] dirs, files = get_directory_entries(sha1_git) except Exception as exc: return handle_view_exception(exc) if revision_id: query_params = {'revision': revision_id} else: query_params = {'branch': branch} path_info = gen_path_info(path) breadcrumbs = [] breadcrumbs.append({'name': root_sha1_git[:7], 'url': reverse('browse-origin-directory', kwargs=url_args, query_params=query_params)}) for pi in path_info: bc_url_args = dict(url_args) bc_url_args['path'] = pi['path'] breadcrumbs.append({'name': pi['name'], 'url': reverse('browse-origin-directory', kwargs=bc_url_args, query_params=query_params)}) path = '' if path is None else (path + '/') for d in dirs: bc_url_args = dict(url_args) bc_url_args['path'] = path + d['name'] d['url'] = reverse('browse-origin-directory', kwargs=bc_url_args, query_params=query_params) for f in files: bc_url_args = dict(url_args) bc_url_args['path'] = path + f['name'] f['url'] = reverse('browse-origin-content', kwargs=bc_url_args, query_params=query_params) history_url = reverse('browse-origin-log', kwargs=url_args, query_params=query_params) return render(request, 'directory.html', {'dir_sha1_git': sha1_git, 'dirs': dirs, 'files': files, 'breadcrumbs': breadcrumbs, 'branches': branches, 'branch': branch, 'top_right_link': history_url, 'top_right_link_text': 'History'}) @browse_route(r'origin/(?P[0-9]+)/content/(?P.+)/', r'origin/(?P[0-9]+)/visit/(?P[0-9]+)/content/(?P.+)/', # noqa - r'origin/(?P[0-9]+)/ts/(?P[0-9]+)/content/(?P.+)/', # noqa + r'origin/(?P[0-9]+)/ts/(?P[0-9]+)/content/(?P.+)/', # noqa view_name='browse-origin-content') -def origin_content_display(request, origin_id, path, visit_id=None, ts=None): +def origin_content_display(request, origin_id, path, + visit_id=None, timestamp=None): """Django view that produces an HTML display of a swh content associated to an origin for a given visit. The url scheme that points to it is the following: * :http:get:`/browse/origin/(origin_id)/content/(path)/` * :http:get:`/browse/origin/(origin_id)/visit/(visit_id)/content/(path)/` - * :http:get:`/browse/origin/(origin_id)/ts/(ts)/content/(path)/` + * :http:get:`/browse/origin/(origin_id)/ts/(timestamp)/content/(path)/` Args: request: input django http request origin_id: id of a swh origin path: path of the content relative to the origin root directory visit_id: optionnal visit id parameter (the last one will be used by default) - ts: optionnal visit timestamp parameter + timestamp: optionnal visit timestamp parameter (the last one will be used by default) branch: optionnal query parameter that specifies the origin branch from which to retrieve the content revision: optional query parameter to specify the origin revision from which to retrieve the content Returns: The HTML rendering of the requested content associated to the provided origin and visit. """ # noqa try: - if not visit_id and not ts: + if not visit_id and not timestamp: origin_visits = get_origin_visits(origin_id) return origin_content_display(request, origin_id, path, origin_visits[-1]['visit']) branches, url_args = _get_origin_branches_and_url_args(origin_id, - visit_id, ts) + visit_id, + timestamp) for b in branches: bc_url_args = dict(url_args) bc_url_args['path'] = path b['url'] = reverse('browse-origin-content', kwargs=bc_url_args, query_params={'branch': b['name']}) revision_id = request.GET.get('revision', None) if revision_id: revision = service.lookup_revision(revision_id) root_sha1_git = revision['directory'] branches.append({'name': revision_id, 'revision': revision_id, 'directory': root_sha1_git}) branch = revision_id else: branch = request.GET.get('branch', 'master') filtered_branches = [b for b in branches if branch in b['name']] if len(filtered_branches) > 0: root_sha1_git = filtered_branches[0]['directory'] branch = filtered_branches[0]['name'] else: - _raise_exception_if_branch_not_found(origin_id, visit_id, ts, - branch) + _raise_exception_if_branch_not_found(origin_id, visit_id, + timestamp, branch) content_info = service.lookup_directory_with_path(root_sha1_git, path) sha1_git = content_info['target'] query_string = 'sha1_git:' + sha1_git content_data, mime_type = request_content(query_string) except Exception as exc: return handle_view_exception(exc) if revision_id: query_params = {'revision': revision_id} else: query_params = {'branch': branch} content_display_data = prepare_content_for_display(content_data, mime_type, path) filename = None path_info = None breadcrumbs = [] split_path = path.split('/') filename = split_path[-1] path = path.replace(filename, '') path_info = gen_path_info(path) breadcrumbs.append({'name': root_sha1_git[:7], 'url': reverse('browse-origin-directory', kwargs=url_args, query_params=query_params)}) for pi in path_info: bc_url_args = dict(url_args) bc_url_args['path'] = pi['path'] breadcrumbs.append({'name': pi['name'], 'url': reverse('browse-origin-directory', kwargs=bc_url_args, query_params=query_params)}) breadcrumbs.append({'name': filename, 'url': None}) content_raw_url = reverse('browse-content-raw', kwargs={'query_string': query_string}, query_params={'filename': filename}) return render(request, 'content.html', {'content_hash_algo': 'sha1_git', 'content_checksum': sha1_git, 'content': content_display_data['content_data'], 'content_raw_url': content_raw_url, 'mime_type': mime_type, 'language': content_display_data['language'], 'breadcrumbs': breadcrumbs, 'branches': branches, 'branch': branch, 'top_right_link': content_raw_url, 'top_right_link_text': 'Raw File'}) def _gen_directory_link(url_args, revision, link_text): directory_url = reverse('browse-origin-directory', kwargs=url_args, query_params={'revision': revision}) return gen_link(directory_url, link_text) NB_LOG_ENTRIES = 20 @browse_route(r'origin/(?P[0-9]+)/log/', r'origin/(?P[0-9]+)/visit/(?P[0-9]+)/log/', # noqa - r'origin/(?P[0-9]+)/ts/(?P[0-9]+)/log/', + r'origin/(?P[0-9]+)/ts/(?P[0-9]+)/log/', view_name='browse-origin-log') -def origin_log_browse(request, origin_id, visit_id=None, ts=None): +def origin_log_browse(request, origin_id, visit_id=None, timestamp=None): """Django view that produces an HTML display of revisions history (aka the commit log) associated to a SWH origin. The url scheme that points to it is the following: * :http:get:`/browse/origin/(origin_id)/log/` * :http:get:`/browse/origin/(origin_id)/visit/(visit_id)/log/` - * :http:get:`/browse/origin/(origin_id)/ts/(ts)/log/` + * :http:get:`/browse/origin/(origin_id)/ts/(timestamp)/log/` Args: request: input django http request origin_id: id of a swh origin visit_id: optionnal visit id parameter (the last one will be used by default) - ts: optionnal visit timestamp parameter + timestamp: optionnal visit timestamp parameter (the last one will be used by default) revs_breadcrumb: query parameter used internally to store the navigation breadcrumbs (i.e. the list of descendant revisions visited so far). per_page: optionnal query parameter used to specify the number of log entries per page branch: optionnal query parameter that specifies the origin branch from which to retrieve the content revision: optional query parameter to specify the origin revision from which to retrieve the directory Returns: The HTML rendering of revisions history for a given SWH visit. """ # noqa try: - if not visit_id and not ts: + if not visit_id and not timestamp: origin_visits = get_origin_visits(origin_id) return origin_log_browse(request, origin_id, origin_visits[-1]['visit']) branches, url_args = _get_origin_branches_and_url_args(origin_id, - visit_id, ts) + visit_id, + timestamp) for b in branches: b['url'] = reverse('browse-origin-log', kwargs=url_args, query_params={'branch': b['name']}) revision_id = request.GET.get('revision', None) revs_breadcrumb = request.GET.get('revs_breadcrumb', None) branch = request.GET.get('branch', 'master') if revision_id: revision = service.lookup_revision(revision_id) branches.append({'name': revision_id, 'revision': revision_id, 'directory': revision['directory']}) revision = revision_id branch = revision_id elif revs_breadcrumb: revs = revs_breadcrumb.split('/') revision = revs[-1] else: filtered_branches = [b for b in branches if branch in b['name']] if len(filtered_branches) > 0: revision = filtered_branches[0]['revision'] branch = filtered_branches[0]['name'] else: - _raise_exception_if_branch_not_found(origin_id, visit_id, ts, - branch) + _raise_exception_if_branch_not_found(origin_id, visit_id, + timestamp, branch) per_page = int(request.GET.get('per_page', NB_LOG_ENTRIES)) revision_log = service.lookup_revision_log(revision, limit=per_page+1) revision_log = list(revision_log) except Exception as exc: return handle_view_exception(exc) revision_log_display_data = prepare_revision_log_for_display( revision_log, per_page, revs_breadcrumb, origin_context=True) prev_rev = revision_log_display_data['prev_rev'] prev_revs_breadcrumb = revision_log_display_data['prev_revs_breadcrumb'] prev_log_url = None if prev_rev: prev_log_url = \ reverse('browse-origin-log', kwargs=url_args, query_params={'revs_breadcrumb': prev_revs_breadcrumb, 'per_page': per_page, 'branch': branch}) next_rev = revision_log_display_data['next_rev'] next_revs_breadcrumb = revision_log_display_data['next_revs_breadcrumb'] next_log_url = None if next_rev: next_log_url = \ reverse('browse-origin-log', kwargs=url_args, query_params={'revs_breadcrumb': next_revs_breadcrumb, 'per_page': per_page, 'branch': branch}) revision_log_data = revision_log_display_data['revision_log_data'] for i, log in enumerate(revision_log_data): log['directory'] = _gen_directory_link(url_args, revision_log[i]['id'], 'Tree') return render(request, 'revision-log.html', {'revision_log': revision_log_data, 'next_log_url': next_log_url, 'prev_log_url': prev_log_url, 'breadcrumbs': None, 'branches': branches, 'branch': branch, 'top_right_link': None, 'top_right_link_text': None}) diff --git a/swh/web/browse/views/revision.py b/swh/web/browse/views/revision.py index 8604d775..c1cea726 100644 --- a/swh/web/browse/views/revision.py +++ b/swh/web/browse/views/revision.py @@ -1,144 +1,144 @@ # Copyright (C) 2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information from django.shortcuts import render from django.utils.safestring import mark_safe from swh.web.common import service from swh.web.common.utils import reverse, format_utc_iso_date from swh.web.common.exc import handle_view_exception from swh.web.browse.browseurls import browse_route from swh.web.browse.utils import ( gen_link, gen_person_link, gen_revision_link, prepare_revision_log_for_display ) def _gen_directory_link(sha1_git, link_text): directory_url = reverse('browse-directory', kwargs={'sha1_git': sha1_git}) return gen_link(directory_url, link_text) def _gen_revision_log_link(revision_id): revision_log_url = reverse('browse-revision-log', kwargs={'sha1_git': revision_id}) return gen_link(revision_log_url, revision_log_url) @browse_route(r'revision/(?P[0-9a-f]+)/', view_name='browse-revision') def revision_browse(request, sha1_git): """ Django view that produces an HTML display of a SWH revision identified by its id. - The url that points to it is :http:get:`/browse/revision/(revision_id)/`. + The url that points to it is :http:get:`/browse/revision/(sha1_git)/`. Args: request: input django http request sha1_git: a SWH revision id Returns: The HMTL rendering for the metadata of the provided revision. """ try: revision = service.lookup_revision(sha1_git) except Exception as exc: return handle_view_exception(exc) revision_data = {} revision_data['author'] = gen_person_link( revision['author']['id'], revision['author']['name']) revision_data['committer'] = gen_person_link( revision['committer']['id'], revision['committer']['name']) revision_data['committer date'] = format_utc_iso_date( revision['committer_date']) revision_data['date'] = format_utc_iso_date(revision['date']) revision_data['directory'] = _gen_directory_link(revision['directory'], revision['directory']) revision_data['history log'] = _gen_revision_log_link(sha1_git) revision_data['id'] = sha1_git revision_data['merge'] = revision['merge'] revision_data['message'] = revision['message'] parents = '' for p in revision['parents']: parent_link = gen_revision_link(p) parents += parent_link + '
' revision_data['parents'] = mark_safe(parents) revision_data['synthetic'] = revision['synthetic'] revision_data['type'] = revision['type'] return render(request, 'revision.html', {'revision': revision_data}) NB_LOG_ENTRIES = 20 @browse_route(r'revision/(?P[0-9a-f]+)/log/', view_name='browse-revision-log') def revision_log_browse(request, sha1_git): """ Django view that produces an HTML display of the history log for a SWH revision identified by its id. - The url that points to it is :http:get:`/browse/revision/(revision_id)/log/`. + The url that points to it is :http:get:`/browse/revision/(sha1_git)/log/`. Args: request: input django http request sha1_git: a SWH revision id Returns: The HMTL rendering of the revision history log. """ # noqa try: per_page = int(request.GET.get('per_page', NB_LOG_ENTRIES)) revision_log = service.lookup_revision_log(sha1_git, limit=per_page+1) revision_log = list(revision_log) except Exception as exc: return handle_view_exception(exc) revs_breadcrumb = request.GET.get('revs_breadcrumb', None) revision_log_display_data = prepare_revision_log_for_display( revision_log, per_page, revs_breadcrumb) prev_rev = revision_log_display_data['prev_rev'] prev_revs_breadcrumb = revision_log_display_data['prev_revs_breadcrumb'] prev_log_url = None if prev_rev: prev_log_url = \ reverse('browse-revision-log', kwargs={'sha1_git': prev_rev}, query_params={'revs_breadcrumb': prev_revs_breadcrumb, 'per_page': per_page}) next_rev = revision_log_display_data['next_rev'] next_revs_breadcrumb = revision_log_display_data['next_revs_breadcrumb'] next_log_url = None if next_rev: next_log_url = \ reverse('browse-revision-log', kwargs={'sha1_git': next_rev}, query_params={'revs_breadcrumb': next_revs_breadcrumb, 'per_page': per_page}) revision_log_data = revision_log_display_data['revision_log_data'] for log in revision_log_data: log['directory'] = _gen_directory_link(log['directory'], 'Tree') return render(request, 'revision-log.html', {'revision_log': revision_log_data, 'next_log_url': next_log_url, 'prev_log_url': prev_log_url, 'breadcrumbs': None, 'branches': None, 'branch': None, 'top_right_link': None, 'top_right_link_text': None}) diff --git a/swh/web/doc_config.py b/swh/web/doc_config.py new file mode 100644 index 00000000..118f7288 --- /dev/null +++ b/swh/web/doc_config.py @@ -0,0 +1,21 @@ +# Copyright (C) 2017 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + + +_swh_web_base_url = 'https://archive.softwareheritage.org' +_swh_web_api_endpoint = 'api' +_swh_web_api_version = 1 +_swh_web_api_url = '%s/%s/%s/' % (_swh_web_base_url, + _swh_web_api_endpoint, + _swh_web_api_version) + +_swh_web_browse_endpoint = 'browse' +_swh_web_browse_url = '%s/%s/' % (_swh_web_base_url, + _swh_web_browse_endpoint) + + +def customize_sphinx_conf(sphinx_conf): + sphinx_conf.extlinks['swh_web_api'] = (_swh_web_api_url + '%s', None) + sphinx_conf.extlinks['swh_web_browse'] = (_swh_web_browse_url + '%s', None) diff --git a/swh/web/tests/browse/views/test_origin.py b/swh/web/tests/browse/views/test_origin.py index d355b604..713b2cd5 100644 --- a/swh/web/tests/browse/views/test_origin.py +++ b/swh/web/tests/browse/views/test_origin.py @@ -1,353 +1,353 @@ # Copyright (C) 2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information from unittest.mock import patch from nose.tools import istest, nottest from django.test import TestCase from django.utils.html import escape from swh.web.common.utils import reverse from .data.origin_test_data import ( origin_info_test_data, origin_visits_test_data, stub_content_origin_id, stub_content_origin_visit_id, stub_content_origin_visit_ts, stub_content_origin_branch, stub_content_origin_visits, stub_content_origin_branches, stub_origin_id, stub_visit_id, stub_origin_visits, stub_origin_branches, stub_origin_root_directory_entries, stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_path, stub_origin_sub_directory_entries, stub_visit_ts ) from .data.content_test_data import ( stub_content_root_dir, stub_content_text_data, stub_content_text_sha1, stub_content_text_path ) from swh.web.browse.utils import ( gen_path_info ) class SwhBrowseOriginTest(TestCase): @patch('swh.web.browse.views.origin.get_origin_visits') @patch('swh.web.browse.views.origin.service') @istest def test_origin_browse(self, mock_service, mock_get_origin_visits): mock_service.lookup_origin.return_value = origin_info_test_data mock_get_origin_visits.return_value = origin_visits_test_data url = reverse('browse-origin', kwargs={'origin_id': origin_info_test_data['id']}) resp = self.client.get(url) self.assertEquals(resp.status_code, 200) self.assertTemplateUsed('origin.html') self.assertContains(resp, '%s' % origin_info_test_data['id']) self.assertContains(resp, '%s' % origin_info_test_data['type']) # noqa self.assertContains(resp, '%s' % (origin_info_test_data['url'], origin_info_test_data['url'])) self.assertContains(resp, '', count=len(origin_visits_test_data)) for visit in origin_visits_test_data: browse_url = reverse('browse-origin-directory', kwargs={'origin_id': visit['origin'], 'visit_id': visit['visit']}) self.assertContains(resp, '%s' % (browse_url, browse_url)) @nottest def origin_content_view_test(self, origin_id, origin_visits, origin_branches, origin_branch, root_dir_sha1, content_sha1, content_path, content_data, content_language, visit_id=None, ts=None): url_args = {'origin_id': origin_id, 'path': content_path} if not visit_id: visit_id = origin_visits[-1]['visit'] if ts: - url_args['ts'] = ts + url_args['timestamp'] = ts else: url_args['visit_id'] = visit_id url = reverse('browse-origin-content', kwargs=url_args) resp = self.client.get(url) self.assertEquals(resp.status_code, 200) self.assertTemplateUsed('content.html') self.assertContains(resp, '' % content_language) self.assertContains(resp, escape(content_data)) split_path = content_path.split('/') filename = split_path[-1] path = content_path.replace(filename, '')[:-1] path_info = gen_path_info(path) del url_args['path'] root_dir_url = reverse('browse-origin-directory', kwargs=url_args, query_params={'branch': origin_branch}) self.assertContains(resp, '
  • ', count=len(path_info)+1) self.assertContains(resp, '%s' % (root_dir_url, root_dir_sha1[:7])) for p in path_info: url_args['path'] = p['path'] dir_url = reverse('browse-origin-directory', kwargs=url_args, query_params={'branch': origin_branch}) self.assertContains(resp, '%s' % (dir_url, p['name'])) self.assertContains(resp, '
  • %s
  • ' % filename) query_string = 'sha1_git:' + content_sha1 url_raw = reverse('browse-content-raw', kwargs={'query_string': query_string}, query_params={'filename': filename}) self.assertContains(resp, url_raw) self.assertContains(resp, '
  • ', count=len(origin_branches)) url_args['path'] = content_path for branch in origin_branches: root_dir_branch_url = \ reverse('browse-origin-content', kwargs=url_args, query_params={'branch': branch['name']}) self.assertContains(resp, '%s' % (root_dir_branch_url, branch['name'])) @patch('swh.web.browse.views.origin.get_origin_visits') @patch('swh.web.browse.views.origin.get_origin_visit_branches') @patch('swh.web.browse.views.origin.service') @patch('swh.web.browse.views.origin.request_content') @istest def origin_content_view(self, mock_request_content, mock_service, mock_get_origin_visit_branches, mock_get_origin_visits): mock_get_origin_visits.return_value = stub_content_origin_visits mock_get_origin_visit_branches.return_value = stub_content_origin_branches # noqa mock_service.lookup_directory_with_path.return_value = \ {'target': stub_content_text_sha1} mock_request_content.return_value = stub_content_text_data, 'text/x-c++' # noqa self.origin_content_view_test(stub_content_origin_id, stub_content_origin_visits, stub_content_origin_branches, stub_content_origin_branch, stub_content_root_dir, stub_content_text_sha1, stub_content_text_path, stub_content_text_data, 'cpp') self.origin_content_view_test(stub_content_origin_id, stub_content_origin_visits, stub_content_origin_branches, stub_content_origin_branch, stub_content_root_dir, stub_content_text_sha1, stub_content_text_path, stub_content_text_data, 'cpp', visit_id=stub_content_origin_visit_id) self.origin_content_view_test(stub_content_origin_id, stub_content_origin_visits, stub_content_origin_branches, stub_content_origin_branch, stub_content_root_dir, stub_content_text_sha1, stub_content_text_path, stub_content_text_data, 'cpp', ts=stub_content_origin_visit_ts) @nottest def origin_directory_view(self, origin_id, origin_visits, origin_branches, origin_branch, root_directory_sha1, directory_entries, visit_id=None, ts=None, path=None): dirs = [e for e in directory_entries if e['type'] == 'dir'] files = [e for e in directory_entries if e['type'] == 'file'] if not visit_id: visit_id = origin_visits[-1]['visit'] url_args = {'origin_id': origin_id} if ts: - url_args['ts'] = ts + url_args['timestamp'] = ts else: url_args['visit_id'] = visit_id if path: url_args['path'] = path url = reverse('browse-origin-directory', kwargs=url_args) resp = self.client.get(url) self.assertEquals(resp.status_code, 200) self.assertTemplateUsed('directory.html') self.assertContains(resp, '', count=len(dirs)) self.assertContains(resp, '', count=len(files)) for d in dirs: dir_path = d['name'] if path: dir_path = "%s/%s" % (path, d['name']) dir_url_args = dict(url_args) dir_url_args['path'] = dir_path dir_url = reverse('browse-origin-directory', kwargs=dir_url_args, query_params={'branch': origin_branch}) # noqa self.assertContains(resp, dir_url) for f in files: file_path = f['name'] if path: file_path = "%s/%s" % (path, f['name']) file_url_args = dict(url_args) file_url_args['path'] = file_path file_url = reverse('browse-origin-content', kwargs=file_url_args, query_params={'branch': origin_branch}) # noqa self.assertContains(resp, file_url) if 'path' in url_args: del url_args['path'] root_dir_branch_url = \ reverse('browse-origin-directory', kwargs=url_args, query_params={'branch': origin_branch}) nb_bc_paths = 1 if path: nb_bc_paths = len(path.split('/')) + 1 self.assertContains(resp, '
  • ', count=nb_bc_paths) self.assertContains(resp, '%s' % (root_dir_branch_url, root_directory_sha1[:7])) self.assertContains(resp, '
  • ', count=len(origin_branches)) if path: url_args['path'] = path for branch in origin_branches: root_dir_branch_url = \ reverse('browse-origin-directory', kwargs=url_args, query_params={'branch': branch['name']}) self.assertContains(resp, '%s' % (root_dir_branch_url, branch['name'])) @patch('swh.web.browse.views.origin.get_origin_visits') @patch('swh.web.browse.views.origin.get_origin_visit_branches') @patch('swh.web.browse.utils.service') @istest def origin_root_directory_view(self, mock_service, mock_get_origin_visit_branches, mock_get_origin_visits): mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_branches.return_value = stub_origin_branches mock_service.lookup_directory.return_value = \ stub_origin_root_directory_entries self.origin_directory_view(stub_origin_id, stub_origin_visits, stub_origin_branches, stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries) self.origin_directory_view(stub_origin_id, stub_origin_visits, stub_origin_branches, stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries, visit_id=stub_visit_id) self.origin_directory_view(stub_origin_id, stub_origin_visits, stub_origin_branches, stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries, ts=stub_visit_ts) @patch('swh.web.browse.views.origin.get_origin_visits') @patch('swh.web.browse.views.origin.get_origin_visit_branches') @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.origin.service') @istest def origin_sub_directory_view(self, mock_origin_service, mock_utils_service, mock_get_origin_visit_branches, mock_get_origin_visits): mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_branches.return_value = stub_origin_branches mock_utils_service.lookup_directory.return_value = \ stub_origin_sub_directory_entries mock_origin_service.lookup_directory_with_path.return_value = \ {'target': '120c39eeb566c66a77ce0e904d29dfde42228adb'} self.origin_directory_view(stub_origin_id, stub_origin_visits, stub_origin_branches, stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, path=stub_origin_sub_directory_path) self.origin_directory_view(stub_origin_id, stub_origin_visits, stub_origin_branches, stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, visit_id=stub_visit_id, path=stub_origin_sub_directory_path) self.origin_directory_view(stub_origin_id, stub_origin_visits, stub_origin_branches, stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, ts=stub_visit_ts, path=stub_origin_sub_directory_path) diff --git a/swh/web/urls.py b/swh/web/urls.py index 62654233..3cda50e7 100644 --- a/swh/web/urls.py +++ b/swh/web/urls.py @@ -1,50 +1,27 @@ # Copyright (C) 2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information -"""swhweb URL Configuration - -The :data:`urlpatterns` list routes URLs to views. For more information please - see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ - -Examples: - -- Function views: - - 1. Add an import: ``from my_app import views`` - 2. Add a URL to urlpatterns: ``url(r'^$', views.home, name='home')`` - -- Class-based views: - - 1. Add an import: ``from other_app.views import Home`` - 2. Add a URL to urlpatterns: ``url(r'^$', Home.as_view(), name='home')`` - -- Including another URLconf: - - 1. Import the include function: ``from django.conf.urls import url, include`` - 2. Add a URL to urlpatterns: ``url(r'^blog/', include('blog.urls'))`` - -""" from django.conf.urls import url, include from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.shortcuts import redirect from django.views.generic.base import RedirectView favicon_view = RedirectView.as_view(url='/static/img/icons/swh-logo-32x32.png', permanent=True) def default_view(request): return redirect('api_homepage') urlpatterns = [ url(r'^favicon\.ico$', favicon_view), url(r'^api/', include('swh.web.api.urls')), url(r'^browse/', include('swh.web.browse.urls')), url(r'^$', default_view), ] urlpatterns += staticfiles_urlpatterns() diff --git a/swh/web/wsgi.py b/swh/web/wsgi.py index 5177b9ac..9eee6ac1 100644 --- a/swh/web/wsgi.py +++ b/swh/web/wsgi.py @@ -1,21 +1,12 @@ # Copyright (C) 2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information -""" -WSGI config for swhweb project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ -""" - import os from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "swh.web.settings.production") application = get_wsgi_application()