Returns a unique URL identifier that representing the Apprise URL itself. The url_id is always a hash string or None if it can't be generated. The idea is to only build the ID based on the credentials or specific elements relative to the URL itself. The URL ID should
(self, lazy=True, hash_engine=hashlib.sha256)
| 392 | ) |
| 393 | |
| 394 | def url_id(self, lazy=True, hash_engine=hashlib.sha256): |
| 395 | """Returns a unique URL identifier that representing the Apprise URL |
| 396 | itself. The url_id is always a hash string or None if it can't be |
| 397 | generated. |
| 398 | |
| 399 | The idea is to only build the ID based on the credentials or specific |
| 400 | elements relative to the URL itself. The URL ID should never factor in |
| 401 | (or else it's a bug) the following: |
| 402 | - any targets defined |
| 403 | - all GET parameters options unless they explicitly change the |
| 404 | complete function of the code. |
| 405 | |
| 406 | For example: GET parameters like ?image=false&avatar=no should |
| 407 | have no bearing in the uniqueness of the Apprise URL Identifier. |
| 408 | |
| 409 | Consider plugins where some get parameters completely change |
| 410 | how the entire upstream comunication works such as slack:// and |
| 411 | matrix:// which has a mode. In these circumstances, they should |
| 412 | be considered in he unique generation. |
| 413 | |
| 414 | The intention of this function is to help align Apprise URLs that are |
| 415 | common with one another and therefore can share the same persistent |
| 416 | storage even when subtle changes are made to them. |
| 417 | |
| 418 | Hence the following would all return the same URL Identifier: |
| 419 | json://abc/def/ghi?image=no |
| 420 | json://abc/def/ghi/?test=yes&image=yes |
| 421 | """ |
| 422 | |
| 423 | if lazy and self.__cached_url_identifier is not False: |
| 424 | return ( |
| 425 | self.__cached_url_identifier |
| 426 | if not ( |
| 427 | self.__cached_url_identifier and self.asset.storage_idlen |
| 428 | ) |
| 429 | else self.__cached_url_identifier[: self.asset.storage_idlen] |
| 430 | ) |
| 431 | |
| 432 | # Python v3.9 introduces usedforsecurity argument |
| 433 | kwargs = ( |
| 434 | {"usedforsecurity": False} if sys.version_info >= (3, 9) else {} |
| 435 | ) |
| 436 | |
| 437 | if self.url_identifier is False: |
| 438 | # Disabled |
| 439 | self.__cached_url_identifier = None |
| 440 | |
| 441 | elif self.url_identifier in (None, True): |
| 442 | # Prepare our object |
| 443 | engine = hash_engine( |
| 444 | self.asset.storage_salt |
| 445 | + self.schema.encode(self.asset.encoding), |
| 446 | **kwargs, |
| 447 | ) |
| 448 | |
| 449 | # We want to treat `None` differently then a blank entry |
| 450 | engine.update( |
| 451 | b"\0" |