just futzing around so far with flask/mustache + a very basic design document as well
Getty Ritter
8 years ago
1 | # GitNode Design Document | |
2 | ||
3 | ## Interoperability | |
4 | ||
5 | One major design goal of GitNode is to allow GitNode instances | |
6 | to interoperate—that is, to support pull requests and | |
7 | collaboration between GitNode instances. To do this, GitNode | |
8 | repos can include a "link file", which is a special metadata | |
9 | file including metadata like: | |
10 | ||
11 | - what kind of information the original endpoint accepts: | |
12 | pull requests, issues and bug reports, wiki pages, &c. | |
13 | - the original HTTP location of the repo | |
14 | - the original API endpoint of that repo | |
15 | - the "API style" of the repo in question | |
16 | - recursive data on the above, if the original repo also | |
17 | included a link file. | |
18 | ||
19 | For example, if I maintain a GitNode instance at | |
20 | `http://gitnode.gdritter.com/` and have a project called | |
21 | `my-project`, then the HTTP location of my repo is | |
22 | `http://gitnode.gdritter.com/p:my-project`, the API endpoint is | |
23 | `http://gitnode.gdritter.com/api`, and the API style is | |
24 | `gitnode`. If my friend clones this repo to | |
25 | `http://gitnode.moreproductive.com/p:my-project`, then those | |
26 | values are stored in the repo metadata. Consequently, his | |
27 | `gitnode` instance knows how to submit a merge request back | |
28 | to my instance. | |
29 | ||
30 | If I clone a repo from GitHub, then the link file can also | |
31 | be generated automatically: this allows a GitNode instance to | |
32 | host a project, but | |
33 | ||
34 | ||
35 | ## User-Facing | |
36 | ||
37 | ``` | |
38 | ``` | |
39 | ||
40 | ## API | |
41 | ||
42 | The API is modeled after GitHub's API, but is missing all the | |
43 | features that GitNode _also_ lacks: for example, GitNode has | |
44 | no notion of users or organizations, so a GitHub endpoint | |
45 | like `/orgs/...` is not provided. You can always issue a | |
46 | `GET` request to the root endpoint in order to discover which | |
47 | endpoints are supported. | |
48 | ||
49 | ``` | |
50 | ``` |
1 | from flask import Flask | |
2 | import mustache | |
3 | ||
4 | app = Flask(__name__) | |
5 | ||
6 | ||
7 | @mustache.template("templates/tree.mustache") | |
8 | def file_tree(): | |
9 | return {'files': | |
10 | [dict(type='dir', name='this', url='/tree/this'), | |
11 | dict(type='file', name='that', url='/tree/that'), | |
12 | dict(type='file', name='the-other', url='/tree/the-other'), | |
13 | ]}, {} | |
14 | ||
15 | ||
16 | @app.route("/") | |
17 | @mustache.template('templates/main.mustache') | |
18 | def index(): | |
19 | context = {'title': 'index', 'content': file_tree()} | |
20 | return context, {} | |
21 | ||
22 | if __name__ == '__main__': | |
23 | app.run(debug=True) |
1 | <ul> | |
2 | <li>gitnode ©2016 getty ritter</li> | |
3 | <li><a href="http://infinitenegativeutility.com/gitnode/help/">help</a></li> | |
4 | <li><a href="http://infinitenegativeutility.com/gitnode/">about</a></li> | |
5 | </ul> |
1 | <h1>gitnode: {{title}}</h1> |
1 | <!DOCTYPE html> | |
2 | <html> | |
3 | <head> | |
4 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8;"/> | |
5 | <title>GitNode {{title}}</title> | |
6 | <style type="text/css"> | |
7 | body { | |
8 | font-family: fira, "Helvetica", "Arial", sans-serif; | |
9 | } | |
10 | .content { | |
11 | border: solid; | |
12 | border-width: 1px; | |
13 | width: 95%; | |
14 | padding: 20px; | |
15 | margin-top: 20px; | |
16 | margin-left: auto; | |
17 | margin-right: auto; | |
18 | } | |
19 | .file-listing { | |
20 | border: solid; | |
21 | border-width: 1px; | |
22 | } | |
23 | .file-listing li { | |
24 | list-style-type: none; | |
25 | } | |
26 | .header { | |
27 | text-align: center; | |
28 | } | |
29 | .footer { | |
30 | text-align: center; | |
31 | } | |
32 | .footer li { | |
33 | display: inline; | |
34 | list-style-type: none; | |
35 | padding-left: 10px; | |
36 | padding-right: 10px; | |
37 | } | |
38 | </style> | |
39 | </head> | |
40 | <body> | |
41 | <div class="content"> | |
42 | <div class="header">{{>header}}</div> | |
43 | <div class="main">{{{content}}}</div> | |
44 | <div class="footer">{{>footer}}</div> | |
45 | </div> | |
46 | </body> | |
47 | </html> |