Merge branch 'master' into flowing_master

This commit is contained in:
Tom 2024-02-24 13:47:19 +01:00
commit 411965dbe0
128 changed files with 14342 additions and 6598 deletions

View file

@ -14,9 +14,7 @@ CONTRIBUTORS
docker-compose.* docker-compose.*
Dockerfile Dockerfile
docs docs
LICENSE
Makefile Makefile
MANIFEST.in MANIFEST.in
README.md
SECURITY.md SECURITY.md
tox.ini tox.ini

View file

@ -3,9 +3,9 @@ name: CI to Docker Hub
on: on:
push: push:
tags: ['*'] tags: ['*']
branches: [ master ] branches: [ 'master', 'stable-*' ]
pull_request: pull_request:
branches: [ master ] branches: [ 'master', 'stable-*' ]
jobs: jobs:
@ -61,6 +61,7 @@ jobs:
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache
platforms: linux/amd64,linux/arm64,linux/arm/v7
- name: Image digest - name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }} run: echo ${{ steps.docker_build.outputs.digest }}

View file

@ -2,9 +2,9 @@ name: Test & Docs
on: on:
push: push:
branches: [ master ] branches: [ 'master', 'stable-*' ]
pull_request: pull_request:
branches: [ master ] branches: [ 'master', 'stable-*' ]
jobs: jobs:
build: build:
@ -36,7 +36,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: [3.7, 3.8, 3.9, "3.10", "3.11"] python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12"]
dependencies: [normal] dependencies: [normal]
database: [sqlite] database: [sqlite]
# Test other databases only with one version of Python (Debian buster has 3.7) # Test other databases only with one version of Python (Debian buster has 3.7)
@ -66,6 +66,9 @@ jobs:
- python-version: "3.11" - python-version: "3.11"
dependencies: minimal dependencies: minimal
database: sqlite database: sqlite
- python-version: "3.12"
dependencies: minimal
database: sqlite
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -74,9 +77,9 @@ jobs:
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: 'pip' cache: 'pip'
cache-dependency-path: '**/setup.cfg' cache-dependency-path: '**/pyproject.toml'
- name: Change dependencies to minimal supported versions - name: Change dependencies to minimal supported versions
run: sed -i -e 's/>=/==/g; s/~=.*==\(.*\)/==\1/g; s/~=/==/g;' setup.cfg run: sed -i -e 's/>=/==/g; s/~=.*==\(.*\)/==\1/g; s/~=/==/g;' pyproject.toml
if: matrix.dependencies == 'minimal' if: matrix.dependencies == 'minimal'
- name: Install dependencies - name: Install dependencies
run: | run: |
@ -100,9 +103,4 @@ jobs:
TESTING_SQLALCHEMY_DATABASE_URI: 'mysql+pymysql://root:ihatemoney@localhost:3306/ihatemoney_ci' TESTING_SQLALCHEMY_DATABASE_URI: 'mysql+pymysql://root:ihatemoney@localhost:3306/ihatemoney_ci'
- name: Run Lint & Docs - name: Run Lint & Docs
run: tox -e lint_docs run: tox -e lint_docs
if: matrix.python-version == '3.8' if: matrix.python-version == '3.12'
- name: Run vermin to check Python compat
run: |
python -m pip install vermin
vermin --no-tips --violations -t=3.6 .
if: matrix.python-version == '3.10'

4
.gitignore vendored
View file

@ -1,5 +1,6 @@
*.pyc *.pyc
*.egg-info *.egg-info
*.mo
dist dist
.venv .venv
docs/_build/ docs/_build/
@ -16,4 +17,5 @@ ihatemoney/budget.db
.DS_Store .DS_Store
.idea .idea
.python-version .python-version
.coverage*
prof

View file

@ -1,7 +1,11 @@
version: 2 version: 2
build:
os: ubuntu-22.04
tools:
python: "3.11"
python: python:
version: "3.7"
install: install:
- method: pip - method: pip
path: . path: .

View file

@ -1,11 +0,0 @@
sudo: false
language: python
python:
- "3.7"
- "3.8"
- "3.9"
script: tox
before_install:
- python -m pip install --upgrade pip virtualenv
install:
- pip install tox-travis

View file

@ -2,19 +2,103 @@
This document describes changes between each past release. This document describes changes between each past release.
## 6.0.0 (unreleased) ## 6.2.0 (unreleased)
### Breaking
- Add support for python 3.12 (#757)
## 6.1.3 (2023-11-23)
- Revert update to flask and werkzeug 2.3 because of a regression (see #1272)
## 6.1.2 (2023-11-19)
- Fix password generation command line crash (#1242)
- Update to flask and werkzeug 2.3 (#1244)
## 6.1.1 (2023-10-04)
### Currency conversion API workarounds
We are using an external API for currency conversion. This API recently
started requiring an API key, and this broke I Hate Money in many ways.
This release adds a set of workarounds for this issue. This should restore
basic functionality such as adding bills. However, we had to disable
some operations to prevent crashing:
- Setting or changing the default currency on an existing project is no longer possible.
However, setting a project to "No currency" is still possible.
- Adding or editing a bill with a currency that differs from the default currency
of the project is no longer possible
[Longer-term solutions are being discussed](https://github.com/spiral-project/ihatemoney/issues/1232).
If you are using currencies in your projects, your input is welcome.
### Added
- Simplifies adding a bill with keyboard only (#1221)
- Add details of bills in history (#1223)
- Remember last "For whom?" field when adding a new bill (#1222)
- Speed up unit tests (#1214)
- Update translations for Spanish, Russian, Kannada, Swedish, Polish, German, and Italian
### Fixed
- Fix remembering the last selected payer when switching project (#1224)
## 6.1.0 (2023-07-29)
### Added
- Add RSS feed for each project (#1158)
- Security: require private code to edit a project settings (#1204)
### Fixed
- Fix 404 page crash (#1201)
## 6.0.1 (2023-07-22)
### Added
- Add support for `APPLICATION_ROOT` in Docker container (#1189)
- Improve docker-compose example: admin password and volume for database (#1169)
### Fixed
- Fix docker-compose example quoting (#1164)
- Fix crash when using existing sessions (migrate them to dict) (#1194)
- Add newly created projects to the list of projects (#1193)
## 6.0.0 (2023-07-13)
### Breaking changes
- Drop Python 3.6 support - Drop Python 3.6 support
- Add Python 3.11 support - Add Python 3.11 support
The minimum supported version is now Python 3.7, and the project is The minimum supported version is now Python 3.7, and the project is
tested with up to Python 3.11 tested with up to Python 3.11
### Added
- Enable new languages: Catalan, Czech, Spanish, Persian, Hebrew, Hungarian, Kannada, Serbian, Telugu, Thai
- Build ARM64 and ARMv7 Docker image (#1141)
- Allow bills with an amount of zero (#1133)
- Add confirmation for expense deletion (#1096)
- Display a QR code when inviting people (#1000)
- Add a cancel button when editing a bill for better UX (#1013)
### Fixed
- Fix project deletion in the dashboard (#1094)
- Fix duplicate project name in dropdown list (#1082)
- Fix captcha validation, it should be case insensitive on both side (#1061)
- Fix CSRF on logout (#1040)
- Fix XSS when inviting people by email (#1044)
### Changed ### Changed
- Add a cancel button when editing a bill for better UX - Use a better quality favicon (#1102)
- Translations: Bengali, Indonesian, Polish - Use Flask-Limiter to implement rate limiting (#1054)
- Pin Werkzeug to avoid dropping Python 3.6 compatibility
## 5.2.0 (2022-04-07) ## 5.2.0 (2022-04-07)

View file

@ -17,12 +17,15 @@ bmatticus
Brice Maron Brice Maron
Byron Ullauri Byron Ullauri
Carey Metcalfe Carey Metcalfe
cbrosnan
Daniel Schreiber Daniel Schreiber
DavidRThrashJr DavidRThrashJr
donkers donkers
Edwin Smulders Edwin Smulders
Elizabeth Sherrock Elizabeth Sherrock
Éloi Rivard
eMerzh eMerzh
Erwan Lacoudre
Feth AREZKI Feth AREZKI
Frédéric Sureau Frédéric Sureau
Gianluca De Cola Gianluca De Cola
@ -30,6 +33,8 @@ Glandos
Heimen Stoffels Heimen Stoffels
James Leong James Leong
Jocelyn Delalande Jocelyn Delalande
Jojo144
Lod
Luc Didry Luc Didry
Lucas Verney Lucas Verney
Marien Fressinaud Marien Fressinaud
@ -46,10 +51,12 @@ Quentin Roy
Rémy HUBSCHER Rémy HUBSCHER
Richard Coates Richard Coates
Salamandar Salamandar
Saroj Regmi
THANOS SIOURDAKIS THANOS SIOURDAKIS
Toover Toover
Xavier Mehrenberger Xavier Mehrenberger
Youe Graillot Youe Graillot
zorun zorun
Zottelchen
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.

View file

@ -26,6 +26,7 @@ ENV DEBUG="False" \
SHOW_ADMIN_EMAIL="True" \ SHOW_ADMIN_EMAIL="True" \
SQLALCHEMY_DATABASE_URI="sqlite:////database/ihatemoney.db" \ SQLALCHEMY_DATABASE_URI="sqlite:////database/ihatemoney.db" \
SQLALCHEMY_TRACK_MODIFICATIONS="False" \ SQLALCHEMY_TRACK_MODIFICATIONS="False" \
APPLICATION_ROOT="/" \
ENABLE_CAPTCHA="False" \ ENABLE_CAPTCHA="False" \
LEGAL_LINK="" LEGAL_LINK=""

View file

@ -1,3 +0,0 @@
include *.rst
recursive-include ihatemoney *.rst *.py *.yaml *.po *.mo *.html *.css *.js *.eot *.svg *.woff *.txt *.png *.webp *.ini *.cfg *.j2 *.jpg *.gif *.ico
include LICENSE CONTRIBUTORS CHANGELOG.rst

View file

@ -11,7 +11,7 @@ MAGICK_MOGRIFY := mogrify
.PHONY: all .PHONY: all
all: install ## Alias for install all: install ## Alias for install
.PHONY: install .PHONY: install
install: virtualenv setup.cfg $(INSTALL_STAMP) ## Install dependencies install: virtualenv pyproject.toml $(INSTALL_STAMP) ## Install dependencies
$(INSTALL_STAMP): $(INSTALL_STAMP):
$(VENV)/bin/pip install -U pip $(VENV)/bin/pip install -U pip
$(VENV)/bin/pip install -e . $(VENV)/bin/pip install -e .
@ -23,7 +23,7 @@ $(PYTHON):
$(VIRTUALENV) $(VENV) $(VIRTUALENV) $(VENV)
.PHONY: install-dev .PHONY: install-dev
install-dev: virtualenv setup.cfg $(INSTALL_STAMP) $(DEV_STAMP) ## Install development dependencies install-dev: virtualenv pyproject.toml $(INSTALL_STAMP) $(DEV_STAMP) ## Install development dependencies
$(DEV_STAMP): $(PYTHON) $(DEV_STAMP): $(PYTHON)
$(VENV)/bin/pip install -Ue .[dev] $(VENV)/bin/pip install -Ue .[dev]
touch $(DEV_STAMP) touch $(DEV_STAMP)
@ -36,9 +36,9 @@ remove-install-stamp:
update: remove-install-stamp install ## Update the dependencies update: remove-install-stamp install ## Update the dependencies
.PHONY: serve .PHONY: serve
serve: install ## Run the ihatemoney server serve: install build-translations ## Run the ihatemoney server
@echo 'Running ihatemoney on http://localhost:5000' @echo 'Running ihatemoney on http://localhost:5000'
FLASK_DEBUG=1 FLASK_ENV=development FLASK_APP=ihatemoney.wsgi $(VENV)/bin/flask run --host=0.0.0.0 FLASK_DEBUG=1 FLASK_APP=ihatemoney.wsgi $(VENV)/bin/flask run --host=0.0.0.0
.PHONY: test .PHONY: test
test: install-dev ## Run the tests test: install-dev ## Run the tests
@ -74,8 +74,8 @@ compress-assets: compress-showcase ## Compress static assets
build-translations: ## Build the translations build-translations: ## Build the translations
$(VENV)/bin/pybabel compile -d ihatemoney/translations $(VENV)/bin/pybabel compile -d ihatemoney/translations
.PHONY: update-translations .PHONY: extract-translations
update-translations: ## Extract new translations from source code extract-translations: ## Extract new translations from source code
$(VENV)/bin/pybabel extract --add-comments "I18N:" --strip-comments --omit-header --no-location --mapping-file ihatemoney/babel.cfg -o ihatemoney/messages.pot ihatemoney $(VENV)/bin/pybabel extract --add-comments "I18N:" --strip-comments --omit-header --no-location --mapping-file ihatemoney/babel.cfg -o ihatemoney/messages.pot ihatemoney
$(VENV)/bin/pybabel update -i ihatemoney/messages.pot -d ihatemoney/translations/ $(VENV)/bin/pybabel update -i ihatemoney/messages.pot -d ihatemoney/translations/

View file

@ -22,7 +22,7 @@ highly encouraged to do so.
## Requirements ## Requirements
- **Python**: version 3.7 to 3.11. - **Python**: version 3.7 to 3.12.
- **Backends**: SQLite, PostgreSQL, MariaDB (version 10.3.2 or above), - **Backends**: SQLite, PostgreSQL, MariaDB (version 10.3.2 or above),
Memory. Memory.

View file

@ -4,9 +4,9 @@
| Version | Supported | | Version | Supported |
| ------- | ------------------ | | ------- | ------------------ |
| 5.0.x | :heavy_check_mark: | | 6.2.x | :heavy_check_mark: |
| 4.1.x | :heavy_check_mark: | | 6.1.x | :heavy_check_mark: |
| <= 4.0 | :x: | | <= 6.0 | :x: |
## Reporting a Vulnerability ## Reporting a Vulnerability

View file

@ -23,6 +23,7 @@ SHOW_ADMIN_EMAIL = $SHOW_ADMIN_EMAIL
SQLACHEMY_DEBUG = DEBUG SQLACHEMY_DEBUG = DEBUG
SQLALCHEMY_DATABASE_URI = "$SQLALCHEMY_DATABASE_URI" SQLALCHEMY_DATABASE_URI = "$SQLALCHEMY_DATABASE_URI"
SQLALCHEMY_TRACK_MODIFICATIONS = $SQLALCHEMY_TRACK_MODIFICATIONS SQLALCHEMY_TRACK_MODIFICATIONS = $SQLALCHEMY_TRACK_MODIFICATIONS
APPLICATION_ROOT = "$APPLICATION_ROOT"
ENABLE_CAPTCHA = $ENABLE_CAPTCHA ENABLE_CAPTCHA = $ENABLE_CAPTCHA
LEGAL_LINK = "$LEGAL_LINK" LEGAL_LINK = "$LEGAL_LINK"
EOF EOF

View file

@ -6,6 +6,6 @@ services:
build: . build: .
sut: sut:
image: alpine image: alpine
command: sh -c 'wget -qO- ihatemoney:8000/healthcheck | grep "OK"' command: sh -c 'sleep 5; wget -qO- ihatemoney:8000/healthcheck | grep "OK"'
depends_on: depends_on:
- ihatemoney - ihatemoney

View file

@ -1,4 +1,14 @@
# This is an example. Please change the configuration variables listed here. # This is an example. Please change the configuration variables listed here.
#
# This example uses a volume to persist the sqlite database outside of the container,
# please adapt the local path. If you use a custom PUID and PGID, you need to create
# the local path beforehand with the correct user/group.
#
# You can generate an admin password with: docker run -it --rm --entrypoint ihatemoney ihatemoney/ihatemoney:latest generate_password_hash
# IMPORTANT: replace every dollar character in the result with a double dollar ($ -> $$)
# To disable admin access, simply set the password to an empty string (ADMIN_PASSWORD=)
#
# See https://ihatemoney.readthedocs.io/en/latest/configuration.html to understand all settings.
version: "3.9" version: "3.9"
@ -7,13 +17,13 @@ services:
image: ihatemoney/ihatemoney:latest image: ihatemoney/ihatemoney:latest
environment: environment:
- DEBUG=False - DEBUG=False
- ACTIVATE_ADMIN_DASHBOARD=False
- ACTIVATE_DEMO_PROJECT=True - ACTIVATE_DEMO_PROJECT=True
- ACTIVATE_ADMIN_DASHBOARD=False
- ADMIN_PASSWORD= - ADMIN_PASSWORD=
- ALLOW_PUBLIC_PROJECT_CREATION=True - ALLOW_PUBLIC_PROJECT_CREATION=True
- BABEL_DEFAULT_TIMEZONE=UTC - BABEL_DEFAULT_TIMEZONE=UTC
- GREENLET_TEST_CPP=no - GREENLET_TEST_CPP=no
- MAIL_DEFAULT_SENDER="Budget manager <admin@example.com>" - MAIL_DEFAULT_SENDER=Budget manager <admin@example.com>
- MAIL_PASSWORD= - MAIL_PASSWORD=
- MAIL_PORT=25 - MAIL_PORT=25
- MAIL_SERVER=localhost - MAIL_SERVER=localhost
@ -25,10 +35,13 @@ services:
- SHOW_ADMIN_EMAIL=True - SHOW_ADMIN_EMAIL=True
- SQLALCHEMY_DATABASE_URI=sqlite:////database/ihatemoney.db - SQLALCHEMY_DATABASE_URI=sqlite:////database/ihatemoney.db
- SQLALCHEMY_TRACK_MODIFICATIONS=False - SQLALCHEMY_TRACK_MODIFICATIONS=False
- APPLICATION_ROOT=/
- ENABLE_CAPTCHA=False - ENABLE_CAPTCHA=False
- LEGAL_LINK= - LEGAL_LINK=
- PORT=8000 - PORT=8000
- PUID=0 - PUID=0
- PGID=0 - PGID=0
volumes:
- /path/to/local/dir/for/sqlite/db:/database
ports: ports:
- "8000:8000" - "8000:8000"

View file

@ -34,9 +34,9 @@ the token (of course, you need to authenticate):
$ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo/token $ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo/token
{"token": "WyJ0ZXN0Il0.Rt04fNMmxp9YslCRq8hB6jE9s1Q"} {"token": "WyJ0ZXN0Il0.Rt04fNMmxp9YslCRq8hB6jE9s1Q"}
Make sure to store this token securely: it allows full access to the Make sure to store this token securely: it allows almost full access to the
project. For instance, use it to obtain information about the project project. For instance, use it to obtain information about the project
(replace PROJECT_TOKEN with the actual token): (replace `PROJECT_TOKEN` with the actual token):
$ curl --oauth2-bearer "PROJECT_TOKEN" https://ihatemoney.org/api/projects/demo $ curl --oauth2-bearer "PROJECT_TOKEN" https://ihatemoney.org/api/projects/demo
@ -51,7 +51,8 @@ simply create an URL of the form:
https://ihatemoney.org/demo/join/PROJECT_TOKEN https://ihatemoney.org/demo/join/PROJECT_TOKEN
Such a link grants full access to the project associated with the token. Such a link grants read-write access to the project associated with the token,
but it does not allow to change project settings.
### Projects ### Projects
@ -67,8 +68,8 @@ A project needs the following arguments:
- `name`: the project name (string) - `name`: the project name (string)
- `id`: the project identifier (string without special chars or - `id`: the project identifier (string without special chars or
spaces) spaces)
- `password`: the project password / secret code (string) - `password`: the project password / private code (string)
- `contact_email`: the contact email (string) - `contact_email`: the contact email, used to recover the private code (string)
Optional arguments: Optional arguments:
@ -83,7 +84,9 @@ Here is the command:
-d 'name=yay&id=yay&password=yay&contact_email=yay@notmyidea.org' -d 'name=yay&id=yay&password=yay&contact_email=yay@notmyidea.org'
"yay" "yay"
As you can see, the API returns the identifier of the project. As you can see, the API returns the identifier of the project. It might be different
from what you requested, because the ID is normalized (remove special characters,
change to lowercase, etc).
#### Getting information about the project #### Getting information about the project
@ -108,7 +111,12 @@ Updating a project is done with the `PUT` verb:
$ curl --basic -u yay:yay -X PUT\ $ curl --basic -u yay:yay -X PUT\
https://ihatemoney.org/api/projects/yay -d\ https://ihatemoney.org/api/projects/yay -d\
'name=yay&id=yay&password=yay&contact_email=youpi@notmyidea.org' 'name=yay&id=yay&current_password=yay&password=newyay&contact_email=youpi@notmyidea.org'
You need to give the current private code as the `current_password` field. This is a security
measure to ensure that knowledge of an auth token is not enough to update settings.
Note that in any case you can never change the ID of a project.
#### Deleting a project #### Deleting a project
@ -125,7 +133,7 @@ You can get all the members with a `GET` on
[{"weight": 1, "activated": true, "id": 31, "name": "Arnaud"}, [{"weight": 1, "activated": true, "id": 31, "name": "Arnaud"},
{"weight": 1, "activated": true, "id": 32, "name": "Alexis"}, {"weight": 1, "activated": true, "id": 32, "name": "Alexis"},
{"weight": 1, "activated": true, "id": 33, "name": "Olivier"}, {"weight": 1, "activated": true, "id": 33, "name": "Olivier"},
{"weight": 1, "activated": true, "id": 34, "name": "Fred"}] {"weight": 1, "activated": true, "id": 34, "name": "Jeanne"}]
Add a member with a `POST` request on `/api/projects/<id>/members`: Add a member with a `POST` request on `/api/projects/<id>/members`:
@ -236,7 +244,7 @@ You can get some project stats with a `GET` on
"balance": 10.5 "balance": 10.5
}, },
{ {
"member": {"activated": true, "id": 2, "name": "fred", "weight": 1.0}, "member": {"activated": true, "id": 2, "name": "jeanne", "weight": 1.0},
"paid": 5, "paid": 5,
"spent": 15.5, "spent": 15.5,
"balance": -10.5 "balance": -10.5

View file

@ -1,9 +1,12 @@
import datetime
templates_path = ["_templates"] templates_path = ["_templates"]
source_suffix = ".rst" source_suffix = ".rst"
master_doc = "index" master_doc = "index"
project = "I hate money" project = "I hate money"
copyright = "2011-2021, The 'I hate money' team" year = datetime.datetime.now().strftime("%Y")
copyright = f"2011-{year}, The 'I hate money' team"
version = "5.0" version = "5.0"
release = "5.0" release = "5.0"

View file

@ -30,9 +30,9 @@ Specifies the type of backend to use and its location. More information
on the format used can be found on [the SQLAlchemy on the format used can be found on [the SQLAlchemy
documentation](http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls). documentation](http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls).
- **Default value:** `sqlite:///tmp/ihatemoney.db` - **Default value:** `sqlite:////tmp/ihatemoney.db`
- **Production value:** Set it to some path on your disk. Typically - **Production value:** Set it to some path on your disk. Typically
`sqlite:///home/ihatemoney/ihatemoney.db`. Do *not* store it under `sqlite:////home/ihatemoney/ihatemoney.db`. Do *not* store it under
`/tmp` as this folder is cleared at each boot. `/tmp` as this folder is cleared at each boot.
For example, if you're using MariaDB, use a configuration similar to For example, if you're using MariaDB, use a configuration similar to
@ -127,11 +127,11 @@ ADMIN_PASSWORD needs to be set.
## APPLICATION_ROOT ## APPLICATION_ROOT
If empty, ihatemoney will be served at domain root (e.g: By default, ihatemoney will be served at domain root (e.g:
*http://domain.tld*), if set to `"somestring"`, it will be served from a *http://domain.tld*), if set to `"/somestring"`, it will be served from a
"folder" (e.g: *http://domain.tld/somestring*). "folder" (e.g: *http://domain.tld/somestring*).
- **Default value:** `""` (empty string) - **Default value:** `"/"`
## BABEL_DEFAULT_TIMEZONE ## BABEL_DEFAULT_TIMEZONE
@ -188,3 +188,12 @@ project](https://pythonhosted.org/flask-mail/#configuring-flask-mail)
- **MAIL_USERNAME** : default **None** - **MAIL_USERNAME** : default **None**
- **MAIL_PASSWORD** : default **None** - **MAIL_PASSWORD** : default **None**
- **DEFAULT_MAIL_SENDER** : default **None** - **DEFAULT_MAIL_SENDER** : default **None**
## Configuring password hashes
The werkzeug [generate_password_hash](https://werkzeug.palletsprojects.com/utils/#werkzeug.security.generate_password_hash)
is used to create password hashes. By default the default werkzeug values
are used, however you can customize those values with:
- **PASSWORD_HASH_METHOD** : default **None**
- **PASSWORD_HASH_SALT_LENGTH** : default **None**

View file

@ -190,6 +190,19 @@ revision file which can be created with the following command:
You then need to write the migration steps yourself. You then need to write the migration steps yourself.
## Repository rules
- Please, try to keep it to **one pull request per feature:** if you want to do more
than one thing, send multiple pull requests. It will be easier for us to review and
merge.
- **Document your code:** if you add a new feature, please document it in the
- All the people working on this project do it on their spare time. So please, be
patient if we don't answer right away.
- We try to have two maintainers review the pull requests before merging it. So please,
be patient if we don't merge it right away. After one week, only one maintainer approval
is required.
## How to build the documentation ? ## How to build the documentation ?
The documentation is using The documentation is using
@ -261,10 +274,9 @@ In order to issue a new release, follow the following steps:
make compress-assets make compress-assets
- Build the translations: - Extract the translations:
make update-translations make extract-translations
make build-translations
- If you're not completely sure of yourself at this point, you can - If you're not completely sure of yourself at this point, you can
optionally: create a new branch, push it, open a pull request, check optionally: create a new branch, push it, open a pull request, check
@ -281,7 +293,7 @@ Index](https://pypi.org) (PyPI) and publish a tag in the git repository.
::: {note} ::: {note}
The above command will prompt for version number, handle The above command will prompt for version number, handle
`CHANGELOG.md` and `setup.cfg` updates, package creation, `CHANGELOG.md` and `pyproject.toml` updates, package creation,
pypi upload. It will prompt you before each step to get your consent. pypi upload. It will prompt you before each step to get your consent.
::: :::

View file

@ -83,7 +83,7 @@ Some Paas (Platform-as-a-Service), provide a documentation or even a quick insta
«Ihatemoney» depends on: «Ihatemoney» depends on:
- **Python**: any version from 3.7 to 3.11 will work. - **Python**: any version from 3.7 to 3.12 will work.
- **A database backend**: choose among SQLite, PostgreSQL, MariaDB (>= - **A database backend**: choose among SQLite, PostgreSQL, MariaDB (>=
10.3.2). 10.3.2).
- **Virtual environment** (recommended): [python3-venv]{.title-ref} - **Virtual environment** (recommended): [python3-venv]{.title-ref}
@ -133,6 +133,9 @@ Install the latest release with pip:
Once installed, you can start a test server: Once installed, you can start a test server:
ihatemoney generate-config ihatemoney.cfg > ihatemoney.cfg
export IHATEMONEY_SETTINGS_FILE_PATH=$PWD/ihatemoney.cfg
ihatemoney db upgrade head
ihatemoney runserver ihatemoney runserver
And point your browser at <http://localhost:5000>. And point your browser at <http://localhost:5000>.

View file

@ -11,39 +11,48 @@ expenses in the first place!
That being said, there are a few mechanisms to limit the impact of a That being said, there are a few mechanisms to limit the impact of a
malicious member and to manage changes in membership (e.g. ensuring that malicious member and to manage changes in membership (e.g. ensuring that
a previous member can no longer access the project). But these a previous member can no longer access the project). But these
mechanisms don\'t prevent a malicious member from breaking things in mechanisms don't prevent a malicious member from breaking things in
your project! your project!
## Security model ## Security model
A project has three main parameters when it comes to security: A project has four main parameters when it comes to security:
- **project identifier** (equivalent to a \"login\") - **project identifier** (equivalent to a \"login\")
- **private code** (equivalent to a \"password\") - **private code** (equivalent to a \"password\")
- **token** (cryptographically derived from the private code) - **auth token** (cryptographically derived from the private code)
- **feed token** (also cryptographically derived from the private code)
Somebody with the private code can: Somebody with the **private code** can:
- access the project through the web interface or the API - access the project through the web interface or the API
- add, modify or remove participants
- add, modify or remove bills - add, modify or remove bills
- view statistics of the project
- view project history - view project history
- change basic settings of the project - change basic settings of the project
- change the email address associated to the project - change the email address associated to the project
- change the private code of the project - change the private code of the project
- delete the project
Somebody with the token can manipulate the project through the API to do Somebody with the **auth token** can manipulate the project through the API:
essentially the same thing:
- access the project - access the project
- add, modify or remove participants
- add, modify or remove bills - add, modify or remove bills
- change basic settings of the project - view statistics of the project
- change the email address associated to the project - delete the project
- change the private code of the project
The token can also be used to build \"invitation links\". These links The auth token is not enough to change basic settings of the project,
or to change the email address or the private code.
The auth token can also be used to build "invitation links". These links
allow to login on the web interface without knowing the private code, allow to login on the web interface without knowing the private code,
see below. see below.
Somebody with the **feed token** can only access a read-only view of the project
through a RSS feed (at `/<project_id>/feed/<token>.xml`).
## Giving access to a project ## Giving access to a project
There are two main ways to give access to a project to a new person: There are two main ways to give access to a project to a new person:
@ -57,25 +66,36 @@ The second method is interesting because it does not reveal the private
code. In particular, somebody that is logged-in through the invitation code. In particular, somebody that is logged-in through the invitation
link will not be able to change the private code, because the web link will not be able to change the private code, because the web
interface requires a confirmation of the existing private code to change interface requires a confirmation of the existing private code to change
it. However, a motivated person could extract the token from the it. Similarly, changing other important settings or deleting the project
from the web interface requires knowledge of the private code.
However, a motivated person could extract the auth token from the
invitation link, use it to access the project through the API, and invitation link, use it to access the project through the API, and
change the private code through the API. delete the project through the API. This is a [known issue](https://github.com/spiral-project/ihatemoney/issues/1206).
## Removing access to a project ## Removing access to a project
If a person should no longer be able to access a project, the only way If a person should no longer be able to access a project, the only way
is to change the private code. is to change the private code for the whole project.
This will also automatically change the token: old invitation links This will prevent anybody from logging in with the old private code.
won\'t work anymore, and anybody with the old token will no longer be However, anybody with an existing session cookie will still have
able to access the project through the API. access to the project. This is a [known issue](https://github.com/spiral-project/ihatemoney/issues/857)
that should be fixed.
Changing the private code will automatically change the auth token:
old invitation links won't work anymore, and anybody with the old token
will no longer be able to access the project through the API.
This will also automatically change the feed token, so that existing
links to the RSS feed for the project will no longer work.
## Recovering access to a project ## Recovering access to a project
If the private code is no longer known, the creator of the project can If the private code is no longer known, the creator of the project can
still recover access. He/she must have provided an email address when still recover access. He/she must have provided an email address when
creating the project, and Ihatemoney can send a reset link to this email creating the project, and Ihatemoney can send a reset link to this email
address (classical \"forgot your password\" functionality). address (classical "forgot your password" functionality).
Note, however, that somebody with the private code could have changed Note, however, that somebody with the private code could have changed
the email address in the settings at any time. the email address in the settings at any time.
@ -91,6 +111,6 @@ Note, however, that the history feature is primarily meant to protect
against mistakes: a malicious member can easily remove all entries from against mistakes: a malicious member can easily remove all entries from
the history! the history!
The best defense against this kind of issues is\... backups! All data The best defense against this kind of issues is... backups! All data
for a project can be exported through the settings page or through the for a project can be exported through the settings page or through the
API. API. The server administrator can also backup the database.

11
hatch_build.py Normal file
View file

@ -0,0 +1,11 @@
import sys
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
class CustomBuildHook(BuildHookInterface):
def initialize(self, version, build_data):
sys.path.insert(0, "./ihatemoney")
from babel_utils import compile_catalogs
compile_catalogs()

View file

@ -1,3 +1,2 @@
[python: **.py] [python: **.py]
[jinja2: **/templates/**.html] [jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_

11
ihatemoney/babel_utils.py Normal file
View file

@ -0,0 +1,11 @@
from pathlib import Path
from babel.messages.frontend import compile_catalog
def compile_catalogs():
cmd = compile_catalog()
cmd.directory = Path(__file__).parent / "translations"
cmd.statistics = True
cmd.finalize_options()
cmd.run()

View file

@ -47,11 +47,14 @@ ACTIVATE_ADMIN_DASHBOARD = False
# service over plain HTTP. # service over plain HTTP.
SESSION_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True
# Set this to a URL path under which the application will be served. Defaults to "/"
APPLICATION_ROOT = "/"
# You can activate an optional CAPTCHA if you want to. It can be helpful # You can activate an optional CAPTCHA if you want to. It can be helpful
# to filter spammer bots. # to filter spammer bots.
# ENABLE_CAPTCHA = True ENABLE_CAPTCHA = False
# You may want to point to a special legal page, for instance to give information # You may want to point to a special legal page, for instance to give information
# about GDPR, or how you handle the data of your users. # about GDPR, or how you handle the data of your users.
# Set this variable to the URL you want. # Set this variable to the URL you want.
# LEGAL_LINK = "" LEGAL_LINK = ""

View file

@ -36,13 +36,181 @@ class CurrencyConverter(object, metaclass=Singleton):
return rates return rates
def get_currencies(self, with_no_currency=True): def get_currencies(self, with_no_currency=True):
rates = [ currencies = [
rate "AED",
for rate in self.get_rates() "AFN",
if with_no_currency or rate != self.no_currency "ALL",
"AMD",
"ANG",
"AOA",
"ARS",
"AUD",
"AWG",
"AZN",
"BAM",
"BBD",
"BDT",
"BGN",
"BHD",
"BIF",
"BMD",
"BND",
"BOB",
"BRL",
"BSD",
"BTC",
"BTN",
"BWP",
"BYN",
"BZD",
"CAD",
"CDF",
"CHF",
"CLF",
"CLP",
"CNH",
"CNY",
"COP",
"CRC",
"CUC",
"CUP",
"CVE",
"CZK",
"DJF",
"DKK",
"DOP",
"DZD",
"EGP",
"ERN",
"ETB",
"EUR",
"FJD",
"FKP",
"GBP",
"GEL",
"GGP",
"GHS",
"GIP",
"GMD",
"GNF",
"GTQ",
"GYD",
"HKD",
"HNL",
"HRK",
"HTG",
"HUF",
"IDR",
"ILS",
"IMP",
"INR",
"IQD",
"IRR",
"ISK",
"JEP",
"JMD",
"JOD",
"JPY",
"KES",
"KGS",
"KHR",
"KMF",
"KPW",
"KRW",
"KWD",
"KYD",
"KZT",
"LAK",
"LBP",
"LKR",
"LRD",
"LSL",
"LYD",
"MAD",
"MDL",
"MGA",
"MKD",
"MMK",
"MNT",
"MOP",
"MRU",
"MUR",
"MVR",
"MWK",
"MXN",
"MYR",
"MZN",
"NAD",
"NGN",
"NIO",
"NOK",
"NPR",
"NZD",
"OMR",
"PAB",
"PEN",
"PGK",
"PHP",
"PKR",
"PLN",
"PYG",
"QAR",
"RON",
"RSD",
"RUB",
"RWF",
"SAR",
"SBD",
"SCR",
"SDG",
"SEK",
"SGD",
"SHP",
"SLL",
"SOS",
"SRD",
"SSP",
"STD",
"STN",
"SVC",
"SYP",
"SZL",
"THB",
"TJS",
"TMT",
"TND",
"TOP",
"TRY",
"TTD",
"TWD",
"TZS",
"UAH",
"UGX",
"USD",
"UYU",
"UZS",
"VEF",
"VES",
"VND",
"VUV",
"WST",
"XAF",
"XAG",
"XAU",
"XCD",
"XDR",
"XOF",
"XPD",
"XPF",
"XPT",
"YER",
"ZAR",
"ZMW",
"ZWL",
] ]
rates.sort(key=lambda rate: "" if rate == self.no_currency else rate) if with_no_currency:
return rates currencies.append(self.no_currency)
return currencies
def exchange_currency(self, amount, source_currency, dest_currency): def exchange_currency(self, amount, source_currency, dest_currency):
if ( if (

View file

@ -6,33 +6,43 @@ SECRET_KEY = "tralala"
MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>" MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>"
SHOW_ADMIN_EMAIL = True SHOW_ADMIN_EMAIL = True
ACTIVATE_DEMO_PROJECT = True ACTIVATE_DEMO_PROJECT = True
ACTIVATE_ADMIN_DASHBOARD = False
ADMIN_PASSWORD = "" ADMIN_PASSWORD = ""
ALLOW_PUBLIC_PROJECT_CREATION = True ALLOW_PUBLIC_PROJECT_CREATION = True
ACTIVATE_ADMIN_DASHBOARD = False SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = False APPLICATION_ROOT = "/"
TEMPLATES_AUTO_RELOAD = True ENABLE_CAPTCHA = False
LEGAL_LINK = ""
SUPPORTED_LANGUAGES = [ SUPPORTED_LANGUAGES = [
"ca",
"cs",
"de", "de",
"el", "el",
"en", "en",
"eo", "eo",
"es",
"es_419", "es_419",
"fa",
"fr", "fr",
"he",
"hi", "hi",
"hu",
"id", "id",
"it", "it",
"ja", "ja",
"kn",
"nb_NO", "nb_NO",
"nl", "nl",
"pl", "pl",
"pt", "pt",
"pt_BR", "pt_BR",
"ru", "ru",
"sr",
"sv", "sv",
"ta", "ta",
"te",
"th",
"tr", "tr",
"uk", "uk",
"zh_Hans", "zh_Hans",
] ]
ENABLE_CAPTCHA = False
LEGAL_LINK = ""

View file

@ -9,7 +9,7 @@ from flask_babel import lazy_gettext as _
from flask_wtf.file import FileAllowed, FileField, FileRequired from flask_wtf.file import FileAllowed, FileField, FileRequired
from flask_wtf.form import FlaskForm from flask_wtf.form import FlaskForm
from markupsafe import Markup from markupsafe import Markup
from werkzeug.security import check_password_hash, generate_password_hash from werkzeug.security import check_password_hash
from wtforms.fields import ( from wtforms.fields import (
BooleanField, BooleanField,
DateField, DateField,
@ -43,6 +43,7 @@ from ihatemoney.models import Bill, LoggingMode, Person, Project
from ihatemoney.utils import ( from ihatemoney.utils import (
em_surround, em_surround,
eval_arithmetic_expression, eval_arithmetic_expression,
generate_password_hash,
render_localized_currency, render_localized_currency,
slugify, slugify,
) )
@ -66,6 +67,9 @@ def get_billform_for(project, set_default=True, **kwargs):
if form.original_currency.data is None: if form.original_currency.data is None:
form.original_currency.data = project.default_currency form.original_currency.data = project.default_currency
# Used in validate_original_currency
form.project_currency = project.default_currency
show_no_currency = form.original_currency.data == CurrencyConverter.no_currency show_no_currency = form.original_currency.data == CurrencyConverter.no_currency
form.original_currency.choices = [ form.original_currency.choices = [
@ -122,6 +126,11 @@ class CalculatorStringField(StringField):
class EditProjectForm(FlaskForm): class EditProjectForm(FlaskForm):
name = StringField(_("Project name"), validators=[DataRequired()]) name = StringField(_("Project name"), validators=[DataRequired()])
current_password = PasswordField(
_("Current private code"),
description=_("Enter existing private code to edit project"),
validators=[DataRequired()],
)
# If empty -> don't change the password # If empty -> don't change the password
password = PasswordField( password = PasswordField(
_("New private code"), _("New private code"),
@ -155,6 +164,13 @@ class EditProjectForm(FlaskForm):
for currency_name in self.currency_helper.get_currencies() for currency_name in self.currency_helper.get_currencies()
] ]
def validate_current_password(self, field):
project = Project.query.get(self.id.data)
if project is None:
raise ValidationError(_("Unknown error"))
if not check_password_hash(project.password, self.current_password.data):
raise ValidationError(_("Invalid private code."))
@property @property
def logging_preference(self): def logging_preference(self):
"""Get the LoggingMode object corresponding to current form data.""" """Get the LoggingMode object corresponding to current form data."""
@ -173,12 +189,20 @@ class EditProjectForm(FlaskForm):
and field.data == CurrencyConverter.no_currency and field.data == CurrencyConverter.no_currency
and project.has_multiple_currencies() and project.has_multiple_currencies()
): ):
raise ValidationError( msg = _(
_( "This project cannot be set to 'no currency'"
"This project cannot be set to 'no currency'" " because it contains bills in multiple currencies."
" because it contains bills in multiple currencies."
)
) )
raise ValidationError(msg)
if (
project is not None
and field.data != CurrencyConverter.no_currency
and project.has_bills()
):
msg = _(
"Cannot change project currency because currency conversion is broken"
)
raise ValidationError(msg)
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"""
@ -213,7 +237,9 @@ class ImportProjectForm(FlaskForm):
class ProjectForm(EditProjectForm): class ProjectForm(EditProjectForm):
id = StringField(_("Project identifier"), validators=[DataRequired()]) id = StringField(_("Project identifier"), validators=[DataRequired()])
# This field overrides the one from EditProjectForm # Remove this field that is inherited from EditProjectForm
current_password = None
# This field overrides the one from EditProjectForm (to make it mandatory)
password = PasswordField(_("Private code"), validators=[DataRequired()]) password = PasswordField(_("Private code"), validators=[DataRequired()])
submit = SubmitField(_("Create the project")) submit = SubmitField(_("Create the project"))
@ -392,12 +418,21 @@ class BillForm(FlaskForm):
self.payed_for.data = self.payed_for.default self.payed_for.data = self.payed_for.default
def validate_amount(self, field): def validate_amount(self, field):
if field.data == "0": if decimal.Decimal(field.data) > decimal.MAX_EMAX:
raise ValidationError(_("Bills can't be null"))
elif decimal.Decimal(field.data) > decimal.MAX_EMAX:
# See https://github.com/python-babel/babel/issues/821 # See https://github.com/python-babel/babel/issues/821
raise ValidationError(f"Result is too high: {field.data}") raise ValidationError(f"Result is too high: {field.data}")
def validate_original_currency(self, field):
# Workaround for currency API breakage
# See #1232
if field.data not in [CurrencyConverter.no_currency, self.project_currency]:
msg = _(
"Failed to convert from %(bill_currency)s currency to %(project_currency)s",
bill_currency=field.data,
project_currency=self.project_currency,
)
raise ValidationError(msg)
def validate_bill_type(self, field): def validate_bill_type(self, field):
if (field.data, field.data) not in Project.bill_types: if (field.data, field.data) not in Project.bill_types:
raise ValidationError(_("Invalid Bill Type")) raise ValidationError(_("Invalid Bill Type"))
@ -443,7 +478,7 @@ class MemberForm(FlaskForm):
class InviteForm(FlaskForm): class InviteForm(FlaskForm):
emails = StringField(_("People to notify"), render_kw={"class": "tag"}) emails = StringField(_("People to notify"), render_kw={"class": "tag"})
submit = SubmitField(_("Send invites")) submit = SubmitField(_("Send the invitations"))
def validate_emails(self, field): def validate_emails(self, field):
for email in [email.strip() for email in self.emails.data.split(",")]: for email in [email.strip() for email in self.emails.data.split(",")]:

View file

@ -83,10 +83,26 @@ def get_history(project, human_readable_names=True):
"time": version.transaction.issued_at, "time": version.transaction.issued_at,
"operation_type": version.operation_type, "operation_type": version.operation_type,
"object_type": object_type, "object_type": object_type,
"bill_details": None,
"object_desc": object_str, "object_desc": object_str,
"ip": version.transaction.remote_addr, "ip": version.transaction.remote_addr,
} }
if object_type == "Bill":
if version.operation_type == Operation.INSERT or not version.previous:
detailed_version = version
else:
detailed_version = version.previous
details = {
"date": detailed_version.date,
"payer": describe_version(detailed_version.payer),
"amount": detailed_version.amount,
"owers": [describe_version(o) for o in detailed_version.owers],
"external_link": detailed_version.external_link,
"original_currency": detailed_version.original_currency,
}
common_properties["bill_details"] = details
if version.operation_type == Operation.UPDATE: if version.operation_type == Operation.UPDATE:
# Only iterate the changeset if the previous version # Only iterate the changeset if the previous version
# Was logged # Was logged
@ -111,7 +127,7 @@ def get_history(project, human_readable_names=True):
): ):
del changeset["converted_amount"] del changeset["converted_amount"]
for (prop, (val_before, val_after)) in changeset.items(): for prop, (val_before, val_after) in changeset.items():
if human_readable_names: if human_readable_names:
if prop == "payer_id": if prop == "payer_id":
prop = "payer" prop = "payer"

View file

@ -7,11 +7,10 @@ import sys
import click import click
from flask.cli import FlaskGroup from flask.cli import FlaskGroup
from werkzeug.security import generate_password_hash
from ihatemoney.models import Project, db from ihatemoney.models import Project, db
from ihatemoney.run import create_app from ihatemoney.run import create_app
from ihatemoney.utils import create_jinja_env from ihatemoney.utils import create_jinja_env, generate_password_hash
@click.group(cls=FlaskGroup, create_app=create_app) @click.group(cls=FlaskGroup, create_app=create_app)
@ -33,14 +32,14 @@ def runserver(ctx):
ctx.forward(run) ctx.forward(run)
@click.command(name="generate_password_hash") @cli.command(name="generate_password_hash")
def password_hash(): def password_hash():
"""Get password from user and hash it without printing it in clear text.""" """Get password from user and hash it without printing it in clear text."""
password = getpass.getpass(prompt="Password: ") password = getpass.getpass(prompt="Password: ")
print(generate_password_hash(password)) print(generate_password_hash(password))
@click.command() @cli.command()
@click.argument( @click.argument(
"config_file", "config_file",
type=click.Choice( type=click.Choice(

View file

@ -1,3 +1,7 @@
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
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."
@ -6,6 +10,12 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "" msgstr ""
msgid "Current private code"
msgstr ""
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "" msgstr ""
@ -27,15 +37,18 @@ msgstr ""
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
msgid "Unknown error"
msgstr ""
msgid "Invalid private code."
msgstr ""
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr ""
msgid "Import"
msgstr "" msgstr ""
msgid "Project identifier" msgid "Project identifier"
@ -65,12 +78,6 @@ msgstr ""
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "" msgstr ""
msgid "Unknown error"
msgstr ""
msgid "Invalid private code."
msgstr ""
msgid "Get in" msgid "Get in"
msgstr "" msgstr ""
@ -95,16 +102,16 @@ msgstr ""
msgid "Reset password" msgid "Reset password"
msgstr "" msgstr ""
msgid "Date" msgid "When?"
msgstr "" msgstr ""
msgid "What?" msgid "What?"
msgstr "" msgstr ""
msgid "Payer" msgid "Who paid?"
msgstr "" msgstr ""
msgid "Amount paid" msgid "How much?"
msgstr "" msgstr ""
msgid "Currency" msgid "Currency"
@ -129,9 +136,6 @@ msgstr ""
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "" msgstr ""
msgid "Bills can't be null"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -153,13 +157,25 @@ msgstr ""
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "" msgstr ""
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "" msgstr ""
msgid "Logout"
msgstr ""
msgid "Please check the email configuration of the server."
msgstr ""
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "" msgstr ""
@ -187,7 +203,7 @@ msgstr ""
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "" msgstr ""
#, python-format #, python-format
@ -200,10 +216,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "" msgstr ""
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "" msgstr ""
@ -212,14 +224,9 @@ msgid ""
"still use the project normally." "still use the project normally."
msgstr "" msgstr ""
#, python-format
msgid "The project identifier is %(project)s"
msgstr ""
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
msgid "No token provided" msgid "No token provided"
@ -234,10 +241,14 @@ msgstr ""
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "" msgstr ""
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "" msgstr ""
msgid "" msgid ""
@ -245,12 +256,18 @@ msgid ""
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr ""
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "" msgstr ""
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr ""
@ -258,10 +275,7 @@ msgstr ""
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "" msgstr ""
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
#, python-format #, python-format
@ -304,6 +318,10 @@ msgstr ""
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "" msgstr ""
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "" msgstr ""
@ -364,7 +382,7 @@ msgstr ""
msgid "edit" msgid "edit"
msgstr "" msgstr ""
msgid "delete" msgid "Delete project"
msgstr "" msgstr ""
msgid "show" msgid "show"
@ -379,19 +397,10 @@ msgstr ""
msgid "Get it on" msgid "Get it on"
msgstr "" msgstr ""
msgid "Are you sure?"
msgstr ""
msgid "Edit project" msgid "Edit project"
msgstr "" msgstr ""
msgid "Delete project" msgid "Import project"
msgstr ""
msgid "Import JSON"
msgstr ""
msgid "Choose file"
msgstr "" msgstr ""
msgid "Download project's data" msgid "Download project's data"
@ -418,18 +427,27 @@ msgstr ""
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "" msgstr ""
msgid "Edit the project" msgid "Save changes"
msgstr "" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
msgid "Import previously exported project"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Edit this bill" msgid "Edit this bill"
msgstr "" msgstr ""
msgid "Add a bill" msgid "Add a bill"
msgstr "" msgstr ""
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr ""
@ -448,9 +466,6 @@ msgstr ""
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "" msgstr ""
msgid "Send the invitations"
msgstr ""
msgid "Download" msgid "Download"
msgstr "" msgstr ""
@ -515,23 +530,18 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"disabling project history. You can\n" msgstr ""
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
"data-target=\"#confirm-erase\">clear project history</a> to remove " msgid "You can clear the project history to remove them."
"them.</i></p>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
@ -542,18 +552,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "" msgstr ""
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "Time" msgid "Time"
msgstr "" msgstr ""
@ -615,9 +625,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr ""
msgid "Amount" msgid "Amount"
msgstr "" msgstr ""
msgid "Date"
msgstr ""
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "" msgstr ""
@ -718,6 +734,9 @@ msgstr ""
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "" msgstr ""
@ -727,7 +746,8 @@ msgstr ""
msgid "Dashboard" msgid "Dashboard"
msgstr "" msgstr ""
msgid "Logout" #, python-format
msgid "Please retry after %(date)s."
msgstr "" msgstr ""
msgid "Code" msgid "Code"
@ -761,30 +781,21 @@ msgstr ""
msgid "Invite people" msgid "Invite people"
msgstr "" msgstr ""
msgid "You should start by adding participants"
msgstr ""
msgid "Add a new bill"
msgstr ""
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr ""
msgid "When?" msgid "You should start by adding participants"
msgstr "" msgstr ""
msgid "Who paid?" msgid "Add a new bill"
msgstr "" msgstr ""
msgid "For what?" msgid "For what?"
msgstr "" msgstr ""
msgid "How much?"
msgstr ""
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "" msgstr ""
@ -793,19 +804,19 @@ msgstr ""
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "" msgstr ""
msgid "delete"
msgstr ""
msgid "No bills" msgid "No bills"
msgstr "" msgstr ""
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "" msgstr ""
msgid "You probably want to" msgid "Add your first bill"
msgstr "" msgstr ""
msgid "add a bill" msgid "Add the first participant"
msgstr ""
msgid "add participants"
msgstr "" msgstr ""
msgid "Password reminder" msgid "Password reminder"
@ -828,31 +839,48 @@ msgstr ""
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "" msgstr ""
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
msgid "Identifier:" msgid "Scan QR code"
msgstr "" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "" msgstr ""
msgid "Send via Emails" msgid "Send via Emails"
msgstr "" msgstr ""
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you." msgstr ""
msgid "Share Identifier & code"
msgstr ""
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr ""
msgid "Private code:"
msgstr ""
msgid "the private code was defined when you created the project"
msgstr "" msgstr ""
msgid "Who pays?" msgid "Who pays?"

View file

@ -18,10 +18,10 @@ from sqlalchemy import orm
from sqlalchemy.sql import func from sqlalchemy.sql import func
from sqlalchemy_continuum import make_versioned, version_class from sqlalchemy_continuum import make_versioned, version_class
from sqlalchemy_continuum.plugins import FlaskPlugin from sqlalchemy_continuum.plugins import FlaskPlugin
from werkzeug.security import generate_password_hash
from ihatemoney.currency_convertor import CurrencyConverter from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.utils import get_members, same_bill from ihatemoney.monkeypath_continuum import PatchedTransactionFactory
from ihatemoney.utils import generate_password_hash, get_members, same_bill
from ihatemoney.versioning import ( from ihatemoney.versioning import (
ConditionalVersioningManager, ConditionalVersioningManager,
LoggingMode, LoggingMode,
@ -35,6 +35,8 @@ make_versioned(
# Conditionally Disable the versioning based on each # Conditionally Disable the versioning based on each
# project's privacy preferences # project's privacy preferences
tracking_predicate=version_privacy_predicate, tracking_predicate=version_privacy_predicate,
# MonkeyPatching
transaction_cls=PatchedTransactionFactory(),
), ),
plugins=[ plugins=[
FlaskPlugin( FlaskPlugin(
@ -474,7 +476,8 @@ class Project(db.Model):
"""Generate a timed and serialized JsonWebToken """Generate a timed and serialized JsonWebToken
:param token_type: Either "auth" for authentication (invalidated when project code changed), :param token_type: Either "auth" for authentication (invalidated when project code changed),
or "reset" for password reset (invalidated after expiration) or "reset" for password reset (invalidated after expiration),
or "feed" for project feeds (invalidated when project code changed)
""" """
if token_type == "reset": if token_type == "reset":
@ -497,9 +500,10 @@ class Project(db.Model):
:param token: Serialized TimedJsonWebToken :param token: Serialized TimedJsonWebToken
:param token_type: Either "auth" for authentication (invalidated when project code changed), :param token_type: Either "auth" for authentication (invalidated when project code changed),
or "reset" for password reset (invalidated after expiration) or "reset" for password reset (invalidated after expiration),
:param project_id: Project ID. Used for token_type "auth" to use the password as serializer or "feed" for project feeds (invalidated when project code changed)
secret key. :param project_id: Project ID. Used for token_type "auth" and "feed" to use the password
as serializer secret key.
:param max_age: Token expiration time (in seconds). Only used with token_type "reset" :param max_age: Token expiration time (in seconds). Only used with token_type "reset"
""" """
loads_kwargs = {} loads_kwargs = {}

View file

@ -0,0 +1,97 @@
from collections import OrderedDict
import six
import sqlalchemy as sa
from sqlalchemy_continuum import __version__ as continuum_version
from sqlalchemy_continuum.exc import ImproperlyConfigured
from sqlalchemy_continuum.transaction import (
TransactionBase,
TransactionFactory,
create_triggers,
)
if continuum_version != "1.3.14":
import warnings
warnings.warn(
"SQLAlchemy-continuum version changed. Please check monkeypatching usefulness."
)
class PatchedTransactionFactory(TransactionFactory):
"""
Monkeypatching TransactionFactory for
https://github.com/kvesteri/sqlalchemy-continuum/issues/264
There is no easy way to really remove Sequence without redefining the whole method. So,
this is a copy/paste. :/
"""
def create_class(self, manager):
"""
Create Transaction class.
"""
class Transaction(manager.declarative_base, TransactionBase):
__tablename__ = "transaction"
__versioning_manager__ = manager
id = sa.Column(
sa.types.BigInteger,
# sa.schema.Sequence('transaction_id_seq'),
primary_key=True,
autoincrement=True,
)
if self.remote_addr:
remote_addr = sa.Column(sa.String(50))
if manager.user_cls:
user_cls = manager.user_cls
Base = manager.declarative_base
try:
registry = Base.registry._class_registry
except AttributeError: # SQLAlchemy < 1.4
registry = Base._decl_class_registry
if isinstance(user_cls, six.string_types):
try:
user_cls = registry[user_cls]
except KeyError:
raise ImproperlyConfigured(
"Could not build relationship between Transaction"
" and %s. %s was not found in declarative class "
"registry. Either configure VersioningManager to "
"use different user class or disable this "
"relationship " % (user_cls, user_cls)
)
user_id = sa.Column(
sa.inspect(user_cls).primary_key[0].type,
sa.ForeignKey(sa.inspect(user_cls).primary_key[0]),
index=True,
)
user = sa.orm.relationship(user_cls)
def __repr__(self):
fields = ["id", "issued_at", "user"]
field_values = OrderedDict(
(field, getattr(self, field))
for field in fields
if hasattr(self, field)
)
return "<Transaction %s>" % ", ".join(
(
"%s=%r" % (field, value)
if not isinstance(value, six.integer_types)
# We want the following line to ensure that longs get
# shown without the ugly L suffix on python 2.x
# versions
else "%s=%d" % (field, value)
for field, value in field_values.items()
)
)
if manager.options["native_versioning"]:
create_triggers(Transaction)
return Transaction

View file

@ -86,7 +86,6 @@ def load_configuration(app, configuration=None):
def validate_configuration(app): def validate_configuration(app):
if app.config["SECRET_KEY"] == default_settings.SECRET_KEY: if app.config["SECRET_KEY"] == default_settings.SECRET_KEY:
warnings.warn( warnings.warn(
"Running a server without changing the SECRET_KEY can lead to" "Running a server without changing the SECRET_KEY can lead to"
@ -203,7 +202,23 @@ def create_app(
default_timezone = str(LOCALTZ) default_timezone = str(LOCALTZ)
except pytz.exceptions.UnknownTimeZoneError: except pytz.exceptions.UnknownTimeZoneError:
pass pass
babel = Babel(app, default_timezone=default_timezone)
def get_locale():
# get the lang from the session if defined, fallback on the browser "accept
# languages" header.
lang = session.get(
"lang",
request.accept_languages.best_match(app.config["SUPPORTED_LANGUAGES"]),
)
setattr(g, "lang", lang)
return lang
if hasattr(Babel, "localeselector"):
# Compatibility for flask-babel <= 2
babel = Babel(app, default_timezone=default_timezone)
babel.localeselector(get_locale)
else:
Babel(app, default_timezone=default_timezone, locale_selector=get_locale)
# Undocumented currencyformat filter from flask_babel is forwarding to Babel format_currency # Undocumented currencyformat filter from flask_babel is forwarding to Babel format_currency
# We overwrite it to remove the currency sign ¤ when there is no currency # We overwrite it to remove the currency sign ¤ when there is no currency
@ -224,17 +239,6 @@ def create_app(
app.jinja_env.filters["currency"] = currency app.jinja_env.filters["currency"] = currency
@babel.localeselector
def get_locale():
# get the lang from the session if defined, fallback on the browser "accept
# languages" header.
lang = session.get(
"lang",
request.accept_languages.best_match(app.config["SUPPORTED_LANGUAGES"]),
)
setattr(g, "lang", lang)
return lang
return app return app

View file

@ -14,18 +14,22 @@ body {
.navbar-brand span { .navbar-brand span {
color: #abe128; color: #abe128;
} }
.navbar h1 { .navbar h1 {
font-size: 1rem; font-size: 1rem;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.navbar .secondary-nav { .navbar .secondary-nav {
text-align: right; text-align: right;
flex-direction: row-reverse; flex-direction: row-reverse;
} }
.secondary-nav .nav-link { .secondary-nav .nav-link {
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
} }
.navbar-brand { .navbar-brand {
font-family: "Lobster", arial, serif; font-family: "Lobster", arial, serif;
font-size: 1.5rem; font-size: 1.5rem;
@ -51,7 +55,8 @@ body {
font-size: 2.4em; font-size: 2.4em;
} }
#header .tryout, #header .showcase { #header .tryout,
#header .showcase {
color: #fff; color: #fff;
background-color: #414141; background-color: #414141;
border-color: #414141; border-color: #414141;
@ -59,7 +64,8 @@ body {
margin-right: 3px; margin-right: 3px;
} }
#header .tryout:hover, #header .showcase:hover { #header .tryout:hover,
#header .showcase:hover {
background-color: #606060; background-color: #606060;
border-color: #606060; border-color: #606060;
cursor: pointer; cursor: pointer;
@ -91,9 +97,11 @@ body {
.balance tr td { .balance tr td {
font-weight: bold; font-weight: bold;
} }
.positive { .positive {
color: green; color: green;
} }
.negative { .negative {
color: red; color: red;
} }
@ -113,6 +121,7 @@ body {
flex: 1 1 auto; flex: 1 1 auto;
overflow-y: auto; overflow-y: auto;
} }
.identifier { .identifier {
margin-bottom: 15px; margin-bottom: 15px;
} }
@ -143,10 +152,12 @@ body {
.home-container { .home-container {
background: linear-gradient(150deg, #abe128 0%, #43ca61 100%); background: linear-gradient(150deg, #abe128 0%, #43ca61 100%);
} }
.home { .home {
padding-top: 1em; padding-top: 1em;
padding-bottom: 3em; padding-bottom: 3em;
} }
#authentication-form legend { #authentication-form legend {
text-align: right; text-align: right;
} }
@ -160,11 +171,13 @@ body {
margin-bottom: 20px; margin-bottom: 20px;
margin-left: 25px; margin-left: 25px;
} }
@media (max-width: 450px) { @media (max-width: 450px) {
.home .card { .home .card {
min-width: unset; min-width: unset;
} }
} }
/* Other */ /* Other */
#bills { #bills {
@ -174,6 +187,7 @@ body {
.empty-bill { .empty-bill {
margin-top: 5rem !important; margin-top: 5rem !important;
} }
.empty-bill .card { .empty-bill .card {
border: 0; border: 0;
} }
@ -250,12 +264,15 @@ footer .footer-right a {
border-radius: 50%; border-radius: 50%;
opacity: 0.5; opacity: 0.5;
} }
@-moz-document url-prefix() { @-moz-document url-prefix() {
/** Firefox style fix **/ /** Firefox style fix **/
footer .footer-right a { footer .footer-right a {
padding-top: 2px; padding-top: 2px;
} }
} }
footer .footer-right a:hover { footer .footer-right a:hover {
opacity: 1; opacity: 1;
} }
@ -268,6 +285,7 @@ footer .footer-left {
/* If you don't want the footer to be responsive, remove these media queries */ /* If you don't want the footer to be responsive, remove these media queries */
@media (max-width: 600px) { @media (max-width: 600px) {
footer .footer-left, footer .footer-left,
footer .footer-right { footer .footer-right {
text-align: center; text-align: center;
@ -291,35 +309,40 @@ footer .footer-left {
.bill-actions { .bill-actions {
padding-top: 10px; padding-top: 10px;
text-align: center; text-align: center;
column-gap: 8px;
min-height: 56px;
/* To be able to set absolute element positionning for confirm deletion */
position: relative;
} }
.bill-actions > form > .delete, .bill-actions>form>.delete,
.bill-actions > .edit, .bill-actions>.edit,
.bill-actions > .show { .bill-actions>.show {
font-size: 0px; font-size: 0px;
display: block; display: block;
width: 16px; width: 16px;
height: 16px; height: 16px;
margin: 2px;
margin-left: 5px;
float: left;
border: none; border: none;
} }
.bill-actions > form > .delete { .bill-actions .confirm {
position: absolute;
top: 4px;
left: 4px;
width: calc(100% - 8px);
height: calc(100% - 8px);
}
.bill-actions>form>.delete {
background: url("../images/delete.png") no-repeat right; background: url("../images/delete.png") no-repeat right;
} }
.bill-actions > form > .confirm.btn-danger { .bill-actions>.edit {
outline-color: #c82333;
box-shadow: none;
}
.bill-actions > .edit {
background: url("../images/edit.png") no-repeat right; background: url("../images/edit.png") no-repeat right;
} }
.bill-actions > .show { .bill-actions>.show {
background: url("../images/show.png") no-repeat right; background: url("../images/show.png") no-repeat right;
} }
@ -339,6 +362,7 @@ footer .footer-left {
} }
@media (min-width: 768px) { @media (min-width: 768px) {
.split_bills, .split_bills,
#table_overflow.statistics { #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 */
@ -346,9 +370,9 @@ footer .footer-left {
} }
} }
.project-actions > .delete, .project-actions>form>.delete,
.project-actions > .edit, .project-actions>.edit,
.project-actions > .show { .project-actions>.show {
font-size: 0px; font-size: 0px;
display: block; display: block;
width: 16px; width: 16px;
@ -358,21 +382,22 @@ footer .footer-left {
float: left; float: left;
} }
.project-actions > .delete { .project-actions>form>.delete {
background: url("../images/delete.png") no-repeat right; background: url("../images/delete.png") no-repeat right;
border: 0px !important;
} }
.project-actions > .edit { .project-actions>.edit {
background: url("../images/edit.png") no-repeat right; background: url("../images/edit.png") no-repeat right;
} }
.project-actions > .show { .project-actions>.show {
background: url("../images/show.png") no-repeat right; background: url("../images/show.png") no-repeat right;
} }
.history_icon > .delete, .history_icon>.delete,
.history_icon > .add, .history_icon>.add,
.history_icon > .edit { .history_icon>.edit {
font-size: 0px; font-size: 0px;
display: block; display: block;
width: 16px; width: 16px;
@ -383,15 +408,15 @@ footer .footer-left {
float: left; float: left;
} }
.history_icon > .delete { .history_icon>.delete {
background: url("../images/delete.png") no-repeat right; background: url("../images/delete.png") no-repeat right;
} }
.history_icon > .edit { .history_icon>.edit {
background: url("../images/edit.png") no-repeat right; background: url("../images/edit.png") no-repeat right;
} }
.history_icon > .add { .history_icon>.add {
background: url("../images/add.png") no-repeat right; background: url("../images/add.png") no-repeat right;
} }
@ -399,6 +424,15 @@ footer .footer-left {
display: table-cell; display: table-cell;
} }
/* used to tuncate long urls */
.truncated {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 250px;
display: inline-block;
vertical-align: top;
}
.balance .balance-value { .balance .balance-value {
text-align: right; text-align: right;
@ -456,7 +490,7 @@ tr.payer_line .balance-name {
margin-top: 30px; margin-top: 30px;
} }
#bill-form > fieldset { #bill-form>fieldset {
margin-top: 10px; margin-top: 10px;
} }
@ -480,64 +514,81 @@ tr:hover .extra-info {
/* Fluid Offsets for Boostrap */ /* Fluid Offsets for Boostrap */
.row-fluid > [class*="span"]:not([class*="offset"]):first-child { .row-fluid>[class*="span"]:not([class*="offset"]):first-child {
margin-left: 0; margin-left: 0;
} }
.row-fluid > .offset12 {
.row-fluid>.offset12 {
margin-left: 100%; margin-left: 100%;
} }
.row-fluid > .offset11 {
.row-fluid>.offset11 {
margin-left: 93.5%; margin-left: 93.5%;
} }
.row-fluid > .offset10 {
.row-fluid>.offset10 {
margin-left: 85%; margin-left: 85%;
} }
.row-fluid > .offset9 {
.row-fluid>.offset9 {
margin-left: 76.5%; margin-left: 76.5%;
} }
.row-fluid > .offset8 {
.row-fluid>.offset8 {
margin-left: 68%; margin-left: 68%;
} }
.row-fluid > .offset7 {
.row-fluid>.offset7 {
margin-left: 59.5%; margin-left: 59.5%;
} }
.row-fluid > .offset6 {
.row-fluid>.offset6 {
margin-left: 51%; margin-left: 51%;
} }
.row-fluid > .offset5 {
.row-fluid>.offset5 {
margin-left: 42.5%; margin-left: 42.5%;
} }
.row-fluid > .offset4 {
.row-fluid>.offset4 {
margin-left: 34%; margin-left: 34%;
} }
.row-fluid > .offset3 {
.row-fluid>.offset3 {
margin-left: 25.5%; margin-left: 25.5%;
} }
.row-fluid > .offset2 {
.row-fluid>.offset2 {
margin-left: 17%; margin-left: 17%;
} }
.row-fluid > .offset1 {
.row-fluid>.offset1 {
margin-left: 8.5%; margin-left: 8.5%;
} }
.globe-europe svg { .globe-europe svg {
fill: rgba(255, 255, 255, 0.5); fill: rgba(255, 255, 255, 0.5);
} }
.navbar-nav .dropdown-toggle:hover .globe-europe svg { .navbar-nav .dropdown-toggle:hover .globe-europe svg {
fill: rgba(255, 255, 255, 0.75); fill: rgba(255, 255, 255, 0.75);
} }
.navbar-dark .navbar-nav .show > .nav-link svg {
.navbar-dark .navbar-nav .show>.nav-link svg {
fill: white; fill: white;
} }
.navbar-dark .dropdown-menu { .navbar-dark .dropdown-menu {
max-height: 50vh; max-height: 50vh;
overflow-y: auto; overflow-y: auto;
} }
.icon svg { .icon svg {
display: inline-block; display: inline-block;
border-bottom: 0.2em solid transparent; border-bottom: 0.2em solid transparent;
height: 1.2em; height: 1.2em;
width: 1.2em; /* protection for IE11 */ width: 1.2em;
/* protection for IE11 */
} }
.icon.high svg { .icon.high svg {
@ -553,9 +604,11 @@ tr:hover .extra-info {
.icon.before-text svg { .icon.before-text svg {
margin-right: 3px; margin-right: 3px;
} }
footer .icon svg { footer .icon svg {
fill: white; fill: white;
} }
.icon.icon-white { .icon.icon-white {
fill: white; fill: white;
} }
@ -563,7 +616,8 @@ footer .icon svg {
.icon.icon-red { .icon.icon-red {
fill: #dc3545; fill: #dc3545;
} }
.btn:hover .icon.icon-red {
.btn:hover .icon.icon-red {
fill: white !important; fill: white !important;
} }
@ -587,6 +641,7 @@ footer .icon svg {
margin-top: 1em; margin-top: 1em;
margin-bottom: 3em; margin-bottom: 3em;
} }
.edit-project .custom-file { .edit-project .custom-file {
margin-bottom: 2em; margin-bottom: 2em;
} }

View file

@ -2,32 +2,51 @@
{% block content %} {% block content %}
{% if is_admin_dashboard_activated %} {% if is_admin_dashboard_activated %}
<table id="bill_table" class="table table-striped"> <table id="bill_table" class="table table-striped">
<thead><tr><th>{{ _("Project") }}</th><th>{{ _("Number of participants") }}</th><th>{{ _("Number of bills") }}</th><th>{{_("Newest bill")}}</th><th>{{_("Oldest bill")}}</th><th>{{_("Actions")}}</th></tr></thead> <thead>
<tr>
<th>{{ _("Project") }}</th>
<th>{{ _("Number of participants") }}</th>
<th>{{ _("Number of bills") }}</th>
<th>{{_("Newest bill")}}</th>
<th>{{_("Oldest bill")}}</th>
<th>{{_("Actions")}}</th>
</tr>
</thead>
<tbody>{% for project in projects|sort(attribute='name') %} <tbody>{% for project in projects|sort(attribute='name') %}
<tr> <tr>
<td><a href="{{ url_for(".list_bills", project_id=project.id) }}" title="{{ project.name }}">{{ project.name }}</a></td><td>{{ project.members | count }}</td><td>{{ project.get_bills_unordered().count() }}</td> <td><a href="{{ url_for('.list_bills', project_id=project.id) }}"
{% if project.has_bills() %} title="{{ project.name }}">{{project.name}}</a></td>
<td>{{ project.get_bills().all()[0].date }}</td> <td>{{ project.members | count }}</td>
<td>{{ project.get_bills().all()[-1].date }}</td> <td>{{ project.get_bills_unordered().count() }}</td>
{% else %} {% if project.has_bills() %}
<td></td> <td>{{ project.get_bills().all()[0].date }}</td>
<td></td> <td>{{ project.get_bills().all()[-1].date }}</td>
{% endif %} {% else %}
<td class="project-actions"> <td></td>
<a class="edit" href="{{ url_for(".edit_project", project_id=project.id) }}" title="{{ _("edit") }}">{{ _('edit') }}</a> <td></td>
<a class="delete" href="{{ url_for(".delete_project", project_id=project.id) }}" title="{{ _("delete") }}">{{ _('delete') }}</a> {% endif %}
<a class="show" href="{{ url_for(".list_bills", project_id=project.id) }}" title="{{ _("show") }}">{{ _('show') }}</a> <td class="project-actions">
</td> <a class="edit" href="{{ url_for('.edit_project', project_id=project.id) }}" title=" {{ _('edit')}}">{{
_('edit') }}</a>
<form id="delete-project" class="form-horizontal" action="{{ url_for('.dashboard_delete_project',
project_id=project.id) }}" method="post">
<button class="delete">{{ _("Delete project") }}</button>
</form>
<a class="show" href="{{ url_for('.list_bills', project_id=project.id) }}" title="{{ _("show") }}">{{
_('show') }}</a>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<script language="JavaScript"> <script language="JavaScript">
$(document).ready(function() { $(document).ready(function () {
$('#bill_table').DataTable({ $('#bill_table').DataTable({
paging: true paging: true
}); });
}) })
</script> </script>
{% else %} {% else %}
<div class="alert alert-danger">{{ _("The Dashboard is currently deactivated.") }}</div> <div class="alert alert-danger">{{ _("The Dashboard is currently deactivated.") }}</div>

View file

@ -1,22 +1,8 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block js %} {% block js %}
{% include "helpers.js" %}
let link = $('#delete-project').find('button'); confirm_action("#delete-project")
let deleteOriginalHTML = link.html();
link.click(function() {
if (link.hasClass("confirm")){
return true;
}
link.html("{{_("Are you sure?")}}");
link.addClass("confirm btn-danger");
return false;
});
$('#delete-project').focusout(function() {
link.removeClass("confirm btn-danger");
link.html(deleteOriginalHTML);
});
$('.custom-file-input').on('change', function(event) { $('.custom-file-input').on('change', function(event) {
var filename = [].slice.call(this.files).map(function (file) { return file.name}).join(',') var filename = [].slice.call(this.files).map(function (file) { return file.name}).join(',')

View file

@ -100,8 +100,9 @@
</div> </div>
{{ input(form.default_currency) }} {{ input(form.default_currency) }}
{{ input(form.current_password) }}
<div class="actions"> <div class="actions">
<button class="btn btn-primary">{{ _("Edit the project") }}</button> <button class="btn btn-primary">{{ _("Save changes") }}</button>
</div> </div>
{% endmacro %} {% endmacro %}
@ -113,7 +114,7 @@
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
{{ input(form.password) }} {{ input(form.password) }}
<div class="actions"> <div class="actions">
<button class="btn btn-primary">{{ _("Delete project") }}</button> <button class="btn btn-danger">{{ _("Delete project") }}</button>
</div> </div>
{% endmacro %} {% endmacro %}
@ -179,7 +180,11 @@
<a class="badge badge-secondary" href="#" id="selectnone" onclick="selectCheckboxes(false)">{{_("No one")}}</a> <a class="badge badge-secondary" href="#" id="selectnone" onclick="selectCheckboxes(false)">{{_("No one")}}</a>
</p> </p>
<div class="d-flex flex-column flex-wrap overflow-auto" style="max-height: 20em;"> <div class="d-flex flex-column flex-wrap overflow-auto" style="max-height: 20em;">
{% for key, value, checked in form.payed_for.iter_choices() | sort(attribute='1') %} {% for choices in form.payed_for.iter_choices() | sort(attribute='1') %}
{# Compatibility with wtforms<3.1 #}
{% set key = choices[0] %}
{% set value = choices[1] %}
{% set checked = choices[2] %}
<p class="form-check text-break" style="max-width: 50%;"> <p class="form-check text-break" style="max-width: 50%;">
<label for="payed_for-{{key}}" class="form-check-label"> <label for="payed_for-{{key}}" class="form-check-label">
<input name="payed_for" type="checkbox" {% if checked %}checked{% endif %} class="form-check-input" value="{{key}}" id="payed_for-{{key}}"/> <input name="payed_for" type="checkbox" {% if checked %}checked{% endif %} class="form-check-input" value="{{key}}" id="payed_for-{{key}}"/>

View file

@ -0,0 +1,23 @@
function confirm_action(selector, { exclude_classes, add_classes } = { exclude_classes: "", add_classes: "" }) {
const elements = $(selector)
elements.each(function () {
const element = $(this)
let link = element.find('button')
let deleteOriginalHTML = link.html()
link.click(function () {
if (link.hasClass("confirm")) {
return true
}
link.html("{{_('Are you sure?')}}")
link.removeClass(exclude_classes)
link.addClass(`confirm btn-danger ${add_classes}`)
return false
})
element.focusout(function () {
link.removeClass(`confirm btn-danger ${add_classes}`)
link.html(deleteOriginalHTML)
link.addClass(exclude_classes)
})
})
}

View file

@ -91,6 +91,21 @@
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}
{% macro bill_details(details, before=False) %}
{% set owers_list_str=details.owers|localize_list|safe %}
<details class="small">
<summary>{% if before %} {{ _("Details of the bill (before the change)") }} {% else %} {{ _("Details of the bill") }} {% endif %}</summary>
{{ _("Date:") }} {{ details.date|em_surround }}.
{{ _("Payer:") }} {{ details.payer|em_surround }}.
{{ _("Amount:") }} {{ details.amount|currency(details.original_currency)|em_surround }}.
{{ _("Owers:") }} {{ owers_list_str }}.
{% if details.external_link %}
{{ _("External link:") }}
<a class="truncated" href="{{ details.external_link }}">{{ details.external_link }}</a>
{% endif %}
</details>
{% endmacro %}
{% block sidebar %} {% block sidebar %}
<div id="table_overflow"> <div id="table_overflow">
{{ balance_table(show_weight=False, show_header=True) }} {{ balance_table(show_weight=False, show_header=True) }}
@ -103,18 +118,17 @@
{% if current_log_pref == LoggingMode.DISABLED or (current_log_pref != LoggingMode.RECORD_IP and any_ip_addresses) %} {% 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"> <div id="history_warnings" class="card card-body bg-light">
{% if current_log_pref == LoggingMode.DISABLED %} {% if current_log_pref == LoggingMode.DISABLED %}
<p>{% set url = url_for(".edit_project") %} <p>
{% trans %} <i>{{ _("This project has history disabled. New actions won't appear below.") }}
<i>This project has history disabled. New actions won't appear below. You can enable history on the</i> <a href="{{ url_for(".edit_project") }}">{{ _("You can enable history on the settings page.") }}</a>
<a href="{{ url }}">settings page</a> </i>
{% endtrans %}
</p> </p>
{% if history %} {% if history %}
<p> <p>
{% trans %} <i>{{ _("The table below reflects actions recorded prior to disabling project history.") }}
<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">{{ _("You can clear the project history to remove them.") }}</a>
<a href="#" data-toggle="modal" data-keyboard="false" data-target="#confirm-erase">clear project history</a> to remove them.</i></p> </i>
{% endtrans %} </p>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if current_log_pref != LoggingMode.RECORD_IP and any_ip_addresses %} {% if current_log_pref != LoggingMode.RECORD_IP and any_ip_addresses %}
@ -178,13 +192,16 @@
{% trans %}Project {{ name }} added{% endtrans %} {% trans %}Project {{ name }} added{% endtrans %}
{% elif event.object_type == "Bill" %} {% elif event.object_type == "Bill" %}
{% trans %}Bill {{ name }} added{% endtrans %} {% trans %}Bill {{ name }} added{% endtrans %}
{{ bill_details(event.bill_details) }}
{% elif event.object_type == "Person" %} {% elif event.object_type == "Person" %}
{% trans %}Participant {{ name }} added{% endtrans %} {% trans %}Participant {{ name }} added{% endtrans %}
{% endif %} {% endif %}
{% elif event.operation_type == OperationType.UPDATE %} {% elif event.operation_type == OperationType.UPDATE %}
{% if event.object_type == "Project" %} {% if event.object_type == "Project" %}
{% if event.prop_changed == "password" %} {% if event.prop_changed == "password" %}
{{ _("Project private code changed") }} {{ _("Project private code changed") }}
{% elif event.prop_changed == "logging_preference" %} {% elif event.prop_changed == "logging_preference" %}
{{ change_to_logging_preference(event) }} {{ change_to_logging_preference(event) }}
{% elif event.prop_changed == "name" %} {% elif event.prop_changed == "name" %}
@ -196,51 +213,58 @@
{% else %} {% else %}
{{ _("Project settings modified") }} {{ _("Project settings modified") }}
{% endif %} {% endif %}
{% elif event.prop_changed == "activated" %} {% elif event.object_type == "Bill" %}
{% if event.val_after == False %} {% if event.prop_changed == "what" %}
{% trans %}Participant {{ name }} deactivated{% endtrans %}
{% else %}
{% trans %}Participant {{ name }} reactivated{% endtrans %}
{% endif %}
{% elif event.prop_changed == "name" %}
{% set new_name=event.val_after|em_surround %}
{% trans %}Participant {{ name }} renamed to {{ new_name }}{% endtrans %}
{% elif event.prop_changed == "what" %}
{% set new_description=event.val_after|em_surround %} {% set new_description=event.val_after|em_surround %}
{% trans %}Bill {{ name }} renamed to {{ new_description }}{% endtrans %} {% trans %}Bill {{ name }} renamed to {{ new_description }}{% endtrans %}
{% elif event.prop_changed == "weight" %} {% elif event.prop_changed == "external_link" %}
{% set old_weight=event.val_before|em_surround %} {{ bill_property_change(event, _("External link"), None, "<a class='truncated' href='{link}' >{link}</a>".format(link=event.val_after | escape) | safe | em_surround) }}
{% set new_weight=event.val_after|em_surround %} {% elif event.prop_changed == "owers_added" %}
{% trans %}Participant {{ name }}: weight changed from {{ old_weight }} to {{ new_weight }}{% endtrans %} {{ owers_changed(event, True)}}
{% elif event.prop_changed == "external_link" %} {% elif event.prop_changed == "owers_removed" %}
{{ bill_property_change(event, _("External link"), None, "<a href='{link}' >{link}</a>".format(link=event.val_after | escape) | safe | em_surround) }} {{ owers_changed(event, False)}}
{% elif event.prop_changed == "owers_added" %} {% elif event.prop_changed == "payer" %}
{{ owers_changed(event, True)}} {{ bill_property_change(event, _("Payer"))}}
{% elif event.prop_changed == "owers_removed" %} {% elif event.prop_changed == "amount" %}
{{ owers_changed(event, False)}} {{ bill_property_change(event, _("Amount")) }}
{% elif event.prop_changed == "payer" %} {% elif event.prop_changed == "date" %}
{{ bill_property_change(event, _("Payer"))}} {{ bill_property_change(event, _("Date")) }}
{% elif event.prop_changed == "amount" %} {% elif event.prop_changed == "original_currency" %}
{{ bill_property_change(event, _("Amount")) }} {{ bill_property_change(event, _("Currency")) }}
{% elif event.prop_changed == "date" %} {% elif event.prop_changed == "converted_amount" %}
{{ bill_property_change(event, _("Date")) }} {{ bill_property_change(event, _("Amount in %(currency)s", currency=g.project.default_currency)) }}
{% elif event.prop_changed == "original_currency" %} {% else %}
{{ bill_property_change(event, _("Currency")) }}
{% elif event.prop_changed == "converted_amount" %}
{{ bill_property_change(event, _("Amount in %(currency)s", currency=g.project.default_currency)) }}
{% else %}
{% if event.object_type == "Bill" %}
{% trans %}Bill {{ name }} modified{% endtrans %} {% trans %}Bill {{ name }} modified{% endtrans %}
{% elif event.object_type == "Person" %} {% endif %}
{{ bill_details(event.bill_details, before=True) }}
{% elif event.object_type == "Person" %}
{% if event.prop_changed == "activated" %}
{% if event.val_after == False %}
{% trans %}Participant {{ name }} deactivated{% endtrans %}
{% else %}
{% trans %}Participant {{ name }} reactivated{% endtrans %}
{% endif %}
{% elif event.prop_changed == "name" %}
{% set new_name=event.val_after|em_surround %}
{% trans %}Participant {{ name }} renamed to {{ new_name }}{% endtrans %}
{% elif event.prop_changed == "weight" %}
{% set old_weight=event.val_before|em_surround %}
{% set new_weight=event.val_after|em_surround %}
{% trans %}Participant {{ name }}: weight changed from {{ old_weight }} to {{ new_weight }}{% endtrans %}
{% else %}
{% trans %}Participant {{ name }} modified{% endtrans %} {% trans %}Participant {{ name }} modified{% endtrans %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% elif event.operation_type == OperationType.DELETE %} {% elif event.operation_type == OperationType.DELETE %}
{% if event.object_type == "Bill" %} {% if event.object_type == "Bill" %}
{% trans %}Bill {{ name }} removed{% endtrans %} {% trans %}Bill {{ name }} removed{% endtrans %}
{{ bill_details(event.bill_details) }}
{% elif event.object_type == "Person" %} {% elif event.object_type == "Person" %}
{% trans %}Participant {{ name }} removed{% endtrans %} {% trans %}Participant {{ name }} removed{% endtrans %}
{% endif %} {% endif %}
{% else %} {% else %}
{# Should be unreachable #} {# Should be unreachable #}
{% if event.object_type == "Project" %} {% if event.object_type == "Project" %}

View file

@ -103,6 +103,7 @@
{% if g.project %} {% if g.project %}
<li><a class="dropdown-item" href="{{ url_for("main.history") }}">{{ _("History") }}</a></li> <li><a class="dropdown-item" href="{{ url_for("main.history") }}">{{ _("History") }}</a></li>
<li><a class="dropdown-item" href="{{ url_for("main.edit_project") }}">{{ _("Settings") }}</a></li> <li><a class="dropdown-item" href="{{ url_for("main.edit_project") }}">{{ _("Settings") }}</a></li>
<li><a class="dropdown-item" href="{{ url_for("main.feed", token=g.project.generate_token("feed")) }}">{{ _("RSS Feed") }}</a></li>
{% endif %} {% endif %}
{% if session['projects'] and not ((session['projects'] | length) == 1 and g.project and g.project.id in session['projects']) %} {% if session['projects'] and not ((session['projects'] | length) == 1 and g.project and g.project.id in session['projects']) %}
@ -118,12 +119,14 @@
{% if session['is_admin'] %} {% if session['is_admin'] %}
<li><a class="dropdown-item" href="{{ url_for("main.dashboard") }}">{{ _("Dashboard") }}</a></li> <li><a class="dropdown-item" href="{{ url_for("main.dashboard") }}">{{ _("Dashboard") }}</a></li>
{% endif %} {% endif %}
{% if g.logout_form %}
<li> <li>
<form action="{{ url_for("main.exit") }}" method="post"> <form action="{{ url_for("main.exit") }}" method="post">
{{ g.logout_form.hidden_tag() }} {{ g.logout_form.hidden_tag() }}
{{ g.logout_form.submit(class="dropdown-item") }} {{ g.logout_form.submit(class="dropdown-item") }}
</form> </form>
</li> </li>
{% endif %}
</ul> </ul>
</li> </li>
{% endif %} {% endif %}

View file

@ -11,6 +11,11 @@
{% block js %} {% block js %}
{% if add_bill %} $('#new-bill > a').click(); {% endif %} {% if add_bill %} $('#new-bill > a').click(); {% endif %}
// focus on first field when adding a bill
$("#bill-form").on('shown.bs.modal', function(){
$(this).find('#what').focus();
});
// ask for confirmation before removing an user // ask for confirmation before removing an user
$('.action.delete').each(function(){ $('.action.delete').each(function(){
var link = $(this).find('button'); var link = $(this).find('button');
@ -39,28 +44,14 @@
$('#bill_table tbody tr').hover(highlight_owers, unhighlight_owers); $('#bill_table tbody tr').hover(highlight_owers, unhighlight_owers);
{% include "helpers.js" %}
confirm_action(".delete-bill", { exclude_classes: "action delete", add_classes: "btn btn-sm" });
let link = $('#delete-bill').find('button');
let deleteOriginalHTML = link.html();
link.click(function() {
if (link.hasClass("confirm")){
return true;
}
link.html("{{_("Are you sure?")}}");
link.removeClass("action delete");
link.addClass("confirm btn-danger");
return false;
});
$('#delete-bill').focusout(function() {
link.removeClass("confirm btn-danger");
link.html(deleteOriginalHTML);
link.addClass("action delete");
});
{% endblock %} {% endblock %}
{% block head %}
<link href="{{ url_for(".feed", token=g.project.generate_token("feed")) }}" type="application/rss+xml" rel="alternate" title="{{ g.project.name }}" />
{% endblock %}
{% block sidebar %} {% block sidebar %}
<div class="sidebar_content"> <div class="sidebar_content">
@ -115,7 +106,7 @@
</ul> </ul>
{% endif %} {% endif %}
<span id="new-bill" class="ml-auto pb-2" {% if not g.project.members %} data-toggle="tooltip" title="{{_('You should start by adding participants')}}" {% endif %}> <span id="new-bill" class="ml-auto pb-2" {% if not g.project.members %} data-toggle="tooltip" title="{{_('You should start by adding participants')}}" {% endif %}>
<a href="{{ url_for('.add_bill') }}" class="btn btn-primary {% if not g.project.members %} disabled {% endif %}" data-toggle="modal" data-keyboard="false" data-target="#bill-form"> <a href="{{ url_for('.add_bill') }}" class="btn btn-primary {% if not g.project.members %} disabled {% endif %}" data-toggle="modal" data-keyboard="true" data-target="#bill-form" autofocus>
<i class="icon icon-white before-text">{{ static_include("images/plus.svg") | safe }}</i> <i class="icon icon-white before-text">{{ static_include("images/plus.svg") | safe }}</i>
{{ _("Add a new bill") }} {{ _("Add a new bill") }}
</a> </a>
@ -158,9 +149,9 @@
{{ weighted_bill_amount(bill, weights) }} {{ weighted_bill_amount(bill, weights) }}
</span> </span>
</td> </td>
<td class="bill-actions"> <td class="bill-actions d-flex align-items-center">
<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>
<form id="delete-bill"action="{{ url_for(".delete_bill", bill_id=bill.id) }}" method="POST"> <form class="delete-bill" action="{{ url_for(".delete_bill", bill_id=bill.id) }}" method="POST">
{{ csrf_form.csrf_token }} {{ csrf_form.csrf_token }}
<button class="action delete" type="submit" title="{{ _("delete") }}"></button> <button class="action delete" type="submit" title="{{ _("delete") }}"></button>
</form> </form>
@ -180,13 +171,14 @@
<h3>{{ _('No bills')}}</h3> <h3>{{ _('No bills')}}</h3>
<p> <p>
{{ _("Nothing to list yet.")}}<br /> {{ _("Nothing to list yet.")}}<br />
{{ _("You probably want to") }} {%- if g.project.members %}
{%- if g.project.members %} <a href="{{ url_for('.add_bill') }}" data-toggle="modal" data-target="#bill-form"> <a href="{{ url_for('.add_bill') }}" data-toggle="modal" data-target="#bill-form">
{{- _("add a bill") -}} {{- _("Add your first bill") -}}
</a> ? </a>
{% else %} <a href="{{ url_for('.add_member') }}"> {% else %}
{{- _('add participants') -}} <a href="{{ url_for('.add_member') }}">
</a> ? {{- _("Add the first participant") -}}
</a>
{%- endif -%} {%- endif -%}
</p> </p>
</div> </div>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title>I Hate Money — {{ g.project.name }}</title>
<description>{% trans project_name=g.project.name %}Latest bills from {{ project_name }}{% endtrans %}</description>
<atom:link href="{{ url_for(".feed", token=g.project.generate_token("feed"), _external=True) }}" rel="self" type="application/rss+xml" />
<link>{{ url_for(".list_bills", _external=True) }}</link>
{% for (weights, bill) in bills.items -%}
<item>
<title>{{ bill.what }} - {{ bill.amount|currency(bill.original_currency) }}</title>
<guid isPermaLink="false">{{ bill.id }}</guid>
<dc:creator>{{ bill.payer }}</dc:creator>
{% if bill.external_link %}<link>{{ bill.external_link }}</link>{% endif -%}
<description>{{ bill.date|dateformat("long") }} - {{ bill.owers|join(', ', 'name') }} : {{ (bill.amount/weights)|currency(bill.original_currency) }}</description>
<pubDate>{{ bill.creation_date.strftime("%a, %d %b %Y %T") }} +0000</pubDate>
</item>
{% endfor -%}
</channel>
</rss>

View file

@ -7,20 +7,10 @@
<tbody> <tbody>
<tr> <tr>
<td> <td>
<h3>{{ _('Share Identifier & code') }}</h3> <h3>{{ _('Share an invitation link') }}</h3>
</td> </td>
<td> <td>
{{ _("You can share the project identifier and the private code by any communication means.") }} {{ _("The easiest way to invite people is to give them the following invitation link.<br />They will be able to access the project, manage participants, add/edit/delete bills. However, they will not have access to important settings such as changing the private code or deleting the whole project.") }}</br>
<br />
<strong>{{ _('Identifier:') }}</strong> <a href="{{ url_for("main.list_bills", project_id=g.project.id) }}">{{ g.project.id }}</a>
</td>
</tr>
<tr>
<td>
<h3>{{ _('Share the Link') }}</h3>
</td>
<td>
{{ _("You can directly share the following link via your prefered medium") }}</br>
<a href="{{ url_for(".join_project", _external=True, project_id=g.project.id, token=g.project.generate_token()) }}"> <a href="{{ url_for(".join_project", _external=True, project_id=g.project.id, token=g.project.generate_token()) }}">
{{ url_for(".join_project", _external=True, project_id=g.project.id, token=g.project.generate_token()) }} {{ url_for(".join_project", _external=True, project_id=g.project.id, token=g.project.generate_token()) }}
</a> </a>
@ -29,7 +19,7 @@
<tr> <tr>
<td> <td>
<h3>{{ _('Scan QR code') }}</h3> <h3>{{ _('Scan QR code') }}</h3>
<p><small>{% trans download_mobile=url_for(".mobile") %}On a mobile device, with <a href="{{ download_mobile }}">a compatible app installed</a>.{% endtrans %}</small></p> <p><small><a href="{{ url_for(".mobile") }}">{{ _("Use a mobile device with a compatible app.") }}</a></small></p>
</td> </td>
<td> <td>
{{ qrcode | safe }} {{ qrcode | safe }}
@ -40,14 +30,26 @@
<h3>{{ _('Send via Emails') }}</h3> <h3>{{ _('Send via Emails') }}</h3>
</td> </td>
<td> <td>
<p>{{ _("Specify a (comma separated) list of email adresses you want to notify about the <p>{{ _("Specify a list of email adresses (separated by comma) of people you want to notify about the creation of this project. We will send them an email with the invitation link.") }}</p>
creation of this budget management project and we will send them an email for you.") }}</p>
{% include "display_errors.html" %} {% include "display_errors.html" %}
<form class="invites form-horizontal" method="post" accept-charset="utf-8"> <form class="invites form-horizontal" method="post" accept-charset="utf-8">
{{ forms.invites(form) }} {{ forms.invites(form) }}
</form> </form>
</td> </td>
</tr> </tr>
<tr>
<td>
<h3>{{ _('Share Identifier & code') }}</h3>
</td>
<td>
<p>{{ _("You can share the project identifier and the private code by any communication means.<br />Anyone with the private code will have access to the full project, including changing settings such as the private code or project email address, or even deleting the whole project.") }}</p>
<p>
<strong>{{ _('Identifier:') }}</strong> <a href="{{ url_for("main.list_bills", project_id=g.project.id) }}">{{ g.project.id }}</a>
<br />
<strong>{{ _('Private code:') }}</strong> {{ _('the private code was defined when you created the project') }}
</p>
</td>
</tr>
</tbody> </tbody>
</table> </table>

View file

@ -1,13 +1,14 @@
import base64 import base64
import datetime import datetime
import json import json
import unittest
import pytest
from ihatemoney.tests.common.help_functions import em_surround from ihatemoney.tests.common.help_functions import em_surround
from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase
class APITestCase(IhatemoneyTestCase): class TestAPI(IhatemoneyTestCase):
"""Tests the API""" """Tests the API"""
@ -42,7 +43,7 @@ class APITestCase(IhatemoneyTestCase):
def get_auth(self, username, password=None): def get_auth(self, username, password=None):
password = password or username password = password or username
base64string = ( base64string = (
base64.encodebytes(f"{username}:{password}".encode("utf-8")) base64.encodebytes(f"{username}:{password}".encode("utf-8")) # noqa: E231
.decode("utf-8") .decode("utf-8")
.replace("\n", "") .replace("\n", "")
) )
@ -57,7 +58,7 @@ class APITestCase(IhatemoneyTestCase):
resp = self.client.options( resp = self.client.options(
"/api/projects/raclette", headers=self.get_auth("raclette") "/api/projects/raclette", headers=self.get_auth("raclette")
) )
self.assertEqual(resp.headers["Access-Control-Allow-Origin"], "*") assert resp.headers["Access-Control-Allow-Origin"] == "*"
def test_basic_auth(self): def test_basic_auth(self):
# create a project # create a project
@ -94,34 +95,32 @@ class APITestCase(IhatemoneyTestCase):
}, },
) )
self.assertTrue(400, resp.status_code) assert 400 == resp.status_code
self.assertEqual( assert '{"contact_email": ["Invalid email address."]}\n' == resp.data.decode(
"".join('{"contact_email": ["Invalid email address."]}\n'.split()), "utf-8"
"".join(resp.data.decode("utf-8").split()),
) )
# create it # create it
with self.app.mail.record_messages() as outbox: with self.app.mail.record_messages() as outbox:
resp = self.api_create("raclette") resp = self.api_create("raclette")
self.assertTrue(201, resp.status_code) assert 201 == resp.status_code
# Check that email messages have been sent. # Check that email messages have been sent.
self.assertEqual(len(outbox), 1) assert len(outbox) == 1
self.assertEqual(outbox[0].recipients, ["raclette@notmyidea.org"]) assert outbox[0].recipients == ["raclette@notmyidea.org"]
# create it twice should return a 400 # create it twice should return a 400
resp = self.api_create("raclette") resp = self.api_create("raclette")
self.assertTrue(400, resp.status_code) assert 400 == resp.status_code
self.assertIn("id", json.loads(resp.data.decode("utf-8"))) assert "id" in json.loads(resp.data.decode("utf-8"))
# get information about it # get information about it
resp = self.client.get( resp = self.client.get(
"/api/projects/raclette", headers=self.get_auth("raclette") "/api/projects/raclette", headers=self.get_auth("raclette")
) )
self.assertTrue(200, resp.status_code) assert 200 == resp.status_code
expected = { expected = {
"members": [], "members": [],
"name": "raclette", "name": "raclette",
@ -131,9 +130,9 @@ class APITestCase(IhatemoneyTestCase):
"logging_preference": 1, "logging_preference": 1,
} }
decoded_resp = json.loads(resp.data.decode("utf-8")) decoded_resp = json.loads(resp.data.decode("utf-8"))
self.assertDictEqual(decoded_resp, expected) assert decoded_resp == expected
# edit should work # edit should fail if we don't provide the current private code
resp = self.client.put( resp = self.client.put(
"/api/projects/raclette", "/api/projects/raclette",
data={ data={
@ -145,14 +144,43 @@ class APITestCase(IhatemoneyTestCase):
}, },
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
assert 400 == resp.status_code
self.assertEqual(200, resp.status_code) # edit should fail if we provide the wrong private code
resp = self.client.put(
"/api/projects/raclette",
data={
"contact_email": "yeah@notmyidea.org",
"default_currency": "XXX",
"current_password": "fromage aux patates",
"password": "raclette",
"name": "The raclette party",
"project_history": "y",
},
headers=self.get_auth("raclette"),
)
assert 400 == resp.status_code
# edit with the correct private code should work
resp = self.client.put(
"/api/projects/raclette",
data={
"contact_email": "yeah@notmyidea.org",
"default_currency": "XXX",
"current_password": "raclette",
"password": "raclette",
"name": "The raclette party",
"project_history": "y",
},
headers=self.get_auth("raclette"),
)
assert 200 == resp.status_code
resp = self.client.get( resp = self.client.get(
"/api/projects/raclette", headers=self.get_auth("raclette") "/api/projects/raclette", headers=self.get_auth("raclette")
) )
self.assertEqual(200, resp.status_code) assert 200 == resp.status_code
expected = { expected = {
"name": "The raclette party", "name": "The raclette party",
"contact_email": "yeah@notmyidea.org", "contact_email": "yeah@notmyidea.org",
@ -162,7 +190,7 @@ class APITestCase(IhatemoneyTestCase):
"logging_preference": 1, "logging_preference": 1,
} }
decoded_resp = json.loads(resp.data.decode("utf-8")) decoded_resp = json.loads(resp.data.decode("utf-8"))
self.assertDictEqual(decoded_resp, expected) assert decoded_resp == expected
# password change is possible via API # password change is possible via API
resp = self.client.put( resp = self.client.put(
@ -170,18 +198,19 @@ class APITestCase(IhatemoneyTestCase):
data={ data={
"contact_email": "yeah@notmyidea.org", "contact_email": "yeah@notmyidea.org",
"default_currency": "XXX", "default_currency": "XXX",
"current_password": "raclette",
"password": "tartiflette", "password": "tartiflette",
"name": "The raclette party", "name": "The raclette party",
}, },
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
self.assertEqual(200, resp.status_code) assert 200 == resp.status_code
resp = self.client.get( resp = self.client.get(
"/api/projects/raclette", headers=self.get_auth("raclette", "tartiflette") "/api/projects/raclette", headers=self.get_auth("raclette", "tartiflette")
) )
self.assertEqual(200, resp.status_code) assert 200 == resp.status_code
# delete should work # delete should work
resp = self.client.delete( resp = self.client.delete(
@ -192,21 +221,21 @@ class APITestCase(IhatemoneyTestCase):
resp = self.client.get( resp = self.client.get(
"/api/projects/raclette", headers=self.get_auth("raclette") "/api/projects/raclette", headers=self.get_auth("raclette")
) )
self.assertEqual(401, resp.status_code) assert 401 == resp.status_code
def test_token_creation(self): def test_token_creation(self):
"""Test that token of project is generated""" """Test that token of project is generated"""
# Create project # Create project
resp = self.api_create("raclette") resp = self.api_create("raclette")
self.assertTrue(201, resp.status_code) assert 201 == resp.status_code
# Get token # Get token
resp = self.client.get( resp = self.client.get(
"/api/projects/raclette/token", headers=self.get_auth("raclette") "/api/projects/raclette/token", headers=self.get_auth("raclette")
) )
self.assertEqual(200, resp.status_code) assert 200 == resp.status_code
decoded_resp = json.loads(resp.data.decode("utf-8")) decoded_resp = json.loads(resp.data.decode("utf-8"))
@ -215,8 +244,22 @@ class APITestCase(IhatemoneyTestCase):
"/api/projects/raclette/token", "/api/projects/raclette/token",
headers={"Authorization": f"Basic {decoded_resp['token']}"}, headers={"Authorization": f"Basic {decoded_resp['token']}"},
) )
assert 200 == resp.status_code
self.assertEqual(200, resp.status_code) # We shouldn't be able to edit project without private code
resp = self.client.put(
"/api/projects/raclette",
data={
"contact_email": "yeah@notmyidea.org",
"default_currency": "XXX",
"password": "tartiflette",
"name": "The raclette party",
},
headers={"Authorization": f"Basic {decoded_resp['token']}"},
)
assert 400 == resp.status_code
expected_resp = {"current_password": ["This field is required."]}
assert expected_resp == json.loads(resp.data.decode("utf-8"))
def test_token_login(self): def test_token_login(self):
resp = self.api_create("raclette") resp = self.api_create("raclette")
@ -227,7 +270,7 @@ class APITestCase(IhatemoneyTestCase):
decoded_resp = json.loads(resp.data.decode("utf-8")) decoded_resp = json.loads(resp.data.decode("utf-8"))
resp = self.client.get(f"/raclette/join/{decoded_resp['token']}") resp = self.client.get(f"/raclette/join/{decoded_resp['token']}")
# Test that we are redirected. # Test that we are redirected.
self.assertEqual(302, resp.status_code) assert 302 == resp.status_code
def test_member(self): def test_member(self):
# create a project # create a project
@ -239,7 +282,7 @@ class APITestCase(IhatemoneyTestCase):
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual("[]\n", req.data.decode("utf-8")) assert "[]\n" == req.data.decode("utf-8")
# add a member # add a member
req = self.client.post( req = self.client.post(
@ -250,7 +293,7 @@ class APITestCase(IhatemoneyTestCase):
# the id of the new member should be returned # the id of the new member should be returned
self.assertStatus(201, req) self.assertStatus(201, req)
self.assertEqual("1\n", req.data.decode("utf-8")) assert "1\n" == req.data.decode("utf-8")
# the list of participants should contain one member # the list of participants should contain one member
req = self.client.get( req = self.client.get(
@ -258,7 +301,7 @@ class APITestCase(IhatemoneyTestCase):
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual(len(json.loads(req.data.decode("utf-8"))), 1) assert len(json.loads(req.data.decode("utf-8"))) == 1
# Try to add another member with the same name. # Try to add another member with the same name.
req = self.client.post( req = self.client.post(
@ -271,7 +314,7 @@ class APITestCase(IhatemoneyTestCase):
# edit the participant # edit the participant
req = self.client.put( req = self.client.put(
"/api/projects/raclette/members/1", "/api/projects/raclette/members/1",
data={"name": "Fred", "weight": 2}, data={"name": "Jeanne", "weight": 2},
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
@ -283,14 +326,14 @@ class APITestCase(IhatemoneyTestCase):
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual("Fred", json.loads(req.data.decode("utf-8"))["name"]) assert "Jeanne" == json.loads(req.data.decode("utf-8"))["name"]
self.assertEqual(2, json.loads(req.data.decode("utf-8"))["weight"]) assert 2 == json.loads(req.data.decode("utf-8"))["weight"]
# edit this member with same information # edit this member with same information
# (test PUT idemopotence) # (test PUT idempotence)
req = self.client.put( req = self.client.put(
"/api/projects/raclette/members/1", "/api/projects/raclette/members/1",
data={"name": "Fred"}, data={"name": "Jeanne"},
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
@ -299,7 +342,7 @@ class APITestCase(IhatemoneyTestCase):
# de-activate the participant # de-activate the participant
req = self.client.put( req = self.client.put(
"/api/projects/raclette/members/1", "/api/projects/raclette/members/1",
data={"name": "Fred", "activated": False}, data={"name": "Jeanne", "activated": False},
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
self.assertStatus(200, req) self.assertStatus(200, req)
@ -308,12 +351,12 @@ class APITestCase(IhatemoneyTestCase):
"/api/projects/raclette/members/1", headers=self.get_auth("raclette") "/api/projects/raclette/members/1", headers=self.get_auth("raclette")
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual(False, json.loads(req.data.decode("utf-8"))["activated"]) assert not json.loads(req.data.decode("utf-8"))["activated"]
# re-activate the participant # re-activate the participant
req = self.client.put( req = self.client.put(
"/api/projects/raclette/members/1", "/api/projects/raclette/members/1",
data={"name": "Fred", "activated": True}, data={"name": "Jeanne", "activated": True},
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
@ -321,7 +364,7 @@ class APITestCase(IhatemoneyTestCase):
"/api/projects/raclette/members/1", headers=self.get_auth("raclette") "/api/projects/raclette/members/1", headers=self.get_auth("raclette")
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual(True, json.loads(req.data.decode("utf-8"))["activated"]) assert json.loads(req.data.decode("utf-8"))["activated"]
# delete a member # delete a member
@ -337,7 +380,7 @@ class APITestCase(IhatemoneyTestCase):
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual("[]\n", req.data.decode("utf-8")) assert "[]\n" == req.data.decode("utf-8")
def test_bills(self): def test_bills(self):
# create a project # create a project
@ -345,7 +388,7 @@ class APITestCase(IhatemoneyTestCase):
# add participants # add participants
self.api_add_member("raclette", "zorglub") self.api_add_member("raclette", "zorglub")
self.api_add_member("raclette", "fred") self.api_add_member("raclette", "jeanne")
self.api_add_member("raclette", "quentin") self.api_add_member("raclette", "quentin")
# get the list of bills (should be empty) # get the list of bills (should be empty)
@ -354,7 +397,7 @@ class APITestCase(IhatemoneyTestCase):
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual("[]\n", req.data.decode("utf-8")) assert "[]\n" == req.data.decode("utf-8")
# add a bill # add a bill
req = self.client.post( req = self.client.post(
@ -373,7 +416,7 @@ class APITestCase(IhatemoneyTestCase):
# should return the id # should return the id
self.assertStatus(201, req) self.assertStatus(201, req)
self.assertEqual(req.data.decode("utf-8"), "1\n") assert req.data.decode("utf-8") == "1\n"
# get this bill details # get this bill details
req = self.client.get( req = self.client.get(
@ -387,7 +430,7 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 1, "payer_id": 1,
"owers": [ "owers": [
{"activated": True, "id": 1, "name": "zorglub", "weight": 1}, {"activated": True, "id": 1, "name": "zorglub", "weight": 1},
{"activated": True, "id": 2, "name": "fred", "weight": 1}, {"activated": True, "id": 2, "name": "jeanne", "weight": 1},
], ],
"bill_type": "Expense", "bill_type": "Expense",
"amount": 25.0, "amount": 25.0,
@ -399,19 +442,19 @@ class APITestCase(IhatemoneyTestCase):
} }
got = json.loads(req.data.decode("utf-8")) got = json.loads(req.data.decode("utf-8"))
self.assertEqual( assert (
datetime.date.today(), datetime.date.today()
datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(), == datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date()
) )
del got["creation_date"] del got["creation_date"]
self.assertDictEqual(expected, got) assert expected == got
# the list of bills should length 1 # the list of bills should length 1
req = self.client.get( req = self.client.get(
"/api/projects/raclette/bills", headers=self.get_auth("raclette") "/api/projects/raclette/bills", headers=self.get_auth("raclette")
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual(1, len(json.loads(req.data.decode("utf-8")))) assert 1 == len(json.loads(req.data.decode("utf-8")))
# edit with errors should return an error # edit with errors should return an error
req = self.client.put( req = self.client.put(
@ -429,10 +472,7 @@ class APITestCase(IhatemoneyTestCase):
) )
self.assertStatus(400, req) self.assertStatus(400, req)
self.assertEqual( assert '{"date": ["This field is required."]}\n' == req.data.decode("utf-8")
"".join('{"date": ["This field is required."]}'.split()),
"".join(req.data.decode("utf-8").split()),
)
# edit a bill # edit a bill
req = self.client.put( req = self.client.put(
@ -462,7 +502,7 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 2, "payer_id": 2,
"owers": [ "owers": [
{"activated": True, "id": 1, "name": "zorglub", "weight": 1}, {"activated": True, "id": 1, "name": "zorglub", "weight": 1},
{"activated": True, "id": 2, "name": "fred", "weight": 1}, {"activated": True, "id": 2, "name": "jeanne", "weight": 1},
], ],
"bill_type": "Expense", "bill_type": "Expense",
"amount": 25.0, "amount": 25.0,
@ -474,12 +514,12 @@ class APITestCase(IhatemoneyTestCase):
} }
got = json.loads(req.data.decode("utf-8")) got = json.loads(req.data.decode("utf-8"))
self.assertEqual( assert (
creation_date, creation_date
datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(), == datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date()
) )
del got["creation_date"] del got["creation_date"]
self.assertDictEqual(expected, got) assert expected == got
# delete a bill # delete a bill
req = self.client.delete( req = self.client.delete(
@ -499,7 +539,7 @@ class APITestCase(IhatemoneyTestCase):
# add participants # add participants
self.api_add_member("raclette", "zorglub") self.api_add_member("raclette", "zorglub")
self.api_add_member("raclette", "fred") self.api_add_member("raclette", "jeanne")
# valid amounts # valid amounts
input_expected = [ input_expected = [
@ -527,7 +567,7 @@ class APITestCase(IhatemoneyTestCase):
# should return the id # should return the id
self.assertStatus(201, req) self.assertStatus(201, req)
self.assertEqual(req.data.decode("utf-8"), "{}\n".format(id)) assert req.data.decode("utf-8") == "{}\n".format(id)
# get this bill's details # get this bill's details
req = self.client.get( req = self.client.get(
@ -542,7 +582,7 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 1, "payer_id": 1,
"owers": [ "owers": [
{"activated": True, "id": 1, "name": "zorglub", "weight": 1}, {"activated": True, "id": 1, "name": "zorglub", "weight": 1},
{"activated": True, "id": 2, "name": "fred", "weight": 1}, {"activated": True, "id": 2, "name": "jeanne", "weight": 1},
], ],
"bill_type": "Expense", "bill_type": "Expense",
"amount": expected_amount, "amount": expected_amount,
@ -554,12 +594,12 @@ class APITestCase(IhatemoneyTestCase):
} }
got = json.loads(req.data.decode("utf-8")) got = json.loads(req.data.decode("utf-8"))
self.assertEqual( assert (
datetime.date.today(), datetime.date.today()
datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(), == datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date()
) )
del got["creation_date"] del got["creation_date"]
self.assertDictEqual(expected, got) assert expected == got
# should raise errors # should raise errors
erroneous_amounts = [ erroneous_amounts = [
@ -585,22 +625,23 @@ class APITestCase(IhatemoneyTestCase):
) )
self.assertStatus(400, req) self.assertStatus(400, req)
@pytest.mark.skip(reason="Currency conversion is broken")
def test_currencies(self): def test_currencies(self):
# check /currencies for list of supported currencies # check /currencies for list of supported currencies
resp = self.client.get("/api/currencies") resp = self.client.get("/api/currencies")
self.assertTrue(201, resp.status_code) assert 200 == resp.status_code
self.assertIn("XXX", json.loads(resp.data.decode("utf-8"))) assert "XXX" in json.loads(resp.data.decode("utf-8"))
# create project with a default currency # create project with a default currency
resp = self.api_create("raclette", default_currency="EUR") resp = self.api_create("raclette", default_currency="EUR")
self.assertTrue(201, resp.status_code) assert 201 == resp.status_code
# get information about it # get information about it
resp = self.client.get( resp = self.client.get(
"/api/projects/raclette", headers=self.get_auth("raclette") "/api/projects/raclette", headers=self.get_auth("raclette")
) )
self.assertTrue(200, resp.status_code) assert 200 == resp.status_code
expected = { expected = {
"members": [], "members": [],
"name": "raclette", "name": "raclette",
@ -610,11 +651,11 @@ class APITestCase(IhatemoneyTestCase):
"logging_preference": 1, "logging_preference": 1,
} }
decoded_resp = json.loads(resp.data.decode("utf-8")) decoded_resp = json.loads(resp.data.decode("utf-8"))
self.assertDictEqual(decoded_resp, expected) assert decoded_resp == expected
# Add participants # Add participants
self.api_add_member("raclette", "zorglub") self.api_add_member("raclette", "zorglub")
self.api_add_member("raclette", "fred") self.api_add_member("raclette", "jeanne")
self.api_add_member("raclette", "quentin") self.api_add_member("raclette", "quentin")
# Add a bill without explicit currency # Add a bill without explicit currency
@ -634,7 +675,7 @@ class APITestCase(IhatemoneyTestCase):
# should return the id # should return the id
self.assertStatus(201, req) self.assertStatus(201, req)
self.assertEqual(req.data.decode("utf-8"), "1\n") assert req.data.decode("utf-8") == "1\n"
# get this bill details # get this bill details
req = self.client.get( req = self.client.get(
@ -648,7 +689,7 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 1, "payer_id": 1,
"owers": [ "owers": [
{"activated": True, "id": 1, "name": "zorglub", "weight": 1}, {"activated": True, "id": 1, "name": "zorglub", "weight": 1},
{"activated": True, "id": 2, "name": "fred", "weight": 1}, {"activated": True, "id": 2, "name": "jeanne", "weight": 1},
], ],
"bill_type": "Expense", "bill_type": "Expense",
"amount": 25.0, "amount": 25.0,
@ -660,12 +701,12 @@ class APITestCase(IhatemoneyTestCase):
} }
got = json.loads(req.data.decode("utf-8")) got = json.loads(req.data.decode("utf-8"))
self.assertEqual( assert (
datetime.date.today(), datetime.date.today()
datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(), == datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date()
) )
del got["creation_date"] del got["creation_date"]
self.assertDictEqual(expected, got) assert expected == got
# Change bill amount and currency # Change bill amount and currency
req = self.client.put( req = self.client.put(
@ -695,7 +736,7 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 1, "payer_id": 1,
"owers": [ "owers": [
{"activated": True, "id": 1, "name": "zorglub", "weight": 1.0}, {"activated": True, "id": 1, "name": "zorglub", "weight": 1.0},
{"activated": True, "id": 2, "name": "fred", "weight": 1.0}, {"activated": True, "id": 2, "name": "jeanne", "weight": 1.0},
], ],
"bill_type": "Expense", "bill_type": "Expense",
"amount": 30.0, "amount": 30.0,
@ -708,7 +749,7 @@ class APITestCase(IhatemoneyTestCase):
got = json.loads(req.data.decode("utf-8")) got = json.loads(req.data.decode("utf-8"))
del got["creation_date"] del got["creation_date"]
self.assertDictEqual(expected, got) assert expected == got
# Add a bill with yet another currency # Add a bill with yet another currency
req = self.client.post( req = self.client.post(
@ -727,7 +768,7 @@ class APITestCase(IhatemoneyTestCase):
# should return the id # should return the id
self.assertStatus(201, req) self.assertStatus(201, req)
self.assertEqual(req.data.decode("utf-8"), "2\n") assert req.data.decode("utf-8") == "2\n"
# Try to remove default project currency, it should fail # Try to remove default project currency, it should fail
req = self.client.put( req = self.client.put(
@ -735,15 +776,16 @@ class APITestCase(IhatemoneyTestCase):
data={ data={
"contact_email": "yeah@notmyidea.org", "contact_email": "yeah@notmyidea.org",
"default_currency": "XXX", "default_currency": "XXX",
"current_password": "raclette",
"password": "raclette", "password": "raclette",
"name": "The raclette party", "name": "The raclette party",
}, },
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
self.assertStatus(400, req) self.assertStatus(400, req)
self.assertIn("This project cannot be set", req.data.decode("utf-8")) assert "This project cannot be set" in req.data.decode("utf-8")
self.assertIn( assert "because it contains bills in multiple currencies" in req.data.decode(
"because it contains bills in multiple currencies", req.data.decode("utf-8") "utf-8"
) )
def test_statistics(self): def test_statistics(self):
@ -752,7 +794,7 @@ class APITestCase(IhatemoneyTestCase):
# add participants # add participants
self.api_add_member("raclette", "zorglub") self.api_add_member("raclette", "zorglub")
self.api_add_member("raclette", "fred") self.api_add_member("raclette", "jeanne")
# add a bill # add a bill
req = self.client.post( req = self.client.post(
@ -773,33 +815,30 @@ class APITestCase(IhatemoneyTestCase):
"/api/projects/raclette/statistics", headers=self.get_auth("raclette") "/api/projects/raclette/statistics", headers=self.get_auth("raclette")
) )
self.assertStatus(200, req) self.assertStatus(200, req)
self.assertEqual( assert [
[ {
{ "balance": 12.5,
"balance": 12.5, "member": {
"member": { "activated": True,
"activated": True, "id": 1,
"id": 1, "name": "zorglub",
"name": "zorglub", "weight": 1.0,
"weight": 1.0,
},
"paid": 25.0,
"spent": 12.5,
}, },
{ "paid": 25.0,
"balance": -12.5, "spent": 12.5,
"member": { },
"activated": True, {
"id": 2, "balance": -12.5,
"name": "fred", "member": {
"weight": 1.0, "activated": True,
}, "id": 2,
"paid": 0, "name": "jeanne",
"spent": 12.5, "weight": 1.0,
}, },
], "paid": 0,
json.loads(req.data.decode("utf-8")), "spent": 12.5,
) },
] == json.loads(req.data.decode("utf-8"))
def test_username_xss(self): def test_username_xss(self):
# create a project # create a project
@ -811,7 +850,7 @@ class APITestCase(IhatemoneyTestCase):
self.api_add_member("raclette", "<script>") self.api_add_member("raclette", "<script>")
result = self.client.get("/raclette/") result = self.client.get("/raclette/")
self.assertNotIn("<script>", result.data.decode("utf-8")) assert "<script>" not in result.data.decode("utf-8")
def test_weighted_bills(self): def test_weighted_bills(self):
# create a project # create a project
@ -819,7 +858,7 @@ class APITestCase(IhatemoneyTestCase):
# add participants # add participants
self.api_add_member("raclette", "zorglub") self.api_add_member("raclette", "zorglub")
self.api_add_member("raclette", "freddy familly", 4) self.api_add_member("raclette", "jeannedy familly", 4)
self.api_add_member("raclette", "quentin") self.api_add_member("raclette", "quentin")
# add a bill # add a bill
@ -851,7 +890,7 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 1, "payer_id": 1,
"owers": [ "owers": [
{"activated": True, "id": 1, "name": "zorglub", "weight": 1}, {"activated": True, "id": 1, "name": "zorglub", "weight": 1},
{"activated": True, "id": 2, "name": "freddy familly", "weight": 4}, {"activated": True, "id": 2, "name": "jeannedy familly", "weight": 4},
], ],
"bill_type": "Expense", "bill_type": "Expense",
"amount": 25.0, "amount": 25.0,
@ -862,12 +901,12 @@ class APITestCase(IhatemoneyTestCase):
"original_currency": "XXX", "original_currency": "XXX",
} }
got = json.loads(req.data.decode("utf-8")) got = json.loads(req.data.decode("utf-8"))
self.assertEqual( assert (
creation_date, creation_date
datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(), == datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date()
) )
del got["creation_date"] del got["creation_date"]
self.assertDictEqual(expected, got) assert expected == got
# getting it should return a 404 # getting it should return a 404
req = self.client.get( req = self.client.get(
@ -886,7 +925,7 @@ class APITestCase(IhatemoneyTestCase):
{ {
"activated": True, "activated": True,
"id": 2, "id": 2,
"name": "freddy familly", "name": "jeannedy familly",
"weight": 4.0, "weight": 4.0,
"balance": -20.0, "balance": -20.0,
}, },
@ -907,7 +946,7 @@ class APITestCase(IhatemoneyTestCase):
self.assertStatus(200, req) self.assertStatus(200, req)
decoded_req = json.loads(req.data.decode("utf-8")) decoded_req = json.loads(req.data.decode("utf-8"))
self.assertDictEqual(decoded_req, expected) assert decoded_req == expected
def test_log_created_from_api_call(self): def test_log_created_from_api_call(self):
# create a project # create a project
@ -918,15 +957,13 @@ class APITestCase(IhatemoneyTestCase):
self.api_add_member("raclette", "zorglub") self.api_add_member("raclette", "zorglub")
resp = self.client.get("/raclette/history", follow_redirects=True) resp = self.client.get("/raclette/history", follow_redirects=True)
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert f"Participant {em_surround('zorglub')} added" in resp.data.decode(
f"Participant {em_surround('zorglub')} added", resp.data.decode("utf-8") "utf-8"
) )
self.assertIn( assert f"Project {em_surround('raclette')} added" in resp.data.decode("utf-8")
f"Project {em_surround('raclette')} added", resp.data.decode("utf-8") assert resp.data.decode("utf-8").count("<td> -- </td>") == 2
) assert "127.0.0.1" not in resp.data.decode("utf-8")
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2)
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
def test_amount_is_null(self): def test_amount_is_null(self):
self.api_create("raclette") self.api_create("raclette")
@ -946,7 +983,7 @@ class APITestCase(IhatemoneyTestCase):
}, },
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
self.assertStatus(400, req) self.assertStatus(201, req)
def test_project_creation_with_mixed_case(self): def test_project_creation_with_mixed_case(self):
self.api_create("Raclette") self.api_create("Raclette")
@ -976,7 +1013,3 @@ class APITestCase(IhatemoneyTestCase):
headers=self.get_auth("raclette"), headers=self.get_auth("raclette"),
) )
self.assertStatus(400, req) self.assertStatus(400, req)
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load diff

View file

@ -1,45 +1,20 @@
import os import os
from unittest.mock import MagicMock
from flask_testing import TestCase import pytest
from werkzeug.security import generate_password_hash
from ihatemoney import models from ihatemoney import models
from ihatemoney.currency_convertor import CurrencyConverter from ihatemoney.utils import generate_password_hash
from ihatemoney.run import create_app, db
class BaseTestCase(TestCase): @pytest.mark.usefixtures("client", "converter")
class BaseTestCase:
SECRET_KEY = "TEST SESSION" SECRET_KEY = "TEST SESSION"
SQLALCHEMY_DATABASE_URI = os.environ.get( SQLALCHEMY_DATABASE_URI = os.environ.get(
"TESTING_SQLALCHEMY_DATABASE_URI", "sqlite://" "TESTING_SQLALCHEMY_DATABASE_URI", "sqlite://"
) )
ENABLE_CAPTCHA = False ENABLE_CAPTCHA = False
PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
def create_app(self): PASSWORD_HASH_SALT_LENGTH = 1
# Pass the test object as a configuration.
return create_app(self)
def setUp(self):
db.create_all()
# Add dummy data to CurrencyConverter for all tests (since it's a singleton)
mock_data = {
"USD": 1,
"EUR": 0.8,
"CAD": 1.2,
"PLN": 4,
CurrencyConverter.no_currency: 1,
}
converter = CurrencyConverter()
converter.get_rates = MagicMock(return_value=mock_data)
# Also add it to an attribute to make tests clearer
self.converter = converter
def tearDown(self):
# clean after testing
db.session.remove()
db.drop_all()
def login(self, project, password=None, test_client=None): def login(self, project, password=None, test_client=None):
password = password or project password = password or project
@ -57,6 +32,7 @@ class BaseTestCase(TestCase):
default_currency="XXX", default_currency="XXX",
name=None, name=None,
password=None, password=None,
project_history=True,
): ):
"""Create a fake project""" """Create a fake project"""
name = name or id name = name or id
@ -70,6 +46,7 @@ class BaseTestCase(TestCase):
"password": password, "password": password,
"contact_email": f"{id}@notmyidea.org", "contact_email": f"{id}@notmyidea.org",
"default_currency": default_currency, "default_currency": default_currency,
"project_history": project_history,
}, },
follow_redirects=follow_redirects, follow_redirects=follow_redirects,
) )
@ -80,7 +57,7 @@ class BaseTestCase(TestCase):
data=data, data=data,
# follow_redirects=True, # follow_redirects=True,
) )
self.assertEqual("/{id}/edit" in str(resp.response), not success) assert ("/{id}/edit" in str(resp.response)) == (not success)
def create_project(self, id, default_currency="XXX", name=None, password=None): def create_project(self, id, default_currency="XXX", name=None, password=None):
name = name or str(id) name = name or str(id)
@ -106,8 +83,15 @@ class IhatemoneyTestCase(BaseTestCase):
def assertStatus(self, expected, resp, url=None): def assertStatus(self, expected, resp, url=None):
if url is None: if url is None:
url = resp.request.path url = resp.request.path
return self.assertEqual( assert (
expected, expected == resp.status_code
resp.status_code, ), f"{url} expected {expected}, got {resp.status_code}"
f"{url} expected {expected}, got {resp.status_code}",
def enable_admin(self, password="adminpass"):
self.app.config["ACTIVATE_ADMIN_DASHBOARD"] = True
self.app.config["ADMIN_PASSWORD"] = generate_password_hash(password)
return self.client.post(
"/admin?goto=%2Fdashboard",
data={"admin_password": password},
follow_redirects=True,
) )

View file

@ -0,0 +1,55 @@
from unittest.mock import MagicMock
from flask import Flask
import pytest
from ihatemoney.babel_utils import compile_catalogs
from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.run import create_app, db
@pytest.fixture(autouse=True, scope="session")
def babel_catalogs():
compile_catalogs()
@pytest.fixture
def app(request: pytest.FixtureRequest):
"""Create the Flask app with database"""
app = create_app(request.cls)
with app.app_context():
db.create_all()
request.cls.app = app
yield app
# clean after testing
db.session.remove()
db.drop_all()
@pytest.fixture
def client(app: Flask, request: pytest.FixtureRequest):
client = app.test_client()
request.cls.client = client
yield client
@pytest.fixture
def converter(request: pytest.FixtureRequest):
# Add dummy data to CurrencyConverter for all tests (since it's a singleton)
mock_data = {
"USD": 1,
"EUR": 0.8,
"CAD": 1.2,
"PLN": 4,
CurrencyConverter.no_currency: 1,
}
converter = CurrencyConverter()
converter.get_rates = MagicMock(return_value=mock_data)
# Also add it to an attribute to make tests clearer
request.cls.converter = converter
yield converter

View file

@ -1,4 +1,6 @@
import unittest import re
import pytest
from ihatemoney import history, models from ihatemoney import history, models
from ihatemoney.tests.common.help_functions import em_surround from ihatemoney.tests.common.help_functions import em_surround
@ -6,24 +8,40 @@ from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase
from ihatemoney.versioning import LoggingMode from ihatemoney.versioning import LoggingMode
class HistoryTestCase(IhatemoneyTestCase): @pytest.fixture
def setUp(self): def demo(client):
super().setUp() client.post(
self.post_project("demo") "/create",
self.login("demo") data={
"name": "demo",
"id": "demo",
"password": "demo",
"contact_email": "demo@notmyidea.org",
"default_currency": "XXX",
"project_history": True,
},
)
client.post(
"/authenticate",
data=dict(id="demo", password="demo"),
)
@pytest.mark.usefixtures("demo")
class TestHistory(IhatemoneyTestCase):
def test_simple_create_logentry_no_ip(self): def test_simple_create_logentry_no_ip(self):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn(f"Project {em_surround('demo')} added", resp.data.decode("utf-8")) assert f"Project {em_surround('demo')} added" in resp.data.decode("utf-8")
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 1) assert resp.data.decode("utf-8").count("<td> -- </td>") == 1
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) assert "127.0.0.1" not in resp.data.decode("utf-8")
def change_privacy_to(self, logging_preference): def change_privacy_to(self, current_password, logging_preference):
# Change only logging_preferences # Change only logging_preferences
new_data = { new_data = {
"name": "demo", "name": "demo",
"contact_email": "demo@notmyidea.org", "contact_email": "demo@notmyidea.org",
"current_password": current_password,
"password": "demo", "password": "demo",
"default_currency": "XXX", "default_currency": "XXX",
} }
@ -35,142 +53,136 @@ class HistoryTestCase(IhatemoneyTestCase):
# Disable History # Disable History
resp = self.client.post("/demo/edit", data=new_data, follow_redirects=True) resp = self.client.post("/demo/edit", data=new_data, follow_redirects=True)
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertNotIn("danger", resp.data.decode("utf-8")) assert "alert-danger" not in resp.data.decode("utf-8")
resp = self.client.get("/demo/edit") resp = self.client.get("/demo/edit")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
if logging_preference == LoggingMode.DISABLED: if logging_preference == LoggingMode.DISABLED:
self.assertIn('<input id="project_history"', resp.data.decode("utf-8")) assert '<input id="project_history"' in resp.data.decode("utf-8")
else: else:
self.assertIn( assert '<input checked id="project_history"' in resp.data.decode("utf-8")
'<input checked id="project_history"', resp.data.decode("utf-8")
)
if logging_preference == LoggingMode.RECORD_IP: if logging_preference == LoggingMode.RECORD_IP:
self.assertIn('<input checked id="ip_recording"', resp.data.decode("utf-8")) assert '<input checked id="ip_recording"' in resp.data.decode("utf-8")
else: else:
self.assertIn('<input id="ip_recording"', resp.data.decode("utf-8")) assert '<input id="ip_recording"' in resp.data.decode("utf-8")
def assert_empty_history_logging_disabled(self): def assert_empty_history_logging_disabled(self):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertIn( assert (
"This project has history disabled. New actions won't appear below. ", "This project has history disabled. New actions won't appear below."
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
self.assertIn("Nothing to list", resp.data.decode("utf-8")) assert "Nothing to list" in resp.data.decode("utf-8")
self.assertNotIn( assert (
"The table below reflects actions recorded prior to disabling project history.", "The table below reflects actions recorded prior to disabling project history."
resp.data.decode("utf-8"), not in resp.data.decode("utf-8")
) )
self.assertNotIn( assert "Some entries below contain IP addresses," not in resp.data.decode(
"Some entries below contain IP addresses,", resp.data.decode("utf-8") "utf-8"
)
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
self.assertNotIn("<td> -- </td>", resp.data.decode("utf-8"))
self.assertNotIn(
f"Project {em_surround('demo')} added", resp.data.decode("utf-8")
) )
assert "127.0.0.1" not in resp.data.decode("utf-8")
assert "<td> -- </td>" not in resp.data.decode("utf-8")
assert f"Project {em_surround('demo')} added" not in resp.data.decode("utf-8")
def test_project_edit(self): def test_project_edit(self):
new_data = { new_data = {
"name": "demo2", "name": "demo2",
"contact_email": "demo2@notmyidea.org", "contact_email": "demo2@notmyidea.org",
"current_password": "demo",
"password": "123456", "password": "123456",
"project_history": "y", "project_history": "y",
"default_currency": "USD", # Currency changed from default "default_currency": "USD", # Currency changed from default
} }
resp = self.client.post("/demo/edit", data=new_data, follow_redirects=True) resp = self.client.post("/demo/edit", data=new_data, follow_redirects=True)
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn(f"Project {em_surround('demo')} added", resp.data.decode("utf-8")) assert f"Project {em_surround('demo')} added" in resp.data.decode("utf-8")
self.assertIn( assert (
f"Project contact email changed to {em_surround('demo2@notmyidea.org')}", f"Project contact email changed to {em_surround('demo2@notmyidea.org')}"
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
self.assertIn("Project private code changed", resp.data.decode("utf-8")) assert "Project private code changed" in resp.data.decode("utf-8")
self.assertIn( assert f"Project renamed to {em_surround('demo2')}" in resp.data.decode("utf-8")
f"Project renamed to {em_surround('demo2')}", resp.data.decode("utf-8") assert resp.data.decode("utf-8").index("Project renamed ") < resp.data.decode(
) "utf-8"
self.assertLess( ).index("Project contact email changed to ")
resp.data.decode("utf-8").index("Project renamed "), assert resp.data.decode("utf-8").index("Project renamed ") < resp.data.decode(
resp.data.decode("utf-8").index("Project contact email changed to "), "utf-8"
) ).index("Project private code changed")
self.assertLess( assert resp.data.decode("utf-8").count("<td> -- </td>") == 5
resp.data.decode("utf-8").index("Project renamed "), assert "127.0.0.1" not in resp.data.decode("utf-8")
resp.data.decode("utf-8").index("Project private code changed"),
)
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 5)
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
def test_project_privacy_edit(self): def test_project_privacy_edit(self):
resp = self.client.get("/demo/edit") resp = self.client.get("/demo/edit")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert (
'<input checked id="project_history" name="project_history" type="checkbox" value="y">', '<input checked id="project_history" name="project_history" type="checkbox" value="y">'
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
self.change_privacy_to(LoggingMode.DISABLED) self.change_privacy_to("demo", LoggingMode.DISABLED)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn("Disabled Project History\n", resp.data.decode("utf-8")) assert "Disabled Project History\n" in resp.data.decode("utf-8")
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2) assert resp.data.decode("utf-8").count("<td> -- </td>") == 2
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) assert "127.0.0.1" not in resp.data.decode("utf-8")
self.change_privacy_to(LoggingMode.RECORD_IP) self.change_privacy_to("demo", LoggingMode.RECORD_IP)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert "Enabled Project History & IP Address Recording" in resp.data.decode(
"Enabled Project History & IP Address Recording", resp.data.decode("utf-8") "utf-8"
) )
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2) assert resp.data.decode("utf-8").count("<td> -- </td>") == 2
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 1) assert resp.data.decode("utf-8").count("127.0.0.1") == 1
self.change_privacy_to(LoggingMode.ENABLED) self.change_privacy_to("demo", LoggingMode.ENABLED)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn("Disabled IP Address Recording\n", resp.data.decode("utf-8")) assert "Disabled IP Address Recording\n" in resp.data.decode("utf-8")
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2) assert resp.data.decode("utf-8").count("<td> -- </td>") == 2
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 2) assert resp.data.decode("utf-8").count("127.0.0.1") == 2
def test_project_privacy_edit2(self): def test_project_privacy_edit2(self):
self.change_privacy_to(LoggingMode.RECORD_IP) self.change_privacy_to("demo", LoggingMode.RECORD_IP)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn("Enabled IP Address Recording\n", resp.data.decode("utf-8")) assert "Enabled IP Address Recording\n" in resp.data.decode("utf-8")
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 1) assert resp.data.decode("utf-8").count("<td> -- </td>") == 1
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 1) assert resp.data.decode("utf-8").count("127.0.0.1") == 1
self.change_privacy_to(LoggingMode.DISABLED) self.change_privacy_to("demo", LoggingMode.DISABLED)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert "Disabled Project History & IP Address Recording" in resp.data.decode(
"Disabled Project History & IP Address Recording", resp.data.decode("utf-8") "utf-8"
) )
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 1) assert resp.data.decode("utf-8").count("<td> -- </td>") == 1
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 2) assert resp.data.decode("utf-8").count("127.0.0.1") == 2
self.change_privacy_to(LoggingMode.ENABLED) self.change_privacy_to("demo", LoggingMode.ENABLED)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn("Enabled Project History\n", resp.data.decode("utf-8")) assert "Enabled Project History\n" in resp.data.decode("utf-8")
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2) assert resp.data.decode("utf-8").count("<td> -- </td>") == 2
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 2) assert resp.data.decode("utf-8").count("127.0.0.1") == 2
def do_misc_database_operations(self, logging_mode): def do_misc_database_operations(self, logging_mode):
new_data = { new_data = {
"name": "demo2", "name": "demo2",
"contact_email": "demo2@notmyidea.org", "contact_email": "demo2@notmyidea.org",
"current_password": "demo",
"password": "123456", "password": "123456",
"default_currency": "USD", "default_currency": "USD",
} }
@ -182,13 +194,13 @@ class HistoryTestCase(IhatemoneyTestCase):
new_data["ip_recording"] = "y" new_data["ip_recording"] = "y"
resp = self.client.post("/demo/edit", data=new_data, follow_redirects=True) resp = self.client.post("/demo/edit", data=new_data, follow_redirects=True)
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
# adds a member to this project # adds a member to this project
resp = self.client.post( resp = self.client.post(
"/demo/members/add", data={"name": "zorglub"}, follow_redirects=True "/demo/members/add", data={"name": "zorglub"}, follow_redirects=True
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
user_id = models.Person.query.one().id user_id = models.Person.query.one().id
@ -205,7 +217,7 @@ class HistoryTestCase(IhatemoneyTestCase):
}, },
follow_redirects=True, follow_redirects=True,
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
bill_id = models.Bill.query.one().id bill_id = models.Bill.query.one().id
@ -222,44 +234,41 @@ class HistoryTestCase(IhatemoneyTestCase):
}, },
follow_redirects=True, follow_redirects=True,
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
# delete the bill # delete the bill
resp = self.client.post(f"/demo/delete/{bill_id}", follow_redirects=True) resp = self.client.post(f"/demo/delete/{bill_id}", follow_redirects=True)
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
# delete user using POST method # delete user using POST method
resp = self.client.post( resp = self.client.post(
f"/demo/members/{user_id}/delete", follow_redirects=True f"/demo/members/{user_id}/delete", follow_redirects=True
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
def test_disable_clear_no_new_records(self): def test_disable_clear_no_new_records(self):
# Disable logging # Disable logging
self.change_privacy_to(LoggingMode.DISABLED) self.change_privacy_to("demo", LoggingMode.DISABLED)
# Ensure we can't clear history with a GET or with a password-less POST # Ensure we can't clear history with a GET or with a password-less POST
resp = self.client.get("/demo/erase_history") resp = self.client.get("/demo/erase_history")
self.assertEqual(resp.status_code, 405) assert resp.status_code == 405
resp = self.client.post("/demo/erase_history", follow_redirects=True) resp = self.client.post("/demo/erase_history", follow_redirects=True)
self.assertIn( assert "Error deleting project history" in resp.data.decode("utf-8")
"Error deleting project history",
resp.data.decode("utf-8"),
)
# List history # List history
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert (
"This project has history disabled. New actions won't appear below. ", "This project has history disabled. New actions won't appear below."
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
self.assertIn( assert (
"The table below reflects actions recorded prior to disabling project history.", "The table below reflects actions recorded prior to disabling project history."
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
self.assertNotIn("Nothing to list", resp.data.decode("utf-8")) assert "Nothing to list" not in resp.data.decode("utf-8")
self.assertNotIn( assert "Some entries below contain IP addresses," not in resp.data.decode(
"Some entries below contain IP addresses,", resp.data.decode("utf-8") "utf-8"
) )
# Clear Existing Entries # Clear Existing Entries
@ -268,7 +277,7 @@ class HistoryTestCase(IhatemoneyTestCase):
data={"password": "demo"}, data={"password": "demo"},
follow_redirects=True, follow_redirects=True,
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assert_empty_history_logging_disabled() self.assert_empty_history_logging_disabled()
# Do lots of database operations & check that there's still no history # Do lots of database operations & check that there's still no history
@ -278,52 +287,47 @@ class HistoryTestCase(IhatemoneyTestCase):
def test_clear_ip_records(self): def test_clear_ip_records(self):
# Enable IP Recording # Enable IP Recording
self.change_privacy_to(LoggingMode.RECORD_IP) self.change_privacy_to("demo", LoggingMode.RECORD_IP)
# Do lots of database operations to generate IP address entries # Do lots of database operations to generate IP address entries
self.do_misc_database_operations(LoggingMode.RECORD_IP) self.do_misc_database_operations(LoggingMode.RECORD_IP)
# Disable IP Recording # Disable IP Recording
self.change_privacy_to(LoggingMode.ENABLED) self.change_privacy_to("123456", LoggingMode.ENABLED)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertNotIn( assert (
"This project has history disabled. New actions won't appear below. ", "This project has history disabled. New actions won't appear below."
resp.data.decode("utf-8"), not in resp.data.decode("utf-8")
) )
self.assertNotIn( assert (
"The table below reflects actions recorded prior to disabling project history.", "The table below reflects actions recorded prior to disabling project history."
resp.data.decode("utf-8"), not in resp.data.decode("utf-8")
) )
self.assertNotIn("Nothing to list", resp.data.decode("utf-8")) assert "Nothing to list" not in resp.data.decode("utf-8")
self.assertIn( assert "Some entries below contain IP addresses," in resp.data.decode("utf-8")
"Some entries below contain IP addresses,", resp.data.decode("utf-8") assert resp.data.decode("utf-8").count("127.0.0.1") == 12
) assert resp.data.decode("utf-8").count("<td> -- </td>") == 1
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 12)
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 1)
# Generate more operations to confirm additional IP info isn't recorded # Generate more operations to confirm additional IP info isn't recorded
self.do_misc_database_operations(LoggingMode.ENABLED) self.do_misc_database_operations(LoggingMode.ENABLED)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 12) assert resp.data.decode("utf-8").count("127.0.0.1") == 12
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 7) assert resp.data.decode("utf-8").count("<td> -- </td>") == 7
# Ensure we can't clear IP data with a GET or with a password-less POST # Ensure we can't clear IP data with a GET or with a password-less POST
resp = self.client.get("/demo/strip_ip_addresses") resp = self.client.get("/demo/strip_ip_addresses")
self.assertEqual(resp.status_code, 405) assert resp.status_code == 405
resp = self.client.post("/demo/strip_ip_addresses", follow_redirects=True) resp = self.client.post("/demo/strip_ip_addresses", follow_redirects=True)
self.assertIn( assert "Error deleting recorded IP addresses" in resp.data.decode("utf-8")
"Error deleting recorded IP addresses",
resp.data.decode("utf-8"),
)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 12) assert resp.data.decode("utf-8").count("127.0.0.1") == 12
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 7) assert resp.data.decode("utf-8").count("<td> -- </td>") == 7
# Clear IP Data # Clear IP Data
resp = self.client.post( resp = self.client.post(
@ -332,33 +336,33 @@ class HistoryTestCase(IhatemoneyTestCase):
follow_redirects=True, follow_redirects=True,
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertNotIn( assert (
"This project has history disabled. New actions won't appear below. ", "This project has history disabled. New actions won't appear below."
resp.data.decode("utf-8"), not in resp.data.decode("utf-8")
) )
self.assertNotIn( assert (
"The table below reflects actions recorded prior to disabling project history.", "The table below reflects actions recorded prior to disabling project history."
resp.data.decode("utf-8"), not in resp.data.decode("utf-8")
) )
self.assertNotIn("Nothing to list", resp.data.decode("utf-8")) assert "Nothing to list" not in resp.data.decode("utf-8")
self.assertNotIn( assert "Some entries below contain IP addresses," not in resp.data.decode(
"Some entries below contain IP addresses,", resp.data.decode("utf-8") "utf-8"
) )
self.assertEqual(resp.data.decode("utf-8").count("127.0.0.1"), 0) assert resp.data.decode("utf-8").count("127.0.0.1") == 0
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 19) assert resp.data.decode("utf-8").count("<td> -- </td>") == 19
def test_logs_for_common_actions(self): def test_logs_for_common_actions(self):
# adds a member to this project # adds a member to this project
resp = self.client.post( resp = self.client.post(
"/demo/members/add", data={"name": "zorglub"}, follow_redirects=True "/demo/members/add", data={"name": "zorglub"}, follow_redirects=True
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert f"Participant {em_surround('zorglub')} added" in resp.data.decode(
f"Participant {em_surround('zorglub')} added", resp.data.decode("utf-8") "utf-8"
) )
# create a bill # create a bill
@ -374,13 +378,12 @@ class HistoryTestCase(IhatemoneyTestCase):
}, },
follow_redirects=True, follow_redirects=True,
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert f"Bill {em_surround('fromage à raclette')} added" in resp.data.decode(
f"Bill {em_surround('fromage à raclette')} added", "utf-8"
resp.data.decode("utf-8"),
) )
# edit the bill # edit the bill
@ -396,44 +399,37 @@ class HistoryTestCase(IhatemoneyTestCase):
}, },
follow_redirects=True, follow_redirects=True,
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert f"Bill {em_surround('fromage à raclette')} added" in resp.data.decode(
f"Bill {em_surround('fromage à raclette')} added", "utf-8"
resp.data.decode("utf-8"),
) )
self.assertRegex( assert re.search(
resp.data.decode("utf-8"),
r"Bill %s:\s* Amount changed\s* from %s\s* to %s" r"Bill %s:\s* Amount changed\s* from %s\s* to %s"
% ( % (
em_surround("fromage à raclette", regex_escape=True), em_surround("fromage à raclette", regex_escape=True),
em_surround("25.0", regex_escape=True), em_surround("25.0", regex_escape=True),
em_surround("10.0", regex_escape=True), em_surround("10.0", regex_escape=True),
), ),
)
self.assertIn(
"Bill %s renamed to %s"
% (em_surround("fromage à raclette"), em_surround("new thing")),
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
) )
self.assertLess( assert "Bill %s renamed to %s" % (
resp.data.decode("utf-8").index( em_surround("fromage à raclette"),
f"Bill {em_surround('fromage à raclette')} renamed to" em_surround("new thing"),
), ) in resp.data.decode("utf-8")
resp.data.decode("utf-8").index("Amount changed"), assert resp.data.decode("utf-8").index(
) f"Bill {em_surround('fromage à raclette')} renamed to"
) < resp.data.decode("utf-8").index("Amount changed")
# delete the bill # delete the bill
resp = self.client.post("/demo/delete/1", follow_redirects=True) resp = self.client.post("/demo/delete/1", follow_redirects=True)
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert f"Bill {em_surround('new thing')} removed" in resp.data.decode("utf-8")
f"Bill {em_surround('new thing')} removed", resp.data.decode("utf-8")
)
# edit user # edit user
resp = self.client.post( resp = self.client.post(
@ -441,43 +437,38 @@ class HistoryTestCase(IhatemoneyTestCase):
data={"weight": 2, "name": "new name"}, data={"weight": 2, "name": "new name"},
follow_redirects=True, follow_redirects=True,
) )
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertRegex( assert re.search(
resp.data.decode("utf-8"),
r"Participant %s:\s* weight changed\s* from %s\s* to %s" r"Participant %s:\s* weight changed\s* from %s\s* to %s"
% ( % (
em_surround("zorglub", regex_escape=True), em_surround("zorglub", regex_escape=True),
em_surround("1.0", regex_escape=True), em_surround("1.0", regex_escape=True),
em_surround("2.0", regex_escape=True), em_surround("2.0", regex_escape=True),
), ),
)
self.assertIn(
"Participant %s renamed to %s"
% (em_surround("zorglub"), em_surround("new name")),
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
) )
self.assertLess( assert "Participant %s renamed to %s" % (
resp.data.decode("utf-8").index( em_surround("zorglub"),
f"Participant {em_surround('zorglub')} renamed" em_surround("new name"),
), ) in resp.data.decode("utf-8")
resp.data.decode("utf-8").index("weight changed"), assert resp.data.decode("utf-8").index(
) f"Participant {em_surround('zorglub')} renamed"
) < resp.data.decode("utf-8").index("weight changed")
# delete user using POST method # delete user using POST method
resp = self.client.post("/demo/members/1/delete", follow_redirects=True) resp = self.client.post("/demo/members/1/delete", follow_redirects=True)
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertIn( assert f"Participant {em_surround('new name')} removed" in resp.data.decode(
f"Participant {em_surround('new name')} removed", resp.data.decode("utf-8") "utf-8"
) )
def test_double_bill_double_person_edit_second(self): def test_double_bill_double_person_edit_second(self):
# add two members # add two members
self.client.post("/demo/members/add", data={"name": "User 1"}) self.client.post("/demo/members/add", data={"name": "User 1"})
self.client.post("/demo/members/add", data={"name": "User 2"}) self.client.post("/demo/members/add", data={"name": "User 2"})
@ -508,9 +499,9 @@ class HistoryTestCase(IhatemoneyTestCase):
# Should be 5 history entries at this point # Should be 5 history entries at this point
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 5) assert resp.data.decode("utf-8").count("<td> -- </td>") == 5
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) assert "127.0.0.1" not in resp.data.decode("utf-8")
# Edit ONLY the amount on the first bill # Edit ONLY the amount on the first bill
self.client.post( self.client.post(
@ -526,28 +517,27 @@ class HistoryTestCase(IhatemoneyTestCase):
) )
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertRegex( assert re.search(
resp.data.decode("utf-8"),
r"Bill {}:\s* Amount changed\s* from {}\s* to {}".format( r"Bill {}:\s* Amount changed\s* from {}\s* to {}".format(
em_surround("Bill 1", regex_escape=True), em_surround("Bill 1", regex_escape=True),
em_surround("25.0", regex_escape=True), em_surround("25.0", regex_escape=True),
em_surround("88.0", regex_escape=True), em_surround("88.0", regex_escape=True),
), ),
resp.data.decode("utf-8"),
) )
self.assertNotRegex( assert not re.search(
resp.data.decode("utf-8"),
r"Removed\s* {}\s* and\s* {}\s* from\s* owers list".format( r"Removed\s* {}\s* and\s* {}\s* from\s* owers list".format(
em_surround("User 1", regex_escape=True), em_surround("User 1", regex_escape=True),
em_surround("User 2", regex_escape=True), em_surround("User 2", regex_escape=True),
), ),
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
) ), resp.data.decode("utf-8")
# Should be 6 history entries at this point # Should be 6 history entries at this point
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 6) assert resp.data.decode("utf-8").count("<td> -- </td>") == 6
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) assert "127.0.0.1" not in resp.data.decode("utf-8")
def test_bill_add_remove_add(self): def test_bill_add_remove_add(self):
# add two members # add two members
@ -571,13 +561,11 @@ class HistoryTestCase(IhatemoneyTestCase):
self.client.post("/demo/delete/1", follow_redirects=True) self.client.post("/demo/delete/1", follow_redirects=True)
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 5) assert resp.data.decode("utf-8").count("<td> -- </td>") == 5
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) assert "127.0.0.1" not in resp.data.decode("utf-8")
self.assertIn(f"Bill {em_surround('Bill 1')} added", resp.data.decode("utf-8")) assert f"Bill {em_surround('Bill 1')} added" in resp.data.decode("utf-8")
self.assertIn( assert f"Bill {em_surround('Bill 1')} removed" in resp.data.decode("utf-8")
f"Bill {em_surround('Bill 1')} removed", resp.data.decode("utf-8")
)
# Add a new bill # Add a new bill
self.client.post( self.client.post(
@ -593,17 +581,15 @@ class HistoryTestCase(IhatemoneyTestCase):
) )
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) assert resp.status_code == 200
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 6) assert resp.data.decode("utf-8").count("<td> -- </td>") == 6
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) assert "127.0.0.1" not in resp.data.decode("utf-8")
self.assertIn(f"Bill {em_surround('Bill 1')} added", resp.data.decode("utf-8")) assert f"Bill {em_surround('Bill 1')} added" in resp.data.decode("utf-8")
self.assertEqual( assert (
resp.data.decode("utf-8").count(f"Bill {em_surround('Bill 1')} added"), 1 resp.data.decode("utf-8").count(f"Bill {em_surround('Bill 1')} added") == 1
)
self.assertIn(f"Bill {em_surround('Bill 2')} added", resp.data.decode("utf-8"))
self.assertIn(
f"Bill {em_surround('Bill 1')} removed", resp.data.decode("utf-8")
) )
assert f"Bill {em_surround('Bill 2')} added" in resp.data.decode("utf-8")
assert f"Bill {em_surround('Bill 1')} removed" in resp.data.decode("utf-8")
def test_double_bill_double_person_edit_second_no_web(self): def test_double_bill_double_person_edit_second_no_web(self):
u1 = models.Person(project_id="demo", name="User 1") u1 = models.Person(project_id="demo", name="User 1")
@ -624,7 +610,7 @@ class HistoryTestCase(IhatemoneyTestCase):
models.db.session.commit() models.db.session.commit()
history_list = history.get_history(self.get_project("demo")) history_list = history.get_history(self.get_project("demo"))
self.assertEqual(len(history_list), 5) assert len(history_list) == 5
# Change just the amount # Change just the amount
b1.amount = 5 b1.amount = 5
@ -633,8 +619,8 @@ class HistoryTestCase(IhatemoneyTestCase):
history_list = history.get_history(self.get_project("demo")) history_list = history.get_history(self.get_project("demo"))
for entry in history_list: for entry in history_list:
if "prop_changed" in entry: if "prop_changed" in entry:
self.assertNotIn("owers", entry["prop_changed"]) assert "owers" not in entry["prop_changed"]
self.assertEqual(len(history_list), 6) assert len(history_list) == 6
def test_delete_history_with_project(self): def test_delete_history_with_project(self):
self.post_project("raclette", password="party") self.post_project("raclette", password="party")
@ -668,7 +654,3 @@ class HistoryTestCase(IhatemoneyTestCase):
# History should be equal to project creation # History should be equal to project creation
history_list = history.get_history(self.get_project("raclette")) history_list = history.get_history(self.get_project("raclette"))
assert len(history_list) == 1 assert len(history_list) == 1
if __name__ == "__main__":
unittest.main()

View file

@ -7,3 +7,6 @@ SQLACHEMY_ECHO = DEBUG
SECRET_KEY = "supersecret" SECRET_KEY = "supersecret"
MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>" MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>"
PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
PASSWORD_HASH_SALT_LENGTH = 1

View file

@ -7,3 +7,6 @@ SQLACHEMY_ECHO = DEBUG
SECRET_KEY = "lalatra" SECRET_KEY = "lalatra"
MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>" MAIL_DEFAULT_SENDER = "Budget manager <admin@example.com>"
PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
PASSWORD_HASH_SALT_LENGTH = 1

View file

@ -1,12 +1,46 @@
import copy import copy
import json import json
import unittest
import pytest
from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase
from ihatemoney.utils import list_of_dicts2csv, list_of_dicts2json from ihatemoney.utils import list_of_dicts2csv, list_of_dicts2json
@pytest.fixture
def import_data(request: pytest.FixtureRequest):
data = [
{
"date": "2017-01-01",
"what": "refund",
"amount": 13.33,
"payer_name": "tata",
"payer_weight": 1.0,
"owers": ["jeanne"],
},
{
"date": "2016-12-31",
"what": "red wine",
"amount": 200.0,
"payer_name": "jeanne",
"payer_weight": 1.0,
"owers": ["zorglub", "tata"],
},
{
"date": "2016-12-31",
"what": "fromage a raclette",
"amount": 10.0,
"payer_name": "zorglub",
"payer_weight": 2.0,
"owers": ["zorglub", "jeanne", "tata", "pepe"],
},
]
request.cls.data = data
yield data
class CommonTestCase(object): class CommonTestCase(object):
@pytest.mark.usefixtures("import_data")
class Import(IhatemoneyTestCase): class Import(IhatemoneyTestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -18,14 +52,14 @@ class CommonTestCase(object):
"amount": 13.33, "amount": 13.33,
"payer_name": "tata", "payer_name": "tata",
"payer_weight": 1.0, "payer_weight": 1.0,
"owers": ["fred"], "owers": ["jeanne"],
}, },
{ {
"date": "2016-12-31", "date": "2016-12-31",
"what": "red wine", "what": "red wine",
"bill_type": "Expense", "bill_type": "Expense",
"amount": 200.0, "amount": 200.0,
"payer_name": "fred", "payer_name": "jeanne",
"payer_weight": 1.0, "payer_weight": 1.0,
"owers": ["zorglub", "tata"], "owers": ["zorglub", "tata"],
}, },
@ -36,7 +70,7 @@ class CommonTestCase(object):
"amount": 10.0, "amount": 10.0,
"payer_name": "zorglub", "payer_name": "zorglub",
"payer_weight": 2.0, "payer_weight": 2.0,
"owers": ["zorglub", "fred", "tata", "pepe"], "owers": ["zorglub", "jeanne", "tata", "pepe"],
}, },
] ]
@ -58,7 +92,7 @@ class CommonTestCase(object):
bills = project.get_pretty_bills() bills = project.get_pretty_bills()
# Check if all bills have been added # Check if all bills have been added
self.assertEqual(len(bills), len(self.data)) assert len(bills) == len(self.data)
# Check if name of bills are ok # Check if name of bills are ok
b = [e["what"] for e in bills] b = [e["what"] for e in bills]
@ -66,23 +100,23 @@ class CommonTestCase(object):
ref = [e["what"] for e in self.data] ref = [e["what"] for e in self.data]
ref.sort() ref.sort()
self.assertEqual(b, ref) assert b == ref
# Check if other informations in bill are ok # Check if other informations in bill are ok
for d in self.data: for d in self.data:
for b in bills: for b in bills:
if b["what"] == d["what"]: if b["what"] == d["what"]:
self.assertEqual(b["payer_name"], d["payer_name"]) assert b["payer_name"] == d["payer_name"]
self.assertEqual(b["amount"], d["amount"]) assert b["amount"] == d["amount"]
self.assertEqual(b["bill_type"], d["bill_type"]) assert b["currency"] == d["currency"]
self.assertEqual(b["currency"], d["currency"]) assert b["payer_weight"] == d["payer_weight"]
self.assertEqual(b["payer_weight"], d["payer_weight"]) assert b["date"] == d["date"]
self.assertEqual(b["date"], d["date"]) assert b["bill_type"] == d["bill_type"]
list_project = [ower for ower in b["owers"]] list_project = [ower for ower in b["owers"]]
list_project.sort() list_project.sort()
list_json = [ower for ower in d["owers"]] list_json = [ower for ower in d["owers"]]
list_json.sort() list_json.sort()
self.assertEqual(list_project, list_json) assert list_project == list_json
def test_import_single_currency_in_empty_project_without_currency(self): def test_import_single_currency_in_empty_project_without_currency(self):
# Import JSON with a single currency in an empty project with no # Import JSON with a single currency in an empty project with no
@ -100,7 +134,7 @@ class CommonTestCase(object):
bills = project.get_pretty_bills() bills = project.get_pretty_bills()
# Check if all bills have been added # Check if all bills have been added
self.assertEqual(len(bills), len(self.data)) assert len(bills) == len(self.data)
# Check if name of bills are ok # Check if name of bills are ok
b = [e["what"] for e in bills] b = [e["what"] for e in bills]
@ -108,24 +142,24 @@ class CommonTestCase(object):
ref = [e["what"] for e in self.data] ref = [e["what"] for e in self.data]
ref.sort() ref.sort()
self.assertEqual(b, ref) assert b == ref
# Check if other informations in bill are ok # Check if other informations in bill are ok
for d in self.data: for d in self.data:
for b in bills: for b in bills:
if b["what"] == d["what"]: if b["what"] == d["what"]:
self.assertEqual(b["payer_name"], d["payer_name"]) assert b["payer_name"] == d["payer_name"]
self.assertEqual(b["amount"], d["amount"]) assert b["amount"] == d["amount"]
# Currency should have been stripped # Currency should have been stripped
self.assertEqual(b["currency"], "XXX") assert b["currency"] == "XXX"
self.assertEqual(b["bill_type"], d["bill_type"]) assert b["payer_weight"] == d["payer_weight"]
self.assertEqual(b["payer_weight"], d["payer_weight"]) assert b["date"] == d["date"]
self.assertEqual(b["date"], d["date"]) assert b["bill_type"] == d["bill_type"]
list_project = [ower for ower in b["owers"]] list_project = [ower for ower in b["owers"]]
list_project.sort() list_project.sort()
list_json = [ower for ower in d["owers"]] list_json = [ower for ower in d["owers"]]
list_json.sort() list_json.sort()
self.assertEqual(list_project, list_json) assert list_project == list_json
def test_import_multiple_currencies_in_empty_project_without_currency(self): def test_import_multiple_currencies_in_empty_project_without_currency(self):
# Import JSON with multiple currencies in an empty project with no # Import JSON with multiple currencies in an empty project with no
@ -143,7 +177,7 @@ class CommonTestCase(object):
bills = project.get_pretty_bills() bills = project.get_pretty_bills()
# Check that there are no bills # Check that there are no bills
self.assertEqual(len(bills), 0) assert len(bills) == 0
def test_import_no_currency_in_empty_project_with_currency(self): def test_import_no_currency_in_empty_project_with_currency(self):
# Import JSON without currencies (from ihatemoney < 5) in an empty # Import JSON without currencies (from ihatemoney < 5) in an empty
@ -159,7 +193,7 @@ class CommonTestCase(object):
bills = project.get_pretty_bills() bills = project.get_pretty_bills()
# Check if all bills have been added # Check if all bills have been added
self.assertEqual(len(bills), len(self.data)) assert len(bills) == len(self.data)
# Check if name of bills are ok # Check if name of bills are ok
b = [e["what"] for e in bills] b = [e["what"] for e in bills]
@ -167,24 +201,24 @@ class CommonTestCase(object):
ref = [e["what"] for e in self.data] ref = [e["what"] for e in self.data]
ref.sort() ref.sort()
self.assertEqual(b, ref) assert b == ref
# Check if other informations in bill are ok # Check if other informations in bill are ok
for d in self.data: for d in self.data:
for b in bills: for b in bills:
if b["what"] == d["what"]: if b["what"] == d["what"]:
self.assertEqual(b["payer_name"], d["payer_name"]) assert b["payer_name"] == d["payer_name"]
self.assertEqual(b["amount"], d["amount"]) assert b["amount"] == d["amount"]
# All bills are converted to default project currency # All bills are converted to default project currency
self.assertEqual(b["currency"], "EUR") assert b["currency"] == "EUR"
self.assertEqual(b["bill_type"], d["bill_type"]) assert b["payer_weight"] == d["payer_weight"]
self.assertEqual(b["payer_weight"], d["payer_weight"]) assert b["date"] == d["date"]
self.assertEqual(b["date"], d["date"]) assert b["bill_type"] == d["bill_type"]
list_project = [ower for ower in b["owers"]] list_project = [ower for ower in b["owers"]]
list_project.sort() list_project.sort()
list_json = [ower for ower in d["owers"]] list_json = [ower for ower in d["owers"]]
list_json.sort() list_json.sort()
self.assertEqual(list_project, list_json) assert list_project == list_json
def test_import_no_currency_in_empty_project_without_currency(self): def test_import_no_currency_in_empty_project_without_currency(self):
# Import JSON without currencies (from ihatemoney < 5) in an empty # Import JSON without currencies (from ihatemoney < 5) in an empty
@ -200,7 +234,7 @@ class CommonTestCase(object):
bills = project.get_pretty_bills() bills = project.get_pretty_bills()
# Check if all bills have been added # Check if all bills have been added
self.assertEqual(len(bills), len(self.data)) assert len(bills) == len(self.data)
# Check if name of bills are ok # Check if name of bills are ok
b = [e["what"] for e in bills] b = [e["what"] for e in bills]
@ -208,23 +242,23 @@ class CommonTestCase(object):
ref = [e["what"] for e in self.data] ref = [e["what"] for e in self.data]
ref.sort() ref.sort()
self.assertEqual(b, ref) assert b == ref
# Check if other informations in bill are ok # Check if other informations in bill are ok
for d in self.data: for d in self.data:
for b in bills: for b in bills:
if b["what"] == d["what"]: if b["what"] == d["what"]:
self.assertEqual(b["payer_name"], d["payer_name"]) assert b["payer_name"] == d["payer_name"]
self.assertEqual(b["amount"], d["amount"]) assert b["amount"] == d["amount"]
self.assertEqual(b["bill_type"], d["bill_type"]) assert b["currency"] == "XXX"
self.assertEqual(b["currency"], "XXX") assert b["payer_weight"] == d["payer_weight"]
self.assertEqual(b["payer_weight"], d["payer_weight"]) assert b["date"] == d["date"]
self.assertEqual(b["date"], d["date"]) assert b["bill_type"] == d["bill_type"]
list_project = [ower for ower in b["owers"]] list_project = [ower for ower in b["owers"]]
list_project.sort() list_project.sort()
list_json = [ower for ower in d["owers"]] list_json = [ower for ower in d["owers"]]
list_json.sort() list_json.sort()
self.assertEqual(list_project, list_json) assert list_project == list_json
def test_import_partial_project(self): def test_import_partial_project(self):
# Import a JSON in a project with already existing data # Import a JSON in a project with already existing data
@ -237,7 +271,7 @@ class CommonTestCase(object):
self.client.post( self.client.post(
"/raclette/members/add", data={"name": "zorglub", "weight": 2} "/raclette/members/add", data={"name": "zorglub", "weight": 2}
) )
self.client.post("/raclette/members/add", data={"name": "fred"}) self.client.post("/raclette/members/add", data={"name": "jeanne"})
self.client.post("/raclette/members/add", data={"name": "tata"}) self.client.post("/raclette/members/add", data={"name": "tata"})
self.client.post( self.client.post(
"/raclette/add", "/raclette/add",
@ -258,7 +292,7 @@ class CommonTestCase(object):
bills = project.get_pretty_bills() bills = project.get_pretty_bills()
# Check if all bills have been added # Check if all bills have been added
self.assertEqual(len(bills), len(self.data)) assert len(bills) == len(self.data)
# Check if name of bills are ok # Check if name of bills are ok
b = [e["what"] for e in bills] b = [e["what"] for e in bills]
@ -266,23 +300,23 @@ class CommonTestCase(object):
ref = [e["what"] for e in self.data] ref = [e["what"] for e in self.data]
ref.sort() ref.sort()
self.assertEqual(b, ref) assert b == ref
# Check if other informations in bill are ok # Check if other informations in bill are ok
for d in self.data: for d in self.data:
for b in bills: for b in bills:
if b["what"] == d["what"]: if b["what"] == d["what"]:
self.assertEqual(b["payer_name"], d["payer_name"]) assert b["payer_name"] == d["payer_name"]
self.assertEqual(b["amount"], d["amount"]) assert b["amount"] == d["amount"]
self.assertEqual(b["bill_type"], d["bill_type"]) assert b["currency"] == d["currency"]
self.assertEqual(b["currency"], d["currency"]) assert b["payer_weight"] == d["payer_weight"]
self.assertEqual(b["payer_weight"], d["payer_weight"]) assert b["date"] == d["date"]
self.assertEqual(b["date"], d["date"]) assert b["bill_type"] == d["bill_type"]
list_project = [ower for ower in b["owers"]] list_project = [ower for ower in b["owers"]]
list_project.sort() list_project.sort()
list_json = [ower for ower in d["owers"]] list_json = [ower for ower in d["owers"]]
list_json.sort() list_json.sort()
self.assertEqual(list_project, list_json) assert list_project == list_json
def test_import_wrong_data(self): def test_import_wrong_data(self):
self.post_project("raclette") self.post_project("raclette")
@ -304,7 +338,7 @@ class CommonTestCase(object):
"bill_type": "Reimbursement", "bill_type": "Reimbursement",
"payer_name": "tata", "payer_name": "tata",
"payer_weight": 1.0, "payer_weight": 1.0,
"owers": ["fred"], "owers": ["jeanne"],
} }
] ]
for data in [data_wrong_keys, data_amount_missing]: for data in [data_wrong_keys, data_amount_missing]:
@ -312,7 +346,7 @@ class CommonTestCase(object):
self.import_project("raclette", self.generate_form_data(data), 400) self.import_project("raclette", self.generate_form_data(data), 400)
class ExportTestCase(IhatemoneyTestCase): class TestExport(IhatemoneyTestCase):
def test_export(self): def test_export(self):
# Export a simple project without currencies # Export a simple project without currencies
@ -320,7 +354,7 @@ class ExportTestCase(IhatemoneyTestCase):
# add participants # add participants
self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2}) self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2})
self.client.post("/raclette/members/add", data={"name": "fred"}) self.client.post("/raclette/members/add", data={"name": "jeanne"})
self.client.post("/raclette/members/add", data={"name": "tata"}) self.client.post("/raclette/members/add", data={"name": "tata"})
self.client.post("/raclette/members/add", data={"name": "pépé"}) self.client.post("/raclette/members/add", data={"name": "pépé"})
@ -372,7 +406,7 @@ class ExportTestCase(IhatemoneyTestCase):
"currency": "XXX", "currency": "XXX",
"payer_name": "tata", "payer_name": "tata",
"payer_weight": 1.0, "payer_weight": 1.0,
"owers": ["fred"], "owers": ["jeanne"],
}, },
{ {
"date": "2016-12-31", "date": "2016-12-31",
@ -380,7 +414,7 @@ class ExportTestCase(IhatemoneyTestCase):
"what": "red wine", "what": "red wine",
"amount": 200.0, "amount": 200.0,
"currency": "XXX", "currency": "XXX",
"payer_name": "fred", "payer_name": "jeanne",
"payer_weight": 1.0, "payer_weight": 1.0,
"owers": ["zorglub", "tata"], "owers": ["zorglub", "tata"],
}, },
@ -392,25 +426,23 @@ class ExportTestCase(IhatemoneyTestCase):
"currency": "XXX", "currency": "XXX",
"payer_name": "zorglub", "payer_name": "zorglub",
"payer_weight": 2.0, "payer_weight": 2.0,
"owers": ["zorglub", "fred", "tata", "p\xe9p\xe9"], "owers": ["zorglub", "jeanne", "tata", "p\xe9p\xe9"],
}, },
] ]
self.assertEqual(json.loads(resp.data.decode("utf-8")), expected) assert json.loads(resp.data.decode("utf-8")) == expected
# generate csv export of bills # generate csv export of bills
resp = self.client.get("/raclette/export/bills.csv") resp = self.client.get("/raclette/export/bills.csv")
expected = [ expected = [
"date,what,bill_type,amount,currency,payer_name,payer_weight,owers", "date,what,bill_type,amount,currency,payer_name,payer_weight,owers",
"2017-01-01,refund,Reimbursement,XXX,13.33,tata,1.0,fred", "2017-01-01,refund,Reimbursement,XXX,13.33,tata,1.0,jeanne",
'2016-12-31,red wine,Expense,XXX,200.0,fred,1.0,"zorglub, tata"', '2016-12-31,red wine,Expense,XXX,200.0,jeanne,1.0,"zorglub, tata"',
'2016-12-31,à raclette,Expense,10.0,XXX,zorglub,2.0,"zorglub, fred, tata, pépé"', '2016-12-31,à raclette,Expense,10.0,XXX,zorglub,2.0,"zorglub, jeanne, tata, pépé"',
] ]
received_lines = resp.data.decode("utf-8").split("\n") received_lines = resp.data.decode("utf-8").split("\n")
for i, line in enumerate(expected): for i, line in enumerate(expected):
self.assertEqual( assert set(line.split(",")) == set(received_lines[i].strip("\r").split(","))
set(line.split(",")), set(received_lines[i].strip("\r").split(","))
)
# generate json export of transactions # generate json export of transactions
resp = self.client.get("/raclette/export/transactions.json") resp = self.client.get("/raclette/export/transactions.json")
@ -418,46 +450,45 @@ class ExportTestCase(IhatemoneyTestCase):
{ {
"amount": 2.00, "amount": 2.00,
"currency": "XXX", "currency": "XXX",
"receiver": "fred", "receiver": "jeanne",
"ower": "p\xe9p\xe9", "ower": "p\xe9p\xe9",
}, },
{"amount": 55.34, "currency": "XXX", "receiver": "fred", "ower": "tata"}, {"amount": 55.34, "currency": "XXX", "receiver": "jeanne", "ower": "tata"},
{ {
"amount": 127.33, "amount": 127.33,
"currency": "XXX", "currency": "XXX",
"receiver": "fred", "receiver": "jeanne",
"ower": "zorglub", "ower": "zorglub",
}, },
] ]
self.assertEqual(json.loads(resp.data.decode("utf-8")), expected) assert json.loads(resp.data.decode("utf-8")) == expected
# generate csv export of transactions # generate csv export of transactions
resp = self.client.get("/raclette/export/transactions.csv") resp = self.client.get("/raclette/export/transactions.csv")
expected = [ expected = [
"amount,currency,receiver,ower", "amount,currency,receiver,ower",
"2.0,XXX,fred,pépé", "2.0,XXX,jeanne,pépé",
"55.34,XXX,fred,tata", "55.34,XXX,jeanne,tata",
"127.33,XXX,fred,zorglub", "127.33,XXX,jeanne,zorglub",
] ]
received_lines = resp.data.decode("utf-8").split("\n") received_lines = resp.data.decode("utf-8").split("\n")
for i, line in enumerate(expected): for i, line in enumerate(expected):
self.assertEqual( assert set(line.split(",")) == set(received_lines[i].strip("\r").split(","))
set(line.split(",")), set(received_lines[i].strip("\r").split(","))
)
# wrong export_format should return a 404 # wrong export_format should return a 404
resp = self.client.get("/raclette/export/transactions.wrong") resp = self.client.get("/raclette/export/transactions.wrong")
self.assertEqual(resp.status_code, 404) assert resp.status_code == 404
@pytest.mark.skip(reason="Currency conversion is broken")
def test_export_with_currencies(self): def test_export_with_currencies(self):
self.post_project("raclette", default_currency="EUR") self.post_project("raclette", default_currency="EUR")
# add participants # add participants
self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2}) self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2})
self.client.post("/raclette/members/add", data={"name": "fred"}) self.client.post("/raclette/members/add", data={"name": "jeanne"})
self.client.post("/raclette/members/add", data={"name": "tata"}) self.client.post("/raclette/members/add", data={"name": "tata"})
self.client.post("/raclette/members/add", data={"name": "pépé"}) self.client.post("/raclette/members/add", data={"name": "pépé"})
@ -512,7 +543,7 @@ class ExportTestCase(IhatemoneyTestCase):
"currency": "EUR", "currency": "EUR",
"payer_name": "tata", "payer_name": "tata",
"payer_weight": 1.0, "payer_weight": 1.0,
"owers": ["fred"], "owers": ["jeanne"],
}, },
{ {
"date": "2016-12-31", "date": "2016-12-31",
@ -520,7 +551,7 @@ class ExportTestCase(IhatemoneyTestCase):
"bill_type": "Expense", "bill_type": "Expense",
"amount": 100.0, "amount": 100.0,
"currency": "CAD", "currency": "CAD",
"payer_name": "fred", "payer_name": "jeanne",
"payer_weight": 1.0, "payer_weight": 1.0,
"owers": ["zorglub", "tata"], "owers": ["zorglub", "tata"],
}, },
@ -532,25 +563,23 @@ class ExportTestCase(IhatemoneyTestCase):
"currency": "EUR", "currency": "EUR",
"payer_name": "zorglub", "payer_name": "zorglub",
"payer_weight": 2.0, "payer_weight": 2.0,
"owers": ["zorglub", "fred", "tata", "p\xe9p\xe9"], "owers": ["zorglub", "jeanne", "tata", "p\xe9p\xe9"],
}, },
] ]
self.assertEqual(json.loads(resp.data.decode("utf-8")), expected) assert json.loads(resp.data.decode("utf-8")) == expected
# generate csv export of bills # generate csv export of bills
resp = self.client.get("/raclette/export/bills.csv") resp = self.client.get("/raclette/export/bills.csv")
expected = [ expected = [
"date,what,bill_type,amount,currency,payer_name,payer_weight,owers", "date,what,bill_type,amount,currency,payer_name,payer_weight,owers",
"2017-01-01,refund,Reimbursement,13.33,EUR,tata,1.0,fred", "2017-01-01,refund,Reimbursement,13.33,EUR,tata,1.0,jeanne",
'2016-12-31,poutine from Québec,Expense,100.0,CAD,fred,1.0,"zorglub, tata"', '2016-12-31,poutine from Québec,Expense,100.0,CAD,jeanne,1.0,"zorglub, tata"',
'2016-12-31,à raclette,Expense,10.0,EUR,zorglub,2.0,"zorglub, fred, tata, pépé"', '2016-12-31,à raclette,Expense,10.0,EUR,zorglub,2.0,"zorglub, jeanne, tata, pépé"',
] ]
received_lines = resp.data.decode("utf-8").split("\n") received_lines = resp.data.decode("utf-8").split("\n")
for i, line in enumerate(expected): for i, line in enumerate(expected):
self.assertEqual( assert set(line.split(",")) == set(received_lines[i].strip("\r").split(","))
set(line.split(",")), set(received_lines[i].strip("\r").split(","))
)
# generate json export of transactions (in EUR!) # generate json export of transactions (in EUR!)
resp = self.client.get("/raclette/export/transactions.json") resp = self.client.get("/raclette/export/transactions.json")
@ -558,30 +587,33 @@ class ExportTestCase(IhatemoneyTestCase):
{ {
"amount": 2.00, "amount": 2.00,
"currency": "EUR", "currency": "EUR",
"receiver": "fred", "receiver": "jeanne",
"ower": "p\xe9p\xe9", "ower": "p\xe9p\xe9",
}, },
{"amount": 10.89, "currency": "EUR", "receiver": "fred", "ower": "tata"}, {"amount": 10.89, "currency": "EUR", "receiver": "jeanne", "ower": "tata"},
{"amount": 38.45, "currency": "EUR", "receiver": "fred", "ower": "zorglub"}, {
"amount": 38.45,
"currency": "EUR",
"receiver": "jeanne",
"ower": "zorglub",
},
] ]
self.assertEqual(json.loads(resp.data.decode("utf-8")), expected) assert json.loads(resp.data.decode("utf-8")) == expected
# generate csv export of transactions # generate csv export of transactions
resp = self.client.get("/raclette/export/transactions.csv") resp = self.client.get("/raclette/export/transactions.csv")
expected = [ expected = [
"amount,currency,receiver,ower", "amount,currency,receiver,ower",
"2.0,EUR,fred,pépé", "2.0,EUR,jeanne,pépé",
"10.89,EUR,fred,tata", "10.89,EUR,jeanne,tata",
"38.45,EUR,fred,zorglub", "38.45,EUR,jeanne,zorglub",
] ]
received_lines = resp.data.decode("utf-8").split("\n") received_lines = resp.data.decode("utf-8").split("\n")
for i, line in enumerate(expected): for i, line in enumerate(expected):
self.assertEqual( assert set(line.split(",")) == set(received_lines[i].strip("\r").split(","))
set(line.split(",")), set(received_lines[i].strip("\r").split(","))
)
# Change project currency to CAD # Change project currency to CAD
project = self.get_project("raclette") project = self.get_project("raclette")
@ -593,30 +625,33 @@ class ExportTestCase(IhatemoneyTestCase):
{ {
"amount": 3.00, "amount": 3.00,
"currency": "CAD", "currency": "CAD",
"receiver": "fred", "receiver": "jeanne",
"ower": "p\xe9p\xe9", "ower": "p\xe9p\xe9",
}, },
{"amount": 16.34, "currency": "CAD", "receiver": "fred", "ower": "tata"}, {"amount": 16.34, "currency": "CAD", "receiver": "jeanne", "ower": "tata"},
{"amount": 57.67, "currency": "CAD", "receiver": "fred", "ower": "zorglub"}, {
"amount": 57.67,
"currency": "CAD",
"receiver": "jeanne",
"ower": "zorglub",
},
] ]
self.assertEqual(json.loads(resp.data.decode("utf-8")), expected) assert json.loads(resp.data.decode("utf-8")) == expected
# generate csv export of transactions # generate csv export of transactions
resp = self.client.get("/raclette/export/transactions.csv") resp = self.client.get("/raclette/export/transactions.csv")
expected = [ expected = [
"amount,currency,receiver,ower", "amount,currency,receiver,ower",
"3.0,CAD,fred,pépé", "3.0,CAD,jeanne,pépé",
"16.34,CAD,fred,tata", "16.34,CAD,jeanne,tata",
"57.67,CAD,fred,zorglub", "57.67,CAD,jeanne,zorglub",
] ]
received_lines = resp.data.decode("utf-8").split("\n") received_lines = resp.data.decode("utf-8").split("\n")
for i, line in enumerate(expected): for i, line in enumerate(expected):
self.assertEqual( assert set(line.split(",")) == set(received_lines[i].strip("\r").split(","))
set(line.split(",")), set(received_lines[i].strip("\r").split(","))
)
def test_export_escape_formulae(self): def test_export_escape_formulae(self):
self.post_project("raclette", default_currency="EUR") self.post_project("raclette", default_currency="EUR")
@ -647,23 +682,17 @@ class ExportTestCase(IhatemoneyTestCase):
received_lines = resp.data.decode("utf-8").split("\n") received_lines = resp.data.decode("utf-8").split("\n")
for i, line in enumerate(expected): for i, line in enumerate(expected):
self.assertEqual( assert set(line.split(",")) == set(received_lines[i].strip("\r").split(","))
set(line.split(",")), set(received_lines[i].strip("\r").split(","))
)
class ImportTestCaseJSON(CommonTestCase.Import): class TestImportJSON(CommonTestCase.Import):
def generate_form_data(self, data): def generate_form_data(self, data):
return {"file": (list_of_dicts2json(data), "test.json")} return {"file": (list_of_dicts2json(data), "test.json")}
class ImportTestCaseCSV(CommonTestCase.Import): class TestImportCSV(CommonTestCase.Import):
def generate_form_data(self, data): def generate_form_data(self, data):
formatted_data = copy.deepcopy(data) formatted_data = copy.deepcopy(data)
for d in formatted_data: for d in formatted_data:
d["owers"] = ", ".join([o for o in d.get("owers", [])]) d["owers"] = ", ".join([o for o in d.get("owers", [])])
return {"file": (list_of_dicts2csv(formatted_data), "test.csv")} return {"file": (list_of_dicts2csv(formatted_data), "test.csv")}
if __name__ == "__main__":
unittest.main()

View file

@ -1,9 +1,9 @@
import os import os
import smtplib import smtplib
import socket import socket
import unittest
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
import pytest
from sqlalchemy import orm from sqlalchemy import orm
from werkzeug.security import check_password_hash from werkzeug.security import check_password_hash
@ -19,19 +19,18 @@ os.environ.pop("IHATEMONEY_SETTINGS_FILE_PATH", None)
__HERE__ = os.path.dirname(os.path.abspath(__file__)) __HERE__ = os.path.dirname(os.path.abspath(__file__))
class ConfigurationTestCase(BaseTestCase): class TestConfiguration(BaseTestCase):
def test_default_configuration(self): def test_default_configuration(self):
"""Test that default settings are loaded when no other configuration file is specified""" """Test that default settings are loaded when no other configuration file is specified"""
self.assertFalse(self.app.config["DEBUG"]) assert not self.app.config["DEBUG"]
self.assertFalse(self.app.config["SQLALCHEMY_TRACK_MODIFICATIONS"]) assert not self.app.config["SQLALCHEMY_TRACK_MODIFICATIONS"]
self.assertEqual( assert self.app.config["MAIL_DEFAULT_SENDER"] == (
self.app.config["MAIL_DEFAULT_SENDER"], "Budget manager <admin@example.com>"
("Budget manager <admin@example.com>"),
) )
self.assertTrue(self.app.config["ACTIVATE_DEMO_PROJECT"]) assert self.app.config["ACTIVATE_DEMO_PROJECT"]
self.assertTrue(self.app.config["ALLOW_PUBLIC_PROJECT_CREATION"]) assert self.app.config["ALLOW_PUBLIC_PROJECT_CREATION"]
self.assertFalse(self.app.config["ACTIVATE_ADMIN_DASHBOARD"]) assert not self.app.config["ACTIVATE_ADMIN_DASHBOARD"]
self.assertFalse(self.app.config["ENABLE_CAPTCHA"]) assert not self.app.config["ENABLE_CAPTCHA"]
def test_env_var_configuration_file(self): def test_env_var_configuration_file(self):
"""Test that settings are loaded from a configuration file specified """Test that settings are loaded from a configuration file specified
@ -40,7 +39,7 @@ class ConfigurationTestCase(BaseTestCase):
__HERE__, "ihatemoney_envvar.cfg" __HERE__, "ihatemoney_envvar.cfg"
) )
load_configuration(self.app) load_configuration(self.app)
self.assertEqual(self.app.config["SECRET_KEY"], "lalatra") assert self.app.config["SECRET_KEY"] == "lalatra"
# Test that the specified configuration file is loaded # Test that the specified configuration file is loaded
# even if the default configuration file ihatemoney.cfg exists # even if the default configuration file ihatemoney.cfg exists
@ -50,7 +49,7 @@ class ConfigurationTestCase(BaseTestCase):
) )
self.app.config.root_path = __HERE__ self.app.config.root_path = __HERE__
load_configuration(self.app) load_configuration(self.app)
self.assertEqual(self.app.config["SECRET_KEY"], "lalatra") assert self.app.config["SECRET_KEY"] == "lalatra"
os.environ.pop("IHATEMONEY_SETTINGS_FILE_PATH", None) os.environ.pop("IHATEMONEY_SETTINGS_FILE_PATH", None)
@ -59,10 +58,10 @@ class ConfigurationTestCase(BaseTestCase):
in the current directory.""" in the current directory."""
self.app.config.root_path = __HERE__ self.app.config.root_path = __HERE__
load_configuration(self.app) load_configuration(self.app)
self.assertEqual(self.app.config["SECRET_KEY"], "supersecret") assert self.app.config["SECRET_KEY"] == "supersecret"
class ServerTestCase(IhatemoneyTestCase): class TestServer(IhatemoneyTestCase):
def test_homepage(self): def test_homepage(self):
# See https://github.com/spiral-project/ihatemoney/pull/358 # See https://github.com/spiral-project/ihatemoney/pull/358
self.app.config["APPLICATION_ROOT"] = "/" self.app.config["APPLICATION_ROOT"] = "/"
@ -80,7 +79,7 @@ class ServerTestCase(IhatemoneyTestCase):
self.assertStatus(200, req) self.assertStatus(200, req)
class CommandTestCase(BaseTestCase): class TestCommand(BaseTestCase):
def test_generate_config(self): def test_generate_config(self):
"""Simply checks that all config file generation """Simply checks that all config file generation
- raise no exception - raise no exception
@ -89,32 +88,32 @@ class CommandTestCase(BaseTestCase):
runner = self.app.test_cli_runner() runner = self.app.test_cli_runner()
for config_file in generate_config.params[0].type.choices: for config_file in generate_config.params[0].type.choices:
result = runner.invoke(generate_config, config_file) result = runner.invoke(generate_config, config_file)
self.assertNotEqual(len(result.output.strip()), 0) assert len(result.output.strip()) != 0
def test_generate_password_hash(self): def test_generate_password_hash(self):
runner = self.app.test_cli_runner() runner = self.app.test_cli_runner()
with patch("getpass.getpass", new=lambda prompt: "secret"): with patch("getpass.getpass", new=lambda prompt: "secret"):
result = runner.invoke(password_hash) result = runner.invoke(password_hash)
self.assertTrue(check_password_hash(result.output.strip(), "secret")) assert check_password_hash(result.output.strip(), "secret")
def test_demo_project_deletion(self): def test_demo_project_deletion(self):
self.create_project("demo") self.create_project("demo")
self.assertEqual(self.get_project("demo").name, "demo") assert self.get_project("demo").name == "demo"
runner = self.app.test_cli_runner() runner = self.app.test_cli_runner()
runner.invoke(delete_project, "demo") runner.invoke(delete_project, "demo")
self.assertEqual(len(models.Project.query.all()), 0) assert len(models.Project.query.all()) == 0
class ModelsTestCase(IhatemoneyTestCase): class TestModels(IhatemoneyTestCase):
def test_weighted_bills(self): def test_weighted_bills(self):
"""Test the SQL request that fetch all bills and weights""" """Test the SQL request that fetch all bills and weights"""
self.post_project("raclette") self.post_project("raclette")
# add members # add members
self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2}) self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2})
self.client.post("/raclette/members/add", data={"name": "fred"}) self.client.post("/raclette/members/add", data={"name": "jeanne"})
self.client.post("/raclette/members/add", data={"name": "tata"}) self.client.post("/raclette/members/add", data={"name": "tata"})
# Add a member with a balance=0 : # Add a member with a balance=0 :
self.client.post("/raclette/members/add", data={"name": "pépé"}) self.client.post("/raclette/members/add", data={"name": "pépé"})
@ -156,24 +155,23 @@ class ModelsTestCase(IhatemoneyTestCase):
}, },
) )
project = models.Project.query.get_by_name(name="raclette") project = models.Project.query.get_by_name(name="raclette")
for (weight, bill) in project.get_bill_weights().all(): for weight, bill in project.get_bill_weights().all():
if bill.what == "red wine": if bill.what == "red wine":
pay_each_expected = 20 / 2 pay_each_expected = 20 / 2
self.assertEqual(bill.amount / weight, pay_each_expected) assert bill.amount / weight == pay_each_expected
if bill.what == "fromage à raclette": if bill.what == "fromage à raclette":
pay_each_expected = 10 / 4 pay_each_expected = 10 / 4
self.assertEqual(bill.amount / weight, pay_each_expected) assert bill.amount / weight == pay_each_expected
if bill.what == "delicatessen": if bill.what == "delicatessen":
pay_each_expected = 10 / 3 pay_each_expected = 10 / 3
self.assertEqual(bill.amount / weight, pay_each_expected) assert bill.amount / weight == pay_each_expected
def test_bill_pay_each(self): def test_bill_pay_each(self):
self.post_project("raclette") self.post_project("raclette")
# add members # add members
self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2}) self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2})
self.client.post("/raclette/members/add", data={"name": "fred"}) self.client.post("/raclette/members/add", data={"name": "jeanne"})
self.client.post("/raclette/members/add", data={"name": "tata"}) self.client.post("/raclette/members/add", data={"name": "tata"})
# Add a member with a balance=0 : # Add a member with a balance=0 :
self.client.post("/raclette/members/add", data={"name": "pépé"}) self.client.post("/raclette/members/add", data={"name": "pépé"})
@ -223,16 +221,16 @@ class ModelsTestCase(IhatemoneyTestCase):
for bill in zorglub_bills.all(): for bill in zorglub_bills.all():
if bill.what == "red wine": if bill.what == "red wine":
pay_each_expected = 20 / 2 pay_each_expected = 20 / 2
self.assertEqual(bill.pay_each(), pay_each_expected) assert bill.pay_each() == pay_each_expected
if bill.what == "fromage à raclette": if bill.what == "fromage à raclette":
pay_each_expected = 10 / 4 pay_each_expected = 10 / 4
self.assertEqual(bill.pay_each(), pay_each_expected) assert bill.pay_each() == pay_each_expected
if bill.what == "delicatessen": if bill.what == "delicatessen":
pay_each_expected = 10 / 3 pay_each_expected = 10 / 3
self.assertEqual(bill.pay_each(), pay_each_expected) assert bill.pay_each() == pay_each_expected
class EmailFailureTestCase(IhatemoneyTestCase): class TestEmailFailure(IhatemoneyTestCase):
def test_creation_email_failure_smtp(self): def test_creation_email_failure_smtp(self):
self.login("raclette") self.login("raclette")
with patch.object( with patch.object(
@ -240,14 +238,14 @@ class EmailFailureTestCase(IhatemoneyTestCase):
): ):
resp = self.post_project("raclette") resp = self.post_project("raclette")
# Check that an error message is displayed # Check that an error message is displayed
self.assertIn( assert (
"We tried to send you an reminder email, but there was an error", "We tried to send you an reminder email, but there was an error"
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
# Check that we were redirected to the home page anyway # Check that we were redirected to the home page anyway
self.assertIn( assert (
'You probably want to <a href="/raclette/members/add"', '<a href="/raclette/members/add">Add the first participant'
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
def test_creation_email_failure_socket(self): def test_creation_email_failure_socket(self):
@ -255,14 +253,14 @@ class EmailFailureTestCase(IhatemoneyTestCase):
with patch.object(self.app.mail, "send", MagicMock(side_effect=socket.error)): with patch.object(self.app.mail, "send", MagicMock(side_effect=socket.error)):
resp = self.post_project("raclette") resp = self.post_project("raclette")
# Check that an error message is displayed # Check that an error message is displayed
self.assertIn( assert (
"We tried to send you an reminder email, but there was an error", "We tried to send you an reminder email, but there was an error"
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
# Check that we were redirected to the home page anyway # Check that we were redirected to the home page anyway
self.assertIn( assert (
'You probably want to <a href="/raclette/members/add"', '<a href="/raclette/members/add">Add the first participant'
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
def test_password_reset_email_failure(self): def test_password_reset_email_failure(self):
@ -273,14 +271,13 @@ class EmailFailureTestCase(IhatemoneyTestCase):
"/password-reminder", data={"id": "raclette"}, follow_redirects=True "/password-reminder", data={"id": "raclette"}, follow_redirects=True
) )
# Check that an error message is displayed # Check that an error message is displayed
self.assertIn( assert "there was an error while sending you an email" in resp.data.decode(
"there was an error while sending you an email", "utf-8"
resp.data.decode("utf-8"),
) )
# Check that we were not redirected to the success page # Check that we were not redirected to the success page
self.assertNotIn( assert (
"A link to reset your password has been sent to you", "A link to reset your password has been sent to you"
resp.data.decode("utf-8"), not in resp.data.decode("utf-8")
) )
def test_invitation_email_failure(self): def test_invitation_email_failure(self):
@ -294,17 +291,15 @@ class EmailFailureTestCase(IhatemoneyTestCase):
follow_redirects=True, follow_redirects=True,
) )
# Check that an error message is displayed # Check that an error message is displayed
self.assertIn( assert (
"there was an error while trying to send the invitation emails", "there was an error while trying to send the invitation emails"
resp.data.decode("utf-8"), in resp.data.decode("utf-8")
) )
# Check that we are still on the same page (no redirection) # Check that we are still on the same page (no redirection)
self.assertIn( assert "Invite people to join this project" in resp.data.decode("utf-8")
"Invite people to join this project", resp.data.decode("utf-8")
)
class CaptchaTestCase(IhatemoneyTestCase): class TestCaptcha(IhatemoneyTestCase):
ENABLE_CAPTCHA = True ENABLE_CAPTCHA = True
def test_project_creation_with_captcha_case_insensitive(self): def test_project_creation_with_captcha_case_insensitive(self):
@ -375,11 +370,11 @@ class CaptchaTestCase(IhatemoneyTestCase):
"contact_email": "raclette@notmyidea.org", "contact_email": "raclette@notmyidea.org",
}, },
) )
self.assertTrue(resp.status, 201) assert resp.status_code == 201
assert len(models.Project.query.all()) == 1 assert len(models.Project.query.all()) == 1
class TestCurrencyConverter(unittest.TestCase): class TestCurrencyConverter:
converter = CurrencyConverter() converter = CurrencyConverter()
mock_data = { mock_data = {
"USD": 1, "USD": 1,
@ -393,28 +388,23 @@ class TestCurrencyConverter(unittest.TestCase):
def test_only_one_instance(self): def test_only_one_instance(self):
one = id(CurrencyConverter()) one = id(CurrencyConverter())
two = id(CurrencyConverter()) two = id(CurrencyConverter())
self.assertEqual(one, two) assert one == two
def test_get_currencies(self): def test_get_currencies(self):
self.assertCountEqual( currencies = self.converter.get_currencies()
self.converter.get_currencies(), for currency in ["USD", "EUR", "CAD", "PLN", CurrencyConverter.no_currency]:
["USD", "EUR", "CAD", "PLN", CurrencyConverter.no_currency], assert currency in currencies
)
def test_exchange_currency(self): def test_exchange_currency(self):
result = self.converter.exchange_currency(100, "USD", "EUR") result = self.converter.exchange_currency(100, "USD", "EUR")
self.assertEqual(result, 80.0) assert result == 80.0
def test_failing_remote(self): def test_failing_remote(self):
rates = {} rates = {}
with patch("requests.Response.json", new=lambda _: {}), self.assertWarns( with patch("requests.Response.json", new=lambda _: {}), pytest.warns(
UserWarning UserWarning
): ):
# we need a non-patched converter, but it seems that MagickMock # we need a non-patched converter, but it seems that MagickMock
# is mocking EVERY instance of the class method. Too bad. # is mocking EVERY instance of the class method. Too bad.
rates = CurrencyConverter.get_rates(self.converter) rates = CurrencyConverter.get_rates(self.converter)
self.assertDictEqual(rates, {CurrencyConverter.no_currency: 1}) assert rates == {CurrencyConverter.no_currency: 1}
if __name__ == "__main__":
unittest.main()

View file

@ -1,18 +1,23 @@
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: 2022-04-13 21:42+0200\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2022-04-14 21:10+0000\n" "PO-Revision-Date: 2022-04-14 21:10+0000\n"
"Last-Translator: Hasidul Islam <ihasidul@gmail.com>\n" "Last-Translator: Hasidul Islam <ihasidul@gmail.com>\n"
"Language-Team: Bengali <https://hosted.weblate.org/projects/i-hate-money/"
"i-hate-money/bn/>\n"
"Language: bn\n" "Language: bn\n"
"Language-Team: Bengali <https://hosted.weblate.org/projects/i-hate-"
"money/i-hate-money/bn/>\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.9.0\n"
"X-Generator: Weblate 4.12-dev\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
msgid "" msgid ""
"Not a valid amount or expression. Only numbers and + - * / operators are " "Not a valid amount or expression. Only numbers and + - * / operators are "
@ -22,6 +27,13 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "প্রজেক্টের নাম" msgstr "প্রজেক্টের নাম"
#, fuzzy
msgid "Current private code"
msgstr "নতুন ব্যক্তিগত কোড"
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "নতুন ব্যক্তিগত কোড" msgstr "নতুন ব্যক্তিগত কোড"
@ -43,6 +55,12 @@ msgstr "ডিফল্ট মুদ্রা"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
msgid "Unknown error"
msgstr "অজানা ত্রুটি"
msgid "Invalid private code."
msgstr "অবৈধ ব্যক্তিগত কোড."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
@ -50,10 +68,7 @@ msgstr ""
"এই প্রজেক্টটি 'নো কারেন্সি' সেট করা যাবে না কারণ এতে একাধিক মুদ্রার বিল " "এই প্রজেক্টটি 'নো কারেন্সি' সেট করা যাবে না কারণ এতে একাধিক মুদ্রার বিল "
"রয়েছে৷" "রয়েছে৷"
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr ""
msgid "Import"
msgstr "" msgstr ""
msgid "Project identifier" msgid "Project identifier"
@ -70,8 +85,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 ""
"এই শনাক্তকারী(\"%(project)s\")সহ একটি প্রজেক্ট ইতিমধ্যেই বিদ্যমান৷ একটি নতুন " "এই শনাক্তকারী(\"%(project)s\")সহ একটি প্রজেক্ট ইতিমধ্যেই বিদ্যমান৷ একটি "
"শনাক্তকারী ঠিক করুন" "নতুন শনাক্তকারী ঠিক করুন"
msgid "Which is a real currency: Euro or Petro dollar?" msgid "Which is a real currency: Euro or Petro dollar?"
msgstr "কোনটি আসল মুদ্রা: ইউরো না পেট্রো ডলার?" msgstr "কোনটি আসল মুদ্রা: ইউরো না পেট্রো ডলার?"
@ -85,12 +100,6 @@ msgstr "অনুগ্রহ করে, এগিয়ে যেতে ক্
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "মুছে ফেলা নিশ্চিত করতে ব্যক্তিগত কোড লিখুন" msgstr "মুছে ফেলা নিশ্চিত করতে ব্যক্তিগত কোড লিখুন"
msgid "Unknown error"
msgstr "অজানা ত্রুটি"
msgid "Invalid private code."
msgstr "অবৈধ ব্যক্তিগত কোড."
msgid "Get in" msgid "Get in"
msgstr "প্রবেশ করুন" msgstr "প্রবেশ করুন"
@ -115,16 +124,16 @@ msgstr "পাসওয়ার্ড নিশ্চিতকরণ"
msgid "Reset password" msgid "Reset password"
msgstr "পাসওয়ার্ড রিসেট করুন" msgstr "পাসওয়ার্ড রিসেট করুন"
msgid "Date" msgid "When?"
msgstr "তারিখ" msgstr ""
msgid "What?" msgid "What?"
msgstr "কি?" msgstr "কি?"
msgid "Payer" msgid "Who paid?"
msgstr "প্রদানকারী" msgstr ""
msgid "Amount paid" msgid "How much?"
msgstr "" msgstr ""
msgid "Currency" msgid "Currency"
@ -149,9 +158,6 @@ msgstr ""
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "" msgstr ""
msgid "Bills can't be null"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -173,13 +179,25 @@ msgstr ""
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "" msgstr ""
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "" msgstr ""
msgid "Logout"
msgstr ""
msgid "Please check the email configuration of the server."
msgstr ""
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "" msgstr ""
@ -207,7 +225,7 @@ msgstr ""
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "" msgstr ""
#, python-format #, python-format
@ -220,10 +238,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "" msgstr ""
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "" msgstr ""
@ -232,14 +246,9 @@ msgid ""
"still use the project normally." "still use the project normally."
msgstr "" msgstr ""
#, python-format
msgid "The project identifier is %(project)s"
msgstr ""
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
msgid "No token provided" msgid "No token provided"
@ -254,10 +263,14 @@ msgstr ""
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "" msgstr ""
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "" msgstr ""
msgid "" msgid ""
@ -265,12 +278,18 @@ msgid ""
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr ""
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "" msgstr ""
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr ""
@ -278,10 +297,7 @@ msgstr ""
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "" msgstr ""
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
#, python-format #, python-format
@ -324,6 +340,10 @@ msgstr ""
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "" msgstr ""
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "" msgstr ""
@ -384,7 +404,7 @@ msgstr ""
msgid "edit" msgid "edit"
msgstr "" msgstr ""
msgid "delete" msgid "Delete project"
msgstr "" msgstr ""
msgid "show" msgid "show"
@ -399,20 +419,12 @@ msgstr ""
msgid "Get it on" msgid "Get it on"
msgstr "" msgstr ""
msgid "Are you sure?"
msgstr ""
msgid "Edit project" msgid "Edit project"
msgstr "" msgstr ""
msgid "Delete project" #, fuzzy
msgstr "" msgid "Import project"
msgstr "প্রজেক্ট তৈরি করুন"
msgid "Import JSON"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Download project's data" msgid "Download project's data"
msgstr "" msgstr ""
@ -438,18 +450,27 @@ msgstr ""
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "" msgstr ""
msgid "Edit the project" msgid "Save changes"
msgstr "" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
msgid "Import previously exported project"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Edit this bill" msgid "Edit this bill"
msgstr "" msgstr ""
msgid "Add a bill" msgid "Add a bill"
msgstr "" msgstr ""
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr ""
@ -468,9 +489,6 @@ msgstr ""
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "" msgstr ""
msgid "Send the invitations"
msgstr ""
msgid "Download" msgid "Download"
msgstr "" msgstr ""
@ -535,23 +553,18 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"disabling project history. You can\n" msgstr ""
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
"data-target=\"#confirm-erase\">clear project history</a> to remove " msgid "You can clear the project history to remove them."
"them.</i></p>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
@ -562,18 +575,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "" msgstr ""
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "Time" msgid "Time"
msgstr "" msgstr ""
@ -635,9 +648,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "প্রদানকারী"
msgid "Amount" msgid "Amount"
msgstr "" msgstr ""
msgid "Date"
msgstr "তারিখ"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "" msgstr ""
@ -738,6 +757,9 @@ msgstr ""
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "" msgstr ""
@ -747,7 +769,8 @@ msgstr ""
msgid "Dashboard" msgid "Dashboard"
msgstr "" msgstr ""
msgid "Logout" #, python-format
msgid "Please retry after %(date)s."
msgstr "" msgstr ""
msgid "Code" msgid "Code"
@ -781,30 +804,21 @@ msgstr ""
msgid "Invite people" msgid "Invite people"
msgstr "" msgstr ""
msgid "You should start by adding participants"
msgstr ""
msgid "Add a new bill"
msgstr ""
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr ""
msgid "When?" msgid "You should start by adding participants"
msgstr "" msgstr ""
msgid "Who paid?" msgid "Add a new bill"
msgstr "" msgstr ""
msgid "For what?" msgid "For what?"
msgstr "" msgstr ""
msgid "How much?"
msgstr ""
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "" msgstr ""
@ -813,19 +827,19 @@ msgstr ""
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "" msgstr ""
msgid "delete"
msgstr ""
msgid "No bills" msgid "No bills"
msgstr "" msgstr ""
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "" msgstr ""
msgid "You probably want to" msgid "Add your first bill"
msgstr "" msgstr ""
msgid "add a bill" msgid "Add the first participant"
msgstr ""
msgid "add participants"
msgstr "" msgstr ""
msgid "Password reminder" msgid "Password reminder"
@ -848,31 +862,49 @@ msgstr ""
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "" msgstr ""
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
msgid "Identifier:" msgid "Scan QR code"
msgstr "" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "" msgstr ""
msgid "Send via Emails" msgid "Send via Emails"
msgstr "" msgstr ""
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you." msgstr ""
msgid "Share Identifier & code"
msgstr ""
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr ""
#, fuzzy
msgid "Private code:"
msgstr "ব্যক্তিগত কোড"
msgid "the private code was defined when you created the project"
msgstr "" msgstr ""
msgid "Who pays?" msgid "Who pays?"
@ -904,3 +936,118 @@ msgstr ""
msgid "Period" msgid "Period"
msgstr "" msgstr ""
#~ msgid "Import previously exported JSON file"
#~ msgstr ""
#~ msgid "Import"
#~ msgstr ""
#~ msgid "Amount paid"
#~ msgstr ""
#~ msgid "Bills can't be null"
#~ msgstr ""
#~ msgid "Too many failed login attempts, please retry later."
#~ msgstr ""
#~ msgid "The project identifier is %(project)s"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "sending you an email with password "
#~ "reset instructions. Please check the "
#~ "email configuration of the server or "
#~ "contact the administrator."
#~ msgstr ""
#~ msgid "Invalid JSON"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "trying to send the invitation emails."
#~ " Please check the email configuration "
#~ "of the server or contact the "
#~ "administrator."
#~ msgstr ""
#~ msgid "Are you sure?"
#~ msgstr ""
#~ msgid "Import JSON"
#~ msgstr ""
#~ 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 "Send invites"
#~ msgstr ""
#~ msgid " show"
#~ msgstr ""
#~ msgid "Edit the project"
#~ msgstr ""
#~ msgid "You probably want to"
#~ msgstr ""
#~ msgid "add a bill"
#~ msgstr ""
#~ msgid "add participants"
#~ msgstr ""
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ msgid "Share the Link"
#~ msgstr ""
#~ msgid "You can directly share the following link via your prefered medium"
#~ 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 ""
#~ "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 with the invitation "
#~ "link."
#~ msgstr ""

View file

@ -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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2020-08-01 10:41+0000\n" "PO-Revision-Date: 2020-08-01 10:41+0000\n"
"Last-Translator: Oymate <dhruboadittya96@gmail.com>\n" "Last-Translator: Oymate <dhruboadittya96@gmail.com>\n"
"Language: bn_BD\n" "Language: bn_BD\n"
@ -15,6 +15,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
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."
@ -25,6 +29,13 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "প্রকল্পের নাম" msgstr "প্রকল্পের নাম"
#, fuzzy
msgid "Current private code"
msgstr "ব্যক্তিগত কোড"
msgid "Enter existing private code to edit project"
msgstr ""
#, fuzzy #, fuzzy
msgid "New private code" msgid "New private code"
msgstr "ব্যক্তিগত কোড" msgstr "ব্যক্তিগত কোড"
@ -47,16 +58,20 @@ msgstr "ডিফল্ট মুদ্রা"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
msgid "Unknown error"
msgstr "অজানা ত্রুট"
#, fuzzy
msgid "Invalid private code."
msgstr "ব্যক্তিগত কোড"
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "পূর্বে রপ্তানি করা JSON ফাইল আমদানি করুন" msgstr ""
msgid "Import"
msgstr "আমদানি"
msgid "Project identifier" msgid "Project identifier"
msgstr "প্রকল্প শনাক্তকারী" msgstr "প্রকল্প শনাক্তকারী"
@ -85,13 +100,6 @@ msgstr ""
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "মুছে ফেলার জন্য ব্যক্তিগত কোড লিখুন" msgstr "মুছে ফেলার জন্য ব্যক্তিগত কোড লিখুন"
msgid "Unknown error"
msgstr "অজানা ত্রুট"
#, fuzzy
msgid "Invalid private code."
msgstr "ব্যক্তিগত কোড"
msgid "Get in" msgid "Get in"
msgstr "ভিতরে আস" msgstr "ভিতরে আস"
@ -116,16 +124,16 @@ msgstr ""
msgid "Reset password" msgid "Reset password"
msgstr "" msgstr ""
msgid "Date" msgid "When?"
msgstr "" msgstr ""
msgid "What?" msgid "What?"
msgstr "" msgstr ""
msgid "Payer" msgid "Who paid?"
msgstr "" msgstr ""
msgid "Amount paid" msgid "How much?"
msgstr "" msgstr ""
msgid "Currency" msgid "Currency"
@ -150,9 +158,6 @@ msgstr ""
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "" msgstr ""
msgid "Bills can't be null"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr ""
@ -174,13 +179,25 @@ msgstr ""
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "" msgstr ""
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "" msgstr ""
msgid "Logout"
msgstr ""
msgid "Please check the email configuration of the server."
msgstr ""
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "" msgstr ""
@ -208,7 +225,7 @@ msgstr ""
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "" msgstr ""
#, python-format #, python-format
@ -221,10 +238,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "" msgstr ""
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "" msgstr ""
@ -233,14 +246,9 @@ msgid ""
"still use the project normally." "still use the project normally."
msgstr "" msgstr ""
#, python-format
msgid "The project identifier is %(project)s"
msgstr ""
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
msgid "No token provided" msgid "No token provided"
@ -255,10 +263,14 @@ msgstr ""
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "" msgstr ""
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "" msgstr ""
msgid "" msgid ""
@ -266,12 +278,18 @@ msgid ""
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr ""
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "" msgstr ""
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr ""
@ -279,10 +297,7 @@ msgstr ""
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "" msgstr ""
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
#, python-format #, python-format
@ -325,6 +340,10 @@ msgstr ""
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "" msgstr ""
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
#, fuzzy #, fuzzy
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "প্রকল্পের ইতিহাস সক্রিয় করো" msgstr "প্রকল্পের ইতিহাস সক্রিয় করো"
@ -387,7 +406,7 @@ msgstr ""
msgid "edit" msgid "edit"
msgstr "" msgstr ""
msgid "delete" msgid "Delete project"
msgstr "" msgstr ""
msgid "show" msgid "show"
@ -402,20 +421,12 @@ msgstr ""
msgid "Get it on" msgid "Get it on"
msgstr "" msgstr ""
msgid "Are you sure?"
msgstr ""
msgid "Edit project" msgid "Edit project"
msgstr "" msgstr ""
msgid "Delete project" #, fuzzy
msgstr "" msgid "Import project"
msgstr "প্রকল্প তৈরি করুন"
msgid "Import JSON"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Download project's data" msgid "Download project's data"
msgstr "" msgstr ""
@ -441,18 +452,28 @@ msgstr ""
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "" msgstr ""
msgid "Edit the project" msgid "Save changes"
msgstr "" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
#, fuzzy
msgid "Import previously exported project"
msgstr "পূর্বে রপ্তানি করা JSON ফাইল আমদানি করুন"
msgid "Choose file"
msgstr ""
msgid "Edit this bill" msgid "Edit this bill"
msgstr "" msgstr ""
msgid "Add a bill" msgid "Add a bill"
msgstr "" msgstr ""
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr ""
@ -471,9 +492,6 @@ msgstr ""
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "" msgstr ""
msgid "Send the invitations"
msgstr ""
msgid "Download" msgid "Download"
msgstr "" msgstr ""
@ -538,23 +556,18 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"disabling project history. You can\n" msgstr ""
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
"data-target=\"#confirm-erase\">clear project history</a> to remove " msgid "You can clear the project history to remove them."
"them.</i></p>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
@ -565,18 +578,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "" msgstr ""
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "Time" msgid "Time"
msgstr "" msgstr ""
@ -638,9 +651,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr ""
msgid "Amount" msgid "Amount"
msgstr "" msgstr ""
msgid "Date"
msgstr ""
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "" msgstr ""
@ -741,6 +760,9 @@ msgstr ""
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "" msgstr ""
@ -750,7 +772,8 @@ msgstr ""
msgid "Dashboard" msgid "Dashboard"
msgstr "" msgstr ""
msgid "Logout" #, python-format
msgid "Please retry after %(date)s."
msgstr "" msgstr ""
msgid "Code" msgid "Code"
@ -784,30 +807,21 @@ msgstr ""
msgid "Invite people" msgid "Invite people"
msgstr "" msgstr ""
msgid "You should start by adding participants"
msgstr ""
msgid "Add a new bill"
msgstr ""
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr ""
msgid "When?" msgid "You should start by adding participants"
msgstr "" msgstr ""
msgid "Who paid?" msgid "Add a new bill"
msgstr "" msgstr ""
msgid "For what?" msgid "For what?"
msgstr "" msgstr ""
msgid "How much?"
msgstr ""
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "" msgstr ""
@ -816,19 +830,19 @@ msgstr ""
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "" msgstr ""
msgid "delete"
msgstr ""
msgid "No bills" msgid "No bills"
msgstr "" msgstr ""
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "" msgstr ""
msgid "You probably want to" msgid "Add your first bill"
msgstr "" msgstr ""
msgid "add a bill" msgid "Add the first participant"
msgstr ""
msgid "add participants"
msgstr "" msgstr ""
msgid "Password reminder" msgid "Password reminder"
@ -851,31 +865,49 @@ msgstr ""
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "" msgstr ""
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
msgid "Identifier:" msgid "Scan QR code"
msgstr "" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "" msgstr ""
msgid "Send via Emails" msgid "Send via Emails"
msgstr "" msgstr ""
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you." msgstr ""
msgid "Share Identifier & code"
msgstr ""
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr ""
#, fuzzy
msgid "Private code:"
msgstr "ব্যক্তিগত কোড"
msgid "the private code was defined when you created the project"
msgstr "" msgstr ""
msgid "Who pays?" msgid "Who pays?"
@ -1012,3 +1044,115 @@ msgstr ""
#~ msgid "Participants to notify" #~ msgid "Participants to notify"
#~ msgstr "" #~ msgstr ""
#~ msgid "Import"
#~ msgstr "আমদানি"
#~ msgid "Amount paid"
#~ msgstr ""
#~ msgid "Bills can't be null"
#~ msgstr ""
#~ msgid "Too many failed login attempts, please retry later."
#~ msgstr ""
#~ msgid "The project identifier is %(project)s"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "sending you an email with password "
#~ "reset instructions. Please check the "
#~ "email configuration of the server or "
#~ "contact the administrator."
#~ msgstr ""
#~ msgid "Invalid JSON"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "trying to send the invitation emails."
#~ " Please check the email configuration "
#~ "of the server or contact the "
#~ "administrator."
#~ msgstr ""
#~ msgid "Are you sure?"
#~ msgstr ""
#~ msgid "Import JSON"
#~ msgstr ""
#~ 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 "Send invites"
#~ msgstr ""
#~ msgid " show"
#~ msgstr ""
#~ msgid "Edit the project"
#~ msgstr ""
#~ msgid "You probably want to"
#~ msgstr ""
#~ msgid "add a bill"
#~ msgstr ""
#~ msgid "add participants"
#~ msgstr ""
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ msgid "Share the Link"
#~ msgstr ""
#~ msgid "You can directly share the following link via your prefered medium"
#~ 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 ""
#~ "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 with the invitation "
#~ "link."
#~ msgstr ""

View file

@ -1,29 +1,41 @@
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: 2022-08-29 18:51+0200\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2022-09-12 15:25+0000\n" "PO-Revision-Date: 2022-09-12 15:25+0000\n"
"Last-Translator: Maite Guix <maite.guix@gmail.com>\n" "Last-Translator: Maite Guix <maite.guix@gmail.com>\n"
"Language-Team: Catalan <https://hosted.weblate.org/projects/i-hate-money/"
"i-hate-money/ca/>\n"
"Language: ca\n" "Language: ca\n"
"Language-Team: Catalan <https://hosted.weblate.org/projects/i-hate-"
"money/i-hate-money/ca/>\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.9.0\n"
"X-Generator: Weblate 4.14.1-dev\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Acabes de crear '%(project)s' per a compartir les teves despeses"
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 ""
"No és un import o expressió vàlida. Només s'accepten números i els operadors " "No és un import o expressió vàlida. Només s'accepten números i els "
"+ - * /." "operadors + - * /."
msgid "Project name" msgid "Project name"
msgstr "Nom del projecte" msgstr "Nom del projecte"
#, fuzzy
msgid "Current private code"
msgstr "Codi privat nou"
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "Codi privat nou" msgstr "Codi privat nou"
@ -47,18 +59,21 @@ msgstr ""
"L'establiment d'una moneda predeterminada permet la conversió de moneda " "L'establiment d'una moneda predeterminada permet la conversió de moneda "
"entre factures" "entre factures"
msgid "Unknown error"
msgstr "Error desconegut"
msgid "Invalid private code."
msgstr "Codi privat no vàlid."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
"Aquest projecte no es pot definir com a «cap moneda» perquè conté factures " "Aquest projecte no es pot definir com a «cap moneda» perquè conté "
"en diverses monedes." "factures en diverses monedes."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Importar el fitxer JSON anteriorment exportat" msgstr ""
msgid "Import"
msgstr "Importar"
msgid "Project identifier" msgid "Project identifier"
msgstr "Identificador del projecte" msgstr "Identificador del projecte"
@ -74,8 +89,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 ""
"Ja existeix un projecte amb aquest identificador (\"%(project)s\"). Si us " "Ja existeix un projecte amb aquest identificador (\"%(project)s\"). Si us"
"plau, tria un identificador nou" " plau, tria un identificador nou"
msgid "Which is a real currency: Euro or Petro dollar?" msgid "Which is a real currency: Euro or Petro dollar?"
msgstr "En quina moneda: euro o petrodòlar?" msgstr "En quina moneda: euro o petrodòlar?"
@ -89,12 +104,6 @@ msgstr "Si us plau, valida el captcha per a continuar."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Introdueix el codi privat per a confirmar la supressió" msgstr "Introdueix el codi privat per a confirmar la supressió"
msgid "Unknown error"
msgstr "Error desconegut"
msgid "Invalid private code."
msgstr "Codi privat no vàlid."
msgid "Get in" msgid "Get in"
msgstr "Entrar-hi" msgstr "Entrar-hi"
@ -119,17 +128,17 @@ msgstr "Confirmació de contrasenya"
msgid "Reset password" msgid "Reset password"
msgstr "Restablir la contrasenya" msgstr "Restablir la contrasenya"
msgid "Date" msgid "When?"
msgstr "Data" msgstr "Quan?"
msgid "What?" msgid "What?"
msgstr "Què?" msgstr "Què?"
msgid "Payer" msgid "Who paid?"
msgstr "Pagador" msgstr "Qui va pagar?"
msgid "Amount paid" msgid "How much?"
msgstr "Import pagat" msgstr "Quant?"
msgid "Currency" msgid "Currency"
msgstr "Moneda" msgstr "Moneda"
@ -153,9 +162,6 @@ msgstr "Enviar i afegir-ne un de nou"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Moneda predeterminada del projecte: %(currency)s" msgstr "Moneda predeterminada del projecte: %(currency)s"
msgid "Bills can't be null"
msgstr "Les factures no poden ser nul·les"
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
@ -177,13 +183,28 @@ msgstr "Aquest projecte ja compta amb aquest participant"
msgid "People to notify" msgid "People to notify"
msgstr "Gent a notificar" msgstr "Gent a notificar"
msgid "Send invites" msgid "Send the invitations"
msgstr "Enviar invitacions" msgstr "Enviar les invitacions"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "El correu electrònic %(email)s no és vàlid" msgstr "El correu electrònic %(email)s no és vàlid"
msgid "Logout"
msgstr "Tancar sessió"
msgid "Please check the email configuration of the server."
msgstr ""
#, fuzzy, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Ho sentim, s'ha produït un error en intentar enviar els correus "
"electrònics d'invitació. Comprova la configuració de correu electrònic "
"del servidor o posa't en contacte amb l'administrador."
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} i {dual_object_1}" msgstr "{dual_object_0} i {dual_object_1}"
@ -211,14 +232,15 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix}:<br />{errors}" msgstr "{prefix}:<br />{errors}"
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "Massa intents d'inici de sessió fallits, torna-ho a provar més tard." msgstr "Massa intents d'inici de sessió fallits, torna-ho a provar més tard."
#, python-format #, python-format
msgid "This admin password is not the right one. Only %(num)d attempts left." msgid "This admin password is not the right one. Only %(num)d attempts left."
msgstr "" msgstr ""
"Aquesta contrasenya d'administrador no és la correcta. Només queden %(num)d " "Aquesta contrasenya d'administrador no és la correcta. Només queden "
"intents." "%(num)d intents."
msgid "Provided token is invalid" msgid "Provided token is invalid"
msgstr "El testimoni proporcionat no és vàlid" msgstr "El testimoni proporcionat no és vàlid"
@ -226,10 +248,6 @@ msgstr "El testimoni proporcionat no és vàlid"
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Aquest codi privat no és el correcte" msgstr "Aquest codi privat no és el correcte"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Acabes de crear '%(project)s' per a compartir les teves despeses"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "T'acaben d'enviar un correu electrònic de recordatori" msgstr "T'acaben d'enviar un correu electrònic de recordatori"
@ -240,18 +258,15 @@ msgstr ""
"Hem intentat enviar-vos un correu electrònic de recordatori, però s'ha " "Hem intentat enviar-vos un correu electrònic de recordatori, però s'ha "
"produït un error. Encara podeu utilitzar el projecte amb normalitat." "produït un error. Encara podeu utilitzar el projecte amb normalitat."
#, python-format #, fuzzy
msgid "The project identifier is %(project)s"
msgstr "L'identificador del projecte és %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"Ho sentim, s'ha produït un error en enviar-te un correu electrònic amb " "Ho sentim, s'ha produït un error en enviar-te un correu electrònic amb "
"instruccions de restabliment de la contrasenya. Comprova la configuració de " "instruccions de restabliment de la contrasenya. Comprova la configuració "
"correu electrònic del servidor o posa't en contacte amb l'administrador." "de correu electrònic del servidor o posa't en contacte amb "
"l'administrador."
msgid "No token provided" msgid "No token provided"
msgstr "No s'ha proporcionat cap testimoni" msgstr "No s'ha proporcionat cap testimoni"
@ -265,18 +280,25 @@ msgstr "Projecte desconegut"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "La contrasenya s'ha restablert correctament." msgstr "La contrasenya s'ha restablert correctament."
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "El projecte s'ha penjat correctament" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "JSON no vàlid" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
"No es poden afegir factures en diverses monedes a un projecte sense moneda " "No es poden afegir factures en diverses monedes a un projecte sense "
"predeterminada" "moneda predeterminada"
msgid "Project successfully uploaded"
msgstr "El projecte s'ha penjat correctament"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "El projecte s'ha suprimit correctament" msgstr "El projecte s'ha suprimit correctament"
@ -284,6 +306,9 @@ msgstr "El projecte s'ha suprimit correctament"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "S'ha produït un error en suprimir el projecte" msgstr "S'ha produït un error en suprimir el projecte"
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "T'han convidat a compartir les teves despeses per a %(project)s" msgstr "T'han convidat a compartir les teves despeses per a %(project)s"
@ -291,14 +316,12 @@ msgstr "T'han convidat a compartir les teves despeses per a %(project)s"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "S'han enviat les teves invitacions" msgstr "S'han enviat les teves invitacions"
msgid "" #, fuzzy
"Sorry, there was an error while trying to send the invitation emails. " msgid "Sorry, there was an error while trying to send the invitation emails."
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Ho sentim, s'ha produït un error en intentar enviar els correus electrònics " "Ho sentim, s'ha produït un error en intentar enviar els correus "
"d'invitació. Comprova la configuració de correu electrònic del servidor o " "electrònics d'invitació. Comprova la configuració de correu electrònic "
"posa't en contacte amb l'administrador." "del servidor o posa't en contacte amb l'administrador."
#, python-format #, python-format
msgid "%(member)s has been added" msgid "%(member)s has been added"
@ -319,8 +342,8 @@ msgid ""
"Participant '%(name)s' has been deactivated. It will still appear in the " "Participant '%(name)s' has been deactivated. It will still appear in the "
"list until its balance reach zero." "list until its balance reach zero."
msgstr "" msgstr ""
"El participant «%(name)s» ha estat desactivat. Continuarà apareixent a la " "El participant «%(name)s» ha estat desactivat. Continuarà apareixent a la"
"llista fins que el seu saldo arribi a zero." " llista fins que el seu saldo arribi a zero."
#, python-format #, python-format
msgid "Participant '%(name)s' has been removed" msgid "Participant '%(name)s' has been removed"
@ -342,6 +365,10 @@ msgstr "La factura s'ha suprimit"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "La factura ha estat modificada" msgstr "La factura ha estat modificada"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "S'ha produït un error en suprimir l'historial del projecte" msgstr "S'ha produït un error en suprimir l'historial del projecte"
@ -402,8 +429,8 @@ msgstr "Accions"
msgid "edit" msgid "edit"
msgstr "editar" msgstr "editar"
msgid "delete" msgid "Delete project"
msgstr "suprimir" msgstr "Suprimir el projecte"
msgid "show" msgid "show"
msgstr "mostrar" msgstr "mostrar"
@ -417,20 +444,12 @@ msgstr "Descarregar l'aplicació mòbil"
msgid "Get it on" msgid "Get it on"
msgstr "Aconsegueix-ho" msgstr "Aconsegueix-ho"
msgid "Are you sure?"
msgstr "N'estàs segur?"
msgid "Edit project" msgid "Edit project"
msgstr "Editar el projecte" msgstr "Editar el projecte"
msgid "Delete project" #, fuzzy
msgstr "Suprimir el projecte" msgid "Import project"
msgstr "Editar el projecte"
msgid "Import JSON"
msgstr "Importar JSON"
msgid "Choose file"
msgstr "Triar fitxer"
msgid "Download project's data" msgid "Download project's data"
msgstr "Descarregar les dades del projecte" msgstr "Descarregar les dades del projecte"
@ -446,8 +465,8 @@ msgstr "Plans de liquidació"
msgid "Download the list of transactions needed to settle the current bills." msgid "Download the list of transactions needed to settle the current bills."
msgstr "" msgstr ""
"Descarregar la llista transaccions necessàries per a liquidar les factures " "Descarregar la llista transaccions necessàries per a liquidar les "
"actuals." "factures actuals."
msgid "Can't remember the password?" msgid "Can't remember the password?"
msgstr "No recordes la contrasenya?" msgstr "No recordes la contrasenya?"
@ -458,12 +477,20 @@ msgstr "Cancel·lar"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Configuració de la privacitat" msgstr "Configuració de la privacitat"
msgid "Edit the project" msgid "Save changes"
msgstr "Editar el projecte" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
"Això eliminarà totes les factures i tots els participants en aquest projecte!" "Això eliminarà totes les factures i tots els participants en aquest "
"projecte!"
#, fuzzy
msgid "Import previously exported project"
msgstr "Importar el fitxer JSON anteriorment exportat"
msgid "Choose file"
msgstr "Triar fitxer"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Editar aquesta factura" msgstr "Editar aquesta factura"
@ -471,6 +498,9 @@ msgstr "Editar aquesta factura"
msgid "Add a bill" msgid "Add a bill"
msgstr "Afegir una factura" msgstr "Afegir una factura"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "Tothom" msgstr "Tothom"
@ -489,9 +519,6 @@ msgstr "Editar aquest participant"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "eloi.serra@exemple.cat, maria.canut@lloc.com" msgstr "eloi.serra@exemple.cat, maria.canut@lloc.com"
msgid "Send the invitations"
msgstr "Enviar les invitacions"
msgid "Download" msgid "Download"
msgstr "Descarregar" msgstr "Descarregar"
@ -518,8 +545,7 @@ msgstr "S'ha canviat la configuració de l'historial"
#, python-format #, python-format
msgid "Bill %(name)s: %(property_name)s changed from %(before)s to %(after)s" msgid "Bill %(name)s: %(property_name)s changed from %(before)s to %(after)s"
msgstr "" msgstr "Factura %(name)s: %(property_name)s ha canviat de %(before)s a %(after)s"
"Factura %(name)s: %(property_name)s ha canviat de %(before)s a %(after)s"
#, python-format #, python-format
msgid "Bill %(name)s: %(property_name)s changed to %(after)s" msgid "Bill %(name)s: %(property_name)s changed to %(after)s"
@ -534,10 +560,10 @@ msgid ""
" The rest of the project history will be unaffected. This " " The rest of the project history will be unaffected. This "
"action cannot be undone." "action cannot be undone."
msgstr "" msgstr ""
"Estàs segur que vols suprimir totes les adreces IP enregistrades d'aquest " "Estàs segur que vols suprimir totes les adreces IP enregistrades d'aquest"
"projecte?\n" " projecte?\n"
" La resta de l'historial del projecte no es veurà afectat. " " La resta de l'historial del projecte no es veurà afectat."
"Aquesta acció no es pot desfer." " Aquesta acció no es pot desfer."
msgid "Confirm deletion" msgid "Confirm deletion"
msgstr "Confirmar la supressió" msgstr "Confirmar la supressió"
@ -561,39 +587,23 @@ msgstr "Factura %(name)s: afegida a la llista de propietaris %(owers_list_str)s"
#, python-format #, python-format
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr "Factura %(name)s: eliminada de la llista de propietaris %(owers_list_str)s"
"Factura %(name)s: eliminada de la llista de propietaris %(owers_list_str)s"
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n"
" <i>Aquest projecte té l'historial deshabilitat. Les accions " #, fuzzy
"noves no apareixeran a continuació. Pots habilitar l'historial a la </i>\n" msgid "You can enable history on the settings page."
" <a href=\"%(url)s\">pàgina de configuració</a>\n" msgstr "L'enregistrament d'adreces IP es pot habilitar a la pàgina de configuració"
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n"
" <i>La taula següent reflecteix les accions enregistrades abans " #, fuzzy
"de deshabilitar l'historial de projectes. Pots \n" msgid "You can clear the project history to remove them."
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" data-" msgstr "Probablement algú ha netejat l'historial del projecte."
"target=\"#confirm-erase\"> netejar l'historial del projecte</a> per a "
"eliminar-les.</i></p>\n"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -605,18 +615,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Suprimir les adreces IP emmagatzemades" msgstr "Suprimir les adreces IP emmagatzemades"
msgid "No history to erase"
msgstr "No hi ha historial a esborrar"
msgid "Clear Project History"
msgstr "Netejar l'historial del projecte"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "No hi ha adreces IP a esborrar" msgstr "No hi ha adreces IP a esborrar"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Suprimir les adreces IP emmagatzemades" msgstr "Suprimir les adreces IP emmagatzemades"
msgid "No history to erase"
msgstr "No hi ha historial a esborrar"
msgid "Clear Project History"
msgstr "Netejar l'historial del projecte"
msgid "Time" msgid "Time"
msgstr "Hora" msgstr "Hora"
@ -624,12 +634,12 @@ msgid "Event"
msgstr "Esdeveniment" msgstr "Esdeveniment"
msgid "IP address recording can be enabled on the settings page" msgid "IP address recording can be enabled on the settings page"
msgstr "" msgstr "L'enregistrament d'adreces IP es pot habilitar a la pàgina de configuració"
"L'enregistrament d'adreces IP es pot habilitar a la pàgina de configuració"
msgid "IP address recording can be disabled on the settings page" msgid "IP address recording can be disabled on the settings page"
msgstr "" msgstr ""
"L'enregistrament d'adreces IP es pot deshabilitar a la pàgina de configuració" "L'enregistrament d'adreces IP es pot deshabilitar a la pàgina de "
"configuració"
msgid "From IP" msgid "From IP"
msgstr "Des d'IP" msgstr "Des d'IP"
@ -655,8 +665,7 @@ msgstr "S'ha canviat el nom del projecte a %(new_project_name)s"
#, python-format #, python-format
msgid "Project contact email changed to %(new_email)s" msgid "Project contact email changed to %(new_email)s"
msgstr "" msgstr "El correu electrònic de contacte del projecte ha canviat a %(new_email)s"
"El correu electrònic de contacte del projecte ha canviat a %(new_email)s"
msgid "Project settings modified" msgid "Project settings modified"
msgstr "S'ha modificat la configuració del projecte" msgstr "S'ha modificat la configuració del projecte"
@ -679,12 +688,17 @@ msgstr "Factura %(name)s ha canviat el nom a %(new_description)s"
#, python-format #, python-format
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr "Participant %(name)s: el pes ha canviat de %(old_weight)s a %(new_weight)s"
"Participant %(name)s: el pes ha canviat de %(old_weight)s a %(new_weight)s"
msgid "Payer"
msgstr "Pagador"
msgid "Amount" msgid "Amount"
msgstr "Import" msgstr "Import"
msgid "Date"
msgstr "Data"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Import en %(currency)s" msgstr "Import en %(currency)s"
@ -757,8 +771,8 @@ msgid ""
"Don\\'t reuse a personal password. Choose a private code and send it to " "Don\\'t reuse a personal password. Choose a private code and send it to "
"your friends" "your friends"
msgstr "" msgstr ""
"No reutilitzis una contrasenya personal. Tria un codi privat i envia'l als " "No reutilitzis una contrasenya personal. Tria un codi privat i envia'l "
"teus amics" "als teus amics"
msgid "Account manager" msgid "Account manager"
msgstr "Gestor de comptes" msgstr "Gestor de comptes"
@ -787,6 +801,9 @@ msgstr "Historial"
msgid "Settings" msgid "Settings"
msgstr "Configuració" msgstr "Configuració"
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "Altres projectes:" msgstr "Altres projectes:"
@ -796,8 +813,9 @@ msgstr "commutar a"
msgid "Dashboard" msgid "Dashboard"
msgstr "Panell" msgstr "Panell"
msgid "Logout" #, python-format
msgstr "Tancar sessió" msgid "Please retry after %(date)s."
msgstr ""
msgid "Code" msgid "Code"
msgstr "Codi" msgstr "Codi"
@ -830,30 +848,21 @@ msgstr "n'estàs segur?"
msgid "Invite people" msgid "Invite people"
msgstr "Convidar gent" msgstr "Convidar gent"
msgid "You should start by adding participants"
msgstr "Hauries de començar afegint participants"
msgid "Add a new bill"
msgstr "Afegir una factura nova"
msgid "Newer bills" msgid "Newer bills"
msgstr "Factures més noves" msgstr "Factures més noves"
msgid "Older bills" msgid "Older bills"
msgstr "Factures més antigues" msgstr "Factures més antigues"
msgid "When?" msgid "You should start by adding participants"
msgstr "Quan?" msgstr "Hauries de començar afegint participants"
msgid "Who paid?" msgid "Add a new bill"
msgstr "Qui va pagar?" msgstr "Afegir una factura nova"
msgid "For what?" msgid "For what?"
msgstr "Què va pagar?" msgstr "Què va pagar?"
msgid "How much?"
msgstr "Quant?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Afegida el %(date)s" msgstr "Afegida el %(date)s"
@ -862,20 +871,22 @@ msgstr "Afegida el %(date)s"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Tothom menys %(excluded)s" msgstr "Tothom menys %(excluded)s"
msgid "delete"
msgstr "suprimir"
msgid "No bills" msgid "No bills"
msgstr "Sense factures" msgstr "Sense factures"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Res a enumerar encara." msgstr "Res a enumerar encara."
msgid "You probably want to" #, fuzzy
msgstr "Probablement vulguis" msgid "Add your first bill"
msgid "add a bill"
msgstr "afegir una factura" msgstr "afegir una factura"
msgid "add participants" #, fuzzy
msgstr "afegir participants" msgid "Add the first participant"
msgstr "Editar aquest participant"
msgid "Password reminder" msgid "Password reminder"
msgstr "Recordatori de contrasenya" msgstr "Recordatori de contrasenya"
@ -884,8 +895,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 ""
"Se t'ha enviat un enllaç per a restablir la vostra contrasenya, comprova els " "Se t'ha enviat un enllaç per a restablir la vostra contrasenya, comprova "
"teus correus electrònics." "els teus correus electrònics."
msgid "Return to home page" msgid "Return to home page"
msgstr "Tornar a la pàgina d'inici" msgstr "Tornar a la pàgina d'inici"
@ -899,39 +910,55 @@ msgstr "Restablir la contrasenya"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Convidar a persones a unir-se a aquest projecte" msgstr "Convidar a persones a unir-se a aquest projecte"
msgid "Share an invitation link"
msgstr ""
msgid ""
"The easiest way to invite people is to give them the following invitation"
" link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr ""
msgid "Scan QR code"
msgstr ""
msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "Send via Emails"
msgstr "Enviar per correu electrònic"
#, fuzzy
msgid ""
"Specify a list of email adresses (separated by comma) of people you want "
"to notify about the creation of this project. We will send them an email "
"with the invitation link."
msgstr ""
"Especifica una llista (separada per comes) dels correus electrònic als "
"que vols notificar la\n"
" creació d'aquest projecte de gestió pressupostària i els "
"hi enviarem un correu electrònic."
msgid "Share Identifier & code" msgid "Share Identifier & code"
msgstr "Compartir l'identificador i el codi" msgstr "Compartir l'identificador i el codi"
msgid "" 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.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr "" msgstr ""
"Pots compartir l'identificador del projecte i el codi privat per qualsevol "
"mitjà de comunicació."
msgid "Identifier:" msgid "Identifier:"
msgstr "Identificador:" msgstr "Identificador:"
msgid "Share the Link" #, fuzzy
msgstr "Compartir l'enllaç" msgid "Private code:"
msgstr "Codi privat"
msgid "You can directly share the following link via your prefered medium" msgid "the private code was defined when you created the project"
msgstr "" msgstr ""
"Pots compartir directament l'enllaç següent a través del teu mitjà preferit"
msgid "Send via Emails"
msgstr "Enviar per correu electrònic"
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 ""
"Especifica una llista (separada per comes) dels correus electrònic als que "
"vols notificar la\n"
" creació d'aquest projecte de gestió pressupostària i els hi "
"enviarem un correu electrònic."
msgid "Who pays?" msgid "Who pays?"
msgstr "Qui ha de pagar?" msgstr "Qui ha de pagar?"
@ -962,3 +989,97 @@ msgstr "Despeses per mes"
msgid "Period" msgid "Period"
msgstr "Període" msgstr "Període"
#~ msgid "Import"
#~ msgstr "Importar"
#~ msgid "Amount paid"
#~ msgstr "Import pagat"
#~ msgid "Bills can't be null"
#~ msgstr "Les factures no poden ser nul·les"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "L'identificador del projecte és %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "JSON no vàlid"
#~ msgid "Are you sure?"
#~ msgstr "N'estàs segur?"
#~ msgid "Import JSON"
#~ msgstr "Importar JSON"
#~ 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>Aquest projecte té l'historial"
#~ " deshabilitat. Les accions noves no "
#~ "apareixeran a continuació. Pots habilitar "
#~ "l'historial a la </i>\n"
#~ " <a href=\"%(url)s\">pàgina de configuració</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>La taula següent reflecteix "
#~ "les accions enregistrades abans de "
#~ "deshabilitar l'historial de projectes. Pots"
#~ " \n"
#~ " <a href=\"#\" data-"
#~ "toggle=\"modal\" data-keyboard=\"false\" data-"
#~ "target=\"#confirm-erase\"> netejar l'historial "
#~ "del projecte</a> per a eliminar-"
#~ "les.</i></p>\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "Enviar invitacions"
#~ msgid " show"
#~ msgstr "mostrar"
#~ msgid "Edit the project"
#~ msgstr "Editar el projecte"
#~ msgid "You probably want to"
#~ msgstr "Probablement vulguis"
#~ msgid "add participants"
#~ msgstr "afegir participants"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "Pots compartir l'identificador del projecte"
#~ " i el codi privat per qualsevol "
#~ "mitjà de comunicació."
#~ msgid "Share the Link"
#~ msgstr "Compartir l'enllaç"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr ""
#~ "Pots compartir directament l'enllaç següent"
#~ " a través del teu mitjà preferit"

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,9 @@ 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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2021-11-29 23:53+0000\n" "PO-Revision-Date: 2023-08-20 00:58+0000\n"
"Last-Translator: Jannik Lang <jannik.lang@posteo.de>\n" "Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
"Language-Team: German <https://hosted.weblate.org/projects/i-hate-money/" "Language-Team: German <https://hosted.weblate.org/projects/i-hate-money/"
"i-hate-money/de/>\n" "i-hate-money/de/>\n"
"Language: de\n" "Language: de\n"
@ -12,9 +12,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 4.10-dev\n" "X-Generator: Weblate 5.0-dev\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
"Du hast gerade das Projekt '%(project)s' erstellt, um deine Ausgaben zu "
"teilen"
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."
@ -25,6 +31,12 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Projektname" msgstr "Projektname"
msgid "Current private code"
msgstr "Aktueller privater Code"
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "Neuer privater Code" msgstr "Neuer privater Code"
@ -48,6 +60,12 @@ msgstr ""
"Das Festlegen einer Standardwährung ermöglicht die Währungsumrechnung " "Das Festlegen einer Standardwährung ermöglicht die Währungsumrechnung "
"zwischen Rechnungen" "zwischen Rechnungen"
msgid "Unknown error"
msgstr "Unbekannter Fehler"
msgid "Invalid private code."
msgstr "ungültiger privater Code."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
@ -55,11 +73,8 @@ msgstr ""
"Dieses Projekt kann nicht auf \"ohne Währung\" eingestellt werden, weil " "Dieses Projekt kann nicht auf \"ohne Währung\" eingestellt werden, weil "
"es Rechnungen unterschiedlicher Währungen enthält." "es Rechnungen unterschiedlicher Währungen enthält."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Zuvor exportierte JSON-Datei importieren" msgstr "Kompatibel mit Cospend"
msgid "Import"
msgstr "Importieren"
msgid "Project identifier" msgid "Project identifier"
msgstr "Projektkennung" msgstr "Projektkennung"
@ -90,12 +105,6 @@ msgstr "Bitte bestätige das Captcha, um fortzufahren."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Geben Sie Ihren privaten Code ein, um die Löschung zu bestätigen" msgstr "Geben Sie Ihren privaten Code ein, um die Löschung zu bestätigen"
msgid "Unknown error"
msgstr "Unbekannter Fehler"
msgid "Invalid private code."
msgstr "ungültiger privater Code."
msgid "Get in" msgid "Get in"
msgstr "Eintreten" msgstr "Eintreten"
@ -120,17 +129,17 @@ msgstr "Passwort bestätigen"
msgid "Reset password" msgid "Reset password"
msgstr "Passwort zurücksetzen" msgstr "Passwort zurücksetzen"
msgid "Date" msgid "When?"
msgstr "Datum" msgstr "Wann?"
msgid "What?" msgid "What?"
msgstr "Was?" msgstr "Was?"
msgid "Payer" msgid "Who paid?"
msgstr "Von" msgstr "Wer hat bezahlt?"
msgid "Amount paid" msgid "How much?"
msgstr "Betrag" msgstr "Wieviel?"
msgid "Currency" msgid "Currency"
msgstr "Währung" msgstr "Währung"
@ -156,9 +165,6 @@ msgstr "Hinzufügen und neuen erstellen"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Projekt Standardwährung: %(currency)s" msgstr "Projekt Standardwährung: %(currency)s"
msgid "Bills can't be null"
msgstr "Der Betrag darf nicht null sein"
msgid "Name" msgid "Name"
msgstr "Name" msgstr "Name"
@ -180,13 +186,28 @@ msgstr "Der Benutzer ist bereits diesem Projekt zugeordnet"
msgid "People to notify" msgid "People to notify"
msgstr "Personen, die informiert werden sollen" msgstr "Personen, die informiert werden sollen"
msgid "Send invites" msgid "Send the invitations"
msgstr "Einladungen senden" msgstr "Einladung versenden"
#, python-format #, python-format
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 "Logout"
msgstr "Ausloggen"
msgid "Please check the email configuration of the server."
msgstr ""
#, fuzzy, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Entschuldigung, es trat ein Fehler beim Versenden der Einladungsmails "
"auf. Bitte überprüfe die E-Mail Konfiguration des Servers oder "
"kontaktiere einen Administrator."
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} und {dual_object_1}" msgstr "{dual_object_0} und {dual_object_1}"
@ -214,9 +235,11 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix}:<br />{errors}" msgstr "{prefix}:<br />{errors}"
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "" msgstr ""
"Zu viele fehlgeschlagene Anmeldeversuche, bitte versuche es später nochmal." "Zu viele fehlgeschlagene Anmeldeversuche, bitte versuche es später "
"nochmal."
#, python-format #, python-format
msgid "This admin password is not the right one. Only %(num)d attempts left." msgid "This admin password is not the right one. Only %(num)d attempts left."
@ -230,12 +253,6 @@ msgstr "Bereitgestelltes Token ist ungültig"
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"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
"Du hast gerade das Projekt '%(project)s' erstellt, um deine Ausgaben zu "
"teilen"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "Dir wurde soeben eine Erinnerungsmail gesendet" msgstr "Dir wurde soeben eine Erinnerungsmail gesendet"
@ -246,14 +263,10 @@ msgstr ""
"Wir haben versucht dir eine Erinnerungsmail zu senden, aber das hat nicht" "Wir haben versucht dir eine Erinnerungsmail zu senden, aber das hat nicht"
" geklappt. Du kannst das Projekt weiterhin wie gewohnt nutzen." " geklappt. Du kannst das Projekt weiterhin wie gewohnt nutzen."
#, python-format #, fuzzy
msgid "The project identifier is %(project)s"
msgstr "Die Projektkennung ist %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"Entschuldigung, es trat ein Fehler beim Senden der E-Mail zur Passwort " "Entschuldigung, es trat ein Fehler beim Senden der E-Mail zur Passwort "
"Zurücksetzung auf. Bitte überprüfe die E-Mail Konfiguration des Servers " "Zurücksetzung auf. Bitte überprüfe die E-Mail Konfiguration des Servers "
@ -271,18 +284,25 @@ 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" msgid "Project settings have been changed successfully."
msgstr "Projekt erfolgreich hochgeladen" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "Ungültiges JSON" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
"Rechnungen in mehreren Währungen können einem Projekt ohne Standardwährung " "Rechnungen in mehreren Währungen können einem Projekt ohne "
"nicht hinzugefügt werden" "Standardwährung nicht hinzugefügt werden"
msgid "Project successfully uploaded"
msgstr "Projekt erfolgreich hochgeladen"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "Projekt erfolgreich gelöscht" msgstr "Projekt erfolgreich gelöscht"
@ -290,6 +310,9 @@ msgstr "Projekt erfolgreich gelöscht"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "Fehler bei Projektlöschung" msgstr "Fehler bei Projektlöschung"
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "Du wurdest eingeladen, deine Ausgaben für %(project)s zu teilen" msgstr "Du wurdest eingeladen, deine Ausgaben für %(project)s zu teilen"
@ -297,10 +320,8 @@ msgstr "Du wurdest eingeladen, deine Ausgaben für %(project)s zu teilen"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "Deine Einladungen wurden versendet" msgstr "Deine Einladungen wurden versendet"
msgid "" #, fuzzy
"Sorry, there was an error while trying to send the invitation emails. " msgid "Sorry, there was an error while trying to send the invitation emails."
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Entschuldigung, es trat ein Fehler beim Versenden der Einladungsmails " "Entschuldigung, es trat ein Fehler beim Versenden der Einladungsmails "
"auf. Bitte überprüfe die E-Mail Konfiguration des Servers oder " "auf. Bitte überprüfe die E-Mail Konfiguration des Servers oder "
@ -348,6 +369,10 @@ msgstr "Die Ausgabe wurde entfernt"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "Die Ausgabe wurde bearbeitet" msgstr "Die Ausgabe wurde bearbeitet"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Projekthistorie konnte nicht gelöscht werden" msgstr "Projekthistorie konnte nicht gelöscht werden"
@ -379,7 +404,7 @@ msgid "The project you are trying to access do not exist, do you want to"
msgstr "Das Projekt existiert nicht, willst du" msgstr "Das Projekt existiert nicht, willst du"
msgid "create it" msgid "create it"
msgstr "Erstellen" msgstr "es erstellen"
msgid "?" msgid "?"
msgstr "?" msgstr "?"
@ -408,8 +433,8 @@ msgstr "Aktionen"
msgid "edit" msgid "edit"
msgstr "Bearbeiten" msgstr "Bearbeiten"
msgid "delete" msgid "Delete project"
msgstr "Löschen" msgstr "Projekt löschen"
msgid "show" msgid "show"
msgstr "Zeigen" msgstr "Zeigen"
@ -423,20 +448,11 @@ msgstr "Handy-Applikation herunterladen"
msgid "Get it on" msgid "Get it on"
msgstr "Mach mit" msgstr "Mach mit"
msgid "Are you sure?"
msgstr "Bist du sicher?"
msgid "Edit project" msgid "Edit project"
msgstr "Projekt bearbeiten" msgstr "Projekt bearbeiten"
msgid "Delete project" msgid "Import project"
msgstr "Projekt löschen" msgstr "Projekt importieren"
msgid "Import JSON"
msgstr "JSON importieren"
msgid "Choose file"
msgstr "Datei auswählen"
msgid "Download project's data" msgid "Download project's data"
msgstr "Projektdaten herunterladen" msgstr "Projektdaten herunterladen"
@ -462,18 +478,28 @@ msgstr "Abbrechen"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Datenschutzeinstellungen" msgstr "Datenschutzeinstellungen"
msgid "Edit the project" msgid "Save changes"
msgstr "Projekt bearbeiten" msgstr "Änderungen speichern"
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "Dies wird alle Ausgaben und Mitglieder dieses Projektes löschen!" msgstr "Dies wird alle Ausgaben und Mitglieder dieses Projektes löschen!"
#, fuzzy
msgid "Import previously exported project"
msgstr "Zuvor exportierte JSON-Datei importieren"
msgid "Choose file"
msgstr "Datei auswählen"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Ausgabe bearbeiten" msgstr "Ausgabe bearbeiten"
msgid "Add a bill" msgid "Add a bill"
msgstr "Ausgabe hinzufügen" msgstr "Ausgabe hinzufügen"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "Jeder" msgstr "Jeder"
@ -492,9 +518,6 @@ msgstr "Diesen Benutzer bearbeiten"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "max.mustermann@beispiel.com, mary.moe@site.com" msgstr "max.mustermann@beispiel.com, mary.moe@site.com"
msgid "Send the invitations"
msgstr "Einladung versenden"
msgid "Download" msgid "Download"
msgstr "Herunterladen" msgstr "Herunterladen"
@ -567,36 +590,21 @@ msgstr "Rechnung %(name)s: %(owers_list_str)s zur Eigentümerliste hinzugefügt"
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "Rechnung %(name)s: %(owers_list_str)s von der Eigentümerliste entfernt" msgstr "Rechnung %(name)s: %(owers_list_str)s von der Eigentümerliste entfernt"
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n"
" <i>Der Verlauf dieses Projekts ist deaktiviert. Neue Aktionen" #, fuzzy
" werden nicht im Folgenden auftauchen. Du kannst den Verlauf auf der\n" msgid "You can enable history on the settings page."
"<a href=\"%(url)s\">Einstellungsseite</a> aktivieren.</i>\n" msgstr "IP-Adresserfassung kann in den Einstellungen aktiviert werden"
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n"
" <I>Die folgende Tabelle zeigt alle aufgezeichneten Aktionen " #, fuzzy
"bevor der Projektverlauf deaktiviert wurde. Du kannst den\n" msgid "You can clear the project history to remove them."
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" " msgstr "Wahrscheinlich hat jemand den Projektverlauf gelöscht."
"data-target=\"#confirm-erase\">Projektverlauf löschen</a>, um sie zu "
"entfernen.</i></p>\n"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -608,18 +616,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Gespeicherte IP-Adressen löschen" msgstr "Gespeicherte IP-Adressen löschen"
msgid "No history to erase"
msgstr "Kein Verlauf zu löschen"
msgid "Clear Project History"
msgstr "Projektverlauf löschen"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "Keine IP-Adressen zu löschen" msgstr "Keine IP-Adressen zu löschen"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Gespeicherte IP-Adressen löschen" msgstr "Gespeicherte IP-Adressen löschen"
msgid "No history to erase"
msgstr "Kein Verlauf zu löschen"
msgid "Clear Project History"
msgstr "Projektverlauf löschen"
msgid "Time" msgid "Time"
msgstr "Zeit" msgstr "Zeit"
@ -683,9 +691,15 @@ msgstr ""
"Teinehmer %(name)s: Gewichtung von %(old_weight)s auf %(new_weight)s " "Teinehmer %(name)s: Gewichtung von %(old_weight)s auf %(new_weight)s "
"geändert" "geändert"
msgid "Payer"
msgstr "Von"
msgid "Amount" msgid "Amount"
msgstr "Betrag" msgstr "Betrag"
msgid "Date"
msgstr "Datum"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Betrag in %(currency)s" msgstr "Betrag in %(currency)s"
@ -788,6 +802,9 @@ msgstr "Verlauf"
msgid "Settings" msgid "Settings"
msgstr "Einstellungen" msgstr "Einstellungen"
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "Andere Projekte:" msgstr "Andere Projekte:"
@ -797,8 +814,9 @@ msgstr "wechseln zu"
msgid "Dashboard" msgid "Dashboard"
msgstr "Dashboard" msgstr "Dashboard"
msgid "Logout" #, python-format
msgstr "Ausloggen" msgid "Please retry after %(date)s."
msgstr ""
msgid "Code" msgid "Code"
msgstr "Code" msgstr "Code"
@ -831,37 +849,31 @@ msgstr "Bist du sicher?"
msgid "Invite people" msgid "Invite people"
msgstr "Leute einladen" msgstr "Leute einladen"
msgid "You should start by adding participants"
msgstr "Du kannst anfangen, Teilnehmer hinzuzufügen"
msgid "Add a new bill"
msgstr "Neue Ausgabe"
msgid "Newer bills" msgid "Newer bills"
msgstr "Aktuellere Rechnungen" msgstr "Aktuellere Rechnungen"
msgid "Older bills" msgid "Older bills"
msgstr "Ältere Rechnungen" msgstr "Ältere Rechnungen"
msgid "When?" msgid "You should start by adding participants"
msgstr "Wann?" msgstr "Du kannst anfangen, Teilnehmer hinzuzufügen"
msgid "Who paid?" msgid "Add a new bill"
msgstr "Wer hat bezahlt?" msgstr "Neue Ausgabe"
msgid "For what?" msgid "For what?"
msgstr "Wofür?" msgstr "Wofür?"
msgid "How much?"
msgstr "Wieviel?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Hinzugefügt am %(date)s" msgstr "Hinzugefügt am %(date)s"
#, python-format #, python-format
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Jeder außer %(excluded)s" msgstr "Alle außer %(excluded)s"
msgid "delete"
msgstr "Löschen"
msgid "No bills" msgid "No bills"
msgstr "Keine Ausgaben" msgstr "Keine Ausgaben"
@ -869,14 +881,13 @@ msgstr "Keine Ausgaben"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Noch nichts aufzulisten." msgstr "Noch nichts aufzulisten."
msgid "You probably want to" #, fuzzy
msgstr "Du willst wahrscheinlich" msgid "Add your first bill"
msgid "add a bill"
msgstr "eine Ausgabe hinzufügen" msgstr "eine Ausgabe hinzufügen"
msgid "add participants" #, fuzzy
msgstr "Teilnehmer hinzufügen" msgid "Add the first participant"
msgstr "Diesen Benutzer bearbeiten"
msgid "Password reminder" msgid "Password reminder"
msgstr "Passwort-Erinnerung" msgstr "Passwort-Erinnerung"
@ -900,39 +911,56 @@ msgstr "Setze dein Passwort zurück"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Lade Leute ein, diesem Projekt beizutreten" msgstr "Lade Leute ein, diesem Projekt beizutreten"
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "Teile die ID & den Code" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
"Du kannst die Projekt-ID und den privaten Code auf jedem "
"Kommunikationsweg weitergeben."
msgid "Identifier:" msgid "Scan QR code"
msgstr "ID:" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr "Link teilen" msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "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"
#, fuzzy
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"Gib eine (durch Kommas getrennte) Liste von E-Mail-Adressen an, die du " "Gib eine (durch Kommas getrennte) Liste von E-Mail-Adressen an, die du "
"über die\n" "über die\n"
"\t\t\tErstellung dieses Projekts informieren möchtest, und wir senden " "\t\t\tErstellung dieses Projekts informieren möchtest, und wir senden "
"ihnen eine E-Mail." "ihnen eine E-Mail."
msgid "Share Identifier & code"
msgstr "Teile die ID & den Code"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr "ID:"
#, fuzzy
msgid "Private code:"
msgstr "Privater Code"
msgid "the private code was defined when you created the project"
msgstr ""
msgid "Who pays?" msgid "Who pays?"
msgstr "Wer zahlt?" msgstr "Wer zahlt?"
@ -1068,3 +1096,93 @@ msgstr "Zeitraum"
#~ msgid "Participants to notify" #~ msgid "Participants to notify"
#~ msgstr "Teilnehmer hinzufügen" #~ msgstr "Teilnehmer hinzufügen"
#~ msgid "Import"
#~ msgstr "Importieren"
#~ msgid "Amount paid"
#~ msgstr "Betrag"
#~ msgid "Bills can't be null"
#~ msgstr "Der Betrag darf nicht null sein"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "Die Projektkennung ist %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "Ungültiges JSON"
#~ msgid "Are you sure?"
#~ msgstr "Bist du sicher?"
#~ msgid "Import JSON"
#~ msgstr "JSON importieren"
#~ 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>Der Verlauf dieses Projekts "
#~ "ist deaktiviert. Neue Aktionen werden "
#~ "nicht im Folgenden auftauchen. Du kannst"
#~ " den Verlauf auf der\n"
#~ "<a href=\"%(url)s\">Einstellungsseite</a> aktivieren.</i>\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>Die folgende Tabelle zeigt "
#~ "alle aufgezeichneten Aktionen bevor der "
#~ "Projektverlauf deaktiviert wurde. Du kannst"
#~ " den\n"
#~ " <a href=\"#\" data-"
#~ "toggle=\"modal\" data-keyboard=\"false\" data-"
#~ "target=\"#confirm-erase\">Projektverlauf löschen</a>, "
#~ "um sie zu entfernen.</i></p>\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "Einladungen senden"
#~ msgid " show"
#~ msgstr "Zeigen"
#~ msgid "Edit the project"
#~ msgstr "Projekt bearbeiten"
#~ msgid "You probably want to"
#~ msgstr "Du willst wahrscheinlich"
#~ msgid "add participants"
#~ msgstr "Teilnehmer hinzufügen"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "Du kannst die Projekt-ID und den"
#~ " privaten Code auf jedem Kommunikationsweg"
#~ " weitergeben."
#~ msgid "Share the Link"
#~ msgstr "Link teilen"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr "Du kannst den folgenden Link direkt über dein bevorzugtes Medium teilen"

View file

@ -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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2021-08-01 08:34+0000\n" "PO-Revision-Date: 2021-08-01 08:34+0000\n"
"Last-Translator: Eugenia Russell <eugenia.russell2019@gmail.com>\n" "Last-Translator: Eugenia Russell <eugenia.russell2019@gmail.com>\n"
"Language: el\n" "Language: el\n"
@ -15,6 +15,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
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."
@ -23,6 +27,13 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Τίτλος εργασίας" msgstr "Τίτλος εργασίας"
#, fuzzy
msgid "Current private code"
msgstr "Ιδιωτικός κωδικός"
msgid "Enter existing private code to edit project"
msgstr ""
#, fuzzy #, fuzzy
msgid "New private code" msgid "New private code"
msgstr "Ιδιωτικός κωδικός" msgstr "Ιδιωτικός κωδικός"
@ -45,6 +56,14 @@ msgstr "Προεπιλεγμένο Νόμισμα"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
#, fuzzy
msgid "Unknown error"
msgstr "Άγνωστο πρότζεκτ"
#, fuzzy
msgid "Invalid private code."
msgstr "Ιδιωτικός κωδικός"
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
@ -52,11 +71,8 @@ msgstr ""
"Αυτό το έργο δεν μπορεί να οριστεί σε \"χωρίς νόμισμα\" επειδή περιέχει " "Αυτό το έργο δεν μπορεί να οριστεί σε \"χωρίς νόμισμα\" επειδή περιέχει "
"λογαριασμούς σε πολλαπλά νομίσματα." "λογαριασμούς σε πολλαπλά νομίσματα."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Εισαγωγή αρχείου JSON που έχει εξαχθεί προηγουμένως" msgstr ""
msgid "Import"
msgstr "Εισαγωγή"
msgid "Project identifier" msgid "Project identifier"
msgstr "Αναγνωριστικό έργου" msgstr "Αναγνωριστικό έργου"
@ -88,14 +104,6 @@ msgstr ""
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Εισαγάγετε ιδιωτικό κωδικό για επιβεβαίωση της διαγραφής" msgstr "Εισαγάγετε ιδιωτικό κωδικό για επιβεβαίωση της διαγραφής"
#, fuzzy
msgid "Unknown error"
msgstr "Άγνωστο πρότζεκτ"
#, fuzzy
msgid "Invalid private code."
msgstr "Ιδιωτικός κωδικός"
msgid "Get in" msgid "Get in"
msgstr "Συνδεθείτε" msgstr "Συνδεθείτε"
@ -120,17 +128,17 @@ msgstr "Επιβεβαίωση κωδικού πρόσβασης"
msgid "Reset password" msgid "Reset password"
msgstr "Επαναφορά κωδικού πρόσβασης" msgstr "Επαναφορά κωδικού πρόσβασης"
msgid "Date" msgid "When?"
msgstr "Ημερομηνία" msgstr ""
msgid "What?" msgid "What?"
msgstr "Τι?" msgstr "Τι?"
msgid "Payer" msgid "Who paid?"
msgstr "Φορέας πληρωμής" msgstr ""
msgid "Amount paid" msgid "How much?"
msgstr "Καταβληθέν ποσό" msgstr ""
msgid "Currency" msgid "Currency"
msgstr "Νόμισμα" msgstr "Νόμισμα"
@ -156,9 +164,6 @@ msgstr "Υποβολή και προσθήκη νέου"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Προεπιλογή έργου: %(currency)s" msgstr "Προεπιλογή έργου: %(currency)s"
msgid "Bills can't be null"
msgstr "Οι λογαριασμοί δεν μπορούν να είναι μηδενικοί"
msgid "Name" msgid "Name"
msgstr "Όνομα" msgstr "Όνομα"
@ -182,13 +187,25 @@ msgstr "Αυτό το έργο έχει ήδη αυτό το μέλος"
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "Αποστολή προσκλήσεων" msgstr "Αποστολή των προσκλήσεων"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "Το μήνυμα ηλεκτρονικού ταχυδρομείου %(email)s δεν είναι έγκυρο" msgstr "Το μήνυμα ηλεκτρονικού ταχυδρομείου %(email)s δεν είναι έγκυρο"
msgid "Logout"
msgstr ""
msgid "Please check the email configuration of the server."
msgstr ""
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "" msgstr ""
@ -216,7 +233,8 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "Πάρα πολλές αποτυχημένες προσπάθειες σύνδεσης, δοκιμάστε ξανά αργότερα." msgstr "Πάρα πολλές αποτυχημένες προσπάθειες σύνδεσης, δοκιμάστε ξανά αργότερα."
#, python-format #, python-format
@ -231,10 +249,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Αυτός ο ιδιωτικός κωδικός δεν είναι ο σωστός" msgstr "Αυτός ο ιδιωτικός κωδικός δεν είναι ο σωστός"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "Ένα εμάιλ υπενθύμισης μόλις σας στάλθηκε" msgstr "Ένα εμάιλ υπενθύμισης μόλις σας στάλθηκε"
@ -245,14 +259,9 @@ msgstr ""
"Προσπαθήσαμε να σας στείλουμε ένα εμάιλ υπενθύμισης, αλλά υπήρξε ένα " "Προσπαθήσαμε να σας στείλουμε ένα εμάιλ υπενθύμισης, αλλά υπήρξε ένα "
"λάθος. Μπορείτε ακόμα να χρησιμοποιήσετε το πρότζεκτ κανονικά." "λάθος. Μπορείτε ακόμα να χρησιμοποιήσετε το πρότζεκτ κανονικά."
#, python-format
msgid "The project identifier is %(project)s"
msgstr "Το αναγνωριστικό έργου είναι %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
msgid "No token provided" msgid "No token provided"
@ -267,23 +276,33 @@ msgstr "Άγνωστο πρότζεκτ"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "Επαναφορά του κωδικού επιτυχώς." msgstr "Επαναφορά του κωδικού επιτυχώς."
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "Έργο που φορτώθηκε επιτυχώς" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "Η JSON δεν είναι έγκυρη" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr "Έργο που φορτώθηκε επιτυχώς"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "Το πρότζεκτ διαγράφηκε επιτυχώς" msgstr "Το πρότζεκτ διαγράφηκε επιτυχώς"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "Έχετε κληθεί να μοιραστείτε τα έξοδά σας για %(project)s" msgstr "Έχετε κληθεί να μοιραστείτε τα έξοδά σας για %(project)s"
@ -291,10 +310,7 @@ msgstr "Έχετε κληθεί να μοιραστείτε τα έξοδά σα
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "Οι προσκλήσεις έχουν σταλθεί" msgstr "Οι προσκλήσεις έχουν σταλθεί"
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
#, python-format #, python-format
@ -337,6 +353,10 @@ msgstr "Ο λογαριασμός έχει διαγραφεί"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "Ο λογαριασμός έχει τροποποιηθεί" msgstr "Ο λογαριασμός έχει τροποποιηθεί"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
#, fuzzy #, fuzzy
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Ενεργοποίηση ιστορικού έργων" msgstr "Ενεργοποίηση ιστορικού έργων"
@ -403,8 +423,9 @@ msgstr "Ενέργειες"
msgid "edit" msgid "edit"
msgstr "επιμελειθήτε" msgstr "επιμελειθήτε"
msgid "delete" #, fuzzy
msgstr "διαγραφή" msgid "Delete project"
msgstr "Επεξεργασία έργου"
msgid "show" msgid "show"
msgstr "εμφάνιση" msgstr "εμφάνιση"
@ -419,23 +440,13 @@ msgstr ""
msgid "Get it on" msgid "Get it on"
msgstr "Συνδεθείτε" msgstr "Συνδεθείτε"
#, fuzzy
msgid "Are you sure?"
msgstr "Είστε σίγουρος;"
msgid "Edit project" msgid "Edit project"
msgstr "Επεξεργασία έργου" msgstr "Επεξεργασία έργου"
#, fuzzy #, fuzzy
msgid "Delete project" msgid "Import project"
msgstr "Επεξεργασία έργου" msgstr "Επεξεργασία έργου"
msgid "Import JSON"
msgstr "Εισαγωγή JSON"
msgid "Choose file"
msgstr "Επιλογή αρχείου"
msgid "Download project's data" msgid "Download project's data"
msgstr "Κατεβάστε τα δεδομένα του έργου" msgstr "Κατεβάστε τα δεδομένα του έργου"
@ -464,18 +475,28 @@ msgstr "Ακύρωση"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Ρυθμίσεις απορρήτου" msgstr "Ρυθμίσεις απορρήτου"
msgid "Edit the project" msgid "Save changes"
msgstr "Επεξεργαστείτε το έργο" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
#, fuzzy
msgid "Import previously exported project"
msgstr "Εισαγωγή αρχείου JSON που έχει εξαχθεί προηγουμένως"
msgid "Choose file"
msgstr "Επιλογή αρχείου"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Επεξεργαστείτε αυτόν τον λογαριασμό" msgstr "Επεξεργαστείτε αυτόν τον λογαριασμό"
msgid "Add a bill" msgid "Add a bill"
msgstr "Προσθήκη λογαριασμού" msgstr "Προσθήκη λογαριασμού"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr ""
@ -495,9 +516,6 @@ msgstr "Προσθήκη συμμετέχοντος"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "" msgstr ""
msgid "Send the invitations"
msgstr "Αποστολή των προσκλήσεων"
msgid "Download" msgid "Download"
msgstr "Κατεβάστε" msgstr "Κατεβάστε"
@ -563,25 +581,21 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
#, fuzzy
msgid "You can clear the project history to remove them."
msgstr "Κάποιος πιθανώς διέγραψε το ιστορικό του έργου."
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
"recording disabled. " "recording disabled. "
@ -590,18 +604,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Διαγραφή αποθηκευμένων διευθύνσεων IP" msgstr "Διαγραφή αποθηκευμένων διευθύνσεων IP"
msgid "No history to erase"
msgstr "Δεν υπάρχει ιστορία για διαγραφή"
msgid "Clear Project History"
msgstr "Απαλοιφή ιστορικού έργου"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "Δεν υπάρχουν διευθύνσεις IP προς διαγραφή" msgstr "Δεν υπάρχουν διευθύνσεις IP προς διαγραφή"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Διαγραφή αποθηκευμένων διευθύνσεων IP" msgstr "Διαγραφή αποθηκευμένων διευθύνσεων IP"
msgid "No history to erase"
msgstr "Δεν υπάρχει ιστορία για διαγραφή"
msgid "Clear Project History"
msgstr "Απαλοιφή ιστορικού έργου"
msgid "Time" msgid "Time"
msgstr "Ώρα" msgstr "Ώρα"
@ -663,9 +677,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "Φορέας πληρωμής"
msgid "Amount" msgid "Amount"
msgstr "Ποσό" msgstr "Ποσό"
msgid "Date"
msgstr "Ημερομηνία"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Ποσό σε %(currency)s" msgstr "Ποσό σε %(currency)s"
@ -766,6 +786,9 @@ msgstr ""
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "" msgstr ""
@ -775,7 +798,8 @@ msgstr ""
msgid "Dashboard" msgid "Dashboard"
msgstr "" msgstr ""
msgid "Logout" #, python-format
msgid "Please retry after %(date)s."
msgstr "" msgstr ""
msgid "Code" msgid "Code"
@ -810,30 +834,21 @@ msgstr "Είστε σίγουρος;"
msgid "Invite people" msgid "Invite people"
msgstr "" msgstr ""
msgid "You should start by adding participants"
msgstr ""
msgid "Add a new bill"
msgstr ""
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr ""
msgid "When?" msgid "You should start by adding participants"
msgstr "" msgstr ""
msgid "Who paid?" msgid "Add a new bill"
msgstr "" msgstr ""
msgid "For what?" msgid "For what?"
msgstr "" msgstr ""
msgid "How much?"
msgstr ""
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "" msgstr ""
@ -842,20 +857,21 @@ msgstr ""
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "" msgstr ""
msgid "delete"
msgstr "διαγραφή"
msgid "No bills" msgid "No bills"
msgstr "" msgstr ""
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "" msgstr ""
msgid "You probably want to" msgid "Add your first bill"
msgstr "" msgstr ""
msgid "add a bill" #, fuzzy
msgstr "" msgid "Add the first participant"
msgstr "Προσθήκη συμμετέχοντος"
msgid "add participants"
msgstr ""
msgid "Password reminder" msgid "Password reminder"
msgstr "" msgstr ""
@ -877,31 +893,49 @@ msgstr ""
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "" msgstr ""
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
msgid "Identifier:" msgid "Scan QR code"
msgstr "" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "" msgstr ""
msgid "Send via Emails" msgid "Send via Emails"
msgstr "" msgstr ""
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you." msgstr ""
msgid "Share Identifier & code"
msgstr ""
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr ""
#, fuzzy
msgid "Private code:"
msgstr "Ιδιωτικός κωδικός"
msgid "the private code was defined when you created the project"
msgstr "" msgstr ""
msgid "Who pays?" msgid "Who pays?"
@ -1017,3 +1051,112 @@ msgstr "Περίοδος"
#~ msgid "People to notify" #~ msgid "People to notify"
#~ msgstr "Πρόσωπα προς ενημέρωση" #~ msgstr "Πρόσωπα προς ενημέρωση"
#~ msgid "Import"
#~ msgstr "Εισαγωγή"
#~ msgid "Amount paid"
#~ msgstr "Καταβληθέν ποσό"
#~ msgid "Bills can't be null"
#~ msgstr "Οι λογαριασμοί δεν μπορούν να είναι μηδενικοί"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "Το αναγνωριστικό έργου είναι %(project)s"
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "sending you an email with password "
#~ "reset instructions. Please check the "
#~ "email configuration of the server or "
#~ "contact the administrator."
#~ msgstr ""
#~ msgid "Invalid JSON"
#~ msgstr "Η JSON δεν είναι έγκυρη"
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "trying to send the invitation emails."
#~ " Please check the email configuration "
#~ "of the server or contact the "
#~ "administrator."
#~ msgstr ""
#~ msgid "Are you sure?"
#~ msgstr "Είστε σίγουρος;"
#~ msgid "Import JSON"
#~ msgstr "Εισαγωγή JSON"
#~ 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 "Send invites"
#~ msgstr "Αποστολή προσκλήσεων"
#~ msgid " show"
#~ msgstr "εμφάνιση"
#~ msgid "Edit the project"
#~ msgstr "Επεξεργαστείτε το έργο"
#~ msgid "You probably want to"
#~ msgstr ""
#~ msgid "add a bill"
#~ msgstr ""
#~ msgid "add participants"
#~ msgstr ""
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ msgid "Share the Link"
#~ msgstr ""
#~ msgid "You can directly share the following link via your prefered medium"
#~ 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 ""
#~ "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 with the invitation "
#~ "link."
#~ msgstr ""

View file

@ -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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2021-10-01 20:35+0000\n" "PO-Revision-Date: 2021-10-01 20:35+0000\n"
"Last-Translator: phlostically <phlostically@mailinator.com>\n" "Last-Translator: phlostically <phlostically@mailinator.com>\n"
"Language: eo\n" "Language: eo\n"
@ -15,6 +15,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Vi ĵus kreis la projekton «%(project)s» por dividi viajn elspezojn"
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."
@ -25,6 +29,13 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Nomo de projekto" msgstr "Nomo de projekto"
#, fuzzy
msgid "Current private code"
msgstr "Nova privata kodo"
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "Nova privata kodo" msgstr "Nova privata kodo"
@ -46,6 +57,12 @@ msgstr "Implicita valuto"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
msgid "Unknown error"
msgstr "Nekonata eraro"
msgid "Invalid private code."
msgstr "Nevalida privata kodo."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
@ -53,11 +70,8 @@ msgstr ""
"Ĉi tiu projekto ne povas esti agordita al «neniu valuto», ĉar ĝi enhavas " "Ĉi tiu projekto ne povas esti agordita al «neniu valuto», ĉar ĝi enhavas "
"fakturojn en pluraj valutoj." "fakturojn en pluraj valutoj."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Importi antaŭe elportitan JSON-dosieron" msgstr ""
msgid "Import"
msgstr "Enporti"
msgid "Project identifier" msgid "Project identifier"
msgstr "Identigilo de projekto" msgstr "Identigilo de projekto"
@ -89,12 +103,6 @@ msgstr ""
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "" msgstr ""
msgid "Unknown error"
msgstr "Nekonata eraro"
msgid "Invalid private code."
msgstr "Nevalida privata kodo."
msgid "Get in" msgid "Get in"
msgstr "Eniri" msgstr "Eniri"
@ -119,17 +127,17 @@ msgstr "Konfirmo de pasvorto"
msgid "Reset password" msgid "Reset password"
msgstr "Restarigi pasvorton" msgstr "Restarigi pasvorton"
msgid "Date" msgid "When?"
msgstr "Dato" msgstr "Kiam?"
msgid "What?" msgid "What?"
msgstr "Kio?" msgstr "Kio?"
msgid "Payer" msgid "Who paid?"
msgstr "Paganto" msgstr "Kiu pagis?"
msgid "Amount paid" msgid "How much?"
msgstr "Kvanto pagita" msgstr "Kiom?"
msgid "Currency" msgid "Currency"
msgstr "Valuto" msgstr "Valuto"
@ -153,9 +161,6 @@ msgstr "Submeti kaj aldoni novan"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Implicita valuto de la projekto: %(currency)s" msgstr "Implicita valuto de la projekto: %(currency)s"
msgid "Bills can't be null"
msgstr "Fakturoj ne povas esti nulaj"
msgid "Name" msgid "Name"
msgstr "Nomo" msgstr "Nomo"
@ -179,13 +184,27 @@ msgstr "Ĉi tiu projekto jam havas ĉi tiun anon"
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "Sendi invitojn" msgstr "Sendi la invitojn"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "La retpoŝta adreso %(email)s ne validas" msgstr "La retpoŝta adreso %(email)s ne validas"
msgid "Logout"
msgstr "Adiaŭi"
msgid "Please check the email configuration of the server."
msgstr ""
#, fuzzy, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Pardonu, okazis eraro dum sendado de la invitoj. Bonvolu kontroli la "
"retpoŝtan agordon de la servilo aŭ kontakti la administranton."
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} kaj {dual_object_1}" msgstr "{dual_object_0} kaj {dual_object_1}"
@ -213,7 +232,8 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix}:<br />{errors}" msgstr "{prefix}:<br />{errors}"
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "Tro da malsukcesaj provoj de salutado; bonvolu reprovi poste." msgstr "Tro da malsukcesaj provoj de salutado; bonvolu reprovi poste."
#, python-format #, python-format
@ -226,10 +246,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Ĉi tiu privata kodo ne ĝustas" msgstr "Ĉi tiu privata kodo ne ĝustas"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Vi ĵus kreis la projekton «%(project)s» por dividi viajn elspezojn"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "Rememoriga retpoŝta mesaĝo ĵus estis sendita al vi" msgstr "Rememoriga retpoŝta mesaĝo ĵus estis sendita al vi"
@ -240,14 +256,10 @@ msgstr ""
"Ni provis sendi al vi rememorigan retpoŝtan mesaĝon, sed okazis eraro. Vi" "Ni provis sendi al vi rememorigan retpoŝtan mesaĝon, sed okazis eraro. Vi"
" ankoraŭ povas uzi la projekton normale." " ankoraŭ povas uzi la projekton normale."
#, python-format #, fuzzy
msgid "The project identifier is %(project)s"
msgstr "La identigilo de la projekto estas %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"Pardonu, okazis eraro dum sendado al vi de retpoŝta mesaĝo de instrukcioj" "Pardonu, okazis eraro dum sendado al vi de retpoŝta mesaĝo de instrukcioj"
" pri restarigo de pasvorto. Bonvolu kontroli la retpoŝtan agordon de la " " pri restarigo de pasvorto. Bonvolu kontroli la retpoŝtan agordon de la "
@ -265,23 +277,33 @@ msgstr "Nekonata projekto"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "Pasvorto sukcese restarigita." msgstr "Pasvorto sukcese restarigita."
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "Projekto sukcese alŝutita" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "Nevalida JSON" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr "Projekto sukcese alŝutita"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "La projekto estis sukcese forigitaj" msgstr "La projekto estis sukcese forigitaj"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "Vi estis invitita dividi viajn elspezojn por %(project)s" msgstr "Vi estis invitita dividi viajn elspezojn por %(project)s"
@ -289,10 +311,8 @@ msgstr "Vi estis invitita dividi viajn elspezojn por %(project)s"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "Viaj invitoj estis senditaj" msgstr "Viaj invitoj estis senditaj"
msgid "" #, fuzzy
"Sorry, there was an error while trying to send the invitation emails. " msgid "Sorry, there was an error while trying to send the invitation emails."
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Pardonu, okazis eraro dum sendado de la invitoj. Bonvolu kontroli la " "Pardonu, okazis eraro dum sendado de la invitoj. Bonvolu kontroli la "
"retpoŝtan agordon de la servilo aŭ kontakti la administranton." "retpoŝtan agordon de la servilo aŭ kontakti la administranton."
@ -339,6 +359,10 @@ msgstr "La fakturo estis forigita"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "La fakturo estis modifita" msgstr "La fakturo estis modifita"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
#, fuzzy #, fuzzy
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Ŝalti projektan historion" msgstr "Ŝalti projektan historion"
@ -404,8 +428,8 @@ msgstr "Agoj"
msgid "edit" msgid "edit"
msgstr "redakti" msgstr "redakti"
msgid "delete" msgid "Delete project"
msgstr "forigi" msgstr "Forviŝi projekton"
msgid "show" msgid "show"
msgstr "montri" msgstr "montri"
@ -419,20 +443,12 @@ msgstr "Elŝuti programon por poŝaparato"
msgid "Get it on" msgid "Get it on"
msgstr "Elŝuti ĝin ĉe" msgstr "Elŝuti ĝin ĉe"
msgid "Are you sure?"
msgstr "Ĉu vi certas?"
msgid "Edit project" msgid "Edit project"
msgstr "Redakti projekton" msgstr "Redakti projekton"
msgid "Delete project" #, fuzzy
msgstr "Forviŝi projekton" msgid "Import project"
msgstr "Redakti projekton"
msgid "Import JSON"
msgstr "Enporti JSON-dosieron"
msgid "Choose file"
msgstr "Elekti dosieron"
msgid "Download project's data" msgid "Download project's data"
msgstr "Elŝuti projektajn datenojn" msgstr "Elŝuti projektajn datenojn"
@ -458,18 +474,28 @@ msgstr "Nuligi"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Agordoj pri privateco" msgstr "Agordoj pri privateco"
msgid "Edit the project" msgid "Save changes"
msgstr "Redakti la projekton" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
#, fuzzy
msgid "Import previously exported project"
msgstr "Importi antaŭe elportitan JSON-dosieron"
msgid "Choose file"
msgstr "Elekti dosieron"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Redakti ĉi tiun fakturon" msgstr "Redakti ĉi tiun fakturon"
msgid "Add a bill" msgid "Add a bill"
msgstr "Aldoni fakturon" msgstr "Aldoni fakturon"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "Ĉiuj" msgstr "Ĉiuj"
@ -489,9 +515,6 @@ msgstr "Aldono partoprenanton"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "johano.zamenhof@example.com, maria.baghy@example.net" msgstr "johano.zamenhof@example.com, maria.baghy@example.net"
msgid "Send the invitations"
msgstr "Sendi la invitojn"
msgid "Download" msgid "Download"
msgstr "Elŝuti" msgstr "Elŝuti"
@ -563,36 +586,21 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n"
" <i>Historio estis malŝaltita por ĉi tiu projekto. Novaj agoj " #, fuzzy
"ne aperos ĉi-sube. Vi povas ŝalti historion ĉe la</i>\n" msgid "You can enable history on the settings page."
" <a href=\"%(url)s\">paĝo pri agordoj</a>\n" msgstr "Registrado de IP-adresoj estas ŝaltebla per la agorda paĝo"
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n"
" <i>La ĉi-suba tabelo montras agojn registritajn antaŭ " #, fuzzy
"malŝalto de la projekta historio. Vi povas\n" msgid "You can clear the project history to remove them."
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" " msgstr "Iu verŝajne forviŝis la historion de la projekto."
"data-target=\"#confirm-erase\">forviŝi la projektan historion</a> por "
"forigi ilin.</i></ p >\n"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -604,18 +612,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Forviŝi konservitajn IP-adresojn" msgstr "Forviŝi konservitajn IP-adresojn"
msgid "No history to erase"
msgstr "Neniom da forviŝebla historio"
msgid "Clear Project History"
msgstr "Forviŝi historion de projekto"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "Neniom da forviŝeblaj IP-adresoj" msgstr "Neniom da forviŝeblaj IP-adresoj"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Forviŝi konservitajn IP-adresojn" msgstr "Forviŝi konservitajn IP-adresojn"
msgid "No history to erase"
msgstr "Neniom da forviŝebla historio"
msgid "Clear Project History"
msgstr "Forviŝi historion de projekto"
msgid "Time" msgid "Time"
msgstr "Tempo" msgstr "Tempo"
@ -677,9 +685,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "Paganto"
msgid "Amount" msgid "Amount"
msgstr "Kvanto" msgstr "Kvanto"
msgid "Date"
msgstr "Dato"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Kvanto en %(currency)s" msgstr "Kvanto en %(currency)s"
@ -782,6 +796,9 @@ msgstr "Historio"
msgid "Settings" msgid "Settings"
msgstr "Agordoj" msgstr "Agordoj"
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "Aliaj projektoj:" msgstr "Aliaj projektoj:"
@ -791,8 +808,9 @@ msgstr "salti al"
msgid "Dashboard" msgid "Dashboard"
msgstr "Panelo" msgstr "Panelo"
msgid "Logout" #, python-format
msgstr "Adiaŭi" msgid "Please retry after %(date)s."
msgstr ""
msgid "Code" msgid "Code"
msgstr "Kodo" msgstr "Kodo"
@ -826,30 +844,21 @@ msgstr "ĉu vi certas?"
msgid "Invite people" msgid "Invite people"
msgstr "Inviti homojn" msgstr "Inviti homojn"
msgid "You should start by adding participants"
msgstr "Vi komencu aldonante partoprenantojn"
msgid "Add a new bill"
msgstr "Aldoni novan fakturon"
msgid "Newer bills" msgid "Newer bills"
msgstr "Pli novaj fakturoj" msgstr "Pli novaj fakturoj"
msgid "Older bills" msgid "Older bills"
msgstr "Pli malnovaj fakturoj" msgstr "Pli malnovaj fakturoj"
msgid "When?" msgid "You should start by adding participants"
msgstr "Kiam?" msgstr "Vi komencu aldonante partoprenantojn"
msgid "Who paid?" msgid "Add a new bill"
msgstr "Kiu pagis?" msgstr "Aldoni novan fakturon"
msgid "For what?" msgid "For what?"
msgstr "Por kio?" msgstr "Por kio?"
msgid "How much?"
msgstr "Kiom?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Aldonita en %(date)s" msgstr "Aldonita en %(date)s"
@ -858,20 +867,22 @@ msgstr "Aldonita en %(date)s"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Ĉiuj krom %(excluded)s" msgstr "Ĉiuj krom %(excluded)s"
msgid "delete"
msgstr "forigi"
msgid "No bills" msgid "No bills"
msgstr "Neniu fakturo" msgstr "Neniu fakturo"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Nenio listigebla ankoraŭ." msgstr "Nenio listigebla ankoraŭ."
msgid "You probably want to" #, fuzzy
msgstr "Vi probable volas" msgid "Add your first bill"
msgid "add a bill"
msgstr "aldoni fakturon" msgstr "aldoni fakturon"
msgid "add participants" #, fuzzy
msgstr "aldoni partoprenantojn" msgid "Add the first participant"
msgstr "Aldono partoprenanton"
msgid "Password reminder" msgid "Password reminder"
msgstr "Rememorigilo pri pasvorto" msgstr "Rememorigilo pri pasvorto"
@ -895,37 +906,56 @@ msgstr "Restarigi vian pasvorton"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Inviti homojn aliĝi al ĉi tiu projekto" msgstr "Inviti homojn aliĝi al ĉi tiu projekto"
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "Konigi identigilon kaj kodon" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
msgstr "Vi povas iel ajn konigi la projektan identigilon kaj la privatan kodon." " add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr ""
msgid "Identifier:" msgid "Scan QR code"
msgstr "Identigilo:" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr "Sendi la ligon" msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "Vi povas rekte sendi la jenan hiperligon per via preferata komunikilo"
msgid "Send via Emails" msgid "Send via Emails"
msgstr "Sendi retpoŝte" msgstr "Sendi retpoŝte"
#, fuzzy
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"Specifu (kome apartigitan) liston de tiuj retpoŝtaj adresoj, kiujn vi " "Specifu (kome apartigitan) liston de tiuj retpoŝtaj adresoj, kiujn vi "
"volas sciigi pri la\n" "volas sciigi pri la\n"
" kreado de ĉi tiu buĝet-administra projekto, kaj ni sendos" " kreado de ĉi tiu buĝet-administra projekto, kaj ni sendos"
" al ili retpoŝtajn mesaĝojn por vi." " al ili retpoŝtajn mesaĝojn por vi."
msgid "Share Identifier & code"
msgstr "Konigi identigilon kaj kodon"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr "Identigilo:"
#, fuzzy
msgid "Private code:"
msgstr "Privata kodo"
msgid "the private code was defined when you created the project"
msgstr ""
msgid "Who pays?" msgid "Who pays?"
msgstr "Kiu pagas?" msgstr "Kiu pagas?"
@ -1021,3 +1051,91 @@ msgstr "Periodo"
#~ msgid "People to notify" #~ msgid "People to notify"
#~ msgstr "Sciigotaj homoj" #~ msgstr "Sciigotaj homoj"
#~ msgid "Import"
#~ msgstr "Enporti"
#~ msgid "Amount paid"
#~ msgstr "Kvanto pagita"
#~ msgid "Bills can't be null"
#~ msgstr "Fakturoj ne povas esti nulaj"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "La identigilo de la projekto estas %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "Nevalida JSON"
#~ msgid "Are you sure?"
#~ msgstr "Ĉu vi certas?"
#~ msgid "Import JSON"
#~ msgstr "Enporti JSON-dosieron"
#~ 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>Historio estis malŝaltita por"
#~ " ĉi tiu projekto. Novaj agoj ne "
#~ "aperos ĉi-sube. Vi povas ŝalti "
#~ "historion ĉe la</i>\n"
#~ " <a href=\"%(url)s\">paĝo pri agordoj</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>La ĉi-suba tabelo montras"
#~ " agojn registritajn antaŭ malŝalto de "
#~ "la projekta historio. Vi povas\n"
#~ " <a href=\"#\" data-"
#~ "toggle=\"modal\" data-keyboard=\"false\" data-"
#~ "target=\"#confirm-erase\">forviŝi la projektan "
#~ "historion</a> por forigi ilin.</i></ p >"
#~ "\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "Sendi invitojn"
#~ msgid " show"
#~ msgstr "montri"
#~ msgid "Edit the project"
#~ msgstr "Redakti la projekton"
#~ msgid "You probably want to"
#~ msgstr "Vi probable volas"
#~ msgid "add participants"
#~ msgstr "aldoni partoprenantojn"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr "Vi povas iel ajn konigi la projektan identigilon kaj la privatan kodon."
#~ msgid "Share the Link"
#~ msgstr "Sendi la ligon"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr "Vi povas rekte sendi la jenan hiperligon per via preferata komunikilo"

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,9 @@ 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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2022-04-11 17:12+0000\n" "PO-Revision-Date: 2023-11-27 05:02+0000\n"
"Last-Translator: Santiago José Gutiérrez Llanos <gutierrezapata17@gmail.com>" "Last-Translator: Wilfredo Gomez <thepageguy@mailfence.com>\n"
"\n"
"Language-Team: Spanish (Latin America) <https://hosted.weblate.org/projects/" "Language-Team: Spanish (Latin America) <https://hosted.weblate.org/projects/"
"i-hate-money/i-hate-money/es_419/>\n" "i-hate-money/i-hate-money/es_419/>\n"
"Language: es_419\n" "Language: es_419\n"
@ -13,9 +12,13 @@ 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 4.12-dev\n" "X-Generator: Weblate 5.2.1-rc\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Acabas de crear '%(project)s' para compartir tus gastos"
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."
@ -26,11 +29,17 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Nombre del Proyecto" msgstr "Nombre del Proyecto"
msgid "Current private code"
msgstr "código privado actual"
msgid "Enter existing private code to edit project"
msgstr "Ingrese el código privado existente para editar el proyecto"
msgid "New private code" msgid "New private code"
msgstr "Nuevo código privado" msgstr "Nuevo Código privado"
msgid "Enter a new code if you want to change it" msgid "Enter a new code if you want to change it"
msgstr "Entra un nuevo código si tu quieres cambiarlo" msgstr "Introduce un nuevo código si quieres cambiarlo"
msgid "Email" msgid "Email"
msgstr "Correo Electrónico" msgstr "Correo Electrónico"
@ -39,28 +48,31 @@ msgid "Enable project history"
msgstr "Habilitar historial del proyecto" msgstr "Habilitar historial del proyecto"
msgid "Use IP tracking for project history" msgid "Use IP tracking for project history"
msgstr "Registrar la IPs para el historial del proyecto" msgstr "Utilice el seguimiento de IP para el historial del proyecto"
msgid "Default Currency" msgid "Default Currency"
msgstr "Moneda por defecto" msgstr "Moneda por defecto"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
"Establecer una moneda predeterminada permite la conversión de divisas entre " "Establecer una moneda predeterminada permite la conversión de moneda entre "
"facturas" "billetes"
msgid "Unknown error"
msgstr "Error desconocido"
msgid "Invalid private code."
msgstr "Código privado no válido."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
"Este proyecto no se puede establecer en 'ninguna moneda' porque contiene " "Este proyecto no se puede configurar como \"sin moneda\" porque contiene "
"facturas en varias monedas." "billetes en varias monedas."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Importar archivo JSON previamente exportado" msgstr "Compatible con Cospend"
msgid "Import"
msgstr "Importar"
msgid "Project identifier" msgid "Project identifier"
msgstr "Identificador de proyecto" msgstr "Identificador de proyecto"
@ -80,22 +92,16 @@ msgstr ""
"favor, elija un nuevo identificador" "favor, elija un nuevo identificador"
msgid "Which is a real currency: Euro or Petro dollar?" msgid "Which is a real currency: Euro or Petro dollar?"
msgstr "¿Cuál es una moneda real: euro o petro dólar?" msgstr "¿Cuál es la moneda real: el euro o el petrodólar?"
msgid "euro" msgid "euro"
msgstr "Euro" msgstr "euro"
msgid "Please, validate the captcha to proceed." msgid "Please, validate the captcha to proceed."
msgstr "Por favor, completa el captcha para seguir." msgstr "Por favor, valide la captcha para proceder."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Introduzca el código privado para confirmar la eliminación" msgstr "Ingrese el código privado para confirmar la eliminación"
msgid "Unknown error"
msgstr "Error desconocido"
msgid "Invalid private code."
msgstr "Código privado inválido."
msgid "Get in" msgid "Get in"
msgstr "Entrar" msgstr "Entrar"
@ -116,22 +122,22 @@ msgid "Password"
msgstr "Contraseña" msgstr "Contraseña"
msgid "Password confirmation" msgid "Password confirmation"
msgstr "Confirmar contraseña" msgstr "confirmación de contraseña"
msgid "Reset password" msgid "Reset password"
msgstr "Restablecer contraseña" msgstr "Restablecer contraseña"
msgid "Date" msgid "When?"
msgstr "Fecha" msgstr "¿Cuando?"
msgid "What?" msgid "What?"
msgstr "¿Qué?" msgstr "¿Qué?"
msgid "Payer" msgid "Who paid?"
msgstr "Paga" msgstr "¿Quién pagó?"
msgid "Amount paid" msgid "How much?"
msgstr "Cantidad pagada" msgstr "¿Cuánto?"
msgid "Currency" msgid "Currency"
msgstr "Moneda" msgstr "Moneda"
@ -153,10 +159,7 @@ msgstr "Enviar y agregar uno nuevo"
#, python-format #, python-format
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "moneda predeterminada del projecto: %(currency)s" msgstr "Projecto por defecto: %(currency)s"
msgid "Bills can't be null"
msgstr "Las facturas no pueden ser nulas"
msgid "Name" msgid "Name"
msgstr "Nombre" msgstr "Nombre"
@ -179,13 +182,28 @@ msgstr "Este proyecto ya tiene a este participante"
msgid "People to notify" msgid "People to notify"
msgstr "Personas para notificar" msgstr "Personas para notificar"
msgid "Send invites" msgid "Send the invitations"
msgstr "Enviar invitaciones" msgstr "Enviar las invitaciones"
#, python-format #, python-format
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 "Logout"
msgstr "Cerrar sesión"
msgid "Please check the email configuration of the server."
msgstr ""
"Por favor verifique la configuración de correo electrónico del servidor."
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Verifique la configuración de correo electrónico del servidor o comuníquese "
"con el administrador: %(admin_email)s"
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} y {dual_object_1}" msgstr "{dual_object_0} y {dual_object_1}"
@ -203,60 +221,47 @@ msgid "{start_object}, {next_object}"
msgstr "{start_object}, {next_object}" msgstr "{start_object}, {next_object}"
msgid "No Currency" msgid "No Currency"
msgstr "no moneda" msgstr "No Moneda"
#. Form error with only one error #. Form error with only one error
msgid "{prefix}: {error}" msgid "{prefix}: {error}"
msgstr "{prefijo}: {error}" msgstr "{prefix}: {error}"
#. Form error with a list of errors #. Form error with a list of errors
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefijo}:<br />{errores}" msgstr "{prefix}:<br />{errors}"
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "" msgstr "Demasiados intentos fallidos de inicio de sesión."
"Demasiados intentos fallidos de inicio de sesión, vuelva a intentarlo más"
" tarde."
#, python-format #, python-format
msgid "This admin password is not the right one. Only %(num)d attempts left." msgid "This admin password is not the right one. Only %(num)d attempts left."
msgstr "" msgstr ""
"Esta contraseña de administrador no es la correcta. Solo quedan %(num)d " "Esta contraseña de administrador no es la correcta. Solo quedan %(num)d "
"intentos." "intentos restantes."
msgid "Provided token is invalid" msgid "Provided token is invalid"
msgstr "La muestra proporcionada no es válida" msgstr "El token proporcionado no es válido"
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Este código privado no es el correcto" msgstr "Este código privado no es el correcto"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Acabas de crear '%(project)s' para compartir tus gastos"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "Acabamos de enviarte un email de recordatorio" msgstr "Se le acaba de enviar un correo electrónico de recordatorio"
msgid "" msgid ""
"We tried to send you an reminder email, but there was an error. You can " "We tried to send you an reminder email, but there was an error. You can "
"still use the project normally." "still use the project normally."
msgstr "" msgstr ""
"Te hemos intentado enviar un correo electrónico recordatorio pero ha " "Intentamos enviarte un correo electrónico de recordatorio, pero hubo un "
"habido un error. Todavía puedes usar el proyecto habitualmente." "error. Aún puedes usar el proyecto normalmente."
#, python-format
msgid "The project identifier is %(project)s"
msgstr "El identificador del proyecto es %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"Lo sentimos, hubo un error al enviarle un correo electrónico con las " "Lo sentimos, hubo un error al enviarle un correo electrónico con "
"instrucciones de restablecimiento de contraseña. Compruebe la configuración " "instrucciones para restablecer la contraseña."
"de correo electrónico del servidor o póngase en contacto con el "
"administrador."
msgid "No token provided" msgid "No token provided"
msgstr "No se proporciono ningún token" msgstr "No se proporciono ningún token"
@ -270,24 +275,34 @@ 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" msgid "Project settings have been changed successfully."
msgstr "El proyecto se subió exitosamente" msgstr "La configuración del proyecto se ha cambiado correctamente."
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "JSON inválido" msgstr "No se puede analizar CSV"
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "Atributo faltante: %(attribute)s"
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
"No se pueden agregar facturas en varias monedas a un proyecto sin la moneda " "No se pueden agregar billetes en varias monedas a un proyecto sin moneda "
"predeterminada" "predeterminada"
msgid "Project successfully uploaded"
msgstr "Proyecto cargado exitosamente"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "Proyecto eliminado correctamente" msgstr "Proyecto eliminado correctamente"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "Error al borrar poryecto" msgstr "Error al borrar proyecto"
msgid "Unable to logout"
msgstr "No se puede cerrar sesión"
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
@ -296,36 +311,32 @@ msgstr "Usted ha sido invitado a compartir sus gastos para %(project)s"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "Sus invitaciones han sido enviadas" msgstr "Sus invitaciones han sido enviadas"
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Lo sentimos, hubo un error cuando intentamos enviarle correos de " "Lo sentimos, hubo un error al intentar enviar los correos electrónicos de "
"invitación. Por favor, revise la configuración de correo en el servidor o" "invitación."
" contactese con el administrador."
#, python-format #, python-format
msgid "%(member)s has been added" msgid "%(member)s has been added"
msgstr "Se añadieron %(member)s" msgstr "%(member)s ha sido añadido"
msgid "Error activating participant" msgid "Error activating participant"
msgstr "Error activando participante" msgstr "Error al activar el participante"
#, python-format #, python-format
msgid "%(name)s is part of this project again" msgid "%(name)s is part of this project again"
msgstr "%(name)s es parte de este nuevo proyecto" msgstr "%(name)s es parte de este proyecto otra vez"
msgid "Error removing participant" msgid "Error removing participant"
msgstr "Error eliminando participante" msgstr "Error al eliminar el participante"
#, python-format #, python-format
msgid "" msgid ""
"Participant '%(name)s' has been deactivated. It will still appear in the " "Participant '%(name)s' has been deactivated. It will still appear in the "
"list until its balance reach zero." "list until its balance reach zero."
msgstr "" msgstr ""
"El participante '%(name)s' ha sido desactivado. Seguirá apareciendo en la " "El participante '%(name)s' ha sido desactivado. Seguirá apareciendo en la"
"lista hasta que su saldo llegue a cero." " lista hasta que su saldo llegue a cero."
#, python-format #, python-format
msgid "Participant '%(name)s' has been removed" msgid "Participant '%(name)s' has been removed"
@ -339,7 +350,7 @@ msgid "The bill has been added"
msgstr "La factura ha sido agregada" msgstr "La factura ha sido agregada"
msgid "Error deleting bill" msgid "Error deleting bill"
msgstr "Error eliminando factura" msgstr "Error al eliminar la factura"
msgid "The bill has been deleted" msgid "The bill has been deleted"
msgstr "La factura ha sido eliminada" msgstr "La factura ha sido eliminada"
@ -347,6 +358,10 @@ msgstr "La factura ha sido eliminada"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "La factura ha sido modificada" msgstr "La factura ha sido modificada"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr "%(lang)s no es un idioma admitido"
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Error al eliminar el historial del proyecto" msgstr "Error al eliminar el historial del proyecto"
@ -407,8 +422,8 @@ msgstr "Acciones"
msgid "edit" msgid "edit"
msgstr "Editar" msgstr "Editar"
msgid "delete" msgid "Delete project"
msgstr "Eliminar" msgstr "Borrar proyecto"
msgid "show" msgid "show"
msgstr "enseñar" msgstr "enseñar"
@ -422,20 +437,11 @@ msgstr "Instalar aplicación móvil"
msgid "Get it on" msgid "Get it on"
msgstr "Conseguir en" msgstr "Conseguir en"
msgid "Are you sure?"
msgstr "¿Estás segura?"
msgid "Edit project" msgid "Edit project"
msgstr "Editar proyecto" msgstr "Editar proyecto"
msgid "Delete project" msgid "Import project"
msgstr "Borrar proyecto" msgstr "Importar 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"
@ -463,18 +469,27 @@ msgstr "Cancelar"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Ajustes de privacidad" msgstr "Ajustes de privacidad"
msgid "Edit the project" msgid "Save changes"
msgstr "Editar el proyecto" msgstr "Guardar cambios"
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "Esto va a remover todas las facturas y participantes en este proyecto!" msgstr "Esto va a remover todas las facturas y participantes en este proyecto!"
msgid "Import previously exported project"
msgstr "Importar proyecto previamente exportado"
msgid "Choose file"
msgstr "Escoger un archivo"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Editar esta factura" msgstr "Editar esta factura"
msgid "Add a bill" msgid "Add a bill"
msgstr "Agregar una factura" msgstr "Agregar una factura"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr "Se permiten operaciones simples, e.j. (18+36.2)/3"
msgid "Everyone" msgid "Everyone"
msgstr "Todos" msgstr "Todos"
@ -493,20 +508,17 @@ msgstr "Editar este participante"
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 "john.doe@example.com, mary.moe@site.com"
msgid "Send the invitations"
msgstr "Enviar las invitaciones"
msgid "Download" msgid "Download"
msgstr "Descargar" msgstr "Descargar"
msgid "Disabled Project History" msgid "Disabled Project History"
msgstr "Historial de proyecto activo" msgstr "Historial de proyectos deshabilitado"
msgid "Disabled Project History & IP Address Recording" msgid "Disabled Project History & IP Address Recording"
msgstr "Historial de proyecto y registros de dirección IP inactivos" msgstr "Historial de proyecto y registros de dirección IP inactivos"
msgid "Enabled Project History" msgid "Enabled Project History"
msgstr "Historial de proyecto activo" msgstr "Historial de proyectos habilitado"
msgid "Disabled IP Address Recording" msgid "Disabled IP Address Recording"
msgstr "Registro de direcciones IP activo" msgstr "Registro de direcciones IP activo"
@ -522,8 +534,7 @@ msgstr "Se cambiaron los ajustes del historial"
#, python-format #, python-format
msgid "Bill %(name)s: %(property_name)s changed from %(before)s to %(after)s" msgid "Bill %(name)s: %(property_name)s changed from %(before)s to %(after)s"
msgstr "" msgstr "Factura %(name)s: %(property_name)s ha cambiado de %(before)s a %(after)s"
"Factura %(name)s: %(property_name)s ha cambiado de %(before)s a %(after)s"
#, python-format #, python-format
msgid "Bill %(name)s: %(property_name)s changed to %(after)s" msgid "Bill %(name)s: %(property_name)s changed to %(after)s"
@ -567,37 +578,23 @@ msgstr "Factura%(name)s: añadida %(owers_list_str)s a la lista de dueños"
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "Factura %(name)s: removida %(owers_list_str)s de la lista de dueños" msgstr "Factura %(name)s: removida %(owers_list_str)s de la lista de dueños"
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n" "Este proyecto tiene el historial deshabilitado. Las nuevas acciones no "
" <i>El historial de este proyecto ha sido desactivado. Nuevas " "aparecerán a continuación."
"operaciones no apareceran a continuacion. El historial se puede "
"agregar</i> \n" msgid "You can enable history on the settings page."
" <a href=\"%(url)s\">en la página de ajustes</a>\n" msgstr "Puede habilitar el historial en la página de configuración."
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n" "La siguiente tabla refleja las acciones registradas antes de deshabilitar el "
" <i>Este registro muestra la actividad previa a la " "historial del proyecto."
"desactivación del historial del proyecto. Use la opción \n"
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" " msgid "You can clear the project history to remove them."
"data-target=\"#confirm-erase\">Eliminar historial del proyecto</a> para " msgstr "Puede borrar el historial del proyecto para eliminarlos."
"borrarlo.</i></p>\n"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -609,18 +606,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Borrar las direcciones IP registradas" 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" msgid "No IP Addresses to erase"
msgstr "No hay direcciones IP para borrar" msgstr "No hay direcciones IP para borrar"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Borrar direcciones IP registradas" msgstr "Borrar 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 "Time" msgid "Time"
msgstr "Hora" msgstr "Hora"
@ -682,9 +679,15 @@ msgstr "Factura %(name)s renombrada a %(new_description)s"
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "Participante %(name)s: peso cambiado de %(old_weight)s a %(new_weight)s" msgstr "Participante %(name)s: peso cambiado de %(old_weight)s a %(new_weight)s"
msgid "Payer"
msgstr "Paga"
msgid "Amount" msgid "Amount"
msgstr "Cantidad" msgstr "Cantidad"
msgid "Date"
msgstr "Fecha"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Cantidad en %(currency)s" msgstr "Cantidad en %(currency)s"
@ -757,8 +760,8 @@ msgid ""
"Don\\'t reuse a personal password. Choose a private code and send it to " "Don\\'t reuse a personal password. Choose a private code and send it to "
"your friends" "your friends"
msgstr "" msgstr ""
"No reutilice una contraseña personal. Elija un código privado y envíelo a " "No reutilice una contraseña personal. Elija un código privado y envíelo a"
"sus amigos" " sus amigos"
msgid "Account manager" msgid "Account manager"
msgstr "Gestor de cuentas" msgstr "Gestor de cuentas"
@ -787,6 +790,9 @@ msgstr "Historial"
msgid "Settings" msgid "Settings"
msgstr "Configuración" msgstr "Configuración"
msgid "RSS Feed"
msgstr "rss Feed"
msgid "Other projects :" msgid "Other projects :"
msgstr "Otros proyectos :" msgstr "Otros proyectos :"
@ -796,8 +802,9 @@ msgstr "cambiar a"
msgid "Dashboard" msgid "Dashboard"
msgstr "Tablero" msgstr "Tablero"
msgid "Logout" #, python-format
msgstr "Cerrar sesión" msgid "Please retry after %(date)s."
msgstr "Vuelva a intentarlo después de %(date)s."
msgid "Code" msgid "Code"
msgstr "Código" msgstr "Código"
@ -830,30 +837,21 @@ msgstr "¿Estás seguro?"
msgid "Invite people" msgid "Invite people"
msgstr "Invitar personas" msgstr "Invitar personas"
msgid "You should start by adding participants"
msgstr "Deberías comenzar agregando participantes"
msgid "Add a new bill"
msgstr "Añadir una nueva factura"
msgid "Newer bills" msgid "Newer bills"
msgstr "Nuevas facturas" msgstr "Nuevas facturas"
msgid "Older bills" msgid "Older bills"
msgstr "Facturas anteriores" msgstr "Facturas anteriores"
msgid "When?" msgid "You should start by adding participants"
msgstr "¿Cuando?" msgstr "Deberías comenzar agregando participantes"
msgid "Who paid?" msgid "Add a new bill"
msgstr "¿Quién pagó?" msgstr "Añadir una nueva factura"
msgid "For what?" msgid "For what?"
msgstr "¿Para qué?" msgstr "¿Para qué?"
msgid "How much?"
msgstr "¿Cuánto?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Agregado el %(date)s" msgstr "Agregado el %(date)s"
@ -862,20 +860,20 @@ msgstr "Agregado el %(date)s"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Todo el mundo menos %(excluded)s" msgstr "Todo el mundo menos %(excluded)s"
msgid "delete"
msgstr "Eliminar"
msgid "No bills" msgid "No bills"
msgstr "Sin facturas" msgstr "Sin facturas"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Aún no hay nada que listar." msgstr "Aún no hay nada que listar."
msgid "You probably want to" msgid "Add your first bill"
msgstr "Probablemente quieras" msgstr "Añade tu primera factura"
msgid "add a bill" msgid "Add the first participant"
msgstr "agregar una factura" msgstr "Agregar el primer participante"
msgid "add participants"
msgstr "agregar participantes"
msgid "Password reminder" msgid "Password reminder"
msgstr "Recordar contraseña" msgstr "Recordar contraseña"
@ -899,40 +897,62 @@ msgstr "Restablecer su contraseña"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Invita a personas a unirse a este proyecto" msgstr "Invita a personas a unirse a este proyecto"
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "Compartir identificador y código" msgstr "Compartir un enlace de invitación"
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
"Puede compartir el identificador del proyecto y el código privado por " "La forma más sencilla de invitar personas es dándoles el siguiente enlace de "
"cualquier medio de comunicación." "invitación.<br />Podrán acceder al proyecto, administrar participantes, "
"agregar/editar/eliminar facturas. Sin embargo, no tendrán acceso a "
"configuraciones importantes como cambiar el código privado o eliminar todo "
"el proyecto."
msgid "Identifier:" msgid "Scan QR code"
msgstr "Identificador:" msgstr "Escanear código QR"
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr "Comparte el enlace" msgstr "Utilice un dispositivo móvil con una aplicación compatible."
msgid "You can directly share the following link via your prefered medium"
msgstr ""
"Puedes compartir directamente el siguiente enlace a través de tu medio "
"preferido"
msgid "Send via Emails" msgid "Send via Emails"
msgstr "Enviar por correo electrónico" msgstr "Enviar por correo electrónico"
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"Especifique una lista (separada por comas) de las direcciones de correo " "Especifique una lista de direcciones de correo electrónico (separadas por "
"electrónico a las que desea notificar acerca de la\n" "comas) de las personas a las que desea notificar sobre la creación de este "
"creación de este proyecto de gestión presupuestaria y les enviaremos un " "proyecto. Les enviaremos un correo electrónico con el enlace de invitación."
"correo electrónico para usted."
msgid "Share Identifier & code"
msgstr "Compartir identificador y código"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
"Puede compartir el identificador del proyecto y el código privado por "
"cualquier medio de comunicación.<br />Cualquier persona con el código "
"privado tendrá acceso al proyecto completo, incluido el cambio de "
"configuraciones como el código privado o la dirección de correo electrónico "
"del proyecto, o incluso la eliminación completa. proyecto."
msgid "Identifier:"
msgstr "Identificador:"
msgid "Private code:"
msgstr "Código privado:"
msgid "the private code was defined when you created the project"
msgstr "el código privado se definió cuando creaste el proyecto"
msgid "Who pays?" msgid "Who pays?"
msgstr "¿Quién paga?" msgstr "¿Quién paga?"
@ -1052,3 +1072,96 @@ msgstr "Período"
#~ msgid "People to notify" #~ msgid "People to notify"
#~ msgstr "Personas a notificar" #~ msgstr "Personas a notificar"
#~ msgid "Import"
#~ msgstr "Importar"
#~ msgid "Amount paid"
#~ msgstr "Cantidad pagada"
#~ msgid "Bills can't be null"
#~ msgstr "Las facturas no pueden ser nulas"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "El identificador del proyecto es %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "JSON inválido"
#~ msgid "Are you sure?"
#~ msgstr "¿Estás segura?"
#~ msgid "Import JSON"
#~ msgstr "Importar JSON"
#~ 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 "Send invites"
#~ msgstr "Enviar invitaciones"
#~ msgid " show"
#~ msgstr "enseñar"
#~ msgid "Edit the project"
#~ msgstr "Editar el proyecto"
#~ msgid "You probably want to"
#~ msgstr "Probablemente quieras"
#~ msgid "add participants"
#~ msgstr "agregar participantes"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "Puede compartir el identificador del "
#~ "proyecto y el código privado por "
#~ "cualquier medio de comunicación."
#~ msgid "Share the Link"
#~ msgstr "Comparte el enlace"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr ""
#~ "Puedes compartir directamente el siguiente "
#~ "enlace a través de tu medio "
#~ "preferido"

View file

@ -3,177 +3,199 @@ 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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: 2023-03-19 21:40+0000\n"
"Last-Translator: Automatically generated\n" "Last-Translator: Sai Mohammad-Hossein Emami <emami@outlook.com>\n"
"Language: fa\n" "Language: fa\n"
"Language-Team: none\n" "Language-Team: Persian <https://hosted.weblate.org/projects/i-hate-"
"money/i-hate-money/fa/>\n"
"Plural-Forms: nplurals=1; plural=0\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"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
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 "مقدار یا عبارت نامعتبر. فقط اعداد و عملیات‌های + - * / مجاز هستند."
msgid "Project name" msgid "Project name"
msgstr "نام پروژه"
#, fuzzy
msgid "Current private code"
msgstr "کد خصوصی جدید"
msgid "Enter existing private code to edit project"
msgstr "" msgstr ""
msgid "New private code" msgid "New private code"
msgstr "" msgstr "کد خصوصی جدید"
msgid "Enter a new code if you want to change it" msgid "Enter a new code if you want to change it"
msgstr "" msgstr "اگر مایل به تغییر هستید یه کد جدید وارد کنید"
msgid "Email" msgid "Email"
msgstr "" msgstr "ایمیل"
msgid "Enable project history" msgid "Enable project history"
msgstr "" msgstr "فعال کردن تاریخچه‌ی پروژه"
msgid "Use IP tracking for project history" msgid "Use IP tracking for project history"
msgstr "" msgstr "برای تاریخچه‌ی پروژه از ردیابی آدرس IP استفاده شود"
msgid "Default Currency" msgid "Default Currency"
msgstr "" msgstr "واحد پولی پیش فرض"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr "تنظیم واحد پولی پیش فرض امکان تبدیل ارز بین قبض‌ها رو فراهم می‌کنه"
msgid "Unknown error"
msgstr "خطای ناشناخته"
msgid "Invalid private code."
msgstr "کد خصوصی نامعتبر."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
"این پروژه نمی‌تونه به صورت «بدون واحد پولی» تنظیم بشه چون شامل قبوض با "
"ارزهای مختلفه."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr ""
msgid "Import"
msgstr "" msgstr ""
msgid "Project identifier" msgid "Project identifier"
msgstr "" msgstr "شناسه پروژه"
msgid "Private code" msgid "Private code"
msgstr "" msgstr "کد خصوصی"
msgid "Create the project" msgid "Create the project"
msgstr "" msgstr "ساخت پروژه"
#, python-format #, python-format
msgid "" 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 ""
"پروژه‌ای با شناسه‌ی (\"%(project)s\") از قبل وجود داره. لطفا یه شناسه‌ی "
"جدید وارد کن"
msgid "Which is a real currency: Euro or Petro dollar?" msgid "Which is a real currency: Euro or Petro dollar?"
msgstr "" msgstr "کدوم یکی واقعا واحد پولیه: یورو یا دلار نفتی؟"
msgid "euro" msgid "euro"
msgstr "" msgstr "یورو"
msgid "Please, validate the captcha to proceed." msgid "Please, validate the captcha to proceed."
msgstr "" msgstr "لطفا برای ادامه کپچا رو تایید کن."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "" msgstr "کد خصوصی رو برای تایید حذف وارد کن"
msgid "Unknown error"
msgstr ""
msgid "Invalid private code."
msgstr ""
msgid "Get in" msgid "Get in"
msgstr "" msgstr "بیا تو"
msgid "Admin password" msgid "Admin password"
msgstr "" msgstr "گذرواژه‌ی مدیر"
msgid "Send me the code by email" msgid "Send me the code by email"
msgstr "" msgstr "کد رو برام ایمیل کن"
msgid "This project does not exists" msgid "This project does not exists"
msgstr "" msgstr "این پروژه وجود نداره"
msgid "Password mismatch" msgid "Password mismatch"
msgstr "" msgstr "گذرواژه‌ها با هم نمی‌خونه"
msgid "Password" msgid "Password"
msgstr "" msgstr "گذرواژه"
msgid "Password confirmation" msgid "Password confirmation"
msgstr "" msgstr "تایید گذرواژه"
msgid "Reset password" msgid "Reset password"
msgstr "" msgstr "بازنشانی گذرواژه"
msgid "Date" msgid "When?"
msgstr "" msgstr ""
msgid "What?" msgid "What?"
msgstr "چی؟"
msgid "Who paid?"
msgstr "" msgstr ""
msgid "Payer" msgid "How much?"
msgstr ""
msgid "Amount paid"
msgstr "" msgstr ""
msgid "Currency" msgid "Currency"
msgstr "" msgstr "واحد پولی"
msgid "External link" msgid "External link"
msgstr "" msgstr "لینک خارجی"
msgid "A link to an external document, related to this bill" msgid "A link to an external document, related to this bill"
msgstr "" msgstr "یه لینک به سند خارجی به این قبض مربوطه"
msgid "For whom?" msgid "For whom?"
msgstr "" msgstr "برای کی؟"
msgid "Submit" msgid "Submit"
msgstr "" msgstr "ثبت"
msgid "Submit and add a new one" msgid "Submit and add a new one"
msgstr "" msgstr "ثبت و اضافه کردن جدید"
#, python-format #, python-format
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "" msgstr "پیش فرض پروژه: %(currency)s"
msgid "Bills can't be null"
msgstr ""
msgid "Name" msgid "Name"
msgstr "" msgstr "نام"
msgid "Weights should be positive" msgid "Weights should be positive"
msgstr "" msgstr "وزن باید مثبت باشه"
msgid "Weight" msgid "Weight"
msgstr "" msgstr "وزن"
msgid "Add" msgid "Add"
msgstr "" msgstr "اضافه"
msgid "The participant name is invalid" msgid "The participant name is invalid"
msgstr "" msgstr "نام شرکت کننده نامعتبره"
msgid "This project already have this participant" msgid "This project already have this participant"
msgstr "" msgstr "این شرکت کننده از قبل عضو پروژه هست"
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr "افرادی که براشون نوتیفیکیشن ارسال میشه"
msgid "Send invites" msgid "Send the invitations"
msgstr "" msgstr ""
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "ایمیل %(email)s نامعتبره"
msgid "Logout"
msgstr ""
msgid "Please check the email configuration of the server."
msgstr ""
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr "" msgstr ""
#. List with two items only #. List with two items only
@ -193,7 +215,7 @@ msgid "{start_object}, {next_object}"
msgstr "" msgstr ""
msgid "No Currency" msgid "No Currency"
msgstr "" msgstr "بدون واحد پولی"
#. Form error with only one error #. Form error with only one error
msgid "{prefix}: {error}" msgid "{prefix}: {error}"
@ -203,22 +225,18 @@ msgstr ""
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "" msgstr ""
#, python-format #, python-format
msgid "This admin password is not the right one. Only %(num)d attempts left." msgid "This admin password is not the right one. Only %(num)d attempts left."
msgstr "" msgstr "گذرواژه‌ی مدیر صحیح نیست. فقط %(num)d بار دیگه میشه سعی کنی."
msgid "Provided token is invalid" msgid "Provided token is invalid"
msgstr "" msgstr "توکن وارد شده نامعتبره"
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "" msgstr "این کد خصوصی اون کد خصوصی درست نیست"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "" msgstr ""
@ -228,14 +246,9 @@ msgid ""
"still use the project normally." "still use the project normally."
msgstr "" msgstr ""
#, python-format
msgid "The project identifier is %(project)s"
msgstr ""
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
msgid "No token provided" msgid "No token provided"
@ -250,10 +263,14 @@ msgstr ""
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "" msgstr ""
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "" msgstr ""
msgid "" msgid ""
@ -261,12 +278,18 @@ msgid ""
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr ""
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "" msgstr ""
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr ""
@ -274,10 +297,7 @@ msgstr ""
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "" msgstr ""
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
#, python-format #, python-format
@ -320,6 +340,10 @@ msgstr ""
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "" msgstr ""
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "" msgstr ""
@ -380,7 +404,7 @@ msgstr ""
msgid "edit" msgid "edit"
msgstr "" msgstr ""
msgid "delete" msgid "Delete project"
msgstr "" msgstr ""
msgid "show" msgid "show"
@ -395,20 +419,12 @@ msgstr ""
msgid "Get it on" msgid "Get it on"
msgstr "" msgstr ""
msgid "Are you sure?"
msgstr ""
msgid "Edit project" msgid "Edit project"
msgstr "" msgstr ""
msgid "Delete project" #, fuzzy
msgstr "" msgid "Import project"
msgstr "ساخت پروژه"
msgid "Import JSON"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Download project's data" msgid "Download project's data"
msgstr "" msgstr ""
@ -434,18 +450,27 @@ msgstr ""
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "" msgstr ""
msgid "Edit the project" msgid "Save changes"
msgstr "" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
msgid "Import previously exported project"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Edit this bill" msgid "Edit this bill"
msgstr "" msgstr ""
msgid "Add a bill" msgid "Add a bill"
msgstr "" msgstr ""
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr ""
@ -464,9 +489,6 @@ msgstr ""
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "" msgstr ""
msgid "Send the invitations"
msgstr ""
msgid "Download" msgid "Download"
msgstr "" msgstr ""
@ -531,23 +553,18 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"disabling project history. You can\n" msgstr ""
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
"data-target=\"#confirm-erase\">clear project history</a> to remove " msgid "You can clear the project history to remove them."
"them.</i></p>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
@ -558,18 +575,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "" msgstr ""
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "Time" msgid "Time"
msgstr "" msgstr ""
@ -631,9 +648,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "پرداخت کننده"
msgid "Amount" msgid "Amount"
msgstr "" msgstr ""
msgid "Date"
msgstr "تاریخ"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "" msgstr ""
@ -734,6 +757,9 @@ msgstr ""
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "" msgstr ""
@ -743,7 +769,8 @@ msgstr ""
msgid "Dashboard" msgid "Dashboard"
msgstr "" msgstr ""
msgid "Logout" #, python-format
msgid "Please retry after %(date)s."
msgstr "" msgstr ""
msgid "Code" msgid "Code"
@ -777,30 +804,21 @@ msgstr ""
msgid "Invite people" msgid "Invite people"
msgstr "" msgstr ""
msgid "You should start by adding participants"
msgstr ""
msgid "Add a new bill"
msgstr ""
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr ""
msgid "When?" msgid "You should start by adding participants"
msgstr "" msgstr ""
msgid "Who paid?" msgid "Add a new bill"
msgstr "" msgstr ""
msgid "For what?" msgid "For what?"
msgstr "" msgstr ""
msgid "How much?"
msgstr ""
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "" msgstr ""
@ -809,19 +827,19 @@ msgstr ""
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "" msgstr ""
msgid "delete"
msgstr ""
msgid "No bills" msgid "No bills"
msgstr "" msgstr ""
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "" msgstr ""
msgid "You probably want to" msgid "Add your first bill"
msgstr "" msgstr ""
msgid "add a bill" msgid "Add the first participant"
msgstr ""
msgid "add participants"
msgstr "" msgstr ""
msgid "Password reminder" msgid "Password reminder"
@ -844,31 +862,49 @@ msgstr ""
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "" msgstr ""
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
msgid "Identifier:" msgid "Scan QR code"
msgstr "" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "" msgstr ""
msgid "Send via Emails" msgid "Send via Emails"
msgstr "" msgstr ""
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you." msgstr ""
msgid "Share Identifier & code"
msgstr ""
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr ""
#, fuzzy
msgid "Private code:"
msgstr "کد خصوصی"
msgid "the private code was defined when you created the project"
msgstr "" msgstr ""
msgid "Who pays?" msgid "Who pays?"
@ -943,3 +979,117 @@ msgstr ""
#~ msgid "Participants to notify" #~ msgid "Participants to notify"
#~ msgstr "" #~ msgstr ""
#~ msgid "Import previously exported JSON file"
#~ msgstr ""
#~ msgid "Import"
#~ msgstr ""
#~ msgid "Amount paid"
#~ msgstr ""
#~ msgid "Bills can't be null"
#~ msgstr "قبض‌ها نمی‌تونند تهی باشن"
#~ msgid "Too many failed login attempts, please retry later."
#~ msgstr ""
#~ msgid "The project identifier is %(project)s"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "sending you an email with password "
#~ "reset instructions. Please check the "
#~ "email configuration of the server or "
#~ "contact the administrator."
#~ msgstr ""
#~ msgid "Invalid JSON"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "trying to send the invitation emails."
#~ " Please check the email configuration "
#~ "of the server or contact the "
#~ "administrator."
#~ msgstr ""
#~ msgid "Are you sure?"
#~ msgstr ""
#~ msgid "Import JSON"
#~ msgstr ""
#~ 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 "Send invites"
#~ msgstr "فرستادن دعوت نامه"
#~ msgid " show"
#~ msgstr ""
#~ msgid "Edit the project"
#~ msgstr ""
#~ msgid "You probably want to"
#~ msgstr ""
#~ msgid "add a bill"
#~ msgstr ""
#~ msgid "add participants"
#~ msgstr ""
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ msgid "Share the Link"
#~ msgstr ""
#~ msgid "You can directly share the following link via your prefered medium"
#~ 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 ""
#~ "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 with the invitation "
#~ "link."
#~ msgstr ""

View file

@ -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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2021-11-25 23:51+0000\n" "PO-Revision-Date: 2023-07-29 13:07+0000\n"
"Last-Translator: Alexis Metaireau <alexis@notmyidea.org>\n" "Last-Translator: Baptiste <weblate@bitsofnetworks.org>\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,9 +17,13 @@ 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 4.10-dev\n" "X-Generator: Weblate 5.0-dev\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Vous venez de créer « %(project)s » pour partager vos dépenses"
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."
@ -30,6 +34,12 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Nom de projet" msgstr "Nom de projet"
msgid "Current private code"
msgstr "Code daccès actuel"
msgid "Enter existing private code to edit project"
msgstr "Entrez le code d'accès existant pour éditer le projet"
msgid "New private code" msgid "New private code"
msgstr "Nouveau code daccès" msgstr "Nouveau code daccès"
@ -53,6 +63,12 @@ msgstr ""
"Choisir une devise par défaut permet d'activer la conversion de devises " "Choisir une devise par défaut permet d'activer la conversion de devises "
"entre les factures" "entre les factures"
msgid "Unknown error"
msgstr "Erreur inconnue"
msgid "Invalid private code."
msgstr "Code daccès invalide."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
@ -60,11 +76,8 @@ msgstr ""
"Ce projet ne peut pas être sans devise car il contient des factures " "Ce projet ne peut pas être sans devise car il contient des factures "
"utilisant des devises différentes." "utilisant des devises différentes."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Importer un fichier JSON précédemment exporté" msgstr "Compatible avec Cospend"
msgid "Import"
msgstr "Importer"
msgid "Project identifier" msgid "Project identifier"
msgstr "Identifiant du projet" msgstr "Identifiant du projet"
@ -80,11 +93,11 @@ 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 ""
"Il existe déjà un projet avec l'identifiant (\"%(project)s\"). Merci d'en " "Il existe déjà un projet avec l'identifiant (\"%(project)s\"). Merci d'en"
"choisir un autre" " choisir un autre"
msgid "Which is a real currency: Euro or Petro dollar?" msgid "Which is a real currency: Euro or Petro dollar?"
msgstr "Euro ou Petrodollar ?" msgstr "Quelle est la vraie monnaie : Euro ou Petrodollar ?"
msgid "euro" msgid "euro"
msgstr "euro" msgstr "euro"
@ -95,12 +108,6 @@ msgstr "Merci de valider le captcha avant de continuer."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Entrez le code d'accès pour confirmer la suppression" msgstr "Entrez le code d'accès pour confirmer la suppression"
msgid "Unknown error"
msgstr "Erreur inconnue"
msgid "Invalid private code."
msgstr "Code daccès invalide."
msgid "Get in" msgid "Get in"
msgstr "Entrer" msgstr "Entrer"
@ -125,17 +132,17 @@ msgstr "Confirmation du mot de passe"
msgid "Reset password" msgid "Reset password"
msgstr "Réinitialiser le mot de passe" msgstr "Réinitialiser le mot de passe"
msgid "Date" msgid "When?"
msgstr "Date" msgstr "Quand ?"
msgid "What?" msgid "What?"
msgstr "Quoi ?" msgstr "Quoi ?"
msgid "Payer" msgid "Who paid?"
msgstr "Payeur" msgstr "Qui a payé ?"
msgid "Amount paid" msgid "How much?"
msgstr "Montant" msgstr "Combien ?"
msgid "Currency" msgid "Currency"
msgstr "Devise" msgstr "Devise"
@ -159,9 +166,6 @@ msgstr "Valider et ajouter une autre facture"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Devise du projet : %(currency)s" msgstr "Devise du projet : %(currency)s"
msgid "Bills can't be null"
msgstr "Le montant dune facture ne peut pas être vide"
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
@ -175,7 +179,7 @@ msgid "Add"
msgstr "Ajouter" msgstr "Ajouter"
msgid "The participant name is invalid" msgid "The participant name is invalid"
msgstr "Participant⋅e %(name)s réactivé⋅e" msgstr "Le nom du participant est incorrect"
msgid "This project already have this participant" msgid "This project already have this participant"
msgstr "Ce⋅tte membre existe déjà pour ce projet" msgstr "Ce⋅tte membre existe déjà pour ce projet"
@ -183,13 +187,27 @@ msgstr "Ce⋅tte membre existe déjà pour ce projet"
msgid "People to notify" msgid "People to notify"
msgstr "Personnes à inviter" msgstr "Personnes à inviter"
msgid "Send invites" msgid "Send the invitations"
msgstr "Envoyer les invitations" msgstr "Envoyer les invitations"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "Lemail %(email)s est invalide" msgstr "Lemail %(email)s est invalide"
msgid "Logout"
msgstr "Se déconnecter"
msgid "Please check the email configuration of the server."
msgstr "Veuillez vérifier la configuration email du serveur."
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Veuillez vérifier la configuration email du serveur ou contacter "
"ladministrateur⋅ice : %(admin_email)s"
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} et {dual_object_1}" msgstr "{dual_object_0} et {dual_object_1}"
@ -217,14 +235,14 @@ msgstr "{prefix} : {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix} :<br />{errors}" msgstr "{prefix} :<br />{errors}"
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "Trop d'échecs dauthentification successifs, veuillez réessayer plus tard." msgstr "Trop d'échecs dauthentification successifs."
#, python-format #, python-format
msgid "This admin password is not the right one. Only %(num)d attempts left." msgid "This admin password is not the right one. Only %(num)d attempts left."
msgstr "" msgstr ""
"Le mot de passe administrateur⋅ice que vous avez entré nest pas correct. " "Le mot de passe administrateur⋅ice que vous avez entré nest pas correct."
"Plus que %(num)d tentatives." " Plus que %(num)d tentatives."
msgid "Provided token is invalid" msgid "Provided token is invalid"
msgstr "Ce jeton est invalide" msgstr "Ce jeton est invalide"
@ -232,10 +250,6 @@ msgstr "Ce jeton est invalide"
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Le code d'accès nest pas correct" msgstr "Le code d'accès nest pas correct"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Vous venez de créer « %(project)s » pour partager vos dépenses"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "Un courriel de rappel vient de vous être envoyé" msgstr "Un courriel de rappel vient de vous être envoyé"
@ -247,18 +261,12 @@ msgstr ""
"sest produite. Il est toujours possible dutiliser le projet " "sest produite. Il est toujours possible dutiliser le projet "
"normalement." "normalement."
#, python-format
msgid "The project identifier is %(project)s"
msgstr "Lidentifiant de ce projet est %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"Désolé, une erreur sest produite lors de lenvoi du courriel contenant les " "Désolé, une erreur sest produite lors de lenvoi du courriel contenant "
"instructions de réinitialisation de mot de passe. Veuillez vérifier la " "les instructions de réinitialisation de mot de passe."
"configuration des courriels du serveur ou contacter ladministrateur⋅ice."
msgid "No token provided" msgid "No token provided"
msgstr "Aucun jeton na été fourni" msgstr "Aucun jeton na été fourni"
@ -272,23 +280,33 @@ msgstr "Projet 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" msgid "Project settings have been changed successfully."
msgstr "Le projet a été correctement importé" msgstr "Les paramètres du projet ont bien été enregistrés."
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "Le fichier JSON est invalide" msgstr "Erreur lors de la lecture du fichier CSV"
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "Attribut manquant : %(attribute)s"
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "Impossible d'ajouter plusieurs devises à un projet sans devise par défaut" msgstr "Impossible d'ajouter plusieurs devises à un projet sans devise par défaut"
msgid "Project successfully uploaded"
msgstr "Le projet a été correctement importé"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "Projet supprimé" msgstr "Projet supprimé"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "Erreur lors de la suppression du projet" msgstr "Erreur lors de la suppression du projet"
msgid "Unable to logout"
msgstr "Impossible de se déconnecter"
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "Vous avez été invité⋅e à partager vos dépenses pour %(project)s" msgstr "Vous avez été invité⋅e à partager vos dépenses pour %(project)s"
@ -296,14 +314,10 @@ msgstr "Vous avez été invité⋅e à partager vos dépenses pour %(project)s"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "Vos invitations ont bien été envoyées" msgstr "Vos invitations ont bien été envoyées"
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Désolé, une erreur sest produite lors de lenvoi du courriel dinvitation. " "Désolé, une erreur sest produite lors de lenvoi du courriel "
"Veuillez vérifier la configuration des courriels du serveur ou contacter " "dinvitation."
"ladministrateur⋅ice."
#, python-format #, python-format
msgid "%(member)s has been added" msgid "%(member)s has been added"
@ -324,8 +338,8 @@ msgid ""
"Participant '%(name)s' has been deactivated. It will still appear in the " "Participant '%(name)s' has been deactivated. It will still appear in the "
"list until its balance reach zero." "list until its balance reach zero."
msgstr "" msgstr ""
"« %(name)s » a été désactivé⋅e. Il⋅elle continuera dapparaître jusqu'à ce " "« %(name)s » a été désactivé⋅e. Il⋅elle continuera dapparaître jusqu'à "
"que son solde soit nul." "ce que son solde soit nul."
#, python-format #, python-format
msgid "Participant '%(name)s' has been removed" msgid "Participant '%(name)s' has been removed"
@ -347,6 +361,10 @@ msgstr "La facture a été supprimée"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "La facture a été modifiée" msgstr "La facture a été modifiée"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr "La langue %(lang)s n'est pas prise en charge"
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Erreur lors de la suppression de l'historique du projet" msgstr "Erreur lors de la suppression de l'historique du projet"
@ -390,7 +408,7 @@ msgid "Project"
msgstr "Projet" msgstr "Projet"
msgid "Number of participants" msgid "Number of participants"
msgstr "ajouter des participant⋅es" msgstr "Nombre de participant⋅es"
msgid "Number of bills" msgid "Number of bills"
msgstr "Nombre de factures" msgstr "Nombre de factures"
@ -407,8 +425,8 @@ msgstr "Actions"
msgid "edit" msgid "edit"
msgstr "éditer" msgstr "éditer"
msgid "delete" msgid "Delete project"
msgstr "supprimer" msgstr "Supprimer le projet"
msgid "show" msgid "show"
msgstr "voir" msgstr "voir"
@ -422,20 +440,11 @@ msgstr "Télécharger lapplication mobile"
msgid "Get it on" msgid "Get it on"
msgstr "Télécharger depuis" msgstr "Télécharger depuis"
msgid "Are you sure?"
msgstr "Êtes-vous sûr⋅e ?"
msgid "Edit project" msgid "Edit project"
msgstr "Éditer le projet" msgstr "Éditer le projet"
msgid "Delete project" msgid "Import project"
msgstr "Supprimer le projet" msgstr "Importer le projet"
msgid "Import JSON"
msgstr "Importer le fichier 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"
@ -461,18 +470,27 @@ msgstr "Annuler"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Vie privée" msgstr "Vie privée"
msgid "Edit the project" msgid "Save changes"
msgstr "Éditer le projet" msgstr "Sauvegarder les modifications"
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "Cela supprimera toutes les factures et participant⋅es du projet !" msgstr "Cela supprimera toutes les factures et participant⋅es du projet !"
msgid "Import previously exported project"
msgstr "Importer un projet précédemment exporté"
msgid "Choose file"
msgstr "Choisir un fichier"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Éditer cette facture" msgstr "Éditer cette facture"
msgid "Add a bill" msgid "Add a bill"
msgstr "Ajouter une facture" msgstr "Ajouter une facture"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr "Les opérations simples sont possibles, par exemple (18+36.2)/3"
msgid "Everyone" msgid "Everyone"
msgstr "Tout le monde" msgstr "Tout le monde"
@ -486,14 +504,11 @@ msgid "Add participant"
msgstr "Ajouter un⋅e participant⋅e" msgstr "Ajouter un⋅e participant⋅e"
msgid "Edit this participant" msgid "Edit this participant"
msgstr "Ajouter un⋅e participant⋅e" msgstr "Modifier un⋅e participant⋅e"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "marie@site.com, jean.dupont@exemple.com" msgstr "marie@site.com, jean.dupont@exemple.com"
msgid "Send the invitations"
msgstr "Envoyer les invitations"
msgid "Download" msgid "Download"
msgstr "Télécharger" msgstr "Télécharger"
@ -558,45 +573,31 @@ msgstr ""
#, python-format #, python-format
msgid "Bill %(name)s: added %(owers_list_str)s to owers list" msgid "Bill %(name)s: added %(owers_list_str)s to owers list"
msgstr "" msgstr "Facture %(name)s : %(owers_list_str)s ajouté à la liste des débiteur⋅ices"
"Facture %(name)s : %(owers_list_str)s ajouté à la liste des débiteur⋅ices"
#, python-format #, python-format
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
"Facture %(name)s : %(owers_list_str)s supprimé de la liste des débiteur⋅ices" "Facture %(name)s : %(owers_list_str)s supprimé de la liste des "
"débiteur⋅ices"
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n" "L'historique de ce projet est désactivé. Les nouvelles actions "
" <i>L'historique de ce projet a été désactivé. Les nouvelles " "n'apparaîtront pas ci-dessous."
"actions n'apparaîtront pas ci-dessous. Vous pouvez réactiver l'historique"
" du projet dans les </i>\n" msgid "You can enable history on the settings page."
" <a href=\"%(url)s\">paramètres du projet</a>\n" msgstr "Vous pouvez activer l'historique dans les paramètres."
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n" "Le tableau ci-dessous affiche uniquement les actions enregistrées avant "
" <i>Le tableau ci-dessous liste les actions enregistrées avant la " "que l'historique n'ait été désactivé pour ce projet."
"désactivation de l'historique du projet. Vous pouvez\n"
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" data-" msgid "You can clear the project history to remove them."
"target=\"#confirm-erase\">supprimer l'historique du projet</a> pour les " msgstr "Vous pouvez supprimer l'historique du projet pour les enlever."
"supprimer.</i></p>\n"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -608,18 +609,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Supprimer toutes les adresses IP enregistrées" 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" msgid "No IP Addresses to erase"
msgstr "Aucune adresse IP à supprimer" msgstr "Aucune adresse IP à supprimer"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Supprimer les adresses IP enregistrées" msgstr "Supprimer 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 "Time" msgid "Time"
msgstr "Heure" msgstr "Heure"
@ -628,8 +629,8 @@ msgstr "Évènement"
msgid "IP address recording can be enabled on the settings page" msgid "IP address recording can be enabled on the settings page"
msgstr "" msgstr ""
"Vous pouvez activer l'enregistrement des adresses IP dans les paramètres de " "Vous pouvez activer l'enregistrement des adresses IP dans les paramètres "
"la page" "de la page"
msgid "IP address recording can be disabled on the settings page" msgid "IP address recording can be disabled on the settings page"
msgstr "" msgstr ""
@ -687,9 +688,15 @@ msgstr ""
"Participant⋅e %(name)s : nombre de parts changé de %(old_weight)s en " "Participant⋅e %(name)s : nombre de parts changé de %(old_weight)s en "
"%(new_weight)s" "%(new_weight)s"
msgid "Payer"
msgstr "Payeur"
msgid "Amount" msgid "Amount"
msgstr "Montant" msgstr "Montant"
msgid "Date"
msgstr "Date"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Montant en %(currency)s" msgstr "Montant en %(currency)s"
@ -792,6 +799,9 @@ msgstr "Historique"
msgid "Settings" msgid "Settings"
msgstr "Options" msgstr "Options"
msgid "RSS Feed"
msgstr "Flux RSS"
msgid "Other projects :" msgid "Other projects :"
msgstr "Autres projets :" msgstr "Autres projets :"
@ -801,8 +811,9 @@ msgstr "aller à"
msgid "Dashboard" msgid "Dashboard"
msgstr "Tableau de bord" msgstr "Tableau de bord"
msgid "Logout" #, python-format
msgstr "Se déconnecter" msgid "Please retry after %(date)s."
msgstr "Veuillez réessayer après %(date)s."
msgid "Code" msgid "Code"
msgstr "Code" msgstr "Code"
@ -835,30 +846,21 @@ msgstr "vous confirmez ?"
msgid "Invite people" msgid "Invite people"
msgstr "Inviter des gens" msgstr "Inviter des gens"
msgid "You should start by adding participants"
msgstr "Vous devriez commencer par ajouter des participant⋅es"
msgid "Add a new bill"
msgstr "Nouvelle facture"
msgid "Newer bills" msgid "Newer bills"
msgstr "Factures suivantes" msgstr "Factures suivantes"
msgid "Older bills" msgid "Older bills"
msgstr "Factures précédentes" msgstr "Factures précédentes"
msgid "When?" msgid "You should start by adding participants"
msgstr "Quand ?" msgstr "Vous devriez commencer par ajouter des participant⋅es"
msgid "Who paid?" msgid "Add a new bill"
msgstr "Qui a payé ?" msgstr "Nouvelle facture"
msgid "For what?" msgid "For what?"
msgstr "Pour quoi ?" msgstr "Pour quoi ?"
msgid "How much?"
msgstr "Combien ?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Ajouté le %(date)s" msgstr "Ajouté le %(date)s"
@ -867,20 +869,20 @@ msgstr "Ajouté le %(date)s"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Tout le monde sauf %(excluded)s" msgstr "Tout le monde sauf %(excluded)s"
msgid "delete"
msgstr "supprimer"
msgid "No bills" msgid "No bills"
msgstr "Pas encore de factures" msgstr "Pas encore de factures"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Rien à lister pour le moment." msgstr "Rien à lister pour le moment."
msgid "You probably want to" msgid "Add your first bill"
msgstr "Vous souhaitez sûrement" msgstr "Ajouter votre première facture"
msgid "add a bill" msgid "Add the first participant"
msgstr "ajouter une facture" msgstr "Ajouter le premier participant ou la première participante"
msgid "add participants"
msgstr "ajouter des participant⋅es"
msgid "Password reminder" msgid "Password reminder"
msgstr "Rappel du code daccès" msgstr "Rappel du code daccès"
@ -904,36 +906,62 @@ msgstr "Changez votre code d'accès"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Invitez des personnes à rejoindre ce projet" msgstr "Invitez des personnes à rejoindre ce projet"
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "Partager l'identifiant et le code" msgstr "Partager un lien d'invitation"
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
"Vous pouvez partager l'identifiant de ce projet et le code d'accès par " "Pour inviter des personnes dans ce projet, vous pouvez leur donner le "
"d'autres moyens." "lien d'invitation ci-dessous.<br />Elles pourront ainsi accéder au "
"projet, gérer les participants, ajouter/modifier/supprimer des factures. "
"En revanche, elles ne pourront pas modifier des paramètres importants "
"tels que le code d'accès ou supprimer le projet."
msgid "Identifier:" msgid "Scan QR code"
msgstr "Identifiant :" msgstr "Scannez le QR code"
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr "Partagez le lien" msgstr "Utilisez un appareil mobile avec une application compatible."
msgid "You can directly share the following link via your prefered medium"
msgstr "Vous pouvez directement partager le lien suivant"
msgid "Send via Emails" msgid "Send via Emails"
msgstr "Envoyer par email(s)" msgstr "Envoyer par email(s)"
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"Entrez les emails des personnes avec qui vous souhaitez partager ce projet, " "Entrez les emails des personnes avec qui vous souhaitez partager ce projet ("
"nous leur enverrons un lien d'invitation." "en séparant les adresses emails avec des virgules). Nous leur enverrons un "
"mail avec le lien d'invitation."
msgid "Share Identifier & code"
msgstr "Partager l'identifiant et le code"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
"Vous pouvez partager l'identifiant de ce projet et le code d'accès par "
"tout moyen de votre choix.<br />Une personne possédant le code d'accès "
"aura un accès complet au projet, y compris pour changer le code d'accès "
"ou l'adresse email associée au projet, voire même supprimer complètement "
"le projet."
msgid "Identifier:"
msgstr "Identifiant :"
msgid "Private code:"
msgstr "Code daccès :"
msgid "the private code was defined when you created the project"
msgstr "le code d'accès a été défini lorsque vous avez créé le projet"
msgid "Who pays?" msgid "Who pays?"
msgstr "Qui doit payer ?" msgstr "Qui doit payer ?"
@ -1269,3 +1297,94 @@ msgstr "Période"
#~ msgid "Participants to notify" #~ msgid "Participants to notify"
#~ msgstr "ajouter des participant⋅e⋅s" #~ msgstr "ajouter des participant⋅e⋅s"
#~ msgid "Import"
#~ msgstr "Importer"
#~ msgid "Amount paid"
#~ msgstr "Montant"
#~ msgid "Bills can't be null"
#~ msgstr "Le montant dune facture ne peut pas être vide"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "Lidentifiant de ce projet est %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "Le fichier JSON est invalide"
#~ msgid "Are you sure?"
#~ msgstr "Êtes-vous sûr⋅e ?"
#~ msgid "Import JSON"
#~ msgstr "Importer le fichier JSON"
#~ 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\">supprimer l'historique du"
#~ " projet</a> pour les supprimer.</i></p>\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "Envoyer les invitations"
#~ msgid " show"
#~ msgstr "voir"
#~ msgid "Edit the project"
#~ msgstr "Éditer le projet"
#~ msgid "You probably want to"
#~ msgstr "Vous souhaitez sûrement"
#~ msgid "add participants"
#~ msgstr "ajouter des participant⋅es"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "Vous pouvez partager l'identifiant de ce"
#~ " projet et le code d'accès par "
#~ "d'autres moyens."
#~ msgid "Share the Link"
#~ msgstr "Partagez le lien"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr "Vous pouvez directement partager le lien suivant"

View file

@ -1,19 +1,24 @@
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: 2022-05-22 20:21+0200\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2022-05-24 08:15+0000\n" "PO-Revision-Date: 2023-07-24 07:07+0000\n"
"Last-Translator: G Pery <gpery+weblate@proton.me>\n" "Last-Translator: Nati Lintzer <nlintzer@gmail.com>\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/i-hate-money/"
"i-hate-money/he/>\n"
"Language: he\n" "Language: he\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/i-hate-money/i"
"-hate-money/he/>\n"
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 "
"&& n % 10 == 0) ? 2 : 3))\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=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "Generated-By: Babel 2.9.0\n"
"n % 10 == 0) ? 2 : 3));\n"
"X-Generator: Weblate 4.13-dev\n" #, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "יצרת את פרויקט '%(project)s' כדי לחלוק את הוצאותיך"
msgid "" msgid ""
"Not a valid amount or expression. Only numbers and + - * / operators are " "Not a valid amount or expression. Only numbers and + - * / operators are "
@ -23,6 +28,13 @@ msgstr "כמות או ביטוי לא תקין. יש להזין רק מספרי
msgid "Project name" msgid "Project name"
msgstr "שם הפרויקט" msgstr "שם הפרויקט"
#, fuzzy
msgid "Current private code"
msgstr "קוד פרטי חדש"
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "קוד פרטי חדש" msgstr "קוד פרטי חדש"
@ -44,17 +56,21 @@ msgstr "מטבע ברירת המחדל"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "בחירת מטבע ברירת מחדל מאפשרת המרת מטבע בין חשבונות" msgstr "בחירת מטבע ברירת מחדל מאפשרת המרת מטבע בין חשבונות"
msgid "Unknown error"
msgstr "שגיאה לא ידועה"
msgid "Invalid private code."
msgstr "קוד פרטי לא תקין."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
"בפרויקט זה לא ניתן להגדיר 'ללא מטבע' מכיוון שהוא כולל חשבונות במספר מטבעות." "בפרויקט זה לא ניתן להגדיר 'ללא מטבע' מכיוון שהוא כולל חשבונות במספר "
"מטבעות."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "ייבא קובץ JSON מיוצא" msgstr ""
msgid "Import"
msgstr "ייבא"
msgid "Project identifier" msgid "Project identifier"
msgstr "מזהה פרויקט" msgstr "מזהה פרויקט"
@ -83,12 +99,6 @@ msgstr "אנא אמת את ה-Captcha כדי להמשיך."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "הזן את הקוד הפרטי כדי לאשר מחיקה" msgstr "הזן את הקוד הפרטי כדי לאשר מחיקה"
msgid "Unknown error"
msgstr "שגיאה לא ידועה"
msgid "Invalid private code."
msgstr "קוד פרטי לא תקין."
msgid "Get in" msgid "Get in"
msgstr "היכנס" msgstr "היכנס"
@ -113,17 +123,17 @@ msgstr "אימות סיסמה"
msgid "Reset password" msgid "Reset password"
msgstr "איפוס סיסמה" msgstr "איפוס סיסמה"
msgid "Date" msgid "When?"
msgstr "תאריך" msgstr "מתי?"
msgid "What?" msgid "What?"
msgstr "מה?" msgstr "מה?"
msgid "Payer" msgid "Who paid?"
msgstr "משלם" msgstr "מי שילם?"
msgid "Amount paid" msgid "How much?"
msgstr "כמות ששולמה" msgstr "כמה?"
msgid "Currency" msgid "Currency"
msgstr "מטבע" msgstr "מטבע"
@ -147,9 +157,6 @@ msgstr "הזן והוסף אחד חדש"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "ברירת המחדל בפרויקט: %(currency)s" msgstr "ברירת המחדל בפרויקט: %(currency)s"
msgid "Bills can't be null"
msgstr "חשבונות לא יכולים להיות ריקים"
msgid "Name" msgid "Name"
msgstr "שם" msgstr "שם"
@ -171,13 +178,27 @@ msgstr "המשתתף כבר נמצא בפרויקט זה"
msgid "People to notify" msgid "People to notify"
msgstr "אנשים להתריע להם" msgstr "אנשים להתריע להם"
msgid "Send invites" msgid "Send the invitations"
msgstr "שלח הזמנות" msgstr "שלח את ההזמנות"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "כתובת הדוא\"ל %(email)s אינה תקינה" msgstr "כתובת הדוא\"ל %(email)s אינה תקינה"
msgid "Logout"
msgstr "להתנתק"
msgid "Please check the email configuration of the server."
msgstr ""
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"מצטערים, אך אירעה שגיאה בעת ששלחנו לכם את המייל עם הוראות איפוס הסיסמה. "
"אנא בדקו את הגדרות המייל בשרת או פנו למנהל השרת:%(admin_email)s"
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} ו- {dual_object_1}" msgstr "{dual_object_0} ו- {dual_object_1}"
@ -205,23 +226,19 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix}:<br />{errors}" msgstr "{prefix}:<br />{errors}"
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "יותר מדי ניסיון התחברות כושלים, אנא נסו שם מאוחר יותר." msgstr "יותר מדי ניסיון התחברות כושלים."
#, python-format #, python-format
msgid "This admin password is not the right one. Only %(num)d attempts left." msgid "This admin password is not the right one. Only %(num)d attempts left."
msgstr "סיסמת המנהל הזו שגויה. נותרו %(num)d ניסיונות." msgstr "סיסמת המנהל הזו שגויה. נותרו %(num)d ניסיונות."
msgid "Provided token is invalid" msgid "Provided token is invalid"
msgstr "" msgstr "הטוקן שהוזן אינו תקין"
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "קוד פרטי זה שגוי" msgstr "קוד פרטי זה שגוי"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "יצרת את פרויקט '%(project)s' כדי לחלוק את הוצאותיך"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "דוא\"ל תזכורת נשלח אליך כעת" msgstr "דוא\"ל תזכורת נשלח אליך כעת"
@ -229,64 +246,69 @@ msgid ""
"We tried to send you an reminder email, but there was an error. You can " "We tried to send you an reminder email, but there was an error. You can "
"still use the project normally." "still use the project normally."
msgstr "" msgstr ""
"ניסינו לשלוח לך דוא\"ל תזכורת, אבל הייתה שגיאה. תוכל.י להמשיך להשתמש בפרויקט " "ניסינו לשלוח לך דוא\"ל תזכורת, אבל הייתה שגיאה. תוכל.י להמשיך להשתמש "
"כרגיל." "בפרויקט כרגיל."
#, python-format
msgid "The project identifier is %(project)s"
msgstr ""
#, fuzzy
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"מצטערים, אך אירעה שגיאה בעת ששלחנו לכם את המייל עם הוראות איפוס הסיסמה. "
"בבקשה תבדקו את הגדרות המייל בשרת או פנו למנהל השרת."
msgid "No token provided" msgid "No token provided"
msgstr "" msgstr "טוקן לא הוזן"
msgid "Invalid token" msgid "Invalid token"
msgstr "" msgstr "טוקן לא תקין"
msgid "Unknown project" msgid "Unknown project"
msgstr "" msgstr "פרויקט לא ידוע"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "הסיסמה אופסה בהצלחה."
msgid "Project settings have been changed successfully."
msgstr "" msgstr ""
msgid "Project successfully uploaded" msgid "Unable to parse CSV"
msgstr "" msgstr ""
msgid "Invalid JSON" #, python-format
msgstr "" msgid "Missing attribute: %(attribute)s"
msgstr "תכונה חסרה:%(attribute)s"
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr "לא ניתן להוסיף חשבונות במספר מטבעות לפרויקט ללא מטבע ברירת מחדל"
msgid "Project successfully uploaded"
msgstr "הפרויקט הועלה בהצלחה"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "" msgstr "הפרויקט נמחק בהצלחה"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr "שגיאה במחיקת הפרויקט"
msgid "Unable to logout"
msgstr "לא ניתן להתנתק"
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr "הוזמנת לשתף הוצאות בפרויקט %(project)s"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "" msgstr "ההזמנות שלך נשלחו"
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. " msgstr "מצטערים, אך אירעה שגיאה בעת שליחת ההזמנות."
"Please check the email configuration of the server or contact the "
"administrator."
msgstr ""
#, python-format #, python-format
msgid "%(member)s has been added" msgid "%(member)s has been added"
msgstr "" msgstr "%(member)s נוסף"
msgid "Error activating participant" msgid "Error activating participant"
msgstr "" msgstr ""
@ -313,22 +335,27 @@ msgid "Participant '%(name)s' has been modified"
msgstr "" msgstr ""
msgid "The bill has been added" msgid "The bill has been added"
msgstr "" msgstr "החשבון נוסף"
msgid "Error deleting bill" msgid "Error deleting bill"
msgstr "" msgstr "שגיאה בעת מחיקת החשבון"
#, fuzzy
msgid "The bill has been deleted" msgid "The bill has been deleted"
msgstr "" msgstr "ההוצאה נמחקה"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "" msgstr ""
#, python-format
msgid "%(lang)s is not a supported language"
msgstr "%(lang)s אינה שפה נתמכת"
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "" msgstr "שגיאה במחיקת הסטוריית הפרויקט"
msgid "Deleted project history." msgid "Deleted project history."
msgstr "" msgstr "הסטוריית הפרויקט נמחקה."
msgid "Error deleting recorded IP addresses" msgid "Error deleting recorded IP addresses"
msgstr "" msgstr ""
@ -337,19 +364,19 @@ msgid "Deleted recorded IP addresses in project history."
msgstr "" msgstr ""
msgid "Sorry, we were unable to find the page you've asked for." msgid "Sorry, we were unable to find the page you've asked for."
msgstr "" msgstr "מצטערים, לא הצלחנו לגשת לדף שחיפשת."
msgid "The best thing to do is probably to get back to the main page." msgid "The best thing to do is probably to get back to the main page."
msgstr "" msgstr "כנראה שהדבר הטוב ביותר לעשות הוא לחזור לעמוד הראשי."
msgid "Back to the list" msgid "Back to the list"
msgstr "" msgstr "חזרה לרשימה"
msgid "Administration tasks are currently disabled." msgid "Administration tasks are currently disabled."
msgstr "" msgstr "פעולות ניהול מבוטלות לעת עתה."
msgid "Authentication" msgid "Authentication"
msgstr "" msgstr "הזדהות"
msgid "The project you are trying to access do not exist, do you want to" msgid "The project you are trying to access do not exist, do you want to"
msgstr "" msgstr ""
@ -358,34 +385,34 @@ msgid "create it"
msgstr "" msgstr ""
msgid "?" msgid "?"
msgstr "" msgstr "?"
msgid "Create a new project" msgid "Create a new project"
msgstr "" msgstr "צור פרויקט חדש"
msgid "Project" msgid "Project"
msgstr "" msgstr "פרויקט"
msgid "Number of participants" msgid "Number of participants"
msgstr "" msgstr "מספר משתתפים"
msgid "Number of bills" msgid "Number of bills"
msgstr "" msgstr "מספר חשבונות"
msgid "Newest bill" msgid "Newest bill"
msgstr "" msgstr "החשבון החדש ביותר"
msgid "Oldest bill" msgid "Oldest bill"
msgstr "" msgstr "החשבון הישן ביותר"
msgid "Actions" msgid "Actions"
msgstr "" msgstr "פעולות"
msgid "edit" msgid "edit"
msgstr "" msgstr "ערוך"
msgid "delete" msgid "Delete project"
msgstr "" msgstr "מחק פרויקט"
msgid "show" msgid "show"
msgstr "" msgstr ""
@ -394,25 +421,16 @@ msgid "The Dashboard is currently deactivated."
msgstr "" msgstr ""
msgid "Download Mobile Application" msgid "Download Mobile Application"
msgstr "" msgstr "הורד אפליקציית מובייל"
msgid "Get it on" msgid "Get it on"
msgstr "" msgstr ""
msgid "Are you sure?"
msgstr ""
msgid "Edit project" msgid "Edit project"
msgstr "" msgstr ""
msgid "Delete project" msgid "Import project"
msgstr "" msgstr "ייבא פרוייקטים"
msgid "Import JSON"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Download project's data" msgid "Download project's data"
msgstr "" msgstr ""
@ -438,44 +456,50 @@ msgstr ""
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "" msgstr ""
msgid "Edit the project" msgid "Save changes"
msgstr "" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
msgid "Import previously exported project"
msgstr "ייבא פרוייקט קודם מיוצא"
msgid "Choose file"
msgstr "בחר קובץ"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "" msgstr "ערוך את החשבון"
msgid "Add a bill" msgid "Add a bill"
msgstr "הוסף חשבון"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr "" msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr "כולם"
msgid "No one" msgid "No one"
msgstr "" msgstr "אף אחד"
msgid "More options" msgid "More options"
msgstr "" msgstr "יותר אפשרויות"
msgid "Add participant" msgid "Add participant"
msgstr "" msgstr "הוסף משתתפים"
msgid "Edit this participant" msgid "Edit this participant"
msgstr "" msgstr "ערוך את המשתתף"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "" msgstr "john.doe@example.com, mary.moe@site.com"
msgid "Send the invitations"
msgstr ""
msgid "Download" msgid "Download"
msgstr "" msgstr "הורד"
msgid "Disabled Project History" msgid "Disabled Project History"
msgstr "" msgstr "היסטורית פרויקט מושבתת"
msgid "Disabled Project History & IP Address Recording" msgid "Disabled Project History & IP Address Recording"
msgstr "" msgstr ""
@ -535,23 +559,18 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"disabling project history. You can\n" msgstr ""
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
"data-target=\"#confirm-erase\">clear project history</a> to remove " msgid "You can clear the project history to remove them."
"them.</i></p>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
@ -562,24 +581,24 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "" msgstr ""
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "" msgstr ""
msgid "Time" msgid "No history to erase"
msgstr "" msgstr ""
msgid "Event" msgid "Clear Project History"
msgstr "" msgstr ""
msgid "Time"
msgstr "זמן"
msgid "Event"
msgstr "אירוע"
msgid "IP address recording can be enabled on the settings page" msgid "IP address recording can be enabled on the settings page"
msgstr "" msgstr ""
@ -587,7 +606,7 @@ msgid "IP address recording can be disabled on the settings page"
msgstr "" msgstr ""
msgid "From IP" msgid "From IP"
msgstr "" msgstr "מכתובת IP"
#, python-format #, python-format
msgid "Project %(name)s added" msgid "Project %(name)s added"
@ -635,8 +654,14 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "משלם"
msgid "Amount" msgid "Amount"
msgstr "" msgstr "סכום"
msgid "Date"
msgstr "תאריך"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
@ -671,7 +696,7 @@ msgid "Participant %(name)s changed in an unknown way"
msgstr "" msgstr ""
msgid "Nothing to list" msgid "Nothing to list"
msgstr "" msgstr "אין מה להציג"
msgid "Someone probably cleared the project history." msgid "Someone probably cleared the project history."
msgstr "" msgstr ""
@ -680,7 +705,7 @@ msgid "Manage your shared <br />expenses, easily"
msgstr "" msgstr ""
msgid "Try out the demo" msgid "Try out the demo"
msgstr "" msgstr "נסו את הדמו"
msgid "You're sharing a house?" msgid "You're sharing a house?"
msgstr "" msgstr ""
@ -692,16 +717,16 @@ msgid "Simply sharing money with others?"
msgstr "" msgstr ""
msgid "We can help!" msgid "We can help!"
msgstr "" msgstr "אנחנו יכולים לעזור!"
msgid "Log in to an existing project" msgid "Log in to an existing project"
msgstr "" msgstr "התחבר לפרויקט קיים"
msgid "Log in" msgid "Log in"
msgstr "" msgstr "התחבר"
msgid "can't remember your password?" msgid "can't remember your password?"
msgstr "" msgstr "לא זוכרים את הסיסמה?"
msgid "Create" msgid "Create"
msgstr "" msgstr ""
@ -712,7 +737,7 @@ msgid ""
msgstr "" msgstr ""
msgid "Account manager" msgid "Account manager"
msgstr "" msgstr "מנהל החשבון"
msgid "Bills" msgid "Bills"
msgstr "" msgstr ""
@ -724,168 +749,182 @@ msgid "Statistics"
msgstr "" msgstr ""
msgid "Languages" msgid "Languages"
msgstr "" msgstr "שפות"
msgid "Projects" msgid "Projects"
msgstr "" msgstr "פרויקטים"
msgid "Start a new project" msgid "Start a new project"
msgstr "" msgstr "התחל פרוייקט חדש"
msgid "History" msgid "History"
msgstr "" msgstr "הסטוריה"
msgid "Settings" msgid "Settings"
msgstr "הגדרות"
msgid "RSS Feed"
msgstr "" msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "" msgstr "פרויקטים אחרים:"
msgid "switch to" msgid "switch to"
msgstr "" msgstr "שנה ל"
msgid "Dashboard" msgid "Dashboard"
msgstr "" msgstr ""
msgid "Logout" #, python-format
msgid "Please retry after %(date)s."
msgstr "" msgstr ""
msgid "Code" msgid "Code"
msgstr "" msgstr "קוד"
msgid "Mobile Application" msgid "Mobile Application"
msgstr "" msgstr "יישום לנייד"
msgid "Documentation" msgid "Documentation"
msgstr "" msgstr "דוקומנטציה"
msgid "Administation Dashboard" msgid "Administation Dashboard"
msgstr "" msgstr ""
msgid "Legal information" msgid "Legal information"
msgstr "" msgstr "מידע משפטי"
msgid "\"I hate money\" is free software" msgid "\"I hate money\" is free software"
msgstr "" msgstr "\"אני שונא כסף\" היא תוכנה חינמית"
msgid "you can contribute and improve it!" msgid "you can contribute and improve it!"
msgstr "" msgstr "אתה יכול לתרום ולשפר אותו!"
#, python-format #, python-format
msgid "%(amount)s each" msgid "%(amount)s each"
msgstr "" msgstr ""
msgid "you sure?" msgid "you sure?"
msgstr "" msgstr "האם אתה בטוח?"
msgid "Invite people" msgid "Invite people"
msgstr "" msgstr "הזמן אנשים"
msgid "You should start by adding participants"
msgstr ""
msgid "Add a new bill"
msgstr ""
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr "הוצאות ישנות"
msgid "When?" msgid "You should start by adding participants"
msgstr "" msgstr "כדאי להתחיל בהוספת משתמשים"
msgid "Who paid?" msgid "Add a new bill"
msgstr "" msgstr "הוסף הוצאה חדשה"
msgid "For what?" msgid "For what?"
msgstr "" msgstr "עבור מה?"
msgid "How much?"
msgstr ""
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "" msgstr "נוסף בתאריך %(date)s"
#, python-format #, python-format
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "" msgstr ""
msgid "delete"
msgstr "מחק"
msgid "No bills" msgid "No bills"
msgstr "" msgstr "אין הוצאות"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "" msgstr ""
msgid "You probably want to" msgid "Add your first bill"
msgstr "" msgstr ""
msgid "add a bill" #, fuzzy
msgstr "" msgid "Add the first participant"
msgstr "ערוך את המשתתף"
msgid "add participants"
msgstr ""
msgid "Password reminder" msgid "Password reminder"
msgstr "" msgstr "תזכורת סיסמה"
msgid "" 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 "נשלח לחשבונך לינק לאיפוס הסיסמה, אנא בדוק את תיבת הדוא\"ל שלך."
msgid "Return to home page" msgid "Return to home page"
msgstr "" msgstr "חזור לעמוד הבית"
msgid "Your projects" msgid "Your projects"
msgstr "" msgstr "הפרויקטים שלך"
msgid "Reset your password" msgid "Reset your password"
msgstr "" msgstr "אפס את סיסמתך"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "הזמן אנשים להצטרף לפרויקט"
msgid "Share an invitation link"
msgstr ""
msgid ""
"The easiest way to invite people is to give them the following invitation"
" link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr ""
msgid "Scan QR code"
msgstr "סרוק את הברקוד"
msgid "Use a mobile device with a compatible app."
msgstr "השתמש במכשיר נייד עם יישום תואם."
msgid "Send via Emails"
msgstr "שלח באמצעות דוא\"ל"
msgid ""
"Specify a list of email adresses (separated by comma) of people you want "
"to notify about the creation of this project. We will send them an email "
"with the invitation link."
msgstr "" msgstr ""
msgid "Share Identifier & code" msgid "Share Identifier & code"
msgstr "" msgstr "שתף מזהה וקוד"
msgid "" 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.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr "" msgstr ""
msgid "Identifier:" msgid "Identifier:"
msgstr "" msgstr "מזהה:"
msgid "Share the Link" #, fuzzy
msgstr "" msgid "Private code:"
msgstr "קוד פרטי"
msgid "You can directly share the following link via your prefered medium" msgid "the private code was defined when you created the project"
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 "" msgstr ""
msgid "Who pays?" msgid "Who pays?"
msgstr "" msgstr "מי משלם?"
msgid "To whom?" msgid "To whom?"
msgstr "" msgstr "למי?"
msgid "Who?" msgid "Who?"
msgstr "" msgstr "מי?"
msgid "Balance" msgid "Balance"
msgstr "" msgstr "מאזן"
msgid "deactivate" msgid "deactivate"
msgstr "" msgstr ""
@ -894,13 +933,114 @@ msgid "reactivate"
msgstr "" msgstr ""
msgid "Paid" msgid "Paid"
msgstr "" msgstr "שולם"
msgid "Spent" msgid "Spent"
msgstr "" msgstr ""
msgid "Expenses by Month" msgid "Expenses by Month"
msgstr "" msgstr "הוצאות לפי חודש"
msgid "Period" msgid "Period"
msgstr "" msgstr "תקופה"
#~ msgid "Import"
#~ msgstr "ייבא"
#~ msgid "Amount paid"
#~ msgstr "כמות ששולמה"
#~ msgid "Bills can't be null"
#~ msgstr "חשבונות לא יכולים להיות ריקים"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "מזהה הפרויקט הוא %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "פורמט JSON לא תקין"
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "trying to send the invitation emails."
#~ " Please check the email configuration "
#~ "of the server or contact the "
#~ "administrator."
#~ msgstr ""
#~ msgid "Are you sure?"
#~ msgstr ""
#~ msgid "Import JSON"
#~ msgstr "ייבא JSON"
#~ 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 "Send invites"
#~ msgstr "שלח הזמנות"
#~ msgid " show"
#~ msgstr ""
#~ msgid "Edit the project"
#~ msgstr ""
#~ msgid "You probably want to"
#~ msgstr "אתה כנראה רוצה"
#~ msgid "add a bill"
#~ msgstr ""
#~ msgid "add participants"
#~ msgstr "הוסף משתמשים"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr "אתה יכול לשתף את מזהה הפרויקט והקוד הפרטי באמצעות כל אמצעי תקשורת."
#~ msgid "Share the Link"
#~ msgstr "שתף את הלינק"
#~ msgid "You can directly share the following link via your prefered medium"
#~ 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 ""
#~ "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 with the invitation "
#~ "link."
#~ msgstr ""

View file

@ -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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2020-06-14 14:41+0000\n" "PO-Revision-Date: 2020-06-14 14:41+0000\n"
"Last-Translator: raghupalash <singhpalash0@gmail.com>\n" "Last-Translator: raghupalash <singhpalash0@gmail.com>\n"
"Language: hi\n" "Language: hi\n"
@ -15,6 +15,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "आपने अभी अभी अपने खर्चों को साझा करने के लिए '%(project)s' बनाया है"
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."
@ -25,6 +29,13 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "परियोजना का नाम" msgstr "परियोजना का नाम"
#, fuzzy
msgid "Current private code"
msgstr "निजी कोड"
msgid "Enter existing private code to edit project"
msgstr ""
#, fuzzy #, fuzzy
msgid "New private code" msgid "New private code"
msgstr "निजी कोड" msgstr "निजी कोड"
@ -47,16 +58,21 @@ msgstr "डिफ़ॉल्ट मुद्रा"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
#, fuzzy
msgid "Unknown error"
msgstr "अज्ञात परियोजना"
#, fuzzy
msgid "Invalid private code."
msgstr "निजी कोड"
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "पूर्व में निर्यात की गई JSON फ़ाइल आयात करें" msgstr ""
msgid "Import"
msgstr "आयात"
msgid "Project identifier" msgid "Project identifier"
msgstr "परियोजना पहचानकर्ता" msgstr "परियोजना पहचानकर्ता"
@ -88,14 +104,6 @@ msgstr ""
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "" msgstr ""
#, fuzzy
msgid "Unknown error"
msgstr "अज्ञात परियोजना"
#, fuzzy
msgid "Invalid private code."
msgstr "निजी कोड"
msgid "Get in" msgid "Get in"
msgstr "अंदर जाइये" msgstr "अंदर जाइये"
@ -120,17 +128,17 @@ msgstr "पासवर्ड पुष्टीकरण"
msgid "Reset password" msgid "Reset password"
msgstr "पासवर्ड रीसेट" msgstr "पासवर्ड रीसेट"
msgid "Date" msgid "When?"
msgstr "तारीख" msgstr "कब?"
msgid "What?" msgid "What?"
msgstr "क्या?" msgstr "क्या?"
msgid "Payer" msgid "Who paid?"
msgstr "भुगतानकर्ता" msgstr "किसने भुगतान किया?"
msgid "Amount paid" msgid "How much?"
msgstr "भुगतान की गई राशि" msgstr "कितना?"
msgid "Currency" msgid "Currency"
msgstr "मुद्रा" msgstr "मुद्रा"
@ -154,9 +162,6 @@ msgstr "जमा करें और एक नया जोड़ें"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "प्रोजेक्ट डिफ़ॉल्ट:%(currency)s" msgstr "प्रोजेक्ट डिफ़ॉल्ट:%(currency)s"
msgid "Bills can't be null"
msgstr "बिल शून्य नहीं हो सकते"
msgid "Name" msgid "Name"
msgstr "नाम" msgstr "नाम"
@ -180,13 +185,27 @@ msgstr "इस परियोजना में पहले से ही य
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "मंत्रण भेजें" msgstr "निमंत्रण भेजें"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "ईमेल %(email)s मान्य नहीं है" msgstr "ईमेल %(email)s मान्य नहीं है"
msgid "Logout"
msgstr "लॉग आउट"
msgid "Please check the email configuration of the server."
msgstr ""
#, fuzzy, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"क्षमा करें, आमंत्रण ईमेल भेजने का प्रयास करते समय कोई त्रुटि हुई। कृपया "
"सर्वर के ईमेल कॉन्फ़िगरेशन की जाँच करें या व्यवस्थापक से संपर्क करें।"
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "" msgstr ""
@ -214,7 +233,8 @@ msgstr ""
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "बहुत से विफल लॉगिन प्रयास, कृपया बाद में पुनः प्रयास करें।" msgstr "बहुत से विफल लॉगिन प्रयास, कृपया बाद में पुनः प्रयास करें।"
#, python-format #, python-format
@ -227,10 +247,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "यह निजी कोड सही नहीं है" msgstr "यह निजी कोड सही नहीं है"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "आपने अभी अभी अपने खर्चों को साझा करने के लिए '%(project)s' बनाया है"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "आपको अभी एक अनुस्मारक ईमेल भेजा गया है" msgstr "आपको अभी एक अनुस्मारक ईमेल भेजा गया है"
@ -241,14 +257,10 @@ msgstr ""
"हमने आपको एक अनुस्मारक ईमेल भेजने की कोशिश की, लेकिन कोई त्रुटि थी। आप " "हमने आपको एक अनुस्मारक ईमेल भेजने की कोशिश की, लेकिन कोई त्रुटि थी। आप "
"अभी भी सामान्य रूप से प्रोजेक्ट का उपयोग कर सकते हैं।" "अभी भी सामान्य रूप से प्रोजेक्ट का उपयोग कर सकते हैं।"
#, python-format #, fuzzy
msgid "The project identifier is %(project)s"
msgstr "प्रोजेक्ट पहचानकर्ता %(project)s है"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"क्षमा करें, पासवर्ड रीसेट निर्देशों के साथ आपको एक ईमेल भेजते समय कोई " "क्षमा करें, पासवर्ड रीसेट निर्देशों के साथ आपको एक ईमेल भेजते समय कोई "
"त्रुटि हुई थी। कृपया सर्वर के ईमेल कॉन्फ़िगरेशन की जाँच करें या " "त्रुटि हुई थी। कृपया सर्वर के ईमेल कॉन्फ़िगरेशन की जाँच करें या "
@ -266,23 +278,33 @@ msgstr "अज्ञात परियोजना"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "पासवर्ड सफलतापूर्वक रीसेट हो गया है।" msgstr "पासवर्ड सफलतापूर्वक रीसेट हो गया है।"
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "प्रोजेक्ट सफलतापूर्वक अपलोड किया गया" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "अमान्य JSON" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr "प्रोजेक्ट सफलतापूर्वक अपलोड किया गया"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "प्रोजेक्ट सफलतापूर्वक हटा दिया गया" msgstr "प्रोजेक्ट सफलतापूर्वक हटा दिया गया"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr ""
@ -292,10 +314,8 @@ msgstr ""
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "आपके निमंत्रण भेज दिए गए हैं" msgstr "आपके निमंत्रण भेज दिए गए हैं"
msgid "" #, fuzzy
"Sorry, there was an error while trying to send the invitation emails. " msgid "Sorry, there was an error while trying to send the invitation emails."
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"क्षमा करें, आमंत्रण ईमेल भेजने का प्रयास करते समय कोई त्रुटि हुई। कृपया " "क्षमा करें, आमंत्रण ईमेल भेजने का प्रयास करते समय कोई त्रुटि हुई। कृपया "
"सर्वर के ईमेल कॉन्फ़िगरेशन की जाँच करें या व्यवस्थापक से संपर्क करें।" "सर्वर के ईमेल कॉन्फ़िगरेशन की जाँच करें या व्यवस्थापक से संपर्क करें।"
@ -342,6 +362,10 @@ msgstr "बिल को हटा दिया गया है"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "बिल को संशोधित कर दिया गया है" msgstr "बिल को संशोधित कर दिया गया है"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
#, fuzzy #, fuzzy
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "प्रोजेक्ट इतिहास सक्षम करें" msgstr "प्रोजेक्ट इतिहास सक्षम करें"
@ -409,8 +433,9 @@ msgstr "कार्य"
msgid "edit" msgid "edit"
msgstr "संपादित करें" msgstr "संपादित करें"
msgid "delete" #, fuzzy
msgstr "हटाइये" msgid "Delete project"
msgstr "परियोजना संपादित करें"
msgid "show" msgid "show"
msgstr "प्रदर्शन" msgstr "प्रदर्शन"
@ -426,23 +451,13 @@ msgstr "मोबाइल एप्लीकेशन"
msgid "Get it on" msgid "Get it on"
msgstr "अंदर जाइये" msgstr "अंदर जाइये"
#, fuzzy
msgid "Are you sure?"
msgstr "आपको यकीन है?"
msgid "Edit project" msgid "Edit project"
msgstr "परियोजना संपादित करें" msgstr "परियोजना संपादित करें"
#, fuzzy #, fuzzy
msgid "Delete project" msgid "Import project"
msgstr "परियोजना संपादित करें" msgstr "परियोजना संपादित करें"
msgid "Import JSON"
msgstr "JSON को आयात करे"
msgid "Choose file"
msgstr "फ़ाइल चुनें"
msgid "Download project's data" msgid "Download project's data"
msgstr "प्रोजेक्ट का डेटा डाउनलोड करें" msgstr "प्रोजेक्ट का डेटा डाउनलोड करें"
@ -467,18 +482,28 @@ msgstr "रद्द करें"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "प्राइवेसी सेटिंग्स" msgstr "प्राइवेसी सेटिंग्स"
msgid "Edit the project" msgid "Save changes"
msgstr "प्रोजेक्ट संपादित करें" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
#, fuzzy
msgid "Import previously exported project"
msgstr "पूर्व में निर्यात की गई JSON फ़ाइल आयात करें"
msgid "Choose file"
msgstr "फ़ाइल चुनें"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "इस बिल को संपादित करें" msgstr "इस बिल को संपादित करें"
msgid "Add a bill" msgid "Add a bill"
msgstr "बिल जोड़ें" msgstr "बिल जोड़ें"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "सब" msgstr "सब"
@ -498,9 +523,6 @@ msgstr "प्रतिभागी जोड़ें"
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 "john.doe@example.com, mary.moe@site.com"
msgid "Send the invitations"
msgstr "निमंत्रण भेजें"
msgid "Download" msgid "Download"
msgstr "डाउनलोड" msgstr "डाउनलोड"
@ -572,36 +594,21 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n"
" <i>इस प्रोजेक्ट में इतिहास अक्षम है। नई कार्रवाइयां नीचे " #, fuzzy
"दिखाई नहीं देंगी। आप इतिहास को यहाँ से सक्षम कर सकते हैं</i>\n" msgid "You can enable history on the settings page."
" <a href=\"%(url)s\">सेटिंग्स पृष्ठ</a>\n" msgstr "आईपी पता रिकॉर्डिंग को सेटिंग पेज पर सक्षम किया जा सकता है"
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n"
" <i>नीचे दी गई तालिका परियोजना इतिहास को अक्षम करने से पहले " #, fuzzy
"दर्ज की गई कार्रवाइयों को दर्शाती है। आप उन्हें हटाने के लिए\n" msgid "You can clear the project history to remove them."
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" " msgstr "किसी ने शायद परियोजना के इतिहास को हटा दिया है।"
"data-target=\"#confirm-erase\">प्रोजेक्ट इतिहास हटा</a>सकते हैं।</i></p>"
"\n"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -613,18 +620,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "संग्रहीत IP पते हटाएं" msgstr "संग्रहीत IP पते हटाएं"
msgid "No history to erase"
msgstr "मिटाने के लिए कोई इतिहास नहीं है"
msgid "Clear Project History"
msgstr "प्रोजेक्ट इतिहास हटाएं"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "मिटाने के लिए कोई IP पते नहीं हैं" msgstr "मिटाने के लिए कोई IP पते नहीं हैं"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "संग्रहीत IP पते हटाएं" msgstr "संग्रहीत IP पते हटाएं"
msgid "No history to erase"
msgstr "मिटाने के लिए कोई इतिहास नहीं है"
msgid "Clear Project History"
msgstr "प्रोजेक्ट इतिहास हटाएं"
msgid "Time" msgid "Time"
msgstr "समय" msgstr "समय"
@ -686,9 +693,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "भुगतानकर्ता"
msgid "Amount" msgid "Amount"
msgstr "रकम" msgstr "रकम"
msgid "Date"
msgstr "तारीख"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "%(currency)s में राशि" msgstr "%(currency)s में राशि"
@ -791,6 +804,9 @@ msgstr "इतिहास"
msgid "Settings" msgid "Settings"
msgstr "सेटिंग्स" msgstr "सेटिंग्स"
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "अन्य परियोजनाएँ :" msgstr "अन्य परियोजनाएँ :"
@ -800,8 +816,9 @@ msgstr "पर स्विच करें"
msgid "Dashboard" msgid "Dashboard"
msgstr "डैशबोर्ड" msgstr "डैशबोर्ड"
msgid "Logout" #, python-format
msgstr "लॉग आउट" msgid "Please retry after %(date)s."
msgstr ""
msgid "Code" msgid "Code"
msgstr "कोड" msgstr "कोड"
@ -835,30 +852,21 @@ msgstr "आपको यकीन है?"
msgid "Invite people" msgid "Invite people"
msgstr "लोगों को निमंत्रण भेजें" msgstr "लोगों को निमंत्रण भेजें"
msgid "You should start by adding participants"
msgstr "शुरू करने के लिए प्रतिभागियों को जोड़ें"
msgid "Add a new bill"
msgstr "नया बिल जोड़ें"
msgid "Newer bills" msgid "Newer bills"
msgstr "नए बिल" msgstr "नए बिल"
msgid "Older bills" msgid "Older bills"
msgstr "पुराने बिल" msgstr "पुराने बिल"
msgid "When?" msgid "You should start by adding participants"
msgstr "कब?" msgstr "शुरू करने के लिए प्रतिभागियों को जोड़ें"
msgid "Who paid?" msgid "Add a new bill"
msgstr "किसने भुगतान किया?" msgstr "नया बिल जोड़ें"
msgid "For what?" msgid "For what?"
msgstr "किस लिए?" msgstr "किस लिए?"
msgid "How much?"
msgstr "कितना?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "%(date)s पर जोड़ा गया" msgstr "%(date)s पर जोड़ा गया"
@ -867,20 +875,22 @@ msgstr "%(date)s पर जोड़ा गया"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "%(excluded)s को छोड़ के बाकी सब" msgstr "%(excluded)s को छोड़ के बाकी सब"
msgid "delete"
msgstr "हटाइये"
msgid "No bills" msgid "No bills"
msgstr "कोई बिल नहीं" msgstr "कोई बिल नहीं"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "सूचि बनाने के लिए कुछ नहीं।" msgstr "सूचि बनाने के लिए कुछ नहीं।"
msgid "You probably want to" #, fuzzy
msgstr "आप शायद यह करना चाहते हैं" msgid "Add your first bill"
msgid "add a bill"
msgstr "बिल जोड़ें" msgstr "बिल जोड़ें"
msgid "add participants" #, fuzzy
msgstr "प्रतिभागियों को जोड़ें" msgid "Add the first participant"
msgstr "प्रतिभागी जोड़ें"
msgid "Password reminder" msgid "Password reminder"
msgstr "पासवर्ड अनुस्मारक" msgstr "पासवर्ड अनुस्मारक"
@ -904,39 +914,56 @@ msgstr "अपना पासवर्ड रीसेट करें"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "इस परियोजना से जुड़ने के लिए लोगों को आमंत्रित करें" msgstr "इस परियोजना से जुड़ने के लिए लोगों को आमंत्रित करें"
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "पहचानकर्ता और कोड साझा करें" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
"आप किसी भी संचार माध्यम से परियोजना पहचानकर्ता और निजी कोड साझा कर सकते "
"हैं।"
msgid "Identifier:" msgid "Scan QR code"
msgstr "पहचानकर्ता:" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr "लिंक साझा करें" msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "आप नीचे दिए गए लिंक को सीधे अपने पसंदीदा माध्यम से साझा कर सकते हैं"
msgid "Send via Emails" msgid "Send via Emails"
msgstr "ईमेल के माध्यम से भेजें" msgstr "ईमेल के माध्यम से भेजें"
#, fuzzy
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"उन ईमेल पतों की एक (अल्पविराम से अलग की गयी) सूची निर्दिष्ट करें जिन्हे " "उन ईमेल पतों की एक (अल्पविराम से अलग की गयी) सूची निर्दिष्ट करें जिन्हे "
"आप इस \n" "आप इस \n"
"\t\t बजट प्रबंधन परियोजना के निर्माण के बारे में सूचित करना चाहते हैं " "\t\t बजट प्रबंधन परियोजना के निर्माण के बारे में सूचित करना चाहते हैं "
"और हम उन्हें आपके लिए एक ईमेल भेजेंगे।" "और हम उन्हें आपके लिए एक ईमेल भेजेंगे।"
msgid "Share Identifier & code"
msgstr "पहचानकर्ता और कोड साझा करें"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr "पहचानकर्ता:"
#, fuzzy
msgid "Private code:"
msgstr "निजी कोड"
msgid "the private code was defined when you created the project"
msgstr ""
msgid "Who pays?" msgid "Who pays?"
msgstr "किसे भुगतान करना है?" msgstr "किसे भुगतान करना है?"
@ -1035,3 +1062,95 @@ msgstr "अवधि"
#~ msgid "People to notify" #~ msgid "People to notify"
#~ msgstr "सूचित किये जाने वाले लोग" #~ msgstr "सूचित किये जाने वाले लोग"
#~ msgid "Import"
#~ msgstr "आयात"
#~ msgid "Amount paid"
#~ msgstr "भुगतान की गई राशि"
#~ msgid "Bills can't be null"
#~ msgstr "बिल शून्य नहीं हो सकते"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "प्रोजेक्ट पहचानकर्ता %(project)s है"
#~ msgid "Invalid JSON"
#~ msgstr "अमान्य JSON"
#~ msgid "Are you sure?"
#~ msgstr "आपको यकीन है?"
#~ msgid "Import JSON"
#~ msgstr "JSON को आयात करे"
#~ 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>सकते हैं।</i></p>\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "आमंत्रण भेजें"
#~ msgid " show"
#~ msgstr "प्रदर्शन"
#~ msgid "Edit the project"
#~ msgstr "प्रोजेक्ट संपादित करें"
#~ msgid "You probably want to"
#~ msgstr "आप शायद यह करना चाहते हैं"
#~ msgid "add participants"
#~ msgstr "प्रतिभागियों को जोड़ें"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "आप किसी भी संचार माध्यम से "
#~ "परियोजना पहचानकर्ता और निजी कोड साझा "
#~ "कर सकते हैं।"
#~ msgid "Share the Link"
#~ msgstr "लिंक साझा करें"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr "आप नीचे दिए गए लिंक को सीधे अपने पसंदीदा माध्यम से साझा कर सकते हैं"

File diff suppressed because it is too large Load diff

View file

@ -1,21 +1,25 @@
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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2022-04-11 17:12+0000\n" "PO-Revision-Date: 2022-04-11 17:12+0000\n"
"Last-Translator: Santiago José Gutiérrez Llanos <gutierrezapata17@gmail.com>" "Last-Translator: Santiago José Gutiérrez Llanos "
"\n" "<gutierrezapata17@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"
"X-Generator: Weblate 4.12-dev\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Anda baru saja membuat %(project)s untuk membagikan harga Anda"
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."
@ -26,6 +30,13 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Nama proyek" msgstr "Nama proyek"
#, fuzzy
msgid "Current private code"
msgstr "Kode pribadi baru"
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "Kode pribadi baru" msgstr "Kode pribadi baru"
@ -45,8 +56,13 @@ msgid "Default Currency"
msgstr "Mata Uang Standar" msgstr "Mata Uang Standar"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr "Menetapkan mata uang default memungkinkan konversi mata uang antar tagihan"
"Menetapkan mata uang default memungkinkan konversi mata uang antar tagihan"
msgid "Unknown error"
msgstr "Kesalahan tidak diketahui"
msgid "Invalid private code."
msgstr "Kode pribadi tidak valid."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
@ -55,11 +71,8 @@ msgstr ""
"Proyek ini tidak dapat disetel ke 'tanpa mata uang' karena berisi tagihan" "Proyek ini tidak dapat disetel ke 'tanpa mata uang' karena berisi tagihan"
" dalam berbagai mata uang." " dalam berbagai mata uang."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Impor file JSON yang sudah diekspor sebelumnya" msgstr ""
msgid "Import"
msgstr "Impor"
msgid "Project identifier" msgid "Project identifier"
msgstr "Pengidentifikasi proyek" msgstr "Pengidentifikasi proyek"
@ -90,12 +103,6 @@ msgstr "Mohon, silahkan validasi captcha untuk melanjutkan."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Masukkan kode pribadi untuk mengkonfirmasi penghapusan" msgstr "Masukkan kode pribadi untuk mengkonfirmasi penghapusan"
msgid "Unknown error"
msgstr "Kesalahan tidak diketahui"
msgid "Invalid private code."
msgstr "Kode pribadi tidak valid."
msgid "Get in" msgid "Get in"
msgstr "Masuk" msgstr "Masuk"
@ -120,17 +127,17 @@ msgstr "Konfirmasi kata sandi"
msgid "Reset password" msgid "Reset password"
msgstr "Atur ulang kata sandi" msgstr "Atur ulang kata sandi"
msgid "Date" msgid "When?"
msgstr "Tanggal" msgstr "Kapan?"
msgid "What?" msgid "What?"
msgstr "Apa?" msgstr "Apa?"
msgid "Payer" msgid "Who paid?"
msgstr "Pembayar" msgstr "Siapa yang bayar?"
msgid "Amount paid" msgid "How much?"
msgstr "Jumlah bayar" msgstr "Berapa banyak?"
msgid "Currency" msgid "Currency"
msgstr "Mata Uang" msgstr "Mata Uang"
@ -154,9 +161,6 @@ msgstr "Ajukan dan tambah yang baru"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Default proyek: %(currency)s" msgstr "Default proyek: %(currency)s"
msgid "Bills can't be null"
msgstr "Tagihan tidak boleh kosong"
msgid "Name" msgid "Name"
msgstr "Nama" msgstr "Nama"
@ -178,13 +182,27 @@ msgstr "Proyek ini sudah mempunyai /ada anggota ini"
msgid "People to notify" msgid "People to notify"
msgstr "Orang yang akan dinotifikasi" msgstr "Orang yang akan dinotifikasi"
msgid "Send invites" msgid "Send the invitations"
msgstr "Kirim undangan" msgstr "Kirim undangan"
#, python-format #, python-format
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 "Logout"
msgstr "Keluar"
msgid "Please check the email configuration of the server."
msgstr ""
#, fuzzy, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Maaf, ada galat saat mencoba mengirim email undangan. Silakan periksa "
"konfigurasi email peladen atau hubungi administrator."
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} dan {dual_object_1}" msgstr "{dual_object_0} dan {dual_object_1}"
@ -212,7 +230,8 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix}:1<br />{errors}" msgstr "{prefix}:1<br />{errors}"
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "Terlalu banyak percobaan masuk, silakan coba lagi nanti." msgstr "Terlalu banyak percobaan masuk, silakan coba lagi nanti."
#, python-format #, python-format
@ -225,10 +244,6 @@ msgstr "Token yang disediakan tidak valid"
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Kode pribadi ini tidak benar" msgstr "Kode pribadi ini tidak benar"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Anda baru saja membuat %(project)s untuk membagikan harga Anda"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "Email pengingat baru saja dikirimkan kepada Anda" msgstr "Email pengingat baru saja dikirimkan kepada Anda"
@ -239,14 +254,10 @@ msgstr ""
"Kami telah mengirimi Anda email pengingat, tetapi ada kesalahan. Anda " "Kami telah mengirimi Anda email pengingat, tetapi ada kesalahan. Anda "
"masih dapat menggunakan proyek secara normal." "masih dapat menggunakan proyek secara normal."
#, python-format #, fuzzy
msgid "The project identifier is %(project)s"
msgstr "Pengidentifikasi proyek adalah %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"Maaf, ada galat saat mengirim email berisi instruksi pengaturan ulang " "Maaf, ada galat saat mengirim email berisi instruksi pengaturan ulang "
"kata sandi. Silakan periksa konfigurasi email peladen atau hubungi " "kata sandi. Silakan periksa konfigurasi email peladen atau hubungi "
@ -264,23 +275,33 @@ 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" msgid "Project settings have been changed successfully."
msgstr "Proyek berhasil diunggah" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "JSON tidak valid" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr "Proyek berhasil diunggah"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "Proyek berhasil dihapus" msgstr "Proyek berhasil dihapus"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "Anda telah diundang untuk membagikan harga Anda untuk %(project)s" msgstr "Anda telah diundang untuk membagikan harga Anda untuk %(project)s"
@ -288,10 +309,8 @@ msgstr "Anda telah diundang untuk membagikan harga Anda untuk %(project)s"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "Undangan Anda telah dikirim" msgstr "Undangan Anda telah dikirim"
msgid "" #, fuzzy
"Sorry, there was an error while trying to send the invitation emails. " msgid "Sorry, there was an error while trying to send the invitation emails."
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Maaf, ada galat saat mencoba mengirim email undangan. Silakan periksa " "Maaf, ada galat saat mencoba mengirim email undangan. Silakan periksa "
"konfigurasi email peladen atau hubungi administrator." "konfigurasi email peladen atau hubungi administrator."
@ -338,6 +357,10 @@ msgstr "Tagihan telah dihapus"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "Tagihan telah diperbarui" msgstr "Tagihan telah diperbarui"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Kesalahan saat menghapus riwayat proyek" msgstr "Kesalahan saat menghapus riwayat proyek"
@ -398,8 +421,8 @@ msgstr "Aksi"
msgid "edit" msgid "edit"
msgstr "ubah" msgstr "ubah"
msgid "delete" msgid "Delete project"
msgstr "hapus" msgstr "Hapus proyek"
msgid "show" msgid "show"
msgstr "tampilkan" msgstr "tampilkan"
@ -413,20 +436,12 @@ msgstr "Unduh Aplikasi Seluler"
msgid "Get it on" msgid "Get it on"
msgstr "Dapatkan di" msgstr "Dapatkan di"
msgid "Are you sure?"
msgstr "Apakah Anda yakin?"
msgid "Edit project" msgid "Edit project"
msgstr "Ubah proyek" msgstr "Ubah proyek"
msgid "Delete project" #, fuzzy
msgstr "Hapus proyek" msgid "Import project"
msgstr "Ubah proyek"
msgid "Import JSON"
msgstr "Impor JSON"
msgid "Choose file"
msgstr "Pilih berkas"
msgid "Download project's data" msgid "Download project's data"
msgstr "Unduh data proyek" msgstr "Unduh data proyek"
@ -452,18 +467,28 @@ msgstr "Batalkan"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Pengaturan Privasi" msgstr "Pengaturan Privasi"
msgid "Edit the project" msgid "Save changes"
msgstr "Ubah proyek" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
#, fuzzy
msgid "Import previously exported project"
msgstr "Impor file JSON yang sudah diekspor sebelumnya"
msgid "Choose file"
msgstr "Pilih berkas"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Ubah tagihan ini" msgstr "Ubah tagihan ini"
msgid "Add a bill" msgid "Add a bill"
msgstr "Tambah tagihan" msgstr "Tambah tagihan"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "Semua orang" msgstr "Semua orang"
@ -482,9 +507,6 @@ msgstr "Sunting anggota ini"
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 "john.doe@example.com, mary.moe@site.com"
msgid "Send the invitations"
msgstr "Kirim undangan"
msgid "Download" msgid "Download"
msgstr "Unduh" msgstr "Unduh"
@ -555,37 +577,21 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n"
" <i> Proyek ini memiliki riwayat yang dinonaktifkan. Tindakan " #, fuzzy
"baru tidak akan muncul di bawah ini. Anda dapat mengaktifkan riwayat " msgid "You can enable history on the settings page."
"pada</i>\n" msgstr "Perekaman alamat IP dapat diaktifkan di halaman pengaturan"
" <a href=\"%(url)s\">halaman pengaturan</a>\n"
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n"
" <i> Tabel di bawah mencerminkan tindakan yang direkam sebelum" #, fuzzy
" menonaktifkan riwayat proyek. Anda bisa\n" msgid "You can clear the project history to remove them."
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" " msgstr "Seseorang mungkin membersihkan riwayat proyek."
"data-target=\"#confirm-erase\"> membersihkan riwayat proyek </a> untuk "
"menghapusnya. </i> </ p >\n"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -597,18 +603,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Hapus alamat IP yang disimpan" msgstr "Hapus alamat IP yang disimpan"
msgid "No history to erase"
msgstr "Tidak ada riwayat untuk dihapus"
msgid "Clear Project History"
msgstr "Bersihkan Riwayat Proyek"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "Tidak ada Alamat IP untuk dihapus" msgstr "Tidak ada Alamat IP untuk dihapus"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Hapus alamat IP yang disimpan" msgstr "Hapus alamat IP yang disimpan"
msgid "No history to erase"
msgstr "Tidak ada riwayat untuk dihapus"
msgid "Clear Project History"
msgstr "Bersihkan Riwayat Proyek"
msgid "Time" msgid "Time"
msgstr "Waktu" msgstr "Waktu"
@ -670,9 +676,15 @@ msgstr "Tagihan %(name)s diganti ke %(new_description)s"
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "Pengguna %(name)s: berat berubah dari %(old_weight)s ke %(new_weight)s" msgstr "Pengguna %(name)s: berat berubah dari %(old_weight)s ke %(new_weight)s"
msgid "Payer"
msgstr "Pembayar"
msgid "Amount" msgid "Amount"
msgstr "Jumlah" msgstr "Jumlah"
msgid "Date"
msgstr "Tanggal"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Jumlah dalam %(currency)s" msgstr "Jumlah dalam %(currency)s"
@ -775,6 +787,9 @@ msgstr "Riwayat"
msgid "Settings" msgid "Settings"
msgstr "Pengaturan" msgstr "Pengaturan"
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "Proyek lainnya:" msgstr "Proyek lainnya:"
@ -784,8 +799,9 @@ msgstr "ganti ke"
msgid "Dashboard" msgid "Dashboard"
msgstr "Dasbor" msgstr "Dasbor"
msgid "Logout" #, python-format
msgstr "Keluar" msgid "Please retry after %(date)s."
msgstr ""
msgid "Code" msgid "Code"
msgstr "Kode" msgstr "Kode"
@ -818,30 +834,21 @@ msgstr "Anda yakin?"
msgid "Invite people" msgid "Invite people"
msgstr "Undang orang" msgstr "Undang orang"
msgid "You should start by adding participants"
msgstr "Anda harus mulai dengan menambahkan partisipan"
msgid "Add a new bill"
msgstr "Tambah tagihan baru"
msgid "Newer bills" msgid "Newer bills"
msgstr "Tagihan terbaru" msgstr "Tagihan terbaru"
msgid "Older bills" msgid "Older bills"
msgstr "Tagihan terdahulu" msgstr "Tagihan terdahulu"
msgid "When?" msgid "You should start by adding participants"
msgstr "Kapan?" msgstr "Anda harus mulai dengan menambahkan partisipan"
msgid "Who paid?" msgid "Add a new bill"
msgstr "Siapa yang bayar?" msgstr "Tambah tagihan baru"
msgid "For what?" msgid "For what?"
msgstr "Untuk apa?" msgstr "Untuk apa?"
msgid "How much?"
msgstr "Berapa banyak?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Ditambahkan pada %(date)s" msgstr "Ditambahkan pada %(date)s"
@ -850,20 +857,22 @@ msgstr "Ditambahkan pada %(date)s"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Semua orang kecuali %(excluded)s" msgstr "Semua orang kecuali %(excluded)s"
msgid "delete"
msgstr "hapus"
msgid "No bills" msgid "No bills"
msgstr "Tidak ada tagihan" msgstr "Tidak ada tagihan"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Belum ada untuk didaftarkan." msgstr "Belum ada untuk didaftarkan."
msgid "You probably want to" #, fuzzy
msgstr "Anda mungkin menginginkan" msgid "Add your first bill"
msgid "add a bill"
msgstr "tambah tagihan" msgstr "tambah tagihan"
msgid "add participants" #, fuzzy
msgstr "tambah partisipan" msgid "Add the first participant"
msgstr "Sunting anggota ini"
msgid "Password reminder" msgid "Password reminder"
msgstr "Pengingat kata sandi" msgstr "Pengingat kata sandi"
@ -887,41 +896,56 @@ msgstr "Atur ulang kata sandi Anda"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Undang orang untuk bergabung dalam proyek ini" msgstr "Undang orang untuk bergabung dalam proyek ini"
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "Bagikan ID & kode" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
"Anda bisa membagikan ID proyek dan kode pribadi dengan cara komunikasi "
"apapun."
msgid "Identifier:" msgid "Scan QR code"
msgstr "ID:" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr "Bagikan tautan"
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"
msgid "Send via Emails" msgid "Send via Emails"
msgstr "Kirim melalui surel" msgstr "Kirim melalui surel"
#, fuzzy
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"Spesifikkan daftar alamat surel (dipisah dengan koma) yang akan Anda " "Spesifikkan daftar alamat surel (dipisah dengan koma) yang akan Anda "
"kirim pemberitahuan tentang\n" "kirim pemberitahuan tentang\n"
" pembuatan dari manajemen anggaran proyek ini dan kami " " pembuatan dari manajemen anggaran proyek ini dan kami "
"akan memngirim mereka sebuah surel." "akan memngirim mereka sebuah surel."
msgid "Share Identifier & code"
msgstr "Bagikan ID & kode"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr "ID:"
#, fuzzy
msgid "Private code:"
msgstr "Kode pribadi"
msgid "the private code was defined when you created the project"
msgstr ""
msgid "Who pays?" msgid "Who pays?"
msgstr "Siapa membayar?" msgstr "Siapa membayar?"
@ -1046,3 +1070,99 @@ msgstr "Periode"
#~ msgid "People to notify" #~ msgid "People to notify"
#~ msgstr "Orang yang akan diberi pemberitahuan" #~ msgstr "Orang yang akan diberi pemberitahuan"
#~ msgid "Import"
#~ msgstr "Impor"
#~ msgid "Amount paid"
#~ msgstr "Jumlah bayar"
#~ msgid "Bills can't be null"
#~ msgstr "Tagihan tidak boleh kosong"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "Pengidentifikasi proyek adalah %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "JSON tidak valid"
#~ msgid "Are you sure?"
#~ msgstr "Apakah Anda yakin?"
#~ msgid "Import JSON"
#~ msgstr "Impor JSON"
#~ 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> Proyek ini memiliki "
#~ "riwayat yang dinonaktifkan. Tindakan baru "
#~ "tidak akan muncul di bawah ini. "
#~ "Anda dapat mengaktifkan riwayat pada</i>\n"
#~ ""
#~ " <a href=\"%(url)s\">halaman pengaturan</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> Tabel di bawah "
#~ "mencerminkan tindakan yang direkam sebelum "
#~ "menonaktifkan riwayat proyek. Anda bisa\n"
#~ ""
#~ " <a href=\"#\" data-"
#~ "toggle=\"modal\" data-keyboard=\"false\" data-"
#~ "target=\"#confirm-erase\"> membersihkan riwayat "
#~ "proyek </a> untuk menghapusnya. </i> </"
#~ " p >\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "Kirim undangan"
#~ msgid " show"
#~ msgstr "tampilkan"
#~ msgid "Edit the project"
#~ msgstr "Ubah proyek"
#~ msgid "You probably want to"
#~ msgstr "Anda mungkin menginginkan"
#~ msgid "add participants"
#~ msgstr "tambah partisipan"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "Anda bisa membagikan ID proyek dan "
#~ "kode pribadi dengan cara komunikasi "
#~ "apapun."
#~ msgid "Share the Link"
#~ msgstr "Bagikan tautan"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr ""
#~ "Anda bisa membagikan tautan secara "
#~ "langsung melalui media yang Anda "
#~ "inginkan"

File diff suppressed because it is too large Load diff

View file

@ -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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2020-11-11 16:28+0000\n" "PO-Revision-Date: 2020-11-11 16:28+0000\n"
"Last-Translator: Jwen921 <yangjingwen0921@gmail.com>\n" "Last-Translator: Jwen921 <yangjingwen0921@gmail.com>\n"
"Language: ja\n" "Language: ja\n"
@ -15,6 +15,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "費用を共有するため、%(project)sが作られました"
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."
@ -23,6 +27,13 @@ msgstr "無効な入力です。数字と「+ - * / 」の演算子しか入力
msgid "Project name" msgid "Project name"
msgstr "プロジェクトの名前" msgstr "プロジェクトの名前"
#, fuzzy
msgid "Current private code"
msgstr "暗証コード"
msgid "Enter existing private code to edit project"
msgstr ""
#, fuzzy #, fuzzy
msgid "New private code" msgid "New private code"
msgstr "暗証コード" msgstr "暗証コード"
@ -45,16 +56,21 @@ msgstr "初期設定にする通貨"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
#, fuzzy
msgid "Unknown error"
msgstr "未知のプロジェクト"
#, fuzzy
msgid "Invalid private code."
msgstr "暗証コード"
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "以前のJSONファイルをインポートする" msgstr ""
msgid "Import"
msgstr "インポート"
msgid "Project identifier" msgid "Project identifier"
msgstr "プロジェクトの名前" msgstr "プロジェクトの名前"
@ -84,14 +100,6 @@ msgstr ""
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "" msgstr ""
#, fuzzy
msgid "Unknown error"
msgstr "未知のプロジェクト"
#, fuzzy
msgid "Invalid private code."
msgstr "暗証コード"
msgid "Get in" msgid "Get in"
msgstr "入る" msgstr "入る"
@ -116,17 +124,17 @@ msgstr "パスワードの確認"
msgid "Reset password" msgid "Reset password"
msgstr "パスワードの再設定" msgstr "パスワードの再設定"
msgid "Date" msgid "When?"
msgstr "日付" msgstr "いつ?"
msgid "What?" msgid "What?"
msgstr "何ですか?" msgstr "何ですか?"
msgid "Payer" msgid "Who paid?"
msgstr "支払人" msgstr "誰が支払った?"
msgid "Amount paid" msgid "How much?"
msgstr "支払額" msgstr "いくら?"
msgid "Currency" msgid "Currency"
msgstr "通貨" msgstr "通貨"
@ -150,9 +158,6 @@ msgstr "確認して、新しいのを作成します"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "初期プロジェクト: %(currency)s" msgstr "初期プロジェクト: %(currency)s"
msgid "Bills can't be null"
msgstr "数値を空値にしてはいけません"
msgid "Name" msgid "Name"
msgstr "名前" msgstr "名前"
@ -176,13 +181,25 @@ msgstr "プロジェクトはすでにこのメンバーを含めています"
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "招待状を出す" msgstr "招待状を送る"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "メールアドレス%(email)sは無効" msgstr "メールアドレス%(email)sは無効"
msgid "Logout"
msgstr "ログアウト"
msgid "Please check the email configuration of the server."
msgstr ""
#, fuzzy, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr "申し訳ございませんが、招待メールを送ったとき、エラーが発生しました。メールアドレスを再度チェックするかまたは管理者に連絡ください。"
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "" msgstr ""
@ -210,7 +227,8 @@ msgstr ""
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "何度もログインに失敗したので、時間をおいてから再度ログインして下さい。" msgstr "何度もログインに失敗したので、時間をおいてから再度ログインして下さい。"
#, python-format #, python-format
@ -223,10 +241,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "私用コードは正しくない" msgstr "私用コードは正しくない"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "費用を共有するため、%(project)sが作られました"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "催促メールがただいまあなたに送りました" msgstr "催促メールがただいまあなたに送りました"
@ -235,14 +249,10 @@ msgid ""
"still use the project normally." "still use the project normally."
msgstr "催促メールを送った時、エラーが発生しました。このプロジェクトはまだ使えます。" msgstr "催促メールを送った時、エラーが発生しました。このプロジェクトはまだ使えます。"
#, python-format #, fuzzy
msgid "The project identifier is %(project)s"
msgstr "プロジェクト名は%(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "申し訳ございませんが、パスワード再設定の説明メールを送った時、エラーが発生しました。メールアドレスを一度確認してまたは管理者に連絡してください。" msgstr "申し訳ございませんが、パスワード再設定の説明メールを送った時、エラーが発生しました。メールアドレスを一度確認してまたは管理者に連絡してください。"
msgid "No token provided" msgid "No token provided"
@ -257,23 +267,33 @@ msgstr "未知のプロジェクト"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "パスワードを再設定できました。" msgstr "パスワードを再設定できました。"
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "プロジェクトをアップロードできました" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "無効なJSON" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr "プロジェクトをアップロードできました"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "プロジェクトを削除できました" msgstr "プロジェクトを削除できました"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "%(project)sの費用を共有すると、あなたが誘われた" msgstr "%(project)sの費用を共有すると、あなたが誘われた"
@ -281,10 +301,8 @@ msgstr "%(project)sの費用を共有すると、あなたが誘われた"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "あなたの招待状が送られました" msgstr "あなたの招待状が送られました"
msgid "" #, fuzzy
"Sorry, there was an error while trying to send the invitation emails. " msgid "Sorry, there was an error while trying to send the invitation emails."
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "申し訳ございませんが、招待メールを送ったとき、エラーが発生しました。メールアドレスを再度チェックするかまたは管理者に連絡ください。" msgstr "申し訳ございませんが、招待メールを送ったとき、エラーが発生しました。メールアドレスを再度チェックするかまたは管理者に連絡ください。"
#, python-format #, python-format
@ -327,6 +345,10 @@ msgstr "明細が削除されました"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "明細が変更されました" msgstr "明細が変更されました"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
#, fuzzy #, fuzzy
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "プロジェクトの歴史を有効にする" msgstr "プロジェクトの歴史を有効にする"
@ -392,8 +414,9 @@ msgstr "操作"
msgid "edit" msgid "edit"
msgstr "編集" msgstr "編集"
msgid "delete" #, fuzzy
msgstr "削除" msgid "Delete project"
msgstr "プロジェクトを編集する"
msgid "show" msgid "show"
msgstr "表示" msgstr "表示"
@ -409,23 +432,13 @@ msgstr "携帯アプリ"
msgid "Get it on" msgid "Get it on"
msgstr "入る" msgstr "入る"
#, fuzzy
msgid "Are you sure?"
msgstr "確認?"
msgid "Edit project" msgid "Edit project"
msgstr "プロジェクトを編集する" msgstr "プロジェクトを編集する"
#, fuzzy #, fuzzy
msgid "Delete project" msgid "Import project"
msgstr "プロジェクトを編集する" msgstr "プロジェクトを編集する"
msgid "Import JSON"
msgstr "JSONを導入する"
msgid "Choose file"
msgstr "ファイルを選択する"
msgid "Download project's data" msgid "Download project's data"
msgstr "プロジェクトのデータをダウンロードする" msgstr "プロジェクトのデータをダウンロードする"
@ -450,18 +463,28 @@ msgstr "キャンセル"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "プライバシーの設定" msgstr "プライバシーの設定"
msgid "Edit the project" msgid "Save changes"
msgstr "プロジェクトを編集する" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
#, fuzzy
msgid "Import previously exported project"
msgstr "以前のJSONファイルをインポートする"
msgid "Choose file"
msgstr "ファイルを選択する"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "明細を編集する" msgstr "明細を編集する"
msgid "Add a bill" msgid "Add a bill"
msgstr "新しい明細書を追加する" msgstr "新しい明細書を追加する"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "皆" msgstr "皆"
@ -481,9 +504,6 @@ msgstr "参加者を追加する"
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 "john.doe@example.com, mary.moe@site.com"
msgid "Send the invitations"
msgstr "招待状を送る"
msgid "Download" msgid "Download"
msgstr "ダウンロードする" msgstr "ダウンロードする"
@ -551,33 +571,21 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n"
" <i>このプロジェクトの歴史は操作できません。新しい操作は下に出ません。</i>で歴史を操作可能にすることができます。\n" #, fuzzy
"<a href=\"%(url)s\">設定ページ</a>\n" msgid "You can enable history on the settings page."
" " msgstr "設定ページでIPアドレス記録を編集可能にすることができる"
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n"
" <i>下の表では操作不可になる前に、プロジェクトの歴史に対して記録された操作が反映されています。…できます。\n" #, fuzzy
"<a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" data-target" msgid "You can clear the project history to remove them."
"=\"#confirm-erase\">プロジェクトの歴史を取り除く</a> で取り除きます.</i></p>\n" msgstr "プロジェクトの歴史が誰かに取り除かれたかもしれません。"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -587,18 +595,18 @@ msgstr "このプロジェクトのIP記録が操作できない一方、下の
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "保存されたIPアドレスを削除する" msgstr "保存されたIPアドレスを削除する"
msgid "No history to erase"
msgstr "削除できる歴史はない"
msgid "Clear Project History"
msgstr "プロジェクトの歴史を取り除く"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "削除できるIPアドレスはない" msgstr "削除できるIPアドレスはない"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "保存されたIPアドレスを削除する" msgstr "保存されたIPアドレスを削除する"
msgid "No history to erase"
msgstr "削除できる歴史はない"
msgid "Clear Project History"
msgstr "プロジェクトの歴史を取り除く"
msgid "Time" msgid "Time"
msgstr "時間" msgstr "時間"
@ -660,9 +668,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "支払人"
msgid "Amount" msgid "Amount"
msgstr "金額" msgstr "金額"
msgid "Date"
msgstr "日付"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "%(currency)sでの金額" msgstr "%(currency)sでの金額"
@ -763,6 +777,9 @@ msgstr "歴史"
msgid "Settings" msgid "Settings"
msgstr "設定" msgstr "設定"
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "他のプロジェクト:" msgstr "他のプロジェクト:"
@ -772,8 +789,9 @@ msgstr "…に切り替える"
msgid "Dashboard" msgid "Dashboard"
msgstr "ダッシュボード" msgstr "ダッシュボード"
msgid "Logout" #, python-format
msgstr "ログアウト" msgid "Please retry after %(date)s."
msgstr ""
msgid "Code" msgid "Code"
msgstr "コード" msgstr "コード"
@ -807,30 +825,21 @@ msgstr "確認?"
msgid "Invite people" msgid "Invite people"
msgstr "人を誘う" msgstr "人を誘う"
msgid "You should start by adding participants"
msgstr "参加者を追加して始めましょう"
msgid "Add a new bill"
msgstr "新しい明細を追加する"
msgid "Newer bills" msgid "Newer bills"
msgstr "もっと新しい明細" msgstr "もっと新しい明細"
msgid "Older bills" msgid "Older bills"
msgstr "もっと古い明細" msgstr "もっと古い明細"
msgid "When?" msgid "You should start by adding participants"
msgstr "いつ?" msgstr "参加者を追加して始めましょう"
msgid "Who paid?" msgid "Add a new bill"
msgstr "誰が支払った?" msgstr "新しい明細を追加する"
msgid "For what?" msgid "For what?"
msgstr "何のため?" msgstr "何のため?"
msgid "How much?"
msgstr "いくら?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "%(date)sに追加された" msgstr "%(date)sに追加された"
@ -839,19 +848,21 @@ msgstr "%(date)sに追加された"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "%(excluded)s以外にみんな" msgstr "%(excluded)s以外にみんな"
msgid "delete"
msgstr "削除"
msgid "No bills" msgid "No bills"
msgstr "明細なし" msgstr "明細なし"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "表示できるものはありません。" msgstr "表示できるものはありません。"
msgid "You probably want to" #, fuzzy
msgstr "…したいかもしれない" msgid "Add your first bill"
msgid "add a bill"
msgstr "明細を追加する" msgstr "明細を追加する"
msgid "add participants" #, fuzzy
msgid "Add the first participant"
msgstr "参加者を追加する" msgstr "参加者を追加する"
msgid "Password reminder" msgid "Password reminder"
@ -874,34 +885,53 @@ msgstr "パスワードを再設定する"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "他人をこのプロジェクトに招待する" msgstr "他人をこのプロジェクトに招待する"
msgid "Share an invitation link"
msgstr ""
msgid ""
"The easiest way to invite people is to give them the following invitation"
" link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr ""
msgid "Scan QR code"
msgstr ""
msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "Send via Emails"
msgstr "メールで送る"
#, fuzzy
msgid ""
"Specify a list of email adresses (separated by comma) of people you want "
"to notify about the creation of this project. We will send them an email "
"with the invitation link."
msgstr ""
"…を知らせたいメールアドレスのリストを特定する(カンマ区切り)\n"
"彼らにこの予算管理プロジェクトの作成をメールでお知らせします。"
msgid "Share Identifier & code" msgid "Share Identifier & code"
msgstr "名前とコードを共有する" msgstr "名前とコードを共有する"
msgid "" 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.<br />Anyone with the private code will have access "
msgstr "プロジェクト名と私用コードは何の方法でも共有できます。" "to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:" msgid "Identifier:"
msgstr "名前:" msgstr "名前:"
msgid "Share the Link" #, fuzzy
msgstr "リンクを共有する" msgid "Private code:"
msgstr "暗証コード"
msgid "You can directly share the following link via your prefered medium" msgid "the private code was defined when you created the project"
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 "" msgstr ""
"…を知らせたいメールアドレスのリストを特定する(カンマ区切り)\n"
"彼らにこの予算管理プロジェクトの作成をメールでお知らせします。"
msgid "Who pays?" msgid "Who pays?"
msgstr "誰が支払った?" msgstr "誰が支払った?"
@ -998,3 +1028,85 @@ msgstr "期間"
#~ msgid "People to notify" #~ msgid "People to notify"
#~ msgstr "知らせたい人" #~ msgstr "知らせたい人"
#~ msgid "Import"
#~ msgstr "インポート"
#~ msgid "Amount paid"
#~ msgstr "支払額"
#~ msgid "Bills can't be null"
#~ msgstr "数値を空値にしてはいけません"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "プロジェクト名は%(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "無効なJSON"
#~ msgid "Are you sure?"
#~ msgstr "確認?"
#~ msgid "Import JSON"
#~ msgstr "JSONを導入する"
#~ 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> で取り除きます.</i></p>\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "招待状を出す"
#~ msgid " show"
#~ msgstr "表示"
#~ msgid "Edit the project"
#~ msgstr "プロジェクトを編集する"
#~ msgid "You probably want to"
#~ msgstr "…したいかもしれない"
#~ msgid "add participants"
#~ msgstr "参加者を追加する"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr "プロジェクト名と私用コードは何の方法でも共有できます。"
#~ msgid "Share the Link"
#~ msgstr "リンクを共有する"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr "好きの手段で以下のリンクを直接に共有できる"

View file

@ -1,20 +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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2021-10-17 04:56+0000\n" "PO-Revision-Date: 2023-09-16 10:59+0000\n"
"Last-Translator: a-g-rao <athrigrao@gmail.com>\n" "Last-Translator: Baptiste <weblate@bitsofnetworks.org>\n"
"Language-Team: Kannada <https://hosted.weblate.org/projects/i-hate-money/"
"i-hate-money/kn/>\n"
"Language: kn\n" "Language: kn\n"
"Language-Team: Kannada <https://hosted.weblate.org/projects/i-hate-"
"money/i-hate-money/kn/>\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"
"X-Generator: Weblate 5.0.2\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
"ನೀವು ನಿಮ್ಮ ಖರ್ಚು/ವೆಚ್ಚವನ್ನು ಹಂಚಿಕೊಳ್ಳಲು %(project)s ಯೋಜನೆಯನ್ನು "
"ಸೃಷ್ಟಿಸಿದ್ದೀರಿ"
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."
@ -25,11 +31,17 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "ಯೋಜನೆಯ ಹೆಸರು" msgstr "ಯೋಜನೆಯ ಹೆಸರು"
msgid "Current private code"
msgstr "ಪ್ರಸ್ತುತ ಸಂಕೇತಪದ"
msgid "Enter existing private code to edit project"
msgstr "ಯೋಜನೆಯನ್ನು ಪರಿಷ್ಕರಿಸಲು ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಸಂಕೇತಪದವನ್ನು ನಮೂದಿಸಿ"
msgid "New private code" msgid "New private code"
msgstr "ಹೊಸ ಸಂಕೇತಪದ" msgstr "ಹೊಸ ಸಂಕೇತಪದ"
msgid "Enter a new code if you want to change it" msgid "Enter a new code if you want to change it"
msgstr "ಸಂಕೇತಪದ ಬದಲಾಯಿಸಬೇಕೆಂದರೆ ನಮೂದಿಸಿ." msgstr "ಸಂಕೇತಪದ ಬದಲಾಯಿಸಬೇಕೆಂದರೆ ನಮೂದಿಸಿ"
msgid "Email" msgid "Email"
msgstr "ಮಿನ್ನಂಚೆ" msgstr "ಮಿನ್ನಂಚೆ"
@ -41,24 +53,31 @@ msgid "Use IP tracking for project history"
msgstr "" msgstr ""
msgid "Default Currency" msgid "Default Currency"
msgstr "" msgstr "ಪುರ್ವನಿಯೋಜಿತ ಕರನ್ಸಿ"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
"ಪುರ್ವನಿಯೋಜಿತ ಕರನ್ಸಿಯನ್ನು ನಮೋದಿಸುವುದರಿಂದ ರಶೀದಿಗಳ ನಡುವೆ ಕರನ್ಸಿ ಪರಿವರ್ತನೆಯನ್ನು "
"ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ"
msgid "Unknown error"
msgstr "ಅಜ್ಞಾತ ದೋಷ"
msgid "Invalid private code."
msgstr "ನಮೂದಿಸಿರುವ ಸಂಕೇತಪದ ಅಮಾನ್ಯವಾಗಿದೆ."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
"ಅನೇಕ ಕರೆನ್ಸಿಯ ರಶೀದಿ ಇರುವುದರಿಂದ ಈ ಯೋಜನೆಯನ್ನು \"ಯಾವುದೆ ಕರೆನ್ಸಿ ಇಲ್ಲ\" ಯಂದು "
"ನಮೋದಿಸಲು ಆಗುವುದಿಲ್ಲ."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "" msgstr "ಖರ್ಚನ್ನು ಜೊತೆಗಾರನೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಬಹುದು"
msgid "Import"
msgstr "ಆಮದು"
msgid "Project identifier" msgid "Project identifier"
msgstr "" msgstr "ಯೋಜನೆ ಸಂಕೇತ"
msgid "Private code" msgid "Private code"
msgstr "ಸಂಕೇತಪದ" msgstr "ಸಂಕೇತಪದ"
@ -71,25 +90,21 @@ 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 ""
"ಈ ಸಂಕೇತದ (\"%(project)s\") ಇನೊಂದು ಯೋಜನೆ ಆಗಲೆ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ. ದಯವಿಟ್ಟು ಹೊಸ "
"ಸಂಕೇತವನ್ನು ಆರಿಸಿ"
msgid "Which is a real currency: Euro or Petro dollar?" msgid "Which is a real currency: Euro or Petro dollar?"
msgstr "" msgstr "ನಿಜವಾದ ಕರೆನ್ಸಿ ಯಾವುದು: ಯುರೋ ಅಥವಾ ಪೆಟ್ರೋ ಡಾಲರ್?"
msgid "euro" msgid "euro"
msgstr "ಯೂರೋ" msgstr "ಯೂರೋ"
msgid "Please, validate the captcha to proceed." msgid "Please, validate the captcha to proceed."
msgstr "" msgstr "ಮುಂದುವರೆಯಲು ದಯವಿಟ್ಟು, ಕ್ಯಾಪ್ಚಾವನ್ನು ಮೌಲ್ಯೀಕರಿಸಿ."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "ತೆಗೆದುಹಾಕಲು ನಿಮ್ಮ ಸಂಕೇತಪದವನ್ನು ನಮೂದಿಸಿ" msgstr "ತೆಗೆದುಹಾಕಲು ನಿಮ್ಮ ಸಂಕೇತಪದವನ್ನು ನಮೂದಿಸಿ"
msgid "Unknown error"
msgstr "ಅಜ್ಞಾತ ದೋಷ"
msgid "Invalid private code."
msgstr "ನಮೂದಿಸಿರುವ ಸಂಕೇತಪದ ಅಮಾನ್ಯವಾಗಿದೆ."
msgid "Get in" msgid "Get in"
msgstr "ಒಳಹೊಗು" msgstr "ಒಳಹೊಗು"
@ -114,26 +129,27 @@ msgstr "ಪ್ರವೇಶಪದ ದೃಢೀಕರಿಸಿ"
msgid "Reset password" msgid "Reset password"
msgstr "ಪ್ರವೇಶಪದ ಮರುಹೊಂದಿಸಿ" msgstr "ಪ್ರವೇಶಪದ ಮರುಹೊಂದಿಸಿ"
msgid "Date" msgid "When?"
msgstr "ದಿನಾಂಕ" msgstr "ಯಾವಾಗ?"
msgid "What?" msgid "What?"
msgstr "ಏನು?" msgstr "ಏನು?"
msgid "Payer" msgid "Who paid?"
msgstr "ಪಾವತಿಸಿದವರು" msgstr "ಯಾರು ಪಾವತಿಸಿದ್ದಾರೆ?"
msgid "Amount paid" msgid "How much?"
msgstr "ಪಾವತಿಸಿದ ಮೊತ್ತ" msgstr "ಎಷ್ಟು?"
msgid "Currency" msgid "Currency"
msgstr "ನಾಣ್ಯಪದ್ಧತಿ" msgstr "ನಾಣ್ಯಪದ್ಧತಿ"
#, fuzzy
msgid "External link" msgid "External link"
msgstr "" msgstr "ಬಾಹ್ಯ ಲಿಂಕ್"
msgid "A link to an external document, related to this bill" msgid "A link to an external document, related to this bill"
msgstr "" msgstr "ಈ ರಶೀದಿಗೆ ಸಂಬಂಧಿಸಿದ ಬಾಹ್ಯ ಕಡತದ ಲಿಂಕ್"
msgid "For whom?" msgid "For whom?"
msgstr "ಯಾರಿಂದ?" msgstr "ಯಾರಿಂದ?"
@ -146,16 +162,13 @@ msgstr "ಕೋರಿಕೆ ಸಲ್ಲಿಸಿ ಹೊಸದನ್ನುಸೇ
#, python-format #, python-format
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "" msgstr "ಯೋಜನೆಯ ಪೂರ್ವನಿಯೋಜಿತ ಕರೆನ್ಸಿ: %(currency)s"
msgid "Bills can't be null"
msgstr ""
msgid "Name" msgid "Name"
msgstr "ಹೆಸರು" msgstr "ಹೆಸರು"
msgid "Weights should be positive" msgid "Weights should be positive"
msgstr "" msgstr "ತೂಕವು ಧನಾತ್ಮಕವಾಗಿರಬೇಕು"
msgid "Weight" msgid "Weight"
msgstr "ತೂಕ" msgstr "ತೂಕ"
@ -164,22 +177,34 @@ msgid "Add"
msgstr "ಕೂಡು" msgstr "ಕೂಡು"
msgid "The participant name is invalid" msgid "The participant name is invalid"
msgstr "" msgstr "ಸದಸ್ಯರ ಹೆಸರು ಅಮಾನ್ಯವಾಗಿದೆ"
#, fuzzy
msgid "This project already have this participant" msgid "This project already have this participant"
msgstr "ಈ ಸದಸ್ಯರು ಈಗಾಗಲೆ ಈ ಯೋಜನೆಯ ಸದಸ್ಯರಾಗಿದ್ದಾರೆ" msgstr "ಈ ಸದಸ್ಯರು ಈಗಾಗಲೆ ಈ ಯೋಜನೆಯ ಸದಸ್ಯರಾಗಿದ್ದಾರೆ"
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr "ಸೂಚಿಸಬೇಕಾದ ಜನರು"
msgid "Send invites" msgid "Send the invitations"
msgstr "ಆಮಂತ್ರಣ ಕಳುಹಿಸು" msgstr "ಆಮಂತ್ರಣಗಳನ್ನು ಕಳುಹಿಸಿ"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "ಮಿನ್ನಂಚೆ %(email)s ಸಮಂಜಸವಾಗಿಲ್ಲ" msgstr "ಮಿನ್ನಂಚೆ %(email)s ಸಮಂಜಸವಾಗಿಲ್ಲ"
msgid "Logout"
msgstr "ನಿರ್ಗಮಿಸಿ"
msgid "Please check the email configuration of the server."
msgstr "ದಯವಿಟ್ಟು, ಇಮೇಲ್ ಸಂರಚನೆ ಪರಿಶೀಲಿಸಿ."
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"ದಯವಿಟ್ಟು, ಇಮೇಲ್ ಸಂರಚನೆ ಪರಿಶೀಲಿಸಿ ಅಥವಾ ನಿರ್ವಾಹಕನನ್ನು ಸಂಪರ್ಕಿಸಿ:%(admin_email)s"
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} ಮತ್ತು {dual_object_1}" msgstr "{dual_object_0} ಮತ್ತು {dual_object_1}"
@ -197,7 +222,7 @@ msgid "{start_object}, {next_object}"
msgstr "{start_object}, {next_object}" msgstr "{start_object}, {next_object}"
msgid "No Currency" msgid "No Currency"
msgstr "" msgstr "ಯಾವುದೆ ಕರೆನ್ಸಿ ಇಲ್ಲ"
#. Form error with only one error #. Form error with only one error
msgid "{prefix}: {error}" msgid "{prefix}: {error}"
@ -207,7 +232,7 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix}:<br />{errors}" msgstr "{prefix}:<br />{errors}"
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "" msgstr ""
#, python-format #, python-format
@ -220,12 +245,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "" msgstr ""
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
"ನೀವು ನಿಮ್ಮ ಖರ್ಚು/ವೆಚ್ಚವನ್ನು ಹಂಚಿಕೊಳ್ಳಲು %(project)s ಯೋಜನೆಯನ್ನು "
"ಸೃಷ್ಟಿಸಿದ್ದೀರಿ"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "ನಿಮಗೆ ನೆನೆವಿ ಮಿನ್ನಂಚೆಯನ್ನು ಈಗ ಕಳುಹಿಸಲಾಗಿದೆ" msgstr "ನಿಮಗೆ ನೆನೆವಿ ಮಿನ್ನಂಚೆಯನ್ನು ಈಗ ಕಳುಹಿಸಲಾಗಿದೆ"
@ -236,14 +255,9 @@ msgstr ""
"ನಿಮಗೆ ನೆನವಿ ಮಿನ್ನಂಚೆ ಕಳುಹಿಸಲು ಪ್ರಯತ್ನಿಸಿದ್ದೆವೆ, ಆದರೆ ದೋಷವಿತ್ತು. ನೀವು " "ನಿಮಗೆ ನೆನವಿ ಮಿನ್ನಂಚೆ ಕಳುಹಿಸಲು ಪ್ರಯತ್ನಿಸಿದ್ದೆವೆ, ಆದರೆ ದೋಷವಿತ್ತು. ನೀವು "
"ಯೋಜನೆಯನ್ನು ಸಾಮಾನ್ಯ ಪದತಿಯಂತೆ ಉಪಯೋಗಿಸ ಬಹುದು." "ಯೋಜನೆಯನ್ನು ಸಾಮಾನ್ಯ ಪದತಿಯಂತೆ ಉಪಯೋಗಿಸ ಬಹುದು."
#, python-format
msgid "The project identifier is %(project)s"
msgstr ""
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
msgid "No token provided" msgid "No token provided"
@ -258,10 +272,14 @@ msgstr "ಗೊತ್ತಿಲ್ಲದ ಯೋಜನೆ"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "" msgstr ""
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "" msgstr ""
msgid "" msgid ""
@ -269,12 +287,18 @@ msgid ""
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr ""
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "" msgstr ""
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr ""
@ -284,10 +308,7 @@ msgstr ""
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "ನಿಮ್ಮ ಆಮಂತ್ರಣವನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ" msgstr "ನಿಮ್ಮ ಆಮಂತ್ರಣವನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ"
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
#, python-format #, python-format
@ -330,6 +351,10 @@ msgstr "ಬೆಲೆಪಟ್ಟಿಯನ್ನುತೆಗೆಯಲಾಗಿದ
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "ಬೆಲೆಪಟ್ಟಿಯನ್ನು ಮಾರ್ಪಡಿಸಲಾಗಿದೆ" msgstr "ಬೆಲೆಪಟ್ಟಿಯನ್ನು ಮಾರ್ಪಡಿಸಲಾಗಿದೆ"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "ಯೋಜನೆಯ ಇತಿಹಾಸವನ್ನು ತೆಗೆಯಲು ದೋಷವಾಗಿದೆ" msgstr "ಯೋಜನೆಯ ಇತಿಹಾಸವನ್ನು ತೆಗೆಯಲು ದೋಷವಾಗಿದೆ"
@ -390,8 +415,8 @@ msgstr "ಕಾರ್ಯಗಳು"
msgid "edit" msgid "edit"
msgstr "ಪರಿಷ್ಕರಿಸಿ" msgstr "ಪರಿಷ್ಕರಿಸಿ"
msgid "delete" msgid "Delete project"
msgstr "ತೆಗೆಯಿರಿ" msgstr ""
msgid "show" msgid "show"
msgstr "ತೋರಿಸಿ" msgstr "ತೋರಿಸಿ"
@ -405,20 +430,12 @@ msgstr ""
msgid "Get it on" msgid "Get it on"
msgstr "" msgstr ""
msgid "Are you sure?"
msgstr ""
msgid "Edit project" msgid "Edit project"
msgstr "" msgstr ""
msgid "Delete project" #, fuzzy
msgstr "" msgid "Import project"
msgstr "ಯೋಜನೆಯನ್ನು ರಚಿಸಿ/ಸೃಷ್ಟಿಸಿ"
msgid "Import JSON"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Download project's data" msgid "Download project's data"
msgstr "" msgstr ""
@ -444,18 +461,27 @@ msgstr ""
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "" msgstr ""
msgid "Edit the project" msgid "Save changes"
msgstr "" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
msgid "Import previously exported project"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Edit this bill" msgid "Edit this bill"
msgstr "" msgstr ""
msgid "Add a bill" msgid "Add a bill"
msgstr "" msgstr ""
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr ""
@ -474,9 +500,6 @@ msgstr ""
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "" msgstr ""
msgid "Send the invitations"
msgstr ""
msgid "Download" msgid "Download"
msgstr "" msgstr ""
@ -541,23 +564,18 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"disabling project history. You can\n" msgstr ""
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
"data-target=\"#confirm-erase\">clear project history</a> to remove " msgid "You can clear the project history to remove them."
"them.</i></p>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
@ -568,18 +586,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "" msgstr ""
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "Time" msgid "Time"
msgstr "" msgstr ""
@ -641,9 +659,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "ಪಾವತಿಸಿದವರು"
msgid "Amount" msgid "Amount"
msgstr "" msgstr ""
msgid "Date"
msgstr "ದಿನಾಂಕ"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "" msgstr ""
@ -744,6 +768,9 @@ msgstr ""
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "" msgstr ""
@ -753,7 +780,8 @@ msgstr ""
msgid "Dashboard" msgid "Dashboard"
msgstr "" msgstr ""
msgid "Logout" #, python-format
msgid "Please retry after %(date)s."
msgstr "" msgstr ""
msgid "Code" msgid "Code"
@ -787,30 +815,21 @@ msgstr ""
msgid "Invite people" msgid "Invite people"
msgstr "" msgstr ""
msgid "You should start by adding participants"
msgstr ""
msgid "Add a new bill"
msgstr ""
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr ""
msgid "When?" msgid "You should start by adding participants"
msgstr "" msgstr ""
msgid "Who paid?" msgid "Add a new bill"
msgstr "" msgstr ""
msgid "For what?" msgid "For what?"
msgstr "" msgstr ""
msgid "How much?"
msgstr ""
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "" msgstr ""
@ -819,19 +838,19 @@ msgstr ""
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "" msgstr ""
msgid "delete"
msgstr "ತೆಗೆಯಿರಿ"
msgid "No bills" msgid "No bills"
msgstr "" msgstr ""
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "" msgstr ""
msgid "You probably want to" msgid "Add your first bill"
msgstr "" msgstr ""
msgid "add a bill" msgid "Add the first participant"
msgstr ""
msgid "add participants"
msgstr "" msgstr ""
msgid "Password reminder" msgid "Password reminder"
@ -854,31 +873,48 @@ msgstr ""
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "" msgstr ""
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
msgid "Identifier:" msgid "Scan QR code"
msgstr "" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "" msgstr ""
msgid "Send via Emails" msgid "Send via Emails"
msgstr "" msgstr ""
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you." msgstr ""
msgid "Share Identifier & code"
msgstr ""
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr ""
msgid "Private code:"
msgstr "ಸಂಕೇತಪದ:"
msgid "the private code was defined when you created the project"
msgstr "" msgstr ""
msgid "Who pays?" msgid "Who pays?"
@ -944,3 +980,116 @@ msgstr ""
#~ msgid "Participants to notify" #~ msgid "Participants to notify"
#~ msgstr "" #~ msgstr ""
#~ msgid "Import previously exported JSON file"
#~ msgstr ""
#~ msgid "Import"
#~ msgstr "ಆಮದು"
#~ msgid "Amount paid"
#~ msgstr "ಪಾವತಿಸಿದ ಮೊತ್ತ"
#~ msgid "Bills can't be null"
#~ msgstr ""
#~ msgid "Too many failed login attempts, please retry later."
#~ msgstr ""
#~ msgid "The project identifier is %(project)s"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "sending you an email with password "
#~ "reset instructions. Please check the "
#~ "email configuration of the server or "
#~ "contact the administrator."
#~ msgstr ""
#~ msgid "Invalid JSON"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "trying to send the invitation emails."
#~ " Please check the email configuration "
#~ "of the server or contact the "
#~ "administrator."
#~ msgstr ""
#~ msgid "Are you sure?"
#~ msgstr ""
#~ msgid "Import JSON"
#~ msgstr ""
#~ 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 "Send invites"
#~ msgstr "ಆಮಂತ್ರಣ ಕಳುಹಿಸು"
#~ msgid " show"
#~ msgstr "ತೋರಿಸಿ"
#~ msgid "Edit the project"
#~ msgstr ""
#~ msgid "You probably want to"
#~ msgstr ""
#~ msgid "add a bill"
#~ msgstr ""
#~ msgid "add participants"
#~ msgstr ""
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ msgid "Share the Link"
#~ msgstr ""
#~ msgid "You can directly share the following link via your prefered medium"
#~ 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 ""
#~ "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 with the invitation "
#~ "link."
#~ msgstr ""

View file

@ -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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2021-07-18 12:32+0000\n" "PO-Revision-Date: 2021-07-18 12:32+0000\n"
"Last-Translator: Kemystra <izzmin97@gmail.com>\n" "Last-Translator: Kemystra <izzmin97@gmail.com>\n"
"Language: ms\n" "Language: ms\n"
@ -15,6 +15,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
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."
@ -23,6 +27,13 @@ msgstr "Nilai atau ungkapan yang sah. Hanya nombor dan operasi + - * / diterima.
msgid "Project name" msgid "Project name"
msgstr "Nama projek" msgstr "Nama projek"
#, fuzzy
msgid "Current private code"
msgstr "Kod peribadi baharu"
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "Kod peribadi baharu" msgstr "Kod peribadi baharu"
@ -47,6 +58,13 @@ msgstr "Mata wang asal"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
#, fuzzy
msgid "Unknown error"
msgstr "Ralat yang tidak dikenalpasti"
msgid "Invalid private code."
msgstr "Kod peribadi tidak sah."
#, fuzzy #, fuzzy
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
@ -55,12 +73,8 @@ msgstr ""
"Projek ini tidak boleh disetkan kepada 'tiada mata wang' kerana projek " "Projek ini tidak boleh disetkan kepada 'tiada mata wang' kerana projek "
"ini mempunyai wang dalam beberapa bentuk mata wang" "ini mempunyai wang dalam beberapa bentuk mata wang"
#, fuzzy msgid "Compatible with Cospend"
msgid "Import previously exported JSON file" msgstr ""
msgstr "Import fail JSON yang telah dieksport sebelum ini"
msgid "Import"
msgstr "Import"
msgid "Project identifier" msgid "Project identifier"
msgstr "" msgstr ""
@ -89,13 +103,6 @@ msgstr ""
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Masukkan kod peribadi untuk mengesahkan penghapusan" msgstr "Masukkan kod peribadi untuk mengesahkan penghapusan"
#, fuzzy
msgid "Unknown error"
msgstr "Ralat yang tidak dikenalpasti"
msgid "Invalid private code."
msgstr "Kod peribadi tidak sah."
msgid "Get in" msgid "Get in"
msgstr "Masuk" msgstr "Masuk"
@ -122,17 +129,17 @@ msgstr "Pengesahan kata laluan"
msgid "Reset password" msgid "Reset password"
msgstr "Tetapkan semula kata laluan" msgstr "Tetapkan semula kata laluan"
msgid "Date" msgid "When?"
msgstr "Tarikh" msgstr ""
msgid "What?" msgid "What?"
msgstr "Apa?" msgstr "Apa?"
msgid "Payer" msgid "Who paid?"
msgstr "Pembayar" msgstr ""
msgid "Amount paid" msgid "How much?"
msgstr "Jumlah dibayar" msgstr ""
msgid "Currency" msgid "Currency"
msgstr "Mata wang" msgstr "Mata wang"
@ -158,10 +165,6 @@ msgstr "Hantar dan tambah yang baharu"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "" msgstr ""
#, fuzzy
msgid "Bills can't be null"
msgstr "Bil tidak boleh kosong"
msgid "Name" msgid "Name"
msgstr "Nama" msgstr "Nama"
@ -186,13 +189,25 @@ msgstr "Projek ini sudah mempunyai ahli"
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "" msgstr ""
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "" msgstr ""
msgid "Logout"
msgstr ""
msgid "Please check the email configuration of the server."
msgstr ""
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "" msgstr ""
@ -220,7 +235,7 @@ msgstr ""
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "" msgstr ""
#, python-format #, python-format
@ -233,10 +248,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "" msgstr ""
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "" msgstr ""
@ -245,14 +256,9 @@ msgid ""
"still use the project normally." "still use the project normally."
msgstr "" msgstr ""
#, python-format
msgid "The project identifier is %(project)s"
msgstr ""
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
msgid "No token provided" msgid "No token provided"
@ -267,10 +273,14 @@ msgstr ""
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "" msgstr ""
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "" msgstr ""
msgid "" msgid ""
@ -278,12 +288,18 @@ msgid ""
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr ""
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "" msgstr ""
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr ""
@ -291,10 +307,7 @@ msgstr ""
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "" msgstr ""
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
#, python-format #, python-format
@ -337,6 +350,10 @@ msgstr ""
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "" msgstr ""
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "" msgstr ""
@ -397,7 +414,7 @@ msgstr ""
msgid "edit" msgid "edit"
msgstr "" msgstr ""
msgid "delete" msgid "Delete project"
msgstr "" msgstr ""
msgid "show" msgid "show"
@ -412,20 +429,12 @@ msgstr ""
msgid "Get it on" msgid "Get it on"
msgstr "" msgstr ""
msgid "Are you sure?"
msgstr ""
msgid "Edit project" msgid "Edit project"
msgstr "" msgstr ""
msgid "Delete project" #, fuzzy
msgstr "" msgid "Import project"
msgstr "Cipta projek ini"
msgid "Import JSON"
msgstr ""
msgid "Choose file"
msgstr ""
msgid "Download project's data" msgid "Download project's data"
msgstr "" msgstr ""
@ -451,18 +460,28 @@ msgstr ""
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "" msgstr ""
msgid "Edit the project" msgid "Save changes"
msgstr "" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
#, fuzzy
msgid "Import previously exported project"
msgstr "Import fail JSON yang telah dieksport sebelum ini"
msgid "Choose file"
msgstr ""
msgid "Edit this bill" msgid "Edit this bill"
msgstr "" msgstr ""
msgid "Add a bill" msgid "Add a bill"
msgstr "" msgstr ""
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "" msgstr ""
@ -481,9 +500,6 @@ msgstr ""
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "" msgstr ""
msgid "Send the invitations"
msgstr ""
msgid "Download" msgid "Download"
msgstr "" msgstr ""
@ -548,23 +564,18 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"disabling project history. You can\n" msgstr ""
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" "
"data-target=\"#confirm-erase\">clear project history</a> to remove " msgid "You can clear the project history to remove them."
"them.</i></p>\n"
" "
msgstr "" msgstr ""
msgid "" msgid ""
@ -575,18 +586,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "" msgstr ""
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr ""
msgid "Clear Project History"
msgstr ""
msgid "Time" msgid "Time"
msgstr "" msgstr ""
@ -648,9 +659,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "Pembayar"
msgid "Amount" msgid "Amount"
msgstr "" msgstr ""
msgid "Date"
msgstr "Tarikh"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "" msgstr ""
@ -751,6 +768,9 @@ msgstr ""
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "" msgstr ""
@ -760,7 +780,8 @@ msgstr ""
msgid "Dashboard" msgid "Dashboard"
msgstr "" msgstr ""
msgid "Logout" #, python-format
msgid "Please retry after %(date)s."
msgstr "" msgstr ""
msgid "Code" msgid "Code"
@ -794,30 +815,21 @@ msgstr ""
msgid "Invite people" msgid "Invite people"
msgstr "" msgstr ""
msgid "You should start by adding participants"
msgstr ""
msgid "Add a new bill"
msgstr ""
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr ""
msgid "When?" msgid "You should start by adding participants"
msgstr "" msgstr ""
msgid "Who paid?" msgid "Add a new bill"
msgstr "" msgstr ""
msgid "For what?" msgid "For what?"
msgstr "" msgstr ""
msgid "How much?"
msgstr ""
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "" msgstr ""
@ -826,19 +838,19 @@ msgstr ""
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "" msgstr ""
msgid "delete"
msgstr ""
msgid "No bills" msgid "No bills"
msgstr "" msgstr ""
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "" msgstr ""
msgid "You probably want to" msgid "Add your first bill"
msgstr "" msgstr ""
msgid "add a bill" msgid "Add the first participant"
msgstr ""
msgid "add participants"
msgstr "" msgstr ""
msgid "Password reminder" msgid "Password reminder"
@ -861,31 +873,49 @@ msgstr ""
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "" msgstr ""
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
msgid "Identifier:" msgid "Scan QR code"
msgstr "" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "" msgstr ""
msgid "Send via Emails" msgid "Send via Emails"
msgstr "" msgstr ""
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you." msgstr ""
msgid "Share Identifier & code"
msgstr ""
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr ""
#, fuzzy
msgid "Private code:"
msgstr "Kod peribadi"
msgid "the private code was defined when you created the project"
msgstr "" msgstr ""
msgid "Who pays?" msgid "Who pays?"
@ -954,3 +984,114 @@ msgstr ""
#~ msgid "Participants to notify" #~ msgid "Participants to notify"
#~ msgstr "" #~ msgstr ""
#~ msgid "Import"
#~ msgstr "Import"
#~ msgid "Amount paid"
#~ msgstr "Jumlah dibayar"
#~ msgid "Bills can't be null"
#~ msgstr "Bil tidak boleh kosong"
#~ msgid "Too many failed login attempts, please retry later."
#~ msgstr ""
#~ msgid "The project identifier is %(project)s"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "sending you an email with password "
#~ "reset instructions. Please check the "
#~ "email configuration of the server or "
#~ "contact the administrator."
#~ msgstr ""
#~ msgid "Invalid JSON"
#~ msgstr ""
#~ msgid ""
#~ "Sorry, there was an error while "
#~ "trying to send the invitation emails."
#~ " Please check the email configuration "
#~ "of the server or contact the "
#~ "administrator."
#~ msgstr ""
#~ msgid "Are you sure?"
#~ msgstr ""
#~ msgid "Import JSON"
#~ msgstr ""
#~ 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 "Send invites"
#~ msgstr ""
#~ msgid " show"
#~ msgstr ""
#~ msgid "Edit the project"
#~ msgstr ""
#~ msgid "You probably want to"
#~ msgstr ""
#~ msgid "add a bill"
#~ msgstr ""
#~ msgid "add participants"
#~ msgstr ""
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ msgid "Share the Link"
#~ msgstr ""
#~ msgid "You can directly share the following link via your prefered medium"
#~ 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 ""
#~ "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 with the invitation "
#~ "link."
#~ msgstr ""

View file

@ -1,20 +1,24 @@
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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2022-02-13 16:54+0000\n" "PO-Revision-Date: 2022-02-13 16:54+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"
"X-Generator: Weblate 4.11-dev\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Du har akkurat opprettet \"%(project)s\" for å dele dine utgifter"
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."
@ -25,6 +29,13 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Prosjektnavn" msgstr "Prosjektnavn"
#, fuzzy
msgid "Current private code"
msgstr "Ny privat kode"
msgid "Enter existing private code to edit project"
msgstr ""
msgid "New private code" msgid "New private code"
msgstr "Ny privat kode" msgstr "Ny privat kode"
@ -46,6 +57,12 @@ msgstr "Forvalgt valuta"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "En forvalg valutainnstilling skrur på konvertering mellom regninger" msgstr "En forvalg valutainnstilling skrur på konvertering mellom regninger"
msgid "Unknown error"
msgstr "Ukjent feil"
msgid "Invalid private code."
msgstr "Ugyldig privat kode"
#, fuzzy #, fuzzy
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
@ -54,11 +71,8 @@ msgstr ""
"Dette prosjektet kan ikke settes til «Ingen valuta» fordi det inneholder " "Dette prosjektet kan ikke settes til «Ingen valuta» fordi det inneholder "
"regninger i flere valutaer." "regninger i flere valutaer."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Importer tidligere eksportert JSON-fil" msgstr ""
msgid "Import"
msgstr "Importer"
msgid "Project identifier" msgid "Project identifier"
msgstr "Prosjektidentifikator" msgstr "Prosjektidentifikator"
@ -90,12 +104,6 @@ msgstr "Bekreft CAPTCHA-en for å fortsette."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Skriv inn privat kode for å bekrefte sletting" msgstr "Skriv inn privat kode for å bekrefte sletting"
msgid "Unknown error"
msgstr "Ukjent feil"
msgid "Invalid private code."
msgstr "Ugyldig privat kode"
#, fuzzy #, fuzzy
msgid "Get in" msgid "Get in"
msgstr "Til prosjektet" msgstr "Til prosjektet"
@ -121,17 +129,17 @@ msgstr "Passordbekreftelse"
msgid "Reset password" msgid "Reset password"
msgstr "Tilbakestill passord" msgstr "Tilbakestill passord"
msgid "Date" msgid "When?"
msgstr "Dato" msgstr "Når?"
msgid "What?" msgid "What?"
msgstr "Hva?" msgstr "Hva?"
msgid "Payer" msgid "Who paid?"
msgstr "Betaler" msgstr "Hvem betalte?"
msgid "Amount paid" msgid "How much?"
msgstr "Beløp betalt" msgstr "Hvor meget?"
msgid "Currency" msgid "Currency"
msgstr "Valuta" msgstr "Valuta"
@ -155,9 +163,6 @@ msgstr "Send inn og legg til ny"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Prosjektforvalg: %(currency)s" msgstr "Prosjektforvalg: %(currency)s"
msgid "Bills can't be null"
msgstr "Regninger kan ikke være null"
msgid "Name" msgid "Name"
msgstr "Navn" msgstr "Navn"
@ -181,13 +186,28 @@ msgstr "Allerede medlem av prosjektet"
msgid "People to notify" msgid "People to notify"
msgstr "Folk å varsle" msgstr "Folk å varsle"
msgid "Send invites" msgid "Send the invitations"
msgstr "Send invitasjoner" msgstr "Send ut invitasjonene"
#, fuzzy, python-format #, fuzzy, python-format
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"
#, fuzzy
msgid "Logout"
msgstr "Logg ut"
msgid "Please check the email configuration of the server."
msgstr ""
#, fuzzy, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Kunne ikke sende invitasjoner per e-post. Sjekk at e-postoppsettet på "
"tjeneren stemmer, eller kontakt administratoren."
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} og {dual_object_1}" msgstr "{dual_object_0} og {dual_object_1}"
@ -215,7 +235,8 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix}:<br />{errors}" msgstr "{prefix}:<br />{errors}"
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "For mange mislykkede innloggingsforsøk, prøv igjen senere." msgstr "For mange mislykkede innloggingsforsøk, prøv igjen senere."
#, python-format #, python-format
@ -228,10 +249,6 @@ msgstr "Angitt symbol er ugyldig"
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Denne private koden er ikke rett" msgstr "Denne private koden er ikke rett"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Du har akkurat opprettet \"%(project)s\" for å dele dine utgifter"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "En påminnelse har blitt sendt til deg per e-post" msgstr "En påminnelse har blitt sendt til deg per e-post"
@ -243,15 +260,10 @@ msgstr ""
"En påminnelse ble sendt til deg per e-post, men en feil inntraff. Du kan " "En påminnelse ble sendt til deg per e-post, men en feil inntraff. Du kan "
"fremdeles bruke prosjektet normalt." "fremdeles bruke prosjektet normalt."
#, python-format
msgid "The project identifier is %(project)s"
msgstr "Prosjektidentifikatoren er %(project)s"
#, fuzzy #, fuzzy
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"En feil inntraff under forsendelse av passordtilbakestilling til deg per " "En feil inntraff under forsendelse av passordtilbakestilling til deg per "
"e-post. Sjekk at e-postoppsettet til tjeneren er rett, eller kontakt " "e-post. Sjekk at e-postoppsettet til tjeneren er rett, eller kontakt "
@ -270,19 +282,26 @@ msgstr "Ukjent prosjekt"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "Passord tilbakestilt." msgstr "Passord tilbakestilt."
#, fuzzy msgid "Project settings have been changed successfully."
msgid "Project successfully uploaded" msgstr ""
msgstr "Prosjekt opplastet"
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "Ugyldig JSON" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
"Kan ikke legge til regninger i flere valutaer i et prosjekt uten forvalgt " "Kan ikke legge til regninger i flere valutaer i et prosjekt uten forvalgt"
"valuta" " valuta"
#, fuzzy
msgid "Project successfully uploaded"
msgstr "Prosjekt opplastet"
#, fuzzy #, fuzzy
msgid "Project successfully deleted" msgid "Project successfully deleted"
@ -292,6 +311,9 @@ msgstr "Prosjekt slettet"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "Kunne ikke slette prosjekt" msgstr "Kunne ikke slette prosjekt"
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "" msgstr ""
@ -302,10 +324,7 @@ msgid "Your invitations have been sent"
msgstr "Invitasjonene dine har blitt sendt" msgstr "Invitasjonene dine har blitt sendt"
#, fuzzy #, fuzzy
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Kunne ikke sende invitasjoner per e-post. Sjekk at e-postoppsettet på " "Kunne ikke sende invitasjoner per e-post. Sjekk at e-postoppsettet på "
"tjeneren stemmer, eller kontakt administratoren." "tjeneren stemmer, eller kontakt administratoren."
@ -354,6 +373,10 @@ msgstr "Regningen har blitt slettet"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "Regningen har blitt endret" msgstr "Regningen har blitt endret"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
#, fuzzy #, fuzzy
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Skru på prosjekthistorikk" msgstr "Skru på prosjekthistorikk"
@ -421,8 +444,8 @@ msgstr "Handlinger"
msgid "edit" msgid "edit"
msgstr "rediger" msgstr "rediger"
msgid "delete" msgid "Delete project"
msgstr "slett" msgstr "Slett prosjekt"
msgid "show" msgid "show"
msgstr "vis" msgstr "vis"
@ -437,21 +460,12 @@ msgstr "Last ned mobilprogram"
msgid "Get it on" msgid "Get it on"
msgstr "Til prosjektet" msgstr "Til prosjektet"
#, fuzzy
msgid "Are you sure?"
msgstr "er du sikker?"
msgid "Edit project" msgid "Edit project"
msgstr "Rediger prosjekt" msgstr "Rediger prosjekt"
msgid "Delete project" #, fuzzy
msgstr "Slett prosjekt" msgid "Import project"
msgstr "Rediger prosjekt"
msgid "Import JSON"
msgstr "Importer JSON"
msgid "Choose file"
msgstr "Velg fil"
msgid "Download project's data" msgid "Download project's data"
msgstr "Last ned prosjektets data" msgstr "Last ned prosjektets data"
@ -480,18 +494,28 @@ msgstr "Avbryt"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Personvernsinnstillinger" msgstr "Personvernsinnstillinger"
msgid "Edit the project" msgid "Save changes"
msgstr "Rediger prosjektet" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "Dette vil fjerne alle regninger og deltagere i prosjektet!" msgstr "Dette vil fjerne alle regninger og deltagere i prosjektet!"
#, fuzzy
msgid "Import previously exported project"
msgstr "Importer tidligere eksportert JSON-fil"
msgid "Choose file"
msgstr "Velg fil"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Rediger denne regningen" msgstr "Rediger denne regningen"
msgid "Add a bill" msgid "Add a bill"
msgstr "Legg til en regning" msgstr "Legg til en regning"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "Alle" msgstr "Alle"
@ -512,9 +536,6 @@ msgstr "Legg til deltager"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "ola@eksempel.no, kari@eksempel.no" msgstr "ola@eksempel.no, kari@eksempel.no"
msgid "Send the invitations"
msgstr "Send ut invitasjonene"
msgid "Download" msgid "Download"
msgstr "Last nd" msgstr "Last nd"
@ -591,37 +612,21 @@ msgstr "Regning %(name)s: La til %(owers_list_str)s på eierlisten"
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "Regning %(name)s: fjernet %(owers_list_str)s fra eierlisten" msgstr "Regning %(name)s: fjernet %(owers_list_str)s fra eierlisten"
#, fuzzy, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n"
" <i>Prosjektets historikk er avskrudd. Nye handlinger vil ikke"
" vises nedenfor. Du kan skru på hisorikk på</i>\n"
" <a href=\"%(url)s\">innstillingssiden</a>\n"
" "
#, fuzzy #, fuzzy
msgid "You can enable history on the settings page."
msgstr "IP-adresseregistrering kan skrus på fra innstillingssiden"
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n"
" <i>Tabellen nedenfor viser handlinger registrert før " #, fuzzy
"prosjekthistorikken ble avskrudd. Du kan\n" msgid "You can clear the project history to remove them."
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" " msgstr "Noen tømte antagelig prosjekthistorikken."
"data-target=\"#confirm-erase\">tømme prosjekthistorikken</a> for å fjerne"
" dem.</i></p>\n"
" "
#, fuzzy #, fuzzy
msgid "" msgid ""
@ -634,12 +639,6 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Slett lagrede IP-adresser" msgstr "Slett lagrede IP-adresser"
msgid "No history to erase"
msgstr "Ingen historikk å slette"
msgid "Clear Project History"
msgstr "Tøm prosjekthistorikk"
#, fuzzy #, fuzzy
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "Ingen IP-adresser å slette" msgstr "Ingen IP-adresser å slette"
@ -648,6 +647,12 @@ msgstr "Ingen IP-adresser å slette"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Slett lagrede IP-adresser" msgstr "Slett lagrede IP-adresser"
msgid "No history to erase"
msgstr "Ingen historikk å slette"
msgid "Clear Project History"
msgstr "Tøm prosjekthistorikk"
msgid "Time" msgid "Time"
msgstr "Tid" msgstr "Tid"
@ -711,9 +716,15 @@ msgstr "Regningen %(name)s fikk sitt navn endret til %(new_description)s"
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "Deltager %(name)s: vekting endret fra %(old_weight)s til %(new_weight)s" msgstr "Deltager %(name)s: vekting endret fra %(old_weight)s til %(new_weight)s"
msgid "Payer"
msgstr "Betaler"
msgid "Amount" msgid "Amount"
msgstr "Beløp" msgstr "Beløp"
msgid "Date"
msgstr "Dato"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Beløp i %(currency)s" msgstr "Beløp i %(currency)s"
@ -818,6 +829,9 @@ msgstr "Historikk"
msgid "Settings" msgid "Settings"
msgstr "Innstillinger" msgstr "Innstillinger"
msgid "RSS Feed"
msgstr ""
#, fuzzy #, fuzzy
msgid "Other projects :" msgid "Other projects :"
msgstr "Andre prosjekter:" msgstr "Andre prosjekter:"
@ -828,9 +842,9 @@ msgstr "bytt til"
msgid "Dashboard" msgid "Dashboard"
msgstr "Oversikt" msgstr "Oversikt"
#, fuzzy #, python-format
msgid "Logout" msgid "Please retry after %(date)s."
msgstr "Logg ut" msgstr ""
msgid "Code" msgid "Code"
msgstr "Kode" msgstr "Kode"
@ -865,30 +879,21 @@ msgstr "er du sikker?"
msgid "Invite people" msgid "Invite people"
msgstr "Inviter folk" msgstr "Inviter folk"
msgid "You should start by adding participants"
msgstr "Du kan starte ved å legge til deltagere"
msgid "Add a new bill"
msgstr "Legg til en ny regning"
msgid "Newer bills" msgid "Newer bills"
msgstr "Nyere regninger" msgstr "Nyere regninger"
msgid "Older bills" msgid "Older bills"
msgstr "Eldre regninger" msgstr "Eldre regninger"
msgid "When?" msgid "You should start by adding participants"
msgstr "Når?" msgstr "Du kan starte ved å legge til deltagere"
msgid "Who paid?" msgid "Add a new bill"
msgstr "Hvem betalte?" msgstr "Legg til en ny regning"
msgid "For what?" msgid "For what?"
msgstr "For hva?" msgstr "For hva?"
msgid "How much?"
msgstr "Hvor meget?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Lagt til %(date)s" msgstr "Lagt til %(date)s"
@ -897,6 +902,9 @@ msgstr "Lagt til %(date)s"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Alle, unntagen %(excluded)s" msgstr "Alle, unntagen %(excluded)s"
msgid "delete"
msgstr "slett"
msgid "No bills" msgid "No bills"
msgstr "Ingen regninger" msgstr "Ingen regninger"
@ -904,14 +912,13 @@ msgstr "Ingen regninger"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Ingenting å liste opp enda." msgstr "Ingenting å liste opp enda."
msgid "You probably want to" #, fuzzy
msgstr "Du ønsker antagelig å" msgid "Add your first bill"
msgid "add a bill"
msgstr "legge til en regning" msgstr "legge til en regning"
msgid "add participants" #, fuzzy
msgstr "legge til deltagere" msgid "Add the first participant"
msgstr "Legg til deltager"
msgid "Password reminder" msgid "Password reminder"
msgstr "Passordpåminner" msgstr "Passordpåminner"
@ -935,26 +942,21 @@ msgstr "Tilbakestill passordet ditt"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Inviter folk til å ta del i dette prosjektet" msgstr "Inviter folk til å ta del i dette prosjektet"
#, fuzzy msgid "Share an invitation link"
msgid "Share Identifier & code" msgstr ""
msgstr "Del identifikator og kode"
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
"Du kan dele prosjektidentifikatoren og den private koden slik det måtte "
"passe deg."
msgid "Identifier:" msgid "Scan QR code"
msgstr "Identifikator:" msgstr ""
#, fuzzy msgid "Use a mobile device with a compatible app."
msgid "Share the Link" msgstr ""
msgstr "Del lenken"
msgid "You can directly share the following link via your prefered medium"
msgstr "Du kan dele denne lenken slik du ønsker"
#, fuzzy #, fuzzy
msgid "Send via Emails" msgid "Send via Emails"
@ -962,15 +964,35 @@ msgstr "Send via e-poster"
#, fuzzy #, fuzzy
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"Angi en (kommainndelt) liste over e-postadresser du ønsker å varsle om\n" "Angi en (kommainndelt) liste over e-postadresser du ønsker å varsle om\n"
"opprettelsen av dette budsjetthåndteringsprosjektet, og de vil få en " "opprettelsen av dette budsjetthåndteringsprosjektet, og de vil få en "
"e-post om det." "e-post om det."
#, fuzzy
msgid "Share Identifier & code"
msgstr "Del identifikator og kode"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr "Identifikator:"
#, fuzzy
msgid "Private code:"
msgstr "Privat kode"
msgid "the private code was defined when you created the project"
msgstr ""
msgid "Who pays?" msgid "Who pays?"
msgstr "Hvem betaler?" msgstr "Hvem betaler?"
@ -1227,3 +1249,93 @@ msgstr "Periode"
#~ msgid "Participants to notify" #~ msgid "Participants to notify"
#~ msgstr "legge til deltagere" #~ msgstr "legge til deltagere"
#~ msgid "Import"
#~ msgstr "Importer"
#~ msgid "Amount paid"
#~ msgstr "Beløp betalt"
#~ msgid "Bills can't be null"
#~ msgstr "Regninger kan ikke være null"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "Prosjektidentifikatoren er %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "Ugyldig JSON"
#~ msgid "Are you sure?"
#~ msgstr "er du sikker?"
#~ msgid "Import JSON"
#~ msgstr "Importer JSON"
#~ 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>Prosjektets historikk er "
#~ "avskrudd. Nye handlinger vil ikke vises"
#~ " nedenfor. Du kan skru på hisorikk"
#~ " på</i>\n"
#~ " <a href=\"%(url)s\">innstillingssiden</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>Tabellen nedenfor viser "
#~ "handlinger registrert før prosjekthistorikken "
#~ "ble avskrudd. Du kan\n"
#~ " <a href=\"#\" data-"
#~ "toggle=\"modal\" data-keyboard=\"false\" data-"
#~ "target=\"#confirm-erase\">tømme prosjekthistorikken</a>"
#~ " for å fjerne dem.</i></p>\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "Send invitasjoner"
#~ msgid " show"
#~ msgstr "vis"
#~ msgid "Edit the project"
#~ msgstr "Rediger prosjektet"
#~ msgid "You probably want to"
#~ msgstr "Du ønsker antagelig å"
#~ msgid "add participants"
#~ msgstr "legge til deltagere"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "Du kan dele prosjektidentifikatoren og "
#~ "den private koden slik det måtte "
#~ "passe deg."
#~ msgid "Share the Link"
#~ msgstr "Del lenken"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr "Du kan dele denne lenken slik du ønsker"

View file

@ -3,7 +3,7 @@ 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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2021-02-17 02:50+0000\n" "PO-Revision-Date: 2021-02-17 02:50+0000\n"
"Last-Translator: Sander Kooijmans <weblate@gogognome.nl>\n" "Last-Translator: Sander Kooijmans <weblate@gogognome.nl>\n"
"Language: nl\n" "Language: nl\n"
@ -15,6 +15,12 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
"Je hebt zojuist het project '%(project)s' aangemaakt om je uitgaven te "
"verdelen"
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."
@ -25,6 +31,13 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Projectnaam" msgstr "Projectnaam"
#, fuzzy
msgid "Current private code"
msgstr "Privécode"
msgid "Enter existing private code to edit project"
msgstr ""
#, fuzzy #, fuzzy
msgid "New private code" msgid "New private code"
msgstr "Privécode" msgstr "Privécode"
@ -47,16 +60,21 @@ msgstr "Standaard munteenheid"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
#, fuzzy
msgid "Unknown error"
msgstr "Onbekend project"
#, fuzzy
msgid "Invalid private code."
msgstr "Privécode"
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Eerder geëxporteerd JSON-bestand importeren" msgstr ""
msgid "Import"
msgstr "Importeren"
msgid "Project identifier" msgid "Project identifier"
msgstr "Project-id" msgstr "Project-id"
@ -86,14 +104,6 @@ msgstr ""
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "" msgstr ""
#, fuzzy
msgid "Unknown error"
msgstr "Onbekend project"
#, fuzzy
msgid "Invalid private code."
msgstr "Privécode"
msgid "Get in" msgid "Get in"
msgstr "Inloggen" msgstr "Inloggen"
@ -118,17 +128,17 @@ msgstr "Wachtwoord bevestigen"
msgid "Reset password" msgid "Reset password"
msgstr "Wachtwoord herstellen" msgstr "Wachtwoord herstellen"
msgid "Date" msgid "When?"
msgstr "Datum" msgstr "Wanneer?"
msgid "What?" msgid "What?"
msgstr "Wat?" msgstr "Wat?"
msgid "Payer" msgid "Who paid?"
msgstr "Betaler" msgstr "Wie heeft er betaald?"
msgid "Amount paid" msgid "How much?"
msgstr "Betaald bedrag" msgstr "Hoeveel?"
msgid "Currency" msgid "Currency"
msgstr "Munteenheid" msgstr "Munteenheid"
@ -152,9 +162,6 @@ msgstr "Versturen en nieuwe toevoegen"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Projectstandaard: %(currency)s" msgstr "Projectstandaard: %(currency)s"
msgid "Bills can't be null"
msgstr "Rekeningen mogen niet null zijn"
msgid "Name" msgid "Name"
msgstr "Naam" msgstr "Naam"
@ -178,13 +185,28 @@ msgstr "Deze deelnemer is al lid van het project"
msgid "People to notify" msgid "People to notify"
msgstr "" msgstr ""
msgid "Send invites" msgid "Send the invitations"
msgstr "Uitnodigingen versturen" msgstr "Uitnodigingen versturen"
#, python-format #, python-format
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 "Logout"
msgstr "Uitloggen"
msgid "Please check the email configuration of the server."
msgstr ""
#, fuzzy, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Sorry, er is iets fout gegaan bij het verzenden van de uitnodigingsmails."
" Controleer de e-mailinstellingen van de server of neem contact op met de"
" beheerder."
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "" msgstr ""
@ -212,7 +234,8 @@ msgstr ""
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "" msgstr ""
msgid "Too many failed login attempts, please retry later." #, fuzzy
msgid "Too many failed login attempts."
msgstr "Te vaak onjuist ingelogd. Probeer het later opnieuw." msgstr "Te vaak onjuist ingelogd. Probeer het later opnieuw."
#, python-format #, python-format
@ -225,12 +248,6 @@ msgstr ""
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Deze privécode is onjuist" msgstr "Deze privécode is onjuist"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr ""
"Je hebt zojuist het project '%(project)s' aangemaakt om je uitgaven te "
"verdelen"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "Een herinneringsmail is zojuist naar u verzonden" msgstr "Een herinneringsmail is zojuist naar u verzonden"
@ -241,14 +258,10 @@ msgstr ""
"We hebben geprobeerd een herinneringsmail te versturen, maar er is iets " "We hebben geprobeerd een herinneringsmail te versturen, maar er is iets "
"fout gegaan. Je kunt het project nog steeds normaal gebruiken." "fout gegaan. Je kunt het project nog steeds normaal gebruiken."
#, python-format #, fuzzy
msgid "The project identifier is %(project)s"
msgstr "Het project-id is %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"Sorry, er is iets fout gegaan bij het verzenden van een e-mail met " "Sorry, er is iets fout gegaan bij het verzenden van een e-mail met "
"instructies om je wachtwoord te herstellen. Controleer de " "instructies om je wachtwoord te herstellen. Controleer de "
@ -266,23 +279,33 @@ msgstr "Onbekend project"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "Wachtwoord is hersteld." msgstr "Wachtwoord is hersteld."
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "Project succesvol geüpload" msgstr ""
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "Ongeldige JSON" msgstr ""
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr ""
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
msgid "Project successfully uploaded"
msgstr "Project succesvol geüpload"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "Project is verwijderd" msgstr "Project is verwijderd"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "" msgstr ""
msgid "Unable to logout"
msgstr ""
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "Je bent uitgenodigd om je uitgaven te delen met %(project)s" msgstr "Je bent uitgenodigd om je uitgaven te delen met %(project)s"
@ -290,10 +313,8 @@ msgstr "Je bent uitgenodigd om je uitgaven te delen met %(project)s"
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "Je uitnodigingen zijn verstuurd" msgstr "Je uitnodigingen zijn verstuurd"
msgid "" #, fuzzy
"Sorry, there was an error while trying to send the invitation emails. " msgid "Sorry, there was an error while trying to send the invitation emails."
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Sorry, er is iets fout gegaan bij het verzenden van de uitnodigingsmails." "Sorry, er is iets fout gegaan bij het verzenden van de uitnodigingsmails."
" Controleer de e-mailinstellingen van de server of neem contact op met de" " Controleer de e-mailinstellingen van de server of neem contact op met de"
@ -341,6 +362,10 @@ msgstr "De rekening is verwijderd"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "De rekening is aangepast" msgstr "De rekening is aangepast"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr ""
#, fuzzy #, fuzzy
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Projectgeschiedenis inschakelen" msgstr "Projectgeschiedenis inschakelen"
@ -406,8 +431,9 @@ msgstr "Acties"
msgid "edit" msgid "edit"
msgstr "bewerken" msgstr "bewerken"
msgid "delete" #, fuzzy
msgstr "verwijderen" msgid "Delete project"
msgstr "Project aanpassen"
msgid "show" msgid "show"
msgstr "tonen" msgstr "tonen"
@ -423,23 +449,13 @@ msgstr "Mobiele app"
msgid "Get it on" msgid "Get it on"
msgstr "Inloggen" msgstr "Inloggen"
#, fuzzy
msgid "Are you sure?"
msgstr "weet je het zeker?"
msgid "Edit project" msgid "Edit project"
msgstr "Project aanpassen" msgstr "Project aanpassen"
#, fuzzy #, fuzzy
msgid "Delete project" msgid "Import project"
msgstr "Project aanpassen" msgstr "Project aanpassen"
msgid "Import JSON"
msgstr "JSON importeren"
msgid "Choose file"
msgstr "Bestand kiezen"
msgid "Download project's data" msgid "Download project's data"
msgstr "Projectgegevens downloaden" msgstr "Projectgegevens downloaden"
@ -466,18 +482,28 @@ msgstr "Annuleren"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Privacy-instellingen" msgstr "Privacy-instellingen"
msgid "Edit the project" msgid "Save changes"
msgstr "Project bewerken" msgstr ""
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr ""
#, fuzzy
msgid "Import previously exported project"
msgstr "Eerder geëxporteerd JSON-bestand importeren"
msgid "Choose file"
msgstr "Bestand kiezen"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Deze rekening bewerken" msgstr "Deze rekening bewerken"
msgid "Add a bill" msgid "Add a bill"
msgstr "Rekening toevoegen" msgstr "Rekening toevoegen"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr ""
msgid "Everyone" msgid "Everyone"
msgstr "Iedereen" msgstr "Iedereen"
@ -497,9 +523,6 @@ msgstr "Deelnemer toevoegen"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "jan.jansen@voorbeeld.nl, maria.magdalena@website.nl" msgstr "jan.jansen@voorbeeld.nl, maria.magdalena@website.nl"
msgid "Send the invitations"
msgstr "Uitnodigingen versturen"
msgid "Download" msgid "Download"
msgstr "Downloaden" msgstr "Downloaden"
@ -571,31 +594,21 @@ msgstr ""
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "" msgstr ""
#, python-format msgid "This project has history disabled. New actions won't appear below."
msgid "" msgstr ""
"\n"
" <i>This project has history disabled. New actions won't " msgid "You can enable history on the settings page."
"appear below. You can enable history on the</i>\n"
" <a href=\"%(url)s\">settings page</a>\n"
" "
msgstr "" msgstr ""
"\n"
" <i>Dit project heeft de geschiedenis uitgeschakeld. Nieuwe "
"acties zullen niet hieronder verschijnen. Je kunt de geschiedenis "
"aanzetten op de </i>\n"
" <a href=\"%(url)s\">instellingen-pagina</a>\n"
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
#, fuzzy
msgid "You can clear the project history to remove them."
msgstr "Iemand heeft waarschijnlijk de projectgeschiedenis verwijderd."
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
"recording disabled. " "recording disabled. "
@ -604,18 +617,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "" msgstr ""
msgid "No history to erase"
msgstr "Geen geschiedenis om te wissen"
msgid "Clear Project History"
msgstr "Verwijder Projectgeschiedenis"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "Geen IP-adressen te verwijderen" msgstr "Geen IP-adressen te verwijderen"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Verwijder opgeslagen IP-adressen" msgstr "Verwijder opgeslagen IP-adressen"
msgid "No history to erase"
msgstr "Geen geschiedenis om te wissen"
msgid "Clear Project History"
msgstr "Verwijder Projectgeschiedenis"
msgid "Time" msgid "Time"
msgstr "Tijd" msgstr "Tijd"
@ -677,9 +690,15 @@ msgstr ""
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "" msgstr ""
msgid "Payer"
msgstr "Betaler"
msgid "Amount" msgid "Amount"
msgstr "Hoeveelheid" msgstr "Hoeveelheid"
msgid "Date"
msgstr "Datum"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Hoeveelheid in %(currency)s" msgstr "Hoeveelheid in %(currency)s"
@ -782,6 +801,9 @@ msgstr "Geschiedenis"
msgid "Settings" msgid "Settings"
msgstr "Instellingen" msgstr "Instellingen"
msgid "RSS Feed"
msgstr ""
msgid "Other projects :" msgid "Other projects :"
msgstr "Overige projecten:" msgstr "Overige projecten:"
@ -791,8 +813,9 @@ msgstr "overschakelen naar"
msgid "Dashboard" msgid "Dashboard"
msgstr "Overzicht" msgstr "Overzicht"
msgid "Logout" #, python-format
msgstr "Uitloggen" msgid "Please retry after %(date)s."
msgstr ""
msgid "Code" msgid "Code"
msgstr "Code" msgstr "Code"
@ -826,30 +849,21 @@ msgstr "weet je het zeker?"
msgid "Invite people" msgid "Invite people"
msgstr "Anderen uitnodigen" msgstr "Anderen uitnodigen"
msgid "You should start by adding participants"
msgstr "Begin met het toevoegen van deelnemers"
msgid "Add a new bill"
msgstr "Nieuwe rekening toevoegen"
msgid "Newer bills" msgid "Newer bills"
msgstr "" msgstr ""
msgid "Older bills" msgid "Older bills"
msgstr "" msgstr ""
msgid "When?" msgid "You should start by adding participants"
msgstr "Wanneer?" msgstr "Begin met het toevoegen van deelnemers"
msgid "Who paid?" msgid "Add a new bill"
msgstr "Wie heeft er betaald?" msgstr "Nieuwe rekening toevoegen"
msgid "For what?" msgid "For what?"
msgstr "Voor wat?" msgstr "Voor wat?"
msgid "How much?"
msgstr "Hoeveel?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Toegevoegd op %(date)s" msgstr "Toegevoegd op %(date)s"
@ -858,20 +872,22 @@ msgstr "Toegevoegd op %(date)s"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Iedereen, behalve %(excluded)s" msgstr "Iedereen, behalve %(excluded)s"
msgid "delete"
msgstr "verwijderen"
msgid "No bills" msgid "No bills"
msgstr "Geen rekeningen" msgstr "Geen rekeningen"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Nog niks." msgstr "Nog niks."
msgid "You probably want to" #, fuzzy
msgstr "Waarschijnlijk wil je" msgid "Add your first bill"
msgid "add a bill"
msgstr "een rekening toevoegen" msgstr "een rekening toevoegen"
msgid "add participants" #, fuzzy
msgstr "deelnemers toevoegen" msgid "Add the first participant"
msgstr "Deelnemer toevoegen"
msgid "Password reminder" msgid "Password reminder"
msgstr "Wachtwoordhint" msgstr "Wachtwoordhint"
@ -895,39 +911,56 @@ msgstr "Wachtwoord herstellen"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Nodig mensen uit voor dit project" msgstr "Nodig mensen uit voor dit project"
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "Identificatie en code delen" msgstr ""
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
"Je kunt de projectidentificatie en privécode delen via welk "
"communicatieplatform dan ook."
msgid "Identifier:" msgid "Scan QR code"
msgstr "Identificatie:" msgstr ""
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr "Link delen" msgstr ""
msgid "You can directly share the following link via your prefered medium"
msgstr "Je kunt de volgende link direct delen"
msgid "Send via Emails" msgid "Send via Emails"
msgstr "Versturen via e-mail" msgstr "Versturen via e-mail"
#, fuzzy
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"Stel een (kommagescheiden) lijst op met e-mailadressen van personen die " "Stel een (kommagescheiden) lijst op met e-mailadressen van personen die "
"je op de\n" "je op de\n"
" hoogte wilt stellen van dit project - wij sturen hen een " " hoogte wilt stellen van dit project - wij sturen hen een "
"e-mail." "e-mail."
msgid "Share Identifier & code"
msgstr "Identificatie en code delen"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
msgid "Identifier:"
msgstr "Identificatie:"
#, fuzzy
msgid "Private code:"
msgstr "Privécode"
msgid "the private code was defined when you created the project"
msgstr ""
msgid "Who pays?" msgid "Who pays?"
msgstr "Wie betaalt?" msgstr "Wie betaalt?"
@ -1049,3 +1082,85 @@ msgstr "Periode"
#~ msgid "People to notify" #~ msgid "People to notify"
#~ msgstr "Te melden personen" #~ msgstr "Te melden personen"
#~ msgid "Import"
#~ msgstr "Importeren"
#~ msgid "Amount paid"
#~ msgstr "Betaald bedrag"
#~ msgid "Bills can't be null"
#~ msgstr "Rekeningen mogen niet null zijn"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "Het project-id is %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "Ongeldige JSON"
#~ msgid "Are you sure?"
#~ msgstr "weet je het zeker?"
#~ msgid "Import JSON"
#~ msgstr "JSON importeren"
#~ 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>Dit project heeft de "
#~ "geschiedenis uitgeschakeld. Nieuwe acties "
#~ "zullen niet hieronder verschijnen. Je "
#~ "kunt de geschiedenis aanzetten op de "
#~ "</i>\n"
#~ " <a href=\"%(url)s\">instellingen-pagina</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 ""
#~ msgid "Send invites"
#~ msgstr "Uitnodigingen versturen"
#~ msgid " show"
#~ msgstr "tonen"
#~ msgid "Edit the project"
#~ msgstr "Project bewerken"
#~ msgid "You probably want to"
#~ msgstr "Waarschijnlijk wil je"
#~ msgid "add participants"
#~ msgstr "deelnemers toevoegen"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "Je kunt de projectidentificatie en "
#~ "privécode delen via welk communicatieplatform"
#~ " dan ook."
#~ msgid "Share the Link"
#~ msgstr "Link delen"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr "Je kunt de volgende link direct delen"

View file

@ -2,9 +2,9 @@ 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: 2021-11-01 18:01+0100\n" "POT-Creation-Date: 2023-07-29 14:24+0200\n"
"PO-Revision-Date: 2022-09-27 14:19+0000\n" "PO-Revision-Date: 2023-08-24 18:48+0000\n"
"Last-Translator: Andrzej Ochodek <andrzej.ochodek@gmail.com>\n" "Last-Translator: Eryk Michalak <gnu.ewm@protonmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/i-hate-money/" "Language-Team: Polish <https://hosted.weblate.org/projects/i-hate-money/"
"i-hate-money/pl/>\n" "i-hate-money/pl/>\n"
"Language: pl\n" "Language: pl\n"
@ -13,9 +13,13 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n" "|| n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 4.14.1\n" "X-Generator: Weblate 5.0\n"
"Generated-By: Babel 2.9.0\n" "Generated-By: Babel 2.9.0\n"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Właśnie utworzyłeś „%(project)s”, aby podzielić się wydatkami"
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."
@ -26,6 +30,12 @@ msgstr ""
msgid "Project name" msgid "Project name"
msgstr "Nazwa projektu" msgstr "Nazwa projektu"
msgid "Current private code"
msgstr "Bieżący kod prywatny"
msgid "Enter existing private code to edit project"
msgstr "Wprowadź kod prywatny aby edytować projekt"
msgid "New private code" msgid "New private code"
msgstr "Nowy kod prywatny" msgstr "Nowy kod prywatny"
@ -46,20 +56,24 @@ msgstr "Domyślna waluta"
msgid "Setting a default currency enables currency conversion between bills" msgid "Setting a default currency enables currency conversion between bills"
msgstr "" msgstr ""
"Wybranie domyślnej waluty pozwala na konwersję walutową pomiędzy rachunkami" "Wybranie domyślnej waluty pozwala na konwersję walutową pomiędzy "
"rachunkami"
msgid "Unknown error"
msgstr "Nieznany błąd"
msgid "Invalid private code."
msgstr "Nieprawidłowy kod prywatny."
msgid "" msgid ""
"This project cannot be set to 'no currency' because it contains bills in " "This project cannot be set to 'no currency' because it contains bills in "
"multiple currencies." "multiple currencies."
msgstr "" msgstr ""
"Ten projekt nie może zostać oznaczony jako 'bez waluty', ponieważ zawiera on " "Ten projekt nie może zostać oznaczony jako 'bez waluty', ponieważ zawiera"
"rachunki w różnych walutach." " on rachunki w różnych walutach."
msgid "Import previously exported JSON file" msgid "Compatible with Cospend"
msgstr "Zaimportuj wcześniej wyeksportowany plik JSON" msgstr "Zgodne z Cospend"
msgid "Import"
msgstr "Importuj"
msgid "Project identifier" msgid "Project identifier"
msgstr "Identyfikator projektu" msgstr "Identyfikator projektu"
@ -75,8 +89,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 ""
"Projekt o tym identyfikatorze (\"%(project)s\") już istnieje. Wybierz nowy " "Projekt o tym identyfikatorze (\"%(project)s\") już istnieje. Wybierz "
"identyfikator" "nowy identyfikator"
msgid "Which is a real currency: Euro or Petro dollar?" msgid "Which is a real currency: Euro or Petro dollar?"
msgstr "Która waluta jest prawdziwa: euro czy petrodolar?" msgstr "Która waluta jest prawdziwa: euro czy petrodolar?"
@ -90,12 +104,6 @@ msgstr "Rozwiąż captcha, by kontynuować."
msgid "Enter private code to confirm deletion" msgid "Enter private code to confirm deletion"
msgstr "Wprowadź kod prywatny w celu potwierdzenia usunięcia" msgstr "Wprowadź kod prywatny w celu potwierdzenia usunięcia"
msgid "Unknown error"
msgstr "Nieznany błąd"
msgid "Invalid private code."
msgstr "Nieprawidłowy kod prywatny."
msgid "Get in" msgid "Get in"
msgstr "Wejdź" msgstr "Wejdź"
@ -120,17 +128,17 @@ msgstr "Potwierdzenie hasła"
msgid "Reset password" msgid "Reset password"
msgstr "Zmień hasło" msgstr "Zmień hasło"
msgid "Date" msgid "When?"
msgstr "Data" msgstr "Kiedy?"
msgid "What?" msgid "What?"
msgstr "Co?" msgstr "Co?"
msgid "Payer" msgid "Who paid?"
msgstr "Płatnik" msgstr "Kto zapłacił?"
msgid "Amount paid" msgid "How much?"
msgstr "Zapłacona kwota" msgstr "Jak dużo?"
msgid "Currency" msgid "Currency"
msgstr "Waluta" msgstr "Waluta"
@ -154,9 +162,6 @@ msgstr "Zatwierdź i dodaj nowy"
msgid "Project default: %(currency)s" msgid "Project default: %(currency)s"
msgstr "Wartość domyślna projektu: %(currency)s" msgstr "Wartość domyślna projektu: %(currency)s"
msgid "Bills can't be null"
msgstr "Rachunki nie mogą być zerowe"
msgid "Name" msgid "Name"
msgstr "Nazwa" msgstr "Nazwa"
@ -178,13 +183,27 @@ msgstr "Ten projekt ma już tego członka"
msgid "People to notify" msgid "People to notify"
msgstr "Osoby do powiadomienia" msgstr "Osoby do powiadomienia"
msgid "Send invites" msgid "Send the invitations"
msgstr "Wyślij zaproszenia" msgstr "Wyślij zaproszenia"
#, python-format #, python-format
msgid "The email %(email)s is not valid" msgid "The email %(email)s is not valid"
msgstr "Ten email %(email)s jest nieprawidłowy" msgstr "Ten email %(email)s jest nieprawidłowy"
msgid "Logout"
msgstr "Wyloguj"
msgid "Please check the email configuration of the server."
msgstr "Prosimy sprawdzić konfigurację e-mail serwera."
#, python-format
msgid ""
"Please check the email configuration of the server or contact the "
"administrator: %(admin_email)s"
msgstr ""
"Prosimy sprawdzić konfigurację e-mail serwera lub skontaktować się z "
"administratorem: %(admin_email)s"
#. List with two items only #. List with two items only
msgid "{dual_object_0} and {dual_object_1}" msgid "{dual_object_0} and {dual_object_1}"
msgstr "{dual_object_0} i {dual_object_1}" msgstr "{dual_object_0} i {dual_object_1}"
@ -212,8 +231,8 @@ msgstr "{prefix}: {error}"
msgid "{prefix}:<br />{errors}" msgid "{prefix}:<br />{errors}"
msgstr "{prefix}:<br />{errors}" msgstr "{prefix}:<br />{errors}"
msgid "Too many failed login attempts, please retry later." msgid "Too many failed login attempts."
msgstr "Zbyt wiele nieudanych prób logowania, spróbuj ponownie później." msgstr "Zbyt wiele nieudanych prób logowania."
#, python-format #, python-format
msgid "This admin password is not the right one. Only %(num)d attempts left." msgid "This admin password is not the right one. Only %(num)d attempts left."
@ -225,10 +244,6 @@ msgstr "Podany token jest niepoprawny"
msgid "This private code is not the right one" msgid "This private code is not the right one"
msgstr "Ten prywatny kod jest niewłaściwy" msgstr "Ten prywatny kod jest niewłaściwy"
#, python-format
msgid "You have just created '%(project)s' to share your expenses"
msgstr "Właśnie utworzyłeś „%(project)s”, aby podzielić się wydatkami"
msgid "A reminder email has just been sent to you" msgid "A reminder email has just been sent to you"
msgstr "Wiadomość e-mail z przypomnieniem została właśnie wysłana" msgstr "Wiadomość e-mail z przypomnieniem została właśnie wysłana"
@ -239,18 +254,12 @@ msgstr ""
"Próbowaliśmy wysłać Ci wiadomość e-mail z przypomnieniem, ale wystąpił " "Próbowaliśmy wysłać Ci wiadomość e-mail z przypomnieniem, ale wystąpił "
"błąd. Nadal możesz normalnie korzystać z projektu." "błąd. Nadal możesz normalnie korzystać z projektu."
#, python-format
msgid "The project identifier is %(project)s"
msgstr "Identyfikator projektu to %(project)s"
msgid "" msgid ""
"Sorry, there was an error while sending you an email with password reset " "Sorry, there was an error while sending you an email with password reset "
"instructions. Please check the email configuration of the server or " "instructions."
"contact the administrator."
msgstr "" msgstr ""
"Przepraszamy, wystąpił błąd podczas wysyłania wiadomości e-mail z " "Przepraszamy, wystąpił błąd podczas wysyłania wiadomości e-mail z "
"instrukcjami resetowania hasła. Sprawdź konfigurację e-mail serwera lub " "instrukcjami resetowania hasła."
"skontaktuj się z administratorem."
msgid "No token provided" msgid "No token provided"
msgstr "Nie podano tokena" msgstr "Nie podano tokena"
@ -264,17 +273,25 @@ msgstr "Nieznany projekt"
msgid "Password successfully reset." msgid "Password successfully reset."
msgstr "Hasło zostało pomyślnie zresetowane." msgstr "Hasło zostało pomyślnie zresetowane."
msgid "Project successfully uploaded" msgid "Project settings have been changed successfully."
msgstr "Projekt został pomyślnie przesłany" msgstr "Ustawienia projektu zostały pomyślnie zmienione."
msgid "Invalid JSON" msgid "Unable to parse CSV"
msgstr "Niepoprawny JSON" msgstr "Nie udało się odczytać pliku CSV"
#, python-format
msgid "Missing attribute: %(attribute)s"
msgstr "Brakujący atrybut: %(attribute)s"
msgid "" msgid ""
"Cannot add bills in multiple currencies to a project without default " "Cannot add bills in multiple currencies to a project without default "
"currency" "currency"
msgstr "" msgstr ""
"Nie można dodawać rachunków w wielu walutach do projektu bez waluty domyślnej" "Nie można dodawać rachunków w wielu walutach do projektu bez waluty "
"domyślnej"
msgid "Project successfully uploaded"
msgstr "Projekt został pomyślnie przesłany"
msgid "Project successfully deleted" msgid "Project successfully deleted"
msgstr "Projekt został pomyślnie usunięty" msgstr "Projekt został pomyślnie usunięty"
@ -282,6 +299,9 @@ msgstr "Projekt został pomyślnie usunięty"
msgid "Error deleting project" msgid "Error deleting project"
msgstr "Błąd podczas usuwania projektu" msgstr "Błąd podczas usuwania projektu"
msgid "Unable to logout"
msgstr "Nie można się wylogować"
#, python-format #, python-format
msgid "You have been invited to share your expenses for %(project)s" msgid "You have been invited to share your expenses for %(project)s"
msgstr "Zostałeś zaproszony do podzielenia się swoimi wydatkami w %(project)s" msgstr "Zostałeś zaproszony do podzielenia się swoimi wydatkami w %(project)s"
@ -289,14 +309,10 @@ msgstr "Zostałeś zaproszony do podzielenia się swoimi wydatkami w %(project)s
msgid "Your invitations have been sent" msgid "Your invitations have been sent"
msgstr "Twoje zaproszenia zostały wysłane" msgstr "Twoje zaproszenia zostały wysłane"
msgid "" msgid "Sorry, there was an error while trying to send the invitation emails."
"Sorry, there was an error while trying to send the invitation emails. "
"Please check the email configuration of the server or contact the "
"administrator."
msgstr "" msgstr ""
"Przepraszamy, wystąpił błąd podczas próby wysłania wiadomości e-mail z " "Przepraszamy, wystąpił błąd podczas próby wysłania wiadomości e-mail z "
"zaproszeniem. Sprawdź konfigurację e-mail serwera lub skontaktuj się z " "zaproszeniem."
"administratorem."
#, python-format #, python-format
msgid "%(member)s has been added" msgid "%(member)s has been added"
@ -317,8 +333,8 @@ msgid ""
"Participant '%(name)s' has been deactivated. It will still appear in the " "Participant '%(name)s' has been deactivated. It will still appear in the "
"list until its balance reach zero." "list until its balance reach zero."
msgstr "" msgstr ""
"Uczestnik „%(name)s” został wyłączony. Będzie nadal pojawiać się na liście " "Uczestnik „%(name)s” został wyłączony. Będzie nadal pojawiać się na "
"użytkowników, dopóki jego saldo nie wyniesie zero." "liście użytkowników, dopóki jego saldo nie wyniesie zero."
#, python-format #, python-format
msgid "Participant '%(name)s' has been removed" msgid "Participant '%(name)s' has been removed"
@ -340,6 +356,10 @@ msgstr "Rachunek został usunięty"
msgid "The bill has been modified" msgid "The bill has been modified"
msgstr "Rachunek został zmieniony" msgstr "Rachunek został zmieniony"
#, python-format
msgid "%(lang)s is not a supported language"
msgstr "%(lang)s nie jest obsługowanym językiem"
msgid "Error deleting project history" msgid "Error deleting project history"
msgstr "Błąd podczas usuwania historii projektu" msgstr "Błąd podczas usuwania historii projektu"
@ -402,8 +422,8 @@ msgstr "Akcje"
msgid "edit" msgid "edit"
msgstr "edytuj" msgstr "edytuj"
msgid "delete" msgid "Delete project"
msgstr "usuń" msgstr "Usuń projekt"
msgid "show" msgid "show"
msgstr "pokaż" msgstr "pokaż"
@ -417,20 +437,11 @@ msgstr "Pobierz aplikację mobilną"
msgid "Get it on" msgid "Get it on"
msgstr "Pobierz na" msgstr "Pobierz na"
msgid "Are you sure?"
msgstr "Czy jesteś pewien?"
msgid "Edit project" msgid "Edit project"
msgstr "Edytuj projekt" msgstr "Edytuj projekt"
msgid "Delete project" msgid "Import project"
msgstr "Usuń projekt" msgstr "Importuj projekt"
msgid "Import JSON"
msgstr "Importuj JSON"
msgid "Choose file"
msgstr "Wybierz plik"
msgid "Download project's data" msgid "Download project's data"
msgstr "Pobierz dane projektu" msgstr "Pobierz dane projektu"
@ -456,12 +467,17 @@ msgstr "Anuluj"
msgid "Privacy Settings" msgid "Privacy Settings"
msgstr "Ustawienia prywatności" msgstr "Ustawienia prywatności"
msgid "Edit the project" msgid "Save changes"
msgstr "Edytuj projekt" msgstr "Zapisz zmiany"
msgid "This will remove all bills and participants in this project!" msgid "This will remove all bills and participants in this project!"
msgstr "" msgstr "Spowoduje to usunięcie wszystkich rachunków i uczestników tego projektu!"
"Spowoduje to usunięcie wszystkich rachunków i uczestników tego projektu!"
msgid "Import previously exported project"
msgstr "Zaimportuj wcześniej wyeksportowany projekt"
msgid "Choose file"
msgstr "Wybierz plik"
msgid "Edit this bill" msgid "Edit this bill"
msgstr "Edytuj ten rachunek" msgstr "Edytuj ten rachunek"
@ -469,6 +485,9 @@ msgstr "Edytuj ten rachunek"
msgid "Add a bill" msgid "Add a bill"
msgstr "Dodaj rachunek" msgstr "Dodaj rachunek"
msgid "Simple operations are allowed, e.g. (18+36.2)/3"
msgstr "Dozwolone są proste operacje, np. (18+36.2)/3"
msgid "Everyone" msgid "Everyone"
msgstr "Wszyscy" msgstr "Wszyscy"
@ -487,9 +506,6 @@ msgstr "Edytuj tego uczestnika"
msgid "john.doe@example.com, mary.moe@site.com" msgid "john.doe@example.com, mary.moe@site.com"
msgstr "jan.kowalski@przykład.com, anna.nowak@strona.com" msgstr "jan.kowalski@przykład.com, anna.nowak@strona.com"
msgid "Send the invitations"
msgstr "Wyślij zaproszenia"
msgid "Download" msgid "Download"
msgstr "Pobierz" msgstr "Pobierz"
@ -516,8 +532,7 @@ msgstr "Ustawienia historii zmienione"
#, python-format #, python-format
msgid "Bill %(name)s: %(property_name)s changed from %(before)s to %(after)s" msgid "Bill %(name)s: %(property_name)s changed from %(before)s to %(after)s"
msgstr "" msgstr "Rachunek %(name)s: %(property_name)s zmieniono z %(before)s na %(after)s"
"Rachunek %(name)s: %(property_name)s zmieniono z %(before)s na %(after)s"
#, python-format #, python-format
msgid "Bill %(name)s: %(property_name)s changed to %(after)s" msgid "Bill %(name)s: %(property_name)s changed to %(after)s"
@ -561,36 +576,22 @@ msgstr "Bill %(name)s: dodano %(owers_list_str)s do listy właścicieli"
msgid "Bill %(name)s: removed %(owers_list_str)s from owers list" msgid "Bill %(name)s: removed %(owers_list_str)s from owers list"
msgstr "Bill %(name)s: usunięto %(owers_list_str)s z listy właścicieli" msgstr "Bill %(name)s: usunięto %(owers_list_str)s z listy właścicieli"
#, python-format msgid "This project has history disabled. New actions won't appear below."
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 "" msgstr ""
"\n" "Ten projekt ma wyłączoną historię. Nowe działania nie pojawią się poniżej."
" <i>Historia tego projektu została wyłączona. Nowe działania "
"nie pojawią się poniżej. Możesz włączyć historię w</i>\n" msgid "You can enable history on the settings page."
" <a href=\"%(url)s\">ustawieniach</a>\n" msgstr "Możliwe jest włączenie historii na stronie ustawień."
" "
msgid "" msgid ""
"\n" "The table below reflects actions recorded prior to disabling project "
" <i>The table below reflects actions recorded prior to " "history."
"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 "" msgstr ""
"\n" "Poniższa tabela przedstawia działania zarejestrowane przed wyłączeniem "
" <i>Poniższa tabela przedstawia działania zarejestrowane przed" "historii projektu."
" wyłączeniem historii projektu. Możesz\n"
" <a href=\"#\" data-toggle=\"modal\" data-keyboard=\"false\" " msgid "You can clear the project history to remove them."
"data-target=\"#confirm-erase\">wyczyścić historię projektu</a>, aby je " msgstr "Możesz wyczyścić historię projektu aby ją usunąć."
"usunąć.</i></p>\n"
" "
msgid "" msgid ""
"Some entries below contain IP addresses, even though this project has IP " "Some entries below contain IP addresses, even though this project has IP "
@ -602,18 +603,18 @@ msgstr ""
msgid "Delete stored IP addresses" msgid "Delete stored IP addresses"
msgstr "Usuń przechowywane adresy IP" msgstr "Usuń przechowywane adresy IP"
msgid "No history to erase"
msgstr "Brak historii do usunięcia"
msgid "Clear Project History"
msgstr "Wyczyść historię projektu"
msgid "No IP Addresses to erase" msgid "No IP Addresses to erase"
msgstr "Brak adresów IP do usunięcia" msgstr "Brak adresów IP do usunięcia"
msgid "Delete Stored IP Addresses" msgid "Delete Stored IP Addresses"
msgstr "Usuń przechowywane adresy IP" msgstr "Usuń przechowywane adresy IP"
msgid "No history to erase"
msgstr "Brak historii do usunięcia"
msgid "Clear Project History"
msgstr "Wyczyść historię projektu"
msgid "Time" msgid "Time"
msgstr "Czas" msgstr "Czas"
@ -650,8 +651,7 @@ msgstr "Nazwa projektu zmieniona na %(new_project_name)s"
#, python-format #, python-format
msgid "Project contact email changed to %(new_email)s" msgid "Project contact email changed to %(new_email)s"
msgstr "" msgstr "Adres e-mail osoby kontaktowej projektu został zmieniony na %(new_email)s"
"Adres e-mail osoby kontaktowej projektu został zmieniony na %(new_email)s"
msgid "Project settings modified" msgid "Project settings modified"
msgstr "Zmieniono ustawienia projektu" msgstr "Zmieniono ustawienia projektu"
@ -676,9 +676,15 @@ msgstr "Rachunek %(name)s zmienił nazwę na %(new_description)s"
msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s" msgid "Participant %(name)s: weight changed from %(old_weight)s to %(new_weight)s"
msgstr "Uczestnik %(name)s: zmiana wagi z %(old_weight)s na %(new_weight)s" msgstr "Uczestnik %(name)s: zmiana wagi z %(old_weight)s na %(new_weight)s"
msgid "Payer"
msgstr "Płatnik"
msgid "Amount" msgid "Amount"
msgstr "Ilość" msgstr "Ilość"
msgid "Date"
msgstr "Data"
#, python-format #, python-format
msgid "Amount in %(currency)s" msgid "Amount in %(currency)s"
msgstr "Ilość w %(currency)s" msgstr "Ilość w %(currency)s"
@ -781,6 +787,9 @@ msgstr "Historia"
msgid "Settings" msgid "Settings"
msgstr "Ustawienia" msgstr "Ustawienia"
msgid "RSS Feed"
msgstr "Kanał RSS"
msgid "Other projects :" msgid "Other projects :"
msgstr "Inne projekty:" msgstr "Inne projekty:"
@ -790,8 +799,9 @@ msgstr "przełącz na"
msgid "Dashboard" msgid "Dashboard"
msgstr "Kokpit" msgstr "Kokpit"
msgid "Logout" #, python-format
msgstr "Wyloguj" msgid "Please retry after %(date)s."
msgstr "Prosimy spróbować ponownie po %(date)s."
msgid "Code" msgid "Code"
msgstr "Kod" msgstr "Kod"
@ -824,30 +834,21 @@ msgstr "jesteś pewny?"
msgid "Invite people" msgid "Invite people"
msgstr "Zaproś ludzi" msgstr "Zaproś ludzi"
msgid "You should start by adding participants"
msgstr "Powinieneś zacząć od dodania uczestników"
msgid "Add a new bill"
msgstr "Dodaj nowy rachunek"
msgid "Newer bills" msgid "Newer bills"
msgstr "Nowsze rachunki" msgstr "Nowsze rachunki"
msgid "Older bills" msgid "Older bills"
msgstr "Starsze rachunki" msgstr "Starsze rachunki"
msgid "When?" msgid "You should start by adding participants"
msgstr "Kiedy?" msgstr "Powinieneś zacząć od dodania uczestników"
msgid "Who paid?" msgid "Add a new bill"
msgstr "Kto zapłacił?" msgstr "Dodaj nowy rachunek"
msgid "For what?" msgid "For what?"
msgstr "Za co?" msgstr "Za co?"
msgid "How much?"
msgstr "Jak dużo?"
#, python-format #, python-format
msgid "Added on %(date)s" msgid "Added on %(date)s"
msgstr "Dodano %(date)s" msgstr "Dodano %(date)s"
@ -856,20 +857,20 @@ msgstr "Dodano %(date)s"
msgid "Everyone but %(excluded)s" msgid "Everyone but %(excluded)s"
msgstr "Wszyscy poza %(excluded)s" msgstr "Wszyscy poza %(excluded)s"
msgid "delete"
msgstr "usuń"
msgid "No bills" msgid "No bills"
msgstr "Brak rachunków" msgstr "Brak rachunków"
msgid "Nothing to list yet." msgid "Nothing to list yet."
msgstr "Nie ma jeszcze żadnej listy." msgstr "Nie ma jeszcze żadnej listy."
msgid "You probably want to" msgid "Add your first bill"
msgstr "Prawdopodobnie chcesz" msgstr "Dodaj swój pierwszy rachunek"
msgid "add a bill" msgid "Add the first participant"
msgstr "dodać rachunek" msgstr "Dodaj pierwszego uczestnika"
msgid "add participants"
msgstr "dodać członków"
msgid "Password reminder" msgid "Password reminder"
msgstr "Przypomnienie hasła" msgstr "Przypomnienie hasła"
@ -893,40 +894,61 @@ msgstr "Zresetuj swoje hasło"
msgid "Invite people to join this project" msgid "Invite people to join this project"
msgstr "Zaproś ludzi do dołączenia do tego projektu" msgstr "Zaproś ludzi do dołączenia do tego projektu"
msgid "Share Identifier & code" msgid "Share an invitation link"
msgstr "Udostępnij identyfikator i kod" msgstr "Udostępnij link z zaproszeniem"
msgid "" msgid ""
"You can share the project identifier and the private code by any " "The easiest way to invite people is to give them the following invitation"
"communication means." " link.<br />They will be able to access the project, manage participants,"
" add/edit/delete bills. However, they will not have access to important "
"settings such as changing the private code or deleting the whole project."
msgstr "" msgstr ""
"Identyfikator projektu i kod prywatny można udostępniać dowolnymi " "Najłatwiejszym sposobem zapraszania nowych osób jest podanie im poniższego "
"środkami komunikacji." "linku ze zaproszeniem.<br />Osoby te będą mogły uzyskać dostęp do projektu, "
"zarządzać uczestnikami, dodawać/edytować/usuwać rachunki. Nie będą jednak "
"mieli dostępu do ważnych ustawień, takich jak zmiana kodu prywatnego lub "
"usunięcie całego projektu."
msgid "Identifier:" msgid "Scan QR code"
msgstr "Identyfikator:" msgstr "Skanuj kod QR"
msgid "Share the Link" msgid "Use a mobile device with a compatible app."
msgstr "Udostępnij link" msgstr "Użyj urządzenia mobilnego ze zgodną aplikacją."
msgid "You can directly share the following link via your prefered medium"
msgstr ""
"Możesz bezpośrednio udostępnić poniższy link za pośrednictwem "
"preferowanego medium"
msgid "Send via Emails" msgid "Send via Emails"
msgstr "Wyślij przez maile" msgstr "Wyślij przez maile"
msgid "" msgid ""
"Specify a (comma separated) list of email adresses you want to notify " "Specify a list of email adresses (separated by comma) of people you want "
"about the\n" "to notify about the creation of this project. We will send them an email "
" creation of this budget management project and we will " "with the invitation link."
"send them an email for you."
msgstr "" msgstr ""
"Podaj (adresy rozdzielone przecinkami) adresy email, które chcesz " "Podaj listę adresów e-mail (oddzielonych przecinkami) osób, które chcesz "
"powiadomić o \n" "powiadomić o utworzeniu tego projektu. Wyślemy im wiadomość e-mail z linkiem "
" utworzeniu tego projektu zarządzania budżetem, a my " "zaproszającym."
"wyślemy Ci wiadomość email."
msgid "Share Identifier & code"
msgstr "Udostępnij identyfikator i kod"
msgid ""
"You can share the project identifier and the private code by any "
"communication means.<br />Anyone with the private code will have access "
"to the full project, including changing settings such as the private code"
" or project email address, or even deleting the whole project."
msgstr ""
"Identyfikator projektu i kod prywatny można udostępniać za pomocą dowolnych "
"środków komunikacji.<br />Każda osoba posiadająca kod prywatny będzie miała "
"dostęp do całego projektu, w tym do zmiany ustawień, takich jak kod prywatny "
"lub adres e-mail projektu, a nawet do usunięcia całego projektu."
msgid "Identifier:"
msgstr "Identyfikator:"
msgid "Private code:"
msgstr "Kod prywatny:"
msgid "the private code was defined when you created the project"
msgstr "kod prywatny został zdefiniowany podczas tworzenia projektu"
msgid "Who pays?" msgid "Who pays?"
msgstr "Kto płaci?" msgstr "Kto płaci?"
@ -1043,3 +1065,94 @@ msgstr "Okres"
#~ msgid "People to notify" #~ msgid "People to notify"
#~ msgstr "Osoby do powiadomienia" #~ msgstr "Osoby do powiadomienia"
#~ msgid "Import"
#~ msgstr "Importuj"
#~ msgid "Amount paid"
#~ msgstr "Zapłacona kwota"
#~ msgid "Bills can't be null"
#~ msgstr "Rachunki nie mogą być zerowe"
#~ msgid "The project identifier is %(project)s"
#~ msgstr "Identyfikator projektu to %(project)s"
#~ msgid "Invalid JSON"
#~ msgstr "Niepoprawny JSON"
#~ msgid "Are you sure?"
#~ msgstr "Czy jesteś pewien?"
#~ msgid "Import JSON"
#~ msgstr "Importuj JSON"
#~ 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>Historia tego projektu została"
#~ " wyłączona. Nowe działania nie pojawią "
#~ "się poniżej. Możesz włączyć historię "
#~ "w</i>\n"
#~ " <a href=\"%(url)s\">ustawieniach</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>Poniższa tabela przedstawia "
#~ "działania zarejestrowane przed wyłączeniem "
#~ "historii projektu. Możesz\n"
#~ " <a href=\"#\" data-"
#~ "toggle=\"modal\" data-keyboard=\"false\" data-"
#~ "target=\"#confirm-erase\">wyczyścić historię "
#~ "projektu</a>, aby je usunąć.</i></p>\n"
#~ " "
#~ msgid "Send invites"
#~ msgstr "Wyślij zaproszenia"
#~ msgid " show"
#~ msgstr "pokaż"
#~ msgid "Edit the project"
#~ msgstr "Edytuj projekt"
#~ msgid "You probably want to"
#~ msgstr "Prawdopodobnie chcesz"
#~ msgid "add participants"
#~ msgstr "dodać członków"
#~ msgid ""
#~ "You can share the project identifier "
#~ "and the private code by any "
#~ "communication means."
#~ msgstr ""
#~ "Identyfikator projektu i kod prywatny "
#~ "można udostępniać dowolnymi środkami "
#~ "komunikacji."
#~ msgid "Share the Link"
#~ msgstr "Udostępnij link"
#~ msgid "You can directly share the following link via your prefered medium"
#~ msgstr ""
#~ "Możesz bezpośrednio udostępnić poniższy link"
#~ " za pośrednictwem preferowanego medium"

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more