Update icecast2 FIP relay using HTTP/Json API http://zmpd.zered.net:8042/fip-metadata.mp3
python
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fip_current.py 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #!/usr/bin/python3
  2. #
  3. # Copyright 2016 Yann Weber
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. import requests
  18. import configparser
  19. from argparse import ArgumentParser
  20. API_URL = 'http://www.fipradio.fr/livemeta/7'
  21. def main():
  22. """ Parse arguments and run wanted function """
  23. parser = ArgumentParser(description="Fetch FIP radio stream metadata")
  24. parser.add_argument(
  25. '-u', '--icecast-update',
  26. dest='update',
  27. action='store_const',
  28. const=True,
  29. default=False,
  30. help="Run Icecast2 metadata update")
  31. parser.add_argument(
  32. '-c', '--config',
  33. dest='conf',
  34. type=str,
  35. default='conf.ini',
  36. help="Configuration file")
  37. args = parser.parse_args()
  38. if args.update:
  39. conf = configparser.ConfigParser()
  40. conf.read(args.conf)
  41. host = conf.get('conf', 'host', fallback='127.0.0.1:8000')
  42. mount = conf.get('conf', 'mount', fallback='/example.ogg')
  43. login = conf.get('conf', 'login', fallback='admin')
  44. password = conf.get('conf', 'password', fallback='hackme')
  45. icecast_update(host, mount, login, password)
  46. else:
  47. print(format_current())
  48. def get_all():
  49. """ Return a dict containing all FIP API metadatas """
  50. res = requests.get(API_URL)
  51. if res.status_code != 200:
  52. msg = "Got status code %d for %s"
  53. msg %= (res.status_code, API_URL)
  54. raise RuntimeError(msg)
  55. return res.json()
  56. def get_current():
  57. """ Return a dict containing currently playing song metadatas """
  58. datas = get_all()
  59. position = datas['levels'][0]['position']
  60. item_id = datas['levels'][0]['items'][position]
  61. item = datas['steps'][item_id]
  62. expt = ['authors', 'title', 'titreAlbum', 'visual', 'lienYoutube']
  63. for k in expt:
  64. if k not in item:
  65. item[k] = ''
  66. return item
  67. def format_current():
  68. """ Return a string representing formated current playing song
  69. metadatas """
  70. item = get_current()
  71. infos = """Title :\t\t{title}
  72. Authors :\t{author}
  73. Album :\t\t{album}
  74. Visual :\t{image}
  75. Youtube :\t{youtube}
  76. """
  77. return infos.format(
  78. title=item['title'].title(),
  79. author=item['authors'].title(),
  80. album=item['titreAlbum'].title(),
  81. image=item['visual'],
  82. youtube=item['lienYoutube'])
  83. def icecast_infos():
  84. """ Return formated Icecast2 metadatas from FIP current song
  85. metadatas """
  86. item = get_current()
  87. infos = item['title']
  88. if len(item['authors']) > 0:
  89. infos += ' - '+item['authors']
  90. if len(item['titreAlbum']):
  91. infos += ' ('+item['titreAlbum']+')'
  92. return infos
  93. def icecast_update(host, mount, login=None, password=None):
  94. """ Update metadatas to an Icecast2 mount """
  95. infos = icecast_infos()
  96. url = "http://{host}/admin/metadata"
  97. url = url.format(host=host)
  98. params = {
  99. 'mount': mount,
  100. 'mode': 'updinfo',
  101. 'song': infos}
  102. auth = None
  103. if login is not None and password is not None:
  104. auth = (login, password)
  105. try:
  106. res = requests.get(url, auth=auth, params=params)
  107. except requests.exceptions.ConnectionError:
  108. raise RuntimeError("Connection refuse for "+res.url)
  109. if res.status_code != 200:
  110. msg = "Got status code %d for %s"
  111. msg %= (res.status_code, res.url)
  112. raise RuntimeError(msg)
  113. if __name__ == '__main__':
  114. main()