@@ -574,22 +574,66 @@ def update(
574
574
self .meta [metadata_fn ] = MetadataInfo (version , length , hashes )
575
575
576
576
577
+ class TargetInfo :
578
+ """A container with information about a particular target file.
579
+ Instances of TargetInfo are used as values in a dictionary
580
+ called "targets" in Targets.
581
+
582
+ Attributes:
583
+ length: An integer indicating the length of the target file.
584
+ hashes: A dictionary containing hash algorithms and the
585
+ hashes resulted from applying them over the target file::
586
+
587
+ 'hashes': {
588
+ '<HASH ALGO 1>': '<TARGET FILE HASH 1>',
589
+ '<HASH ALGO 2>': '<TARGET FILE HASH 2>',
590
+ ...
591
+ }
592
+
593
+ custom: An optional dictionary which may include version numbers,
594
+ dependencies, or any other data that the application wants
595
+ to include to describe the target file::
596
+
597
+ 'custom': {
598
+ 'type': 'metadata',
599
+ 'file_permissions': '0644',
600
+ ...
601
+ } // optional
602
+
603
+ """
604
+
605
+ def __init__ (self , length : int , hashes : JsonDict ,
606
+ custom : Optional [JsonDict ] = None ) -> None :
607
+ self .length = length
608
+ self .hashes = hashes
609
+ self .custom = custom
610
+
611
+
612
+ def __eq__ (self , other : 'TargetInfo' ) -> bool :
613
+ """Compare objects by their values instead of by their addresses."""
614
+ return (self .length == other .length and
615
+ self .hashes == other .hashes and
616
+ self .custom == other .custom )
617
+
618
+
619
+ def to_dict (self ) -> JsonDict :
620
+ """Returns the JSON-serializable dictionary representation of self. """
621
+ json_dict = {'length' : self .length , 'hashes' : self .hashes }
622
+
623
+ if self .custom is not None :
624
+ json_dict ['custom' ] = self .custom
625
+
626
+ return json_dict
627
+
628
+
577
629
class Targets (Signed ):
578
630
"""A container for the signed part of targets metadata.
579
631
580
632
Attributes:
581
633
targets: A dictionary that contains information about target files::
582
634
583
635
{
584
- '<TARGET FILE NAME>': {
585
- 'length': <TARGET FILE SIZE>,
586
- 'hashes': {
587
- '<HASH ALGO 1>': '<TARGET FILE HASH 1>',
588
- '<HASH ALGO 2>': '<TARGETS FILE HASH 2>',
589
- ...
590
- },
591
- 'custom': <CUSTOM OPAQUE DICT> // optional
592
- },
636
+ '<TARGET FILE NAME>': <TargetInfo INSTANCE>,
593
637
...
594
638
}
595
639
@@ -633,25 +677,43 @@ class Targets(Signed):
633
677
# pylint: disable=too-many-arguments
634
678
def __init__ (
635
679
self , _type : str , version : int , spec_version : str ,
636
- expires : datetime , targets : JsonDict , delegations : JsonDict
637
- ) -> None :
680
+ expires : datetime , targets : Dict [ str , TargetInfo ],
681
+ delegations : JsonDict ) -> None :
638
682
super ().__init__ (_type , version , spec_version , expires )
639
- # TODO: Add class for meta
640
683
self .targets = targets
684
+
685
+ # TODO: Add Key and Role classes
641
686
self .delegations = delegations
642
687
643
688
689
+ @classmethod
690
+ def from_dict (cls , signed_dict : JsonDict ) -> 'Targets' :
691
+ """Creates Targets object from its JSON/dict representation. """
692
+
693
+ # signed is passed by reference, make sure we are not changing it.
694
+ changed_signed = signed_dict .copy ()
695
+ for target_path in signed_dict ['targets' ].keys ():
696
+ changed_signed ['targets' ][target_path ] = TargetInfo (
697
+ ** signed_dict ['targets' ][target_path ])
698
+
699
+ return super ().from_dict (changed_signed )
700
+
701
+
644
702
# Serialization.
645
703
def to_dict (self ) -> JsonDict :
646
704
"""Returns the JSON-serializable dictionary representation of self. """
647
705
json_dict = super ().to_dict ()
706
+ target_dict = {}
707
+ for target_path , target_file_obj in self .targets .items ():
708
+ target_dict [target_path ] = target_file_obj .to_dict ()
709
+
648
710
json_dict .update ({
649
- 'targets' : self . targets ,
711
+ 'targets' : target_dict ,
650
712
'delegations' : self .delegations ,
651
713
})
652
714
return json_dict
653
715
654
716
# Modification.
655
717
def update (self , filename : str , fileinfo : JsonDict ) -> None :
656
718
"""Assigns passed target file info to meta dict. """
657
- self .targets [filename ] = fileinfo
719
+ self .targets [filename ] = TargetInfo ( ** fileinfo )
0 commit comments