mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-05-06 21:11:49 +02:00
Merge branch 'master' into almet/feat/showcase
This commit is contained in:
commit
af1562ce24
72 changed files with 7043 additions and 1059 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,4 +1,3 @@
|
||||||
ihatemoney.cfg
|
|
||||||
*.pyc
|
*.pyc
|
||||||
*.egg-info
|
*.egg-info
|
||||||
dist
|
dist
|
||||||
|
@ -11,4 +10,10 @@ build
|
||||||
.vscode
|
.vscode
|
||||||
.env
|
.env
|
||||||
.pytest_cache
|
.pytest_cache
|
||||||
|
ihatemoney/budget.db
|
||||||
|
.idea/
|
||||||
|
.envrc
|
||||||
|
.DS_Store
|
||||||
|
.idea
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
|
13
.isort.cfg
Normal file
13
.isort.cfg
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[settings]
|
||||||
|
# Needed for black compatibility
|
||||||
|
multi_line_output=3
|
||||||
|
include_trailing_comma=True
|
||||||
|
force_grid_wrap=0
|
||||||
|
line_length=88
|
||||||
|
combine_as_imports=True
|
||||||
|
|
||||||
|
# If set, imports will be sorted within their section independent to the import_type.
|
||||||
|
force_sort_within_sections=True
|
||||||
|
|
||||||
|
# skip
|
||||||
|
skip_glob=.local,**/migrations/**,**/node_modules/**,**/node-forge/**
|
|
@ -1,9 +1,9 @@
|
||||||
sudo: false
|
sudo: false
|
||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- "3.5"
|
|
||||||
- "3.6"
|
- "3.6"
|
||||||
- "3.7"
|
- "3.7"
|
||||||
|
- "3.8"
|
||||||
script: tox
|
script: tox
|
||||||
install:
|
install:
|
||||||
- pip install tox-travis
|
- pip install tox-travis
|
||||||
|
|
|
@ -9,7 +9,7 @@ This document describes changes between each past release.
|
||||||
- Add support for espanol latino america (es_419)
|
- Add support for espanol latino america (es_419)
|
||||||
- Use the external debts lib to solve settlements (#476)
|
- Use the external debts lib to solve settlements (#476)
|
||||||
- Remove balance column in statistics view (#323)
|
- Remove balance column in statistics view (#323)
|
||||||
|
- Remove requirements files in favor of setup.cfg pinning (#558)
|
||||||
|
|
||||||
4.1.3 (2019-09-18)
|
4.1.3 (2019-09-18)
|
||||||
==================
|
==================
|
||||||
|
|
|
@ -7,20 +7,27 @@ Adrien CLERC
|
||||||
Alexandre Avenel
|
Alexandre Avenel
|
||||||
Alexis Métaireau
|
Alexis Métaireau
|
||||||
Allan Nordhøy
|
Allan Nordhøy
|
||||||
|
am97
|
||||||
|
Andrew Dickinson
|
||||||
Arnaud Bos
|
Arnaud Bos
|
||||||
Baptiste Jonglez
|
Baptiste Jonglez
|
||||||
Benjamin Bouvier
|
Benjamin Bouvier
|
||||||
Berteh
|
Berteh
|
||||||
|
bmatticus
|
||||||
Brice Maron
|
Brice Maron
|
||||||
Byron Ullauri
|
Byron Ullauri
|
||||||
Carey Metcalfe
|
Carey Metcalfe
|
||||||
Daniel Schreiber
|
Daniel Schreiber
|
||||||
|
DavidRThrashJr
|
||||||
donkers
|
donkers
|
||||||
|
Edwin Smulders
|
||||||
Elizabeth Sherrock
|
Elizabeth Sherrock
|
||||||
|
eMerzh
|
||||||
Feth AREZKI
|
Feth AREZKI
|
||||||
Frédéric Sureau
|
Frédéric Sureau
|
||||||
Glandos
|
Glandos
|
||||||
Heimen Stoffels
|
Heimen Stoffels
|
||||||
|
James Leong
|
||||||
Jocelyn Delalande
|
Jocelyn Delalande
|
||||||
Lucas Verney
|
Lucas Verney
|
||||||
Luc Didry
|
Luc Didry
|
||||||
|
@ -37,5 +44,6 @@ Richard Coates
|
||||||
THANOS SIOURDAKIS
|
THANOS SIOURDAKIS
|
||||||
Toover
|
Toover
|
||||||
Xavier Mehrenberger
|
Xavier Mehrenberger
|
||||||
|
zorun
|
||||||
|
|
||||||
The manual drawings are from Coline Billon, they are under CC BY 4.0.
|
The manual drawings are from Coline Billon, they are under CC BY 4.0.
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
include *.rst
|
include *.rst
|
||||||
recursive-include ihatemoney *.rst *.py *.yaml *.po *.mo *.html *.css *.js *.eot *.svg *.woff *.txt *.png *.ini *.cfg *.j2
|
recursive-include ihatemoney *.rst *.py *.yaml *.po *.mo *.html *.css *.js *.eot *.svg *.woff *.txt *.png *.ini *.cfg *.j2
|
||||||
include LICENSE CONTRIBUTORS CHANGELOG.rst requirements.txt
|
include LICENSE CONTRIBUTORS CHANGELOG.rst
|
||||||
|
|
29
Makefile
29
Makefile
|
@ -11,10 +11,10 @@ ZOPFLIPNG := zopflipng
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: install ## Alias for install
|
all: install ## Alias for install
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: virtualenv $(INSTALL_STAMP) ## Install dependencies
|
install: virtualenv setup.cfg $(INSTALL_STAMP) ## Install dependencies
|
||||||
$(INSTALL_STAMP):
|
$(INSTALL_STAMP):
|
||||||
$(VENV)/bin/pip install -U pip
|
$(VENV)/bin/pip install -U pip
|
||||||
$(VENV)/bin/pip install -r requirements.txt
|
$(VENV)/bin/pip install -e .
|
||||||
touch $(INSTALL_STAMP)
|
touch $(INSTALL_STAMP)
|
||||||
|
|
||||||
.PHONY: virtualenv
|
.PHONY: virtualenv
|
||||||
|
@ -23,9 +23,9 @@ $(PYTHON):
|
||||||
$(VIRTUALENV) $(VENV)
|
$(VIRTUALENV) $(VENV)
|
||||||
|
|
||||||
.PHONY: install-dev
|
.PHONY: install-dev
|
||||||
install-dev: $(INSTALL_STAMP) $(DEV_STAMP) ## Install development dependencies
|
install-dev: virtualenv setup.cfg $(INSTALL_STAMP) $(DEV_STAMP) ## Install development dependencies
|
||||||
$(DEV_STAMP): $(PYTHON) dev-requirements.txt
|
$(DEV_STAMP): $(PYTHON)
|
||||||
$(VENV)/bin/pip install -Ur dev-requirements.txt
|
$(VENV)/bin/pip install -Ue .[dev]
|
||||||
touch $(DEV_STAMP)
|
touch $(DEV_STAMP)
|
||||||
|
|
||||||
.PHONY: remove-install-stamp
|
.PHONY: remove-install-stamp
|
||||||
|
@ -41,11 +41,19 @@ serve: install ## Run the ihatemoney server
|
||||||
$(PYTHON) -m ihatemoney.manage runserver
|
$(PYTHON) -m ihatemoney.manage runserver
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: $(DEV_STAMP) ## Run the tests
|
test: install-dev ## Run the tests
|
||||||
$(VENV)/bin/tox
|
$(VENV)/bin/tox
|
||||||
|
|
||||||
|
.PHONY: black
|
||||||
|
black: install-dev ## Run the tests
|
||||||
|
$(VENV)/bin/black --target-version=py34 .
|
||||||
|
|
||||||
|
.PHONY: isort
|
||||||
|
isort: install-dev ## Run the tests
|
||||||
|
$(VENV)/bin/isort -rc .
|
||||||
|
|
||||||
.PHONY: release
|
.PHONY: release
|
||||||
release: $(DEV_STAMP) ## Release a new version (see https://ihatemoney.readthedocs.io/en/latest/contributing.html#how-to-release)
|
release: install-dev ## Release a new version (see https://ihatemoney.readthedocs.io/en/latest/contributing.html#how-to-release)
|
||||||
$(VENV)/bin/fullrelease
|
$(VENV)/bin/fullrelease
|
||||||
|
|
||||||
.PHONY: compress-assets
|
.PHONY: compress-assets
|
||||||
|
@ -76,13 +84,6 @@ create-empty-database-revision: ## Create an empty database revision
|
||||||
@read -p "Please enter a message describing this revision: " rev_message; \
|
@read -p "Please enter a message describing this revision: " rev_message; \
|
||||||
$(PYTHON) -m ihatemoney.manage db revision -d ihatemoney/migrations -m "$${rev_message}"
|
$(PYTHON) -m ihatemoney.manage db revision -d ihatemoney/migrations -m "$${rev_message}"
|
||||||
|
|
||||||
.PHONY: build-requirements
|
|
||||||
build-requirements: ## Save currently installed packages to requirements.txt
|
|
||||||
$(VIRTUALENV) $(TEMPDIR)
|
|
||||||
$(TEMPDIR)/bin/pip install -U pip
|
|
||||||
$(TEMPDIR)/bin/pip install -Ue "."
|
|
||||||
$(TEMPDIR)/bin/pip freeze | grep -v -- '-e' > requirements.txt
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: ## Destroy the virtual environment
|
clean: ## Destroy the virtual environment
|
||||||
rm -rf .venv
|
rm -rf .venv
|
||||||
|
|
12
README.rst
12
README.rst
|
@ -5,6 +5,10 @@ I hate money
|
||||||
:target: https://travis-ci.org/spiral-project/ihatemoney
|
:target: https://travis-ci.org/spiral-project/ihatemoney
|
||||||
:alt: Travis CI Build Status
|
:alt: Travis CI Build Status
|
||||||
|
|
||||||
|
.. image:: https://hosted.weblate.org/widgets/i-hate-money/-/i-hate-money/svg-badge.svg
|
||||||
|
:target: https://hosted.weblate.org/engage/i-hate-money/?utm_source=widget
|
||||||
|
:alt: Translation status from Weblate
|
||||||
|
|
||||||
*I hate money* is a web application made to ease shared budget management.
|
*I hate money* is a web application made to ease shared budget management.
|
||||||
It keeps track of who bought what, when, and for whom; and helps to settle the
|
It keeps track of who bought what, when, and for whom; and helps to settle the
|
||||||
bills.
|
bills.
|
||||||
|
@ -21,7 +25,7 @@ encouraged to do so.
|
||||||
Requirements
|
Requirements
|
||||||
============
|
============
|
||||||
|
|
||||||
* **Python**: 3.5, 3.6, 3.7.
|
* **Python**: 3.6, 3.7, 3.8.
|
||||||
* **Backends**: MySQL, PostgreSQL, SQLite, Memory.
|
* **Backends**: MySQL, PostgreSQL, SQLite, Memory.
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
|
@ -31,3 +35,9 @@ Do you wish to contribute to IHateMoney? Fantastic! There's a lot of very
|
||||||
useful help on the official `contributing
|
useful help on the official `contributing
|
||||||
<https://ihatemoney.readthedocs.io/en/latest/contributing.html>`_ page.
|
<https://ihatemoney.readthedocs.io/en/latest/contributing.html>`_ page.
|
||||||
|
|
||||||
|
Translation status
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. image:: https://hosted.weblate.org/widgets/i-hate-money/-/i-hate-money/multi-blue.svg
|
||||||
|
:target: https://hosted.weblate.org/engage/i-hate-money/?utm_source=widget
|
||||||
|
:alt: Translation status for each language
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
zest.releaser
|
|
||||||
tox
|
|
||||||
pytest
|
|
||||||
flake8
|
|
||||||
Flask-Testing
|
|
||||||
black ; python_version >= '3.6'
|
|
|
@ -1,6 +1,3 @@
|
||||||
# coding: utf8
|
|
||||||
import sys, os
|
|
||||||
|
|
||||||
templates_path = ["_templates"]
|
templates_path = ["_templates"]
|
||||||
source_suffix = ".rst"
|
source_suffix = ".rst"
|
||||||
master_doc = "index"
|
master_doc = "index"
|
||||||
|
|
|
@ -1,14 +1,64 @@
|
||||||
Contributing
|
Contributing
|
||||||
############
|
############
|
||||||
|
|
||||||
Setup a dev environment
|
.. _how-to-contribute:
|
||||||
=======================
|
|
||||||
|
|
||||||
You must develop on top of the git master branch::
|
How to contribute
|
||||||
|
=================
|
||||||
|
|
||||||
|
You would like to contribute? First, thanks a bunch! This project is a small
|
||||||
|
project with just a few people behind it, so any help is appreciated!
|
||||||
|
|
||||||
|
There are different ways to help us, regarding if you are a designer,
|
||||||
|
a developer or an user.
|
||||||
|
|
||||||
|
As a developer
|
||||||
|
--------------
|
||||||
|
|
||||||
|
If you want to contribute code, you can write it and then issue a pull request
|
||||||
|
on github. To get started, please read :ref:`setup-dev-environment` and
|
||||||
|
:ref:`contributing-developer`.
|
||||||
|
|
||||||
|
As a designer / Front-end developer
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
Feel free to provide mockups, or to involve yourself in the discussions
|
||||||
|
happening on the GitHub issue tracker. All ideas are welcome. Of course, if you
|
||||||
|
know how to implement them, feel free to fork and make a pull request.
|
||||||
|
|
||||||
|
As a translator
|
||||||
|
---------------
|
||||||
|
|
||||||
|
If you're able to translate Ihatemoney in your own language,
|
||||||
|
head over to `the website we use for translations <https://hosted.weblate.org/projects/i-hate-money/i-hate-money/>`_
|
||||||
|
and start translating.
|
||||||
|
|
||||||
|
All the heavy lifting will be done automatically, and your strings will
|
||||||
|
eventually be integrated.
|
||||||
|
|
||||||
|
Once a language is ready to be integrated, add it to the
|
||||||
|
``SUPPORTED_LANGUAGES`` list, in ``ihatemoney/default_settings.py``.
|
||||||
|
|
||||||
|
End-user
|
||||||
|
--------
|
||||||
|
|
||||||
|
You are using the application and found a bug? You have some ideas about how to
|
||||||
|
improve the project? Please tell us `by filling a new issue <https://github.com/spiral-project/ihatemoney/issues>`_.
|
||||||
|
Or, if you prefer, you can send me an e-mail to `alexis@notmyidea.org` and I
|
||||||
|
will update the issue tracker with your feedback.
|
||||||
|
|
||||||
|
Thanks again!
|
||||||
|
|
||||||
|
.. _setup-dev-environment:
|
||||||
|
|
||||||
|
Set up a dev environment
|
||||||
|
========================
|
||||||
|
|
||||||
|
You must develop on top of the Git master branch::
|
||||||
|
|
||||||
git clone https://github.com/spiral-project/ihatemoney.git
|
git clone https://github.com/spiral-project/ihatemoney.git
|
||||||
|
|
||||||
Then you need to build your dev environments. Choose your way…
|
Then you need to build your dev environment. Choose your way…
|
||||||
|
|
||||||
The quick way
|
The quick way
|
||||||
-------------
|
-------------
|
||||||
|
@ -23,10 +73,8 @@ install dependencies, and run the test server.
|
||||||
The hard way
|
The hard way
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Alternatively, you can also use the `requirements.txt` file to install the
|
Alternatively, you can use pip to install dependencies yourself. That would be::
|
||||||
dependencies yourself. That would be::
|
|
||||||
|
|
||||||
pip install -r requirements.txt
|
|
||||||
pip install -e .
|
pip install -e .
|
||||||
|
|
||||||
And then run the application::
|
And then run the application::
|
||||||
|
@ -43,28 +91,10 @@ It's as simple as that!
|
||||||
Updating
|
Updating
|
||||||
--------
|
--------
|
||||||
|
|
||||||
In case you want to update to newer versions (from git), you can just run the "update" command::
|
In case you want to update to newer versions (from Git), you can just run the "update" command::
|
||||||
|
|
||||||
make update
|
make update
|
||||||
|
|
||||||
Create database migrations
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
In case you need to modify the database schema, first update the models in
|
|
||||||
``ihatemoney/models.py``. Then run the following command to create a new
|
|
||||||
database revision file::
|
|
||||||
|
|
||||||
make create-database-revision
|
|
||||||
|
|
||||||
If your changes are simple enough, the generated script will be populated with
|
|
||||||
the necessary migrations steps. You can edit the generated script. eg: to add
|
|
||||||
data migrations.
|
|
||||||
|
|
||||||
For complex migrations, it is recommended to start from an empty revision file
|
|
||||||
which can be created with the following command::
|
|
||||||
|
|
||||||
make create-empty-database-revision
|
|
||||||
|
|
||||||
Useful settings
|
Useful settings
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -80,64 +110,81 @@ Then before running the application, declare its path with ::
|
||||||
|
|
||||||
export IHATEMONEY_SETTINGS_FILE_PATH="$(pwd)/settings.cfg"
|
export IHATEMONEY_SETTINGS_FILE_PATH="$(pwd)/settings.cfg"
|
||||||
|
|
||||||
How to contribute
|
.. _contributing-developer:
|
||||||
=================
|
|
||||||
|
|
||||||
You would like to contribute? First, thanks a bunch! This project is a small
|
Contributing as a developer
|
||||||
project with just a few people behind it, so any help is appreciated!
|
===========================
|
||||||
|
|
||||||
There are different ways to help us, regarding if you are a designer,
|
All code contributions should be submitted as Pull Requests on the
|
||||||
a developer or an user.
|
`github project <https://github.com/spiral-project/ihatemoney>`_.
|
||||||
|
|
||||||
As a developer
|
Below are some points that you should check to help you prepare your Pull Request.
|
||||||
--------------
|
|
||||||
|
|
||||||
If you want to contribute code, you can write it and then issue a pull request
|
Running tests
|
||||||
on github. Please, think about updating and running the tests before asking for
|
-------------
|
||||||
a pull request as it will help us to maintain the code clean and running.
|
|
||||||
|
|
||||||
To do so::
|
Please, think about updating and running the tests before asking for a pull request
|
||||||
|
as it will help us to maintain the code clean and running.
|
||||||
|
|
||||||
|
To run the tests::
|
||||||
|
|
||||||
make test
|
make test
|
||||||
|
|
||||||
We are using the `black <https://black.readthedocs.io/en/stable/>`_ formatter
|
Tests can be edited in ``ihatemoney/tests/tests.py``. If some test cases fail because
|
||||||
for all the python files in this project. Be sure to run it locally on your
|
of your changes, first check whether your code correctly handle these cases.
|
||||||
files. To do so, just run::
|
If you are confident that your code is correct and that the test cases simply need
|
||||||
|
to be updated to match your changes, update the test cases and send them as part of
|
||||||
|
your pull request.
|
||||||
|
|
||||||
black ihatemoney
|
If you are introducing a new feature, you need to either add tests to existing classes,
|
||||||
|
or add a new class (if your new feature is significantly different from existing code).
|
||||||
|
|
||||||
You can also integrate it with your dev environment (as a *format-on-save*
|
Formatting code
|
||||||
hook, for instance).
|
|
||||||
|
|
||||||
As a designer / Front-end developer
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
Feel free to provide us mockups or to involve yourself into the discussions
|
|
||||||
hapenning on the github issue tracker. All ideas are welcome. Of course, if you
|
|
||||||
know how to implement them, feel free to fork and make a pull request.
|
|
||||||
|
|
||||||
As a translator
|
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
If you're able to translate Ihatemoney in your own language,
|
We are using `black <https://black.readthedocs.io/en/stable/>`_ and
|
||||||
head over to `the website we use for translations <https://hosted.weblate.org/settings/i-hate-money/i-hate-money/>`_
|
`isort <https://timothycrosley.github.io/isort/>`_ formatters for all the Python
|
||||||
and start translating!
|
files in this project. Be sure to run it locally on your files.
|
||||||
|
To do so, just run::
|
||||||
|
|
||||||
All the heavy lifting will be done automatically, and your strings will
|
make black isort
|
||||||
eventually be integrated.
|
|
||||||
|
|
||||||
Once a language is ready to be integrated, add it to the
|
You can also integrate them with your dev environment (as a *format-on-save*
|
||||||
``SUPPORTED_LANGUAGES`` list, in ``ihatemoney/default_settings.py``.
|
hook, for instance).
|
||||||
|
|
||||||
End-user
|
Creating database migrations
|
||||||
--------
|
----------------------------
|
||||||
|
|
||||||
You are using the application and found a bug? You have some ideas about how to
|
In case you need to modify the database schema, first make sure that you have
|
||||||
improve the project? Please tell us `by filling a new issue <https://github.com/spiral-project/ihatemoney/issues>`_.
|
an up-to-date database by running the dev server at least once (the quick way
|
||||||
Or, if you prefer, you can send me an email to `alexis@notmyidea.org` and I
|
or the hard way, see above). The dev server applies all existing migrations
|
||||||
will update the issue tracker with your feedback.
|
when starting up.
|
||||||
|
|
||||||
|
You can now update the models in ``ihatemoney/models.py``. Then run the following
|
||||||
|
command to create a new database revision file::
|
||||||
|
|
||||||
|
make create-database-revision
|
||||||
|
|
||||||
|
If your changes are simple enough, the generated script will be populated with
|
||||||
|
the necessary migrations steps. You can view and edit the generated script, which
|
||||||
|
is useful to review that the expected model changes have been properly detected.
|
||||||
|
Usually the auto-detection works well in most cases, but you can of course edit the
|
||||||
|
script to fix small issues. You could also edit the script to add data migrations.
|
||||||
|
|
||||||
|
When you are done with your changes, don't forget to add the migration script to
|
||||||
|
your final git commit!
|
||||||
|
|
||||||
|
If the migration script looks completely wrong, remove the script and start again
|
||||||
|
with an empty database. The simplest way is to remove or rename the dev database
|
||||||
|
located at ``/tmp/ihatemoney.db``, and run the dev server at least once.
|
||||||
|
|
||||||
|
For complex migrations, it is recommended to start from an empty revision file
|
||||||
|
which can be created with the following command::
|
||||||
|
|
||||||
|
make create-empty-database-revision
|
||||||
|
|
||||||
|
You then need to write the migration steps yourself.
|
||||||
|
|
||||||
Thanks again!
|
|
||||||
|
|
||||||
How to build the documentation ?
|
How to build the documentation ?
|
||||||
================================
|
================================
|
||||||
|
@ -150,7 +197,7 @@ Install doc dependencies (within the virtualenv, if any)::
|
||||||
|
|
||||||
pip install -r docs/requirements.txt
|
pip install -r docs/requirements.txt
|
||||||
|
|
||||||
And to produce html doc in `docs/_output` folder::
|
And to produce a HTML doc in the `docs/_output` folder::
|
||||||
|
|
||||||
cd docs/
|
cd docs/
|
||||||
make html
|
make html
|
||||||
|
|
|
@ -17,7 +17,7 @@ Requirements
|
||||||
|
|
||||||
«Ihatemoney» depends on:
|
«Ihatemoney» depends on:
|
||||||
|
|
||||||
* **Python**: either 3.5, 3.6 or 3.7 will work.
|
* **Python**: either 3.6, 3.7 or 3.8 will work.
|
||||||
* **A Backend**: to choose among MySQL, PostgreSQL, SQLite or Memory.
|
* **A Backend**: to choose among MySQL, PostgreSQL, SQLite or Memory.
|
||||||
* **Virtualenv** (recommended): `virtualenv` package under Debian/Ubuntu.
|
* **Virtualenv** (recommended): `virtualenv` package under Debian/Ubuntu.
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
Sphinx==1.5.5
|
Sphinx==3.0.3
|
||||||
docutils==0.13.1
|
docutils==0.16
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# coding: utf8
|
from functools import wraps
|
||||||
from flask import request, current_app
|
|
||||||
|
from flask import current_app, request
|
||||||
from flask_restful import Resource, abort
|
from flask_restful import Resource, abort
|
||||||
|
from werkzeug.security import check_password_hash
|
||||||
from wtforms.fields.core import BooleanField
|
from wtforms.fields.core import BooleanField
|
||||||
|
|
||||||
from ihatemoney.models import db, Project, Person, Bill
|
from ihatemoney.forms import EditProjectForm, MemberForm, ProjectForm, get_billform_for
|
||||||
from ihatemoney.forms import ProjectForm, EditProjectForm, MemberForm, get_billform_for
|
from ihatemoney.models import Bill, Person, Project, db
|
||||||
from werkzeug.security import check_password_hash
|
|
||||||
from functools import wraps
|
|
||||||
|
|
||||||
|
|
||||||
def need_auth(f):
|
def need_auth(f):
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
# coding: utf8
|
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
from flask_restful import Api
|
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
|
from flask_restful import Api
|
||||||
|
|
||||||
from ihatemoney.api.common import (
|
from ihatemoney.api.common import (
|
||||||
ProjectsHandler,
|
|
||||||
ProjectHandler,
|
|
||||||
TokenHandler,
|
|
||||||
MemberHandler,
|
|
||||||
ProjectStatsHandler,
|
|
||||||
MembersHandler,
|
|
||||||
BillHandler,
|
BillHandler,
|
||||||
BillsHandler,
|
BillsHandler,
|
||||||
|
MemberHandler,
|
||||||
|
MembersHandler,
|
||||||
|
ProjectHandler,
|
||||||
|
ProjectsHandler,
|
||||||
|
ProjectStatsHandler,
|
||||||
|
TokenHandler,
|
||||||
)
|
)
|
||||||
|
|
||||||
api = Blueprint("api", __name__, url_prefix="/api")
|
api = Blueprint("api", __name__, url_prefix="/api")
|
||||||
|
|
46
ihatemoney/currency_convertor.py
Normal file
46
ihatemoney/currency_convertor.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
from cachetools import TTLCache, cached
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
class Singleton(type):
|
||||||
|
_instances = {}
|
||||||
|
|
||||||
|
def __call__(cls, *args, **kwargs):
|
||||||
|
if cls not in cls._instances:
|
||||||
|
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
||||||
|
return cls._instances[cls]
|
||||||
|
|
||||||
|
|
||||||
|
class CurrencyConverter(object, metaclass=Singleton):
|
||||||
|
# Get exchange rates
|
||||||
|
default = "No Currency"
|
||||||
|
api_url = "https://api.exchangeratesapi.io/latest?base=USD"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@cached(cache=TTLCache(maxsize=1, ttl=86400))
|
||||||
|
def get_rates(self):
|
||||||
|
rates = requests.get(self.api_url).json()["rates"]
|
||||||
|
rates[self.default] = 1.0
|
||||||
|
return rates
|
||||||
|
|
||||||
|
def get_currencies(self):
|
||||||
|
rates = [rate for rate in self.get_rates()]
|
||||||
|
rates.sort(key=lambda rate: "" if rate == self.default else rate)
|
||||||
|
return rates
|
||||||
|
|
||||||
|
def exchange_currency(self, amount, source_currency, dest_currency):
|
||||||
|
if (
|
||||||
|
source_currency == dest_currency
|
||||||
|
or source_currency == self.default
|
||||||
|
or dest_currency == self.default
|
||||||
|
):
|
||||||
|
return amount
|
||||||
|
|
||||||
|
rates = self.get_rates()
|
||||||
|
source_rate = rates[source_currency]
|
||||||
|
dest_rate = rates[dest_currency]
|
||||||
|
new_amount = (float(amount) / source_rate) * dest_rate
|
||||||
|
# round to two digits because we are dealing with money
|
||||||
|
return round(new_amount, 2)
|
|
@ -8,4 +8,4 @@ ACTIVATE_DEMO_PROJECT = True
|
||||||
ADMIN_PASSWORD = ""
|
ADMIN_PASSWORD = ""
|
||||||
ALLOW_PUBLIC_PROJECT_CREATION = True
|
ALLOW_PUBLIC_PROJECT_CREATION = True
|
||||||
ACTIVATE_ADMIN_DASHBOARD = False
|
ACTIVATE_ADMIN_DASHBOARD = False
|
||||||
SUPPORTED_LANGUAGES = ["en", "fr", "de", "nl", "es_419"]
|
SUPPORTED_LANGUAGES = ["en", "fr", "de", "nl", "es_419", "nb_NO", "id"]
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
|
import copy
|
||||||
|
from datetime import datetime
|
||||||
|
from re import match
|
||||||
|
|
||||||
|
import email_validator
|
||||||
|
from flask import request
|
||||||
|
from flask_babel import lazy_gettext as _
|
||||||
|
from flask_wtf.file import FileAllowed, FileField, FileRequired
|
||||||
from flask_wtf.form import FlaskForm
|
from flask_wtf.form import FlaskForm
|
||||||
from wtforms.fields.core import SelectField, SelectMultipleField
|
from jinja2 import Markup
|
||||||
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
from wtforms.fields.core import Label, SelectField, SelectMultipleField
|
||||||
from wtforms.fields.html5 import DateField, DecimalField, URLField
|
from wtforms.fields.html5 import DateField, DecimalField, URLField
|
||||||
from wtforms.fields.simple import PasswordField, SubmitField, StringField
|
from wtforms.fields.simple import BooleanField, PasswordField, StringField, SubmitField
|
||||||
from wtforms.validators import (
|
from wtforms.validators import (
|
||||||
Email,
|
|
||||||
DataRequired,
|
DataRequired,
|
||||||
ValidationError,
|
Email,
|
||||||
EqualTo,
|
EqualTo,
|
||||||
NumberRange,
|
NumberRange,
|
||||||
Optional,
|
Optional,
|
||||||
|
ValidationError,
|
||||||
)
|
)
|
||||||
from flask_wtf.file import FileField, FileAllowed, FileRequired
|
|
||||||
|
|
||||||
from flask_babel import lazy_gettext as _
|
from ihatemoney.currency_convertor import CurrencyConverter
|
||||||
from flask import request
|
from ihatemoney.models import LoggingMode, Person, Project
|
||||||
from werkzeug.security import generate_password_hash
|
from ihatemoney.utils import eval_arithmetic_expression, slugify
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
from re import match
|
|
||||||
from jinja2 import Markup
|
|
||||||
|
|
||||||
import email_validator
|
|
||||||
|
|
||||||
from ihatemoney.models import Project, Person
|
|
||||||
from ihatemoney.utils import slugify, eval_arithmetic_expression
|
|
||||||
|
|
||||||
|
|
||||||
def strip_filter(string):
|
def strip_filter(string):
|
||||||
|
@ -33,6 +33,18 @@ def strip_filter(string):
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
def get_editprojectform_for(project, **kwargs):
|
||||||
|
"""Return an instance of EditProjectForm configured for a particular project.
|
||||||
|
"""
|
||||||
|
form = EditProjectForm(**kwargs)
|
||||||
|
choices = copy.copy(form.default_currency.choices)
|
||||||
|
choices.sort(
|
||||||
|
key=lambda rates: "" if rates[0] == project.default_currency else rates[0]
|
||||||
|
)
|
||||||
|
form.default_currency.choices = choices
|
||||||
|
return form
|
||||||
|
|
||||||
|
|
||||||
def get_billform_for(project, set_default=True, **kwargs):
|
def get_billform_for(project, set_default=True, **kwargs):
|
||||||
"""Return an instance of BillForm configured for a particular project.
|
"""Return an instance of BillForm configured for a particular project.
|
||||||
|
|
||||||
|
@ -41,6 +53,23 @@ def get_billform_for(project, set_default=True, **kwargs):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
form = BillForm(**kwargs)
|
form = BillForm(**kwargs)
|
||||||
|
if form.original_currency.data == "None":
|
||||||
|
form.original_currency.data = project.default_currency
|
||||||
|
|
||||||
|
if form.original_currency.data != CurrencyConverter.default:
|
||||||
|
choices = copy.copy(form.original_currency.choices)
|
||||||
|
choices.remove((CurrencyConverter.default, CurrencyConverter.default))
|
||||||
|
choices.sort(
|
||||||
|
key=lambda rates: "" if rates[0] == project.default_currency else rates[0]
|
||||||
|
)
|
||||||
|
form.original_currency.choices = choices
|
||||||
|
else:
|
||||||
|
form.original_currency.render_kw = {"default": True}
|
||||||
|
form.original_currency.data = CurrencyConverter.default
|
||||||
|
|
||||||
|
form.original_currency.label = Label(
|
||||||
|
"original_currency", "Currency (Default: %s)" % (project.default_currency)
|
||||||
|
)
|
||||||
active_members = [(m.id, m.name) for m in project.active_members]
|
active_members = [(m.id, m.name) for m in project.active_members]
|
||||||
|
|
||||||
form.payed_for.choices = form.payer.choices = active_members
|
form.payed_for.choices = form.payer.choices = active_members
|
||||||
|
@ -89,6 +118,28 @@ class EditProjectForm(FlaskForm):
|
||||||
name = StringField(_("Project name"), validators=[DataRequired()])
|
name = StringField(_("Project name"), validators=[DataRequired()])
|
||||||
password = StringField(_("Private code"), validators=[DataRequired()])
|
password = StringField(_("Private code"), validators=[DataRequired()])
|
||||||
contact_email = StringField(_("Email"), validators=[DataRequired(), Email()])
|
contact_email = StringField(_("Email"), validators=[DataRequired(), Email()])
|
||||||
|
project_history = BooleanField(_("Enable project history"))
|
||||||
|
ip_recording = BooleanField(_("Use IP tracking for project history"))
|
||||||
|
currency_helper = CurrencyConverter()
|
||||||
|
default_currency = SelectField(
|
||||||
|
_("Default Currency"),
|
||||||
|
choices=[
|
||||||
|
(currency_name, currency_name)
|
||||||
|
for currency_name in currency_helper.get_currencies()
|
||||||
|
],
|
||||||
|
validators=[DataRequired()],
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def logging_preference(self):
|
||||||
|
"""Get the LoggingMode object corresponding to current form data."""
|
||||||
|
if not self.project_history.data:
|
||||||
|
return LoggingMode.DISABLED
|
||||||
|
else:
|
||||||
|
if self.ip_recording.data:
|
||||||
|
return LoggingMode.RECORD_IP
|
||||||
|
else:
|
||||||
|
return LoggingMode.ENABLED
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""Create a new project with the information given by this form.
|
"""Create a new project with the information given by this form.
|
||||||
|
@ -100,22 +151,33 @@ class EditProjectForm(FlaskForm):
|
||||||
id=self.id.data,
|
id=self.id.data,
|
||||||
password=generate_password_hash(self.password.data),
|
password=generate_password_hash(self.password.data),
|
||||||
contact_email=self.contact_email.data,
|
contact_email=self.contact_email.data,
|
||||||
|
logging_preference=self.logging_preference,
|
||||||
|
default_currency=self.default_currency.data,
|
||||||
)
|
)
|
||||||
return project
|
return project
|
||||||
|
|
||||||
def update(self, project):
|
def update(self, project):
|
||||||
"""Update the project with the information from the form"""
|
"""Update the project with the information from the form"""
|
||||||
project.name = self.name.data
|
project.name = self.name.data
|
||||||
project.password = generate_password_hash(self.password.data)
|
|
||||||
|
# Only update password if changed to prevent spurious log entries
|
||||||
|
if not check_password_hash(project.password, self.password.data):
|
||||||
|
project.password = generate_password_hash(self.password.data)
|
||||||
|
|
||||||
project.contact_email = self.contact_email.data
|
project.contact_email = self.contact_email.data
|
||||||
|
project.logging_preference = self.logging_preference
|
||||||
|
project.default_currency = self.default_currency.data
|
||||||
|
|
||||||
return project
|
return project
|
||||||
|
|
||||||
|
|
||||||
class UploadForm(FlaskForm):
|
class UploadForm(FlaskForm):
|
||||||
file = FileField(
|
file = FileField(
|
||||||
"JSON", validators=[FileRequired(), FileAllowed(["json", "JSON"], "JSON only!")]
|
"JSON",
|
||||||
|
validators=[FileRequired(), FileAllowed(["json", "JSON"], "JSON only!")],
|
||||||
|
description=_("Import previously exported JSON file"),
|
||||||
)
|
)
|
||||||
|
submit = SubmitField(_("Import"))
|
||||||
|
|
||||||
|
|
||||||
class ProjectForm(EditProjectForm):
|
class ProjectForm(EditProjectForm):
|
||||||
|
@ -123,6 +185,14 @@ class ProjectForm(EditProjectForm):
|
||||||
password = PasswordField(_("Private code"), validators=[DataRequired()])
|
password = PasswordField(_("Private code"), validators=[DataRequired()])
|
||||||
submit = SubmitField(_("Create the project"))
|
submit = SubmitField(_("Create the project"))
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
# WTForms Boolean Fields don't insert the default value when the
|
||||||
|
# request doesn't include any value the way that other fields do,
|
||||||
|
# so we'll manually do it here
|
||||||
|
self.project_history.data = LoggingMode.default() != LoggingMode.DISABLED
|
||||||
|
self.ip_recording.data = LoggingMode.default() == LoggingMode.RECORD_IP
|
||||||
|
return super().save()
|
||||||
|
|
||||||
def validate_id(form, field):
|
def validate_id(form, field):
|
||||||
form.id.data = slugify(field.data)
|
form.id.data = slugify(field.data)
|
||||||
if (form.id.data == "dashboard") or Project.query.get(form.id.data):
|
if (form.id.data == "dashboard") or Project.query.get(form.id.data):
|
||||||
|
@ -171,6 +241,15 @@ class BillForm(FlaskForm):
|
||||||
what = StringField(_("What?"), validators=[DataRequired()])
|
what = StringField(_("What?"), validators=[DataRequired()])
|
||||||
payer = SelectField(_("Payer"), validators=[DataRequired()], coerce=int)
|
payer = SelectField(_("Payer"), validators=[DataRequired()], coerce=int)
|
||||||
amount = CalculatorStringField(_("Amount paid"), validators=[DataRequired()])
|
amount = CalculatorStringField(_("Amount paid"), validators=[DataRequired()])
|
||||||
|
currency_helper = CurrencyConverter()
|
||||||
|
original_currency = SelectField(
|
||||||
|
_("Currency"),
|
||||||
|
choices=[
|
||||||
|
(currency_name, currency_name)
|
||||||
|
for currency_name in currency_helper.get_currencies()
|
||||||
|
],
|
||||||
|
validators=[DataRequired()],
|
||||||
|
)
|
||||||
external_link = URLField(
|
external_link = URLField(
|
||||||
_("External link"),
|
_("External link"),
|
||||||
validators=[Optional()],
|
validators=[Optional()],
|
||||||
|
@ -189,6 +268,10 @@ class BillForm(FlaskForm):
|
||||||
bill.external_link = self.external_link.data
|
bill.external_link = self.external_link.data
|
||||||
bill.date = self.date.data
|
bill.date = self.date.data
|
||||||
bill.owers = [Person.query.get(ower, project) for ower in self.payed_for.data]
|
bill.owers = [Person.query.get(ower, project) for ower in self.payed_for.data]
|
||||||
|
bill.original_currency = self.original_currency.data
|
||||||
|
bill.converted_amount = self.currency_helper.exchange_currency(
|
||||||
|
bill.amount, bill.original_currency, project.default_currency
|
||||||
|
)
|
||||||
return bill
|
return bill
|
||||||
|
|
||||||
def fake_form(self, bill, project):
|
def fake_form(self, bill, project):
|
||||||
|
@ -198,6 +281,10 @@ class BillForm(FlaskForm):
|
||||||
bill.external_link = ""
|
bill.external_link = ""
|
||||||
bill.date = self.date
|
bill.date = self.date
|
||||||
bill.owers = [Person.query.get(ower, project) for ower in self.payed_for]
|
bill.owers = [Person.query.get(ower, project) for ower in self.payed_for]
|
||||||
|
bill.original_currency = CurrencyConverter.default
|
||||||
|
bill.converted_amount = self.currency_helper.exchange_currency(
|
||||||
|
bill.amount, bill.original_currency, project.default_currency
|
||||||
|
)
|
||||||
|
|
||||||
return bill
|
return bill
|
||||||
|
|
||||||
|
@ -206,6 +293,7 @@ class BillForm(FlaskForm):
|
||||||
self.amount.data = bill.amount
|
self.amount.data = bill.amount
|
||||||
self.what.data = bill.what
|
self.what.data = bill.what
|
||||||
self.external_link.data = bill.external_link
|
self.external_link.data = bill.external_link
|
||||||
|
self.original_currency.data = bill.original_currency
|
||||||
self.date.data = bill.date
|
self.date.data = bill.date
|
||||||
self.payed_for.data = [int(ower.id) for ower in bill.owers]
|
self.payed_for.data = [int(ower.id) for ower in bill.owers]
|
||||||
|
|
||||||
|
|
139
ihatemoney/history.py
Normal file
139
ihatemoney/history.py
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
from flask_babel import gettext as _
|
||||||
|
from sqlalchemy_continuum import Operation, parent_class
|
||||||
|
|
||||||
|
from ihatemoney.models import BillVersion, Person, PersonVersion, ProjectVersion
|
||||||
|
|
||||||
|
|
||||||
|
def get_history_queries(project):
|
||||||
|
"""Generate queries for each type of version object for a given project."""
|
||||||
|
person_changes = PersonVersion.query.filter_by(project_id=project.id)
|
||||||
|
|
||||||
|
project_changes = ProjectVersion.query.filter_by(id=project.id)
|
||||||
|
|
||||||
|
bill_changes = (
|
||||||
|
BillVersion.query.with_entities(BillVersion.id.label("bill_version_id"))
|
||||||
|
.join(Person, BillVersion.payer_id == Person.id)
|
||||||
|
.filter(Person.project_id == project.id)
|
||||||
|
)
|
||||||
|
sub_query = bill_changes.subquery()
|
||||||
|
bill_changes = BillVersion.query.filter(BillVersion.id.in_(sub_query))
|
||||||
|
|
||||||
|
return person_changes, project_changes, bill_changes
|
||||||
|
|
||||||
|
|
||||||
|
def history_sort_key(history_item_dict):
|
||||||
|
"""
|
||||||
|
Return the key necessary to sort history entries. First order sort is time
|
||||||
|
of modification, but for simultaneous modifications we make the re-name
|
||||||
|
modification occur last so that the simultaneous entries make sense using
|
||||||
|
the old name.
|
||||||
|
"""
|
||||||
|
second_order = 0
|
||||||
|
if "prop_changed" in history_item_dict:
|
||||||
|
changed_property = history_item_dict["prop_changed"]
|
||||||
|
if changed_property == "name" or changed_property == "what":
|
||||||
|
second_order = 1
|
||||||
|
|
||||||
|
return history_item_dict["time"], second_order
|
||||||
|
|
||||||
|
|
||||||
|
def describe_version(version_obj):
|
||||||
|
"""Use the base model str() function to describe a version object"""
|
||||||
|
return parent_class(type(version_obj)).__str__(version_obj)
|
||||||
|
|
||||||
|
|
||||||
|
def describe_owers_change(version, human_readable_names):
|
||||||
|
"""Compute the set difference to get added/removed owers lists."""
|
||||||
|
before_owers = {version.id: version for version in version.previous.owers}
|
||||||
|
after_owers = {version.id: version for version in version.owers}
|
||||||
|
|
||||||
|
added_ids = set(after_owers).difference(set(before_owers))
|
||||||
|
removed_ids = set(before_owers).difference(set(after_owers))
|
||||||
|
|
||||||
|
if not human_readable_names:
|
||||||
|
return added_ids, removed_ids
|
||||||
|
|
||||||
|
added = [describe_version(after_owers[ower_id]) for ower_id in added_ids]
|
||||||
|
removed = [describe_version(before_owers[ower_id]) for ower_id in removed_ids]
|
||||||
|
|
||||||
|
return added, removed
|
||||||
|
|
||||||
|
|
||||||
|
def get_history(project, human_readable_names=True):
|
||||||
|
"""
|
||||||
|
Fetch history for all models associated with a given project.
|
||||||
|
:param human_readable_names Whether to replace id numbers with readable names
|
||||||
|
:return A sorted list of dicts with history information
|
||||||
|
"""
|
||||||
|
person_query, project_query, bill_query = get_history_queries(project)
|
||||||
|
history = []
|
||||||
|
for version_list in [person_query.all(), project_query.all(), bill_query.all()]:
|
||||||
|
for version in version_list:
|
||||||
|
object_type = {
|
||||||
|
"Person": _("Participant"),
|
||||||
|
"Bill": _("Bill"),
|
||||||
|
"Project": _("Project"),
|
||||||
|
}[parent_class(type(version)).__name__]
|
||||||
|
|
||||||
|
# Use the old name if applicable
|
||||||
|
if version.previous:
|
||||||
|
object_str = describe_version(version.previous)
|
||||||
|
else:
|
||||||
|
object_str = describe_version(version)
|
||||||
|
|
||||||
|
common_properties = {
|
||||||
|
"time": version.transaction.issued_at.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||||
|
"operation_type": version.operation_type,
|
||||||
|
"object_type": object_type,
|
||||||
|
"object_desc": object_str,
|
||||||
|
"ip": version.transaction.remote_addr,
|
||||||
|
}
|
||||||
|
|
||||||
|
if version.operation_type == Operation.UPDATE:
|
||||||
|
# Only iterate the changeset if the previous version
|
||||||
|
# Was logged
|
||||||
|
if version.previous:
|
||||||
|
changeset = version.changeset
|
||||||
|
if isinstance(version, BillVersion):
|
||||||
|
if version.owers != version.previous.owers:
|
||||||
|
added, removed = describe_owers_change(
|
||||||
|
version, human_readable_names
|
||||||
|
)
|
||||||
|
|
||||||
|
if added:
|
||||||
|
changeset["owers_added"] = (None, added)
|
||||||
|
if removed:
|
||||||
|
changeset["owers_removed"] = (None, removed)
|
||||||
|
|
||||||
|
# Remove converted_amount if amount changed in the same way.
|
||||||
|
if (
|
||||||
|
"amount" in changeset
|
||||||
|
and "converted_amount" in changeset
|
||||||
|
and changeset["amount"] == changeset["converted_amount"]
|
||||||
|
):
|
||||||
|
del changeset["converted_amount"]
|
||||||
|
|
||||||
|
for (prop, (val_before, val_after),) in changeset.items():
|
||||||
|
if human_readable_names:
|
||||||
|
if prop == "payer_id":
|
||||||
|
prop = "payer"
|
||||||
|
if val_after is not None:
|
||||||
|
val_after = describe_version(version.payer)
|
||||||
|
if version.previous and val_before is not None:
|
||||||
|
val_before = describe_version(
|
||||||
|
version.previous.payer
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
val_after = None
|
||||||
|
|
||||||
|
next_event = common_properties.copy()
|
||||||
|
next_event["prop_changed"] = prop
|
||||||
|
next_event["val_before"] = val_before
|
||||||
|
next_event["val_after"] = val_after
|
||||||
|
history.append(next_event)
|
||||||
|
else:
|
||||||
|
history.append(common_properties)
|
||||||
|
else:
|
||||||
|
history.append(common_properties)
|
||||||
|
|
||||||
|
return sorted(history, key=history_sort_key, reverse=True)
|
|
@ -1,16 +1,16 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import getpass
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
import getpass
|
|
||||||
|
|
||||||
from flask_script import Manager, Command, Option
|
|
||||||
from flask_migrate import Migrate, MigrateCommand
|
from flask_migrate import Migrate, MigrateCommand
|
||||||
|
from flask_script import Command, Manager, Option
|
||||||
from werkzeug.security import generate_password_hash
|
from werkzeug.security import generate_password_hash
|
||||||
|
|
||||||
|
from ihatemoney.models import Project, db
|
||||||
from ihatemoney.run import create_app
|
from ihatemoney.run import create_app
|
||||||
from ihatemoney.models import db, Project
|
|
||||||
from ihatemoney.utils import create_jinja_env
|
from ihatemoney.utils import create_jinja_env
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class GenerateConfig(Command):
|
||||||
|
|
||||||
def run(self, config_file):
|
def run(self, config_file):
|
||||||
env = create_jinja_env("conf-templates", strict_rendering=True)
|
env = create_jinja_env("conf-templates", strict_rendering=True)
|
||||||
template = env.get_template("%s.j2" % config_file)
|
template = env.get_template(f"{config_file}.j2")
|
||||||
|
|
||||||
bin_path = os.path.dirname(sys.executable)
|
bin_path = os.path.dirname(sys.executable)
|
||||||
pkg_path = os.path.abspath(os.path.dirname(__file__))
|
pkg_path = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
|
@ -12,6 +12,18 @@ msgstr ""
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -106,6 +118,15 @@ msgstr ""
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -139,6 +160,12 @@ msgstr ""
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -150,7 +177,7 @@ msgid "Your invitations have been sent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -204,9 +231,6 @@ msgstr ""
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -228,6 +252,9 @@ msgstr ""
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -237,6 +264,12 @@ msgstr ""
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -258,6 +291,9 @@ msgstr ""
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -288,6 +324,177 @@ msgstr ""
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -335,6 +542,9 @@ msgstr ""
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -392,6 +602,12 @@ msgstr ""
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -418,9 +634,6 @@ msgstr ""
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -489,15 +702,15 @@ msgstr ""
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ def run_migrations_offline():
|
||||||
|
|
||||||
"""
|
"""
|
||||||
url = config.get_main_option("sqlalchemy.url")
|
url = config.get_main_option("sqlalchemy.url")
|
||||||
context.configure(url=url)
|
context.configure(url=url, include_object=include_object)
|
||||||
|
|
||||||
with context.begin_transaction():
|
with context.begin_transaction():
|
||||||
context.run_migrations()
|
context.run_migrations()
|
||||||
|
@ -75,6 +75,7 @@ def run_migrations_online():
|
||||||
context.configure(
|
context.configure(
|
||||||
connection=connection,
|
connection=connection,
|
||||||
target_metadata=target_metadata,
|
target_metadata=target_metadata,
|
||||||
|
include_object=include_object,
|
||||||
process_revision_directives=process_revision_directives,
|
process_revision_directives=process_revision_directives,
|
||||||
**current_app.extensions["migrate"].configure_args
|
**current_app.extensions["migrate"].configure_args
|
||||||
)
|
)
|
||||||
|
@ -86,6 +87,12 @@ def run_migrations_online():
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
|
def include_object(object, name, type_, reflected, compare_to):
|
||||||
|
if name == "sqlite_sequence":
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
if context.is_offline_mode():
|
if context.is_offline_mode():
|
||||||
run_migrations_offline()
|
run_migrations_offline()
|
||||||
else:
|
else:
|
||||||
|
|
232
ihatemoney/migrations/versions/2dcb0c0048dc_autologger.py
Normal file
232
ihatemoney/migrations/versions/2dcb0c0048dc_autologger.py
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
"""autologger
|
||||||
|
|
||||||
|
Revision ID: 2dcb0c0048dc
|
||||||
|
Revises: 6c6fb2b7f229
|
||||||
|
Create Date: 2020-04-10 18:12:41.285590
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "2dcb0c0048dc"
|
||||||
|
down_revision = "6c6fb2b7f229"
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table(
|
||||||
|
"bill_version",
|
||||||
|
sa.Column("id", sa.Integer(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column("payer_id", sa.Integer(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("amount", sa.Float(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("date", sa.Date(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("creation_date", sa.Date(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("what", sa.UnicodeText(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"external_link", sa.UnicodeText(), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("archive", sa.Integer(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||||
|
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint("id", "transaction_id"),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_bill_version_end_transaction_id"),
|
||||||
|
"bill_version",
|
||||||
|
["end_transaction_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_bill_version_operation_type"),
|
||||||
|
"bill_version",
|
||||||
|
["operation_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_bill_version_transaction_id"),
|
||||||
|
"bill_version",
|
||||||
|
["transaction_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"billowers_version",
|
||||||
|
sa.Column("bill_id", sa.Integer(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column("person_id", sa.Integer(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||||
|
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint("bill_id", "person_id", "transaction_id"),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_billowers_version_end_transaction_id"),
|
||||||
|
"billowers_version",
|
||||||
|
["end_transaction_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_billowers_version_operation_type"),
|
||||||
|
"billowers_version",
|
||||||
|
["operation_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_billowers_version_transaction_id"),
|
||||||
|
"billowers_version",
|
||||||
|
["transaction_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"person_version",
|
||||||
|
sa.Column("id", sa.Integer(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"project_id", sa.String(length=64), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("name", sa.UnicodeText(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("weight", sa.Float(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("activated", sa.Boolean(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||||
|
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint("id", "transaction_id"),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_person_version_end_transaction_id"),
|
||||||
|
"person_version",
|
||||||
|
["end_transaction_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_person_version_operation_type"),
|
||||||
|
"person_version",
|
||||||
|
["operation_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_person_version_transaction_id"),
|
||||||
|
"person_version",
|
||||||
|
["transaction_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"project_version",
|
||||||
|
sa.Column("id", sa.String(length=64), autoincrement=False, nullable=False),
|
||||||
|
sa.Column("name", sa.UnicodeText(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"password", sa.String(length=128), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"contact_email", sa.String(length=128), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"logging_preference",
|
||||||
|
sa.Enum("DISABLED", "ENABLED", "RECORD_IP", name="loggingmode"),
|
||||||
|
server_default="ENABLED",
|
||||||
|
autoincrement=False,
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"transaction_id", sa.BigInteger(), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column("end_transaction_id", sa.BigInteger(), nullable=True),
|
||||||
|
sa.Column("operation_type", sa.SmallInteger(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint("id", "transaction_id"),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_project_version_end_transaction_id"),
|
||||||
|
"project_version",
|
||||||
|
["end_transaction_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_project_version_operation_type"),
|
||||||
|
"project_version",
|
||||||
|
["operation_type"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_project_version_transaction_id"),
|
||||||
|
"project_version",
|
||||||
|
["transaction_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"transaction",
|
||||||
|
sa.Column("issued_at", sa.DateTime(), nullable=True),
|
||||||
|
sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
|
||||||
|
sa.Column("remote_addr", sa.String(length=50), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
)
|
||||||
|
bind = op.get_bind()
|
||||||
|
if bind.engine.name == "sqlite":
|
||||||
|
with op.batch_alter_table("project", recreate="always") as batch_op:
|
||||||
|
batch_op.add_column(
|
||||||
|
sa.Column(
|
||||||
|
"logging_preference",
|
||||||
|
sa.Enum("DISABLED", "ENABLED", "RECORD_IP", name="loggingmode"),
|
||||||
|
server_default="ENABLED",
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
op.add_column(
|
||||||
|
"project",
|
||||||
|
sa.Column(
|
||||||
|
"logging_preference",
|
||||||
|
sa.Enum("DISABLED", "ENABLED", "RECORD_IP", name="loggingmode"),
|
||||||
|
server_default="ENABLED",
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
|
||||||
|
bind = op.get_bind()
|
||||||
|
if bind.engine.name == "sqlite":
|
||||||
|
with op.batch_alter_table("project", recreate="always") as batch_op:
|
||||||
|
batch_op.drop_column("logging_preference")
|
||||||
|
else:
|
||||||
|
op.drop_column("project", "logging_preference")
|
||||||
|
op.drop_table("transaction")
|
||||||
|
op.drop_index(
|
||||||
|
op.f("ix_project_version_transaction_id"), table_name="project_version"
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
op.f("ix_project_version_operation_type"), table_name="project_version"
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
op.f("ix_project_version_end_transaction_id"), table_name="project_version"
|
||||||
|
)
|
||||||
|
op.drop_table("project_version")
|
||||||
|
op.drop_index(op.f("ix_person_version_transaction_id"), table_name="person_version")
|
||||||
|
op.drop_index(op.f("ix_person_version_operation_type"), table_name="person_version")
|
||||||
|
op.drop_index(
|
||||||
|
op.f("ix_person_version_end_transaction_id"), table_name="person_version"
|
||||||
|
)
|
||||||
|
op.drop_table("person_version")
|
||||||
|
op.drop_index(
|
||||||
|
op.f("ix_billowers_version_transaction_id"), table_name="billowers_version"
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
op.f("ix_billowers_version_operation_type"), table_name="billowers_version"
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
op.f("ix_billowers_version_end_transaction_id"), table_name="billowers_version"
|
||||||
|
)
|
||||||
|
op.drop_table("billowers_version")
|
||||||
|
op.drop_index(op.f("ix_bill_version_transaction_id"), table_name="bill_version")
|
||||||
|
op.drop_index(op.f("ix_bill_version_operation_type"), table_name="bill_version")
|
||||||
|
op.drop_index(op.f("ix_bill_version_end_transaction_id"), table_name="bill_version")
|
||||||
|
op.drop_table("bill_version")
|
||||||
|
# ### end Alembic commands ###
|
|
@ -0,0 +1,73 @@
|
||||||
|
"""Add currencies
|
||||||
|
|
||||||
|
Revision ID: 927ed575acbd
|
||||||
|
Revises: cb038f79982e
|
||||||
|
Create Date: 2020-04-25 14:49:41.136602
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "927ed575acbd"
|
||||||
|
down_revision = "cb038f79982e"
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from ihatemoney.currency_convertor import CurrencyConverter
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column("bill", sa.Column("converted_amount", sa.Float(), nullable=True))
|
||||||
|
op.add_column(
|
||||||
|
"bill",
|
||||||
|
sa.Column(
|
||||||
|
"original_currency",
|
||||||
|
sa.String(length=3),
|
||||||
|
server_default=CurrencyConverter.default,
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"bill_version",
|
||||||
|
sa.Column("converted_amount", sa.Float(), autoincrement=False, nullable=True),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"bill_version",
|
||||||
|
sa.Column(
|
||||||
|
"original_currency", sa.String(length=3), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"project",
|
||||||
|
sa.Column(
|
||||||
|
"default_currency",
|
||||||
|
sa.String(length=3),
|
||||||
|
server_default=CurrencyConverter.default,
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"project_version",
|
||||||
|
sa.Column(
|
||||||
|
"default_currency", sa.String(length=3), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
op.execute(
|
||||||
|
"""
|
||||||
|
UPDATE bill
|
||||||
|
SET converted_amount = amount
|
||||||
|
WHERE converted_amount IS NULL
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column("project_version", "default_currency")
|
||||||
|
op.drop_column("project", "default_currency")
|
||||||
|
op.drop_column("bill_version", "original_currency")
|
||||||
|
op.drop_column("bill_version", "converted_amount")
|
||||||
|
op.drop_column("bill", "original_currency")
|
||||||
|
op.drop_column("bill", "converted_amount")
|
||||||
|
# ### end Alembic commands ###
|
|
@ -0,0 +1,60 @@
|
||||||
|
"""sqlite_autoincrement
|
||||||
|
|
||||||
|
Revision ID: cb038f79982e
|
||||||
|
Revises: 2dcb0c0048dc
|
||||||
|
Create Date: 2020-04-13 17:40:02.426957
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "cb038f79982e"
|
||||||
|
down_revision = "2dcb0c0048dc"
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
bind = op.get_bind()
|
||||||
|
if bind.engine.name == "sqlite":
|
||||||
|
alter_table_batches = [
|
||||||
|
op.batch_alter_table(
|
||||||
|
"person", recreate="always", table_kwargs={"sqlite_autoincrement": True}
|
||||||
|
),
|
||||||
|
op.batch_alter_table(
|
||||||
|
"bill", recreate="always", table_kwargs={"sqlite_autoincrement": True}
|
||||||
|
),
|
||||||
|
op.batch_alter_table(
|
||||||
|
"billowers",
|
||||||
|
recreate="always",
|
||||||
|
table_kwargs={"sqlite_autoincrement": True},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
for batch_op in alter_table_batches:
|
||||||
|
with batch_op:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
bind = op.get_bind()
|
||||||
|
if bind.engine.name == "sqlite":
|
||||||
|
alter_table_batches = [
|
||||||
|
op.batch_alter_table(
|
||||||
|
"person",
|
||||||
|
recreate="always",
|
||||||
|
table_kwargs={"sqlite_autoincrement": False},
|
||||||
|
),
|
||||||
|
op.batch_alter_table(
|
||||||
|
"bill", recreate="always", table_kwargs={"sqlite_autoincrement": False}
|
||||||
|
),
|
||||||
|
op.batch_alter_table(
|
||||||
|
"billowers",
|
||||||
|
recreate="always",
|
||||||
|
table_kwargs={"sqlite_autoincrement": False},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
for batch_op in alter_table_batches:
|
||||||
|
with batch_op:
|
||||||
|
pass
|
|
@ -1,17 +1,49 @@
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from flask_sqlalchemy import SQLAlchemy, BaseQuery
|
|
||||||
from flask import g, current_app
|
|
||||||
|
|
||||||
from debts import settle
|
from debts import settle
|
||||||
from sqlalchemy import orm
|
from flask import current_app, g
|
||||||
from sqlalchemy.sql import func
|
from flask_sqlalchemy import BaseQuery, SQLAlchemy
|
||||||
from itsdangerous import (
|
from itsdangerous import (
|
||||||
TimedJSONWebSignatureSerializer,
|
|
||||||
URLSafeSerializer,
|
|
||||||
BadSignature,
|
BadSignature,
|
||||||
SignatureExpired,
|
SignatureExpired,
|
||||||
|
TimedJSONWebSignatureSerializer,
|
||||||
|
URLSafeSerializer,
|
||||||
|
)
|
||||||
|
import sqlalchemy
|
||||||
|
from sqlalchemy import orm
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
from sqlalchemy_continuum import make_versioned, version_class
|
||||||
|
from sqlalchemy_continuum.plugins import FlaskPlugin
|
||||||
|
|
||||||
|
from ihatemoney.patch_sqlalchemy_continuum import PatchedBuilder
|
||||||
|
from ihatemoney.versioning import (
|
||||||
|
ConditionalVersioningManager,
|
||||||
|
LoggingMode,
|
||||||
|
get_ip_if_allowed,
|
||||||
|
version_privacy_predicate,
|
||||||
|
)
|
||||||
|
|
||||||
|
make_versioned(
|
||||||
|
user_cls=None,
|
||||||
|
manager=ConditionalVersioningManager(
|
||||||
|
# Conditionally Disable the versioning based on each
|
||||||
|
# project's privacy preferences
|
||||||
|
tracking_predicate=version_privacy_predicate,
|
||||||
|
# Patch in a fix to a SQLAchemy-Continuum Bug.
|
||||||
|
# See patch_sqlalchemy_continuum.py
|
||||||
|
builder=PatchedBuilder(),
|
||||||
|
),
|
||||||
|
plugins=[
|
||||||
|
FlaskPlugin(
|
||||||
|
# Redirect to our own function, which respects user preferences
|
||||||
|
# on IP address collection
|
||||||
|
remote_addr_factory=get_ip_if_allowed,
|
||||||
|
# Suppress the plugin's attempt to grab a user id,
|
||||||
|
# which imports the flask_login module (causing an error)
|
||||||
|
current_user_id_factory=lambda: None,
|
||||||
|
)
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
|
@ -22,14 +54,24 @@ class Project(db.Model):
|
||||||
def get_by_name(self, name):
|
def get_by_name(self, name):
|
||||||
return Project.query.filter(Project.name == name).one()
|
return Project.query.filter(Project.name == name).one()
|
||||||
|
|
||||||
|
# Direct SQLAlchemy-Continuum to track changes to this model
|
||||||
|
__versioned__ = {}
|
||||||
|
|
||||||
id = db.Column(db.String(64), primary_key=True)
|
id = db.Column(db.String(64), primary_key=True)
|
||||||
|
|
||||||
name = db.Column(db.UnicodeText)
|
name = db.Column(db.UnicodeText)
|
||||||
password = db.Column(db.String(128))
|
password = db.Column(db.String(128))
|
||||||
contact_email = db.Column(db.String(128))
|
contact_email = db.Column(db.String(128))
|
||||||
|
logging_preference = db.Column(
|
||||||
|
db.Enum(LoggingMode),
|
||||||
|
default=LoggingMode.default(),
|
||||||
|
nullable=False,
|
||||||
|
server_default=LoggingMode.default().name,
|
||||||
|
)
|
||||||
members = db.relationship("Person", backref="project")
|
members = db.relationship("Person", backref="project")
|
||||||
|
|
||||||
query_class = ProjectQuery
|
query_class = ProjectQuery
|
||||||
|
default_currency = db.Column(db.String(3))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _to_serialize(self):
|
def _to_serialize(self):
|
||||||
|
@ -37,7 +79,9 @@ class Project(db.Model):
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"contact_email": self.contact_email,
|
"contact_email": self.contact_email,
|
||||||
|
"logging_preference": self.logging_preference.value,
|
||||||
"members": [],
|
"members": [],
|
||||||
|
"default_currency": self.default_currency,
|
||||||
}
|
}
|
||||||
|
|
||||||
balance = self.balance
|
balance = self.balance
|
||||||
|
@ -86,7 +130,10 @@ class Project(db.Model):
|
||||||
{
|
{
|
||||||
"member": member,
|
"member": member,
|
||||||
"paid": sum(
|
"paid": sum(
|
||||||
[bill.amount for bill in self.get_member_bills(member.id).all()]
|
[
|
||||||
|
bill.converted_amount
|
||||||
|
for bill in self.get_member_bills(member.id).all()
|
||||||
|
]
|
||||||
),
|
),
|
||||||
"spent": sum(
|
"spent": sum(
|
||||||
[
|
[
|
||||||
|
@ -109,7 +156,7 @@ class Project(db.Model):
|
||||||
"""
|
"""
|
||||||
monthly = defaultdict(lambda: defaultdict(float))
|
monthly = defaultdict(lambda: defaultdict(float))
|
||||||
for bill in self.get_bills().all():
|
for bill in self.get_bills().all():
|
||||||
monthly[bill.date.year][bill.date.month] += bill.amount
|
monthly[bill.date.year][bill.date.month] += bill.converted_amount
|
||||||
return monthly
|
return monthly
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -277,8 +324,11 @@ class Project(db.Model):
|
||||||
return None
|
return None
|
||||||
return data["project_id"]
|
return data["project_id"]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Project %s>" % self.name
|
return f"<Project {self.name}>"
|
||||||
|
|
||||||
|
|
||||||
class Person(db.Model):
|
class Person(db.Model):
|
||||||
|
@ -301,6 +351,11 @@ class Person(db.Model):
|
||||||
|
|
||||||
query_class = PersonQuery
|
query_class = PersonQuery
|
||||||
|
|
||||||
|
# Direct SQLAlchemy-Continuum to track changes to this model
|
||||||
|
__versioned__ = {}
|
||||||
|
|
||||||
|
__table_args__ = {"sqlite_autoincrement": True}
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
project_id = db.Column(db.String(64), db.ForeignKey("project.id"))
|
project_id = db.Column(db.String(64), db.ForeignKey("project.id"))
|
||||||
bills = db.relationship("Bill", backref="payer")
|
bills = db.relationship("Bill", backref="payer")
|
||||||
|
@ -331,14 +386,15 @@ class Person(db.Model):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Person %s for project %s>" % (self.name, self.project.name)
|
return f"<Person {self.name} for project {self.project.name}>"
|
||||||
|
|
||||||
|
|
||||||
# We need to manually define a join table for m2m relations
|
# We need to manually define a join table for m2m relations
|
||||||
billowers = db.Table(
|
billowers = db.Table(
|
||||||
"billowers",
|
"billowers",
|
||||||
db.Column("bill_id", db.Integer, db.ForeignKey("bill.id")),
|
db.Column("bill_id", db.Integer, db.ForeignKey("bill.id"), primary_key=True),
|
||||||
db.Column("person_id", db.Integer, db.ForeignKey("person.id")),
|
db.Column("person_id", db.Integer, db.ForeignKey("person.id"), primary_key=True),
|
||||||
|
sqlite_autoincrement=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -365,6 +421,11 @@ class Bill(db.Model):
|
||||||
|
|
||||||
query_class = BillQuery
|
query_class = BillQuery
|
||||||
|
|
||||||
|
# Direct SQLAlchemy-Continuum to track changes to this model
|
||||||
|
__versioned__ = {}
|
||||||
|
|
||||||
|
__table_args__ = {"sqlite_autoincrement": True}
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
|
||||||
payer_id = db.Column(db.Integer, db.ForeignKey("person.id"))
|
payer_id = db.Column(db.Integer, db.ForeignKey("person.id"))
|
||||||
|
@ -376,6 +437,9 @@ class Bill(db.Model):
|
||||||
what = db.Column(db.UnicodeText)
|
what = db.Column(db.UnicodeText)
|
||||||
external_link = db.Column(db.UnicodeText)
|
external_link = db.Column(db.UnicodeText)
|
||||||
|
|
||||||
|
original_currency = db.Column(db.String(3))
|
||||||
|
converted_amount = db.Column(db.Float)
|
||||||
|
|
||||||
archive = db.Column(db.Integer, db.ForeignKey("archive.id"))
|
archive = db.Column(db.Integer, db.ForeignKey("archive.id"))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -389,9 +453,11 @@ class Bill(db.Model):
|
||||||
"creation_date": self.creation_date,
|
"creation_date": self.creation_date,
|
||||||
"what": self.what,
|
"what": self.what,
|
||||||
"external_link": self.external_link,
|
"external_link": self.external_link,
|
||||||
|
"original_currency": self.original_currency,
|
||||||
|
"converted_amount": self.converted_amount,
|
||||||
}
|
}
|
||||||
|
|
||||||
def pay_each(self):
|
def pay_each_default(self, amount):
|
||||||
"""Compute what each share has to pay"""
|
"""Compute what each share has to pay"""
|
||||||
if self.owers:
|
if self.owers:
|
||||||
weights = (
|
weights = (
|
||||||
|
@ -399,15 +465,20 @@ class Bill(db.Model):
|
||||||
.join(billowers, Bill)
|
.join(billowers, Bill)
|
||||||
.filter(Bill.id == self.id)
|
.filter(Bill.id == self.id)
|
||||||
).scalar()
|
).scalar()
|
||||||
return self.amount / weights
|
return amount / weights
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.what
|
||||||
|
|
||||||
|
def pay_each(self):
|
||||||
|
return self.pay_each_default(self.converted_amount)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Bill of %s from %s for %s>" % (
|
return (
|
||||||
self.amount,
|
f"<Bill of {self.amount} from {self.payer} for "
|
||||||
self.payer,
|
f"{', '.join([o.name for o in self.owers])}>"
|
||||||
", ".join([o.name for o in self.owers]),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -426,3 +497,10 @@ class Archive(db.Model):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Archive>"
|
return "<Archive>"
|
||||||
|
|
||||||
|
|
||||||
|
sqlalchemy.orm.configure_mappers()
|
||||||
|
|
||||||
|
PersonVersion = version_class(Person)
|
||||||
|
ProjectVersion = version_class(Project)
|
||||||
|
BillVersion = version_class(Bill)
|
||||||
|
|
138
ihatemoney/patch_sqlalchemy_continuum.py
Normal file
138
ihatemoney/patch_sqlalchemy_continuum.py
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
"""
|
||||||
|
A temporary work-around to patch SQLAlchemy-continuum per:
|
||||||
|
https://github.com/kvesteri/sqlalchemy-continuum/pull/242
|
||||||
|
|
||||||
|
Source code reproduced under their license:
|
||||||
|
|
||||||
|
Copyright (c) 2012, Konsta Vesterinen
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* The names of the contributors may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
|
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy_continuum import Operation
|
||||||
|
from sqlalchemy_continuum.builder import Builder
|
||||||
|
from sqlalchemy_continuum.expression_reflector import VersionExpressionReflector
|
||||||
|
from sqlalchemy_continuum.relationship_builder import RelationshipBuilder
|
||||||
|
from sqlalchemy_continuum.utils import adapt_columns, option
|
||||||
|
|
||||||
|
|
||||||
|
class PatchedRelationShipBuilder(RelationshipBuilder):
|
||||||
|
def association_subquery(self, obj):
|
||||||
|
"""
|
||||||
|
Returns an EXISTS clause that checks if an association exists for given
|
||||||
|
SQLAlchemy declarative object. This query is used by
|
||||||
|
many_to_many_criteria method.
|
||||||
|
|
||||||
|
Example query:
|
||||||
|
|
||||||
|
.. code-block:: sql
|
||||||
|
|
||||||
|
EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM article_tag_version
|
||||||
|
WHERE article_id = 3
|
||||||
|
AND tag_id = tags_version.id
|
||||||
|
AND operation_type != 2
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM article_tag_version as article_tag_version2
|
||||||
|
WHERE article_tag_version2.tag_id = article_tag_version.tag_id
|
||||||
|
AND article_tag_version2.tx_id <=5
|
||||||
|
AND article_tag_version2.article_id = 3
|
||||||
|
GROUP BY article_tag_version2.tag_id
|
||||||
|
HAVING
|
||||||
|
MAX(article_tag_version2.tx_id) =
|
||||||
|
article_tag_version.tx_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
:param obj: SQLAlchemy declarative object
|
||||||
|
"""
|
||||||
|
|
||||||
|
tx_column = option(obj, "transaction_column_name")
|
||||||
|
join_column = self.property.primaryjoin.right.name
|
||||||
|
object_join_column = self.property.primaryjoin.left.name
|
||||||
|
reflector = VersionExpressionReflector(obj, self.property)
|
||||||
|
|
||||||
|
association_table_alias = self.association_version_table.alias()
|
||||||
|
association_cols = [
|
||||||
|
association_table_alias.c[association_col.name]
|
||||||
|
for _, association_col in self.remote_to_association_column_pairs
|
||||||
|
]
|
||||||
|
|
||||||
|
association_exists = sa.exists(
|
||||||
|
sa.select([1])
|
||||||
|
.where(
|
||||||
|
sa.and_(
|
||||||
|
association_table_alias.c[tx_column] <= getattr(obj, tx_column),
|
||||||
|
association_table_alias.c[join_column]
|
||||||
|
== getattr(obj, object_join_column),
|
||||||
|
*[
|
||||||
|
association_col
|
||||||
|
== self.association_version_table.c[association_col.name]
|
||||||
|
for association_col in association_cols
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.group_by(*association_cols)
|
||||||
|
.having(
|
||||||
|
sa.func.max(association_table_alias.c[tx_column])
|
||||||
|
== self.association_version_table.c[tx_column]
|
||||||
|
)
|
||||||
|
.correlate(self.association_version_table)
|
||||||
|
)
|
||||||
|
return sa.exists(
|
||||||
|
sa.select([1])
|
||||||
|
.where(
|
||||||
|
sa.and_(
|
||||||
|
reflector(self.property.primaryjoin),
|
||||||
|
association_exists,
|
||||||
|
self.association_version_table.c.operation_type != Operation.DELETE,
|
||||||
|
adapt_columns(self.property.secondaryjoin),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.correlate(self.local_cls, self.remote_cls)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PatchedBuilder(Builder):
|
||||||
|
def build_relationships(self, version_classes):
|
||||||
|
"""
|
||||||
|
Builds relationships for all version classes.
|
||||||
|
|
||||||
|
:param version_classes: list of generated version classes
|
||||||
|
"""
|
||||||
|
for cls in version_classes:
|
||||||
|
if not self.manager.option(cls, "versioning"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for prop in sa.inspect(cls).iterate_properties:
|
||||||
|
if prop.key == "versions":
|
||||||
|
continue
|
||||||
|
builder = PatchedRelationShipBuilder(self.manager, cls, prop)
|
||||||
|
builder()
|
|
@ -2,13 +2,15 @@ import os
|
||||||
import os.path
|
import os.path
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from flask import Flask, g, request, session, render_template
|
from flask import Flask, g, render_template, request, session
|
||||||
from flask_babel import Babel
|
from flask_babel import Babel
|
||||||
from flask_mail import Mail
|
from flask_mail import Mail
|
||||||
from flask_migrate import Migrate, upgrade, stamp
|
from flask_migrate import Migrate, stamp, upgrade
|
||||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
|
||||||
|
from ihatemoney import default_settings
|
||||||
from ihatemoney.api.v1 import api as apiv1
|
from ihatemoney.api.v1 import api as apiv1
|
||||||
|
from ihatemoney.currency_convertor import CurrencyConverter
|
||||||
from ihatemoney.models import db
|
from ihatemoney.models import db
|
||||||
from ihatemoney.utils import (
|
from ihatemoney.utils import (
|
||||||
IhmJSONEncoder,
|
IhmJSONEncoder,
|
||||||
|
@ -19,8 +21,6 @@ from ihatemoney.utils import (
|
||||||
)
|
)
|
||||||
from ihatemoney.web import main as web_interface
|
from ihatemoney.web import main as web_interface
|
||||||
|
|
||||||
from ihatemoney import default_settings
|
|
||||||
|
|
||||||
|
|
||||||
def setup_database(app):
|
def setup_database(app):
|
||||||
"""Prepare the database. Create tables, run migrations etc."""
|
"""Prepare the database. Create tables, run migrations etc."""
|
||||||
|
@ -138,6 +138,9 @@ def create_app(
|
||||||
# Configure the a, root="main"pplication
|
# Configure the a, root="main"pplication
|
||||||
setup_database(app)
|
setup_database(app)
|
||||||
|
|
||||||
|
# Setup Currency Cache
|
||||||
|
CurrencyConverter()
|
||||||
|
|
||||||
mail = Mail()
|
mail = Mail()
|
||||||
mail.init_app(app)
|
mail.init_app(app)
|
||||||
app.mail = mail
|
app.mail = mail
|
||||||
|
|
|
@ -162,6 +162,11 @@ body {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
margin-left: 25px;
|
margin-left: 25px;
|
||||||
}
|
}
|
||||||
|
@media (max-width: 400px) {
|
||||||
|
.home .card {
|
||||||
|
min-width: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Other */
|
/* Other */
|
||||||
|
|
||||||
#bills {
|
#bills {
|
||||||
|
@ -192,7 +197,7 @@ footer {
|
||||||
padding: 45px 50px;
|
padding: 45px 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 1024px) {
|
||||||
footer {
|
footer {
|
||||||
padding-left: calc(25% + 50px);
|
padding-left: calc(25% + 50px);
|
||||||
}
|
}
|
||||||
|
@ -332,13 +337,16 @@ footer .footer-left {
|
||||||
background: url("../images/see.png") no-repeat right;
|
background: url("../images/see.png") no-repeat right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bill_table, #monthly_stats {
|
#bill_table,
|
||||||
|
#monthly_stats,
|
||||||
|
#history_table {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.split_bills, #table_overflow.statistics {
|
.split_bills,
|
||||||
|
#table_overflow.statistics {
|
||||||
/* The table is shifted to left, so add the spacer width on the right to match */
|
/* The table is shifted to left, so add the spacer width on the right to match */
|
||||||
width: calc(100% + 15px);
|
width: calc(100% + 15px);
|
||||||
}
|
}
|
||||||
|
@ -368,6 +376,36 @@ footer .footer-left {
|
||||||
background: url("../images/see.png") no-repeat right;
|
background: url("../images/see.png") no-repeat right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history_icon > .delete,
|
||||||
|
.history_icon > .add,
|
||||||
|
.history_icon > .edit {
|
||||||
|
font-size: 0px;
|
||||||
|
display: block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin: 2px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 3px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history_icon > .delete {
|
||||||
|
background: url("../images/delete.png") no-repeat right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history_icon > .edit {
|
||||||
|
background: url("../images/edit.png") no-repeat right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history_icon > .add {
|
||||||
|
background: url("../images/add.png") no-repeat right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history_text {
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.balance .balance-value {
|
.balance .balance-value {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
@ -529,6 +567,13 @@ footer .icon svg {
|
||||||
fill: white;
|
fill: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon.icon-red {
|
||||||
|
fill: #dc3545;
|
||||||
|
}
|
||||||
|
.btn:hover .icon.icon-red {
|
||||||
|
fill: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* align the first column */
|
/* align the first column */
|
||||||
#monthly_stats tr *:first-child {
|
#monthly_stats tr *:first-child {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -538,3 +583,17 @@ footer .icon svg {
|
||||||
.hiddenpswp {
|
.hiddenpswp {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#history_warnings {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* edit settings */
|
||||||
|
|
||||||
|
.edit-project form {
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 3em;
|
||||||
|
}
|
||||||
|
.edit-project .custom-file {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
BIN
ihatemoney/static/images/add.png
Normal file
BIN
ihatemoney/static/images/add.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 264 B |
8
ihatemoney/static/images/x.svg
Normal file
8
ihatemoney/static/images/x.svg
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 807 807"><g
|
||||||
|
transform="translate(-20,-20)"
|
||||||
|
id="g8"><polygon
|
||||||
|
id="polygon6"
|
||||||
|
points="173,20 423,269 673,20 827,173 577,423 827,673 673,827 423,577 173,827 20,673 269,423 20,173 "
|
||||||
|
class="fil0" /></g></svg>
|
After Width: | Height: | Size: 291 B |
|
@ -5,3 +5,7 @@ function selectCheckboxes(value){
|
||||||
els[i].checked = value;
|
els[i].checked = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function localizeTime(utcTimestamp) {
|
||||||
|
return new Date(utcTimestamp).toLocaleString()
|
||||||
|
}
|
||||||
|
|
|
@ -10,4 +10,5 @@
|
||||||
<div class="col-xs-12 col-sm-5 col-md-4 offset-md-2">
|
<div class="col-xs-12 col-sm-5 col-md-4 offset-md-2">
|
||||||
<a href='{{ url_for("main.home") }}'>{{ _("The best thing to do is probably to get back to the main page.")}}</a>
|
<a href='{{ url_for("main.home") }}'>{{ _("The best thing to do is probably to get back to the main page.")}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -5,18 +5,43 @@
|
||||||
{
|
{
|
||||||
$(this).html("<a style='color:red; ' href='{{ url_for('.delete_project') }}' >{{_("you sure?")}}</a>");
|
$(this).html("<a style='color:red; ' href='{{ url_for('.delete_project') }}' >{{_("you sure?")}}</a>");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.custom-file-input').on('change', function(event) {
|
||||||
|
var filename = [].slice.call(this.files).map(function (file) { return file.name}).join(',')
|
||||||
|
var $labelElement = $(this).parents('.custom-file').find('.custom-file-label')
|
||||||
|
$labelElement.text(filename)
|
||||||
|
})
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{{ _("Edit project") }}</h2>
|
<div class="container edit-project">
|
||||||
<p>
|
|
||||||
<form class="form-horizontal" method="post">
|
|
||||||
{{ forms.edit_project(edit_form) }}
|
|
||||||
</form>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>{{ _("Download project's data") }}</h2>
|
<h2>{{ _("Edit project") }}</h2>
|
||||||
<p>
|
<form class="form-horizontal" method="post">
|
||||||
|
{{ forms.edit_project(edit_form) }}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>{{ _("Import JSON") }}</h2>
|
||||||
|
<form class="form-horizontal" method="post" enctype="multipart/form-data">
|
||||||
|
{{ import_form.hidden_tag() }}
|
||||||
|
|
||||||
|
<div class="custom-file">
|
||||||
|
<div class="form-group">
|
||||||
|
{{ import_form.file(class="custom-file-input") }}
|
||||||
|
<small class="form-text text-muted">
|
||||||
|
{{ import_form.file.description }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<label class="custom-file-label" for="customFile">{{ _('Choose file') }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
{{ import_form.submit(class="btn btn-primary") }}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h2>{{ _("Download project's data") }}</h2>
|
||||||
<div class="list-group download-project">
|
<div class="list-group download-project">
|
||||||
<div class="list-group-item list-group-item-action">
|
<div class="list-group-item list-group-item-action">
|
||||||
<h5 class="d-flex w-100 justify-content-between">
|
<h5 class="d-flex w-100 justify-content-between">
|
||||||
|
@ -51,5 +76,5 @@
|
||||||
<p class="mb-1 text-muted">{{ _('Download the list of transactions needed to settle the current bills.') }}</p>
|
<p class="mb-1 text-muted">{{ _('Download the list of transactions needed to settle the current bills.') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -20,6 +20,16 @@
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro checkbox(field) %}
|
||||||
|
<div class="controls{% if inline %} col-9{% endif %}">
|
||||||
|
{{ field(id=field.name) }}
|
||||||
|
<label for="{{ field.name }}">{{ field.label() }}</label>
|
||||||
|
{% if field.description %}
|
||||||
|
<small id="{{field.name}}_description"" class="form-text text-muted">{{ field.description }}</small>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro submit(field, cancel=False, home=False) -%}
|
{% macro submit(field, cancel=False, home=False) -%}
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button type="submit" class="btn btn-primary">{{ field.name }}</button>
|
<button type="submit" class="btn btn-primary">{{ field.name }}</button>
|
||||||
|
@ -65,6 +75,7 @@
|
||||||
{{ input(form.name) }}
|
{{ input(form.name) }}
|
||||||
{{ input(form.password) }}
|
{{ input(form.password) }}
|
||||||
{{ input(form.contact_email) }}
|
{{ input(form.contact_email) }}
|
||||||
|
{{ input(form.default_currency) }}
|
||||||
{% if not home %}
|
{% if not home %}
|
||||||
{{ submit(form.submit, home=True) }}
|
{{ submit(form.submit, home=True) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -78,6 +89,15 @@
|
||||||
{{ input(form.name) }}
|
{{ input(form.name) }}
|
||||||
{{ input(form.password) }}
|
{{ input(form.password) }}
|
||||||
{{ input(form.contact_email) }}
|
{{ input(form.contact_email) }}
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="privacy_checkboxes">{{ _("Privacy Settings") }}</label>
|
||||||
|
<div id="privacy_checkboxes" class="card card-body bg-light">
|
||||||
|
{{ checkbox(form.project_history) }}
|
||||||
|
{{ checkbox(form.ip_recording) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ input(form.default_currency) }}
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="btn btn-primary">{{ _("Edit the project") }}</button>
|
<button class="btn btn-primary">{{ _("Edit the project") }}</button>
|
||||||
<a id="delete-project" style="color:red; margin-left:10px; cursor:pointer; ">{{ _("delete") }}</a>
|
<a id="delete-project" style="color:red; margin-left:10px; cursor:pointer; ">{{ _("delete") }}</a>
|
||||||
|
@ -104,6 +124,9 @@
|
||||||
{{ input(form.what, inline=True) }}
|
{{ input(form.what, inline=True) }}
|
||||||
{{ input(form.payer, inline=True, class="form-control custom-select") }}
|
{{ input(form.payer, inline=True, class="form-control custom-select") }}
|
||||||
{{ input(form.amount, inline=True) }}
|
{{ input(form.amount, inline=True) }}
|
||||||
|
{% if not form.original_currency.render_kw %}
|
||||||
|
{{ input(form.original_currency, inline=True) }}
|
||||||
|
{% endif %}
|
||||||
{{ input(form.external_link, inline=True) }}
|
{{ input(form.external_link, inline=True) }}
|
||||||
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
|
|
261
ihatemoney/templates/history.html
Normal file
261
ihatemoney/templates/history.html
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
{% extends "sidebar_table_layout.html" %}
|
||||||
|
|
||||||
|
{% macro change_to_logging_preference(event) %}
|
||||||
|
{% if event.val_after == LoggingMode.DISABLED %}
|
||||||
|
{% if event.val_before == LoggingMode.ENABLED %}
|
||||||
|
{{ _("Disabled Project History") }}
|
||||||
|
{% else %}
|
||||||
|
{{ _("Disabled Project History & IP Address Recording") }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif event.val_after == LoggingMode.ENABLED %}
|
||||||
|
{% if event.val_before == LoggingMode.DISABLED %}
|
||||||
|
{{ _("Enabled Project History") }}
|
||||||
|
{% elif event.val_before == LoggingMode.RECORD_IP %}
|
||||||
|
{{ _("Disabled IP Address Recording") }}
|
||||||
|
{% else %}
|
||||||
|
{{ _("Enabled Project History") }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif event.val_after == LoggingMode.RECORD_IP %}
|
||||||
|
{% if event.val_before == LoggingMode.DISABLED %}
|
||||||
|
{{ _("Enabled Project History & IP Address Recording") }}
|
||||||
|
{% elif event.val_before == LoggingMode.ENABLED %}
|
||||||
|
{{ _("Enabled IP Address Recording") }}
|
||||||
|
{% else %}
|
||||||
|
{{ _("Enabled Project History & IP Address Recording") }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{# Should be unreachable #}
|
||||||
|
{{ _("History Settings Changed") }}
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro describe_object(event) %}{{ event.object_type }} <em class="font-italic">{{ event.object_desc }}</em>{% endmacro %}
|
||||||
|
|
||||||
|
{% macro simple_property_change(event, localized_property_name, from=True) %}
|
||||||
|
{{ describe_object(event) }}:
|
||||||
|
{{ localized_property_name }} {{ _("changed") }}
|
||||||
|
{% if from %}{{ _("from") }} <em class="font-italic">{{ event.val_before }}</em>{% endif %}
|
||||||
|
{{ _("to") }} <em class="font-italic">{{ event.val_after }}</em>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro clear_history_modals() %}
|
||||||
|
<!-- Modal -->
|
||||||
|
<div id="confirm-ip-delete" class="modal fade show" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title">{{ _('Confirm Remove IP Adresses') }}</h3>
|
||||||
|
<a href="#" class="close" data-dismiss="modal">×</a>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>{{ _("Are you sure you want to delete all recorded IP addresses from this project?
|
||||||
|
The rest of the project history will be unaffected. This action cannot be undone.") }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ _("Close") }}</button>
|
||||||
|
<form action="{{ url_for(".strip_ip_addresses") }}" method="post">
|
||||||
|
<input type="submit" class="btn btn-danger" value="{{ _("Confirm Delete") }}" name="{{ _("Confirm Delete") }}"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div id="confirm-erase" class="modal fade show" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title">{{ _('Delete Confirmation') }}</h3>
|
||||||
|
<a href="#" class="close" data-dismiss="modal">×</a>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>{{ _("Are you sure you want to erase all history for this project? This action cannot be undone.") }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ _("Close") }}</button>
|
||||||
|
<form action="{{ url_for(".erase_history") }}" method="post">
|
||||||
|
<input type="submit" class="btn btn-danger" value="{{ _("Confirm Delete") }}" name="{{ _("Confirm Delete") }}"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro owers_changed(event, add) %}
|
||||||
|
{{ describe_object(event) }}: {% if add %}{{ _("Added") }}{% else %}{{ _("Removed") }}{% endif %}
|
||||||
|
{% if event.val_after|length > 1 %}
|
||||||
|
{% for name in event.val_after %}
|
||||||
|
<em class="font-italic">{{ name }}</em>{% if event.val_after|length > 2 and loop.index != event.val_after|length %},{% endif %}
|
||||||
|
{% if loop.index == event.val_after|length - 1 %} {{ _("and") }} {% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<em class="font-italic">{{ event.val_after[0] }}</em>
|
||||||
|
{% endif %}
|
||||||
|
{% if add %}{{ _("to") }}{% else %}{{ _("from") }}{% endif %}
|
||||||
|
{{ _("owers list") }}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% block sidebar %}
|
||||||
|
<div id="table_overflow">
|
||||||
|
<table class="balance table">
|
||||||
|
<thead>
|
||||||
|
<tr class="d-none d-md-table-row">
|
||||||
|
<th>{{ _("Who?") }}</th>
|
||||||
|
<th class="balance-value">{{ _("Balance") }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% set balance = g.project.balance %}
|
||||||
|
{% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id]|round(2) != 0 %}
|
||||||
|
<tr id="bal-member-{{ member.id }}" action={% if member.activated %}delete{% else %}reactivate{% endif %}>
|
||||||
|
<td class="balance-name">{{ member.name }}</td>
|
||||||
|
<td class="balance-value {% if balance[member.id]|round(2) > 0 %}positive{% elif balance[member.id]|round(2) < 0 %}negative{% endif %}">
|
||||||
|
{% if balance[member.id]|round(2) > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if current_log_pref == LoggingMode.DISABLED or (current_log_pref != LoggingMode.RECORD_IP and any_ip_addresses) %}
|
||||||
|
<div id="history_warnings" class="card card-body bg-light">
|
||||||
|
{% if current_log_pref == LoggingMode.DISABLED %}
|
||||||
|
<p>{% set url = url_for(".edit_project") %}
|
||||||
|
{% trans %}
|
||||||
|
<i>This project has history disabled. New actions won't appear below. You can enable history on the</i>
|
||||||
|
<a href="{{ url }}">settings page</a>
|
||||||
|
{% endtrans %}
|
||||||
|
</p>
|
||||||
|
{% if history %}
|
||||||
|
<p>
|
||||||
|
{% trans %}
|
||||||
|
<i>The table below reflects actions recorded prior to disabling project history. You can
|
||||||
|
<a href="#" data-toggle="modal" data-keyboard="false" data-target="#confirm-erase">clear project history</a> to remove them.</i></p>
|
||||||
|
{% endtrans %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if current_log_pref != LoggingMode.RECORD_IP and any_ip_addresses %}
|
||||||
|
<p>
|
||||||
|
<i>{{ _("Some entries below contain IP addresses, even though this project has IP recording disabled. ") }}
|
||||||
|
<a href="#" data-toggle="modal" data-keyboard="false" data-target="#confirm-ip-delete">{{ _("Delete stored IP addresses") }}</a></i>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{{ clear_history_modals() }}
|
||||||
|
<span class="float-right mt-3" {% if not history %} data-toggle="tooltip" title="{{_('No history to erase')}}" {% endif %}>
|
||||||
|
<a href="#" class="btn btn-outline-danger float-right {% if not history %} disabled {% endif %}" data-toggle="modal" data-keyboard="false" data-target="#confirm-erase">
|
||||||
|
<i class="icon icon-red plus">{{ static_include("images/x.svg") | safe }}</i>
|
||||||
|
{{ _("Clear Project History") }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span class="float-right mt-3" {% if not any_ip_addresses %}data-placement="top" data-toggle="tooltip" title="{{_('No IP Addresses to erase')}}" {% endif %}>
|
||||||
|
<a href="#" class="btn btn-outline-danger float-right mr-2 {% if not any_ip_addresses %} disabled {% endif %}" data-toggle="modal" data-keyboard="false" data-target="#confirm-ip-delete">
|
||||||
|
<i class="icon icon-red plus">{{ static_include("images/x.svg") | safe }}</i>
|
||||||
|
{{ _("Delete Stored IP Addresses") }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
{% if history %}
|
||||||
|
<table id="history_table" class="split_bills table table-striped">
|
||||||
|
<thead><tr>
|
||||||
|
<th style="width: 15%">{{ _("Time") }}</th>
|
||||||
|
<th style="width: 65%">{{ _("Event") }}</th>
|
||||||
|
<th style="width: 20%">
|
||||||
|
<span data-toggle="tooltip" title="{% if current_log_pref != LoggingMode.RECORD_IP %}
|
||||||
|
{{_('IP address recording can be enabled on the settings page') }}
|
||||||
|
{% else %}
|
||||||
|
{{_('IP address recording can be disabled on the settings page') }}
|
||||||
|
{% endif %}">
|
||||||
|
{{ _("From IP") }}</span></th>
|
||||||
|
</tr></thead>
|
||||||
|
<tbody>
|
||||||
|
{% for event in history %}
|
||||||
|
<tr>
|
||||||
|
<td><script>document.write(localizeTime("{{ event.time }}"));</script></td>
|
||||||
|
<td >
|
||||||
|
<div class="history_icon">
|
||||||
|
<i {% if event.operation_type == OperationType.INSERT %}
|
||||||
|
class="add"
|
||||||
|
{% elif event.operation_type == OperationType.UPDATE %}
|
||||||
|
class="edit"
|
||||||
|
{% elif event.operation_type == OperationType.DELETE %}
|
||||||
|
class="delete"
|
||||||
|
{% endif %}
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
<div class="history_text">
|
||||||
|
{% if event.operation_type == OperationType.INSERT %}
|
||||||
|
{{ event.object_type }} <em class="font-italic">{{ event.object_desc }}</em> {{ _("added") }}
|
||||||
|
{% elif event.operation_type == OperationType.UPDATE %}
|
||||||
|
{% if event.object_type == _("Project") %}
|
||||||
|
{% if event.prop_changed == "password" %}
|
||||||
|
{{ _("Project private code changed") }}
|
||||||
|
{% elif event.prop_changed == "logging_preference" %}
|
||||||
|
{{ change_to_logging_preference(event) }}
|
||||||
|
{% elif event.prop_changed == "name" %}
|
||||||
|
{{ _("Project renamed to") }} <em class="font-italic">{{ event.val_after }}</em>
|
||||||
|
{% elif event.prop_changed == "contact_email" %}
|
||||||
|
{{ _("Project contact email changed to") }} <em class="font-italic">{{ event.val_after }}</em>
|
||||||
|
{% else %}
|
||||||
|
{{ _("Project settings modified") }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif event.prop_changed == "activated" %}
|
||||||
|
{{ event.object_type }} <em class="font-italic">{{ event.object_desc }}</em>
|
||||||
|
{% if event.val_after == False %}{{ _("deactivated") }}{% else %}{{ _("reactivated") }}{% endif %}
|
||||||
|
{% elif event.prop_changed == "name" or event.prop_changed == "what" %}
|
||||||
|
{{ describe_object(event) }} {{ _("renamed to") }} <em class="font-italic">{{ event.val_after }}</em>
|
||||||
|
{% elif event.prop_changed == "weight" %}
|
||||||
|
{{ simple_property_change(event, _("Weight")) }}
|
||||||
|
{% elif event.prop_changed == "external_link" %}
|
||||||
|
{{ describe_object(event) }}: {{ _("External link changed to") }}
|
||||||
|
<a href="{{ event.val_after }}" class="font-italic">{{ event.val_after }}</a>
|
||||||
|
{% elif event.prop_changed == "owers_added" %}
|
||||||
|
{{ owers_changed(event, True)}}
|
||||||
|
{% elif event.prop_changed == "owers_removed" %}
|
||||||
|
{{ owers_changed(event, False)}}
|
||||||
|
{% elif event.prop_changed == "payer" %}
|
||||||
|
{{ simple_property_change(event, _("Payer"))}}
|
||||||
|
{% elif event.prop_changed == "amount" %}
|
||||||
|
{{ simple_property_change(event, _("Amount")) }}
|
||||||
|
{% elif event.prop_changed == "date" %}
|
||||||
|
{{ simple_property_change(event, _("Date")) }}
|
||||||
|
{% elif event.prop_changed == "original_currency" %}
|
||||||
|
{{ simple_property_change(event, _("Currency")) }}
|
||||||
|
{% elif event.prop_changed == "converted_amount" %}
|
||||||
|
{{ simple_property_change(event, _("Amount in %(currency)s", currency=g.project.default_currency)) }}
|
||||||
|
{% else %}
|
||||||
|
{{ describe_object(event) }} {{ _("modified") }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif event.operation_type == OperationType.DELETE %}
|
||||||
|
{{ event.object_type }} <em class="font-italic">{{ event.object_desc }}</em> {{ _("removed") }}
|
||||||
|
{% else %}
|
||||||
|
{# Should be unreachable #}
|
||||||
|
{{ describe_object(event) }} {{ _("changed in a unknown way") }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>{% if event.ip %}{{ event.ip }}{% else %} -- {% endif %}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<div class="py-3 d-flex justify-content-center empty-bill">
|
||||||
|
<div class="card d-inline-flex p-2">
|
||||||
|
<div class="card-body text-center text-muted">
|
||||||
|
<i class="icon icon-white hand-holding-heart">{{ static_include("images/hand-holding-heart.svg") | safe }}</i>
|
||||||
|
<h3>{{ _('Nothing to list')}}</h3>
|
||||||
|
<p>
|
||||||
|
{{ _("Someone probably cleared the project history.") }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -47,8 +47,8 @@
|
||||||
<li class="nav-item{% if current_view == 'list_bills' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.list_bills") }}">{{ _("Bills") }}</a></li>
|
<li class="nav-item{% if current_view == 'list_bills' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.list_bills") }}">{{ _("Bills") }}</a></li>
|
||||||
<li class="nav-item{% if current_view == 'settle_bill' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.settle_bill") }}">{{ _("Settle") }}</a></li>
|
<li class="nav-item{% if current_view == 'settle_bill' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.settle_bill") }}">{{ _("Settle") }}</a></li>
|
||||||
<li class="nav-item{% if current_view == 'statistics' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.statistics") }}">{{ _("Statistics") }}</a></li>
|
<li class="nav-item{% if current_view == 'statistics' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.statistics") }}">{{ _("Statistics") }}</a></li>
|
||||||
|
<li class="nav-item{% if current_view == 'history' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.history") }}">{{ _("History") }}</a></li>
|
||||||
<li class="nav-item{% if current_view == 'edit_project' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.edit_project") }}">{{ _("Settings") }}</a></li>
|
<li class="nav-item{% if current_view == 'edit_project' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.edit_project") }}">{{ _("Settings") }}</a></li>
|
||||||
<li class="nav-item{% if current_view == 'upload_json' %} active{% endif %}"><a class="nav-link" href="{{ url_for("main.upload_json") }}">{{ _("Import") }}</a></li>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -127,9 +127,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="messages">
|
<div class="messages">
|
||||||
{% for message in get_flashed_messages() %}
|
{% for category, message in get_flashed_messages(with_categories=true) %}
|
||||||
<div class="flash alert alert-success">{{ message }}</div>
|
{% if category == "message" %}{# Default category for flash(msg) #}
|
||||||
{% endfor %}
|
<div class="flash alert alert-success">{{ message }}</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="flash alert alert-{{ category }}">{{ message }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% block footer %}
|
{% block footer %}
|
||||||
|
|
|
@ -117,7 +117,19 @@
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
|
|
||||||
<table id="bill_table" class="col table table-striped table-hover table-responsive-sm">
|
<table id="bill_table" class="col table table-striped table-hover table-responsive-sm">
|
||||||
<thead><tr><th>{{ _("When?") }}</th><th>{{ _("Who paid?") }}</<th><th>{{ _("For what?") }}</th><th>{{ _("For whom?") }}</th><th>{{ _("How much?") }}</th><th>{{ _("Actions") }}</th></tr></thead>
|
<thead>
|
||||||
|
<tr><th>{{ _("When?") }}
|
||||||
|
</th><th>{{ _("Who paid?") }}
|
||||||
|
</th><th>{{ _("For what?") }}
|
||||||
|
</th><th>{{ _("For whom?") }}
|
||||||
|
</th><th>{{ _("How much?") }}
|
||||||
|
{% if g.project.default_currency != "No Currency" %}
|
||||||
|
</th><th>{{ _("Amount in %(currency)s", currency=g.project.default_currency) }}
|
||||||
|
{%- else -%}
|
||||||
|
</th><th>{{ _("Amount") }}
|
||||||
|
{% endif %}
|
||||||
|
</th><th>{{ _("Actions") }}</th></tr>
|
||||||
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for bill in bills.items %}
|
{% for bill in bills.items %}
|
||||||
<tr owers="{{bill.owers|join(',','id')}}" payer="{{bill.payer.id}}">
|
<tr owers="{{bill.owers|join(',','id')}}" payer="{{bill.payer.id}}">
|
||||||
|
@ -136,7 +148,14 @@
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{{ bill.owers|join(', ', 'name') }}
|
{{ bill.owers|join(', ', 'name') }}
|
||||||
{%- endif %}</td>
|
{%- endif %}</td>
|
||||||
<td>{{ "%0.2f"|format(bill.amount) }} ({{ "%0.2f"|format(bill.pay_each()) }} {{ _("each") }})</td>
|
<td>
|
||||||
|
{% if bill.original_currency != "No Currency" %}
|
||||||
|
{{ "%0.2f"|format(bill.amount) }} {{bill.original_currency}} ({{ "%0.2f"|format(bill.pay_each_default(bill.amount)) }} {{bill.original_currency}} {{ _(" each") }})
|
||||||
|
{%- else -%}
|
||||||
|
{{ "%0.2f"|format(bill.amount) }} ({{ "%0.2f"|format(bill.pay_each_default(bill.amount)) }} {{ _(" each") }})
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ "%0.2f"|format(bill.converted_amount) }}</td>
|
||||||
<td class="bill-actions">
|
<td class="bill-actions">
|
||||||
<a class="edit" href="{{ url_for(".edit_bill", bill_id=bill.id) }}" title="{{ _("edit") }}">{{ _('edit') }}</a>
|
<a class="edit" href="{{ url_for(".edit_bill", bill_id=bill.id) }}" title="{{ _("edit") }}">{{ _('edit') }}</a>
|
||||||
<a class="delete" href="{{ url_for(".delete_bill", bill_id=bill.id) }}" title="{{ _("delete") }}">{{ _('delete') }}</a>
|
<a class="delete" href="{{ url_for(".delete_bill", bill_id=bill.id) }}" title="{{ _("delete") }}">{{ _('delete') }}</a>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<th class="balance-value">{{ _("Balance") }}</th>
|
<th class="balance-value">{{ _("Balance") }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{% for stat in members_stats| sort(attribute='member.name') %}
|
{% for stat in members_stats|sort(attribute='member.name') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="balance-name">{{ stat.member.name }}</td>
|
<td class="balance-name">{{ stat.member.name }}</td>
|
||||||
<td class="balance-value {% if stat.balance|round(2) > 0 %}positive{% elif stat.balance|round(2) < 0 %}negative{% endif %}">
|
<td class="balance-value {% if stat.balance|round(2) > 0 %}positive{% elif stat.balance|round(2) < 0 %}negative{% endif %}">
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<table id="bill_table" class="split_bills table table-striped ml-md-n3">
|
<table id="bill_table" class="split_bills table table-striped ml-md-n3">
|
||||||
<thead><tr><th class="d-md-none">{{ _("Who?") }}</th><th>{{ _("Paid") }}</th><th>{{ _("Spent") }}</th></tr></thead>
|
<thead><tr><th class="d-md-none">{{ _("Who?") }}</th><th>{{ _("Paid") }}</th><th>{{ _("Spent") }}</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for stat in members_stats %}
|
{% for stat in members_stats|sort(attribute='member.name') %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="d-md-none">{{ stat.member.name }}</td>
|
<td class="d-md-none">{{ stat.member.name }}</td>
|
||||||
<td>{{ "%0.2f"|format(stat.paid) }}</td>
|
<td>{{ "%0.2f"|format(stat.paid) }}</td>
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
{% extends "layout.html" %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h2>{{ _("Import JSON") }}</h2>
|
|
||||||
<p>
|
|
||||||
<form class="form-horizontal" method="post" enctype="multipart/form-data">
|
|
||||||
{{ forms.upload_json(form) }}
|
|
||||||
</form>
|
|
||||||
</p>
|
|
||||||
{% endblock %}
|
|
File diff suppressed because it is too large
Load diff
BIN
ihatemoney/translations/cs/LC_MESSAGES/messages.mo
Normal file
BIN
ihatemoney/translations/cs/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
|
@ -1,16 +1,18 @@
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-10-24 18:27+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: Automatically generated\n"
|
"Last-Translator: Automatically generated\n"
|
||||||
"Language-Team: none\n"
|
|
||||||
"Language: cs\n"
|
"Language: cs\n"
|
||||||
|
"Language-Team: none\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: Translate Toolkit 2.4.0\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
@ -26,6 +28,18 @@ msgstr ""
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -120,6 +134,15 @@ msgstr ""
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -153,6 +176,12 @@ msgstr ""
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -164,7 +193,7 @@ msgid "Your invitations have been sent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -218,9 +247,6 @@ msgstr ""
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -242,6 +268,9 @@ msgstr ""
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -251,6 +280,12 @@ msgstr ""
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -272,6 +307,9 @@ msgstr ""
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -302,6 +340,177 @@ msgstr ""
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -349,6 +558,9 @@ msgstr ""
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -406,6 +618,12 @@ msgstr ""
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -432,9 +650,6 @@ msgstr ""
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -503,14 +718,14 @@ msgstr ""
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
Binary file not shown.
|
@ -1,25 +1,26 @@
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-10-12 09:58+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2020-02-12 10:50+0000\n"
|
"PO-Revision-Date: 2020-02-12 10:50+0000\n"
|
||||||
"Last-Translator: flolilo <flolilo@mailbox.org>\n"
|
"Last-Translator: flolilo <flolilo@mailbox.org>\n"
|
||||||
"Language-Team: German <https://hosted.weblate.org/projects/i-hate-money/"
|
|
||||||
"i-hate-money/de/>\n"
|
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
|
"Language-Team: German <https://hosted.weblate.org/projects/i-hate-money/i"
|
||||||
|
"-hate-money/de/>\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=n != 1\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
"X-Generator: Weblate 3.11-dev\n"
|
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
"accepted."
|
"accepted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Kein gültiger Betrag oder Ausdruck. Es werden nur Zahlen und die Operatoren +"
|
"Kein gültiger Betrag oder Ausdruck. Es werden nur Zahlen und die "
|
||||||
" - * / akzeptiert."
|
"Operatoren + - * / akzeptiert."
|
||||||
|
|
||||||
msgid "Project name"
|
msgid "Project name"
|
||||||
msgstr "Projektname"
|
msgstr "Projektname"
|
||||||
|
@ -30,6 +31,18 @@ msgstr "Privater Code"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "E-Mail"
|
msgstr "E-Mail"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "Projektkennung"
|
msgstr "Projektkennung"
|
||||||
|
|
||||||
|
@ -41,8 +54,8 @@ msgid ""
|
||||||
"A project with this identifier (\"%(project)s\") already exists. Please "
|
"A project with this identifier (\"%(project)s\") already exists. Please "
|
||||||
"choose a new identifier"
|
"choose a new identifier"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ein Projekt mit der Kennung (\"%(project)s\") existiert bereits. Bitte wähle "
|
"Ein Projekt mit der Kennung (\"%(project)s\") existiert bereits. Bitte "
|
||||||
"eine andere Kennung"
|
"wähle eine andere Kennung"
|
||||||
|
|
||||||
msgid "Get in"
|
msgid "Get in"
|
||||||
msgstr "Eintreten"
|
msgstr "Eintreten"
|
||||||
|
@ -80,6 +93,12 @@ msgstr "Von"
|
||||||
msgid "Amount paid"
|
msgid "Amount paid"
|
||||||
msgstr "Betrag"
|
msgstr "Betrag"
|
||||||
|
|
||||||
|
msgid "External link"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "A link to an external document, related to this bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "For whom?"
|
msgid "For whom?"
|
||||||
msgstr "Für wen?"
|
msgstr "Für wen?"
|
||||||
|
|
||||||
|
@ -120,6 +139,15 @@ msgstr "Einladung senden"
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr "Die E-Mail-Adresse(n) %(email)s ist/sind nicht gültig"
|
msgstr "Die E-Mail-Adresse(n) %(email)s ist/sind nicht gültig"
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr "Projekt"
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr "Zu viele fehlgeschlagene Anmeldeversuche, bitte versuche es später."
|
msgstr "Zu viele fehlgeschlagene Anmeldeversuche, bitte versuche es später."
|
||||||
|
|
||||||
|
@ -130,8 +158,7 @@ msgstr ""
|
||||||
"verbleibend."
|
"verbleibend."
|
||||||
|
|
||||||
msgid "You either provided a bad token or no project identifier."
|
msgid "You either provided a bad token or no project identifier."
|
||||||
msgstr ""
|
msgstr "Du hast entweder einen ungültigen Token oder keine Projekt-ID angegeben."
|
||||||
"Du hast entweder einen ungültigen Token oder keine Projekt-ID angegeben."
|
|
||||||
|
|
||||||
msgid "This private code is not the right one"
|
msgid "This private code is not the right one"
|
||||||
msgstr "Der private Code ist nicht korrekt"
|
msgstr "Der private Code ist nicht korrekt"
|
||||||
|
@ -158,6 +185,12 @@ msgstr "Unbekanntes Projekt"
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr "Passwort erfolgreich zurückgesetzt."
|
msgstr "Passwort erfolgreich zurückgesetzt."
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr "Projekt erfolgreich gelöscht"
|
msgstr "Projekt erfolgreich gelöscht"
|
||||||
|
|
||||||
|
@ -169,8 +202,8 @@ msgid "Your invitations have been sent"
|
||||||
msgstr "Deine Einladungen wurden versendet"
|
msgstr "Deine Einladungen wurden versendet"
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr "%(member)s wurde(n) hinzugefügt"
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s is part of this project again"
|
msgid "%(name)s is part of this project again"
|
||||||
|
@ -225,9 +258,6 @@ msgstr "?"
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr "Neues Projekt erstellen"
|
msgstr "Neues Projekt erstellen"
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr "Projekt"
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr "Anzahl der Teilnehmer"
|
msgstr "Anzahl der Teilnehmer"
|
||||||
|
|
||||||
|
@ -249,6 +279,9 @@ msgstr "Bearbeiten"
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr "Löschen"
|
msgstr "Löschen"
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr "Das Dashboard ist aktuell deaktiviert."
|
msgstr "Das Dashboard ist aktuell deaktiviert."
|
||||||
|
|
||||||
|
@ -258,6 +291,12 @@ msgstr "Bist du sicher?"
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr "Projekt bearbeiten"
|
msgstr "Projekt bearbeiten"
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr "Projektdaten herunterladen"
|
msgstr "Projektdaten herunterladen"
|
||||||
|
|
||||||
|
@ -279,6 +318,9 @@ msgstr "Passwort vergessen?"
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Abbrechen"
|
msgstr "Abbrechen"
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr "Projekt bearbeiten"
|
msgstr "Projekt bearbeiten"
|
||||||
|
|
||||||
|
@ -309,6 +351,177 @@ msgstr "Einladung versenden"
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr "Herunterladen"
|
msgstr "Herunterladen"
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr "Wer?"
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr "Bilanz"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr "Verwalten deine geteilten <br />Ausgaben ganz einfach"
|
msgstr "Verwalten deine geteilten <br />Ausgaben ganz einfach"
|
||||||
|
|
||||||
|
@ -343,8 +556,9 @@ msgid ""
|
||||||
"This access code will be sent to your friends. It is stored as-is by the "
|
"This access code will be sent to your friends. It is stored as-is by the "
|
||||||
"server, so don\\'t reuse a personal password!"
|
"server, so don\\'t reuse a personal password!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Dieser Zugangscode wird an deine Freunde gesendet. Es wird als Klartext auf "
|
"Dieser Zugangscode wird an deine Freunde gesendet. Es wird als Klartext "
|
||||||
"dem Server gespeichert. Bitte verwenden daher kein persönliches Passwort!"
|
"auf dem Server gespeichert. Bitte verwenden daher kein persönliches "
|
||||||
|
"Passwort!"
|
||||||
|
|
||||||
msgid "Account manager"
|
msgid "Account manager"
|
||||||
msgstr "Konten"
|
msgstr "Konten"
|
||||||
|
@ -358,6 +572,9 @@ msgstr "Bilanz"
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Statistik"
|
msgstr "Statistik"
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Einstellungen"
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
|
@ -415,6 +632,12 @@ msgstr "Du kannst anfangen, Teilnehmer hinzuzufügen"
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr "Neue Ausgabe"
|
msgstr "Neue Ausgabe"
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr "Wann?"
|
msgstr "Wann?"
|
||||||
|
|
||||||
|
@ -485,8 +708,8 @@ msgid ""
|
||||||
"You can share the project identifier and the private code by any "
|
"You can share the project identifier and the private code by any "
|
||||||
"communication means."
|
"communication means."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Du kannst die Projekt-ID und den privaten Code auf jedem Kommunikationsweg "
|
"Du kannst die Projekt-ID und den privaten Code auf jedem "
|
||||||
"weitergeben."
|
"Kommunikationsweg weitergeben."
|
||||||
|
|
||||||
msgid "Identifier:"
|
msgid "Identifier:"
|
||||||
msgstr "ID:"
|
msgstr "ID:"
|
||||||
|
@ -495,8 +718,7 @@ msgid "Share the Link"
|
||||||
msgstr "Link teilen"
|
msgstr "Link teilen"
|
||||||
|
|
||||||
msgid "You can directly share the following link via your prefered medium"
|
msgid "You can directly share the following link via your prefered medium"
|
||||||
msgstr ""
|
msgstr "Du kannst den folgenden Link direkt über dein bevorzugtes Medium teilen"
|
||||||
"Du kannst den folgenden Link direkt über dein bevorzugtes Medium teilen"
|
|
||||||
|
|
||||||
msgid "Send via Emails"
|
msgid "Send via Emails"
|
||||||
msgstr "Per E-Mail versenden"
|
msgstr "Per E-Mail versenden"
|
||||||
|
@ -507,10 +729,10 @@ msgid ""
|
||||||
" creation of this budget management project and we will "
|
" creation of this budget management project and we will "
|
||||||
"send them an email for you."
|
"send them an email for you."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Gib eine (durch Kommas getrennte) Liste von E-Mail-Adressen an, die du über "
|
"Gib eine (durch Kommas getrennte) Liste von E-Mail-Adressen an, die du "
|
||||||
"die\n"
|
"über die\n"
|
||||||
"\t\t\tErstellung dieses Projekts informieren möchtest, und wir senden ihnen "
|
"\t\t\tErstellung dieses Projekts informieren möchtest, und wir senden "
|
||||||
"eine E-Mail."
|
"ihnen eine E-Mail."
|
||||||
|
|
||||||
msgid "Who pays?"
|
msgid "Who pays?"
|
||||||
msgstr "Wer zahlt?"
|
msgstr "Wer zahlt?"
|
||||||
|
@ -518,14 +740,21 @@ msgstr "Wer zahlt?"
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr "An wen?"
|
msgstr "An wen?"
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr "Wer?"
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr "Bezahlt"
|
msgstr "Bezahlt"
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr "Ausgegeben"
|
msgstr "Ausgegeben"
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
msgstr "Bilanz"
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "Someone probably"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "cleared the project history."
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -3,7 +3,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-10-01 21:48+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: Automatically generated\n"
|
"Last-Translator: Automatically generated\n"
|
||||||
"Language: el\n"
|
"Language: el\n"
|
||||||
|
@ -12,7 +12,7 @@ msgstr ""
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.7.0\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
@ -28,6 +28,18 @@ msgstr ""
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -122,6 +134,15 @@ msgstr ""
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -155,6 +176,12 @@ msgstr ""
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -166,7 +193,7 @@ msgid "Your invitations have been sent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -220,9 +247,6 @@ msgstr ""
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -244,6 +268,9 @@ msgstr ""
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -253,6 +280,12 @@ msgstr ""
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -274,6 +307,9 @@ msgstr ""
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -304,6 +340,177 @@ msgstr ""
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -351,6 +558,9 @@ msgstr ""
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -408,6 +618,12 @@ msgstr ""
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -434,9 +650,6 @@ msgstr ""
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -505,97 +718,14 @@ msgstr ""
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid ""
|
msgid "Period"
|
||||||
#~ "Not a valid amount or expression.Only"
|
msgstr ""
|
||||||
#~ " numbers and + - * / "
|
|
||||||
#~ "operatorsare accepted."
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "What do you want to download ?"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "bills"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "transactions"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Export file format"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Edit this project"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Download this project's data"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Type user name here"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "No, thanks"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Manage your shared <br>expenses, easily"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Log to an existing project"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "log in"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "or create a new one"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "let's get started"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "options"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Project settings"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "This is a free software"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Invite people to join this project!"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Added on"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Nothing to list yet. You probably want to"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "Specify a (comma separated) list of "
|
|
||||||
#~ "email adresses you want to notify "
|
|
||||||
#~ "about the\n"
|
|
||||||
#~ "creation of this budget management "
|
|
||||||
#~ "project and we will send them an"
|
|
||||||
#~ " email for you."
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "If you prefer, you can share the project identifier and the shared\n"
|
|
||||||
#~ "password by other communication means. "
|
|
||||||
#~ "Or even directly share the following "
|
|
||||||
#~ "link:"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "A link to reset your password has been sent to your email."
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -1,19 +1,19 @@
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-10-20 11:52+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2019-09-25 22:28+0000\n"
|
"PO-Revision-Date: 2020-05-03 15:20+0000\n"
|
||||||
"Last-Translator: Diego Caraballo <diegocaraballo84@gmail.com>\n"
|
"Last-Translator: Fabian Rodriguez <fabian@fabianrodriguez.com>\n"
|
||||||
|
"Language-Team: Spanish (Latin America) <https://hosted.weblate.org/projects/"
|
||||||
|
"i-hate-money/i-hate-money/es_419/>\n"
|
||||||
"Language: es_419\n"
|
"Language: es_419\n"
|
||||||
"Language-Team: Spanish (Latin America) "
|
|
||||||
"<https://hosted.weblate.org/projects/i-hate-money/i-hate-money/es_419/>\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.7.0\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
|
"X-Generator: Weblate 4.1-dev\n"
|
||||||
|
"Generated-By: Babel 2.8.0\n"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
@ -31,6 +31,18 @@ msgstr "Código privado"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Correo Electrónico"
|
msgstr "Correo Electrónico"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr "Habilitar historial del proyecto"
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr "Registrar la IPs para el historial del proyecto"
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr "Importar archivo JSON previamente exportado"
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importar"
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "Identificador de proyecto"
|
msgstr "Identificador de proyecto"
|
||||||
|
|
||||||
|
@ -127,6 +139,15 @@ msgstr "Enviar invitaciones"
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr "El correo electrónico %(email)s no es válido"
|
msgstr "El correo electrónico %(email)s no es válido"
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr "Participante"
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr "Factura"
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr "Proyecto"
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Demasiados intentos fallidos de inicio de sesión, vuelva a intentarlo más"
|
"Demasiados intentos fallidos de inicio de sesión, vuelva a intentarlo más"
|
||||||
|
@ -164,6 +185,12 @@ msgstr "Proyecto desconocido"
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr "Contraseña restablecida con éxito."
|
msgstr "Contraseña restablecida con éxito."
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr "El proyecto se subió exitosamente"
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr "JSON inválido"
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr "Proyecto eliminado correctamente"
|
msgstr "Proyecto eliminado correctamente"
|
||||||
|
|
||||||
|
@ -175,8 +202,8 @@ msgid "Your invitations have been sent"
|
||||||
msgstr "Sus invitaciones han sido enviadas"
|
msgstr "Sus invitaciones han sido enviadas"
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr "se han añadido %(member)s"
|
msgstr "Se añadieron %(member)s"
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s is part of this project again"
|
msgid "%(name)s is part of this project again"
|
||||||
|
@ -231,9 +258,6 @@ msgstr "?"
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr "Crear un nuevo proyecto"
|
msgstr "Crear un nuevo proyecto"
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr "Proyecto"
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr "Número de miembros"
|
msgstr "Número de miembros"
|
||||||
|
|
||||||
|
@ -255,6 +279,9 @@ msgstr "Editar"
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr "Eliminar"
|
msgstr "Eliminar"
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr "ver"
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr "El panel está desactivado actualmente."
|
msgstr "El panel está desactivado actualmente."
|
||||||
|
|
||||||
|
@ -264,6 +291,12 @@ msgstr "¿Estás seguro?"
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr "Editar proyecto"
|
msgstr "Editar proyecto"
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr "Importar JSON"
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr "Escoger un archivo"
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr "Descargar datos del proyecto"
|
msgstr "Descargar datos del proyecto"
|
||||||
|
|
||||||
|
@ -287,6 +320,9 @@ msgstr "¿No recuerdas la contraseña?"
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancelar"
|
msgstr "Cancelar"
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr "Ajustes de privacidad"
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr "Editar el proyecto"
|
msgstr "Editar el proyecto"
|
||||||
|
|
||||||
|
@ -309,7 +345,7 @@ msgid "Edit this member"
|
||||||
msgstr "Editar este miembro"
|
msgstr "Editar este miembro"
|
||||||
|
|
||||||
msgid "john.doe@example.com, mary.moe@site.com"
|
msgid "john.doe@example.com, mary.moe@site.com"
|
||||||
msgstr "john.doe@example.com, mary.moe@site.com"
|
msgstr "juan.perez@example.com, ana.rodriguez@site.com"
|
||||||
|
|
||||||
msgid "Send the invitations"
|
msgid "Send the invitations"
|
||||||
msgstr "Enviar las invitaciones"
|
msgstr "Enviar las invitaciones"
|
||||||
|
@ -317,6 +353,199 @@ msgstr "Enviar las invitaciones"
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr "Descargar"
|
msgstr "Descargar"
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr "Historial de proyecto activo"
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr "Historial de proyecto y registros de dirección IP inactivos"
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr "Historial de proyecto activo"
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr "Registro de direcciones IP activo"
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr "Historial de proyecto y registros de dirección IP activos"
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr "Se activó el registros de dirección IP"
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr "Se cambiaron los ajustes del historial"
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr "cambió"
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr "de"
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr "a"
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr "Confirmar eliminación de direcciones IP"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
"Por favor confirme la eliminación completa del registro de direcciones IP "
|
||||||
|
"del proyecto.\n"
|
||||||
|
" El resto de historial del proyecto no será afectado. Este "
|
||||||
|
"cambio es irreversible."
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Cerrar"
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr "Confirmar eliminación"
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr "Confirmación de eliminación"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
"Por favor confirme la eliminación completa del historial del proyecto. Esta "
|
||||||
|
"acción es irreversible."
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr "Agregado"
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr "Eliminado"
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr "y"
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr "lista de deudores"
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr "¿Quién?"
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr "Balance"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" <i>El historial de este proyecto ha sido desactivado. Nuevas "
|
||||||
|
"operaciones no apareceran a continuacion. El historial se puede agregar</i> "
|
||||||
|
"\n"
|
||||||
|
" <a href=\"%(url)s\">en la página de ajustes</a>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" <i>Este registro muestra la actividad previa a la desactivación "
|
||||||
|
"del historial del proyecto. Use la opción \n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" data-"
|
||||||
|
"target=\"#confirm-erase\">Eliminar historial del proyecto</a> para "
|
||||||
|
"borrarlo.</i></p>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
"Algunos registros contienen direcciones IP, a pesar de que el registro de "
|
||||||
|
"direcciones IP del proyecto no está activo. "
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr "Borrar las direcciones IP registradas"
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr "No hay historial para borrar"
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr "Borrar el historial del proyecto"
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr "No hay direcciones IP para borrar"
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr "Borrar direcciones IP registradas"
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr "Hora"
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr "Evento"
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr "El registro de direcciones IP se puede activar en la página de ajustes"
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
"El registro de direcciones IP se puede desactivar en la página de ajustes"
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr "IP de origen"
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr "agregado"
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr "Se cambió el código privado del proyecto"
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr "Se cambió el nombre del proyecto a"
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr "Se cambió el correo electrónico de contacto a"
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr "Ajustes del proyecto modificados"
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr "desactivado"
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr "reactivado"
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr "se cambió de nombre a"
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr "Se cambió el enlace externo por"
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr "Monto"
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr "modificado"
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr "removido"
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr "se cambió de manera desconocida"
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr "Nada por listar"
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr "Es probable que alguien borrara el historial del proyecto."
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr "Gestione sus gastos compartidos <br />fácilmente"
|
msgstr "Gestione sus gastos compartidos <br />fácilmente"
|
||||||
|
|
||||||
|
@ -366,6 +595,9 @@ msgstr "Resolver"
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Estadísticas"
|
msgstr "Estadísticas"
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr "Historial"
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Configuración"
|
msgstr "Configuración"
|
||||||
|
|
||||||
|
@ -423,6 +655,12 @@ msgstr "Deberías comenzar agregando participantes"
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr "Añadir una nueva factura"
|
msgstr "Añadir una nueva factura"
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr "Nuevas facturas"
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr "Facturas anteriores"
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr "¿Cuando?"
|
msgstr "¿Cuando?"
|
||||||
|
|
||||||
|
@ -449,9 +687,6 @@ msgstr "Todo el mundo menos %(excluded)s"
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr "Cada"
|
msgstr "Cada"
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr "ver"
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr "Sin facturas"
|
msgstr "Sin facturas"
|
||||||
|
|
||||||
|
@ -478,7 +713,7 @@ msgstr ""
|
||||||
"correos electrónicos."
|
"correos electrónicos."
|
||||||
|
|
||||||
msgid "Return to home page"
|
msgid "Return to home page"
|
||||||
msgstr "Regresar a la página principal"
|
msgstr "Regresar al inicio"
|
||||||
|
|
||||||
msgid "Your projects"
|
msgid "Your projects"
|
||||||
msgstr "Sus proyectos"
|
msgstr "Sus proyectos"
|
||||||
|
@ -530,15 +765,17 @@ msgstr "¿Quién paga?"
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr "¿A quién?"
|
msgstr "¿A quién?"
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr "¿Quién?"
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr "Pagado"
|
msgstr "Pagado"
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr "Gastado"
|
msgstr "Gastado"
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
msgstr "Balance"
|
msgstr "Gastos por mes"
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
|
msgstr "Período"
|
||||||
|
|
||||||
|
#~ msgid "%(member)s had been added"
|
||||||
|
#~ msgstr "se han añadido %(member)s"
|
||||||
|
|
Binary file not shown.
|
@ -7,9 +7,9 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2019-10-01 21:48+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2019-10-07 22:56+0000\n"
|
"PO-Revision-Date: 2020-04-25 11:14+0000\n"
|
||||||
"Last-Translator: Alexis Metaireau <alexis@notmyidea.org>\n"
|
"Last-Translator: Rémy Hubscher <hubscher.remy@gmail.com>\n"
|
||||||
"Language-Team: French <https://hosted.weblate.org/projects/i-hate-money/"
|
"Language-Team: French <https://hosted.weblate.org/projects/i-hate-money/"
|
||||||
"i-hate-money/fr/>\n"
|
"i-hate-money/fr/>\n"
|
||||||
"Language: fr\n"
|
"Language: fr\n"
|
||||||
|
@ -17,15 +17,15 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
"X-Generator: Weblate 3.9-dev\n"
|
"X-Generator: Weblate 4.0.2-dev\n"
|
||||||
"Generated-By: Babel 2.7.0\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
"accepted."
|
"accepted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ceci n'est pas pas un montant ou une expression valide. Seuls les nombres"
|
"Ceci n'est pas un montant ou une expression valide. Seuls les nombres et "
|
||||||
" et les opérateurs + - * / sont acceptés."
|
"les opérateurs + - * / sont acceptés."
|
||||||
|
|
||||||
msgid "Project name"
|
msgid "Project name"
|
||||||
msgstr "Nom de projet"
|
msgstr "Nom de projet"
|
||||||
|
@ -36,6 +36,18 @@ msgstr "Code d’accès"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Email"
|
msgstr "Email"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr "Activer l'historique de projet"
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr "Collecter les adresses IP dans l'historique de projet"
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr "Importer un fichier JSON précédemment exporté"
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importer"
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "Identifiant du projet"
|
msgstr "Identifiant du projet"
|
||||||
|
|
||||||
|
@ -132,6 +144,15 @@ msgstr "Envoyer les invitations"
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr "L’email %(email)s est invalide"
|
msgstr "L’email %(email)s est invalide"
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr "Participant"
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr "Facture"
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr "Projet"
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr "Trop d'échecs d’authentification successifs, veuillez réessayer plus tard."
|
msgstr "Trop d'échecs d’authentification successifs, veuillez réessayer plus tard."
|
||||||
|
|
||||||
|
@ -167,6 +188,12 @@ msgstr "Project inconnu"
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr "Le mot de passe a été changé avec succès."
|
msgstr "Le mot de passe a été changé avec succès."
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr "Le projet a été correctement importé"
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr "Le fichier JSON est invalide"
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr "Projet supprimé"
|
msgstr "Projet supprimé"
|
||||||
|
|
||||||
|
@ -178,8 +205,8 @@ msgid "Your invitations have been sent"
|
||||||
msgstr "Vos invitations ont bien été envoyées"
|
msgstr "Vos invitations ont bien été envoyées"
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr "%(member)s a bien été ajouté"
|
msgstr "%(member)s a été ajouté"
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s is part of this project again"
|
msgid "%(name)s is part of this project again"
|
||||||
|
@ -234,9 +261,6 @@ msgstr " ?"
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr "Créer un nouveau projet"
|
msgstr "Créer un nouveau projet"
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr "Projets"
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr "Nombre de membres"
|
msgstr "Nombre de membres"
|
||||||
|
|
||||||
|
@ -258,6 +282,9 @@ msgstr "éditer"
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr "supprimer"
|
msgstr "supprimer"
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr "voir"
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr "Le tableau de bord est actuellement désactivée."
|
msgstr "Le tableau de bord est actuellement désactivée."
|
||||||
|
|
||||||
|
@ -267,6 +294,12 @@ msgstr "c’est sûr ?"
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr "Éditer le projet"
|
msgstr "Éditer le projet"
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr "Import JSON"
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr "Choisir un fichier"
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr "Télécharger les données du projet"
|
msgstr "Télécharger les données du projet"
|
||||||
|
|
||||||
|
@ -288,6 +321,9 @@ msgstr "Vous ne vous souvenez plus du code d’accès ?"
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annuler"
|
msgstr "Annuler"
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr "Vie privée"
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr "Éditer le projet"
|
msgstr "Éditer le projet"
|
||||||
|
|
||||||
|
@ -318,6 +354,202 @@ msgstr "Envoyer les invitations"
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr "Télécharger"
|
msgstr "Télécharger"
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr "Désactiver l'historique du projet"
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr "Désactiver l'historique du projet et l'enregistrement des adresses IP"
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr "Activer l'historique du projet"
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr "Désactiver l'enregistrement des adresses IP"
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr "Activer l'historique du projet et l’enregistrement des adresses IP"
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr "Activer l'enregistrement des adresses IP"
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr "Paramètres d'historique modifiés"
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr "modifié"
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr "du"
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr "au"
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr "Confirmer la suppression des adresses IP"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
"Êtes-vous sur de vouloir supprimer toutes les adresses IP enregistrées pour "
|
||||||
|
"ce projet ?\n"
|
||||||
|
"Le reste de l'historique ne sera pas affecté. Cette action n'est pas "
|
||||||
|
"réversible."
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Fermer"
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr "Confirmer la suppression"
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr "Confirmation de suppression"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
"Êtes-vous sur de vouloir supprimer tout l'historique du projet ? Cette "
|
||||||
|
"action n'est pas réversible."
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr "Ajouté"
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr "Supprimé"
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr "et"
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr "Liste des débiteurs"
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr "Qui ?"
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr "Solde"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" <i>L'historique de ce projet a été désactivé. Les nouvelles "
|
||||||
|
"actions n'apparaîtront pas ci-dessous. Vous pouvez réactiver l'historique"
|
||||||
|
" du projet dans les </i>\n"
|
||||||
|
" <a href=\"%(url)s\">paramètres du projet</a>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" <i>Le tableau ci-dessous liste les actions enregistrées avant"
|
||||||
|
" la désactivation de l'historique du projet. Vous pouvez\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> cliquer ici pour"
|
||||||
|
" les supprimer.</i></p>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
"Certaines entrées de l'historique contiennent une adresse IP, bien que ce"
|
||||||
|
" projet ait désactivé l'enregistrement des adresses IP. "
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr "Supprimer toutes les adresses IP enregistrées"
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr "Aucun historique à supprimer"
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr "Supprimer les entrées de l'historique du projet"
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr "Aucune adresse IP à supprimer"
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr "Supprimer les adresses IP enregistrées"
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr "Heure"
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr "Évènement"
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
"L'enregistrement des adresses IP peut-être activé dans les paramètres de "
|
||||||
|
"la page"
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
"L'enregistrement des adresses IP peut-être désactivé dans les paramètres "
|
||||||
|
"de la page"
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr "Depuis l'IP"
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr "ajouté"
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr "Le mot de passe du projet a été modifié"
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr "Le projet a été renommé"
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr "L'adresse email de contact du projet a été modifié en"
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr "Les paramètres du projet ont été modifiés"
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr "désactivé"
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr "réactivé"
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr "renommé en"
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr "Le lien d'accès a été modifié en"
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr "Montant"
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr "modifié"
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr "supprimé"
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr "modifié d'une manière inconnue"
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr "Rien à afficher"
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr "Quelqu'un a probablement vidé l'historique du projet."
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr "Gérez vos dépenses <br />partagées, facilement"
|
msgstr "Gérez vos dépenses <br />partagées, facilement"
|
||||||
|
|
||||||
|
@ -367,6 +599,9 @@ msgstr "Remboursements"
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Statistiques"
|
msgstr "Statistiques"
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr "Historique"
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Options"
|
msgstr "Options"
|
||||||
|
|
||||||
|
@ -424,6 +659,12 @@ msgstr "Vous devriez commencer par ajouter des participants"
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr "Nouvelle facture"
|
msgstr "Nouvelle facture"
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr "Nouvelles factures"
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr "Ancienne factures"
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr "Quand ?"
|
msgstr "Quand ?"
|
||||||
|
|
||||||
|
@ -450,9 +691,6 @@ msgstr "Tout le monde sauf %(excluded)s"
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr "chacun"
|
msgstr "chacun"
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr "voir"
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr "Pas encore de factures"
|
msgstr "Pas encore de factures"
|
||||||
|
|
||||||
|
@ -527,27 +765,17 @@ msgstr "Qui doit payer ?"
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr "Pour qui ?"
|
msgstr "Pour qui ?"
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr "Qui ?"
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr "A payé"
|
msgstr "A payé"
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr "A dépensé"
|
msgstr "A dépensé"
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
msgstr "Solde"
|
msgstr "Dépenses par mois"
|
||||||
|
|
||||||
msgid "Import"
|
|
||||||
msgstr "Importer"
|
|
||||||
|
|
||||||
msgid "Project successfully uploaded"
|
|
||||||
msgstr "Le projet a été correctement importé"
|
|
||||||
|
|
||||||
msgid "Invalid JSON"
|
|
||||||
msgstr "Le fichier JSON est invalide"
|
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
|
msgstr "Période"
|
||||||
|
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "The project identifier is used to "
|
#~ "The project identifier is used to "
|
||||||
|
@ -695,3 +923,72 @@ msgstr "Le fichier JSON est invalide"
|
||||||
|
|
||||||
#~ msgid "A link to reset your password has been sent to your email."
|
#~ msgid "A link to reset your password has been sent to your email."
|
||||||
#~ msgstr "Un lien pour changer votre mot de passe vous a été envoyé par mail."
|
#~ msgstr "Un lien pour changer votre mot de passe vous a été envoyé par mail."
|
||||||
|
|
||||||
|
#~ msgid "%(member)s had been added"
|
||||||
|
#~ msgstr "%(member)s a bien été ajouté"
|
||||||
|
|
||||||
|
#~ msgid "Disabled Project History"
|
||||||
|
#~ msgstr "Historisation du projet désactivée"
|
||||||
|
|
||||||
|
#~ msgid "Disabled Project History & IP Address Recording"
|
||||||
|
#~ msgstr "Historisation du projet et enregistrement des adresses IP désactivés"
|
||||||
|
|
||||||
|
#~ msgid "Enabled Project History"
|
||||||
|
#~ msgstr "Historisation du projet activée"
|
||||||
|
|
||||||
|
#~ msgid "Disabled IP Address Recording"
|
||||||
|
#~ msgstr "Enregistrement des adresses IP désactivé"
|
||||||
|
|
||||||
|
#~ msgid "Enabled Project History & IP Address Recording"
|
||||||
|
#~ msgstr "Historisation du projet et enregistrement des adresses IP activés"
|
||||||
|
|
||||||
|
#~ msgid "Enabled IP Address Recording"
|
||||||
|
#~ msgstr "Enregistrement des adresses IP activé"
|
||||||
|
|
||||||
|
#~ msgid "History Settings Changed"
|
||||||
|
#~ msgstr "Changement des paramètres d’historisation"
|
||||||
|
|
||||||
|
#~ msgid "changed"
|
||||||
|
#~ msgstr "modifié"
|
||||||
|
|
||||||
|
#~ msgid "from"
|
||||||
|
#~ msgstr "depuis"
|
||||||
|
|
||||||
|
#~ msgid "to"
|
||||||
|
#~ msgstr "vers"
|
||||||
|
|
||||||
|
#~ msgid "Confirm Remove IP Adresses"
|
||||||
|
#~ msgstr "Confirmer la suppression des adresses IP"
|
||||||
|
|
||||||
|
#~ msgid ""
|
||||||
|
#~ "Are you sure you want to delete"
|
||||||
|
#~ " all recorded IP addresses from this"
|
||||||
|
#~ " project?\n"
|
||||||
|
#~ " The rest of the project"
|
||||||
|
#~ " history will be unaffected. This "
|
||||||
|
#~ "action cannot be undone."
|
||||||
|
#~ msgstr ""
|
||||||
|
#~ "Êtes vous sûr de supprimer toutes "
|
||||||
|
#~ "les adresses IP enregistrées dans ce "
|
||||||
|
#~ "projet ?\n"
|
||||||
|
#~ "Le reste de l’historique du projet "
|
||||||
|
#~ "restera inchangé. Cette action est "
|
||||||
|
#~ "irréversible."
|
||||||
|
|
||||||
|
#~ msgid "Close"
|
||||||
|
#~ msgstr "Fermer"
|
||||||
|
|
||||||
|
#~ msgid "Confirm Delete"
|
||||||
|
#~ msgstr "Confirmer la suppression"
|
||||||
|
|
||||||
|
#~ msgid "Delete Confirmation"
|
||||||
|
#~ msgstr "Confirmation de suppression"
|
||||||
|
|
||||||
|
#~ msgid ""
|
||||||
|
#~ "Are you sure you want to erase "
|
||||||
|
#~ "all history for this project? This "
|
||||||
|
#~ "action cannot be undone."
|
||||||
|
#~ msgstr ""
|
||||||
|
#~ "Êtes vous sûr de supprimer la "
|
||||||
|
#~ "totalité de l’historique de ce projet"
|
||||||
|
#~ " ? Cette action est irréversible."
|
||||||
|
|
BIN
ihatemoney/translations/id/LC_MESSAGES/messages.mo
Normal file
BIN
ihatemoney/translations/id/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
|
@ -1,24 +1,26 @@
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-11-15 09:12+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2019-11-16 10:04+0000\n"
|
"PO-Revision-Date: 2019-11-16 10:04+0000\n"
|
||||||
"Last-Translator: Muhammad Fauzi <fauzi.padlaw@gmail.com>\n"
|
"Last-Translator: Muhammad Fauzi <fauzi.padlaw@gmail.com>\n"
|
||||||
"Language-Team: Indonesian <https://hosted.weblate.org/projects/i-hate-money/"
|
|
||||||
"i-hate-money/id/>\n"
|
|
||||||
"Language: id\n"
|
"Language: id\n"
|
||||||
|
"Language-Team: Indonesian <https://hosted.weblate.org/projects/i-hate-"
|
||||||
|
"money/i-hate-money/id/>\n"
|
||||||
|
"Plural-Forms: nplurals=1; plural=0\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
"X-Generator: Weblate 3.10-dev\n"
|
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
"accepted."
|
"accepted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Jumlah atau operator tidak valid. Hanya angka dan opertaor +-* yang diterima."
|
"Jumlah atau operator tidak valid. Hanya angka dan opertaor +-* yang "
|
||||||
|
"diterima."
|
||||||
|
|
||||||
msgid "Project name"
|
msgid "Project name"
|
||||||
msgstr "Nama proyek"
|
msgstr "Nama proyek"
|
||||||
|
@ -29,6 +31,18 @@ msgstr "Kode pribadi"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Surel"
|
msgstr "Surel"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "Pengidentifikasi proyek"
|
msgstr "Pengidentifikasi proyek"
|
||||||
|
|
||||||
|
@ -40,8 +54,8 @@ msgid ""
|
||||||
"A project with this identifier (\"%(project)s\") already exists. Please "
|
"A project with this identifier (\"%(project)s\") already exists. Please "
|
||||||
"choose a new identifier"
|
"choose a new identifier"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Sebuah proyek dengan ID ini (\"%(project)s\") sudah ada. Silakan pilih ID "
|
"Sebuah proyek dengan ID ini (\"%(project)s\") sudah ada. Silakan pilih ID"
|
||||||
"baru"
|
" baru"
|
||||||
|
|
||||||
msgid "Get in"
|
msgid "Get in"
|
||||||
msgstr "Masuk"
|
msgstr "Masuk"
|
||||||
|
@ -125,6 +139,15 @@ msgstr "Kirim undangan"
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr "Surel %(email)s tidak valid"
|
msgstr "Surel %(email)s tidak valid"
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr "Proyek"
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr "Terlalu banyak percobaan masuk, silakan coba lagi nanti."
|
msgstr "Terlalu banyak percobaan masuk, silakan coba lagi nanti."
|
||||||
|
|
||||||
|
@ -158,6 +181,12 @@ msgstr "Proyek tidak diketahui"
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr "Kata sandi berhasil diatur ulang."
|
msgstr "Kata sandi berhasil diatur ulang."
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr "Proyek berhasil dihapus"
|
msgstr "Proyek berhasil dihapus"
|
||||||
|
|
||||||
|
@ -169,8 +198,8 @@ msgid "Your invitations have been sent"
|
||||||
msgstr "Undangan Anda telah dikirim"
|
msgstr "Undangan Anda telah dikirim"
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr "%(member)s telah ditambahkan"
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s is part of this project again"
|
msgid "%(name)s is part of this project again"
|
||||||
|
@ -225,9 +254,6 @@ msgstr "?"
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr "Buat proyek baru"
|
msgstr "Buat proyek baru"
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr "Proyek"
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr "Jumlah anggota"
|
msgstr "Jumlah anggota"
|
||||||
|
|
||||||
|
@ -249,6 +275,9 @@ msgstr "ubah"
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr "hapus"
|
msgstr "hapus"
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr "lihat"
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr "Dasbor sekarang ini sedang dinonaktifkan."
|
msgstr "Dasbor sekarang ini sedang dinonaktifkan."
|
||||||
|
|
||||||
|
@ -258,6 +287,12 @@ msgstr "Anda yakin?"
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr "Ubah proyek"
|
msgstr "Ubah proyek"
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr "Unduh data proyek"
|
msgstr "Unduh data proyek"
|
||||||
|
|
||||||
|
@ -279,6 +314,9 @@ msgstr "Tidak bisa mengingat kata sandi?"
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Batalkan"
|
msgstr "Batalkan"
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr "Ubah proyek"
|
msgstr "Ubah proyek"
|
||||||
|
|
||||||
|
@ -309,6 +347,177 @@ msgstr "Kirim undangan"
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr "Unduh"
|
msgstr "Unduh"
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr "Siapa?"
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr "Saldo"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr "Atur pembagian harga <br />Anda, dengan mudah"
|
msgstr "Atur pembagian harga <br />Anda, dengan mudah"
|
||||||
|
|
||||||
|
@ -343,8 +552,8 @@ msgid ""
|
||||||
"This access code will be sent to your friends. It is stored as-is by the "
|
"This access code will be sent to your friends. It is stored as-is by the "
|
||||||
"server, so don\\'t reuse a personal password!"
|
"server, so don\\'t reuse a personal password!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Kode akses ini akan dikirimkan ke teman Anda. Kode ini disimpan dalam bentuk "
|
"Kode akses ini akan dikirimkan ke teman Anda. Kode ini disimpan dalam "
|
||||||
"teks biasa dalam server, jadi jangan gunakan password Anda!"
|
"bentuk teks biasa dalam server, jadi jangan gunakan password Anda!"
|
||||||
|
|
||||||
msgid "Account manager"
|
msgid "Account manager"
|
||||||
msgstr "Pengatur akun"
|
msgstr "Pengatur akun"
|
||||||
|
@ -358,6 +567,9 @@ msgstr "Atur"
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Statistik"
|
msgstr "Statistik"
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Pengaturan"
|
msgstr "Pengaturan"
|
||||||
|
|
||||||
|
@ -415,6 +627,12 @@ msgstr "Anda harus mulai dengan menambahkan partisipan"
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr "Tambah tagihan baru"
|
msgstr "Tambah tagihan baru"
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr "Kapan?"
|
msgstr "Kapan?"
|
||||||
|
|
||||||
|
@ -441,9 +659,6 @@ msgstr "Semua orang kecuali %(excluded)s"
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr "setiap"
|
msgstr "setiap"
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr "lihat"
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr "Tidak ada tagihan"
|
msgstr "Tidak ada tagihan"
|
||||||
|
|
||||||
|
@ -466,8 +681,8 @@ msgid ""
|
||||||
"A link to reset your password has been sent to you, please check your "
|
"A link to reset your password has been sent to you, please check your "
|
||||||
"emails."
|
"emails."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Tautan atur ulang kata sandi telah dikirim kepada Anda, silakan cek email "
|
"Tautan atur ulang kata sandi telah dikirim kepada Anda, silakan cek email"
|
||||||
"Anda."
|
" Anda."
|
||||||
|
|
||||||
msgid "Return to home page"
|
msgid "Return to home page"
|
||||||
msgstr "Kembali ke halaman depan"
|
msgstr "Kembali ke halaman depan"
|
||||||
|
@ -499,7 +714,8 @@ msgstr "Bagikan tautan"
|
||||||
|
|
||||||
msgid "You can directly share the following link via your prefered medium"
|
msgid "You can directly share the following link via your prefered medium"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Anda bisa membagikan tautan secara langsung melalui media yang Anda inginkan"
|
"Anda bisa membagikan tautan secara langsung melalui media yang Anda "
|
||||||
|
"inginkan"
|
||||||
|
|
||||||
msgid "Send via Emails"
|
msgid "Send via Emails"
|
||||||
msgstr "Kirim melalui surel"
|
msgstr "Kirim melalui surel"
|
||||||
|
@ -510,10 +726,10 @@ msgid ""
|
||||||
" creation of this budget management project and we will "
|
" creation of this budget management project and we will "
|
||||||
"send them an email for you."
|
"send them an email for you."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Spesifikkan daftar alamat surel (dipisah dengan koma) yang akan Anda kirim "
|
"Spesifikkan daftar alamat surel (dipisah dengan koma) yang akan Anda "
|
||||||
"pemberitahuan tentang\n"
|
"kirim pemberitahuan tentang\n"
|
||||||
" pembuatan dari manajemen anggaran proyek ini dan kami akan "
|
" pembuatan dari manajemen anggaran proyek ini dan kami "
|
||||||
"memngirim mereka sebuah surel."
|
"akan memngirim mereka sebuah surel."
|
||||||
|
|
||||||
msgid "Who pays?"
|
msgid "Who pays?"
|
||||||
msgstr "Siapa membayar?"
|
msgstr "Siapa membayar?"
|
||||||
|
@ -521,14 +737,24 @@ msgstr "Siapa membayar?"
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr "Kepada siapa?"
|
msgstr "Kepada siapa?"
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr "Siapa?"
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr "Dibayar"
|
msgstr "Dibayar"
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr "Dihabiskan"
|
msgstr "Dihabiskan"
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
msgstr "Saldo"
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "%(member)s had been added"
|
||||||
|
#~ msgstr "%(member)s telah ditambahkan"
|
||||||
|
|
||||||
|
#~ msgid "Someone probably"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "cleared the project history."
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
|
|
729
ihatemoney/translations/it/LC_MESSAGES/messages.po
Normal file
729
ihatemoney/translations/it/LC_MESSAGES/messages.po
Normal file
|
@ -0,0 +1,729 @@
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2020-04-28 10:30+0200\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: Automatically generated\n"
|
||||||
|
"Language-Team: none\n"
|
||||||
|
"Language: it\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Generator: Translate Toolkit 2.5.1\n"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
"accepted."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Private code"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project identifier"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Create the project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"A project with this identifier (\"%(project)s\") already exists. Please "
|
||||||
|
"choose a new identifier"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Get in"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Admin password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Send me the code by email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "This project does not exists"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Password mismatch"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Password confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reset password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "What?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Payer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount paid"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "A link to an external document, related to this bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "For whom?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Submit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Submit and add a new one"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bills can't be null"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Weights should be positive"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Weight"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Add"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "User name incorrect"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "This project already have this member"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "People to notify"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Send invites"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "The email %(email)s is not valid"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Too many failed login attempts, please retry later."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "This admin password is not the right one. Only %(num)d attempts left."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "You either provided a bad token or no project identifier."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "This private code is not the right one"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "You have just created '%(project)s' to share your expenses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "%(msg_compl)sThe project identifier is %(project)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No token provided"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid token"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Unknown project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Password successfully reset."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project successfully deleted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "You have been invited to share your expenses for %(project)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Your invitations have been sent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "%(member)s has been added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "%(name)s is part of this project again"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"User '%(name)s' has been deactivated. It will still appear in the users "
|
||||||
|
"list until its balance becomes zero."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "User '%(name)s' has been removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "User '%(name)s' has been edited"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The bill has been added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The bill has been deleted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The bill has been modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Sorry, we were unable to find the page you've asked for."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The best thing to do is probably to get back to the main page."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Back to the list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Administration tasks are currently disabled."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The project you are trying to access do not exist, do you want to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "create it"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Create a new project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Number of members"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Number of bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Newest bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Oldest bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Actions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "edit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "The Dashboard is currently deactivated."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "you sure?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Download project's data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill items"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Download the list of bills with owner, amount, reason,... "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Settle plans"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Download the list of transactions needed to settle the current bills."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Can't remember the password?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit the project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit this bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Add a bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select all"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select none"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Add participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit this member"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "john.doe@example.com, mary.moe@site.com"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Send the invitations"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Download"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Try out the demo"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "You're sharing a house?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Going on holidays with friends?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Simply sharing money with others?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "We can help!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Log in to an existing project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Log in"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "can't remember your password?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Create"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"This access code will be sent to your friends. It is stored as-is by the "
|
||||||
|
"server, so don\\'t reuse a personal password!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Account manager"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Settle"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Statistics"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Languages"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Projects"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Start a new project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Other projects :"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "switch to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Dashboard"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Logout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Code"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Mobile Application"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Documentation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Administation Dashboard"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "\"I hate money\" is a free software"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "you can contribute and improve it!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invite people"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "You should start by adding participants"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Add a new bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "When?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who paid?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "For what?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "How much?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "Added on %(date)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Everyone"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "Everyone but %(excluded)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "each"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list yet."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "You probably want to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "add a bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "add participants"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Password reminder"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"A link to reset your password has been sent to you, please check your "
|
||||||
|
"emails."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Return to home page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Your projects"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reset your password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invite people to join this project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Share Identifier & code"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"You can share the project identifier and the private code by any "
|
||||||
|
"communication means."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Identifier:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Share the Link"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "You can directly share the following link via your prefered medium"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Send via Emails"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Specify a (comma separated) list of email adresses you want to notify "
|
||||||
|
"about the\n"
|
||||||
|
" creation of this budget management project and we will "
|
||||||
|
"send them an email for you."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who pays?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "To whom?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Paid"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Spent"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Expenses by Month"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
|
msgstr ""
|
Binary file not shown.
|
@ -1,19 +1,19 @@
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-09-30 23:53+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2019-11-12 09:04+0000\n"
|
"PO-Revision-Date: 2019-11-12 09:04+0000\n"
|
||||||
"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
|
"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
|
||||||
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/"
|
|
||||||
"i-hate-money/i-hate-money/nb_NO/>\n"
|
|
||||||
"Language: nb_NO\n"
|
"Language: nb_NO\n"
|
||||||
|
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/i"
|
||||||
|
"-hate-money/i-hate-money/nb_NO/>\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=n != 1\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
"X-Generator: Weblate 3.10-dev\n"
|
|
||||||
"Generated-By: Babel 2.7.0\n"
|
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
@ -31,6 +31,18 @@ msgstr "Privat kode"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "E-post"
|
msgstr "E-post"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "Prosjektidentifikator"
|
msgstr "Prosjektidentifikator"
|
||||||
|
|
||||||
|
@ -129,6 +141,15 @@ msgstr "Send invitasjoner"
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr "E-posten \"%(email)s\" er ikke gyldig"
|
msgstr "E-posten \"%(email)s\" er ikke gyldig"
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr "Prosjekt"
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr "For mange mislykkede innloggingsforsøk, prøv igjen senere."
|
msgstr "For mange mislykkede innloggingsforsøk, prøv igjen senere."
|
||||||
|
|
||||||
|
@ -165,6 +186,12 @@ msgstr "Ukjent prosjekt"
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr "Passord tilbakestilt."
|
msgstr "Passord tilbakestilt."
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr "Prosjekt slettet"
|
msgstr "Prosjekt slettet"
|
||||||
|
@ -179,8 +206,8 @@ msgid "Your invitations have been sent"
|
||||||
msgstr "Invitasjonene dine har blitt sendt"
|
msgstr "Invitasjonene dine har blitt sendt"
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr "%(member)s lagt til"
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s is part of this project again"
|
msgid "%(name)s is part of this project again"
|
||||||
|
@ -237,9 +264,6 @@ msgstr "?"
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr "Opprett et nytt prosjekt"
|
msgstr "Opprett et nytt prosjekt"
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr "Prosjekt"
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr "Antall medlemmer"
|
msgstr "Antall medlemmer"
|
||||||
|
|
||||||
|
@ -261,6 +285,10 @@ msgstr "rediger"
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr "slett"
|
msgstr "slett"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
msgid "see"
|
||||||
|
msgstr "se"
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr "Oversikten er for tiden avskrudd."
|
msgstr "Oversikten er for tiden avskrudd."
|
||||||
|
|
||||||
|
@ -270,6 +298,12 @@ msgstr "er du sikker?"
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr "Rediger prosjekt"
|
msgstr "Rediger prosjekt"
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr "Last ned prosjektets data"
|
msgstr "Last ned prosjektets data"
|
||||||
|
|
||||||
|
@ -294,6 +328,9 @@ msgstr "Husker du ikke passordet?"
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Avbryt"
|
msgstr "Avbryt"
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr "Rediger prosjektet"
|
msgstr "Rediger prosjektet"
|
||||||
|
|
||||||
|
@ -325,6 +362,178 @@ msgstr "Send ut invitasjonene"
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr "Last nd"
|
msgstr "Last nd"
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr "Hvem?"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr "Kontobalanse"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr "Håndter delte <br />utgifter, enkelt"
|
msgstr "Håndter delte <br />utgifter, enkelt"
|
||||||
|
|
||||||
|
@ -376,6 +585,9 @@ msgstr "Gjør opp"
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Statistikk"
|
msgstr "Statistikk"
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Innstillinger"
|
msgstr "Innstillinger"
|
||||||
|
|
||||||
|
@ -436,6 +648,12 @@ msgstr "Du kan starte ved å legge til deltagere"
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr "Legg til en ny regning"
|
msgstr "Legg til en ny regning"
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr "Når?"
|
msgstr "Når?"
|
||||||
|
|
||||||
|
@ -462,10 +680,6 @@ msgstr "Alle, unntagen %(excluded)s"
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr "hver"
|
msgstr "hver"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "see"
|
|
||||||
msgstr "se"
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr "Ingen regninger"
|
msgstr "Ingen regninger"
|
||||||
|
|
||||||
|
@ -546,18 +760,17 @@ msgstr "Hvem betaler?"
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr "Til hvem?"
|
msgstr "Til hvem?"
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr "Hvem?"
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr "Betalt"
|
msgstr "Betalt"
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr "Forbrukt"
|
msgstr "Forbrukt"
|
||||||
|
|
||||||
#, fuzzy
|
msgid "Expenses by Month"
|
||||||
msgid "Balance"
|
msgstr ""
|
||||||
msgstr "Kontobalanse"
|
|
||||||
|
msgid "Period"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "The project identifier is used to "
|
#~ "The project identifier is used to "
|
||||||
|
@ -672,3 +885,6 @@ msgstr "Kontobalanse"
|
||||||
#~ "En lenke for å tilbakestille passordet"
|
#~ "En lenke for å tilbakestille passordet"
|
||||||
#~ " har blitt sent til deg per "
|
#~ " har blitt sent til deg per "
|
||||||
#~ "e-post."
|
#~ "e-post."
|
||||||
|
|
||||||
|
#~ msgid "%(member)s had been added"
|
||||||
|
#~ msgstr "%(member)s lagt til"
|
||||||
|
|
Binary file not shown.
|
@ -1,19 +1,19 @@
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2019-09-30 23:53+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2019-10-07 22:56+0000\n"
|
"PO-Revision-Date: 2019-10-07 22:56+0000\n"
|
||||||
"Last-Translator: Heimen Stoffels <vistausss@outlook.com>\n"
|
"Last-Translator: Heimen Stoffels <vistausss@outlook.com>\n"
|
||||||
"Language-Team: Dutch <https://hosted.weblate.org/projects/i-hate-money/"
|
|
||||||
"i-hate-money/nl/>\n"
|
|
||||||
"Language: nl\n"
|
"Language: nl\n"
|
||||||
|
"Language-Team: Dutch <https://hosted.weblate.org/projects/i-hate-money/i"
|
||||||
|
"-hate-money/nl/>\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=n != 1\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
"X-Generator: Weblate 3.9-dev\n"
|
|
||||||
"Generated-By: Babel 2.7.0\n"
|
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
@ -29,6 +29,18 @@ msgstr "Privécode"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "E-mailadres"
|
msgstr "E-mailadres"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "Project-id"
|
msgstr "Project-id"
|
||||||
|
|
||||||
|
@ -123,6 +135,15 @@ msgstr "Uitnodigingen versturen"
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr "Het e-mailadres '%(email)s' is onjuist"
|
msgstr "Het e-mailadres '%(email)s' is onjuist"
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr "Project"
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr "Te vaak onjuist ingelogd. Probeer het later opnieuw."
|
msgstr "Te vaak onjuist ingelogd. Probeer het later opnieuw."
|
||||||
|
|
||||||
|
@ -158,6 +179,12 @@ msgstr "Onbekend project"
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr "Wachtwoord is hersteld."
|
msgstr "Wachtwoord is hersteld."
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr "Project is verwijderd"
|
msgstr "Project is verwijderd"
|
||||||
|
|
||||||
|
@ -169,8 +196,8 @@ msgid "Your invitations have been sent"
|
||||||
msgstr "Je uitnodigingen zijn verstuurd"
|
msgstr "Je uitnodigingen zijn verstuurd"
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr "%(member)s is toegevoegd"
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s is part of this project again"
|
msgid "%(name)s is part of this project again"
|
||||||
|
@ -225,9 +252,6 @@ msgstr "?"
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr "Nieuw project aanmaken"
|
msgstr "Nieuw project aanmaken"
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr "Project"
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr "Aantal deelnemers"
|
msgstr "Aantal deelnemers"
|
||||||
|
|
||||||
|
@ -249,6 +273,9 @@ msgstr "bewerken"
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr "verwijderen"
|
msgstr "verwijderen"
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr "bekijk"
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr "De overzichtspagina is momenteel uitgeschakeld."
|
msgstr "De overzichtspagina is momenteel uitgeschakeld."
|
||||||
|
|
||||||
|
@ -258,6 +285,12 @@ msgstr "weet je het zeker?"
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr "Project aanpassen"
|
msgstr "Project aanpassen"
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr "Projectgegevens downloaden"
|
msgstr "Projectgegevens downloaden"
|
||||||
|
|
||||||
|
@ -281,6 +314,9 @@ msgstr "Ben je je wachtwoord vergeten?"
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annuleren"
|
msgstr "Annuleren"
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr "Project bewerken"
|
msgstr "Project bewerken"
|
||||||
|
|
||||||
|
@ -311,6 +347,177 @@ msgstr "Uitnodigingen versturen"
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr "Downloaden"
|
msgstr "Downloaden"
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr "Wie?"
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr "Saldo"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr "Beheer eenvoudig je <br />gedeelde uitgaven"
|
msgstr "Beheer eenvoudig je <br />gedeelde uitgaven"
|
||||||
|
|
||||||
|
@ -360,6 +567,9 @@ msgstr "Schikken"
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Statistieken"
|
msgstr "Statistieken"
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Instellingen"
|
msgstr "Instellingen"
|
||||||
|
|
||||||
|
@ -417,6 +627,12 @@ msgstr "Begin met het toevoegen van deelnemers"
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr "Nieuwe rekening toevoegen"
|
msgstr "Nieuwe rekening toevoegen"
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr "Wanneer?"
|
msgstr "Wanneer?"
|
||||||
|
|
||||||
|
@ -443,9 +659,6 @@ msgstr "Iedereen, behalve %(excluded)s"
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr "per persoon"
|
msgstr "per persoon"
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr "bekijk"
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr "Geen rekeningen"
|
msgstr "Geen rekeningen"
|
||||||
|
|
||||||
|
@ -522,128 +735,14 @@ msgstr "Wie betaalt?"
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr "Aan wie?"
|
msgstr "Aan wie?"
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr "Wie?"
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr "Betaald"
|
msgstr "Betaald"
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr "Uitgegeven"
|
msgstr "Uitgegeven"
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
msgstr "Saldo"
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid ""
|
msgid "Period"
|
||||||
#~ "The project identifier is used to "
|
msgstr ""
|
||||||
#~ "log in and for the URL of "
|
|
||||||
#~ "the project. We tried to generate "
|
|
||||||
#~ "an identifier for you but a "
|
|
||||||
#~ "project with this identifier already "
|
|
||||||
#~ "exists. Please create a new identifier"
|
|
||||||
#~ " that you will be able to "
|
|
||||||
#~ "remember"
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "De project-id wordt gebruikt om in"
|
|
||||||
#~ " te loggen en als url van het"
|
|
||||||
#~ " project. We hebben geprobeerd om een"
|
|
||||||
#~ " id voor je te genereren, maar "
|
|
||||||
#~ "er is al een project met deze "
|
|
||||||
#~ "id. Creëer een nieuwe id die je"
|
|
||||||
#~ " makkelijk kunt onthouden."
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "Not a valid amount or expression.Only"
|
|
||||||
#~ " numbers and + - * / "
|
|
||||||
#~ "operatorsare accepted."
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "Geen geldig bedrag of geldige expressie."
|
|
||||||
#~ " Alleen getallen en + - * / "
|
|
||||||
#~ "zijn toegestaan."
|
|
||||||
|
|
||||||
#~ msgid "What do you want to download ?"
|
|
||||||
#~ msgstr "Wat wil je downloaden?"
|
|
||||||
|
|
||||||
#~ msgid "bills"
|
|
||||||
#~ msgstr "rekeningen"
|
|
||||||
|
|
||||||
#~ msgid "transactions"
|
|
||||||
#~ msgstr "transacties"
|
|
||||||
|
|
||||||
#~ msgid "Export file format"
|
|
||||||
#~ msgstr "Bestandsformaat voor exporteren"
|
|
||||||
|
|
||||||
#~ msgid "Edit this project"
|
|
||||||
#~ msgstr "Dit project bewerken"
|
|
||||||
|
|
||||||
#~ msgid "Download this project's data"
|
|
||||||
#~ msgstr "Projectgegevens downloaden"
|
|
||||||
|
|
||||||
#~ msgid "Type user name here"
|
|
||||||
#~ msgstr "Typ hier de gebruikersnaam"
|
|
||||||
|
|
||||||
#~ msgid "No, thanks"
|
|
||||||
#~ msgstr "Nee, bedankt"
|
|
||||||
|
|
||||||
#~ msgid "Manage your shared <br>expenses, easily"
|
|
||||||
#~ msgstr "Beheer eenvoudig je gedeelde <br>uitgaven"
|
|
||||||
|
|
||||||
#~ msgid "Log to an existing project"
|
|
||||||
#~ msgstr "Log in op een bestaand project"
|
|
||||||
|
|
||||||
#~ msgid "log in"
|
|
||||||
#~ msgstr "inloggen"
|
|
||||||
|
|
||||||
#~ msgid "or create a new one"
|
|
||||||
#~ msgstr "of creëer een nieuwe"
|
|
||||||
|
|
||||||
#~ msgid "let's get started"
|
|
||||||
#~ msgstr "aan de slag"
|
|
||||||
|
|
||||||
#~ msgid "options"
|
|
||||||
#~ msgstr "opties"
|
|
||||||
|
|
||||||
#~ msgid "Project settings"
|
|
||||||
#~ msgstr "Projectinstellingen"
|
|
||||||
|
|
||||||
#~ msgid "This is a free software"
|
|
||||||
#~ msgstr "Dit is vrije software"
|
|
||||||
|
|
||||||
#~ msgid "Invite people to join this project!"
|
|
||||||
#~ msgstr "Nodig mensen uit voor dit project!"
|
|
||||||
|
|
||||||
#~ msgid "Added on"
|
|
||||||
#~ msgstr "Toegevoegd op"
|
|
||||||
|
|
||||||
#~ msgid "Nothing to list yet. You probably want to"
|
|
||||||
#~ msgstr "Er kan nog geen opsomming worden gemaakt. Voeg"
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "Specify a (comma separated) list of "
|
|
||||||
#~ "email adresses you want to notify "
|
|
||||||
#~ "about the\n"
|
|
||||||
#~ "creation of this budget management "
|
|
||||||
#~ "project and we will send them an"
|
|
||||||
#~ " email for you."
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "Geef een kommagescheiden lijst van "
|
|
||||||
#~ "e-mailadressen op. Deze mensen worden op"
|
|
||||||
#~ " de\n"
|
|
||||||
#~ "hoogte gebracht van het bestaan van "
|
|
||||||
#~ "dit project en wij sturen hen een"
|
|
||||||
#~ " e-mail."
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "If you prefer, you can share the project identifier and the shared\n"
|
|
||||||
#~ "password by other communication means. "
|
|
||||||
#~ "Or even directly share the following "
|
|
||||||
#~ "link:"
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "Als je wilt, dan kun je de project-id en het gedeelde wachtwoord\n"
|
|
||||||
#~ "delen via andere kanalen. Of deel gewoon de volgende link:"
|
|
||||||
|
|
||||||
#~ msgid "A link to reset your password has been sent to your email."
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "Er is een link met "
|
|
||||||
#~ "wachtwoordherstelinstructies naar je e-mailadres "
|
|
||||||
#~ "verstuurd."
|
|
||||||
|
|
768
ihatemoney/translations/ru/LC_MESSAGES/messages.po
Normal file
768
ihatemoney/translations/ru/LC_MESSAGES/messages.po
Normal file
|
@ -0,0 +1,768 @@
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2020-04-26 19:50+0200\n"
|
||||||
|
"PO-Revision-Date: 2020-04-28 07:11+0000\n"
|
||||||
|
"Last-Translator: Vsevolod <sevauserg.com@gmail.com>\n"
|
||||||
|
"Language-Team: Russian <https://hosted.weblate.org/projects/i-hate-money/"
|
||||||
|
"i-hate-money/ru/>\n"
|
||||||
|
"Language: ru\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<="
|
||||||
|
"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||||
|
"X-Generator: Weblate 4.0.2\n"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
"accepted."
|
||||||
|
msgstr ""
|
||||||
|
"Недопустимая сумма выражения. Принимаются только цифры и операторы + - * / ."
|
||||||
|
|
||||||
|
msgid "Project name"
|
||||||
|
msgstr "Имя проекта"
|
||||||
|
|
||||||
|
msgid "Private code"
|
||||||
|
msgstr "Приватный код"
|
||||||
|
|
||||||
|
msgid "Email"
|
||||||
|
msgstr "Email"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr "Включить историю проекта"
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr "Использовать отслеживание по IP для истории проекта"
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr "Импортировать ранее экспортированный JSON файл"
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Импортировать"
|
||||||
|
|
||||||
|
msgid "Project identifier"
|
||||||
|
msgstr "Идентификатор проекта"
|
||||||
|
|
||||||
|
msgid "Create the project"
|
||||||
|
msgstr "Создать проект"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"A project with this identifier (\"%(project)s\") already exists. Please "
|
||||||
|
"choose a new identifier"
|
||||||
|
msgstr ""
|
||||||
|
"Проект с идентификатором (\"%(project)s\") уже существует. Пожалуйста, "
|
||||||
|
"выберете новый идентификатор"
|
||||||
|
|
||||||
|
msgid "Get in"
|
||||||
|
msgstr "Войти"
|
||||||
|
|
||||||
|
msgid "Admin password"
|
||||||
|
msgstr "Пароль администратора"
|
||||||
|
|
||||||
|
msgid "Send me the code by email"
|
||||||
|
msgstr "Отправить код мне на Email"
|
||||||
|
|
||||||
|
msgid "This project does not exists"
|
||||||
|
msgstr "Такой проект не существует"
|
||||||
|
|
||||||
|
msgid "Password mismatch"
|
||||||
|
msgstr "Пароли не совпадают"
|
||||||
|
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Пароль"
|
||||||
|
|
||||||
|
msgid "Password confirmation"
|
||||||
|
msgstr "Подтвердите пароль"
|
||||||
|
|
||||||
|
msgid "Reset password"
|
||||||
|
msgstr "Восстановить пароль"
|
||||||
|
|
||||||
|
msgid "Date"
|
||||||
|
msgstr "Дата"
|
||||||
|
|
||||||
|
msgid "What?"
|
||||||
|
msgstr "Что?"
|
||||||
|
|
||||||
|
msgid "Payer"
|
||||||
|
msgstr "Плательщик"
|
||||||
|
|
||||||
|
msgid "Amount paid"
|
||||||
|
msgstr "Уплаченная сумма"
|
||||||
|
|
||||||
|
msgid "External link"
|
||||||
|
msgstr "Внешняя ссылка"
|
||||||
|
|
||||||
|
msgid "A link to an external document, related to this bill"
|
||||||
|
msgstr "Ссылка на внешний документ, относящийся к этому счёту"
|
||||||
|
|
||||||
|
msgid "For whom?"
|
||||||
|
msgstr "Кому?"
|
||||||
|
|
||||||
|
msgid "Submit"
|
||||||
|
msgstr "Отправить"
|
||||||
|
|
||||||
|
msgid "Submit and add a new one"
|
||||||
|
msgstr "Отправить и добавить новый"
|
||||||
|
|
||||||
|
msgid "Bills can't be null"
|
||||||
|
msgstr "Счета не могут быть нулевыми"
|
||||||
|
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Имя"
|
||||||
|
|
||||||
|
msgid "Weights should be positive"
|
||||||
|
msgstr "Вес должен быть положительным"
|
||||||
|
|
||||||
|
msgid "Weight"
|
||||||
|
msgstr "Вес"
|
||||||
|
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Добавить"
|
||||||
|
|
||||||
|
msgid "User name incorrect"
|
||||||
|
msgstr "Неправильное имя пользователя"
|
||||||
|
|
||||||
|
msgid "This project already have this member"
|
||||||
|
msgstr "В этом проекте уже есть такой участник"
|
||||||
|
|
||||||
|
msgid "People to notify"
|
||||||
|
msgstr "Люди для уведомления"
|
||||||
|
|
||||||
|
msgid "Send invites"
|
||||||
|
msgstr "Отправить приглашения"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "The email %(email)s is not valid"
|
||||||
|
msgstr "Email %(email)s не правильный"
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr "Участник"
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr "Счёт"
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr "Проект"
|
||||||
|
|
||||||
|
msgid "Too many failed login attempts, please retry later."
|
||||||
|
msgstr "Слишком много неудачных попыток входа, попробуйте позже."
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "This admin password is not the right one. Only %(num)d attempts left."
|
||||||
|
msgstr ""
|
||||||
|
"Этот пароль администратора неправильный. Осталось только %(num)d попыток."
|
||||||
|
|
||||||
|
msgid "You either provided a bad token or no project identifier."
|
||||||
|
msgstr ""
|
||||||
|
"Вы либо предоставили неверный токен, либо не указали идентификатор проекта."
|
||||||
|
|
||||||
|
msgid "This private code is not the right one"
|
||||||
|
msgstr "Этот приватный код не подходит"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "You have just created '%(project)s' to share your expenses"
|
||||||
|
msgstr "Вы только что создали '%(project)s' , чтобы разделить расходы"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "%(msg_compl)sThe project identifier is %(project)s"
|
||||||
|
msgstr "%(msg_compl)sИдентификатор проекта это %(project)s"
|
||||||
|
|
||||||
|
msgid "No token provided"
|
||||||
|
msgstr "Не предоставлен токен"
|
||||||
|
|
||||||
|
msgid "Invalid token"
|
||||||
|
msgstr "Неправильный токен"
|
||||||
|
|
||||||
|
msgid "Unknown project"
|
||||||
|
msgstr "Неизвестный проект"
|
||||||
|
|
||||||
|
msgid "Password successfully reset."
|
||||||
|
msgstr "Пароль успешно восстановлен."
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr "Проект успешно загружен"
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr "Неправильный JSON"
|
||||||
|
|
||||||
|
msgid "Project successfully deleted"
|
||||||
|
msgstr "Проект удалён"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "You have been invited to share your expenses for %(project)s"
|
||||||
|
msgstr "Вас пригласили разделить расходы в проект %(project)s"
|
||||||
|
|
||||||
|
msgid "Your invitations have been sent"
|
||||||
|
msgstr "Ваш код приглашения был отправлен"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "%(member)s has been added"
|
||||||
|
msgstr "%(member)s был добавлен"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "%(name)s is part of this project again"
|
||||||
|
msgstr "%(name)s снова часть этого проекта"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"User '%(name)s' has been deactivated. It will still appear in the users "
|
||||||
|
"list until its balance becomes zero."
|
||||||
|
msgstr ""
|
||||||
|
"Пользователь '%(name)s' был деактивирован. Он будет отображаться в списке "
|
||||||
|
"пользователей до тех пор, пока его баланс не станет равным нулю."
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "User '%(name)s' has been removed"
|
||||||
|
msgstr "Пользователь '%(name)s' был удалён"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "User '%(name)s' has been edited"
|
||||||
|
msgstr "Пользователь '%(name)s' был изменён"
|
||||||
|
|
||||||
|
msgid "The bill has been added"
|
||||||
|
msgstr "Счёт был добавлен"
|
||||||
|
|
||||||
|
msgid "The bill has been deleted"
|
||||||
|
msgstr "Счёт был удалён"
|
||||||
|
|
||||||
|
msgid "The bill has been modified"
|
||||||
|
msgstr "Счёт был изменён"
|
||||||
|
|
||||||
|
msgid "Sorry, we were unable to find the page you've asked for."
|
||||||
|
msgstr "К сожалению, нам не удалось найти страницу, которую вы запросили."
|
||||||
|
|
||||||
|
msgid "The best thing to do is probably to get back to the main page."
|
||||||
|
msgstr "Лучше всего вернуться на главную страницу."
|
||||||
|
|
||||||
|
msgid "Back to the list"
|
||||||
|
msgstr "Вернутся к списку"
|
||||||
|
|
||||||
|
msgid "Administration tasks are currently disabled."
|
||||||
|
msgstr "Задачи администратора в данный момент отключены."
|
||||||
|
|
||||||
|
msgid "The project you are trying to access do not exist, do you want to"
|
||||||
|
msgstr ""
|
||||||
|
"Проект, к которому вы пытаетесь получить доступ, не существует, вы хотите"
|
||||||
|
|
||||||
|
msgid "create it"
|
||||||
|
msgstr "создать его"
|
||||||
|
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
msgid "Create a new project"
|
||||||
|
msgstr "Создать новый проект"
|
||||||
|
|
||||||
|
msgid "Number of members"
|
||||||
|
msgstr "Число участников"
|
||||||
|
|
||||||
|
msgid "Number of bills"
|
||||||
|
msgstr "Число счетов"
|
||||||
|
|
||||||
|
msgid "Newest bill"
|
||||||
|
msgstr "Новейший счёт"
|
||||||
|
|
||||||
|
msgid "Oldest bill"
|
||||||
|
msgstr "Старейший счёт"
|
||||||
|
|
||||||
|
msgid "Actions"
|
||||||
|
msgstr "Действия"
|
||||||
|
|
||||||
|
msgid "edit"
|
||||||
|
msgstr "изменить"
|
||||||
|
|
||||||
|
msgid "delete"
|
||||||
|
msgstr "удалить"
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr "просмотреть"
|
||||||
|
|
||||||
|
msgid "The Dashboard is currently deactivated."
|
||||||
|
msgstr "Панель инструментов в данный момент отключена."
|
||||||
|
|
||||||
|
msgid "you sure?"
|
||||||
|
msgstr "вы уверены?"
|
||||||
|
|
||||||
|
msgid "Edit project"
|
||||||
|
msgstr "Изменить проект"
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr "Импортировать JSON"
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr "Выбрать файл"
|
||||||
|
|
||||||
|
msgid "Download project's data"
|
||||||
|
msgstr "Скачать данные проекта"
|
||||||
|
|
||||||
|
msgid "Bill items"
|
||||||
|
msgstr "Пункты счета"
|
||||||
|
|
||||||
|
msgid "Download the list of bills with owner, amount, reason,... "
|
||||||
|
msgstr "Скачать список счетов с владельцем, суммой, причиной, .. "
|
||||||
|
|
||||||
|
msgid "Settle plans"
|
||||||
|
msgstr "Урегулировать планы"
|
||||||
|
|
||||||
|
msgid "Download the list of transactions needed to settle the current bills."
|
||||||
|
msgstr "Скачать список переводов нужных, чтобы урегулировать данные счета."
|
||||||
|
|
||||||
|
msgid "Can't remember the password?"
|
||||||
|
msgstr "Не помните пароль?"
|
||||||
|
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Отменить"
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr "Настройки приватности"
|
||||||
|
|
||||||
|
msgid "Edit the project"
|
||||||
|
msgstr "Изменить проект"
|
||||||
|
|
||||||
|
msgid "Edit this bill"
|
||||||
|
msgstr "Изменить счёт"
|
||||||
|
|
||||||
|
msgid "Add a bill"
|
||||||
|
msgstr "Добавить счёт"
|
||||||
|
|
||||||
|
msgid "Select all"
|
||||||
|
msgstr "Выбрать всё"
|
||||||
|
|
||||||
|
msgid "Select none"
|
||||||
|
msgstr "Отменить выбор"
|
||||||
|
|
||||||
|
msgid "Add participant"
|
||||||
|
msgstr "Добавить участника"
|
||||||
|
|
||||||
|
msgid "Edit this member"
|
||||||
|
msgstr "Изменить этого участника"
|
||||||
|
|
||||||
|
msgid "john.doe@example.com, mary.moe@site.com"
|
||||||
|
msgstr "john.doe@example.com, mary.moe@site.com"
|
||||||
|
|
||||||
|
msgid "Send the invitations"
|
||||||
|
msgstr "Отправить приглашения"
|
||||||
|
|
||||||
|
msgid "Download"
|
||||||
|
msgstr "Скачать"
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr "История отключенных проектов"
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr "Отключенная история проекта и запись IP-адреса"
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr "Включить историю проекта"
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr "Выключить запись IP-адрессов"
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr "Включить историю проекта и запись IP адрессов"
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr "Включить запись IP адрессов"
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr "Настройки истории изменены"
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr "изменены"
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr "от"
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr "кому"
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr "Подтвердите удаление IP-адресов"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
"Вы уверены, что хотите удалить все записанные IP-адреса из этого проекта?\n"
|
||||||
|
" Остальная часть истории проекта не будет затронута. Это "
|
||||||
|
"действие не может быть отменено."
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Закрыть"
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr "Подтвердить удаление"
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr "Подтверждение удаления"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
"Вы уверены, что хотите стереть историю проекта? Это действие нельзя отменить."
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr "Добавлен"
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr "Удалён"
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr "и"
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr "список владельцев"
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr "Кто?"
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr "Баланс"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" <i>У этого проекта история отключена. Новые действия не появятся "
|
||||||
|
"ниже. Вы можете включить историю в</i>\n"
|
||||||
|
" <a href=\"%(url)s\">настройках</a>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" <i>В таблице ниже отражены действия, записанные до отключения "
|
||||||
|
"истории проекта. Вы можете\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" data-"
|
||||||
|
"target=\"#confirm-erase\">очистить историю проекта</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
"Некоторые записи ниже содержат IP-адреса, хотя в этом проекте запись IP "
|
||||||
|
"отключена. "
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr "Удалить сохраненные IP-адреса"
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr "Нечего стирать"
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr "Стереть историю проекта"
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr "Нечего стирать"
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr "Удалить сохраненные IP-адреса"
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr "Время"
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr "Событие"
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr "Запись IP-адреса может быть включена на странице настроек"
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr "Запись IP-адреса может быть отключена на странице настроек"
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr "От IP"
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr "добавлен"
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr "Приватный код проекта изменен"
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr "Проект переименован в"
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr "Контактная почта проекта изменена на"
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr "Настройки проекта изменены"
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr "отключено"
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr "реактивирован"
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr "переименован в"
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr "Внешняя ссылка изменена на"
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr "Количество"
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr "изменено"
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr "удалено"
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr "изменилось неизвестным образом"
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr "Нечего перечислять"
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr "Кто-то скорее всего стёр историю проекта."
|
||||||
|
|
||||||
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
|
msgstr "Управляйте своими общими <br />расходами проще"
|
||||||
|
|
||||||
|
msgid "Try out the demo"
|
||||||
|
msgstr "Попробуйте"
|
||||||
|
|
||||||
|
msgid "You're sharing a house?"
|
||||||
|
msgstr "Вы живете в одном доме с другими людьми?"
|
||||||
|
|
||||||
|
msgid "Going on holidays with friends?"
|
||||||
|
msgstr "Собираетесь в отпуск с друзьями?"
|
||||||
|
|
||||||
|
msgid "Simply sharing money with others?"
|
||||||
|
msgstr "Просто делиться деньгами с другими?"
|
||||||
|
|
||||||
|
msgid "We can help!"
|
||||||
|
msgstr "Мы поможем!"
|
||||||
|
|
||||||
|
msgid "Log in to an existing project"
|
||||||
|
msgstr "Войти в существующий проект"
|
||||||
|
|
||||||
|
msgid "Log in"
|
||||||
|
msgstr "Войти"
|
||||||
|
|
||||||
|
msgid "can't remember your password?"
|
||||||
|
msgstr "не помните пароль?"
|
||||||
|
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Создать"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"This access code will be sent to your friends. It is stored as-is by the "
|
||||||
|
"server, so don\\'t reuse a personal password!"
|
||||||
|
msgstr ""
|
||||||
|
"Этот код доступа будет отправлен вашим друзьям. Он хранится на сервере как "
|
||||||
|
"есть, поэтому не используйте личный пароль!"
|
||||||
|
|
||||||
|
msgid "Account manager"
|
||||||
|
msgstr "Менеджер аккаунтов"
|
||||||
|
|
||||||
|
msgid "Bills"
|
||||||
|
msgstr "Счета"
|
||||||
|
|
||||||
|
msgid "Settle"
|
||||||
|
msgstr "Отрегулировать"
|
||||||
|
|
||||||
|
msgid "Statistics"
|
||||||
|
msgstr "Статистика"
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr "История"
|
||||||
|
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr "Настройки"
|
||||||
|
|
||||||
|
msgid "Languages"
|
||||||
|
msgstr "Языки"
|
||||||
|
|
||||||
|
msgid "Projects"
|
||||||
|
msgstr "Проекты"
|
||||||
|
|
||||||
|
msgid "Start a new project"
|
||||||
|
msgstr "Начать новый проект"
|
||||||
|
|
||||||
|
msgid "Other projects :"
|
||||||
|
msgstr "Остальные проекты :"
|
||||||
|
|
||||||
|
msgid "switch to"
|
||||||
|
msgstr "сменён на"
|
||||||
|
|
||||||
|
msgid "Dashboard"
|
||||||
|
msgstr "Панель инструментов"
|
||||||
|
|
||||||
|
msgid "Logout"
|
||||||
|
msgstr "Выйти"
|
||||||
|
|
||||||
|
msgid "Code"
|
||||||
|
msgstr "Код"
|
||||||
|
|
||||||
|
msgid "Mobile Application"
|
||||||
|
msgstr "Мобильное приложение"
|
||||||
|
|
||||||
|
msgid "Documentation"
|
||||||
|
msgstr "Документация"
|
||||||
|
|
||||||
|
msgid "Administation Dashboard"
|
||||||
|
msgstr "Панель инструментов администратора"
|
||||||
|
|
||||||
|
msgid "\"I hate money\" is a free software"
|
||||||
|
msgstr "\" I hate money \" - бесплатная программа"
|
||||||
|
|
||||||
|
msgid "you can contribute and improve it!"
|
||||||
|
msgstr "вы можете способствовать развитию и улучшать её!"
|
||||||
|
|
||||||
|
msgid "deactivate"
|
||||||
|
msgstr "отключить"
|
||||||
|
|
||||||
|
msgid "reactivate"
|
||||||
|
msgstr "включить"
|
||||||
|
|
||||||
|
msgid "Invite people"
|
||||||
|
msgstr "Пригласить людей"
|
||||||
|
|
||||||
|
msgid "You should start by adding participants"
|
||||||
|
msgstr "Вам стоит начать с добавления пользователей"
|
||||||
|
|
||||||
|
msgid "Add a new bill"
|
||||||
|
msgstr "Добавить новый счёт"
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr "Новые счета"
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr "Старые счета"
|
||||||
|
|
||||||
|
msgid "When?"
|
||||||
|
msgstr "Когда?"
|
||||||
|
|
||||||
|
msgid "Who paid?"
|
||||||
|
msgstr "Кто заплатил?"
|
||||||
|
|
||||||
|
msgid "For what?"
|
||||||
|
msgstr "За что?"
|
||||||
|
|
||||||
|
msgid "How much?"
|
||||||
|
msgstr "Сколько?"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "Added on %(date)s"
|
||||||
|
msgstr "Добавлено %(date)s"
|
||||||
|
|
||||||
|
msgid "Everyone"
|
||||||
|
msgstr "Каждый"
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid "Everyone but %(excluded)s"
|
||||||
|
msgstr "Каждый, кроме %(excluded)s"
|
||||||
|
|
||||||
|
msgid "each"
|
||||||
|
msgstr "каждый"
|
||||||
|
|
||||||
|
msgid "No bills"
|
||||||
|
msgstr "Нет счетов"
|
||||||
|
|
||||||
|
msgid "Nothing to list yet."
|
||||||
|
msgstr "Нечего перечислять еще."
|
||||||
|
|
||||||
|
msgid "You probably want to"
|
||||||
|
msgstr "Возможно вы хотите"
|
||||||
|
|
||||||
|
msgid "add a bill"
|
||||||
|
msgstr "добавить счёт"
|
||||||
|
|
||||||
|
msgid "add participants"
|
||||||
|
msgstr "добавить пользователя"
|
||||||
|
|
||||||
|
msgid "Password reminder"
|
||||||
|
msgstr "Напоминание пароля"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"A link to reset your password has been sent to you, please check your "
|
||||||
|
"emails."
|
||||||
|
msgstr ""
|
||||||
|
"Ссылка для восстановления пароля отправлена, пожалуйста, проверьте Email."
|
||||||
|
|
||||||
|
msgid "Return to home page"
|
||||||
|
msgstr "Вернуться на главную страницу"
|
||||||
|
|
||||||
|
msgid "Your projects"
|
||||||
|
msgstr "Ваши проекты"
|
||||||
|
|
||||||
|
msgid "Reset your password"
|
||||||
|
msgstr "Восстановить пароль"
|
||||||
|
|
||||||
|
msgid "Invite people to join this project"
|
||||||
|
msgstr "Пригласить людей присоединиться к этому проекту"
|
||||||
|
|
||||||
|
msgid "Share Identifier & code"
|
||||||
|
msgstr "Поделиться идентификатором и кодом"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"You can share the project identifier and the private code by any "
|
||||||
|
"communication means."
|
||||||
|
msgstr ""
|
||||||
|
"Вы можете поделиться идентификатором проекта и личным кодом любым способом "
|
||||||
|
"связи."
|
||||||
|
|
||||||
|
msgid "Identifier:"
|
||||||
|
msgstr "Идентификатор:"
|
||||||
|
|
||||||
|
msgid "Share the Link"
|
||||||
|
msgstr "Поделиться ссылкой"
|
||||||
|
|
||||||
|
msgid "You can directly share the following link via your prefered medium"
|
||||||
|
msgstr ""
|
||||||
|
"Вы можете напрямую поделиться следующей ссылкой через любой способ связи"
|
||||||
|
|
||||||
|
msgid "Send via Emails"
|
||||||
|
msgstr "Отправить по почте"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Specify a (comma separated) list of email adresses you want to notify "
|
||||||
|
"about the\n"
|
||||||
|
" creation of this budget management project and we will "
|
||||||
|
"send them an email for you."
|
||||||
|
msgstr ""
|
||||||
|
"Укажите (разделенный запятыми) список адресов электронной почты, которые вы "
|
||||||
|
"хотите уведомить о\n"
|
||||||
|
" создание этого проекта управления бюджетом, и мы вышлем им "
|
||||||
|
"письмо."
|
||||||
|
|
||||||
|
msgid "Who pays?"
|
||||||
|
msgstr "Кто платит?"
|
||||||
|
|
||||||
|
msgid "To whom?"
|
||||||
|
msgstr "Кому?"
|
||||||
|
|
||||||
|
msgid "Paid"
|
||||||
|
msgstr "Оплачено"
|
||||||
|
|
||||||
|
msgid "Spent"
|
||||||
|
msgstr "Потрачено"
|
||||||
|
|
||||||
|
msgid "Expenses by Month"
|
||||||
|
msgstr "Расходы по месяцам"
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
|
msgstr "Период"
|
Binary file not shown.
|
@ -3,7 +3,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-10-01 21:48+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2019-08-07 13:24+0000\n"
|
"PO-Revision-Date: 2019-08-07 13:24+0000\n"
|
||||||
"Last-Translator: Mesut Akcan <makcan@gmail.com>\n"
|
"Last-Translator: Mesut Akcan <makcan@gmail.com>\n"
|
||||||
"Language: tr\n"
|
"Language: tr\n"
|
||||||
|
@ -13,7 +13,7 @@ msgstr ""
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.7.0\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
@ -31,6 +31,18 @@ msgstr "Özel kod"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "E-posta"
|
msgstr "E-posta"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "Proje tanımlayıcısı"
|
msgstr "Proje tanımlayıcısı"
|
||||||
|
|
||||||
|
@ -127,6 +139,15 @@ msgstr ""
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -160,6 +181,12 @@ msgstr ""
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -171,7 +198,7 @@ msgid "Your invitations have been sent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -225,9 +252,6 @@ msgstr ""
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -249,6 +273,9 @@ msgstr ""
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -258,6 +285,12 @@ msgstr ""
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -279,6 +312,9 @@ msgstr ""
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -309,6 +345,177 @@ msgstr ""
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -356,6 +563,9 @@ msgstr ""
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -413,6 +623,12 @@ msgstr ""
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -439,9 +655,6 @@ msgstr ""
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -510,91 +723,14 @@ msgstr ""
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "What do you want to download ?"
|
msgid "Period"
|
||||||
#~ msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "bills"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "transactions"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Export file format"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Edit this project"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Download this project's data"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Type user name here"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "No, thanks"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Manage your shared <br>expenses, easily"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Log to an existing project"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "log in"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "or create a new one"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "let's get started"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "options"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Project settings"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "This is a free software"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Invite people to join this project!"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Added on"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Nothing to list yet. You probably want to"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "Specify a (comma separated) list of "
|
|
||||||
#~ "email adresses you want to notify "
|
|
||||||
#~ "about the\n"
|
|
||||||
#~ "creation of this budget management "
|
|
||||||
#~ "project and we will send them an"
|
|
||||||
#~ " email for you."
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "If you prefer, you can share the project identifier and the shared\n"
|
|
||||||
#~ "password by other communication means. "
|
|
||||||
#~ "Or even directly share the following "
|
|
||||||
#~ "link:"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "A link to reset your password has been sent to your email."
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
|
|
BIN
ihatemoney/translations/uk/LC_MESSAGES/messages.mo
Normal file
BIN
ihatemoney/translations/uk/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
|
@ -1,19 +1,20 @@
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-12-05 15:35+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2019-12-08 16:26+0000\n"
|
"PO-Revision-Date: 2019-12-08 16:26+0000\n"
|
||||||
"Last-Translator: Tymofij Lytvynenko <till.svit@gmail.com>\n"
|
"Last-Translator: Tymofij Lytvynenko <till.svit@gmail.com>\n"
|
||||||
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/i-hate-money/"
|
|
||||||
"i-hate-money/uk/>\n"
|
|
||||||
"Language: uk\n"
|
"Language: uk\n"
|
||||||
|
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/i-hate-"
|
||||||
|
"money/i-hate-money/uk/>\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||||
|
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<="
|
"Generated-By: Babel 2.8.0\n"
|
||||||
"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
|
||||||
"X-Generator: Weblate 3.10-dev\n"
|
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
@ -29,6 +30,18 @@ msgstr "Приватний код"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Е-пошта"
|
msgstr "Е-пошта"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "Ідентифікатор проєкту"
|
msgstr "Ідентифікатор проєкту"
|
||||||
|
|
||||||
|
@ -123,6 +136,15 @@ msgstr ""
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -156,6 +178,12 @@ msgstr ""
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -167,7 +195,7 @@ msgid "Your invitations have been sent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -221,9 +249,6 @@ msgstr ""
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -245,6 +270,9 @@ msgstr ""
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -254,6 +282,12 @@ msgstr ""
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -275,6 +309,9 @@ msgstr ""
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -305,6 +342,177 @@ msgstr ""
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -352,6 +560,9 @@ msgstr ""
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -409,6 +620,12 @@ msgstr ""
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -435,9 +652,6 @@ msgstr ""
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -506,14 +720,14 @@ msgstr ""
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Period"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
Binary file not shown.
|
@ -1,19 +1,20 @@
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-10-01 21:48+0200\n"
|
"POT-Creation-Date: 2020-04-25 13:02+0200\n"
|
||||||
"PO-Revision-Date: 2020-02-09 12:01+0000\n"
|
"PO-Revision-Date: 2020-02-09 12:01+0000\n"
|
||||||
"Last-Translator: Muge Niu <mugeniu12138@gmail.com>\n"
|
"Last-Translator: Muge Niu <mugeniu12138@gmail.com>\n"
|
||||||
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
|
"Language: zh_HANS_CN\n"
|
||||||
"i-hate-money/i-hate-money/zh_Hans/>\n"
|
"Language-Team: Chinese (Simplified) "
|
||||||
"Language: zh_HANS-CN\n"
|
"<https://hosted.weblate.org/projects/i-hate-money/i-hate-money/zh_Hans/>"
|
||||||
|
"\n"
|
||||||
|
"Plural-Forms: nplurals=1; plural=0\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Generated-By: Babel 2.8.0\n"
|
||||||
"X-Generator: Weblate 3.11-dev\n"
|
|
||||||
"Generated-By: Babel 2.7.0\n"
|
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
"Not a valid amount or expression. Only numbers and + - * / operators are "
|
||||||
|
@ -29,6 +30,18 @@ msgstr "共享密钥"
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "邮箱"
|
msgstr "邮箱"
|
||||||
|
|
||||||
|
msgid "Enable project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Use IP tracking for project history"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import previously exported JSON file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project identifier"
|
msgid "Project identifier"
|
||||||
msgstr "账目名称"
|
msgstr "账目名称"
|
||||||
|
|
||||||
|
@ -123,6 +136,15 @@ msgstr ""
|
||||||
msgid "The email %(email)s is not valid"
|
msgid "The email %(email)s is not valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Participant"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Too many failed login attempts, please retry later."
|
msgid "Too many failed login attempts, please retry later."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -156,6 +178,12 @@ msgstr ""
|
||||||
msgid "Password successfully reset."
|
msgid "Password successfully reset."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project successfully uploaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Invalid JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project successfully deleted"
|
msgid "Project successfully deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -167,7 +195,7 @@ msgid "Your invitations have been sent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(member)s had been added"
|
msgid "%(member)s has been added"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -221,9 +249,6 @@ msgstr "?"
|
||||||
msgid "Create a new project"
|
msgid "Create a new project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Project"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Number of members"
|
msgid "Number of members"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -245,6 +270,9 @@ msgstr ""
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "see"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Dashboard is currently deactivated."
|
msgid "The Dashboard is currently deactivated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -254,6 +282,12 @@ msgstr ""
|
||||||
msgid "Edit project"
|
msgid "Edit project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Import JSON"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Choose file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download project's data"
|
msgid "Download project's data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -275,6 +309,9 @@ msgstr ""
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "取消"
|
msgstr "取消"
|
||||||
|
|
||||||
|
msgid "Privacy Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit the project"
|
msgid "Edit the project"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -305,6 +342,177 @@ msgstr ""
|
||||||
msgid "Download"
|
msgid "Download"
|
||||||
msgstr "下载"
|
msgstr "下载"
|
||||||
|
|
||||||
|
msgid "Disabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Disabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled Project History & IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Enabled IP Address Recording"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History Settings Changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "from"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Remove IP Adresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to delete all recorded IP addresses from this "
|
||||||
|
"project?\n"
|
||||||
|
" The rest of the project history will be unaffected. This "
|
||||||
|
"action cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Confirm Delete"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Confirmation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Are you sure you want to erase all history for this project? This action "
|
||||||
|
"cannot be undone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "owers list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Who?"
|
||||||
|
msgstr "谁?"
|
||||||
|
|
||||||
|
msgid "Balance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>This project has history disabled. New actions won't "
|
||||||
|
"appear below. You can enable history on the</i>\n"
|
||||||
|
" <a href=\"%(url)s\">settings page</a>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" <i>The table below reflects actions recorded prior to "
|
||||||
|
"disabling project history. You can\n"
|
||||||
|
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
|
||||||
|
"data-target=\"#confirm-erase\">clear project history</a> to remove "
|
||||||
|
"them.</i></p>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Some entries below contain IP addresses, even though this project has IP "
|
||||||
|
"recording disabled. "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete stored IP addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No history to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clear Project History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "No IP Addresses to erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Delete Stored IP Addresses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be enabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "IP address recording can be disabled on the settings page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "From IP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "added"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project private code changed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project contact email changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Project settings modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "deactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "reactivated"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "renamed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "External link changed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Amount"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "modified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "changed in a unknown way"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Nothing to list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Someone probably cleared the project history."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Manage your shared <br />expenses, easily"
|
msgid "Manage your shared <br />expenses, easily"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -352,6 +560,9 @@ msgstr ""
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "History"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -409,6 +620,12 @@ msgstr ""
|
||||||
msgid "Add a new bill"
|
msgid "Add a new bill"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Newer bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Older bills"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "When?"
|
msgid "When?"
|
||||||
msgstr "什么时候?"
|
msgstr "什么时候?"
|
||||||
|
|
||||||
|
@ -435,9 +652,6 @@ msgstr ""
|
||||||
msgid "each"
|
msgid "each"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "see"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "No bills"
|
msgid "No bills"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -506,107 +720,14 @@ msgstr ""
|
||||||
msgid "To whom?"
|
msgid "To whom?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Who?"
|
|
||||||
msgstr "谁?"
|
|
||||||
|
|
||||||
msgid "Paid"
|
msgid "Paid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Spent"
|
msgid "Spent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Balance"
|
msgid "Expenses by Month"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid ""
|
msgid "Period"
|
||||||
#~ "The project identifier is used to "
|
msgstr ""
|
||||||
#~ "log in and for the URL of "
|
|
||||||
#~ "the project. We tried to generate "
|
|
||||||
#~ "an identifier for you but a "
|
|
||||||
#~ "project with this identifier already "
|
|
||||||
#~ "exists. Please create a new identifier"
|
|
||||||
#~ " that you will be able to "
|
|
||||||
#~ "remember"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "Not a valid amount or expression.Only"
|
|
||||||
#~ " numbers and + - * / "
|
|
||||||
#~ "operatorsare accepted."
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "What do you want to download ?"
|
|
||||||
#~ msgstr "你想下载什么?"
|
|
||||||
|
|
||||||
#~ msgid "bills"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "transactions"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Export file format"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Edit this project"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Download this project's data"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Type user name here"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "No, thanks"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Manage your shared <br>expenses, easily"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Log to an existing project"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "log in"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "or create a new one"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "let's get started"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "options"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Project settings"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "This is a free software"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Invite people to join this project!"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Added on"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Nothing to list yet. You probably want to"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "Specify a (comma separated) list of "
|
|
||||||
#~ "email adresses you want to notify "
|
|
||||||
#~ "about the\n"
|
|
||||||
#~ "creation of this budget management "
|
|
||||||
#~ "project and we will send them an"
|
|
||||||
#~ " email for you."
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "If you prefer, you can share the project identifier and the shared\n"
|
|
||||||
#~ "password by other communication means. "
|
|
||||||
#~ "Or even directly share the following "
|
|
||||||
#~ "link:"
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "A link to reset your password has been sent to your email."
|
|
||||||
#~ msgstr ""
|
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import ast
|
import ast
|
||||||
import operator
|
|
||||||
|
|
||||||
from io import BytesIO, StringIO
|
|
||||||
|
|
||||||
import jinja2
|
|
||||||
from json import dumps, JSONEncoder
|
|
||||||
from flask import redirect, current_app
|
|
||||||
from babel import Locale
|
|
||||||
from werkzeug.routing import HTTPException, RoutingException
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from enum import Enum
|
||||||
|
from io import BytesIO, StringIO
|
||||||
|
from json import JSONEncoder, dumps
|
||||||
|
import operator
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
from babel import Locale
|
||||||
|
from flask import current_app, redirect, render_template
|
||||||
|
from flask_babel import get_locale
|
||||||
|
import jinja2
|
||||||
|
from werkzeug.routing import HTTPException, RoutingException
|
||||||
|
|
||||||
|
|
||||||
def slugify(value):
|
def slugify(value):
|
||||||
|
@ -99,7 +98,7 @@ def static_include(filename):
|
||||||
|
|
||||||
|
|
||||||
def locale_from_iso(iso_code):
|
def locale_from_iso(iso_code):
|
||||||
return Locale(iso_code)
|
return Locale.parse(iso_code)
|
||||||
|
|
||||||
|
|
||||||
def list_of_dicts2json(dict_to_convert):
|
def list_of_dicts2json(dict_to_convert):
|
||||||
|
@ -257,3 +256,40 @@ def same_bill(bill1, bill2):
|
||||||
if bill1[a] != bill2[a]:
|
if bill1[a] != bill2[a]:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class FormEnum(Enum):
|
||||||
|
"""Extend builtin Enum class to be seamlessly compatible with WTForms"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def choices(cls):
|
||||||
|
return [(choice, choice.name) for choice in cls]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def coerce(cls, item):
|
||||||
|
"""Coerce a str or int representation into an Enum object"""
|
||||||
|
if isinstance(item, cls):
|
||||||
|
return item
|
||||||
|
|
||||||
|
# If item is not already a Enum object then it must be
|
||||||
|
# a string or int corresponding to an ID (e.g. '0' or 1)
|
||||||
|
# Either int() or cls() will correctly throw a TypeError if this
|
||||||
|
# is not the case
|
||||||
|
return cls(int(item))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.value)
|
||||||
|
|
||||||
|
|
||||||
|
def render_localized_template(template_name_prefix, **context):
|
||||||
|
"""Like render_template(), but selects the right template according to the
|
||||||
|
current user language. Fallback to English if a template for the
|
||||||
|
current language does not exist.
|
||||||
|
"""
|
||||||
|
fallback = "en"
|
||||||
|
templates = [
|
||||||
|
f"{template_name_prefix}.{lang}.j2"
|
||||||
|
for lang in (get_locale().language, fallback)
|
||||||
|
]
|
||||||
|
# render_template() supports a list of templates to try in order
|
||||||
|
return render_template(templates, **context)
|
||||||
|
|
94
ihatemoney/versioning.py
Normal file
94
ihatemoney/versioning.py
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
from flask import g
|
||||||
|
from sqlalchemy.orm.attributes import get_history
|
||||||
|
from sqlalchemy_continuum import VersioningManager
|
||||||
|
from sqlalchemy_continuum.plugins.flask import fetch_remote_addr
|
||||||
|
|
||||||
|
from ihatemoney.utils import FormEnum
|
||||||
|
|
||||||
|
|
||||||
|
class LoggingMode(FormEnum):
|
||||||
|
"""Represents a project's history preferences."""
|
||||||
|
|
||||||
|
DISABLED = 0
|
||||||
|
ENABLED = 1
|
||||||
|
RECORD_IP = 2
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def default(cls):
|
||||||
|
return cls.ENABLED
|
||||||
|
|
||||||
|
|
||||||
|
class ConditionalVersioningManager(VersioningManager):
|
||||||
|
"""Conditionally enable version tracking based on the given predicate."""
|
||||||
|
|
||||||
|
def __init__(self, tracking_predicate, *args, **kwargs):
|
||||||
|
"""Create version entry iff tracking_predicate() returns True."""
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.tracking_predicate = tracking_predicate
|
||||||
|
|
||||||
|
def before_flush(self, session, flush_context, instances):
|
||||||
|
if self.tracking_predicate():
|
||||||
|
return super().before_flush(session, flush_context, instances)
|
||||||
|
else:
|
||||||
|
# At least one call to unit_of_work() needs to be made against the
|
||||||
|
# session object to prevent a KeyError later. This doesn't create
|
||||||
|
# a version or transaction entry
|
||||||
|
self.unit_of_work(session)
|
||||||
|
|
||||||
|
def after_flush(self, session, flush_context):
|
||||||
|
if self.tracking_predicate():
|
||||||
|
return super().after_flush(session, flush_context)
|
||||||
|
else:
|
||||||
|
# At least one call to unit_of_work() needs to be made against the
|
||||||
|
# session object to prevent a KeyError later. This doesn't create
|
||||||
|
# a version or transaction entry
|
||||||
|
self.unit_of_work(session)
|
||||||
|
|
||||||
|
|
||||||
|
def version_privacy_predicate():
|
||||||
|
"""Evaluate if the project of the current session has enabled logging."""
|
||||||
|
logging_enabled = False
|
||||||
|
try:
|
||||||
|
if g.project.logging_preference != LoggingMode.DISABLED:
|
||||||
|
logging_enabled = True
|
||||||
|
|
||||||
|
# If logging WAS enabled prior to this transaction,
|
||||||
|
# we log this one last transaction
|
||||||
|
old_logging_mode = get_history(g.project, "logging_preference")[2]
|
||||||
|
if old_logging_mode and old_logging_mode[0] != LoggingMode.DISABLED:
|
||||||
|
logging_enabled = True
|
||||||
|
except AttributeError:
|
||||||
|
# g.project doesn't exist, it's being created or this action is outside
|
||||||
|
# the scope of a project. Use the default logging mode to decide
|
||||||
|
if LoggingMode.default() != LoggingMode.DISABLED:
|
||||||
|
logging_enabled = True
|
||||||
|
return logging_enabled
|
||||||
|
|
||||||
|
|
||||||
|
def get_ip_if_allowed():
|
||||||
|
"""
|
||||||
|
Get the remote address (IP address) of the current Flask context, if the
|
||||||
|
project's privacy settings allow it. Behind the scenes, this calls back to
|
||||||
|
the FlaskPlugin from SQLAlchemy-Continuum in order to maintain forward
|
||||||
|
compatibility
|
||||||
|
"""
|
||||||
|
ip_logging_allowed = False
|
||||||
|
try:
|
||||||
|
if g.project.logging_preference == LoggingMode.RECORD_IP:
|
||||||
|
ip_logging_allowed = True
|
||||||
|
|
||||||
|
# If ip recording WAS enabled prior to this transaction,
|
||||||
|
# we record the IP for this one last transaction
|
||||||
|
old_logging_mode = get_history(g.project, "logging_preference")[2]
|
||||||
|
if old_logging_mode and old_logging_mode[0] == LoggingMode.RECORD_IP:
|
||||||
|
ip_logging_allowed = True
|
||||||
|
except AttributeError:
|
||||||
|
# g.project doesn't exist, it's being created or this action is outside
|
||||||
|
# the scope of a project. Use the default logging mode to decide
|
||||||
|
if LoggingMode.default() == LoggingMode.RECORD_IP:
|
||||||
|
ip_logging_allowed = True
|
||||||
|
|
||||||
|
if ip_logging_allowed:
|
||||||
|
return fetch_remote_addr()
|
||||||
|
else:
|
||||||
|
return None
|
|
@ -8,55 +8,59 @@ Basically, this blueprint takes care of the authentication and provides
|
||||||
some shortcuts to make your life better when coding (see `pull_project`
|
some shortcuts to make your life better when coding (see `pull_project`
|
||||||
and `add_project_id` for a quick overview)
|
and `add_project_id` for a quick overview)
|
||||||
"""
|
"""
|
||||||
|
from datetime import datetime
|
||||||
|
from functools import wraps
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from functools import wraps
|
|
||||||
from smtplib import SMTPRecipientsRefused
|
from smtplib import SMTPRecipientsRefused
|
||||||
|
|
||||||
from dateutil.parser import parse
|
from dateutil.parser import parse
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
from flask import (
|
from flask import (
|
||||||
abort,
|
|
||||||
Blueprint,
|
Blueprint,
|
||||||
|
abort,
|
||||||
current_app,
|
current_app,
|
||||||
flash,
|
flash,
|
||||||
g,
|
g,
|
||||||
redirect,
|
redirect,
|
||||||
render_template,
|
render_template,
|
||||||
request,
|
request,
|
||||||
session,
|
|
||||||
url_for,
|
|
||||||
send_file,
|
send_file,
|
||||||
send_from_directory,
|
send_from_directory,
|
||||||
|
session,
|
||||||
|
url_for,
|
||||||
)
|
)
|
||||||
from flask_babel import get_locale, gettext as _
|
from flask_babel import gettext as _
|
||||||
from flask_mail import Message
|
from flask_mail import Message
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
|
from sqlalchemy_continuum import Operation
|
||||||
from werkzeug.exceptions import NotFound
|
from werkzeug.exceptions import NotFound
|
||||||
from werkzeug.security import check_password_hash, generate_password_hash
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
|
||||||
|
from ihatemoney.currency_convertor import CurrencyConverter
|
||||||
from ihatemoney.forms import (
|
from ihatemoney.forms import (
|
||||||
AdminAuthenticationForm,
|
AdminAuthenticationForm,
|
||||||
AuthenticationForm,
|
AuthenticationForm,
|
||||||
EditProjectForm,
|
|
||||||
InviteForm,
|
InviteForm,
|
||||||
MemberForm,
|
MemberForm,
|
||||||
PasswordReminder,
|
PasswordReminder,
|
||||||
ResetPasswordForm,
|
|
||||||
ProjectForm,
|
ProjectForm,
|
||||||
get_billform_for,
|
ResetPasswordForm,
|
||||||
UploadForm,
|
UploadForm,
|
||||||
|
get_billform_for,
|
||||||
|
get_editprojectform_for,
|
||||||
)
|
)
|
||||||
from ihatemoney.models import db, Project, Person, Bill
|
from ihatemoney.history import get_history, get_history_queries
|
||||||
|
from ihatemoney.models import Bill, LoggingMode, Person, Project, db
|
||||||
from ihatemoney.utils import (
|
from ihatemoney.utils import (
|
||||||
Redirect303,
|
|
||||||
list_of_dicts2json,
|
|
||||||
list_of_dicts2csv,
|
|
||||||
LoginThrottler,
|
LoginThrottler,
|
||||||
|
Redirect303,
|
||||||
get_members,
|
get_members,
|
||||||
|
list_of_dicts2csv,
|
||||||
|
list_of_dicts2json,
|
||||||
|
render_localized_template,
|
||||||
same_bill,
|
same_bill,
|
||||||
)
|
)
|
||||||
from datetime import datetime
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
|
|
||||||
main = Blueprint("main", __name__)
|
main = Blueprint("main", __name__)
|
||||||
|
|
||||||
|
@ -235,6 +239,8 @@ def authenticate(project_id=None):
|
||||||
# add the project on the top of the list
|
# add the project on the top of the list
|
||||||
session["projects"].insert(0, (project_id, project.name))
|
session["projects"].insert(0, (project_id, project.name))
|
||||||
session[project_id] = True
|
session[project_id] = True
|
||||||
|
# Set session to permanent to make language choice persist
|
||||||
|
session.permanent = True
|
||||||
session.update()
|
session.update()
|
||||||
setattr(g, "project", project)
|
setattr(g, "project", project)
|
||||||
return redirect(url_for(".list_bills"))
|
return redirect(url_for(".list_bills"))
|
||||||
|
@ -297,9 +303,7 @@ def create_project():
|
||||||
project=g.project.name,
|
project=g.project.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
message_body = render_template(
|
message_body = render_localized_template("reminder_mail")
|
||||||
"reminder_mail.%s.j2" % get_locale().language
|
|
||||||
)
|
|
||||||
|
|
||||||
msg = Message(
|
msg = Message(
|
||||||
message_title, body=message_body, recipients=[project.contact_email]
|
message_title, body=message_body, recipients=[project.contact_email]
|
||||||
|
@ -307,19 +311,10 @@ def create_project():
|
||||||
try:
|
try:
|
||||||
current_app.mail.send(msg)
|
current_app.mail.send(msg)
|
||||||
except SMTPRecipientsRefused:
|
except SMTPRecipientsRefused:
|
||||||
msg_compl = "Problem sending mail. "
|
flash(_("Error while sending reminder email"), category="danger")
|
||||||
# TODO: destroy the project and cancel instead?
|
|
||||||
else:
|
|
||||||
msg_compl = ""
|
|
||||||
|
|
||||||
# redirect the user to the next step (invite)
|
# redirect the user to the next step (invite)
|
||||||
flash(
|
flash(_("The project identifier is %(project)s", project=project.id))
|
||||||
_(
|
|
||||||
"%(msg_compl)sThe project identifier is %(project)s",
|
|
||||||
msg_compl=msg_compl,
|
|
||||||
project=project.id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return redirect(url_for(".list_bills", project_id=project.id))
|
return redirect(url_for(".list_bills", project_id=project.id))
|
||||||
|
|
||||||
return render_template("create_project.html", form=form)
|
return render_template("create_project.html", form=form)
|
||||||
|
@ -333,11 +328,12 @@ def remind_password():
|
||||||
# get the project
|
# get the project
|
||||||
project = Project.query.get(form.id.data)
|
project = Project.query.get(form.id.data)
|
||||||
# send a link to reset the password
|
# send a link to reset the password
|
||||||
password_reminder = "password_reminder.%s.j2" % get_locale().language
|
|
||||||
current_app.mail.send(
|
current_app.mail.send(
|
||||||
Message(
|
Message(
|
||||||
"password recovery",
|
"password recovery",
|
||||||
body=render_template(password_reminder, project=project),
|
body=render_localized_template(
|
||||||
|
"password_reminder", project=project
|
||||||
|
),
|
||||||
recipients=[project.contact_email],
|
recipients=[project.contact_email],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -381,37 +377,55 @@ def reset_password():
|
||||||
|
|
||||||
@main.route("/<project_id>/edit", methods=["GET", "POST"])
|
@main.route("/<project_id>/edit", methods=["GET", "POST"])
|
||||||
def edit_project():
|
def edit_project():
|
||||||
edit_form = EditProjectForm()
|
edit_form = get_editprojectform_for(g.project)
|
||||||
if request.method == "POST":
|
import_form = UploadForm()
|
||||||
if edit_form.validate():
|
# Import form
|
||||||
project = edit_form.update(g.project)
|
if import_form.validate_on_submit():
|
||||||
db.session.add(project)
|
try:
|
||||||
db.session.commit()
|
import_project(import_form.file.data.stream, g.project)
|
||||||
|
flash(_("Project successfully uploaded"))
|
||||||
|
|
||||||
return redirect(url_for(".list_bills"))
|
return redirect(url_for("main.list_bills"))
|
||||||
|
except ValueError:
|
||||||
|
flash(_("Invalid JSON"), category="danger")
|
||||||
|
|
||||||
|
# Edit form
|
||||||
|
if edit_form.validate_on_submit():
|
||||||
|
project = edit_form.update(g.project)
|
||||||
|
# Update converted currency
|
||||||
|
if project.default_currency != CurrencyConverter.default:
|
||||||
|
for bill in project.get_bills():
|
||||||
|
|
||||||
|
if bill.original_currency == CurrencyConverter.default:
|
||||||
|
bill.original_currency = project.default_currency
|
||||||
|
|
||||||
|
bill.converted_amount = CurrencyConverter().exchange_currency(
|
||||||
|
bill.amount, bill.original_currency, project.default_currency
|
||||||
|
)
|
||||||
|
db.session.add(bill)
|
||||||
|
|
||||||
|
db.session.add(project)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for("main.list_bills"))
|
||||||
else:
|
else:
|
||||||
edit_form.name.data = g.project.name
|
edit_form.name.data = g.project.name
|
||||||
|
|
||||||
|
if g.project.logging_preference != LoggingMode.DISABLED:
|
||||||
|
edit_form.project_history.data = True
|
||||||
|
if g.project.logging_preference == LoggingMode.RECORD_IP:
|
||||||
|
edit_form.ip_recording.data = True
|
||||||
|
|
||||||
edit_form.contact_email.data = g.project.contact_email
|
edit_form.contact_email.data = g.project.contact_email
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"edit_project.html", edit_form=edit_form, current_view="edit_project"
|
"edit_project.html",
|
||||||
|
edit_form=edit_form,
|
||||||
|
import_form=import_form,
|
||||||
|
current_view="edit_project",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@main.route("/<project_id>/upload_json", methods=["GET", "POST"])
|
|
||||||
def upload_json():
|
|
||||||
form = UploadForm()
|
|
||||||
if form.validate_on_submit():
|
|
||||||
try:
|
|
||||||
import_project(form.file.data.stream, g.project)
|
|
||||||
flash(_("Project successfully uploaded"))
|
|
||||||
except ValueError:
|
|
||||||
flash(_("Invalid JSON"), category="error")
|
|
||||||
return redirect(url_for("main.list_bills"))
|
|
||||||
|
|
||||||
return render_template("upload_json.html", form=form)
|
|
||||||
|
|
||||||
|
|
||||||
def import_project(file, project):
|
def import_project(file, project):
|
||||||
json_file = json.load(file)
|
json_file = json.load(file)
|
||||||
|
|
||||||
|
@ -477,6 +491,7 @@ def import_project(file, project):
|
||||||
form.date = parse(b["date"])
|
form.date = parse(b["date"])
|
||||||
form.payer = id_dict[b["payer_name"]]
|
form.payer = id_dict[b["payer_name"]]
|
||||||
form.payed_for = owers_id
|
form.payed_for = owers_id
|
||||||
|
form.original_currency = b.get("original_currency")
|
||||||
|
|
||||||
db.session.add(form.fake_form(bill, project))
|
db.session.add(form.fake_form(bill, project))
|
||||||
|
|
||||||
|
@ -510,7 +525,7 @@ def export_project(file, format):
|
||||||
|
|
||||||
return send_file(
|
return send_file(
|
||||||
file2export,
|
file2export,
|
||||||
attachment_filename="%s-%s.%s" % (g.project.id, file, format),
|
attachment_filename=f"{g.project.id}-{file}.{format}",
|
||||||
as_attachment=True,
|
as_attachment=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -542,6 +557,7 @@ def demo():
|
||||||
name="demonstration",
|
name="demonstration",
|
||||||
password=generate_password_hash("demo"),
|
password=generate_password_hash("demo"),
|
||||||
contact_email="demo@notmyidea.org",
|
contact_email="demo@notmyidea.org",
|
||||||
|
default_currency="EUR",
|
||||||
)
|
)
|
||||||
db.session.add(project)
|
db.session.add(project)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -558,11 +574,7 @@ def invite():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if form.validate():
|
if form.validate():
|
||||||
# send the email
|
# send the email
|
||||||
|
message_body = render_localized_template("invitation_mail")
|
||||||
message_body = render_template(
|
|
||||||
"invitation_mail.%s.j2" % get_locale().language
|
|
||||||
)
|
|
||||||
|
|
||||||
message_title = _(
|
message_title = _(
|
||||||
"You have been invited to share your " "expenses for %(project)s",
|
"You have been invited to share your " "expenses for %(project)s",
|
||||||
project=g.project.name,
|
project=g.project.name,
|
||||||
|
@ -610,7 +622,7 @@ def add_member():
|
||||||
if form.validate():
|
if form.validate():
|
||||||
member = form.save(g.project, Person())
|
member = form.save(g.project, Person())
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(_("%(member)s had been added", member=member.name))
|
flash(_("%(member)s has been added", member=member.name))
|
||||||
return redirect(url_for(".list_bills"))
|
return redirect(url_for(".list_bills"))
|
||||||
|
|
||||||
return render_template("add_member.html", form=form)
|
return render_template("add_member.html", form=form)
|
||||||
|
@ -740,6 +752,45 @@ def settle_bill():
|
||||||
return render_template("settle_bills.html", bills=bills, current_view="settle_bill")
|
return render_template("settle_bills.html", bills=bills, current_view="settle_bill")
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/<project_id>/history")
|
||||||
|
def history():
|
||||||
|
"""Query for the version entries associated with this project."""
|
||||||
|
history = get_history(g.project, human_readable_names=True)
|
||||||
|
|
||||||
|
any_ip_addresses = any(event["ip"] for event in history)
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
"history.html",
|
||||||
|
current_view="history",
|
||||||
|
history=history,
|
||||||
|
any_ip_addresses=any_ip_addresses,
|
||||||
|
LoggingMode=LoggingMode,
|
||||||
|
OperationType=Operation,
|
||||||
|
current_log_pref=g.project.logging_preference,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/<project_id>/erase_history", methods=["POST"])
|
||||||
|
def erase_history():
|
||||||
|
"""Erase all history entries associated with this project."""
|
||||||
|
for query in get_history_queries(g.project):
|
||||||
|
query.delete(synchronize_session="fetch")
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
return redirect(url_for(".history"))
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/<project_id>/strip_ip_addresses", methods=["POST"])
|
||||||
|
def strip_ip_addresses():
|
||||||
|
"""Strip ip addresses from history entries associated with this project."""
|
||||||
|
for query in get_history_queries(g.project):
|
||||||
|
for version_object in query.all():
|
||||||
|
version_object.transaction.remote_addr = None
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
return redirect(url_for(".history"))
|
||||||
|
|
||||||
|
|
||||||
@main.route("/<project_id>/statistics")
|
@main.route("/<project_id>/statistics")
|
||||||
def statistics():
|
def statistics():
|
||||||
"""Compute what each member has paid and spent and display it"""
|
"""Compute what each member has paid and spent and display it"""
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
alembic==1.2.0
|
|
||||||
aniso8601==8.0.0
|
|
||||||
Babel==2.7.0
|
|
||||||
blinker==1.4
|
|
||||||
Click==7.0
|
|
||||||
debts==0.4
|
|
||||||
dnspython==1.16.0
|
|
||||||
email-validator==1.0.4
|
|
||||||
Flask==1.1.1
|
|
||||||
Flask-Babel==0.12.2
|
|
||||||
Flask-Cors==3.0.8
|
|
||||||
Flask-Mail==0.9.1
|
|
||||||
Flask-Migrate==2.5.2
|
|
||||||
Flask-RESTful==0.3.7
|
|
||||||
Flask-Script==2.0.6
|
|
||||||
Flask-SQLAlchemy==2.4.1
|
|
||||||
Flask-WTF==0.14.2
|
|
||||||
idna==2.8
|
|
||||||
itsdangerous==1.1.0
|
|
||||||
Jinja2==2.10.1
|
|
||||||
Mako==1.1.0
|
|
||||||
MarkupSafe==1.1.1
|
|
||||||
python-dateutil==2.8.0
|
|
||||||
pytz==2019.2
|
|
||||||
SQLAlchemy==1.3.8
|
|
||||||
Werkzeug==0.16.0
|
|
||||||
WTForms==2.2.1
|
|
46
setup.cfg
46
setup.cfg
|
@ -11,9 +11,9 @@ license = Custom BSD Beerware
|
||||||
classifiers =
|
classifiers =
|
||||||
Programming Language :: Python
|
Programming Language :: Python
|
||||||
Programming Language :: Python :: 3
|
Programming Language :: Python :: 3
|
||||||
Programming Language :: Python :: 3.5
|
|
||||||
Programming Language :: Python :: 3.6
|
Programming Language :: Python :: 3.6
|
||||||
Programming Language :: Python :: 3.7
|
Programming Language :: Python :: 3.7
|
||||||
|
Programming Language :: Python :: 3.8
|
||||||
Topic :: Internet :: WWW/HTTP
|
Topic :: Internet :: WWW/HTTP
|
||||||
Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
||||||
|
|
||||||
|
@ -22,28 +22,34 @@ packages = find:
|
||||||
include_package_data = True
|
include_package_data = True
|
||||||
zip_safe = False
|
zip_safe = False
|
||||||
install_requires =
|
install_requires =
|
||||||
flask
|
blinker==1.4
|
||||||
flask-wtf
|
cachetools==4.1.0
|
||||||
flask-sqlalchemy<3.0
|
debts==0.5
|
||||||
flask-mail
|
email_validator==1.0.5
|
||||||
Flask-Migrate
|
Flask-Babel==1.0.0
|
||||||
Flask-script
|
Flask-Cors==3.0.8
|
||||||
flask-babel
|
Flask-Mail==0.9.1
|
||||||
flask-restful
|
Flask-Migrate==2.5.3
|
||||||
jinja2
|
Flask-RESTful==0.3.8
|
||||||
blinker
|
Flask-Script==2.0.6
|
||||||
flask-cors
|
Flask-SQLAlchemy==2.4.1
|
||||||
itsdangerous
|
Flask-WTF==0.14.3
|
||||||
email_validator
|
WTForms==2.2.1
|
||||||
debts
|
Flask==1.1.2
|
||||||
|
itsdangerous==1.1.0
|
||||||
|
Jinja2==2.11.2
|
||||||
|
requests==2.22.0
|
||||||
|
SQLAlchemy-Continuum==1.3.9
|
||||||
|
|
||||||
[options.extras_require]
|
[options.extras_require]
|
||||||
dev =
|
dev =
|
||||||
zest.releaser
|
black==19.10b0 ; python_version >= '3.6'
|
||||||
tox
|
flake8==3.7.9
|
||||||
pytest
|
Flask-Testing==0.8.0
|
||||||
flake8
|
isort==4.3.21
|
||||||
Flask-Testing
|
pytest==5.4.1
|
||||||
|
tox==3.14.6
|
||||||
|
zest.releaser==6.20.1
|
||||||
|
|
||||||
[options.entry_points]
|
[options.entry_points]
|
||||||
console_scripts =
|
console_scripts =
|
||||||
|
|
17
tox.ini
17
tox.ini
|
@ -1,5 +1,5 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py37,py36,py35,docs,flake8,black
|
envlist = py38,py37,py36,docs,flake8,black
|
||||||
skip_missing_interpreters = True
|
skip_missing_interpreters = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
@ -9,8 +9,7 @@ commands =
|
||||||
py.test --pyargs ihatemoney.tests.tests
|
py.test --pyargs ihatemoney.tests.tests
|
||||||
|
|
||||||
deps =
|
deps =
|
||||||
-rdev-requirements.txt
|
-e.[dev]
|
||||||
-rrequirements.txt
|
|
||||||
|
|
||||||
# To be sure we are importing ihatemoney pkg from pip-installed version
|
# To be sure we are importing ihatemoney pkg from pip-installed version
|
||||||
changedir = /tmp
|
changedir = /tmp
|
||||||
|
@ -22,15 +21,13 @@ deps =
|
||||||
changedir = {toxinidir}
|
changedir = {toxinidir}
|
||||||
|
|
||||||
[testenv:black]
|
[testenv:black]
|
||||||
commands = black --check --target-version=py34 .
|
commands =
|
||||||
deps =
|
black --check --target-version=py34 .
|
||||||
-rdev-requirements.txt
|
isort -c -rc .
|
||||||
changedir = {toxinidir}
|
changedir = {toxinidir}
|
||||||
|
|
||||||
[testenv:flake8]
|
[testenv:flake8]
|
||||||
commands = flake8 ihatemoney
|
commands = flake8 ihatemoney
|
||||||
deps =
|
|
||||||
-rdev-requirements.txt
|
|
||||||
changedir = {toxinidir}
|
changedir = {toxinidir}
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
|
@ -42,6 +39,6 @@ extend-ignore =
|
||||||
|
|
||||||
[travis]
|
[travis]
|
||||||
python =
|
python =
|
||||||
3.5: py35
|
3.6: py36
|
||||||
3.6: py36, docs, black, flake8
|
|
||||||
3.7: py37
|
3.7: py37
|
||||||
|
3.8: py38, docs, black, flake8
|
||||||
|
|
Loading…
Reference in a new issue