Files
parentzone_downloader/__pycache__/asset_tracker.cpython-313.pyc

121 lines
14 KiB
Plaintext
Raw Normal View History

2025-10-07 14:52:04 +01:00
<EFBFBD>
3<><33>h<EFBFBD>'<00><00><><00>SrSSKrSSKrSSKrSSKJr SSKJr SSKJrJ r J
r
J r J r SSK r "SS5rSr\S :Xa\"5 gg)
z<EFBFBD>
Asset Tracker for ParentZone Downloader
This module handles tracking of downloaded assets to avoid re-downloading
and to identify new assets that need to be downloaded.
<EFBFBD>N)<01>datetime)<01>Path)<05>Dict<63>List<73>Set<65>Any<6E>Optionalc<00>b<00>\rSrSrSrSS\S\4SjjrS\\\\\444Sjr Sr
S \\\4S\4S
jr S \\\4S\4S jr S \\\4S\ 4S jrS \\\4S\ 4S jrS\\\\4S\\\\44SjrSS \\\4S\S\ 4SjjrS\\\\\444SjrSrS\\\44SjrSrSrg)<1B> AssetTracker<65>z3
Tracks downloaded assets and identifies new ones.
<EFBFBD> storage_dir<69> metadata_filec<00><><00>[U5UlURRSS9 URU- Ul[R
"[ 5UlUR5Ul g)z<>
Initialize the asset tracker.
Args:
storage_dir: Directory where downloaded assets are stored
metadata_file: JSON file to store asset metadata
T)<01>exist_okN)
rr <00>mkdirr<00>logging<6E> getLogger<65>__name__<5F>logger<65>_load_metadata<74>metadata)<03>selfr rs <20>B/Users/tudorsitaru/projects/parentzone_downloader/asset_tracker.py<70>__init__<5F>AssetTracker.__init__s_<00><00> <20> <0B>,<2C><04><18> <0C><18><18><1E><1E><04><1E>-<2D>!<21>-<2D>-<2D> <0A>=<3D><04><1A><1D>'<27>'<27><08>1<><04> <0B><1D>+<2B>+<2B>-<2D><04> <0A><00>returnc<00><><00>URR5(a`[URSSS9n[R"U5nUR
R S[U5S35 UsSSS5 $UR
R S5 0$!,(df  g=f![a*nUR
RSU35 0sSnA$SnAff=f) zf
Load asset metadata from the JSON file.
Returns:
Dictionary of asset metadata keyed by asset ID
<EFBFBD>r<>utf-8<><01>encodingzLoaded metadata for <20> assetsNzFailed to load metadata file: z/No existing metadata file found, starting fresh)
r<00>exists<74>open<65>json<6F>loadr<00>info<66>len<65> Exception<6F>error)r<00>f<>data<74>es rr<00>AssetTracker._load_metadata(s<><00><00> <10> <1D> <1D> $<24> $<24> &<26> &<26> <1A><19>$<24>,<2C>,<2C>c<EFBFBD>G<EFBFBD>D<><01><1F>9<EFBFBD>9<EFBFBD>Q<EFBFBD><<3C>D<EFBFBD><18>K<EFBFBD>K<EFBFBD>$<24>$<24>';<3B>C<EFBFBD><04>I<EFBFBD>;<3B>g<EFBFBD>%N<>O<><1F>E<01>D<> <11>K<EFBFBD>K<EFBFBD> <1C> <1C>N<> O<><15>I<EFBFBD>E<01>D<><44><1D> <1A><14> <0B> <0B>!<21>!<21>$B<>1<EFBFBD>#<23>"F<>G<><19> <09><> <1A>s;<00>B.<00>AB<03>6 B.<00>
B+<07>'B.<00>+B.<00>.
C"<03>8C<03>C"<03>C"c<00>|<00>[URSSS9n[R"URUS[
S9 SSS5 UR RS[UR5S35 g!,(df  NA=f![a(nUR RS U35 SnAgSnAff=f)
z%Save asset metadata to the JSON file.<2E>wr r!<00>)<02>indent<6E>defaultNzSaved metadata for r#zFailed to save metadata file: ) r%rr&<00>dumpr<00>strr<00>debugr)r*r+)rr,r.s r<00>_save_metadata<74>AssetTracker._save_metadata<s<><00><00> D<01><15>d<EFBFBD>(<28>(<28>#<23><07>@<40>A<EFBFBD><14> <09> <09>$<24>-<2D>-<2D><11>1<EFBFBD>c<EFBFBD>B<>A<01> <10>K<EFBFBD>K<EFBFBD> <1D> <1D> 3<>C<EFBFBD><04> <0A> <0A>4F<34>3G<33>w<EFBFBD>O<> P<>A<01>@<40><><19> D<01> <10>K<EFBFBD>K<EFBFBD> <1D> <1D> ><3E>q<EFBFBD>c<EFBFBD>B<> C<> C<><43> D<01>s-<00>B <00>&A8<03>:B <00>8
B<07>B <00>
B;<03>B6<03>6B;<03>assetc<00><00>SU;a[US5$SU;a[US5$SU;a[US5$[R"US[S9n[R"UR 55R 5$)zx
Generate a unique key for an asset.
Args:
asset: Asset dictionary from API
Returns:
Unique key for the asset
<EFBFBD>id<69>assetId<49>uuidT<64><02> sort_keysr4)r6r&<00>dumps<70>hashlib<69>md5<64>encode<64> hexdigest)rr:<00> asset_strs r<00>_get_asset_key<65>AssetTracker._get_asset_keyEs}<00><00> <10>5<EFBFBD>=<3D><16>u<EFBFBD>T<EFBFBD>{<7B>#<23> #<23> <16>%<25> <1F><16>u<EFBFBD>Y<EFBFBD>'<27>(<28> (<28> <13>u<EFBFBD>_<EFBFBD><16>u<EFBFBD>V<EFBFBD>}<7D>%<25> %<25><1D>
<EFBFBD>
<EFBFBD>5<EFBFBD>D<EFBFBD>#<23>F<>I<EFBFBD><1A>;<3B>;<3B>y<EFBFBD>/<2F>/<2F>1<>2<><<3C><<3C>><3E> >rc<00><><00>/SQn0nUHnXA;dM
XX4'M U(dUn[R"US[S9n[R"UR 55R 5$)z<>
Generate a hash for asset content to detect changes.
Args:
asset: Asset dictionary from API
Returns:
Hash of asset content
)<06>updated<65>modified<65> lastModified<65>size<7A>checksum<75>etagTr?)r&rAr6rBrCrDrE)rr:<00>content_fields<64> content_data<74>field<6C> content_strs r<00>_get_asset_hash<73>AssetTracker._get_asset_hash[se<00><00>]<01><0E><19> <0C>#<23>E<EFBFBD><14>~<7E>&+<2B>l<EFBFBD> <0C>#<23>$<24>
<1C> <20>L<EFBFBD><1A>j<EFBFBD>j<EFBFBD><1C><14>s<EFBFBD>K<> <0B><16>{<7B>{<7B>;<3B>-<2D>-<2D>/<2F>0<>:<3A>:<3A><<3C><rc<00>@<00>URU5nX R;$)z<>
Check if an asset has already been downloaded.
Args:
asset: Asset dictionary from API
Returns:
True if asset is already downloaded, False otherwise
)rGr)rr:<00> asset_keys r<00>is_asset_downloaded<65> AssetTracker.is_asset_downloadedts!<00><00><19>'<27>'<27><05>.<2E> <09><18>M<EFBFBD>M<EFBFBD>)<29>)rc<00><><00>URU5nX R;agURU5nURURSS5nX4:g$)z<>
Check if an asset has been modified since last download.
Args:
asset: Asset dictionary from API
Returns:
True if asset has been modified, False otherwise
T<EFBFBD> content_hash<73>)rGrrT<00>get)rr:rW<00> current_hash<73> stored_hashs r<00>is_asset_modified<65>AssetTracker.is_asset_modified<65>sU<00><00><19>'<27>'<27><05>.<2E> <09> <14>M<EFBFBD>M<EFBFBD> )<29><17><1B>+<2B>+<2B>E<EFBFBD>2<> <0C><1A>m<EFBFBD>m<EFBFBD>I<EFBFBD>.<2E>2<>2<>><3E>2<EFBFBD>F<> <0B><1B>*<2A>*r<00>
api_assetsc<00><><00>/nUH<>nURU5nURU5(d1URRSU35 UR U5 M[UR U5(a1URRSU35 UR U5 M<>URR SU35 M<> URRS[U5S[U5S35 U$)z<>
Identify new or modified assets that need to be downloaded.
Args:
api_assets: List of assets from API response
Returns:
List of assets that need to be downloaded
zNew asset found: zModified asset found: zAsset unchanged: zFound z new/modified assets out of z total)rGrXrr(<00>appendr`r7r))rrb<00>
new_assetsr:rWs r<00>get_new_assets<74>AssetTracker.get_new_assets<74>s<><00><00><18>
<EFBFBD><1F>E<EFBFBD><1C>+<2B>+<2B>E<EFBFBD>2<>I<EFBFBD><17>+<2B>+<2B>E<EFBFBD>2<>2<><14> <0B> <0B> <20> <20>#4<>Y<EFBFBD>K<EFBFBD>!@<40>A<><1A>!<21>!<21>%<25>(<28><15>'<27>'<27><05>.<2E>.<2E><14> <0B> <0B> <20> <20>#9<>)<29><1B>!E<>F<><1A>!<21>!<21>%<25>(<28><14> <0B> <0B>!<21>!<21>$5<>i<EFBFBD>[<5B>"A<>B<> <20> <0A> <0B> <0B><18><18>6<EFBFBD>#<23>j<EFBFBD>/<2F>!2<>2N<32>s<EFBFBD>S]<5D><EFBFBD>N_<4E>_e<5F>f<>g<><19>r<00>filepath<74>successc<00>$<00>URU5nUUR[U5[R"5R 5UUR U5US.nU(aoUR5(aZUR5nURUR[R"UR5R 5S.5 XPRU'UR5 URR!SU35 g)z<>
Mark an asset as downloaded in the metadata.
Args:
asset: Asset dictionary from API
filepath: Path where asset was saved
success: Whether download was successful
)<07>asset_id<69>filenamerh<00> download_daterir[<00>api_data)<02> file_size<7A> file_modifiedzMarked asset as downloaded: N)rG<00>namer6r<00>now<6F> isoformatrTr$<00>stat<61>update<74>st_size<7A> fromtimestamp<6D>st_mtimerr8rr7)rr:rhrirW<00>metadata_entryrts r<00>mark_asset_downloaded<65>"AssetTracker.mark_asset_downloaded<65>s<><00><00><19>'<27>'<27><05>.<2E> <09>"<22> <20> <0A> <0A><1B>H<EFBFBD> <0A>%<25>\<5C>\<5C>^<5E>5<>5<>7<><1E> <20>0<>0<><15>7<><1D>
<EFBFBD><0E> <13>x<EFBFBD><EFBFBD><EFBFBD>(<28>(<28><1B>=<3D>=<3D>?<3F>D<EFBFBD> <1A> !<21> !<21>!<21>\<5C>\<5C>!)<29>!7<>!7<><04> <0A> <0A>!F<>!P<>!P<>!R<>#<0E> <0F>
$2<> <0A> <0A>i<EFBFBD> <20> <0C><1B><1B><1D> <0C> <0B> <0B><19><19>8<><19> <0B>D<>Erc<00>6<00>URR5$)zZ
Get all downloaded asset metadata.
Returns:
Dictionary of downloaded asset metadata
)r<00>copy)rs r<00>get_downloaded_assets<74>"AssetTracker.get_downloaded_assets<74>s<00><00><14>}<7D>}<7D>!<21>!<21>#<23>#rc<00><><00>Sn/nURR5Hfup4[URSS55nUR 5(aM7UR U5 UR RSU35 Mh UHnURU US- nM US:<3A>a0UR5 UR RSUS35 gg) zA
Remove metadata entries for files that no longer exist on disk.
rrhr\z&File missing, removing from metadata: <20>z Cleaned up z# missing file entries from metadataN)
r<00>itemsrr]r$rdr<00>warningr8r()r<00> removed_count<6E>assets_to_removerWryrhs r<00>cleanup_missing_files<65>"AssetTracker.cleanup_missing_files<65>s<><00><00><1A> <0A><1D><18>)-<2D><1D><1D>)<<3C>)<<3C>)><3E> %<25>I<EFBFBD><1B>N<EFBFBD>.<2E>.<2E>z<EFBFBD>2<EFBFBD>><3E>?<3F>H<EFBFBD><1B>?<3F>?<3F>$<24>$<24> <20>'<27>'<27> <09>2<><14> <0B> <0B>#<23>#<23>&L<>X<EFBFBD>J<EFBFBD>$W<>X<> *?<3F> *<2A>I<EFBFBD><14> <0A> <0A>i<EFBFBD>(<28> <19>Q<EFBFBD> <1E>M<EFBFBD>*<2A> <19>1<EFBFBD> <1C> <10> <1F> <1F> !<21> <10>K<EFBFBD>K<EFBFBD> <1C> <1C>{<7B>=<3D>/<2F>9\<5C>]<5D> ^<5E> rc
<00><><00>[UR5n[SURR555nX-
nSnSnURR5HGnSU;aXFS- n[ UR SS55nUR 5(dMBUS- nMI UUUUX-
U[US- S5S .$)
zO
Get statistics about tracked assets.
Returns:
Dictionary with statistics
c3<00>V# <00>UHoRSS5(dMSv<00> M! g7f)riFr<46>N)r])<02>.0<EFBFBD>entrys r<00> <genexpr><3E>)AssetTracker.get_stats.<locals>.<genexpr><3E>s!<00><00><00>"h<>2H<32><15>I<EFBFBD>I<EFBFBD>V_<56>af<61>Lg<4C>1<EFBFBD>1<EFBFBD>2H<32>s<00>)<01> )rrorhr\r<>ir2)<07>total_tracked_assets<74>successful_downloads<64>failed_downloads<64>existing_files<65> missing_files<65>total_size_bytes<65> total_size_mb)r)r<00>sum<75>valuesrr]r$<00>round)r<00> total_assetsr<73>r<><00>
total_sizer<EFBFBD>r<>rhs r<00> get_stats<74>AssetTracker.get_stats<74>s<><00><00><1B>4<EFBFBD>=<3D>=<3D>)<29> <0C>"<22>"h<>$<24>-<2D>-<2D>2F<32>2F<32>2H<32>"h<>h<><1C>'<27>><3E><18><16>
<EFBFBD><1A><0E><19>]<5D>]<5D>)<29>)<29>+<2B>E<EFBFBD><1A>e<EFBFBD>#<23><1A>K<EFBFBD>0<>0<>
<EFBFBD><1B>E<EFBFBD>I<EFBFBD>I<EFBFBD>j<EFBFBD>"<22>5<>6<>H<EFBFBD><17><EFBFBD><EFBFBD> <20> <20><1E>!<21>#<23><0E> ,<2C>%1<>$8<> 0<>,<2C>)<29>:<3A> *<2A>"<22>:<3A><1B>#=<3D>q<EFBFBD>A<>
<EFBFBD>
rc<00>V<00>UR5n[S5 [S5 [S5 [SUS35 [SUS35 [SUS35 [S US
35 [S US 35 [S USSUSS35 [S5 g)z&Print statistics about tracked assets.z<============================================================zASSET TRACKER STATISTICSzTotal tracked assets: r<>zSuccessful downloads: r<>zFailed downloads: r<>zExisting files: r<>zMissing files: r<>z Total size: r<>z MB (r<>z bytes)N)r<><00>print)r<00>statss r<00> print_stats<74>AssetTracker.print_statss<><00><00><14><0E><0E> <20><05> <0A>h<EFBFBD><0F> <0A>(<28>)<29> <0A>h<EFBFBD><0F> <0A>&<26>u<EFBFBD>-C<>'D<>&E<>F<>G<> <0A>&<26>u<EFBFBD>-C<>'D<>&E<>F<>G<> <0A>"<22>5<EFBFBD>);<3B>#<<3C>"=<3D>><3E>?<3F> <0A> <20><15>'7<>!8<> 9<>:<3A>;<3B> <0A><0F><05>o<EFBFBD> 6<>7<>8<>9<> <0A> <0C>U<EFBFBD>?<3F>3<>4<>E<EFBFBD>%<25>@R<>:S<>9T<39>T[<5B>\<5C>]<5D> <0A>h<EFBFBD>r)rrrr N)<02>downloaded_imageszasset_metadata.json)T)r<00>
__module__<EFBFBD> __qualname__<5F>__firstlineno__<5F>__doc__r6rrrrr8rGrT<00>boolrXr`rrfrrzr~r<>r<>r<><00>__static_attributes__<5F>rrr r s=<00><00><08>.<2E>C<EFBFBD>.<2E>c<EFBFBD>.<2E>"<16><04>S<EFBFBD>$<24>s<EFBFBD>C<EFBFBD>x<EFBFBD>.<2E>%8<> 9<><16>(D<01>?<3F>D<EFBFBD><13>c<EFBFBD><18>N<EFBFBD>?<3F>s<EFBFBD>?<3F>,=<3D>T<EFBFBD>#<23>s<EFBFBD>(<28>^<5E>=<3D><03>=<3D>2 *<2A><14>c<EFBFBD>3<EFBFBD>h<EFBFBD><1E> *<2A>D<EFBFBD> *<2A>+<2B>t<EFBFBD>C<EFBFBD><13>H<EFBFBD>~<7E>+<2B>$<24>+<2B>(<1A><14>d<EFBFBD>3<EFBFBD><03>8<EFBFBD>n<EFBFBD>)=<3D><1A>$<24>t<EFBFBD>C<EFBFBD>QT<51>H<EFBFBD>~<7E>BV<42><1A>6 F<01>4<EFBFBD><03>S<EFBFBD><08>><3E> F<01>T<EFBFBD> F<01>TX<54> F<01>D$<24>t<EFBFBD>C<EFBFBD><14>c<EFBFBD>3<EFBFBD>h<EFBFBD><1E>,?<3F>'@<40>$<24>_<01>*
<EFBFBD>4<EFBFBD><03>S<EFBFBD><08>><3E>
<EFBFBD>> rr c<00>8<00>SSKn[R"[RSS9 [ 5nUR 5 UR 5 [UR5S:<3A>a0URSS:Xa[S5 UR 5 ggg)z%Test the asset tracker functionality.rNz4%(asctime)s - %(name)s - %(levelname)s - %(message)s)<02>level<65>formatr<74>z --cleanupz
After cleanup:)
<EFBFBD>sysr<00> basicConfig<69>INFOr r<>r<>r)<00>argvr<76>)r<><00>trackers r<00>mainr<6E>s<><00><00><0E> <0C><17><17><15>l<EFBFBD>l<EFBFBD>E<><06> <1B>n<EFBFBD>G<EFBFBD> <0C><17><17><19> <0C>!<21>!<21>#<23> <0B>3<EFBFBD>8<EFBFBD>8<EFBFBD>}<7D>q<EFBFBD><18>S<EFBFBD>X<EFBFBD>X<EFBFBD>a<EFBFBD>[<5B>K<EFBFBD>7<> <0A> <20>!<21><0F><1B><1B><1D>8<>r<00>__main__)r<>r&r<00>osr<00>pathlibr<00>typingrrrrr rBr r<>rr<>rr<00><module>r<>sJ<00><01><04> <0C><0E> <09><1D><18>1<>1<><0E>J<18>J<18>Z<1E>2 <0C>z<EFBFBD><19><08>F<EFBFBD>r