zacahuil 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zacahuil-0.1.0/LICENSE +0 -0
- zacahuil-0.1.0/PKG-INFO +8 -0
- zacahuil-0.1.0/README.md +15 -0
- zacahuil-0.1.0/pyproject.toml +12 -0
- zacahuil-0.1.0/setup.cfg +4 -0
- zacahuil-0.1.0/zacahuil/__init__.py +0 -0
- zacahuil-0.1.0/zacahuil/acts.py +205 -0
- zacahuil-0.1.0/zacahuil/fsOperations.py +93 -0
- zacahuil-0.1.0/zacahuil/mem.py +50 -0
- zacahuil-0.1.0/zacahuil/pub.py +68 -0
- zacahuil-0.1.0/zacahuil/sub.py +46 -0
- zacahuil-0.1.0/zacahuil.egg-info/PKG-INFO +8 -0
- zacahuil-0.1.0/zacahuil.egg-info/SOURCES.txt +13 -0
- zacahuil-0.1.0/zacahuil.egg-info/dependency_links.txt +1 -0
- zacahuil-0.1.0/zacahuil.egg-info/top_level.txt +1 -0
zacahuil-0.1.0/LICENSE
ADDED
|
File without changes
|
zacahuil-0.1.0/PKG-INFO
ADDED
zacahuil-0.1.0/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
# Cliente de sistema de almacenamiento basado en memoria
|
|
3
|
+
|
|
4
|
+
Es un cliente para el sistema de almacenamiento en memoria "ESS v1". El cliente es capaz de cargar en memoria datos locales, enviar datos al sistema de almacenamiento, cargar los datos en la memoria local y enviarlos al sistema de almacenamiento, y descargar datos del sistema de almacenamiento.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## Authors
|
|
8
|
+
|
|
9
|
+
- [@juliocsp03](https://www.github.com/juliocsp03)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## License
|
|
13
|
+
|
|
14
|
+
[MIT](https://choosealicense.com/licenses/mit/)
|
|
15
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "zacahuil"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Cliente del sistema de almacenamiendo en memoria ESS v1"
|
|
9
|
+
authors = [
|
|
10
|
+
{ name="Julio Salazar", email="juliocsp03@gmail.com" },
|
|
11
|
+
]
|
|
12
|
+
requires-python = ">=3.8"
|
zacahuil-0.1.0/setup.cfg
ADDED
|
File without changes
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from . import fsOperations as fso
|
|
3
|
+
from multiprocessing import shared_memory, Pool
|
|
4
|
+
# import mem
|
|
5
|
+
# import sub
|
|
6
|
+
# import pub
|
|
7
|
+
from . import mem
|
|
8
|
+
from . import sub
|
|
9
|
+
from . import pub
|
|
10
|
+
|
|
11
|
+
url = "localhost"
|
|
12
|
+
urlStorage = "localhost"
|
|
13
|
+
chunk_size = 1048576
|
|
14
|
+
workers = 1
|
|
15
|
+
|
|
16
|
+
def loadRes(path, s = False, load_to_memory = True):
|
|
17
|
+
mem.remove_shm_from_resource_tracker()
|
|
18
|
+
metadata = fso.getMetadata(path)
|
|
19
|
+
segments = []
|
|
20
|
+
for index, resource in enumerate(metadata["resources"]): # GENERA LOS ESPACIOS DE MEMEORIA
|
|
21
|
+
try: # SI YA EXISTEN SE AGREGA UN CAMPO 'local' CON VALOR 'True'
|
|
22
|
+
shm = shared_memory.SharedMemory(name = resource['hash'], create = False)
|
|
23
|
+
metadata["resources"][index]['local'] = True
|
|
24
|
+
shm.close()
|
|
25
|
+
except FileNotFoundError: # SI NO EXISTEN SE AGREGA UN CAMPO 'local' CON VALOR 'False'
|
|
26
|
+
mem.createLocalSharedMemorySpace(resource['hash'], resource['size'])
|
|
27
|
+
metadata["resources"][index]['local'] = False
|
|
28
|
+
except Exception as e:
|
|
29
|
+
return
|
|
30
|
+
for file in metadata["resources"]: # OBTENER LOS SEGMENTOS DE LOS ARCHIVOS QUE NO ESTÁN EN MEMORIA
|
|
31
|
+
if(file['local'] == False):
|
|
32
|
+
segments+=fso.array_of_segments(file['size'], file["path"], file['hash'], chunk_size)
|
|
33
|
+
|
|
34
|
+
if (load_to_memory):
|
|
35
|
+
with Pool(processes = workers) as p: # CARGARLOS EN MEMORIA A TRAVÉS DE TRABAJADORES
|
|
36
|
+
p.map(mem.loadToLocalSharedMemory, segments)
|
|
37
|
+
|
|
38
|
+
for index, resource in enumerate(metadata["resources"]):
|
|
39
|
+
if(resource['local'] == False):
|
|
40
|
+
metadata["resources"][index]['local'] = True
|
|
41
|
+
if s:
|
|
42
|
+
return metadata, segments
|
|
43
|
+
else:
|
|
44
|
+
return metadata
|
|
45
|
+
|
|
46
|
+
def loadAndUploadToCloud(path):
|
|
47
|
+
res, segments = loadRes(path, True)
|
|
48
|
+
# print(segments)
|
|
49
|
+
for index, resource in enumerate(res["resources"]):
|
|
50
|
+
verification = verify(resource['hash'])
|
|
51
|
+
if (verification):
|
|
52
|
+
# print("Registrado")
|
|
53
|
+
# print(verification['file'])
|
|
54
|
+
if (verification['file']['state']=="reserving"):
|
|
55
|
+
print("Reservando espacio en memoria del servidor")
|
|
56
|
+
sub.subToTopic(resource['hash'])
|
|
57
|
+
verification['file']['state']="ready"
|
|
58
|
+
res['resources'][index] = verification['file']
|
|
59
|
+
elif (verification['file']['state']=="ready"):
|
|
60
|
+
res['resources'][index] = verification['file']
|
|
61
|
+
pass
|
|
62
|
+
else:
|
|
63
|
+
return False
|
|
64
|
+
else:
|
|
65
|
+
resource.pop("local")
|
|
66
|
+
resource['state'] = "reserving"
|
|
67
|
+
register = registry(resource)
|
|
68
|
+
pub.pubTopic(resource['hash'], "loading")
|
|
69
|
+
if (register["created"]):
|
|
70
|
+
response_reserve = requests.post(f"{urlStorage}/reserve", json={"name":resource['hash'], "size": resource['size']})
|
|
71
|
+
segments_res = list(filter(lambda x : x['segment'] == resource['hash'], segments))
|
|
72
|
+
for segment in segments_res:
|
|
73
|
+
print(segment)
|
|
74
|
+
data = None
|
|
75
|
+
with open(segment['origin'], "rb") as file:
|
|
76
|
+
file.seek(segment['start_position'])
|
|
77
|
+
data = file.read(segment['chunk_size'])
|
|
78
|
+
files = {"files": data}
|
|
79
|
+
response_fill = requests.post(f"{urlStorage}/fill", files = files, data = segment)
|
|
80
|
+
resUpdateState = update(resource['hash'], "ready")
|
|
81
|
+
pub.pubTopic(resource['hash'], "ready")
|
|
82
|
+
return res
|
|
83
|
+
|
|
84
|
+
def uploadToCloud(path):
|
|
85
|
+
res, segments = loadRes(path, True, False)
|
|
86
|
+
# print(segments)
|
|
87
|
+
for index, resource in enumerate(res["resources"]):
|
|
88
|
+
verification = verify(resource['hash'])
|
|
89
|
+
if (verification):
|
|
90
|
+
# print("Registrado")
|
|
91
|
+
# print(verification['file'])
|
|
92
|
+
if (verification['file']['state']=="reserving"):
|
|
93
|
+
print("Reservando espacio en memoria del servidor")
|
|
94
|
+
sub.subToTopic(resource['hash'])
|
|
95
|
+
verification['file']['state']="ready"
|
|
96
|
+
res['resources'][index] = verification['file']
|
|
97
|
+
elif (verification['file']['state']=="ready"):
|
|
98
|
+
res['resources'][index] = verification['file']
|
|
99
|
+
print("Archivo listo para consumo")
|
|
100
|
+
pass
|
|
101
|
+
else:
|
|
102
|
+
return False
|
|
103
|
+
else:
|
|
104
|
+
resource.pop("local")
|
|
105
|
+
resource['state'] = "reserving"
|
|
106
|
+
register = registry(resource)
|
|
107
|
+
pub.pubTopic(resource['hash'], "loading")
|
|
108
|
+
if (register["created"]):
|
|
109
|
+
response_reserve = requests.post(f"{urlStorage}/reserve", json={"name":resource['hash'], "size": resource['size']})
|
|
110
|
+
segments_res = list(filter(lambda x : x['segment'] == resource['hash'], segments))
|
|
111
|
+
for segment in segments_res:
|
|
112
|
+
# print(segment)
|
|
113
|
+
data = None
|
|
114
|
+
with open(segment['origin'], "rb") as file:
|
|
115
|
+
file.seek(segment['start_position'])
|
|
116
|
+
data = file.read(segment['chunk_size'])
|
|
117
|
+
files = {"files": data}
|
|
118
|
+
response_fill = requests.post(f"{urlStorage}/fill", files = files, data = segment)
|
|
119
|
+
resUpdateState = update(resource['hash'], "ready")
|
|
120
|
+
pub.pubTopic(resource['hash'], "ready")
|
|
121
|
+
return res
|
|
122
|
+
|
|
123
|
+
def downloadFromCloud(hash):
|
|
124
|
+
mem.remove_shm_from_resource_tracker()
|
|
125
|
+
md = verify(hash)
|
|
126
|
+
md = md['file']
|
|
127
|
+
# print(md)
|
|
128
|
+
mem.createLocalSharedMemorySpace(md['hash'], md['size'])
|
|
129
|
+
segments_to_get = fso.array_of_segments_for_server_file(md['size'], md['hash'], chunk_size)
|
|
130
|
+
print("*"*100)
|
|
131
|
+
filename = f"{md['hash']+md['extension']}"
|
|
132
|
+
with open(filename, "w") as file:
|
|
133
|
+
pass
|
|
134
|
+
for segment in segments_to_get:
|
|
135
|
+
response = requests.post(f"{urlStorage}/chunk", data = segment)
|
|
136
|
+
# print(type(response.content))
|
|
137
|
+
with open(f"{filename}", "r+b") as f:
|
|
138
|
+
f.seek(segment['start_position'])
|
|
139
|
+
f.write(response.content)
|
|
140
|
+
mem.loadDowloadedToLocalSharedMemory(md['hash'], segment['start_position'], segment['end_position'], response.content)
|
|
141
|
+
downloadedFile = getRes(md['hash'])
|
|
142
|
+
return downloadedFile
|
|
143
|
+
|
|
144
|
+
def verify(hash):
|
|
145
|
+
try:
|
|
146
|
+
response = requests.post(f"{url}/hash", json = {"hash": hash})
|
|
147
|
+
if response.json()['registered']:
|
|
148
|
+
return response.json()
|
|
149
|
+
else:
|
|
150
|
+
return False
|
|
151
|
+
except requests.exceptions.RequestException as err:
|
|
152
|
+
print(f"Error al realizar la petición POST de verificación: {err}")
|
|
153
|
+
return {"message": "Error"}
|
|
154
|
+
|
|
155
|
+
def update(hash, state):
|
|
156
|
+
try:
|
|
157
|
+
response = requests.post(f"{url}/update-file-state", json = {"hash": hash, "state": state})
|
|
158
|
+
if response.json():
|
|
159
|
+
return response.json()
|
|
160
|
+
else:
|
|
161
|
+
return False
|
|
162
|
+
except requests.exceptions.RequestException as err:
|
|
163
|
+
print(f"Error al realizar la petición POST de actualización de estado: {err}")
|
|
164
|
+
return {"message": "Error"}
|
|
165
|
+
|
|
166
|
+
def registry(rmd):
|
|
167
|
+
try:
|
|
168
|
+
response = requests.post(f"{url}/register-file", json=rmd)
|
|
169
|
+
return response.json()
|
|
170
|
+
except requests.exceptions.RequestException as err:
|
|
171
|
+
print(f"Error al realizar la petición POST de registro: {err}")
|
|
172
|
+
|
|
173
|
+
def getRes(file):
|
|
174
|
+
return mem.getData(file)
|
|
175
|
+
|
|
176
|
+
def saveFile(path, data, name):
|
|
177
|
+
fso.saveFile(path, data, name)
|
|
178
|
+
|
|
179
|
+
def setWorkers(w):
|
|
180
|
+
global workers
|
|
181
|
+
workers = w
|
|
182
|
+
|
|
183
|
+
def setChunkSize(cs):
|
|
184
|
+
global chunk_size
|
|
185
|
+
chunk_size = cs
|
|
186
|
+
|
|
187
|
+
def setUrl(u):
|
|
188
|
+
global url
|
|
189
|
+
url = u
|
|
190
|
+
|
|
191
|
+
def setStorageUrl(u):
|
|
192
|
+
global urlStorage
|
|
193
|
+
urlStorage = u
|
|
194
|
+
|
|
195
|
+
def getWorkers():
|
|
196
|
+
return workers
|
|
197
|
+
|
|
198
|
+
def getChunkSize():
|
|
199
|
+
return chunk_size
|
|
200
|
+
|
|
201
|
+
def getUrl():
|
|
202
|
+
return url
|
|
203
|
+
|
|
204
|
+
def getStorageUrl():
|
|
205
|
+
return urlStorage
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import hashlib
|
|
3
|
+
|
|
4
|
+
def getMetadata(res):
|
|
5
|
+
type = None
|
|
6
|
+
data = []
|
|
7
|
+
if (os.path.isdir(res)):
|
|
8
|
+
data = dirs(res)
|
|
9
|
+
type = "directorio"
|
|
10
|
+
elif (os.path.isfile(res)):
|
|
11
|
+
data.append(files(res))
|
|
12
|
+
type = "archivo"
|
|
13
|
+
else:
|
|
14
|
+
print("Entrada inválida")
|
|
15
|
+
return {"type": type, "resources": data}
|
|
16
|
+
|
|
17
|
+
def getSegmentData(segment):
|
|
18
|
+
data = None
|
|
19
|
+
with open(segment['origin'], "rb") as file:
|
|
20
|
+
file.seek(segment['start_position'])
|
|
21
|
+
data = file.read(segment['chunk_size'])
|
|
22
|
+
return data
|
|
23
|
+
|
|
24
|
+
def files(res):
|
|
25
|
+
with open(res, "rb") as file:
|
|
26
|
+
digest = getFileHash(res)
|
|
27
|
+
return {"hash": digest, "path": res, "size": os.path.getsize(res), "extension": os.path.splitext(res)[1], "state": "none", "temperature": "none", "owners": "none" }
|
|
28
|
+
|
|
29
|
+
def getFileHash(path):
|
|
30
|
+
hash_func = getattr(hashlib, "sha256")()
|
|
31
|
+
with open(path, "rb") as file:
|
|
32
|
+
while chunk := file.read(1048576):
|
|
33
|
+
hash_func.update(chunk)
|
|
34
|
+
return hash_func.hexdigest()
|
|
35
|
+
|
|
36
|
+
def saveFile(path, data, name):
|
|
37
|
+
with open(f"{path}{name}", "wb") as file:
|
|
38
|
+
file.write(data)
|
|
39
|
+
|
|
40
|
+
def dirs(res):
|
|
41
|
+
list_metadata = []
|
|
42
|
+
for element in os.listdir(res):
|
|
43
|
+
if os.path.isdir(res + '/' + element):
|
|
44
|
+
list_metadata = list_metadata + dirs(res + '/' + element)
|
|
45
|
+
elif os.path.isfile(res + '/' + element):
|
|
46
|
+
list_metadata.append(files(f"{res}/{element}"))
|
|
47
|
+
return list_metadata
|
|
48
|
+
|
|
49
|
+
def array_of_segments(file_size, path, segment_name, chunk_size):
|
|
50
|
+
# INICIALIZA POSICIÓN EN 0
|
|
51
|
+
position = 0
|
|
52
|
+
# DEFINE EL TAMAÑO DEL SEGMENTO
|
|
53
|
+
chunk = chunk_size
|
|
54
|
+
# OBTIENE EL NOMBRE Y EXTENSIÓN DEL ARCHIVO
|
|
55
|
+
filename, extension = os.path.splitext(os.path.basename(path))
|
|
56
|
+
# DEFINE ARREGLO DE POSICIONES
|
|
57
|
+
positions = []
|
|
58
|
+
while position < file_size:
|
|
59
|
+
# DEFINE POSICIÓN FINAL DE UN CHUNK
|
|
60
|
+
end_position = position + chunk if ((position + chunk) < file_size) else position + (file_size - position)
|
|
61
|
+
# AGREGA ELEMENTO AL ARREGLO DE POSICIONES
|
|
62
|
+
positions.append({"origin": path, "filename": filename, "extension": extension,"start_position": position, "end_position": end_position, "file_size": file_size, "segment": segment_name, "chunk_size": chunk})
|
|
63
|
+
# ACTUALIZA LA POSICIÓN
|
|
64
|
+
position = position + chunk
|
|
65
|
+
# RETORNA LAS POSICIONES
|
|
66
|
+
return positions
|
|
67
|
+
|
|
68
|
+
def array_of_segments_for_server_file(file_size, segment_name, chunk_size):
|
|
69
|
+
# INICIALIZA POSICIÓN EN 0
|
|
70
|
+
position = 0
|
|
71
|
+
# DEFINE EL TAMAÑO DEL SEGMENTO
|
|
72
|
+
chunk = chunk_size
|
|
73
|
+
# OBTIENE EL NOMBRE Y EXTENSIÓN DEL ARCHIVO
|
|
74
|
+
# filename, extension = os.path.splitext(os.path.basename(path))
|
|
75
|
+
# DEFINE ARREGLO DE POSICIONES
|
|
76
|
+
positions = []
|
|
77
|
+
while position < file_size:
|
|
78
|
+
# DEFINE POSICIÓN FINAL DE UN CHUNK
|
|
79
|
+
end_position = position + chunk if ((position + chunk) < file_size) else position + (file_size - position)
|
|
80
|
+
# AGREGA ELEMENTO AL ARREGLO DE POSICIONES
|
|
81
|
+
positions.append({"start_position": position, "end_position": end_position, "file_size": file_size, "segment": segment_name, "chunk_size": chunk})
|
|
82
|
+
# ACTUALIZA LA POSICIÓN
|
|
83
|
+
position = position + chunk
|
|
84
|
+
# RETORNA LAS POSICIONES
|
|
85
|
+
return positions
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# if __name__ == '__main__':
|
|
89
|
+
# response = get_metadata("/home/julio/objects")
|
|
90
|
+
# # response = metadata_extractor("/home/julio/objects/one/f.txt")
|
|
91
|
+
# # response = dirs("/home/julio/objects")
|
|
92
|
+
# # print()
|
|
93
|
+
# print(json.dumps(response))
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from multiprocessing import shared_memory, Pool
|
|
2
|
+
from multiprocessing import resource_tracker
|
|
3
|
+
|
|
4
|
+
def createLocalSharedMemorySpace(name, size):
|
|
5
|
+
# self.remove_shm_from_resource_tracker()
|
|
6
|
+
shm = shared_memory.SharedMemory(create=True, size = size, name = name)
|
|
7
|
+
resource_tracker.unregister(shm._name, 'shared_memory')
|
|
8
|
+
shm.close()
|
|
9
|
+
return shm.name
|
|
10
|
+
|
|
11
|
+
def loadToLocalSharedMemory(segment):
|
|
12
|
+
shm = shared_memory.SharedMemory(name = segment['segment'], create=False)
|
|
13
|
+
with open(segment['origin'], "rb") as file:
|
|
14
|
+
file.seek(segment['start_position'])
|
|
15
|
+
shm.buf[segment['start_position']:segment['end_position']] = file.read(segment['chunk_size'])
|
|
16
|
+
shm.close()
|
|
17
|
+
|
|
18
|
+
def loadDowloadedToLocalSharedMemory(shm_name, start_position, end_position, data):
|
|
19
|
+
shm = shared_memory.SharedMemory(name = shm_name, create=False)
|
|
20
|
+
shm.buf[start_position:end_position] = data
|
|
21
|
+
shm.close()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def getData(file):
|
|
25
|
+
remove_shm_from_resource_tracker()
|
|
26
|
+
shm = shared_memory.SharedMemory(name = file, create=False)
|
|
27
|
+
data = bytes(shm.buf[:])
|
|
28
|
+
shm.close()
|
|
29
|
+
return data
|
|
30
|
+
|
|
31
|
+
def remove_shm_from_resource_tracker():
|
|
32
|
+
"""Monkey-patch multiprocessing.resource_tracker so SharedMemory won't be tracked
|
|
33
|
+
|
|
34
|
+
More details at: https://bugs.python.org/issue38119
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def fix_register(name, rtype):
|
|
38
|
+
if rtype == "shared_memory":
|
|
39
|
+
return
|
|
40
|
+
return resource_tracker._resource_tracker.register(self, name, rtype)
|
|
41
|
+
resource_tracker.register = fix_register
|
|
42
|
+
|
|
43
|
+
def fix_unregister(name, rtype):
|
|
44
|
+
if rtype == "shared_memory":
|
|
45
|
+
return
|
|
46
|
+
return resource_tracker._resource_tracker.unregister(self, name, rtype)
|
|
47
|
+
resource_tracker.unregister = fix_unregister
|
|
48
|
+
|
|
49
|
+
if "shared_memory" in resource_tracker._CLEANUP_FUNCS:
|
|
50
|
+
del resource_tracker._CLEANUP_FUNCS["shared_memory"]
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import paho.mqtt.client as mqtt
|
|
2
|
+
import time
|
|
3
|
+
import random
|
|
4
|
+
|
|
5
|
+
# broker = "148.247.201.226"
|
|
6
|
+
broker = "localhost"
|
|
7
|
+
port = 1883
|
|
8
|
+
topic = "files/"
|
|
9
|
+
pub_confirmed = False
|
|
10
|
+
def on_connect(client, userdata, flags, rc, properties = None):
|
|
11
|
+
if rc == 0:
|
|
12
|
+
# print("Conectado al broker MQTT!")
|
|
13
|
+
pass
|
|
14
|
+
else:
|
|
15
|
+
print(f"Fallo al conectar, código de retorno: {rc}")
|
|
16
|
+
|
|
17
|
+
def on_publish(client, userdata, mid, rc, properties=None):
|
|
18
|
+
global pub_confirmed
|
|
19
|
+
if rc == 0:
|
|
20
|
+
# print(f"Mensaje con ID {mid} publicado y confirmado.")
|
|
21
|
+
pub_confirmed = True
|
|
22
|
+
else:
|
|
23
|
+
# print(f"Fallo al publicar el mensaje con ID {mid}.")
|
|
24
|
+
pub_confirmed = False
|
|
25
|
+
|
|
26
|
+
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
|
27
|
+
|
|
28
|
+
def pubTopic(hash = "test-hash", value = "test value"):
|
|
29
|
+
client.on_connect = on_connect
|
|
30
|
+
client.on_publish = on_publish
|
|
31
|
+
try:
|
|
32
|
+
client.connect(broker, port, 60)
|
|
33
|
+
except Exception as e:
|
|
34
|
+
print(f"Error al conectar: {e}")
|
|
35
|
+
exit()
|
|
36
|
+
|
|
37
|
+
client.loop_start()
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
result = client.publish(f"{topic}{hash}", value, retain=True, qos = 1)
|
|
41
|
+
timeout = time.time() + 10
|
|
42
|
+
while not pub_confirmed and time.time() < timeout:
|
|
43
|
+
time.sleep(0.1)
|
|
44
|
+
if (pub_confirmed):
|
|
45
|
+
# print(f"Publicado exitosamente '{value}' en el tema '{topic}{hash}'")
|
|
46
|
+
client.loop_stop()
|
|
47
|
+
client.disconnect()
|
|
48
|
+
# print("Publicador detenido.")
|
|
49
|
+
return {"pub": True}
|
|
50
|
+
else:
|
|
51
|
+
# print(f"Fallo al publicar mensaje al tema {topic}")
|
|
52
|
+
client.loop_stop()
|
|
53
|
+
client.disconnect()
|
|
54
|
+
# print("Publicador detenido.")
|
|
55
|
+
return {"pub": False}
|
|
56
|
+
# if result[0] == 0:
|
|
57
|
+
# print(f"Publicado exitosamente '{value}' en el tema '{topic}{hash}'")
|
|
58
|
+
# return {"pub": True}
|
|
59
|
+
# else:
|
|
60
|
+
# # print(f"Fallo al publicar mensaje al tema {topic}")
|
|
61
|
+
# return {"pub": False}
|
|
62
|
+
# client.loop_stop()
|
|
63
|
+
# client.disconnect()
|
|
64
|
+
# print("Publicador detenido.")
|
|
65
|
+
|
|
66
|
+
except KeyboardInterrupt:
|
|
67
|
+
print("Fallo inesperado.")
|
|
68
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import paho.mqtt.client as mqtt
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
# broker = "148.247.201.226"
|
|
5
|
+
broker = "localhost"
|
|
6
|
+
port = 1883
|
|
7
|
+
topic = "files/"
|
|
8
|
+
hash = "ejemplo"
|
|
9
|
+
file_state = None
|
|
10
|
+
waiting = True
|
|
11
|
+
|
|
12
|
+
def on_connect(client, userdata, flags, rc, properties = None):
|
|
13
|
+
if rc == 0:
|
|
14
|
+
client.subscribe(f"{topic}{hash}", qos = 1)
|
|
15
|
+
else:
|
|
16
|
+
print(f"Fallo al conectar, código: {rc}")
|
|
17
|
+
|
|
18
|
+
def on_message(client, userdata, msg):
|
|
19
|
+
print(f"Mensaje recibido: {msg.payload.decode()} en el tema: {msg.topic}")
|
|
20
|
+
if (msg.payload.decode() == "ready"):
|
|
21
|
+
print("ENTRANDO A CANCELAR")
|
|
22
|
+
global waiting
|
|
23
|
+
waiting = False
|
|
24
|
+
# client.loop_stop()
|
|
25
|
+
|
|
26
|
+
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
|
27
|
+
|
|
28
|
+
def subToTopic(topic_hash):
|
|
29
|
+
global hash
|
|
30
|
+
hash = topic_hash
|
|
31
|
+
|
|
32
|
+
client.on_connect = on_connect
|
|
33
|
+
client.on_message = on_message
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
client.connect(broker, port)
|
|
37
|
+
# client.loop_forever()
|
|
38
|
+
client.loop_start()
|
|
39
|
+
while waiting:
|
|
40
|
+
time.sleep(0.5)
|
|
41
|
+
except Exception as e:
|
|
42
|
+
print(f"Error al conectar: {e}")
|
|
43
|
+
# exit()
|
|
44
|
+
finally:
|
|
45
|
+
client.loop_stop()
|
|
46
|
+
client.disconnect()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
zacahuil/__init__.py
|
|
5
|
+
zacahuil/acts.py
|
|
6
|
+
zacahuil/fsOperations.py
|
|
7
|
+
zacahuil/mem.py
|
|
8
|
+
zacahuil/pub.py
|
|
9
|
+
zacahuil/sub.py
|
|
10
|
+
zacahuil.egg-info/PKG-INFO
|
|
11
|
+
zacahuil.egg-info/SOURCES.txt
|
|
12
|
+
zacahuil.egg-info/dependency_links.txt
|
|
13
|
+
zacahuil.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
zacahuil
|