Esempio n. 1
0
    def test_update_client_prefs(self):
        self._login('alice', 'Alic3')
        self.skipTest('Hello logger')
        rv = self.client.post('/user/me')
        self.assertIn('updated', rv.data) # does nothing, says it's updated anyway
        # error cases, silently ignored
        self.client.post('/user/me', data = { 'garbage': 'trash' })
        self.client.post('/user/me', data = { 'a_b_c_d_e_f': 'g_h_i_j_k' })
        self.client.post('/user/me', data = { '_l': 'm' })
        self.client.post('/user/me', data = { 'n_': 'o' })
        self.client.post('/user/me', data = { 'inexisting_client': 'setting' })

        prefs = ClientPrefs()
        prefs.user_id = self.users['alice'].id
        prefs.client_name = 'tests'
        self.store.add(prefs)
        self.store.commit()

        rv = self.client.post('/user/me', data = { 'tests_format': 'mp3', 'tests_bitrate': 128 })
        self.assertIn('updated', rv.data)
        self.assertEqual(prefs.format, 'mp3')
        self.assertEqual(prefs.bitrate, 128)

        self.client.post('/user/me', data = { 'tests_delete': 1 })
        self.assertEqual(self.store.find(ClientPrefs).count(), 0)
Esempio n. 2
0
    def test_update_client_prefs(self):
        self._login('alice', 'Alic3')
        self.skipTest('Hello logger')
        rv = self.client.post('/user/me')
        self.assertIn('updated',
                      rv.data)  # does nothing, says it's updated anyway
        # error cases, silently ignored
        self.client.post('/user/me', data={'garbage': 'trash'})
        self.client.post('/user/me', data={'a_b_c_d_e_f': 'g_h_i_j_k'})
        self.client.post('/user/me', data={'_l': 'm'})
        self.client.post('/user/me', data={'n_': 'o'})
        self.client.post('/user/me', data={'inexisting_client': 'setting'})

        prefs = ClientPrefs()
        prefs.user_id = self.users['alice'].id
        prefs.client_name = 'tests'
        self.store.add(prefs)
        self.store.commit()

        rv = self.client.post('/user/me',
                              data={
                                  'tests_format': 'mp3',
                                  'tests_bitrate': 128
                              })
        self.assertIn('updated', rv.data)
        self.assertEqual(prefs.format, 'mp3')
        self.assertEqual(prefs.bitrate, 128)

        self.client.post('/user/me', data={'tests_delete': 1})
        self.assertEqual(self.store.find(ClientPrefs).count(), 0)
Esempio n. 3
0
    def test_set_rating(self):
        self._make_request('setRating', error = 10)
        self._make_request('setRating', { 'id': str(self.trackid) }, error = 10)
        self._make_request('setRating', { 'rating': 3 }, error = 10)
        self._make_request('setRating', { 'id': 'string', 'rating': 3 }, error = 0)
        self._make_request('setRating', { 'id': str(uuid.uuid4()), 'rating': 3 }, error = 70)
        self._make_request('setRating', { 'id': str(self.artistid), 'rating': 3 }, error = 70)
        self._make_request('setRating', { 'id': str(self.albumid), 'rating': 3 }, error = 70)
        self._make_request('setRating', { 'id': str(self.trackid), 'rating': 'string' }, error = 0)
        self._make_request('setRating', { 'id': str(self.trackid), 'rating': -1 }, error = 0)
        self._make_request('setRating', { 'id': str(self.trackid), 'rating': 6 }, error = 0)

        with db_session:
            prefs = ClientPrefs.get(lambda p: p.user.name == 'alice' and p.client_name == 'tests')
            self.assertNotIn('userRating', Track[self.trackid].as_subsonic_child(self.user, prefs))

        for i in range(1, 6):
            self._make_request('setRating', { 'id': str(self.trackid), 'rating': i }, skip_post = True)
            with db_session:
                prefs = ClientPrefs.get(lambda p: p.user.name == 'alice' and p.client_name == 'tests')
                self.assertEqual(Track[self.trackid].as_subsonic_child(self.user, prefs)['userRating'], i)

        self._make_request('setRating', { 'id': str(self.trackid), 'rating': 0 }, skip_post = True)
        with db_session:
            prefs = ClientPrefs.get(lambda p: p.user.name == 'alice' and p.client_name == 'tests')
            self.assertNotIn('userRating', Track[self.trackid].as_subsonic_child(self.user, prefs))

            self.assertNotIn('userRating', Folder[self.folderid].as_subsonic_child(self.user))
        for i in range(1, 6):
            self._make_request('setRating', { 'id': str(self.folderid), 'rating': i }, skip_post = True)
            with db_session:
                self.assertEqual(Folder[self.folderid].as_subsonic_child(self.user)['userRating'], i)
        self._make_request('setRating', { 'id': str(self.folderid), 'rating': 0 }, skip_post = True)
        with db_session:
            self.assertNotIn('userRating', Folder[self.folderid].as_subsonic_child(self.user))
Esempio n. 4
0
    def test_details(self):
        self._login('alice', 'Alic3')
        rv = self.client.get('/user/string', follow_redirects=True)
        self.assertIn('Invalid', rv.data)
        rv = self.client.get('/user/' + str(uuid.uuid4()),
                             follow_redirects=True)
        self.assertIn('No such user', rv.data)
        rv = self.client.get('/user/' + str(self.users['bob'].id))
        self.assertIn('bob', rv.data)
        self._logout()

        prefs = ClientPrefs()
        prefs.user_id = self.users['bob'].id
        prefs.client_name = 'tests'
        self.store.add(prefs)
        self.store.commit()

        self._login('bob', 'B0b')
        rv = self.client.get('/user/' + str(self.users['alice'].id),
                             follow_redirects=True)
        self.assertIn('There\'s nothing much to see', rv.data)
        self.assertNotIn('<h2>bob</h2>', rv.data)
        rv = self.client.get('/user/me')
        self.assertIn('<h2>bob</h2>', rv.data)
        self.assertIn('tests', rv.data)
Esempio n. 5
0
    def test_update_client_prefs(self):
        self._login("alice", "Alic3")
        rv = self.client.post("/user/me")
        self.assertIn("updated",
                      rv.data)  # does nothing, says it's updated anyway
        # error cases, silently ignored
        self.client.post("/user/me", data={"garbage": "trash"})
        self.client.post("/user/me", data={"a_b_c_d_e_f": "g_h_i_j_k"})
        self.client.post("/user/me", data={"_l": "m"})
        self.client.post("/user/me", data={"n_": "o"})
        self.client.post("/user/me", data={"inexisting_client": "setting"})

        with db_session:
            ClientPrefs(user=User[self.users["alice"]], client_name="tests")

        rv = self.client.post("/user/me",
                              data={
                                  "tests_format": "mp3",
                                  "tests_bitrate": 128
                              })
        self.assertIn("updated", rv.data)
        with db_session:
            prefs = ClientPrefs[User[self.users["alice"]], "tests"]
            self.assertEqual(prefs.format, "mp3")
            self.assertEqual(prefs.bitrate, 128)

        self.client.post("/user/me", data={"tests_delete": 1})
        with db_session:
            self.assertEqual(ClientPrefs.select().count(), 0)
Esempio n. 6
0
    def test_unstar(self):
        self._make_request('star', {
            'id': [str(self.folder.id),
                   str(self.track.id)],
            'artistId': str(self.artist.id),
            'albumId': str(self.album.id)
        },
                           skip_post=True)

        self._make_request('unstar', error=10)
        self._make_request('unstar', {'id': 'unknown'}, error=0, skip_xsd=True)
        self._make_request('unstar', {'albumId': 'unknown'}, error=0)
        self._make_request('unstar', {'artistId': 'unknown'}, error=0)

        self._make_request('unstar', {'id': str(self.track.id)},
                           skip_post=True)
        self.assertNotIn(
            'starred', self.track.as_subsonic_child(self.user, ClientPrefs()))

        self._make_request('unstar', {'id': str(self.folder.id)},
                           skip_post=True)
        self.assertNotIn('starred', self.folder.as_subsonic_child(self.user))

        self._make_request('unstar', {'albumId': str(self.album.id)},
                           skip_post=True)
        self.assertNotIn('starred', self.album.as_subsonic_album(self.user))

        self._make_request('unstar', {'artistId': str(self.artist.id)},
                           skip_post=True)
        self.assertNotIn('starred', self.artist.as_subsonic_artist(self.user))
Esempio n. 7
0
    def test_star(self):
        self._make_request('star', error=10)
        self._make_request('star', {'id': 'unknown'}, error=0, skip_xsd=True)
        self._make_request('star', {'albumId': 'unknown'}, error=0)
        self._make_request('star', {'artistId': 'unknown'}, error=0)
        self._make_request('star', {'id': str(uuid.uuid4())},
                           error=70,
                           skip_xsd=True)
        self._make_request('star', {'albumId': str(uuid.uuid4())}, error=70)
        self._make_request('star', {'artistId': str(uuid.uuid4())}, error=70)

        self._make_request('star', {'id': str(self.artistid)},
                           error=70,
                           skip_xsd=True)
        self._make_request('star', {'id': str(self.albumid)},
                           error=70,
                           skip_xsd=True)
        self._make_request('star', {'id': str(self.trackid)}, skip_post=True)
        with db_session:
            prefs = ClientPrefs.get(
                lambda p: p.user.name == 'alice' and p.client_name == 'tests')
            self.assertIn(
                'starred',
                Track[self.trackid].as_subsonic_child(self.user, prefs))
        self._make_request('star', {'id': str(self.trackid)},
                           error=0,
                           skip_xsd=True)

        self._make_request('star', {'id': str(self.folderid)}, skip_post=True)
        with db_session:
            self.assertIn('starred',
                          Folder[self.folderid].as_subsonic_child(self.user))
        self._make_request('star', {'id': str(self.folderid)},
                           error=0,
                           skip_xsd=True)

        self._make_request('star', {'albumId': str(self.folderid)}, error=70)
        self._make_request('star', {'albumId': str(self.artistid)}, error=70)
        self._make_request('star', {'albumId': str(self.trackid)}, error=70)
        self._make_request('star', {'albumId': str(self.albumid)},
                           skip_post=True)
        with db_session:
            self.assertIn('starred',
                          Album[self.albumid].as_subsonic_album(self.user))
        self._make_request('star', {'albumId': str(self.albumid)}, error=0)

        self._make_request('star', {'artistId': str(self.folderid)}, error=70)
        self._make_request('star', {'artistId': str(self.albumid)}, error=70)
        self._make_request('star', {'artistId': str(self.trackid)}, error=70)
        self._make_request('star', {'artistId': str(self.artistid)},
                           skip_post=True)
        with db_session:
            self.assertIn('starred',
                          Artist[self.artistid].as_subsonic_artist(self.user))
        self._make_request('star', {'artistId': str(self.artistid)}, error=0)
Esempio n. 8
0
    def test_star(self):
        self._make_request("star", error=10)
        self._make_request("star", {"id": "unknown"}, error=0, skip_xsd=True)
        self._make_request("star", {"albumId": "unknown"}, error=0)
        self._make_request("star", {"artistId": "unknown"}, error=0)
        self._make_request("star", {"id": str(uuid.uuid4())},
                           error=70,
                           skip_xsd=True)
        self._make_request("star", {"albumId": str(uuid.uuid4())}, error=70)
        self._make_request("star", {"artistId": str(uuid.uuid4())}, error=70)

        self._make_request("star", {"id": str(self.artistid)},
                           error=70,
                           skip_xsd=True)
        self._make_request("star", {"id": str(self.albumid)},
                           error=70,
                           skip_xsd=True)
        self._make_request("star", {"id": str(self.trackid)}, skip_post=True)
        with db_session:
            prefs = ClientPrefs.get(
                lambda p: p.user.name == "alice" and p.client_name == "tests")
            self.assertIn(
                "starred",
                Track[self.trackid].as_subsonic_child(self.user, prefs))
        self._make_request("star", {"id": str(self.trackid)},
                           error=0,
                           skip_xsd=True)

        self._make_request("star", {"id": str(self.folderid)}, skip_post=True)
        with db_session:
            self.assertIn("starred",
                          Folder[self.folderid].as_subsonic_child(self.user))
        self._make_request("star", {"id": str(self.folderid)},
                           error=0,
                           skip_xsd=True)

        self._make_request("star", {"albumId": str(self.folderid)}, error=0)
        self._make_request("star", {"albumId": str(self.artistid)}, error=70)
        self._make_request("star", {"albumId": str(self.trackid)}, error=70)
        self._make_request("star", {"albumId": str(self.albumid)},
                           skip_post=True)
        with db_session:
            self.assertIn("starred",
                          Album[self.albumid].as_subsonic_album(self.user))
        self._make_request("star", {"albumId": str(self.albumid)}, error=0)

        self._make_request("star", {"artistId": str(self.folderid)}, error=0)
        self._make_request("star", {"artistId": str(self.albumid)}, error=70)
        self._make_request("star", {"artistId": str(self.trackid)}, error=70)
        self._make_request("star", {"artistId": str(self.artistid)},
                           skip_post=True)
        with db_session:
            self.assertIn("starred",
                          Artist[self.artistid].as_subsonic_artist(self.user))
        self._make_request("star", {"artistId": str(self.artistid)}, error=0)
Esempio n. 9
0
    def test_details(self):
        self._login('alice', 'Alic3')
        rv = self.client.get('/user/string', follow_redirects = True)
        self.assertIn('Invalid', rv.data)
        rv = self.client.get('/user/' + str(uuid.uuid4()), follow_redirects = True)
        self.assertIn('No such user', rv.data)
        rv = self.client.get('/user/' + str(self.users['bob'].id))
        self.assertIn('bob', rv.data)
        self._logout()

        prefs = ClientPrefs()
        prefs.user_id = self.users['bob'].id
        prefs.client_name = 'tests'
        self.store.add(prefs)
        self.store.commit()

        self._login('bob', 'B0b')
        rv = self.client.get('/user/' + str(self.users['alice'].id), follow_redirects = True)
        self.assertIn('There\'s nothing much to see', rv.data)
        self.assertNotIn('<h2>bob</h2>', rv.data)
        rv = self.client.get('/user/me')
        self.assertIn('<h2>bob</h2>', rv.data)
        self.assertIn('tests', rv.data)
Esempio n. 10
0
    def test_details(self):
        self._login("alice", "Alic3")
        rv = self.client.get("/user/string", follow_redirects=True)
        self.assertIn("badly formed", rv.data)
        rv = self.client.get("/user/" + str(uuid.uuid4()), follow_redirects=True)
        self.assertIn("No such user", rv.data)
        rv = self.client.get("/user/" + str(self.users["bob"]))
        self.assertIn("bob", rv.data)
        self._logout()

        with db_session:
            ClientPrefs(user=User[self.users["bob"]], client_name="tests")

        self._login("bob", "B0b")
        rv = self.client.get("/user/" + str(self.users["alice"]), follow_redirects=True)
        self.assertIn("There's nothing much to see", rv.data)
        self.assertNotIn("<h2>bob</h2>", rv.data)
        rv = self.client.get("/user/me")
        self.assertIn("<h2>bob</h2>", rv.data)
        self.assertIn("tests", rv.data)
Esempio n. 11
0
    def test_star(self):
        self._make_request('star', error = 10)
        self._make_request('star', { 'id': 'unknown' }, error = 0, skip_xsd = True)
        self._make_request('star', { 'albumId': 'unknown' }, error = 0)
        self._make_request('star', { 'artistId': 'unknown' }, error = 0)
        self._make_request('star', { 'id': str(uuid.uuid4()) }, error = 70, skip_xsd = True)
        self._make_request('star', { 'albumId': str(uuid.uuid4()) }, error = 70)
        self._make_request('star', { 'artistId': str(uuid.uuid4()) }, error = 70)

        self._make_request('star', { 'id': str(self.artistid) }, error = 70, skip_xsd = True)
        self._make_request('star', { 'id': str(self.albumid) }, error = 70, skip_xsd = True)
        self._make_request('star', { 'id': str(self.trackid) }, skip_post = True)
        with db_session:
            prefs = ClientPrefs.get(lambda p: p.user.name == 'alice' and p.client_name == 'tests')
            self.assertIn('starred', Track[self.trackid].as_subsonic_child(self.user, prefs))
        self._make_request('star', { 'id': str(self.trackid) }, error = 0, skip_xsd = True)

        self._make_request('star', { 'id': str(self.folderid) }, skip_post = True)
        with db_session:
            self.assertIn('starred', Folder[self.folderid].as_subsonic_child(self.user))
        self._make_request('star', { 'id': str(self.folderid) }, error = 0, skip_xsd = True)

        self._make_request('star', { 'albumId': str(self.folderid) }, error = 70)
        self._make_request('star', { 'albumId': str(self.artistid) }, error = 70)
        self._make_request('star', { 'albumId': str(self.trackid) }, error = 70)
        self._make_request('star', { 'albumId': str(self.albumid) }, skip_post = True)
        with db_session:
            self.assertIn('starred', Album[self.albumid].as_subsonic_album(self.user))
        self._make_request('star', { 'albumId': str(self.albumid) }, error = 0)

        self._make_request('star', { 'artistId': str(self.folderid) }, error = 70)
        self._make_request('star', { 'artistId': str(self.albumid) }, error = 70)
        self._make_request('star', { 'artistId': str(self.trackid) }, error = 70)
        self._make_request('star', { 'artistId': str(self.artistid) }, skip_post = True)
        with db_session:
            self.assertIn('starred', Artist[self.artistid].as_subsonic_artist(self.user))
        self._make_request('star', { 'artistId': str(self.artistid) }, error = 0)
Esempio n. 12
0
    def test_set_rating(self):
        self._make_request("setRating", error=10)
        self._make_request("setRating", {"id": str(self.trackid)}, error=10)
        self._make_request("setRating", {"rating": 3}, error=10)
        self._make_request("setRating", {"id": "string", "rating": 3}, error=0)
        self._make_request("setRating", {
            "id": str(uuid.uuid4()),
            "rating": 3
        },
                           error=70)
        self._make_request("setRating", {
            "id": str(self.artistid),
            "rating": 3
        },
                           error=70)
        self._make_request("setRating", {
            "id": str(self.albumid),
            "rating": 3
        },
                           error=70)
        self._make_request("setRating", {
            "id": str(self.trackid),
            "rating": "string"
        },
                           error=0)
        self._make_request("setRating", {
            "id": str(self.trackid),
            "rating": -1
        },
                           error=0)
        self._make_request("setRating", {
            "id": str(self.trackid),
            "rating": 6
        },
                           error=0)

        with db_session:
            prefs = ClientPrefs.get(
                lambda p: p.user.name == "alice" and p.client_name == "tests")
            self.assertNotIn(
                "userRating",
                Track[self.trackid].as_subsonic_child(self.user, prefs))

        for i in range(1, 6):
            self._make_request("setRating", {
                "id": str(self.trackid),
                "rating": i
            },
                               skip_post=True)
            with db_session:
                prefs = ClientPrefs.get(lambda p: p.user.name == "alice" and p.
                                        client_name == "tests")
                self.assertEqual(
                    Track[self.trackid].as_subsonic_child(self.user,
                                                          prefs)["userRating"],
                    i,
                )

        self._make_request("setRating", {
            "id": str(self.trackid),
            "rating": 0
        },
                           skip_post=True)
        with db_session:
            prefs = ClientPrefs.get(
                lambda p: p.user.name == "alice" and p.client_name == "tests")
            self.assertNotIn(
                "userRating",
                Track[self.trackid].as_subsonic_child(self.user, prefs))

            self.assertNotIn(
                "userRating",
                Folder[self.folderid].as_subsonic_child(self.user))
        for i in range(1, 6):
            self._make_request("setRating", {
                "id": str(self.folderid),
                "rating": i
            },
                               skip_post=True)
            with db_session:
                self.assertEqual(
                    Folder[self.folderid].as_subsonic_child(
                        self.user)["userRating"], i)
        self._make_request("setRating", {
            "id": str(self.folderid),
            "rating": 0
        },
                           skip_post=True)
        with db_session:
            self.assertNotIn(
                "userRating",
                Folder[self.folderid].as_subsonic_child(self.user))
Esempio n. 13
0
def stream_media():
	status, res = get_entity(request, Track)
	if not status:
		return res

	maxBitRate, format, timeOffset, size, estimateContentLength, client = map(request.values.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength', 'c' ])
	if format:
		format = format.lower()

	src_suffix = res.suffix()
	dst_suffix = res.suffix()
	dst_bitrate = res.bitrate
	dst_mimetype = res.content_type

	if client:
		prefs = store.get(ClientPrefs, (request.user.id, client))
		if not prefs:
			prefs = ClientPrefs()
			prefs.user_id = request.user.id
			prefs.client_name = client
			store.add(prefs)

		if prefs.format:
			dst_suffix = prefs.format
		if prefs.bitrate and prefs.bitrate < dst_bitrate:
			dst_bitrate = prefs.bitrate

	if maxBitRate:
		try:
			maxBitRate = int(maxBitRate)
		except:
			return request.error_formatter(0, 'Invalid bitrate value')

		if dst_bitrate > maxBitRate and maxBitRate != 0:
			dst_bitrate = maxBitRate

	if format and format != 'raw' and format != src_suffix:
		dst_suffix = format
		dst_mimetype = scanner.get_mime(dst_suffix)

	if format != 'raw' and (dst_suffix != src_suffix or dst_bitrate != res.bitrate):
		transcoder = config.get('transcoding', 'transcoder_{}_{}'.format(src_suffix, dst_suffix))
		decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder')
		encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder')
		if not transcoder and (not decoder or not encoder):
			transcoder = config.get('transcoding', 'transcoder')
			if not transcoder:
				return request.error_formatter(0, 'No way to transcode from {} to {}'.format(src_suffix, dst_suffix))

		transcoder, decoder, encoder = map(lambda x: prepare_transcoding_cmdline(x, res.path, src_suffix, dst_suffix, dst_bitrate), [ transcoder, decoder, encoder ])
		try:
			if transcoder:
				dec_proc = None
				proc = subprocess.Popen(transcoder, stdout = subprocess.PIPE)
			else:
				dec_proc = subprocess.Popen(decoder, stdout = subprocess.PIPE)
				proc = subprocess.Popen(encoder, stdin = dec_proc.stdout, stdout = subprocess.PIPE)
		except:
			return request.error_formatter(0, 'Error while running the transcoding process')

		def transcode():
			try:
				while True:
					data = proc.stdout.read(8192)
					if not data:
						break
					yield data
			except:
				if dec_proc != None:
					dec_proc.terminate()
				proc.terminate()

			if dec_proc != None:
				dec_proc.wait()
			proc.wait()

		app.logger.info('Transcoding track {0.id} for user {1.id}. Source: {2} at {0.bitrate}kbps. Dest: {3} at {4}kbps'.format(res, request.user, src_suffix, dst_suffix, dst_bitrate))
		response = Response(transcode(), mimetype = dst_mimetype)
	else:
		response = send_file(res.path, mimetype = dst_mimetype)

	res.play_count = res.play_count + 1
	res.last_play = now()
	request.user.last_play = res
	request.user.last_play_date = now()
	store.commit()

	return response
Esempio n. 14
0
    def test_set_rating(self):
        self._make_request('setRating', error=10)
        self._make_request('setRating', {'id': str(self.track.id)}, error=10)
        self._make_request('setRating', {'rating': 3}, error=10)
        self._make_request('setRating', {'id': 'string', 'rating': 3}, error=0)
        self._make_request('setRating', {
            'id': str(uuid.uuid4()),
            'rating': 3
        },
                           error=70)
        self._make_request('setRating', {
            'id': str(self.artist.id),
            'rating': 3
        },
                           error=70)
        self._make_request('setRating', {
            'id': str(self.album.id),
            'rating': 3
        },
                           error=70)
        self._make_request('setRating', {
            'id': str(self.track.id),
            'rating': 'string'
        },
                           error=0)
        self._make_request('setRating', {
            'id': str(self.track.id),
            'rating': -1
        },
                           error=0)
        self._make_request('setRating', {
            'id': str(self.track.id),
            'rating': 6
        },
                           error=0)

        prefs = ClientPrefs()
        self.assertNotIn('userRating',
                         self.track.as_subsonic_child(self.user, prefs))

        for i in range(1, 6):
            self._make_request('setRating', {
                'id': str(self.track.id),
                'rating': i
            },
                               skip_post=True)
            self.assertEqual(
                self.track.as_subsonic_child(self.user, prefs)['userRating'],
                i)
        self._make_request('setRating', {
            'id': str(self.track.id),
            'rating': 0
        },
                           skip_post=True)
        self.assertNotIn('userRating',
                         self.track.as_subsonic_child(self.user, prefs))

        self.assertNotIn('userRating',
                         self.folder.as_subsonic_child(self.user))
        for i in range(1, 6):
            self._make_request('setRating', {
                'id': str(self.folder.id),
                'rating': i
            },
                               skip_post=True)
            self.assertEqual(
                self.folder.as_subsonic_child(self.user)['userRating'], i)
        self._make_request('setRating', {
            'id': str(self.folder.id),
            'rating': 0
        },
                           skip_post=True)
        self.assertNotIn('userRating',
                         self.folder.as_subsonic_child(self.user))
Esempio n. 15
0
def stream_media():
	status, res = get_entity(request, Track)
	if not status:
		return res

	maxBitRate, format, timeOffset, size, estimateContentLength, client = map(request.args.get, [ 'maxBitRate', 'format', 'timeOffset', 'size', 'estimateContentLength', 'c' ])
	if format:
		format = format.lower()

	src_suffix = res.suffix()
	dst_suffix = res.suffix()
	dst_bitrate = res.bitrate
	dst_mimetype = res.content_type

	if client:
		prefs = store.get(ClientPrefs, (request.user.id, client))
		if not prefs:
			prefs = ClientPrefs()
			prefs.user_id = request.user.id
			prefs.client_name = client
			store.add(prefs)

		if prefs.format:
			dst_suffix = prefs.format
		if prefs.bitrate and prefs.bitrate < dst_bitrate:
			dst_bitrate = prefs.bitrate

	if maxBitRate:
		try:
			maxBitRate = int(maxBitRate)
		except:
			return request.error_formatter(0, 'Invalid bitrate value')

		if dst_bitrate > maxBitRate and maxBitRate != 0:
			dst_bitrate = maxBitRate

	if format and format != 'raw' and format != src_suffix:
		dst_suffix = format
		dst_mimetype = scanner.get_mime(dst_suffix)

	if format != 'raw' and (dst_suffix != src_suffix or dst_bitrate != res.bitrate):
		transcoder = config.get('transcoding', 'transcoder_{}_{}'.format(src_suffix, dst_suffix))
		decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder')
		encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder')
		if not transcoder and (not decoder or not encoder):
			transcoder = config.get('transcoding', 'transcoder')
			if not transcoder:
				return request.error_formatter(0, 'No way to transcode from {} to {}'.format(src_suffix, dst_suffix))

		transcoder, decoder, encoder = map(lambda x: prepare_transcoding_cmdline(x, res.path, src_suffix, dst_suffix, dst_bitrate), [ transcoder, decoder, encoder ])
		try:
			if transcoder:
				proc = subprocess.Popen(transcoder, stdout = subprocess.PIPE)
			else:
				dec_proc = subprocess.Popen(decoder, stdout = subprocess.PIPE)
				proc = subprocess.Popen(encoder, stdin = dec_proc.stdout, stdout = subprocess.PIPE)
		except:
			return request.error_formatter(0, 'Error while running the transcoding process')

		def transcode():
			while True:
				data = proc.stdout.read(8192)
				if not data:
					break
				yield data
			proc.terminate()
			proc.wait()

		app.logger.info('Transcoding track {0.id} for user {1.id}. Source: {2} at {0.bitrate}kbps. Dest: {3} at {4}kbps'.format(res, request.user, src_suffix, dst_suffix, dst_bitrate))
		response = Response(transcode(), mimetype = dst_mimetype)
	else:
		response = send_file(res.path, mimetype = dst_mimetype)

	res.play_count = res.play_count + 1
	res.last_play = now()
	request.user.last_play = res
	request.user.last_play_date = now()
	store.commit()

	return response