diff --git a/LXMF/LXMF.py b/LXMF/LXMF.py index c128652..d981ae0 100644 --- a/LXMF/LXMF.py +++ b/LXMF/LXMF.py @@ -101,20 +101,6 @@ RENDERER_MICRON = 0x01 RENDERER_MARKDOWN = 0x02 RENDERER_BBCODE = 0x03 -############################################################ -# To be finalized in 1.0.0. A workdoc with open interaction -# through rngit is available for comments and nuancing on: -# -# a8d24177d946de4f1f0a0fe1af9a1338:/page/work.mu`g=reticulum|r=lxmf -# -# Clients that have implemented different reply, reaction -# or comment mechanisms can choose to transitionally parse -# their own specific formats, but are recommended to attempt -# parsing the structure and format defined herein first, -# and fall back to their client-specific structure second. - -# Reaction dict indicies are integers to preserve bandwidth. -# # Clients choose how to handle reaction content, if at all. # While reactions are typically a single unicode emoji or # similar, the exact implementation and sanitization is @@ -123,8 +109,6 @@ RENDERER_BBCODE = 0x03 REACTION_TO = 0x00 # Bytes, full LXMessage.hash REACTION_CONTENT = 0x01 # Bytes, the reaction content in UTF-8 encoding -# Comment dict indicies are integers to preserve bandwidth. -# # Clients choose how to handle messages intended as comments # for other message, if at all. The actual comment content # is carried as the normal LXM content, meaning clients that @@ -133,8 +117,6 @@ REACTION_CONTENT = 0x01 # Bytes, the reaction content in UTF-8 encoding # with the following keys: COMMENT_FOR = 0x00 # Bytes, full LXMessage.hash -# Continuation dict indicies are integers to preserve bandwidth. -# # Clients choose how to handle messages that continue earlier # messages, if at all. The actual continuation content is # carried as the normal LXM content, meaning clients that @@ -142,7 +124,6 @@ COMMENT_FOR = 0x00 # Bytes, full LXMessage.hash # When using the FIELD_CONTINUATION field, the contents is a # dict with the following keys: CONTINUATION_OF = 0x00 # Bytes, full LXMessage.hash -############################################################ # Optional propagation node metadata fields. These # fields may be highly unstable in allocation and @@ -188,8 +169,7 @@ def display_name_from_app_data(app_data=None): return None # Original announce format - else: - return app_data.decode("utf-8") + else: return app_data.decode("utf-8") def stamp_cost_from_app_data(app_data=None): if app_data == None or app_data == b"": return None @@ -238,8 +218,8 @@ def pn_stamp_cost_from_app_data(app_data=None): if pn_announce_data_is_valid(app_data): data = msgpack.unpackb(app_data) return data[5][0] - else: - return None + + else: return None def pn_announce_data_is_valid(data): try: diff --git a/LXMF/LXMPeer.py b/LXMF/LXMPeer.py index 0dbf8ce..37515e6 100644 --- a/LXMF/LXMPeer.py +++ b/LXMF/LXMPeer.py @@ -404,7 +404,7 @@ class LXMPeer: if response == LXMPeer.ERROR_NO_IDENTITY: if self.link != None: RNS.log("Remote peer indicated that no identification was received, retrying...", RNS.LOG_VERBOSE) - self.link.identify() + self.link.identify(self.router.identity) self.state = LXMPeer.LINK_READY self.sync() return diff --git a/LXMF/LXMessage.py b/LXMF/LXMessage.py index c128c00..95d2310 100644 --- a/LXMF/LXMessage.py +++ b/LXMF/LXMessage.py @@ -8,6 +8,7 @@ import multiprocessing import LXMF.LXStamper as LXStamper from .LXMF import APP_NAME, compression_support_from_app_data +from threading import Lock class LXMessage: @@ -184,6 +185,7 @@ class LXMessage: self.__delivery_destination = None self.__delivery_callback = None self.__pn_encrypted_data = None + self.__persist_lock = Lock() self.failed_callback = None self.deferred_stamp_generating = False @@ -672,25 +674,26 @@ class LXMessage: def write_to_directory(self, directory_path): file_name = RNS.hexrep(self.hash, delimit=False) file_path = directory_path+"/"+file_name - tmp_path = file_path+".tmp."+str(os.getpid() or time.time()) + tmp_path = file_path+".tmp."+str(os.getpid() or time.time())+"."+RNS.hexrep(os.urandom(8), delimit=False) - try: - with open(tmp_path, "wb") as file: - file.write(self.packed_container()) - file.flush() - try: os.fsync(file.fileno()) - except OSError as e: RNS.log(f"Error while waiting for persist fsync for {self}: {e}", RNS.LOG_WARNING) - - os.replace(tmp_path, file_path) - return file_path - - except Exception as e: + with self.__persist_lock: try: - if os.path.exists(tmp_path): os.unlink(tmp_path) - except Exception as e: RNS.log(f"Error while cleaning temporary file {tmp_path} for {self}: {e}", RNS.LOG_ERROR) + with open(tmp_path, "wb") as file: + file.write(self.packed_container()) + file.flush() + try: os.fsync(file.fileno()) + except OSError as e: RNS.log(f"Error while waiting for persist fsync for {self}: {e}", RNS.LOG_WARNING) - RNS.log(f"Error while writing LXMF message to file \"{file_path}\". The contained exception was: {e}", RNS.LOG_ERROR) - return None + os.replace(tmp_path, file_path) + return file_path + + except Exception as e: + try: + if os.path.exists(tmp_path): os.unlink(tmp_path) + except Exception as e: RNS.log(f"Error while cleaning temporary file {tmp_path} for {self}: {e}", RNS.LOG_ERROR) + + RNS.log(f"Error while writing LXMF message to file \"{file_path}\". The contained exception was: {e}", RNS.LOG_ERROR) + return None def as_uri(self, finalise=True): if not self.packed: diff --git a/LXMF/_version.py b/LXMF/_version.py index 88081a7..5c4105c 100644 --- a/LXMF/_version.py +++ b/LXMF/_version.py @@ -1 +1 @@ -__version__ = "0.9.9" +__version__ = "1.0.1" diff --git a/Makefile b/Makefile index 5fe5f96..cb7f141 100644 --- a/Makefile +++ b/Makefile @@ -26,5 +26,10 @@ build_spkg: remove_symlinks build_sdist create_symlinks release: remove_symlinks build_wheel build_spkg create_symlinks upload: + @echo Ready to publish release over Reticulum + @read VOID + rngit release rns://7649a50d84610232d1416b41d2896aff/reticulum/lxmf create $$(python setup.py --getversion):dist --name lxmf + +upload-pip: @echo Uploading to PyPi... twine upload dist/*.whl dist/*.tar.gz diff --git a/setup.py b/setup.py index 2ed6932..82521ec 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,4 @@ +import sys import setuptools with open("README.md", "r") as fh: @@ -5,6 +6,10 @@ with open("README.md", "r") as fh: exec(open("LXMF/_version.py", "r").read()) +if "--getversion" in sys.argv: + print(__version__, end="") + exit(0) + setuptools.setup( name="lxmf", version=__version__, @@ -26,6 +31,6 @@ setuptools.setup( 'lxmd=LXMF.Utilities.lxmd:main', ] }, - install_requires=["rns>=1.3.0"], + install_requires=["rns>=1.3.5"], python_requires=">=3.7", )