33import logging
44import requests
55
6- from helpers import (DEFAULT_HEADERS , process_listing , read_entry ,
7- write_token_entry )
6+ from helpers import (DEFAULT_HEADERS , process_listing )
7+ from entry_io import ( read_entry , write_token_entry , update_token_entry )
88
99CMC_LISTINGS_API_URL = "https://api.coinmarketcap.com/v2/listings/"
1010
1111
12- def get_listings ():
12+ def get_api_listings ():
1313 """
1414 Returns a list of CoinMarketCap-listed currencies via /v2/listings/ API endpoint.
1515
@@ -20,12 +20,12 @@ def get_listings():
2020 return r .json ()["data" ]
2121
2222
23- def map_existing_entries (files , exclude_deprecated = True ):
23+ def map_entries_to_sets (files , key , exclude_deprecated = True ):
2424 """
25- Returns a hash keyed by CoinMarketCap asset ID with sets of Ethereum addresses
26- known to be associated with that asset ID.
25+ Returns a dict keyed by CoinMarketCap asset ID with sets of values for
26+ the given key known to be associated with that asset ID.
2727 """
28- entries = ((entry ["id" ], entry ["address" ])
28+ entries = ((entry ["id" ], entry [key ])
2929 for entry in (read_entry (fn ) for fn in files )
3030 if not (exclude_deprecated and entry .get ("_DEPRECATED" , False )))
3131
@@ -35,46 +35,71 @@ def map_existing_entries(files, exclude_deprecated=True):
3535 }
3636
3737
38- def deprecate_token_entry (address ):
39- old_listing = read_entry ("tokens/{}.yaml" .format (address ))
40- old_listing .update ({"_DEPRECATED" : True })
41- del old_listing ["address" ]
42- write_token_entry (address , old_listing )
38+ def map_entries_to_discrete (files , key , exclude_deprecated = True ):
39+ return {
40+ entry ["id" ]: entry [key ]
41+ for entry in (read_entry (fn ) for fn in files )
42+ if not (exclude_deprecated and entry .get ("_DEPRECATED" , False ))
43+ }
4344
4445
45- def main (listings ):
46+ def main ():
4647 from time import sleep
4748
48- id_to_address = map_existing_entries (sorted (glob ("tokens/0x*.yaml" )))
49+ existing_files = sorted (glob ("tokens/0x*.yaml" ))
50+ id_to_addresses = map_entries_to_sets (existing_files , "address" )
51+ slugs = map_entries_to_discrete (existing_files , "slug" )
52+
53+ api_listings = get_api_listings ()
54+ api_slugs = {e ["id" ]: e ["website_slug" ] for e in api_listings }
55+
56+ slugs .update (api_slugs )
4957
50- for listing in listings :
58+ for ( asset_id , asset_website_slug ) in slugs . items () :
5159 try :
52- result = process_listing (listing )
60+ result = process_listing (asset_website_slug )
5361 except :
5462 logging .exception (
5563 "Final error when trying to process listing for '%s'" ,
56- listing [ "website_slug" ] )
64+ asset_website_slug )
5765 continue
5866
59- (updated_listing , current_addresses ) = result
60-
61- existing_addresses = id_to_address .get (listing ["id" ], set ())
62- for address in existing_addresses - current_addresses :
63- logging .warning ("'%s' has deprecated %s" , listing ["website_slug" ],
64- address )
65- deprecate_token_entry (address )
67+ (listing , current_addresses ) = result
68+
69+ if listing :
70+ assert listing ["id" ] == asset_id
71+
72+ if asset_website_slug != listing ["slug" ]:
73+ logging .warning ("'%s' redirected to slug '%s' when queried" ,
74+ asset_website_slug , listing ['slug' ])
75+
76+ existing_addresses = id_to_addresses .get (asset_id , set ())
77+ # Deal with delisted assets and deprecated addresses
78+ if existing_addresses and listing is None :
79+ # listing is None when the page failed to fetch (404ed)
80+ logging .warning ("'%s' has been delisted" , asset_website_slug )
81+ for address in existing_addresses :
82+ update_token_entry (address , {
83+ "status" : "delisted" ,
84+ "markets" : [],
85+ "rank" : None
86+ })
87+ else :
88+ for address in existing_addresses - current_addresses :
89+ logging .warning ("'%s' has deprecated %s" , asset_website_slug ,
90+ address )
91+ update_token_entry (
92+ address , {
93+ "_DEPRECATED" : True ,
94+ "status" : "deprecated" ,
95+ "markets" : [],
96+ "rank" : None
97+ })
6698
6799 for address in current_addresses :
68- write_token_entry (address , updated_listing )
69-
70- listings_ids = [e ["id" ] for e in listings ]
71- ids_removed_from_listings = id_to_address .keys () - listings_ids
72- for removed_id in ids_removed_from_listings :
73- for removed_asset_address in id_to_address [removed_id ]:
74- deprecate_token_entry (removed_asset_address )
100+ write_token_entry (address , listing )
75101
76102
77103if __name__ == "__main__" :
78104 logging .getLogger ().setLevel (logging .DEBUG )
79-
80- main (get_listings ())
105+ main ()
0 commit comments