Add spotify_uri_to_int(uri) util function
This commit is contained in:
parent
85ee2b71a1
commit
e27438bcec
@ -37,3 +37,49 @@ def unpickle_connection(pickled_connection):
|
||||
# From http://stackoverflow.com/questions/1446004
|
||||
(func, args) = pickle.loads(pickled_connection)
|
||||
return func(*args)
|
||||
|
||||
def spotify_uri_to_int(uri, output_bits=31):
|
||||
"""
|
||||
Stable one-way translation from Spotify URI to 31-bit integer.
|
||||
|
||||
Spotify track URIs has 62^22 possible values, which requires 131 bits of
|
||||
storage. The original MPD server uses 32-bit unsigned integers for track
|
||||
IDs. GMPC seems to think the track ID is a signed integer, thus we use 31
|
||||
output bits.
|
||||
|
||||
In other words, this function throws away 100 bits of information. Since we
|
||||
only use the track IDs to identify a track within a single Mopidy instance,
|
||||
this information loss is acceptable. The chances of getting two different
|
||||
tracks with the same track ID loaded in the same Mopidy instance is still
|
||||
rather slim. 1 to 2,147,483,648 to be exact.
|
||||
|
||||
Normal usage, with data loss::
|
||||
|
||||
>>> spotify_uri_to_int('spotify:track:5KRRcT67VNIZUygEbMoIC1')
|
||||
624351954
|
||||
|
||||
No data loss, may be converted back into a Spotify URI::
|
||||
|
||||
>>> spotify_uri_to_int('spotify:track:5KRRcT67VNIZUygEbMoIC1',
|
||||
... output_bits=131)
|
||||
101411513484007705241035418492696638725L
|
||||
|
||||
:param uri: Spotify URI on the format ``spotify:track:*``
|
||||
:type uri: string
|
||||
:param output_bits: number of bits of information kept in the return value
|
||||
:type output_bits: int
|
||||
:rtype: int
|
||||
"""
|
||||
|
||||
CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
BITS_PER_CHAR = 6 # int(math.ceil(math.log(len(CHARS), 2)))
|
||||
|
||||
key = uri.split(':')[-1]
|
||||
full_id = 0
|
||||
for i, char in enumerate(key):
|
||||
full_id ^= CHARS.index(char) << BITS_PER_CHAR * i
|
||||
compressed_id = 0
|
||||
while full_id != 0:
|
||||
compressed_id ^= (full_id & (2 ** output_bits - 1))
|
||||
full_id >>= output_bits
|
||||
return int(compressed_id)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user