diff --git a/MANIFEST.in b/MANIFEST.in index 32faac0..cdc112e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,3 @@ recursive-include rein/html * recursive-include rein/lib/crypto/resources * +recursive-include rein/locale * \ No newline at end of file diff --git a/Makefile b/Makefile index 341b589..6f267a4 100644 --- a/Makefile +++ b/Makefile @@ -3,5 +3,7 @@ clean: rm -f enrollment.txt.sig test: - python -m unittest2 rein/lib/script.py - python -m unittest2 rein/lib/bitcoinaddress.py + nosetests -v --ignore-files="test_cli.py" + +test_all: + nosetests -v diff --git a/README.md b/README.md index 77492af..8d2f543 100644 --- a/README.md +++ b/README.md @@ -80,27 +80,40 @@ For the mediator payment, a mandatory multisig address is created. To spend the Like with the primary payment, a user is prompted for a signed mediator payment if they are a job creator accepting a delivery or they are the mediator resolving a dispute. -## Development and Testing +## Developer Notes We have [a quick Vagrant-based setup](https://github.com/ReinProject/devsetup) that gives you a virtual machine with the python-rein client, Causway server and its Bitcoin Core (testnet) node all configured to work together. Testing usually involves creating users and walking through jobs so a virtual machine that has all components going, even allowing payments to be sent is very helpful. -Tests are run using nose: +To generate or update pot files for translation, run the following from the root of the repo: - $ nosetests + xgettext.pl rein/cli.py rein/lib/*.py + +## Testing + +We have [a quick Vagrant-based setup](https://github.com/ReinProject/devsetup) that gives you a virtual machine with the python-rein client, Causway server and its Bitcoin Core (testnet) node all configured to work together. Testing usually involves creating users and walking through jobs so a virtual machine that has all components going, even allowing payments to be sent is very helpful. + +Tests are run using nose, with the make file specifying two different test commands: + + $ make test + nosetests -v --ignore-files="test_cli.py" .. ---------------------------------------------------------------------- - Ran 2 tests in 0.837s + Ran 5 tests in 0.344 OK -And unittest2: +and - $ make test - python -m unittest2 rein/lib/*.py - .... + $ make test_all + nosetests -v + .. ---------------------------------------------------------------------- - Ran 4 tests in 0.001s - + Ran 7 tests in 2.393s + OK +By default, the more limited "test" command should be used when a dedicated test-environment, such as the Vagrant set-up mentioned above, is not available. It currently runs all tests except the tests specified in "tests/test_cli.py". + Tox fails right now but does run flake so will be helpful for cleanup. + +Be aware that new unit tests should be added to a file within the tests directory. Both the file name and the test method names should follow the naming convention "test_*". \ No newline at end of file diff --git a/rein/cli.py b/rein/cli.py index fb5a95d..b18f4b8 100644 --- a/rein/cli.py +++ b/rein/cli.py @@ -26,6 +26,7 @@ from .lib.util import unique from .lib.io import safe_get from .lib.script import build_2_of_3, build_mandatory_multisig, check_redeem_scripts +from .lib.localization import init_localization from .lib.transaction import partial_spend_p2sh, spend_p2sh, spend_p2sh_mediator, partial_spend_p2sh_mediator, partial_spend_p2sh_mediator_2 from .lib.rating import add_rating, get_user_jobs @@ -45,17 +46,20 @@ from .lib.mediator import Mediator rein = config.Config() +init_localization() + import bitcoin from bitcoin.wallet import P2PKHBitcoinAddress from bitcoin.core import x if (rein.testnet): bitcoin.SelectParams('testnet') +init_localization() @click.group() @click.option('--debug/--no-debug', default=False) @click.pass_context def cli(ctx, debug): - """ + _(""" Rein is a decentralized professional services market and Python-rein is a client that provides a user interface. Use this program from your local browser or command line to create an account, post a job, bid, etc. @@ -79,7 +83,7 @@ def cli(ctx, debug): $ rein resolve - mediator posts decision For more info and the setup guide visit: http://reinproject.org - """ + """) if debug: click.echo("Debuggin'") pass @@ -88,23 +92,24 @@ def cli(ctx, debug): @cli.command() @click.option('--multi/--no-multi', default=False, help="add even if an identity exists") def setup(multi): - """ + _(""" Setup or import an identity. You will choose a name or handle for your account, include public contact information, and a delegate Bitcoin address/private key that the program will use to sign documents on your behalf. An enrollment document will be created and you will need to sign it with your master Bitcoin private key. - """ + """) log = rein.get_log() if multi: rein.set_multiuser() log.info('entering setup') if multi or rein.has_no_account(): - click.echo("\n" + highlight("Welcome to Rein.", True, True) + "\n\n" - "Do you want to import a backup or create a new account?\n\n" - "1 - Create new account\n2 - Import backup\n") + click.echo("\n" + highlight(_("Welcome to Rein."), True, True) + "\n\n" + + _("Do you want to import a backup or create a new account?\n\n") + + _("1 - Create new account\n2 - Import backup\n")) choice = click.prompt(highlight("Choice", True, True), type=int, default=1) + if choice == 1: create_account(rein) log.info('account created') diff --git a/rein/lib/bitcoinaddress.py b/rein/lib/bitcoinaddress.py index ced735e..4e9700a 100644 --- a/rein/lib/bitcoinaddress.py +++ b/rein/lib/bitcoinaddress.py @@ -2,11 +2,9 @@ from crypto.util import ripemd160 from bitcoin import base58 from binascii import unhexlify -import unittest digits58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' - def to_bytes(n, length, endianess='big'): h = '%x' % n s = ('0' * (len(h) % 2) + h).zfill(length * 2).decode('hex') @@ -26,16 +24,6 @@ def check_bitcoin_address(bc): bcbytes = decode_base58(bc, 25) return bcbytes[-4:] == sha256(sha256(bcbytes[:-4]).digest()).digest()[:4] - -class BitcoinAddressTest(unittest.TestCase): - def test_check_bitcoin_address(self): - self.assertTrue(check_bitcoin_address('1CptxARjqcfkVwGFSjR82zmPT8YtRMubub')) - self.assertTrue(check_bitcoin_address('3746f7fjJ6fG1pQXDjA8xy9WAzf4968WWv')) - self.assertFalse(check_bitcoin_address('2746f7fjJ6fG1pQXDjA8xy9WAzf4968WWv')) - - def test_check_sin(self): - self.assertEqual(generate_sin('02F840A04114081690223B7069071A70D6DABB891763B638CC20C7EC3BD58E6C86'), 'TfG4ScDgysrSpodWD4Re5UtXmcLbY5CiUHA') - def generate_sin(master_key): """Generates a type 2 'Secure Identity Number' using the bip32 master public key""" prefix = 0x0F diff --git a/rein/lib/forms.py b/rein/lib/forms.py index 04ff505..09efc57 100644 --- a/rein/lib/forms.py +++ b/rein/lib/forms.py @@ -16,16 +16,16 @@ def validate_privkey(form, field): if not privkey_to_address(field.data): - raise ValidationError("Not a valid private key.") + raise ValidationError(_("Not a valid private key.")) def validate_address(form, field): if not check_bitcoin_address(field.data): - raise ValidationError("Invalid address") + raise ValidationError(_("Invalid address")) def validate_en(form, field): message = field.data.replace("\r\n","\n") if not validate_enrollment(message): - raise ValidationError("Invalid signature") + raise ValidationError(_("Invalid signature")) def validate_mediator_fee(form, field): try: @@ -38,55 +38,55 @@ def avoid_self_rating(form, field): raise ValidationError('You may not rate yourself!') class SetupForm(Form): - name = TextField('Name / Handle', validators = [Required()]) - contact = TextField('Email / Bitmessage', validators = [Required()]) - maddr = TextField('Master Bitcoin address', validators = [Required(), validate_address]) - daddr = TextField('Delegate Bitcoin address', validators = [Required(), validate_address]) - dkey = PasswordField('Delegate Bitcoin private Key', validators = [Required(), validate_privkey]) - will_mediate = RadioField('Register as a mediator?', choices = [('1','Yes'), ('0', 'No')]) - mediator_fee = TextField('Mediator Fee', validators = [validate_mediator_fee]) # TODO make required only if Yes above + name = TextField(_('Name / Handle'), validators = [Required()]) + contact = TextField(_('Email / Bitmessage'), validators = [Required()]) + maddr = TextField(_('Master Bitcoin address'), validators = [Required(), validate_address]) + daddr = TextField(_('Delegate Bitcoin address'), validators = [Required(), validate_address]) + dkey = PasswordField(_('Delegate Bitcoin private Key'), validators = [Required(), validate_privkey]) + will_mediate = RadioField(_('Register as a mediator?'), choices = [('1','Yes'), ('0', 'No')]) + mediator_fee = TextField(_('Mediator Fee'), validators = [validate_mediator_fee]) # TODO make required only if Yes above class SignForm(Form): identity_id = HiddenInput("identity_id") - signed = TextAreaField('Signed enrollment', validators = [Required(), validate_en]) + signed = TextAreaField(_('Signed enrollment'), validators = [Required(), validate_en]) class JobPostForm(Form): - job_name = TextField('Job name', validators = [Required()]) - description = TextAreaField('Description', validators = [Required()]) - tags = TextField('Tags', validators = [Required()]) - expire_days = TextField('Expiration (days)', validators = [Required()]) - mediator_maddr = RadioField('Choose mediator') + job_name = TextField(_('Job name'), validators = [Required()]) + description = TextAreaField(_('Description'), validators = [Required()]) + tags = TextField(_('Tags'), validators = [Required()]) + expire_days = TextField(_('Expiration (days)'), validators = [Required()]) + mediator_maddr = RadioField(_('Choose mediator')) class BidForm(Form): - description = TextAreaField('Description', validators = [Required()]) - bid_amount = TextAreaField('Bid amount', validators = [Required()]) - job_id = RadioField('Choose Job to bid on') + description = TextAreaField(_('Description'), validators = [Required()]) + bid_amount = TextAreaField(_('Bid amount'), validators = [Required()]) + job_id = RadioField(_('Choose Job to bid on')) class JobOfferForm(Form): - bid_id = RadioField('Choose bid') + bid_id = RadioField(_('Choose bid')) class DeliverForm(Form): - deliverable = TextAreaField('Deliverables', validators = [Required()]) - job_id = RadioField('Choose job associated with deliverables') + deliverable = TextAreaField(_('Deliverables'), validators = [Required()]) + job_id = RadioField(_('Choose job associated with deliverables')) class DisputeForm(Form): - dispute_detail = TextAreaField('Dispute detail', validators = [Required()]) - order_id = RadioField('Choose job') + dispute_detail = TextAreaField(_('Dispute detail'), validators = [Required()]) + order_id = RadioField(_('Choose job')) class AcceptForm(Form): - deliverable_id = RadioField('Deliverables') + deliverable_id = RadioField(_('Deliverables')) class ResolveForm(Form): - resolution = TextAreaField('Resolution', validators = [Required()]) - client_payment_amount = TextField('Client payment amount in BTC (remainder sent to worker)', validators = [Required()]) - dispute_id = RadioField('Disputes') + resolution = TextAreaField(_('Resolution'), validators = [Required()]) + client_payment_amount = TextField(_('Client payment amount in BTC (remainder sent to worker)'), validators = [Required()]) + dispute_id = RadioField(_('Disputes')) class AcceptResolutionForm(Form): - resolution_id = RadioField('Resolution') + resolution_id = RadioField(_('Resolution')) class RatingForm(Form): - job_id = TextField('Job id', validators = [Required()], default='') - user_id = TextField('User SIN', validators = [Required(), avoid_self_rating], default='') - rated_by_id = TextField('Rated by SIN', validators = [Required()], default='') - rating = TextField('Rating', validators=[Required()], default=0, widget=HiddenInput()) - comments = TextAreaField('Comments', validators = [], default='') + job_id = TextField(_('Job ID'), validators = [Required()], default='') + user_id = TextField(_('User SIN'), validators = [Required(), avoid_self_rating], default='') + rated_by_id = TextField(_('Rated by SIN'), validators = [Required()], default='') + rating = TextField(_('Rating'), validators=[Required()], default=0, widget=HiddenInput()) + comments = TextAreaField(_('Comments'), validators = [], default='') diff --git a/rein/lib/io.py b/rein/lib/io.py index 7ecdcf4..528ca51 100644 --- a/rein/lib/io.py +++ b/rein/lib/io.py @@ -13,7 +13,7 @@ def safe_get(log, url): try: answer = requests.get(url=url, proxies=rein.proxies) except requests.ConnectionError: - click.echo('Error connecting to server.') + click.echo(_('Error connecting to server.')) log.error('server connect error ' + url) return None diff --git a/rein/lib/localization.py b/rein/lib/localization.py new file mode 100644 index 0000000..e0d3863 --- /dev/null +++ b/rein/lib/localization.py @@ -0,0 +1,26 @@ +import gettext +import locale +import logging +import os +import rein.locale + +def init_localization(): + '''prepare l10n''' + # Extract system locale identifier + loc = locale.getdefaultlocale()[0] + file_name = "messages-%s.mo" % loc.split('_')[0].upper() + file_path = os.path.join(os.path.dirname(os.path.abspath(rein.locale.__file__)), file_name) + + try: + logging.debug("Opening message file %s for locale %s", file_name, loc[0]) + trans = gettext.GNUTranslations(open(file_path, "rb" )) + + except IOError: + logging.debug("Locale not found. Using default messages") + trans = gettext.NullTranslations() + + trans.install() + +if __name__ == '__main__': + init_localization() + \ No newline at end of file diff --git a/rein/lib/market.py b/rein/lib/market.py index 56a913f..6e8c688 100644 --- a/rein/lib/market.py +++ b/rein/lib/market.py @@ -53,7 +53,7 @@ def sign_and_store_document(rein, doc_type, document, signature_address=None, si click.echo("\n%s\n" % document) done = False while not done: - filename = click.prompt("File containing signed document", type=str, default=doc_type + '.sig.txt') + filename = click.prompt(_("File containing signed document"), type=str, default=doc_type + '.sig.txt') if os.path.isfile(filename): done = True f = open(filename, 'r') diff --git a/rein/lib/order.py b/rein/lib/order.py index cbdff82..f3af1af 100644 --- a/rein/lib/order.py +++ b/rein/lib/order.py @@ -1,76 +1,78 @@ from sqlalchemy import Column, Integer, String, Boolean, and_ from sqlalchemy.ext.declarative import declarative_base +from localization import init_localization try: from document import Document except: pass Base = declarative_base() +init_localization() STATE = { 'job_posting': { 'pre': [], 'next': ['bid'], 'endpoint': '/post', - 'past_tense': 'posted', - 'description': "Funds for each job in Rein are stored in two multisig addresses. One address\n" \ - "is for the primary payment that will go to the worker on completion. The\n" \ - "second address pays the mediator to be available to resolve a dispute\n" \ - "if necessary. The second address should be funded according to the percentage\n" \ - "specified by the mediator and is in addition to the primary payment. The\n" \ - "listing below shows available mediators and the fee they charge. You should\n" \ - "consider the fee as well as any reputational data you are able to find when\n" \ - "choosing a mediator. Your choice may affect the number and quality of bids\n" + 'past_tense': _('posted'), + 'description': _("""Funds for each job in Rein are stored in two multisig addresses. One address +is for the primary payment that will go to the worker on completion. The +second address pays the mediator to be available to resolve a dispute +if necessary. The second address should be funded according to the percentage +specified by the mediator and is in addition to the primary payment. The +listing below shows available mediators and the fee they charge. You should +consider the fee as well as any reputational data you are able to find when +choosing a mediator. Your choice may affect the number and quality of bids"""), }, 'bid': { 'pre': ['job_posting'], 'next': ['offer'], 'endpoint': None, - 'past_tense': 'bid submitted' + 'past_tense': _('bid submitted'), }, 'offer': { 'pre': ['bid'], 'next': ['delivery', 'creatordispute', 'workerdispute'], 'endpoint': '/offer', - 'past_tense': 'job awarded', + 'past_tense': _('job awarded'), }, 'delivery': { 'pre': ['offer'], 'next': ['accept', 'creatordispute', 'workerdispute'], 'endpoint': '/deliver', - 'past_tense': 'deliverables submitted' + 'past_tense': _('deliverables submitted'), }, 'creatordispute': { 'pre': ['offer', 'delivery'], 'next': ['resolve', 'workerdispute'], 'endpoint': '/dispute', - 'past_tense':'disputed by job creator' + 'past_tense': _('disputed by job creator'), }, 'workerdispute': { 'pre': ['offer', 'delivery', 'accept'], 'next': ['resolve', 'creatordispute'], 'endpoint': '/dispute', - 'past_tense': 'disputed by worker' + 'past_tense': _('disputed by worker'), }, 'accept': { 'pre': ['delivery'], 'next': ['workerdispute', 'complete'], 'endpoint': '/accept', - 'past_tense': 'complete, work accepted', + 'past_tense': _('complete, work accepted'), }, 'resolve': { 'pre': ['creatordispute', 'workerdispute'], 'next': ['acceptresolution'], 'endpoint': '/resolve', - 'past_tense': 'dispute resolved' + 'past_tense': _('complete, dispute resolved'), }, 'acceptresolution': { 'pre': ['resolve'], 'next': ['complete'], 'endpoint': '/acceptresolution', - 'past_tense': 'complete, resolution accepted' + 'past_tense': _('complete, resolution accepted'), } -} + } class Order(Base): __tablename__ = 'order' diff --git a/rein/lib/script.py b/rein/lib/script.py index 1b39a92..14a5869 100644 --- a/rein/lib/script.py +++ b/rein/lib/script.py @@ -4,7 +4,6 @@ from bitcoin.core.script import CScript, OP_CHECKMULTISIG, OP_CHECKSIGVERIFY from bitcoin.wallet import CBitcoinAddress from .validate import parse_document -import unittest def parse_script(text): try: @@ -80,43 +79,4 @@ def check_redeem_scripts(document): ret['Mediator public key'], pubkeys): click.echo("2-of-3 check failed") return False - return True - -class BitcoinScriptTest(unittest.TestCase): - def test_2_of_3(self): - # primary payment 2-of-3 redeem script - p = parse_script('5221029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb0052102f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c4651921026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc53ae') - self.assertTrue(check_2_of_3(p, ['029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', - '02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', - '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) - # switch key order - self.assertTrue(check_2_of_3(p, ['02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', - '029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', - '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) - - def test_mandatory_multisig(self): - # mandatory multisig for mediator - - m = parse_script('2102f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519ad5121029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb00521026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc52ae') - self.assertTrue(check_mandatory_multisig(m, '02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', - ['029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', - '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) - # switch non-mandatory key order - self.assertTrue(check_mandatory_multisig(m, '02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', - ['029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', - '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) - # mix up mandatory and non-mandatory keys - self.assertFalse(check_mandatory_multisig(m, '029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', - ['02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', - '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) - - def test_build_redeem_scripts(self): - self.assertEquals(build_2_of_3(['02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', - '029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', - '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])[0], - '522102f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c4651921029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb00521026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc53ae') - - self.assertEquals(build_mandatory_multisig('02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', - ['029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', - '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])[0], - '2102f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519ad5121029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb00521026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc52ae') + return True \ No newline at end of file diff --git a/rein/lib/toolbox.py b/rein/lib/toolbox.py index 8787e0e..017cfc3 100644 --- a/rein/lib/toolbox.py +++ b/rein/lib/toolbox.py @@ -6,4 +6,4 @@ def yes_or_no(question): if len(reply) > 0 and reply[0] == 'n': return False else: - return yes_or_no("Please enter ") + return yes_or_no(_("Please enter ")) diff --git a/rein/lib/validate.py b/rein/lib/validate.py index 65a929a..123d2f4 100644 --- a/rein/lib/validate.py +++ b/rein/lib/validate.py @@ -11,7 +11,7 @@ def filter_out_expired(rein, user, urls, jobs): live = [] times = {} - click.echo('Verifying block times...') + click.echo(_('Verifying block times...')) with click.progressbar(jobs) as bar: for j in bar: if 'Block hash' not in j: @@ -165,7 +165,7 @@ def remote_query(rein, user, urls, log, query_type, distinct): sel_url = "{0}query?owner={1}&query={2}&testnet={3}" data = safe_get(log, sel_url.format(url, user.maddr, query_type, rein.testnet)) if data is None or query_type not in data or len(data[query_type]) == 0: - click.echo('None found') + click.echo(_('None found')) continue res += filter_and_parse_valid_sigs(rein, data[query_type]) return unique(res, distinct) diff --git a/rein/locale/__init__.py b/rein/locale/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rein/locale/compile.py b/rein/locale/compile.py new file mode 100644 index 0000000..e032d62 --- /dev/null +++ b/rein/locale/compile.py @@ -0,0 +1,8 @@ +import os +import subprocess + +# Compile all .po files within the current working directory to .mo format +for f in os.listdir(os.getcwd()): + if f.endswith('.po'): + subprocess.call("msgfmt {} -o {}".format(f, f.replace('.po', '.mo'))) + print('Compiling {} to .mo format'.format(f)) \ No newline at end of file diff --git a/rein/locale/messages-ES.mo b/rein/locale/messages-ES.mo new file mode 100644 index 0000000..5bb16af Binary files /dev/null and b/rein/locale/messages-ES.mo differ diff --git a/rein/locale/messages-ES.po b/rein/locale/messages-ES.po new file mode 100644 index 0000000..e8aaabb --- /dev/null +++ b/rein/locale/messages-ES.po @@ -0,0 +1,296 @@ +# Rein Decentralized Freelance Market. +# Copyright (C) 2017 +# This file is distributed under the same license as the python-rein package. +# David Sterry , 2017. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 0.2\n" +"POT-Creation-Date: 2016-12-21 11:00+PST\n" +"PO-Revision-Date: 2016-12-21 11:00+PST\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: rein/cli.py:52 +msgid "" +"\n" +" Rein is a decentralized professional services market and Python-rein is a client\n" +"that provides a user interface. Use this program from your local browser or command \n" +"line to create an account, post a job, bid, etc.\n" +"\n" +"\b\n" +" Quick start:\n" +" $ rein start - create an identity, run the Web UI\n" +" $ rein buy - request microhosting\n" +" $ rein sync - push your identity to microhosting servers\n" +" $ rein status - get user status, or dump of job's documents\n" +"\n" +"\b\n" +" Workers\n" +" $ rein bid - view and bid on jobs\n" +" $ rein deliver - complete job by providing deliverables\n" +"\n" +"\b\n" +" Disputes\n" +" $ rein workerdispute - worker files dispute\n" +" $ rein creatordispute - job creator files dispute\n" +" $ rein resolve - mediator posts decision\n" +"\n" +" For more info and the setup guide visit: http://reinproject.org\n" +" " +msgstr "" +"\n" +" Rein es un mercado profesional, descentralizado, de servicios y Python-rein es el cliente\n" +"que provee la interfaz de usuario. Usa este programa desde tu navegador o línea de comandos \n" +"para crear una cuenta, publicar un trabajo, ofertarse para un trabajo, etc.\n" +"\n" +"\b\n" +" Iniciándose:\n" +" $ rein start - crea una identidad, ejecuta la interfaz de usuario web\n" +" $ rein buy - pide microhosting\n" +" $ rein sync - sincroniza tu identidad con los servidores\n" +" $ rein status - comprobar estado de identidad, transacción, etc\n" +"\n" +"\b\n" +" Trabajadores\n" +" $ rein bid - mirar y ofertarse para un trabajo\n" +" $ rein deliver - completar trabajo suministrando entregas\n" +"\n" +"\b\n" +" Disputas\n" +" $ rein workerdispute - mediante este comando el trabajador puede comenzar un conflicto,\n" +" debe especificar la razón de la misma, i.e. el epmpleador no \n" +" fue razonable, etc, enlazar pruebas \n" +" $ rein creatordispute - mediante este comando el empleador puede comenzar un conflicto, \n" +" debe especificar la razón de la misma, i.e. el trabajador no realizó \n" +" la entrega o hizo un mal trabajo, etc\n" +" $ rein resolve - este comando es el usado por el mediador para revisar la información \n" +" dada por el empleador y el trabajador con el fin de decidir cómo \n" +" resolver el conflicto.\n" +"\n" +" Para más información y guía de configuración visitar: http://reinproject.org\n" +" " + +#: rein/cli.py:85 +msgid "" +"\n" +" Setup or import an identity.\n" +"\n" +" You will choose a name or handle for your account, include public contact information, \n" +" and a delegate Bitcoin address/private key that the program will use to sign documents\n" +" on your behalf. An enrollment document will be created and you will need to sign it\n" +" with your master Bitcoin private key.\n" +" " +msgstr "" +"\n" +" Configurar o importar una identidad.\n" +"\n" +" Escoger un nombre de usuario para la cuenta, incluyendo información pública de contacto, \n" +" y una dirección/llave privada delegada de Bitcoinand que el programa utilizará para firmar documentos\n" +" a tu favor. Se creará un documento llamado matrícula el cual deberás firmar con \n" +" la llave privada de la dirección Bitcoin principal .\n" +" " + +#: rein/cli.py:98 +msgid "" +"1 - Create new account\n" +"2 - Import backup\n" +msgstr "" +"1 - Crear nueva cuenta\n" +"2 - Restaurar respaldo\n" + +#: rein/lib/forms.py:51 +msgid "Bid amount" +msgstr "Ofrecer cantidad" + +#: rein/lib/forms.py:52 +msgid "Choose Job to bid on" +msgstr "Escoger trabajo para ofrecerse" + +#: rein/lib/forms.py:55 +msgid "Choose bid" +msgstr "Escoger oferta" + +#: rein/lib/forms.py:63 +msgid "Choose job" +msgstr "Escoger trabajo" + +#: rein/lib/forms.py:59 +msgid "Choose job associated with deliverables" +msgstr "Escoger trabajo asociado a entregas" + +#: rein/lib/forms.py:47 +msgid "Choose mediator" +msgstr "Escoger mediador" + +#: rein/lib/forms.py:33 +msgid "Delegate Bitcoin address" +msgstr "Dirección Bitcoin delegada" + +#: rein/lib/forms.py:34 +msgid "Delegate Bitcoin private Key" +msgstr "Llave privada de dirección delegada" + +#: rein/lib/forms.py:58 rein/lib/forms.py:68 +msgid "Deliverables" +msgstr "Entregas" + +#: rein/lib/forms.py:44 rein/lib/forms.py:50 +msgid "Description" +msgstr "Descripción" + +#: rein/lib/forms.py:62 +msgid "Dispute detail" +msgstr "Detalles de conflicto" + +#: rein/lib/forms.py:74 +msgid "Disputes" +msgstr "Conflictos" + +#: rein/cli.py:97 +msgid "" +"Do you want to import a backup or create a new account?\n" +"\n" +msgstr "" +"Deseas restaurar copia de respaldo o crear una nueva cuenta?\n" +"\n" + +#: rein/lib/forms.py:31 +msgid "Email / Bitmessage" +msgstr "Email" + +#: rein/lib/io.py:16 +msgid "Error connecting to server." +msgstr "Error conectándose al servidor" + +#: rein/lib/forms.py:46 +msgid "Expiration (days)" +msgstr "Expira (días)" + +#: rein/lib/market.py:54 +msgid "File containing signed document" +msgstr "Archivo que contiene documento firmado" + +#: rein/lib/order.py:18 +msgid "" +"Funds for each job in Rein are stored in two multisig addresses. One address\n" +"is for the primary payment that will go to the worker on completion. The\n" +"second address pays the mediator to be available to resolve a dispute\n" +"if necessary. The second address should be funded according to the percentage\n" +"specified by the mediator and is in addition to the primary payment. The\n" +"listing below shows available mediators and the fee they charge. You should\n" +"consider the fee as well as any reputational data you are able to find when\n" +"choosing a mediator. Your choice may affect the number and quality of bids" +msgstr "" +"Los fondos para cada trabajo en Rein se almacenan en dos direcciones multi-firma. \n" +"En la primera se transfieren los pagos al trabajador, tras terminar el trabajo,\n" +"en la segunda dirección, los pagos al mediador que resolverá los conflictos.\n" +"A la segunda dirección se le transferirá un monto de acuerdo a los honorarios establecidos\n" +"por el mediador, en adición a los fondos transferidos a la primera dirección. La lista mostrada\n" +"debajo muestra los mediadores disponibles y sus respectivos honorarios. Debes considerar\n" +"dichos honorarios así como los datos disponibles de reputación al buscar un mediador.\n" +"La elección de un mediador podría influir en el número y calidad de las ofertas." + +#: rein/lib/forms.py:22 +msgid "Invalid address" +msgstr "Dirección no válida" + +#: rein/lib/forms.py:27 +msgid "Invalid signature" +msgstr "Firma no válida" + +#: rein/lib/forms.py:43 +msgid "Job name" +msgstr "Nombre del trabajo" + +#: rein/lib/forms.py:32 +msgid "Master Bitcoin address" +msgstr "Dirección Bitcoin principal" + +#: rein/lib/forms.py:36 +msgid "Mediator Fee" +msgstr "Honorarios del mediador" + +#: rein/lib/forms.py:30 +msgid "Name / Handle" +msgstr "Nombre" + +#: rein/lib/validate.py:168 +msgid "None found" +msgstr "No se encontró" + +#: rein/lib/forms.py:18 +msgid "Not a valid private key." +msgstr "Llave privada no válida" + +#: rein/lib/toolbox.py:9 +msgid "Please enter " +msgstr "Por favor entre" + +#: rein/lib/forms.py:35 +msgid "Register as a mediator?" +msgstr "Registrarse como mediador?" + +#: rein/lib/forms.py:73 +msgid "Resolution" +msgstr "Decisión del mediador" + +#: rein/lib/forms.py:40 +msgid "Signed enrollment" +msgstr "Matrícula firmada" + +#: rein/lib/forms.py:67 rein/lib/forms.py:72 +msgid "Signed mediator payment" +msgstr "Pago de mediador firmado" + +#: rein/lib/forms.py:66 rein/lib/forms.py:71 +msgid "Signed primary payment" +msgstr "Pago principal firmado" + +#: rein/lib/forms.py:45 +msgid "Tags" +msgstr "Etiquetas" + +#: rein/lib/validate.py:14 +msgid "Verifying block times..." +msgstr "Verificando block ..." + +#: rein/cli.py:98 +msgid "Welcome to Rein." +msgstr "Bienvenido a Rein" + +#: rein/lib/order.py:31 +msgid "bid submitted" +msgstr "oferta enviada" + +#: rein/lib/order.py:67 +msgid "complete, dispute resolved" +msgstr "completo, conflicto resuelto" + +#: rein/lib/order.py:61 +msgid "complete, work accepted" +msgstr "completo, trabajo aceptado" + +#: rein/lib/order.py:43 +msgid "deliverables submitted" +msgstr "entregas enviadas" + +#: rein/lib/order.py:49 +msgid "disputed by job creator" +msgstr "dispudato por el creador del trabajo" + +#: rein/lib/order.py:55 +msgid "disputed by worker" +msgstr "dispudato por el trabajador" + +#: rein/lib/order.py:37 +msgid "job awarded" +msgstr "trabajo otorgado" + +#: rein/lib/order.py:17 +msgid "posted" +msgstr "publicado" diff --git a/rein/locale/messages-FIL.mo b/rein/locale/messages-FIL.mo new file mode 100644 index 0000000..75302bd Binary files /dev/null and b/rein/locale/messages-FIL.mo differ diff --git a/rein/locale/messages-FIL.po b/rein/locale/messages-FIL.po new file mode 100644 index 0000000..15ca5f4 --- /dev/null +++ b/rein/locale/messages-FIL.po @@ -0,0 +1,290 @@ +# Rein Decentralized Freelance Market. +# Copyright (C) 2017 +# This file is distributed under the same license as the python-rein package. +# David Sterry , 2017. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 0.2\n" +"POT-Creation-Date: 2016-12-21 11:00+PST\n" +"PO-Revision-Date: 2016-12-21 11:00+PST\n" +"Last-Translator: FULL NAME \n" +"Language-Team: FILIPINO \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: rein/cli.py:52 +msgid "" +"\n" +" Rein is a decentralized professional services market and Python-rein is a client\n" +"that provides a user interface. Use this program from your local browser or command \n" +"line to create an account, post a job, bid, etc.\n" +"\n" +"\b\n" +" Quick start:\n" +" $ rein start - create an identity, run the Web UI\n" +" $ rein buy - request microhosting\n" +" $ rein sync - push your identity to microhosting servers\n" +" $ rein status - get user status, or dump of job's documents\n" +"\n" +"\b\n" +" Workers\n" +" $ rein bid - view and bid on jobs\n" +" $ rein deliver - complete job by providing deliverables\n" +"\n" +"\b\n" +" Disputes\n" +" $ rein workerdispute - worker files dispute\n" +" $ rein creatordispute - job creator files dispute\n" +" $ rein resolve - mediator posts decision\n" +"\n" +" For more info and the setup guide visit: http://reinproject.org\n" +" " +msgstr "" +"\n" +" Ang Rein ay isang desentrilisadong merkado ng serbisyo ng mga propesyonal at anv Python-rein ay isang client\n" +"na nagbibigay ng user interface. Gamitin ang program na ito sa iyong local browser o sa command \n" +"linya para sa account , mag post ng trabaho, bid, at iba pa.\n" +"\n" +"\b\n" +" Mabilis na panimula:\n" +" $ rein start - gumawa ng kilanlan, patakbuhin ang Web UI\n" +" $ rein buy - humiling ng microhosting\n" +" $ rein sync - ilagay ay iyong pagkilablan sa microhosting servers\n" +" $ rein status - kunin ang status ng user o ibasura ang dokumento ng trabaho\n" +"\n" +"\b\n" +" Mga trabahador\n" +" $ rein bid - tingnan at mag bid sa mga trabaho\n" +" $ rein deliver - kompletuhin ang trabaho sa pamamagitan ng deliverables \n" +"\n" +"\b\n" +" Disputes\n" +" $ rein workerdispute - mga dispute files ng mga trabahador \n" +" $ rein creatordispute - mga dispute files ng mga tagagawa ng trabaho\n" +" $ rein resolve - paglathala ng desisyon ng mediator\n" +"\n" +" Para sa iba pang impormasyon bumisita sa: http://reinproject.org\n" +" " + +#: rein/cli.py:85 +msgid "" +"\n" +" Setup or import an identity.\n" +"\n" +" You will choose a name or handle for your account, include public contact information, \n" +" and a delegate Bitcoin address/private key that the program will use to sign documents\n" +" on your behalf. An enrollment document will be created and you will need to sign it\n" +" with your master Bitcoin private key.\n" +" " +msgstr "" +"\n" +" Setup o i-angkat ang pagkakilanlan.\n" +"\n" +" Pipili ka ng pangalan o hawakan ang iyong account, kasama ang mga impormasyon ng pampublikong contacts , \n" +" at mga delegadong Bitcoin address/private key na program na gagamitin sa pag sign ng documents\n" +" sa ngalan mo. Ang mga dokumento ng mga enrollment ay magagaqa at kailangan mo itong isign it\n" +" kasama ang iyong Master Bitcoin key.\n" +" " + +#: rein/cli.py:98 +msgid "" +"1 - Create new account\n" +"2 - Import backup\n" +msgstr "" +"1 - Gumawa ng bagong account\n" +"2 - Iimport ang backup\n" + +#: rein/lib/forms.py:51 +msgid "Bid amount" +msgstr "Halaga ng tawaran" + +#: rein/lib/forms.py:52 +msgid "Choose Job to bid on" +msgstr "Pumili ng trabaho kung saan mag tatawaran" + +#: rein/lib/forms.py:55 +msgid "Choose bid" +msgstr "Pumili ng tatawaran" + +#: rein/lib/forms.py:63 +msgid "Choose job" +msgstr "Pumili ng trabaho" + +#: rein/lib/forms.py:59 +msgid "Choose job associated with deliverables" +msgstr "Pumili ng trabaho kaugnay sa paghatid" + +#: rein/lib/forms.py:47 +msgid "Choose mediator" +msgstr "Mamili ng mediator" + +#: rein/lib/forms.py:33 +msgid "Delegate Bitcoin address" +msgstr "Delegado ng Bitcoin address" + +#: rein/lib/forms.py:34 +msgid "Delegate Bitcoin private Key" +msgstr "Delegado ng Bitcoin private Key" + +#: rein/lib/forms.py:58 rein/lib/forms.py:68 +msgid "Deliverables" +msgstr "Paghahatid" + +#: rein/lib/forms.py:44 rein/lib/forms.py:50 +msgid "Description" +msgstr "Paglalarawan" + +#: rein/lib/forms.py:62 +msgid "Dispute detail" +msgstr "Detalye sa pagmamatwiranan " + +#: rein/lib/forms.py:74 +msgid "Disputes" +msgstr "Pagmamatwiranan" + +#: rein/cli.py:97 +msgid "" +"Do you want to import a backup or create a new account?\n" +"\n" +msgstr "" +"Gusto mong iimport ang backup o gumawa na bagong account?\n" +"\n" + +#: rein/lib/forms.py:31 +msgid "Email / Bitmessage" +msgstr "Email / Bitmessage" + +#: rein/lib/io.py:16 +msgid "Error connecting to server." +msgstr "May mali sa pagkonekta sa server." + +#: rein/lib/forms.py:46 +msgid "Expiration (days)" +msgstr "Paglipas (araw)" + +#: rein/lib/market.py:54 +msgid "File containing signed document" +msgstr "File ng dokumento na may perma" + +#: rein/lib/order.py:18 +msgid "" +"Funds for each job in Rein are stored in two multisig addresses. One address\n" +"is for the primary payment that will go to the worker on completion. The\n" +"second address pays the mediator to be available to resolve a dispute\n" +"if necessary. The second address should be funded according to the percentage\n" +"specified by the mediator and is in addition to the primary payment. The\n" +"listing below shows available mediators and the fee they charge. You should\n" +"consider the fee as well as any reputational data you are able to find when\n" +"choosing a mediator. Your choice may affect the number and quality of bids" +msgstr "" +"Ang pondo sa bawat trabaho sa Rein ay itatago sa dalawanv multisig addresses. Ang isang address\n" +"ay para sa pangunahing bayad na mapupunta sa trabahador kapag natapos ito. Ang\n" +"pangalawang address ay pambayad sa mediator na puwedeng ma resolba sa pangangatwiran.\n" +"kung kinakailangan. Anv pangalawang ay dapat pondihan ayon sa porsyento\n" +"na ibinigay o gusto ng mediator at idagdag sa pangunahing bayad. Ang\n" +"nakalista sa baba ay mga bakanteng mediators at ang kanilang bayad na sisingilin. Dapat mong\n" +"ikonsidera ang fee pati ng ang kaniyang reputational data na mahahanap mo sa\n" +"pagpili ng mediator. Ang iyong nais ay makaka-epekto sa bilang at kalidad ng pakikipatawaran." + +#: rein/lib/forms.py:22 +msgid "Invalid address" +msgstr "" + +#: rein/lib/forms.py:27 +msgid "Invalid signature" +msgstr "Mali ang address" + +#: rein/lib/forms.py:43 +msgid "Job name" +msgstr "Pangalan ng trabaho" + +#: rein/lib/forms.py:32 +msgid "Master Bitcoin address" +msgstr "Master Bitcoin address" + +#: rein/lib/forms.py:36 +msgid "Mediator Fee" +msgstr "Singil ng Mediator" + +#: rein/lib/forms.py:30 +msgid "Name / Handle" +msgstr "Pangalan / Tagahawak" + +#: rein/lib/validate.py:168 +msgid "None found" +msgstr "Hindi makita" + +#: rein/lib/forms.py:18 +msgid "Not a valid private key." +msgstr "Hindi tama ang private key." + +#: rein/lib/toolbox.py:9 +msgid "Please enter " +msgstr "Pakiusap i-enter " + +#: rein/lib/forms.py:35 +msgid "Register as a mediator?" +msgstr "Magrehistro bilang mediator?" + +#: rein/lib/forms.py:73 +msgid "Resolution" +msgstr "Resolusyon" + +#: rein/lib/forms.py:40 +msgid "Signed enrollment" +msgstr "Permado ng pagpapalista" + +#: rein/lib/forms.py:67 rein/lib/forms.py:72 +msgid "Signed mediator payment" +msgstr "Permado ng bayad sa mediator " + +#: rein/lib/forms.py:66 rein/lib/forms.py:71 +msgid "Signed primary payment" +msgstr "Permado na paunang bayad" + +#: rein/lib/forms.py:45 +msgid "Tags" +msgstr "Mga tag" + +#: rein/lib/validate.py:14 +msgid "Verifying block times..." +msgstr "Pag beripiko ng oras ng block..." + +#: rein/cli.py:98 +msgid "Welcome to Rein." +msgstr "Maligayang Pagdating sa Rein." + +#: rein/lib/order.py:31 +msgid "bid submitted" +msgstr "Na sumite na ang tawad" + +#: rein/lib/order.py:67 +msgid "complete, dispute resolved" +msgstr "Tapos na, na resolba na ang pangagatwiran" + +#: rein/lib/order.py:61 +msgid "complete, work accepted" +msgstr "Tapos na, ang trabaho ay tinanggap" + +#: rein/lib/order.py:43 +msgid "deliverables submitted" +msgstr "na sumite na ang hatid" + +#: rein/lib/order.py:49 +msgid "disputed by job creator" +msgstr "pangagatwiran ng tagagawa ng trabaho" + +#: rein/lib/order.py:55 +msgid "disputed by worker" +msgstr "pangagatwiran ng trabahador" + +#: rein/lib/order.py:37 +msgid "job awarded" +msgstr "ang tabaho ay naibigay na" + +#: rein/lib/order.py:17 +msgid "posted" +msgstr "ipaskil" diff --git a/rein/locale/messages-HI.mo b/rein/locale/messages-HI.mo new file mode 100644 index 0000000..40f2bd4 Binary files /dev/null and b/rein/locale/messages-HI.mo differ diff --git a/rein/locale/messages-HI.po b/rein/locale/messages-HI.po new file mode 100644 index 0000000..c0057f4 --- /dev/null +++ b/rein/locale/messages-HI.po @@ -0,0 +1,289 @@ +# Rein Decentralized Freelance Market. +# Copyright (C) 2016 +# This file is distributed under the same license as the python-rein package. +# David Stery , 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: 0.2\n" +"POT-Creation-Date: 2016-12-21 11:00+PST\n" +"PO-Revision-Date: 2017-02-16 20:14+0100\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: hi_IN\n" +"X-Generator: Poedit 1.8.11\n" + +#: rein/cli.py:52 +msgid "" +"\n" +" Rein is a decentralized professional services market and Python-rein is a client\n" +"that provides a user interface. Use this program from your local browser or command \n" +"line to create an account, post a job, bid, etc.\n" +"\n" +"\b\n" +" Quick start:\n" +" $ rein start - create an identity, run the Web UI\n" +" $ rein buy - request microhosting\n" +" $ rein sync - push your identity to microhosting servers\n" +" $ rein status - get user status, or dump of job's documents\n" +"\n" +"\b\n" +" Workers\n" +" $ rein bid - view and bid on jobs\n" +" $ rein deliver - complete job by providing deliverables\n" +"\n" +"\b\n" +" Disputes\n" +" $ rein workerdispute - worker files dispute\n" +" $ rein creatordispute - job creator files dispute\n" +" $ rein resolve - mediator posts decision\n" +"\n" +" For more info and the setup guide visit: http://reinproject.org\n" +" " +msgstr "" +"\n" +" रेन एक विकेन्द्रीकृत पेशेवर सेवाओं का त्रय-विक्रय-स्थान है और Python-rein एक असामी है\n" +"जो एक उपयोगकर्ता अंतरापृष्ठ प्रदान करता है। अपने स्थानीय विचरक या आदेशसे इस क्रमादेश का उपयोग करना\n" +"एक खाता बनाने के लिए, कार्य का विज्ञापन, बोली, आदि भेजने के लिए यह पंक्ति है\n" +"\b\n" +" त्वरित प्रारंभ:\n" +" $ रेन की शुरूवात - एक पहचान बनाने, चलाने के लिए वेब यूआई\n" +" $ रेन की खरीद - सूक्ष्महोस्टिंग का अनुरोध करे\n" +" $ रेन का संकालन - सूक्ष्महोस्टिंग के सर्वर तक अपनी पहचान पहुंचाहिए\n" +" $ रेन की स्थिति - उपयोगकर्ता की स्थिति, या नौकरी के दस्तावेजों का ढेर जमा करे\n" +"\n" +"\b\n" +" श्रमिक\n" +" $ रेन बोली - देखे और कार्यों पर बोली लगाए\n" +" $ रेन पहुंचाना - प्रदेय का उपलब्ध करके पूरा काम ख़तम करना\n" +"\n" +"\b\n" +" मतभेद\n" +" $ रेन श्रमिकों का मतभेद - कार्यकर्ता फ़ाइलों विवाद\n" +" $ रेन निर्माताओं का विवाद - नौकरी के निर्माता मतभेद का दावा करता है\n" +" $ रेन का संकल्प - मध्यस्थ निर्णय को घोषित करता है\n" +"\n" +" अधिक जानकारी और स्थापित करने की सूचना के लिए: http://reinproject.org\n" +" " + +#: rein/cli.py:85 +msgid "" +"\n" +" Setup or import an identity.\n" +"\n" +" You will choose a name or handle for your account, include public contact information, \n" +" and a delegate Bitcoin address/private key that the program will use to sign documents\n" +" on your behalf. An enrollment document will be created and you will need to sign it\n" +" with your master Bitcoin private key.\n" +" " +msgstr "" +"\n" +" पहचान को स्थापित या आयत करें.\n" +"\n" +" आपको अपने खाते के लिए एक नाम या उपाधि का चयन करना होगा, जिसमे आप सार्वजनिक संपर्क जानकारी शामिल करेंगे, \n" +" और एक प्रतिनिधि बिटकॉइन की पता/गुप्त चाबी है जसिका उपयोग वो प्रोग्राम दस्तावेजों पर हस्ताक्षर करने के लिए करेगा\n" +" आपकी जगह पर। एक नामांकन दस्तावेज बनाया जाएगा और आपको इसपर हस्ताक्षर करने की आवश्यकता होगी\n" +" अपने विशेषज्ञ बिटकॉइन के गुप्त चाबी के साथ.\n" +" " + +#: rein/cli.py:98 +msgid "" +"1 - Create new account\n" +"2 - Import backup\n" +msgstr "" +"१ - एक नया खता बनाए\n" +"२ - बवैकअप का आयत करें\n" + +#: rein/lib/forms.py:51 +msgid "Bid amount" +msgstr " नीलामी राशि" + +#: rein/lib/forms.py:52 +msgid "Choose Job to bid on" +msgstr "बोली के लिए कार्य का चयन करें" + +#: rein/lib/forms.py:55 +msgid "Choose bid" +msgstr "बोली चुनें" + +#: rein/lib/forms.py:63 +msgid "Choose job" +msgstr "कार्य का चयन" + +#: rein/lib/forms.py:59 +msgid "Choose job associated with deliverables" +msgstr "प्रदेय के साथ जुड़े कार्य का चयन" + +#: rein/lib/forms.py:47 +msgid "Choose mediator" +msgstr "मध्यस्थ चुनें " + +#: rein/lib/forms.py:33 +msgid "Delegate Bitcoin address" +msgstr "बिटकॉइन के पता की नियुक्ति" + +#: rein/lib/forms.py:34 +msgid "Delegate Bitcoin private Key" +msgstr "प्बिटकॉइन गुप्त चाबी की नियुक्ति" + +#: rein/lib/forms.py:58 rein/lib/forms.py:68 +msgid "Deliverables" +msgstr "प्रदेय " + +#: rein/lib/forms.py:44 rein/lib/forms.py:50 +msgid "Description" +msgstr "विवरण" + +#: rein/lib/forms.py:62 +msgid "Dispute detail" +msgstr "मतभेद की जानकारी" + +#: rein/lib/forms.py:74 +msgid "Disputes" +msgstr "मतभेद" + +#: rein/cli.py:97 +msgid "" +"Do you want to import a backup or create a new account?\n" +"\n" +msgstr "" +"क्या आप एक बैकअप का आयात या एक नया खाता बनाना चाहते हैं?\n" +"\n" + +#: rein/lib/forms.py:31 +msgid "Email / Bitmessage" +msgstr "ईमेल/बिटकॉइन का सन्देश (Bitmessage)" + +#: rein/lib/io.py:16 +msgid "Error connecting to server." +msgstr "सर्वर से संपर्क बनाने में त्रुटि।" + +#: rein/lib/forms.py:46 +msgid "Expiration (days)" +msgstr "समय सीमा समाप्त (दिन)" + +#: rein/lib/market.py:54 +msgid "File containing signed document" +msgstr "फ़ाइल ज्सिमे हस्ताक्षर किए दस्तावेज़ युक्त है" + +#: rein/lib/order.py:18 +msgid "" +"Funds for each job in Rein are stored in two multisig addresses. One address\n" +"is for the primary payment that will go to the worker on completion. The\n" +"second address pays the mediator to be available to resolve a dispute\n" +"if necessary. The second address should be funded according to the percentage\n" +"specified by the mediator and is in addition to the primary payment. The\n" +"listing below shows available mediators and the fee they charge. You should\n" +"consider the fee as well as any reputational data you are able to find when\n" +"choosing a mediator. Your choice may affect the number and quality of bids" +msgstr "" +"\"Rein में किए गए प्रत्येक कार्य के लिए जमा की गई रकम दो एकाधिकहस्ताक्षर के पता में जमा हो जाती है। एक की पता\n" +"\"\"में प्राथमिक भुगतान है जो कि पूरा होने पर काम करनेवाले को मिलेगा।\n" +"\"दूसरी पता मध्यस्थ का भुगतान करती है ताकि वो मतभेद हल करने के लिए उपलब्ध हो सके\n" +"अगर आवश्यक है। दूसरी पता प्रतिशत के अनुसार रकम जमा किया जाना चाहिए\n" +"मध्यस्थ द्वारा निर्दिष्ट और इसके साथ में प्राथमिक भुगतान करने के लिए है।\n" +"निचे दी गयी सूची उपलब्ध मध्यस्थों और उनके शुल्क की जानकारी देता है। आपको\n" +"एक मध्यस्थ चुनें। आपकी पसंद आपके अंकों और बोलियों की गुणवत्ता को प्रभावित कर सकता है" + +#: rein/lib/forms.py:22 +msgid "Invalid address" +msgstr "अवैध पता" + +#: rein/lib/forms.py:27 +msgid "Invalid signature" +msgstr "अवैध हस्ताक्षर" + +#: rein/lib/forms.py:43 +msgid "Job name" +msgstr "कार्य का नाम" + +#: rein/lib/forms.py:32 +msgid "Master Bitcoin address" +msgstr "विशेषज्ञ बिटकॉइन का पता" + +#: rein/lib/forms.py:36 +msgid "Mediator Fee" +msgstr "मध्यस्थ का शुल्क" + +#: rein/lib/forms.py:30 +msgid "Name / Handle" +msgstr "नाम / उपाधि (Handle)" + +#: rein/lib/validate.py:168 +msgid "None found" +msgstr "कोई जानकारी नहीं मिला" + +#: rein/lib/forms.py:18 +msgid "Not a valid private key." +msgstr "एक अमान्य गुप्त चाबी।" + +#: rein/lib/toolbox.py:9 +msgid "Please enter " +msgstr "कृपया दर्ज करें " + +#: rein/lib/forms.py:35 +msgid "Register as a mediator?" +msgstr "एक मध्यस्थ के रूप में दर्ज करें?" + +#: rein/lib/forms.py:73 +msgid "Resolution" +msgstr "संकल्प" + +#: rein/lib/forms.py:40 +msgid "Signed enrollment" +msgstr "हस्ताक्षर किए गए नामांकन" + +#: rein/lib/forms.py:67 rein/lib/forms.py:72 +msgid "Signed mediator payment" +msgstr "हस्ताक्षर किए गए मध्यस्थ भुगतान" + +#: rein/lib/forms.py:66 rein/lib/forms.py:71 +msgid "Signed primary payment" +msgstr "हस्ताक्षर किए गए प्राथमिक भुगतान" + +#: rein/lib/forms.py:45 +msgid "Tags" +msgstr "टैग्स " + +#: rein/lib/validate.py:14 +msgid "Verifying block times..." +msgstr "ब्लॉक समय का सत्यापन ..." + +#: rein/cli.py:98 +msgid "Welcome to Rein." +msgstr "रेन में आपका स्वागत है|" + +#: rein/lib/order.py:31 +msgid "bid submitted" +msgstr "बोली प्रस्तुत की गई है " + +#: rein/lib/order.py:67 +msgid "complete, dispute resolved" +msgstr "पूरा करना, मतभेद सुलझाया" + +#: rein/lib/order.py:61 +msgid "complete, work accepted" +msgstr "पूरा करना, काम स्वीकार कर लिया" + +#: rein/lib/order.py:43 +msgid "deliverables submitted" +msgstr "प्रदेय प्रस्तुत की गई है" + +#: rein/lib/order.py:49 +msgid "disputed by job creator" +msgstr "काम निर्माता द्वारा मतभेद" + +#: rein/lib/order.py:55 +msgid "disputed by worker" +msgstr "काम करनेवालों द्वारा मतभेद" + +#: rein/lib/order.py:37 +msgid "job awarded" +msgstr "काम को सौंपा गया है" + +#: rein/lib/order.py:17 +msgid "posted" +msgstr "को दर्ज करना " diff --git a/rein/locale/messages-LV.mo b/rein/locale/messages-LV.mo new file mode 100644 index 0000000..3ca5374 Binary files /dev/null and b/rein/locale/messages-LV.mo differ diff --git a/rein/locale/messages-LV.po b/rein/locale/messages-LV.po new file mode 100644 index 0000000..2491361 --- /dev/null +++ b/rein/locale/messages-LV.po @@ -0,0 +1,293 @@ +# Rein Patstāvīgo darbu tirgus. +# Copyright (C) 2017 +# Šis fails ir izplatīts zem tās pašas licenses kā python-rein paka. +# David Sterry , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: 0.2\n" +"POT-Creation-Date: 2016-12-21 11:00+PST\n" +"PO-Revision-Date: 2017-02-16 19:43+0100\n" +"Last-Translator: Kaspars Lapiņš \n" +"Language-Team: Latviešu \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: lv\n" +"X-Generator: Poedit 1.8.11\n" + +#: rein/cli.py:52 +msgid "" +"\n" +" Rein is a decentralized professional services market and Python-rein is a client\n" +"that provides a user interface. Use this program from your local browser or command \n" +"line to create an account, post a job, bid, etc.\n" +"\n" +"\b\n" +" Quick start:\n" +" $ rein start - create an identity, run the Web UI\n" +" $ rein buy - request microhosting\n" +" $ rein sync - push your identity to microhosting servers\n" +" $ rein status - get user status, or dump of job's documents\n" +"\n" +"\b\n" +" Workers\n" +" $ rein bid - view and bid on jobs\n" +" $ rein deliver - complete job by providing deliverables\n" +"\n" +"\b\n" +" Disputes\n" +" $ rein workerdispute - worker files dispute\n" +" $ rein creatordispute - job creator files dispute\n" +" $ rein resolve - mediator posts decision\n" +"\n" +" For more info and the setup guide visit: http://reinproject.org\n" +" " +msgstr "" +"\n" +" Rein ir centralizēts pakalpojumu tirgus un Python-rein ir klients\n" +"kas nodrošina lietotāja interfeisu. Izmanto šo programmu no jūsu patstāvīgās " +"pārlukprogrammas \n" +"vieta kur reģistrēties, pievono darbu, liec likmes, u.c.\n" +"\n" +"\b\n" +" Ātrā palaišana:\n" +" $ rein start - izveidot identitāti, palaist tīklu UI\n" +" $ rein buy - pieprasīt microhostingu\n" +" $ rein sync - ielikt savu identitāti microhosting serveros\n" +" $ rein status - dabūt lietotāja statusus, vai kaudzi ar darba " +"doukumentiem\n" +"\n" +"\b\n" +" Darbinieki\n" +" $ rein bid - apskatīt un ievietot darbus\n" +" $ rein deliver - pabeigt darbu nodrošinot nodevas\n" +"\n" +"\b\n" +" Strīdi\n" +" $ rein workerdispute - darbinieku failu apstrīde\n" +" $ rein creatordispute - darba devēju failu apstrīde\n" +" $ rein resolve - starpnieks pasludina lēmumu\n" +"\n" +" Vairāk info šeit: http://reinproject.org\n" +" " + +#: rein/cli.py:85 +msgid "" +"\n" +" Setup or import an identity.\n" +"\n" +" You will choose a name or handle for your account, include public contact information, \n" +" and a delegate Bitcoin address/private key that the program will use to sign documents\n" +" on your behalf. An enrollment document will be created and you will need to sign it\n" +" with your master Bitcoin private key.\n" +" " +msgstr "" +"\n" +" izveidot vai ievietot identitāti.\n" +"\n" +" Jūs izvēlēsieties savu vārdu priekš jūsu profila, ievietojot publisku " +"kontaktinformāciju, \n" +" ievietojot Bitcoin adresi/privāto atslēgu ko programma izmantos " +"parakstot dokumentus\n" +" jūsu vārdā. Uzņemšanas dokuments tiks izveidots un jums tas būs " +"jāparaksta\n" +" ar jūsu Bitcoin private key/privāto atslēgu.\n" +" " + +#: rein/cli.py:98 +msgid "" +"1 - Create new account\n" +"2 - Import backup\n" +msgstr "" +"1 - Izveidot profilu\n" +"2 - atgūt dublētos datus\n" + +#: rein/lib/forms.py:51 +msgid "Bid amount" +msgstr "Pieteikties" + +#: rein/lib/forms.py:52 rein/lib/forms.py:63 +msgid "Choose Job to bid on" +msgstr "Izvēlēties darbu" + +#: rein/lib/forms.py:55 +msgid "Choose bid" +msgstr "Izvēlēties pieteikumu" + +#: rein/lib/forms.py:59 +msgid "Choose job associated with deliverables" +msgstr "Izvēlēties darbu ar nodevām" + +#: rein/lib/forms.py:47 +msgid "Choose mediator" +msgstr "Izvēlēties starpnieku" + +#: rein/lib/forms.py:33 +msgid "Delegate Bitcoin address" +msgstr "Pārskatīt BITCOIN adresi" + +#: rein/lib/forms.py:34 +msgid "Delegate Bitcoin private Key" +msgstr "Pārskatīt Bitcoin Private Key/atslēgu" + +#: rein/lib/forms.py:58 rein/lib/forms.py:68 +msgid "Deliverables" +msgstr "Nodevas" + +#: rein/lib/forms.py:44 rein/lib/forms.py:50 +msgid "Description" +msgstr "Apraksts" + +#: rein/lib/forms.py:62 +msgid "Dispute detail" +msgstr "apstrīdēt detaļas" + +#: rein/lib/forms.py:74 +msgid "Disputes" +msgstr "Strīdi" + +#: rein/cli.py:97 +msgid "" +"Do you want to import a backup or create a new account?\n" +"\n" +msgstr "" +"Vai vēlaties atgūt dublētos datus vai izveidot jaunu profilu?\n" +"\n" + +#: rein/lib/forms.py:31 +msgid "Email / Bitmessage" +msgstr "E-pasts / Bitvēstule" + +#: rein/lib/io.py:16 +msgid "Error connecting to server." +msgstr "Kļuda piekļūšanai serverim." + +#: rein/lib/forms.py:46 +msgid "Expiration (days)" +msgstr "Atlikušās dienas" + +#: rein/lib/market.py:54 +msgid "File containing signed document" +msgstr "Failā ietilpst parakstīts dokuments" + +#: rein/lib/order.py:18 +msgid "" +"Funds for each job in Rein are stored in two multisig addresses. One address\n" +"is for the primary payment that will go to the worker on completion. The\n" +"second address pays the mediator to be available to resolve a dispute\n" +"if necessary. The second address should be funded according to the percentage\n" +"specified by the mediator and is in addition to the primary payment. The\n" +"listing below shows available mediators and the fee they charge. You should\n" +"consider the fee as well as any reputational data you are able to find when\n" +"choosing a mediator. Your choice may affect the number and quality of bids" +msgstr "" +"Uzkrājumi darbā Rein ir saglabāti divās adresēs. Viena adrese\n" +"ir priekš primārās samaksas darbiniekam par pabeigtu darbu.\n" +"Otrā adrese ir priekš starpnieka, lai varētu atrisināt strīdus\n" +"ja vajadzīgs. Otrā adrese tiks uzkrāta ņemot vērā attiecīgos procentus\n" +",to noteiks starpnieks arī ņemot vērā primāro samaksu. The\n" +"Saraksts lejā norāda brīvos starpniekus un to procentus ko viņi pieprasa. " +"Jums vajadzētu\n" +"apsvērt samaksu starpniekam kā reputācijas datu kad\n" +"izvēlēsieties starpnieku. Jūsu izvēle nosaka skaitu un kvalitāti pieteikumiem" + +#: rein/lib/forms.py:22 +msgid "Invalid address" +msgstr "Nederīga adrese" + +#: rein/lib/forms.py:27 +msgid "Invalid signature" +msgstr "Nederīgs paraksts" + +#: rein/lib/forms.py:43 +msgid "Job name" +msgstr "Darba nosaukums" + +#: rein/lib/forms.py:32 +msgid "Master Bitcoin address" +msgstr "Bitcoin adrese" + +#: rein/lib/forms.py:36 +msgid "Mediator Fee" +msgstr "Starnieka samaksa" + +#: rein/lib/forms.py:30 +msgid "Name / Handle" +msgstr "Vārds" + +#: rein/lib/validate.py:168 +msgid "None found" +msgstr "Netika atrasts" + +#: rein/lib/forms.py:18 +msgid "Not a valid private key." +msgstr "nederīga privātā atslēga." + +#: rein/lib/toolbox.py:9 +msgid "Please enter " +msgstr "Lūdzu ievadiet " + +#: rein/lib/forms.py:35 +msgid "Register as a mediator?" +msgstr "Reģistrēties kā starpniekam?" + +#: rein/lib/forms.py:73 +msgid "Resolution" +msgstr "Rezolūcija" + +#: rein/lib/forms.py:40 +msgid "Signed enrollment" +msgstr "Parakstīta uzņemšana" + +#: rein/lib/forms.py:67 rein/lib/forms.py:72 +msgid "Signed mediator payment" +msgstr "Parakstīta starpnieka samaksa" + +#: rein/lib/forms.py:66 rein/lib/forms.py:71 +msgid "Signed primary payment" +msgstr "Parakstīta primārā samaksa" + +#: rein/lib/forms.py:45 +msgid "Tags" +msgstr "Etiķetes" + +#: rein/lib/validate.py:14 +msgid "Verifying block times..." +msgstr "Pārbauda bloku laiku..." + +#: rein/cli.py:98 +msgid "Welcome to Rein." +msgstr "Sveicināti Rein." + +#: rein/lib/order.py:31 +msgid "bid submitted" +msgstr "pieteikums apstiprināts" + +#: rein/lib/order.py:67 +msgid "complete, dispute resolved" +msgstr "Pabeigts, strīds atrisināts" + +#: rein/lib/order.py:61 +msgid "complete, work accepted" +msgstr "Pabeigts, darbs apstiprināts" + +#: rein/lib/order.py:43 +msgid "deliverables submitted" +msgstr "nodevas pieņemtas" + +#: rein/lib/order.py:49 +msgid "disputed by job creator" +msgstr "apstrīdēts no darba devēja" + +#: rein/lib/order.py:55 +msgid "disputed by worker" +msgstr "apstrīdēts no darbinieka" + +#: rein/lib/order.py:37 +msgid "job awarded" +msgstr "Darbs piešķirts" + +#: rein/lib/order.py:17 +msgid "posted" +msgstr "Publicēts" diff --git a/rein/locale/messages-RU.mo b/rein/locale/messages-RU.mo new file mode 100644 index 0000000..6bc89ee Binary files /dev/null and b/rein/locale/messages-RU.mo differ diff --git a/rein/locale/messages-RU.po b/rein/locale/messages-RU.po new file mode 100644 index 0000000..76a8166 --- /dev/null +++ b/rein/locale/messages-RU.po @@ -0,0 +1,290 @@ +# Rein Decentralized Freelance Market. +# Copyright (C) 2017 +# This file is distributed under the same license as the python-rein package. +# David Sterry , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: 0.2\n" +"POT-Creation-Date: 2016-12-21 11:00+PST\n" +"PO-Revision-Date: 2017-02-16 19:44+0100\n" +"Language-Team: RUSSIAN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: \n" +"Language: ru\n" +"X-Generator: Poedit 1.8.11\n" + +#: rein/cli.py:52 +msgid "" +"\n" +" Rein is a decentralized professional services market and Python-rein is a client\n" +"that provides a user interface. Use this program from your local browser or command \n" +"line to create an account, post a job, bid, etc.\n" +"\n" +"\b\n" +" Quick start:\n" +" $ rein start - create an identity, run the Web UI\n" +" $ rein buy - request microhosting\n" +" $ rein sync - push your identity to microhosting servers\n" +" $ rein status - get user status, or dump of job's documents\n" +"\n" +"\b\n" +" Workers\n" +" $ rein bid - view and bid on jobs\n" +" $ rein deliver - complete job by providing deliverables\n" +"\n" +"\b\n" +" Disputes\n" +" $ rein workerdispute - worker files dispute\n" +" $ rein creatordispute - job creator files dispute\n" +" $ rein resolve - mediator posts decision\n" +"\n" +" For more info and the setup guide visit: http://reinproject.org\n" +" " +msgstr "" +"\n" +" Rein это децентрализованный рынок профессиональных услуг и Python-rein это клиент\n" +"который предоставляет интерфейс пользователя. Используйте эту программу из вашего локального браузера \n" +"или коммандной строки что бы создать аккаунт, опубликовать работу, сделать ставку и т.д.\n" +"\n" +"\b\n" +" Быстрый старт:\n" +" $ rein start - создать идентификатор, запустить Web UI\n" +" $ rein buy - запросить микрохостинг\n" +" $ rein sync - синхронизировать идентификатор с серверами микрохостинга\n" +" $ rein status - узнать статус пользоваля, сбросить рабочие документы\n" +"\n" +"\b\n" +" Исполнители\n" +" $ rein bid - показать проекты и сделать ставку\n" +" $ rein deliver - окончить работу предоставив результат\n" +"\n" +"\b\n" +" Споры\n" +" $ rein workerdispute - оспорить рабочие файлы работника\n" +" $ rein creatordispute - оспорить рабочие файлы работодателя\n" +" $ rein resolve - публичное решение медиатора\n" +"\n" +" Для подробной информации и инструкции установки посетите ресурс: http://reinproject.org\n" +" " + +#: rein/cli.py:85 +msgid "" +"\n" +" Setup or import an identity.\n" +"\n" +" You will choose a name or handle for your account, include public contact information, \n" +" and a delegate Bitcoin address/private key that the program will use to sign documents\n" +" on your behalf. An enrollment document will be created and you will need to sign it\n" +" with your master Bitcoin private key.\n" +" " +msgstr "" +"\n" +" Установите или импортируйте идентификатор.\n" +"\n" +" Вы выберете имя для вашего аккаунта, включая публичную контактную информацию, \n" +" и Bitcoin адрес/приватный ключ, которые программа будет использовать для подписи документов\n" +" от вашего имени. Зарегистрированный документ будет создан и вы должны будете подписать это\n" +" вашим приватным Bitcoin ключем.\n" +" " + +#: rein/cli.py:98 +msgid "" +"1 - Create new account\n" +"2 - Import backup\n" +msgstr "" +"1 - Создать новый аккаунт\n" +"2 - Импортировать бэкап\n" + +#: rein/lib/forms.py:51 +msgid "Bid amount" +msgstr "Сделать ставку" + +#: rein/lib/forms.py:52 +msgid "Choose Job to bid on" +msgstr "Выбрать проект для ставки" + +#: rein/lib/forms.py:55 +msgid "Choose bid" +msgstr "Выбрать ставку" + +#: rein/lib/forms.py:63 +msgid "Choose job" +msgstr "Выбрать работу" + +#: rein/lib/forms.py:59 +msgid "Choose job associated with deliverables" +msgstr "Выбрать работу ассоциированную с результатом" + +#: rein/lib/forms.py:47 +msgid "Choose mediator" +msgstr "Выбрать медиатора" + +#: rein/lib/forms.py:33 +msgid "Delegate Bitcoin address" +msgstr "Выбрать Bitcoin адрес" + +#: rein/lib/forms.py:34 +msgid "Delegate Bitcoin private Key" +msgstr "Выбрать приватный ключ Bitcoin" + +#: rein/lib/forms.py:58 rein/lib/forms.py:68 +msgid "Deliverables" +msgstr "Результат" + +#: rein/lib/forms.py:44 rein/lib/forms.py:50 +msgid "Description" +msgstr "Описание" + +#: rein/lib/forms.py:62 +msgid "Dispute detail" +msgstr "Оспорить деталь" + +#: rein/lib/forms.py:74 +msgid "Disputes" +msgstr "Споры" + +#: rein/cli.py:97 +msgid "" +"Do you want to import a backup or create a new account?\n" +"\n" +msgstr "" +"Вы хотите имортировать бэкап или создать новый аккаунт?\n" +"\n" + +#: rein/lib/forms.py:31 +msgid "Email / Bitmessage" +msgstr "Email / Bitmessage" + +#: rein/lib/io.py:16 +msgid "Error connecting to server." +msgstr "Ошибка подключения к серверу." + +#: rein/lib/forms.py:46 +msgid "Expiration (days)" +msgstr "Истекает (дней)" + +#: rein/lib/market.py:54 +msgid "File containing signed document" +msgstr "Файл содержит подписанный документ" + +#: rein/lib/order.py:18 +msgid "" +"Funds for each job in Rein are stored in two multisig addresses. One address\n" +"is for the primary payment that will go to the worker on completion. The\n" +"second address pays the mediator to be available to resolve a dispute\n" +"if necessary. The second address should be funded according to the percentage\n" +"specified by the mediator and is in addition to the primary payment. The\n" +"listing below shows available mediators and the fee they charge. You should\n" +"consider the fee as well as any reputational data you are able to find when\n" +"choosing a mediator. Your choice may affect the number and quality of bids" +msgstr "" +"Средства для каждой работы в реин хранятся в двух мультиподписанных адресах. Один адрес\n" +"для личного платежа который будет отправлен работнику по окончании проекта. \n" +"Второй для медиатора, на случай разрешения спора при необходимости. Второй адрес должен быть пополнен опираясь на процент\n" +"указанный медиатором и быть в дополнении к личному платежу. \n" +"Список ниже показывает доступных медиаторов и комиссии, которые они требуют. \n" +"Вы должны учитывать комиссию так же, как и любую другую репутационную информацию, которую вы можете найти,\n" +"когда выбираете медиатора. Ваш выбор может повлиять на количество и качество ставок." + +#: rein/lib/forms.py:22 +msgid "Invalid address" +msgstr "Неправильный адрес" + +#: rein/lib/forms.py:27 +msgid "Invalid signature" +msgstr "Неправильная подпись" + +#: rein/lib/forms.py:43 +msgid "Job name" +msgstr "Имя работы" + +#: rein/lib/forms.py:32 +msgid "Master Bitcoin address" +msgstr "Адрес Bitcoin" + +#: rein/lib/forms.py:36 +msgid "Mediator Fee" +msgstr "Комиссия медиатора" + +#: rein/lib/forms.py:30 +msgid "Name / Handle" +msgstr "Имя / Держатель" + +#: rein/lib/validate.py:168 +msgid "None found" +msgstr "Ничего не найдено" + +#: rein/lib/forms.py:18 +msgid "Not a valid private key." +msgstr "Не правильный приватный ключ." + +#: rein/lib/toolbox.py:9 +msgid "Please enter " +msgstr "Пожалуйста введите " + +#: rein/lib/forms.py:35 +msgid "Register as a mediator?" +msgstr "Зарегистрировать как медиатор?" + +#: rein/lib/forms.py:73 +msgid "Resolution" +msgstr "Решение" + +#: rein/lib/forms.py:40 +msgid "Signed enrollment" +msgstr "Подписанное зачисление" + +#: rein/lib/forms.py:67 rein/lib/forms.py:72 +msgid "Signed mediator payment" +msgstr "Подписанный платеж медиатора" + +#: rein/lib/forms.py:66 rein/lib/forms.py:71 +msgid "Signed primary payment" +msgstr "Подписанный частный платеж" + +#: rein/lib/forms.py:45 +msgid "Tags" +msgstr "Тэги" + +#: rein/lib/validate.py:14 +msgid "Verifying block times..." +msgstr "Верификация блока раз..." + +#: rein/cli.py:98 +msgid "Welcome to Rein." +msgstr "Добро пожаловать в Rein." + +#: rein/lib/order.py:31 +msgid "bid submitted" +msgstr "ставка принята" + +#: rein/lib/order.py:67 +msgid "complete, dispute resolved" +msgstr "окончено, спор окончен" + +#: rein/lib/order.py:61 +msgid "complete, work accepted" +msgstr "окончено, работа принята" + +#: rein/lib/order.py:43 +msgid "deliverables submitted" +msgstr "результаты отправлены" + +#: rein/lib/order.py:49 +msgid "disputed by job creator" +msgstr "оспорено работодателем" + +#: rein/lib/order.py:55 +msgid "disputed by worker" +msgstr "оспорено исполнителем" + +#: rein/lib/order.py:37 +msgid "job awarded" +msgstr "выбран исполнитель" + +#: rein/lib/order.py:17 +msgid "posted" +msgstr "опубликовано" diff --git a/requirements.txt b/requirements.txt index 9105e47..aa713ba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,18 +1,20 @@ +appdirs==1.4.0 bip32utils==0.3.post3 -click==6.2 +click==6.7 ecdsa==0.13 Flask==0.12 -Flask-WTF==0.14 +Flask-WTF==0.14.2 itsdangerous==0.24 -Jinja2==2.9.3 +Jinja2==2.9.5 MarkupSafe==0.23 +nose==1.3.7 +packaging==16.8 pbkdf2==1.3 -PySocks==1.6.5 -python-bitcoinlib==0.5.0 -python-dateutil==2.4.2 -requests==2.10.0 +pyparsing==2.1.10 +PySocks==1.6.6 +python-bitcoinlib==0.7.0 +requests==2.13.0 six==1.10.0 -unittest2 -SQLAlchemy==1.0.11 +SQLAlchemy==1.1.5 Werkzeug==0.11.15 WTForms==2.1 diff --git a/tests/lib/test_bitcoinaddress.py b/tests/lib/test_bitcoinaddress.py new file mode 100644 index 0000000..1aa43b7 --- /dev/null +++ b/tests/lib/test_bitcoinaddress.py @@ -0,0 +1,12 @@ +import unittest + +from rein.lib.bitcoinaddress import check_bitcoin_address, generate_sin + +class TestBitcoinAddress(unittest.TestCase): + def test_check_bitcoin_address(self): + self.assertTrue(check_bitcoin_address('1CptxARjqcfkVwGFSjR82zmPT8YtRMubub')) + self.assertTrue(check_bitcoin_address('3746f7fjJ6fG1pQXDjA8xy9WAzf4968WWv')) + self.assertFalse(check_bitcoin_address('2746f7fjJ6fG1pQXDjA8xy9WAzf4968WWv')) + + def test_sin_generation(self): + self.assertEqual(generate_sin('02F840A04114081690223B7069071A70D6DABB891763B638CC20C7EC3BD58E6C86'), 'TfG4ScDgysrSpodWD4Re5UtXmcLbY5CiUHA') \ No newline at end of file diff --git a/tests/lib/test_script.py b/tests/lib/test_script.py new file mode 100644 index 0000000..e3200a6 --- /dev/null +++ b/tests/lib/test_script.py @@ -0,0 +1,42 @@ +import unittest + +from rein.lib.script import parse_script, check_2_of_3, check_mandatory_multisig, build_2_of_3, build_mandatory_multisig + +class TestScript(unittest.TestCase): + def test_2_of_3(self): + # primary payment 2-of-3 redeem script + p = parse_script('5221029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb0052102f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c4651921026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc53ae') + self.assertTrue(check_2_of_3(p, ['029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', + '02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', + '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) + # switch key order + self.assertTrue(check_2_of_3(p, ['02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', + '029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', + '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) + + def test_mandatory_multisig(self): + # mandatory multisig for mediator + + m = parse_script('2102f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519ad5121029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb00521026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc52ae') + self.assertTrue(check_mandatory_multisig(m, '02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', + ['029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', + '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) + # switch non-mandatory key order + self.assertTrue(check_mandatory_multisig(m, '02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', + ['029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', + '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) + # mix up mandatory and non-mandatory keys + self.assertFalse(check_mandatory_multisig(m, '029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', + ['02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', + '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])) + + def test_build_redeem_scripts(self): + self.assertEquals(build_2_of_3(['02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', + '029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', + '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])[0], + '522102f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c4651921029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb00521026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc53ae') + + self.assertEquals(build_mandatory_multisig('02f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519', + ['029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb005', + '026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc'])[0], + '2102f719f009fb8eb20ccdbfda7d38f378ed2f103ac0a6768df830740c6835c46519ad5121029fcafbe2dced6fe79865b265ea90387c5411658ca11449999d5020a9f67bb00521026bc363139ebc1cad8e6eee402507d2b4874f5450585f1e6a1cd30a63ecdfc9dc52ae') \ No newline at end of file