diff --git a/.travis.yml b/.travis.yml index 4ce4b7877f02c6b29bc4d92c7e9b382e92d00dc7..dc5bc0e55e35721f18b60961d166e2c7c8f57bea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,21 @@ deploy: provider: releases api_key: secure: MUdvTDBeCxO9d/EpzIhr+QYra/KxgYkXX6177SjqWCWDqw9xB3fwSUj8I9ht9DGtwVdadtveumtvLw3pbtVIR0GtIPC9pyvtNz4j6T4Ei3TSE6+StXdMK4NnInvPeTRlobGL+9sZt9MwheJwZ8YGewhBcR0F5UzVfxWeSSrxmyk= - file: sakia-${TRAVIS_OS_NAME}.zip + file: + - sakia-${TRAVIS_OS_NAME}.zip skip_cleanup: true on: tags: true + condition: ${TRAVIS_OS_NAME} = osx + +deploy: + provider: releases + api_key: + secure: MUdvTDBeCxO9d/EpzIhr+QYra/KxgYkXX6177SjqWCWDqw9xB3fwSUj8I9ht9DGtwVdadtveumtvLw3pbtVIR0GtIPC9pyvtNz4j6T4Ei3TSE6+StXdMK4NnInvPeTRlobGL+9sZt9MwheJwZ8YGewhBcR0F5UzVfxWeSSrxmyk= + file: + - sakia-${TRAVIS_OS_NAME}.deb + - sakia-${TRAVIS_OS_NAME}.zip + skip_cleanup: true + on: + tags: true + condition: ${TRAVIS_OS_NAME} = linux diff --git a/README.md b/README.md index 72f7b5568d28162df6f32b5f2ab64546512fcd06..37ef60117e11c5682c48354c4fd76cf0c0c2a37c 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,21 @@ -<!-- Landscape | [](https://landscape.io/github/ucoin-io/sakia/dev) --> +<!-- Landscape | [](https://landscape.io/github/duniter/sakia/dev) --> - + + +# Sakia +[](https://coveralls.io/r/duniter/sakia) + [](https://travis-ci.org/duniter/sakia) + [](https://ci.appveyor.com/project/Insoleet/sakia-bee4m/branch/dev) + [](http://weblate.duniter.org/engage/sakia/?utm_source=widget) + [](https://www.quantifiedcode.com/app/project/3fff212226eb4027a586bc32e32d909b) -Sakia [](https://coveralls.io/r/ucoin-io/sakia) [](https://travis-ci.org/ucoin-io/sakia) [](https://ci.appveyor.com/project/Insoleet/sakia/branch/dev) [](http://weblate.ucoin.io/engage/sakia/?utm_source=widget) ======== -Python3 and PyQt5 Client for [uCoin](http://www.ucoin.io) project. +Python3 and PyQt5 Client for [duniter](http://www.duniter.org) project. ## Goal features - * Ucoin account management via wallets and communities + * duniter account management via wallets and communities * Multi-currency * Multi-community * Multi-wallets @@ -35,9 +41,9 @@ Python3 and PyQt5 Client for [uCoin](http://www.ucoin.io) project. * [pyqt5](http://www.riverbankcomputing.co.uk/software/pyqt/download5) * [libsodium](http://doc.libsodium.org/installation/README.html) * Python libraries dependencies : - * __ucoinpy__ + * __duniterpy__ - * General tips : use pyenv to build sakia, as described in the [wiki](https://github.com/ucoin-io/sakia/wiki/Cutecoin-install-for-developpers) + * General tips : use pyenv to build sakia, as described in the [wiki](https://github.com/duniter/sakia/wiki/Cutecoin-install-for-developpers) ### Build scripts * Run __python3 gen_resources.py__ in sakia folder @@ -46,10 +52,10 @@ Python3 and PyQt5 Client for [uCoin](http://www.ucoin.io) project. * The executable is generated in "build" folder, named "sakia" ### Download latest release - * Go to [current release](https://github.com/ucoin-io/sakia/releases) + * Go to [current release](https://github.com/duniter/sakia/releases) * Download corresponding package to your operating system * Unzip and start "sakia" :) - * Join our beta community by contacting us on [uCoin forum](http://forum.ucoin.io/) + * Join our beta community by contacting us on [duniter forum](http://forum.duniter.org/) ## License -This software is distributed under [GNU GPLv3](https://raw.github.com/ucoin-io/sakia/dev/LICENSE). +This software is distributed under [GNU GPLv3](https://raw.github.com/duniter/sakia/dev/LICENSE). diff --git a/appveyor.yml b/appveyor.yml index 59fa0afa974c16f5e786a622d7957d55ad05b857..4b50efe2be49ddc6c21f0968a07744a85d6516f2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,9 +11,7 @@ environment: PYTHON_ARCH: "64" CONDA_PY: "35" CONDA_NPY: "18" - QTDIR: "C:\\Qt\\5.6\\5.6\\msvc2015_64" - QDOWNLOAD: "http://download.qt.io/development_releases/qt/5.6/5.6.0-beta/qt-opensource-windows-x86-msvc2015_64-5.6.0-beta.exe" - QINSTALLER: "qt-opensource-windows-x86-msvc2015_64-5.6.0-beta.exe" + QTDIR: "C:\\Qt\\5.6\\msvc2015_64" platform: x64 - PYTHON: "C:\\Python35_32" @@ -21,9 +19,7 @@ environment: PYTHON_ARCH: "32" CONDA_PY: "35" CONDA_NPY: "18" - QTDIR: "C:\\Qt\\5.6\\5.6\\msvc2015" - QDOWNLOAD: "http://download.qt.io/development_releases/qt/5.6/5.6.0-beta/qt-opensource-windows-x86-msvc2015-5.6.0-beta.exe" - QINSTALLER: "qt-opensource-windows-x86-msvc2015-5.6.0-beta.exe" + QTDIR: "C:\\Qt\\5.6\\msvc2015" platform: x86 install: @@ -31,20 +27,16 @@ install: # as well as pip, conda-build, and the binstar CLI - powershell .\\ci\\appveyor\\install.ps1 - - IF NOT EXIST C:\Qt\5.6\5.6 curl -kLO %QDOWNLOAD% - - IF NOT EXIST C:\Qt\5.6\5.6 %QINSTALLER% --script ci\appveyor\qt-installer-noninteractive.qs - # - dir /b /s /ad c:\Qt + #- dir /b /s /ad c:\Qt\5.6 - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - - "IF EXIST %QTDIR%\\include\\QtNfc MOVE %QTDIR%\\include\\QtNfc %QTDIR%\\include\\QtNfc-disable" # Add qt to path - - "set PATH=%QTDIR%\\bin;%PATH%" - - - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" + - "SET PATH=%QTDIR%\\bin;%QTDIR%\\lib;%PATH%" - "SET QT_PLUGIN_PATH=%QTDIR%\\plugins" + - echo %PATH% - choco install -y vcredist2015 - "%CMD_IN_ENV% conda config --set always_yes yes --set changeps1 no" - "%CMD_IN_ENV% conda config --add channels inso/channel/sakia" - - "%CMD_IN_ENV% conda create -q -n test-environment python=%PYTHON_VERSION% pyqt5 libsodium=1.0.3" + - "%CMD_IN_ENV% conda create -q -n test-environment python=%PYTHON_VERSION% pyqt5=5.6 libsodium=1.0.3 setuptools=19.2" cache: - C:\Qt\5.6\5.6 @@ -56,9 +48,17 @@ build_script: - ".\\ci\\appveyor\\tests.cmd" - echo %errorlevel% + # Windows Installer + - if [%APPVEYOR_REPO_TAG_NAME%] neq [] choco install -y InnoSetup + - if [%APPVEYOR_REPO_TAG_NAME%] neq [] set PATH="C:\Program Files (x86)\Inno Setup 5";%PATH% + - if [%APPVEYOR_REPO_TAG_NAME%] neq [] iscc %cd%\ci\appveyor\sakia.iss /DROOT_PATH=%cd% + - if [%APPVEYOR_REPO_TAG_NAME%] neq [] move %cd%\sakia.exe %cd%\sakia-%APPVEYOR_REPO_TAG_NAME%-win%PYTHON_ARCH%.exe + artifacts: - path: dist name: sakia-win$(PYTHON_ARCH) + - path: sakia*.exe + name: sakia-exe # upload to releases deploy: tag: $(APPVEYOR_REPO_TAG_NAME) @@ -66,7 +66,7 @@ deploy: provider: GitHub auth_token: secure: wbzlh6nx1zY1J1avlB0C3hKGm1abFNHBdM60u/U09i5Nam//D6kazvnv5ZBKdR89 - artifact: sakia-win$(PYTHON_ARCH) + artifact: /sakia-/ draft: true prerelease: true on: diff --git a/ci/appveyor/after_install.cmd b/ci/appveyor/after_install.cmd new file mode 100644 index 0000000000000000000000000000000000000000..4ed2b33cc065472277c1f2822615d0f0b7d33155 --- /dev/null +++ b/ci/appveyor/after_install.cmd @@ -0,0 +1,3 @@ +@ECHO OFF + +rd /s /q %APPDATA%\sakia \ No newline at end of file diff --git a/ci/appveyor/sakia.iss b/ci/appveyor/sakia.iss new file mode 100644 index 0000000000000000000000000000000000000000..68fdca7588058e1c56d560eabd93c481d6317c07 --- /dev/null +++ b/ci/appveyor/sakia.iss @@ -0,0 +1,65 @@ +#define MyAppName "Sakia" +#define MyAppPublisher "Sakia team" +#define MyAppURL "http://sakia-wallet.org" +#define MyAppExeName "sakia.exe" + +#if !Defined(ROOT_PATH) +#define ROOT_PATH "." +#endif + +#define MyAppSrc ROOT_PATH +#define MyAppExe ROOT_PATH + "\dist\sakia\" + MyAppExeName +#pragma message MyAppSrc + +#if !FileExists(MyAppExe) +#error "Unable to find MyAppExe" +#endif + +#define MyAppVerStr "0.20.1" + +[Setup] +AppName={#MyAppName} +AppVersion={#MyAppVerStr} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={pf}\{#MyAppName} +DisableDirPage=yes +DefaultGroupName={#MyAppName} +DisableProgramGroupPage=yes +OutputDir={#ROOT_PATH} +OutputBaseFilename={#MyAppName} +Compression=lzma +SolidCompression=yes +UninstallDisplayIcon={app}\{#MyAppExeName} + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" +Name: "french"; MessagesFile: "compiler:Languages\French.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "{#MyAppSrc}\dist\sakia\*"; DestDir: "{app}\"; Flags: ignoreversion recursesubdirs +Source: "{#MyAppSrc}\sakia.ico"; DestDir: "{app}\"; Flags: ignoreversion recursesubdirs +Source: "{#MyAppSrc}\sakia.png"; DestDir: "{app}\"; Flags: ignoreversion recursesubdirs +Source: "{#MyAppSrc}\LICENSE"; DestDir: "{app}\"; Flags: ignoreversion recursesubdirs +Source: "{#MyAppSrc}\ci\appveyor\after_install.cmd"; DestDir: "{app}\"; Flags: ignoreversion + +[Icons] +Name: "{group}\{#MyAppName}"; IconFilename: "{app}\sakia.ico"; Filename: "{app}\{#MyAppExeName}" +Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" +Name: "{commondesktop}\{#MyAppName}"; IconFilename: "{app}\sakia.ico"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent +Filename: "{app}\after_install.cmd"; Description: "Delete ALL existing data"; Flags: postinstall nowait skipifsilent unchecked + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{2F4DA7A9-B15B-06FC-474C-A470394CAEAA} +LicenseFile="{#MyAppSrc}\LICENSE" diff --git a/ci/travis/after_success.sh b/ci/travis/after_success.sh index 0211ad359a565119a92b904116b0030ed42fdc99..cb2acfb751351082ac3f7f3b078f53469136bf55 100755 --- a/ci/travis/after_success.sh +++ b/ci/travis/after_success.sh @@ -3,7 +3,7 @@ eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" -cd $HOME/build/ucoin-io/sakia +cd $HOME/build/duniter/sakia pyenv activate sakia-env coverage -rm diff --git a/ci/travis/before_deploy.sh b/ci/travis/before_deploy.sh index 569192a9b193e22237f20a39228211e66d8c35be..b4fd6dbef45860e89130856e2b29eac175df6ad0 100755 --- a/ci/travis/before_deploy.sh +++ b/ci/travis/before_deploy.sh @@ -6,4 +6,15 @@ then elif [ $TRAVIS_OS_NAME == "linux" ] then zip -r sakia-${TRAVIS_OS_NAME}.zip dist/ + + # Debian package + chmod 755 ci/travis/debian/DEBIAN/post* + chmod 755 ci/travis/debian/DEBIAN/pre* + mkdir -p ci/travis/debian/opt/sakia + + cp sakia.png ci/travis/debian/opt/sakia/ + cp sakia-${TRAVIS_OS_NAME}.zip ci/travis/debian/opt/sakia/sakia.zip + + fakeroot dpkg-deb --build ci/travis/debian + mv ci/travis/debian.deb sakia-${TRAVIS_OS_NAME}.deb fi diff --git a/ci/travis/before_install.sh b/ci/travis/before_install.sh index ba2085b4ef33aa5fb5759befc1bacf0ee8667cf3..517bcd5f62f3e6ee1ee8472c77af5da09fe03229 100755 --- a/ci/travis/before_install.sh +++ b/ci/travis/before_install.sh @@ -1,12 +1,22 @@ #!/usr/bin/env bash + +if [ $TRAVIS_OS_NAME == "linux" ] +then + export XVFBARGS="-screen 0 1280x1024x24" + export DISPLAY=:99.0 + sh -e /etc/init.d/xvfb start + sleep 3 +fi + if [ $TRAVIS_OS_NAME == "osx" ] then + brew tap homebrew/versions brew update brew install libsodium ## Ensure your brew QT version is up to date. (brew install qt -> qt 4.8) - brew install qt5 - brew link --force qt5 + brew install qt55 + brew link --force qt55 brew install pyenv-virtualenv elif [ $TRAVIS_OS_NAME == "linux" ] then @@ -15,10 +25,16 @@ then libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev \ libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0 \ libxcb-render-util0-dev libxcb-glx0-dev libgl1-mesa-dri libegl1-mesa libpcre3-dev \ - curl qt5-qmake qtbase5-dev qttools5-dev-tools libqt5svg5-dev libdbus-1-dev libdbus-glib-1-dev autoconf automake libtool + curl libdbus-1-dev libdbus-glib-1-dev autoconf automake libtool libgstreamer-plugins-base0.10-0 + wget https://download.qt.io/official_releases/qt/5.5/5.5.1/qt-opensource-linux-x64-5.5.1.run + chmod +x qt-opensource-linux-x64-5.5.1.run + ./qt-opensource-linux-x64-5.5.1.run --script $HOME/build/duniter/sakia/ci/travis/qt-installer-noninteractive.qs + wget http://archive.ubuntu.com/ubuntu/pool/universe/libs/libsodium/libsodium13_1.0.1-1_amd64.deb sudo dpkg -i libsodium13_1.0.1-1_amd64.deb curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash + sudo lconfig + ldconfig -p fi eval "$(pyenv init -)" @@ -61,19 +77,27 @@ then --enable QtCore \ --enable QtWidgets \ --enable QtGui \ - --enable QtSvg\ + --enable QtSvg \ + --enable QtWebChannel \ + --enable QtWebEngineWidgets \ + --enable QtNetwork \ + --enable QtPrintSupport \ --enable QtTest elif [ $TRAVIS_OS_NAME == "linux" ] then - python configure.py --qmake "/usr/lib/x86_64-linux-gnu/qt5/bin/qmake" --confirm-license \ + python configure.py --qmake "/tmp/qt/5.5/5.5/gcc_64/bin/qmake" --confirm-license \ --enable QtCore \ --enable QtWidgets \ --enable QtGui \ - --enable QtSvg\ + --enable QtSvg \ + --enable QtWebChannel \ + --enable QtWebEngineWidgets \ + --enable QtNetwork \ + --enable QtPrintSupport \ --enable QtTest fi make -j 2 && make install pyenv rehash -fi \ No newline at end of file +fi diff --git a/ci/travis/build.sh b/ci/travis/build.sh index f097d6d62b23a9376612f3da80f93a1c69d83dcf..0235b7f481065b11292caeb32fa6eddb4dd0ca99 100755 --- a/ci/travis/build.sh +++ b/ci/travis/build.sh @@ -3,7 +3,9 @@ eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" -cd $HOME/build/ucoin-io/sakia +cd $HOME/build/duniter/sakia + + pyenv activate sakia-env pip install coveralls pip install pyinstaller @@ -12,10 +14,12 @@ if [ $TRAVIS_OS_NAME == "linux" ] then pip install -U git+https://github.com/posborne/dbus-python.git pip install notify2 + + export PATH=/tmp/qt/5.5/5.5/gcc_64/bin:$PATH fi python gen_resources.py -python gen_translations.py +python gen_translations.py --lrelease if [ $TRAVIS_OS_NAME == "osx" ] then diff --git a/ci/travis/debian/DEBIAN/control b/ci/travis/debian/DEBIAN/control new file mode 100644 index 0000000000000000000000000000000000000000..9089c08af01faa140dca59d012dff199d3a597c8 --- /dev/null +++ b/ci/travis/debian/DEBIAN/control @@ -0,0 +1,8 @@ +Package: sakia +Version: 0.20.1 +Section: misc +Priority: optional +Architecture: all +Installed-Size: 122000 +Maintainer: inso <insomniak.fr@gmail.com> +Description: Sakia Wallet diff --git a/ci/travis/debian/DEBIAN/postinst b/ci/travis/debian/DEBIAN/postinst new file mode 100755 index 0000000000000000000000000000000000000000..bd3530cddadc3bb9e12d4d8233843ab2435e2cf7 --- /dev/null +++ b/ci/travis/debian/DEBIAN/postinst @@ -0,0 +1,9 @@ +#!/bin/bash + +SAKIA_ROOT=/opt/sakia + +unzip -d $SAKIA_ROOT/ $SAKIA_ROOT/sakia.zip +mv $SAKIA_ROOT/dist/sakia/* $SAKIA_ROOT/ +rm $SAKIA_ROOT/sakia.zip + +ln -s /opt/sakia/sakia /usr/bin/sakia diff --git a/ci/travis/debian/DEBIAN/prerm b/ci/travis/debian/DEBIAN/prerm new file mode 100755 index 0000000000000000000000000000000000000000..5a966f58f55449608c291fb3027c1ea7aeea946d --- /dev/null +++ b/ci/travis/debian/DEBIAN/prerm @@ -0,0 +1,4 @@ +#!/bin/bash + +rm /usr/bin/sakia +rm -Rf /opt/sakia diff --git a/ci/travis/debian/usr/share/applications/sakia.desktop b/ci/travis/debian/usr/share/applications/sakia.desktop new file mode 100644 index 0000000000000000000000000000000000000000..2842f12f24d6fb6727129d037ea27aac4a6b466d --- /dev/null +++ b/ci/travis/debian/usr/share/applications/sakia.desktop @@ -0,0 +1,6 @@ +[Desktop Entry] +Name=Sakia +Exec=sakia +Icon=/opt/sakia/sakia.png +Type=Application +Categories=Utility diff --git a/ci/travis/qt-installer-noninteractive.qs b/ci/travis/qt-installer-noninteractive.qs new file mode 100644 index 0000000000000000000000000000000000000000..30c54f9904c52fdceedbca08b6bf8e634856d14a --- /dev/null +++ b/ci/travis/qt-installer-noninteractive.qs @@ -0,0 +1,56 @@ +// Emacs mode hint: -*- mode: JavaScript -*- + +function Controller() { + installer.autoRejectMessageBoxes(); + installer.installationFinished.connect(function() { + gui.clickButton(buttons.NextButton); + }) +} + +Controller.prototype.WelcomePageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.CredentialsPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.TargetDirectoryPageCallback = function() +{ + gui.currentPageWidget().TargetDirectoryLineEdit.setText("/tmp/qt/5.5"); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() { + //var widget = gui.currentPageWidget(); + + //widget.selectAll(); + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.LicenseAgreementPageCallback = function() { + gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.StartMenuDirectoryPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ReadyForInstallationPageCallback = function() +{ + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.FinishedPageCallback = function() { +var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm +if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) { + checkBoxForm.launchQtCreatorCheckBox.checked = false; +} + gui.clickButton(buttons.FinishButton); +} diff --git a/ci/travis/test.sh b/ci/travis/test.sh index 1f772c1afb7d71ccc809900e9751e9b9625d6819..23b92d82e8824fa4d6630cb1c7026640c0c032fd 100755 --- a/ci/travis/test.sh +++ b/ci/travis/test.sh @@ -3,16 +3,15 @@ eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" -cd $HOME/build/ucoin-io/sakia -pyenv activate sakia-env - if [ $TRAVIS_OS_NAME == "linux" ] then export XVFBARGS="-screen 0 1280x1024x24" export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start + sh -e /etc/init.d/xvfb restart sleep 3 fi +cd $HOME/build/duniter/sakia +pyenv activate sakia-env coverage run --source=sakia.core,sakia.gui,sakia.models setup.py test diff --git a/doc/uml/api.png b/doc/uml/api.png index 259a52ab048c4393ba1c7adcbab06ae694732ef5..f557d71281f747f665355c62849852fd427b0826 100644 Binary files a/doc/uml/api.png and b/doc/uml/api.png differ diff --git a/doc/uml/core-classes.png b/doc/uml/core-classes.png index 810bd6cd7d5eca4fcf1e8cc22d532ca1899d76ca..54e0d69e92bc3200fa7bcd1bc6d2458cad95ff81 100644 Binary files a/doc/uml/core-classes.png and b/doc/uml/core-classes.png differ diff --git a/doc/uml/core-classes.pu b/doc/uml/core-classes.pu index fc8d1e6d972241369d76c3d582a79dc3d6f28762..c1463421238e08d35f9872ef6c926a4aa55c5003 100644 --- a/doc/uml/core-classes.pu +++ b/doc/uml/core-classes.pu @@ -1,5 +1,8 @@ @startuml +hide fields +hide methods + package core { class App { -- Signals -- @@ -96,6 +99,10 @@ package net { state -- Methods -- } - + + Network "1" --* "1" BmaAccess + + class BmaAccess { + } } -@enduml \ No newline at end of file +@enduml diff --git a/doc/uml/cutecoin.png b/doc/uml/cutecoin.png index 1a80c93cee49c91457f966685a13b0b277547d21..417230847dec853471dc5e7a618273d5be5e898b 100644 Binary files a/doc/uml/cutecoin.png and b/doc/uml/cutecoin.png differ diff --git a/doc/uml/gui-classes.png b/doc/uml/gui-classes.png index 08d764e03f869566e321ebaa76e98baf0e28d800..e00da1f229639c06e0ee5f201ea8d1d7e487f111 100644 Binary files a/doc/uml/gui-classes.png and b/doc/uml/gui-classes.png differ diff --git a/doc/uml/gui-classes.pu b/doc/uml/gui-classes.pu index f8a0bc964fc2dd6a5714d56dab6da971bdd5e2cd..1b00e1a188119584fcbc71d86e0ccf60b92d3ee7 100644 --- a/doc/uml/gui-classes.pu +++ b/doc/uml/gui-classes.pu @@ -4,20 +4,17 @@ package gui { class MainWindow { } - MainWindow "1" --* "*" CurrencyTab + MainWindow "1" --* "1" CommunityView - class CurrencyTab { + class CommunityView { } - CurrencyTab "1" --* "1" CommunityTab - CurrencyTab "1" --* "1" WalletTab - CurrencyTab "1" --* "1" InformationsTab - CurrencyTab "1" --* "1" TransactionsTab + CommunityView "1" --* "1" WalletTab + CommunityView "1" -down-* "1" InformationsTab + CommunityView "1" --* "1" TransactionsTab + CommunityView "1" --* "1" IdentitiesTab + CommunityView "1" --* "1" WotTab + CommunityView "1" -down-* "1" NetworkTab - class CommunityTab { - } - - CommunityTab "1" --* "1" IdentitiesTab - CommunityTab "1" --* "1" WotTab class WalletTab { } @@ -31,8 +28,6 @@ package gui { class NetworkTab { } - CurrencyTab "1" --* "1" NetworkTab - class IdentitiesTab { } @@ -51,8 +46,5 @@ package gui { MainWindow --> ContactDialog MainWindow --> ConfigureAccountDialog ConfigureAccountDialog --> ConfigureCommunityDialog - - class Wot - WotTab --> Wot } -@enduml \ No newline at end of file +@enduml diff --git a/doc/uml/models-classes.png b/doc/uml/models-classes.png index 9fa40280c691de29c350ba64206f9bf2f17d5b41..5833c6ecaf2c4c1b57601a5c682bdb941c2a61ea 100644 Binary files a/doc/uml/models-classes.png and b/doc/uml/models-classes.png differ diff --git a/doc/uml/network.png b/doc/uml/network.png index 6c327e5ff688c208b3de546486b68e501e9a67d8..c31386d981219956b30d8dc291e48fd9d69c4745 100644 Binary files a/doc/uml/network.png and b/doc/uml/network.png differ diff --git a/doc/uml/network.pu b/doc/uml/network.pu index b43bc97e5b0c1b8c6d1c6f7d151276cb91fd2e5f..68934532e5cc170c96f94fe7ae8d611faf6921f3 100644 --- a/doc/uml/network.pu +++ b/doc/uml/network.pu @@ -3,11 +3,11 @@ Network -->o Node : Connect to node_received() Network -> Node : Starts network discovery activate Node -Node -> ucoinpy : HTTP GET peering/peers?leaves=true +Node -> duniterpy : HTTP GET peering/peers?leaves=true alt "root" hash changed loop "for all leaves changed" activate Node -Node -> ucoinpy : HTTP GET peering/peers/leaf=leaf_hash +Node -> duniterpy : HTTP GET peering/peers/leaf=leaf_hash end end Network <-- Node : node_received() diff --git a/doc/uml/requests.png b/doc/uml/requests.png index a2744a23295b33628ecbc049ff86d701549ad1a4..85339a6ae644809ea4836ee4c109da64144f3e71 100644 Binary files a/doc/uml/requests.png and b/doc/uml/requests.png differ diff --git a/doc/uml/requests.pu b/doc/uml/requests.pu index ea824469889c4860069cdb067a413ceda3920848..642458e45a8858b7bfbfcea0bb005530e66e6fb1 100644 --- a/doc/uml/requests.pu +++ b/doc/uml/requests.pu @@ -8,7 +8,7 @@ ref over BmaAccess (new block mined since last caching) end ref -BmaAccess -> ucoinpy : HTTP GET +BmaAccess -> duniterpy : HTTP GET alt Rollback BmaAccess -> BmaAccess : Find last block number rollbacked ref over BmaAccess diff --git a/doc/uml/tx_lifecycle.png b/doc/uml/tx_lifecycle.png index 3c852325045ab309c6477d203d8b8831d11278ea..7f7102c0cac56b9a5aafa90498611f8caa9df429 100644 Binary files a/doc/uml/tx_lifecycle.png and b/doc/uml/tx_lifecycle.png differ diff --git a/gen_translations.py b/gen_translations.py index d587a62599da3cf318579598e089b437a10e0f63..35c1d6b0c3c6f53f79f797f9fc0b52560a2110ea 100644 --- a/gen_translations.py +++ b/gen_translations.py @@ -27,7 +27,7 @@ def prepare_qm(): for (ts_file, qm_file) in translations: # avoid conflict with qt4 lrelease by running qtchooser directly - if sys.platform.startswith('win') or shutil.which("qtchooser") == None: + if sys.platform.startswith('win') or shutil.which("qtchooser") == None or "--lrelease" in sys.argv: subprocess.call(["lrelease", ts_file, "-qm", qm_file]) else: subprocess.call(["qtchooser", "-run-tool=lrelease", "-qt=5", ts_file, "-qm", qm_file]) diff --git a/hooks/hook-PyQt5.QtGui.py b/hooks/hook-PyQt5.QtGui.py index d82904c2aa7bfc748c3b1144663541b2739d7d3a..c603f289080ef5e19dc773e25e30a575c33f8cf7 100644 --- a/hooks/hook-PyQt5.QtGui.py +++ b/hooks/hook-PyQt5.QtGui.py @@ -10,17 +10,17 @@ hiddenimports = ['sip', 'PyQt5.QtCore'] -from PyInstaller.utils.hooks import qt5_plugins_binaries +from PyInstaller.utils.hooks import qt_plugins_binaries from PyInstaller.compat import is_linux binaries = [] -binaries.extend(qt5_plugins_binaries('accessible')) -binaries.extend(qt5_plugins_binaries('iconengines')) -binaries.extend(qt5_plugins_binaries('imageformats')) -binaries.extend(qt5_plugins_binaries('inputmethods')) -binaries.extend(qt5_plugins_binaries('graphicssystems')) -binaries.extend(qt5_plugins_binaries('platforms')) +binaries.extend(qt_plugins_binaries('accessible', namespace='PyQt5')) +binaries.extend(qt_plugins_binaries('iconengines', namespace='PyQt5')) +binaries.extend(qt_plugins_binaries('imageformats', namespace='PyQt5')) +binaries.extend(qt_plugins_binaries('inputmethods', namespace='PyQt5')) +binaries.extend(qt_plugins_binaries('graphicssystems', namespace='PyQt5')) +binaries.extend(qt_plugins_binaries('platforms', namespace='PyQt5')) if is_linux: - binaries.extend(qt5_plugins_binaries('platformthemes')) + binaries.extend(qt_plugins_binaries('platformthemes', namespace='PyQt5')) diff --git a/release.sh b/release.sh new file mode 100755 index 0000000000000000000000000000000000000000..e8be965b5af5c7140cecdc4d42cfb7472013c3ab --- /dev/null +++ b/release.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +#__version_info__ = ('0', '20', '0dev6') +current=`grep -P "__version_info__ = \(\'\d+\', \'\d+\', \'\d+(\w*)\'\)" src/sakia/__init__.py | grep -oP "\'\d+\', \'\d+\', \'\d+(\w*)\'"` +echo "Current version: $current" + +if [[ $1 =~ ^[0-9]+.[0-9]+.[0-9]+[0-9a-z]*$ ]]; then + IFS='.' read -r -a array <<< "$1" + sed -i "s/__version_info__\ = ($current)/__version_info__ = ('${array[0]}', '${array[1]}', '${array[2]}')/g" src/sakia/__init__.py + sed -i "s/#define MyAppVerStr .*/#define MyAppVerStr \"$1\"/g" ci/appveyor/sakia.iss + sed -i "s/Version: .*/Version: $1/g" ci/travis/debian/DEBIAN/control + git commit src/sakia/__init__.py ci/appveyor/sakia.iss ci/travis/debian/DEBIAN/control -m "$1" + git tag "$1" -a -m "$1" +else + echo "Wrong version format" +fi diff --git a/requirements.txt b/requirements.txt index c4379dc46caef502b33db85fe8b273c1058bd20a..847ac1a6b4e9387237eb3f6723554f601ea44d1c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -ucoinpy>=0.13 +duniterpy>=0.20.dev0 git+https://github.com/harvimt/quamash.git@gh45 asynctest -git+https://github.com/networkx/networkx.git@v1.11 \ No newline at end of file +networkx \ No newline at end of file diff --git a/res/i18n/ts/de_DE.ts b/res/i18n/ts/de_DE.ts index f64848c2dba4d8c05c7d0aa78104434ba896116a..11a8db2302e333e48998b773c4b370e22228b8f2 100644 --- a/res/i18n/ts/de_DE.ts +++ b/res/i18n/ts/de_DE.ts @@ -51,8 +51,23 @@ <translation type="obsolete">Relative Z-Summe</translation> </message> <message> - <location filename="../../../src/sakia/core/account.py" line="510"/> + <location filename="../../../src/sakia/core/account.py" line="540"/> <source>Could not find user self certification.</source> + <translation>Konnte nicht gefunden werden User-Self-Zertifizierung.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="67"/> + <source>Warning : Your membership is expiring soon.</source> + <translation type="unfinished">Warnung: Ihre Mitgliedschaft läuft bald ab.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="72"/> + <source>Warning : Your could miss certifications soon.</source> + <translation type="unfinished">Warnung: In Kürze könnten Sie Zertifizierungen verpassen.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="77"/> + <source>Warning : If you don't renew soon, your identity will be considerd revoked.</source> <translation type="unfinished"></translation> </message> </context> @@ -91,7 +106,7 @@ <message> <location filename="../../ui/account_cfg.ui" line="143"/> <source>CryptoID</source> - <translation>CryptoID</translation> + <translation type="obsolete">CryptoID</translation> </message> <message> <location filename="../../ui/account_cfg.ui" line="153"/> @@ -138,49 +153,54 @@ <source>Communities</source> <translation>Gemeinschaften</translation> </message> + <message> + <location filename="../../ui/account_cfg.ui" line="143"/> + <source>Entropy</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Application</name> <message> <location filename="../../../src/sakia/core/app.py" line="76"/> <source>Warning : Your membership is expiring soon.</source> - <translation type="unfinished">Warnung: Ihre Mitgliedschaft läuft bald ab.</translation> + <translation type="obsolete">Warnung: Ihre Mitgliedschaft läuft bald ab.</translation> </message> <message> <location filename="../../../src/sakia/core/app.py" line="81"/> <source>Warning : Your could miss certifications soon.</source> - <translation type="unfinished">Warnung: In Kürze könnten Sie Zertifizierungen verpassen.</translation> + <translation type="obsolete">Warnung: In Kürze könnten Sie Zertifizierungen verpassen.</translation> </message> </context> <context> <name>CertificationDialog</name> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Certification</source> <translation>Zertifizierung</translation> </message> <message> - <location filename="../../ui/certification.ui" line="20"/> + <location filename="../../ui/certification.ui" line="26"/> <source>Community</source> <translation>Gemeinschaft</translation> </message> <message> - <location filename="../../ui/certification.ui" line="32"/> + <location filename="../../ui/certification.ui" line="54"/> <source>Certify user</source> <translation>Nutzer zertifizieren</translation> </message> <message> <location filename="../../ui/certification.ui" line="40"/> <source>Contact</source> - <translation>Kontakt</translation> + <translation type="obsolete">Kontakt</translation> </message> <message> <location filename="../../ui/certification.ui" line="61"/> <source>User public key</source> - <translation>Öffentlicher Schlüssel des Nutzers</translation> + <translation type="obsolete">Öffentlicher Schlüssel des Nutzers</translation> </message> <message> - <location filename="../../ui/certification.ui" line="80"/> + <location filename="../../ui/certification.ui" line="157"/> <source>Key</source> <translation>Schlüssel</translation> </message> @@ -200,7 +220,7 @@ <translation type="obsolete">OK</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="112"/> + <location filename="../../../src/sakia/gui/certification.py" line="227"/> <source>Not a member</source> <translation>Kein Mitglied</translation> </message> @@ -210,20 +230,75 @@ <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="109"/> + <location filename="../../../src/sakia/gui/certification.py" line="221"/> <source>&Ok</source> <translation>&Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="75"/> + <location filename="../../../src/sakia/gui/certification.py" line="126"/> <source>Success sending certification</source> - <translation type="unfinished"></translation> + <translation>Erfolg Absenden Zertifizierung</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Could not broadcast certification : {0}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/certification.ui" line="73"/> + <source>Con&tact</source> + <translation>Kontakt</translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="116"/> + <source>&User public key</source> + <translation type="unfinished">User public key</translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="161"/> + <source>S&earch user</source> + <translation type="obsolete">Suche Benutzer</translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="35"/> + <source>Certifications stock</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="177"/> + <source>Sea&rch user</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="197"/> + <source>Certifications sent : {nb_certifications}/{stock}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="206"/> + <source>{days} days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="208"/> + <source>{hours} hours and {min} min.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="210"/> + <source>Remaining time before next certification validation : {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="217"/> + <source> (Not validated before </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="224"/> + <source>No more certifications</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityConfigurationDialog</name> @@ -253,17 +328,17 @@ <translation>Server</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="200"/> + <location filename="../../ui/community_cfg.ui" line="203"/> <source>Add</source> <translation>Hinzufügen</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="221"/> + <location filename="../../ui/community_cfg.ui" line="224"/> <source>Previous</source> <translation>Zurück</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="244"/> + <location filename="../../ui/community_cfg.ui" line="247"/> <source>Next</source> <translation>Weiter</translation> </message> @@ -280,12 +355,12 @@ <message> <location filename="../../ui/community_cfg.ui" line="115"/> <source>Connect using your account</source> - <translation type="unfinished"></translation> + <translation>Verbinden Sie mit Ihrem Konto</translation> </message> <message> <location filename="../../ui/community_cfg.ui" line="132"/> <source>Connect as a guest</source> - <translation type="unfinished"></translation> + <translation>Verbinden Sie als Gast</translation> </message> </context> <context> @@ -384,45 +459,80 @@ <context> <name>CommunityTile</name> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="81"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Member</source> <translation>Mitglied</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="82"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Non-Member</source> <translation>Nichtmitglied</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>members</source> <translation>Mitglieder</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Monetary mass</source> - <translation type="unfinished"></translation> + <translation>Währungsmassen</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Status</source> <translation>Status</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Balance</source> <translation>Gleichgewicht</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="112"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="162"/> <source>Not connected</source> - <translation type="unfinished"></translation> + <translation>Nicht verbunden</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="125"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="175"/> <source>Community not initialized</source> + <translation>Gemeinschaft nicht initialisiert</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="100"/> + <source>Expired or never published</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="101"/> + <source>Outdistanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="110"/> + <source>In WoT range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="116"/> + <source>Expires in </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="124"/> + <source>#FF0000</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Certs. received</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Membership</source> + <translation type="unfinished">Mitgliedschaft</translation> + </message> </context> <context> <name>CommunityWidget</name> @@ -442,7 +552,7 @@ <translation type="unfinished">Zertifizierung</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="289"/> + <location filename="../../../src/sakia/gui/community_view.py" line="286"/> <source>Renew membership</source> <translation>Mitgliedschaft erneuern</translation> </message> @@ -457,62 +567,57 @@ <translation type="obsolete">Warnung: In Kürze könnten Sie Zertifizierungen verpassen.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="34"/> + <location filename="../../../src/sakia/gui/community_view.py" line="33"/> <source>Transactions</source> <translation type="unfinished">Transaktionen</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <location filename="../../../src/sakia/gui/community_view.py" line="34"/> <source>Web of Trust</source> - <translation type="unfinished">Web of Trust</translation> + <translation>Netz des Vertrauens</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="37"/> + <location filename="../../../src/sakia/gui/community_view.py" line="90"/> <source>Network</source> - <translation type="unfinished">Netzwerk</translation> + <translation>Netzwerk</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source>Membership expiration</source> <translation type="unfinished">Ablauf der Mitgliedschaft</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source><b>Warning : Membership expiration in {0} days</b></source> <translation type="unfinished"><b>Warnung: Ihre Mitgliedschaft läuft in {0} Tagen aus.</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source>Certifications number</source> - <translation type="unfinished"></translation> + <translation>Zertifizierungen Nummer</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source><b>Warning : You are certified by only {0} persons, need {1}</b></source> <translation type="unfinished"><b>Warnung: Sie wurden nur von {0} Personen zertifiziert, benötigt werden {1}</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="228"/> + <location filename="../../../src/sakia/gui/community_view.py" line="235"/> <source> Block {0}</source> - <translation type="unfinished"> Block {0}</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/community_view.py" line="270"/> - <source> - Median fork window : {0}</source> - <translation type="unfinished"></translation> + <translation type="obsolete"> Block {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="295"/> + <location filename="../../../src/sakia/gui/community_view.py" line="292"/> <source>Send membership demand</source> <translation type="unfinished">Mitgliedschaft beantragen</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Warning</source> <translation type="unfinished">Warnung</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Are you sure ? Sending a leaving demand cannot be canceled. The process to join back the community later will have to be done again.</source> @@ -533,7 +638,7 @@ Die Veröffentlichung der UID kann durch Widerruf der UID rückgängig gemacht w <translation type="obsolete">UID-Veröffentlichung</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="375"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Success publishing your UID</source> <translation type="unfinished">UID erfolgreich veröffentlicht</translation> </message> @@ -565,22 +670,22 @@ Revoking your UID can only success if it is not already validated by the network Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert wurde.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Membership</source> <translation type="unfinished">Mitgliedschaft</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="329"/> + <location filename="../../../src/sakia/gui/community_view.py" line="325"/> <source>Success sending Membership demand</source> <translation type="unfinished">Mitglieds-Antrag erfolgreich versandt</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="361"/> + <location filename="../../../src/sakia/gui/community_view.py" line="356"/> <source>Revoke</source> <translation type="unfinished">Widerruf</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="355"/> + <location filename="../../../src/sakia/gui/community_view.py" line="350"/> <source>Success sending Revoke demand</source> <translation type="unfinished">Widerruf-Antrag erfolgreich versandt</translation> </message> @@ -595,12 +700,12 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="obsolete">Selbstzertifizierung erfolgreich versandt</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <location filename="../../../src/sakia/gui/community_view.py" line="94"/> <source>Show informations</source> - <translation type="unfinished"></translation> + <translation>Informationen anzeigen</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="38"/> + <location filename="../../../src/sakia/gui/community_view.py" line="95"/> <source>Informations</source> <translation type="unfinished">Informationen</translation> </message> @@ -610,23 +715,43 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="unfinished">UID veröffentlichen</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="399"/> + <location filename="../../../src/sakia/gui/community_view.py" line="41"/> <source>Revoke UID</source> <translation type="unfinished">UID widerrufen</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="401"/> + <location filename="../../../src/sakia/gui/community_view.py" line="375"/> <source>UID</source> <translation type="unfinished">UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="398"/> <source>Your UID was revoked successfully.</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Ihre Kennung wurde erfolgreich widerrufen.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="36"/> + <location filename="../../../src/sakia/gui/community_view.py" line="35"/> <source>Search Identities</source> + <translation>Suche nach Identität</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <source>Explore the Web of Trust</source> + <translation>Erkunden Sie die Netz des Vertrauens</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="99"/> + <source>Show explorer</source> + <translation>Zeigen Sie den entdecker</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="100"/> + <source>Explorer</source> + <translation>Der entdecker</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="234"/> + <source>Block {0}</source> <translation type="unfinished"></translation> </message> </context> @@ -648,11 +773,26 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation>Öffentlicher Schlüssel</translation> </message> <message> - <location filename="../../../src/sakia/gui/contact.py" line="52"/> + <location filename="../../../src/sakia/gui/contact.py" line="81"/> <source>Contact already exists</source> <translation>Kontakt ist schon vorhanden</translation> </message> </context> +<context> + <name>ContextMenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Warning</source> + <translation type="unfinished">Warnung</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Are you sure ? +This money transfer will be removed and not sent.</source> + <translation type="unfinished">Bist du sicher ? +Diese Überweisung, werden entfernt und nicht gesendet.</translation> + </message> +</context> <context> <name>CreateWalletDialog</name> <message> @@ -744,48 +884,159 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <message> <location filename="../../ui/member.ui" line="14"/> <source>Informations</source> - <translation>Informationen</translation> + <translation type="obsolete">Informationen</translation> </message> <message> <location filename="../../ui/member.ui" line="34"/> <source>Member</source> - <translation>Mitglied</translation> + <translation type="obsolete">Mitglied</translation> </message> <message> <location filename="../../ui/member.ui" line="65"/> <source>uid</source> - <translation>uid</translation> + <translation type="obsolete">uid</translation> </message> <message> <location filename="../../ui/member.ui" line="72"/> <source>properties</source> - <translation>Eigenschaften</translation> + <translation type="obsolete">Eigenschaften</translation> + </message> +</context> +<context> + <name>DividendPerDay</name> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="9"/> + <source>UDD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="10"/> + <source>{0} {1}UDD {2}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="11"/> + <source>UDD {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="12"/> + <source>UDD(t) = (Q * 100) / (UD(t) / DT) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>ExplorerTabWidget</name> + <message> + <location filename="../../ui/explorer_tab.ui" line="14"/> + <source>Form</source> + <translation>Form</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="48"/> + <source>Steps</source> + <translation>Schritte</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="65"/> + <source>Go</source> + <translation>Gehen</translation> + </message> +</context> +<context> + <name>GraphTabWidget</name> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="71"/> + <source>Membership</source> + <translation type="unfinished">Mitgliedschaft</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source>Last renewal on {:}, expiration on {:}</source> + <translation>Letzte Erneuerung auf {:}, Ablauf auf {:}</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Your web of trust</source> + <translation>Ihr Netz des Vertrauens</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Certified by {:} members; Certifier of {:} members</source> + <translation>Zertifiziert durch {:} mitglieder; Zertifizierer von {:} mitglieder</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Not a member</source> + <translation type="unfinished">Kein Mitglied</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> </message> </context> <context> <name>HistoryTableModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Date</source> <translation>Datum</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>UID/Public key</source> <translation>UID/öffentlicher Schlüssel</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Payment</source> <translation>Zahlung</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Deposit</source> <translation>Einzahlung</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Comment</source> <translation>Kommentar</translation> </message> @@ -838,7 +1089,7 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <message> <location filename="../../../src/sakia/gui/homescreen.py" line="73"/> <source>Connected as {0}</source> - <translation type="unfinished"></translation> + <translation>Verbunden {0}</translation> </message> </context> <context> @@ -851,7 +1102,7 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <message> <location filename="../../ui/homescreen.ui" line="47"/> <source>Connected as</source> - <translation type="unfinished"></translation> + <translation>Verbunden</translation> </message> <message> <location filename="../../ui/homescreen.ui" line="54"/> @@ -861,22 +1112,22 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <message> <location filename="../../ui/homescreen.ui" line="71"/> <source>Disconnect</source> - <translation type="unfinished"></translation> + <translation>Ausloggen</translation> </message> <message> <location filename="../../ui/homescreen.ui" line="119"/> <source><html><head/><body><p><span style=" font-size:12pt; font-weight:600;">Not Connected</span></p></body></html></source> - <translation type="unfinished"></translation> + <translation><html><head/><body><p><span style=" font-size:12pt; font-weight:600;">offline</span></p></body></html></translation> </message> <message> <location filename="../../ui/homescreen.ui" line="126"/> <source>Connect</source> - <translation type="unfinished"></translation> + <translation>Verbinden</translation> </message> <message> <location filename="../../ui/homescreen.ui" line="149"/> <source>New account</source> - <translation type="unfinished"></translation> + <translation>Neues Konto</translation> </message> </context> <context> @@ -902,75 +1153,80 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="36"/> <source>Members</source> - <translation type="unfinished">Mitglieder</translation> + <translation type="obsolete">Mitglieder</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="37"/> <source>Direct connections</source> - <translation type="unfinished">Direkte Verbindungen</translation> + <translation type="obsolete">Direkte Verbindungen</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="112"/> <source>Informations</source> - <translation type="unfinished">Informationen</translation> + <translation type="obsolete">Informationen</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="115"/> <source>Add as contact</source> - <translation type="unfinished">Als Kontakt hinzufügen</translation> + <translation type="obsolete">Als Kontakt hinzufügen</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="119"/> <source>Send money</source> - <translation type="unfinished">Geld schicken</translation> + <translation type="obsolete">Geld schicken</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="123"/> <source>Certify identity</source> - <translation type="unfinished">Identität zertifizieren</translation> + <translation type="obsolete">Identität zertifizieren</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="127"/> <source>View in Web of Trust</source> - <translation type="unfinished">Im Web of Trust anschauen</translation> + <translation type="obsolete">Im Web of Trust anschauen</translation> </message> <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="131"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <location filename="../../../src/sakia/gui/identities_tab.py" line="32"/> + <source>Search direct certifications</source> + <translation>Suche Direkt Zertifizierungen</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/identities_tab.py" line="33"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Nach öffentlichem Schlüssel oder uid suchen…</translation> </message> </context> <context> <name>IdentitiesTableModel</name> <message> - <location filename="../../../src/sakia/models/identities.py" line="89"/> + <location filename="../../../src/sakia/models/identities.py" line="118"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="90"/> + <location filename="../../../src/sakia/models/identities.py" line="119"/> <source>Pubkey</source> <translation>Öffentlicher Schlüssel</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="91"/> + <location filename="../../../src/sakia/models/identities.py" line="120"/> <source>Renewed</source> <translation>Erneuert</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="92"/> + <location filename="../../../src/sakia/models/identities.py" line="121"/> <source>Expiration</source> <translation>Ablaufdatum</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="94"/> + <location filename="../../../src/sakia/models/identities.py" line="123"/> <source>Validation</source> <translation>Validierungs</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="93"/> + <location filename="../../../src/sakia/models/identities.py" line="122"/> <source>Publication</source> - <translation type="unfinished"></translation> + <translation>Veröffentlichung</translation> </message> </context> <context> @@ -1079,27 +1335,27 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="obsolete">label_wot</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Universal Dividend UD(t) in</source> <translation>Universelle Dividende (UD)(t) in</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Members N(t)</source> <translation>Mitglieder N(t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Next UD date and time (t+1)</source> <translation>Datum und Zeit der nächsten UD (t+1)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="194"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="196"/> <source>No Universal Dividend created yet.</source> <translation>Noch keine universelle Dividende erhalten.</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1116,32 +1372,32 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:2.0%} / {:} days</source> <translation>{:2.0%} / {:} Tage</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Fundamental growth (c) / Delta time (dt)</source> <translation>Effektives Wachstum (c) / Delta Zeit (dt)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (formula)</source> <translation>Universelle Dividende (Formel)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</source> <translation>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (computed)</source> <translation>Universelle Dividende (errechnet)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> @@ -1168,47 +1424,47 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Fundamental growth (c)</source> <translation>Effektives Wachstum (c)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Initial Universal Dividend UD(0) in</source> <translation>Initiale universelle Dividende UD(0) in</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Time period (dt) in days (86400 seconds) between two UD</source> <translation>Zeitraum (dt) in Tagen (86400 Sekunden) zwischen zwei UDs</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Number of blocks used for calculating median time</source> <translation>Anzahl der Blöcke zur Berechnung des Zeit-Medians</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The average time in seconds for writing 1 block (wished time)</source> <translation>Durchschnittliche Zeit zum Schreiben eines Blocks in Sekunden (erhoffte Zeit)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of blocks required to evaluate again PoWMin value</source> <translation>Anzahl der Blöcke, die mindesten gegen den POWMin-Wert validiert werden müssen</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of previous blocks to check for personalized difficulty</source> <translation>Anzahl vorhergehender Blöcke, um den individuellen Schwierigkeitsgrad zu erhalten</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The percent of previous issuers to reach for personalized difficulty</source> <translation type="unfinished">Prozentsatz vorhergehender Emittenten, der erreicht werden muss, um den persönlichen Schwierigkeitsgrad zu erhalten</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1219,7 +1475,7 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1231,32 +1487,27 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum delay between 2 identical certifications (in days)</source> - <translation>Minimale Frist (in Tagen) zwischen zwei identischen Zertifizierungen</translation> + <translation type="obsolete">Minimale Frist (in Tagen) zwischen zwei identischen Zertifizierungen</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid signature (in days)</source> <translation>Maximales Alter einer validen Unterschrift (in Tagen)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Minimum quantity of signatures to be part of the WoT</source> <translation>Mindestanzahl an Unterschriften, um ein Teil des WoT zu werden</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> - <source>Minimum quantity of valid made certifications to be part of the WoT for distance rule</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid membership (in days)</source> <translation>Höchstalter eines gültigen Mitgliedschaft (in Tagen)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum distance between each WoT member and a newcomer</source> <translation type="unfinished"></translation> </message> @@ -1286,32 +1537,32 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass M(t-1) in</source> <translation>Geldversorgung M(t-1) im</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass per member M(t-1)/N(t) in</source> <translation>Geldmenge pro Mitglied M(t-1)/N(t) im</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Actual growth c = UD(t)/[M(t-1)/N(t)]</source> <translation>Tatsächliche Wachstum : c = UD(t) / [ M(t-1) / N(t) ]</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Last UD date and time (t)</source> <translation>Letzte UD Datum und Uhrzeit (t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</source> <translation>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> @@ -1324,10 +1575,21 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"></translation> + <translation type="unfinished"> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> + <tr><td align="right"><b>{:2.2%} / {:} tage</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Penultimate UD date and time (t-1)</source> <translation type="unfinished"></translation> </message> @@ -1337,40 +1599,76 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Name</source> <translation type="unfinished">Name</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Units</source> <translation type="unfinished">Einheiten</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Formula</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Description</source> <translation type="unfinished"></translation> </message> -</context> -<context> - <name>MainWindow</name> <message> - <location filename="../../ui/mainwindow.ui" line="30"/> - <source>Fi&le</source> - <translation type="unfinished">&Datei</translation> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="131"/> - <source>Account</source> - <translation>Account</translation> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum delay between 2 certifications (in days)</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="55"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum quantity of active certifications made by member.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum delay a certification can wait before being expired for non-writing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum percent of sentries to reach to match the distance rule</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MainWindow</name> + <message> + <location filename="../../ui/mainwindow.ui" line="30"/> + <source>Fi&le</source> + <translation type="unfinished">&Datei</translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="138"/> + <source>Account</source> + <translation>Account</translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="55"/> <source>&Contacts</source> <translation type="obsolete">&Kontakte</translation> </message> @@ -1385,12 +1683,12 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation>&Helfen</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="76"/> + <location filename="../../ui/mainwindow.ui" line="83"/> <source>Manage accounts</source> <translation>Konten verwalten</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="81"/> + <location filename="../../ui/mainwindow.ui" line="88"/> <source>Configure trustable nodes</source> <translation>Konfigurieren Sie vertrauenswürdige Knoten</translation> </message> @@ -1400,47 +1698,47 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="obsolete">&Hinzufügen eines Kontakts</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="106"/> + <location filename="../../ui/mainwindow.ui" line="113"/> <source>Send a message</source> <translation>Eine Nachricht schicken</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="111"/> + <location filename="../../ui/mainwindow.ui" line="118"/> <source>Send money</source> <translation type="unfinished">Geld schicken</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="116"/> + <location filename="../../ui/mainwindow.ui" line="123"/> <source>Remove contact</source> <translation>Kontakt löschen</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="121"/> + <location filename="../../ui/mainwindow.ui" line="128"/> <source>Save</source> <translation>Speichern</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="126"/> + <location filename="../../ui/mainwindow.ui" line="133"/> <source>&Quit</source> <translation>&Beenden</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="136"/> + <location filename="../../ui/mainwindow.ui" line="143"/> <source>&Transfer money</source> <translation type="unfinished">&Geld überweisen</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="141"/> + <location filename="../../ui/mainwindow.ui" line="148"/> <source>&Configure</source> <translation>&Konfigurieren</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="146"/> + <location filename="../../ui/mainwindow.ui" line="153"/> <source>&Import</source> <translation>&Import</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="151"/> + <location filename="../../ui/mainwindow.ui" line="158"/> <source>&Export</source> <translation>&Export</translation> </message> @@ -1450,32 +1748,32 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="obsolete">Zertifizierung</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="161"/> + <location filename="../../ui/mainwindow.ui" line="168"/> <source>&Set as default</source> <translation type="unfinished">&Als Standard einstellen</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="166"/> + <location filename="../../ui/mainwindow.ui" line="173"/> <source>A&bout</source> <translation>&Über</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="171"/> + <location filename="../../ui/mainwindow.ui" line="178"/> <source>&Preferences</source> <translation>%Voreinstellungen</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="176"/> + <location filename="../../ui/mainwindow.ui" line="183"/> <source>&Add account</source> <translation>&Konto hinzufügen</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="211"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="285"/> <source>Latest release : {version}</source> <translation>Neueste Version : {version}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="218"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="292"/> <source>Download link</source> <translation>Download link</translation> </message> @@ -1515,17 +1813,17 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="251"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="326"/> <source>Please get the latest release {version}</source> <translation type="unfinished">Bitte laden Sie die neueste Version {version} herunter</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="283"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="358"/> <source>Edit</source> <translation>Bearbeiten</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="286"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="361"/> <source>Delete</source> <translation>Löschen</translation> </message> @@ -1540,39 +1838,39 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="obsolete">CuteCoin {0} - Konto : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="348"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="424"/> <source>Export an account</source> <translation>Konto exportieren</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="349"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="425"/> <source>All account files (*.acc)</source> <translation type="unfinished">Alle Konten-Dateien (*.acc)</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="350"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="426"/> <source>Export</source> <translation>Export</translation> </message> <message> <location filename="../../ui/mainwindow.ui" line="40"/> <source>Acco&unt</source> - <translation type="unfinished"></translation> + <translation>Konto</translation> </message> <message> <location filename="../../ui/mainwindow.ui" line="44"/> <source>Co&ntacts</source> - <translation type="unfinished"></translation> + <translation>Kontakte</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="86"/> + <location filename="../../ui/mainwindow.ui" line="93"/> <source>A&dd a contact</source> - <translation type="unfinished"></translation> + <translation>Einen Kontakt hinzufügen</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="156"/> + <location filename="../../ui/mainwindow.ui" line="163"/> <source>C&ertification</source> - <translation type="unfinished"></translation> + <translation>Bescheinigung</translation> </message> <message> <location filename="../../../src/sakia/gui/mainwindow.py" line="225"/> @@ -1593,123 +1891,200 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <p>Moul</p> <p>canercandan</p> </source> - <translation type="unfinished"></translation> + <translation type="obsolete"> + <h1>Sakia</h1> + + <p>Python/Qt uCoin client</p> + + <p>Version : {:}</p> + {new_version_text} + + <p>Lizenz : GPLv3</p> + + <p><b>Autoren</b></p> + + <p>inso</p> + <p>vit</p> + <p>Moul</p> + <p>canercandan</p> + </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="303"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="383"/> <source>sakia {0}</source> - <translation type="unfinished"></translation> + <translation>Sakia {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="330"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="407"/> <source>sakia {0} - Account : {1}</source> + <translation>Sakia {0} - Konto : {1}</translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="71"/> + <source>&Duniter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="188"/> + <source>&Manage local node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="299"/> + <source> + <h1>sakia</h1> + + <p>Python/Qt duniter client</p> + <p><a href="https://github.com/duniter/sakia">https://github.com/duniter/sakia</a></p> + + <p>Version : {:}</p> + {new_version_text} + + <p>License : GPLv3</p> + + <p><b>Authors</b></p> + + <p>inso</p> + <p>vit</p> + <p>Moul</p> + <p>canercandan</p> + </source> <translation type="unfinished"></translation> </message> </context> <context> <name>MemberDialog</name> <message> - <location filename="../../../src/sakia/gui/member.py" line="46"/> + <location filename="../../../src/sakia/gui/member.py" line="73"/> <source>not a member</source> <translation>Kein Mitglied</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="60"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> - </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Public key</source> <translation>Einen öffentlichen Schlüssel</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Join date</source> <translation>Registriert seit</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="87"/> + <location filename="../../../src/sakia/gui/member.py" line="144"/> <source><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></source> <translation><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="73"/> + <location filename="../../../src/sakia/gui/member.py" line="130"/> <source>Distance</source> <translation>Abstand</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="80"/> + <location filename="../../../src/sakia/gui/member.py" line="139"/> <source>Path</source> <translation type="unfinished">Weg</translation> </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="92"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </source> + <translation> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </translation> + </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="97"/> + <source>UID Published on</source> + <translation type="unfinished">Die Kennung veröffentlicht</translation> + </message> +</context> +<context> + <name>MemberView</name> + <message> + <location filename="../../ui/member.ui" line="14"/> + <source>Member informations</source> + <translation>Mitglied Informationen</translation> + </message> + <message> + <location filename="../../ui/member.ui" line="34"/> + <source>Member</source> + <translation type="unfinished">Mitglied</translation> + </message> </context> <context> <name>NetworkFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="48"/> + <location filename="../../../src/sakia/models/network.py" line="54"/> <source>Address</source> <translation>Anschrift</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="49"/> + <location filename="../../../src/sakia/models/network.py" line="55"/> <source>Port</source> <translation>Port</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="50"/> + <location filename="../../../src/sakia/models/network.py" line="56"/> <source>Block</source> <translation>Block</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="52"/> + <location filename="../../../src/sakia/models/network.py" line="59"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="53"/> + <location filename="../../../src/sakia/models/network.py" line="60"/> <source>Member</source> <translation>Mitglied</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="54"/> + <location filename="../../../src/sakia/models/network.py" line="61"/> <source>Pubkey</source> <translation type="unfinished">Öffentlicher Schlüssel</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="55"/> + <location filename="../../../src/sakia/models/network.py" line="62"/> <source>Software</source> <translation>Software</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="56"/> + <location filename="../../../src/sakia/models/network.py" line="63"/> <source>Version</source> <translation>Version</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>yes</source> <translation>ja</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>no</source> <translation>nein</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>offline</source> <translation>offline</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="51"/> + <location filename="../../../src/sakia/models/network.py" line="57"/> <source>Hash</source> <translation>Hash</translation> </message> + <message> + <location filename="../../../src/sakia/models/network.py" line="58"/> + <source>Time</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>NetworkTabWidget</name> @@ -1719,17 +2094,17 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation>Formular</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="70"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="72"/> <source>Unset root node</source> - <translation type="unfinished"></translation> + <translation></translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="76"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="78"/> <source>Set as root node</source> - <translation type="unfinished"></translation> + <translation></translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="82"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="84"/> <source>Open in browser</source> <translation>Im Browser öffnen</translation> </message> @@ -1737,26 +2112,34 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <context> <name>NetworkTableModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="136"/> + <location filename="../../../src/sakia/models/network.py" line="155"/> <source>Online</source> <translation>Online</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="137"/> + <location filename="../../../src/sakia/models/network.py" line="156"/> <source>Offline</source> <translation>Offline</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="138"/> + <location filename="../../../src/sakia/models/network.py" line="157"/> <source>Unsynchronized</source> <translation>Unsynchronisierten</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="139"/> + <location filename="../../../src/sakia/models/network.py" line="158"/> <source>Corrupted</source> <translation>Beschädigt</translation> </message> </context> +<context> + <name>NodeManager</name> + <message> + <location filename="../../ui/node_manager.ui" line="14"/> + <source>Node manager</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>PasswordAskerDialog</name> <message> @@ -1775,22 +2158,22 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation>Passwort speichern während dieser Sitzung</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Bad password</source> <translation type="unfinished">Ein falsches Kennwort</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Non printable characters in password</source> <translation type="unfinished">Nicht druckbare Zeichen in das Kennwort</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Failed to get private key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Wrong password typed. Cannot open the private key</source> <translation type="unfinished">Mot de passe incorrect est entré. Impossible d'ouvrir la clé privée</translation> </message> @@ -1853,61 +2236,66 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="329"/> + <location filename="../../ui/preferences.ui" line="356"/> <source><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Network settings</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="345"/> + <location filename="../../ui/preferences.ui" line="372"/> <source>Proxy server address : </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="355"/> + <location filename="../../ui/preferences.ui" line="382"/> <source>:</source> <translation type="unfinished">:</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="336"/> + <location filename="../../ui/preferences.ui" line="363"/> <source>Use a http proxy server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="379"/> + <location filename="../../ui/preferences.ui" line="406"/> <source>Automatically refresh identities informations</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/preferences.ui" line="330"/> + <source>Enable forgetfulness</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureAccount</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="163"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="165"/> <source>New account</source> - <translation type="unfinished"></translation> + <translation type="unfinished">Neues Konto</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="170"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="175"/> <source>Configure {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="185"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="190"/> <source>Ok</source> <translation type="unfinished">OK</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="243"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="249"/> <source>Error</source> <translation type="unfinished">Fehler</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> <source>Warning</source> <translation type="unfinished">Warnung</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> - <source>This action will delete your account locally. + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> + <source>This action will delete your account ({0}) locally. Please note your key parameters (salt and password) if you wish to recover it later. Your account won't be removed from the networks it joined. Are you sure ?</source> @@ -1917,22 +2305,22 @@ Are you sure ?</source> <context> <name>ProcessConfigureCommunity</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="227"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="240"/> <source>Configure community {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="230"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="243"/> <source>Add a community</source> <translation type="unfinished">Community hinzufügen</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="264"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="276"/> <source>Error</source> <translation type="unfinished">Fehler</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="293"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="305"/> <source>Delete</source> <translation type="unfinished">Löschen</translation> </message> @@ -1982,16 +2370,16 @@ Are you sure ?</source> <source>Quant Z-sum</source> <translation type="unfinished">Quant Z-Summe</translation> </message> - <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> - <source>{0} Q0 {1}</source> - <translation type="unfinished"></translation> - </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> <source>Q0 {0}</source> <translation type="unfinished">Q0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <source>{0} {1}Q0 {2}</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="10"/> <source>Z0 = Q - ( M(t-1) / N(t) ) @@ -2010,22 +2398,22 @@ Are you sure ?</source> <context> <name>Relative</name> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="7"/> + <location filename="../../../src/sakia/core/money/relative.py" line="9"/> <source>UD</source> <translation type="unfinished">UD</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative.py" line="10"/> <source>{0} {1}UD {2}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="9"/> + <location filename="../../../src/sakia/core/money/relative.py" line="11"/> <source>UD {0}</source> <translation type="unfinished">UD {0}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="10"/> + <location filename="../../../src/sakia/core/money/relative.py" line="12"/> <source>R = Q / UD(t) <br > <table> @@ -2037,6 +2425,36 @@ Are you sure ?</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>RelativeToPast</name> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="6"/> + <source>Past UD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="7"/> + <source>{0} {1}UD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="8"/> + <source>UD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Relative value</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RelativeZSum</name> <message> @@ -2044,16 +2462,16 @@ Are you sure ?</source> <source>Relat Z-sum</source> <translation type="unfinished">Relative Z-Summe</translation> </message> - <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> - <source>{0} R0 {1}</source> - <translation type="unfinished"></translation> - </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> <source>R0 {0}</source> <translation type="unfinished">R0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <source>{0} {1}R0 {2}</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="10"/> <source>R0 = (R / UD(t)) - (( M(t-1) / N(t) ) / UD(t)) @@ -2070,62 +2488,87 @@ Are you sure ?</source> </message> </context> <context> - <name>Scene</name> + <name>SearchUserWidget</name> + <message> + <location filename="../../ui/search_user_view.ui" line="14"/> + <source>Form</source> + <translation type="unfinished"></translation> + </message> <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="158"/> - <source>Certification expires at {0}</source> + <location filename="../../ui/search_user_view.ui" line="33"/> + <source>Center the view on me</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/widgets/search_user.py" line="15"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Nach öffentlichem Schlüssel oder uid suchen…</translation> + </message> </context> <context> <name>StepPageInit</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="95"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="101"/> <source>Could not find your identity on the network.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="127"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> <source>Broadcasting identity...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>UID broadcast</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>Identity broadcasted to the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>Error</source> <translation type="unfinished">Fehler</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>{0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="153"/> <source>Your pubkey or UID was already found on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="145"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="156"/> <source>Your account already exists on the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="97"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="103"/> <source>Your pubkey or UID is different on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="124"/> + <source>connecting...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="164"/> + <source>Could not connect. Check hostname, ip address or port</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="162"/> + <source>Could not connect. Check node peering entry</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Toast</name> @@ -2142,56 +2585,30 @@ Yours : {0}, the network : {1}</source> <source><b>Balance</b> {:} {:}</source> <translation type="obsolete"><b></b> {:} {:}</translation> </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="175"/> - <source>Actions</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="190"/> - <source>Send again</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="195"/> - <source>Cancel</source> - <translation type="unfinished"></translation> - </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="201"/> <source>Informations</source> - <translation type="unfinished">Informationen</translation> + <translation type="obsolete">Informationen</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="206"/> <source>Add as contact</source> - <translation type="unfinished">Als Kontakt hinzufügen</translation> + <translation type="obsolete">Als Kontakt hinzufügen</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="211"/> <source>Send money</source> - <translation type="unfinished">Geld schicken</translation> + <translation type="obsolete">Geld schicken</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="217"/> <source>View in Web of Trust</source> - <translation type="unfinished">Im Web of Trust anschauen</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="222"/> - <source>Copy pubkey to clipboard</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Im Web of Trust anschauen</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Warning</source> - <translation type="unfinished">Warnung</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> - <source>Are you sure ? -This money transfer will be removed and not sent.</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Warnung</translation> </message> <message> <location filename="../../../src/cutecoin/gui/transactions_tab.py" line="135"/> @@ -2204,7 +2621,7 @@ This money transfer will be removed and not sent.</source> <translation type="unfinished">Neue Transaktionen eingegangen</translation> </message> <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="160"/> + <location filename="../../../src/sakia/gui/transactions_tab.py" line="159"/> <source>{:}</source> <translation type="unfinished"></translation> </message> @@ -2237,27 +2654,27 @@ This money transfer will be removed and not sent.</source> <translation type="obsolete">Kontakt</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="80"/> + <location filename="../../ui/transfer.ui" line="136"/> <source>Key</source> <translation type="unfinished">Schlüssel</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="148"/> + <location filename="../../ui/transfer.ui" line="250"/> <source> UD</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="166"/> + <location filename="../../ui/transfer.ui" line="268"/> <source>Transaction message</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>Money transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>No amount. Please give the transfert amount</source> <translation type="unfinished"></translation> </message> @@ -2267,54 +2684,91 @@ This money transfer will be removed and not sent.</source> <translation type="obsolete">Fehler</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="139"/> + <location filename="../../../src/sakia/gui/transfer.py" line="163"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="126"/> + <location filename="../../../src/sakia/gui/transfer.py" line="150"/> <source>Success sending money to {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="61"/> + <location filename="../../ui/transfer.ui" line="95"/> <source>&Recipient public key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="106"/> + <location filename="../../ui/transfer.ui" line="208"/> <source>Wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="125"/> + <location filename="../../ui/transfer.ui" line="227"/> <source>Available money : </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="134"/> + <location filename="../../ui/transfer.ui" line="236"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="40"/> + <location filename="../../ui/transfer.ui" line="46"/> <source>Con&tact</source> - <translation type="unfinished"></translation> + <translation type="unfinished">Kontakt</translation> + </message> + <message> + <location filename="../../ui/transfer.ui" line="156"/> + <source>S&earch user</source> + <translation type="unfinished">Suche Benutzer</translation> </message> </context> <context> <name>TxFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="165"/> + <location filename="../../../src/sakia/models/txhistory.py" line="166"/> <source>{0} / {1} confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="169"/> + <location filename="../../../src/sakia/models/txhistory.py" line="170"/> <source>Confirming... {0} %</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>UDDToPast</name> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="6"/> + <source>Past UUD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="7"/> + <source>{0} {1}UUD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="8"/> + <source>UUD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table>></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>WalletsTab</name> <message> @@ -2474,27 +2928,22 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <message> <location filename="../../../src/sakia/gui/views/wot.py" line="294"/> <source>Informations</source> - <translation type="unfinished">Informationen</translation> + <translation type="obsolete">Informationen</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="299"/> <source>Add as contact</source> - <translation type="unfinished">Als Kontakt hinzufügen</translation> + <translation type="obsolete">Als Kontakt hinzufügen</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="304"/> <source>Send money</source> - <translation type="unfinished">Geld schicken</translation> + <translation type="obsolete">Geld schicken</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="309"/> <source>Certify identity</source> - <translation type="unfinished">Identität zertifizieren</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="314"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Identität zertifizieren</translation> </message> </context> <context> @@ -2505,92 +2954,144 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="unfinished">Form</translation> </message> <message> - <location filename="../../ui/wot_tab.ui" line="33"/> - <source>Center the view on me</source> + <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> + <source>Research a pubkey, an uid...</source> + <translation type="obsolete">Nach öffentlichem Schlüssel oder uid suchen…</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/wot_tab.py" line="122"/> + <source>Membership</source> + <translation type="obsolete">Mitgliedschaft</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> + <source>Not a member</source> + <translation type="obsolete">Kein Mitglied</translation> + </message> +</context> +<context> + <name>certificationsTabWidget</name> + <message> + <location filename="../../ui/certifications_tab.ui" line="14"/> + <source>Form</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> - <source>Research a pubkey, an uid...</source> - <translation type="unfinished">Nach öffentlichem Schlüssel oder uid suchen…</translation> + <location filename="../../ui/certifications_tab.ui" line="20"/> + <source>Certifications</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - </source> + <location filename="../../ui/certifications_tab.ui" line="33"/> + <source>loading...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="126"/> - <source>Membership</source> - <translation type="unfinished">Mitgliedschaft</translation> + <location filename="../../ui/certifications_tab.ui" line="63"/> + <source>dd/MM/yyyy</source> + <translation type="unfinished"></translation> </message> +</context> +<context> + <name>menu</name> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> - <source>Last renewal on {:}, expiration on {:}</source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="57"/> + <source>Certify identity</source> + <translation type="unfinished">Identität zertifizieren</translation> + </message> +</context> +<context> + <name>menu.qmenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="42"/> + <source>Informations</source> + <translation type="unfinished">Informationen</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="47"/> + <source>Add as contact</source> + <translation type="unfinished">Als Kontakt hinzufügen</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="52"/> + <source>Send money</source> + <translation type="unfinished">Geld schicken</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="61"/> + <source>View in Web of Trust</source> + <translation type="unfinished">Im Web of Trust anschauen</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="65"/> + <source>Copy pubkey to clipboard</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source>Your web of trust</source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="70"/> + <source>Copy membership document to clipboard</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source>Certified by {:} members; Certifier of {:} members</source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="74"/> + <source>Copy self-certification document to clipboard</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source>Not a member</source> - <translation type="unfinished">Kein Mitglied</translation> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="84"/> + <source>Transfer</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - </source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="86"/> + <source>Send again</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="90"/> + <source>Cancel</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="95"/> + <source>Copy raw transaction to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="100"/> + <source>Copy transaction block to clipboard</source> <translation type="unfinished"></translation> </message> </context> <context> <name>self.config_dialog</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="191"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="204"/> <source>Ok</source> <translation type="unfinished">OK</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="70"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="72"/> <source>Forbidden : salt is too short</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="74"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="76"/> <source>Forbidden : password is too short</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="78"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="80"/> <source>Forbidden : Invalid characters in salt field</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="82"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="84"/> <source>Forbidden : Invalid characters in password field</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="88"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="90"/> <source>Error : passwords are different</source> <translation type="unfinished"></translation> </message> @@ -2603,7 +3104,7 @@ Sie können die UID nur widerrufen, wenn sie noch nicht vom Netzwerk validiert w <translation type="unfinished">Form</translation> </message> <message> - <location filename="../../ui/transactions_tab.ui" line="63"/> + <location filename="../../ui/transactions_tab.ui" line="66"/> <source>dd/MM/yyyy</source> <translation type="unfinished"></translation> </message> diff --git a/res/i18n/ts/es_ES.ts b/res/i18n/ts/es_ES.ts index a8cd39b7c9e92286e441e3251bf66a014a94290c..ffc18d96a24a5ebc296333f0fb585fb769aba0da 100644 --- a/res/i18n/ts/es_ES.ts +++ b/res/i18n/ts/es_ES.ts @@ -51,8 +51,23 @@ <translation type="obsolete">Relat. Z-Σ</translation> </message> <message> - <location filename="../../../src/sakia/core/account.py" line="510"/> + <location filename="../../../src/sakia/core/account.py" line="540"/> <source>Could not find user self certification.</source> + <translation>No he encontrado la identidad del usuario.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="67"/> + <source>Warning : Your membership is expiring soon.</source> + <translation type="unfinished">Advertencia: Su membresía expira pronto.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="72"/> + <source>Warning : Your could miss certifications soon.</source> + <translation type="unfinished">Advertencia: Tu podía faltar certificaciones pronto.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="77"/> + <source>Warning : If you don't renew soon, your identity will be considerd revoked.</source> <translation type="unfinished"></translation> </message> </context> @@ -91,7 +106,7 @@ <message> <location filename="../../ui/account_cfg.ui" line="143"/> <source>CryptoID</source> - <translation>Identidad de cripto</translation> + <translation type="obsolete">Identidad de cripto</translation> </message> <message> <location filename="../../ui/account_cfg.ui" line="153"/> @@ -138,49 +153,54 @@ <source>Communities</source> <translation>Comunidades</translation> </message> + <message> + <location filename="../../ui/account_cfg.ui" line="143"/> + <source>Entropy</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Application</name> <message> <location filename="../../../src/sakia/core/app.py" line="76"/> <source>Warning : Your membership is expiring soon.</source> - <translation type="unfinished">Advertencia: Su membresía expira pronto.</translation> + <translation type="obsolete">Advertencia: Su membresía expira pronto.</translation> </message> <message> <location filename="../../../src/sakia/core/app.py" line="81"/> <source>Warning : Your could miss certifications soon.</source> - <translation type="unfinished">Advertencia: Tu podía faltar certificaciones pronto.</translation> + <translation type="obsolete">Advertencia: Tu podía faltar certificaciones pronto.</translation> </message> </context> <context> <name>CertificationDialog</name> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Certification</source> <translation>Certificatión</translation> </message> <message> - <location filename="../../ui/certification.ui" line="20"/> + <location filename="../../ui/certification.ui" line="26"/> <source>Community</source> <translation>Comunidad</translation> </message> <message> - <location filename="../../ui/certification.ui" line="32"/> + <location filename="../../ui/certification.ui" line="54"/> <source>Certify user</source> <translation>Certificar usuario</translation> </message> <message> <location filename="../../ui/certification.ui" line="40"/> <source>Contact</source> - <translation>Contacto</translation> + <translation type="obsolete">Contacto</translation> </message> <message> <location filename="../../ui/certification.ui" line="61"/> <source>User public key</source> - <translation>Clave pública del usuario</translation> + <translation type="obsolete">Clave pública del usuario</translation> </message> <message> - <location filename="../../ui/certification.ui" line="80"/> + <location filename="../../ui/certification.ui" line="157"/> <source>Key</source> <translation>Clave</translation> </message> @@ -200,7 +220,7 @@ <translation type="obsolete">Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="112"/> + <location filename="../../../src/sakia/gui/certification.py" line="227"/> <source>Not a member</source> <translation>No es un miembro</translation> </message> @@ -210,20 +230,70 @@ <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="109"/> + <location filename="../../../src/sakia/gui/certification.py" line="221"/> <source>&Ok</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="75"/> + <location filename="../../../src/sakia/gui/certification.py" line="126"/> <source>Success sending certification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Could not broadcast certification : {0}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/certification.ui" line="73"/> + <source>Con&tact</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="116"/> + <source>&User public key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="35"/> + <source>Certifications stock</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="177"/> + <source>Sea&rch user</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="197"/> + <source>Certifications sent : {nb_certifications}/{stock}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="206"/> + <source>{days} days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="208"/> + <source>{hours} hours and {min} min.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="210"/> + <source>Remaining time before next certification validation : {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="217"/> + <source> (Not validated before </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="224"/> + <source>No more certifications</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityConfigurationDialog</name> @@ -253,17 +323,17 @@ <translation>Servidor</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="200"/> + <location filename="../../ui/community_cfg.ui" line="203"/> <source>Add</source> <translation>Añadir</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="221"/> + <location filename="../../ui/community_cfg.ui" line="224"/> <source>Previous</source> <translation>Anterior</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="244"/> + <location filename="../../ui/community_cfg.ui" line="247"/> <source>Next</source> <translation>Siguiente</translation> </message> @@ -384,45 +454,80 @@ <context> <name>CommunityTile</name> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="81"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Member</source> <translation type="unfinished">Miembro</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="82"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Non-Member</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>members</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Monetary mass</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Balance</source> <translation type="unfinished">Saldo</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="112"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="162"/> <source>Not connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="125"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="175"/> <source>Community not initialized</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="100"/> + <source>Expired or never published</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="101"/> + <source>Outdistanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="110"/> + <source>In WoT range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="116"/> + <source>Expires in </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="124"/> + <source>#FF0000</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Certs. received</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Membership</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityWidget</name> @@ -442,7 +547,7 @@ <translation type="unfinished">Certificatión</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="289"/> + <location filename="../../../src/sakia/gui/community_view.py" line="286"/> <source>Renew membership</source> <translation type="unfinished">Renovar la membresía</translation> </message> @@ -457,62 +562,57 @@ <translation type="obsolete">Advertencia: Tu podía faltar certificaciones pronto.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="34"/> + <location filename="../../../src/sakia/gui/community_view.py" line="33"/> <source>Transactions</source> <translation type="unfinished">Transacciones</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <location filename="../../../src/sakia/gui/community_view.py" line="34"/> <source>Web of Trust</source> <translation type="unfinished">Anillo de Confianza</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="37"/> + <location filename="../../../src/sakia/gui/community_view.py" line="90"/> <source>Network</source> <translation type="unfinished">Red</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source>Membership expiration</source> <translation type="unfinished">Membresía expira</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source><b>Warning : Membership expiration in {0} days</b></source> <translation type="unfinished"><b>Advertencia : Expiración la membresía en {0} días</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source>Certifications number</source> <translation type="unfinished">Número de certificaciones</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source><b>Warning : You are certified by only {0} persons, need {1}</b></source> <translation type="unfinished"><b>Advertencia : Usted está certificado por sólo {0} personas, necesitará {1}</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="228"/> + <location filename="../../../src/sakia/gui/community_view.py" line="235"/> <source> Block {0}</source> - <translation type="unfinished"> Bloque {0}</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/community_view.py" line="270"/> - <source> - Median fork window : {0}</source> - <translation type="unfinished"></translation> + <translation type="obsolete"> Bloque {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="295"/> + <location filename="../../../src/sakia/gui/community_view.py" line="292"/> <source>Send membership demand</source> <translation type="unfinished">Enviar una solicitud de membresía</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Warning</source> <translation type="unfinished">Advertencia</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Are you sure ? Sending a leaving demand cannot be canceled. The process to join back the community later will have to be done again.</source> @@ -528,7 +628,7 @@ Publishing your UID can be canceled by Revoke UID.</source> Publicar su UID puede ser cancelada por Revocar UID.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="375"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Success publishing your UID</source> <translation type="unfinished">Éxito con la publicación de su UID</translation> </message> @@ -560,22 +660,22 @@ Revoking your UID can only success if it is not already validated by the network Revocar de su UID sólo puede éxito si no está ya validado por la red.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Membership</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="329"/> + <location filename="../../../src/sakia/gui/community_view.py" line="325"/> <source>Success sending Membership demand</source> <translation type="unfinished">Éxito de enviar una solicitud de afiliación</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="361"/> + <location filename="../../../src/sakia/gui/community_view.py" line="356"/> <source>Revoke</source> <translation type="unfinished">Revocar</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="355"/> + <location filename="../../../src/sakia/gui/community_view.py" line="350"/> <source>Success sending Revoke demand</source> <translation type="unfinished">Éxito enviar Revocar una solicitud</translation> </message> @@ -590,12 +690,12 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="obsolete">Éxito enviar Documento de auto-certificación</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <location filename="../../../src/sakia/gui/community_view.py" line="94"/> <source>Show informations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="38"/> + <location filename="../../../src/sakia/gui/community_view.py" line="95"/> <source>Informations</source> <translation type="unfinished">Informaciones</translation> </message> @@ -605,23 +705,38 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="unfinished">Publicar UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="399"/> + <location filename="../../../src/sakia/gui/community_view.py" line="41"/> <source>Revoke UID</source> <translation type="unfinished">Revocar UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="401"/> + <location filename="../../../src/sakia/gui/community_view.py" line="375"/> <source>UID</source> <translation type="unfinished">UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> - <source>Your UID was revoked successfully.</source> + <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <source>Search Identities</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="36"/> - <source>Search Identities</source> + <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <source>Explore the Web of Trust</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="99"/> + <source>Show explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="100"/> + <source>Explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="234"/> + <source>Block {0}</source> <translation type="unfinished"></translation> </message> </context> @@ -643,11 +758,26 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation>Clave pública</translation> </message> <message> - <location filename="../../../src/sakia/gui/contact.py" line="52"/> + <location filename="../../../src/sakia/gui/contact.py" line="81"/> <source>Contact already exists</source> <translation>Contacto ya existe</translation> </message> </context> +<context> + <name>ContextMenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Warning</source> + <translation type="unfinished">Advertencia</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Are you sure ? +This money transfer will be removed and not sent.</source> + <translation type="unfinished">¿ Estas seguro ? +Esta transferencia de dinero será eliminado y no se ha enviado.</translation> + </message> +</context> <context> <name>CreateWalletDialog</name> <message> @@ -744,48 +874,160 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <message> <location filename="../../ui/member.ui" line="14"/> <source>Informations</source> - <translation>Informaciones</translation> + <translation type="obsolete">Informaciones</translation> </message> <message> <location filename="../../ui/member.ui" line="34"/> <source>Member</source> - <translation>Miembro</translation> + <translation type="obsolete">Miembro</translation> </message> <message> <location filename="../../ui/member.ui" line="65"/> <source>uid</source> - <translation>uid</translation> + <translation type="obsolete">uid</translation> </message> <message> <location filename="../../ui/member.ui" line="72"/> <source>properties</source> - <translation>propiedades</translation> + <translation type="obsolete">propiedades</translation> + </message> +</context> +<context> + <name>DividendPerDay</name> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="9"/> + <source>UDD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="10"/> + <source>{0} {1}UDD {2}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="11"/> + <source>UDD {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="12"/> + <source>UDD(t) = (Q * 100) / (UD(t) / DT) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>ExplorerTabWidget</name> + <message> + <location filename="../../ui/explorer_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Forma</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="48"/> + <source>Steps</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="65"/> + <source>Go</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>GraphTabWidget</name> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="71"/> + <source>Membership</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source>Last renewal on {:}, expiration on {:}</source> + <translation type="unfinished">Última renovación en {:}, caducidad en {:}</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Your web of trust</source> + <translation type="unfinished">Su Anillo de Confianza ( AdC )</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Certified by {:} members; Certifier of {:} members</source> + <translation type="unfinished">Certificado por: {} miembros; Certificador de {:} miembros</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Not a member</source> + <translation type="unfinished">No es un miembro</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"> + ↵ + <table cellpadding="5">↵ + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>↵ + <tr><td align="right"><b>{:}</b></td></tr>↵ + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>↵ + </table>↵ + </translation> </message> </context> <context> <name>HistoryTableModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Date</source> <translation>Fecha</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>UID/Public key</source> <translation>UID/Clave pública</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Payment</source> <translation>Pago</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Deposit</source> <translation>Deposito</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Comment</source> <translation type="unfinished">Comentario</translation> </message> @@ -902,73 +1144,68 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="36"/> <source>Members</source> - <translation type="unfinished">Miembros</translation> + <translation type="obsolete">Miembros</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="37"/> <source>Direct connections</source> - <translation type="unfinished">Conexiones directas</translation> + <translation type="obsolete">Conexiones directas</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="112"/> <source>Informations</source> - <translation type="unfinished">Informaciones</translation> + <translation type="obsolete">Informaciones</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="115"/> <source>Add as contact</source> - <translation type="unfinished">Añadir como contacto</translation> + <translation type="obsolete">Añadir como contacto</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="119"/> <source>Send money</source> - <translation type="unfinished">Enviar dinero</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="123"/> - <source>Certify identity</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Enviar dinero</translation> </message> <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="127"/> - <source>View in Web of Trust</source> + <location filename="../../../src/sakia/gui/identities_tab.py" line="32"/> + <source>Search direct certifications</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="131"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <location filename="../../../src/sakia/gui/identities_tab.py" line="33"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Investicar a clave pública, identificatión del usuario…</translation> </message> </context> <context> <name>IdentitiesTableModel</name> <message> - <location filename="../../../src/sakia/models/identities.py" line="89"/> + <location filename="../../../src/sakia/models/identities.py" line="118"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="90"/> + <location filename="../../../src/sakia/models/identities.py" line="119"/> <source>Pubkey</source> <translation>Clave pública</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="91"/> + <location filename="../../../src/sakia/models/identities.py" line="120"/> <source>Renewed</source> <translation>Renovado</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="92"/> + <location filename="../../../src/sakia/models/identities.py" line="121"/> <source>Expiration</source> <translation>Caducidad</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="94"/> + <location filename="../../../src/sakia/models/identities.py" line="123"/> <source>Validation</source> <translation>Validación</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="93"/> + <location filename="../../../src/sakia/models/identities.py" line="122"/> <source>Publication</source> <translation type="unfinished"></translation> </message> @@ -1079,27 +1316,27 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="obsolete">label_wot</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Universal Dividend UD(t) in</source> <translation>Dividendo Universales DU(t) en</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Members N(t)</source> <translation>Miembros N(t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Next UD date and time (t+1)</source> <translation>Siguiente DU fecha y tiempo ( t+1 )</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="194"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="196"/> <source>No Universal Dividend created yet.</source> <translation>Dividendo Universales no se ha creado.</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1116,32 +1353,32 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:2.0%} / {:} days</source> <translation>{:2.0%} / {:} día</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Fundamental growth (c) / Delta time (dt)</source> <translation>Crecimiento fundamental (c) / Delta tiempo (dt)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (formula)</source> <translation>Dividendo Universales ( fórmula )</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</source> <translation>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (computed)</source> <translation>Dividendo Universales (computarizada)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> @@ -1168,47 +1405,47 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Fundamental growth (c)</source> <translation>Crecimiento fundamental (c)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Initial Universal Dividend UD(0) in</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Time period (dt) in days (86400 seconds) between two UD</source> <translation>Un período de tiempo ( dt ) en días ( 86400 segundos ) entre dos DU</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Number of blocks used for calculating median time</source> <translation>El número de bloques utilizados para calcular la mediana del tiempo</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The average time in seconds for writing 1 block (wished time)</source> <translation>El promedio de tiempo en segundos para escribir 1 bloque (el tiempo de espera)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of blocks required to evaluate again PoWMin value</source> <translation>El número de bloques requerido para evaluar de nuevo el valor PoWMin</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of previous blocks to check for personalized difficulty</source> <translation>El número de bloques anteriores para comprobar en una dificultad a medida</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The percent of previous issuers to reach for personalized difficulty</source> <translation>El porcentaje de los emisores anteriores para llegar a la dificultad personalizada</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1219,7 +1456,7 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1231,32 +1468,32 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum delay between 2 identical certifications (in days)</source> - <translation>Tiempo mínimo entre 2 certificaciones idénticas (en días)</translation> + <translation type="obsolete">Tiempo mínimo entre 2 certificaciones idénticas (en días)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid signature (in days)</source> <translation>La edad máxima de una firma válida (en días)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Minimum quantity of signatures to be part of the WoT</source> <translation>La cantidad mínima de firmas para ser incluido en la AdC</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum quantity of valid made certifications to be part of the WoT for distance rule</source> - <translation>La cantidad mínima de certificados válidos para ser parte de la Anillo de Confianza bajo el imperio de la distancia</translation> + <translation type="obsolete">La cantidad mínima de certificados válidos para ser parte de la Anillo de Confianza bajo el imperio de la distancia</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid membership (in days)</source> <translation>La edad máxima de una membresía válida (en días)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum distance between each WoT member and a newcomer</source> <translation>La distancia máxima entre cada miembro de la AdC y un recién llegado</translation> </message> @@ -1286,32 +1523,32 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass M(t-1) in</source> <translation>Oferta monetaria M(t-1) en</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass per member M(t-1)/N(t) in</source> <translation>Oferta monetaria por cada miembro M(t-1) / N(t) en</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Actual growth c = UD(t)/[M(t-1)/N(t)]</source> <translation>Crecimiento actual c = UD( t ) / [ M( t-1 ) / N( t ) ]</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Last UD date and time (t)</source> <translation>última DU fecha y tiempo ( t )</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</source> <translation>DU(t+1) = MAX { DU(t) ; c &#215; M(t) / N(t+1) }</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> @@ -1327,7 +1564,7 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Penultimate UD date and time (t-1)</source> <translation type="unfinished"></translation> </message> @@ -1337,25 +1574,61 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Name</source> <translation type="unfinished">Nombre</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Units</source> <translation type="unfinished">Unidades</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Formula</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Description</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum delay between 2 certifications (in days)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum quantity of active certifications made by member.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum delay a certification can wait before being expired for non-writing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum percent of sentries to reach to match the distance rule</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>MainWindow</name> @@ -1365,7 +1638,7 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="131"/> + <location filename="../../ui/mainwindow.ui" line="138"/> <source>Account</source> <translation>Cuenta</translation> </message> @@ -1385,12 +1658,12 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="unfinished">&Ayuda</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="76"/> + <location filename="../../ui/mainwindow.ui" line="83"/> <source>Manage accounts</source> <translation>Administrar cuentas</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="81"/> + <location filename="../../ui/mainwindow.ui" line="88"/> <source>Configure trustable nodes</source> <translation>Configure los nodos de confianza</translation> </message> @@ -1400,47 +1673,47 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="obsolete">&Añadir un contacto</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="106"/> + <location filename="../../ui/mainwindow.ui" line="113"/> <source>Send a message</source> <translation>Enviar un mensaje</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="111"/> + <location filename="../../ui/mainwindow.ui" line="118"/> <source>Send money</source> <translation>Enviar dinero</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="116"/> + <location filename="../../ui/mainwindow.ui" line="123"/> <source>Remove contact</source> <translation>Remover contacto</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="121"/> + <location filename="../../ui/mainwindow.ui" line="128"/> <source>Save</source> <translation>Guardar</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="126"/> + <location filename="../../ui/mainwindow.ui" line="133"/> <source>&Quit</source> <translation type="unfinished">&Dejar</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="136"/> + <location filename="../../ui/mainwindow.ui" line="143"/> <source>&Transfer money</source> <translation type="unfinished">&Transferir dinero</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="141"/> + <location filename="../../ui/mainwindow.ui" line="148"/> <source>&Configure</source> <translation>&Configurar</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="146"/> + <location filename="../../ui/mainwindow.ui" line="153"/> <source>&Import</source> <translation>&Importar</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="151"/> + <location filename="../../ui/mainwindow.ui" line="158"/> <source>&Export</source> <translation type="unfinished">&Exportar</translation> </message> @@ -1450,32 +1723,32 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="obsolete">&Certificación</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="161"/> + <location filename="../../ui/mainwindow.ui" line="168"/> <source>&Set as default</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="166"/> + <location filename="../../ui/mainwindow.ui" line="173"/> <source>A&bout</source> <translation type="unfinished">&Acerca</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="171"/> + <location filename="../../ui/mainwindow.ui" line="178"/> <source>&Preferences</source> <translation>&Preferencias</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="176"/> + <location filename="../../ui/mainwindow.ui" line="183"/> <source>&Add account</source> <translation>&Agregar una cuenta</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="211"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="285"/> <source>Latest release : {version}</source> <translation>Último lanzamiento : {version}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="218"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="292"/> <source>Download link</source> <translation>Enlace de descarga</translation> </message> @@ -1515,17 +1788,17 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="251"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="326"/> <source>Please get the latest release {version}</source> <translation>Por favor, obtener la última versión {version}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="283"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="358"/> <source>Edit</source> <translation>Editar</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="286"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="361"/> <source>Delete</source> <translation>Borrar</translation> </message> @@ -1540,17 +1813,17 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="obsolete">CuteCoin {0} - Cuenta : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="348"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="424"/> <source>Export an account</source> <translation>Exportar una cuenta</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="349"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="425"/> <source>All account files (*.acc)</source> <translation>Archivos de cuentas (*.acc)</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="350"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="426"/> <source>Export</source> <translation>Exportar</translation> </message> @@ -1565,21 +1838,42 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="86"/> + <location filename="../../ui/mainwindow.ui" line="93"/> <source>A&dd a contact</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="156"/> + <location filename="../../ui/mainwindow.ui" line="163"/> <source>C&ertification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="225"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="383"/> + <source>sakia {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="407"/> + <source>sakia {0} - Account : {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="71"/> + <source>&Duniter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="188"/> + <source>&Manage local node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="299"/> <source> <h1>sakia</h1> - <p>Python/Qt uCoin client</p> + <p>Python/Qt duniter client</p> + <p><a href="https://github.com/duniter/sakia">https://github.com/duniter/sakia</a></p> <p>Version : {:}</p> {new_version_text} @@ -1595,21 +1889,11 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl </source> <translation type="unfinished"></translation> </message> - <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="303"/> - <source>sakia {0}</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="330"/> - <source>sakia {0} - Account : {1}</source> - <translation type="unfinished"></translation> - </message> </context> <context> <name>MemberDialog</name> <message> - <location filename="../../../src/sakia/gui/member.py" line="46"/> + <location filename="../../../src/sakia/gui/member.py" line="73"/> <source>not a member</source> <translation>no es un miembro</translation> </message> @@ -1620,100 +1904,133 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> </source> - <translation type="unfinished"> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> </translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Public key</source> <translation>Clave pública</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Join date</source> <translation>Adjuntar una fecha</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="87"/> + <location filename="../../../src/sakia/gui/member.py" line="144"/> <source><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></source> <translation><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="73"/> + <location filename="../../../src/sakia/gui/member.py" line="130"/> <source>Distance</source> <translation>Distancia</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="80"/> + <location filename="../../../src/sakia/gui/member.py" line="139"/> <source>Path</source> <translation>Camino</translation> </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="92"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="97"/> + <source>UID Published on</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MemberView</name> + <message> + <location filename="../../ui/member.ui" line="14"/> + <source>Member informations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/member.ui" line="34"/> + <source>Member</source> + <translation type="unfinished">Miembro</translation> + </message> </context> <context> <name>NetworkFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="48"/> + <location filename="../../../src/sakia/models/network.py" line="54"/> <source>Address</source> <translation>Dirección</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="49"/> + <location filename="../../../src/sakia/models/network.py" line="55"/> <source>Port</source> <translation>Puerto</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="50"/> + <location filename="../../../src/sakia/models/network.py" line="56"/> <source>Block</source> <translation>Bloque</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="52"/> + <location filename="../../../src/sakia/models/network.py" line="59"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="53"/> + <location filename="../../../src/sakia/models/network.py" line="60"/> <source>Member</source> <translation>Miembro</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="54"/> + <location filename="../../../src/sakia/models/network.py" line="61"/> <source>Pubkey</source> <translation>Clave pública</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="55"/> + <location filename="../../../src/sakia/models/network.py" line="62"/> <source>Software</source> <translation>Software</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="56"/> + <location filename="../../../src/sakia/models/network.py" line="63"/> <source>Version</source> <translation>Versión</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>yes</source> <translation>sí</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>no</source> <translation>no</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>offline</source> <translation>Desconectado</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="51"/> + <location filename="../../../src/sakia/models/network.py" line="57"/> <source>Hash</source> <translation>Hash</translation> </message> + <message> + <location filename="../../../src/sakia/models/network.py" line="58"/> + <source>Time</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>NetworkTabWidget</name> @@ -1723,17 +2040,17 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation>Forma</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="70"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="72"/> <source>Unset root node</source> <translation type="unfinished">Desactivar el nodo raíz</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="76"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="78"/> <source>Set as root node</source> <translation type="unfinished">Activar como nodo raíz</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="82"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="84"/> <source>Open in browser</source> <translation>Abrir en un explorador</translation> </message> @@ -1741,26 +2058,34 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <context> <name>NetworkTableModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="136"/> + <location filename="../../../src/sakia/models/network.py" line="155"/> <source>Online</source> <translation>En línea</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="137"/> + <location filename="../../../src/sakia/models/network.py" line="156"/> <source>Offline</source> <translation type="unfinished">Desconectado</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="138"/> + <location filename="../../../src/sakia/models/network.py" line="157"/> <source>Unsynchronized</source> <translation>No sincronizado</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="139"/> + <location filename="../../../src/sakia/models/network.py" line="158"/> <source>Corrupted</source> <translation>Corrupto</translation> </message> </context> +<context> + <name>NodeManager</name> + <message> + <location filename="../../ui/node_manager.ui" line="14"/> + <source>Node manager</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>PasswordAskerDialog</name> <message> @@ -1779,22 +2104,22 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation>Recordar mi contraseña durante esta sesión</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Bad password</source> <translation>Contraseña incorrecta</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Non printable characters in password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Failed to get private key</source> <translation>No se puede obtener la clave privada</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Wrong password typed. Cannot open the private key</source> <translation>Contraseña incorrecta. No se puede abrir la clave privada</translation> </message> @@ -1862,7 +2187,7 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation>Usar una Sistema Internacional de Unidades</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="329"/> + <location filename="../../ui/preferences.ui" line="356"/> <source><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Network settings</span></p></body></html></source> <translation><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Configuración de la red</span></p></body></html></translation> </message> @@ -1887,40 +2212,45 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="obsolete">SOCKS5</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="345"/> + <location filename="../../ui/preferences.ui" line="372"/> <source>Proxy server address : </source> <translation type="unfinished">Dirección del servidor proxy : </translation> </message> <message> - <location filename="../../ui/preferences.ui" line="355"/> + <location filename="../../ui/preferences.ui" line="382"/> <source>:</source> <translation>:</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="336"/> + <location filename="../../ui/preferences.ui" line="363"/> <source>Use a http proxy server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="379"/> + <location filename="../../ui/preferences.ui" line="406"/> <source>Automatically refresh identities informations</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/preferences.ui" line="330"/> + <source>Enable forgetfulness</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureAccount</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="163"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="165"/> <source>New account</source> <translation>Nueva cuenta</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="170"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="175"/> <source>Configure {0}</source> <translation>Configurar {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="185"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="190"/> <source>Ok</source> <translation type="unfinished">Ok</translation> </message> @@ -1935,12 +2265,12 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation type="obsolete">Estos parámetros de claves públicas son : {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="243"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="249"/> <source>Error</source> <translation>Error</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> <source>Warning</source> <translation>Advertencia</translation> </message> @@ -1950,31 +2280,39 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl Please note your key parameters (salt and password) if you wish to recover it later. Your account won't be removed from the networks it joined. Are you sure ?</source> - <translation>Esta acción borrará tu cuenta a nivel local. + <translation type="obsolete">Esta acción borrará tu cuenta a nivel local. Por favor, tenga en cuenta los parámetros clave (sal y contraseña) si desea recuperarlo más tarde. Su cuenta no será retirado de las redes a las que se unieron. ¿ Estas seguro ?</translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> + <source>This action will delete your account ({0}) locally. +Please note your key parameters (salt and password) if you wish to recover it later. +Your account won't be removed from the networks it joined. +Are you sure ?</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureCommunity</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="227"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="240"/> <source>Configure community {0}</source> <translation>Configurar comunidad {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="230"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="243"/> <source>Add a community</source> <translation>Añadir una comunidad</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="264"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="276"/> <source>Error</source> <translation>Error</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="293"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="305"/> <source>Delete</source> <translation>Borrar</translation> </message> @@ -2058,15 +2396,20 @@ Would you like to publish the key ?</source> <translation type="unfinished">Quant. Z-Σ</translation> </message> <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="7"/> <source>{0} Q0 {1}</source> - <translation>{0} Q0 {1}</translation> + <translation type="obsolete">{0} Q0 {1}</translation> </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> <source>Q0 {0}</source> <translation>Q0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <source>{0} {1}Q0 {2}</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="10"/> <source>Z0 = Q - ( M(t-1) / N(t) ) @@ -2085,22 +2428,22 @@ Would you like to publish the key ?</source> <context> <name>Relative</name> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="7"/> + <location filename="../../../src/sakia/core/money/relative.py" line="9"/> <source>UD</source> <translation>DU</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative.py" line="10"/> <source>{0} {1}UD {2}</source> <translation>{0} {1}DU {2}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="9"/> + <location filename="../../../src/sakia/core/money/relative.py" line="11"/> <source>UD {0}</source> <translation>DU {0}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="10"/> + <location filename="../../../src/sakia/core/money/relative.py" line="12"/> <source>R = Q / UD(t) <br > <table> @@ -2112,6 +2455,36 @@ Would you like to publish the key ?</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>RelativeToPast</name> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="6"/> + <source>Past UD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="7"/> + <source>{0} {1}UD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="8"/> + <source>UD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Relative value</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RelativeZSum</name> <message> @@ -2120,15 +2493,20 @@ Would you like to publish the key ?</source> <translation type="unfinished">Relat. Z-Σ</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="7"/> <source>{0} R0 {1}</source> - <translation>{0} R0 {1}</translation> + <translation type="obsolete">{0} R0 {1}</translation> </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> <source>R0 {0}</source> <translation>R0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <source>{0} {1}R0 {2}</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="10"/> <source>R0 = (R / UD(t)) - (( M(t-1) / N(t) ) / UD(t)) @@ -2149,33 +2527,51 @@ Would you like to publish the key ?</source> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="158"/> <source>Certification expires at {0}</source> - <translation>Certificación expira a {0}</translation> + <translation type="obsolete">Certificación expira a {0}</translation> + </message> +</context> +<context> + <name>SearchUserWidget</name> + <message> + <location filename="../../ui/search_user_view.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Forma</translation> + </message> + <message> + <location filename="../../ui/search_user_view.ui" line="33"/> + <source>Center the view on me</source> + <translation type="unfinished">Centrar la vista en mí</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/search_user.py" line="15"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Investicar a clave pública, identificatión del usuario…</translation> </message> </context> <context> <name>StepPageInit</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="95"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="101"/> <source>Could not find your identity on the network.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="127"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> <source>Broadcasting identity...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>UID broadcast</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>Identity broadcasted to the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>Error</source> <translation type="unfinished">Error</translation> </message> @@ -2185,27 +2581,42 @@ Would you like to publish the key ?</source> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>{0}</source> <translation type="unfinished">{0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="153"/> <source>Your pubkey or UID was already found on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="145"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="156"/> <source>Your account already exists on the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="97"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="103"/> <source>Your pubkey or UID is different on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="124"/> + <source>connecting...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="164"/> + <source>Could not connect. Check hostname, ip address or port</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="162"/> + <source>Could not connect. Check node peering entry</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Toast</name> @@ -2235,53 +2646,53 @@ Yours : {0}, the network : {1}</source> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="175"/> <source>Actions</source> - <translation>Acción</translation> + <translation type="obsolete">Acción</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="190"/> <source>Send again</source> - <translation>Enviar de nuevo</translation> + <translation type="obsolete">Enviar de nuevo</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="195"/> <source>Cancel</source> - <translation>Cancelar</translation> + <translation type="obsolete">Cancelar</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="201"/> <source>Informations</source> - <translation>Informaciones</translation> + <translation type="obsolete">Informaciones</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="206"/> <source>Add as contact</source> - <translation>Añadir como contacto</translation> + <translation type="obsolete">Añadir como contacto</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="211"/> <source>Send money</source> - <translation>Enviar dinero</translation> + <translation type="obsolete">Enviar dinero</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="217"/> <source>View in Web of Trust</source> - <translation>Ver en el Anillo de Confianza</translation> + <translation type="obsolete">Ver en el Anillo de Confianza</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="222"/> <source>Copy pubkey to clipboard</source> - <translation>Copiare la clave pública al portapapeles</translation> + <translation type="obsolete">Copiare la clave pública al portapapeles</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Warning</source> - <translation>Advertencia</translation> + <translation type="obsolete">Advertencia</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Are you sure ? This money transfer will be removed and not sent.</source> - <translation>¿ Estas seguro ? + <translation type="obsolete">¿ Estas seguro ? Esta transferencia de dinero será eliminado y no se ha enviado.</translation> </message> <message> @@ -2295,7 +2706,7 @@ Esta transferencia de dinero será eliminado y no se ha enviado.</translation> <translation>Nuevos transacciones recibidas</translation> </message> <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="160"/> + <location filename="../../../src/sakia/gui/transactions_tab.py" line="159"/> <source>{:}</source> <translation type="unfinished">{:}</translation> </message> @@ -2328,27 +2739,27 @@ Esta transferencia de dinero será eliminado y no se ha enviado.</translation> <translation type="obsolete">Contacto</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="80"/> + <location filename="../../ui/transfer.ui" line="136"/> <source>Key</source> <translation>Clave</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="148"/> + <location filename="../../ui/transfer.ui" line="250"/> <source> UD</source> <translation> DU</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="166"/> + <location filename="../../ui/transfer.ui" line="268"/> <source>Transaction message</source> <translation>Mensaje de transacción</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>Money transfer</source> <translation>Transferencia de dinero</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>No amount. Please give the transfert amount</source> <translation>Ninguna cantidad. Indique el monto de la transferencia</translation> </message> @@ -2358,12 +2769,12 @@ Esta transferencia de dinero será eliminado y no se ha enviado.</translation> <translation type="obsolete">Error</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="139"/> + <location filename="../../../src/sakia/gui/transfer.py" line="163"/> <source>Transfer</source> <translation>Transferir</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="126"/> + <location filename="../../../src/sakia/gui/transfer.py" line="150"/> <source>Success sending money to {0}</source> <translation>Éxito enviar dinero a {0}</translation> </message> @@ -2373,30 +2784,35 @@ Esta transferencia de dinero será eliminado y no se ha enviado.</translation> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="61"/> + <location filename="../../ui/transfer.ui" line="95"/> <source>&Recipient public key</source> <translation>&Clave pública de destinatarios</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="106"/> + <location filename="../../ui/transfer.ui" line="208"/> <source>Wallet</source> <translation>Cartera</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="125"/> + <location filename="../../ui/transfer.ui" line="227"/> <source>Available money : </source> <translation>Dinero disponible : </translation> </message> <message> - <location filename="../../ui/transfer.ui" line="134"/> + <location filename="../../ui/transfer.ui" line="236"/> <source>Amount</source> <translation>Cantidad</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="40"/> + <location filename="../../ui/transfer.ui" line="46"/> <source>Con&tact</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/transfer.ui" line="156"/> + <source>S&earch user</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>TxFilterProxyModel</name> @@ -2411,16 +2827,48 @@ Esta transferencia de dinero será eliminado y no se ha enviado.</translation> <translation type="obsolete">Validación... {0} %</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="165"/> + <location filename="../../../src/sakia/models/txhistory.py" line="166"/> <source>{0} / {1} confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="169"/> + <location filename="../../../src/sakia/models/txhistory.py" line="170"/> <source>Confirming... {0} %</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>UDDToPast</name> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="6"/> + <source>Past UUD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="7"/> + <source>{0} {1}UUD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="8"/> + <source>UUD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table>></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>WalletsTab</name> <message> @@ -2653,27 +3101,22 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <message> <location filename="../../../src/sakia/gui/views/wot.py" line="294"/> <source>Informations</source> - <translation>Informaciones</translation> + <translation type="obsolete">Informaciones</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="299"/> <source>Add as contact</source> - <translation>Añadir como contacto</translation> + <translation type="obsolete">Añadir como contacto</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="304"/> <source>Send money</source> - <translation>Enviar dinero</translation> + <translation type="obsolete">Enviar dinero</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="309"/> <source>Certify identity</source> - <translation>Certificar la identidad</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="314"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Certificar la identidad</translation> </message> </context> <context> @@ -2686,15 +3129,15 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <message> <location filename="../../ui/wot_tab.ui" line="33"/> <source>Center the view on me</source> - <translation>Centrar la vista en mí</translation> + <translation type="obsolete">Centrar la vista en mí</translation> </message> <message> <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> <source>Research a pubkey, an uid...</source> - <translation type="unfinished">Investicar a clave pública, identificatión del usuario…</translation> + <translation type="obsolete">Investicar a clave pública, identificatión del usuario…</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2702,7 +3145,7 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2711,32 +3154,27 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="126"/> - <source>Membership</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source>Last renewal on {:}, expiration on {:}</source> - <translation type="unfinished">Última renovación en {:}, caducidad en {:}</translation> + <translation type="obsolete">Última renovación en {:}, caducidad en {:}</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Your web of trust</source> - <translation type="unfinished">Su Anillo de Confianza ( AdC )</translation> + <translation type="obsolete">Su Anillo de Confianza ( AdC )</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Certified by {:} members; Certifier of {:} members</source> - <translation type="unfinished">Certificado por: {} miembros; Certificador de {:} miembros</translation> + <translation type="obsolete">Certificado por: {} miembros; Certificador de {:} miembros</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Not a member</source> - <translation type="unfinished">No es un miembro</translation> + <translation type="obsolete">No es un miembro</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2744,7 +3182,7 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"> + <translation type="obsolete"> ↵ <table cellpadding="5">↵ <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>↵ @@ -2754,35 +3192,129 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl </translation> </message> </context> +<context> + <name>certificationsTabWidget</name> + <message> + <location filename="../../ui/certifications_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Forma</translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="20"/> + <source>Certifications</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="33"/> + <source>loading...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="63"/> + <source>dd/MM/yyyy</source> + <translation type="unfinished">dd/MM/yyyy</translation> + </message> +</context> +<context> + <name>menu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="57"/> + <source>Certify identity</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>menu.qmenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="42"/> + <source>Informations</source> + <translation type="unfinished">Informaciones</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="47"/> + <source>Add as contact</source> + <translation type="unfinished">Añadir como contacto</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="52"/> + <source>Send money</source> + <translation type="unfinished">Enviar dinero</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="61"/> + <source>View in Web of Trust</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="65"/> + <source>Copy pubkey to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="70"/> + <source>Copy membership document to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="74"/> + <source>Copy self-certification document to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="84"/> + <source>Transfer</source> + <translation type="unfinished">Transferir</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="86"/> + <source>Send again</source> + <translation type="unfinished">Enviar de nuevo</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="90"/> + <source>Cancel</source> + <translation type="unfinished">Cancelar</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="95"/> + <source>Copy raw transaction to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="100"/> + <source>Copy transaction block to clipboard</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>self.config_dialog</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="191"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="204"/> <source>Ok</source> <translation type="unfinished">Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="70"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="72"/> <source>Forbidden : salt is too short</source> <translation>Prohibido: sal es demasiado corto</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="74"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="76"/> <source>Forbidden : password is too short</source> <translation>Prohibido: contraseña es demasiado corta</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="78"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="80"/> <source>Forbidden : Invalid characters in salt field</source> <translation>Prohibida: caracteres no válidos en el campo de la sal</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="82"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="84"/> <source>Forbidden : Invalid characters in password field</source> <translation>Prohibida: caracteres no válidos en el campo de la contraseña</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="88"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="90"/> <source>Error : passwords are different</source> <translation type="unfinished"></translation> </message> @@ -2795,7 +3327,7 @@ Revocar de su UID sólo puede éxito si no está ya validado por la red.</transl <translation>Forma</translation> </message> <message> - <location filename="../../ui/transactions_tab.ui" line="63"/> + <location filename="../../ui/transactions_tab.ui" line="66"/> <source>dd/MM/yyyy</source> <translation>dd/MM/yyyy</translation> </message> diff --git a/res/i18n/ts/fr_FR.ts b/res/i18n/ts/fr_FR.ts index 83570dbdd934a40502acecfd05e2f4688ddb36cf..06250ca135466d079691a4841f382425b9ebb1cb 100644 --- a/res/i18n/ts/fr_FR.ts +++ b/res/i18n/ts/fr_FR.ts @@ -89,10 +89,25 @@ <translation type="obsolete">R0 {0}</translation> </message> <message> - <location filename="../../../src/sakia/core/account.py" line="510"/> + <location filename="../../../src/sakia/core/account.py" line="540"/> <source>Could not find user self certification.</source> <translation>Impossible de trouver la certification personnelle de l'utilisateur.</translation> </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="67"/> + <source>Warning : Your membership is expiring soon.</source> + <translation>Attention : Votre adhésion expire bientôt.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="72"/> + <source>Warning : Your could miss certifications soon.</source> + <translation>Attention : Vous pourriez manquer de certifications prochainement.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="77"/> + <source>Warning : If you don't renew soon, your identity will be considerd revoked.</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AccountConfigurationDialog</name> @@ -169,56 +184,61 @@ <message> <location filename="../../ui/account_cfg.ui" line="143"/> <source>CryptoID</source> - <translation>CryptoID</translation> + <translation type="obsolete">CryptoID</translation> </message> <message> <location filename="../../ui/account_cfg.ui" line="215"/> <source>Communities</source> <translation>Communautés</translation> </message> + <message> + <location filename="../../ui/account_cfg.ui" line="143"/> + <source>Entropy</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Application</name> <message> <location filename="../../../src/sakia/core/app.py" line="76"/> <source>Warning : Your membership is expiring soon.</source> - <translation>Attention : Votre adhésion expire bientôt.</translation> + <translation type="obsolete">Attention : Votre adhésion expire bientôt.</translation> </message> <message> <location filename="../../../src/sakia/core/app.py" line="81"/> <source>Warning : Your could miss certifications soon.</source> - <translation>Attention : Vous pourriez manquer de certifications prochainement.</translation> + <translation type="obsolete">Attention : Vous pourriez manquer de certifications prochainement.</translation> </message> </context> <context> <name>CertificationDialog</name> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Certification</source> <translation>Certification</translation> </message> <message> - <location filename="../../ui/certification.ui" line="20"/> + <location filename="../../ui/certification.ui" line="26"/> <source>Community</source> <translation>Communauté</translation> </message> <message> - <location filename="../../ui/certification.ui" line="32"/> + <location filename="../../ui/certification.ui" line="54"/> <source>Certify user</source> <translation>Utilisateur certifié</translation> </message> <message> <location filename="../../ui/certification.ui" line="40"/> <source>Contact</source> - <translation>Contact</translation> + <translation type="obsolete">Contact</translation> </message> <message> <location filename="../../ui/certification.ui" line="61"/> <source>User public key</source> - <translation>Clé publique</translation> + <translation type="obsolete">Clé publique</translation> </message> <message> - <location filename="../../ui/certification.ui" line="80"/> + <location filename="../../ui/certification.ui" line="157"/> <source>Key</source> <translation>Clé</translation> </message> @@ -248,25 +268,80 @@ <translation type="obsolete">Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="112"/> + <location filename="../../../src/sakia/gui/certification.py" line="227"/> <source>Not a member</source> <translation>Non-membre</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="75"/> + <location filename="../../../src/sakia/gui/certification.py" line="126"/> <source>Success sending certification</source> <translation>Succès lors de l'envoi de la certification</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Could not broadcast certification : {0}</source> <translation>Impossible de propager la certification : {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="109"/> + <location filename="../../../src/sakia/gui/certification.py" line="221"/> <source>&Ok</source> <translation>&Ok</translation> </message> + <message> + <location filename="../../ui/certification.ui" line="73"/> + <source>Con&tact</source> + <translation>Contact</translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="116"/> + <source>&User public key</source> + <translation>Clé publique de l'utilisateur</translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="161"/> + <source>S&earch user</source> + <translation type="obsolete">Rechercher une identité</translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="35"/> + <source>Certifications stock</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="177"/> + <source>Sea&rch user</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="197"/> + <source>Certifications sent : {nb_certifications}/{stock}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="206"/> + <source>{days} days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="208"/> + <source>{hours} hours and {min} min.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="210"/> + <source>Remaining time before next certification validation : {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="217"/> + <source> (Not validated before </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="224"/> + <source>No more certifications</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommuityWidget</name> @@ -304,17 +379,17 @@ <translation>Serveur</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="200"/> + <location filename="../../ui/community_cfg.ui" line="203"/> <source>Add</source> <translation>Ajouter</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="221"/> + <location filename="../../ui/community_cfg.ui" line="224"/> <source>Previous</source> <translation>Précédent</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="244"/> + <location filename="../../ui/community_cfg.ui" line="247"/> <source>Next</source> <translation>Suivant</translation> </message> @@ -570,45 +645,80 @@ Revoking your UID can only success if it is not already validated by the network <context> <name>CommunityTile</name> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="81"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Member</source> <translation>Membre</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="82"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Non-Member</source> <translation>Non-Membre</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>members</source> <translation>membres</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Monetary mass</source> <translation>Masse monétaire</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Status</source> <translation>Statut</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Balance</source> <translation>Solde</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="112"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="162"/> <source>Not connected</source> <translation>Non connecté</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="125"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="175"/> <source>Community not initialized</source> <translation>Communauté non initialisée</translation> </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="100"/> + <source>Expired or never published</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="101"/> + <source>Outdistanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="110"/> + <source>In WoT range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="116"/> + <source>Expires in </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="124"/> + <source>#FF0000</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Certs. received</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Membership</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityWidget</name> @@ -628,9 +738,9 @@ Revoking your UID can only success if it is not already validated by the network <translation>Certification</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="289"/> + <location filename="../../../src/sakia/gui/community_view.py" line="286"/> <source>Renew membership</source> - <translation>Renouveler le statut de membre</translation> + <translation>Renouveler l'adhésion</translation> </message> <message> <location filename="../../../src/cutecoin/gui/community_view.py" line="46"/> @@ -643,87 +753,87 @@ Revoking your UID can only success if it is not already validated by the network <translation type="obsolete">Attention : Vous pourriez manquer de certifications prochainement.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="34"/> + <location filename="../../../src/sakia/gui/community_view.py" line="33"/> <source>Transactions</source> <translation>Transferts</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <location filename="../../../src/sakia/gui/community_view.py" line="34"/> <source>Web of Trust</source> <translation>Toile de Confiance</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="36"/> + <location filename="../../../src/sakia/gui/community_view.py" line="35"/> <source>Search Identities</source> <translation>Rechercher des identités</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="37"/> + <location filename="../../../src/sakia/gui/community_view.py" line="90"/> <source>Network</source> <translation>Réseau</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <location filename="../../../src/sakia/gui/community_view.py" line="94"/> <source>Show informations</source> <translation>Afficher les informations</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="38"/> + <location filename="../../../src/sakia/gui/community_view.py" line="95"/> <source>Informations</source> <translation>Informations</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source>Membership expiration</source> <translation>Expiration de votre adhésion</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source><b>Warning : Membership expiration in {0} days</b></source> <translation><b>Attention : Expiration de votre adhésion dans {0} jours</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source>Certifications number</source> <translation>Nombre de certifications</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source><b>Warning : You are certified by only {0} persons, need {1}</b></source> <translation><b>Attention : Vous êtes certifiés par seulement {0} personnes, besoin de {1}</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="228"/> + <location filename="../../../src/sakia/gui/community_view.py" line="235"/> <source> Block {0}</source> - <translation> Bloc {0}</translation> + <translation type="obsolete"> Bloc {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="270"/> + <location filename="../../../src/sakia/gui/community_view.py" line="277"/> <source> - Median fork window : {0}</source> - <translation> - Médianne des fenètres de fork : {0}</translation> + <translation type="obsolete"> - Médianne des fenètres de fork : {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="295"/> + <location filename="../../../src/sakia/gui/community_view.py" line="292"/> <source>Send membership demand</source> <translation>Envoyer une demande d'adhésion</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Membership</source> <translation>Adhésion</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="329"/> + <location filename="../../../src/sakia/gui/community_view.py" line="325"/> <source>Success sending Membership demand</source> <translation>Envoi de la demande d'adhésion réussi</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Warning</source> <translation>Attention</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Are you sure ? Sending a leaving demand cannot be canceled. The process to join back the community later will have to be done again.</source> @@ -732,12 +842,12 @@ Envoyer une demande pour quitter la communauté ne peut être annulée. Le processus pour rejoindre la communauté devrait être refait à zéro.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="361"/> + <location filename="../../../src/sakia/gui/community_view.py" line="356"/> <source>Revoke</source> <translation>Révocation</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="355"/> + <location filename="../../../src/sakia/gui/community_view.py" line="350"/> <source>Success sending Revoke demand</source> <translation>Envoi de la demande de révocation réussi</translation> </message> @@ -747,24 +857,44 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation>Publier votre UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="399"/> + <location filename="../../../src/sakia/gui/community_view.py" line="41"/> <source>Revoke UID</source> <translation>Révoquer votre UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="401"/> + <location filename="../../../src/sakia/gui/community_view.py" line="375"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="375"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Success publishing your UID</source> <translation>Succès de publication de votre UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="398"/> <source>Your UID was revoked successfully.</source> - <translation>Votre UID a été révoqué avec succès.</translation> + <translation type="obsolete">Votre UID a été révoqué avec succès.</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <source>Explore the Web of Trust</source> + <translation>Explorer la toile de confiance</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="99"/> + <source>Show explorer</source> + <translation>Afficher l'explorateur</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="100"/> + <source>Explorer</source> + <translation>Explorateur</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="234"/> + <source>Block {0}</source> + <translation type="unfinished"></translation> </message> </context> <context> @@ -780,7 +910,7 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation>Clé publique</translation> </message> <message> - <location filename="../../../src/sakia/gui/contact.py" line="52"/> + <location filename="../../../src/sakia/gui/contact.py" line="81"/> <source>Contact already exists</source> <translation>Le contact existe déja</translation> </message> @@ -790,6 +920,21 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation>Nom</translation> </message> </context> +<context> + <name>ContextMenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Warning</source> + <translation>Attention</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Are you sure ? +This money transfer will be removed and not sent.</source> + <translation>Êtes vous certain ? +Le transfert de monnaie sera annulé et non envoyé.</translation> + </message> +</context> <context> <name>CreateWalletDialog</name> <message> @@ -906,48 +1051,149 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <message> <location filename="../../ui/member.ui" line="14"/> <source>Informations</source> - <translation>Informations</translation> + <translation type="obsolete">Informations</translation> </message> <message> <location filename="../../ui/member.ui" line="34"/> <source>Member</source> - <translation>Membre</translation> + <translation type="obsolete">Membre</translation> + </message> +</context> +<context> + <name>DividendPerDay</name> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="9"/> + <source>UDD</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/member.ui" line="65"/> - <source>uid</source> - <translation></translation> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="10"/> + <source>{0} {1}UDD {2}</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/member.ui" line="72"/> - <source>properties</source> - <translation></translation> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="11"/> + <source>UDD {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="12"/> + <source>UDD(t) = (Q * 100) / (UD(t) / DT) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>ExplorerTabWidget</name> + <message> + <location filename="../../ui/explorer_tab.ui" line="14"/> + <source>Form</source> + <translation>Formulaire</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="48"/> + <source>Steps</source> + <translation>Étapes</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="65"/> + <source>Go</source> + <translation type="unfinished">Envoyer</translation> + </message> +</context> +<context> + <name>GraphTabWidget</name> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="71"/> + <source>Membership</source> + <translation>Adhésion</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source>Last renewal on {:}, expiration on {:}</source> + <translation type="unfinished">Dernier renouvellement le {:}, expire le {:}</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Your web of trust</source> + <translation type="unfinished">Votre toile de confiance</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Certified by {:} members; Certifier of {:} members</source> + <translation type="unfinished">Certifié par {:} membres; Certifieur de {:} membres</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Not a member</source> + <translation type="unfinished">Non-membre</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> </message> </context> <context> <name>HistoryTableModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Date</source> <translation>Date</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>UID/Public key</source> <translation>UID/Clé publique</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Payment</source> <translation>Débit</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Deposit</source> <translation>Crédit</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Comment</source> <translation>Commentaire</translation> </message> @@ -1059,73 +1305,83 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="36"/> <source>Members</source> - <translation>Membres</translation> + <translation type="obsolete">Membres</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="37"/> <source>Direct connections</source> - <translation>Connexions directes</translation> + <translation type="obsolete">Connexions directes</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="112"/> <source>Informations</source> - <translation>Informations</translation> + <translation type="obsolete">Informations</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="115"/> <source>Add as contact</source> - <translation>Ajouter comme contact</translation> + <translation type="obsolete">Ajouter comme contact</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="119"/> <source>Send money</source> - <translation>Envoyer de la monnaie</translation> + <translation type="obsolete">Envoyer de la monnaie</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="123"/> <source>Certify identity</source> - <translation>Certifier cette identité</translation> + <translation type="obsolete">Certifier cette identité</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="127"/> <source>View in Web of Trust</source> - <translation>Voir dans la Toile de Confiance</translation> + <translation type="obsolete">Voir dans la Toile de Confiance</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="131"/> <source>Copy pubkey</source> - <translation>Copier la clé publique</translation> + <translation type="obsolete">Copier la clé publique</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/identities_tab.py" line="32"/> + <source>Search direct certifications</source> + <translation type="unfinished">Rechercher des certifications "directes"</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/identities_tab.py" line="33"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Rechercher une clé publique, un uid...</translation> </message> </context> <context> <name>IdentitiesTableModel</name> <message> - <location filename="../../../src/sakia/models/identities.py" line="89"/> + <location filename="../../../src/sakia/models/identities.py" line="118"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="90"/> + <location filename="../../../src/sakia/models/identities.py" line="119"/> <source>Pubkey</source> <translation>Clé publique</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="91"/> + <location filename="../../../src/sakia/models/identities.py" line="120"/> <source>Renewed</source> <translation>Dernier renouvellement</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="92"/> + <location filename="../../../src/sakia/models/identities.py" line="121"/> <source>Expiration</source> <translation>Expiration</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="94"/> + <location filename="../../../src/sakia/models/identities.py" line="123"/> <source>Validation</source> <translation>Validation</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="93"/> + <location filename="../../../src/sakia/models/identities.py" line="122"/> <source>Publication</source> <translation>Publication</translation> </message> @@ -1239,7 +1495,7 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Universal Dividend UD(t) in</source> <translation>Dividende Universel DU(t) en</translation> </message> @@ -1249,7 +1505,7 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">Masse Monétaire M(t) en</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Members N(t)</source> <translation>Membres N(t)</translation> </message> @@ -1259,22 +1515,22 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">Masse Monétaire par membre M(t)/N(t) en</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Actual growth c = UD(t)/[M(t-1)/N(t)]</source> <translation>Croissance actuelle c = DU(t)/[M(t -1)/N(t)]</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Next UD date and time (t+1)</source> <translation>Date et heure du prochain DU (t+1)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="194"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="196"/> <source>No Universal Dividend created yet.</source> <translation>Pas de dividende universel créé pour le moment.</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1285,12 +1541,12 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:2.0%} / {:} days</source> <translation>{:2.0%} / {:} jours</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Fundamental growth (c) / Delta time (dt)</source> <translation>Croissance fondamentale (c) / Delta de temps (dt)</translation> </message> @@ -1300,17 +1556,17 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">DU(t+1) = MAX { DU(t) ; c * M(t) / N(t) }</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (formula)</source> <translation>Dividende Universel (formule)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (computed)</source> <translation>Dividende Universel (calculé)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> @@ -1337,96 +1593,82 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Fundamental growth (c)</source> <translation>Croissance fondamentale (c)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Initial Universal Dividend UD(0) in</source> <translation>Dividende Universel Initial DU(0) en</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Time period (dt) in days (86400 seconds) between two UD</source> <translation>Période de temps (dt) en jours (86400 secondes) entre deux DU</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Number of blocks used for calculating median time</source> <translation>Nombre de blocs utilisés pour calculer le temps median</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The average time in seconds for writing 1 block (wished time)</source> <translation>Le temps moyen en secondes pour écrire un bloc (temps espéré)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of blocks required to evaluate again PoWMin value</source> <translation>Le nombre de blocs requis pour évaluer une nouvelle valeur de PoWMin</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of previous blocks to check for personalized difficulty</source> <translation>Le nombre de blocs précédents pour vérifier la difficulté personnalisée</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The percent of previous issuers to reach for personalized difficulty</source> <translation>Le pourcentage d'utilisateurs précédents atteignant la difficulté personnalisée</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - </source> - <translation></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum delay between 2 identical certifications (in days)</source> - <translation>Le délai minimum entre 2 certifications identiques (en jours)</translation> + <translation type="obsolete">Le délai minimum entre 2 certifications identiques (en jours)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid signature (in days)</source> <translation>Age maximum d'une signature valide (en jours)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Minimum quantity of signatures to be part of the WoT</source> <translation>Nombre de signatures minimum pour faire partie de la TdC</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum quantity of valid made certifications to be part of the WoT for distance rule</source> - <translation>Quantité minimum de certifications valides pour faire partie de la TdC suivant la règle de distance</translation> + <translation type="obsolete">Quantité minimum de certifications valides pour faire partie de la TdC suivant la règle de distance</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid membership (in days)</source> <translation>Age maximum d'un statut de membre valide (en jours)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum distance between each WoT member and a newcomer</source> <translation>Distance maximum entre chaque membre de la TdC et un nouveau venu</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass M(t-1) in</source> <translation>Masse Monétaire M(t-1) en</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass per member M(t-1)/N(t) in</source> <translation>Masse Monétaire par membre M(t-1)/N(t) en</translation> </message> @@ -1461,12 +1703,12 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">DU(t+1) = MAX { DU(t) ; c &#215; M(t) / N(t) }</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</source> <translation></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</source> <translation></translation> </message> @@ -1496,12 +1738,12 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Last UD date and time (t)</source> <translation>Date et heure du dernier DU (t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> @@ -1514,12 +1756,23 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"></translation> + <translation> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:} {:}</td></tr> + <tr><td align="right"><b>{:2.2%} / {:} jours</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Penultimate UD date and time (t-1)</source> - <translation type="unfinished"></translation> + <translation type="unfinished">Dernier dividende universel</translation> </message> <message> <location filename="../../ui/informations_tab.ui" line="96"/> @@ -1527,75 +1780,111 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Name</source> <translation type="unfinished">Nom</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Units</source> <translation type="unfinished">Unités</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Formula</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Description</source> <translation type="unfinished"></translation> </message> -</context> -<context> - <name>MainWindow</name> <message> - <location filename="../../ui/mainwindow.ui" line="131"/> - <source>Account</source> - <translation>Compte</translation> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="61"/> - <source>Contacts</source> - <translation type="obsolete">Contacts</translation> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum delay between 2 certifications (in days)</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="75"/> - <source>Actions</source> - <translation type="obsolete">Actions</translation> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum quantity of active certifications made by member.</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="76"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum delay a certification can wait before being expired for non-writing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum percent of sentries to reach to match the distance rule</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MainWindow</name> + <message> + <location filename="../../ui/mainwindow.ui" line="138"/> + <source>Account</source> + <translation>Compte</translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="61"/> + <source>Contacts</source> + <translation type="obsolete">Contacts</translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="75"/> + <source>Actions</source> + <translation type="obsolete">Actions</translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="83"/> <source>Manage accounts</source> <translation>Gérer les comptes</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="81"/> + <location filename="../../ui/mainwindow.ui" line="88"/> <source>Configure trustable nodes</source> <translation>Configurer les noeuds de confiance</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="106"/> + <location filename="../../ui/mainwindow.ui" line="113"/> <source>Send a message</source> <translation>Envoyer un message</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="111"/> + <location filename="../../ui/mainwindow.ui" line="118"/> <source>Send money</source> <translation>Envoyer de la monnaie</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="116"/> + <location filename="../../ui/mainwindow.ui" line="123"/> <source>Remove contact</source> <translation>Supprimer un contact</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="121"/> + <location filename="../../ui/mainwindow.ui" line="128"/> <source>Save</source> <translation>Sauvegarder</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="350"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="426"/> <source>Export</source> <translation>Exporter</translation> </message> @@ -1605,7 +1894,7 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">Chargement du compte {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="211"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="285"/> <source>Latest release : {version}</source> <translation>Dernière version : {version}</translation> </message> @@ -1656,12 +1945,12 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="283"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="358"/> <source>Edit</source> <translation>Editer</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="286"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="361"/> <source>Delete</source> <translation>Supprimer</translation> </message> @@ -1676,12 +1965,12 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">CuteCoin {0} - Compte : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="348"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="424"/> <source>Export an account</source> <translation>Exporter un compte</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="349"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="425"/> <source>All account files (*.acc)</source> <translation>Tout fichier de compte (*.acc)</translation> </message> @@ -1706,27 +1995,27 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">&Ajouter</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="126"/> + <location filename="../../ui/mainwindow.ui" line="133"/> <source>&Quit</source> <translation>&Quitter</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="136"/> + <location filename="../../ui/mainwindow.ui" line="143"/> <source>&Transfer money</source> <translation>&Transférer de la monnaie</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="141"/> + <location filename="../../ui/mainwindow.ui" line="148"/> <source>&Configure</source> <translation>&Configurer</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="146"/> + <location filename="../../ui/mainwindow.ui" line="153"/> <source>&Import</source> <translation>&Importer</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="151"/> + <location filename="../../ui/mainwindow.ui" line="158"/> <source>&Export</source> <translation>&Exporter</translation> </message> @@ -1736,22 +2025,22 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">&Certification</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="161"/> + <location filename="../../ui/mainwindow.ui" line="168"/> <source>&Set as default</source> <translation>&Par défaut</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="166"/> + <location filename="../../ui/mainwindow.ui" line="173"/> <source>A&bout</source> <translation>A &propos</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="171"/> + <location filename="../../ui/mainwindow.ui" line="178"/> <source>&Preferences</source> <translation>&Préférences</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="251"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="326"/> <source>Please get the latest release {version}</source> <translation>Veuillez télécharger la dernière version {version}</translation> </message> @@ -1766,7 +2055,7 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation>&Aide</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="176"/> + <location filename="../../ui/mainwindow.ui" line="183"/> <source>&Add account</source> <translation>&Ajouter un compte</translation> </message> @@ -1782,7 +2071,7 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="218"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="292"/> <source>Download link</source> <translation>Lien de téléchargement</translation> </message> @@ -1797,12 +2086,12 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation>Co&ntacts</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="86"/> + <location filename="../../ui/mainwindow.ui" line="93"/> <source>A&dd a contact</source> <translation>A&jouter un contact</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="156"/> + <location filename="../../ui/mainwindow.ui" line="163"/> <source>C&ertification</source> <translation>C&ertification</translation> </message> @@ -1862,7 +2151,7 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <p>Moul</p> <p>canercandan</p> </source> - <translation> + <translation type="obsolete"> <h1>sakia</h1> <p>Python/Qt uCoin client</p> @@ -1881,120 +2170,181 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="303"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="383"/> <source>sakia {0}</source> <translation>sakia {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="330"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="407"/> <source>sakia {0} - Account : {1}</source> <translation>sakia {0} - Account : {1}</translation> </message> + <message> + <location filename="../../ui/mainwindow.ui" line="71"/> + <source>&Duniter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="188"/> + <source>&Manage local node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="299"/> + <source> + <h1>sakia</h1> + + <p>Python/Qt duniter client</p> + <p><a href="https://github.com/duniter/sakia">https://github.com/duniter/sakia</a></p> + + <p>Version : {:}</p> + {new_version_text} + + <p>License : GPLv3</p> + + <p><b>Authors</b></p> + + <p>inso</p> + <p>vit</p> + <p>Moul</p> + <p>canercandan</p> + </source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>MemberDialog</name> <message> - <location filename="../../../src/sakia/gui/member.py" line="46"/> + <location filename="../../../src/sakia/gui/member.py" line="73"/> <source>not a member</source> <translation>Non membre</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="60"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> - </source> - <translation></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Public key</source> <translation>Clé publique</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Join date</source> <translation>Date d'inscription</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="87"/> + <location filename="../../../src/sakia/gui/member.py" line="144"/> <source><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></source> <translation></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="73"/> + <location filename="../../../src/sakia/gui/member.py" line="130"/> <source>Distance</source> <translation>Distance</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="80"/> + <location filename="../../../src/sakia/gui/member.py" line="139"/> <source>Path</source> <translation>Chemin</translation> </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="92"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </source> + <translation> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </translation> + </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="97"/> + <source>UID Published on</source> + <translation>Identifiant publié sur le réseau</translation> + </message> +</context> +<context> + <name>MemberView</name> + <message> + <location filename="../../ui/member.ui" line="14"/> + <source>Member informations</source> + <translation>Information utilisateur</translation> + </message> + <message> + <location filename="../../ui/member.ui" line="34"/> + <source>Member</source> + <translation>Membre</translation> + </message> </context> <context> <name>NetworkFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="48"/> + <location filename="../../../src/sakia/models/network.py" line="54"/> <source>Address</source> <translation>Adresse</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="49"/> + <location filename="../../../src/sakia/models/network.py" line="55"/> <source>Port</source> <translation>Port</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="50"/> + <location filename="../../../src/sakia/models/network.py" line="56"/> <source>Block</source> <translation>Bloc</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="52"/> + <location filename="../../../src/sakia/models/network.py" line="59"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="53"/> + <location filename="../../../src/sakia/models/network.py" line="60"/> <source>Member</source> <translation>Membre</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="54"/> + <location filename="../../../src/sakia/models/network.py" line="61"/> <source>Pubkey</source> <translation>Clé publique</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="55"/> + <location filename="../../../src/sakia/models/network.py" line="62"/> <source>Software</source> <translation>Logiciel</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="56"/> + <location filename="../../../src/sakia/models/network.py" line="63"/> <source>Version</source> <translation>Version</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>yes</source> <translation>oui</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>no</source> <translation>non</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>offline</source> <translation>déconnecté</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="51"/> + <location filename="../../../src/sakia/models/network.py" line="57"/> <source>Hash</source> <translation>Hash</translation> </message> + <message> + <location filename="../../../src/sakia/models/network.py" line="58"/> + <source>Time</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>NetworkTabWidget</name> @@ -2004,17 +2354,17 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation></translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="70"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="72"/> <source>Unset root node</source> <translation>Supprimer des noeuds racines</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="76"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="78"/> <source>Set as root node</source> <translation>Définir comme noeud racine</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="82"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="84"/> <source>Open in browser</source> <translation>Ouvrir dans le navigateur</translation> </message> @@ -2022,22 +2372,22 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <context> <name>NetworkTableModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="136"/> + <location filename="../../../src/sakia/models/network.py" line="155"/> <source>Online</source> <translation>Connecté</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="137"/> + <location filename="../../../src/sakia/models/network.py" line="156"/> <source>Offline</source> <translation>Déconnecté</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="138"/> + <location filename="../../../src/sakia/models/network.py" line="157"/> <source>Unsynchronized</source> <translation>Désynchronisé</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="139"/> + <location filename="../../../src/sakia/models/network.py" line="158"/> <source>Corrupted</source> <translation>Corrompu</translation> </message> @@ -2065,6 +2415,14 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">Certifier cette identité</translation> </message> </context> +<context> + <name>NodeManager</name> + <message> + <location filename="../../ui/node_manager.ui" line="14"/> + <source>Node manager</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>PasswordAskerDialog</name> <message> @@ -2083,22 +2441,22 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation>Sauvegarder le mot de passe durant cette session</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Bad password</source> <translation>Mauvais mot de passe</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Non printable characters in password</source> <translation>Caractères invisibles présents dans le mot de passe</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Failed to get private key</source> <translation>Echec d'ouverture de la clé privée</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Wrong password typed. Cannot open the private key</source> <translation>Mauvais mot de passe. Impossible d'ouvrir votre clé privée</translation> </message> @@ -2171,7 +2529,7 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation>Utiliser le Système d'Unités International</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="329"/> + <location filename="../../ui/preferences.ui" line="356"/> <source><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Network settings</span></p></body></html></source> <translation><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Paramètres réseaux</span></p></body></html></translation> </message> @@ -2196,40 +2554,45 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">SOCKS5</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="345"/> + <location filename="../../ui/preferences.ui" line="372"/> <source>Proxy server address : </source> <translation>Adresse du serveur proxy : </translation> </message> <message> - <location filename="../../ui/preferences.ui" line="355"/> + <location filename="../../ui/preferences.ui" line="382"/> <source>:</source> <translation>:</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="336"/> + <location filename="../../ui/preferences.ui" line="363"/> <source>Use a http proxy server</source> <translation>Utiliser un serveur proxy http</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="379"/> + <location filename="../../ui/preferences.ui" line="406"/> <source>Automatically refresh identities informations</source> <translation>Rafraichir automatiquement les informations des identités</translation> </message> + <message> + <location filename="../../ui/preferences.ui" line="330"/> + <source>Enable forgetfulness</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureAccount</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="163"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="165"/> <source>New account</source> <translation>Nouveau compte</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="170"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="175"/> <source>Configure {0}</source> <translation>Configurer {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="185"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="190"/> <source>Ok</source> <translation>Ok</translation> </message> @@ -2244,12 +2607,12 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans <translation type="obsolete">Les paramètres de cette clé publique sont : {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="243"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="249"/> <source>Error</source> <translation>Erreur</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> <source>Warning</source> <translation>Attention</translation> </message> @@ -2259,31 +2622,39 @@ Le processus pour rejoindre la communauté devrait être refait à zéro.</trans Please note your key parameters (salt and password) if you wish to recover it later. Your account won't be removed from the networks it joined. Are you sure ?</source> - <translation>Cette action supprimera votre compte localement. + <translation type="obsolete">Cette action supprimera votre compte localement. Veuillez noter les paramètres de votre clé (salage et mot de passe) si vous souhaitez le récupérer plus tard. Votre compte ne sera pas supprimer des réseaux rejoins. Êtes vous sure ?</translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> + <source>This action will delete your account ({0}) locally. +Please note your key parameters (salt and password) if you wish to recover it later. +Your account won't be removed from the networks it joined. +Are you sure ?</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureCommunity</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="227"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="240"/> <source>Configure community {0}</source> <translation>Configurer la communauté {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="230"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="243"/> <source>Add a community</source> <translation>Ajouter une communauté</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="264"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="276"/> <source>Error</source> <translation>Erreur</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="293"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="305"/> <source>Delete</source> <translation>Supprimer</translation> </message> @@ -2377,15 +2748,20 @@ Souhaitez-vous publier votre clé publique ?</translation> <translation>Quant. som. 0</translation> </message> <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="7"/> <source>{0} Q0 {1}</source> - <translation>{0} Q0 {1}</translation> + <translation type="obsolete">{0} Q0 {1}</translation> </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> <source>Q0 {0}</source> <translation>Q0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <source>{0} {1}Q0 {2}</source> + <translation>{0} {1}Q0 {2}</translation> + </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="10"/> <source>Z0 = Q - ( M(t-1) / N(t) ) @@ -2404,22 +2780,22 @@ Souhaitez-vous publier votre clé publique ?</translation> <context> <name>Relative</name> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="7"/> + <location filename="../../../src/sakia/core/money/relative.py" line="9"/> <source>UD</source> <translation>DU</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative.py" line="10"/> <source>{0} {1}UD {2}</source> <translation>{0} {1}DU {2}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="9"/> + <location filename="../../../src/sakia/core/money/relative.py" line="11"/> <source>UD {0}</source> <translation>DU {0}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="10"/> + <location filename="../../../src/sakia/core/money/relative.py" line="12"/> <source>R = Q / UD(t) <br > <table> @@ -2431,6 +2807,36 @@ Souhaitez-vous publier votre clé publique ?</translation> <translation type="unfinished"></translation> </message> </context> +<context> + <name>RelativeToPast</name> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="6"/> + <source>Past UD</source> + <translation>Dernier dividende</translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="7"/> + <source>{0} {1}UD({2}) {3}</source> + <translation type="unfinished">{0} {1}UD({2}) {3}</translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="8"/> + <source>UD({0}) {1}</source> + <translation type="unfinished">UD({0}) {1}</translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Relative value</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RelativeZSum</name> <message> @@ -2439,15 +2845,20 @@ Souhaitez-vous publier votre clé publique ?</translation> <translation>Rel. som. 0</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="7"/> <source>{0} R0 {1}</source> - <translation>{0} R0 {1}</translation> + <translation type="obsolete">{0} R0 {1}</translation> </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> <source>R0 {0}</source> <translation>R0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <source>{0} {1}R0 {2}</source> + <translation type="unfinished">{0} {1}R0 {2}</translation> + </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="10"/> <source>R0 = (R / UD(t)) - (( M(t-1) / N(t) ) / UD(t)) @@ -2468,50 +2879,68 @@ Souhaitez-vous publier votre clé publique ?</translation> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="158"/> <source>Certification expires at {0}</source> - <translation>Certification expire le {0}</translation> + <translation type="obsolete">Certification expire le {0}</translation> + </message> +</context> +<context> + <name>SearchUserWidget</name> + <message> + <location filename="../../ui/search_user_view.ui" line="14"/> + <source>Form</source> + <translation>Formulaire</translation> + </message> + <message> + <location filename="../../ui/search_user_view.ui" line="33"/> + <source>Center the view on me</source> + <translation type="unfinished">Centrer la vue sur moi</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/search_user.py" line="15"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Rechercher une clé publique, un uid...</translation> </message> </context> <context> <name>StepPageInit</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="95"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="101"/> <source>Could not find your identity on the network.</source> <translation>Impossible de trouver votre identité sur le réseau.</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="127"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> <source>Broadcasting identity...</source> <translation>Diffusion de votre identité...</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>UID broadcast</source> <translation>Diffusion de l'UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>Identity broadcasted to the network</source> <translation>Identité diffusée sur le réseau</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>Error</source> <translation>Erreur</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>{0}</source> <translation>{0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="153"/> <source>Your pubkey or UID was already found on the network. Yours : {0}, the network : {1}</source> <translation>Votre clé publique ou votre UID est déja présent sur le réseau. Vous : {0}, le réseau : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="145"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="156"/> <source>Your account already exists on the network</source> <translation>Votre compte existe déjà sur le réseau</translation> </message> @@ -2523,12 +2952,27 @@ Vous : {0}, le réseau : {1}</translation> Le votre : {0}, le réseau : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="97"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="103"/> <source>Your pubkey or UID is different on the network. Yours : {0}, the network : {1}</source> <translation>Votre clé publique ou votre UID est différent sur le réseau. De votre coté : {0}, du coté du réseau : {1}</translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="124"/> + <source>connecting...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="164"/> + <source>Could not connect. Check hostname, ip address or port</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="162"/> + <source>Could not connect. Check node peering entry</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Toast</name> @@ -2543,27 +2987,27 @@ De votre coté : {0}, du coté du réseau : {1}</translation> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="175"/> <source>Actions</source> - <translation>Actions</translation> + <translation type="obsolete">Actions</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="190"/> <source>Send again</source> - <translation>Renvoyer</translation> + <translation type="obsolete">Renvoyer</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="195"/> <source>Cancel</source> - <translation>Annuler</translation> + <translation type="obsolete">Annuler</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="201"/> <source>Informations</source> - <translation>Informations</translation> + <translation type="obsolete">Informations</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="206"/> <source>Add as contact</source> - <translation>Ajouter comme contact</translation> + <translation type="obsolete">Ajouter comme contact</translation> </message> <message> <location filename="../../../src/cutecoin/gui/transactions_tab.py" line="153"/> @@ -2578,18 +3022,18 @@ De votre coté : {0}, du coté du réseau : {1}</translation> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="222"/> <source>Copy pubkey to clipboard</source> - <translation>Copier la clé publique</translation> + <translation type="obsolete">Copier la clé publique</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Warning</source> - <translation>Attention</translation> + <translation type="obsolete">Attention</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Are you sure ? This money transfer will be removed and not sent.</source> - <translation>Êtes vous certain ? + <translation type="obsolete">Êtes vous certain ? Le transfert de monnaie sera annulé et non envoyé.</translation> </message> <message> @@ -2610,12 +3054,12 @@ Le transfert de monnaie sera annulé et non envoyé.</translation> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="211"/> <source>Send money</source> - <translation>Envoyer de la monnaie</translation> + <translation type="obsolete">Envoyer de la monnaie</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="217"/> <source>View in Web of Trust</source> - <translation>Voir dans la Toile de Confiance</translation> + <translation type="obsolete">Voir dans la Toile de Confiance</translation> </message> <message> <location filename="../../../src/cutecoin/gui/transactions_tab.py" line="135"/> @@ -2628,7 +3072,7 @@ Le transfert de monnaie sera annulé et non envoyé.</translation> <translation>Nouveaux transferts reçus</translation> </message> <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="160"/> + <location filename="../../../src/sakia/gui/transactions_tab.py" line="159"/> <source>{:}</source> <translation>{:}</translation> </message> @@ -2666,7 +3110,7 @@ Le transfert de monnaie sera annulé et non envoyé.</translation> <translation type="obsolete">Clé publique du receveur</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="80"/> + <location filename="../../ui/transfer.ui" line="136"/> <source>Key</source> <translation>Clé</translation> </message> @@ -2686,22 +3130,22 @@ Le transfert de monnaie sera annulé et non envoyé.</translation> <translation type="obsolete">Montant :</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="148"/> + <location filename="../../ui/transfer.ui" line="250"/> <source> UD</source> <translation> DU</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="166"/> + <location filename="../../ui/transfer.ui" line="268"/> <source>Transaction message</source> <translation>Message</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>Money transfer</source> <translation>Transfert de monnaie</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>No amount. Please give the transfert amount</source> <translation>Pas de montant. Veuillez entrer un montant</translation> </message> @@ -2733,40 +3177,45 @@ Veuillez rééssayer plus tard</translation> <translation type="obsolete">Erreur</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="139"/> + <location filename="../../../src/sakia/gui/transfer.py" line="163"/> <source>Transfer</source> <translation>Transfert</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="126"/> + <location filename="../../../src/sakia/gui/transfer.py" line="150"/> <source>Success sending money to {0}</source> <translation>Envoi de monnaie à {0} réussi</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="106"/> + <location filename="../../ui/transfer.ui" line="208"/> <source>Wallet</source> <translation>Portefeuille</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="125"/> + <location filename="../../ui/transfer.ui" line="227"/> <source>Available money : </source> <translation>Monnaie disponible : </translation> </message> <message> - <location filename="../../ui/transfer.ui" line="134"/> + <location filename="../../ui/transfer.ui" line="236"/> <source>Amount</source> <translation>Montant</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="61"/> + <location filename="../../ui/transfer.ui" line="95"/> <source>&Recipient public key</source> <translation>Clé publique du receveur</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="40"/> + <location filename="../../ui/transfer.ui" line="46"/> <source>Con&tact</source> <translation>Con&tact</translation> </message> + <message> + <location filename="../../ui/transfer.ui" line="156"/> + <source>S&earch user</source> + <translation>Recherche une identité</translation> + </message> </context> <context> <name>TxFilterProxyModel</name> @@ -2781,16 +3230,48 @@ Veuillez rééssayer plus tard</translation> <translation type="obsolete">Validation en cours... {0} %</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="165"/> + <location filename="../../../src/sakia/models/txhistory.py" line="166"/> <source>{0} / {1} confirmations</source> <translation>{0} / {1} confirmations</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="169"/> + <location filename="../../../src/sakia/models/txhistory.py" line="170"/> <source>Confirming... {0} %</source> <translation>Confirmation... {0} %</translation> </message> </context> +<context> + <name>UDDToPast</name> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="6"/> + <source>Past UUD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="7"/> + <source>{0} {1}UUD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="8"/> + <source>UUD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table>></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>WalletsTab</name> <message> @@ -3033,27 +3514,27 @@ Revoking your UID can only success if it is not already validated by the network <message> <location filename="../../../src/sakia/gui/views/wot.py" line="294"/> <source>Informations</source> - <translation>Informations</translation> + <translation type="obsolete">Informations</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="299"/> <source>Add as contact</source> - <translation>Ajouter comme contact</translation> + <translation type="obsolete">Ajouter comme contact</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="304"/> <source>Send money</source> - <translation>Envoyer de la monnaie</translation> + <translation type="obsolete">Envoyer de la monnaie</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="309"/> <source>Certify identity</source> - <translation>Certifier cette identité</translation> + <translation type="obsolete">Certifier cette identité</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="314"/> <source>Copy pubkey</source> - <translation>Copier la clé publique</translation> + <translation type="obsolete">Copier la clé publique</translation> </message> </context> <context> @@ -3071,15 +3552,15 @@ Revoking your UID can only success if it is not already validated by the network <message> <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> <source>Research a pubkey, an uid...</source> - <translation>Rechercher une clé publique, un uid...</translation> + <translation type="obsolete">Rechercher une clé publique, un uid...</translation> </message> <message> <location filename="../../ui/wot_tab.ui" line="33"/> <source>Center the view on me</source> - <translation>Centrer la vue sur moi</translation> + <translation type="obsolete">Centrer la vue sur moi</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -3087,7 +3568,7 @@ Revoking your UID can only success if it is not already validated by the network <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -3096,32 +3577,32 @@ Revoking your UID can only success if it is not already validated by the network </translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="126"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="122"/> <source>Membership</source> - <translation>Adhésion</translation> + <translation type="obsolete">Adhésion</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source>Last renewal on {:}, expiration on {:}</source> - <translation>Dernier renouvellement le {:}, expire le {:}</translation> + <translation type="obsolete">Dernier renouvellement le {:}, expire le {:}</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Your web of trust</source> - <translation>Votre toile de confiance</translation> + <translation type="obsolete">Votre toile de confiance</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Certified by {:} members; Certifier of {:} members</source> - <translation>Certifié par {:} membres; Certifieur de {:} membres</translation> + <translation type="obsolete">Certifié par {:} membres; Certifieur de {:} membres</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Not a member</source> - <translation>Non-membre</translation> + <translation type="obsolete">Non-membre</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -3129,7 +3610,7 @@ Revoking your UID can only success if it is not already validated by the network <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td></tr> @@ -3138,35 +3619,129 @@ Revoking your UID can only success if it is not already validated by the network </translation> </message> </context> +<context> + <name>certificationsTabWidget</name> + <message> + <location filename="../../ui/certifications_tab.ui" line="14"/> + <source>Form</source> + <translation>Formulaire</translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="20"/> + <source>Certifications</source> + <translation>Certifications</translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="33"/> + <source>loading...</source> + <translation>chargement...</translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="63"/> + <source>dd/MM/yyyy</source> + <translation>dd/MM/yyyy</translation> + </message> +</context> +<context> + <name>menu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="57"/> + <source>Certify identity</source> + <translation type="unfinished">Certifier cette identité</translation> + </message> +</context> +<context> + <name>menu.qmenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="42"/> + <source>Informations</source> + <translation type="unfinished">Informations</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="47"/> + <source>Add as contact</source> + <translation>Ajouter comme contact</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="52"/> + <source>Send money</source> + <translation>Envoyer de la monnaie</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="61"/> + <source>View in Web of Trust</source> + <translation>Voir dans la Toile de Confiance</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="65"/> + <source>Copy pubkey to clipboard</source> + <translation>Copier la clé publique</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="70"/> + <source>Copy membership document to clipboard</source> + <translation type="unfinished">Copier le document d'adhésion</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="74"/> + <source>Copy self-certification document to clipboard</source> + <translation type="unfinished">Copier le document d'auto-certification</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="84"/> + <source>Transfer</source> + <translation type="unfinished">Transfert</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="86"/> + <source>Send again</source> + <translation type="unfinished">Renvoyer</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="90"/> + <source>Cancel</source> + <translation type="unfinished">Annuler</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="95"/> + <source>Copy raw transaction to clipboard</source> + <translation type="unfinished">Copier la transaction (format brut)</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="100"/> + <source>Copy transaction block to clipboard</source> + <translation type="unfinished">Copier le bloc de la transaction</translation> + </message> +</context> <context> <name>self.config_dialog</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="191"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="204"/> <source>Ok</source> <translation>Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="70"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="72"/> <source>Forbidden : salt is too short</source> <translation>Interdit : le sel est trop court</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="74"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="76"/> <source>Forbidden : password is too short</source> <translation>Interdit : Le mot de passe est trop court</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="78"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="80"/> <source>Forbidden : Invalid characters in salt field</source> <translation>Interdit : Caractères invalides dans le sel</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="82"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="84"/> <source>Forbidden : Invalid characters in password field</source> <translation>Interdit : Caractères invalides dans le mot de passe</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="88"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="90"/> <source>Error : passwords are different</source> <translation>Erreur : les mots de passes sont différents</translation> </message> @@ -3179,7 +3754,7 @@ Revoking your UID can only success if it is not already validated by the network <translation></translation> </message> <message> - <location filename="../../ui/transactions_tab.ui" line="63"/> + <location filename="../../ui/transactions_tab.ui" line="66"/> <source>dd/MM/yyyy</source> <translation>dd/MM/yyyy</translation> </message> diff --git a/res/i18n/ts/it_IT.ts b/res/i18n/ts/it_IT.ts index 9f8d27b3668d1e1523615a607a31156880fc4f77..4ee912420f746067fef8e495441eb6cc3d3f1f6d 100644 --- a/res/i18n/ts/it_IT.ts +++ b/res/i18n/ts/it_IT.ts @@ -51,10 +51,25 @@ <translation type="obsolete">Relat somma-Z</translation> </message> <message> - <location filename="../../../src/sakia/core/account.py" line="510"/> + <location filename="../../../src/sakia/core/account.py" line="540"/> <source>Could not find user self certification.</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="67"/> + <source>Warning : Your membership is expiring soon.</source> + <translation type="unfinished">Avvertimento : La tua iscrizione sta per scadere.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="72"/> + <source>Warning : Your could miss certifications soon.</source> + <translation type="unfinished">Avvertimento: Tu potrebbe perdere certificazioni presto.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="77"/> + <source>Warning : If you don't renew soon, your identity will be considerd revoked.</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AccountConfigurationDialog</name> @@ -91,7 +106,7 @@ <message> <location filename="../../ui/account_cfg.ui" line="143"/> <source>CryptoID</source> - <translation>ID criptato</translation> + <translation type="obsolete">ID criptato</translation> </message> <message> <location filename="../../ui/account_cfg.ui" line="153"/> @@ -133,49 +148,54 @@ <source>Communities</source> <translation>Comunità</translation> </message> + <message> + <location filename="../../ui/account_cfg.ui" line="143"/> + <source>Entropy</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Application</name> <message> <location filename="../../../src/sakia/core/app.py" line="76"/> <source>Warning : Your membership is expiring soon.</source> - <translation type="unfinished">Avvertimento : La tua iscrizione sta per scadere.</translation> + <translation type="obsolete">Avvertimento : La tua iscrizione sta per scadere.</translation> </message> <message> <location filename="../../../src/sakia/core/app.py" line="81"/> <source>Warning : Your could miss certifications soon.</source> - <translation type="unfinished">Avvertimento: Tu potrebbe perdere certificazioni presto.</translation> + <translation type="obsolete">Avvertimento: Tu potrebbe perdere certificazioni presto.</translation> </message> </context> <context> <name>CertificationDialog</name> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Certification</source> <translation>Certificazione</translation> </message> <message> - <location filename="../../ui/certification.ui" line="20"/> + <location filename="../../ui/certification.ui" line="26"/> <source>Community</source> <translation>Communità</translation> </message> <message> - <location filename="../../ui/certification.ui" line="32"/> + <location filename="../../ui/certification.ui" line="54"/> <source>Certify user</source> <translation>Certifica l’utente</translation> </message> <message> <location filename="../../ui/certification.ui" line="40"/> <source>Contact</source> - <translation>Contatti</translation> + <translation type="obsolete">Contatti</translation> </message> <message> <location filename="../../ui/certification.ui" line="61"/> <source>User public key</source> - <translation>Chiave pubblica dell’utente</translation> + <translation type="obsolete">Chiave pubblica dell’utente</translation> </message> <message> - <location filename="../../ui/certification.ui" line="80"/> + <location filename="../../ui/certification.ui" line="157"/> <source>Key</source> <translation>Chiave</translation> </message> @@ -200,25 +220,75 @@ <translation type="obsolete">Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="112"/> + <location filename="../../../src/sakia/gui/certification.py" line="227"/> <source>Not a member</source> <translation>Non risulti membro di questa comunità</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="109"/> + <location filename="../../../src/sakia/gui/certification.py" line="221"/> <source>&Ok</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="75"/> + <location filename="../../../src/sakia/gui/certification.py" line="126"/> <source>Success sending certification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Could not broadcast certification : {0}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/certification.ui" line="73"/> + <source>Con&tact</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="116"/> + <source>&User public key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="35"/> + <source>Certifications stock</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="177"/> + <source>Sea&rch user</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="197"/> + <source>Certifications sent : {nb_certifications}/{stock}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="206"/> + <source>{days} days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="208"/> + <source>{hours} hours and {min} min.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="210"/> + <source>Remaining time before next certification validation : {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="217"/> + <source> (Not validated before </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="224"/> + <source>No more certifications</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityConfigurationDialog</name> @@ -253,17 +323,17 @@ <translation>Server</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="200"/> + <location filename="../../ui/community_cfg.ui" line="203"/> <source>Add</source> <translation>Aggiungi</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="221"/> + <location filename="../../ui/community_cfg.ui" line="224"/> <source>Previous</source> <translation>Precedente</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="244"/> + <location filename="../../ui/community_cfg.ui" line="247"/> <source>Next</source> <translation>Seguente</translation> </message> @@ -374,45 +444,80 @@ <context> <name>CommunityTile</name> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="81"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Member</source> <translation type="unfinished">Membro</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="82"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Non-Member</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>members</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Monetary mass</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Balance</source> <translation type="unfinished">Bilancia</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="112"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="162"/> <source>Not connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="125"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="175"/> <source>Community not initialized</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="100"/> + <source>Expired or never published</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="101"/> + <source>Outdistanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="110"/> + <source>In WoT range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="116"/> + <source>Expires in </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="124"/> + <source>#FF0000</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Certs. received</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Membership</source> + <translation type="unfinished">Iscrizione</translation> + </message> </context> <context> <name>CommunityWidget</name> @@ -432,7 +537,7 @@ <translation type="unfinished">Certificazione</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="289"/> + <location filename="../../../src/sakia/gui/community_view.py" line="286"/> <source>Renew membership</source> <translation type="unfinished">Rinnova iscrizione</translation> </message> @@ -447,62 +552,57 @@ <translation type="obsolete">Avvertimento: Tu potrebbe perdere certificazioni presto.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="34"/> + <location filename="../../../src/sakia/gui/community_view.py" line="33"/> <source>Transactions</source> <translation type="unfinished">Transazioni</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <location filename="../../../src/sakia/gui/community_view.py" line="34"/> <source>Web of Trust</source> <translation type="unfinished">Rete della fiducia</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="37"/> + <location filename="../../../src/sakia/gui/community_view.py" line="90"/> <source>Network</source> <translation type="unfinished">Rete</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source>Membership expiration</source> <translation type="unfinished">Scadenza dell'iscrizione</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source><b>Warning : Membership expiration in {0} days</b></source> <translation type="unfinished"><b>Avvertimento : scadenza dell'adesione nel {0} giorni</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source>Certifications number</source> <translation type="unfinished">Numero delle Certificazioni</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source><b>Warning : You are certified by only {0} persons, need {1}</b></source> <translation type="unfinished"><b>Avvertimento : Tu è certificato solamente da {0} persone, necessità {1}</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="228"/> + <location filename="../../../src/sakia/gui/community_view.py" line="235"/> <source> Block {0}</source> - <translation type="unfinished"> Blocca {0}</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/community_view.py" line="270"/> - <source> - Median fork window : {0}</source> - <translation type="unfinished"></translation> + <translation type="obsolete"> Blocca {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="295"/> + <location filename="../../../src/sakia/gui/community_view.py" line="292"/> <source>Send membership demand</source> <translation type="unfinished">Invia domanda di iscrizione</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Warning</source> <translation type="unfinished">Avvertimento</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Are you sure ? Sending a leaving demand cannot be canceled. The process to join back the community later will have to be done again.</source> @@ -518,7 +618,7 @@ Publishing your UID can be canceled by Revoke UID.</source> La pubblicazione di tuo UID può essere annullato da Revoca IDU.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="375"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Success publishing your UID</source> <translation type="unfinished">Successo della pubblicazione del tuo IDU</translation> </message> @@ -550,22 +650,22 @@ Revoking your UID can only success if it is not already validated by the network Revoca tuo UID può solo successo se non è già convalidato dalla rete.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Membership</source> <translation type="unfinished">Iscrizione</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="329"/> + <location filename="../../../src/sakia/gui/community_view.py" line="325"/> <source>Success sending Membership demand</source> <translation type="unfinished">Domanda d’iscrizione inviata con successo</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="361"/> + <location filename="../../../src/sakia/gui/community_view.py" line="356"/> <source>Revoke</source> <translation type="unfinished">Revoca</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="355"/> + <location filename="../../../src/sakia/gui/community_view.py" line="350"/> <source>Success sending Revoke demand</source> <translation type="unfinished">Revoca della domanda inviata con successo</translation> </message> @@ -580,12 +680,12 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="obsolete">Autocertificazione inviata con successo</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <location filename="../../../src/sakia/gui/community_view.py" line="94"/> <source>Show informations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="38"/> + <location filename="../../../src/sakia/gui/community_view.py" line="95"/> <source>Informations</source> <translation type="unfinished">Informazioni</translation> </message> @@ -595,23 +695,38 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="unfinished">Pubblica IDU</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="399"/> + <location filename="../../../src/sakia/gui/community_view.py" line="41"/> <source>Revoke UID</source> <translation type="unfinished">Revoca IDU</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="401"/> + <location filename="../../../src/sakia/gui/community_view.py" line="375"/> <source>UID</source> <translation type="unfinished">IDU</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> - <source>Your UID was revoked successfully.</source> + <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <source>Search Identities</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="36"/> - <source>Search Identities</source> + <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <source>Explore the Web of Trust</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="99"/> + <source>Show explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="100"/> + <source>Explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="234"/> + <source>Block {0}</source> <translation type="unfinished"></translation> </message> </context> @@ -633,11 +748,26 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation>Chiave pubblica</translation> </message> <message> - <location filename="../../../src/sakia/gui/contact.py" line="52"/> + <location filename="../../../src/sakia/gui/contact.py" line="81"/> <source>Contact already exists</source> <translation>Questo contatto esiste già</translation> </message> </context> +<context> + <name>ContextMenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Warning</source> + <translation type="unfinished">Avvertimento</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Are you sure ? +This money transfer will be removed and not sent.</source> + <translation type="unfinished">Sei sicuro? ↵ +Questo trasferimento di denaro sarà rimosso e non inviato.</translation> + </message> +</context> <context> <name>CreateWalletDialog</name> <message> @@ -734,48 +864,159 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <message> <location filename="../../ui/member.ui" line="14"/> <source>Informations</source> - <translation>Informazioni</translation> + <translation type="obsolete">Informazioni</translation> </message> <message> <location filename="../../ui/member.ui" line="34"/> <source>Member</source> - <translation>Membro</translation> + <translation type="obsolete">Membro</translation> </message> <message> <location filename="../../ui/member.ui" line="65"/> <source>uid</source> - <translation>idu</translation> + <translation type="obsolete">idu</translation> </message> <message> <location filename="../../ui/member.ui" line="72"/> <source>properties</source> - <translation>proprietà</translation> + <translation type="obsolete">proprietà</translation> + </message> +</context> +<context> + <name>DividendPerDay</name> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="9"/> + <source>UDD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="10"/> + <source>{0} {1}UDD {2}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="11"/> + <source>UDD {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="12"/> + <source>UDD(t) = (Q * 100) / (UD(t) / DT) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>ExplorerTabWidget</name> + <message> + <location filename="../../ui/explorer_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Formulario</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="48"/> + <source>Steps</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="65"/> + <source>Go</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>GraphTabWidget</name> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="71"/> + <source>Membership</source> + <translation type="unfinished">Iscrizione</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source>Last renewal on {:}, expiration on {:}</source> + <translation type="unfinished">Ultimo rinnovo il {:}, scadenza il {:}</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Your web of trust</source> + <translation type="unfinished">La tua rete della fiducia</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Certified by {:} members; Certifier of {:} members</source> + <translation type="unfinished">Certificato da {}: membri; Certificatore di {}: membri</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Not a member</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> </message> </context> <context> <name>HistoryTableModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Date</source> <translation>Data</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>UID/Public key</source> <translation>IDU/Chiave Pubblica</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Payment</source> <translation>Pagamento</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Deposit</source> <translation>Deposito</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Comment</source> <translation>Commento</translation> </message> @@ -892,73 +1133,73 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="36"/> <source>Members</source> - <translation type="unfinished">Membri</translation> + <translation type="obsolete">Membri</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="37"/> <source>Direct connections</source> - <translation type="unfinished">Connessioni dirette</translation> + <translation type="obsolete">Connessioni dirette</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="112"/> <source>Informations</source> - <translation type="unfinished">Informazioni</translation> + <translation type="obsolete">Informazioni</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="115"/> <source>Add as contact</source> - <translation type="unfinished">Aggiungi un contatto</translation> + <translation type="obsolete">Aggiungi un contatto</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="119"/> <source>Send money</source> - <translation type="unfinished">Invia denaro</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="123"/> - <source>Certify identity</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Invia denaro</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="127"/> <source>View in Web of Trust</source> - <translation type="unfinished">Vedi in Rete della Fiducia</translation> + <translation type="obsolete">Vedi in Rete della Fiducia</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/identities_tab.py" line="32"/> + <source>Search direct certifications</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="131"/> - <source>Copy pubkey</source> + <location filename="../../../src/sakia/gui/identities_tab.py" line="33"/> + <source>Research a pubkey, an uid...</source> <translation type="unfinished"></translation> </message> </context> <context> <name>IdentitiesTableModel</name> <message> - <location filename="../../../src/sakia/models/identities.py" line="89"/> + <location filename="../../../src/sakia/models/identities.py" line="118"/> <source>UID</source> <translation>IDU</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="90"/> + <location filename="../../../src/sakia/models/identities.py" line="119"/> <source>Pubkey</source> <translation>Chiave pubblica</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="91"/> + <location filename="../../../src/sakia/models/identities.py" line="120"/> <source>Renewed</source> <translation>Rinnovato</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="92"/> + <location filename="../../../src/sakia/models/identities.py" line="121"/> <source>Expiration</source> <translation>Scadenza</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="94"/> + <location filename="../../../src/sakia/models/identities.py" line="123"/> <source>Validation</source> <translation>Validazione</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="93"/> + <location filename="../../../src/sakia/models/identities.py" line="122"/> <source>Publication</source> <translation type="unfinished"></translation> </message> @@ -1094,47 +1335,47 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Universal Dividend UD(t) in</source> <translation>Il Dividende Universale DU(t) in</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass M(t-1) in</source> <translation>Massa monetaria M(t-1) in</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Members N(t)</source> <translation>Membri N(t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass per member M(t-1)/N(t) in</source> <translation>Massa monetaria per membro M(t-1)/N(t) in</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Actual growth c = UD(t)/[M(t-1)/N(t)]</source> <translation>Crescita effettiva c = DU(t)/[M(t-1)/N (t)]</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Last UD date and time (t)</source> <translation>Ultimo DU data e ora (t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Next UD date and time (t+1)</source> <translation>Seguente DU data e l'ora (t + 1)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="194"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="196"/> <source>No Universal Dividend created yet.</source> <translation>Nessun Dividendo Universale ancora creato.</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1151,37 +1392,37 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:2.0%} / {:} days</source> <translation>{:2.0%} / {:} giorni</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Fundamental growth (c) / Delta time (dt)</source> <translation>Crescita fondamentale (c) / Tempo delta (dt)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</source> <translation>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (formula)</source> <translation>Dividendo universale (formula)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</source> <translation>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (computed)</source> <translation>Dividendo Universale (calcolato)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> @@ -1208,47 +1449,47 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Fundamental growth (c)</source> <translation>Crescita fondamentale (c)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Initial Universal Dividend UD(0) in</source> <translation>Dividendo Universale iniziale UD (0) in</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Time period (dt) in days (86400 seconds) between two UD</source> <translation>Periodo di tempo (dt) in giorni (86400 secondi) tra due DU</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Number of blocks used for calculating median time</source> <translation>Numero di blocchi utilizzati per calcolare il tempo medio</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The average time in seconds for writing 1 block (wished time)</source> <translation>Il tempo medio in secondi per la scrittura di 1 blocco (tempo desiderato)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of blocks required to evaluate again PoWMin value</source> <translation>Il numero di blocchi necessari per valutare il valore di nuovo PoWMin</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of previous blocks to check for personalized difficulty</source> <translation>Il numero di blocchi precedenti per verificare la presenza di difficoltà personalizzata</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The percent of previous issuers to reach for personalized difficulty</source> <translation>La percentuale di emittenti precedenti che arrivano à una difficoltà personalizzata</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1259,7 +1500,7 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1271,37 +1512,37 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum delay between 2 identical certifications (in days)</source> - <translation>Ritardo minimo tra 2 certificazioni identici (in giorni)</translation> + <translation type="obsolete">Ritardo minimo tra 2 certificazioni identici (in giorni)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid signature (in days)</source> <translation>Età massima di una firma valida (in giorni)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Minimum quantity of signatures to be part of the WoT</source> <translation>Quantità minima di firme per far parte della RdF</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum quantity of valid made certifications to be part of the WoT for distance rule</source> - <translation>Quantità minima di certificazioni fatte validi a far parte della RdF per regola di distanza</translation> + <translation type="obsolete">Quantità minima di certificazioni fatte validi a far parte della RdF per regola di distanza</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid membership (in days)</source> <translation>Età massima di un abbonamento valido (in giorni)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum distance between each WoT member and a newcomer</source> <translation>Distanza massima tra ogni membro RdF e un nuovo arrivato</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> @@ -1317,7 +1558,7 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Penultimate UD date and time (t-1)</source> <translation type="unfinished"></translation> </message> @@ -1327,25 +1568,61 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Name</source> <translation type="unfinished">Nome</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Units</source> <translation type="unfinished">Unità</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Formula</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Description</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum delay between 2 certifications (in days)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum quantity of active certifications made by member.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum delay a certification can wait before being expired for non-writing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum percent of sentries to reach to match the distance rule</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>MainWindow</name> @@ -1355,7 +1632,7 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="unfinished">&File</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="131"/> + <location filename="../../ui/mainwindow.ui" line="138"/> <source>Account</source> <translation>Conto</translation> </message> @@ -1375,12 +1652,12 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation>&Aiuto</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="76"/> + <location filename="../../ui/mainwindow.ui" line="83"/> <source>Manage accounts</source> <translation>Gesta i conti</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="81"/> + <location filename="../../ui/mainwindow.ui" line="88"/> <source>Configure trustable nodes</source> <translation>Configura nodi affidabili</translation> </message> @@ -1390,47 +1667,47 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="obsolete">&Aggiungi un contatto</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="106"/> + <location filename="../../ui/mainwindow.ui" line="113"/> <source>Send a message</source> <translation>Invia un messagio</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="111"/> + <location filename="../../ui/mainwindow.ui" line="118"/> <source>Send money</source> <translation>Invia denaro</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="116"/> + <location filename="../../ui/mainwindow.ui" line="123"/> <source>Remove contact</source> <translation>Elimina contatto</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="121"/> + <location filename="../../ui/mainwindow.ui" line="128"/> <source>Save</source> <translation>Salva</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="126"/> + <location filename="../../ui/mainwindow.ui" line="133"/> <source>&Quit</source> <translation>&Abbandona</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="136"/> + <location filename="../../ui/mainwindow.ui" line="143"/> <source>&Transfer money</source> <translation>&Trasferi denaro</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="141"/> + <location filename="../../ui/mainwindow.ui" line="148"/> <source>&Configure</source> <translation>&Configura</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="146"/> + <location filename="../../ui/mainwindow.ui" line="153"/> <source>&Import</source> <translation>&Importa</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="151"/> + <location filename="../../ui/mainwindow.ui" line="158"/> <source>&Export</source> <translation>&Exporta</translation> </message> @@ -1440,32 +1717,32 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="obsolete">&Certificazione</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="161"/> + <location filename="../../ui/mainwindow.ui" line="168"/> <source>&Set as default</source> <translation>&Imposta come predefinito</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="166"/> + <location filename="../../ui/mainwindow.ui" line="173"/> <source>A&bout</source> <translation>A proposito</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="171"/> + <location filename="../../ui/mainwindow.ui" line="178"/> <source>&Preferences</source> <translation>&Preferences</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="176"/> + <location filename="../../ui/mainwindow.ui" line="183"/> <source>&Add account</source> <translation>&Aggiungi conto</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="211"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="285"/> <source>Latest release : {version}</source> <translation>Ultima versione : {version}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="218"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="292"/> <source>Download link</source> <translation>Link per scaricare</translation> </message> @@ -1505,17 +1782,17 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="251"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="326"/> <source>Please get the latest release {version}</source> <translation type="unfinished">Si prega di ottenere l'ultimo rilascio {version}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="283"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="358"/> <source>Edit</source> <translation>Modifica</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="286"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="361"/> <source>Delete</source> <translation>Cancella</translation> </message> @@ -1530,17 +1807,17 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="obsolete">CuteCoin {0} - Conto : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="348"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="424"/> <source>Export an account</source> <translation>Exporta un conto</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="349"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="425"/> <source>All account files (*.acc)</source> <translation>Tutti i file di account (* .acc)</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="350"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="426"/> <source>Export</source> <translation>Exporta</translation> </message> @@ -1555,21 +1832,42 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="86"/> + <location filename="../../ui/mainwindow.ui" line="93"/> <source>A&dd a contact</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="156"/> + <location filename="../../ui/mainwindow.ui" line="163"/> <source>C&ertification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="225"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="383"/> + <source>sakia {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="407"/> + <source>sakia {0} - Account : {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="71"/> + <source>&Duniter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="188"/> + <source>&Manage local node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="299"/> <source> <h1>sakia</h1> - <p>Python/Qt uCoin client</p> + <p>Python/Qt duniter client</p> + <p><a href="https://github.com/duniter/sakia">https://github.com/duniter/sakia</a></p> <p>Version : {:}</p> {new_version_text} @@ -1585,21 +1883,11 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl </source> <translation type="unfinished"></translation> </message> - <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="303"/> - <source>sakia {0}</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="330"/> - <source>sakia {0} - Account : {1}</source> - <translation type="unfinished"></translation> - </message> </context> <context> <name>MemberDialog</name> <message> - <location filename="../../../src/sakia/gui/member.py" line="46"/> + <location filename="../../../src/sakia/gui/member.py" line="73"/> <source>not a member</source> <translation>non un membro</translation> </message> @@ -1610,100 +1898,133 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> </translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Public key</source> <translation>Chiave pubblica</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Join date</source> <translation>Data di iscrizione</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="87"/> + <location filename="../../../src/sakia/gui/member.py" line="144"/> <source><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></source> <translation><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="73"/> + <location filename="../../../src/sakia/gui/member.py" line="130"/> <source>Distance</source> <translation>Distanza</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="80"/> + <location filename="../../../src/sakia/gui/member.py" line="139"/> <source>Path</source> <translation>Percorso</translation> </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="92"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="97"/> + <source>UID Published on</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MemberView</name> + <message> + <location filename="../../ui/member.ui" line="14"/> + <source>Member informations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/member.ui" line="34"/> + <source>Member</source> + <translation type="unfinished">Membro</translation> + </message> </context> <context> <name>NetworkFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="48"/> + <location filename="../../../src/sakia/models/network.py" line="54"/> <source>Address</source> <translation>Indirizzo</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="49"/> + <location filename="../../../src/sakia/models/network.py" line="55"/> <source>Port</source> <translation>Porto</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="50"/> + <location filename="../../../src/sakia/models/network.py" line="56"/> <source>Block</source> <translation>Blocca</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="52"/> + <location filename="../../../src/sakia/models/network.py" line="59"/> <source>UID</source> <translation>IDU</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="53"/> + <location filename="../../../src/sakia/models/network.py" line="60"/> <source>Member</source> <translation>Membro</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="54"/> + <location filename="../../../src/sakia/models/network.py" line="61"/> <source>Pubkey</source> <translation>Chiave pubblica</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="55"/> + <location filename="../../../src/sakia/models/network.py" line="62"/> <source>Software</source> <translation>Software</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="56"/> + <location filename="../../../src/sakia/models/network.py" line="63"/> <source>Version</source> <translation>Versione</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>yes</source> <translation>si</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>no</source> <translation>no</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>offline</source> <translation>offline</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="51"/> + <location filename="../../../src/sakia/models/network.py" line="57"/> <source>Hash</source> <translation>Hash</translation> </message> + <message> + <location filename="../../../src/sakia/models/network.py" line="58"/> + <source>Time</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>NetworkTabWidget</name> @@ -1713,17 +2034,17 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation>Formulario</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="70"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="72"/> <source>Unset root node</source> <translation>Annulla il nodo principale</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="76"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="78"/> <source>Set as root node</source> <translation>Impostato come nodo principale</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="82"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="84"/> <source>Open in browser</source> <translation>Apri nel browser</translation> </message> @@ -1731,26 +2052,34 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <context> <name>NetworkTableModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="136"/> + <location filename="../../../src/sakia/models/network.py" line="155"/> <source>Online</source> <translation>In linea</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="137"/> + <location filename="../../../src/sakia/models/network.py" line="156"/> <source>Offline</source> <translation>Offline</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="138"/> + <location filename="../../../src/sakia/models/network.py" line="157"/> <source>Unsynchronized</source> <translation>Non sincronizzato</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="139"/> + <location filename="../../../src/sakia/models/network.py" line="158"/> <source>Corrupted</source> <translation>Corrotto</translation> </message> </context> +<context> + <name>NodeManager</name> + <message> + <location filename="../../ui/node_manager.ui" line="14"/> + <source>Node manager</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>PasswordAskerDialog</name> <message> @@ -1769,22 +2098,22 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation>Ricorda la mia password durante questa sessione</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Bad password</source> <translation>Password errata</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Non printable characters in password</source> <translation>Caratteri non stampabili in password</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Failed to get private key</source> <translation>Impossibile ottenere la chiave privata</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Wrong password typed. Cannot open the private key</source> <translation>Password errata digitata. Impossibile aprire la chiave privata</translation> </message> @@ -1852,7 +2181,7 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation>Utilizzare Sistema Internazionale di Unità</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="329"/> + <location filename="../../ui/preferences.ui" line="356"/> <source><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Network settings</span></p></body></html></source> <translation><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Impostazioni di rete</span></p></body></html></translation> </message> @@ -1877,40 +2206,45 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="obsolete">SOCK65</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="345"/> + <location filename="../../ui/preferences.ui" line="372"/> <source>Proxy server address : </source> <translation>Indirizzo server proxy : </translation> </message> <message> - <location filename="../../ui/preferences.ui" line="355"/> + <location filename="../../ui/preferences.ui" line="382"/> <source>:</source> <translation>:</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="336"/> + <location filename="../../ui/preferences.ui" line="363"/> <source>Use a http proxy server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="379"/> + <location filename="../../ui/preferences.ui" line="406"/> <source>Automatically refresh identities informations</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/preferences.ui" line="330"/> + <source>Enable forgetfulness</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureAccount</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="163"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="165"/> <source>New account</source> <translation>Nuovo conto</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="170"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="175"/> <source>Configure {0}</source> <translation>Configura {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="185"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="190"/> <source>Ok</source> <translation>Ok</translation> </message> @@ -1925,7 +2259,7 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation type="obsolete">Queste chiave pubbliche parametri sono: {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> <source>Warning</source> <translation>Avvertimento</translation> </message> @@ -1935,36 +2269,44 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl Please note your key parameters (salt and password) if you wish to recover it later. Your account won't be removed from the networks it joined. Are you sure ?</source> - <translation>Questa azione eliminara il tuo conto localmente.↵ + <translation type="obsolete">Questa azione eliminara il tuo conto localmente.↵ Si prega di notare i tui parametri chiave (sale e password), se si vuole recuperarlo più tardi.↵ Il vostro conto non sarà rimosso dalle reti alle quali lui fu connettato.↵ sei sicuro ?</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="243"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="249"/> <source>Error</source> <translation>Errore</translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> + <source>This action will delete your account ({0}) locally. +Please note your key parameters (salt and password) if you wish to recover it later. +Your account won't be removed from the networks it joined. +Are you sure ?</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureCommunity</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="227"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="240"/> <source>Configure community {0}</source> <translation>Configura comunità {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="230"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="243"/> <source>Add a community</source> <translation>Aggiungi una comunità</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="264"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="276"/> <source>Error</source> <translation>Errore</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="293"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="305"/> <source>Delete</source> <translation>Elimina</translation> </message> @@ -2048,15 +2390,20 @@ Vuoi pubblicare la chiave?</translation> <translation type="unfinished">Quant somma-Z</translation> </message> <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="7"/> <source>{0} Q0 {1}</source> - <translation>{0} Q0 {1}</translation> + <translation type="obsolete">{0} Q0 {1}</translation> </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> <source>Q0 {0}</source> <translation>Q0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <source>{0} {1}Q0 {2}</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="10"/> <source>Z0 = Q - ( M(t-1) / N(t) ) @@ -2075,22 +2422,22 @@ Vuoi pubblicare la chiave?</translation> <context> <name>Relative</name> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="7"/> + <location filename="../../../src/sakia/core/money/relative.py" line="9"/> <source>UD</source> <translation type="unfinished">DU</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative.py" line="10"/> <source>{0} {1}UD {2}</source> <translation>{0} {1}DU {2}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="9"/> + <location filename="../../../src/sakia/core/money/relative.py" line="11"/> <source>UD {0}</source> <translation>DU {0}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="10"/> + <location filename="../../../src/sakia/core/money/relative.py" line="12"/> <source>R = Q / UD(t) <br > <table> @@ -2102,6 +2449,36 @@ Vuoi pubblicare la chiave?</translation> <translation type="unfinished"></translation> </message> </context> +<context> + <name>RelativeToPast</name> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="6"/> + <source>Past UD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="7"/> + <source>{0} {1}UD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="8"/> + <source>UD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Relative value</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RelativeZSum</name> <message> @@ -2110,15 +2487,20 @@ Vuoi pubblicare la chiave?</translation> <translation type="unfinished">Relat somma-Z</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="7"/> <source>{0} R0 {1}</source> - <translation>{0} R0 {1}</translation> + <translation type="obsolete">{0} R0 {1}</translation> </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> <source>R0 {0}</source> <translation>R0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <source>{0} {1}R0 {2}</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="10"/> <source>R0 = (R / UD(t)) - (( M(t-1) / N(t) ) / UD(t)) @@ -2139,33 +2521,51 @@ Vuoi pubblicare la chiave?</translation> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="158"/> <source>Certification expires at {0}</source> - <translation>La certificazione scade a {0}</translation> + <translation type="obsolete">La certificazione scade a {0}</translation> + </message> +</context> +<context> + <name>SearchUserWidget</name> + <message> + <location filename="../../ui/search_user_view.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Formulario</translation> + </message> + <message> + <location filename="../../ui/search_user_view.ui" line="33"/> + <source>Center the view on me</source> + <translation type="unfinished">Centrare la vista su di me</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/search_user.py" line="15"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished"></translation> </message> </context> <context> <name>StepPageInit</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="95"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="101"/> <source>Could not find your identity on the network.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="127"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> <source>Broadcasting identity...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>UID broadcast</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>Identity broadcasted to the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>Error</source> <translation type="unfinished">Errore</translation> </message> @@ -2175,27 +2575,42 @@ Vuoi pubblicare la chiave?</translation> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>{0}</source> <translation type="unfinished">{0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="153"/> <source>Your pubkey or UID was already found on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="145"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="156"/> <source>Your account already exists on the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="97"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="103"/> <source>Your pubkey or UID is different on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="124"/> + <source>connecting...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="164"/> + <source>Could not connect. Check hostname, ip address or port</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="162"/> + <source>Could not connect. Check node peering entry</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Toast</name> @@ -2235,57 +2650,57 @@ Yours : {0}, the network : {1}</source> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="175"/> <source>Actions</source> - <translation>Azioni</translation> + <translation type="obsolete">Azioni</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="190"/> <source>Send again</source> - <translation>Invia di nuovo</translation> + <translation type="obsolete">Invia di nuovo</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="195"/> <source>Cancel</source> - <translation>Annulla</translation> + <translation type="obsolete">Annulla</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="201"/> <source>Informations</source> - <translation>Informazioni</translation> + <translation type="obsolete">Informazioni</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="206"/> <source>Add as contact</source> - <translation>Aggiungi un contatto</translation> + <translation type="obsolete">Aggiungi un contatto</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="211"/> <source>Send money</source> - <translation>Invia denaro</translation> + <translation type="obsolete">Invia denaro</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="217"/> <source>View in Web of Trust</source> - <translation>Vedi in Rete della Fiducia</translation> + <translation type="obsolete">Vedi in Rete della Fiducia</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="222"/> <source>Copy pubkey to clipboard</source> - <translation>Copia chiave pubblica negli appunti</translation> + <translation type="obsolete">Copia chiave pubblica negli appunti</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Warning</source> - <translation>Avvertimento</translation> + <translation type="obsolete">Avvertimento</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Are you sure ? This money transfer will be removed and not sent.</source> - <translation>Sei sicuro? ↵ + <translation type="obsolete">Sei sicuro? ↵ Questo trasferimento di denaro sarà rimosso e non inviato.</translation> </message> <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="160"/> + <location filename="../../../src/sakia/gui/transactions_tab.py" line="159"/> <source>{:}</source> <translation type="unfinished">{:}</translation> </message> @@ -2318,37 +2733,37 @@ Questo trasferimento di denaro sarà rimosso e non inviato.</translation> <translation type="obsolete">Contatto</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="80"/> + <location filename="../../ui/transfer.ui" line="136"/> <source>Key</source> <translation>Chiave</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="148"/> + <location filename="../../ui/transfer.ui" line="250"/> <source> UD</source> <translation> DU</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="166"/> + <location filename="../../ui/transfer.ui" line="268"/> <source>Transaction message</source> <translation>Messaggio della transazione</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>Money transfer</source> <translation>Trasferimento del denaro</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>No amount. Please give the transfert amount</source> <translation>Nessun importo. Si prega di dare l'importo di trasferimento</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="139"/> + <location filename="../../../src/sakia/gui/transfer.py" line="163"/> <source>Transfer</source> <translation>Trasferi</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="126"/> + <location filename="../../../src/sakia/gui/transfer.py" line="150"/> <source>Success sending money to {0}</source> <translation>Successo l'invio di denaro a {0}</translation> </message> @@ -2363,30 +2778,35 @@ Questo trasferimento di denaro sarà rimosso e non inviato.</translation> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="61"/> + <location filename="../../ui/transfer.ui" line="95"/> <source>&Recipient public key</source> <translation>Chiave pubblica del destinatario</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="106"/> + <location filename="../../ui/transfer.ui" line="208"/> <source>Wallet</source> <translation>Portafoglio</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="125"/> + <location filename="../../ui/transfer.ui" line="227"/> <source>Available money : </source> <translation>Denaro disponibile : </translation> </message> <message> - <location filename="../../ui/transfer.ui" line="134"/> + <location filename="../../ui/transfer.ui" line="236"/> <source>Amount</source> <translation>Importo</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="40"/> + <location filename="../../ui/transfer.ui" line="46"/> <source>Con&tact</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/transfer.ui" line="156"/> + <source>S&earch user</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>TxFilterProxyModel</name> @@ -2401,16 +2821,48 @@ Questo trasferimento di denaro sarà rimosso e non inviato.</translation> <translation type="obsolete">Convalida... {0} %</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="165"/> + <location filename="../../../src/sakia/models/txhistory.py" line="166"/> <source>{0} / {1} confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="169"/> + <location filename="../../../src/sakia/models/txhistory.py" line="170"/> <source>Confirming... {0} %</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>UDDToPast</name> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="6"/> + <source>Past UUD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="7"/> + <source>{0} {1}UUD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="8"/> + <source>UUD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table>></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>WalletsTab</name> <message> @@ -2652,27 +3104,22 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <message> <location filename="../../../src/sakia/gui/views/wot.py" line="294"/> <source>Informations</source> - <translation>Informazioni</translation> + <translation type="obsolete">Informazioni</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="299"/> <source>Add as contact</source> - <translation>Aggiungi un contatto</translation> + <translation type="obsolete">Aggiungi un contatto</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="304"/> <source>Send money</source> - <translation>Invia denaro</translation> + <translation type="obsolete">Invia denaro</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="309"/> <source>Certify identity</source> - <translation>Certifica l'identità</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="314"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Certifica l'identità</translation> </message> </context> <context> @@ -2685,15 +3132,15 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <message> <location filename="../../ui/wot_tab.ui" line="33"/> <source>Center the view on me</source> - <translation>Centrare la vista su di me</translation> + <translation type="obsolete">Centrare la vista su di me</translation> </message> <message> <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> <source>Research a pubkey, an uid...</source> - <translation>Ricerca un chiave pubblica, un idu ...</translation> + <translation type="obsolete">Ricerca un chiave pubblica, un idu ...</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2701,7 +3148,7 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2710,32 +3157,27 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl </translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="126"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="122"/> <source>Membership</source> - <translation type="unfinished">Iscrizione</translation> + <translation type="obsolete">Iscrizione</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source>Last renewal on {:}, expiration on {:}</source> - <translation type="unfinished">Ultimo rinnovo il {:}, scadenza il {:}</translation> + <translation type="obsolete">Ultimo rinnovo il {:}, scadenza il {:}</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Your web of trust</source> - <translation type="unfinished">La tua rete della fiducia</translation> + <translation type="obsolete">La tua rete della fiducia</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Certified by {:} members; Certifier of {:} members</source> - <translation type="unfinished">Certificato da {}: membri; Certificatore di {}: membri</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source>Not a member</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Certificato da {}: membri; Certificatore di {}: membri</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2743,7 +3185,7 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td></tr> @@ -2752,35 +3194,129 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl </translation> </message> </context> +<context> + <name>certificationsTabWidget</name> + <message> + <location filename="../../ui/certifications_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Formulario</translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="20"/> + <source>Certifications</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="33"/> + <source>loading...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="63"/> + <source>dd/MM/yyyy</source> + <translation type="unfinished">dd/MM/yyyy</translation> + </message> +</context> +<context> + <name>menu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="57"/> + <source>Certify identity</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>menu.qmenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="42"/> + <source>Informations</source> + <translation type="unfinished">Informazioni</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="47"/> + <source>Add as contact</source> + <translation type="unfinished">Aggiungi un contatto</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="52"/> + <source>Send money</source> + <translation type="unfinished">Invia denaro</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="61"/> + <source>View in Web of Trust</source> + <translation type="unfinished">Vedi in Rete della Fiducia</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="65"/> + <source>Copy pubkey to clipboard</source> + <translation type="unfinished">Copia chiave pubblica negli appunti</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="70"/> + <source>Copy membership document to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="74"/> + <source>Copy self-certification document to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="84"/> + <source>Transfer</source> + <translation type="unfinished">Trasferi</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="86"/> + <source>Send again</source> + <translation type="unfinished">Invia di nuovo</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="90"/> + <source>Cancel</source> + <translation type="unfinished">Annulla</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="95"/> + <source>Copy raw transaction to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="100"/> + <source>Copy transaction block to clipboard</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>self.config_dialog</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="191"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="204"/> <source>Ok</source> <translation>Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="70"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="72"/> <source>Forbidden : salt is too short</source> <translation>Vietato: il "salt" è troppo corto</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="74"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="76"/> <source>Forbidden : password is too short</source> <translation>Forbidden: password è troppo corta</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="78"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="80"/> <source>Forbidden : Invalid characters in salt field</source> <translation>Vietato: caratteri non validi nel campo del "salt"</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="82"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="84"/> <source>Forbidden : Invalid characters in password field</source> <translation>Forbidden: caratteri non validi nel campo della password</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="88"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="90"/> <source>Error : passwords are different</source> <translation>Errore: password sono diverse</translation> </message> @@ -2793,7 +3329,7 @@ Revoca tuo UID può solo successo se non è già convalidato dalla rete.</transl <translation>Formulario</translation> </message> <message> - <location filename="../../ui/transactions_tab.ui" line="63"/> + <location filename="../../ui/transactions_tab.ui" line="66"/> <source>dd/MM/yyyy</source> <translation>dd/MM/yyyy</translation> </message> diff --git a/res/i18n/ts/pl_PL.ts b/res/i18n/ts/pl_PL.ts index c605cb79bad44e8e3f910b31952ee8cf5ccfb8e9..7150d5d67f22e5c385d054a08e11ee50e5d72ea1 100644 --- a/res/i18n/ts/pl_PL.ts +++ b/res/i18n/ts/pl_PL.ts @@ -16,10 +16,25 @@ <context> <name>Account</name> <message> - <location filename="../../../src/sakia/core/account.py" line="510"/> + <location filename="../../../src/sakia/core/account.py" line="540"/> <source>Could not find user self certification.</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="67"/> + <source>Warning : Your membership is expiring soon.</source> + <translation type="unfinished">Ostrzeżenie: Twoje członkostwo wygasa szybko.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="72"/> + <source>Warning : Your could miss certifications soon.</source> + <translation type="unfinished">Uwaga: Twój mogło zabraknąć certyfikaty wkrótce.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="77"/> + <source>Warning : If you don't renew soon, your identity will be considerd revoked.</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AccountConfigurationDialog</name> @@ -56,7 +71,7 @@ <message> <location filename="../../ui/account_cfg.ui" line="143"/> <source>CryptoID</source> - <translation>KryptoID / Sól</translation> + <translation type="obsolete">KryptoID / Sól</translation> </message> <message> <location filename="../../ui/account_cfg.ui" line="153"/> @@ -98,49 +113,54 @@ <source>Communities</source> <translation>Społeczności</translation> </message> + <message> + <location filename="../../ui/account_cfg.ui" line="143"/> + <source>Entropy</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Application</name> <message> <location filename="../../../src/sakia/core/app.py" line="76"/> <source>Warning : Your membership is expiring soon.</source> - <translation type="unfinished">Ostrzeżenie: Twoje członkostwo wygasa szybko.</translation> + <translation type="obsolete">Ostrzeżenie: Twoje członkostwo wygasa szybko.</translation> </message> <message> <location filename="../../../src/sakia/core/app.py" line="81"/> <source>Warning : Your could miss certifications soon.</source> - <translation type="unfinished">Uwaga: Twój mogło zabraknąć certyfikaty wkrótce.</translation> + <translation type="obsolete">Uwaga: Twój mogło zabraknąć certyfikaty wkrótce.</translation> </message> </context> <context> <name>CertificationDialog</name> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Certification</source> <translation>Certyfikacja</translation> </message> <message> - <location filename="../../ui/certification.ui" line="20"/> + <location filename="../../ui/certification.ui" line="26"/> <source>Community</source> <translation>Społeczność</translation> </message> <message> - <location filename="../../ui/certification.ui" line="32"/> + <location filename="../../ui/certification.ui" line="54"/> <source>Certify user</source> <translation type="unfinished">Zaświadczyć użytkownika</translation> </message> <message> <location filename="../../ui/certification.ui" line="40"/> <source>Contact</source> - <translation>Kontakt</translation> + <translation type="obsolete">Kontakt</translation> </message> <message> <location filename="../../ui/certification.ui" line="61"/> <source>User public key</source> - <translation>Użytkownik klucz publiczny</translation> + <translation type="obsolete">Użytkownik klucz publiczny</translation> </message> <message> - <location filename="../../ui/certification.ui" line="80"/> + <location filename="../../ui/certification.ui" line="157"/> <source>Key</source> <translation>Klucz</translation> </message> @@ -165,25 +185,75 @@ <translation type="obsolete">Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="112"/> + <location filename="../../../src/sakia/gui/certification.py" line="227"/> <source>Not a member</source> <translation>Nie jest członkiem</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="109"/> + <location filename="../../../src/sakia/gui/certification.py" line="221"/> <source>&Ok</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="75"/> + <location filename="../../../src/sakia/gui/certification.py" line="126"/> <source>Success sending certification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Could not broadcast certification : {0}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/certification.ui" line="73"/> + <source>Con&tact</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="116"/> + <source>&User public key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="35"/> + <source>Certifications stock</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="177"/> + <source>Sea&rch user</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="197"/> + <source>Certifications sent : {nb_certifications}/{stock}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="206"/> + <source>{days} days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="208"/> + <source>{hours} hours and {min} min.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="210"/> + <source>Remaining time before next certification validation : {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="217"/> + <source> (Not validated before </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="224"/> + <source>No more certifications</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityConfigurationDialog</name> @@ -218,17 +288,17 @@ <translation>Serwer</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="200"/> + <location filename="../../ui/community_cfg.ui" line="203"/> <source>Add</source> <translation>Dodać</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="221"/> + <location filename="../../ui/community_cfg.ui" line="224"/> <source>Previous</source> <translation>Poprzedni</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="244"/> + <location filename="../../ui/community_cfg.ui" line="247"/> <source>Next</source> <translation>Następny</translation> </message> @@ -314,45 +384,80 @@ <context> <name>CommunityTile</name> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="81"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Member</source> <translation type="unfinished">Członek</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="82"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Non-Member</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>members</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Monetary mass</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Balance</source> <translation type="unfinished">Równowaga</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="112"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="162"/> <source>Not connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="125"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="175"/> <source>Community not initialized</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="100"/> + <source>Expired or never published</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="101"/> + <source>Outdistanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="110"/> + <source>In WoT range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="116"/> + <source>Expires in </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="124"/> + <source>#FF0000</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Certs. received</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Membership</source> + <translation type="unfinished">Członkostwo</translation> + </message> </context> <context> <name>CommunityWidget</name> @@ -372,7 +477,7 @@ <translation type="unfinished">Certyfikacja</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="289"/> + <location filename="../../../src/sakia/gui/community_view.py" line="286"/> <source>Renew membership</source> <translation type="unfinished">Odnów członkostwo</translation> </message> @@ -387,62 +492,57 @@ <translation type="obsolete">Uwaga: Twój mogło zabraknąć certyfikaty wkrótce.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="34"/> + <location filename="../../../src/sakia/gui/community_view.py" line="33"/> <source>Transactions</source> <translation type="unfinished">Transakcje</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <location filename="../../../src/sakia/gui/community_view.py" line="34"/> <source>Web of Trust</source> <translation type="unfinished">Sieć Zaufania</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="37"/> + <location filename="../../../src/sakia/gui/community_view.py" line="90"/> <source>Network</source> <translation type="unfinished">Sieć</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source>Membership expiration</source> <translation type="unfinished">Wygaśnięcie członkostwa</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source><b>Warning : Membership expiration in {0} days</b></source> <translation type="unfinished"><b>Uwaga : Wygaśnięcie członkostwa w {0} dni</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source>Certifications number</source> <translation type="unfinished">Numer Certyfikaty</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source><b>Warning : You are certified by only {0} persons, need {1}</b></source> <translation type="unfinished"><b>Ostrzeżenie : certyfikowane przez zaledwie {0} osób, potrzebuję {1}</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="228"/> + <location filename="../../../src/sakia/gui/community_view.py" line="235"/> <source> Block {0}</source> - <translation type="unfinished"> Blok {0}</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/community_view.py" line="270"/> - <source> - Median fork window : {0}</source> - <translation type="unfinished"></translation> + <translation type="obsolete"> Blok {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="295"/> + <location filename="../../../src/sakia/gui/community_view.py" line="292"/> <source>Send membership demand</source> <translation type="unfinished">Wyślij popytu członkostwa</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Warning</source> <translation type="unfinished">Ostrzeżenie</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Are you sure ? Sending a leaving demand cannot be canceled. The process to join back the community later will have to be done again.</source> @@ -463,7 +563,7 @@ Publikowanie UID może zostać anulowane przez odwołaniu UID.</translation> <translation type="obsolete">UID wydawnictwa</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="375"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Success publishing your UID</source> <translation type="unfinished">Sukces publikowanie UID</translation> </message> @@ -495,32 +595,32 @@ Revoking your UID can only success if it is not already validated by the network Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez sieć.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Membership</source> <translation type="unfinished">Członkostwo</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="329"/> + <location filename="../../../src/sakia/gui/community_view.py" line="325"/> <source>Success sending Membership demand</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="361"/> + <location filename="../../../src/sakia/gui/community_view.py" line="356"/> <source>Revoke</source> <translation type="unfinished">Odwołać</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="355"/> + <location filename="../../../src/sakia/gui/community_view.py" line="350"/> <source>Success sending Revoke demand</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <location filename="../../../src/sakia/gui/community_view.py" line="94"/> <source>Show informations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="38"/> + <location filename="../../../src/sakia/gui/community_view.py" line="95"/> <source>Informations</source> <translation type="unfinished"></translation> </message> @@ -530,23 +630,38 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="unfinished">Opublikować UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="399"/> + <location filename="../../../src/sakia/gui/community_view.py" line="41"/> <source>Revoke UID</source> <translation type="unfinished">Odwołać UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="401"/> + <location filename="../../../src/sakia/gui/community_view.py" line="375"/> <source>UID</source> <translation type="unfinished">UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> - <source>Your UID was revoked successfully.</source> + <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <source>Search Identities</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="36"/> - <source>Search Identities</source> + <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <source>Explore the Web of Trust</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="99"/> + <source>Show explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="100"/> + <source>Explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="234"/> + <source>Block {0}</source> <translation type="unfinished"></translation> </message> </context> @@ -568,11 +683,26 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation>Klucz publiczny</translation> </message> <message> - <location filename="../../../src/sakia/gui/contact.py" line="52"/> + <location filename="../../../src/sakia/gui/contact.py" line="81"/> <source>Contact already exists</source> <translation>Kontakt już istnieje</translation> </message> </context> +<context> + <name>ContextMenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Warning</source> + <translation type="unfinished">Ostrzeżenie</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Are you sure ? +This money transfer will be removed and not sent.</source> + <translation type="unfinished">Jesteś pewny ? +Ten przelew zostanie usunięty i nie wysłał.</translation> + </message> +</context> <context> <name>CreateWalletDialog</name> <message> @@ -669,48 +799,159 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <message> <location filename="../../ui/member.ui" line="14"/> <source>Informations</source> - <translation>Informacja</translation> + <translation type="obsolete">Informacja</translation> </message> <message> <location filename="../../ui/member.ui" line="34"/> <source>Member</source> - <translation>Członek</translation> + <translation type="obsolete">Członek</translation> </message> <message> <location filename="../../ui/member.ui" line="65"/> <source>uid</source> - <translation>uid</translation> + <translation type="obsolete">uid</translation> </message> <message> <location filename="../../ui/member.ui" line="72"/> <source>properties</source> - <translation type="unfinished">właściwości</translation> + <translation type="obsolete">właściwości</translation> + </message> +</context> +<context> + <name>DividendPerDay</name> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="9"/> + <source>UDD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="10"/> + <source>{0} {1}UDD {2}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="11"/> + <source>UDD {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="12"/> + <source>UDD(t) = (Q * 100) / (UD(t) / DT) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>ExplorerTabWidget</name> + <message> + <location filename="../../ui/explorer_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Forma</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="48"/> + <source>Steps</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="65"/> + <source>Go</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>GraphTabWidget</name> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="71"/> + <source>Membership</source> + <translation type="unfinished">Członkostwo</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source>Last renewal on {:}, expiration on {:}</source> + <translation type="unfinished">Ostatni odnowienia na {:}, wygaśnięciu z dniem {:}</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Your web of trust</source> + <translation type="unfinished">Twój sieć zaufania</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Certified by {:} members; Certifier of {:} members</source> + <translation type="unfinished">Certyfikowany przez {:} członków; Certifier z {:} członków</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Not a member</source> + <translation type="unfinished">Nie jest członkiem</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </translation> </message> </context> <context> <name>HistoryTableModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Date</source> <translation>Data</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>UID/Public key</source> <translation>UID/Klucz publiczny</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Payment</source> <translation>Płatność</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Deposit</source> <translation>Kaucja</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Comment</source> <translation>Uwaga</translation> </message> @@ -827,73 +1068,63 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="36"/> <source>Members</source> - <translation type="unfinished">Członek</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="37"/> - <source>Direct connections</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="112"/> - <source>Informations</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Członek</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="115"/> <source>Add as contact</source> - <translation type="unfinished">Dodaj jako kontakt</translation> + <translation type="obsolete">Dodaj jako kontakt</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="119"/> <source>Send money</source> - <translation type="unfinished">Wyślij pieniądze</translation> + <translation type="obsolete">Wyślij pieniądze</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="123"/> <source>Certify identity</source> - <translation type="unfinished">Poświadcza tożsamość</translation> + <translation type="obsolete">Poświadcza tożsamość</translation> </message> <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="127"/> - <source>View in Web of Trust</source> + <location filename="../../../src/sakia/gui/identities_tab.py" line="32"/> + <source>Search direct certifications</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="131"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <location filename="../../../src/sakia/gui/identities_tab.py" line="33"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Badania klucz publiczny, uid...</translation> </message> </context> <context> <name>IdentitiesTableModel</name> <message> - <location filename="../../../src/sakia/models/identities.py" line="89"/> + <location filename="../../../src/sakia/models/identities.py" line="118"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="90"/> + <location filename="../../../src/sakia/models/identities.py" line="119"/> <source>Pubkey</source> <translation>Klucz publiczny</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="91"/> + <location filename="../../../src/sakia/models/identities.py" line="120"/> <source>Renewed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="92"/> + <location filename="../../../src/sakia/models/identities.py" line="121"/> <source>Expiration</source> <translation type="unfinished">Wygaśnięcie</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="94"/> + <location filename="../../../src/sakia/models/identities.py" line="123"/> <source>Validation</source> <translation>Walidacja</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="93"/> + <location filename="../../../src/sakia/models/identities.py" line="122"/> <source>Publication</source> <translation type="unfinished"></translation> </message> @@ -1029,47 +1260,47 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Universal Dividend UD(t) in</source> <translation>Uniwersalny Dywidendy UD(t) w</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass M(t-1) in</source> <translation>Podaż Pieniądza M(t-1) w</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Members N(t)</source> <translation>Członkowie N(t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass per member M(t-1)/N(t) in</source> <translation>Podaż Pieniądza na członka M(t-1)/N(t) w</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Actual growth c = UD(t)/[M(t-1)/N(t)]</source> <translation>Rzeczywisty wzrost c = UD(t)/[M(t-1)/N(t)]</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Last UD date and time (t)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Next UD date and time (t+1)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="194"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="196"/> <source>No Universal Dividend created yet.</source> <translation type="unfinished">Nie masz jeszcze Uniwersalny dywidendy stworzył.</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1086,37 +1317,37 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:2.0%} / {:} days</source> <translation>{:2.0%} / {:} dni</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Fundamental growth (c) / Delta time (dt)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</source> <translation>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (formula)</source> <translation>Uniwersalny Dywidendy (formuła)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</source> <translation>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (computed)</source> <translation>Uniwersalny Dywidendy (obliczana)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> @@ -1143,47 +1374,47 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Fundamental growth (c)</source> <translation type="unfinished">Podstawowym wzrostu (c)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Initial Universal Dividend UD(0) in</source> <translation>Uniwersalny Dywidendy początkowa UD(0) w</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Time period (dt) in days (86400 seconds) between two UD</source> <translation>Okres czasu (dt) w dni (86400 sekund) między dwoma UD</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Number of blocks used for calculating median time</source> <translation type="unfinished">Liczba bloków stosowane do obliczania mediany czasu</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The average time in seconds for writing 1 block (wished time)</source> <translation>Średni czas w sekundach do pisania 1 blok (szkoda czasu)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of blocks required to evaluate again PoWMin value</source> <translation type="unfinished">Liczba bloków wymagane do oceny wartości ponownie PoWMin</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of previous blocks to check for personalized difficulty</source> <translation>Liczba poprzednich bloków, aby sprawdzić indywidualną trudności</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The percent of previous issuers to reach for personalized difficulty</source> <translation type="unfinished">Procent poprzednich emitentów dotrzeć do spersonalizowanej trudności</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1194,7 +1425,7 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1206,37 +1437,37 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum delay between 2 identical certifications (in days)</source> - <translation>Minimalne opóźnienie między 2 identycznych certyfikatów (w dniach)</translation> + <translation type="obsolete">Minimalne opóźnienie między 2 identycznych certyfikatów (w dniach)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid signature (in days)</source> <translation>Maksymalny wiek ważnego podpisu (w dniach)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Minimum quantity of signatures to be part of the WoT</source> <translation>Minimalna ilość podpisów, aby być częścią WoT</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum quantity of valid made certifications to be part of the WoT for distance rule</source> - <translation type="unfinished">Minimalna ilość ważnych zaświadczeń wydanych być częścią WoT dla rządów odległości</translation> + <translation type="obsolete">Minimalna ilość ważnych zaświadczeń wydanych być częścią WoT dla rządów odległości</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid membership (in days)</source> <translation>Maksymalny wiek ważnego członkostwa (w dniach)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum distance between each WoT member and a newcomer</source> <translation type="unfinished">La distance maximale entre les membres individuels de la WOT et novice</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> @@ -1252,7 +1483,7 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Penultimate UD date and time (t-1)</source> <translation type="unfinished"></translation> </message> @@ -1262,25 +1493,61 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Name</source> <translation type="unfinished">Imię</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Units</source> <translation type="unfinished">Jednostki</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Formula</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Description</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum delay between 2 certifications (in days)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum quantity of active certifications made by member.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum delay a certification can wait before being expired for non-writing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum percent of sentries to reach to match the distance rule</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>MainWindow</name> @@ -1290,7 +1557,7 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="unfinished">Plik</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="131"/> + <location filename="../../ui/mainwindow.ui" line="138"/> <source>Account</source> <translation>Konto</translation> </message> @@ -1310,12 +1577,12 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation>&Pomoc</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="76"/> + <location filename="../../ui/mainwindow.ui" line="83"/> <source>Manage accounts</source> <translation>Zarządzanie kontami</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="81"/> + <location filename="../../ui/mainwindow.ui" line="88"/> <source>Configure trustable nodes</source> <translation>Skonfiguruj zaufanych węzłów</translation> </message> @@ -1325,47 +1592,47 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="obsolete">&Dodawanie kontaktu</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="106"/> + <location filename="../../ui/mainwindow.ui" line="113"/> <source>Send a message</source> <translation>Wyślij wiadomość</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="111"/> + <location filename="../../ui/mainwindow.ui" line="118"/> <source>Send money</source> <translation>Wyślij pieniądze</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="116"/> + <location filename="../../ui/mainwindow.ui" line="123"/> <source>Remove contact</source> <translation>Usuń kontakt</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="121"/> + <location filename="../../ui/mainwindow.ui" line="128"/> <source>Save</source> <translation>Zapisz</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="126"/> + <location filename="../../ui/mainwindow.ui" line="133"/> <source>&Quit</source> <translation type="unfinished">&Zamknij</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="136"/> + <location filename="../../ui/mainwindow.ui" line="143"/> <source>&Transfer money</source> <translation type="unfinished">&Przelać pieniądze</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="141"/> + <location filename="../../ui/mainwindow.ui" line="148"/> <source>&Configure</source> <translation type="unfinished">&Skonfiguruj</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="146"/> + <location filename="../../ui/mainwindow.ui" line="153"/> <source>&Import</source> <translation>&Import</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="151"/> + <location filename="../../ui/mainwindow.ui" line="158"/> <source>&Export</source> <translation>&Eksport</translation> </message> @@ -1375,32 +1642,32 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="obsolete">&Certyfikacja</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="161"/> + <location filename="../../ui/mainwindow.ui" line="168"/> <source>&Set as default</source> <translation>&Ustaw jako domyślne</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="166"/> + <location filename="../../ui/mainwindow.ui" line="173"/> <source>A&bout</source> <translation type="unfinished">&O</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="171"/> + <location filename="../../ui/mainwindow.ui" line="178"/> <source>&Preferences</source> <translation type="unfinished">&Preferencje</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="176"/> + <location filename="../../ui/mainwindow.ui" line="183"/> <source>&Add account</source> <translation>&Dodaj konto</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="211"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="285"/> <source>Latest release : {version}</source> <translation>Najnowsze wydanie: {wersja}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="218"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="292"/> <source>Download link</source> <translation>Link do pobrania</translation> </message> @@ -1440,17 +1707,17 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="251"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="326"/> <source>Please get the latest release {version}</source> <translation>Proszę pobrać najnowsze wydanie {wersja}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="283"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="358"/> <source>Edit</source> <translation>Edycja</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="286"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="361"/> <source>Delete</source> <translation>Kasować</translation> </message> @@ -1465,17 +1732,17 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="obsolete">CuteCoin {0} - Konto : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="348"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="424"/> <source>Export an account</source> <translation>Eksportować konto</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="349"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="425"/> <source>All account files (*.acc)</source> <translation type="unfinished">Pliki konto (*.acc)</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="350"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="426"/> <source>Export</source> <translation>Eksport</translation> </message> @@ -1490,21 +1757,42 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="86"/> + <location filename="../../ui/mainwindow.ui" line="93"/> <source>A&dd a contact</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="156"/> + <location filename="../../ui/mainwindow.ui" line="163"/> <source>C&ertification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="225"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="383"/> + <source>sakia {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="407"/> + <source>sakia {0} - Account : {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="71"/> + <source>&Duniter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="188"/> + <source>&Manage local node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="299"/> <source> <h1>sakia</h1> - <p>Python/Qt uCoin client</p> + <p>Python/Qt duniter client</p> + <p><a href="https://github.com/duniter/sakia">https://github.com/duniter/sakia</a></p> <p>Version : {:}</p> {new_version_text} @@ -1520,21 +1808,11 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez </source> <translation type="unfinished"></translation> </message> - <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="303"/> - <source>sakia {0}</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="330"/> - <source>sakia {0} - Account : {1}</source> - <translation type="unfinished"></translation> - </message> </context> <context> <name>MemberDialog</name> <message> - <location filename="../../../src/sakia/gui/member.py" line="46"/> + <location filename="../../../src/sakia/gui/member.py" line="73"/> <source>not a member</source> <translation>nie jest członkiem</translation> </message> @@ -1545,100 +1823,133 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> </translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Public key</source> <translation>Klucz publiczny</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Join date</source> <translation>Data rejestracji</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="87"/> + <location filename="../../../src/sakia/gui/member.py" line="144"/> <source><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></source> <translation><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="73"/> + <location filename="../../../src/sakia/gui/member.py" line="130"/> <source>Distance</source> <translation>Dystans</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="80"/> + <location filename="../../../src/sakia/gui/member.py" line="139"/> <source>Path</source> <translation>ścieżka</translation> </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="92"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="97"/> + <source>UID Published on</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MemberView</name> + <message> + <location filename="../../ui/member.ui" line="14"/> + <source>Member informations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/member.ui" line="34"/> + <source>Member</source> + <translation type="unfinished">Członek</translation> + </message> </context> <context> <name>NetworkFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="48"/> + <location filename="../../../src/sakia/models/network.py" line="54"/> <source>Address</source> <translation>Adres</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="49"/> + <location filename="../../../src/sakia/models/network.py" line="55"/> <source>Port</source> <translation>Port</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="50"/> + <location filename="../../../src/sakia/models/network.py" line="56"/> <source>Block</source> <translation>Blok</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="52"/> + <location filename="../../../src/sakia/models/network.py" line="59"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="53"/> + <location filename="../../../src/sakia/models/network.py" line="60"/> <source>Member</source> <translation>Członek</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="54"/> + <location filename="../../../src/sakia/models/network.py" line="61"/> <source>Pubkey</source> <translation>Klucz publiczny</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="55"/> + <location filename="../../../src/sakia/models/network.py" line="62"/> <source>Software</source> <translation>Oprogramowanie</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="56"/> + <location filename="../../../src/sakia/models/network.py" line="63"/> <source>Version</source> <translation>Wersja</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>yes</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>no</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>offline</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="51"/> + <location filename="../../../src/sakia/models/network.py" line="57"/> <source>Hash</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/models/network.py" line="58"/> + <source>Time</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>NetworkTabWidget</name> @@ -1648,17 +1959,17 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="unfinished">Forma</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="70"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="72"/> <source>Unset root node</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="76"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="78"/> <source>Set as root node</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="82"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="84"/> <source>Open in browser</source> <translation type="unfinished"></translation> </message> @@ -1666,26 +1977,34 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <context> <name>NetworkTableModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="136"/> + <location filename="../../../src/sakia/models/network.py" line="155"/> <source>Online</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="137"/> + <location filename="../../../src/sakia/models/network.py" line="156"/> <source>Offline</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="138"/> + <location filename="../../../src/sakia/models/network.py" line="157"/> <source>Unsynchronized</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="139"/> + <location filename="../../../src/sakia/models/network.py" line="158"/> <source>Corrupted</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>NodeManager</name> + <message> + <location filename="../../ui/node_manager.ui" line="14"/> + <source>Node manager</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>PasswordAskerDialog</name> <message> @@ -1704,22 +2023,22 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Bad password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Non printable characters in password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Failed to get private key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Wrong password typed. Cannot open the private key</source> <translation type="unfinished"></translation> </message> @@ -1782,45 +2101,50 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="329"/> + <location filename="../../ui/preferences.ui" line="356"/> <source><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Network settings</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="345"/> + <location filename="../../ui/preferences.ui" line="372"/> <source>Proxy server address : </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="355"/> + <location filename="../../ui/preferences.ui" line="382"/> <source>:</source> <translation>:</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="336"/> + <location filename="../../ui/preferences.ui" line="363"/> <source>Use a http proxy server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="379"/> + <location filename="../../ui/preferences.ui" line="406"/> <source>Automatically refresh identities informations</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/preferences.ui" line="330"/> + <source>Enable forgetfulness</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureAccount</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="163"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="165"/> <source>New account</source> <translation>Nowe konto</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="170"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="175"/> <source>Configure {0}</source> <translation>Skonfiguruj {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="185"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="190"/> <source>Ok</source> <translation>Ok</translation> </message> @@ -1830,43 +2154,43 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation type="obsolete">Klucz publiczny</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> <source>Warning</source> <translation type="unfinished">Ostrzeżenie</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> - <source>This action will delete your account locally. + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="249"/> + <source>Error</source> + <translation>Błąd</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> + <source>This action will delete your account ({0}) locally. Please note your key parameters (salt and password) if you wish to recover it later. Your account won't be removed from the networks it joined. Are you sure ?</source> <translation type="unfinished"></translation> </message> - <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="243"/> - <source>Error</source> - <translation>Błąd</translation> - </message> </context> <context> <name>ProcessConfigureCommunity</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="227"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="240"/> <source>Configure community {0}</source> <translation>Skonfiguruj społeczności {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="230"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="243"/> <source>Add a community</source> <translation>Dodać społeczności</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="264"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="276"/> <source>Error</source> <translation>Błąd</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="293"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="305"/> <source>Delete</source> <translation>Kasować</translation> </message> @@ -1930,13 +2254,13 @@ Chciałbyś opublikować klucz ?</translation> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> - <source>{0} Q0 {1}</source> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> + <source>Q0 {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> - <source>Q0 {0}</source> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <source>{0} {1}Q0 {2}</source> <translation type="unfinished"></translation> </message> <message> @@ -1957,22 +2281,22 @@ Chciałbyś opublikować klucz ?</translation> <context> <name>Relative</name> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="7"/> + <location filename="../../../src/sakia/core/money/relative.py" line="9"/> <source>UD</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative.py" line="10"/> <source>{0} {1}UD {2}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="9"/> + <location filename="../../../src/sakia/core/money/relative.py" line="11"/> <source>UD {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="10"/> + <location filename="../../../src/sakia/core/money/relative.py" line="12"/> <source>R = Q / UD(t) <br > <table> @@ -1984,6 +2308,36 @@ Chciałbyś opublikować klucz ?</translation> <translation type="unfinished"></translation> </message> </context> +<context> + <name>RelativeToPast</name> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="6"/> + <source>Past UD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="7"/> + <source>{0} {1}UD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="8"/> + <source>UD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Relative value</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RelativeZSum</name> <message> @@ -1992,13 +2346,13 @@ Chciałbyś opublikować klucz ?</translation> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> - <source>{0} R0 {1}</source> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> + <source>R0 {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> - <source>R0 {0}</source> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <source>{0} {1}R0 {2}</source> <translation type="unfinished"></translation> </message> <message> @@ -2017,37 +2371,47 @@ Chciałbyś opublikować klucz ?</translation> </message> </context> <context> - <name>Scene</name> + <name>SearchUserWidget</name> <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="158"/> - <source>Certification expires at {0}</source> - <translation type="unfinished"></translation> + <location filename="../../ui/search_user_view.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Forma</translation> + </message> + <message> + <location filename="../../ui/search_user_view.ui" line="33"/> + <source>Center the view on me</source> + <translation type="unfinished">Wyśrodkować widok na mnie</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/search_user.py" line="15"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Badania klucz publiczny, uid...</translation> </message> </context> <context> <name>StepPageInit</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="95"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="101"/> <source>Could not find your identity on the network.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="127"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> <source>Broadcasting identity...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>UID broadcast</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>Identity broadcasted to the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>Error</source> <translation type="unfinished">Błąd</translation> </message> @@ -2057,27 +2421,42 @@ Chciałbyś opublikować klucz ?</translation> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>{0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="153"/> <source>Your pubkey or UID was already found on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="145"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="156"/> <source>Your account already exists on the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="97"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="103"/> <source>Your pubkey or UID is different on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="124"/> + <source>connecting...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="164"/> + <source>Could not connect. Check hostname, ip address or port</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="162"/> + <source>Could not connect. Check node peering entry</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Toast</name> @@ -2102,57 +2481,52 @@ Yours : {0}, the network : {1}</source> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="175"/> <source>Actions</source> - <translation type="unfinished">Akcje</translation> + <translation type="obsolete">Akcje</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="190"/> <source>Send again</source> - <translation>Wyślij ponownie</translation> + <translation type="obsolete">Wyślij ponownie</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="195"/> <source>Cancel</source> - <translation>Anuluj</translation> + <translation type="obsolete">Anuluj</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="201"/> <source>Informations</source> - <translation>Informacja</translation> + <translation type="obsolete">Informacja</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="206"/> <source>Add as contact</source> - <translation>Dodaj jako kontakt</translation> + <translation type="obsolete">Dodaj jako kontakt</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="211"/> <source>Send money</source> - <translation>Wyślij pieniądze</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="217"/> - <source>View in Web of Trust</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Wyślij pieniądze</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="222"/> <source>Copy pubkey to clipboard</source> - <translation>Kopiowanie klucza publicznego do schowka</translation> + <translation type="obsolete">Kopiowanie klucza publicznego do schowka</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Warning</source> - <translation>Ostrzeżenie</translation> + <translation type="obsolete">Ostrzeżenie</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Are you sure ? This money transfer will be removed and not sent.</source> - <translation>Jesteś pewny ? + <translation type="obsolete">Jesteś pewny ? Ten przelew zostanie usunięty i nie wysłał.</translation> </message> <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="160"/> + <location filename="../../../src/sakia/gui/transactions_tab.py" line="159"/> <source>{:}</source> <translation type="unfinished">{:}</translation> </message> @@ -2185,37 +2559,37 @@ Ten przelew zostanie usunięty i nie wysłał.</translation> <translation type="obsolete">Kontakt</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="80"/> + <location filename="../../ui/transfer.ui" line="136"/> <source>Key</source> <translation>Klucz</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="148"/> + <location filename="../../ui/transfer.ui" line="250"/> <source> UD</source> <translation> UD</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="166"/> + <location filename="../../ui/transfer.ui" line="268"/> <source>Transaction message</source> <translation type="unfinished">komunikat transakcji</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>Money transfer</source> <translation>Przelew pieniędzy</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>No amount. Please give the transfert amount</source> <translation>Nie ilość. Proszę podać kwotę przelewu</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="139"/> + <location filename="../../../src/sakia/gui/transfer.py" line="163"/> <source>Transfer</source> <translation>Przenieść</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="126"/> + <location filename="../../../src/sakia/gui/transfer.py" line="150"/> <source>Success sending money to {0}</source> <translation type="unfinished">Sukces wysyłania pieniędzy do {0}</translation> </message> @@ -2230,30 +2604,35 @@ Ten przelew zostanie usunięty i nie wysłał.</translation> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="61"/> + <location filename="../../ui/transfer.ui" line="95"/> <source>&Recipient public key</source> <translation type="unfinished">&Odbiorca klucz publiczny</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="106"/> + <location filename="../../ui/transfer.ui" line="208"/> <source>Wallet</source> <translation>Portfel</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="125"/> + <location filename="../../ui/transfer.ui" line="227"/> <source>Available money : </source> <translation>Dostępne pieniądze : </translation> </message> <message> - <location filename="../../ui/transfer.ui" line="134"/> + <location filename="../../ui/transfer.ui" line="236"/> <source>Amount</source> <translation>Ilość</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="40"/> + <location filename="../../ui/transfer.ui" line="46"/> <source>Con&tact</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/transfer.ui" line="156"/> + <source>S&earch user</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>TxFilterProxyModel</name> @@ -2268,16 +2647,48 @@ Ten przelew zostanie usunięty i nie wysłał.</translation> <translation type="obsolete">Walidacji... {0} %</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="165"/> + <location filename="../../../src/sakia/models/txhistory.py" line="166"/> <source>{0} / {1} confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="169"/> + <location filename="../../../src/sakia/models/txhistory.py" line="170"/> <source>Confirming... {0} %</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>UDDToPast</name> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="6"/> + <source>Past UUD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="7"/> + <source>{0} {1}UUD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="8"/> + <source>UUD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table>></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>WalletsTab</name> <message> @@ -2509,27 +2920,22 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <message> <location filename="../../../src/sakia/gui/views/wot.py" line="294"/> <source>Informations</source> - <translation>Informacje</translation> + <translation type="obsolete">Informacje</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="299"/> <source>Add as contact</source> - <translation>Dodaj jako kontakt</translation> + <translation type="obsolete">Dodaj jako kontakt</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="304"/> <source>Send money</source> - <translation>Wyślij pieniądze</translation> + <translation type="obsolete">Wyślij pieniądze</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="309"/> <source>Certify identity</source> - <translation>Poświadcza tożsamość</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="314"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Poświadcza tożsamość</translation> </message> </context> <context> @@ -2542,15 +2948,15 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <message> <location filename="../../ui/wot_tab.ui" line="33"/> <source>Center the view on me</source> - <translation>Wyśrodkować widok na mnie</translation> + <translation type="obsolete">Wyśrodkować widok na mnie</translation> </message> <message> <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> <source>Research a pubkey, an uid...</source> - <translation type="unfinished">Badania klucz publiczny, uid...</translation> + <translation type="obsolete">Badania klucz publiczny, uid...</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2558,7 +2964,7 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2567,32 +2973,32 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez </translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="126"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="122"/> <source>Membership</source> - <translation type="unfinished">Członkostwo</translation> + <translation type="obsolete">Członkostwo</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source>Last renewal on {:}, expiration on {:}</source> - <translation type="unfinished">Ostatni odnowienia na {:}, wygaśnięciu z dniem {:}</translation> + <translation type="obsolete">Ostatni odnowienia na {:}, wygaśnięciu z dniem {:}</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Your web of trust</source> - <translation type="unfinished">Twój sieć zaufania</translation> + <translation type="obsolete">Twój sieć zaufania</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Certified by {:} members; Certifier of {:} members</source> - <translation type="unfinished">Certyfikowany przez {:} członków; Certifier z {:} członków</translation> + <translation type="obsolete">Certyfikowany przez {:} członków; Certifier z {:} członków</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Not a member</source> - <translation type="unfinished">Nie jest członkiem</translation> + <translation type="obsolete">Nie jest członkiem</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2600,7 +3006,7 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td></tr> @@ -2609,35 +3015,129 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez </translation> </message> </context> +<context> + <name>certificationsTabWidget</name> + <message> + <location filename="../../ui/certifications_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Forma</translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="20"/> + <source>Certifications</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="33"/> + <source>loading...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="63"/> + <source>dd/MM/yyyy</source> + <translation type="unfinished">dd/MM/yyyy</translation> + </message> +</context> +<context> + <name>menu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="57"/> + <source>Certify identity</source> + <translation type="unfinished">Poświadcza tożsamość</translation> + </message> +</context> +<context> + <name>menu.qmenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="42"/> + <source>Informations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="47"/> + <source>Add as contact</source> + <translation type="unfinished">Dodaj jako kontakt</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="52"/> + <source>Send money</source> + <translation type="unfinished">Wyślij pieniądze</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="61"/> + <source>View in Web of Trust</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="65"/> + <source>Copy pubkey to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="70"/> + <source>Copy membership document to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="74"/> + <source>Copy self-certification document to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="84"/> + <source>Transfer</source> + <translation type="unfinished">Przenieść</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="86"/> + <source>Send again</source> + <translation type="unfinished">Wyślij ponownie</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="90"/> + <source>Cancel</source> + <translation type="unfinished">Anuluj</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="95"/> + <source>Copy raw transaction to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="100"/> + <source>Copy transaction block to clipboard</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>self.config_dialog</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="191"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="204"/> <source>Ok</source> <translation>Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="70"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="72"/> <source>Forbidden : salt is too short</source> <translation>Zabrania się: sól jest zbyt krótki</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="74"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="76"/> <source>Forbidden : password is too short</source> <translation>Zabrania się: hasło jest za krótkie</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="78"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="80"/> <source>Forbidden : Invalid characters in salt field</source> <translation>Zabrania się: Nieprawidłowe znaki w polu soli</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="82"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="84"/> <source>Forbidden : Invalid characters in password field</source> <translation>Zabrania się: Nieprawidłowe znaki w polu hasła</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="88"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="90"/> <source>Error : passwords are different</source> <translation>Błąd: hasła są różne</translation> </message> @@ -2650,7 +3150,7 @@ Odwołanie UID może tylko sukcesem, jeśli nie jest on już zatwierdzony przez <translation>Forma</translation> </message> <message> - <location filename="../../ui/transactions_tab.ui" line="63"/> + <location filename="../../ui/transactions_tab.ui" line="66"/> <source>dd/MM/yyyy</source> <translation>dd/MM/yyyy</translation> </message> diff --git a/res/i18n/ts/pt_BR.ts b/res/i18n/ts/pt_BR.ts index 68b34bae4c9f1712b1be8e2333a0bac1c945ce72..ca59ffc44093dea240d3ba7fc97b41e9fb8f8d37 100644 --- a/res/i18n/ts/pt_BR.ts +++ b/res/i18n/ts/pt_BR.ts @@ -51,10 +51,25 @@ <translation type="obsolete">Relat Z-sum</translation> </message> <message> - <location filename="../../../src/sakia/core/account.py" line="510"/> + <location filename="../../../src/sakia/core/account.py" line="540"/> <source>Could not find user self certification.</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="67"/> + <source>Warning : Your membership is expiring soon.</source> + <translation type="unfinished">Aviso: sua associação expirará em breve.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="72"/> + <source>Warning : Your could miss certifications soon.</source> + <translation type="unfinished">Aviso: você poderá perder certificações em breve.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="77"/> + <source>Warning : If you don't renew soon, your identity will be considerd revoked.</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AccountConfigurationDialog</name> @@ -91,7 +106,7 @@ <message> <location filename="../../ui/account_cfg.ui" line="143"/> <source>CryptoID</source> - <translation>CryptoID (salt)</translation> + <translation type="obsolete">CryptoID (salt)</translation> </message> <message> <location filename="../../ui/account_cfg.ui" line="153"/> @@ -138,49 +153,54 @@ <source>Communities</source> <translation>Comunidades</translation> </message> + <message> + <location filename="../../ui/account_cfg.ui" line="143"/> + <source>Entropy</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Application</name> <message> <location filename="../../../src/sakia/core/app.py" line="76"/> <source>Warning : Your membership is expiring soon.</source> - <translation type="unfinished">Aviso: sua associação expirará em breve.</translation> + <translation type="obsolete">Aviso: sua associação expirará em breve.</translation> </message> <message> <location filename="../../../src/sakia/core/app.py" line="81"/> <source>Warning : Your could miss certifications soon.</source> - <translation type="unfinished">Aviso: você poderá perder certificações em breve.</translation> + <translation type="obsolete">Aviso: você poderá perder certificações em breve.</translation> </message> </context> <context> <name>CertificationDialog</name> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Certification</source> <translation>Certificação</translation> </message> <message> - <location filename="../../ui/certification.ui" line="20"/> + <location filename="../../ui/certification.ui" line="26"/> <source>Community</source> <translation>Comunidade</translation> </message> <message> - <location filename="../../ui/certification.ui" line="32"/> + <location filename="../../ui/certification.ui" line="54"/> <source>Certify user</source> <translation>Certificar usuário</translation> </message> <message> <location filename="../../ui/certification.ui" line="40"/> <source>Contact</source> - <translation>Contato</translation> + <translation type="obsolete">Contato</translation> </message> <message> <location filename="../../ui/certification.ui" line="61"/> <source>User public key</source> - <translation>Chave pública do usuário</translation> + <translation type="obsolete">Chave pública do usuário</translation> </message> <message> - <location filename="../../ui/certification.ui" line="80"/> + <location filename="../../ui/certification.ui" line="157"/> <source>Key</source> <translation>Chave</translation> </message> @@ -205,25 +225,75 @@ <translation type="obsolete">Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="112"/> + <location filename="../../../src/sakia/gui/certification.py" line="227"/> <source>Not a member</source> <translation>Não é um membro</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="109"/> + <location filename="../../../src/sakia/gui/certification.py" line="221"/> <source>&Ok</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="75"/> + <location filename="../../../src/sakia/gui/certification.py" line="126"/> <source>Success sending certification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Could not broadcast certification : {0}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/certification.ui" line="73"/> + <source>Con&tact</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="116"/> + <source>&User public key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="35"/> + <source>Certifications stock</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="177"/> + <source>Sea&rch user</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="197"/> + <source>Certifications sent : {nb_certifications}/{stock}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="206"/> + <source>{days} days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="208"/> + <source>{hours} hours and {min} min.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="210"/> + <source>Remaining time before next certification validation : {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="217"/> + <source> (Not validated before </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="224"/> + <source>No more certifications</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityConfigurationDialog</name> @@ -258,17 +328,17 @@ <translation>Servidor</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="200"/> + <location filename="../../ui/community_cfg.ui" line="203"/> <source>Add</source> <translation>Adicionar</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="221"/> + <location filename="../../ui/community_cfg.ui" line="224"/> <source>Previous</source> <translation>Anterior</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="244"/> + <location filename="../../ui/community_cfg.ui" line="247"/> <source>Next</source> <translation>Próximo</translation> </message> @@ -384,45 +454,80 @@ <context> <name>CommunityTile</name> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="81"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Member</source> <translation type="unfinished">Membro</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="82"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Non-Member</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>members</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Monetary mass</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Balance</source> <translation type="unfinished">Balanço</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="112"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="162"/> <source>Not connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="125"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="175"/> <source>Community not initialized</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="100"/> + <source>Expired or never published</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="101"/> + <source>Outdistanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="110"/> + <source>In WoT range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="116"/> + <source>Expires in </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="124"/> + <source>#FF0000</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Certs. received</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Membership</source> + <translation type="unfinished">Associação</translation> + </message> </context> <context> <name>CommunityWidget</name> @@ -442,7 +547,7 @@ <translation type="unfinished">Certificação</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="289"/> + <location filename="../../../src/sakia/gui/community_view.py" line="286"/> <source>Renew membership</source> <translation type="unfinished">Renovar associação</translation> </message> @@ -457,62 +562,57 @@ <translation type="obsolete">Aviso: você poderá perder certificações em breve.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="34"/> + <location filename="../../../src/sakia/gui/community_view.py" line="33"/> <source>Transactions</source> <translation type="unfinished">Transações</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <location filename="../../../src/sakia/gui/community_view.py" line="34"/> <source>Web of Trust</source> <translation type="unfinished">Rede de Confiança</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="37"/> + <location filename="../../../src/sakia/gui/community_view.py" line="90"/> <source>Network</source> <translation type="unfinished">Rede</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source>Membership expiration</source> <translation type="unfinished">Expiração da associação</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source><b>Warning : Membership expiration in {0} days</b></source> <translation type="unfinished"><b>Aviso: expiração da associação em {0} dias</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source>Certifications number</source> <translation type="unfinished">Número de certificações</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source><b>Warning : You are certified by only {0} persons, need {1}</b></source> <translation type="unfinished"><b>Aviso: você é certificado por apenas {0} pessoas. São necessárias {1}</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="228"/> + <location filename="../../../src/sakia/gui/community_view.py" line="235"/> <source> Block {0}</source> - <translation type="unfinished"> Bloco {0}</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/community_view.py" line="270"/> - <source> - Median fork window : {0}</source> - <translation type="unfinished"></translation> + <translation type="obsolete"> Bloco {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="295"/> + <location filename="../../../src/sakia/gui/community_view.py" line="292"/> <source>Send membership demand</source> <translation type="unfinished">Enviar pedido de associação</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Warning</source> <translation type="unfinished">Aviso</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Are you sure ? Sending a leaving demand cannot be canceled. The process to join back the community later will have to be done again.</source> @@ -533,7 +633,7 @@ A publicação do seu UID pode ser cancelada através da revogação de UID.</tr <translation type="obsolete">Publicação de UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="375"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Success publishing your UID</source> <translation type="unfinished">Sucesso ao publicar seu UID</translation> </message> @@ -565,22 +665,22 @@ Revoking your UID can only success if it is not already validated by the network Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela rede.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Membership</source> <translation type="unfinished">Associação</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="329"/> + <location filename="../../../src/sakia/gui/community_view.py" line="325"/> <source>Success sending Membership demand</source> <translation type="unfinished">Sucesso ao enviar pedido de associação</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="361"/> + <location filename="../../../src/sakia/gui/community_view.py" line="356"/> <source>Revoke</source> <translation type="unfinished">Revogar</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="355"/> + <location filename="../../../src/sakia/gui/community_view.py" line="350"/> <source>Success sending Revoke demand</source> <translation type="unfinished">Sucesso ao enviar pedido de revoga</translation> </message> @@ -595,12 +695,12 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="obsolete">Sucesso ao enviar documento de Auto-certificação</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <location filename="../../../src/sakia/gui/community_view.py" line="94"/> <source>Show informations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="38"/> + <location filename="../../../src/sakia/gui/community_view.py" line="95"/> <source>Informations</source> <translation type="unfinished">Informações</translation> </message> @@ -610,23 +710,38 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="unfinished">Publicar UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="399"/> + <location filename="../../../src/sakia/gui/community_view.py" line="41"/> <source>Revoke UID</source> <translation type="unfinished">Revogar UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="401"/> + <location filename="../../../src/sakia/gui/community_view.py" line="375"/> <source>UID</source> <translation type="unfinished">UID</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> - <source>Your UID was revoked successfully.</source> + <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <source>Search Identities</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="36"/> - <source>Search Identities</source> + <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <source>Explore the Web of Trust</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="99"/> + <source>Show explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="100"/> + <source>Explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="234"/> + <source>Block {0}</source> <translation type="unfinished"></translation> </message> </context> @@ -648,11 +763,26 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation>Chave pública</translation> </message> <message> - <location filename="../../../src/sakia/gui/contact.py" line="52"/> + <location filename="../../../src/sakia/gui/contact.py" line="81"/> <source>Contact already exists</source> <translation>O contato já existe</translation> </message> </context> +<context> + <name>ContextMenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Warning</source> + <translation type="unfinished">Aviso</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Are you sure ? +This money transfer will be removed and not sent.</source> + <translation type="unfinished">Você tem certeza? +Esta transferência monetária será removida e não enviada.</translation> + </message> +</context> <context> <name>CreateWalletDialog</name> <message> @@ -749,48 +879,153 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <message> <location filename="../../ui/member.ui" line="14"/> <source>Informations</source> - <translation>Informações</translation> + <translation type="obsolete">Informações</translation> </message> <message> <location filename="../../ui/member.ui" line="34"/> <source>Member</source> - <translation>Membro</translation> + <translation type="obsolete">Membro</translation> </message> <message> <location filename="../../ui/member.ui" line="65"/> <source>uid</source> - <translation>UID</translation> + <translation type="obsolete">UID</translation> </message> <message> <location filename="../../ui/member.ui" line="72"/> <source>properties</source> - <translation>propriedades</translation> + <translation type="obsolete">propriedades</translation> + </message> +</context> +<context> + <name>DividendPerDay</name> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="9"/> + <source>UDD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="10"/> + <source>{0} {1}UDD {2}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="11"/> + <source>UDD {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="12"/> + <source>UDD(t) = (Q * 100) / (UD(t) / DT) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>ExplorerTabWidget</name> + <message> + <location filename="../../ui/explorer_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Formulário</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="48"/> + <source>Steps</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="65"/> + <source>Go</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>GraphTabWidget</name> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="71"/> + <source>Membership</source> + <translation type="unfinished">Associação</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source>Last renewal on {:}, expiration on {:}</source> + <translation type="unfinished">Última renovação em {:}, expiração em {:}</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Your web of trust</source> + <translation type="unfinished">Sua Rede de Confiança</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Certified by {:} members; Certifier of {:} members</source> + <translation type="unfinished">Certificado por {:} membros; Certificador de {:} membros</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Not a member</source> + <translation type="unfinished">Não é um membro</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"> + <table cellpadding="5"> +<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> +<tr><td align="right"><b>{:}</b></td></tr> +<tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> +</table> + </translation> </message> </context> <context> <name>HistoryTableModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Date</source> <translation>Data</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>UID/Public key</source> <translation>UID/Chave pública</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Payment</source> <translation>Pagamento</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Deposit</source> <translation>Depósito</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Comment</source> <translation>Comentário</translation> </message> @@ -907,73 +1142,78 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="36"/> <source>Members</source> - <translation type="unfinished">Membros</translation> + <translation type="obsolete">Membros</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="37"/> <source>Direct connections</source> - <translation type="unfinished">Conexões diretas</translation> + <translation type="obsolete">Conexões diretas</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="112"/> <source>Informations</source> - <translation type="unfinished">Informações</translation> + <translation type="obsolete">Informações</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="115"/> <source>Add as contact</source> - <translation type="unfinished">Adicionar como contato</translation> + <translation type="obsolete">Adicionar como contato</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="119"/> <source>Send money</source> - <translation type="unfinished">Enviar dinheiro</translation> + <translation type="obsolete">Enviar dinheiro</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="123"/> <source>Certify identity</source> - <translation type="unfinished">Certificar identidade</translation> + <translation type="obsolete">Certificar identidade</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="127"/> <source>View in Web of Trust</source> - <translation type="unfinished">Ver na Rede de Confiança</translation> + <translation type="obsolete">Ver na Rede de Confiança</translation> </message> <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="131"/> - <source>Copy pubkey</source> + <location filename="../../../src/sakia/gui/identities_tab.py" line="32"/> + <source>Search direct certifications</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/identities_tab.py" line="33"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Busque uma chave pública, um UID...</translation> + </message> </context> <context> <name>IdentitiesTableModel</name> <message> - <location filename="../../../src/sakia/models/identities.py" line="89"/> + <location filename="../../../src/sakia/models/identities.py" line="118"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="90"/> + <location filename="../../../src/sakia/models/identities.py" line="119"/> <source>Pubkey</source> <translation>Chave pública</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="91"/> + <location filename="../../../src/sakia/models/identities.py" line="120"/> <source>Renewed</source> <translation>Renovado</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="92"/> + <location filename="../../../src/sakia/models/identities.py" line="121"/> <source>Expiration</source> <translation>Expiração</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="94"/> + <location filename="../../../src/sakia/models/identities.py" line="123"/> <source>Validation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="93"/> + <location filename="../../../src/sakia/models/identities.py" line="122"/> <source>Publication</source> <translation type="unfinished"></translation> </message> @@ -1109,47 +1349,47 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Universal Dividend UD(t) in</source> <translation>Dividendo Universal "UD(t)" em</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass M(t-1) in</source> <translation>Massa Monetária "M(t-1)" em</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Members N(t)</source> <translation>Membros "N(t)"</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass per member M(t-1)/N(t) in</source> <translation>Massa Monetária por membro "M(t-1)/N(t)" em</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Actual growth c = UD(t)/[M(t-1)/N(t)]</source> <translation>Crescimento real "c = UD(t)/[M(t-1)/N(t)]"</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Last UD date and time (t)</source> <translation>Data e hora do último Dividendo Universal (t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Next UD date and time (t+1)</source> <translation>Data e hora do próximo Dividendo Universal (t+1)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="194"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="196"/> <source>No Universal Dividend created yet.</source> <translation>Nenhum Dividendo Universal criado ainda.</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1166,37 +1406,37 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:2.0%} / {:} days</source> <translation>{:2.0%} / {:} dias</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Fundamental growth (c) / Delta time (dt)</source> <translation>Crescimento fundamental (c) / Tempo delta (dt)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</source> <translation>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (formula)</source> <translation>Dividendo Universal (fórmula)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</source> <translation>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (computed)</source> <translation>Dividendo Universal (computado)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> @@ -1223,47 +1463,47 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Fundamental growth (c)</source> <translation>Crescimento fundamental (c)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Initial Universal Dividend UD(0) in</source> <translation>Dividendo Universal inicial "UD(0)" em</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Time period (dt) in days (86400 seconds) between two UD</source> <translation>Período de tempo em dias (86400 segundos) entre dois Dividendos Universais</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Number of blocks used for calculating median time</source> <translation>Número de blocos utilizados para calcular o tempo mediano</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The average time in seconds for writing 1 block (wished time)</source> <translation>O tempo médio em segundos para escrever 1 bloco (tempo desejado)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of blocks required to evaluate again PoWMin value</source> <translation>O número de blocos necessários para avaliar novamente o valor de 'PoWMin'</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of previous blocks to check for personalized difficulty</source> <translation>O número de blocos anteriores para verificar se há dificuldade personalizada</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The percent of previous issuers to reach for personalized difficulty</source> <translation>A porcentagem de emissores anteriores para alcançar a dificuldade personalizada</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1274,7 +1514,7 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1286,37 +1526,37 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela </translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum delay between 2 identical certifications (in days)</source> - <translation>Atraso mínimo entre 2 certificações idênticas (em dias)</translation> + <translation type="obsolete">Atraso mínimo entre 2 certificações idênticas (em dias)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid signature (in days)</source> <translation>Idade máxima de uma assinatura válida (em dias)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Minimum quantity of signatures to be part of the WoT</source> <translation>Quantidade mínima de assinaturas para ser parte da Rede de Confiança</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="234"/> <source>Minimum quantity of valid made certifications to be part of the WoT for distance rule</source> - <translation>Quantidade mínima de certificações válidas feitas para ser parte da Rede de Confiança pela regra de distância</translation> + <translation type="obsolete">Quantidade mínima de certificações válidas feitas para ser parte da Rede de Confiança pela regra de distância</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid membership (in days)</source> <translation>Idade máxima de uma associação válida (em dias)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum distance between each WoT member and a newcomer</source> <translation>Distância máxima entre cada membro da Rede de Confiança e um novato</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> @@ -1332,7 +1572,7 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Penultimate UD date and time (t-1)</source> <translation type="unfinished"></translation> </message> @@ -1342,25 +1582,61 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Name</source> <translation type="unfinished">Nome</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Units</source> <translation type="unfinished">Unidades</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Formula</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Description</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum delay between 2 certifications (in days)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum quantity of active certifications made by member.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum delay a certification can wait before being expired for non-writing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum percent of sentries to reach to match the distance rule</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>MainWindow</name> @@ -1370,7 +1646,7 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation>Arquivo</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="131"/> + <location filename="../../ui/mainwindow.ui" line="138"/> <source>Account</source> <translation>Conta</translation> </message> @@ -1390,12 +1666,12 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation>Ajuda</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="76"/> + <location filename="../../ui/mainwindow.ui" line="83"/> <source>Manage accounts</source> <translation>Gerenciar contas</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="81"/> + <location filename="../../ui/mainwindow.ui" line="88"/> <source>Configure trustable nodes</source> <translation>Configurar nós confiáveis</translation> </message> @@ -1405,47 +1681,47 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="obsolete">Adicionar um contato</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="106"/> + <location filename="../../ui/mainwindow.ui" line="113"/> <source>Send a message</source> <translation>Enviar uma mensagem</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="111"/> + <location filename="../../ui/mainwindow.ui" line="118"/> <source>Send money</source> <translation>Enviar dinheiro</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="116"/> + <location filename="../../ui/mainwindow.ui" line="123"/> <source>Remove contact</source> <translation>Remover contato</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="121"/> + <location filename="../../ui/mainwindow.ui" line="128"/> <source>Save</source> <translation>Salvar</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="126"/> + <location filename="../../ui/mainwindow.ui" line="133"/> <source>&Quit</source> <translation>Sair</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="136"/> + <location filename="../../ui/mainwindow.ui" line="143"/> <source>&Transfer money</source> <translation>Transferir dinheiro</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="141"/> + <location filename="../../ui/mainwindow.ui" line="148"/> <source>&Configure</source> <translation>Configurar</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="146"/> + <location filename="../../ui/mainwindow.ui" line="153"/> <source>&Import</source> <translation>Importar</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="151"/> + <location filename="../../ui/mainwindow.ui" line="158"/> <source>&Export</source> <translation>Exportar</translation> </message> @@ -1455,32 +1731,32 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="obsolete">Certificação</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="161"/> + <location filename="../../ui/mainwindow.ui" line="168"/> <source>&Set as default</source> <translation>Definir como padrão</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="166"/> + <location filename="../../ui/mainwindow.ui" line="173"/> <source>A&bout</source> <translation>Sobre</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="171"/> + <location filename="../../ui/mainwindow.ui" line="178"/> <source>&Preferences</source> <translation>Preferências</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="176"/> + <location filename="../../ui/mainwindow.ui" line="183"/> <source>&Add account</source> <translation>Adicionar conta</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="211"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="285"/> <source>Latest release : {version}</source> <translation>Última versão: {version}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="218"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="292"/> <source>Download link</source> <translation>Link para baixar</translation> </message> @@ -1515,17 +1791,17 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela </translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="251"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="326"/> <source>Please get the latest release {version}</source> <translation>Por favor, baixe a última versão {version}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="283"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="358"/> <source>Edit</source> <translation>Editar</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="286"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="361"/> <source>Delete</source> <translation>Excluir</translation> </message> @@ -1540,17 +1816,17 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="obsolete">CuteCoin {0} - Conta: {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="348"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="424"/> <source>Export an account</source> <translation>Exportar uma conta</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="349"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="425"/> <source>All account files (*.acc)</source> <translation>Todos os arquivos de conta (*.acc)</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="350"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="426"/> <source>Export</source> <translation>Exportar</translation> </message> @@ -1565,21 +1841,42 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="86"/> + <location filename="../../ui/mainwindow.ui" line="93"/> <source>A&dd a contact</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="156"/> + <location filename="../../ui/mainwindow.ui" line="163"/> <source>C&ertification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="225"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="383"/> + <source>sakia {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="407"/> + <source>sakia {0} - Account : {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="71"/> + <source>&Duniter</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/mainwindow.ui" line="188"/> + <source>&Manage local node</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/mainwindow.py" line="299"/> <source> <h1>sakia</h1> - <p>Python/Qt uCoin client</p> + <p>Python/Qt duniter client</p> + <p><a href="https://github.com/duniter/sakia">https://github.com/duniter/sakia</a></p> <p>Version : {:}</p> {new_version_text} @@ -1595,21 +1892,11 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela </source> <translation type="unfinished"></translation> </message> - <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="303"/> - <source>sakia {0}</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="330"/> - <source>sakia {0} - Account : {1}</source> - <translation type="unfinished"></translation> - </message> </context> <context> <name>MemberDialog</name> <message> - <location filename="../../../src/sakia/gui/member.py" line="46"/> + <location filename="../../../src/sakia/gui/member.py" line="73"/> <source>not a member</source> <translation>não é um membro</translation> </message> @@ -1620,100 +1907,133 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> </source> - <translation> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> </translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Public key</source> <translation>Chave pública</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Join date</source> <translation>Data de ingresso</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="87"/> + <location filename="../../../src/sakia/gui/member.py" line="144"/> <source><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></source> <translation><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="73"/> + <location filename="../../../src/sakia/gui/member.py" line="130"/> <source>Distance</source> <translation>Distância</translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="80"/> + <location filename="../../../src/sakia/gui/member.py" line="139"/> <source>Path</source> <translation>Caminho</translation> </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="92"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="97"/> + <source>UID Published on</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MemberView</name> + <message> + <location filename="../../ui/member.ui" line="14"/> + <source>Member informations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/member.ui" line="34"/> + <source>Member</source> + <translation type="unfinished">Membro</translation> + </message> </context> <context> <name>NetworkFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="48"/> + <location filename="../../../src/sakia/models/network.py" line="54"/> <source>Address</source> <translation>Endereço</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="49"/> + <location filename="../../../src/sakia/models/network.py" line="55"/> <source>Port</source> <translation>Porta</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="50"/> + <location filename="../../../src/sakia/models/network.py" line="56"/> <source>Block</source> <translation>Bloco</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="52"/> + <location filename="../../../src/sakia/models/network.py" line="59"/> <source>UID</source> <translation>UID</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="53"/> + <location filename="../../../src/sakia/models/network.py" line="60"/> <source>Member</source> <translation>Membro</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="54"/> + <location filename="../../../src/sakia/models/network.py" line="61"/> <source>Pubkey</source> <translation>Chave pública</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="55"/> + <location filename="../../../src/sakia/models/network.py" line="62"/> <source>Software</source> <translation>Programa</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="56"/> + <location filename="../../../src/sakia/models/network.py" line="63"/> <source>Version</source> <translation>Versão</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>yes</source> <translation>sim</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>no</source> <translation>não</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>offline</source> <translation>offline</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="51"/> + <location filename="../../../src/sakia/models/network.py" line="57"/> <source>Hash</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/models/network.py" line="58"/> + <source>Time</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>NetworkTabWidget</name> @@ -1723,17 +2043,17 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation>Formulário</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="70"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="72"/> <source>Unset root node</source> <translation>Remover definição de raiz do nó</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="76"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="78"/> <source>Set as root node</source> <translation>Definir como nó raiz</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="82"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="84"/> <source>Open in browser</source> <translation>Abrir no navegador</translation> </message> @@ -1741,26 +2061,34 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <context> <name>NetworkTableModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="136"/> + <location filename="../../../src/sakia/models/network.py" line="155"/> <source>Online</source> <translation>Online</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="137"/> + <location filename="../../../src/sakia/models/network.py" line="156"/> <source>Offline</source> <translation>Offline</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="138"/> + <location filename="../../../src/sakia/models/network.py" line="157"/> <source>Unsynchronized</source> <translation>Dessincronizado</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="139"/> + <location filename="../../../src/sakia/models/network.py" line="158"/> <source>Corrupted</source> <translation>Corrompido</translation> </message> </context> +<context> + <name>NodeManager</name> + <message> + <location filename="../../ui/node_manager.ui" line="14"/> + <source>Node manager</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>PasswordAskerDialog</name> <message> @@ -1779,22 +2107,22 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation>Lembrar minha senha durante esta sessão</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Bad password</source> <translation>Senha ruim</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Non printable characters in password</source> <translation>Há caracteres não imprimíveis na senha</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Failed to get private key</source> <translation>Falha ao obter a chave privada</translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Wrong password typed. Cannot open the private key</source> <translation>Senha incorreta. Não é possível abrir a chave privada</translation> </message> @@ -1862,45 +2190,50 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="329"/> + <location filename="../../ui/preferences.ui" line="356"/> <source><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Network settings</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="345"/> + <location filename="../../ui/preferences.ui" line="372"/> <source>Proxy server address : </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="355"/> + <location filename="../../ui/preferences.ui" line="382"/> <source>:</source> <translation type="unfinished">:</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="336"/> + <location filename="../../ui/preferences.ui" line="363"/> <source>Use a http proxy server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="379"/> + <location filename="../../ui/preferences.ui" line="406"/> <source>Automatically refresh identities informations</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/preferences.ui" line="330"/> + <source>Enable forgetfulness</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureAccount</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="163"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="165"/> <source>New account</source> <translation>Nova conta</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="170"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="175"/> <source>Configure {0}</source> <translation>Configurar {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="185"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="190"/> <source>Ok</source> <translation>Ok</translation> </message> @@ -1915,7 +2248,7 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation type="obsolete">A chave pública desses parâmetros é: {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> <source>Warning</source> <translation>Aviso</translation> </message> @@ -1925,36 +2258,44 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela Please note your key parameters (salt and password) if you wish to recover it later. Your account won't be removed from the networks it joined. Are you sure ?</source> - <translation>Esta ação excluirá sua conta localmente. + <translation type="obsolete">Esta ação excluirá sua conta localmente. Por favor, anote os parâmetros da sua chave (CryptoID e senha) se você deseja recuperá-la posteriormente. Sua conta não será excluída das redes que você ingressou. Você tem certeza?</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="243"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="249"/> <source>Error</source> <translation>Erro</translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> + <source>This action will delete your account ({0}) locally. +Please note your key parameters (salt and password) if you wish to recover it later. +Your account won't be removed from the networks it joined. +Are you sure ?</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureCommunity</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="227"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="240"/> <source>Configure community {0}</source> <translation>Configurar comunidade {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="230"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="243"/> <source>Add a community</source> <translation>Adicionar uma comunidade</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="264"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="276"/> <source>Error</source> <translation>Erro</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="293"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="305"/> <source>Delete</source> <translation>Excluir</translation> </message> @@ -2032,16 +2373,16 @@ Você gostaria de publicar a chave?</translation> <source>Quant Z-sum</source> <translation type="unfinished">Quant Z-sum</translation> </message> - <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> - <source>{0} Q0 {1}</source> - <translation type="unfinished"></translation> - </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> <source>Q0 {0}</source> <translation type="unfinished">Q0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <source>{0} {1}Q0 {2}</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="10"/> <source>Z0 = Q - ( M(t-1) / N(t) ) @@ -2060,22 +2401,22 @@ Você gostaria de publicar a chave?</translation> <context> <name>Relative</name> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="7"/> + <location filename="../../../src/sakia/core/money/relative.py" line="9"/> <source>UD</source> <translation type="unfinished">Dividendo Universal</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative.py" line="10"/> <source>{0} {1}UD {2}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="9"/> + <location filename="../../../src/sakia/core/money/relative.py" line="11"/> <source>UD {0}</source> <translation type="unfinished">Dividendo Universal {0}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="10"/> + <location filename="../../../src/sakia/core/money/relative.py" line="12"/> <source>R = Q / UD(t) <br > <table> @@ -2087,6 +2428,36 @@ Você gostaria de publicar a chave?</translation> <translation type="unfinished"></translation> </message> </context> +<context> + <name>RelativeToPast</name> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="6"/> + <source>Past UD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="7"/> + <source>{0} {1}UD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="8"/> + <source>UD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Relative value</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RelativeZSum</name> <message> @@ -2094,16 +2465,16 @@ Você gostaria de publicar a chave?</translation> <source>Relat Z-sum</source> <translation type="unfinished">Relat Z-sum</translation> </message> - <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> - <source>{0} R0 {1}</source> - <translation type="unfinished"></translation> - </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> <source>R0 {0}</source> <translation type="unfinished">R0 {0}</translation> </message> + <message> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <source>{0} {1}R0 {2}</source> + <translation type="unfinished"></translation> + </message> <message> <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="10"/> <source>R0 = (R / UD(t)) - (( M(t-1) / N(t) ) / UD(t)) @@ -2124,33 +2495,51 @@ Você gostaria de publicar a chave?</translation> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="158"/> <source>Certification expires at {0}</source> - <translation>Certificação expira em {0}</translation> + <translation type="obsolete">Certificação expira em {0}</translation> + </message> +</context> +<context> + <name>SearchUserWidget</name> + <message> + <location filename="../../ui/search_user_view.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Formulário</translation> + </message> + <message> + <location filename="../../ui/search_user_view.ui" line="33"/> + <source>Center the view on me</source> + <translation type="unfinished">Centralizar a visualização em mim</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/search_user.py" line="15"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Busque uma chave pública, um UID...</translation> </message> </context> <context> <name>StepPageInit</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="95"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="101"/> <source>Could not find your identity on the network.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="127"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> <source>Broadcasting identity...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>UID broadcast</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>Identity broadcasted to the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>Error</source> <translation type="unfinished">Erro</translation> </message> @@ -2160,27 +2549,42 @@ Você gostaria de publicar a chave?</translation> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>{0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="153"/> <source>Your pubkey or UID was already found on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="145"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="156"/> <source>Your account already exists on the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="97"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="103"/> <source>Your pubkey or UID is different on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="124"/> + <source>connecting...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="164"/> + <source>Could not connect. Check hostname, ip address or port</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="162"/> + <source>Could not connect. Check node peering entry</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Toast</name> @@ -2220,57 +2624,57 @@ Yours : {0}, the network : {1}</source> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="175"/> <source>Actions</source> - <translation>Ações</translation> + <translation type="obsolete">Ações</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="190"/> <source>Send again</source> - <translation>Enviar novamente</translation> + <translation type="obsolete">Enviar novamente</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="195"/> <source>Cancel</source> - <translation>Cancelar</translation> + <translation type="obsolete">Cancelar</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="201"/> <source>Informations</source> - <translation>Informações</translation> + <translation type="obsolete">Informações</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="206"/> <source>Add as contact</source> - <translation>Adicionar como contato</translation> + <translation type="obsolete">Adicionar como contato</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="211"/> <source>Send money</source> - <translation>Enviar dinheiro</translation> + <translation type="obsolete">Enviar dinheiro</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="217"/> <source>View in Web of Trust</source> - <translation>Ver na Rede de Confiança</translation> + <translation type="obsolete">Ver na Rede de Confiança</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="222"/> <source>Copy pubkey to clipboard</source> - <translation>Copiar chave pública para a área de transferência</translation> + <translation type="obsolete">Copiar chave pública para a área de transferência</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Warning</source> - <translation>Aviso</translation> + <translation type="obsolete">Aviso</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Are you sure ? This money transfer will be removed and not sent.</source> - <translation>Você tem certeza? + <translation type="obsolete">Você tem certeza? Esta transferência monetária será removida e não enviada.</translation> </message> <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="160"/> + <location filename="../../../src/sakia/gui/transactions_tab.py" line="159"/> <source>{:}</source> <translation type="unfinished"></translation> </message> @@ -2303,37 +2707,37 @@ Esta transferência monetária será removida e não enviada.</translation> <translation type="obsolete">Contato</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="80"/> + <location filename="../../ui/transfer.ui" line="136"/> <source>Key</source> <translation>Chave</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="148"/> + <location filename="../../ui/transfer.ui" line="250"/> <source> UD</source> <translation> Dividendo Universal</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="166"/> + <location filename="../../ui/transfer.ui" line="268"/> <source>Transaction message</source> <translation>Mensagem da transação</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>Money transfer</source> <translation>Transferência monetária</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>No amount. Please give the transfert amount</source> <translation>Nenhuma quantia. Por favor, indique a quantia da transferência</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="139"/> + <location filename="../../../src/sakia/gui/transfer.py" line="163"/> <source>Transfer</source> <translation>Transferência</translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="126"/> + <location filename="../../../src/sakia/gui/transfer.py" line="150"/> <source>Success sending money to {0}</source> <translation>Sucesso ao enviar dinheiro para {0}</translation> </message> @@ -2348,44 +2752,81 @@ Esta transferência monetária será removida e não enviada.</translation> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="61"/> + <location filename="../../ui/transfer.ui" line="95"/> <source>&Recipient public key</source> <translation>Chave pública do destinatário</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="106"/> + <location filename="../../ui/transfer.ui" line="208"/> <source>Wallet</source> <translation>Carteira</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="125"/> + <location filename="../../ui/transfer.ui" line="227"/> <source>Available money : </source> <translation>Dinheiro disponível: </translation> </message> <message> - <location filename="../../ui/transfer.ui" line="134"/> + <location filename="../../ui/transfer.ui" line="236"/> <source>Amount</source> <translation>Quantia</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="40"/> + <location filename="../../ui/transfer.ui" line="46"/> <source>Con&tact</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/transfer.ui" line="156"/> + <source>S&earch user</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>TxFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="165"/> + <location filename="../../../src/sakia/models/txhistory.py" line="166"/> <source>{0} / {1} confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="169"/> + <location filename="../../../src/sakia/models/txhistory.py" line="170"/> <source>Confirming... {0} %</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>UDDToPast</name> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="6"/> + <source>Past UUD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="7"/> + <source>{0} {1}UUD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="8"/> + <source>UUD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table>></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>WalletsTab</name> <message> @@ -2617,27 +3058,22 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <message> <location filename="../../../src/sakia/gui/views/wot.py" line="294"/> <source>Informations</source> - <translation>Informações</translation> + <translation type="obsolete">Informações</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="299"/> <source>Add as contact</source> - <translation>Adicionar como contato</translation> + <translation type="obsolete">Adicionar como contato</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="304"/> <source>Send money</source> - <translation>Enviar dinheiro</translation> + <translation type="obsolete">Enviar dinheiro</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="309"/> <source>Certify identity</source> - <translation>Certificar identidade</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="314"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Certificar identidade</translation> </message> </context> <context> @@ -2650,51 +3086,40 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <message> <location filename="../../ui/wot_tab.ui" line="33"/> <source>Center the view on me</source> - <translation>Centralizar a visualização em mim</translation> + <translation type="obsolete">Centralizar a visualização em mim</translation> </message> <message> <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> <source>Research a pubkey, an uid...</source> - <translation>Busque uma chave pública, um UID...</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - </source> - <translation type="unfinished"></translation> + <translation type="obsolete">Busque uma chave pública, um UID...</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="126"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="122"/> <source>Membership</source> - <translation type="unfinished">Associação</translation> + <translation type="obsolete">Associação</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="140"/> <source>Last renewal on {:}, expiration on {:}</source> - <translation type="unfinished">Última renovação em {:}, expiração em {:}</translation> + <translation type="obsolete">Última renovação em {:}, expiração em {:}</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Your web of trust</source> - <translation type="unfinished">Sua Rede de Confiança</translation> + <translation type="obsolete">Sua Rede de Confiança</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Certified by {:} members; Certifier of {:} members</source> - <translation type="unfinished">Certificado por {:} membros; Certificador de {:} membros</translation> + <translation type="obsolete">Certificado por {:} membros; Certificador de {:} membros</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source>Not a member</source> - <translation type="unfinished">Não é um membro</translation> + <translation type="obsolete">Não é um membro</translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -2702,7 +3127,7 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> </source> - <translation type="unfinished"> + <translation type="obsolete"> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td></tr> @@ -2711,35 +3136,129 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela </translation> </message> </context> +<context> + <name>certificationsTabWidget</name> + <message> + <location filename="../../ui/certifications_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Formulário</translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="20"/> + <source>Certifications</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="33"/> + <source>loading...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="63"/> + <source>dd/MM/yyyy</source> + <translation type="unfinished">dd/MM/yyyy</translation> + </message> +</context> +<context> + <name>menu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="57"/> + <source>Certify identity</source> + <translation type="unfinished">Certificar identidade</translation> + </message> +</context> +<context> + <name>menu.qmenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="42"/> + <source>Informations</source> + <translation type="unfinished">Informações</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="47"/> + <source>Add as contact</source> + <translation type="unfinished">Adicionar como contato</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="52"/> + <source>Send money</source> + <translation type="unfinished">Enviar dinheiro</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="61"/> + <source>View in Web of Trust</source> + <translation type="unfinished">Ver na Rede de Confiança</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="65"/> + <source>Copy pubkey to clipboard</source> + <translation type="unfinished">Copiar chave pública para a área de transferência</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="70"/> + <source>Copy membership document to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="74"/> + <source>Copy self-certification document to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="84"/> + <source>Transfer</source> + <translation type="unfinished">Transferência</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="86"/> + <source>Send again</source> + <translation type="unfinished">Enviar novamente</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="90"/> + <source>Cancel</source> + <translation type="unfinished">Cancelar</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="95"/> + <source>Copy raw transaction to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="100"/> + <source>Copy transaction block to clipboard</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>self.config_dialog</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="191"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="204"/> <source>Ok</source> <translation>Ok</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="70"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="72"/> <source>Forbidden : salt is too short</source> <translation>Não permitido: o CryptoID (salt) é muito curto</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="74"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="76"/> <source>Forbidden : password is too short</source> <translation>Não permitido: a senha é muito curta</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="78"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="80"/> <source>Forbidden : Invalid characters in salt field</source> <translation>Não permitido: caracteres inválidos no campo do CryptoID (salt)</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="82"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="84"/> <source>Forbidden : Invalid characters in password field</source> <translation>Não permitido: caracteres inválidos no campo da senha</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="88"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="90"/> <source>Error : passwords are different</source> <translation>Erro: as senhas são diferentes</translation> </message> @@ -2752,7 +3271,7 @@ Revogar seu UID somente funcionará caso ele ainda não tenha sido validado pela <translation>Formulário</translation> </message> <message> - <location filename="../../ui/transactions_tab.ui" line="63"/> + <location filename="../../ui/transactions_tab.ui" line="66"/> <source>dd/MM/yyyy</source> <translation>dd/MM/yyyy</translation> </message> diff --git a/res/i18n/ts/ru_RU.ts b/res/i18n/ts/ru_RU.ts index d7172712d4868064d960f8408016c3b333bfbe84..44cb16d40dff112121159493f91ca7ab7f8dd7be 100644 --- a/res/i18n/ts/ru_RU.ts +++ b/res/i18n/ts/ru_RU.ts @@ -41,10 +41,25 @@ <translation type="obsolete">Относит. Z-сумма</translation> </message> <message> - <location filename="../../../src/sakia/core/account.py" line="510"/> + <location filename="../../../src/sakia/core/account.py" line="540"/> <source>Could not find user self certification.</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="67"/> + <source>Warning : Your membership is expiring soon.</source> + <translation type="unfinished">Внимание: срок вашего членства скоро закончится.</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="72"/> + <source>Warning : Your could miss certifications soon.</source> + <translation type="unfinished">Внимание: скоро вы можете пропустить сертификацию</translation> + </message> + <message> + <location filename="../../../src/sakia/core/account.py" line="77"/> + <source>Warning : If you don't renew soon, your identity will be considerd revoked.</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>AccountConfigurationDialog</name> @@ -78,11 +93,6 @@ <source>Key parameters</source> <translation>Ключевые параметры</translation> </message> - <message> - <location filename="../../ui/account_cfg.ui" line="143"/> - <source>CryptoID</source> - <translation></translation> - </message> <message> <location filename="../../ui/account_cfg.ui" line="153"/> <source>Your password</source> @@ -123,49 +133,54 @@ <source>Communities</source> <translation>Cообществ</translation> </message> + <message> + <location filename="../../ui/account_cfg.ui" line="143"/> + <source>Entropy</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Application</name> <message> <location filename="../../../src/sakia/core/app.py" line="76"/> <source>Warning : Your membership is expiring soon.</source> - <translation type="unfinished">Внимание: срок вашего членства скоро закончится.</translation> + <translation type="obsolete">Внимание: срок вашего членства скоро закончится.</translation> </message> <message> <location filename="../../../src/sakia/core/app.py" line="81"/> <source>Warning : Your could miss certifications soon.</source> - <translation type="unfinished">Внимание: скоро вы можете пропустить сертификацию</translation> + <translation type="obsolete">Внимание: скоро вы можете пропустить сертификацию</translation> </message> </context> <context> <name>CertificationDialog</name> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Certification</source> <translation>Сертификация</translation> </message> <message> - <location filename="../../ui/certification.ui" line="20"/> + <location filename="../../ui/certification.ui" line="26"/> <source>Community</source> <translation>Сообщество</translation> </message> <message> - <location filename="../../ui/certification.ui" line="32"/> + <location filename="../../ui/certification.ui" line="54"/> <source>Certify user</source> <translation>Сертифицировать пользователя</translation> </message> <message> <location filename="../../ui/certification.ui" line="40"/> <source>Contact</source> - <translation>Контакт</translation> + <translation type="obsolete">Контакт</translation> </message> <message> <location filename="../../ui/certification.ui" line="61"/> <source>User public key</source> - <translation>Открытый ключ пользователя</translation> + <translation type="obsolete">Открытый ключ пользователя</translation> </message> <message> - <location filename="../../ui/certification.ui" line="80"/> + <location filename="../../ui/certification.ui" line="157"/> <source>Key</source> <translation>Ключ</translation> </message> @@ -190,25 +205,75 @@ <translation type="obsolete">ОК</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="112"/> + <location filename="../../../src/sakia/gui/certification.py" line="227"/> <source>Not a member</source> <translation>Не член</translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="109"/> + <location filename="../../../src/sakia/gui/certification.py" line="221"/> <source>&Ok</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="75"/> + <location filename="../../../src/sakia/gui/certification.py" line="126"/> <source>Success sending certification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/certification.py" line="84"/> + <location filename="../../../src/sakia/gui/certification.py" line="135"/> <source>Could not broadcast certification : {0}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/certification.ui" line="73"/> + <source>Con&tact</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="116"/> + <source>&User public key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="35"/> + <source>Certifications stock</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/certification.ui" line="177"/> + <source>Sea&rch user</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="197"/> + <source>Certifications sent : {nb_certifications}/{stock}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="206"/> + <source>{days} days</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="208"/> + <source>{hours} hours and {min} min.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="210"/> + <source>Remaining time before next certification validation : {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="217"/> + <source> (Not validated before </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/certification.py" line="224"/> + <source>No more certifications</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityConfigurationDialog</name> @@ -243,17 +308,17 @@ <translation>Cервер</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="200"/> + <location filename="../../ui/community_cfg.ui" line="203"/> <source>Add</source> <translation>Добавить</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="221"/> + <location filename="../../ui/community_cfg.ui" line="224"/> <source>Previous</source> <translation type="unfinished">Предыдущий</translation> </message> <message> - <location filename="../../ui/community_cfg.ui" line="244"/> + <location filename="../../ui/community_cfg.ui" line="247"/> <source>Next</source> <translation type="unfinished">Следующий</translation> </message> @@ -364,45 +429,80 @@ <context> <name>CommunityTile</name> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="81"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Member</source> <translation type="unfinished">Член</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="82"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="123"/> <source>Non-Member</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>members</source> <translation>членами</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Monetary mass</source> <translation>Денежная масса</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Status</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="93"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> <source>Balance</source> <translation>Баланс</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="112"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="162"/> <source>Not connected</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_tile.py" line="125"/> + <location filename="../../../src/sakia/gui/community_tile.py" line="175"/> <source>Community not initialized</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="100"/> + <source>Expired or never published</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="101"/> + <source>Outdistanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="110"/> + <source>In WoT range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="116"/> + <source>Expires in </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="124"/> + <source>#FF0000</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Certs. received</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_tile.py" line="137"/> + <source>Membership</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>CommunityWidget</name> @@ -422,7 +522,7 @@ <translation type="unfinished">Сертификация</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="289"/> + <location filename="../../../src/sakia/gui/community_view.py" line="286"/> <source>Renew membership</source> <translation>Обновить членство</translation> </message> @@ -437,62 +537,57 @@ <translation type="obsolete">Внимание: скоро вы можете пропустить сертификацию</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="34"/> + <location filename="../../../src/sakia/gui/community_view.py" line="33"/> <source>Transactions</source> <translation type="unfinished">Операции</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <location filename="../../../src/sakia/gui/community_view.py" line="34"/> <source>Web of Trust</source> <translation type="unfinished">Сеть доверия</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="37"/> + <location filename="../../../src/sakia/gui/community_view.py" line="90"/> <source>Network</source> <translation type="unfinished">Сеть</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source>Membership expiration</source> <translation type="unfinished">Истечение срока членства</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="184"/> + <location filename="../../../src/sakia/gui/community_view.py" line="191"/> <source><b>Warning : Membership expiration in {0} days</b></source> <translation type="unfinished"><b>Внимание: срок членства истекает через {0} дней</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source>Certifications number</source> <translation type="unfinished">Номер сертификации</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="195"/> + <location filename="../../../src/sakia/gui/community_view.py" line="202"/> <source><b>Warning : You are certified by only {0} persons, need {1}</b></source> <translation type="unfinished"><b>Внимание: вы сертифицированы только {0} людьми, требуется {1}</b></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="228"/> + <location filename="../../../src/sakia/gui/community_view.py" line="235"/> <source> Block {0}</source> - <translation type="unfinished"> Блокировать {0}</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/community_view.py" line="270"/> - <source> - Median fork window : {0}</source> - <translation type="unfinished"></translation> + <translation type="obsolete"> Блокировать {0}</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="295"/> + <location filename="../../../src/sakia/gui/community_view.py" line="292"/> <source>Send membership demand</source> <translation>Отправить запрос о членстве</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Warning</source> <translation>Внимание</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="341"/> + <location filename="../../../src/sakia/gui/community_view.py" line="336"/> <source>Are you sure ? Sending a leaving demand cannot be canceled. The process to join back the community later will have to be done again.</source> @@ -513,7 +608,7 @@ Publishing your UID can be canceled by Revoke UID.</source> <translation type="obsolete">Публикация ИДП</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="375"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Success publishing your UID</source> <translation>Ваш ИДП успешно опубликован</translation> </message> @@ -545,22 +640,22 @@ Revoking your UID can only success if it is not already validated by the network Отмена ИДП может быть успешна, только если она еще не подтверждена сетью.</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> + <location filename="../../../src/sakia/gui/community_view.py" line="369"/> <source>Membership</source> <translation>членстве</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="329"/> + <location filename="../../../src/sakia/gui/community_view.py" line="325"/> <source>Success sending Membership demand</source> <translation type="unfinished">Заявка о членстве отправлена успешно</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="361"/> + <location filename="../../../src/sakia/gui/community_view.py" line="356"/> <source>Revoke</source> <translation type="unfinished">Отмена</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="355"/> + <location filename="../../../src/sakia/gui/community_view.py" line="350"/> <source>Success sending Revoke demand</source> <translation type="unfinished">Заявка об отмене отправлена успешно</translation> </message> @@ -575,12 +670,12 @@ Revoking your UID can only success if it is not already validated by the network <translation type="obsolete">Самостоятельная сертификация успешно</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <location filename="../../../src/sakia/gui/community_view.py" line="94"/> <source>Show informations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="38"/> + <location filename="../../../src/sakia/gui/community_view.py" line="95"/> <source>Informations</source> <translation type="unfinished">Данные</translation> </message> @@ -590,23 +685,38 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="399"/> + <location filename="../../../src/sakia/gui/community_view.py" line="41"/> <source>Revoke UID</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="401"/> + <location filename="../../../src/sakia/gui/community_view.py" line="375"/> <source>UID</source> <translation type="unfinished">ИДП</translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="395"/> - <source>Your UID was revoked successfully.</source> + <location filename="../../../src/sakia/gui/community_view.py" line="35"/> + <source>Search Identities</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="39"/> + <source>Explore the Web of Trust</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="99"/> + <source>Show explorer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/community_view.py" line="36"/> - <source>Search Identities</source> + <location filename="../../../src/sakia/gui/community_view.py" line="100"/> + <source>Explorer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/community_view.py" line="234"/> + <source>Block {0}</source> <translation type="unfinished"></translation> </message> </context> @@ -628,11 +738,25 @@ Revoking your UID can only success if it is not already validated by the network <translation>Открытый ключ</translation> </message> <message> - <location filename="../../../src/sakia/gui/contact.py" line="52"/> + <location filename="../../../src/sakia/gui/contact.py" line="81"/> <source>Contact already exists</source> <translation>Контакт уже существует</translation> </message> </context> +<context> + <name>ContextMenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Warning</source> + <translation type="unfinished">Внимание</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="165"/> + <source>Are you sure ? +This money transfer will be removed and not sent.</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>CreateWalletDialog</name> <message> @@ -729,48 +853,147 @@ Revoking your UID can only success if it is not already validated by the network <message> <location filename="../../ui/member.ui" line="14"/> <source>Informations</source> - <translation>Данные</translation> + <translation type="obsolete">Данные</translation> </message> <message> <location filename="../../ui/member.ui" line="34"/> <source>Member</source> - <translation>Член</translation> + <translation type="obsolete">Член</translation> </message> <message> <location filename="../../ui/member.ui" line="65"/> <source>uid</source> - <translation>ИДП</translation> + <translation type="obsolete">ИДП</translation> </message> <message> <location filename="../../ui/member.ui" line="72"/> <source>properties</source> - <translation>Свойства</translation> + <translation type="obsolete">Свойства</translation> + </message> +</context> +<context> + <name>DividendPerDay</name> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="9"/> + <source>UDD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="10"/> + <source>{0} {1}UDD {2}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="11"/> + <source>UDD {0}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/dividend_per_day.py" line="12"/> + <source>UDD(t) = (Q * 100) / (UD(t) / DT) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>ExplorerTabWidget</name> + <message> + <location filename="../../ui/explorer_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Формуляр</translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="48"/> + <source>Steps</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/explorer_tab.ui" line="65"/> + <source>Go</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>GraphTabWidget</name> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="71"/> + <source>Membership</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="89"/> + <source>Last renewal on {:}, expiration on {:}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Your web of trust</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Certified by {:} members; Certifier of {:} members</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source>Not a member</source> + <translation type="unfinished">Не член</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/graphs/graph_tab.py" line="107"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> </message> </context> <context> <name>HistoryTableModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Date</source> <translation>Дата</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>UID/Public key</source> <translation>ИДП / Открытый ключ</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Payment</source> <translation>Оплата</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Deposit</source> <translation>Депозит</translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="206"/> + <location filename="../../../src/sakia/models/txhistory.py" line="205"/> <source>Comment</source> <translation>Комментарий</translation> </message> @@ -882,73 +1105,78 @@ Revoking your UID can only success if it is not already validated by the network <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="36"/> <source>Members</source> - <translation>Пользователи</translation> + <translation type="obsolete">Пользователи</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="37"/> <source>Direct connections</source> - <translation>Прямые связи</translation> + <translation type="obsolete">Прямые связи</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="112"/> <source>Informations</source> - <translation>Данные</translation> + <translation type="obsolete">Данные</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="115"/> <source>Add as contact</source> - <translation>Добавить контакт</translation> + <translation type="obsolete">Добавить контакт</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="119"/> <source>Send money</source> - <translation>Отправить деньги</translation> + <translation type="obsolete">Отправить деньги</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="123"/> <source>Certify identity</source> - <translation>Удостоверить личность</translation> + <translation type="obsolete">Удостоверить личность</translation> </message> <message> <location filename="../../../src/sakia/gui/identities_tab.py" line="127"/> <source>View in Web of Trust</source> - <translation>Посмотреть в Сети доверия</translation> + <translation type="obsolete">Посмотреть в Сети доверия</translation> </message> <message> - <location filename="../../../src/sakia/gui/identities_tab.py" line="131"/> - <source>Copy pubkey</source> + <location filename="../../../src/sakia/gui/identities_tab.py" line="32"/> + <source>Search direct certifications</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/identities_tab.py" line="33"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Исследовать открытый ключ, ИДП ...</translation> + </message> </context> <context> <name>IdentitiesTableModel</name> <message> - <location filename="../../../src/sakia/models/identities.py" line="89"/> + <location filename="../../../src/sakia/models/identities.py" line="118"/> <source>UID</source> <translation>ИДП</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="90"/> + <location filename="../../../src/sakia/models/identities.py" line="119"/> <source>Pubkey</source> <translation>Открытый ключ</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="91"/> + <location filename="../../../src/sakia/models/identities.py" line="120"/> <source>Renewed</source> <translation>Обновлено</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="92"/> + <location filename="../../../src/sakia/models/identities.py" line="121"/> <source>Expiration</source> <translation>Истечение срока</translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="94"/> + <location filename="../../../src/sakia/models/identities.py" line="123"/> <source>Validation</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/identities.py" line="93"/> + <location filename="../../../src/sakia/models/identities.py" line="122"/> <source>Publication</source> <translation type="unfinished"></translation> </message> @@ -1059,47 +1287,47 @@ Revoking your UID can only success if it is not already validated by the network <translation type="obsolete">ярлык_сд</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Universal Dividend UD(t) in</source> <translation>Универсальный дивиденд УД(t) в</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass M(t-1) in</source> <translation>Денежная масса M(t-1) в</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Members N(t)</source> <translation>Члены N(t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Monetary Mass per member M(t-1)/N(t) in</source> <translation>Денежная масса на члена M(t-1)/N(t) в</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Actual growth c = UD(t)/[M(t-1)/N(t)]</source> <translation>Фактический рост c = UD(t)/[M(t-1)/N(t)]</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Last UD date and time (t)</source> <translation>Дата и время последнего УД (t)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Next UD date and time (t+1)</source> <translation>Дата и время следующего УД (t+1)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="194"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="196"/> <source>No Universal Dividend created yet.</source> <translation>Универсальный дивиденд еще не создан.</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> @@ -1110,37 +1338,37 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:2.0%} / {:} days</source> <translation>{:2.0%} / {:} дней</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Fundamental growth (c) / Delta time (dt)</source> <translation>Основной рост (c) / Дельта времени (dt)</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>UD(t+1) = MAX { UD(t) ; c &#215; M(t) / N(t+1) }</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (formula)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>{:} = MAX {{ {:} {:} ; {:2.0%} &#215; {:} {:} / {:} }}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="169"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="171"/> <source>Universal Dividend (computed)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:2.0%} / {:} days</b></td><td>{:}</td></tr> @@ -1156,91 +1384,67 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Fundamental growth (c)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Initial Universal Dividend UD(0) in</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Time period (dt) in days (86400 seconds) between two UD</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>Number of blocks used for calculating median time</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The average time in seconds for writing 1 block (wished time)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of blocks required to evaluate again PoWMin value</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The number of previous blocks to check for personalized difficulty</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="217"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="223"/> <source>The percent of previous issuers to reach for personalized difficulty</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> - <source>Minimum delay between 2 identical certifications (in days)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid signature (in days)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Minimum quantity of signatures to be part of the WoT</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> - <source>Minimum quantity of valid made certifications to be part of the WoT for distance rule</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum age of a valid membership (in days)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="252"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> <source>Maximum distance between each WoT member and a newcomer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source> <table cellpadding="5"> <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr> @@ -1256,7 +1460,7 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="115"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="119"/> <source>Penultimate UD date and time (t-1)</source> <translation type="unfinished"></translation> </message> @@ -1266,25 +1470,61 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Name</source> <translation type="unfinished">Имя</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Units</source> <translation type="unfinished">Единицы</translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Formula</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/informations_tab.py" line="207"/> + <location filename="../../../src/sakia/gui/informations_tab.py" line="213"/> <source>Description</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + </table> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum delay between 2 certifications (in days)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum quantity of active certifications made by member.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Maximum delay a certification can wait before being expired for non-writing.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/informations_tab.py" line="258"/> + <source>Minimum percent of sentries to reach to match the distance rule</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>MainWindow</name> @@ -1294,7 +1534,7 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="131"/> + <location filename="../../ui/mainwindow.ui" line="138"/> <source>Account</source> <translation type="unfinished"></translation> </message> @@ -1309,117 +1549,117 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="76"/> + <location filename="../../ui/mainwindow.ui" line="83"/> <source>Manage accounts</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="81"/> + <location filename="../../ui/mainwindow.ui" line="88"/> <source>Configure trustable nodes</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="106"/> + <location filename="../../ui/mainwindow.ui" line="113"/> <source>Send a message</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="111"/> + <location filename="../../ui/mainwindow.ui" line="118"/> <source>Send money</source> <translation type="unfinished">Отправить деньги</translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="116"/> + <location filename="../../ui/mainwindow.ui" line="123"/> <source>Remove contact</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="121"/> + <location filename="../../ui/mainwindow.ui" line="128"/> <source>Save</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="126"/> + <location filename="../../ui/mainwindow.ui" line="133"/> <source>&Quit</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="136"/> + <location filename="../../ui/mainwindow.ui" line="143"/> <source>&Transfer money</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="141"/> + <location filename="../../ui/mainwindow.ui" line="148"/> <source>&Configure</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="146"/> + <location filename="../../ui/mainwindow.ui" line="153"/> <source>&Import</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="151"/> + <location filename="../../ui/mainwindow.ui" line="158"/> <source>&Export</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="161"/> + <location filename="../../ui/mainwindow.ui" line="168"/> <source>&Set as default</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="166"/> + <location filename="../../ui/mainwindow.ui" line="173"/> <source>A&bout</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="171"/> + <location filename="../../ui/mainwindow.ui" line="178"/> <source>&Preferences</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="176"/> + <location filename="../../ui/mainwindow.ui" line="183"/> <source>&Add account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="211"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="285"/> <source>Latest release : {version}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="218"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="292"/> <source>Download link</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="251"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="326"/> <source>Please get the latest release {version}</source> <translation type="unfinished">Пожалуйста, получите последний выпуск {version}</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="283"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="358"/> <source>Edit</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="286"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="361"/> <source>Delete</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="348"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="424"/> <source>Export an account</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="349"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="425"/> <source>All account files (*.acc)</source> <translation type="unfinished">Все файлы аккаунта (*.acc)</translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="350"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="426"/> <source>Export</source> <translation type="unfinished"></translation> </message> @@ -1434,151 +1674,186 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="86"/> + <location filename="../../ui/mainwindow.ui" line="93"/> <source>A&dd a contact</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/mainwindow.ui" line="156"/> + <location filename="../../ui/mainwindow.ui" line="163"/> <source>C&ertification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="225"/> - <source> - <h1>sakia</h1> - - <p>Python/Qt uCoin client</p> - - <p>Version : {:}</p> - {new_version_text} - - <p>License : GPLv3</p> - - <p><b>Authors</b></p> - - <p>inso</p> - <p>vit</p> - <p>Moul</p> - <p>canercandan</p> - </source> + <location filename="../../../src/sakia/gui/mainwindow.py" line="383"/> + <source>sakia {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="303"/> - <source>sakia {0}</source> + <location filename="../../../src/sakia/gui/mainwindow.py" line="407"/> + <source>sakia {0} - Account : {1}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/mainwindow.py" line="330"/> - <source>sakia {0} - Account : {1}</source> + <location filename="../../ui/mainwindow.ui" line="71"/> + <source>&Duniter</source> <translation type="unfinished"></translation> </message> -</context> -<context> - <name>MemberDialog</name> <message> - <location filename="../../../src/sakia/gui/member.py" line="46"/> - <source>not a member</source> + <location filename="../../ui/mainwindow.ui" line="188"/> + <source>&Manage local node</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="60"/> + <location filename="../../../src/sakia/gui/mainwindow.py" line="299"/> <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> - </source> + <h1>sakia</h1> + + <p>Python/Qt duniter client</p> + <p><a href="https://github.com/duniter/sakia">https://github.com/duniter/sakia</a></p> + + <p>Version : {:}</p> + {new_version_text} + + <p>License : GPLv3</p> + + <p><b>Authors</b></p> + + <p>inso</p> + <p>vit</p> + <p>Moul</p> + <p>canercandan</p> + </source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MemberDialog</name> + <message> + <location filename="../../../src/sakia/gui/member.py" line="73"/> + <source>not a member</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Public key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="64"/> + <location filename="../../../src/sakia/gui/member.py" line="97"/> <source>Join date</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="87"/> + <location filename="../../../src/sakia/gui/member.py" line="144"/> <source><tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="73"/> + <location filename="../../../src/sakia/gui/member.py" line="130"/> <source>Distance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/member.py" line="80"/> + <location filename="../../../src/sakia/gui/member.py" line="139"/> <source>Path</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="92"/> + <source> + <table cellpadding="5"> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></div></td><td>{:}</td></tr> + </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/member.py" line="97"/> + <source>UID Published on</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MemberView</name> + <message> + <location filename="../../ui/member.ui" line="14"/> + <source>Member informations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../ui/member.ui" line="34"/> + <source>Member</source> + <translation type="unfinished">Член</translation> + </message> </context> <context> <name>NetworkFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="48"/> + <location filename="../../../src/sakia/models/network.py" line="54"/> <source>Address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="49"/> + <location filename="../../../src/sakia/models/network.py" line="55"/> <source>Port</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="50"/> + <location filename="../../../src/sakia/models/network.py" line="56"/> <source>Block</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="52"/> + <location filename="../../../src/sakia/models/network.py" line="59"/> <source>UID</source> <translation type="unfinished">ИДП</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="53"/> + <location filename="../../../src/sakia/models/network.py" line="60"/> <source>Member</source> <translation type="unfinished">Член</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="54"/> + <location filename="../../../src/sakia/models/network.py" line="61"/> <source>Pubkey</source> <translation type="unfinished">Открытый ключ</translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="55"/> + <location filename="../../../src/sakia/models/network.py" line="62"/> <source>Software</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="56"/> + <location filename="../../../src/sakia/models/network.py" line="63"/> <source>Version</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>yes</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>no</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="69"/> + <location filename="../../../src/sakia/models/network.py" line="77"/> <source>offline</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="51"/> + <location filename="../../../src/sakia/models/network.py" line="57"/> <source>Hash</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/models/network.py" line="58"/> + <source>Time</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>NetworkTabWidget</name> @@ -1588,17 +1863,17 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished">Формуляр</translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="70"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="72"/> <source>Unset root node</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="76"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="78"/> <source>Set as root node</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/network_tab.py" line="82"/> + <location filename="../../../src/sakia/gui/network_tab.py" line="84"/> <source>Open in browser</source> <translation type="unfinished"></translation> </message> @@ -1606,26 +1881,34 @@ Revoking your UID can only success if it is not already validated by the network <context> <name>NetworkTableModel</name> <message> - <location filename="../../../src/sakia/models/network.py" line="136"/> + <location filename="../../../src/sakia/models/network.py" line="155"/> <source>Online</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="137"/> + <location filename="../../../src/sakia/models/network.py" line="156"/> <source>Offline</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="138"/> + <location filename="../../../src/sakia/models/network.py" line="157"/> <source>Unsynchronized</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/network.py" line="139"/> + <location filename="../../../src/sakia/models/network.py" line="158"/> <source>Corrupted</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>NodeManager</name> + <message> + <location filename="../../ui/node_manager.ui" line="14"/> + <source>Node manager</source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>PasswordAskerDialog</name> <message> @@ -1644,22 +1927,22 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Bad password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="66"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> <source>Non printable characters in password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Failed to get private key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/password_asker.py" line="72"/> + <location filename="../../../src/sakia/gui/password_asker.py" line="78"/> <source>Wrong password typed. Cannot open the private key</source> <translation type="unfinished"></translation> </message> @@ -1722,86 +2005,91 @@ Revoking your UID can only success if it is not already validated by the network <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="329"/> + <location filename="../../ui/preferences.ui" line="356"/> <source><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Network settings</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="345"/> + <location filename="../../ui/preferences.ui" line="372"/> <source>Proxy server address : </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="355"/> + <location filename="../../ui/preferences.ui" line="382"/> <source>:</source> <translation type="unfinished">:</translation> </message> <message> - <location filename="../../ui/preferences.ui" line="336"/> + <location filename="../../ui/preferences.ui" line="363"/> <source>Use a http proxy server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/preferences.ui" line="379"/> + <location filename="../../ui/preferences.ui" line="406"/> <source>Automatically refresh identities informations</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/preferences.ui" line="330"/> + <source>Enable forgetfulness</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>ProcessConfigureAccount</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="163"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="165"/> <source>New account</source> <translation type="unfinished">новый аккаунт</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="170"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="175"/> <source>Configure {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="185"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="190"/> <source>Ok</source> <translation type="unfinished">ОК</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> <source>Warning</source> <translation type="unfinished">Внимание</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="220"/> - <source>This action will delete your account locally. + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="249"/> + <source>Error</source> + <translation type="unfinished">Ошибка</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="226"/> + <source>This action will delete your account ({0}) locally. Please note your key parameters (salt and password) if you wish to recover it later. Your account won't be removed from the networks it joined. Are you sure ?</source> <translation type="unfinished"></translation> </message> - <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="243"/> - <source>Error</source> - <translation type="unfinished">Ошибка</translation> - </message> </context> <context> <name>ProcessConfigureCommunity</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="227"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="240"/> <source>Configure community {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="230"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="243"/> <source>Add a community</source> <translation type="unfinished">Добавить сообщество</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="264"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="276"/> <source>Error</source> <translation type="unfinished">Ошибка</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="293"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="305"/> <source>Delete</source> <translation type="unfinished"></translation> </message> @@ -1852,13 +2140,13 @@ Are you sure ?</source> <translation type="unfinished">Колич. Z-сумма</translation> </message> <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> - <source>{0} Q0 {1}</source> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> + <source>Q0 {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="9"/> - <source>Q0 {0}</source> + <location filename="../../../src/sakia/core/money/quant_zerosum.py" line="8"/> + <source>{0} {1}Q0 {2}</source> <translation type="unfinished"></translation> </message> <message> @@ -1879,22 +2167,22 @@ Are you sure ?</source> <context> <name>Relative</name> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="7"/> + <location filename="../../../src/sakia/core/money/relative.py" line="9"/> <source>UD</source> <translation type="unfinished">УД</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="8"/> + <location filename="../../../src/sakia/core/money/relative.py" line="10"/> <source>{0} {1}UD {2}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="9"/> + <location filename="../../../src/sakia/core/money/relative.py" line="11"/> <source>UD {0}</source> <translation type="unfinished">УД {0}</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative.py" line="10"/> + <location filename="../../../src/sakia/core/money/relative.py" line="12"/> <source>R = Q / UD(t) <br > <table> @@ -1906,6 +2194,36 @@ Are you sure ?</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>RelativeToPast</name> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="6"/> + <source>Past UD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="7"/> + <source>{0} {1}UD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="8"/> + <source>UD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/relative_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Relative value</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + </table></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>RelativeZSum</name> <message> @@ -1914,13 +2232,13 @@ Are you sure ?</source> <translation type="unfinished">Относит. Z-сумма</translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> - <source>{0} R0 {1}</source> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> + <source>R0 {0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="9"/> - <source>R0 {0}</source> + <location filename="../../../src/sakia/core/money/relative_zerosum.py" line="8"/> + <source>{0} {1}R0 {2}</source> <translation type="unfinished"></translation> </message> <message> @@ -1939,37 +2257,47 @@ Are you sure ?</source> </message> </context> <context> - <name>Scene</name> + <name>SearchUserWidget</name> + <message> + <location filename="../../ui/search_user_view.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Формуляр</translation> + </message> <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="158"/> - <source>Certification expires at {0}</source> + <location filename="../../ui/search_user_view.ui" line="33"/> + <source>Center the view on me</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/widgets/search_user.py" line="15"/> + <source>Research a pubkey, an uid...</source> + <translation type="unfinished">Исследовать открытый ключ, ИДП ...</translation> + </message> </context> <context> <name>StepPageInit</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="95"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="101"/> <source>Could not find your identity on the network.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="127"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> <source>Broadcasting identity...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>UID broadcast</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="131"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> <source>Identity broadcasted to the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>Error</source> <translation type="unfinished">Ошибка</translation> </message> @@ -1979,27 +2307,42 @@ Are you sure ?</source> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="138"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="149"/> <source>{0}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="142"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="153"/> <source>Your pubkey or UID was already found on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="145"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="156"/> <source>Your account already exists on the network</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="97"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="103"/> <source>Your pubkey or UID is different on the network. Yours : {0}, the network : {1}</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="124"/> + <source>connecting...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="164"/> + <source>Could not connect. Check hostname, ip address or port</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="162"/> + <source>Could not connect. Check node peering entry</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Toast</name> @@ -2016,59 +2359,33 @@ Yours : {0}, the network : {1}</source> <source>New transactions received</source> <translation type="unfinished"></translation> </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="175"/> - <source>Actions</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="190"/> - <source>Send again</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="195"/> - <source>Cancel</source> - <translation type="unfinished"></translation> - </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="201"/> <source>Informations</source> - <translation type="unfinished">Данные</translation> + <translation type="obsolete">Данные</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="206"/> <source>Add as contact</source> - <translation type="unfinished">Добавить контакт</translation> + <translation type="obsolete">Добавить контакт</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="211"/> <source>Send money</source> - <translation type="unfinished">Отправить деньги</translation> + <translation type="obsolete">Отправить деньги</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="217"/> <source>View in Web of Trust</source> - <translation type="unfinished">Посмотреть в Сети доверия</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="222"/> - <source>Copy pubkey to clipboard</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Посмотреть в Сети доверия</translation> </message> <message> <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> <source>Warning</source> - <translation type="unfinished">Внимание</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="288"/> - <source>Are you sure ? -This money transfer will be removed and not sent.</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Внимание</translation> </message> <message> - <location filename="../../../src/sakia/gui/transactions_tab.py" line="160"/> + <location filename="../../../src/sakia/gui/transactions_tab.py" line="159"/> <source>{:}</source> <translation type="unfinished"></translation> </message> @@ -2101,37 +2418,37 @@ This money transfer will be removed and not sent.</source> <translation type="obsolete">Контакт</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="80"/> + <location filename="../../ui/transfer.ui" line="136"/> <source>Key</source> <translation type="unfinished">Ключ</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="148"/> + <location filename="../../ui/transfer.ui" line="250"/> <source> UD</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="166"/> + <location filename="../../ui/transfer.ui" line="268"/> <source>Transaction message</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>Money transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="108"/> + <location filename="../../../src/sakia/gui/transfer.py" line="131"/> <source>No amount. Please give the transfert amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="139"/> + <location filename="../../../src/sakia/gui/transfer.py" line="163"/> <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/transfer.py" line="126"/> + <location filename="../../../src/sakia/gui/transfer.py" line="150"/> <source>Success sending money to {0}</source> <translation type="unfinished"></translation> </message> @@ -2146,44 +2463,81 @@ This money transfer will be removed and not sent.</source> <translation type="obsolete">{0} : {1}</translation> </message> <message> - <location filename="../../ui/transfer.ui" line="61"/> + <location filename="../../ui/transfer.ui" line="95"/> <source>&Recipient public key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="106"/> + <location filename="../../ui/transfer.ui" line="208"/> <source>Wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="125"/> + <location filename="../../ui/transfer.ui" line="227"/> <source>Available money : </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="134"/> + <location filename="../../ui/transfer.ui" line="236"/> <source>Amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../ui/transfer.ui" line="40"/> + <location filename="../../ui/transfer.ui" line="46"/> <source>Con&tact</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../../ui/transfer.ui" line="156"/> + <source>S&earch user</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>TxFilterProxyModel</name> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="165"/> + <location filename="../../../src/sakia/models/txhistory.py" line="166"/> <source>{0} / {1} confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/models/txhistory.py" line="169"/> + <location filename="../../../src/sakia/models/txhistory.py" line="170"/> <source>Confirming... {0} %</source> <translation type="unfinished"></translation> </message> </context> +<context> + <name>UDDToPast</name> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="6"/> + <source>Past UUD</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="7"/> + <source>{0} {1}UUD({2}) {3}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="8"/> + <source>UUD({0}) {1}</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/core/money/udd_to_past.py" line="9"/> + <source>R = Q / UD(t) + <br > + <table> + <tr><td>R</td><td>Dividend per day in percent</td></tr> + <tr><td>t</td><td>Last UD time</td></tr> + <tr><td>Q</td><td>Quantitative value</td></tr> + <tr><td>UD</td><td>Universal Dividend</td></tr> + <tr><td>t</td><td>Time when the value appeared</td></tr> + <tr><td>DT</td><td>Delay between two UD in days</td></tr> + </table>></source> + <translation type="unfinished"></translation> + </message> +</context> <context> <name>WalletsTab</name> <message> @@ -2238,27 +2592,22 @@ This money transfer will be removed and not sent.</source> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="294"/> <source>Informations</source> - <translation type="unfinished">Данные</translation> + <translation type="obsolete">Данные</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="299"/> <source>Add as contact</source> - <translation type="unfinished">Добавить контакт</translation> + <translation type="obsolete">Добавить контакт</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="304"/> <source>Send money</source> - <translation type="unfinished">Отправить деньги</translation> + <translation type="obsolete">Отправить деньги</translation> </message> <message> <location filename="../../../src/sakia/gui/views/wot.py" line="309"/> <source>Certify identity</source> - <translation type="unfinished">Удостоверить личность</translation> - </message> - <message> - <location filename="../../../src/sakia/gui/views/wot.py" line="314"/> - <source>Copy pubkey</source> - <translation type="unfinished"></translation> + <translation type="obsolete">Удостоверить личность</translation> </message> </context> <context> @@ -2269,92 +2618,139 @@ This money transfer will be removed and not sent.</source> <translation type="unfinished">Формуляр</translation> </message> <message> - <location filename="../../ui/wot_tab.ui" line="33"/> - <source>Center the view on me</source> + <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> + <source>Research a pubkey, an uid...</source> + <translation type="obsolete">Исследовать открытый ключ, ИДП ...</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/wot_tab.py" line="158"/> + <source>Not a member</source> + <translation type="obsolete">Не член</translation> + </message> +</context> +<context> + <name>certificationsTabWidget</name> + <message> + <location filename="../../ui/certifications_tab.ui" line="14"/> + <source>Form</source> + <translation type="unfinished">Формуляр</translation> + </message> + <message> + <location filename="../../ui/certifications_tab.ui" line="20"/> + <source>Certifications</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="25"/> - <source>Research a pubkey, an uid...</source> - <translation type="unfinished">Исследовать открытый ключ, ИДП ...</translation> + <location filename="../../ui/certifications_tab.ui" line="33"/> + <source>loading...</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - </source> + <location filename="../../ui/certifications_tab.ui" line="63"/> + <source>dd/MM/yyyy</source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>menu</name> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="126"/> - <source>Membership</source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="57"/> + <source>Certify identity</source> + <translation type="unfinished">Удостоверить личность</translation> + </message> +</context> +<context> + <name>menu.qmenu</name> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="42"/> + <source>Informations</source> + <translation type="unfinished">Данные</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="47"/> + <source>Add as contact</source> + <translation type="unfinished">Добавить контакт</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="52"/> + <source>Send money</source> + <translation type="unfinished">Отправить деньги</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="61"/> + <source>View in Web of Trust</source> + <translation type="unfinished">Посмотреть в Сети доверия</translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="65"/> + <source>Copy pubkey to clipboard</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="144"/> - <source>Last renewal on {:}, expiration on {:}</source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="70"/> + <source>Copy membership document to clipboard</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source>Your web of trust</source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="74"/> + <source>Copy self-certification document to clipboard</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source>Certified by {:} members; Certifier of {:} members</source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="84"/> + <source>Transfer</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source>Not a member</source> - <translation type="unfinished">Не член</translation> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="86"/> + <source>Send again</source> + <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/wot_tab.py" line="162"/> - <source> - <table cellpadding="5"> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - <tr><td align="right"><b>{:}</b></td></tr> - <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> - </table> - </source> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="90"/> + <source>Cancel</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="95"/> + <source>Copy raw transaction to clipboard</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../../../src/sakia/gui/widgets/context_menu.py" line="100"/> + <source>Copy transaction block to clipboard</source> <translation type="unfinished"></translation> </message> </context> <context> <name>self.config_dialog</name> <message> - <location filename="../../../src/sakia/gui/process_cfg_community.py" line="191"/> + <location filename="../../../src/sakia/gui/process_cfg_community.py" line="204"/> <source>Ok</source> <translation type="unfinished">ОК</translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="70"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="72"/> <source>Forbidden : salt is too short</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="74"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="76"/> <source>Forbidden : password is too short</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="78"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="80"/> <source>Forbidden : Invalid characters in salt field</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="82"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="84"/> <source>Forbidden : Invalid characters in password field</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../../../src/sakia/gui/process_cfg_account.py" line="88"/> + <location filename="../../../src/sakia/gui/process_cfg_account.py" line="90"/> <source>Error : passwords are different</source> <translation type="unfinished"></translation> </message> @@ -2367,7 +2763,7 @@ This money transfer will be removed and not sent.</source> <translation type="unfinished">Формуляр</translation> </message> <message> - <location filename="../../ui/transactions_tab.ui" line="63"/> + <location filename="../../ui/transactions_tab.ui" line="66"/> <source>dd/MM/yyyy</source> <translation type="unfinished"></translation> </message> diff --git a/res/icons/AUTHORS b/res/icons/AUTHORS index ea1311c735ce47045d80a49dabef8c7a7bdebf42..731d6be797da01b666b7fd46eccb692cd08b10f8 100644 --- a/res/icons/AUTHORS +++ b/res/icons/AUTHORS @@ -41,4 +41,5 @@ noun_269792_cc.svg : by TMD noun_269793_cc.svg : by TMD noun_188924_cc.svg : by anbileru adaleru noun_188905_cc.svg : by anbileru adaleru -noun_188906_cc.svg : by anbileru adaleru \ No newline at end of file +noun_188906_cc.svg : by anbileru adaleru +noun_169247_cc.svg : by anbileru adaleru \ No newline at end of file diff --git a/res/icons/icons.qrc b/res/icons/icons.qrc index b889b5abe8699731a8a6ac86e25ca3bacc0c685f..d7193f256f84c7c5be21a3d9fd88e479e19e94f3 100644 --- a/res/icons/icons.qrc +++ b/res/icons/icons.qrc @@ -13,7 +13,7 @@ <file alias="home_icon">iconmonstr-home-icon.svg</file> <file alias="add_account_icon">noun_7440_cc.svg</file> <file alias="sakia_logo">logo.svg</file> - <file alias="ucoin_info_icon">noun_76373_cc.svg</file> + <file alias="duniter_info_icon">noun_76373_cc.svg</file> <file alias="import_icon">noun_62479_cc.svg</file> <file alias="network_icon">noun_21549_cc.svg</file> <file alias="member_icon">iconmonstr-user-icon.svg</file> @@ -42,5 +42,8 @@ <file alias="dividend">noun_188924_cc.svg</file> <file alias="received">noun_188906_cc.svg</file> <file alias="sent">noun_188905_cc.svg</file> + <file alias="lock_open">noun_424413_cc.svg</file> + <file alias="lock_closed">noun_424414_cc.svg</file> + <file alias="revokation">noun_169247_cc.svg</file> </qresource> </RCC> diff --git a/res/icons/logo.svg b/res/icons/logo.svg index fdb2923af0d34e7b9b377387d5593073ec3c3bcf..dcf855e25d356b846a11e00f52ced713acf93c07 100644 --- a/res/icons/logo.svg +++ b/res/icons/logo.svg @@ -16,7 +16,7 @@ version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="logo.svg" - inkscape:export-filename="/home/inso/code/ucoin/sakia/logo.png" + inkscape:export-filename="/home/inso/code/duniter/sakia/logo.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90"> <metadata diff --git a/res/icons/noun_169247_cc.svg b/res/icons/noun_169247_cc.svg new file mode 100644 index 0000000000000000000000000000000000000000..c961d30443648fee01087a6b21cf41e72449bd49 --- /dev/null +++ b/res/icons/noun_169247_cc.svg @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + viewBox="0 0 100 125" + version="1.1" + x="0px" + y="0px" + id="svg2" + inkscape:version="0.91 r13725" + sodipodi:docname="noun_169247_cc.svg"> + <metadata + id="metadata32"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs30" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1366" + inkscape:window-height="711" + id="namedview28" + showgrid="false" + inkscape:zoom="1.888" + inkscape:cx="-17.33691" + inkscape:cy="62.398508" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /> + <g + transform="matrix(1.2399278,0,0,1.2399278,-8.0778253,-1180.1732)" + id="g4"> + <path + d="m 13.35023,958.55845 c 0,27.33333 0,54.66665 0,82.00005 l 40.73828,0 c -0.45628,-0.642 -0.88502,-1.3036 -1.26172,-2 l -37.47656,0 0,-78.00005 58,0 0,49.79495 c 0.67929,0.1242 1.34726,0.2792 2,0.4726 l 0,-52.26755 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.435;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + id="path6" + inkscape:connector-curvature="0" /> + <path + d="m 28.5121,1006.3699 c 0,0.666 0,1.332 0,1.9981 l 31.67774,0 0,-1.9981 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.435;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + id="path8" + inkscape:connector-curvature="0" /> + <path + d="m 28.51234,1014.1815 c 0,0.666 0,1.332 0,1.998 l 27.23242,0 c 0.6729,-0.7192 1.39538,-1.3878 2.16992,-1.998 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.435;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + id="path10" + inkscape:connector-curvature="0" /> + <path + d="m 38.3246,987.88853 0,0.2168 0,6.02734 12.05274,0 0,-6.24414 -1.9961,0 0,4.24609 -8.06054,0 0,-4.24609 -1.9961,0 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.435;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + id="path12" + inkscape:connector-curvature="0" /> + <path + d="m 44.34999,981.55259 c -1.92949,0 -3.51171,1.58223 -3.51171,3.51172 0,1.92949 1.58235,3.51172 3.51171,3.51172 1.92937,0 3.51368,-1.58223 3.51368,-3.51172 0,-1.92949 -1.58418,-3.51172 -3.51368,-3.51172 z m 0,1.99609 c 0.85126,0 1.51563,0.66438 1.51563,1.51563 0,0.85124 -0.66415,1.51562 -1.51563,1.51562 -0.85147,0 -1.51562,-0.66438 -1.51562,-1.51562 0,-0.85125 0.66437,-1.51563 1.51562,-1.51563 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.435;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + id="path14" + inkscape:connector-curvature="0" /> + <path + d="m 44.34999,975.12681 c -7.01092,0 -12.71484,5.70392 -12.71484,12.71484 0,7.01094 5.70392,12.71485 12.71484,12.71485 7.01094,0 12.7168,-5.70391 12.7168,-12.71485 0,-7.01092 -5.70587,-12.71484 -12.7168,-12.71484 z m 0,1.99609 c 5.93161,0 10.71875,4.78716 10.71875,10.71875 0,5.93162 -4.78714,10.71875 -10.71875,10.71875 -5.9316,0 -10.71679,-4.78713 -10.71679,-10.71875 0,-5.93159 4.78519,-10.71875 10.71679,-10.71875 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.435;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + id="path16" + inkscape:connector-curvature="0" /> + <path + d="m 28.51234,1021.992 c 0,0.6661 0,1.3321 0,1.9981 l 22.77343,0 c 0.19808,-0.6813 0.4245,-1.3498 0.69336,-1.9981 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.435;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + id="path18" + inkscape:connector-curvature="0" /> + <path + d="m 44.35083,975.34329 c -6.89303,0 -12.49769,5.60466 -12.49769,12.49768 0,6.89304 5.60466,12.49763 12.49769,12.49763 6.89304,0 12.4977,-5.60459 12.4977,-12.49763 0,-6.89302 -5.60467,-12.49768 -12.4977,-12.49768 z m 0,1.5622 c 6.04875,0 10.93548,4.88674 10.93548,10.93548 0,6.04876 -4.88673,10.93548 -10.93548,10.93548 -6.04875,0 -10.93548,-4.88672 -10.93548,-10.93548 0,-6.04874 4.88673,-10.93548 10.93548,-10.93548 z" + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.435;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + id="path20" + inkscape:connector-curvature="0" /> + <path + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 69.86267,1012.5937 a 16.785713,16.785713 0 0 0 -16.78516,16.7871 16.785713,16.785713 0 0 0 16.78516,16.7851 16.785713,16.785713 0 0 0 16.7871,-16.7851 16.785713,16.785713 0 0 0 -16.7871,-16.7871 z m -4.59571,10.7754 4.59571,4.5957 4.5957,-4.5957 1.41406,1.414 -4.5957,4.5957 4.5957,4.5977 -1.41406,1.414 -4.5957,-4.5957 -4.59571,4.5957 -1.41406,-1.414 4.5957,-4.5977 -4.5957,-4.5957 1.41406,-1.414 z" + id="path22" + inkscape:connector-curvature="0" /> + </g> +</svg> diff --git a/res/icons/noun_424413_cc.svg b/res/icons/noun_424413_cc.svg new file mode 100644 index 0000000000000000000000000000000000000000..b7f825d846916fcb2554a8c5ed42cdaf7a68588f --- /dev/null +++ b/res/icons/noun_424413_cc.svg @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + preserveAspectRatio="none" + x="0px" + y="0px" + viewBox="0 0 100 125" + id="svg2" + inkscape:version="0.91 r13725" + sodipodi:docname="noun_424413_cc.svg"> + <metadata + id="metadata19"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1366" + inkscape:window-height="711" + id="namedview17" + showgrid="false" + inkscape:zoom="1.888" + inkscape:cx="50" + inkscape:cy="62.5" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /> + <defs + id="defs4"> + <g + id="a"> + <path + fill="#000000" + stroke="none" + d=" M 85.35 83.9 L 85.35 52.7 Q 85.35 41.05 73.7 41.05 L 27.4 41.05 Q 27.4 40.9 27.4 40.7 L 27.4 26 Q 27.4 18.75 32.5 13.6 L 32.55 13.55 Q 37.7 8.45 45 8.45 L 55.1 8.45 Q 62.4 8.45 67.55 13.6 70.75 16.75 72 20.8 72.25 21.6 73 22 73.7 22.35 74.5 22.1 75.3 21.85 75.7 21.15 76.05 20.4 75.8 19.6 74.25 14.65 70.4 10.75 64.1 4.45 55.1 4.45 L 45 4.45 Q 36.05 4.45 29.7 10.75 23.4 17.1 23.4 26 L 23.4 40.7 Q 23.4 41 23.5 41.25 14.7 42.6 14.7 52.7 L 14.7 83.9 Q 14.7 95.55 26.35 95.55 L 73.7 95.55 Q 85.35 95.55 85.35 83.9 M 44 62.2 Q 44.1 62.1 44.25 62 46.6 59.65 50 59.65 53.45 59.65 55.9 62.1 58.3 64.6 58.3 67.95 58.3 71.35 55.95 73.65 55.75 73.8 55.7 73.95 53.35 76.25 50 76.25 46.6 76.25 44.1 73.85 41.7 71.5 41.7 67.95 41.7 64.6 44 62.2 Z" + id="path7" /> + </g> + </defs> + <g + transform="matrix(1.2828975,0,0,1.2828975,-12.340796,-1.2588939)" + id="g9"> + <use + xlink:href="#a" + id="use11" + x="0" + y="0" + width="100%" + height="100%" /> + </g> +</svg> diff --git a/res/icons/noun_424414_cc.svg b/res/icons/noun_424414_cc.svg new file mode 100644 index 0000000000000000000000000000000000000000..addfd8f6d611f3ee7c715d55729522940bd3f789 --- /dev/null +++ b/res/icons/noun_424414_cc.svg @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + preserveAspectRatio="none" + x="0px" + y="0px" + viewBox="0 0 100 125" + id="svg2" + inkscape:version="0.91 r13725" + sodipodi:docname="noun_424414_cc.svg"> + <metadata + id="metadata19"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1366" + inkscape:window-height="711" + id="namedview17" + showgrid="false" + inkscape:zoom="1.888" + inkscape:cx="-30.243644" + inkscape:cy="62.5" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /> + <defs + id="defs4"> + <g + id="a"> + <path + fill="#000000" + stroke="none" + d=" M 85.35 83.9 L 85.35 52.7 Q 85.35 42.6 76.65 41.25 76.7 41 76.7 40.7 L 76.7 26 Q 76.7 17.05 70.4 10.75 64.1 4.45 55.1 4.45 L 45 4.45 Q 36.05 4.45 29.7 10.75 23.4 17.1 23.4 26 L 23.4 40.7 Q 23.4 41 23.5 41.25 14.7 42.6 14.7 52.7 L 14.7 83.9 Q 14.7 95.55 26.35 95.55 L 73.7 95.55 Q 85.35 95.55 85.35 83.9 M 45 8.45 L 55.1 8.45 Q 62.4 8.45 67.55 13.6 72.7 18.75 72.7 26 L 72.7 40.7 Q 72.7 40.9 72.75 41.05 L 27.4 41.05 Q 27.4 40.9 27.4 40.7 L 27.4 26 Q 27.4 18.75 32.5 13.6 L 32.55 13.55 Q 37.7 8.45 45 8.45 M 44 62.2 Q 44.1 62.1 44.25 62 46.6 59.65 50 59.65 53.45 59.65 55.9 62.1 58.3 64.6 58.3 67.95 58.3 71.35 55.95 73.65 55.75 73.8 55.7 73.95 53.35 76.25 50 76.25 46.6 76.25 44.1 73.85 41.7 71.5 41.7 67.95 41.7 64.6 44 62.2 Z" + id="path7" /> + </g> + </defs> + <g + transform="matrix(1.316099,0,0,1.316099,-14.299197,-3.4066404)" + id="g9"> + <use + xlink:href="#a" + id="use11" + x="0" + y="0" + width="100%" + height="100%" /> + </g> +</svg> diff --git a/res/ui/account_cfg.ui b/res/ui/account_cfg.ui index 92ad6c2c4460f11b521f3cd7a927a8e0798a0a5f..6454c71d66e29b88a38ff2f44244234e9fb359cc 100644 --- a/res/ui/account_cfg.ui +++ b/res/ui/account_cfg.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>400</width> - <height>266</height> + <height>272</height> </rect> </property> <property name="windowTitle"> @@ -46,7 +46,7 @@ <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QLabel" name="label"> + <widget class="QLabel" name="label_action"> <property name="text"> <string>Account name (uid)</string> </property> @@ -140,7 +140,7 @@ <string/> </property> <property name="placeholderText"> - <string>CryptoID</string> + <string>Entropy</string> </property> </widget> </item> diff --git a/res/ui/certification.ui b/res/ui/certification.ui index b65ffecfa69f9f79bc2af2230537110e13fcff5e..59f527b542ae9c55862bc1c29a8ae8438b2aa1c7 100644 --- a/res/ui/certification.ui +++ b/res/ui/certification.ui @@ -25,10 +25,26 @@ <property name="title"> <string>Community</string> </property> - <layout class="QHBoxLayout" name="horizontalLayout_4"> + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <widget class="QComboBox" name="combo_community"/> </item> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Certifications stock</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QLabel" name="label_cert_stock"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + </item> </layout> </widget> </item> @@ -158,7 +174,7 @@ </sizepolicy> </property> <property name="text"> - <string>S&earch user</string> + <string>Sea&rch user</string> </property> </widget> </item> diff --git a/res/ui/community_cfg.ui b/res/ui/community_cfg.ui index f5743e91376736441b4f6af78d0e47b1afb72b7b..a31cb57384fab2f61fa4dd97c75d6246fb7e6217 100644 --- a/res/ui/community_cfg.ui +++ b/res/ui/community_cfg.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>400</width> - <height>300</height> + <height>317</height> </rect> </property> <property name="contextMenuPolicy"> @@ -184,10 +184,13 @@ <item> <widget class="QSpinBox" name="spinbox_add_port"> <property name="minimum"> - <number>1025</number> + <number>0</number> </property> <property name="maximum"> - <number>99999</number> + <number>65535</number> + </property> + <property name="singleStep"> + <number>1</number> </property> <property name="value"> <number>8081</number> diff --git a/res/ui/mainwindow.ui b/res/ui/mainwindow.ui index 6d97872b2c0f6bce6f167d4a5cd2427f710555c7..9e68d093597d4b9d2bf952aa91058a41914127b2 100644 --- a/res/ui/mainwindow.ui +++ b/res/ui/mainwindow.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>681</width> - <height>549</height> + <width>900</width> + <height>550</height> </rect> </property> <property name="windowTitle"> @@ -21,7 +21,7 @@ <rect> <x>0</x> <y>0</y> - <width>681</width> + <width>900</width> <height>30</height> </rect> </property> @@ -66,8 +66,15 @@ </property> <addaction name="actionAbout"/> </widget> + <widget class="QMenu" name="menu_duniter"> + <property name="title"> + <string>&Duniter</string> + </property> + <addaction name="actionManage_local_node"/> + </widget> <addaction name="menu_file"/> <addaction name="menu_account"/> + <addaction name="menu_duniter"/> <addaction name="menu_help"/> </widget> <widget class="QStatusBar" name="statusbar"/> @@ -176,6 +183,11 @@ <string>&Add account</string> </property> </action> + <action name="actionManage_local_node"> + <property name="text"> + <string>&Manage local node</string> + </property> + </action> </widget> <resources> <include location="../icons/icons.qrc"/> diff --git a/res/ui/node_manager.ui b/res/ui/node_manager.ui new file mode 100644 index 0000000000000000000000000000000000000000..ef4041a7ec9580838728d1d3066eb14662b72d1f --- /dev/null +++ b/res/ui/node_manager.ui @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>NodeManager</class> + <widget class="QDialog" name="NodeManager"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1024</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>Node manager</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QWidget" name="web_view" native="true"/> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/sakia.spec b/sakia.spec index 52b026d71fd223a2312525c944f42743fa66784d..9a5416b785d7dabe2c4165f289c4f1735273ebe4 100644 --- a/sakia.spec +++ b/sakia.spec @@ -1,13 +1,11 @@ # -*- mode: python -*- -from PyInstaller.compat import is_darwin, is_win +from PyInstaller.compat import is_darwin, is_win, is_linux import ctypes import subprocess import os block_cipher = None - - a = Analysis(['src/sakia/main.py'], pathex=['.'], binaries=None, @@ -31,6 +29,16 @@ if is_darwin: "libsodium.dylib") a.binaries = a.binaries + TOC([('lib/libsodium.dylib', libsodium_path, 'BINARY')]) +if is_linux: + libsodium_path = ctypes.util.find_library('libsodium.so') + if not libsodium_path: + if os.path.isfile('/usr/lib/x86_64-linux-gnu/libsodium.so.13'): + libsodium_path = "/usr/lib/x86_64-linux-gnu/libsodium.so.13" + if os.path.isfile('/usr/lib/i386-linux-gnu/libsodium.so.13'): + libsodium_path = "/usr/lib/i386-linux-gnu/libsodium.so.13" + + a.binaries = a.binaries + TOC([('libsodium.so', libsodium_path, 'BINARY')]) + if is_win: a.binaries = a.binaries + TOC([('libsodium.dll', ctypes.util.find_library('libsodium.dll'), 'BINARY')]) @@ -43,10 +51,10 @@ exe = EXE(pyz, a.scripts, exclude_binaries=True, name='sakia', - debug=False, + debug=True, strip=False, upx=True, - console=False, + console=True, icon='sakia.ico') coll = COLLECT(exe, diff --git a/src/sakia/__init__.py b/src/sakia/__init__.py index d4c85e473175c7b0fccd54e9748b783ab229ab3d..498a4a9e4a7186935706ee3b3c1461c31bfe95a6 100644 --- a/src/sakia/__init__.py +++ b/src/sakia/__init__.py @@ -1,2 +1,2 @@ -__version_info__ = ('0', '12', '0') +__version_info__ = ('0', '20', '1') __version__ = '.'.join(__version_info__) diff --git a/src/sakia/core/account.py b/src/sakia/core/account.py index de06266dfb80d2682560b8890373fa0f4f47589e..f7969f805e596d1b6c0339e931f8a60e1feb3912 100644 --- a/src/sakia/core/account.py +++ b/src/sakia/core/account.py @@ -4,15 +4,16 @@ Created on 1 févr. 2014 @author: inso """ -from ucoinpy.documents.certification import SelfCertification, Certification, Revocation -from ucoinpy.documents.membership import Membership -from ucoinpy.key import SigningKey +from duniterpy.documents import Membership, SelfCertification, Certification, Revokation, BlockUID, Block +from duniterpy.key import SigningKey +from duniterpy.api import bma +from duniterpy.api.bma import PROTOCOL_VERSION +from duniterpy.api import errors import logging -import time import asyncio from pkg_resources import parse_version - +from aiohttp.errors import ClientError from PyQt5.QtCore import QObject, pyqtSignal from . import money @@ -21,9 +22,6 @@ from .community import Community from .registry import LocalState from ..tools.exceptions import ContactAlreadyExists from .. import __version__ -from ucoinpy.api import bma -from ucoinpy.api.bma import PROTOCOL_VERSION -from aiohttp.errors import ClientError class Account(QObject): @@ -74,6 +72,11 @@ class Account(QObject): self.tr("Warning : Your could miss certifications soon."), 0 ], + 'warning_revokation': + [ + self.tr("Warning : If you don't renew soon, your identity will be considerd revoked."), + 0 + ], 'warning_certifying_first_time': True, } @@ -345,13 +348,13 @@ class Account(QObject): return self.name == data['uid'], self.name, data['uid'] def _parse_uid_lookup(data): - timestamp = 0 + timestamp = BlockUID.empty() found_uid = "" for result in data['results']: if result["pubkey"] == self.pubkey: uids = result['uids'] for uid_data in uids: - if uid_data["meta"]["timestamp"] > timestamp: + if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp: timestamp = uid_data["meta"]["timestamp"] found_uid = uid_data["uid"] return self.name == found_uid, self.name, found_uid @@ -360,13 +363,13 @@ class Account(QObject): return self.pubkey == data['pubkey'], self.pubkey, data['pubkey'] def _parse_pubkey_lookup(data): - timestamp = 0 + timestamp = BlockUID.empty() found_uid = "" found_result = ["", ""] for result in data['results']: uids = result['uids'] for uid_data in uids: - if uid_data["meta"]["timestamp"] > timestamp: + if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp: timestamp = uid_data["meta"]["timestamp"] found_uid = uid_data["uid"] if found_uid == self.name: @@ -389,8 +392,9 @@ class Account(QObject): if data: registered = parsers[request](data) tries += 1 - except ValueError as e: - if '404' in str(e) or '400' in str(e): + except errors.DuniterError as e: + if e.ucode in (errors.NO_MEMBER_MATCHING_PUB_OR_UID, + e.ucode == errors.NO_MATCHING_IDENTITY): if request == bma.wot.CertifiersOf: request = bma.wot.Lookup tries = 0 @@ -430,19 +434,26 @@ class Account(QObject): :param str password: The account SigningKey password :param community: The community target of the self certification """ + try: + block_data = await community.bma_access.simple_request(bma.blockchain.Current) + signed_raw = "{0}{1}\n".format(block_data['raw'], block_data['signature']) + block_uid = Block.from_signed_raw(signed_raw).blockUID + except errors.DuniterError as e: + if e.ucode == errors.NO_CURRENT_BLOCK: + block_uid = BlockUID.empty() + else: + raise selfcert = SelfCertification(PROTOCOL_VERSION, community.currency, self.pubkey, - int(time.time()), self.name, + block_uid, None) key = SigningKey(self.salt, password) selfcert.sign([key]) logging.debug("Key publish : {0}".format(selfcert.signed_raw())) - responses = await community.bma_access.broadcast(bma.wot.Add, {}, {'pubkey': self.pubkey, - 'self_': selfcert.signed_raw(), - 'other': {}}) + responses = await community.bma_access.broadcast(bma.wot.Add, {}, {'identity': selfcert.signed_raw()}) result = (False, "") for r in responses: if r.status == 200: @@ -451,6 +462,8 @@ class Account(QObject): result = (False, (await r.text())) else: await r.release() + if result[0]: + (await self.identity(community)).sigdate = block_uid return result async def send_membership(self, password, community, mstype): @@ -464,12 +477,12 @@ class Account(QObject): """ logging.debug("Send membership") - blockid = await community.blockid() + blockUID = community.network.current_blockUID self_identity = await self._identities_registry.future_find(self.pubkey, community) selfcert = await self_identity.selfcert(community) membership = Membership(PROTOCOL_VERSION, community.currency, - selfcert.pubkey, blockid, mstype, selfcert.uid, + selfcert.pubkey, blockUID, mstype, selfcert.uid, selfcert.timestamp, None) key = SigningKey(self.salt, password) membership.sign([key]) @@ -495,23 +508,21 @@ class Account(QObject): :param str pubkey: The certified identity pubkey """ logging.debug("Certdata") - blockid = await community.blockid() + blockUID = community.network.current_blockUID identity = await self._identities_registry.future_find(pubkey, community) selfcert = await identity.selfcert(community) if selfcert: certification = Certification(PROTOCOL_VERSION, community.currency, - self.pubkey, pubkey, blockid, None) + self.pubkey, pubkey, blockUID, None) key = SigningKey(self.salt, password) certification.sign(selfcert, [key]) signed_cert = certification.signed_raw(selfcert) logging.debug("Certification : {0}".format(signed_cert)) - data = {'pubkey': pubkey, - 'self_': selfcert.signed_raw(), - 'other': "{0}\n".format(certification.inline())} + data = {'cert': certification.signed_raw(selfcert)} logging.debug("Posted data : {0}".format(data)) - responses = await community.bma_access.broadcast(bma.wot.Add, {}, data) + responses = await community.bma_access.broadcast(bma.wot.Certify, {}, data) result = (False, "") for r in responses: if r.status == 200: @@ -531,23 +542,23 @@ class Account(QObject): Revoke self-identity on server, not in blockchain :param str password: The account SigningKey password - :param sakia.core.community.Community community: The community target of the revocation + :param sakia.core.community.Community community: The community target of the revokation """ revoked = await self._identities_registry.future_find(self.pubkey, community) - revocation = Revocation(PROTOCOL_VERSION, community.currency, None) + revokation = Revokation(PROTOCOL_VERSION, community.currency, None) selfcert = await revoked.selfcert(community) key = SigningKey(self.salt, password) - revocation.sign(selfcert, [key]) + revokation.sign(selfcert, [key]) - logging.debug("Self-Revocation Document : \n{0}".format(revocation.raw(selfcert))) - logging.debug("Signature : \n{0}".format(revocation.signatures[0])) + logging.debug("Self-Revokation Document : \n{0}".format(revokation.raw(selfcert))) + logging.debug("Signature : \n{0}".format(revokation.signatures[0])) data = { 'pubkey': revoked.pubkey, 'self_': selfcert.signed_raw(), - 'sig': revocation.signatures[0] + 'sig': revokation.signatures[0] } logging.debug("Posted data : {0}".format(data)) responses = await community.bma_access.broadcast(bma.wot.Revoke, {}, data) @@ -565,12 +576,15 @@ class Account(QObject): for c in self.communities: c.start_coroutines() - async def stop_coroutines(self): + async def stop_coroutines(self, closing=False): + logging.debug("Stop communities coroutines") for c in self.communities: - await c.stop_coroutines() + await c.stop_coroutines(closing) + logging.debug("Stop wallets coroutines") for w in self.wallets: - w.stop_coroutines() + w.stop_coroutines(closing) + logging.debug("Account coroutines stopped") def jsonify(self): """ diff --git a/src/sakia/core/app.py b/src/sakia/core/app.py index 529db9d8b312529af2d4d82e8242a865aa8c799f..90afa4158379a908b5c67fb282387fa835ad53e9 100644 --- a/src/sakia/core/app.py +++ b/src/sakia/core/app.py @@ -15,7 +15,7 @@ import asyncio from pkg_resources import parse_version from PyQt5.QtCore import QObject, pyqtSignal, QTranslator, QCoreApplication, QLocale -from ucoinpy.api.bma import API +from duniterpy.api.bma import API from aiohttp.connector import ProxyConnector from . import config from .account import Account @@ -197,14 +197,14 @@ class Application(QObject): self._current_account.start_coroutines() self.account_changed.emit() - async def stop_current_account(self): + async def stop_current_account(self, closing=False): """ Save the account to the cache and stop the coroutines """ self.save_cache(self._current_account) self.save_notifications(self._current_account) - await self._current_account.stop_coroutines() + await self._current_account.stop_coroutines(closing) def load(self): """ @@ -510,7 +510,7 @@ class Application(QObject): async def stop(self): if self._current_account: - await self.stop_current_account() + await self.stop_current_account(closing=True) await asyncio.sleep(0) self.save_registries() @@ -524,7 +524,7 @@ class Application(QObject): connector = None try: with aiohttp.Timeout(15): - response = await aiohttp.get("https://api.github.com/repos/ucoin-io/sakia/releases", connector=connector) + response = await aiohttp.get("https://api.github.com/repos/duniter/sakia/releases", connector=connector) if response.status == 200: releases = await response.json() latest = None diff --git a/src/sakia/core/community.py b/src/sakia/core/community.py index 04ddbe1af6c19e3f119639bea62093eb33e9bbae..23b860c18a18af819ba2b1a8be7b93cf593a1b36 100644 --- a/src/sakia/core/community.py +++ b/src/sakia/core/community.py @@ -5,18 +5,14 @@ Created on 1 févr. 2014 """ import logging -import hashlib import re -import time -import asyncio import math -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt5.QtCore import QObject from ..tools.exceptions import NoPeerAvailable from .net.network import Network -from ucoinpy.api import bma -from ucoinpy.documents import Block, BlockId +from duniterpy.api import bma, errors from .net.api.bma.access import BmaAccess @@ -25,7 +21,7 @@ class Community(QObject): A community is a group of nodes using the same currency. .. warning:: The currency name is supposed to be unique in sakia - but nothing exists in ucoin to assert that a currency name is unique. + but nothing exists in duniter to assert that a currency name is unique. """ def __init__(self, currency, network, bma_access): """ @@ -172,8 +168,8 @@ class Community(QObject): return block else: return None - except ValueError as e: - if '404' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: logging.debug(str(e)) return None except NoPeerAvailable as e: @@ -187,7 +183,7 @@ class Community(QObject): :return: The monetary mass value """ # Get cached block by block number - block_number = self.network.current_blockid.number + block_number = self.network.current_blockUID.number if block_number: block = await self.bma_access.future_request(bma.blockchain.Block, req_args={'number': block_number}) @@ -203,31 +199,33 @@ class Community(QObject): """ try: # Get cached block by block number - block_number = self.network.current_blockid.number + block_number = self.network.current_blockUID.number block = await self.bma_access.future_request(bma.blockchain.Block, req_args={'number': block_number}) return block['membersCount'] - except ValueError as e: - if '404' in e: + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: return 0 except NoPeerAvailable as e: logging.debug(str(e)) return 0 - async def time(self): + async def time(self, block_number=None): """ Get the blockchain time + :param block_number: The block number, None if current block :return: The community blockchain time :rtype: int """ try: # Get cached block by block number - block_number = self.network.current_blockid.number + if block_number is None: + block_number = self.network.current_blockUID.number block = await self.bma_access.future_request(bma.blockchain.Block, req_args={'number': block_number}) return block['medianTime'] - except ValueError as e: - if '404' in e: + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: return 0 except NoPeerAvailable as e: logging.debug(str(e)) @@ -239,7 +237,7 @@ class Community(QObject): Get the community network instance. :return: The community network instance. - :rtype: sakia.core.net.network.Network + :rtype: sakia.core.net.Network """ return self._network @@ -259,19 +257,31 @@ class Community(QObject): """ return await self.bma_access.future_request(bma.blockchain.Parameters) - async def certification_expired(self, certtime): + async def certification_expired(self, cert_time): """ Return True if the certificaton time is too old + + :param int cert_time: the timestamp of the certification + """ + parameters = await self.parameters() + blockchain_time = await self.time() + return blockchain_time - cert_time > parameters['sigValidity'] + + async def certification_writable(self, cert_time): + """ + Return True if the certificaton time is too old + + :param int cert_time: the timestamp of the certification """ parameters = await self.parameters() blockchain_time = await self.time() - return blockchain_time - certtime > parameters['sigValidity'] + return blockchain_time - cert_time < parameters['sigWindow'] * parameters['avgGenTime'] def add_node(self, node): """ Add a peer to the community. - :param peer: The new peer as a ucoinpy Peer object. + :param peer: The new peer as a duniterpy Peer object. """ self._network.add_root_node(node) @@ -290,7 +300,7 @@ class Community(QObject): :param int number: The block number. If none, returns current block. """ if number is None: - block_number = self.network.current_blockid.number + block_number = self.network.current_blockUID.number data = await self.bma_access.future_request(bma.blockchain.Block, req_args={'number': block_number}) else: @@ -299,23 +309,6 @@ class Community(QObject): req_args={'number': number}) return data - async def blockid(self): - """ - Get the block id. - - :return: The current block ID as [NUMBER-HASH] format. - """ - try: - block_number = self.network.current_blockid.number - block = await self.bma_access.future_request(bma.blockchain.Block, - req_args={'number': block_number}) - signed_raw = "{0}{1}\n".format(block['raw'], block['signature']) - except ValueError as e: - if '404' in str(e): - return BlockId.empty() - - return Block.from_signed_raw(signed_raw).blockid - async def members_pubkeys(self): """ Listing members pubkeys of a community @@ -328,8 +321,8 @@ class Community(QObject): def start_coroutines(self): self.network.start_coroutines() - async def stop_coroutines(self): - await self.network.stop_coroutines() + async def stop_coroutines(self, closing=False): + await self.network.stop_coroutines(closing) def rollback_cache(self): self._bma_access.rollback() diff --git a/src/sakia/core/graph/base_graph.py b/src/sakia/core/graph/base_graph.py index 3a2cd9398b6081eb0d67066095de94dda71facc8..d320660b3348fab71d0d767456ab0d2fcf4650ca 100644 --- a/src/sakia/core/graph/base_graph.py +++ b/src/sakia/core/graph/base_graph.py @@ -77,6 +77,25 @@ class BaseGraph(QObject): pass return None + def is_sentry(self, nb_certs, nb_members): + """ + Check if it is a sentry or not + :param int nb_certs: the number of certs + :param int nb_members: the number of members + :return: True if a sentry + """ + Y = { + 10: 2, + 100: 4, + 1000: 6, + 10000: 12, + 100000: 20 + } + for k in reversed(sorted(Y.keys())): + if nb_members >= k: + return nb_certs >= Y[k] + return False + async def add_certifier_list(self, certifier_list, identity, account_identity): """ Add list of certifiers to graph @@ -107,7 +126,7 @@ class BaseGraph(QObject): QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ), 'cert_time': certifier['cert_time'], - 'confirmation_text': self.confirmation_text(certifier['cert_time']) + 'confirmation_text': self.confirmation_text(certifier['block_number']) } self.nx_graph.add_edge(certifier['identity'].pubkey, identity.pubkey, attr_dict=arc, weight=len(certifier_list)) @@ -145,7 +164,7 @@ class BaseGraph(QObject): QLocale.dateFormat(QLocale(), QLocale.ShortFormat) ), 'cert_time': certified['cert_time'], - 'confirmation_text': self.confirmation_text(certified['cert_time']) + 'confirmation_text': self.confirmation_text(certified['block_number']) } self.nx_graph.add_edge(identity.pubkey, certified['identity'].pubkey, attr_dict=arc, @@ -161,7 +180,6 @@ class BaseGraph(QObject): :param int status: Optional, default=None, Node status (see sakia.gui.views.wot) :param list edges: Optional, default=None, List of edges (certified by identity) :param list connected: Optional, default=None, Public key list of the connected nodes around the identity - :return: """ metadata = { 'text': identity.uid, diff --git a/src/sakia/core/graph/explorer_graph.py b/src/sakia/core/graph/explorer_graph.py index 687822e6dbab66e351baa0c6dc2841b4c269a346..856ae22f593ac14d2f8ec988dbbcba8e12f19351 100644 --- a/src/sakia/core/graph/explorer_graph.py +++ b/src/sakia/core/graph/explorer_graph.py @@ -63,6 +63,7 @@ class ExplorerGraph(BaseGraph): current_identity = identity self.nx_graph.clear() self.add_identity(current_identity, NodeStatus.HIGHLIGHTED) + self.nx_graph.node[current_identity.pubkey]['is_sentry'] = False self.graph_changed.emit() for step in range(1, steps + 1): explorable[step] = [] @@ -73,7 +74,8 @@ class ExplorerGraph(BaseGraph): # for each pubkey connected... if current_identity not in explored: self.current_identity_changed.emit(current_identity.pubkey) - self.add_identity(current_identity, NodeStatus.NEUTRAL) + node = self.add_identity(current_identity, NodeStatus.NEUTRAL) + self.nx_graph.node[current_identity.pubkey]['is_sentry'] = False logging.debug("New identity explored : {pubkey}".format(pubkey=current_identity.pubkey[:5])) self.graph_changed.emit() @@ -81,8 +83,13 @@ class ExplorerGraph(BaseGraph): self.community) await self.add_certifier_list(certifier_list, current_identity, identity) logging.debug("New identity certifiers : {pubkey}".format(pubkey=current_identity.pubkey[:5])) + + is_sentry = self.is_sentry(len(certifier_list), await self.community.nb_members()) + self.nx_graph.node[current_identity.pubkey]['is_sentry'] = is_sentry + self.graph_changed.emit() + certified_list = await current_identity.unique_valid_certified_by(self.app.identities_registry, self.community) await self.add_certified_list(certified_list, current_identity, identity) diff --git a/src/sakia/core/graph/wot_graph.py b/src/sakia/core/graph/wot_graph.py index ea01ac29c1a2f379addb1389f278af8e744ce7d1..50a63b74fe893ce6cd5b8e41725bae25be41d487 100644 --- a/src/sakia/core/graph/wot_graph.py +++ b/src/sakia/core/graph/wot_graph.py @@ -55,7 +55,7 @@ class WoTGraph(BaseGraph): # calculate path of nodes between identity and to_identity try: - path = networkx.shortest_path(self.nx_graph.to_undirected(), account_identity.pubkey, to_identity.pubkey) + path = networkx.shortest_path(self.nx_graph.reverse(copy=True), account_identity.pubkey, to_identity.pubkey) except networkx.NetworkXNoPath as e: logging.debug(str(e)) diff --git a/src/sakia/core/money/dividend_per_day.py b/src/sakia/core/money/dividend_per_day.py index 59b5538b82546f3894f27689ad600df46b21d604..7528c867120fd6c249b4e3ba98466c966f2987e2 100644 --- a/src/sakia/core/money/dividend_per_day.py +++ b/src/sakia/core/money/dividend_per_day.py @@ -32,9 +32,9 @@ class DividendPerDay(BaseReferential): @classmethod def instance(cls, amount, community, app, block_number=None): if app.preferences['forgetfulness']: - return UDDToPast(amount, community, app, block_number) - else: return cls(amount, community, app, block_number) + else: + return UDDToPast(amount, community, app, block_number) @classmethod def translated_name(cls): diff --git a/src/sakia/core/money/relative.py b/src/sakia/core/money/relative.py index 696ae43a8501c2058d6adede258804657df8662a..004deb6c3aed2d7b2a597740d41e523a518c349d 100644 --- a/src/sakia/core/money/relative.py +++ b/src/sakia/core/money/relative.py @@ -34,9 +34,9 @@ class Relative(BaseReferential): @classmethod def instance(cls, amount, community, app, block_number=None): if app.preferences['forgetfulness']: - return RelativeToPast(amount, community, app, block_number) - else: return cls(amount, community, app, block_number) + else: + return RelativeToPast(amount, community, app, block_number) @classmethod def translated_name(cls): diff --git a/src/sakia/core/net/api/bma/access.py b/src/sakia/core/net/api/bma/access.py index 5e23008ad29f81ca80fdba4f44ce41bce3d54e3f..e2a8ba1e9e7ee7512b4b11db5ec87a2d7a7e56d6 100644 --- a/src/sakia/core/net/api/bma/access.py +++ b/src/sakia/core/net/api/bma/access.py @@ -1,5 +1,6 @@ from PyQt5.QtCore import QObject, pyqtSlot -from ucoinpy.api import bma +from duniterpy.api import bma +from duniterpy.api import errors from .....tools.exceptions import NoPeerAvailable from ..... import __version__ import logging @@ -9,6 +10,7 @@ import random from socket import gaierror import jsonschema from pkg_resources import parse_version +import copy class BmaAccess(QObject): @@ -125,9 +127,9 @@ class BmaAccess(QObject): if request is bma.blockchain.Parameters and self._rollback_to == 0: need_reload = True elif str(request) in BmaAccess.__saved_requests \ - or cached_data['metadata']['block_hash'] == self._network.current_blockid.sha_hash: + or cached_data['metadata']['block_hash'] == self._network.current_blockUID.sha_hash: need_reload = False - ret_data = cached_data['value'] + ret_data = copy.deepcopy(cached_data['value']) else: need_reload = True ret_data = None @@ -168,11 +170,11 @@ class BmaAccess(QObject): self._data[cache_key] = {'metadata': {}, 'value': {}} - self._data[cache_key]['metadata']['block_number'] = self._network.current_blockid.number - self._data[cache_key]['metadata']['block_hash'] = self._network.current_blockid.sha_hash + self._data[cache_key]['metadata']['block_number'] = self._network.current_blockUID.number + self._data[cache_key]['metadata']['block_hash'] = self._network.current_blockUID.sha_hash self._data[cache_key]['metadata']['sakia_version'] = __version__ if not self._compare_json(self._data[cache_key]['value'], data): - self._data[cache_key]['value'] = data + self._data[cache_key]['value'] = copy.deepcopy(data) return True return False @@ -203,7 +205,7 @@ class BmaAccess(QObject): except TypeError: return False else: - return False + return True filters = { bma.ud.History: lambda n: compare_versions(n, "0.11.0"), bma.tx.History: lambda n: compare_versions(n, "0.11.0"), @@ -236,14 +238,10 @@ class BmaAccess(QObject): conn_handler = node.endpoint.conn_handler() req = request(conn_handler, **req_args) try: - json_data = await req.get(**get_args) + json_data = await req.get(**get_args, session=self._network.session) self._update_cache(request, req_args, get_args, json_data) return json_data - except ValueError as e: - if '404' in str(e) or '400' in str(e): - raise - tries += 1 - except (ClientError, ServerDisconnectedError, gaierror, asyncio.TimeoutError) as e: + except (ClientError, ServerDisconnectedError, gaierror, asyncio.TimeoutError, ValueError) as e: tries += 1 except jsonschema.ValidationError as e: logging.debug(str(e)) @@ -269,17 +267,13 @@ class BmaAccess(QObject): json_data = None while tries < 3: try: - json_data = await req.get(**get_args) + json_data = await req.get(**get_args, session=self._network.session) return json_data - except ValueError as e: - if '404' in str(e) or '400' in str(e): - raise - tries += 1 - except (ClientError, ServerDisconnectedError, gaierror, asyncio.TimeoutError) as e: - tries += 1 - except jsonschema.ValidationError as e: - logging.debug(str(e)) + except (ClientError, ServerDisconnectedError, gaierror, asyncio.TimeoutError, ValueError) as e: tries += 1 + #except jsonschema.ValidationError as e: + # logging.debug(str(e)) + # tries += 1 if len(nodes) == 0 or not json_data: raise NoPeerAvailable("", len(nodes)) return json_data @@ -289,7 +283,7 @@ class BmaAccess(QObject): Broadcast data to a network. Sends the data to all knew nodes. - :param request: A ucoinpy bma request class + :param request: A duniterpy bma request class :param req_args: Arguments to pass to the request constructor :param post_args: Arguments to pass to the request __post__ method :return: All nodes replies @@ -307,7 +301,7 @@ class BmaAccess(QObject): logging.debug("Trying to connect to : " + node.pubkey) conn_handler = node.endpoint.conn_handler() req = request(conn_handler, **req_args) - reply = asyncio.ensure_future(req.post(**post_args)) + reply = asyncio.ensure_future(req.post(**post_args, session=self._network.session)) replies.append(reply) self._invalidate_cache(request) else: @@ -315,9 +309,7 @@ class BmaAccess(QObject): try: result = await asyncio.gather(*replies) - except ValueError as e: - if '404' in str(e) or '400' in str(e): - raise - except (ClientError, ServerDisconnectedError, gaierror, asyncio.TimeoutError) as e: + return tuple(result) + except (ClientError, ServerDisconnectedError, gaierror, asyncio.TimeoutError, ValueError) as e: pass - return tuple(result) + return () diff --git a/src/sakia/core/net/network.py b/src/sakia/core/net/network.py index 06880f02e12820427834d5b5218783860c9902ae..eec21ff4c601e49a2b2bdd31b16904ec70ef8644 100644 --- a/src/sakia/core/net/network.py +++ b/src/sakia/core/net/network.py @@ -5,12 +5,13 @@ Created on 24 févr. 2015 """ from .node import Node from ...tools.exceptions import InvalidNodeCurrency +from ...tools.decorators import asyncify import logging -import statistics +import aiohttp import time import asyncio -from ucoinpy.documents.peer import Peer -from ucoinpy.documents.block import Block, BlockId +from duniterpy.documents import Peer, Block, BlockUID, MalformedDocumentError +from duniterpy.key import VerifyingKey from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QTimer from collections import Counter @@ -27,7 +28,7 @@ class Network(QObject): new_block_mined = pyqtSignal(int) blockchain_rollback = pyqtSignal(int) - def __init__(self, currency, nodes): + def __init__(self, currency, nodes, session): """ Constructor of a network @@ -41,8 +42,10 @@ class Network(QObject): self.add_node(n) self.currency = currency self._must_crawl = False - self._block_found = self.current_blockid + self._block_found = self.current_blockUID self._timer = QTimer() + self._client_session = session + self._discovery_stack = [] @classmethod def create(cls, node): @@ -54,7 +57,7 @@ class Network(QObject): :param node: The first knew node of the network """ nodes = [node] - network = cls(node.currency, nodes) + network = cls(node.currency, nodes, node.session) return network def merge_with_json(self, json_data, file_version): @@ -66,26 +69,29 @@ class Network(QObject): :param NormalizedVersion file_version: The node version """ for data in json_data: - node = Node.from_json(self.currency, data, file_version) - if node.pubkey not in [n.pubkey for n in self.nodes]: - self.add_node(node) - logging.debug("Loading : {:}".format(data['pubkey'])) - else: - other_node = [n for n in self.nodes if n.pubkey == node.pubkey][0] - other_node._uid = node.uid - other_node._version = node.version - other_node._software = node.software - other_node._peer = node.peer - switch = False - if other_node.block and node.block: - if other_node.block['hash'] != node.block['hash']: - switch = True + try: + node = Node.from_json(self.currency, data, file_version, self.session) + if node.pubkey not in [n.pubkey for n in self.nodes]: + self.add_node(node) + logging.debug("Loading : {:}".format(data['pubkey'])) else: - switch = True - if switch: - other_node.set_block(node.block) - other_node.last_change = node.last_change - other_node.state = node.state + other_node = [n for n in self.nodes if n.pubkey == node.pubkey][0] + other_node._uid = node.uid + other_node._version = node.version + other_node._software = node.software + other_node._peer = node.peer + switch = False + if other_node.block and node.block: + if other_node.block['hash'] != node.block['hash']: + switch = True + else: + switch = True + if switch: + other_node.set_block(node.block) + other_node.last_change = node.last_change + other_node.state = node.state + except MalformedDocumentError: + logging.debug("Could not load node {0}".format(data)) @classmethod def from_json(cls, currency, json_data, file_version): @@ -96,11 +102,15 @@ class Network(QObject): :param dict json_data: A json_data view of a network :param NormalizedVersion file_version: the version of the json file """ + session = aiohttp.ClientSession() nodes = [] for data in json_data: - node = Node.from_json(currency, data, file_version) - nodes.append(node) - network = cls(currency, nodes) + try: + node = Node.from_json(currency, data, file_version, session) + nodes.append(node) + except MalformedDocumentError: + logging.debug("Could not load node {0}".format(data)) + network = cls(currency, nodes, session) return network def jsonify(self): @@ -121,7 +131,10 @@ class Network(QObject): """ synced = len(self.synced_nodes) total = len(self.nodes) - ratio_synced = synced / total + if total == 0: + ratio_synced = 0 + else: + ratio_synced = synced / total return ratio_synced def start_coroutines(self): @@ -131,17 +144,26 @@ class Network(QObject): """ asyncio.ensure_future(self.discover_network()) - async def stop_coroutines(self): + async def stop_coroutines(self, closing=False): """ Stop network nodes crawling. """ self._must_crawl = False close_tasks = [] + logging.debug("Start closing") for node in self.nodes: close_tasks.append(asyncio.ensure_future(node.close_ws())) - await asyncio.wait(close_tasks, timeout=15) + logging.debug("Closing {0} websockets".format(len(close_tasks))) + if len(close_tasks) > 0: + await asyncio.wait(close_tasks, timeout=15) + if closing: + logging.debug("Closing client session") + await self._client_session.close() logging.debug("Closed") + @property + def session(self): + return self._client_session def continue_crawling(self): return self._must_crawl @@ -175,16 +197,16 @@ class Network(QObject): return self._root_nodes @property - def current_blockid(self): + def current_blockUID(self): """ Get the latest block considered valid It is the most frequent last block of every known nodes """ blocks = [n.block for n in self.synced_nodes if n.block] if len(blocks) > 0: - return BlockId(blocks[0]['number'], blocks[0]['hash']) + return BlockUID(blocks[0]['number'], blocks[0]['hash']) else: - return BlockId.empty() + return BlockUID.empty() def _check_nodes_sync(self): """ @@ -267,9 +289,9 @@ class Network(QObject): :rtype: int """ if block_number: - if block_number > self.current_blockid.number: + if block_number > self.current_blockUID.number: raise ValueError("Could not compute confirmations : data block number is after current block") - return self.current_blockid.number - block_number + 1 + return self.current_blockUID.number - block_number + 1 else: return 0 @@ -312,8 +334,10 @@ class Network(QObject): node = self.nodes[index] return self._root_nodes.index(node) - def refresh_once(self): + @asyncify + async def refresh_once(self): for node in self._nodes: + await asyncio.sleep(1) node.refresh(manual=True) async def discover_network(self): @@ -323,6 +347,7 @@ class Network(QObject): """ self._must_crawl = True first_loop = True + asyncio.ensure_future(self.pop_discovery_stack()) while self.continue_crawling(): for node in self.nodes: if self.continue_crawling(): @@ -330,24 +355,46 @@ class Network(QObject): if not first_loop: await asyncio.sleep(15) first_loop = False + await asyncio.sleep(15) logging.debug("End of network discovery") - @pyqtSlot(Peer, str) - def handle_new_node(self, peer, pubkey): - pubkeys = [n.pubkey for n in self.nodes] - if peer.pubkey not in pubkeys: - logging.debug("New node found : {0}".format(peer.pubkey[:5])) + async def pop_discovery_stack(self): + """ + Handle poping of nodes in discovery stack + :return: + """ + while self.continue_crawling(): try: - node = Node.from_peer(self.currency, peer, pubkey) - self.add_node(node) - self.nodes_changed.emit() - except InvalidNodeCurrency as e: - logging.debug(str(e)) + await asyncio.sleep(1) + peer = self._discovery_stack.pop() + pubkeys = [n.pubkey for n in self.nodes] + if peer.pubkey not in pubkeys: + logging.debug("New node found : {0}".format(peer.pubkey[:5])) + try: + node = Node.from_peer(self.currency, peer, self.session) + node.refresh(manual=True) + self.add_node(node) + self.nodes_changed.emit() + except InvalidNodeCurrency as e: + logging.debug(str(e)) + else: + node = [n for n in self.nodes if n.pubkey == peer.pubkey][0] + if node.peer.blockUID.number < peer.blockUID.number: + logging.debug("Update node : {0}".format(peer.pubkey[:5])) + node.peer = peer + except IndexError: + await asyncio.sleep(2) + + def handle_new_node(self, peer): + key = VerifyingKey(peer.pubkey) + if key.verify_document(peer): + if len(self._discovery_stack) < 1000 \ + and peer.signatures[0] not in [p.signatures[0] for p in self._discovery_stack]: + logging.debug("Stacking new peer document : {0}".format(peer.pubkey)) + self._discovery_stack.append(peer) else: - node = [n for n in self.nodes if n.pubkey == pubkey][0] - if node.peer.blockid.number < peer.blockid.number: - node.peer = peer + logging.debug("Wrong document received : {0}".format(peer.signed_raw())) @pyqtSlot() def handle_identity_change(self): @@ -376,19 +423,19 @@ class Network(QObject): self.nodes_changed.emit() if node.state == Node.ONLINE: - logging.debug("{0} -> {1}".format(self._block_found.sha_hash[:10], self.current_blockid.sha_hash[:10])) - if self._block_found.sha_hash != self.current_blockid.sha_hash: - logging.debug("Latest block changed : {0}".format(self.current_blockid.number)) + logging.debug("{0} -> {1}".format(self._block_found.sha_hash[:10], self.current_blockUID.sha_hash[:10])) + if self._block_found.sha_hash != self.current_blockUID.sha_hash: + logging.debug("Latest block changed : {0}".format(self.current_blockUID.number)) # If new latest block is lower than the previously found one # or if the previously found block is different locally # than in the main chain, we declare a rollback if self._block_found.number and \ - self.current_blockid.number <= self._block_found.number \ + self.current_blockUID.number <= self._block_found.number \ or node.main_chain_previous_block and \ node.main_chain_previous_block['hash'] != self._block_found.sha_hash: - self._block_found = self.current_blockid - self.blockchain_rollback.emit(self.current_blockid.number) + self._block_found = self.current_blockUID + self.blockchain_rollback.emit(self.current_blockUID.number) else: - self._block_found = self.current_blockid - self.new_block_mined.emit(self.current_blockid.number) + self._block_found = self.current_blockUID + self.new_block_mined.emit(self.current_blockUID.number) diff --git a/src/sakia/core/net/node.py b/src/sakia/core/net/node.py index fbc5fd41b415da3243577e808de19fc77682ac4e..f9d36ab71469c2f7d989b7dca935f893358ba562 100644 --- a/src/sakia/core/net/node.py +++ b/src/sakia/core/net/node.py @@ -4,12 +4,12 @@ Created on 21 févr. 2015 @author: inso """ -from ucoinpy.documents.peer import Peer, Endpoint, BMAEndpoint -from ucoinpy.documents import Block, BlockId, MalformedDocumentError +from duniterpy.documents.peer import Peer, Endpoint, BMAEndpoint +from duniterpy.documents import Block, BlockUID, MalformedDocumentError from ...tools.exceptions import InvalidNodeCurrency from ...tools.decorators import asyncify -from ucoinpy.api import bma as bma -from ucoinpy.api.bma import ConnectionHandler +from duniterpy.api import bma, errors +from duniterpy.api.bma import ConnectionHandler from aiohttp.errors import WSClientDisconnectedError, WSServerHandshakeError, ClientResponseError from aiohttp.errors import ClientError, DisconnectedError @@ -43,10 +43,12 @@ class Node(QObject): changed = pyqtSignal() error = pyqtSignal() identity_changed = pyqtSignal() - neighbour_found = pyqtSignal(Peer, str) + neighbour_found = pyqtSignal(Peer) def __init__(self, peer, uid, pubkey, block, - state, last_change, last_merkle, software, version, fork_window): + state, last_change, last_merkle, + software, version, fork_window, + session): """ Constructor """ @@ -68,6 +70,7 @@ class Node(QObject): 'peer': None} self._connected = {'block': False, 'peer': False} + self._session = session def __del__(self): for ws in self._ws_tasks.values(): @@ -75,7 +78,7 @@ class Node(QObject): ws.cancel() @classmethod - async def from_address(cls, currency, address, port): + async def from_address(cls, currency, address, port, session): """ Factory method to get a node from a given address @@ -86,7 +89,7 @@ class Node(QObject): :return: A new node :rtype: sakia.core.net.Node """ - peer_data = await bma.network.Peering(ConnectionHandler(address, port)).get() + peer_data = await bma.network.Peering(ConnectionHandler(address, port)).get(session) peer = Peer.from_signed_raw("{0}{1}\n".format(peer_data['raw'], peer_data['signature'])) @@ -97,12 +100,12 @@ class Node(QObject): node = cls(peer, "", peer.pubkey, None, Node.ONLINE, time.time(), - {'root': "", 'leaves': []}, "", "", 0) + {'root': "", 'leaves': []}, "", "", 0, session) logging.debug("Node from address : {:}".format(str(node))) return node @classmethod - def from_peer(cls, currency, peer, pubkey): + def from_peer(cls, currency, peer, session): """ Factory method to get a node from a peer document. @@ -116,15 +119,15 @@ class Node(QObject): if peer.currency != currency: raise InvalidNodeCurrency(peer.currency, currency) - node = cls(peer, "", pubkey, None, + node = cls(peer, "", peer.pubkey, None, Node.OFFLINE, time.time(), {'root': "", 'leaves': []}, - "", "", 0) + "", "", 0, session) logging.debug("Node from peer : {:}".format(str(node))) return node @classmethod - def from_json(cls, currency, data, file_version): + def from_json(cls, currency, data, file_version, session): """ Loads a node from json data @@ -174,14 +177,14 @@ class Node(QObject): if currency in data: currency = data['currency'] - peer = Peer("1", currency, pubkey, BlockId(0, Block.Empty_Hash), endpoints, "SOMEFAKESIGNATURE") + peer = Peer(2, currency, pubkey, BlockUID(0, Block.Empty_Hash), endpoints, "SOMEFAKESIGNATURE") else: peer = Peer.from_signed_raw(data['peer']) node = cls(peer, uid, pubkey, block, state, last_change, {'root': "", 'leaves': []}, - software, version, fork_window) + software, version, fork_window, session) logging.debug("Node from json : {:}".format(str(node))) return node @@ -223,6 +226,10 @@ class Node(QObject): await asyncio.sleep(0) await asyncio.sleep(0) + @property + def session(self): + return self._session + @property def pubkey(self): return self._pubkey @@ -327,6 +334,9 @@ class Node(QObject): if not self._ws_tasks['peer']: self._ws_tasks['peer'] = asyncio.ensure_future(self.connect_peers()) + if manual: + asyncio.ensure_future(self.request_peers()) + if self._refresh_counter % 20 == 0 or manual: self.refresh_informations() self.refresh_uid() @@ -344,7 +354,7 @@ class Node(QObject): try: conn_handler = self.endpoint.conn_handler() block_websocket = bma.ws.Block(conn_handler) - ws_connection = block_websocket.connect() + ws_connection = block_websocket.connect(self._session) async with ws_connection as ws: self._connected['block'] = True logging.debug("Connected successfully to block ws : {0}".format(self.pubkey[:5])) @@ -357,10 +367,7 @@ class Node(QObject): break elif msg.tp == aiohttp.MsgType.error: break - except ValueError as e: - logging.debug("Websocket block {0} : {1} - {2}".format(type(e).__name__, str(e), self.pubkey[:5])) - await self.request_current_block() - except (WSServerHandshakeError, WSClientDisconnectedError, ClientResponseError) as e: + except (WSServerHandshakeError, WSClientDisconnectedError, ClientResponseError, ValueError) as e: logging.debug("Websocket block {0} : {1} - {2}".format(type(e).__name__, str(e), self.pubkey[:5])) await self.request_current_block() except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: @@ -381,10 +388,10 @@ class Node(QObject): """ try: conn_handler = self.endpoint.conn_handler() - block_data = await bma.blockchain.Current(conn_handler).get() + block_data = await bma.blockchain.Current(conn_handler).get(self._session) await self.refresh_block(block_data) - except ValueError as e: - if '404' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: self.main_chain_previous_block = None self.set_block(None) else: @@ -392,7 +399,7 @@ class Node(QObject): logging.debug("Error in block reply : {0}".format(self.pubkey[:5])) logging.debug(str(e)) self.changed.emit() - except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + except (ClientError, gaierror, TimeoutError, DisconnectedError, ValueError) as e: logging.debug("{0} : {1}".format(str(e), self.pubkey[:5])) self.state = Node.OFFLINE except jsonschema.ValidationError as e: @@ -415,16 +422,16 @@ class Node(QObject): try: if self.block: self.main_chain_previous_block = await bma.blockchain.Block(conn_handler, - self.block['number']).get() - except ValueError as e: - if '404' in str(e): + self.block['number']).get(self._session) + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: self.main_chain_previous_block = None else: self.state = Node.OFFLINE logging.debug("Error in previous block reply : {0}".format(self.pubkey[:5])) logging.debug(str(e)) self.changed.emit() - except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + except (ClientError, gaierror, TimeoutError, DisconnectedError, ValueError) as e: logging.debug("{0} : {1}".format(str(e), self.pubkey[:5])) self.state = Node.OFFLINE except jsonschema.ValidationError as e: @@ -445,14 +452,14 @@ class Node(QObject): conn_handler = self.endpoint.conn_handler() try: - peering_data = await bma.network.Peering(conn_handler).get() + peering_data = await bma.network.Peering(conn_handler).get(self._session) node_pubkey = peering_data["pubkey"] node_currency = peering_data["currency"] self.state = Node.ONLINE if peering_data['raw'] != self.peer.raw(): peer = Peer.from_signed_raw("{0}{1}\n".format(peering_data['raw'], peering_data['signature'])) - if peer.blockid.number > peer.blockid.number: + if peer.blockUID.number > peer.blockUID.number: self.peer = Peer.from_signed_raw("{0}{1}\n".format(peering_data['raw'], peering_data['signature'])) if node_pubkey != self.pubkey: @@ -464,11 +471,12 @@ class Node(QObject): logging.debug("Change : new state corrupted") self.changed.emit() - except ValueError as e: - logging.debug("Error in peering reply : {0}".format(str(e))) - self.state = Node.OFFLINE - self.changed.emit() - except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + except errors.DuniterError as e: + if e.ucode == errors.PEER_NOT_FOUND: + logging.debug("Error in peering reply : {0}".format(str(e))) + self.state = Node.OFFLINE + self.changed.emit() + except (ClientError, gaierror, TimeoutError, DisconnectedError, ValueError) as e: logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey[:5])) self.state = Node.OFFLINE except jsonschema.ValidationError as e: @@ -484,19 +492,15 @@ class Node(QObject): conn_handler = self.endpoint.conn_handler() try: - summary_data = await bma.node.Summary(conn_handler).get() - self.software = summary_data["ucoin"]["software"] - self.version = summary_data["ucoin"]["version"] + summary_data = await bma.node.Summary(conn_handler).get(self._session) + self.software = summary_data["duniter"]["software"] + self.version = summary_data["duniter"]["version"] self.state = Node.ONLINE - if "forkWindowSize" in summary_data["ucoin"]: - self.fork_window = summary_data["ucoin"]["forkWindowSize"] + if "forkWindowSize" in summary_data["duniter"]: + self.fork_window = summary_data["duniter"]["forkWindowSize"] else: self.fork_window = 0 - except ValueError as e: - logging.debug("Error in summary : {0}".format(e)) - self.state = Node.OFFLINE - self.changed.emit() - except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + except (ClientError, gaierror, TimeoutError, DisconnectedError, ValueError) as e: logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey[:5])) self.state = Node.OFFLINE except jsonschema.ValidationError as e: @@ -511,28 +515,28 @@ class Node(QObject): """ conn_handler = self.endpoint.conn_handler() try: - data = await bma.wot.Lookup(conn_handler, self.pubkey).get() + data = await bma.wot.Lookup(conn_handler, self.pubkey).get(self._session) self.state = Node.ONLINE - timestamp = 0 + timestamp = BlockUID.empty() uid = "" for result in data['results']: if result["pubkey"] == self.pubkey: uids = result['uids'] for uid in uids: - if uid["meta"]["timestamp"] > timestamp: + if BlockUID.from_str(uid["meta"]["timestamp"]) >= timestamp: timestamp = uid["meta"]["timestamp"] uid = uid["uid"] if self._uid != uid: self._uid = uid self.identity_changed.emit() - except ValueError as e: - if '404' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.NO_MATCHING_IDENTITY: logging.debug("UID not found : {0}".format(self.pubkey[:5])) else: logging.debug("error in uid reply : {0}".format(self.pubkey[:5])) self.state = Node.OFFLINE self.identity_changed.emit() - except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + except (ClientError, gaierror, TimeoutError, DisconnectedError, ValueError) as e: logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey[:5])) self.state = Node.OFFLINE except jsonschema.ValidationError as e: @@ -549,7 +553,7 @@ class Node(QObject): try: conn_handler = self.endpoint.conn_handler() peer_websocket = bma.ws.Peer(conn_handler) - ws_connection = peer_websocket.connect() + ws_connection = peer_websocket.connect(self._session) async with ws_connection as ws: self._connected['peer'] = True logging.debug("Connected successfully to peer ws : {0}".format(self.pubkey[:5])) @@ -562,10 +566,7 @@ class Node(QObject): break elif msg.tp == aiohttp.MsgType.error: break - except ValueError as e: - logging.debug("Websocket peer {0} : {1} - {2}".format(type(e).__name__, str(e), self.pubkey[:5])) - await self.request_peers() - except (WSServerHandshakeError, WSClientDisconnectedError, ClientResponseError) as e: + except (WSServerHandshakeError, WSClientDisconnectedError, ClientResponseError, ValueError) as e: logging.debug("Websocket peer {0} : {1} - {2}".format(type(e).__name__, str(e), self.pubkey[:5])) await self.request_peers() except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: @@ -586,21 +587,22 @@ class Node(QObject): conn_handler = self.endpoint.conn_handler() try: - peers_data = await bma.network.peering.Peers(conn_handler).get(leaves='true') + peers_data = await bma.network.peering.Peers(conn_handler).get(leaves='true', session=self._session) self.state = Node.ONLINE if peers_data['root'] != self._last_merkle['root']: leaves = [leaf for leaf in peers_data['leaves'] if leaf not in self._last_merkle['leaves']] for leaf_hash in leaves: try: - leaf_data = await bma.network.peering.Peers(conn_handler).get(leaf=leaf_hash) + leaf_data = await bma.network.peering.Peers(conn_handler).get(leaf=leaf_hash, + session=self._session) self.refresh_peer_data(leaf_data['leaf']['value']) - except (AttributeError, ValueError) as e: + except (AttributeError, ValueError, errors.DuniterError) as e: logging.debug("{pubkey} : Incorrect peer data in {leaf}".format(pubkey=self.pubkey[:5], leaf=leaf_hash)) self.state = Node.OFFLINE self.changed.emit() - except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + except (ClientError, gaierror, TimeoutError, DisconnectedError, ValueError) as e: logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey[:5])) self.state = Node.OFFLINE except jsonschema.ValidationError as e: @@ -609,10 +611,11 @@ class Node(QObject): self.state = Node.CORRUPTED self._last_merkle = {'root' : peers_data['root'], 'leaves': peers_data['leaves']} - except ValueError as e: - logging.debug("Error in peers reply") - self.state = Node.OFFLINE - self.changed.emit() + except errors.DuniterError as e: + if e.ucode == errors.PEER_NOT_FOUND: + logging.debug("Error in peers reply") + self.state = Node.OFFLINE + self.changed.emit() except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey)) self.state = Node.OFFLINE @@ -627,8 +630,7 @@ class Node(QObject): str_doc = "{0}{1}\n".format(peer_data['raw'], peer_data['signature']) peer_doc = Peer.from_signed_raw(str_doc) - pubkey = peer_data['pubkey'] - self.neighbour_found.emit(peer_doc, pubkey) + self.neighbour_found.emit(peer_doc) except MalformedDocumentError as e: logging.debug(str(e)) else: diff --git a/src/sakia/core/registry/identities.py b/src/sakia/core/registry/identities.py index 8ef736f2ead3abbbc9caff83b9c21c6f1f494651..cd0bb3623a8e843c7bf038f0fe4f15c306b54dd9 100644 --- a/src/sakia/core/registry/identities.py +++ b/src/sakia/core/registry/identities.py @@ -1,9 +1,8 @@ -from ucoinpy.api import bma +from duniterpy.api import bma, errors +from duniterpy.documents import BlockUID from .identity import Identity, LocalState, BlockchainState - -import json +from pkg_resources import parse_version import asyncio -import logging from aiohttp.errors import ClientError from ...tools.exceptions import NoPeerAvailable @@ -29,12 +28,13 @@ class IdentitiesRegistry: :param dict json_data: The identities in json format """ instances = {} + version = parse_version(json_data['version']) for currency in json_data['registry']: instances[currency] = {} for person_data in json_data['registry'][currency]: pubkey = person_data['pubkey'] if pubkey not in instances: - person = Identity.from_json(person_data) + person = Identity.from_json(person_data, version) instances[currency][person.pubkey] = person self._instances = instances @@ -68,19 +68,19 @@ class IdentitiesRegistry: try: data = await community.bma_access.simple_request(bma.wot.Lookup, req_args={'search': pubkey}) - timestamp = 0 + timestamp = BlockUID.empty() for result in data['results']: if result["pubkey"] == identity.pubkey: uids = result['uids'] for uid_data in uids: - if uid_data["meta"]["timestamp"] > timestamp: - identity.sigdate = uid_data["meta"]["timestamp"] + if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp: + identity.sigdate = BlockUID.from_str(uid_data["meta"]["timestamp"]) identity.uid = uid_data["uid"] identity.blockchain_state = BlockchainState.BUFFERED identity.local_state = LocalState.PARTIAL timestamp = identity.sigdate return identity - except ValueError: + except errors.DuniterError as e: lookup_tries += 1 except asyncio.TimeoutError: lookup_tries += 1 @@ -109,11 +109,11 @@ class IdentitiesRegistry: data = await community.bma_access.simple_request(bma.blockchain.Membership, req_args={'search': pubkey}) identity.uid = data['uid'] - identity.sigdate = data['sigDate'] + identity.sigdate = BlockUID.from_str(data['sigDate']) identity.local_state = LocalState.PARTIAL identity.blockchain_state = BlockchainState.VALIDATED - except ValueError as e: - if '404' in str(e) or '400' in str(e): + except errors.DuniterError as e: + if errors.NO_MEMBER_MATCHING_PUB_OR_UID: identity = await self._find_by_lookup(pubkey, community) return identity else: @@ -134,7 +134,7 @@ class IdentitiesRegistry: :param str uid: The person uid, also known as its uid on the network :param str pubkey: The person pubkey - :param int sig_date: The date of signature of the self certification + :param BlockUID sig_date: The date of signature of the self certification :param LocalState local_state: The local status of the identity :param sakia.core.Community community: The community from which we found data :rtype: sakia.core.registry.Identity diff --git a/src/sakia/core/registry/identity.py b/src/sakia/core/registry/identity.py index ce0e1d7757c284c59c612c4f4e7b2b7964911826..abd50a0edd5f6c119c4ccc746dc9439ca335659b 100644 --- a/src/sakia/core/registry/identity.py +++ b/src/sakia/core/registry/identity.py @@ -6,12 +6,12 @@ Created on 11 févr. 2014 import logging import time -import asyncio from enum import Enum +from pkg_resources import parse_version -from ucoinpy.documents.certification import SelfCertification -from ucoinpy.api import bma as bma -from ucoinpy.api.bma import PROTOCOL_VERSION +from duniterpy.documents import BlockUID, SelfCertification, MalformedDocumentError +from duniterpy.api import bma, errors +from duniterpy.api.bma import PROTOCOL_VERSION from ...tools.exceptions import Error, NoPeerAvailable,\ MembershipNotFoundError, LookupFailureError @@ -55,14 +55,16 @@ class Identity(QObject): :param str uid: The identity uid, also known as its uid on the network :param str pubkey: The identity pubkey - :parma int sig_date: The date of signature of the self certification + :parma BlockUID sig_date: The date of signature of the self certification :param LocalState local_state: The local status of the identity :param BlockchainState blockchain_state: The blockchain status of the identity """ + if sigdate: + assert type(sigdate) is BlockUID super().__init__() self.uid = uid self.pubkey = pubkey - self.sigdate = sigdate + self._sigdate = sigdate self.local_state = local_state self.blockchain_state = blockchain_state @@ -75,7 +77,7 @@ class Identity(QObject): return cls(uid, pubkey, sigdate, LocalState.COMPLETED, blockchain_state) @classmethod - def from_json(cls, json_data): + def from_json(cls, json_data, version): """ Create a person from json data @@ -84,23 +86,35 @@ class Identity(QObject): """ pubkey = json_data['pubkey'] uid = json_data['uid'] - sigdate = json_data['sigdate'] local_state = LocalState[json_data['local_state']] blockchain_state = BlockchainState[json_data['blockchain_state']] + if version >= parse_version("0.20.0dev0") and json_data['sigdate']: + sigdate = BlockUID.from_str(json_data['sigdate']) + else: + sigdate = BlockUID.empty() return cls(uid, pubkey, sigdate, local_state, blockchain_state) + @property + def sigdate(self): + return self._sigdate + + @sigdate.setter + def sigdate(self, sigdate): + assert type(sigdate) is BlockUID + self._sigdate = sigdate + async def selfcert(self, community): """ Get the identity self certification. This request is not cached in the person object. :param sakia.core.community.Community community: The community target to request the self certification - :return: A SelfCertification ucoinpy object - :rtype: ucoinpy.documents.certification.SelfCertification + :return: A SelfCertification duniterpy object + :rtype: duniterpy.documents.certification.SelfCertification """ try: - timestamp = 0 + timestamp = BlockUID.empty() lookup_data = await community.bma_access.future_request(bma.wot.Lookup, req_args={'search': self.pubkey}) @@ -108,14 +122,14 @@ class Identity(QObject): if result["pubkey"] == self.pubkey: uids = result['uids'] for uid_data in uids: - # If we sigDate was written in the blockchain - if self.sigdate and uid_data["meta"]["timestamp"] == self.sigdate: - timestamp = uid_data["meta"]["timestamp"] - uid = uid_data["uid"] - signature = uid_data["self"] + # If the sigDate was written in the blockchain + if self._sigdate and BlockUID.from_str(uid_data["meta"]["timestamp"]) == self._sigdate: + timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"]) + uid = uid_data["uid"] + signature = uid_data["self"] # Else we choose the latest one found - elif uid_data["meta"]["timestamp"] > timestamp: - timestamp = uid_data["meta"]["timestamp"] + elif BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp: + timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"]) uid = uid_data["uid"] signature = uid_data["self"] @@ -125,12 +139,14 @@ class Identity(QObject): return SelfCertification(PROTOCOL_VERSION, community.currency, self.pubkey, - timestamp, uid, + timestamp, signature) - except ValueError as e: - if '404' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.NO_MATCHING_IDENTITY: raise LookupFailureError(self.pubkey, community) + except MalformedDocumentError: + raise LookupFailureError(self.pubkey, community) except NoPeerAvailable: logging.debug("No peer available") @@ -150,8 +166,8 @@ class Identity(QObject): block = await community.bma_access.future_request(bma.blockchain.Block, req_args={'number': membership_data['blockNumber']}) return block['medianTime'] - except ValueError as e: - if '404' in str(e) or '400' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.NO_MEMBER_MATCHING_PUB_OR_UID: raise MembershipNotFoundError(self.pubkey, community.name) except NoPeerAvailable as e: logging.debug(str(e)) @@ -170,7 +186,7 @@ class Identity(QObject): expiration_date = join_date + parameters['sigValidity'] except NoPeerAvailable: expiration_date = None - except ValueError as e: + except errors.DuniterError as e: logging.debug("Expiration date not found") expiration_date = None except MembershipNotFoundError: @@ -192,9 +208,7 @@ class Identity(QObject): {'search': self.pubkey}) block_number = -1 membership_data = None - #TODO: Should not be here, should be set when we look for the identity - #We do it because we do not have this info in certifiers-of yet... - self.sigdate = search['sigDate'] + for ms in search['memberships']: if ms['blockNumber'] > block_number: block_number = ms['blockNumber'] @@ -208,8 +222,11 @@ class Identity(QObject): else: raise MembershipNotFoundError(self.pubkey, community.name) - except ValueError as e: - if '404' in str(e) or '400' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.NO_MEMBER_MATCHING_PUB_OR_UID: + raise MembershipNotFoundError(self.pubkey, community.name) + else: + logging.debug(str(e)) raise MembershipNotFoundError(self.pubkey, community.name) except NoPeerAvailable as e: logging.debug(str(e)) @@ -219,21 +236,20 @@ class Identity(QObject): try: data = await community.bma_access.future_request(bma.wot.Lookup, req_args={'search': self.pubkey}) - timestamp = 0 + timestamp = BlockUID.empty() for result in data['results']: if result["pubkey"] == self.pubkey: uids = result['uids'] person_uid = "" for uid_data in uids: - if uid_data["meta"]["timestamp"] > timestamp: + if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp: timestamp = uid_data["meta"]["timestamp"] person_uid = uid_data["uid"] if person_uid == self.uid: return True - except ValueError as e: - if '404' in str(e): - return False + except errors.DuniterError as e: + logging.debug("Lookup error : {0}".format(str(e))) except NoPeerAvailable as e: logging.debug(str(e)) return False @@ -244,9 +260,9 @@ class Identity(QObject): try: await community.bma_access.future_request(bma.wot.CertifiersOf, {'search': self.pubkey}) - except ValueError as e: - if '404' in str(e) or '400' in str(e): - return True + except errors.DuniterError as e: + if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID): + logging.debug("Certifiers of error : {0}".format(str(e))) return False async def is_member(self, community): @@ -260,11 +276,9 @@ class Identity(QObject): certifiers = await community.bma_access.future_request(bma.wot.CertifiersOf, {'search': self.pubkey}) return certifiers['isMember'] - except ValueError as e: - if '404' in str(e) or '400' in str(e): + except errors.DuniterError as e: + if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID): pass - else: - raise except NoPeerAvailable as e: logging.debug(str(e)) return False @@ -274,7 +288,7 @@ class Identity(QObject): Get the list of this person certifiers :param sakia.core.registry.identities.IdentitiesRegistry identities_registry: The identities registry - :param sakia.core.community.Community community: The community target to request the join date + :param sakia.core.community.Community community: The community target :return: The list of the certifiers of this community :rtype: list """ @@ -291,15 +305,15 @@ class Identity(QObject): BlockchainState.VALIDATED, community) certifier['cert_time'] = certifier_data['cert_time']['medianTime'] - if 'written' in certifier_data and type(certifier_data['written']) is dict: + if certifier_data['written']: certifier['block_number'] = certifier_data['written']['number'] else: - certifier['block_number'] = certifier_data['cert_time']['block'] + certifier['block_number'] = None certifiers.append(certifier) - except ValueError as e: - if '404' in str(e): - logging.debug('bma.wot.CertifiersOf request error') + except errors.DuniterError as e: + if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID): + logging.debug("Certifiers of error : {0}".format(str(e))) else: logging.debug(str(e)) except NoPeerAvailable as e: @@ -321,56 +335,22 @@ class Identity(QObject): None, BlockchainState.BUFFERED, community) - block = await community.bma_access.future_request(bma.blockchain.Block, - {'number': certifier_data['meta']['block_number']}) - certifier['cert_time'] = block['medianTime'] + certifier['cert_time'] = await community.time(certifier_data['meta']['block_number']) certifier['block_number'] = None certifiers.append(certifier) - except ValueError as e: - logging.debug("Lookup error : {0}".format(str(e))) + except errors.DuniterError as e: + if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID): + logging.debug("Lookup error : {0}".format(str(e))) except NoPeerAvailable as e: logging.debug(str(e)) return certifiers - async def unique_valid_certifiers_of(self, identities_registry, community): - """ - Get the certifications in the blockchain and in the pools - Get only unique and last certification for each pubkey - :param sakia.core.registry.identities.IdentitiesRegistry identities_registry: The identities registry - :param sakia.core.community.Community community: The community target to request the join date - :return: The list of the certifiers of this community - :rtype: list - """ - certifier_list = await self.certifiers_of(identities_registry, community) - unique_valid = [] - # add certifiers of uid - for certifier in tuple(certifier_list): - # add only valid certification... - try: - cert_expired = await community.certification_expired(certifier['cert_time']) - except NoPeerAvailable: - logging.debug("No peer available") - cert_expired = True - - if not cert_expired: - # keep only the latest certification - already_found = [c['identity'].pubkey for c in unique_valid] - if certifier['identity'].pubkey in already_found: - index = already_found.index(certifier['identity'].pubkey) - if certifier['cert_time'] > unique_valid[index]['cert_time']: - unique_valid[index] = certifier - else: - unique_valid.append(certifier) - return unique_valid - async def certified_by(self, identities_registry, community): """ Get the list of persons certified by this person :param sakia.core.registry.IdentitiesRegistry identities_registry: The registry - :param sakia.core.Community community: The community - - :param sakia.core.community.Community community: The community target to request the join date + :param sakia.core.community.Community community: The community target :return: The list of the certified persons of this community in BMA json format :rtype: list """ @@ -385,14 +365,14 @@ class Identity(QObject): BlockchainState.VALIDATED, community) certified['cert_time'] = certified_data['cert_time']['medianTime'] - if 'written' in certified_data and type(certified_data['written']) is dict: + if certified_data['written']: certified['block_number'] = certified_data['written']['number'] else: - certified['block_number'] = certified_data['cert_time']['block'] + certified['block_number'] = None certified_list.append(certified) - except ValueError as e: - if '404' in str(e): - logging.debug('bma.wot.CertifiedBy request error') + except errors.DuniterError as e: + if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID): + logging.debug("Certified by error : {0}".format(str(e))) except NoPeerAvailable as e: logging.debug(str(e)) @@ -408,40 +388,88 @@ class Identity(QObject): None, BlockchainState.BUFFERED, community) - certified['cert_time'] = certified_data['meta']['timestamp'] + timestamp = BlockUID.from_str(certified_data['meta']['timestamp']) + certified['cert_time'] = await community.time(timestamp.number) certified['block_number'] = None certified_list.append(certified) - except ValueError as e: - if '404' in str(e): - logging.debug('bma.wot.Lookup request error') + except errors.DuniterError as e: + if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID): + logging.debug("Lookup error : {0}".format(str(e))) except NoPeerAvailable as e: logging.debug(str(e)) return certified_list - async def unique_valid_certified_by(self, identities_registry, community): - certified_list = await self.certified_by(identities_registry, community) + async def _unique_valid(self, cert_list, community): + """ + Get the certifications in the blockchain and in the pools + Get only unique and last certification for each pubkey + :param list cert_list: The certifications list to filter + :param sakia.core.community.Community community: The community target + :return: The list of the certifiers of this community + :rtype: list + """ unique_valid = [] # add certifiers of uid - for certified in tuple(certified_list): + for certifier in tuple(cert_list): # add only valid certification... try: - cert_expired = await community.certification_expired(certified['cert_time']) + cert_expired = await community.certification_expired(certifier['cert_time']) except NoPeerAvailable: logging.debug("No peer available") cert_expired = True - if not cert_expired: + if not certifier['block_number']: + # add only valid certification... + try: + cert_writable = await community.certification_writable(certifier['cert_time']) + except NoPeerAvailable: + logging.debug("No peer available") + cert_writable = False + else: + cert_writable = True + + if not cert_expired and cert_writable: # keep only the latest certification already_found = [c['identity'].pubkey for c in unique_valid] - if certified['identity'].pubkey in already_found: - index = already_found.index(certified['identity'].pubkey) - if certified['cert_time'] > unique_valid[index]['cert_time']: - unique_valid[index] = certified + if certifier['identity'].pubkey in already_found: + index = already_found.index(certifier['identity'].pubkey) + if certifier['cert_time'] > unique_valid[index]['cert_time']: + unique_valid[index] = certifier else: - unique_valid.append(certified) + unique_valid.append(certifier) return unique_valid + async def unique_valid_certifiers_of(self, identities_registry, community): + """ + Get the certifications in the blockchain and in the pools + Get only unique and last certification for each pubkey + :param sakia.core.registry.identities.IdentitiesRegistry identities_registry: The identities registry + :param sakia.core.community.Community community: The community target + :return: The list of the certifiers of this community + :rtype: list + """ + certifier_list = await self.certifiers_of(identities_registry, community) + return await self._unique_valid(certifier_list, community) + + async def unique_valid_certified_by(self, identities_registry, community): + """ + Get the list of persons certified by this person, filtered to get only unique + and valid certifications. + :param sakia.core.registry.IdentitiesRegistry identities_registry: The registry + :param sakia.core.community.Community community: The community target + :return: The list of the certified persons of this community in BMA json format + :rtype: list + """ + certified_list = await self.certified_by(identities_registry, community) + return await self._unique_valid(certified_list, community) + async def membership_expiration_time(self, community): + """ + Get the remaining time before membership expiration + :param sakia.core.Community community: the community + :return: the remaining time + :rtype: int + """ membership = await self.membership(community) join_block = membership['blockNumber'] block = await community.get_block(join_block) @@ -451,16 +479,52 @@ class Identity(QObject): current_time = time.time() return expiration_date - current_time + async def cert_issuance_delay(self, identities_registry, community): + """ + Get the remaining time before being able to issue new certification. + :param sakia.core.Community community: the community + :return: the remaining time + :rtype: int + """ + certified = await self.certified_by(identities_registry, community) + if len(certified) > 0: + latest_time = max([c['cert_time'] for c in certified if c['cert_time']]) + parameters = await community.parameters() + if parameters and latest_time: + current_time = await community.time() + if current_time - latest_time < parameters['sigPeriod']: + return parameters['sigPeriod'] - (current_time - latest_time) + return 0 + + async def requirements(self, community): + """ + Get the current requirements data. + :param sakia.core.Community community: the community + :return: the requirements + :rtype: dict + """ + try: + requirements = await community.bma_access.future_request(bma.wot.Requirements, + {'search': self.pubkey}) + for req in requirements['identities']: + if req['pubkey'] == self.pubkey and req['uid'] == self.uid and \ + self._sigdate and \ + BlockUID.from_str(req['meta']['timestamp']) == self._sigdate: + return req + except errors.DuniterError as e: + logging.debug(str(e)) + return None + def _refresh_uid(self, uids): """ Refresh UID from uids list, got from a successful lookup request :param list uids: UIDs got from a lookup request """ - timestamp = 0 + timestamp = BlockUID.empty() if self.local_state == LocalState.NOT_FOUND: for uid_data in uids: - if uid_data["meta"]["timestamp"] > timestamp: - timestamp = uid_data["meta"]["timestamp"] + if BlockUID.from_str(uid_data["meta"]["timestamp"]) >= timestamp: + timestamp = BlockUID.from_str(uid_data["meta"]["timestamp"]) identity_uid = uid_data["uid"] self.uid = identity_uid self.blockchain_state = BlockchainState.BUFFERED @@ -473,7 +537,7 @@ class Identity(QObject): """ data = {'uid': self.uid, 'pubkey': self.pubkey, - 'sigdate': self.sigdate, + 'sigdate': str(self._sigdate) if self._sigdate else None, 'local_state': self.local_state.name, 'blockchain_state': self.blockchain_state.name} return data @@ -481,6 +545,6 @@ class Identity(QObject): def __str__(self): return "{uid} - {pubkey} - {sigdate} - {local} - {blockchain}".format(uid=self.uid, pubkey=self.pubkey, - sigdate=self.sigdate, + sigdate=self._sigdate, local=self.local_state, blockchain=self.blockchain_state) diff --git a/src/sakia/core/transfer.py b/src/sakia/core/transfer.py index f1d269fdda00659adfe45240bc6242704092eb01..3234a34a43f88a99b66fb56f1020afb234046b40 100644 --- a/src/sakia/core/transfer.py +++ b/src/sakia/core/transfer.py @@ -5,8 +5,8 @@ Created on 31 janv. 2015 """ import logging import time -from ucoinpy.api import bma -from ucoinpy.documents import Block, BlockId +from duniterpy.api import bma +from duniterpy.documents import Block, BlockUID from PyQt5.QtCore import pyqtSignal, QObject from enum import Enum @@ -36,7 +36,7 @@ class Transfer(QObject): transfer_broadcasted = pyqtSignal(str) broadcast_error = pyqtSignal(int, str) - def __init__(self, sha_hash, state, blockid, metadata, locally_created): + def __init__(self, sha_hash, state, blockUID, metadata, locally_created): """ The constructor of a transfer. Check for metadata keys which must be present : @@ -49,7 +49,7 @@ class Transfer(QObject): :param str sha_hash: The hash of the transaction :param TransferState state: The state of the Transfer - :param ucoinpy.documents.BlockId blockid: The blockid of the transaction in the blockchain + :param duniterpy.documents.BlockUID blockUID: The blockUID of the transaction in the blockchain :param dict metadata: The transfer metadata """ assert('receiver' in metadata) @@ -64,7 +64,7 @@ class Transfer(QObject): self.sha_hash = sha_hash self.state = state - self.blockid = blockid + self.blockUID = blockUID self._locally_created = locally_created self._metadata = metadata @@ -111,16 +111,16 @@ class Transfer(QObject): return cls(None, TransferState.TO_SEND, None, metadata, True) @classmethod - def create_from_blockchain(cls, hash, blockid, metadata): + def create_from_blockchain(cls, hash, blockUID, metadata): """ Create a new transfer sent from another sakia instance :param str hash: The transaction hash - :param ucoinpy.documents.BlockId blockid: The block id were we found the tx + :param duniterpy.documents.BlockUID blockUID: The block id were we found the tx :param dict metadata: The computed metadata of the transaction :return: A new transfer :rtype: Transfer """ - return cls(hash, TransferState.VALIDATING, blockid, metadata, False) + return cls(hash, TransferState.VALIDATING, blockUID, metadata, False) @classmethod def load(cls, data): @@ -132,7 +132,7 @@ class Transfer(QObject): """ return cls(data['hash'], TransferState[data['state']], - BlockId.from_str(data['blockid']) if data['blockid'] else None, + BlockUID.from_str(data['blockUID']) if data['blockUID'] else None, data['metadata'], data['local']) def jsonify(self): @@ -141,7 +141,7 @@ class Transfer(QObject): """ return {'hash': self.sha_hash, 'state': self.state.name, - 'blockid': str(self.blockid) if self.blockid else None, + 'blockUID': str(self.blockUID) if self.blockUID else None, 'metadata': self._metadata, 'local': self._locally_created} @@ -156,7 +156,7 @@ class Transfer(QObject): """ Check if the transaction could not be found in the blockchain :param bool rollback: True if we are in a rollback procedure - :param ucoinpy.documents.Block block: The block to look for the tx + :param duniterpy.documents.Block block: The block to look for the tx :param int mediantime_target: The mediantime to mine a block in the community parameters :param int mediantime_blocks: The number of block used to derive the mediantime :return: True if the transaction could not be found in a given time @@ -174,7 +174,7 @@ class Transfer(QObject): """ Check if the transaction can be found in the blockchain :param bool rollback: True if we are in a rollback procedure - :param ucoinpy.documents.Block block: The block to check for the transaction + :param duniterpy.documents.Block block: The block to check for the transaction :return: True if the transaction was found :rtype: bool """ @@ -188,7 +188,7 @@ class Transfer(QObject): """ Check if the retcode is 200 after a POST :param list ret_codes: The POST return codes of the broadcast - :param ucoinpy.documents.Block block: The current block used for transition. + :param duniterpy.documents.Block block: The current block used for transition. :return: True if the post was successful :rtype: bool """ @@ -207,22 +207,22 @@ class Transfer(QObject): """ Check if the transfer reached enough confrmation in the blockchain :param bool rollback: True if we are in a rollback procedure - :param ucoinpy.documents.Block current_block: The current block of the main blockchain + :param duniterpy.documents.Block current_block: The current block of the main blockchain :param int fork_window: The number of confrmations needed on the network :return: True if the transfer reached enough confrmations :rtype: bool """ - return not rollback and self.blockid.number + fork_window <= current_block.number + return not rollback and self.blockUID.number + fork_window <= current_block.number def _rollback_and_removed(self, rollback, block): """ Check if the transfer is not in the block anymore :param bool rollback: True if we are in a rollback procedure - :param ucoinpy.documents.Block block: The block to check for the transaction + :param duniterpy.documents.Block block: The block to check for the transaction :return: True if the transfer is not found in the block """ if rollback: - if not block or block.blockid != self.blockid: + if not block or block.blockUID != self.blockUID: return True else: return self.sha_hash not in [t.sha_hash for t in block.transactions] @@ -232,21 +232,21 @@ class Transfer(QObject): """ Check if the transfer is not in the block anymore :param bool rollback: True if we are in a rollback procedure - :param ucoinpy.documents.Block current_block: The block to check for the transaction + :param duniterpy.documents.Block current_block: The block to check for the transaction :return: True if the transfer is found in the block """ if rollback: - return self.blockid.number + fork_window > current_block.number + return self.blockUID.number + fork_window > current_block.number return False def _rollback_and_local(self, rollback, block): """ Check if the transfer is not in the block anymore :param bool rollback: True if we are in a rollback procedure - :param ucoinpy.documents.Block block: The block to check for the transaction + :param duniterpy.documents.Block block: The block to check for the transaction :return: True if the transfer is found in the block """ - if rollback and self._locally_created and block.blockid == self.blockid: + if rollback and self._locally_created and block.blockUID == self.blockUID: return self.sha_hash not in [t.sha_hash for t in block.transactions] return False @@ -260,9 +260,9 @@ class Transfer(QObject): def _wait(self, current_block): """ Set the transfer as AWAITING confrmation. - :param ucoinpy.documents.Block current_block: Current block of the main blockchain + :param duniterpy.documents.Block current_block: Current block of the main blockchain """ - self.blockid = current_block.blockid + self.blockUID = current_block.blockUID self._metadata['time'] = int(time.time()) def _be_validating(self, block): @@ -270,9 +270,9 @@ class Transfer(QObject): Action when the transfer ins found in a block :param bool rollback: True if we are in a rollback procedure - :param ucoinpy.documents.Block block: The block checked + :param duniterpy.documents.Block block: The block checked """ - self.blockid = block.blockid + self.blockUID = block.blockUID self._metadata['time'] = block.mediantime def _drop(self): @@ -280,7 +280,7 @@ class Transfer(QObject): Cancel the transfer locally. The transfer state becomes TransferState.DROPPED. """ - self.blockid = None + self.blockUID = None def _try_transition(self, transition_key, inputs): """ @@ -336,15 +336,15 @@ class Transfer(QObject): If the transaction was refused (return code != 200), state becomes REFUSED The txdoc is saved as the transfer txdoc. - :param txdoc: A transaction ucoinpy object + :param txdoc: A transaction duniterpy object :param community: The community target of the transaction """ self.sha_hash = txdoc.sha_hash responses = await community.bma_access.broadcast(bma.tx.Process, post_args={'transaction': txdoc.signed_raw()}) - blockid = await community.blockid() + blockUID = community.network.current_blockUID block = await community.bma_access.future_request(bma.blockchain.Block, - req_args={'number': blockid.number}) + req_args={'number': blockUID.number}) signed_raw = "{0}{1}\n".format(block['raw'], block['signature']) block_doc = Block.from_signed_raw(signed_raw) result = (False, "") @@ -363,7 +363,7 @@ class Transfer(QObject): """ Get the raw documents of this transfer """ - block = await community.get_block(self.blockid.number) + block = await community.get_block(self.blockUID.number) if block: block_doc = Block.from_signed_raw("{0}{1}\n".format(block['raw'], block['signature'])) for tx in block_doc.transactions: diff --git a/src/sakia/core/txhistory.py b/src/sakia/core/txhistory.py index 3e0fe056238bd4e404d41ebd75935d20c61af470..303ba3c1aa0f7f94639d846754fcb56d53b50dbe 100644 --- a/src/sakia/core/txhistory.py +++ b/src/sakia/core/txhistory.py @@ -1,9 +1,9 @@ import asyncio import logging import hashlib -from ucoinpy.documents.transaction import InputSource -from ucoinpy.documents.block import Block -from ucoinpy.api import bma +from duniterpy.documents.transaction import SimpleTransaction +from duniterpy.documents.block import Block +from duniterpy.api import bma, errors from .transfer import Transfer, TransferState from .net.network import MAX_CONFIRMATIONS from ..tools.exceptions import LookupFailureError, NoPeerAvailable @@ -28,7 +28,14 @@ class TxHistory(): def latest_block(self, value): self._latest_block = value - def load_from_json(self, data): + def load_from_json(self, data, version): + """ + Load the tx history cache from json data + + :param dict data: the data + :param version: the version parsed with pkg_resources.parse_version + :return: + """ self._transfers = [] data_sent = data['transfers'] @@ -36,7 +43,7 @@ class TxHistory(): self._transfers.append(Transfer.load(s)) for s in data['sources']: - self.available_sources.append(InputSource.from_inline(s['inline'])) + self.available_sources.append(s.copy()) for d in data['dividends']: d['state'] = TransferState[d['state']] @@ -51,13 +58,20 @@ class TxHistory(): data_sources = [] for s in self.available_sources: - s.index = 0 - data_sources.append({'inline': "{0}\n".format(s.inline())}) + data_sources.append(s) data_dividends = [] - for d in self._dividends.copy(): - d['state'] = d['state'].name - data_dividends.append(d) + for d in self._dividends: + dividend = { + 'block_number': d['block_number'], + "consumed": d['consumed'], + 'time': d['time'], + 'id': d['id'], + 'amount': d['amount'], + 'base': d['base'], + 'state': d['state'].name + } + data_dividends.append(dividend) return {'latest_block': self.latest_block, 'transfers': data_transfer, @@ -72,7 +86,7 @@ class TxHistory(): def dividends(self): return self._dividends.copy() - def stop_coroutines(self): + def stop_coroutines(self, closing=False): self._stop_coroutines = True async def _get_block_doc(self, community, number): @@ -97,26 +111,26 @@ class TxHistory(): logging.debug("Error in {0}".format(number)) block = None tries += 1 - except ValueError as e: - if '404' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: block = None tries += 1 return block_doc - async def _parse_transaction(self, community, tx, blockid, + async def _parse_transaction(self, community, tx, blockUID, mediantime, received_list, txid): """ Parse a transaction :param sakia.core.Community community: The community - :param ucoinpy.documents.Transaction tx: The tx json data - :param ucoinpy.documents.BlockId blockid: The block id where we found the tx + :param duniterpy.documents.Transaction tx: The tx json data + :param duniterpy.documents.BlockUID blockUID: The block id where we found the tx :param int mediantime: Median time on the network :param list received_list: The list of received transactions :param int txid: The latest txid :return: the found transaction """ - receivers = [o.pubkey for o in tx.outputs - if o.pubkey != tx.issuers[0]] + receivers = [o.conditions.left.pubkey for o in tx.outputs + if o.conditions.left.pubkey != tx.issuers[0]] if len(receivers) == 0: receivers = [tx.issuers[0]] @@ -146,35 +160,33 @@ class TxHistory(): in_issuers = len([i for i in tx.issuers if i == self.wallet.pubkey]) > 0 in_outputs = len([o for o in tx.outputs - if o.pubkey == self.wallet.pubkey]) > 0 + if o.conditions.left.pubkey == self.wallet.pubkey]) > 0 - # We check if the transaction correspond to one we sent - # but not from this sakia Instance - tx_hash = hashlib.sha1(tx.signed_raw().encode("ascii")).hexdigest().upper() + tx_hash = hashlib.sha256(tx.signed_raw().encode("ascii")).hexdigest().upper() # If the wallet pubkey is in the issuers we sent this transaction if in_issuers: outputs = [o for o in tx.outputs - if o.pubkey != self.wallet.pubkey] + if o.conditions.left.pubkey != self.wallet.pubkey] amount = 0 for o in outputs: amount += o.amount metadata['amount'] = amount transfer = Transfer.create_from_blockchain(tx_hash, - blockid, + blockUID, metadata.copy()) return transfer # If we are not in the issuers, - # maybe it we are in the recipients of this transaction + # maybe we are in the recipients of this transaction elif in_outputs: outputs = [o for o in tx.outputs - if o.pubkey == self.wallet.pubkey] + if o.conditions.left.pubkey == self.wallet.pubkey] amount = 0 for o in outputs: amount += o.amount metadata['amount'] = amount transfer = Transfer.create_from_blockchain(tx_hash, - blockid, + blockUID, metadata.copy()) received_list.append(transfer) return transfer @@ -197,12 +209,12 @@ class TxHistory(): new_tx = [t for t in block_doc.transactions if t.sha_hash not in [trans.sha_hash for trans in self._transfers] - ] + and SimpleTransaction.is_simple(t)] for (txid, tx) in enumerate(new_tx): - transfer = await self._parse_transaction(community, tx, block_doc.blockid, + transfer = await self._parse_transaction(community, tx, block_doc.blockUID, block_doc.mediantime, received_list, txid+txmax) - if transfer != None: + if transfer: #logging.debug("Transfer amount : {0}".format(transfer.metadata['amount'])) transfers.append(transfer) else: @@ -224,8 +236,8 @@ class TxHistory(): if d['block_number'] < parsed_block: dividends.remove(d) return dividends - except ValueError as e: - if '404' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: pass return {} @@ -304,14 +316,25 @@ class TxHistory(): :param int block_number: The block to check for transfers """ block_doc = await self._get_block_doc(community, block_number) + if block_doc: + # We check the block dividend state + match = [d for d in self._dividends if d['block_number'] == block_number] + if len(match) > 0: + if block_doc.ud: + match[0]['amount'] = block_doc.ud + match[0]['base'] = block_doc.unit_base + else: + self._dividends.remove(match[0]) - # We check if transactions are still present - for transfer in [t for t in self._transfers - if t.state in (TransferState.VALIDATING, TransferState.VALIDATED) and - t.blockid.number == block_number]: - if transfer.blockid.sha_hash == block_doc.blockid.sha_hash: - return True - transfer.run_state_transitions((True, block_doc)) + # We check if transactions are still present + for transfer in [t for t in self._transfers + if t.state in (TransferState.VALIDATING, TransferState.VALIDATED) and + t.blockUID.number == block_number]: + if transfer.blockUID.sha_hash == block_doc.blockUID.sha_hash: + return True + transfer.run_state_transitions((True, block_doc)) + else: + logging.debug("Could not get block document") return False async def _rollback(self, community): @@ -325,35 +348,39 @@ class TxHistory(): logging.debug("Rollback from : {0}".format(self.latest_block)) # We look for the block goal to check for rollback, # depending on validating and validated transfers... - tx_blocks = [tx.blockid.number for tx in self._transfers + tx_blocks = [tx.blockUID.number for tx in self._transfers if tx.state in (TransferState.VALIDATED, TransferState.VALIDATING) and - tx.blockid is not None] - tx_blocks.reverse() - for i, block_number in enumerate(tx_blocks): - self.wallet.refresh_progressed.emit(i, len(tx_blocks), self.wallet.pubkey) - if (await self._check_block(community, block_number)): + tx.blockUID is not None] + ud_blocks = [ud['block_number'] for ud in self._dividends + if ud['state'] in (TransferState.AWAITING, TransferState.VALIDATING)] + blocks = tx_blocks + ud_blocks + blocks.reverse() + for i, block_number in enumerate(blocks): + self.wallet.refresh_progressed.emit(i, len(blocks), self.wallet.pubkey) + if await self._check_block(community, block_number): break - current_block = await self._get_block_doc(community, community.network.current_blockid.number) - members_pubkeys = await community.members_pubkeys() - for transfer in [t for t in self._transfers - if t.state == TransferState.VALIDATED]: - transfer.run_state_transitions((True, current_block, MAX_CONFIRMATIONS)) + current_block = await self._get_block_doc(community, community.network.current_blockUID.number) + if current_block: + members_pubkeys = await community.members_pubkeys() + for transfer in [t for t in self._transfers + if t.state == TransferState.VALIDATED]: + transfer.run_state_transitions((True, current_block, MAX_CONFIRMATIONS)) except NoPeerAvailable: logging.debug("No peer available") async def refresh(self, community, received_list): # We update the block goal try: - current_block_number = community.network.current_blockid.number + current_block_number = community.network.current_blockUID.number if current_block_number: current_block = await community.bma_access.future_request(bma.blockchain.Block, req_args={'number': current_block_number}) members_pubkeys = await community.members_pubkeys() # We look for the first block to parse, depending on awaiting and validating transfers and ud... - tx_blocks = [tx.blockid.number for tx in self._transfers + tx_blocks = [tx.blockUID.number for tx in self._transfers if tx.state in (TransferState.AWAITING, TransferState.VALIDATING) \ - and tx.blockid is not None] + and tx.blockUID is not None] ud_blocks = [ud['block_number'] for ud in self._dividends if ud['state'] in (TransferState.AWAITING, TransferState.VALIDATING)] blocks = tx_blocks + ud_blocks + \ @@ -366,8 +393,9 @@ class TxHistory(): logging.debug("Starts a new refresh") task = asyncio.ensure_future(self._refresh(community, block_from, current_block, received_list)) self._running_refresh.append(task) - except ValueError as e: - logging.debug("Block not found") + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: + logging.debug("Block not found") except NoPeerAvailable: logging.debug("No peer available") diff --git a/src/sakia/core/wallet.py b/src/sakia/core/wallet.py index 70a0b7e0b37aedc7165d6e03fe79a990e1cf24e1..6faefe652cd628cfd3090e34d78a3db4f883fb5b 100644 --- a/src/sakia/core/wallet.py +++ b/src/sakia/core/wallet.py @@ -4,17 +4,19 @@ Created on 1 févr. 2014 @author: inso """ -from ucoinpy.documents.transaction import InputSource, OutputSource, Transaction -from ucoinpy.key import SigningKey +from duniterpy.documents.transaction import InputSource, OutputSource, Unlock, SIGParameter, Transaction, reduce_base +from duniterpy.grammars import output +from duniterpy.key import SigningKey -from ucoinpy.api import bma -from ucoinpy.api.bma import PROTOCOL_VERSION +from duniterpy.api import bma +from duniterpy.api.bma import PROTOCOL_VERSION from ..tools.exceptions import NotEnoughMoneyError, NoPeerAvailable, LookupFailureError from .transfer import Transfer from .txhistory import TxHistory -from .registry import IdentitiesRegistry, Identity +from .. import __version__ -from PyQt5.QtCore import QObject, pyqtSignal, QCoreApplication +from pkg_resources import parse_version +from PyQt5.QtCore import QObject, pyqtSignal import logging import asyncio @@ -78,10 +80,12 @@ class Wallet(QObject): :param dict json_data: The caches as a dict in json format """ + version = parse_version(json_data['version']) for currency in json_data: if currency != 'version': self.caches[currency] = TxHistory(app, self) - self.caches[currency].load_from_json(json_data[currency]) + if version >= parse_version("0.20.dev0"): + self.caches[currency].load_from_json(json_data[currency], version) def jsonify_caches(self): """ @@ -159,10 +163,10 @@ class Wallet(QObject): value = 0 sources = await self.sources(community) for s in sources: - value += s.amount + value += s['amount'] * pow(10, s['base']) return value - def tx_inputs(self, amount, community): + def tx_sources(self, amount, community): """ Get inputs to generate a transaction with a given amount of money @@ -171,21 +175,52 @@ class Wallet(QObject): :return: The list of inputs to use in the transaction document """ - value = 0 - inputs = [] + amount, amount_base = reduce_base(amount, 0) cache = self.caches[community.currency] - - buf_inputs = list(cache.available_sources) - for s in cache.available_sources: - value += s.amount - s.index = 0 - inputs.append(s) - buf_inputs.remove(s) - if value >= amount: - return (inputs, buf_inputs) + current_base = amount_base + while current_base >= 0: + value = 0 + sources = [] + buf_sources = list(cache.available_sources) + for s in [src for src in cache.available_sources if src['base'] == current_base]: + value += s['amount'] * pow(10, s['base']) + sources.append(s) + buf_sources.remove(s) + if value >= amount * pow(10, amount_base): + overhead = value - int(amount) + overhead, overhead_max_base = reduce_base(overhead, 0) + if overhead_max_base >= current_base: + return (sources, buf_sources) + current_base -= 1 raise NotEnoughMoneyError(value, community.currency, - len(inputs), amount) + len(sources), amount * pow(10, amount_base)) + + def tx_inputs(self, sources): + """ + Get inputs to generate a transaction with a given amount of money + + :param list sources: The sources used to send the given amount of money + + :return: The list of inputs to use in the transaction document + """ + inputs = [] + for s in sources: + inputs.append(InputSource(s['type'], s['identifier'], s['noffset'])) + return inputs + + def tx_unlocks(self, sources): + """ + Get unlocks to generate a transaction with a given amount of money + + :param list sources: The sources used to send the given amount of money + + :return: The list of unlocks to use in the transaction document + """ + unlocks = [] + for i, s in enumerate(sources): + unlocks.append(Unlock(i, [SIGParameter(0)])) + return unlocks def tx_outputs(self, pubkey, amount, inputs): """ @@ -201,14 +236,41 @@ class Wallet(QObject): inputs_value = 0 for i in inputs: logging.debug(i) - inputs_value += i.amount - + inputs_value += i['amount'] * pow(10, i['base']) + inputs_max_base = max([i['base'] for i in inputs]) overhead = inputs_value - int(amount) - outputs.append(OutputSource(pubkey, int(amount))) + + amount, amount_base = int(amount / pow(10, inputs_max_base)), inputs_max_base + overhead, overhead_base = int(overhead / pow(10, inputs_max_base)), inputs_max_base + + outputs.append(OutputSource(amount, amount_base, output.Condition.token(output.SIG.token(pubkey)))) if overhead != 0: - outputs.append(OutputSource(self.pubkey, overhead)) + outputs.append(OutputSource(overhead, overhead_base, output.Condition.token(output.SIG.token(self.pubkey)))) return outputs + def prepare_tx(self, pubkey, amount, message, community): + """ + Prepare a simple Transaction document + :param str pubkey: the target of the transaction + :param int amount: the amount sent to the receiver + :param Community community: the target community + :return: the transaction document + :rtype: duniterpy.documents.Transaction + """ + result = self.tx_sources(int(amount), community) + sources = result[0] + self.caches[community.currency].available_sources = result[1][1:] + logging.debug("Inputs : {0}".format(sources)) + + inputs = self.tx_inputs(sources) + unlocks = self.tx_unlocks(sources) + outputs = self.tx_outputs(pubkey, amount, sources) + logging.debug("Outputs : {0}".format(outputs)) + tx = Transaction(PROTOCOL_VERSION, community.currency, 0, + [self.pubkey], inputs, unlocks, + outputs, message, None) + return tx + async def send_money(self, salt, password, community, recipient, amount, message): """ @@ -222,9 +284,9 @@ class Wallet(QObject): :param str message: The message to send with the transfer """ try: - blockid = await community.blockid() + blockUID = community.network.current_blockUID block = await community.bma_access.future_request(bma.blockchain.Block, - req_args={'number': blockid.number}) + req_args={'number': blockUID.number}) except ValueError as e: if '404' in str(e): return False, "Could not send transfer with null blockchain" @@ -260,44 +322,32 @@ class Wallet(QObject): 'txid': txid } transfer = Transfer.initiate(metadata) - self.caches[community.currency]._transfers.append(transfer) - try: - result = self.tx_inputs(int(amount), community) - inputs = result[0] - self.caches[community.currency].available_sources = result[1][1:] - except NotEnoughMoneyError as e: - return False, str(e) - logging.debug("Inputs : {0}".format(inputs)) - - outputs = self.tx_outputs(recipient, amount, inputs) - logging.debug("Outputs : {0}".format(outputs)) - tx = Transaction(PROTOCOL_VERSION, community.currency, - [self.pubkey], inputs, - outputs, message, None) - logging.debug("TX : {0}".format(tx.raw())) + tx = self.prepare_tx(recipient, amount, message, community) + logging.debug("TX : {0}".format(tx.raw())) - tx.sign([key]) - logging.debug("Transaction : {0}".format(tx.signed_raw())) - return (await transfer.send(tx, community)) + tx.sign([key]) + logging.debug("Transaction : [{0}]".format(tx.signed_raw())) + return await transfer.send(tx, community) + except NotEnoughMoneyError as e: + return (False, str(e)) async def sources(self, community): """ Get available sources in a given community :param sakia.core.community.Community community: The community where we want available sources - :return: List of InputSource ucoinpy objects + :return: List of bma sources """ - tx = [] + sources = [] try: data = await community.bma_access.future_request(bma.tx.Sources, req_args={'pubkey': self.pubkey}) - for s in data['sources']: - tx.append(InputSource.from_bma(s)) + return data['sources'].copy() except NoPeerAvailable as e: logging.debug(str(e)) - return tx + return sources def transfers(self, community): """ @@ -323,9 +373,9 @@ class Wallet(QObject): else: return [] - def stop_coroutines(self): + def stop_coroutines(self, closing=False): for c in self.caches.values(): - c.stop_coroutines() + c.stop_coroutines(closing) def jsonify(self): """ @@ -335,4 +385,5 @@ class Wallet(QObject): """ return {'walletid': self.walletid, 'pubkey': self.pubkey, - 'name': self.name} + 'name': self.name, + 'version': __version__} diff --git a/src/sakia/gui/certification.py b/src/sakia/gui/certification.py index 4b847b300bf28b50e7a4356b38cfd87730d779a1..d547c447677834dff63bd6adeb787cef6fe4ceee 100644 --- a/src/sakia/gui/certification.py +++ b/src/sakia/gui/certification.py @@ -5,18 +5,16 @@ Created on 24 dec. 2014 """ import asyncio import logging - +from duniterpy.api import errors from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QApplication, QMessageBox +from PyQt5.QtCore import Qt, QObject, QLocale, QDateTime -from PyQt5.QtCore import Qt, QObject - -from ..gen_resources.certification_uic import Ui_CertificationDialog from .widgets import toast from .widgets.dialogs import QAsyncMessageBox from .member import MemberDialog from ..tools.decorators import asyncify, once_at_a_time from ..tools.exceptions import NoPeerAvailable - +from ..gen_resources.certification_uic import Ui_CertificationDialog class CertificationDialog(QObject): """ @@ -75,15 +73,18 @@ class CertificationDialog(QObject): self.ui.combo_community.currentIndexChanged.connect(self.change_current_community) @classmethod - def open_dialog(cls, app, account, password_asker): + def open_dialog(cls, app, account, community, password_asker): """ Certify and identity :param sakia.core.Application app: the application :param sakia.core.Account account: the account certifying the identity + :param sakia.core.Community community: the community :param sakia.gui.password_asker.PasswordAsker password_asker: the password asker :return: """ dialog = cls(app, account, password_asker, QDialog(), Ui_CertificationDialog()) + dialog.ui.combo_community.setCurrentText(community.name) + dialog.refresh() return dialog.exec() @classmethod @@ -101,6 +102,7 @@ class CertificationDialog(QObject): dialog.ui.combo_community.setCurrentText(community.name) dialog.ui.edit_pubkey.setText(identity.pubkey) dialog.ui.radio_pubkey.setChecked(True) + dialog.refresh() return await dialog.async_exec() @asyncify @@ -139,7 +141,8 @@ class CertificationDialog(QObject): def change_current_community(self, index): self.community = self.account.communities[index] self.ui.search_user.change_community(self.community) - if self.isVisible(): + self.ui.member_widget.change_community(self.community) + if self.widget.isVisible(): self.refresh() def selected_pubkey(self): @@ -181,16 +184,44 @@ class CertificationDialog(QObject): is_member = await account_identity.is_member(self.community) try: block_0 = await self.community.get_block(0) - except ValueError as e: - if '404' in str(e) or '000' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: block_0 = None except NoPeerAvailable as e: logging.debug(str(e)) block_0 = None + params = await self.community.parameters() + nb_certifications = len(await account_identity.unique_valid_certified_by(self.app.identities_registry, self.community)) + remaining_time = await account_identity.cert_issuance_delay(self.app.identities_registry, self.community) + cert_text = self.tr("Certifications sent : {nb_certifications}/{stock}").format( + nb_certifications=nb_certifications, + stock=params['sigStock']) + if remaining_time > 0: + cert_text += "\n" + days, remainder = divmod(remaining_time, 3600*24) + hours, remainder = divmod(remainder, 3600) + minutes, seconds = divmod(remainder, 60) + if days > 0: + remaining_localized = self.tr("{days} days").format(days=days) + else: + remaining_localized = self.tr("{hours} hours and {min} min.").format(hours=hours, + min=minutes) + cert_text += self.tr("Remaining time before next certification validation : {0}".format(remaining_localized)) + self.ui.label_cert_stock.setText(cert_text) + if is_member or not block_0: - self.ui.button_box.button(QDialogButtonBox.Ok).setEnabled(True) - self.ui.button_box.button(QDialogButtonBox.Ok).setText(self.tr("&Ok")) + if nb_certifications < params['sigStock'] or params['sigStock'] == 0: + self.ui.button_box.button(QDialogButtonBox.Ok).setEnabled(True) + if remaining_time > 0: + self.ui.button_box.button(QDialogButtonBox.Ok).setText(self.tr("&Ok") + + self.tr(" (Not validated before ") + + remaining_localized + ")") + else: + self.ui.button_box.button(QDialogButtonBox.Ok).setText(self.tr("&Ok")) + else: + self.ui.button_box.button(QDialogButtonBox.Ok).setEnabled(False) + self.ui.button_box.button(QDialogButtonBox.Ok).setText(self.tr("No more certifications")) else: self.ui.button_box.button(QDialogButtonBox.Ok).setEnabled(False) self.ui.button_box.button(QDialogButtonBox.Ok).setText(self.tr("Not a member")) diff --git a/src/sakia/gui/community_tile.py b/src/sakia/gui/community_tile.py index d8b20cc8668241f25bac6a2fcc8d461d6cfda6f8..3e59dc2574943482645ad20661f03ba739790945 100644 --- a/src/sakia/gui/community_tile.py +++ b/src/sakia/gui/community_tile.py @@ -2,12 +2,12 @@ @author: inso """ -import asyncio import enum from PyQt5.QtWidgets import QFrame, QLabel, QVBoxLayout, QLayout -from PyQt5.QtCore import QSize, pyqtSignal -from ucoinpy.documents.block import Block +from PyQt5.QtCore import QSize, pyqtSignal, QTime +from duniterpy.documents.block import Block +from duniterpy.api import errors from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task from ..tools.exceptions import NoPeerAvailable @@ -62,7 +62,7 @@ background-color: palette(base); def handle_nodes_change(self): if len(self.community.network.online_nodes) > 0: - if self.community.network.current_blockid.sha_hash == Block.Empty_Hash: + if self.community.network.current_blockUID.sha_hash == Block.Empty_Hash: state = CommunityState.NOT_INIT else: state = CommunityState.READY @@ -94,6 +94,31 @@ background-color: palette(base); else: localized_monetary_mass = "" status = self.app.current_account.pubkey in members_pubkeys + account_identity = await self.app.current_account.identity(self.community) + + mstime_remaining_text = self.tr("Expired or never published") + outdistanced_text = self.tr("Outdistanced") + + requirements = await account_identity.requirements(self.community) + mstime_remaining = 0 + nb_certs = 0 + if requirements: + mstime_remaining = requirements['membershipExpiresIn'] + nb_certs = len(requirements['certifications']) + if not requirements['outdistanced']: + outdistanced_text = self.tr("In WoT range") + + if mstime_remaining > 0: + days, remainder = divmod(mstime_remaining, 3600*24) + hours, remainder = divmod(remainder, 3600) + minutes, seconds = divmod(remainder, 60) + mstime_remaining_text = self.tr("Expires in ") + if days > 0: + mstime_remaining_text += "{days} days".format(days=days) + else: + mstime_remaining_text += "{hours} hours and {min} min.".format(hours=hours, + min=minutes) + status_value = self.tr("Member") if status else self.tr("Non-Member") status_color = '#00AA00' if status else self.tr('#FF0000') description = """<html> @@ -104,6 +129,8 @@ background-color: palette(base); <p>{nb_members} {members_label}</p> <p><span style="font-weight:600;">{monetary_mass_label}</span> : {monetary_mass}</p> <p><span style="font-weight:600;">{status_label}</span> : <span style="color:{status_color};">{status}</span></p> + <p><span style="font-weight:600;">{nb_certs_label}</span> : {nb_certs} ({outdistanced_text})</p> + <p><span style="font-weight:600;">{mstime_remaining_label}</span> : {mstime_remaining}</p> <p><span style="font-weight:600;">{balance_label}</span> : {balance}</p> </body> </html>""".format(currency=self.community.currency, @@ -114,6 +141,11 @@ background-color: palette(base); status_color=status_color, status_label=self.tr("Status"), status=status_value, + nb_certs_label=self.tr("Certs. received"), + nb_certs=nb_certs, + outdistanced_text=outdistanced_text, + mstime_remaining_label=self.tr("Membership"), + mstime_remaining=mstime_remaining_text, balance_label=self.tr("Balance"), balance=localized_amount) self.text_label.setText(description) @@ -130,8 +162,8 @@ background-color: palette(base); message=self.tr("Not connected")) self.text_label.setText(description) self._state = CommunityState.OFFLINE - except ValueError as e: - if '404' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: description = """<html> <body> <p> diff --git a/src/sakia/gui/community_view.py b/src/sakia/gui/community_view.py index cbc95c66b0aedbf800bde9654db0ef68c2fadb95..939fe237d28cb00c06054d1859c5c200c30ca5eb 100644 --- a/src/sakia/gui/community_view.py +++ b/src/sakia/gui/community_view.py @@ -6,7 +6,7 @@ Created on 2 févr. 2014 import logging import time - +from duniterpy.api import errors from PyQt5.QtCore import pyqtSlot, QDateTime, QLocale, QEvent, QT_TRANSLATE_NOOP, Qt from PyQt5.QtGui import QIcon, QPixmap from PyQt5.QtWidgets import QWidget, QMessageBox, QDialog, QPushButton, QTabBar, QAction @@ -104,9 +104,6 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): self.action_publish_uid.triggered.connect(self.publish_uid) self.toolbutton_menu.addAction(self.action_publish_uid) - self.action_revoke_uid.triggered.connect(self.revoke_uid) - self.toolbutton_menu.addAction(self.action_revoke_uid) - self.button_membership.clicked.connect(self.send_membership_demand) def show_closable_tab(self, tab, icon, title): @@ -155,6 +152,10 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): community.network.nodes_changed.connect(self.refresh_status) self.label_currency.setText(community.currency) logging.debug("Changed community to {0}".format(community)) + self.button_membership.setText(self.tr("Membership")) + self.button_membership.setEnabled(False) + self.button_certification.setEnabled(False) + self.action_publish_uid.setEnabled(False) self.community = community self.refresh_status() self.refresh_quality_buttons() @@ -231,7 +232,7 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): if self.community: text = "" - current_block_number = self.community.network.current_blockid.number + current_block_number = self.community.network.current_blockUID.number if current_block_number: text += self.tr("Block {0}").format(current_block_number) try: @@ -244,17 +245,16 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): except NoPeerAvailable as e: logging.debug(str(e)) text += " ( ### ) " - except ValueError as e: - logging.debug(str(e)) + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: + logging.debug(str(e)) if len(self.community.network.synced_nodes) == 0: self.button_membership.setEnabled(False) self.button_certification.setEnabled(False) self.button_send_money.setEnabled(False) else: - self.button_membership.setEnabled(True) - self.button_certification.setEnabled(True) - self.button_send_money.setEnabled(True) + self.refresh_quality_buttons() if self.community.network.quality > 0.66: icon = ':/icons/connected' @@ -282,7 +282,7 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): if published_uid: logging.debug("UID Published") self.action_revoke_uid.setEnabled(uid_is_revokable) - is_member = account_identity.is_member(self.community) + is_member = await account_identity.is_member(self.community) if is_member: self.button_membership.setText(self.tr("Renew membership")) self.button_membership.setEnabled(True) @@ -294,15 +294,16 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): self.button_membership.setEnabled(True) self.action_publish_uid.setEnabled(False) if self.community.get_block(0) is not None: - self.button_certification.setEnable(False) + self.button_certification.setEnabled(False) else: logging.debug("UID not published") self.button_membership.setEnabled(False) self.button_certification.setEnabled(False) self.action_publish_uid.setEnabled(True) except LookupFailureError: - self.button_membership.hide() - self.button_certification.hide() + self.button_membership.setEnabled(False) + self.button_certification.setEnabled(False) + self.action_publish_uid.setEnabled(False) def showEvent(self, event): self.refresh_status() @@ -376,25 +377,6 @@ The process to join back the community later will have to be done again.""") await QAsyncMessageBox.critical(self, self.tr("UID"), result[1]) - @asyncify - async def revoke_uid(self, checked=False): - password = await self.password_asker.async_exec() - if self.password_asker.result() == QDialog.Rejected: - return - result = await self.account.revoke(password, self.community) - if result[0]: - if self.app.preferences['notifications']: - toast.display(self.tr("Revoke UID"), self.tr("Your UID was revoked successfully.")) - else: - await QAsyncMessageBox.information(self, self.tr("Membership"), - self.tr("Your UID was revoked successfully.")) - else: - if self.app.preferences['notifications']: - toast.display(self.tr("Revoke UID"), result[1]) - else: - await QAsyncMessageBox.critical(self, self.tr("UID"), - result[1]) - def retranslateUi(self, widget): """ Method to complete translations missing from generated code diff --git a/src/sakia/gui/contact.py b/src/sakia/gui/contact.py index 04fcfb8ab976dbf46c7a1a7979e3e16af433272b..8d3036b91222e6f993f91173a9294fdad1bc6a0b 100644 --- a/src/sakia/gui/contact.py +++ b/src/sakia/gui/contact.py @@ -63,7 +63,7 @@ class ConfigureContactDialog(QDialog, Ui_ConfigureContactDialog): return ConfigureContactDialog(app, account, parent) @classmethod - def edit_contact(cls, app, parent, account, index): + def edit_contact(cls, app, account, parent, index): return ConfigureContactDialog(app, account, parent, None, index) def accept(self): diff --git a/src/sakia/gui/identities_tab.py b/src/sakia/gui/identities_tab.py index 02badc49cf9e7b5c52531f7ca038002c00097377..21e5ab64e61f2f5ee56208bfdee97bfcfc56c90d 100644 --- a/src/sakia/gui/identities_tab.py +++ b/src/sakia/gui/identities_tab.py @@ -10,7 +10,8 @@ from PyQt5.QtCore import Qt, pyqtSignal, QEvent, QT_TRANSLATE_NOOP, QObject from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QWidget, QAction, QMenu, QDialog, \ QAbstractItemView -from ucoinpy.api import bma +from duniterpy.api import bma, errors +from duniterpy.documents import BlockUID from ..models.identities import IdentitiesFilterProxyModel, IdentitiesTableModel from ..gen_resources.identities_tab_uic import Ui_IdentitiesTab @@ -125,14 +126,17 @@ class IdentitiesTabWidget(QObject): for uid_data in identity_data['uids']: identity = Identity.from_handled_data(uid_data['uid'], identity_data['pubkey'], - uid_data['meta']['timestamp'], + BlockUID.from_str(uid_data['meta']['timestamp']), BlockchainState.BUFFERED) identities.append(identity) self.ui.edit_textsearch.clear() self.ui.edit_textsearch.setPlaceholderText(text) await self.refresh_identities(identities) - except ValueError as e: + except errors.DuniterError as e: + if e.ucode == errors.BLOCK_NOT_FOUND: + logging.debug(str(e)) + except NoPeerAvailable as e: logging.debug(str(e)) finally: self.ui.busy.hide() diff --git a/src/sakia/gui/informations_tab.py b/src/sakia/gui/informations_tab.py index 087bcd6cc1fcd20dacfbfa7bb454b3614c08fe4c..15ebe78341ae2dbd728cf6127fc153352c57595d 100644 --- a/src/sakia/gui/informations_tab.py +++ b/src/sakia/gui/informations_tab.py @@ -5,7 +5,6 @@ Created on 31 janv. 2015 """ import logging -import asyncio from PyQt5.QtCore import QLocale, QDateTime, QEvent from PyQt5.QtWidgets import QWidget from ..gen_resources.informations_tab_uic import Ui_InformationsTabWidget @@ -93,6 +92,18 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget): self.community, self.app)\ .diff_localized(True, self.app.preferences['international_system_of_units']) + localized_ud_median_time = QLocale.toString( + QLocale(), + QDateTime.fromTime_t(block_ud['medianTime']), + QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) + ) + + localized_next_ud_median_time = QLocale.toString( + QLocale(), + QDateTime.fromTime_t(block_ud['medianTime'] + params['dt']), + QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) + ) + if block_ud_minus_1: mass_minus_1 = (float(0) if block_ud['membersCount'] == 0 else block_ud_minus_1['monetaryMass'] / block_ud['membersCount']) @@ -107,6 +118,12 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget): actual_growth = float(0) else: actual_growth = block_ud['dividend'] / (block_ud_minus_1['monetaryMass'] / block_ud['membersCount']) + + localized_ud_median_time_minus_1 = QLocale.toString( + QLocale(), + QDateTime.fromTime_t(block_ud_minus_1['medianTime']), + QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) + ) else: localized_mass_minus_1_per_member = QLocale().toString( float(0), 'f', self.app.preferences['digits_after_comma'] @@ -115,6 +132,7 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget): float(0), 'f', self.app.preferences['digits_after_comma'] ) actual_growth = float(0) + localized_ud_median_time_minus_1 = "####" # set infos in label self.label_general.setText( @@ -144,23 +162,11 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget): actual_growth, params['dt'] / 86400, self.tr('Actual growth c = UD(t)/[M(t-1)/N(t)]'), - QLocale.toString( - QLocale(), - QDateTime.fromTime_t(block_ud_minus_1['medianTime']), - QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) - ), + localized_ud_median_time_minus_1, self.tr('Penultimate UD date and time (t-1)'), - QLocale.toString( - QLocale(), - QDateTime.fromTime_t(block_ud['medianTime']), - QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) - ), + localized_ud_median_time, self.tr('Last UD date and time (t)'), - QLocale.toString( - QLocale(), - QDateTime.fromTime_t(block_ud['medianTime'] + params['dt']), - QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) - ), + localized_next_ud_median_time, self.tr('Next UD date and time (t+1)') ) ) @@ -265,17 +271,22 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget): <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> + <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr> </table> """).format( - params['sigDelay'] / 86400, - self.tr('Minimum delay between 2 identical certifications (in days)'), + params['sigPeriod'] / 86400, + self.tr('Minimum delay between 2 certifications (in days)'), params['sigValidity'] / 86400, self.tr('Maximum age of a valid signature (in days)'), params['sigQty'], self.tr('Minimum quantity of signatures to be part of the WoT'), - params['sigWoT'], - self.tr( - 'Minimum quantity of valid made certifications to be part of the WoT for distance rule'), + params['sigStock'], + self.tr('Maximum quantity of active certifications made by member.'), + params['sigWindow'], + self.tr('Maximum delay a certification can wait before being expired for non-writing.'), + params['xpercent'], + self.tr('Minimum percent of sentries to reach to match the distance rule'), params['msValidity'] / 86400, self.tr('Maximum age of a valid membership (in days)'), params['stepMax'], diff --git a/src/sakia/gui/mainwindow.py b/src/sakia/gui/mainwindow.py index 842484ec6172a244cb6fbc4a3b8375c1739f56d3..95ce58f6ab7a3a1e0a9e9d3ebc5d812b309326b2 100644 --- a/src/sakia/gui/mainwindow.py +++ b/src/sakia/gui/mainwindow.py @@ -3,12 +3,12 @@ Created on 1 févr. 2014 @author: inso """ -import asyncio +import aiohttp import logging from PyQt5.QtWidgets import QMainWindow, QAction, QFileDialog, QMessageBox, QLabel, QComboBox, QDialog, QApplication from PyQt5.QtCore import QLocale, QEvent, \ - pyqtSlot, QDateTime, QTimer, Qt, QObject + pyqtSlot, QDateTime, QTimer, Qt, QObject, QUrl from PyQt5.QtGui import QIcon from ..gen_resources.mainwindow_uic import Ui_MainWindow @@ -23,6 +23,7 @@ from .password_asker import PasswordAskerDialog from .preferences import PreferencesDialog from .process_cfg_community import ProcessConfigureCommunity from .homescreen import HomeScreenWidget +from .node_manager import NodeManager from ..core import money from ..core.community import Community from ..tools.decorators import asyncify @@ -35,7 +36,8 @@ class MainWindow(QObject): classdocs """ - def __init__(self, app, account, homescreen, community_view, widget, ui, + def __init__(self, app, account, homescreen, community_view, node_manager, + widget, ui, label_icon, label_status, label_time, combo_referential, password_asker): """ @@ -44,6 +46,7 @@ class MainWindow(QObject): :param sakia.core.Account account: the account :param HomeScreenWidgetcreen homescreen: the homescreen :param CommunityView community_view: the community view + :param NodeManager node_manager: the local node manager dialog :param QMainWindow widget: the widget of the main window :param Ui_MainWindow ui: the ui of the widget :param QLabel label_icon: the label of the icon in the statusbar @@ -76,12 +79,15 @@ class MainWindow(QObject): self.combo_referential = combo_referential self.combo_referential.setEnabled(False) - self.combo_referential.currentIndexChanged.connect(self.referential_changed) + self.combo_referential.currentIndexChanged[int].connect(self.referential_changed) self.homescreen = homescreen self.community_view = community_view + self.node_manager = node_manager + + def _init_ui(self): """ Connects elements of the UI to the local slots @@ -102,6 +108,9 @@ class MainWindow(QObject): self.ui.actionPreferences.triggered.connect(self.open_preferences_dialog) self.ui.actionAbout.triggered.connect(self.open_about_popup) + self.ui.actionManage_local_node.triggered.connect(self.open_duniter_ui) + self.ui.menu_duniter.setDisabled(True) + def _init_homescreen(self): """ Initialize homescreen signals/slots and data @@ -132,8 +141,10 @@ class MainWindow(QObject): @classmethod def startup(cls, app): qmainwindow = QMainWindow() + main_window = cls(app, None, HomeScreenWidget(app, None), CommunityWidget(app, None, None), + None, #NodeManager.create(qmainwindow), qmainwindow, Ui_MainWindow(), QLabel("", qmainwindow), QLabel("", qmainwindow), QLabel("", qmainwindow), QComboBox(qmainwindow), @@ -190,7 +201,7 @@ class MainWindow(QObject): error, QMessageBox.Ok) - @pyqtSlot(str) + @pyqtSlot(int) def referential_changed(self, index): if self.account: self.account.set_display_referential(index) @@ -246,6 +257,7 @@ class MainWindow(QObject): def open_certification_dialog(self): CertificationDialog.open_dialog(self.app, self.account, + self.community_view.community, self.password_asker) def open_add_contact_dialog(self): @@ -284,7 +296,8 @@ class MainWindow(QObject): text = self.tr(""" <h1>sakia</h1> - <p>Python/Qt uCoin client</p> + <p>Python/Qt duniter client</p> + <p><a href="https://github.com/duniter/sakia">https://github.com/duniter/sakia</a></p> <p>Version : {:}</p> {new_version_text} @@ -346,6 +359,11 @@ class MainWindow(QObject): delete_action.setData(contact) delete_action.triggered.connect(self.delete_contact) + @asyncify + async def open_duniter_ui(self, checked=False): + if not self.node_manager.widget.isVisible(): + self.node_manager.open_home_page() + def refresh(self): """ Refresh main window diff --git a/src/sakia/gui/member.py b/src/sakia/gui/member.py index fc88680bf24f580def7eaf11a608d9b0b50704fc..c1c6f63dd253c77d9d7accbdb8207ce3e93fa3e0 100644 --- a/src/sakia/gui/member.py +++ b/src/sakia/gui/member.py @@ -7,7 +7,8 @@ from ..core.graph import WoTGraph from .widgets.busy import Busy from ..tools.decorators import asyncify from ..gen_resources.member_uic import Ui_MemberView -from ..tools.exceptions import MembershipNotFoundError +from ..tools.exceptions import MembershipNotFoundError, LookupFailureError, NoPeerAvailable +from ..core.registry import LocalState class MemberDialog(QObject): @@ -49,29 +50,44 @@ class MemberDialog(QObject): def as_widget(cls, parent_widget, app, account, community, identity): return cls(app, account, community, identity, QWidget(parent_widget), Ui_MemberView()) + def change_community(self, community): + """ + Change current community + :param sakia.core.Community community: the new community + """ + self.community = community + self.refresh() + @asyncify async def refresh(self): - if self.identity: + if self.identity and self.identity.local_state != LocalState.NOT_FOUND: self.ui.busy.show() self.ui.label_uid.setText(self.identity.uid) self.ui.label_properties.setText("") try: + identity_selfcert = await self.identity.selfcert(self.community) + publish_time = await self.community.time(identity_selfcert.timestamp.number) + join_date = await self.identity.get_join_date(self.community) - except MembershipNotFoundError: - join_date = None + if join_date is None: + join_date = self.tr('not a member') + else: + join_date = datetime.datetime.fromtimestamp(join_date).strftime("%d/%m/%Y %I:%M") - if join_date is None: - join_date = self.tr('not a member') + except MembershipNotFoundError: + join_date = "###" + except (LookupFailureError, NoPeerAvailable): + publish_time = None + join_date = "###" + + if publish_time: + uid_publish_date = QLocale.toString( + QLocale(), + QDateTime.fromTime_t(publish_time), + QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) + ) else: - join_date = datetime.datetime.fromtimestamp(join_date).strftime("%d/%m/%Y %I:%M") - - - identity_selfcert = await self.identity.selfcert(self.community) - uid_publish_date = QLocale.toString( - QLocale(), - QDateTime.fromTime_t(identity_selfcert.timestamp), - QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) - ) + uid_publish_date = "###" text = self.tr(""" <table cellpadding="5"> diff --git a/src/sakia/gui/network_tab.py b/src/sakia/gui/network_tab.py index 3264a1b0fc138cb10d06caca6ecc91d206304e67..ace7c59e9a5febad3462debcbb5a8735c9ebcc3a 100644 --- a/src/sakia/gui/network_tab.py +++ b/src/sakia/gui/network_tab.py @@ -11,7 +11,7 @@ from PyQt5.QtGui import QCursor, QDesktopServices from PyQt5.QtWidgets import QWidget, QMenu, QAction from PyQt5.QtCore import Qt, QModelIndex, pyqtSlot, QUrl, QEvent from ..models.network import NetworkTableModel, NetworkFilterProxyModel -from ucoinpy.api import bma +from duniterpy.api import bma from ..gen_resources.network_tab_uic import Ui_NetworkTabWidget diff --git a/src/sakia/gui/node_manager.py b/src/sakia/gui/node_manager.py new file mode 100644 index 0000000000000000000000000000000000000000..7dd8432442563ffc58754f7c52ccc8a2102f0ace --- /dev/null +++ b/src/sakia/gui/node_manager.py @@ -0,0 +1,58 @@ +import aiohttp + +from PyQt5.QtCore import QObject, QEvent, QUrl +from PyQt5.QtWidgets import QDialog + +#from ..gen_resources.node_manager_uic import Ui_NodeManager +from .widgets.dialogs import QAsyncMessageBox +from ..tools.decorators import asyncify + + +class NodeManager(QObject): + """ + A widget showing informations about a member + """ + + def __init__(self, widget, ui): + """ + Init MemberDialog + + :param PyQt5.QtWidget widget: The class of the widget + :param sakia.gen_resources.member_uic.Ui_DialogMember ui: the class of the ui applyed to the widget + :return: + """ + super().__init__() + self.widget = widget + self.ui = ui + self.ui.setupUi(self.widget) + self.widget.installEventFilter(self) + + @classmethod + def create(cls, parent): + raise TypeError("Not implemented ( https://github.com/duniter/sakia/issues/399 )") + #dialog = cls(QDialog(parent), Ui_NodeManager()) + #return dialog + + @asyncify + async def open_home_page(self): + try: + with aiohttp.ClientSession() as session: + response = await session.get("http://127.0.0.1:9220") + if response.status == 200: + self.ui.web_view.load(QUrl("http://127.0.0.1:9220")) + self.ui.web_view.show() + self.widget.show() + else: + await QAsyncMessageBox.critical(self.widget, "Local node manager", + "Could not access to local node ui.") + except aiohttp.ClientError: + await QAsyncMessageBox.critical(self.widget, "Local node manager", + "Could not connect to node. Please make sure it's running.") + + def eventFilter(self, source, event): + if event.type() == QEvent.Resize: + self.widget.resizeEvent(event) + return self.widget.eventFilter(source, event) + + def exec(self): + self.widget.exec() diff --git a/src/sakia/gui/preferences.py b/src/sakia/gui/preferences.py index 33d8ca6f95252f2eabf01af2159cd6aa2dc36d72..6f04bc1d4a8d245fc525c6d6c646f871c3006c65 100644 --- a/src/sakia/gui/preferences.py +++ b/src/sakia/gui/preferences.py @@ -55,6 +55,8 @@ class PreferencesDialog(QDialog, Ui_PreferencesDialog): self.spinbox_proxy_port.setValue(self.app.preferences.get('proxy_port', 8080)) self.edit_proxy_address.setText(self.app.preferences.get('proxy_address', "")) + self.checkbox_forgetfulness.setChecked(self.app.preferences.get('forgetfulness', True)) + def handle_proxy_change(self): self.spinbox_proxy_port.setEnabled(self.checkbox_proxy.isChecked()) self.edit_proxy_address.setEnabled(self.checkbox_proxy.isChecked()) diff --git a/src/sakia/gui/process_cfg_account.py b/src/sakia/gui/process_cfg_account.py index c8faaf50640001af1c4db6bc8c8d2a9353ae15dd..401c229a7a789aed7cd6e6f43350a0a3158826ea 100644 --- a/src/sakia/gui/process_cfg_account.py +++ b/src/sakia/gui/process_cfg_account.py @@ -5,7 +5,7 @@ Created on 6 mars 2014 """ import logging import asyncio -from ucoinpy.key import SigningKey +from duniterpy.key import SigningKey from ..gen_resources.account_cfg_uic import Ui_AccountConfigurationDialog from ..gui.process_cfg_community import ProcessConfigureCommunity from ..gui.password_asker import PasswordAskerDialog, detect_non_printable @@ -165,10 +165,13 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): self.setWindowTitle(self.tr("New account")) self.button_delete.hide() else: + self.label_action.setText("Edit account uid") + self.edit_account_name.setPlaceholderText(self.account.name) self.stacked_pages.removeWidget(self.stacked_pages.widget(1)) step_init.next_step = step_communities self.button_next.setEnabled(True) self.stacked_pages.currentWidget() + self.setWindowTitle(self.tr("Configure {0}".format(self.account.name))) def open_process_add_community(self): @@ -219,12 +222,12 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): dialog.exec_() @asyncify - async def action_delete_account(self): + async def action_delete_account(self, checked=False): reply = await QAsyncMessageBox.question(self, self.tr("Warning"), - self.tr("""This action will delete your account locally. + self.tr("""This action will delete your account ({0}) locally. Please note your key parameters (salt and password) if you wish to recover it later. Your account won't be removed from the networks it joined. -Are you sure ?""")) +Are you sure ?""").format(self.app.current_account.name)) if reply == QMessageBox.Yes: account = self.app.current_account await self.app.delete_account(account) diff --git a/src/sakia/gui/process_cfg_community.py b/src/sakia/gui/process_cfg_community.py index 0622c10d03d81237d331f902b1fab1bf022f80fc..5717579fb5dac384cc8501a94bd48e9f9578c64e 100644 --- a/src/sakia/gui/process_cfg_community.py +++ b/src/sakia/gui/process_cfg_community.py @@ -6,9 +6,11 @@ Created on 8 mars 2014 import logging import asyncio + import aiohttp -from ucoinpy.documents import MalformedDocumentError +from duniterpy.api import errors +from duniterpy.documents import MalformedDocumentError from PyQt5.QtWidgets import QDialog, QMenu, QApplication from PyQt5.QtGui import QCursor from PyQt5.QtCore import pyqtSignal, QObject @@ -20,6 +22,7 @@ from ..core.net import Node from .widgets import toast from .widgets.dialogs import QAsyncMessageBox from ..tools.decorators import asyncify +from ..tools.exceptions import NoPeerAvailable class Step(QObject): @@ -63,8 +66,9 @@ class StepPageInit(Step): server = self.config_dialog.lineedit_server.text() port = self.config_dialog.spinbox_port.value() logging.debug("Is valid ? ") + self.config_dialog.label_error.setText(self.tr("connecting...")) try: - self.node = await Node.from_address(None, server, port) + self.node = await Node.from_address(None, server, port, session=aiohttp.ClientSession()) community = Community.create(self.node) self.config_dialog.button_connect.setEnabled(False) self.config_dialog.button_register.setEnabled(False) @@ -76,14 +80,17 @@ class StepPageInit(Step): self.config_dialog.label_error.setText(str(e)) except (MalformedDocumentError, ValueError) as e: self.config_dialog.label_error.setText(str(e)) + except aiohttp.errors.TimeoutError: + self.config_dialog.label_error.setText(self.tr("Could not connect. Check hostname, ip address or port")) @asyncify async def check_connect(self, checked=False): server = self.config_dialog.lineedit_server.text() port = self.config_dialog.spinbox_port.value() logging.debug("Is valid ? ") + self.config_dialog.label_error.setText(self.tr("connecting...")) try: - self.node = await Node.from_address(None, server, port) + self.node = await Node.from_address(None, server, port, session=aiohttp.ClientSession()) community = Community.create(self.node) self.config_dialog.button_connect.setEnabled(False) self.config_dialog.button_register.setEnabled(False) @@ -104,14 +111,20 @@ Yours : {0}, the network : {1}""".format(registered[1], registered[2]))) self.config_dialog.label_error.setText(str(e)) except (MalformedDocumentError, ValueError) as e: self.config_dialog.label_error.setText(str(e)) + except NoPeerAvailable: + self.config_dialog.label_error.setText(self.tr("Could not connect. Check node peering entry")) + except aiohttp.errors.TimeoutError: + self.config_dialog.label_error.setText(self.tr("Could not connect. Check hostname, ip address or port")) @asyncify async def check_register(self, checked=False): server = self.config_dialog.lineedit_server.text() port = self.config_dialog.spinbox_port.value() logging.debug("Is valid ? ") + self.config_dialog.label_error.setText(self.tr("connecting...")) try: - self.node = await Node.from_address(None, server, port) + session = aiohttp.ClientSession() + self.node = await Node.from_address(None, server, port, session=session) community = Community.create(self.node) self.config_dialog.button_connect.setEnabled(False) self.config_dialog.button_register.setEnabled(False) @@ -141,12 +154,14 @@ Yours : {0}, the network : {1}""".format(registered[1], registered[2]))) Yours : {0}, the network : {1}""".format(registered[1], registered[2]))) else: self.config_dialog.label_error.setText(self.tr("Your account already exists on the network")) - except aiohttp.errors.DisconnectedError as e: - self.config_dialog.label_error.setText(str(e)) - except aiohttp.errors.ClientError as e: - self.config_dialog.label_error.setText(str(e)) - except (MalformedDocumentError, ValueError) as e: + except (MalformedDocumentError, ValueError, errors.DuniterError, + aiohttp.errors.ClientError, aiohttp.errors.DisconnectedError) as e: + session.close() self.config_dialog.label_error.setText(str(e)) + except NoPeerAvailable: + self.config_dialog.label_error.setText(self.tr("Could not connect. Check node peering entry")) + except aiohttp.errors.TimeoutError: + self.config_dialog.label_error.setText(self.tr("Could not connect. Check hostname, ip address or port")) def is_valid(self): return self.node is not None @@ -255,7 +270,7 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog): port = self.spinbox_add_port.value() try: - node = await Node.from_address(self.community.currency, server, port) + node = await Node.from_address(self.community.currency, server, port, session=self.community.network.session) self.community.add_node(node) except Exception as e: await QAsyncMessageBox.critical(self, self.tr("Error"), diff --git a/src/sakia/gui/transactions_tab.py b/src/sakia/gui/transactions_tab.py index 5c7892a00b07c23df681cb3a60edc1cbaf883cfb..a498c54944e80d7fa78313ad712d9e67dd26783c 100644 --- a/src/sakia/gui/transactions_tab.py +++ b/src/sakia/gui/transactions_tab.py @@ -1,6 +1,6 @@ import logging -import asyncio +from duniterpy.api import errors from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView from PyQt5.QtCore import Qt, QObject, QDateTime, QTime, QModelIndex, pyqtSignal, pyqtSlot, QEvent from PyQt5.QtGui import QCursor @@ -106,7 +106,7 @@ class TransactionsTabWidget(QObject): self.ui.date_to.setMaximumDateTime(tomorrow_datetime) except NoPeerAvailable as e: logging.debug(str(e)) - except ValueError as e: + except errors.DuniterError as e: logging.debug(str(e)) def refresh(self): @@ -150,18 +150,23 @@ class TransactionsTabWidget(QObject): @asyncify async def refresh_balance(self): self.ui.busy_balance.show() - amount = await self.app.current_account.amount(self.community) - localized_amount = await self.app.current_account.current_ref.instance(amount, self.community, + try: + amount = await self.app.current_account.amount(self.community) + localized_amount = await self.app.current_account.current_ref.instance(amount, self.community, self.app).localized(units=True, international_system=self.app.preferences['international_system_of_units']) - # set infos in label - self.ui.label_balance.setText( - self.tr("{:}") - .format( - localized_amount + # set infos in label + self.ui.label_balance.setText( + self.tr("{:}") + .format( + localized_amount + ) ) - ) + except NoPeerAvailable as e: + logging.debug(str(e)) + except errors.DuniterError as e: + logging.debug(str(e)) self.ui.busy_balance.hide() @once_at_a_time diff --git a/src/sakia/gui/transfer.py b/src/sakia/gui/transfer.py index f94788e581525d611e745f553bbffead11f128a7..dfa7229d7fb52d14a614d8d43acc2822ca203ec4 100644 --- a/src/sakia/gui/transfer.py +++ b/src/sakia/gui/transfer.py @@ -128,7 +128,7 @@ class TransferMoneyDialog(QObject): amount = self.ui.spinbox_amount.value() if not amount: - await QAsyncMessageBox.critical(self, self.tr("Money transfer"), + await QAsyncMessageBox.critical(self.widget, self.tr("Money transfer"), self.tr("No amount. Please give the transfert amount"), QMessageBox.Ok) self.ui.button_box.setEnabled(True) @@ -139,7 +139,7 @@ class TransferMoneyDialog(QObject): return QApplication.setOverrideCursor(Qt.WaitCursor) - QApplication.processEvents() + result = await self.wallet.send_money(self.account.salt, password, self.community, recipient, amount, comment) if result[0]: @@ -218,7 +218,7 @@ class TransferMoneyDialog(QObject): def async_exec(self): future = asyncio.Future() - self.widget.finished.connect(lambda r: future.set_result(r)) + self.widget.finished.connect(lambda r: future.set_result(r) and self.widget.finished.disconnect()) self.widget.open() return future diff --git a/src/sakia/gui/views/nodes/base_node.py b/src/sakia/gui/views/nodes/base_node.py index 53e0226b0ed0a6c0b2160a16a5811ce09e0fbaff..8c1d3c39a2bfd181664c5cc38692b2d366b5382e 100644 --- a/src/sakia/gui/views/nodes/base_node.py +++ b/src/sakia/gui/views/nodes/base_node.py @@ -24,10 +24,7 @@ class BaseNode(QGraphicsEllipseItem): self.status_wallet = self.metadata['status'] & NodeStatus.HIGHLIGHTED self.status_member = not self.metadata['status'] & NodeStatus.OUT self.text = self.metadata['text'] - try: - self.setToolTip(self.metadata['tooltip']) - except TypeError: - raise + self.setToolTip(self.text + " - " + self.metadata['tooltip']) self.arcs = [] self.menu = None self.action_sign = None @@ -35,6 +32,13 @@ class BaseNode(QGraphicsEllipseItem): self.action_contact = None self.action_show_member = None + def update_metadata(self, metadata): + self.metadata = metadata + self.status_wallet = self.metadata['status'] & NodeStatus.HIGHLIGHTED + self.status_member = not self.metadata['status'] & NodeStatus.OUT + self.text = self.metadata['text'] + self.setToolTip(self.text + " - " + self.metadata['tooltip']) + def mousePressEvent(self, event: QMouseEvent): """ Click on mouse button @@ -62,3 +66,4 @@ class BaseNode(QGraphicsEllipseItem): :param event: scene context menu event """ self.scene().node_context_menu_requested.emit(self.id) + diff --git a/src/sakia/gui/views/nodes/explorer_node.py b/src/sakia/gui/views/nodes/explorer_node.py index 7f985e91950a9d25c3a4195568cd908892c7d827..854d1e8fef5ac9b9eaa50aaf9981a1a696840037 100644 --- a/src/sakia/gui/views/nodes/explorer_node.py +++ b/src/sakia/gui/views/nodes/explorer_node.py @@ -7,7 +7,7 @@ import math class ExplorerNode(BaseNode): - def __init__(self, nx_node, center_pos, nx_pos, steps, steps_max): + def __init__(self, nx_node, center_pos, nx_pos, steps, steps_max, small): """ Create node in the graph scene @@ -16,29 +16,41 @@ class ExplorerNode(BaseNode): :param nx_pos: Position of the nodes in the graph :param int steps: The steps from the center identity :param int steps_max: The steps max of the graph + :param bool small: Small dots for big networks """ super().__init__(nx_node, nx_pos) self.steps = steps self.steps_max = steps_max self.highlighted = False + self.status_sentry = False + + if small: + self.setRect( + 0, + 0, + 10, + 10 + ) + self.text_item = None + else: + # text inside ellipse + self.text_item = QGraphicsSimpleTextItem(self) + self.text_item.setText(self.text) + # center ellipse around text + self.setRect( + 0, + 0, + self.text_item.boundingRect().width() * 2, + self.text_item.boundingRect().height() * 2 + ) + # center text in ellipse + self.text_item.setPos(self.boundingRect().width() / 4.0, self.boundingRect().height() / 4.0) - # text inside ellipse - self.text_item = QGraphicsSimpleTextItem(self) - self.text_item.setText(self.text) - # center ellipse around text - self.setRect( - 0, - 0, - self.text_item.boundingRect().width() * 2, - self.text_item.boundingRect().height() * 2 - ) # set anchor to the center self.setTransform( QTransform().translate(-self.boundingRect().width() / 2.0, -self.boundingRect().height() / 2.0)) - # center text in ellipse - self.text_item.setPos(self.boundingRect().width() / 4.0, self.boundingRect().height() / 4.0) # cursor change on hover self.setAcceptHoverEvents(True) @@ -53,20 +65,28 @@ class ExplorerNode(BaseNode): self.setPos(center_pos) self.move_to(nx_pos) + def update_metadata(self, metadata): + super().update_metadata(metadata) + self.status_sentry = self.metadata['is_sentry'] if 'is_sentry' in self.metadata else False + self._refresh_colors() + def _refresh_colors(self): """ Refresh elements in the node """ # color around ellipse - outline_color = QColor('black') + outline_color = QColor('grey') outline_style = Qt.SolidLine outline_width = 1 if self.status_wallet: - outline_color = QColor('grey') outline_width = 2 if not self.status_member: outline_color = QColor('red') - outline_style = Qt.SolidLine + + if self.status_sentry: + outline_color = QColor('black') + outline_width = 3 + self.setPen(QPen(outline_color, outline_width, outline_style)) if self.highlighted: @@ -76,7 +96,9 @@ class ExplorerNode(BaseNode): if self.status_wallet == NodeStatus.HIGHLIGHTED: text_color = QColor('grey') - self.text_item.setBrush(QBrush(text_color)) + + if self.text_item: + self.text_item.setBrush(QBrush(text_color)) # create gradient inside the ellipse gradient = QRadialGradient(QPointF(0, self.boundingRect().height() / 4), self.boundingRect().width()) @@ -107,7 +129,8 @@ class ExplorerNode(BaseNode): x = origin_x + (final_x - origin_x) * value y = origin_y + (final_y - origin_y) * value self.setPos(x, y) - self.scene().node_moved.emit(self.id, x, y) + if self.scene(): + self.scene().node_moved.emit(self.id, x, y) def timeline_ends(): self.setPos(final_x, final_y) diff --git a/src/sakia/gui/views/scenes/explorer_scene.py b/src/sakia/gui/views/scenes/explorer_scene.py index 0c069ead7b04956cccec6cfa80f19c43715a0bab..11b8511c8ecce401d6079dfc7275826ed0cb1b23 100644 --- a/src/sakia/gui/views/scenes/explorer_scene.py +++ b/src/sakia/gui/views/scenes/explorer_scene.py @@ -73,7 +73,7 @@ class ExplorerScene(BaseScene): while queue: n = queue.pop() nsteps = data[n]['scenter'] + 1 - for edge in networkx.edges(nx_graph, n): + for edge in networkx.edges(nx_graph.to_undirected(), n): next_node = edge[0] if edge[0] is not n else edge[1] if data[next_node]['sparent']: continue @@ -128,7 +128,7 @@ class ExplorerScene(BaseScene): :param str current: the current node which we compute the subtree """ ratio = data[current]['span'] / data[current]['stsize'] - for edge in nx_graph.edges(current): + for edge in nx_graph.to_undirected().edges(current): next_node = edge[0] if edge[0] != current else edge[1] if data[next_node]['sparent'] != current: continue @@ -152,7 +152,7 @@ class ExplorerScene(BaseScene): else: theta = data[current]['theta'] - data[current]['span'] / 2 - for edge in nx_graph.edges(current): + for edge in nx_graph.to_undirected().edges(current): next_node = edge[0] if edge[0] != current else edge[1] if data[next_node]['sparent'] != current: continue @@ -179,7 +179,7 @@ class ExplorerScene(BaseScene): if len(nx_graph.nodes()) == 1: return {nx_graph.nodes()[0]: (0, 0)} - nx_graph = nx_graph.to_undirected() + #nx_graph = nx_graph.to_undirected() data = ExplorerScene._init_layout(nx_graph) if not center: @@ -191,7 +191,7 @@ class ExplorerScene(BaseScene): data[center]['theta'] = 0.0 ExplorerScene._set_positions(nx_graph, data, center) - distances = networkx.shortest_path_length(nx_graph, center) + distances = networkx.shortest_path_length(nx_graph.to_undirected(), center) nx_pos = {} for node in nx_graph.nodes(): hyp = distances[node] + 1 @@ -246,6 +246,7 @@ class ExplorerScene(BaseScene): if nx_node[0] in self.nodes: v = self.nodes[nx_node[0]] v.move_to(graph_pos) + v.update_metadata(nx_node[1]) else: center_pos = None if len(nx_graph.edges(nx_node[0])) > 0: @@ -260,13 +261,15 @@ class ExplorerScene(BaseScene): else: center_pos = QPoint(0, 0) - v = ExplorerNode(nx_node, center_pos, graph_pos, distances[nx_node[0]], dist_max) + small = distances[nx_node[0]] > 1 + + v = ExplorerNode(nx_node, center_pos, graph_pos, distances[nx_node[0]], dist_max, small) self.addItem(v) self.nodes[nx_node[0]] = v for edge in nx_graph.edges(data=True): edge[2]["confirmation_text"] = "" - if (edge[0], edge[1]) not in self.edges and (edge[1], edge[0]) not in self.edges: + if (edge[0], edge[1]) not in self.edges: distance = max(self.nodes[edge[0]].steps, self.nodes[edge[1]].steps) explorer_edge = ExplorerEdge(edge[0], edge[1], edge[2], graph_pos, distance, dist_max) self.node_moved.connect(explorer_edge.move_source_point) @@ -283,18 +286,24 @@ class ExplorerScene(BaseScene): for node in self.nodes.values(): node.neutralize() + + path = [] try: - path = networkx.shortest_path(self.nx_graph.to_undirected(), self.identity.pubkey, node_id) - - for node, next_node in zip(path[:-1], path[1:]): - if (node, next_node) in self.edges: - edge = self.edges[(node, next_node)] - elif (next_node, node) in self.edges: - edge = self.edges[(next_node, node)] - if edge: - edge.highlight() - self.nodes[node].highlight() - self.nodes[next_node].highlight() - logging.debug("Update edge between {0} and {1}".format(node, next_node)) + path = networkx.shortest_path(self.nx_graph, node_id, self.identity.pubkey) except (networkx.exception.NetworkXError, networkx.exception.NetworkXNoPath) as e: logging.debug(str(e)) + try: + path = networkx.shortest_path(self.nx_graph, self.identity.pubkey, node_id) + except (networkx.exception.NetworkXError, networkx.exception.NetworkXNoPath) as e: + logging.debug(str(e)) + + for node, next_node in zip(path[:-1], path[1:]): + if (node, next_node) in self.edges: + edge = self.edges[(node, next_node)] + elif (next_node, node) in self.edges: + edge = self.edges[(next_node, node)] + if edge: + edge.highlight() + self.nodes[node].highlight() + self.nodes[next_node].highlight() + logging.debug("Update edge between {0} and {1}".format(node, next_node)) diff --git a/src/sakia/gui/widgets/context_menu.py b/src/sakia/gui/widgets/context_menu.py index 34b6025ec5748ee2687ebdc288b4d5a0be8272c3..60e7b4a14ca899b66231c30894fe693978ee6b76 100644 --- a/src/sakia/gui/widgets/context_menu.py +++ b/src/sakia/gui/widgets/context_menu.py @@ -1,6 +1,6 @@ from PyQt5.QtWidgets import QMenu, QAction, QApplication, QMessageBox from PyQt5.QtCore import QObject, pyqtSignal -from ucoinpy.documents import Block, Membership +from duniterpy.documents import Block, Membership import logging from ..member import MemberDialog @@ -96,9 +96,9 @@ class ContextMenu(QObject): copy_doc.triggered.connect(lambda checked, tx=transfer: menu.copy_transaction_to_clipboard(tx)) menu.qmenu.addAction(copy_doc) - if transfer.blockid: + if transfer.blockUID: copy_doc = QAction(menu.qmenu.tr("Copy transaction block to clipboard"), menu.qmenu.parent()) - copy_doc.triggered.connect(lambda checked, number=transfer.blockid.number: + copy_doc.triggered.connect(lambda checked, number=transfer.blockUID.number: menu.copy_block_to_clipboard(number)) menu.qmenu.addAction(copy_doc) @@ -174,7 +174,8 @@ QMessageBox.Ok | QMessageBox.Cancel) async def copy_transaction_to_clipboard(self, tx): clipboard = QApplication.clipboard() raw_doc = await tx.get_raw_document(self._community) - clipboard.setText(raw_doc.signed_raw()) + if raw_doc: + clipboard.setText(raw_doc.signed_raw()) @asyncify async def copy_block_to_clipboard(self, number): diff --git a/src/sakia/gui/widgets/search_user.py b/src/sakia/gui/widgets/search_user.py index e93b906e39abfcfd01d07b1a66651055ef9beaba..a2aea2012bdb1d9dcd3fa21c3c2dc154a76069b2 100644 --- a/src/sakia/gui/widgets/search_user.py +++ b/src/sakia/gui/widgets/search_user.py @@ -3,7 +3,7 @@ import logging from PyQt5.QtCore import QEvent, pyqtSignal, QT_TRANSLATE_NOOP, Qt from PyQt5.QtWidgets import QComboBox, QWidget -from ucoinpy.api import bma +from duniterpy.api import bma, errors from ...tools.decorators import asyncify from ...tools.exceptions import NoPeerAvailable @@ -81,8 +81,8 @@ class SearchUserWidget(QWidget, Ui_SearchUserWidget): self.combobox_search.addItem(uid) self.blockSignals(False) self.combobox_search.showPopup() - except ValueError as e: - if '404' in str(e): + except errors.DuniterError as e: + if e.ucode == errors.NO_MATCHING_IDENTITY: self.nodes = list() self.blockSignals(True) self.combobox_search.clear() diff --git a/src/sakia/main.py b/src/sakia/main.py index 071eb66b964556c9c27b7f7524bb12d6dc63c7c9..1ec5f5d1cc9311b710f3fc5e84570b8419a6cb09 100755 --- a/src/sakia/main.py +++ b/src/sakia/main.py @@ -62,6 +62,8 @@ if __name__ == '__main__': # activate ctrl-c interrupt signal.signal(signal.SIGINT, signal.SIG_DFL) sakia = QApplication(sys.argv) + + sakia.setStyle('Fusion') loop = QSelectorEventLoop(sakia) loop.set_exception_handler(async_exception_handler) asyncio.set_event_loop(loop) @@ -72,6 +74,10 @@ if __name__ == '__main__': loop.run_forever() try: loop.run_until_complete(app.stop()) + logging.debug("Application stopped") except asyncio.CancelledError: logging.info('CancelledError') + logging.debug("Exiting") sys.exit() + logging.debug("Application stopped") + diff --git a/src/sakia/models/identities.py b/src/sakia/models/identities.py index 77573b21c2c3c4418e08e30e7eb5737a6f9ee9af..7c81cadd56a8b39cdb3de214c9be2eec707950c8 100644 --- a/src/sakia/models/identities.py +++ b/src/sakia/models/identities.py @@ -62,8 +62,7 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel): if role == Qt.DisplayRole: if source_index.column() in (self.sourceModel().columns_ids.index('renewed'), - self.sourceModel().columns_ids.index('expiration'), - self.sourceModel().columns_ids.index('publication')): + self.sourceModel().columns_ids.index('expiration')): if source_data is not None: return QLocale.toString( QLocale(), @@ -72,6 +71,15 @@ class IdentitiesFilterProxyModel(QSortFilterProxyModel): ) else: return "" + if source_index.column() == self.sourceModel().columns_ids.index('publication'): + if source_data is not None: + return QLocale.toString( + QLocale(), + QDateTime.fromTime_t(source_data), + QLocale.dateTimeFormat(QLocale(), QLocale.LongFormat) + ) + else: + return "" if source_index.column() == self.sourceModel().columns_ids.index('pubkey'): return "pub:{0}".format(source_data[:5]) @@ -145,7 +153,12 @@ class IdentitiesTableModel(QAbstractTableModel): join_date = None expiration_date = None - return identity.uid, identity.pubkey, join_date, expiration_date, identity.sigdate + if identity.sigdate: + sigdate_ts = await self.community.time(identity.sigdate.number) + else: + sigdate_ts = None + + return identity.uid, identity.pubkey, join_date, expiration_date, sigdate_ts async def refresh_identities(self, identities): """ diff --git a/src/sakia/models/network.py b/src/sakia/models/network.py index 5657bc4e96eee661dfa64d01ef3c2df355b1a313..6667f04daef5b352052631ed36c90c042ebe29b6 100644 --- a/src/sakia/models/network.py +++ b/src/sakia/models/network.py @@ -7,7 +7,7 @@ Created on 5 févr. 2014 import logging import asyncio -from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel +from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel, QDateTime, QLocale from PyQt5.QtGui import QColor, QFont, QIcon from ..tools.exceptions import NoPeerAvailable @@ -55,6 +55,7 @@ class NetworkFilterProxyModel(QSortFilterProxyModel): 'port': self.tr('Port'), 'current_block': self.tr('Block'), 'current_hash': self.tr('Hash'), + 'current_time': self.tr('Time'), 'uid': self.tr('UID'), 'is_member': self.tr('Member'), 'pubkey': self.tr('Pubkey'), @@ -70,25 +71,30 @@ class NetworkFilterProxyModel(QSortFilterProxyModel): if not source_index.isValid(): return QVariant() source_data = source_model.data(source_index, role) - if index.column() == source_model.columns_types.index('is_member') \ - and role == Qt.DisplayRole: - value = {True: self.tr('yes'), False: self.tr('no'), None: self.tr('offline')} - return value[source_data] - - if index.column() == source_model.columns_types.index('pubkey') \ - and role == Qt.DisplayRole: - return source_data[:5] - - if index.column() == source_model.columns_types.index('current_block') \ - and role == Qt.DisplayRole: - if source_data == -1: - return "" - else: - return source_data - - if index.column() == source_model.columns_types.index('current_hash') \ - and role == Qt.DisplayRole: - return source_data[:10] + + if role == Qt.DisplayRole: + if index.column() == source_model.columns_types.index('is_member'): + value = {True: self.tr('yes'), False: self.tr('no'), None: self.tr('offline')} + return value[source_data] + + if index.column() == source_model.columns_types.index('pubkey'): + return source_data[:5] + + if index.column() == source_model.columns_types.index('current_block'): + if source_data == -1: + return "" + else: + return source_data + + if index.column() == source_model.columns_types.index('current_hash') : + return source_data[:10] + + if index.column() == source_model.columns_types.index('current_time') and source_data: + return QLocale.toString( + QLocale(), + QDateTime.fromTime_t(source_data), + QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat) + ) if role == Qt.TextAlignmentRole: if source_index.column() == source_model.columns_types.index('address') or source_index.column() == self.sourceModel().columns_types.index('current_block'): @@ -123,6 +129,7 @@ class NetworkTableModel(QAbstractTableModel): 'port', 'current_block', 'current_hash', + 'current_time', 'uid', 'is_member', 'pubkey', @@ -186,10 +193,10 @@ class NetworkTableModel(QAbstractTableModel): is_root = self.community.network.is_root_node(node) if node.block: - number, block_hash = node.block['number'], node.block['hash'] + number, block_hash, block_time = node.block['number'], node.block['hash'], node.block['medianTime'] else: - number, block_hash = "", "" - return (address, port, number, block_hash, node.uid, + number, block_hash, block_time = "", "", "" + return (address, port, number, block_hash, block_time, node.uid, is_member, node.pubkey, node.software, node.version, is_root, node.state) @once_at_a_time diff --git a/src/sakia/models/txhistory.py b/src/sakia/models/txhistory.py index dea8b8d8fadd7a75c56efa224c5dba723f6ff4e9..7ee61c2cdc6d6f75a27efcaf1f138e2f2d6efaa0 100644 --- a/src/sakia/models/txhistory.py +++ b/src/sakia/models/txhistory.py @@ -154,9 +154,9 @@ class TxFilterProxyModel(QSortFilterProxyModel): current_confirmations = 0 if state_data == TransferState.VALIDATING: - current_blockid_number = self.community.network.current_blockid.number - if current_blockid_number: - current_confirmations = current_blockid_number - block_data + current_blockUID_number = self.community.network.current_blockUID.number + if current_blockUID_number: + current_confirmations = current_blockUID_number - block_data elif state_data == TransferState.AWAITING: current_confirmations = 0 @@ -230,8 +230,8 @@ class HistoryTableModel(QAbstractTableModel): async def data_received(self, transfer): amount = transfer.metadata['amount'] - if transfer.blockid: - block_number = transfer.blockid.number + if transfer.blockUID: + block_number = transfer.blockUID.number else: block_number = None try: @@ -256,8 +256,8 @@ class HistoryTableModel(QAbstractTableModel): transfer.metadata['issuer'], block_number, amount) async def data_sent(self, transfer): - if transfer.blockid: - block_number = transfer.blockid.number + if transfer.blockUID: + block_number = transfer.blockUID.number else: block_number = None diff --git a/src/sakia/tests/functional/certification/test_certification.py b/src/sakia/tests/functional/certification/test_certification.py index 2b4c120322076d3d7778cedd07a9c667b749a917..35b214c142704217197e70b86be4b39ed20ff37f 100644 --- a/src/sakia/tests/functional/certification/test_certification.py +++ b/src/sakia/tests/functional/certification/test_certification.py @@ -3,7 +3,8 @@ import unittest import asyncio import time import logging -from ucoinpy.documents.peer import BMAEndpoint +import aiohttp +from duniterpy.documents.peer import BMAEndpoint from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox, QApplication from PyQt5.QtCore import QLocale, Qt from PyQt5.QtTest import QTest @@ -33,7 +34,7 @@ class TestCertificationDialog(unittest.TestCase, QuamashTest): self.node = Node(self.mock_new_community.peer(), "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", None, Node.ONLINE, - time.time(), {}, "ucoin", "0.14.0", 0) + time.time(), {}, "duniter", "0.14.0", 0, session=aiohttp.ClientSession()) self.network = Network.create(self.node) self.bma_access = BmaAccess.create(self.network) self.community = Community("test_currency", self.network, self.bma_access) @@ -50,6 +51,9 @@ class TestCertificationDialog(unittest.TestCase, QuamashTest): self.password_asker.password = "testsakia" self.password_asker.remember = True + def tearDown(self): + self.tearDownQuamash() + def test_certification_init_community(self): time.sleep(2) certification_dialog = CertificationDialog(self.application, @@ -61,8 +65,7 @@ class TestCertificationDialog(unittest.TestCase, QuamashTest): async def open_dialog(certification_dialog): srv, port, url = await self.mock_new_community.create_server() self.addCleanup(srv.close) - result = await certification_dialog.async_exec() - self.assertEqual(result, QDialog.Accepted) + await certification_dialog.async_exec() def close_dialog(): if certification_dialog.widget.isVisible(): @@ -79,12 +82,6 @@ class TestCertificationDialog(unittest.TestCase, QuamashTest): if type(w) is QMessageBox: QTest.keyClick(w, Qt.Key_Enter) - self.lp.call_later(15, close_dialog) + self.lp.call_later(10, close_dialog) asyncio.ensure_future(exec_test()) self.lp.run_until_complete(open_dialog(certification_dialog)) - - -if __name__ == '__main__': - logging.basicConfig(stream=sys.stderr) - logging.getLogger().setLevel(logging.DEBUG) - unittest.main() diff --git a/src/sakia/tests/functional/identities_tab/test_identities_table.py b/src/sakia/tests/functional/identities_tab/test_identities_table.py index bb7aeb65882868e74b4ed9d1e124cd440ef4e1d4..f7855a2ad16c9153b208f1bf7955589765f479e2 100644 --- a/src/sakia/tests/functional/identities_tab/test_identities_table.py +++ b/src/sakia/tests/functional/identities_tab/test_identities_table.py @@ -1,14 +1,11 @@ import sys import unittest import asyncio -import quamash +import aiohttp import logging import time -from PyQt5.QtWidgets import QDialog -from PyQt5.QtCore import QLocale, Qt, QPoint +from PyQt5.QtCore import QLocale, Qt from PyQt5.QtTest import QTest -from ucoinpy.api import bma -from ucoinpy.api.bma import API from sakia.tests.mocks.bma import nice_blockchain from sakia.core.registry.identities import IdentitiesRegistry @@ -17,7 +14,6 @@ from sakia.gui.password_asker import PasswordAskerDialog from sakia.core.app import Application from sakia.core import Account, Community, Wallet from sakia.core.net import Network, Node -from ucoinpy.documents.peer import BMAEndpoint from sakia.core.net.api.bma.access import BmaAccess from sakia.tests import QuamashTest @@ -35,7 +31,7 @@ class TestIdentitiesTable(unittest.TestCase, QuamashTest): self.node = Node(self.mock_nice_blockchain.peer(), "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", None, Node.ONLINE, - time.time(), {}, "ucoin", "0.14.0", 0) + time.time(), {}, "duniter", "0.14.0", 0, session=aiohttp.ClientSession()) self.network = Network.create(self.node) self.bma_access = BmaAccess.create(self.network) self.community = Community("test_currency", self.network, self.bma_access) @@ -76,27 +72,10 @@ class TestIdentitiesTable(unittest.TestCase, QuamashTest): identities_tab.change_account(self.account, self.password_asker) identities_tab.change_community(self.community) await asyncio.sleep(1) - urls = [self.mock_nice_blockchain.get_request(i).url for i in range(0, 7)] - self.assertTrue('/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls, - msg="Not found in {0}".format(urls)) - self.assertTrue('/wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls, - msg="Not found in {0}".format(urls)) - self.assertTrue('/wot/certified-by/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ' in urls, - msg="Not found in {0}".format(urls)) - - - # requests 1 to 3 are for getting certifiers-of and certified-by - # on john, + a lookup QTest.keyClicks(identities_tab.ui.edit_textsearch, "doe") QTest.mouseClick(identities_tab.ui.button_search, Qt.LeftButton) await asyncio.sleep(2) - req = 8 - - self.assertEqual(self.mock_nice_blockchain.get_request(req).method, 'GET') - self.assertEqual(self.mock_nice_blockchain.get_request(req).url, - '/blockchain/memberships/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn') - req += 1 self.assertEqual(identities_tab.ui.table_identities.model().rowCount(), 1) await asyncio.sleep(2) @@ -105,8 +84,3 @@ class TestIdentitiesTable(unittest.TestCase, QuamashTest): asyncio.ensure_future(exec_test()) self.lp.call_later(15, close_dialog) self.lp.run_until_complete(open_widget()) - -if __name__ == '__main__': - logging.basicConfig( stream=sys.stderr ) - logging.getLogger().setLevel( logging.DEBUG ) - unittest.main() diff --git a/src/sakia/tests/functional/main_window/test_main_window_dialogs.py b/src/sakia/tests/functional/main_window/test_main_window_dialogs.py index ab393d1e69aac85c7c2bfea194f929e3ff2d29b6..422f9ded275efc8110b237bd657ecc77170ede68 100644 --- a/src/sakia/tests/functional/main_window/test_main_window_dialogs.py +++ b/src/sakia/tests/functional/main_window/test_main_window_dialogs.py @@ -6,8 +6,6 @@ from sakia.core.app import Application from sakia.tests import QuamashTest from sakia.core.registry.identities import IdentitiesRegistry -# Qapplication cause a core dumped when re-run in setup -# set it as global var class MainWindowDialogsTest(unittest.TestCase, QuamashTest): def setUp(self): diff --git a/src/sakia/tests/functional/main_window/test_main_window_menus.py b/src/sakia/tests/functional/main_window/test_main_window_menus.py index 1b79265df35394dbc8c9c864eba57efbe7ff553b..6b4ad861ba6787e769fc4dcfdfa164c65ddb4165 100644 --- a/src/sakia/tests/functional/main_window/test_main_window_menus.py +++ b/src/sakia/tests/functional/main_window/test_main_window_menus.py @@ -28,10 +28,11 @@ class MainWindowMenusTest(unittest.TestCase, QuamashTest): for child in children: if isinstance(child, QMenu): menus.append(child) - self.assertEqual(len(menus), 3) + self.assertEqual(len(menus), 4) self.assertEqual(menus[0].objectName(), 'menu_file') self.assertEqual(menus[1].objectName(), 'menu_account') self.assertEqual(menus[2].objectName(), 'menu_help') + self.assertEqual(menus[3].objectName(), 'menu_duniter') def test_menu_account(self): actions = self.main_window.ui.menu_account.actions() diff --git a/src/sakia/tests/functional/preferences/test_preferences_dialog.py b/src/sakia/tests/functional/preferences/test_preferences_dialog.py index 5f8e243c93db8ef72c2860f412c8c5bcd5fc915f..f2f1ce3bbbc99572818c07a34c4530fe465bf325 100644 --- a/src/sakia/tests/functional/preferences/test_preferences_dialog.py +++ b/src/sakia/tests/functional/preferences/test_preferences_dialog.py @@ -8,7 +8,7 @@ from sakia.core.registry.identities import IdentitiesRegistry from sakia.gui.preferences import PreferencesDialog from sakia.core.app import Application from sakia.tests import QuamashTest -from ucoinpy.api import bma +from duniterpy.api import bma class TestPreferencesDialog(unittest.TestCase, QuamashTest): diff --git a/src/sakia/tests/functional/process_cfg_community/test_add_community.py b/src/sakia/tests/functional/process_cfg_community/test_add_community.py index 20fe49931097a2e6c0617c4c3a47e3f92efbd84d..256dcba78acfdc9a33e2e0f3b3ba99afabeaead7 100644 --- a/src/sakia/tests/functional/process_cfg_community/test_add_community.py +++ b/src/sakia/tests/functional/process_cfg_community/test_add_community.py @@ -61,27 +61,6 @@ class ProcessAddCommunity(unittest.TestCase, QuamashTest): self.assertEqual(process_community.spinbox_port.value(), port) QTest.mouseClick(process_community.button_register, Qt.LeftButton) await asyncio.sleep(1) - self.assertEqual(mock.get_request(0).method, 'GET') - self.assertEqual(mock.get_request(0).url, '/network/peering') - self.assertEqual(process_community._step_init.node.endpoint.port, port) - self.assertEqual(mock.get_request(1).method, 'GET') - self.assertEqual(mock.get_request(1).url, - '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ') - for i in range(2, 5): - self.assertEqual(mock.get_request(i).method, 'GET') - self.assertEqual(mock.get_request(i).url, - '/wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ') - await asyncio.sleep(5) - self.assertEqual(mock.get_request(5).method, 'GET') - self.assertEqual(mock.get_request(5).url, - '/wot/lookup/john') - for i in range(6, 8): - self.assertEqual(mock.get_request(i).method, 'GET') - self.assertEqual(mock.get_request(i).url, - '/wot/lookup/john') - - self.assertEqual(mock.get_request(8).url[:8], '/wot/add') - self.assertEqual(mock.get_request(8).method, 'POST') self.assertEqual(process_community.label_error.text(), "Broadcasting identity...") await asyncio.sleep(1) @@ -124,13 +103,6 @@ class ProcessAddCommunity(unittest.TestCase, QuamashTest): await asyncio.sleep(2) self.assertEqual(mock.get_request(0).method, 'GET') self.assertEqual(mock.get_request(0).url, '/network/peering') - self.assertEqual(mock.get_request(1).method, 'GET') - self.assertEqual(mock.get_request(1).url, - '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ') - for i in range(2, 5): - self.assertEqual(mock.get_request(i).method, 'GET') - self.assertEqual(mock.get_request(i).url, - '/wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ') self.assertEqual(process_community.stacked_pages.currentWidget(), process_community.page_node, msg="Current widget : {0}".format(process_community.stacked_pages.currentWidget().objectName())) @@ -172,7 +144,7 @@ class ProcessAddCommunity(unittest.TestCase, QuamashTest): self.assertEqual(mock.get_request(0).url, '/network/peering') self.assertEqual(mock.get_request(1).method, 'GET') self.assertEqual(mock.get_request(1).url, - '/wot/lookup/john') + '/wot/certifiers-of/wrong_pubkey') self.assertEqual(process_community.label_error.text(), """Your pubkey or UID is different on the network. Yours : wrong_pubkey, the network : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ""") process_community.close() @@ -211,9 +183,6 @@ Yours : wrong_pubkey, the network : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ await asyncio.sleep(1) self.assertEqual(mock.get_request(0).method, 'GET') self.assertEqual(mock.get_request(0).url, '/network/peering') - self.assertEqual(mock.get_request(1).method, 'GET') - self.assertEqual(mock.get_request(1).url, - '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ') self.assertEqual(process_community.label_error.text(), """Your pubkey or UID is different on the network. Yours : wrong_uid, the network : john""") process_community.close() diff --git a/src/sakia/tests/functional/transfer/test_transfer.py b/src/sakia/tests/functional/transfer/test_transfer.py index 6ba1ca1ef1f8f7e78ef3c89efb800c57353d1714..6f83afb8f5f52ba2a08d7a100ef87f140f2b324c 100644 --- a/src/sakia/tests/functional/transfer/test_transfer.py +++ b/src/sakia/tests/functional/transfer/test_transfer.py @@ -1,13 +1,12 @@ import sys import unittest import asyncio -import quamash +import aiohttp import time import logging from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QMessageBox, QApplication from PyQt5.QtCore import QLocale, Qt from PyQt5.QtTest import QTest -from ucoinpy.api.bma import API from sakia.tests.mocks.bma import nice_blockchain from sakia.core.registry.identities import IdentitiesRegistry @@ -16,10 +15,8 @@ from sakia.gui.password_asker import PasswordAskerDialog from sakia.core.app import Application from sakia.core import Account, Community, Wallet from sakia.core.net import Network, Node -from ucoinpy.documents.peer import BMAEndpoint from sakia.core.net.api.bma.access import BmaAccess from sakia.tests import QuamashTest -from ucoinpy.api import bma class TestTransferDialog(unittest.TestCase, QuamashTest): @@ -35,7 +32,7 @@ class TestTransferDialog(unittest.TestCase, QuamashTest): self.node = Node(self.mock_nice_blockchain.peer(), "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", None, Node.ONLINE, - time.time(), {}, "ucoin", "0.14.0", 0) + time.time(), {}, "duniter", "0.14.0", 0, session=aiohttp.ClientSession()) self.network = Network.create(self.node) self.bma_access = BmaAccess.create(self.network) self.community = Community("test_currency", self.network, self.bma_access) @@ -66,16 +63,15 @@ class TestTransferDialog(unittest.TestCase, QuamashTest): async def open_dialog(transfer_dialog): srv, port, url = await self.mock_nice_blockchain.create_server() self.addCleanup(srv.close) - + await asyncio.sleep(1) result = await transfer_dialog.async_exec() self.assertEqual(result, QDialog.Accepted) def close_dialog(): - if transfer_dialog.isVisible(): - transfer_dialog.close() + if transfer_dialog.widget.isVisible(): + transfer_dialog.widget.close() async def exec_test(): - await asyncio.sleep(1) self.account.wallets[0].caches[self.community.currency].available_sources = await self.wallet.sources(self.community) QTest.mouseClick(transfer_dialog.ui.radio_pubkey, Qt.LeftButton) QTest.keyClicks(transfer_dialog.ui.edit_pubkey, "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn") @@ -86,13 +82,8 @@ class TestTransferDialog(unittest.TestCase, QuamashTest): for w in topWidgets: if type(w) is QMessageBox: QTest.keyClick(w, Qt.Key_Enter) + await asyncio.sleep(1) - self.lp.call_later(15, close_dialog) + self.lp.call_later(30, close_dialog) asyncio.ensure_future(exec_test()) self.lp.run_until_complete(open_dialog(transfer_dialog)) - - -if __name__ == '__main__': - logging.basicConfig(stream=sys.stderr) - logging.getLogger().setLevel(logging.DEBUG) - unittest.main() diff --git a/src/sakia/tests/functional/wot_tab/test_wot_tab.py b/src/sakia/tests/functional/wot_tab/test_wot_tab.py index fc3def5b612e047e706303fb2b5515bc3f74f56d..1beeddb02b372fa391b6dafd22f066b028f4d34e 100644 --- a/src/sakia/tests/functional/wot_tab/test_wot_tab.py +++ b/src/sakia/tests/functional/wot_tab/test_wot_tab.py @@ -2,10 +2,10 @@ import asyncio import logging import sys import time +import aiohttp import unittest from PyQt5.QtCore import QLocale -from ucoinpy.documents.peer import BMAEndpoint from sakia.core import Account, Community, Wallet from sakia.core.app import Application @@ -31,7 +31,7 @@ class TestWotTab(unittest.TestCase, QuamashTest): self.node = Node(self.mock_nice_blockchain.peer(), "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", None, Node.ONLINE, - time.time(), {}, "ucoin", "0.14.0", 0) + time.time(), {}, "duniter", "0.14.0", 0, session=aiohttp.ClientSession()) self.network = Network.create(self.node) self.bma_access = BmaAccess.create(self.network) self.community = Community("test_currency", self.network, self.bma_access) diff --git a/src/sakia/tests/mocks/bma/init_new_community.py b/src/sakia/tests/mocks/bma/init_new_community.py index 8166fd95ec7e238b845900c67f501cc5de895e1c..af732fd1caab4b2b26a35dc3714e35cd47ff1a52 100644 --- a/src/sakia/tests/mocks/bma/init_new_community.py +++ b/src/sakia/tests/mocks/bma/init_new_community.py @@ -1,77 +1,106 @@ - from ..server import MockServer - +from duniterpy.api import errors bma_lookup_test_john = { - "partial": False, - "results": [ - { - "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", - "uids": [ + "partial": False, + "results": [ { - "uid": "john", - "meta": { - "timestamp": 1441130831 - }, - "self": "ZrHK0cCqrxWReROK0ciiSb45+dRphJa68qFaSjdve8bBdnGAu7+DIu0d+u/fXrNRXuObihOKMBIawaIVPNHqDw==", - "others": [] + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "uids": [ + { + "uid": "john", + "meta": { + "timestamp": "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" + }, + "self": "ZrHK0cCqrxWReROK0ciiSb45+dRphJa68qFaSjdve8bBdnGAu7+DIu0d+u/fXrNRXuObihOKMBIawaIVPNHqDw==", + "others": [], + "revocation_sig": "CTmlh3tO4B8f8IbL8iDy5ZEr3jZDcxkPmDmRPQY74C39MRLXi0CKUP+oFzTZPYmyUC7fZrUXrb3LwRKWw1jEBQ==", + "revoked": False, + } + ], + "signed": [] } - ], - "signed": [] - } - ] + ] } bma_lookup_test_doe = { - "partial": False, - "results": [ - { - "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", - "uids": [ + "partial": False, + "results": [ { - "uid": "doe", - "meta": { - "timestamp": 1441130831 - }, - "self": "cIkHPQQ5+xTb4cKWv85rcYcZT+E3GDtX8B2nCK9Vs12p2Yz4bVaZiMvBBwisAAy2WBOaqHS3ydpXGtADchOICw==", - "others": [] + "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + "uids": [ + { + "uid": "doe", + "meta": { + "timestamp": "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" + }, + "self": "cIkHPQQ5+xTb4cKWv85rcYcZT+E3GDtX8B2nCK9Vs12p2Yz4bVaZiMvBBwisAAy2WBOaqHS3ydpXGtADchOICw==", + "others": [], + "revocation_sig": "CTmlh3tO4B8f8IbL8iDy5ZEr3jZDcxkPmDmRPQY74C39MRLXi0CKUP+oFzTZPYmyUC7fZrUXrb3LwRKWw1jEBQ==", + "revoked": False, + } + ], + "signed": [] } - ], - "signed": [] - } - ] + ] } bma_lookup_test_patrick = { - "partial": False, - "results": [ - { - "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", - "uids": [ + "partial": False, + "results": [ { - "uid": "patrick", - "meta": { - "timestamp": 1441130831 - }, - "self": "QNX2HDAxcHawc47TnMqb5/ou2lwa+zYOyeNk0a52dQDJX/NWmeTzGfTjdCtjpXmSCuPSg0F1mOnLQVd60xAzDA==", - "others": [] + "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + "uids": [ + { + "uid": "patrick", + "meta": { + "timestamp": "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" + }, + "self": "QNX2HDAxcHawc47TnMqb5/ou2lwa+zYOyeNk0a52dQDJX/NWmeTzGfTjdCtjpXmSCuPSg0F1mOnLQVd60xAzDA==", + "others": [], + "revocation_sig": "CTmlh3tO4B8f8IbL8iDy5ZEr3jZDcxkPmDmRPQY74C39MRLXi0CKUP+oFzTZPYmyUC7fZrUXrb3LwRKWw1jEBQ==", + "revoked": False, + } + ], + "signed": [] } - ], - "signed": [] - } - ] + ] } +bma_parameters = { + "currency": "test_currency", + "c": 0.1, + "dt": 86400, + "ud0": 100, + "sigPeriod": 600, + "sigValidity": 2629800, + "sigQty": 3, + "xpercent": 0.9, + "sigStock": 10, + "sigWindow": 1000, + "msValidity": 2629800, + "stepMax": 3, + "medianTimeBlocks": 11, + "avgGenTime": 600, + "dtDiffEval": 20, + "blocksRot": 144, + "percentRot": 0.67 +} def get_mock(loop): mock = MockServer(loop) - mock.add_route('GET', '/blockchain/block/0', {"message": "Block not found"}, 404) + mock.add_route('GET', '/blockchain/parameters', bma_parameters, 200) - mock.add_route('GET', '/blockchain/current', {'message': "Block not found"}, 404) + mock.add_route('GET', '/blockchain/block/0', {'ucode': errors.BLOCK_NOT_FOUND, + "message": "Block not found"}, 404) + + mock.add_route('GET', '/blockchain/current', {'ucode': errors.NO_CURRENT_BLOCK, + 'message': "Block not found"}, 404) mock.add_route('GET', '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', - {'message': "No member matching this pubkey or uid"}, 404) + {'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID, + 'message': "No member matching this pubkey or uid"}, 404) mock.add_route('GET', '/wot/lookup/john', bma_lookup_test_john, 200) @@ -87,4 +116,6 @@ def get_mock(loop): mock.add_route('POST', '/wot/add', {}, 200) + mock.add_route('POST', '/wot/certify', {}, 200) + return mock diff --git a/src/sakia/tests/mocks/bma/new_blockchain.py b/src/sakia/tests/mocks/bma/new_blockchain.py index fd73693ebf41b6ed2700f2e1d215c878a7667367..fc83d1241d29f383c27913c534ad744b758605a9 100644 --- a/src/sakia/tests/mocks/bma/new_blockchain.py +++ b/src/sakia/tests/mocks/bma/new_blockchain.py @@ -1,5 +1,5 @@ from ..server import MockServer - +from duniterpy.api import errors bma_wot_add = { "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", @@ -7,33 +7,71 @@ bma_wot_add = { { "uid": "test", "meta": { - "timestamp": 1409990782 + "timestamp": "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" }, "self": "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci", "others": [ - ] + ], + "revocation_sig": "CTmlh3tO4B8f8IbL8iDy5ZEr3jZDcxkPmDmRPQY74C39MRLXi0CKUP+oFzTZPYmyUC7fZrUXrb3LwRKWw1jEBQ==", + "revoked": False, } ] } +bma_parameters = { + "currency": "test_currency", + "c": 0.1, + "dt": 86400, + "ud0": 100, + "sigPeriod": 600, + "sigValidity": 2629800, + "sigQty": 3, + "xpercent": 0.9, + "sigStock": 10, + "sigWindow": 1000, + "msValidity": 2629800, + "stepMax": 3, + "medianTimeBlocks": 11, + "avgGenTime": 600, + "dtDiffEval": 20, + "blocksRot": 144, + "percentRot": 0.67 +} + def get_mock(loop): mock = MockServer(loop) - mock.add_route('GET', '/blockchain/block/0', {'message': "Block not found"}, 404) + mock.add_route('GET', '/blockchain/parameters', bma_parameters, 200) + + mock.add_route('GET', '/blockchain/block/0', {'ucode': errors.BLOCK_NOT_FOUND, + 'message': "Block not found"}, 404) - mock.add_route('GET', '/blockchain/current', {'message': "Block not found"}, 404) + mock.add_route('GET', '/blockchain/current', {'ucode': errors.NO_CURRENT_BLOCK, + 'message': "Block not found"}, 404) mock.add_route('GET', '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', - {'message': "No member matching this pubkey or uid"}, 404) + {'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID, + 'message': "No member matching this pubkey or uid"}, 404) mock.add_route('GET', '/wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', - {'message': "No member matching this pubkey or uid"}, 404) + {'ucode': errors.NO_MATCHING_IDENTITY, + 'message': "No member matching this pubkey or uid"}, 404) mock.add_route('GET', '/wot/lookup/john', - {'message': "No member matching this pubkey or uid"}, 404) + {'ucode': errors.NO_MATCHING_IDENTITY, + 'message': "No member matching this pubkey or uid"}, 404) + + mock.add_route('GET', '/wot/certifiers-of/john', + {'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID, 'message': "No member matching this pubkey or uid"}, 404) mock.add_route('GET', '/wot/lookup/doe', - {'message': "No member matching this pubkey or uid"}, 404) + {'ucode': errors.NO_MATCHING_IDENTITY, + 'message': "No member matching this pubkey or uid"}, 404) + + mock.add_route('GET', '/wot/certifiers-of/doe', + {'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID, 'message': "No member matching this pubkey or uid"}, 404) mock.add_route('POST', '/wot/add', bma_wot_add, 200) + + mock.add_route('POST', '/wot/certify', {}, 200) return mock diff --git a/src/sakia/tests/mocks/bma/nice_blockchain.py b/src/sakia/tests/mocks/bma/nice_blockchain.py index 91ef3a050f73bdfc03648144b3b73c8be5eab51a..b8ad5e293d29b5b3ddab20b05c942799ba4072f6 100644 --- a/src/sakia/tests/mocks/bma/nice_blockchain.py +++ b/src/sakia/tests/mocks/bma/nice_blockchain.py @@ -1,4 +1,5 @@ from ..server import MockServer +from duniterpy.api import errors bma_lookup_john = { "partial": False, @@ -9,22 +10,24 @@ bma_lookup_john = { { "uid": "john", "meta": { - "timestamp": 1441130831 + "timestamp": "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" }, + "revocation_sig": "CTmlh3tO4B8f8IbL8iDy5ZEr3jZDcxkPmDmRPQY74C39MRLXi0CKUP+oFzTZPYmyUC7fZrUXrb3LwRKWw1jEBQ==", + "revoked": False, "self": "ZrHK0cCqrxWReROK0ciiSb45+dRphJa68qFaSjdve8bBdnGAu7+DIu0d+u/fXrNRXuObihOKMBIawaIVPNHqDw==", "others": [ { - "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", - "meta": { - "block_number": 38580 - }, - "uids": [ - "doe" - ], - "isMember": True, - "wasMember": True, - "signature": "4ulycI2MtBu/8bZipy+OsXDCNm9EyUIdZ1HA7hbJ66phKRNvv70Oo2YOF/+VDRJb97z9TqWKgfIQ0NbXU15xDg==" - }, + "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + "meta": { + "block_number": 15 + }, + "uids": [ + "doe" + ], + "isMember": True, + "wasMember": True, + "signature": "4ulycI2MtBu/8bZipy+OsXDCNm9EyUIdZ1HA7hbJ66phKRNvv70Oo2YOF/+VDRJb97z9TqWKgfIQ0NbXU15xDg==" + }, ] } ], @@ -35,16 +38,16 @@ bma_lookup_john = { bma_membership_john = { "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", - "uid": "inso", - "sigDate": 1441130831, + "uid": "john", + "sigDate": "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", "memberships": [ { - "version": 1, + "version": 2, "currency": "test_currency", "membership": "IN", "blockNumber": 0, - "blockHash": "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", + "blockHash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", "written": 10000 } ] @@ -59,13 +62,28 @@ bma_lookup_doe = { { "uid": "doe", "meta": { - "timestamp": 1441130831 + "timestamp": "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" }, + "revocation_sig": "CTmlh3tO4B8f8IbL8iDy5ZEr3jZDcxkPmDmRPQY74C39MRLXi0CKUP+oFzTZPYmyUC7fZrUXrb3LwRKWw1jEBQ==", + "revoked": False, "self": "cIkHPQQ5+xTb4cKWv85rcYcZT+E3GDtX8B2nCK9Vs12p2Yz4bVaZiMvBBwisAAy2WBOaqHS3ydpXGtADchOICw==", "others": [] } ], - "signed": [] + "signed": [ + { + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "meta": { + "block_number": 38580 + }, + "uids": [ + "john" + ], + "isMember": True, + "wasMember": True, + "signature": "4ulycI2MtBu/8bZipy+OsXDCNm9EyUIdZ1HA7hbJ66phKRNvv70Oo2YOF/+VDRJb97z9TqWKgfIQ0NbXU15xDg==" + }, + ] } ] } @@ -76,19 +94,20 @@ bma_certifiers_of_john = { "isMember": True, "certifications": [ { - "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", - "uid": "doe", - "isMember": True, - "wasMember": True, - "cert_time": { - "block": 15, - "medianTime": 1447693329 - }, - "written": { - "number": 15, - "hash": "0000EC88BBBAA29D530D2B815DEE264DDC9F07F4" - }, - "signature": "oliiPDhniZAGHrIFL66oHR+cqD4aTgXX+20VFLMfNHwdYPeik76hy334zxhoDC4cPODMb9df2nF/EDfCefrNBg==" + "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + "uid": "doe", + "isMember": True, + "wasMember": True, + "cert_time": { + "block": 15, + "medianTime": 1500000000 + }, + "sigDate": "101-BAD49448A1AD73C978CEDCB8F137D20A5715EBAA739DAEF76B1E28EE67B2C00C", + "written": { + "number": 15, + "hash": "0000EC88BBBAA29D530D2B815DEE264DDC9F07F4" + }, + "signature": "oliiPDhniZAGHrIFL66oHR+cqD4aTgXX+20VFLMfNHwdYPeik76hy334zxhoDC4cPODMb9df2nF/EDfCefrNBg==" }, ] } @@ -97,19 +116,46 @@ bma_certified_by_john = { "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", "uid": "john", "isMember": True, + "wasMember": False, "certifications": [ ] } +bma_certified_by_doe = { + "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + "uid": "doe", + "isMember": True, + "certifications": [ + { + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "uid": "john", + "isMember": True, + "wasMember": True, + "cert_time": { + "block": 15, + "medianTime": 1500000000 + }, + "sigDate": "20-7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67", + "written": { + "number": 15, + "hash": "0000EC88BBBAA29D530D2B815DEE264DDC9F07F4" + }, + "signature": "oliiPDhniZAGHrIFL66oHR+cqD4aTgXX+20VFLMfNHwdYPeik76hy334zxhoDC4cPODMb9df2nF/EDfCefrNBg==" + }, + ] +} + bma_parameters = { "currency": "test_currency", "c": 0.1, "dt": 86400, "ud0": 100, - "sigDelay": 604800, + "sigPeriod": 600, "sigValidity": 2629800, "sigQty": 3, - "sigWoT": 3, + "xpercent": 0.9, + "sigStock": 10, + "sigWindow": 1000, "msValidity": 2629800, "stepMax": 3, "medianTimeBlocks": 11, @@ -120,7 +166,7 @@ bma_parameters = { } bma_blockchain_0 = { - "version": 1, + "version": 2, "nonce": 10144, "number": 0, "powMin": 3, @@ -132,25 +178,27 @@ bma_blockchain_0 = { "issuer": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", "signature": "+78w7251vvRdhoIJ6IWHEiEOLxNrmfQf45Y5sYvPdnAdXkVpO1unMV5YA/G5Vhphyz1dICrbeKCPM5qbFsoWAQ==", "hash": "00063EB6E83F8717CEF1D25B3E2EE308374A14B1", + "inner_hash": "00063EB6E83F8717CEF1D25B3E2EE308374A14B1", "parameters": "0.1:86400:100:604800:2629800:3:3:2629800:3:11:600:20:144:0.67", "previousHash": None, "previousIssuer": None, "dividend": None, "membersChanges": [], "identities": [ - "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:Ot3zIp/nsHT3zgJy+2YcXPL6vaM5WFsD+F8w3qnJoBRuBG6lv761zoaExp2iyUnm8fDAyKPpMxRK2kf437QSCw==:1421787800:inso", - "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:GZKLgaxJKL+GqxVLePMt8OVLJ6qTLrib5Mr/j2gjiNRY2k485YLB2OlzhBzZVnD3xLs0xi69JUfmLnM54j3aCA==:1421786393:cgeek", - "BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:th576H89dfymkG7/sH+DAIzjlmIqNEW6zY3ONrGeAml+k3f1ver399kYnEgG5YCaKXnnVM7P0oJHah80BV3mDw==:1421790376:moul", - "37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:XRmbTYFkPeGVEU2mJzzN4h1oVNDsZ4yyNZlDAfBm9CWhBsZ82QqX9GPHye2hBxxiu4Nz1BHgQiME6B4JcAC8BA==:1421787461:galuel" + "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:Ot3zIp/nsHT3zgJy+2YcXPL6vaM5WFsD+F8w3qnJoBRuBG6lv761zoaExp2iyUnm8fDAyKPpMxRK2kf437QSCw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:inso", + "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:GZKLgaxJKL+GqxVLePMt8OVLJ6qTLrib5Mr/j2gjiNRY2k485YLB2OlzhBzZVnD3xLs0xi69JUfmLnM54j3aCA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cgeek", + "BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:th576H89dfymkG7/sH+DAIzjlmIqNEW6zY3ONrGeAml+k3f1ver399kYnEgG5YCaKXnnVM7P0oJHah80BV3mDw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:moul", + "37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:XRmbTYFkPeGVEU2mJzzN4h1oVNDsZ4yyNZlDAfBm9CWhBsZ82QqX9GPHye2hBxxiu4Nz1BHgQiME6B4JcAC8BA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:galuel" ], "joiners": [ - "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:ccJm3F44eLMhQtnQY/7+14SWCDqVTL3Miw65hBVpV+YiUSUknIGhBNN0C0Cf+Pf0/pa1tjucW8Us3z5IklFSDg==:0:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709:1421787800:inso", - "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:1lFIiaR0QX0jibr5zQpXVGzBvMGqcsTRlmHiwGz5HOAZT8PTdVUb5q6YGZ6qAUZjdMjPmhLaiMIpYc47wUnzBA==:0:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709:1421786393:cgeek", - "BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:ctyAhpTRrAAOhFJukWI8RBr//nqYYdQibVzjOfaCdcWLb3TNFKrNBBothNsq/YrYHr7gKrpoftucf/oxLF8zAg==:0:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709:1421790376:moul", - "37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:uoiGaC5b7kWqtqdPxwatPk9QajZHCNT9rf8/8ud9Rli24z/igcOf0Zr4A6RTAIKWUq9foW39VqJe+Y9R3rhACw==:0:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709:1421787461:galuel" + "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:ccJm3F44eLMhQtnQY/7+14SWCDqVTL3Miw65hBVpV+YiUSUknIGhBNN0C0Cf+Pf0/pa1tjucW8Us3z5IklFSDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:inso", + "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:1lFIiaR0QX0jibr5zQpXVGzBvMGqcsTRlmHiwGz5HOAZT8PTdVUb5q6YGZ6qAUZjdMjPmhLaiMIpYc47wUnzBA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cgeek", + "BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:ctyAhpTRrAAOhFJukWI8RBr//nqYYdQibVzjOfaCdcWLb3TNFKrNBBothNsq/YrYHr7gKrpoftucf/oxLF8zAg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:moul", + "37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:uoiGaC5b7kWqtqdPxwatPk9QajZHCNT9rf8/8ud9Rli24z/igcOf0Zr4A6RTAIKWUq9foW39VqJe+Y9R3rhACw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:galuel" ], "actives": [], "leavers": [], + "revoked": [], "excluded": [], "certifications": [ "37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:0:3wmCVW8AbVxRFm2PuLXD9UTCIg93MhUblZJvlYrDldSV4xuA7mZCd8TV4vb/6Bkc0FMQgBdHtpXrQ7dpo20uBA==", @@ -167,11 +215,51 @@ bma_blockchain_0 = { "BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:0:q4PCneYkcPH8AHEqEvqTtYQWslhlYO2B87aReuOl1uPczn5Q3VkZFAsU48ZTYryeyWp2nxdQojdFYhlAUNchAw==" ], "transactions": [], - "raw": "Version: 1\nType: Block\nCurrency: test_currency\nNonce: 10144\nNumber: 0\nPoWMin: 3\nTime: 1421838980\nMedianTime: 1421838980\nIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nParameters: 0.1:86400:100:604800:2629800:3:3:2629800:3:11:600:20:144:0.67\nMembersCount: 4\nIdentities:\n8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:Ot3zIp/nsHT3zgJy+2YcXPL6vaM5WFsD+F8w3qnJoBRuBG6lv761zoaExp2iyUnm8fDAyKPpMxRK2kf437QSCw==:1421787800:inso\nHnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:GZKLgaxJKL+GqxVLePMt8OVLJ6qTLrib5Mr/j2gjiNRY2k485YLB2OlzhBzZVnD3xLs0xi69JUfmLnM54j3aCA==:1421786393:cgeek\nBMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:th576H89dfymkG7/sH+DAIzjlmIqNEW6zY3ONrGeAml+k3f1ver399kYnEgG5YCaKXnnVM7P0oJHah80BV3mDw==:1421790376:moul\n37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:XRmbTYFkPeGVEU2mJzzN4h1oVNDsZ4yyNZlDAfBm9CWhBsZ82QqX9GPHye2hBxxiu4Nz1BHgQiME6B4JcAC8BA==:1421787461:galuel\nJoiners:\n8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:ccJm3F44eLMhQtnQY/7+14SWCDqVTL3Miw65hBVpV+YiUSUknIGhBNN0C0Cf+Pf0/pa1tjucW8Us3z5IklFSDg==:0:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709:1421787800:inso\nHnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:1lFIiaR0QX0jibr5zQpXVGzBvMGqcsTRlmHiwGz5HOAZT8PTdVUb5q6YGZ6qAUZjdMjPmhLaiMIpYc47wUnzBA==:0:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709:1421786393:cgeek\nBMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:ctyAhpTRrAAOhFJukWI8RBr//nqYYdQibVzjOfaCdcWLb3TNFKrNBBothNsq/YrYHr7gKrpoftucf/oxLF8zAg==:0:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709:1421790376:moul\n37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:uoiGaC5b7kWqtqdPxwatPk9QajZHCNT9rf8/8ud9Rli24z/igcOf0Zr4A6RTAIKWUq9foW39VqJe+Y9R3rhACw==:0:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709:1421787461:galuel\nActives:\nLeavers:\nExcluded:\nCertifications:\n37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:0:3wmCVW8AbVxRFm2PuLXD9UTCIg93MhUblZJvlYrDldSV4xuA7mZCd8TV4vb/6Bkc0FMQgBdHtpXrQ7dpo20uBA==\nHnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:0:7UMQsUjLvuiZKIzOH5rrZDdDi5rXUo69EuQulY1Zm42xpRx/Gt5CkoTcJ/Mu83oElQbcZZTz/lVJ6IS0jzMiCQ==\nBMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:0:twWSY9etI82FLEHzhdqIoHsC9ehWCA7DCPiGxDLCWGPO4TG77hwtn3RcC68qoKHCib577JCp+fcKyp2vyI6FDA==\n8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:0:7K5MHkO8ibf5SchmPkRrmsg9owEZZ23uEMJJSQYG7L3PUmAKmmV/0VSjivxXH8gJGQBGsXQoK79x1jsYnj2nAg==\nBMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:0:Jua4FcEJFptSE5OoG1/Mgzx4e9jgGnYu7t8g1sqqPujI9hRhLFNXbQXedPS1q1OD5vWivA045gKOq/gnj8opDg==\n37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:0:R/DV4/wYjvBG09QSOGtnxd3bfPFhVjEE5Uy3BsBMVUvjLsgxjf8NgLhYVozcHTRWS43ArxlXKfS5m3+KIPhhAQ==\n8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:0:4hP+ahJK021akL4UxB6c5QLaGJXa9eapd3nfdFQe+Xy87f/XLhj8BCa22XbbOlyGdaZRT3AYzbCL2UD5tI8mCw==\nHnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:0:sZTQJr0d/xQnxrIIdSePUJpSTOa8v6IYGXMF2fVDZxQU8vwfzPm2dUKTaF0nU6E9wOYszzkBHaXL85nir+WtCQ==\n37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:0:hDuBkoFhWhR/FgOU1+9SbQGBMIr47xqUzw1ZMERaPQo4aWm0WFbZurG4lvuJZzTyG6RF/gSw4VPvYZFPxWmADg==\n8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:0:79ZVrBehElVZh82fJdR18IJx06GkEVZTbwdHH4zb0S6VaGwdtLh1rvomm4ukBvUc8r/suTweG/SScsJairXNAg==\nHnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:0:e/ai9E4G5CFB9Qi329e0ffYpZMgxj8mM4rviqIr2+UESA0UG86OuAAyHO11hYeyolZRiU8I7WdtNE98B1uZuBg==\nBMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:0:q4PCneYkcPH8AHEqEvqTtYQWslhlYO2B87aReuOl1uPczn5Q3VkZFAsU48ZTYryeyWp2nxdQojdFYhlAUNchAw==\nTransactions:\n" + "raw": """Version: 2 +Type: Block +Currency: test_currency +Number: 0 +PoWMin: 3 +Time: 1421838980 +MedianTime: 1421838980 +Issuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk +Parameters: 0.1:86400:100:604800:15:604800:2629800:3:0.9:2629800:3:11:600:20:144:0.67 +MembersCount: 4 +Identities: +8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:Ot3zIp/nsHT3zgJy+2YcXPL6vaM5WFsD+F8w3qnJoBRuBG6lv761zoaExp2iyUnm8fDAyKPpMxRK2kf437QSCw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:inso +HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:GZKLgaxJKL+GqxVLePMt8OVLJ6qTLrib5Mr/j2gjiNRY2k485YLB2OlzhBzZVnD3xLs0xi69JUfmLnM54j3aCA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cgeek +BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:th576H89dfymkG7/sH+DAIzjlmIqNEW6zY3ONrGeAml+k3f1ver399kYnEgG5YCaKXnnVM7P0oJHah80BV3mDw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:moul +37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:XRmbTYFkPeGVEU2mJzzN4h1oVNDsZ4yyNZlDAfBm9CWhBsZ82QqX9GPHye2hBxxiu4Nz1BHgQiME6B4JcAC8BA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:galuel +Joiners: +8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:ccJm3F44eLMhQtnQY/7+14SWCDqVTL3Miw65hBVpV+YiUSUknIGhBNN0C0Cf+Pf0/pa1tjucW8Us3z5IklFSDg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:inso +HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:1lFIiaR0QX0jibr5zQpXVGzBvMGqcsTRlmHiwGz5HOAZT8PTdVUb5q6YGZ6qAUZjdMjPmhLaiMIpYc47wUnzBA==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cgeek +BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:ctyAhpTRrAAOhFJukWI8RBr//nqYYdQibVzjOfaCdcWLb3TNFKrNBBothNsq/YrYHr7gKrpoftucf/oxLF8zAg==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:moul +37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:uoiGaC5b7kWqtqdPxwatPk9QajZHCNT9rf8/8ud9Rli24z/igcOf0Zr4A6RTAIKWUq9foW39VqJe+Y9R3rhACw==:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:galuel +Actives: +Leavers: +Revoked: +Excluded: +Certifications: +37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:0:3wmCVW8AbVxRFm2PuLXD9UTCIg93MhUblZJvlYrDldSV4xuA7mZCd8TV4vb/6Bkc0FMQgBdHtpXrQ7dpo20uBA== +HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:0:7UMQsUjLvuiZKIzOH5rrZDdDi5rXUo69EuQulY1Zm42xpRx/Gt5CkoTcJ/Mu83oElQbcZZTz/lVJ6IS0jzMiCQ== +BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:0:twWSY9etI82FLEHzhdqIoHsC9ehWCA7DCPiGxDLCWGPO4TG77hwtn3RcC68qoKHCib577JCp+fcKyp2vyI6FDA== +8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:0:7K5MHkO8ibf5SchmPkRrmsg9owEZZ23uEMJJSQYG7L3PUmAKmmV/0VSjivxXH8gJGQBGsXQoK79x1jsYnj2nAg== +BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:0:Jua4FcEJFptSE5OoG1/Mgzx4e9jgGnYu7t8g1sqqPujI9hRhLFNXbQXedPS1q1OD5vWivA045gKOq/gnj8opDg== +37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:0:R/DV4/wYjvBG09QSOGtnxd3bfPFhVjEE5Uy3BsBMVUvjLsgxjf8NgLhYVozcHTRWS43ArxlXKfS5m3+KIPhhAQ== +8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:0:4hP+ahJK021akL4UxB6c5QLaGJXa9eapd3nfdFQe+Xy87f/XLhj8BCa22XbbOlyGdaZRT3AYzbCL2UD5tI8mCw== +HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:0:sZTQJr0d/xQnxrIIdSePUJpSTOa8v6IYGXMF2fVDZxQU8vwfzPm2dUKTaF0nU6E9wOYszzkBHaXL85nir+WtCQ== +37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:0:hDuBkoFhWhR/FgOU1+9SbQGBMIr47xqUzw1ZMERaPQo4aWm0WFbZurG4lvuJZzTyG6RF/gSw4VPvYZFPxWmADg== +8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:0:79ZVrBehElVZh82fJdR18IJx06GkEVZTbwdHH4zb0S6VaGwdtLh1rvomm4ukBvUc8r/suTweG/SScsJairXNAg== +HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:0:e/ai9E4G5CFB9Qi329e0ffYpZMgxj8mM4rviqIr2+UESA0UG86OuAAyHO11hYeyolZRiU8I7WdtNE98B1uZuBg== +BMAVuMDcGhYAV4wA27DL1VXX2ZARZGJYaMwpf7DJFMYH:37qBxM4hLV2jfyYo2bNzAjkeLngLr2r7G2HpdpKieVxw:0:q4PCneYkcPH8AHEqEvqTtYQWslhlYO2B87aReuOl1uPczn5Q3VkZFAsU48ZTYryeyWp2nxdQojdFYhlAUNchAw== +Transactions: +InnerHash: 09500111588846873CA0110602DDC17FB34AA9F4548B7CE322C845902FFC1429 +Nonce: 10144 +""" } bma_blockchain_current = { - "version": 1, + "version": 2, "nonce": 6909, "number": 15, "powMin": 4, @@ -195,7 +283,28 @@ bma_blockchain_current = { "excluded": [], "certifications": [], "transactions": [], - "raw": "Version: 1\nType: Block\nCurrency: meta_brouzouf\nNonce: 6909\nNumber: 30898\nPoWMin: 4\nTime: 1441618206\nMedianTime: 1441614759\nIssuer: EPs9qX7HmCDy6ptUoMLpTzbh9toHu4au488pBTU9DN6y\nPreviousHash: 00003BDA844D77EEE7CF32A6C3C87F2ACBFCFCBB\nPreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nMembersCount: 20\nIdentities:\nJoiners:\nActives:\nLeavers:\nExcluded:\nCertifications:\nTransactions:\n" + "raw": """Version: 2 +Type: Block +Currency: meta_brouzouf +Number: 30898 +PoWMin: 4 +Time: 1441618206 +MedianTime: 1441614759 +Issuer: EPs9qX7HmCDy6ptUoMLpTzbh9toHu4au488pBTU9DN6y +PreviousHash: 00003BDA844D77EEE7CF32A6C3C87F2ACBFCFCBB +PreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk +MembersCount: 20 +Identities: +Joiners: +Actives: +Leavers: +Revoked: +Excluded: +Certifications: +Transactions: +InnerHash: 6BB2E0BE18BEA428379336FB5F09DCE0EB594D09CDD705085CA91AA966C27CFA +Nonce: 6909 +""" } # Sent 6, received 20 + 30 @@ -207,19 +316,23 @@ bma_txhistory_john = { "sent": [ { - "version": 1, + "version": 2, "issuers": [ "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ" ], "inputs": [ - "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8" + "D:7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:8" + ], + "unlocks": + [ + "SIG(0)" ], "outputs": [ - "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:2", - "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:6" + "2:1:SIG(7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ)", + "6:1:SIG(FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn)" ], "comment": "", "signatures": @@ -234,19 +347,23 @@ bma_txhistory_john = { "received": [ { - "version": 1, + "version": 2, "issuers": [ "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn" ], "inputs": [ - "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8" + "D:FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:8" + ], + "unlocks": + [ + "SIG(0)" ], "outputs": [ - "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:2", - "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:20" + "2:1:SIG(7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ)", + "6:1:SIG(FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn)" ], "comment": "", "signatures": @@ -258,19 +375,23 @@ bma_txhistory_john = { "time": 1421932545 }, { - "version": 1, + "version": 2, "issuers": [ "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn" ], "inputs": [ - "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8" + "D:FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:8" + ], + "unlocks": + [ + "SIG(0)" ], "outputs": [ - "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:5", - "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:40" + "5:1:SIG(FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn)", + "40:1:SIG(7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ)" ], "comment": "", "signatures": @@ -278,9 +399,9 @@ bma_txhistory_john = { "1Mn8q3K7N+R4GZEpAUm+XSyty1Uu+BuOy5t7BIRqgZcKqiaxfhAUfDBOcuk2i4TJy1oA5Rntby8hDN+cUCpvDg==" ], "hash": "5FB3CB80A982E2BDFBB3EA94673A74763F58CB2A", - "block_number": 12, - "time": 1421932454 - } + "block_number": 2, + "time": 1421932545 + }, ], "sending": [], "receiving": [] @@ -298,15 +419,15 @@ bma_udhistory_john = { "block_number": 2, "consumed": False, "time": 1435749971, - "amount": 5 + "amount": 5, + "base": 1 }, { - "block_number": 10, "consumed": False, "time": 1435836032, - "amount": 10 - + "amount": 10, + "base": 1 } ] }} @@ -317,18 +438,18 @@ bma_txsources_john = { "sources": [ { - "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", "type": "D", - "number": 2, - "fingerprint": "4A317E3D676E9800E1E92AA2A7255BCEEFF31185", - "amount": 7 + "noffset": 2, + "identifier": "FCAD5A388AC8A811B45A9334A375585E77071AA9F6E5B6896582961A6C66F365", + "amount": 70, + "base": 0 }, { - "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", "type": "D", - "number": 4, - "fingerprint": "4A317E3D676E9800E1E92AA2A7255BCEEFF31185", - "amount": 9 + "noffset": 4, + "identifier": "A0AC57E2E4B24D66F2D25E66D8501D8E881D9E6453D1789ED753D7D426537ED5", + "amount": 90, + "base": 0 } ]} @@ -345,7 +466,7 @@ def get_mock(loop): mock.add_route('GET', '/blockchain/parameters', bma_parameters, 200) - mock.add_route('GET', '/blockchain/with/[UD|ud]', bma_with_ud, 200) + mock.add_route('GET', '/blockchain/with/{topic}', bma_with_ud, 200) mock.add_route('GET', '/blockchain/current', bma_blockchain_current, 200) @@ -353,13 +474,18 @@ def get_mock(loop): mock.add_route('GET', '/blockchain/block/15', bma_blockchain_current, 200) - mock.add_route('GET', '/tx/history/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ/blocks/0/99', bma_txhistory_john, 200) + mock.add_route('GET', '/tx/history/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ/blocks/0/99', bma_txhistory_john, + 200) mock.add_route('GET', '/tx/sources/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', bma_txsources_john, 200) mock.add_route('GET', '/ud/history/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', bma_udhistory_john, 200) - mock.add_route('GET', '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', bma_certifiers_of_john, 200) + mock.add_route('GET', '/wot/certifiers-of/john', bma_certifiers_of_john, + 200) + + mock.add_route('GET', '/wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', bma_certifiers_of_john, + 200) mock.add_route('GET', '/wot/certified-by/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', bma_certified_by_john, 200) @@ -369,16 +495,29 @@ def get_mock(loop): mock.add_route('GET', '/wot/lookup/doe', bma_lookup_doe, 200) - mock.add_route('GET', '/wot/lookup/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn',bma_lookup_doe,200) + mock.add_route('GET', '/wot/lookup/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn', bma_lookup_doe, 200) + + mock.add_route('GET', '/blockchain/memberships/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ', bma_membership_john, + 200) + + mock.add_route('GET', '/wot/lookup/wrong_pubkey', + {'ucode': errors.NO_MATCHING_IDENTITY, 'message': "No member matching this pubkey or uid"}, 404) + + mock.add_route('GET', '/wot/certifiers-of/wrong_pubkey', + {'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID, 'message': "No member matching this pubkey or uid"}, 404) + + mock.add_route('GET', '/wot/lookup/wrong_uid', + {'ucode': errors.NO_MATCHING_IDENTITY, 'message': "No member matching this pubkey or uid"}, 404) - mock.add_route('GET', '/blockchain/memberships/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ',bma_membership_john,200) + mock.add_route('GET', '/wot/certifiers-of/wrong_uid', + {'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID, 'message': "No member matching this pubkey or uid"}, 404) mock.add_route('GET', '/wot/certifiers-of/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn', - {'error':"No member matching this pubkey or uid"},404) + {'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID, 'message': "No member matching this pubkey or uid"}, 404) mock.add_route('GET', '/blockchain/memberships/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn', - {'error':"No member matching this pubkey or uid"}, 404) + {'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID, 'message': "No member matching this pubkey or uid"}, 404) - mock.add_route('POST', '/tx/process', {},200,) + mock.add_route('POST', '/tx/process', {}, 200, ) return mock diff --git a/src/sakia/tests/mocks/server.py b/src/sakia/tests/mocks/server.py index d614a72ec6a04fa06cbb87a18ac3adac0180389e..38af9e963f52a1b65f6a3fb6cd94d5de652bf8a9 100644 --- a/src/sakia/tests/mocks/server.py +++ b/src/sakia/tests/mocks/server.py @@ -1,30 +1,30 @@ -from aiohttp import web, log +from aiohttp import web, log, errors import json import socket -from ucoinpy.documents import Peer +from duniterpy.documents import Peer def bma_peering_generator(port): return { - "version": 1, + "version": 2, "currency": "test_currency", "endpoints": [ "BASIC_MERKLED_API 127.0.0.1 {port}".format(port=port) ], "status": "UP", - "block": "30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3", + "block": "0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", "signature": "cXuqZuDfyHvxYAEUkPH1TQ1M+8YNDpj8kiHGYi3LIaMqEdVqwVc4yQYGivjxFMYyngRfxXkyvqBKZA6rKOulCA==", - "raw": "Version: 1\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\nEndpoints:\nBASIC_MERKLED_API 127.0.0.1 {port}\n".format(port=port), + "raw": "Version: 2\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\nEndpoints:\nBASIC_MERKLED_API 127.0.0.1 {port}\n".format(port=port), "pubkey": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk" } def peer_document_generator(port): - return Peer.from_signed_raw("""Version: 1 + return Peer.from_signed_raw("""Version: 2 Type: Peer Currency: meta_brouzouf PublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk -Block: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3 +Block: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 Endpoints: BASIC_MERKLED_API 127.0.0.1 {port} cXuqZuDfyHvxYAEUkPH1TQ1M+8YNDpj8kiHGYi3LIaMqEdVqwVc4yQYGivjxFMYyngRfxXkyvqBKZA6rKOulCA== @@ -42,7 +42,8 @@ class MockServer(): def __init__(self, loop): self.lp = loop self.requests = [] - self.app = web.Application(loop=self.lp) + self.app = web.Application(loop=self.lp, + middlewares=[self.middleware_factory]) self.handler = self.app.make_handler( keep_alive_on=False, @@ -53,6 +54,19 @@ class MockServer(): def get_request(self, i): return self.requests[i] + async def middleware_factory(self, app, handler): + async def middleware_handler(request): + try: + resp = await handler(request) + return resp + except web.HTTPNotFound: + return web.Response(status=404, body=bytes(json.dumps({"ucode":1001, + "message": "404 error"}), + "utf-8"), + headers={'Content-Type': 'application/json'}) + + return middleware_handler + async def _handler(self, request, data_dict, http_code): await request.read() self.requests.append(Request(request.method, request.path, request.content)) diff --git a/src/sakia/tests/unit/core/graph/test_explorer_graph.py b/src/sakia/tests/unit/core/graph/test_explorer_graph.py index e4a4e1e0ef00ef5273eccdfdc96a9b60d02f4c2e..e3c99600bc1507f49da756241ee3c4977cf643a0 100644 --- a/src/sakia/tests/unit/core/graph/test_explorer_graph.py +++ b/src/sakia/tests/unit/core/graph/test_explorer_graph.py @@ -126,6 +126,7 @@ class TestExplorerGraph(unittest.TestCase, QuamashTest): def test_explore_full_from_center(self, app, community): community.parameters = CoroutineMock(return_value = {'sigValidity': 1000}) community.network.confirmations = Mock(side_effect=lambda n: 4 if 996 else None) + community.nb_members = CoroutineMock(return_value = 3) app.preferences = {'expert_mode': True} explorer_graph = ExplorerGraph(app, community) @@ -143,6 +144,7 @@ class TestExplorerGraph(unittest.TestCase, QuamashTest): def test_explore_full_from_extremity(self, app, community): community.parameters = CoroutineMock(return_value = {'sigValidity': 1000}) community.network.confirmations = Mock(side_effect=lambda n: 4 if 996 else None) + community.nb_members = CoroutineMock(return_value = 3) app.preferences = {'expert_mode': True} explorer_graph = ExplorerGraph(app, community) @@ -160,6 +162,7 @@ class TestExplorerGraph(unittest.TestCase, QuamashTest): def test_explore_partial(self, app, community): community.parameters = CoroutineMock(return_value = {'sigValidity': 1000}) community.network.confirmations = Mock(side_effect=lambda n: 4 if 996 else None) + community.nb_members = CoroutineMock(return_value = 3) app.preferences = {'expert_mode': True} explorer_graph = ExplorerGraph(app, community) diff --git a/src/sakia/tests/unit/core/graph/test_wot_graph.py b/src/sakia/tests/unit/core/graph/test_wot_graph.py index 1502032c40cc46f648f04987e926cbd82d7af584..cd20d38704ade5d6ad459edf8b877f9494b821a9 100644 --- a/src/sakia/tests/unit/core/graph/test_wot_graph.py +++ b/src/sakia/tests/unit/core/graph/test_wot_graph.py @@ -62,7 +62,7 @@ class TestWotGraph(unittest.TestCase, QuamashTest): { 'cert_time': 49100, 'identity': self.idC, - 'block_number': 990 + 'block_number': 996 } ]) @@ -133,10 +133,10 @@ class TestWotGraph(unittest.TestCase, QuamashTest): self.assertTrue(result) self.assertEqual(len(wot_graph.nx_graph.nodes()), 3) self.assertEqual(len(wot_graph.nx_graph.edges()), 2) - path = await wot_graph.get_shortest_path_to_identity(self.account_identity, self.idC) - self.assertEqual(path[0], self.account_identity.pubkey) + path = await wot_graph.get_shortest_path_to_identity(self.idC, self.account_identity) + self.assertEqual(path[0], self.idC.pubkey) self.assertEqual(path[1], self.idB.pubkey) - self.assertEqual(path[2], self.idC.pubkey) + self.assertEqual(path[2], self.account_identity.pubkey) self.lp.run_until_complete(exec_test()) diff --git a/src/sakia/tests/unit/core/test_account.py b/src/sakia/tests/unit/core/test_account.py index c5134aa731c8a8059a01debd6f5f71d5a1468ab8..12d2982e6307f05b67da665f3178b6354f5d7bd0 100644 --- a/src/sakia/tests/unit/core/test_account.py +++ b/src/sakia/tests/unit/core/test_account.py @@ -4,7 +4,7 @@ from PyQt5.QtCore import QLocale from sakia.core.registry.identities import IdentitiesRegistry, Identity from sakia.core import Account from sakia.tests import QuamashTest -from ucoinpy.documents import BlockId, SelfCertification +from duniterpy.documents import BlockUID, SelfCertification class TestAccount(unittest.TestCase, QuamashTest): @@ -79,17 +79,17 @@ class TestAccount(unittest.TestCase, QuamashTest): "test_account", [], [], [], self.identities_registry) account_identity = MagicMock(autospec='sakia.core.registry.Identity') - account_identity.selfcert = CoroutineMock(return_value=SelfCertification(1, "meta_brouzouf", + account_identity.selfcert = CoroutineMock(return_value=SelfCertification(2, "meta_brouzouf", "H8uYXvyF6GWeCr8cwFJ6V5B8tNprwRdjepFNJBqivrzr", "test_account", 1000000000, "")) community = MagicMock(autospec='sakia.core.Community') - community.blockid = CoroutineMock(return_value=BlockId(3102, "0000C5336F0B64BFB87FF4BC858AE25726B88175")) + community.blockUID = CoroutineMock(return_value=BlockUID(3102, "0000C5336F0B64BFB87FF4BC858AE25726B88175")) self.identities_registry.future_find = CoroutineMock(return_value=account_identity) community.bma_access = MagicMock(autospec='sakia.core.net.api.bma.access.BmaAccess') response = Mock() response.json = CoroutineMock(return_value={ "signature": "H41/8OGV2W4CLKbE35kk5t1HJQsb3jEM0/QGLUf80CwJvGZf3HvVCcNtHPUFoUBKEDQO9mPK3KJkqOoxHpqHCw==", "membership": { - "version": "2", + "version": 2, "currency": "beta_brouzouf", "issuer": "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY", "membership": "IN", @@ -105,7 +105,6 @@ class TestAccount(unittest.TestCase, QuamashTest): self.lp.run_until_complete(exec_test()) - def test_send_certification(self): cert_signal_sent = False def check_certification_accepted(): @@ -117,18 +116,22 @@ class TestAccount(unittest.TestCase, QuamashTest): self.identities_registry) account.certification_accepted.connect(check_certification_accepted) account_identity = MagicMock(autospec='sakia.core.registry.Identity') - account_identity.selfcert = CoroutineMock(return_value=SelfCertification(1, "meta_brouzouf", - "H8uYXvyF6GWeCr8cwFJ6V5B8tNprwRdjepFNJBqivrzr", "test_account", 1000000000, "")) + account_identity.selfcert = CoroutineMock(return_value=SelfCertification(2, "meta_brouzouf", + "H8uYXvyF6GWeCr8cwFJ6V5B8tNprwRdjepFNJBqivrzr", "test_account", + BlockUID(1000, "49E2A1D1131F1496FAD6EDAE794A9ADBFA8844029675E3732D3B027ABB780243"), + "82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw==")) certified = MagicMock(autospec='sakia.core.registry.Identity') certified.uid = "john" certified.pubkey = "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ" certified.sigdate = 1441130831 - certified.selfcert = CoroutineMock(return_value=SelfCertification(1, "meta_brouzouf", - "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", "john", 1441130831, "")) + certified.selfcert = CoroutineMock(return_value=SelfCertification(2, "meta_brouzouf", + "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", "john", + BlockUID(1200, "49E2A1D1131F1496FAD6EDAE794A9ADBFA8844029675E3732D3B027ABB780243"), + "82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw==")) community = MagicMock(autospec='sakia.core.Community') - community.blockid = CoroutineMock(return_value=BlockId(3102, "0000C5336F0B64BFB87FF4BC858AE25726B88175")) + community.blockUID = CoroutineMock(return_value=BlockUID(3102, "49E2A1D1131F1496FAD6EDAE794A9ADBFA8844029675E3732D3B027ABB780243")) self.identities_registry.future_find = CoroutineMock(side_effect=lambda pubkey, community :account_identity \ if pubkey == "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ" else certified) community.bma_access = MagicMock(autospec='sakia.core.net.api.bma.access.BmaAccess') diff --git a/src/sakia/tests/unit/core/test_bma_access.py b/src/sakia/tests/unit/core/test_bma_access.py index d382a5bac015fa36ddb10f474d8defd2fecebc65..b4a3257b403e5eb7447d3e61aee186e07435f295 100644 --- a/src/sakia/tests/unit/core/test_bma_access.py +++ b/src/sakia/tests/unit/core/test_bma_access.py @@ -1,4 +1,5 @@ import unittest +from unittest.mock import Mock import time from PyQt5.QtCore import QLocale from sakia.core.registry.identities import Identity, IdentitiesRegistry, LocalState, BlockchainState @@ -7,7 +8,7 @@ from sakia.tests.mocks.bma import nice_blockchain, corrupted from sakia.tests import QuamashTest from sakia.core import Application, Community from sakia.core.net import Network, Node -from ucoinpy.documents.peer import Peer +from duniterpy.documents.peer import Peer from sakia.core.net.api.bma.access import BmaAccess @@ -20,19 +21,19 @@ class TestBmaAccess(unittest.TestCase, QuamashTest): self.application = Application(self.qapplication, self.lp, self.identities_registry) self.application.preferences['notifications'] = False - self.peer = Peer.from_signed_raw("""Version: 1 + self.peer = Peer.from_signed_raw("""Version: 2 Type: Peer Currency: meta_brouzouf PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU Block: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8 Endpoints: -BASIC_MERKLED_API ucoin.inso.ovh 80 +BASIC_MERKLED_API duniter.inso.ovh 80 82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw== """) self.node = Node(self.peer, "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", None, Node.ONLINE, - time.time(), {}, "ucoin", "0.12.0", 0) + time.time(), {}, "duniter", "0.12.0", 0, Mock("aiohttp.ClientSession")) self.network = Network.create(self.node) self.bma_access = BmaAccess.create(self.network) self.community = Community("test_currency", self.network, self.bma_access) diff --git a/src/sakia/tests/unit/core/test_community.py b/src/sakia/tests/unit/core/test_community.py index 760764e330c3b007631edef042b841ef634a5021..16d2fd66a49a39b449979190a7d9797eed863f74 100644 --- a/src/sakia/tests/unit/core/test_community.py +++ b/src/sakia/tests/unit/core/test_community.py @@ -1,5 +1,5 @@ -import sys import unittest +from unittest.mock import Mock from pkg_resources import parse_version from PyQt5.QtCore import QLocale from sakia.core.net.api.bma.access import BmaAccess @@ -17,7 +17,7 @@ class TestCommunity(unittest.TestCase, QuamashTest): self.tearDownQuamash() def test_load_save_community(self): - network = Network("test_currency", []) + network = Network("test_currency", [], Mock("aiohttp.ClientSession")) bma_access = BmaAccess([], network) community = Community("test_currency", network, bma_access) @@ -25,3 +25,5 @@ class TestCommunity(unittest.TestCase, QuamashTest): community_from_json = Community.load(json_data, parse_version('0.12.0')) self.assertEqual(community.name, community_from_json.name) self.assertEqual(len(community.network._nodes), len(community_from_json.network._nodes)) + community_from_json.network.session.close() + diff --git a/src/sakia/tests/unit/core/test_identity.py b/src/sakia/tests/unit/core/test_identity.py index 0702b5902e8c2198ccd5d765cb8a7605ad48f6ce..5336bb43f7a6c870ded17517bc4da4d74603f0a3 100644 --- a/src/sakia/tests/unit/core/test_identity.py +++ b/src/sakia/tests/unit/core/test_identity.py @@ -1,11 +1,12 @@ import unittest -from asynctest import Mock, CoroutineMock +from asynctest import Mock, CoroutineMock, patch from PyQt5.QtCore import QLocale from sakia.core.registry.identities import Identity, LocalState, BlockchainState from sakia.tests.mocks.bma import nice_blockchain, corrupted from sakia.tests import QuamashTest -from ucoinpy.api import bma +from duniterpy.api import bma +from duniterpy.documents import BlockUID from sakia.tools.exceptions import MembershipNotFoundError @@ -30,13 +31,22 @@ class TestIdentity(unittest.TestCase, QuamashTest): if request is bma.blockchain.Block: return nice_blockchain.bma_blockchain_current - identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831, + def block_to_time(block_number=None): + if block_number == 15: + return 1200000200 + else: + return 1500000400 + + identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + BlockUID(20, "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67"), LocalState.COMPLETED, BlockchainState.VALIDATED) - id_doe = Identity("doe", "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", 1441230831, + id_doe = Identity("doe", "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + BlockUID(101, "BAD49448A1AD73C978CEDCB8F137D20A5715EBAA739DAEF76B1E28EE67B2C00C"), LocalState.COMPLETED, BlockchainState.VALIDATED) self.community.bma_access.future_request = CoroutineMock(side_effect=bma_access) self.identities_registry.from_handled_data = Mock(return_value=id_doe) + self.community.time = CoroutineMock(side_effect=block_to_time) async def exec_test(): certifiers = await identity.certifiers_of(self.identities_registry, self.community) @@ -46,12 +56,46 @@ class TestIdentity(unittest.TestCase, QuamashTest): self.lp.run_until_complete(exec_test()) + @patch('time.time', Mock(return_value=1500000400)) + def test_identity_cert_delay(self): + def bma_access(request, *args): + if request is bma.wot.CertifiedBy: + return nice_blockchain.bma_certified_by_doe + if request is bma.wot.Lookup: + return nice_blockchain.bma_lookup_doe + if request is bma.blockchain.Block: + return nice_blockchain.bma_blockchain_current + + def block_to_time(block_number=None): + if block_number == 38580: + return 1500000200 + else: + return 1500000400 + + identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + BlockUID(20, "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67"), + LocalState.COMPLETED, BlockchainState.VALIDATED) + id_doe = Identity("doe", "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + BlockUID(101, "BAD49448A1AD73C978CEDCB8F137D20A5715EBAA739DAEF76B1E28EE67B2C00C"), + LocalState.COMPLETED, BlockchainState.VALIDATED) + + self.community.bma_access.future_request = CoroutineMock(side_effect=bma_access) + self.community.parameters = CoroutineMock(side_effect=lambda: nice_blockchain.bma_parameters) + self.community.time = CoroutineMock(side_effect=block_to_time) + self.identities_registry.from_handled_data = Mock(return_value=id_doe) + async def exec_test(): + cert_delay = await identity.cert_issuance_delay(self.identities_registry, self.community) + self.assertEqual(cert_delay, 200) + + self.lp.run_until_complete(exec_test()) + def test_identity_membership(self): def bma_access(request, *args): if request is bma.blockchain.Membership: return nice_blockchain.bma_membership_john - identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831, + identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + BlockUID(20, "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67"), LocalState.COMPLETED, BlockchainState.VALIDATED) self.community.bma_access.future_request = CoroutineMock(side_effect=bma_access) @@ -59,7 +103,7 @@ class TestIdentity(unittest.TestCase, QuamashTest): async def exec_test(): ms = await identity.membership(self.community) self.assertEqual(ms["blockNumber"], 0) - self.assertEqual(ms["blockHash"], "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709") + self.assertEqual(ms["blockHash"], "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855") self.assertEqual(ms["membership"], "IN") self.assertEqual(ms["currency"], "test_currency") self.assertEqual(ms["written"], 10000) @@ -71,7 +115,8 @@ class TestIdentity(unittest.TestCase, QuamashTest): if request is bma.blockchain.Membership: return corrupted.bma_memberships_empty_array - identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", 1441130831, + identity = Identity("john", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + BlockUID(20, "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67"), LocalState.COMPLETED, BlockchainState.VALIDATED) self.community.bma_access.future_request = CoroutineMock(side_effect=bma_access) async def exec_test(): diff --git a/src/sakia/tests/unit/core/test_network.py b/src/sakia/tests/unit/core/test_network.py index 60b3a7071e85529f34601c98396bcddd5a502bec..175062c5f3255ca4d711aceb8efd80405cb172d0 100644 --- a/src/sakia/tests/unit/core/test_network.py +++ b/src/sakia/tests/unit/core/test_network.py @@ -1,8 +1,8 @@ -import sys +import aiohttp import unittest from unittest.mock import PropertyMock from asynctest import Mock, patch -from ucoinpy.documents.block import BlockId +from duniterpy.documents.block import BlockUID from PyQt5.QtCore import QLocale from sakia.core.net import Network from sakia.tests import QuamashTest @@ -15,12 +15,3 @@ class TestCommunity(unittest.TestCase, QuamashTest): def tearDown(self): self.tearDownQuamash() - - def test_confirmations(self): - network = Network("test_currency", []) - Network.current_blockid = PropertyMock(return_value=BlockId(1000, "fbf9271d0df23ee03044795aebca8be06dd7f998".upper())) - - self.assertEqual(network.confirmations(996), 5) - self.assertEqual(network.confirmations(900), 101) - with self.assertRaises(ValueError): - network.confirmations(1002) diff --git a/src/sakia/tests/unit/core/test_node.py b/src/sakia/tests/unit/core/test_node.py index 1191b28b1c252a66ec531532acc344db29755130..fd07ca043bd73ee0fc14ee9bcb4741439655a825 100644 --- a/src/sakia/tests/unit/core/test_node.py +++ b/src/sakia/tests/unit/core/test_node.py @@ -1,6 +1,7 @@ import unittest +from unittest.mock import Mock from asynctest import CoroutineMock, patch -from ucoinpy.documents import Peer, BlockId +from duniterpy.documents import Peer, BlockUID from PyQt5.QtCore import QLocale from sakia.core.net import Node from sakia.tests import QuamashTest @@ -17,105 +18,86 @@ class TestNode(unittest.TestCase, QuamashTest): self.tearDownQuamash() def test_from_peer(self): - peer = Peer.from_signed_raw("""Version: 1 + peer = Peer.from_signed_raw("""Version: 2 Type: Peer Currency: meta_brouzouf PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU Block: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8 Endpoints: -BASIC_MERKLED_API ucoin.inso.ovh 80 +BASIC_MERKLED_API duniter.inso.ovh 80 82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw== """) - node = Node.from_peer('meta_brouzouf', peer, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU") + node = Node.from_peer('meta_brouzouf', peer, Mock("aiohttp.ClientSession")) self.assertEqual(node.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU") - self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API ucoin.inso.ovh 80") + self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API duniter.inso.ovh 80") self.assertEqual(node.currency, "meta_brouzouf") - @patch('ucoinpy.api.bma.network.Peering') + @patch('duniterpy.api.bma.network.Peering') def test_from_address(self, peering): peering.return_value.get = CoroutineMock(return_value={ - "version": 1, + "version": 2, "currency": "meta_brouzouf", "endpoints": [ - "BASIC_MERKLED_API ucoin.inso.ovh 80" + "BASIC_MERKLED_API duniter.inso.ovh 80" ], "block": "48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8", "signature": "82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw==", - "raw": "Version: 1\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU\nBlock: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8\nEndpoints:\nBASIC_MERKLED_API ucoin.inso.ovh 80\n", + "raw": "Version: 2\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU\nBlock: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8\nEndpoints:\nBASIC_MERKLED_API duniter.inso.ovh 80\n", "pubkey": "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU" }) async def exec_test(): - node = await Node.from_address("meta_brouzouf", "127.0.0.1", 9000) + node = await Node.from_address("meta_brouzouf", "127.0.0.1", 9000, Mock("aiohttp.ClientSession")) self.assertEqual(node.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU") - self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API ucoin.inso.ovh 80") + self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API duniter.inso.ovh 80") self.assertEqual(node.currency, "meta_brouzouf") self.lp.run_until_complete(exec_test()) - def test_from_json_011(self): - json_data = {"version": "0.12.0", "state": 1, "fork_window": 0, "uid": "cgeek", - "block": nice_blockchain.bma_blockchain_current, - "endpoints": ["BASIC_MERKLED_API metab.ucoin.io 88.174.120.187 9201"], - "pubkey": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", - "last_change": 1448199706.6561477, "currency": "meta_brouzouf", "sofware": "ucoin"} - node = Node.from_json("meta_brouzouf", json_data, parse_version('0.11.5')) - self.assertEqual(node.version, "0.12.0") - self.assertEqual(node.state, 1) - self.assertEqual(node.fork_window, 0) - self.assertEqual(node.uid, "cgeek") - self.assertEqual(node.block, nice_blockchain.bma_blockchain_current) - self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API metab.ucoin.io 88.174.120.187 9201") - self.assertEqual(node.pubkey, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk") - self.assertEqual(node.last_change, 1448199706.6561477) - self.assertEqual(node.currency, "meta_brouzouf") - self.assertEqual(node.peer.pubkey, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk") - self.assertEqual(node.peer.blockid.number, 0) - def test_from_json_to_json(self): json_data = {"version": "0.12.0", "state": 1, "fork_window": 0, "uid": "inso", "block": nice_blockchain.bma_blockchain_current, - "peer": """Version: 1 + "peer": """Version: 2 Type: Peer Currency: meta_brouzouf PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU Block: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8 Endpoints: -BASIC_MERKLED_API ucoin.inso.ovh 80 +BASIC_MERKLED_API duniter.inso.ovh 80 82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw== """, "pubkey": "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU", - "last_change": 1448199706.6561477, "software": "ucoin"} - node = Node.from_json("meta_brouzouf", json_data, parse_version('0.12.0')) + "last_change": 1448199706.6561477, "software": "duniter"} + node = Node.from_json("meta_brouzouf", json_data, parse_version('0.12.0'), Mock("aiohttp.ClientSession")) self.assertEqual(node.version, "0.12.0") self.assertEqual(node.state, 1) self.assertEqual(node.fork_window, 0) self.assertEqual(node.uid, "inso") self.assertEqual(node.block, nice_blockchain.bma_blockchain_current) - self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API ucoin.inso.ovh 80") + self.assertEqual(node.endpoint.inline(), "BASIC_MERKLED_API duniter.inso.ovh 80") self.assertEqual(node.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU") self.assertEqual(node.last_change, 1448199706.6561477) self.assertEqual(node.currency, "meta_brouzouf") self.assertEqual(node.peer.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU") - self.assertEqual(node.peer.blockid.number, 48698) - self.assertEqual(node.peer.blockid.sha_hash, "000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8") + self.assertEqual(node.peer.blockUID.number, 48698) + self.assertEqual(node.peer.blockUID.sha_hash, "000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8") result = node.jsonify() for key in result: self.assertEqual(result[key], json_data[key], "Error with key {0}".format(key)) def test_jsonify_root_node(self): - peer = Peer.from_signed_raw("""Version: 1 + peer = Peer.from_signed_raw("""Version: 2 Type: Peer Currency: meta_brouzouf PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU Block: 48698-000005E0F228038E4DDD4F6CA4ACB01EC88FBAF8 Endpoints: -BASIC_MERKLED_API ucoin.inso.ovh 80 +BASIC_MERKLED_API duniter.inso.ovh 80 82o1sNCh1bLpUXU6nacbK48HBcA9Eu2sPkL1/3c2GtDPxBUZd2U2sb7DxwJ54n6ce9G0Oy7nd1hCxN3fS0oADw== """) node = Node(peer, "inso", "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU", nice_blockchain.bma_blockchain_current, - Node.ONLINE, 1111111111, {}, "ucoin", "0.12", 0) + Node.ONLINE, 1111111111, {}, "duniter", "0.12", 0, Mock("aiohttp.ClientSession")) result = node.jsonify_root_node() self.assertEqual(result['pubkey'], "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU") self.assertEqual(result['uid'], "inso") diff --git a/src/sakia/tests/unit/core/test_wallet.py b/src/sakia/tests/unit/core/test_wallet.py index 04253105d291e1a8ee4264cd646690ff2bc76be3..78eb4a09546e7b290d5808a2225efe59f1942cc1 100644 --- a/src/sakia/tests/unit/core/test_wallet.py +++ b/src/sakia/tests/unit/core/test_wallet.py @@ -1,8 +1,8 @@ -import sys import unittest -import asyncio -import quamash -import logging +import pypeg2 +from unittest.mock import MagicMock, PropertyMock +from asynctest import CoroutineMock +from duniterpy.grammars import output from PyQt5.QtCore import QLocale from sakia.core.registry.identities import IdentitiesRegistry from sakia.core import Wallet @@ -28,3 +28,71 @@ class TestWallet(unittest.TestCase, QuamashTest): self.assertEqual(wallet.pubkey, wallet_from_json.pubkey) self.assertEqual(wallet.name, wallet_from_json.name) self.assertEqual(wallet._identities_registry, wallet_from_json._identities_registry) + + def test_prepare_tx(self): + community = MagicMock("sakia.core.Community") + community.currency = "test_currency" + cache = MagicMock("sakia.core.txhistory.TxHistory") + cache.available_sources = [{ + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "type": "D", + "noffset": 2, + "identifier": "FCAD5A388AC8A811B45A9334A375585E77071AA9F6E5B6896582961A6C66F365", + "amount": 15, + "base": 0 + }, + { + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "type": "D", + "noffset": 4, + "identifier": "A0AC57E2E4B24D66F2D25E66D8501D8E881D9E6453D1789ED753D7D426537ED5", + "amount": 85, + "base": 0 + }, + { + "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + "type": "T", + "noffset": 4, + "identifier": "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67", + "amount": 11, + "base": 1 + }] + wallet = Wallet(0, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "Wallet 1", self.identities_registry) + wallet.caches["test_currency"] = cache + tx = wallet.prepare_tx("FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", + 100, "", community) + self.assertEqual(len(tx.issuers), 1) + self.assertEqual(tx.issuers[0], "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ") + self.assertEqual(len(tx.inputs), 2) + self.assertEqual(tx.inputs[0].origin_id, "FCAD5A388AC8A811B45A9334A375585E77071AA9F6E5B6896582961A6C66F365") + self.assertEqual(tx.inputs[0].source, "D") + self.assertEqual(tx.inputs[0].index, 2) + self.assertEqual(tx.inputs[1].origin_id, "A0AC57E2E4B24D66F2D25E66D8501D8E881D9E6453D1789ED753D7D426537ED5") + self.assertEqual(tx.inputs[1].source, "D") + self.assertEqual(tx.inputs[1].index, 4) + self.assertEqual(len(tx.outputs), 1) + self.assertEqual(tx.outputs[0].amount, 100) + self.assertEqual(tx.outputs[0].base, 0) + self.assertEqual(pypeg2.compose(tx.outputs[0].conditions, output.Condition), + "SIG(FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn)") + self.assertEqual(len(tx.unlocks), 2) + self.assertEqual(tx.unlocks[0].index, 0) + self.assertEqual(tx.unlocks[0].parameters[0].index, 0) + self.assertEqual(tx.unlocks[1].index, 1) + self.assertEqual(tx.unlocks[0].parameters[0].index, 0) + self.assertEqual(tx.raw(), """Version: 2 +Type: Transaction +Currency: test_currency +Locktime: 0 +Issuers: +7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ +Inputs: +D:FCAD5A388AC8A811B45A9334A375585E77071AA9F6E5B6896582961A6C66F365:2 +D:A0AC57E2E4B24D66F2D25E66D8501D8E881D9E6453D1789ED753D7D426537ED5:4 +Unlocks: +0:SIG(0) +1:SIG(0) +Outputs: +100:0:SIG(FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn) +Comment:""" + " \n") diff --git a/src/sakia/tests/unit/core/txhistory/test_txhistory_loading.py b/src/sakia/tests/unit/core/txhistory/test_txhistory_loading.py index 5ec06b989afe3b497e185407bbddb142738c306e..9f4ef8c0618dfc6d002da9bc615ed2f144986a12 100644 --- a/src/sakia/tests/unit/core/txhistory/test_txhistory_loading.py +++ b/src/sakia/tests/unit/core/txhistory/test_txhistory_loading.py @@ -12,7 +12,7 @@ from sakia.core import Account, Community, Wallet from sakia.core.net import Network, Node from sakia.core.net.api.bma.access import BmaAccess from sakia.tests import QuamashTest -from ucoinpy.documents.peer import BMAEndpoint +from duniterpy.documents.peer import BMAEndpoint class TestTxHistory(unittest.TestCase, QuamashTest): @@ -28,7 +28,7 @@ class TestTxHistory(unittest.TestCase, QuamashTest): self.node = Node("test_currency", [self.endpoint], "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", nice_blockchain.bma_blockchain_current, Node.ONLINE, - time.time(), {}, "ucoin", "0.14.0", 0) + time.time(), {}, "duniter", "0.14.0", 0) self.network = Network.create(self.node) self.bma_access = BmaAccess.create(self.network) self.community = Community("test_currency", self.network, self.bma_access) diff --git a/src/sakia/tests/unit/gui/test_context_menu.py b/src/sakia/tests/unit/gui/test_context_menu.py index d12a2aa223d1467acbb77dfdb872359d44563401..c1ee0b9fa17d4cbf9f96afd36cf6dcaeebf515e6 100644 --- a/src/sakia/tests/unit/gui/test_context_menu.py +++ b/src/sakia/tests/unit/gui/test_context_menu.py @@ -5,7 +5,7 @@ from PyQt5.QtCore import QLocale from sakia.tests import QuamashTest from sakia.tests.mocks.bma import nice_blockchain from sakia.gui.widgets.context_menu import ContextMenu -from ucoinpy.documents import Membership, BlockId +from duniterpy.documents import Membership, BlockUID from sakia.tools.exceptions import MembershipNotFoundError @@ -73,20 +73,20 @@ class TestContextMenu(unittest.TestCase, QuamashTest): @patch('PyQt5.QtWidgets.QMenu', create=True) def test_copy_membership_to_clipboard(self, qmenu): ms_data = { - "version": 1, + "version": 2, "currency": "meta_brouzouf", "membership": "IN", "blockNumber": 49116, - "blockHash": "000004CA4F77E36CE52C23A9F2A8F2A259773CE9", + "blockHash": "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67", "written": 49119 } ms_document = Membership(ms_data["version"], ms_data["currency"], self.identity.pubkey, - BlockId(ms_data["blockNumber"], ms_data["blockHash"]), - ms_data["membership"], self.identity.uid, 1421787800, + BlockUID(ms_data["blockNumber"], ms_data["blockHash"]), + ms_data["membership"], self.identity.uid, "49116-7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67", "znWiWP7Sy9gg9pZq4YWKNpel8MM16VBM1lgBg2gWjSonnc+KVRCtQng5JB4JD0PgJJ0F8jdITuggFrRwqRfzAA==") self.identity.membership = CoroutineMock(return_value=ms_data) self.community.get_block = CoroutineMock(return_value={ - "version": 1, + "version": 2, "nonce": 127424, "number": 49119, "powMin": 5, @@ -97,21 +97,45 @@ class TestContextMenu(unittest.TestCase, QuamashTest): "currency": "meta_brouzouf", "issuer": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", "signature": "ZmjhoRubftJ/T2WYQ3gaDeTGGUJ3beUshtlWn1k/r5opk0vt48KG3w+9JU0T9YFR5uezllaek9efoNwAHRBLDw==", - "hash": "0000075129361571E74380B686DE6E1E29FF8400", + "hash": "49E2A1D1131F1496FAD6EDAE794A9ADBFA8844029675E3732D3B027ABB780243", + "innerhash": "273DE1845F8A63677D69DD427E00DAD73D9AEDBA80356A2E0D2152939D9DAF0C", "parameters": "", "previousHash": "000005C27A1636FE07AB01766FBA060565142D79", "previousIssuer": "HBSSmqZjT4UQKsCntTSmZbu7iRP14HYtifLE6mW1PsBD", "dividend": None, "identities": [], "joiners": [ - "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU:znWiWP7Sy9gg9pZq4YWKNpel8MM16VBM1lgBg2gWjSonnc+KVRCtQng5JB4JD0PgJJ0F8jdITuggFrRwqRfzAA==:49116:000004CA4F77E36CE52C23A9F2A8F2A259773CE9:1421787800:inso" + "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:znWiWP7Sy9gg9pZq4YWKNpel8MM16VBM1lgBg2gWjSonnc+KVRCtQng5JB4JD0PgJJ0F8jdITuggFrRwqRfzAA==:49116-7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67:49116-7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67:A" ], "actives": [], "leavers": [], "excluded": [], + "revoked": [], "certifications": [], "transactions": [], - "raw": "Version: 1\nType: Block\nCurrency: meta_brouzouf\nNonce: 127424\nNumber: 49119\nPoWMin: 5\nTime: 1453921638\nMedianTime: 1453912797\nIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nPreviousHash: 000005C27A1636FE07AB01766FBA060565142D79\nPreviousIssuer: HBSSmqZjT4UQKsCntTSmZbu7iRP14HYtifLE6mW1PsBD\nMembersCount: 18\nIdentities:\nJoiners:\nHnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:znWiWP7Sy9gg9pZq4YWKNpel8MM16VBM1lgBg2gWjSonnc+KVRCtQng5JB4JD0PgJJ0F8jdITuggFrRwqRfzAA==:49116:000004CA4F77E36CE52C23A9F2A8F2A259773CE9:1421787800:A\nActives:\nLeavers:\nExcluded:\nCertifications:\nTransactions:\n" + "raw": """Version: 2 +Type: Block +Currency: meta_brouzouf +Number: 49119 +PoWMin: 5 +Time: 1453921638 +MedianTime: 1453912797 +Issuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk +PreviousHash: 000005C27A1636FE07AB01766FBA060565142D79 +PreviousIssuer: HBSSmqZjT4UQKsCntTSmZbu7iRP14HYtifLE6mW1PsBD +MembersCount: 18 +Identities: +Joiners: +HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:znWiWP7Sy9gg9pZq4YWKNpel8MM16VBM1lgBg2gWjSonnc+KVRCtQng5JB4JD0PgJJ0F8jdITuggFrRwqRfzAA==:49116-7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67:49116-7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67:A +Actives: +Leavers: +Revoked: +Excluded: +Certifications: +Transactions: +InnerHash: 273DE1845F8A63677D69DD427E00DAD73D9AEDBA80356A2E0D2152939D9DAF0C +Nonce: 127424 +""" }) self.qapplication.clipboard().clear() diff --git a/src/sakia/tests/unit/gui/test_main_window.py b/src/sakia/tests/unit/gui/test_main_window.py index 12d42269c34e31bae69bdbda4b271d21208168d7..0227edd5086c265d2ca1846af40cd21b8c68238c 100644 --- a/src/sakia/tests/unit/gui/test_main_window.py +++ b/src/sakia/tests/unit/gui/test_main_window.py @@ -34,6 +34,7 @@ class TestMainWindow(unittest.TestCase, QuamashTest): self.homescreen = MagicMock(autospec='sakia.gui.homescreen.Homescreen') self.community_view = MagicMock(autospec='sakia.gui.community_view.CommunityView') self.password_asker = MagicMock(autospec='sakia.gui.password_asker.PasswordAsker') + self.node_manager = MagicMock(autospec='sakia.gui.node_manager.NodeManager') def tearDown(self): self.tearDownQuamash() @@ -47,7 +48,10 @@ class TestMainWindow(unittest.TestCase, QuamashTest): label_status = Mock() label_time = Mock() combo_referentials = Mock() - mainwindow = MainWindow(self.app, self.account_joe, self.homescreen, self.community_view, widget, ui, label_icon, + combo_referentials.currentIndexChanged = {int: Mock()} + mainwindow = MainWindow(self.app, self.account_joe, + self.homescreen, self.community_view, self.node_manager, + widget, ui, label_icon, label_status, label_time, combo_referentials, self.password_asker) mainwindow.refresh = Mock() mainwindow.action_change_account("doe") @@ -69,8 +73,11 @@ class TestMainWindow(unittest.TestCase, QuamashTest): label_status = Mock() label_time = Mock() combo_referentials = Mock() + combo_referentials.currentIndexChanged = {int: Mock()} + type(self.app).current_account = PropertyMock(return_value=None) - mainwindow = MainWindow(self.app, None, self.homescreen, self.community_view, widget, ui, label_icon, + mainwindow = MainWindow(self.app, None, self.homescreen, self.community_view, self.node_manager, + widget, ui, label_icon, label_status, label_time, combo_referentials, self.password_asker) mainwindow.refresh = Mock() mainwindow.action_change_account("doe") diff --git a/src/sakia/tests/unit/gui/views/test_base_node.py b/src/sakia/tests/unit/gui/views/test_base_node.py index 4162afe55fb9dcd61b44a60b675d70e154e84921..3e2016837f242d1235d7658f932158a809e93606 100644 --- a/src/sakia/tests/unit/gui/views/test_base_node.py +++ b/src/sakia/tests/unit/gui/views/test_base_node.py @@ -32,6 +32,6 @@ class TestBaseNode(unittest.TestCase, QuamashTest): self.assertEqual(node.status_wallet, False) self.assertEqual(node.status_member, True) self.assertEqual(node.text, "UserA") - self.assertEqual(node.toolTip(), "TestTooltip") + self.assertEqual(node.toolTip(), "UserA - TestTooltip") self.lp.run_until_complete(exec_test()) \ No newline at end of file diff --git a/src/sakia/tests/unit/gui/views/test_explorer_node.py b/src/sakia/tests/unit/gui/views/test_explorer_node.py index e684d5ab56d23107426561f4ed721e5126d30f84..a27c75e1cc1a7724f518af2ee3c0f352e00b7b1a 100644 --- a/src/sakia/tests/unit/gui/views/test_explorer_node.py +++ b/src/sakia/tests/unit/gui/views/test_explorer_node.py @@ -27,7 +27,7 @@ class TestExplorerNode(unittest.TestCase, QuamashTest): "B": (10, 20) } async def exec_test(): - node = ExplorerNode(("A", metadata), QPointF(0, 0), nx_pos, 0, 1) + node = ExplorerNode(("A", metadata), QPointF(0, 0), nx_pos, 0, 1, False) self.assertEqual(node.id, "A") self.assertEqual(node.metadata['status'], NodeStatus.NEUTRAL) self.assertEqual(node.x(), 0) @@ -35,7 +35,7 @@ class TestExplorerNode(unittest.TestCase, QuamashTest): self.assertEqual(node.status_wallet, False) self.assertEqual(node.status_member, True) self.assertEqual(node.text, "UserA") - self.assertEqual(node.toolTip(), "TestTooltip") + self.assertEqual(node.toolTip(), "UserA - TestTooltip") self.lp.run_until_complete(exec_test()) @@ -52,7 +52,7 @@ class TestExplorerNode(unittest.TestCase, QuamashTest): "B": (10, 20) } async def exec_test(): - node = ExplorerNode(("A", metadata), QPointF(0, 0), nx_pos, 0, 1) + node = ExplorerNode(("A", metadata), QPointF(0, 0), nx_pos, 0, 1, False) node.paint(painter, QStyleOptionGraphicsItem(), widget) self.lp.run_until_complete(exec_test()) @@ -70,7 +70,7 @@ class TestExplorerNode(unittest.TestCase, QuamashTest): "B": (10, 20) } async def exec_test(): - node = ExplorerNode(("A", metadata), QPointF(0, 0), nx_pos, 0, 1) + node = ExplorerNode(("A", metadata), QPointF(0, 0), nx_pos, 0, 1, False) bounding_rect = node.boundingRect() self.assertAlmostEqual(bounding_rect.x(), -0.5, delta=15) self.assertAlmostEqual(bounding_rect.y(), -0.5, delta=15) diff --git a/src/sakia/tests/unit/gui/views/test_explorer_scene.py b/src/sakia/tests/unit/gui/views/test_explorer_scene.py index 9585e42c4eca9f210996c4ceb6229402f51c3778..7ba890170be0b25a011347b4d1a7973b3cddd3da 100644 --- a/src/sakia/tests/unit/gui/views/test_explorer_scene.py +++ b/src/sakia/tests/unit/gui/views/test_explorer_scene.py @@ -22,7 +22,7 @@ class TestExplorerScene(unittest.TestCase, QuamashTest): # -> E self.identity_status = [NodeStatus.SELECTED, NodeStatus.NEUTRAL, NodeStatus.NEUTRAL, NodeStatus.OUT, NodeStatus.NEUTRAL] - self.test_graph = networkx.MultiDiGraph().to_undirected() + self.test_graph = networkx.MultiDiGraph() self.test_graph.add_nodes_from(self.identities_pubkeys) self.test_graph.add_edges_from(self.certifications) for index, node in enumerate(self.test_graph.nodes(data=True)): @@ -119,7 +119,9 @@ class TestExplorerScene(unittest.TestCase, QuamashTest): @patch('networkx.MultiDiGraph') def test_set_subtree_position(self, mock_graph): # We mock the edges generator to ensure the order in which they appear - mock_graph.edges = Mock(return_value=self.certifications) + undirected = Mock('networkx.MultiDiGraph') + undirected.edges = Mock(return_value=self.certifications) + mock_graph.to_undirected = Mock(return_value=undirected) data_layout = {} for pubkey in self.identities_pubkeys: diff --git a/src/sakia/tests/unit/gui/views/test_wot_node.py b/src/sakia/tests/unit/gui/views/test_wot_node.py index 6bf361fa23537deb98c11b0a71fbc03dcd91c5c1..9577447d7408b2b06cdc323781bc56919c1e5ff7 100644 --- a/src/sakia/tests/unit/gui/views/test_wot_node.py +++ b/src/sakia/tests/unit/gui/views/test_wot_node.py @@ -35,7 +35,7 @@ class TestWotNode(unittest.TestCase, QuamashTest): self.assertEqual(node.status_wallet, False) self.assertEqual(node.status_member, True) self.assertEqual(node.text, "UserA") - self.assertEqual(node.toolTip(), "TestTooltip") + self.assertEqual(node.toolTip(), "UserA - TestTooltip") self.lp.run_until_complete(exec_test()) diff --git a/src/sakia/tools/decorators.py b/src/sakia/tools/decorators.py index 669e89bf7a3a60f8885bfd4df9273e78f946fbd3..7648502ebeb53d64180a81e1c5b04e40aa330538 100644 --- a/src/sakia/tools/decorators.py +++ b/src/sakia/tools/decorators.py @@ -35,7 +35,6 @@ def once_at_a_time(fn): if fn.__name__ in args[0].__tasks: args[0].__tasks[fn.__name__]._next_task = fn args[0].__tasks[fn.__name__].cancel() - logging.debug("Previous {0} was cancelled".format(fn.__name__)) else: fn._start()