mirror of
https://github.com/openvk/openvk
synced 2025-04-23 16:43:02 +03:00
Draft some playlist-related API methods
This commit is contained in:
parent
e1de07284e
commit
13a750f296
3 changed files with 303 additions and 20 deletions
|
@ -2,6 +2,7 @@
|
||||||
namespace openvk\VKAPI\Handlers;
|
namespace openvk\VKAPI\Handlers;
|
||||||
use Chandler\Database\DatabaseConnection;
|
use Chandler\Database\DatabaseConnection;
|
||||||
use openvk\Web\Models\Entities\Audio as AEntity;
|
use openvk\Web\Models\Entities\Audio as AEntity;
|
||||||
|
use openvk\Web\Models\Entities\Playlist;
|
||||||
use openvk\Web\Models\Repositories\Audios;
|
use openvk\Web\Models\Repositories\Audios;
|
||||||
use openvk\Web\Models\Repositories\Clubs;
|
use openvk\Web\Models\Repositories\Clubs;
|
||||||
use openvk\Web\Models\Repositories\Util\EntityStream;
|
use openvk\Web\Models\Repositories\Util\EntityStream;
|
||||||
|
@ -61,29 +62,36 @@ final class Audio extends VKAPIRequestHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getById(string $audios, ?string $hash = NULL, int $need_user = 0): object
|
private function audioFromAnyId(string $id): ?AEntity
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$descriptor = explode("_", $id);
|
||||||
|
|
||||||
$audioIds = array_unique(explode(",", $audios));
|
|
||||||
if(sizeof($audioIds) === 1) {
|
|
||||||
$descriptor = explode("_", $audioIds[0]);
|
|
||||||
if(sizeof($descriptor) === 1) {
|
if(sizeof($descriptor) === 1) {
|
||||||
if(ctype_digit($descriptor[0])) {
|
if(ctype_digit($descriptor[0])) {
|
||||||
$audio = (new Audios)->get((int) $descriptor[0]);
|
$audio = (new Audios)->get((int) $descriptor[0]);
|
||||||
} else {
|
} else {
|
||||||
$aid = base64_decode($descriptor[0], true);
|
$aid = base64_decode($descriptor[0], true);
|
||||||
if(!$aid)
|
if(!$aid)
|
||||||
$this->fail(8, "Invalid audio $audioIds[0]");
|
$this->fail(8, "Invalid audio $id");
|
||||||
|
|
||||||
$audio = (new Audios)->get((int) $aid);
|
$audio = (new Audios)->get((int) $aid);
|
||||||
}
|
}
|
||||||
} else if(sizeof($descriptor) === 2) {
|
} else if(sizeof($descriptor) === 2) {
|
||||||
$audio = (new Audios)->getByOwnerAndVID((int) $descriptor[0], (int) $descriptor[1]);
|
$audio = (new Audios)->getByOwnerAndVID((int) $descriptor[0], (int) $descriptor[1]);
|
||||||
} else {
|
} else {
|
||||||
$this->fail(8, "Invalid audio $audioIds[0]");
|
$this->fail(8, "Invalid audio $id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $audio;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getById(string $audios, ?string $hash = NULL, int $need_user = 0): object
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$audioIds = array_unique(explode(",", $audios));
|
||||||
|
if(sizeof($audioIds) === 1) {
|
||||||
|
$audio = $this->audioFromAnyId($audioIds[0]);
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
"count" => 1,
|
"count" => 1,
|
||||||
"items" => [
|
"items" => [
|
||||||
|
@ -104,6 +112,18 @@ final class Audio extends VKAPIRequestHandler
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isLagtrain(string $audio_id): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$audio = $this->audioFromAnyId($audio_id);
|
||||||
|
if(!$audio)
|
||||||
|
$this->fail(0404, "Audio not found");
|
||||||
|
|
||||||
|
# Possible information disclosure risks are acceptable :D
|
||||||
|
return (int) (strpos($audio->getName(), "Lagtrain") !== false);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO stub
|
// TODO stub
|
||||||
function getRecommendations(): object
|
function getRecommendations(): object
|
||||||
{
|
{
|
||||||
|
@ -149,6 +169,8 @@ final class Audio extends VKAPIRequestHandler
|
||||||
|
|
||||||
function getCount(int $owner_id, int $uploaded_only = 0): int
|
function getCount(int $owner_id, int $uploaded_only = 0): int
|
||||||
{
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
if($owner_id < 0) {
|
if($owner_id < 0) {
|
||||||
$owner_id *= -1;
|
$owner_id *= -1;
|
||||||
$group = (new Clubs)->get($owner_id);
|
$group = (new Clubs)->get($owner_id);
|
||||||
|
@ -177,9 +199,6 @@ final class Audio extends VKAPIRequestHandler
|
||||||
{
|
{
|
||||||
$this->requireUser();
|
$this->requireUser();
|
||||||
|
|
||||||
if($album_id != 0)
|
|
||||||
$this->fail(10, "album_id is not supported");
|
|
||||||
|
|
||||||
$shuffleSeed = NULL;
|
$shuffleSeed = NULL;
|
||||||
$shuffleSeedStr = NULL;
|
$shuffleSeedStr = NULL;
|
||||||
if($shuffle == 1) {
|
if($shuffle == 1) {
|
||||||
|
@ -200,6 +219,28 @@ final class Audio extends VKAPIRequestHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($album_id != 0) {
|
||||||
|
$album = (new Audios)->getPlaylist($album_id);
|
||||||
|
if(!$album)
|
||||||
|
$this->fail(0404, "album_id invalid");
|
||||||
|
else if(!$album->canBeViewedBy($this->getUser()))
|
||||||
|
$this->fail(600, "Can't open this album for reading");
|
||||||
|
|
||||||
|
$songs = [];
|
||||||
|
$list = $album->getAudios($offset, $count, $shuffleSeed);
|
||||||
|
foreach($list as $song)
|
||||||
|
$songs[] = $this->toSafeAudioStruct($song, $hash, $need_user == 1);
|
||||||
|
|
||||||
|
$response = (object) [
|
||||||
|
"count" => sizeof($songs),
|
||||||
|
"items" => $songs,
|
||||||
|
];
|
||||||
|
if(!is_null($shuffleSeed))
|
||||||
|
$response->shuffle_seed = $shuffleSeedStr;
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
if(!is_null($audio_ids)) {
|
if(!is_null($audio_ids)) {
|
||||||
$audio_ids = explode(",", $audio_ids);
|
$audio_ids = explode(",", $audio_ids);
|
||||||
if(!$audio_ids)
|
if(!$audio_ids)
|
||||||
|
@ -503,4 +544,219 @@ final class Audio extends VKAPIRequestHandler
|
||||||
|
|
||||||
return $this->getById($vid, $hash)->items[0];
|
return $this->getById($vid, $hash)->items[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAlbums(?int $owner_id = NULL, int $offset = 0, int $count = 50, int $drop_private = 1): object
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$owner_id ??= $this->getUser()->getId();
|
||||||
|
$playlists = [];
|
||||||
|
foreach((new Audios)->getPlaylistsByEntityId($owner_id, $offset, $count) as $playlist) {
|
||||||
|
if(!$playlist->canBeViewedBy($this->getUser())) {
|
||||||
|
if($drop_private == 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$playlists[] = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$playlists[] = $playlist->toVkApiStructure($this->getUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object) [
|
||||||
|
"count" => sizeof($playlists),
|
||||||
|
"items" => $playlists,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchAlbums(string $query, int $offset = 0, int $limit = 25, int $drop_private = 0): object
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$playlists = [];
|
||||||
|
$search = (new Audios)->searchPlaylists($query)->offsetLimit($offset, $limit);
|
||||||
|
foreach($search as $playlist) {
|
||||||
|
if(!$playlist->canBeViewedBy($this->getUser())) {
|
||||||
|
if($drop_private == 0)
|
||||||
|
$playlists[] = NULL;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$playlists[] = $playlist->toVkApiStruct($this->getUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object) [
|
||||||
|
"count" => sizeof($playlists),
|
||||||
|
"items" => $playlists,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAlbum(string $title, ?string $description = NULL, int $group_id = 0): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$group = NULL;
|
||||||
|
if($group_id != 0) {
|
||||||
|
$group = (new Clubs)->get($group_id);
|
||||||
|
if(!$group_id)
|
||||||
|
$this->fail(0404, "Invalid group_id");
|
||||||
|
else if(!$group->canBeModifiedBy($this->getUser()))
|
||||||
|
$this->fail(600, "Insufficient rights to this group");
|
||||||
|
}
|
||||||
|
|
||||||
|
$album = new Playlist;
|
||||||
|
$album->setName($title);
|
||||||
|
if(!is_null($group))
|
||||||
|
$album->setOwner($group_id * -1);
|
||||||
|
else
|
||||||
|
$album->setOwner($this->getUser()->getId());
|
||||||
|
|
||||||
|
if(!is_null($description))
|
||||||
|
$album->setDescription($description);
|
||||||
|
|
||||||
|
$album->save();
|
||||||
|
|
||||||
|
return $album->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
function editAlbum(int $album_id, ?string $title = NULL, ?string $description = NULL): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$album = (new Audios)->getPlaylist($album_id);
|
||||||
|
if(!$album)
|
||||||
|
$this->fail(0404, "Album not found");
|
||||||
|
else if(!$album->canBeModifiedBy($this->getUser()))
|
||||||
|
$this->fail(600, "Insufficient rights to this album");
|
||||||
|
|
||||||
|
if(!is_null($title))
|
||||||
|
$album->setName($title);
|
||||||
|
|
||||||
|
if(!is_null($description))
|
||||||
|
$album->setDescription($description);
|
||||||
|
|
||||||
|
return (int) !(!$title && !$description);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteAlbum(int $album_id): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$album = (new Audios)->getPlaylist($album_id);
|
||||||
|
if(!$album)
|
||||||
|
$this->fail(0404, "Album not found");
|
||||||
|
else if(!$album->canBeModifiedBy($this->getUser()))
|
||||||
|
$this->fail(600, "Insufficient rights to this album");
|
||||||
|
|
||||||
|
$album->delete();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveToAlbum(int $album_id, string $audio_ids): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$album = (new Audios)->getPlaylist($album_id);
|
||||||
|
if(!$album)
|
||||||
|
$this->fail(0404, "Album not found");
|
||||||
|
else if(!$album->canBeModifiedBy($this->getUser()))
|
||||||
|
$this->fail(600, "Insufficient rights to this album");
|
||||||
|
|
||||||
|
$audios = [];
|
||||||
|
$audio_ids = array_unique(explode(",", $audio_ids));
|
||||||
|
if(sizeof($audio_ids) < 1 || sizeof($audio_ids) > 1000)
|
||||||
|
$this->fail(8, "audio_ids must contain at least 1 audio and at most 1000");
|
||||||
|
|
||||||
|
foreach($audio_ids as $audio_id) {
|
||||||
|
$audio = $this->audioFromAnyId($audio_id);
|
||||||
|
if(!$audio)
|
||||||
|
continue;
|
||||||
|
else if($audio->canBeViewedBy($this->getUser()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$audios[] = $audio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sizeof($audios) < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
$res = 1;
|
||||||
|
try {
|
||||||
|
foreach ($audios as $audio)
|
||||||
|
$res = min($res, $album->add($audio));
|
||||||
|
} catch(\OutOfBoundsException $ex) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFromAlbum(int $album_id, string $audio_ids): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$album = (new Audios)->getPlaylist($album_id);
|
||||||
|
if(!$album)
|
||||||
|
$this->fail(0404, "Album not found");
|
||||||
|
else if(!$album->canBeModifiedBy($this->getUser()))
|
||||||
|
$this->fail(600, "Insufficient rights to this album");
|
||||||
|
|
||||||
|
$audios = [];
|
||||||
|
$audio_ids = array_unique(explode(",", $audio_ids));
|
||||||
|
if(sizeof($audio_ids) < 1 || sizeof($audio_ids) > 1000)
|
||||||
|
$this->fail(8, "audio_ids must contain at least 1 audio and at most 1000");
|
||||||
|
|
||||||
|
foreach($audio_ids as $audio_id) {
|
||||||
|
$audio = $this->audioFromAnyId($audio_id);
|
||||||
|
if(!$audio)
|
||||||
|
continue;
|
||||||
|
else if($audio->canBeViewedBy($this->getUser()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$audios[] = $audio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sizeof($audios) < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
foreach($audios as $audio)
|
||||||
|
$album->remove($audio);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToAlbum(int $album_id, string $audio_ids): int
|
||||||
|
{
|
||||||
|
return $this->moveToAlbum($album_id, $audio_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bookmarkAlbum(int $id): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$album = (new Audios)->getPlaylist($id);
|
||||||
|
if(!$album)
|
||||||
|
$this->fail(0404, "Not found");
|
||||||
|
|
||||||
|
if(!$album->canBeViewedBy($this->getUser()))
|
||||||
|
$this->fail(600, "Access error");
|
||||||
|
|
||||||
|
return (int) $album->bookmark($this->getUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
function unBookmarkAlbum(int $id): int
|
||||||
|
{
|
||||||
|
$this->requireUser();
|
||||||
|
|
||||||
|
$album = (new Audios)->getPlaylist($id);
|
||||||
|
if(!$album)
|
||||||
|
$this->fail(0404, "Not found");
|
||||||
|
|
||||||
|
if(!$album->canBeViewedBy($this->getUser()))
|
||||||
|
$this->fail(600, "Access error");
|
||||||
|
|
||||||
|
return (int) $album->unbookmark($this->getUser());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ class Playlist extends MediaCollection
|
||||||
protected $relTableName = "playlist_relations";
|
protected $relTableName = "playlist_relations";
|
||||||
protected $entityTableName = "audios";
|
protected $entityTableName = "audios";
|
||||||
protected $entityClassName = 'openvk\Web\Models\Entities\Audio';
|
protected $entityClassName = 'openvk\Web\Models\Entities\Audio';
|
||||||
|
protected $allowDuplicates = false;
|
||||||
|
|
||||||
private $importTable;
|
private $importTable;
|
||||||
|
|
||||||
|
@ -33,6 +34,11 @@ class Playlist extends MediaCollection
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLength(): int
|
||||||
|
{
|
||||||
|
return $this->getRecord()->length;
|
||||||
|
}
|
||||||
|
|
||||||
function getAudios(int $offset = 0, ?int $limit = NULL, ?int $shuffleSeed = NULL): \Traversable
|
function getAudios(int $offset = 0, ?int $limit = NULL, ?int $shuffleSeed = NULL): \Traversable
|
||||||
{
|
{
|
||||||
if(!$shuffleSeed)
|
if(!$shuffleSeed)
|
||||||
|
@ -114,6 +120,27 @@ class Playlist extends MediaCollection
|
||||||
return $count > 0;
|
return $count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toVkApiStruct(?User $user = NULL): object
|
||||||
|
{
|
||||||
|
$oid = $this->getOwner()->getId();
|
||||||
|
if($this->getOwner() instanceof Club)
|
||||||
|
$oid *= -1;
|
||||||
|
|
||||||
|
return (object) [
|
||||||
|
"id" => $this->getId(),
|
||||||
|
"owner_id" => $oid,
|
||||||
|
"title" => $this->getTitle(),
|
||||||
|
"description" => $this->getDescription(),
|
||||||
|
"size" => $this->size(),
|
||||||
|
"length" => $this->getLength(),
|
||||||
|
"created" => $this->getCreationTime()->relative(),
|
||||||
|
"modified" => $this->getCreationTime()->relative(),
|
||||||
|
"accessible" => $this->canBeViewedBy($user),
|
||||||
|
"editable" => $this->canBeModifiedBy($user),
|
||||||
|
"bookmarked" => $this->isBookmarkedBy($user),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
function setLength(): void
|
function setLength(): void
|
||||||
{
|
{
|
||||||
throw new \LogicException("Can't set length of playlist manually");
|
throw new \LogicException("Can't set length of playlist manually");
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Audios
|
||||||
return new Audio($audio);
|
return new Audio($audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPlaylist(int $id): ?Playlist
|
function getPlaylist(int $id): ?Playlist
|
||||||
{
|
{
|
||||||
$playlist = $this->playlists->get($id);
|
$playlist = $this->playlists->get($id);
|
||||||
if(!$playlist)
|
if(!$playlist)
|
||||||
|
|
Loading…
Reference in a new issue