1 #! /usr/bin/env python3
4 # dcsend - Upload tokens to the Dogeparty blockchain.
5 # Copyright (C) 2014 Rob Myers rob@robmyers.org
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 from optparse import OptionParser
22 from retrying import retry
24 import dogecode.network, dogecode.translation
26 # Send poll wait time in seconds
30 class Uploader(object):
31 """A class to manage the uploading of a program to an addess"""
33 #TODO: Allow restarting upload
34 #TODO: Allow uploading to queue
35 #TODO: When waiting for send to synch, check if sent and received
36 # token list is same length but has different contents,
39 def __init__(self, api, from_account, to_account, csvfile, fee=0):
40 """Record the information needed to perform the upload"""
42 self.from_account = from_account
43 self.to_account = to_account
44 self.reader = csv.reader(csvfile)
46 self.sent_tokens = dogecode.translation.TokenList()
48 def current_receiving_account_token_list(self):
49 """Get the current state of tokens sent to the account"""
50 json = self.api.token_transactions_for_address(self.to_account)
51 token_list = dogecode.translation.TokenList()
52 token_list.from_json(json)
55 def received_tokens_match_sent_tokens(self):
56 """Check whether the tokens on the receiving account match the sent tokens"""
57 receiving_tokens = self.current_receiving_account_token_list()
58 return self.sent_tokens.equals(receiving_tokens)
60 def wait_for_account_state_to_match_sent_tokens(self):
61 """Poll Dogepartyd until the tokens on the receiving account match the sent tokens"""
62 sys.stderr.write("Waiting for token state to synch")
65 while not self.received_tokens_match_sent_tokens():
68 time.sleep(POLL_WAIT_TIME)
70 if try_count > POLL_MAX_WAITS:
71 print("Too many failures.", file=sys.stderr)
73 print("", file=sys.stderr)
75 def send_row(self, row):
76 """Send the token run described by the row"""
78 result = self.api.send_token(self.from_account, self.to_account, token, amount, self.fee)
80 raise Exception("Error calling the api.")
81 self.sent_tokens.append(token, amount)
84 """Send all the tokens, waiting for each send to be included in
86 for row in self.reader:
87 self.wait_for_account_state_to_match_sent_tokens()
88 print("Send {}: {}".format(self.reader.line_num, ",".join(row)), file=sys.stderr)
92 usage = "usage: %prog [options] from_account to_account csv_filename"
93 parser = OptionParser(usage=usage)
94 parser.add_option("-f", "--fee", dest="fee", default="0",
95 help="the fee for each send")
96 parser.add_option("-r", "--rpc-host", dest="host", default="localhost",
97 help="the Dogeparty json-rpc host, probably localhost")
98 parser.add_option("-p", "--rpc-port", dest="port", default="5000",
99 help="the Dogeparty json-rpc port")
100 parser.add_option("-u", "--rpc-user", dest="user", default="rpc",
101 help="the Dogeparty json-rpc username")
102 parser.add_option("-w", "--rpc-password", dest="password", default=None,
103 help="the Dogeparty json-rpc password")
104 opts, args = parser.parse_args()
106 parser.error("must supply from_account to_account csv_filename")
110 (opts, args) = getopts()
111 #TODO: make sure address is valid
113 password = opts.password
115 print("Enter Dogeparty json-rpc password:", file=sys.stderr)
116 password = sys.stdin.readline()
120 from_account = args[0]
122 csv_filename = args[2]
123 print("Sending lots of tokens from {} to {}.".format(from_account,
126 print("Make sure you really want to do this.", file=sys.stderr)
127 api = dogecode.network.DogepartyApi(user, password, host, port)
128 #TODO: Check the sending account has sufficient tokens and fees
129 #TODO: Chech the receiving account has no tokens (or a flag is set)
130 with open(csv_filename, 'r') as csvfile:
131 uploader = Uploader(api, from_account, to_account, csvfile, fee)
134 if __name__ == "__main__":