3 # viz dokumentaci k api https://rapidoc.croapp.cz/
11 from mutagen
.mp3
import MP3
, EasyMP3
12 from mutagen
.easyid3
import EasyID3
13 from mutagen
.id3
import ID3
14 from mutagen
.apev2
import APEv2
, APEv2File
, APENoHeaderError
16 class SessionL(requests
.Session
): # requests Session s automatickým logováním GET požadavků
17 def get_logged(self
, url
, *aargs
, **kwargs
):
18 logging
.info("GET " + url
)
20 r
= self
.get(url
, *aargs
, **kwargs
)
21 except requests
.exceptions
.RequestException
as e
:
22 logging
.warn('Chyba spojení, zkouším znova...')
24 time
.sleep(prodleva
*5)
25 r
= self
.get(url
, *aargs
, **kwargs
)
26 logging
.info(r
.status_code
)
29 def vyžer_vš
e(self
, url
, *aargs
, **kwargs
):
30 r
= self
.get_logged(url
, *aargs
, **kwargs
)
35 while rj
['links']['next'] is not None:
36 r
= self
.get_logged(rj
['links']['next'], *aargs
, **kwargs
)
38 data
.extend(rj
['data'])
41 return {'meta': meta
, 'data': data
}
43 headers
={'user-agent':'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0',
44 'accept-language':'cs',
45 'cache-control':'max-age=0',
47 'upgrade-insecure-requests':'1',
48 'accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
52 s
.headers
.update(headers
)
53 s
.verify
=False # kašlem na ověření TSL certifikátu
54 requests
.urllib3
.disable_warnings() # fujka
56 # Zde je natvrdo link na dětské pořady, ostatní možnosti viz na adrese https://api.mujrozhlas.cz/episodes/
57 episody
= s
.vyžer_vš
e("https://api.mujrozhlas.cz/topics/8ed08518-9d92-437c-a96f-e5df046aff4e/episodes")
59 # složky napevno napraseny
61 dir_origfilename
= os
.path
.join(prefix
, 'by_origfilename')
62 #dir_ep_uuid = os.path.join(prefix, 'by_episode_id')
63 dir_human
= os
.path
.join(prefix
, 'pořady')
64 dir_meta
= os
.path
.join(prefix
, 'meta')
65 os
.makedirs(dir_origfilename
, exist_ok
= True)
66 #os.makedirs(dir_ep_uuid, exist_ok = True)
67 os
.makedirs(dir_human
, exist_ok
= True)
68 os
.makedirs(dir_meta
, exist_ok
= True)
70 for ep
in episody
['data']:
71 al
= ep
['attributes']['audioLinks']
73 logging
.warn("Nalezeno víc audio odkazů, používám první" + str(al
))
75 orig_filename
= al_url
.split('/')[-1]
76 dlpath
= os
.path
.join(dir_origfilename
, orig_filename
)
77 metapath
= os
.path
.join(dir_meta
, orig_filename
+ '.json')
78 if os
.path
.exists(metapath
):
79 logging
.info(metapath
+ " existuje, už zjevně staženo")
81 r
= s
.get_logged(al_url
)
82 if r
.status_code
!= 200:
83 logging
.warn("Divná odpověď %d, ignoruji a jedu dál (%s)" % (r
.status_code
, al_url
))
85 with
open(dlpath
, 'wb') as fil
:
92 ape
= APEv2File(dlpath
)
93 except APENoHeaderError
:
95 title
= ep
['attributes']['shortTitle']
97 part
= ep
['attributes']['part']
98 ape
['Track'] = str(part
)
100 ape
['TotalParts'] = str(ep
['attributes']['mirroredSerial']['totalParts'])
103 show
= ep
['attributes']['mirroredShow']['title']
105 ape
['ShowUrl'] = ep
['relationships']['show']['links']['related']
106 ape
['EpisodeId'] = ep
['id']
108 for key
, val
in id3tags
.items():
109 ape
['id3_'+key
] = val
111 targetdir
= os
.path
.join(dir_human
, show
, title
) if part
is not None else(
112 os
.path
.join(dir_human
, show
) )
113 os
.makedirs(targetdir
, exist_ok
=True)
114 targetpath
= os
.path
.join(targetdir
, '%s_%d.mp3'%(title
, part
) if part
is not None else '%s.mp3'%(title
,))
115 os
.link(dlpath
, targetpath
)
116 # Nakonec si uložíme metadat (čímž taky budeme vědět, že jsme si danou episodu už stáhli)
117 requests
.compat
.json
.dump(ep
, open(metapath
, 'w'), indent
=' ')