dejsem.1.5/python/dejsem.pycharm/client.py
author hh
Wed, 27 Nov 2019 09:50:16 +0100
changeset 0 676905a3b03c
permissions -rw-r--r--
--
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
hh
parents:
diff changeset
     1
# coding=utf8
hh
parents:
diff changeset
     2
hh
parents:
diff changeset
     3
import socket, os, sys, time, signal, subprocess
hh
parents:
diff changeset
     4
from d import D
hh
parents:
diff changeset
     5
from parms import Parms
hh
parents:
diff changeset
     6
from node import Node
hh
parents:
diff changeset
     7
from counter import Counter
hh
parents:
diff changeset
     8
hh
parents:
diff changeset
     9
# síťové operace klienta
hh
parents:
diff changeset
    10
#	- connect to remote server na base_port+CCx
hh
parents:
diff changeset
    11
#	- connect to remote peer na host:port, které dostane ze serveru na base_port+CC0 operací GETPEER
hh
parents:
diff changeset
    12
#	- listen for peer on base_port+CCx - konkrétní host:port zveřejňuje peer na serveru na base_port+CC0 operací SETPEER
hh
parents:
diff changeset
    13
#		- formalizace čísla portu je ovšem nutná jen když oba peers běží na tomtéž stroji
hh
parents:
diff changeset
    14
hh
parents:
diff changeset
    15
class Client():
hh
parents:
diff changeset
    16
hh
parents:
diff changeset
    17
	def __init__(self, d):
hh
parents:
diff changeset
    18
hh
parents:
diff changeset
    19
		self.d = D("client".format(d.debid))
hh
parents:
diff changeset
    20
hh
parents:
diff changeset
    21
		Parms.clientMode = True
hh
parents:
diff changeset
    22
hh
parents:
diff changeset
    23
		self._orig = Parms.orig		# origin data paths
hh
parents:
diff changeset
    24
		self._dest = Parms.dest		# destination data path
hh
parents:
diff changeset
    25
hh
parents:
diff changeset
    26
		self._chan = Parms.sslchannel
hh
parents:
diff changeset
    27
hh
parents:
diff changeset
    28
		if self.d.ll(1): self.d.log("pgm={}, homedir={}, action={}, channel={}, debug={}"
hh
parents:
diff changeset
    29
									.format(sys.argv[0], Parms.client_homedir, Parms.action, self._chan, Parms.debugLevel))
hh
parents:
diff changeset
    30
		if self.d.ll(3): self.d.log("CE path: {}, CA path: {}".format(Parms.sslCert, Parms.sslCAPath))
hh
parents:
diff changeset
    31
hh
parents:
diff changeset
    32
		act = Parms.action
hh
parents:
diff changeset
    33
		if	 not act:
hh
parents:
diff changeset
    34
			return
hh
parents:
diff changeset
    35
		elif act == "PUSHCLIP":     # from cliboard to remote server
hh
parents:
diff changeset
    36
			self.pushclip("clipboard")
hh
parents:
diff changeset
    37
		elif act == "PUSHPRIM":     # from X primary to remote server
hh
parents:
diff changeset
    38
			self.pushclip("primary")
hh
parents:
diff changeset
    39
		elif act == "PUSHFILE":     # from local files to remote server
hh
parents:
diff changeset
    40
			self.pushfile()
hh
parents:
diff changeset
    41
		elif act == "PUSHPEER":     # from local files to remote peer
hh
parents:
diff changeset
    42
			self.pushpeer()
hh
parents:
diff changeset
    43
		elif act == 'PULLCLIP':     # from remote server to cliboard
hh
parents:
diff changeset
    44
			self.pullclip()
hh
parents:
diff changeset
    45
		elif act == 'PULLHIST':     # synchronize local clipboard history from server
hh
parents:
diff changeset
    46
			self.pullhist()
hh
parents:
diff changeset
    47
		elif act == 'PULLFILE':     # from remote server files to local
hh
parents:
diff changeset
    48
			self.pullfile()
hh
parents:
diff changeset
    49
		elif act == 'PULLLIST':     # filelist of server dir
hh
parents:
diff changeset
    50
			self.pulllist()
hh
parents:
diff changeset
    51
		elif act == "PULLPEER":     # from remote peer to local
hh
parents:
diff changeset
    52
			self.pullpeer()
hh
parents:
diff changeset
    53
		elif act == "SRVHACK":
hh
parents:
diff changeset
    54
			self.srv_hack()
hh
parents:
diff changeset
    55
		elif act == "HACK":
hh
parents:
diff changeset
    56
			self.hack()
hh
parents:
diff changeset
    57
		else:
hh
parents:
diff changeset
    58
			self.d.log("ABEND, unknown command {}".format(act))
hh
parents:
diff changeset
    59
		if hasattr(self, "_node"):
hh
parents:
diff changeset
    60
			self._node.close_sc()
hh
parents:
diff changeset
    61
			self._node.close_ssc()
hh
parents:
diff changeset
    62
hh
parents:
diff changeset
    63
	def pushclip(self, buffer):
hh
parents:
diff changeset
    64
		p = subprocess.Popen(["xclip", "-o", "-selection", buffer], stdout=subprocess.PIPE)
hh
parents:
diff changeset
    65
		if not p.stdout.read().lstrip():    	# nejdřív ověřit, že na clipboardu něco visí
hh
parents:
diff changeset
    66
			self.d.abend("{} buf is empty".format(buffer), None)
hh
parents:
diff changeset
    67
		self._node = Node(self.d, conn=True)    # establish server cmd session
hh
parents:
diff changeset
    68
		self._node.putcmd("PUSHCLIP")
hh
parents:
diff changeset
    69
		if self.d.ll(3): self.d.log("push clipboard starting...")
hh
parents:
diff changeset
    70
		p = subprocess.Popen(["xclip", "-o", "-selection", buffer], stdout=subprocess.PIPE)
hh
parents:
diff changeset
    71
		self._node.put(p.stdout.read())
hh
parents:
diff changeset
    72
		p.wait()
hh
parents:
diff changeset
    73
		if self.d.ll(2): self.d.log("push clipboard end")
hh
parents:
diff changeset
    74
hh
parents:
diff changeset
    75
	def longtask(self):
hh
parents:
diff changeset
    76
		# příkaz serveru k otevření paralelního portu pro dlouhý přenos
hh
parents:
diff changeset
    77
		# dostanu číslo portu, uvolním příkazový port a otevřu conn na nový port
hh
parents:
diff changeset
    78
		self._node.putcmd("LONGTASK")
hh
parents:
diff changeset
    79
		port = self._node.getnum()
hh
parents:
diff changeset
    80
		if port == 0:
hh
parents:
diff changeset
    81
			self.d.abend("all server net ports are busy", None)
hh
parents:
diff changeset
    82
		self._node.close()     # free server base port 0
hh
parents:
diff changeset
    83
		self._node = Node(self.d, port=port)
hh
parents:
diff changeset
    84
hh
parents:
diff changeset
    85
	def pushfile(self):
hh
parents:
diff changeset
    86
		if not self._orig:
hh
parents:
diff changeset
    87
			self.d.abendMsg("nothing specified")
hh
parents:
diff changeset
    88
		else:
hh
parents:
diff changeset
    89
			if not self._dest and len(self._orig) > 1:  # je-li na vstupu více jmen, tak poslední je destdir
hh
parents:
diff changeset
    90
				self._dest = os.path.normpath(self._orig[-1])
hh
parents:
diff changeset
    91
				if self._dest.startswith('/'): self._dest = self._dest[1:]  # výstup jenom relativně
hh
parents:
diff changeset
    92
				del self._orig[-1]
hh
parents:
diff changeset
    93
			if not any(os.path.exists(p) for p in self._orig):
hh
parents:
diff changeset
    94
				self.d.abendMsg("{} not found".format(self._orig))
hh
parents:
diff changeset
    95
			else:
hh
parents:
diff changeset
    96
				self._node = Node(self.d, conn=True)
hh
parents:
diff changeset
    97
				self.longtask()     # přechod na datový port
hh
parents:
diff changeset
    98
				self._counter = Counter(self.d, self.batchSize())    # start transfer progress display
hh
parents:
diff changeset
    99
				self._node.putcmd("PUSHFILE")
hh
parents:
diff changeset
   100
				for fp in self._orig:
hh
parents:
diff changeset
   101
					if self.d.ll(3): self.d.log("pushfile '{}' --> '{}' starting...".format(fp, self._dest))
hh
parents:
diff changeset
   102
					if os.path.exists(fp):
hh
parents:
diff changeset
   103
						normfp = os.path.normpath(fp)
hh
parents:
diff changeset
   104
						self.pushfile_recurse(normfp, os.path.dirname(normfp))
hh
parents:
diff changeset
   105
					else:
hh
parents:
diff changeset
   106
						self.d.warn("pushfile: {} not found".format(fp))
hh
parents:
diff changeset
   107
				self._counter.stop()
hh
parents:
diff changeset
   108
				self.d.log("pushfile end", sev=2)
hh
parents:
diff changeset
   109
hh
parents:
diff changeset
   110
	def pushfile_recurse(self, fp, prefix):
hh
parents:
diff changeset
   111
		if self.d.ll(4): self.d.log("fp={}, relative fp={}".format(fp, os.path.relpath(fp, prefix)))
hh
parents:
diff changeset
   112
		dest = os.path.join(self._dest, os.path.relpath(fp, prefix))
hh
parents:
diff changeset
   113
		if os.path.isdir(fp):
hh
parents:
diff changeset
   114
			for cwd, void, entries in os.walk(fp, topdown=True):
hh
parents:
diff changeset
   115
				for entry in entries:
hh
parents:
diff changeset
   116
					if self.d.ll(4): self.d.log("cwd={}, entry={}".format(cwd, entry))
hh
parents:
diff changeset
   117
					self.pushfile_recurse(os.path.join(cwd, entry), prefix)
hh
parents:
diff changeset
   118
				self._node.putfileinfo(cwd, os.path.join(self._dest, os.path.relpath(cwd, prefix)))
hh
parents:
diff changeset
   119
			self._node.putfileinfo(fp, dest)
hh
parents:
diff changeset
   120
		else:
hh
parents:
diff changeset
   121
			self._node.putfileinfo(fp, dest)
hh
parents:
diff changeset
   122
			with open(fp, mode='rb') as f:
hh
parents:
diff changeset
   123
				g = self._node.genput()
hh
parents:
diff changeset
   124
				g.send(None)
hh
parents:
diff changeset
   125
				data = f.read(Parms.bufSize)
hh
parents:
diff changeset
   126
				while data:
hh
parents:
diff changeset
   127
					self._counter.update(len(data))
hh
parents:
diff changeset
   128
					if self.d.ll(5): self.d.log("push file: len read from file={}".format(len(data)))
hh
parents:
diff changeset
   129
					try:
hh
parents:
diff changeset
   130
						g.send(data)
hh
parents:
diff changeset
   131
						data = f.read(Parms.bufSize)
hh
parents:
diff changeset
   132
					except Exception:
hh
parents:
diff changeset
   133
						break
hh
parents:
diff changeset
   134
				g.close()
hh
parents:
diff changeset
   135
hh
parents:
diff changeset
   136
	def pullclip(self):
hh
parents:
diff changeset
   137
		self._node = Node(self.d, conn=True)	# establish server cmd session
hh
parents:
diff changeset
   138
		self._node.putcmd("PULLCLIP")
hh
parents:
diff changeset
   139
		self._node.putstr("")   # empty str means LAST entry in clipboard storage on server
hh
parents:
diff changeset
   140
		if self.d.ll(3): self.d.log("pull clipboard starting...")
hh
parents:
diff changeset
   141
		p = subprocess.Popen(["xclip", "-i", "-selection", "clipboard"], stdin=subprocess.PIPE)
hh
parents:
diff changeset
   142
		for data in self._node.genget(size = self._node.getnum()):
hh
parents:
diff changeset
   143
			p.stdin.write(data)
hh
parents:
diff changeset
   144
		p.stdin.close()
hh
parents:
diff changeset
   145
		p.wait()
hh
parents:
diff changeset
   146
		self._node.close_sc()
hh
parents:
diff changeset
   147
		if self.d.ll(2): self.d.log("pull clipboard end")
hh
parents:
diff changeset
   148
hh
parents:
diff changeset
   149
	def pullhist(self):
hh
parents:
diff changeset
   150
		"""
hh
parents:
diff changeset
   151
		synchronizace historie clipboardu se serverem
hh
parents:
diff changeset
   152
		- entries z clipboardu se drží na serveru v jednotlivých souborech, které se synchronizují do lokálního dir
hh
parents:
diff changeset
   153
		- po synchrnizaci se vytvoří indexový soubor seřazený podle timestampů
hh
parents:
diff changeset
   154
		"""
hh
parents:
diff changeset
   155
		histdir = Parms.client_histdir
hh
parents:
diff changeset
   156
		self._node = Node(self.d, conn=True)      # establish server cmd session
hh
parents:
diff changeset
   157
		self._node.putcmd("PULLHIST")
hh
parents:
diff changeset
   158
		self.d.log("synchronizing clipboard history...")
hh
parents:
diff changeset
   159
		os.makedirs(histdir, mode=0o755, exist_ok=True)
hh
parents:
diff changeset
   160
		os.chdir(histdir)
hh
parents:
diff changeset
   161
		entries = dict()
hh
parents:
diff changeset
   162
		toget = dict()
hh
parents:
diff changeset
   163
		fn = self._node.getfn()
hh
parents:
diff changeset
   164
		while len(fn) > 0:	# inventarizace serveru
hh
parents:
diff changeset
   165
			if self.d.ll(5): self.d.log("fn=" + fn)
hh
parents:
diff changeset
   166
			# entries obsahují prvních 80 bytů z clipboard entry, délku clipboard entry a timestamp
hh
parents:
diff changeset
   167
			# entries mohou být binární i textové, takže se nedekódují
hh
parents:
diff changeset
   168
			entries[fn] = (self._node.getstr(decode=False), self._node.getnum(), self._node.getnum())
hh
parents:
diff changeset
   169
			if not os.path.exists(fn):
hh
parents:
diff changeset
   170
				toget[fn] = entries[fn]
hh
parents:
diff changeset
   171
				if self.d.ll(4): self.d.log("fn {} doesn't exists, toget[fn]={}, toget size={}".format(fn, toget[fn], len(toget)))
hh
parents:
diff changeset
   172
			fn = self._node.getfn()
hh
parents:
diff changeset
   173
		self.d.log("toget={}, toget size={}".format(toget.keys(), len(toget)), sev=4)
hh
parents:
diff changeset
   174
		if len(toget):		# synchronizace
hh
parents:
diff changeset
   175
			for fn in toget.keys():
hh
parents:
diff changeset
   176
				self._node.putcmd("PULLCLIP")
hh
parents:
diff changeset
   177
				self._node.putstr(fn)                           # send requested entry name
hh
parents:
diff changeset
   178
				with open(fn, mode='wb') as f:
hh
parents:
diff changeset
   179
					for data in self._node.genget(size = self._node.getnum()):
hh
parents:
diff changeset
   180
						f.write(data)
hh
parents:
diff changeset
   181
				timestamp = toget[fn][2]
hh
parents:
diff changeset
   182
				os.utime(fn, (timestamp, timestamp))
hh
parents:
diff changeset
   183
			self._node.close_sc()
hh
parents:
diff changeset
   184
		p = subprocess.Popen(["sort", "-k2", "-r"], stdin=subprocess.PIPE, stdout=open('.index', mode='w'), universal_newlines=True)
hh
parents:
diff changeset
   185
		for fn in os.listdir():	# indexing
hh
parents:
diff changeset
   186
			if fn == ".index": continue
hh
parents:
diff changeset
   187
			digest = open(fn, mode="rb").read(80).replace(b'\n', b' ')
hh
parents:
diff changeset
   188
			try: digest = digest.decode()	# to, co nepůjde dekódovat, necháme být
hh
parents:
diff changeset
   189
			except UnicodeDecodeError: pass
hh
parents:
diff changeset
   190
			size = os.path.getsize(fn)
hh
parents:
diff changeset
   191
			timestamp = int(os.path.getmtime(fn))
hh
parents:
diff changeset
   192
			p.stdin.write("{} {} {: 6d} {}\n".format(fn, time.strftime("%Y/%m/%d.%H:%M:%S", time.gmtime(timestamp)), size, digest))
hh
parents:
diff changeset
   193
		p.stdin.close()
hh
parents:
diff changeset
   194
		p.wait()
hh
parents:
diff changeset
   195
		if p.returncode == 0:
hh
parents:
diff changeset
   196
			p = subprocess.Popen(["mc", histdir])
hh
parents:
diff changeset
   197
			p.wait()
hh
parents:
diff changeset
   198
		if self.d.ll(5): self.d.log("clipboard history sync finished")
hh
parents:
diff changeset
   199
hh
parents:
diff changeset
   200
hh
parents:
diff changeset
   201
	def pullfile(self):
hh
parents:
diff changeset
   202
		ldp = len(Parms.datapaths)
hh
parents:
diff changeset
   203
		if ldp:
hh
parents:
diff changeset
   204
			if ldp > 1:	# alespoň 2 argumenty: poslední arg je destination dir, ostatní args jsou požadavky
hh
parents:
diff changeset
   205
				self._orig = Parms.datapaths[:ldp-1]
hh
parents:
diff changeset
   206
				self._dest = Parms.datapaths[-1]
hh
parents:
diff changeset
   207
			else:		# jedinný arg je požadavek, destination dir podle env DEST
hh
parents:
diff changeset
   208
				self._orig = Parms.datapaths[:1]
hh
parents:
diff changeset
   209
				self._dest = Parms.dest
hh
parents:
diff changeset
   210
		else:			# bez argumentů: požadavek i destinace podle env
hh
parents:
diff changeset
   211
			self._orig = Parms.orig
hh
parents:
diff changeset
   212
			self._dest = Parms.dest
hh
parents:
diff changeset
   213
		if not self._orig:
hh
parents:
diff changeset
   214
			self.d.abend("no filename specified, ABEND")
hh
parents:
diff changeset
   215
		else:
hh
parents:
diff changeset
   216
			self._node = Node(self.d, conn=True)
hh
parents:
diff changeset
   217
			size, fnum, dnum = (0, 0, 0)
hh
parents:
diff changeset
   218
			for orig in self._orig:		# zjistíme celkovou velikost dávky pro průběžné sledování
hh
parents:
diff changeset
   219
				orig = os.path.normpath(orig)
hh
parents:
diff changeset
   220
				self._node.putcmd("RECKON")
hh
parents:
diff changeset
   221
				self._node.putstr(orig)
hh
parents:
diff changeset
   222
				size += self._node.getnum()
hh
parents:
diff changeset
   223
				fnum += self._node.getnum()
hh
parents:
diff changeset
   224
				dnum += self._node.getnum()
hh
parents:
diff changeset
   225
			self.longtask()
hh
parents:
diff changeset
   226
			self.d.log("pulling {} bytes in {} files and {} dirs...".format(size, fnum, dnum), sev=3)
hh
parents:
diff changeset
   227
			self._counter = Counter(self.d, size)
hh
parents:
diff changeset
   228
			for orig in self._orig:		# vlastní download dávky
hh
parents:
diff changeset
   229
				orig = os.path.normpath(orig)
hh
parents:
diff changeset
   230
				self._node.putcmd("PULLFILE")
hh
parents:
diff changeset
   231
				if self.d.ll(4): self.d.log("pull of '{}' starting...".format(orig))
hh
parents:
diff changeset
   232
				self._node.putstr(orig)
hh
parents:
diff changeset
   233
				fn = self._node.getfn()
hh
parents:
diff changeset
   234
				while len(fn) > 0:
hh
parents:
diff changeset
   235
					fp = os.path.join(self._dest, fn)
hh
parents:
diff changeset
   236
					size = self._node.getnum()
hh
parents:
diff changeset
   237
					timestamp = self._node.getnum()
hh
parents:
diff changeset
   238
					if self.d.ll(4): self.d.log("pull to '{}, dir={}'...".format(fp, size == -1))
hh
parents:
diff changeset
   239
					if size < 0:
hh
parents:
diff changeset
   240
						self._node.receive_dir(fp, size, timestamp)
hh
parents:
diff changeset
   241
					else:
hh
parents:
diff changeset
   242
						self._node.receive_file(fp, size, timestamp, counter=self._counter)
hh
parents:
diff changeset
   243
					fn = self._node.getfn()
hh
parents:
diff changeset
   244
			self._counter.stop()
hh
parents:
diff changeset
   245
			if self.d.ll(2): self.d.log("pull file end")
hh
parents:
diff changeset
   246
hh
parents:
diff changeset
   247
	def pulllist(self):
hh
parents:
diff changeset
   248
		"""
hh
parents:
diff changeset
   249
		po odeslání příkazu se načítají údaje o souborech ve tvaru
hh
parents:
diff changeset
   250
			<délka_fn><fn><file_size><file_timestamp>
hh
parents:
diff changeset
   251
		"""
hh
parents:
diff changeset
   252
		self._node = Node(self.d, conn=True)
hh
parents:
diff changeset
   253
		self._node.putcmd("PULLLIST")
hh
parents:
diff changeset
   254
		self._node.putstr(os.path.normpath(self._orig[0] if self._orig else "."))
hh
parents:
diff changeset
   255
		fn = self._node.getfn()
hh
parents:
diff changeset
   256
		while fn:
hh
parents:
diff changeset
   257
			size = self._node.getnum()
hh
parents:
diff changeset
   258
			timestamp = time.asctime(time.localtime(self._node.getnum()))
hh
parents:
diff changeset
   259
			print("{: 12d} {:24} {}".format(size, timestamp, fn))
hh
parents:
diff changeset
   260
			fn = self._node.getfn()
hh
parents:
diff changeset
   261
			if self.d.ll(5): self.d.log("fn='{}'".format(str(fn)))
hh
parents:
diff changeset
   262
hh
parents:
diff changeset
   263
	def pushpeer(self):
hh
parents:
diff changeset
   264
		if not self._orig:
hh
parents:
diff changeset
   265
			self.d.abendMsg("nothing specified")
hh
parents:
diff changeset
   266
		elif not any(os.path.exists(p) for p in self._orig):
hh
parents:
diff changeset
   267
			self.d.abendMsg("{} not found".format(self._orig))
hh
parents:
diff changeset
   268
		else:
hh
parents:
diff changeset
   269
			self._node = Node(self.d, conn=True, peering=True)
hh
parents:
diff changeset
   270
			size = self.batchSize()
hh
parents:
diff changeset
   271
			self.sendBatchSize(size)	# poskytneme partnerovi údaje o velikosti odesílané dávky
hh
parents:
diff changeset
   272
			self._counter = Counter(self.d, size)
hh
parents:
diff changeset
   273
			try:
hh
parents:
diff changeset
   274
				for fp in self._orig:
hh
parents:
diff changeset
   275
					if self.d.ll(3): self.d.log("pushpeer: from={}".format(fp))
hh
parents:
diff changeset
   276
					if os.path.exists(fp):
hh
parents:
diff changeset
   277
						normfp = os.path.normpath(fp)
hh
parents:
diff changeset
   278
						self.pushpeer_recurse(normfp, os.path.dirname(normfp))
hh
parents:
diff changeset
   279
					else:
hh
parents:
diff changeset
   280
						self.d.warn("'{}' not found".format(fp))
hh
parents:
diff changeset
   281
			finally:
hh
parents:
diff changeset
   282
				self._node.sendEOD()  # end of batch
hh
parents:
diff changeset
   283
				self._counter.stop()
hh
parents:
diff changeset
   284
hh
parents:
diff changeset
   285
	def pushpeer_recurse(self, fp, prefix):
hh
parents:
diff changeset
   286
		if self.d.ll(4): self.d.log("pushpeer recurse: fp={}, relative fp={}".format(fp, os.path.relpath(fp, prefix)))
hh
parents:
diff changeset
   287
		if os.path.isdir(fp):
hh
parents:
diff changeset
   288
			for cwd, void, entries in os.walk(fp, topdown=True):
hh
parents:
diff changeset
   289
				for entry in entries:
hh
parents:
diff changeset
   290
					self.pushpeer_recurse(os.path.join(cwd, entry), prefix)
hh
parents:
diff changeset
   291
				self._node.putfileinfo(cwd, os.path.relpath(cwd, prefix))
hh
parents:
diff changeset
   292
			self._node.putfileinfo(fp, os.path.relpath(fp, prefix))
hh
parents:
diff changeset
   293
		else:
hh
parents:
diff changeset
   294
			self._node.putfileinfo(fp, os.path.relpath(fp, prefix))
hh
parents:
diff changeset
   295
			with open(fp, mode='rb') as f:
hh
parents:
diff changeset
   296
				g = self._node.genput()
hh
parents:
diff changeset
   297
				g.send(None)
hh
parents:
diff changeset
   298
				data = f.read(Parms.bufSize)
hh
parents:
diff changeset
   299
				while data:
hh
parents:
diff changeset
   300
					self._counter.update(len(data))
hh
parents:
diff changeset
   301
					try:
hh
parents:
diff changeset
   302
						g.send(data)
hh
parents:
diff changeset
   303
						data = f.read(Parms.bufSize)
hh
parents:
diff changeset
   304
					except Exception:
hh
parents:
diff changeset
   305
						break
hh
parents:
diff changeset
   306
				g.close()
hh
parents:
diff changeset
   307
		if self.d.ll(4): self.d.log("PUSHPEER: entry {} sent".format(fp))
hh
parents:
diff changeset
   308
hh
parents:
diff changeset
   309
	def sendBatchSize(self, size):
hh
parents:
diff changeset
   310
		"""
hh
parents:
diff changeset
   311
		odeslání informace o velikosti připravené dávky dat
hh
parents:
diff changeset
   312
		informace se odešle formou informace o souboru (filename, filesize, timestamp)
hh
parents:
diff changeset
   313
		"""
hh
parents:
diff changeset
   314
		if self.d.ll(4): self.d.log("sending batch size to peer...")
hh
parents:
diff changeset
   315
		self._node.putstr("dummy fn for batch size")
hh
parents:
diff changeset
   316
		self._node.putnum(size)
hh
parents:
diff changeset
   317
		self._node.putnum(0)
hh
parents:
diff changeset
   318
hh
parents:
diff changeset
   319
	def pullpeer(self):
hh
parents:
diff changeset
   320
		if not Parms.bindhost:
hh
parents:
diff changeset
   321
			self.d.abend("local host addr for peering not specified", None)
hh
parents:
diff changeset
   322
		try:
hh
parents:
diff changeset
   323
			self._node = Node(self.d, host=Parms.bindhost, tryPort=True, conn=False, peering=True)
hh
parents:
diff changeset
   324
		except Node.AllPortsBusy as e:
hh
parents:
diff changeset
   325
			self.d.abend("all predefined net ports are busy", None)
hh
parents:
diff changeset
   326
		try:
hh
parents:
diff changeset
   327
			self.d.log("accepting...", sev=4)
hh
parents:
diff changeset
   328
			accepted = self._node.acc(acc_TO=Parms.peer_accept_timeout)
hh
parents:
diff changeset
   329
			self.d.log("peer {}accepted".format("not " if not accepted else ""), sev=4)
hh
parents:
diff changeset
   330
			if not accepted: return
hh
parents:
diff changeset
   331
		except Exception as e:
hh
parents:
diff changeset
   332
			self._node.close_ssc()
hh
parents:
diff changeset
   333
			self.d.abend("peer pull accept", None)
hh
parents:
diff changeset
   334
			return
hh
parents:
diff changeset
   335
		finally:
hh
parents:
diff changeset
   336
			self._node.UDPsignalHUP()		# stop UDP broadcast
hh
parents:
diff changeset
   337
		self.d.log("get batch size from peer (dummy fn)", sev=4)
hh
parents:
diff changeset
   338
		self._node.getfn()	# dummy fn in batch size info
hh
parents:
diff changeset
   339
		batchsize = self._node.getnum()
hh
parents:
diff changeset
   340
		self.d.log("batchsize={}".format(batchsize), sev=4)
hh
parents:
diff changeset
   341
		self._node.getnum()	# dummy timestamp
hh
parents:
diff changeset
   342
		counter = Counter(self.d, batchsize)
hh
parents:
diff changeset
   343
		fn = self._node.getfn()
hh
parents:
diff changeset
   344
		while fn:	# receive batch of file/dir objects
hh
parents:
diff changeset
   345
			self.d.log("fn={}".format(fn), sev=4)
hh
parents:
diff changeset
   346
			fp = os.path.join(self._dest, fn)
hh
parents:
diff changeset
   347
			size = self._node.getnum()
hh
parents:
diff changeset
   348
			timestamp = self._node.getnum()
hh
parents:
diff changeset
   349
			if self.d.ll(4): self.d.log("pulling from peer to '{}'...".format(fp))
hh
parents:
diff changeset
   350
			if size < 0:
hh
parents:
diff changeset
   351
				if not self._node.receive_dir(fp, size, timestamp):
hh
parents:
diff changeset
   352
					self._node.close_sc()
hh
parents:
diff changeset
   353
			else:
hh
parents:
diff changeset
   354
				self._node.receive_file(fp, size, timestamp, counter=counter)
hh
parents:
diff changeset
   355
			fn = self._node.getfn()
hh
parents:
diff changeset
   356
		counter.stop()
hh
parents:
diff changeset
   357
		self._node.close_sc()
hh
parents:
diff changeset
   358
		self._node.close_ssc()
hh
parents:
diff changeset
   359
hh
parents:
diff changeset
   360
	def close_sc(self):
hh
parents:
diff changeset
   361
		self._node.close_sc()
hh
parents:
diff changeset
   362
hh
parents:
diff changeset
   363
	def dirsize(self, fp):
hh
parents:
diff changeset
   364
		p = subprocess.Popen(("du", "-sb", fp), stdout=subprocess.PIPE)
hh
parents:
diff changeset
   365
		p.wait()
hh
parents:
diff changeset
   366
		return int(p.stdout.readlines()[0].decode().split("\t")[0]) if p.returncode == 0 else -1
hh
parents:
diff changeset
   367
hh
parents:
diff changeset
   368
	def batchSize(self):
hh
parents:
diff changeset
   369
		size = 0
hh
parents:
diff changeset
   370
		for fp in self._orig:
hh
parents:
diff changeset
   371
			if os.path.exists(fp):
hh
parents:
diff changeset
   372
				size += self.dirsize(fp) if os.path.isdir(fp) else os.path.getsize(fp)
hh
parents:
diff changeset
   373
		return size
hh
parents:
diff changeset
   374
hh
parents:
diff changeset
   375
	def srv_hack(self):
hh
parents:
diff changeset
   376
		self._node = Node(self.d, conn=True)
hh
parents:
diff changeset
   377
		for orig in self._orig:
hh
parents:
diff changeset
   378
			self._node.putcmd("RECKON")
hh
parents:
diff changeset
   379
			self._node.putstr(orig)
hh
parents:
diff changeset
   380
			wholesize = self._node.getnum()
hh
parents:
diff changeset
   381
			fnum = self._node.getnum()
hh
parents:
diff changeset
   382
			dnum = self._node.getnum()
hh
parents:
diff changeset
   383
			self.d.log("reckon: {}, {}, {}".format(wholesize, fnum, dnum))
hh
parents:
diff changeset
   384
hh
parents:
diff changeset
   385
	def hack(self):
hh
parents:
diff changeset
   386
		self._node = Node(self.d, conn=False, tryPort=False, port=1111, host='10.0.1.47')
hh
parents:
diff changeset
   387
		self._node.acc(1)
hh
parents:
diff changeset
   388
hh
parents:
diff changeset
   389
	def hack_recurse(self, realfp, pref):
hh
parents:
diff changeset
   390
		self.d.log("hack realfp={}, relfp={}".format(realfp, os.path.relpath(realfp, pref)))
hh
parents:
diff changeset
   391
		if os.path.isdir(realfp):
hh
parents:
diff changeset
   392
			for cwd, void, entries in os.walk(realfp, topdown=True):
hh
parents:
diff changeset
   393
				for entry in entries:
hh
parents:
diff changeset
   394
					self.hack_recurse2(os.path.join(cwd, entry), pref)
hh
parents:
diff changeset
   395
				self.d.log("node.putfileinfo({}, {})".format(cwd, os.path.relpath(cwd, pref)))
hh
parents:
diff changeset
   396
			self.d.log("node.putfileinfo({}, {})".format(realfp, os.path.relpath(realfp, pref)))
hh
parents:
diff changeset
   397
		else:
hh
parents:
diff changeset
   398
			self.d.log("file {} processing".format(realfp))