1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/ihatemoney_ynh.git synced 2024-09-03 19:26:15 +02:00

Document the API. Fix #46

This commit is contained in:
Alexis Metaireau 2011-10-18 23:26:13 +02:00
parent 4e1819523f
commit 6f4f04b117
11 changed files with 504 additions and 15 deletions

View file

@ -51,7 +51,7 @@ How about the REST API?
=======================
Yep, you're right, there is a REST API with this. Head to the `api
documentation` to know more.
documentation <http://readthedocs.org/docs/ihatemoney/en/latest/api.html>`_ to know more.
How to contribute
=================

View file

@ -12,7 +12,7 @@ db = SQLAlchemy()
class Project(db.Model):
_to_serialize = ("id", "name", "password", "contact_email",
"members", "active_members")
"members", "active_members", "balance")
id = db.Column(db.String, primary_key=True)
@ -25,7 +25,8 @@ class Project(db.Model):
def active_members(self):
return [m for m in self.members if m.activated]
def get_balance(self):
@property
def balance(self):
balances, should_pay, should_receive = defaultdict(int), defaultdict(int), defaultdict(int)
@ -39,7 +40,7 @@ class Project(db.Model):
should_receive[bill.payer] += bill.pay_each()
for person in self.members:
balances[person] = round(should_receive[person] - should_pay[person], 2)
balances[person.id] = round(should_receive[person] - should_pay[person], 2)
return balances

View file

@ -56,13 +56,13 @@
<h2>{{ _("Balance") }}</h2>
<table class="balance">
{% set balance = g.project.get_balance() %}
{% set balance = g.project.balance %}
{% for member in g.project.members %}
{% if member.activated or balance[member] != 0 %}
{% if member.activated or balance[member.id] != 0 %}
<tr>
<td>{{ member.name }}</td>
<td class="{% if balance[member] > 0 %}positive{% elif balance[member] < 0 %}negative{% endif %}">
{% if balance[member] > 0 %}+{% endif %}{{ balance[member] }}
<td class="{% if balance[member.id] > 0 %}positive{% elif balance[member.id] < 0 %}negative{% endif %}">
{% if balance[member.id] > 0 %}+{% endif %}{{ balance[member.id] }}
</td>
<td> {% if member.activated %}<a class="remove" href="{{ url_for(".remove_member", member_id=member.id) }}">{{ _("delete") }}</a>{% else %}<a href="{{ url_for(".reactivate", member_id=member.id) }}">{{ _("reactivate") }}</a>{% endif %}</td>
</tr>

View file

@ -333,7 +333,7 @@ class BudgetTestCase(TestCase):
'amount': '17',
})
balance = models.Project.query.get("raclette").get_balance()
balance = models.Project.query.get("raclette").balance
self.assertEqual(set(balance.values()), set([19.0, -19.0]))
def test_rounding(self):
@ -369,10 +369,8 @@ class BudgetTestCase(TestCase):
'amount': '22',
})
balance = models.Project.query.get("raclette").get_balance()
balance = dict([(user.name, bal) for user, bal in balance.items()])
self.assertDictEqual(balance, {u'tata': -8.12, u'alexis': 8.12,
u'fred': 0.0})
balance = models.Project.query.get("raclette").balance
self.assertDictEqual(balance, {3: -8.12, 1: 8.12, 2: 0.0})
def test_edit_project(self):
@ -489,7 +487,8 @@ class APITestCase(TestCase):
"contact_email": "raclette@notmyidea.org",
"members": [],
"password": "raclette",
"id": "raclette"
"id": "raclette",
"balance": {},
}
self.assertDictEqual(json.loads(resp.data), expected)
@ -512,7 +511,8 @@ class APITestCase(TestCase):
"contact_email": "yeah@notmyidea.org",
"members": [],
"password": "raclette",
"id": "raclette"
"id": "raclette",
"balance": {},
}
self.assertDictEqual(json.loads(resp.data), expected)

130
docs/Makefile Normal file
View file

@ -0,0 +1,130 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Ihatemoney.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Ihatemoney.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Ihatemoney"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Ihatemoney"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
make -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

3
docs/_themes/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.pyc
*.pyo
.DS_Store

1
docs/_themes/pelican vendored Submodule

@ -0,0 +1 @@
Subproject commit 449c2149aa36f89c2cfcf4039b9e9939cca19733

163
docs/api.rst Normal file
View file

@ -0,0 +1,163 @@
The REST API
############
All of what's possible to do with the website is also possible via a web API.
This document explains how the API is organized and how you can query it.
By default, the API talks JSON. There is no other way to speak with it
currently.
Overall organisation
====================
You can access three different things: projects, members and bills. You can
also get the balance for a project.
For the examples, I'm using curl, feel free to use whatever you want to do the
same thing, curl is not a requirement.
Authentication
--------------
To interact with bills and members, and to do something else than creating
a project, you need to be authenticated. The only way to authenticate yourself
currently is using the "basic" HTTP authentication.
If you don't want your credentials to pass in clear trought the network, you
can use the ssl endpoint at https://ihatemoney.notmyidea.org
For instance, here is how to see the what's in a project, using curl::
$ curl --basic -u demo:demo http://ihatemoney.notmyidea.org/api/projects/demo
Projects
--------
You can't list projects, for security reasons. But you can create, update and
delete one directly from the API.
The URLs are `/api/projects` and `/api/projects/<identifier>`.
Creating a project
~~~~~~~~~~~~~~~~~~
A project needs the following arguments:
* `name`: The project name (string)
* `id`: the project identifier (string without special chars or spaces)
* `password`: the project password / secret code (string)
* `contact_email`: the contact email
::
$ curl -X POST https://ihatemoney.notmyidea.org/api/projects \
-d 'name=yay&id=yay&password=yay&contact_email=yay@notmyidea.org'
"yay"
As you can see, the API retuns the identifier of the project
Getting information about the project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Getting information about the project::
$ curl --basic -u demo:demo http://ihatemoney.notmyidea.org/api/projects/demo
{
"name": "demonstration",
"contact_email": "demo@notmyidea.org",
"password": "demo",
"id": "demo",
"active_members": [{"activated": true, "id": 31, "name": "Arnaud"},
{"activated": true, "id": 32, "name": "Alexis"},
{"activated": true, "id": 33, "name": "Olivier"},
{"activated": true, "id": 34, "name": "Fred"}],
"members": [{"activated": true, "id": 31, "name": "Arnaud"},
{"activated": true, "id": 32, "name": "Alexis"},
{"activated": true, "id": 33, "name": "Olivier"},
{"activated": true, "id": 34, "name": "Fred"}],
}
Updating a project
~~~~~~~~~~~~~~~~~~
Updating a project is done with the `PUT` verb::
$ curl --basic -u yay:yay -X PUT\
http://ihatemoney.notmyidea.org/api/projects/yay -d\
'name=yay&id=yay&password=yay&contact_email=youpi@notmyidea.org'
Deleting a project
~~~~~~~~~~~~~~~~~~
Just send a DELETE request ont the project URI ::
$ curl --basic -u demo:demo -X DELETE http://ihatemoney.notmyidea.org/api/projects/demo
Members
-------
You can get all the members with a `GET` on `/api/projects/<id>/members`::
$ curl --basic -u demo:demo http://ihatemoney.notmyidea.org/api/projects/demo/members\
[{"activated": true, "id": 31, "name": "Arnaud"},
{"activated": true, "id": 32, "name": "Alexis"},
{"activated": true, "id": 33, "name": "Olivier"},
{"activated": true, "id": 34, "name": "Fred"}]
Add a member with a `POST` request on `/api/projects/<id>/members`::
$ curl --basic -u demo:demo -X POST\
http://ihatemoney.notmyidea.org/api/projects/demo/members -d 'name=tatayoyo'
35
You can also `PUT` a new version of a member (changing its name)::
$ curl --basic -u demo:demo -X PUT\
http://ihatemoney.notmyidea.org/api/projects/demo/members/36\
-d 'name=yeaaaaah'
{"activated": true, "id": 36, "name": "yeaaaaah"}
Delete a member with a `DELETE` request on `/api/projects/<id>/members/<member-id>`::
$ curl --basic -u demo:demo -X DELETE\
http://ihatemoney.notmyidea.org/api/projects/demo/members/35
"OK
Bills
-----
You can get the list of bills by doing a `GET` on `/api/projects/<id>/bills` ::
$ curl --basic -u demo:demo http://ihatemoney.notmyidea.org/api/projects/demo/bills
Add a bill with a `POST` query on `/api/projects/<id>/bills`. you need the
following params:
* `date`: the date of the bill. (yy-mm-dd)
* `what`: what have been payed
* `payer`: by who ? (id)
* `payed_for`: list of ids
* `amount`: amount payed
Returns the id of the created bill ::
$ curl --basic -u demo:demo -X POST\
http://ihatemoney.notmyidea.org/api/projects/demo/bills\
-d "date=2011-09-10&what=raclette&payer=31&payed_for=31&amount=200"
80
You can also `PUT` a new version of the bill at
`/api/projects/<id>/bills/<bill-id>`::
$ curl --basic -u demo:demo -X PUT\
http://ihatemoney.notmyidea.org/api/projects/demo/bills/80\
-d "date=2011-09-10&what=raclette&payer=31&payed_for=31&amount=250"
80
And you can of course `DELETE` them at `/api/projects/<id>/bills/<bill-id>`::
$ curl --basic -u demo:demo -X DELETE\
http://ihatemoney.notmyidea.org/api/projects/demo/bills/80\
"OK"

20
docs/conf.py Normal file
View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
import sys, os
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'I hate money'
copyright = u'2011, The \'I hate money\' team'
version = '1.0'
release = '1.0'
exclude_patterns = ['_build']
pygments_style = 'sphinx'
sys.path.append(os.path.abspath('_themes'))
html_theme_path = ['_themes']
html_theme = 'pelican'
html_static_path = ['_static']
html_theme_options = { 'nosidebar': True }

1
docs/index.rst Symbolic link
View file

@ -0,0 +1 @@
../README.rst

170
docs/make.bat Normal file
View file

@ -0,0 +1,170 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Ihatemoney.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Ihatemoney.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end