def look_at_res(msg, res): """ takes the result from a kodi json command """ if res is not None: success = False if "result" in res and (res["result"] == "OK" or res["result"] == True): success = True # Application.SetVolume returns an integer # JSONRPC.Ping() returns the string 'pong' elif "result" in res and res["result"] == "pong": utils.log("OK ping returned pong") success = True elif "error" in res and "message" in res["error"]: message = (res["error"]["message"]) amsg = ('msg %s %s' % (msg, message)) utils.log(amsg) raise rutils.MyException(amsg) else: message = ("Kodi Unknown error : '%s'" % (res)) amsg = ('msg %s %s' % (msg, message)) utils.log(amsg) raise rutils.MyException(amsg) if success: utils.log("Success") print("Success.") return success
def remove_collection(target): # movies, games,books,pictures,songs,chapters for mv in target.movies.all(): remove_movie(mv) for pc in target.pictures.all(): remove_picture(pc) for sg in target.songs.all(): remove_song(sg) if target.games.all(): raise rutils.MyException('No Way - games are not implemented') if target.books.all(): raise rutils.MyException('No Way - books are not implemented') if target.chapters.all(): raise rutils.MyException('No Way - chapters are not implemented') target.delete()
def playlist_select(playlist, playback, request): """ handle play requests for playlist given playback from choices.songplay caller should catch MyException which is used for all errors in kodi playback """ try: me = models.User.objects.get(username=request.user) except models.User.DoesNotExist: me = None if playback == choices.KODI_LOCAL: utils.log('local') try: clientip = request.META['REMOTE_ADDR'] except KeyError: message = str('ERROR could not get client ip from request') utils.log(message) raise rutils.MyException(message) time.sleep(5) play_to_kodi(playlist, clientip, me) return True elif playback == choices.KODI_LF: utils.log('lf') play_to_kodi(playlist, settings.HOST_LF, me) return True elif playback == choices.KODI_BF: utils.log('bf') time.sleep(5) play_to_kodi(playlist, settings.HOST_BF, me) return True return False
def playlist_requests_new(playlist, pattern, me, request): """ handle play requests for playlist given the html GET request caller should catch MyException which is used for all errors in kodi playback """ if 'kodi_local' == pattern: try: clientip = request.META['REMOTE_ADDR'] except KeyError: message = str('ERROR could not get client ip from request') utils.log(message) raise rutils.MyException(message) time.sleep(5) play_to_kodi(playlist, clientip, me) return True elif 'kodi_lf' == pattern: play_to_kodi(playlist, settings.HOST_LF, me) return True elif 'kodi_bf' == pattern: time.sleep(5) play_to_kodi(playlist, settings.HOST_BF, me) return True return False
def play_kodi(playlist, host, xbmc_i): """ ping kodi and if successful create a playlist and open kodi Control of the playback is passed to kodi on the selected host xbmc_i should be the initialized kodi connection host is unused except in the message for an exception """ ping_result = xbmc_i.JSONRPC.Ping() look_at_res('ping', ping_result) if ping_result: id_context = {'playlistid': settings.KODI_PLAYLIST} repeat_context = {'repeat': 'all'} open_context = {'item': id_context, 'options': repeat_context} # clear the playlist cresult = xbmc_i.Playlist.Clear(id_context) look_at_res('playlist clear', cresult) # add to playlist for ob in playlist: thefile = utils.object_path_samba(ob) acontext = {'file': thefile} pcontext = {'playlistid': settings.KODI_PLAYLIST, 'item': acontext} addresult = xbmc_i.Playlist.Add(pcontext) msg = ('playlist add %s' % thefile) look_at_res(msg, addresult) # play it result = xbmc_i.Player.Open(open_context) look_at_res('playlist open', result) else: message = str('Error unable to ping kodi at host %s' % host) raise rutils.MyException(message)
def discography_list(request): me = rq.get_me(True, request) rutils.cleanup_my_private_directory(me, u'discography') my_path, _ = rutils.my_private_directory(me, u'discography') my_file = (u'%s/d%s%s' % (my_path, datetime.date.today(), u'.html')) context = { 'title': 'Full discography by artist', 'mlist': Musician.objects.all(), 'my_file': my_file } template_name = 'FHLReader/discography.html' content = render_to_string(template_name, context) try: with open(my_file, 'w') as static_file: static_file.write(content.encode('utf8')) except Exception as ex: # would eventually like to catch the correct message message = str('Error writing file %s' % (type(ex).__name__)) print(message) raise rutils.MyException(message) return render(request, template_name, context)
def cast_picture(devs,picture): """ send a given picture to a given chromecast device """ try: chromecasts = pychromecast.get_chromecasts() dev = int(devs) cast = chromecasts[dev] # wait for device to be ready cast.wait() print(cast.device) print(cast.status) mc=cast.media_controller thefile = utils.object_path_web(picture) print('HERE PATH: %s' % (thefile)) mc.play_media(thefile,'imag/jpg') #time.sleep(20) #mc.play() except Exception as ex: # in this case I want to see what the exception is # but there's no way to handle it, just pass it back for display message = str('ChromeCast exception %s' % (type(ex).__name__)) print (message) raise rutils.MyException(message)
def add_musician(aName, aSlug): if aSlug == 'unknown-mus': raise rutils.MyException('No Way - no unknown musicians') if aSlug == 'unknown-artist-mus': raise rutils.MyException('No Way - no unknown-artist musicians') try: dbobj = bmodels.Musician.objects.get(slug__iexact=aSlug) except bmodels.Musician.DoesNotExist: utility.log("---> ADD Musician %s, slug %s" % (aName, aSlug)) for b in bmodels.Musician.objects.all(): if utility.slugCompare(aSlug, b.slug): return b name = unicode(aName) dbobj = bmodels.Musician(fullName=name, slug=aSlug) dbobj.save() return dbobj
def radio_select_christmas(justme,me,target,cl): """ select an appropriate mix of Christmas songs if justme is true include favourites of me target is the start list to select from if cl is true include some classical music """ # no Christmas part big = exclude_ick_xmas(target,False) if justme: if me is None: # should not happen raise rutils.MyException('User-specific radio from anonymous') yuck = Q(dislikes__username=me) start = big.exclude(yuck) else: start = big.filter(dislikes=None) therest = radio_list(start,False,me,False) # Christmas big = only_xmas(target) if justme: if me is None: # should not happen raise rutils.MyException('User-specific radio from anonymous') yuck = Q(dislikes__username=me) start = big.exclude(yuck) else: start = big.filter(dislikes=None) xmas = radio_list(start,False,me,False) radio = christmas(therest, xmas) if justme or cl: return radio_list(radio,justme,me,cl) return radio
def get_me(allow_anon,request): """ get the user name or None if that is permitted otherwise will raise an exception indicating that anonymouse was permitted to do something not permitted """ try: me = bmod.User.objects.get(username=request.user) except bmod.User.DoesNotExist: if allow_anon: me = None else: # should not happen raise rutils.MyException('User-specific view from anonymous') return me
def slideshow_kodi(playlist, host, xbmc_i, me): """ kodi playlist is from a directory, so this annotates the pictures in the playlist and copies them to /tmp/slides-username Still to do: clean up pictures from previous slide shows """ utils.log("picturelist to kodi") try: rutils.cleanup_my_private_directory(me, 'slides') file_path, _ = rutils.my_private_directory(me, 'slides') # put all the pictures in the directory for picture in playlist: _, _ = rutils.annotate(picture, me) ping_result = xbmc_i.JSONRPC.Ping() look_at_res('ping', ping_result) if ping_result: utils.log('after ping with file_path %s' % file_path) path_context = {'directory': file_path} open_context = {'item': path_context} # play it result = xbmc_i.Player.Open(open_context) look_at_res('playlist open', result) else: message = str('Error unable to ping kodi at host %s' % host) raise rutils.MyException(message) except Exception as ex: # in this case I want to see what the exception is # but there's no way to handle it, just give back message message = str('Cannot create/link kodi directory %s' % (type(ex).__name__)) utils.log(message) utils.log(playlist) raise rutils.MyException(message)
def radio_select(justme,me,target,cl): """ Select a list of non-Christmas songs if justme is true include favourites of me target is the start list to select from if cl is true include some classical music """ big = exclude_ick_xmas(target,False) if justme: if me is None: # should not happen raise rutils.MyException('User-specific radio from anonymous') yuck = Q(dislikes__username=me) start = big.exclude(yuck) else: start = big.filter(dislikes=None) return radio_list(start,justme,me,cl)
def find_chrome_casts(): """ find all chromecasts and return an enumerated list """ try: chromecasts, browser = pychromecast.discovery.discover_chromecasts() pychromecast.discovery.stop_discovery(browser) except Exception as ex: # in this case I want to see what the exception is # but there's no way to handle it, just pass it back for display print('failed cc discovery') message = str('Chromecast fail' % (type(ex).__name__)) print (message) raise rutils.MyException(message) res = [] for x in chromecasts: item = chromecasts.index(x),x.device.friendly_name res.append(item) x.disconnect() return res
def radio_list(start,justme,me,cl): """ Get the list of random songs added prefered songs if requested add classical songs if requested """ if justme: if me is None: # should not happen raise rutils.MyException('User-specific radio from anonymous') g1 = Q(likes__username=me) g2 = Q(loves__username=me) set2 = exclude_ick_xmas(bmod.Song.random_objects.filter(g1|g2),cl) if set2.count(): start = mix(start,set2,10) if cl: cq = Q(tags__name__icontains='classical') clst = exclude_ick_xmas(bmod.Song.random_objects.filter(cq),cl) if clst.count(): start = mix(start,clst,25) return start
def play_to_kodi(playlist, ip, me): """ send the playlist to kodi for playback where ip is the ip address of kodi where playback is requested """ host = ip + settings.KODI_PORT utils.log('play_to_kodi host %s' % host) try: xbmc_i = init_xbmc(host) if playlist[0] and playlist[0].fileKind == choices.PICTURE: slideshow_kodi(playlist, host, xbmc_i, me) utils.log('after calling slideshow_kodi') else: play_kodi(playlist, host, xbmc_i) except Exception as ex: # in this case I want to see what the exception is # but there's no way to handle it, just give back message message = str('Cannot init_xbmc host %s exception %s' % (host, type(ex).__name__)) utils.log(message) raise rutils.MyException(message)
def to_kodi(thefile, host, xbmc_i): """ ping kodi and if successful open the player with the file thefile should be the full samba or local path, not the django static file path used for html Control of the playback is passed to kodi on the selected host xbmc_i should be the initialized kodi connection host is unused except in the message for an exception """ ping_result = xbmc_i.JSONRPC.Ping() look_at_res('ping', ping_result) if ping_result: utils.log('File to kodi %s' % thefile) context = {'item': {'file': thefile}} #guess at what a close might look like, not working #cresult = xbmc_i.Player.Close() #look_at_res(cresult) result = xbmc_i.Player.Open(context) look_at_res('Player.Open', result) else: message = str('Error unable to ping kodi at host %s' % host) raise rutils.MyException(message)
def add_members(self, path, drive, kind, tag, knownCollection=None): """ walk the specified directory to populate the database handles (or should handle) all file type errors this is the main connection to the file system """ #print("ADD_MEMBERS path %s" % (path)) sDrive = utility.get_drive(drive) album = None artist = None setPath = os.path.join(settings.MY_MEDIA_FILES_ROOT, sDrive) scanPath = os.path.join(setPath, path) goodPath = os.path.exists(scanPath) if not goodPath: message = ('ERROR path does not exist check drive setup %s' % scanPath) utility.log(message) raise rutils.MyException(message) for root, _, files in os.walk(scanPath): try: myroot = unicode(root[len(setPath):]) if knownCollection is None: album = self.handle_collection(myroot, drive) else: album = knownCollection for obj in files: try: artist = add_file(unicode(root), unicode(obj), myroot, album, kind, tag) except UnicodeDecodeError: print("UnicodeDecodeError file in collection %s" % (album.title)) except IOError: print("IOError file in collection %s file %s" % (album.title, obj)) except UnicodeDecodeError: print("UnicodeDecodeError collection") return album, artist
def cast_slides_all(pictures,me, add_title): """ cast pictures to all chromecast deviced """ try: chromecasts = pychromecast.get_chromecasts() mcs = [] for cc in chromecasts: # get list of ready devices cc.wait() print(cc.device) print(cc.status) mc = cc.media_controller mcs.append(mc) if add_title: # cleanup working directory rutils.cleanup_my_private_directory(me,'slides') for picture in pictures: tmp_file = None if add_title: thefile,tmp_file = rutils.annotate(picture,me) else: thefile = utils.object_path_web(picture) print('HERE PATH: %s' % (thefile)) for mc in mcs: mc.play_media(thefile,'imag/jpg', title=picture.title) time.sleep(20) if add_title: print('remove %s' % tmp_file) os.unlink(tmp_file) for cc in chromecasts: cc.disconnect() except Exception as ex: # in this case I want to see what the exception is # but there's no way to handle it, just pass it back for display message = str('ChromeCast exception %s' % (type(ex).__name__)) print (message) raise rutils.MyException(message)
def cast_slides(devs,pictures,me, add_title): """ pass a list of pictures to the specificed device """ try: chromecasts = pychromecast.get_chromecasts() dev = int(devs) print('slides to %d' % dev) cast = chromecasts[dev] # wait for device to be ready cast.wait() print(cast.device) print(cast.status) mc=cast.media_controller if add_title: # cleanup working directory rutils.cleanup_my_private_directory(me,'slides') for picture in pictures: tmp_file = None if add_title: thefile,tmp_file = rutils.annotate(picture,me) else: thefile = utils.object_path_web(picture) print('HERE PATH: %s' % (thefile)) mc.play_media(thefile,'imag/jpg') time.sleep(20) if add_title: print('remove %s' % tmp_file) os.unlink(tmp_file) cast.disconnect() except Exception as ex: # in this case I want to see what the exception is # but there's no way to handle it, just pass it back for display message = str('ChromeCast exception %s' % (type(ex).__name__)) print (message) raise rutils.MyException(message)
def send_to_kodi(ob, ip, local=False): """ send an object (song, movie) to kodi for playback where ob is the object, ip is the ip address of kodi where playback is requested """ host = ip + settings.KODI_PORT if local: # use files from the local symbols links, no longer required # only need when running from 127.0.0.1 thefile = utils.object_path_local(ob) else: thefile = utils.object_path_samba(ob) try: utils.log("Host %s" % host) utils.log("ip %s" % ip) xbmc_i = init_xbmc(host) to_kodi(thefile, host, xbmc_i) except Exception as ex: # in this case I want to see what the exception is # but there's no way to handle it, just pass it back for display message = str('Cannot init_xbmc host %s exception %s' % (host, type(ex).__name__)) utils.log(message) raise rutils.MyException(message)