just futzing around so far with flask/mustache + a very basic design document as well
Getty Ritter
9 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> |