|
1 | 1 | """DiffSync front-end classes and logic.
|
2 | 2 |
|
3 |
| -Copyright (c) 2020 Network To Code, LLC <info@networktocode.com> |
| 3 | +Copyright (c) 2020-2021 Network To Code, LLC <info@networktocode.com> |
4 | 4 |
|
5 | 5 | Licensed under the Apache License, Version 2.0 (the "License");
|
6 | 6 | you may not use this file except in compliance with the License.
|
|
16 | 16 | """
|
17 | 17 | from collections import defaultdict
|
18 | 18 | from inspect import isclass
|
19 |
| -from typing import ClassVar, Dict, List, Mapping, MutableMapping, Optional, Text, Tuple, Type, Union |
| 19 | +from typing import Callable, ClassVar, Dict, List, Mapping, MutableMapping, Optional, Text, Tuple, Type, Union |
20 | 20 |
|
21 | 21 | from pydantic import BaseModel, PrivateAttr
|
22 | 22 | import structlog # type: ignore
|
@@ -359,7 +359,7 @@ def remove_child(self, child: "DiffSyncModel"):
|
359 | 359 | class DiffSync:
|
360 | 360 | """Class for storing a group of DiffSyncModel instances and diffing/synchronizing to another DiffSync instance."""
|
361 | 361 |
|
362 |
| - # Add mapping of names to specific model classes here: |
| 362 | + # In any subclass, you would add mapping of names to specific model classes here: |
363 | 363 | # modelname1 = MyModelClass1
|
364 | 364 | # modelname2 = MyModelClass2
|
365 | 365 |
|
@@ -418,6 +418,10 @@ def __str__(self):
|
418 | 418 | def __repr__(self):
|
419 | 419 | return f"<{str(self)}>"
|
420 | 420 |
|
| 421 | + def __len__(self): |
| 422 | + """Total number of elements stored in self._data.""" |
| 423 | + return sum(len(entries) for entries in self._data.values()) |
| 424 | + |
421 | 425 | def load(self):
|
422 | 426 | """Load all desired data from whatever backend data source into this instance."""
|
423 | 427 | # No-op in this generic class
|
@@ -502,29 +506,43 @@ def sync_complete(
|
502 | 506 | # ------------------------------------------------------------------------------
|
503 | 507 |
|
504 | 508 | def diff_from(
|
505 |
| - self, source: "DiffSync", diff_class: Type[Diff] = Diff, flags: DiffSyncFlags = DiffSyncFlags.NONE |
| 509 | + self, |
| 510 | + source: "DiffSync", |
| 511 | + diff_class: Type[Diff] = Diff, |
| 512 | + flags: DiffSyncFlags = DiffSyncFlags.NONE, |
| 513 | + callback: Optional[Callable[[int, int], None]] = None, |
506 | 514 | ) -> Diff:
|
507 | 515 | """Generate a Diff describing the difference from the other DiffSync to this one.
|
508 | 516 |
|
509 | 517 | Args:
|
510 | 518 | source (DiffSync): Object to diff against.
|
511 | 519 | diff_class (class): Diff or subclass thereof to use for diff calculation and storage.
|
512 | 520 | flags (DiffSyncFlags): Flags influencing the behavior of this diff operation.
|
| 521 | + callback (function): Function with parameters (current, total), to be called at intervals as the |
| 522 | + calculation of the diff proceeds. |
513 | 523 | """
|
514 |
| - differ = DiffSyncDiffer(src_diffsync=source, dst_diffsync=self, flags=flags, diff_class=diff_class) |
| 524 | + differ = DiffSyncDiffer( |
| 525 | + src_diffsync=source, dst_diffsync=self, flags=flags, diff_class=diff_class, callback=callback |
| 526 | + ) |
515 | 527 | return differ.calculate_diffs()
|
516 | 528 |
|
517 | 529 | def diff_to(
|
518 |
| - self, target: "DiffSync", diff_class: Type[Diff] = Diff, flags: DiffSyncFlags = DiffSyncFlags.NONE |
| 530 | + self, |
| 531 | + target: "DiffSync", |
| 532 | + diff_class: Type[Diff] = Diff, |
| 533 | + flags: DiffSyncFlags = DiffSyncFlags.NONE, |
| 534 | + callback: Optional[Callable[[int, int], None]] = None, |
519 | 535 | ) -> Diff:
|
520 | 536 | """Generate a Diff describing the difference from this DiffSync to another one.
|
521 | 537 |
|
522 | 538 | Args:
|
523 | 539 | target (DiffSync): Object to diff against.
|
524 | 540 | diff_class (class): Diff or subclass thereof to use for diff calculation and storage.
|
525 | 541 | flags (DiffSyncFlags): Flags influencing the behavior of this diff operation.
|
| 542 | + callback (function): Function with parameters (current, total), to be called at intervals as the |
| 543 | + calculation of the diff proceeds. |
526 | 544 | """
|
527 |
| - return target.diff_from(self, diff_class=diff_class, flags=flags) |
| 545 | + return target.diff_from(self, diff_class=diff_class, flags=flags, callback=callback) |
528 | 546 |
|
529 | 547 | # ------------------------------------------------------------------------------
|
530 | 548 | # Object Storage Management
|
@@ -567,21 +585,21 @@ def get(
|
567 | 585 | raise ObjectNotFound(f"{modelname} {uid} not present in {self.name}")
|
568 | 586 | return self._data[modelname][uid]
|
569 | 587 |
|
570 |
| - def get_all(self, obj: Union[Text, DiffSyncModel, Type[DiffSyncModel]]): |
| 588 | + def get_all(self, obj: Union[Text, DiffSyncModel, Type[DiffSyncModel]]) -> List[DiffSyncModel]: |
571 | 589 | """Get all objects of a given type.
|
572 | 590 |
|
573 | 591 | Args:
|
574 | 592 | obj: DiffSyncModel class or instance, or modelname string, that defines the type of the objects to retrieve
|
575 | 593 |
|
576 | 594 | Returns:
|
577 |
| - ValuesList[DiffSyncModel]: List of Object |
| 595 | + List[DiffSyncModel]: List of Object |
578 | 596 | """
|
579 | 597 | if isinstance(obj, str):
|
580 | 598 | modelname = obj
|
581 | 599 | else:
|
582 | 600 | modelname = obj.get_type()
|
583 | 601 |
|
584 |
| - return self._data[modelname].values() |
| 602 | + return list(self._data[modelname].values()) |
585 | 603 |
|
586 | 604 | def get_by_uids(
|
587 | 605 | self, uids: List[Text], obj: Union[Text, DiffSyncModel, Type[DiffSyncModel]]
|
|
0 commit comments