Select Git revision
-
Pascal Engélibert authoredPascal Engélibert authored
utils.py 4.46 KiB
#!/usr/bin/env python3
"""
This file is part of ĞMixer-py.
ĞMixer-py is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ĞMixer-py is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with ĞMixer-py. If not, see <https://www.gnu.org/licenses/>.
"""
import sys, os, re, socket, time
import socks
from duniterpy.key import SigningKey, PublicKey
_argv = sys.argv # silkaj reads sys.argv!
sys.argv = []
import silkaj.money, silkaj.tx, silkaj.auth
sys.argv = _argv
#-------- DATA
# Decode binary int (Big Endian)
def bin_to_int(b):
return sum([b[i]*256**i for i in range(len(b))])
# Encode int into bin (Big Endian)
# n: number ; b: bytes
def int_to_bin(n, b=4):
return bytes([(n>>(i*8))&255 for i in range(b)])
# Set fixed length 44
def normalize_pubkey(pubkey):
return pubkey + " "*(44-len(pubkey))
# Set original length (43 or 44)
def clean_pubkey(pubkey):
return pubkey.replace(" ", "")
#-------- NETWORK
RECBUF = 1024
p_clen = re.compile("\r?\ncontent-length: *(\d+)\r?\n?", re.IGNORECASE)
def sdata(host, mode, url="/", data=b"", uagent="GMixer-py", proxy=None, proxy_onion_only=False):
tsocket = socket.socket
if proxy and (not proxy_onion_only or re.match("^.+\.onion$", host[0])):
socks.set_default_proxy(socks.PROXY_TYPE_SOCKS5, proxy[0], proxy[1])
tsocket = socks.socksocket
if ":" in host[0]: # IPv6
sock = tsocket(socket.AF_INET6, socket.SOCK_STREAM)
else: # IPv4
sock = tsocket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(host)
raw = (mode+" "+url+" HTTP/1.1\r\nHost: "+host[0]+":"+str(host[1])+"\r\nUser-Agent: "+uagent+"\r\nAccept: */*\r\nContent-Length: "+str(len(data))+"\r\n\r\n").encode()+data
sock.sendall(raw)
paquet = b""
header = b""
content = b""
content_len = 0
resp = {}
lf = 0
while True:
raw = sock.recv(RECBUF)
if raw:
paquet += raw
if lf >= 0:
for c in raw:
if c == 10:# LF
lf += 1
elif c != 13:# CR
lf = 0
if lf > 1:
parts = paquet.split(b"\r\n\r\n")
header = parts[0]
content = parts[1]
try:
content_len = int(p_clen.search(header.decode()).group(1))
except AttributeError:
content_len = 0
break
if lf > 1:
break
else:
break
while len(content) < content_len:
raw = sock.recv(RECBUF)
paquet += raw
content += raw
return header, content
#-------- CONSOLE
LOG_INFO = 1
LOG_TRACE = 2
LOG_WARN = 3
LOG_ERROR = 4
LOGMSG_TYPES = {LOG_INFO:"\033[96minfo\033[0m", LOG_TRACE:"\033[39mtrace\033[0m", LOG_WARN:"\033[93mwarn\033[0m", LOG_ERROR:"\033[91merror\033[0m"}
def logPrint(msg, msgtype):
print(time.strftime("%Y-%m-%d %H:%M:%S")+" ["+LOGMSG_TYPES[msgtype]+"] "+msg)
def getargv(arg, default="", n=1, args=sys.argv):
if arg in args and len(args) > args.index(arg)+n:
return args[args.index(arg)+n]
else:
return default
#-------- ĞMixer
class Peer:
def __init__(self, pubkey, host, port, up):
self.pubkey = pubkey
self.host = host
self.port = int(port)
self.up = up
self.keys = PublicKey(pubkey)
def __str__(self):
return self.pubkey[:8] + "@" + self.host + ":" + str(self.port)
def export_str(self):
return self.pubkey + " " + self.host + " " + str(self.port)
# Read peers list
def readPeers(dir):
if not os.path.isfile(dir+"/peers"):
open(dir+"/peers", "w").close()
peers = []
peers_index = {}
peersfile = open(dir+"/peers", "r")
while True:
line = peersfile.readline()
if len(line) <= 1:
break
else:
cols = line.replace("\n", "").split(" ")
peer = Peer(cols[0], cols[1], cols[2], None)
peers.append(peer)
peers_index[peer.pubkey] = peer
peersfile.close()
return peers, peers_index
# Save peers list
def writePeers(dir, peers):
peersfile = open(dir+"/peers", "w")
for peer in peers:
peersfile.write(peer.export_str()+"\n")
peersfile.close()
def sendTransaction(sender_keys, receiver_pubkey, amount, comment):
sender_amount = silkaj.money.get_amount_from_pubkey(sender_keys.pubkey)[0]
assert sender_amount >= amount
silkaj.tx.generate_and_send_transaction(sender_keys.hex_seed().decode(), sender_keys.pubkey, amount, [receiver_pubkey], comment)