Add Commands

This commit is contained in:
Kelvin Zhang 2015-08-31 15:19:23 +01:00
parent 0f8d11fa83
commit b6dad84d67
16 changed files with 1125 additions and 0 deletions

View file

@ -0,0 +1,46 @@
<?php
namespace App\Commands;
use App\Playlist;
use App\Track;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class AddTrackToPlaylistCommand extends CommandBase
{
private $_track;
private $_playlist;
function __construct($playlistId, $trackId)
{
$this->_playlist = Playlist::find($playlistId);
$this->_track = Track::find($trackId);
}
/**
* @return bool
*/
public function authorize()
{
$user = Auth::user();
return $user != null && $this->_playlist && $this->_track && $this->_playlist->user_id == $user->id;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$songIndex = $this->_playlist->tracks()->count() + 1;
$this->_playlist->tracks()->attach($this->_track, ['position' => $songIndex]);
Playlist::whereId($this->_playlist->id)->update([
'track_count' => DB::raw('(SELECT COUNT(id) FROM playlist_track WHERE playlist_id = ' . $this->_playlist->id . ')')
]);
return CommandResponse::succeed(['message' => 'Track added!']);
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace App\Commands;
abstract class CommandBase
{
private $_listeners = array();
public function listen($listener)
{
$this->_listeners[] = $listener;
}
protected function notify($message, $progress)
{
foreach ($this->_listeners as $listener) {
$listener($message, $progress);
}
}
/**
* @return bool
*/
public function authorize()
{
return true;
}
/**
* @return CommandResponse
*/
public abstract function execute();
}

View file

@ -0,0 +1,58 @@
<?php
namespace App\Commands;
use Illuminate\Validation\Validator;
class CommandResponse
{
public static function fail($validator)
{
$response = new CommandResponse();
$response->_didFail = true;
$response->_validator = $validator;
return $response;
}
public static function succeed($response = null)
{
$cmdResponse = new CommandResponse();
$cmdResponse->_didFail = false;
$cmdResponse->_response = $response;
return $cmdResponse;
}
private $_validator;
private $_response;
private $_didFail;
private function __construct()
{
}
/**
* @return bool
*/
public function didFail()
{
return $this->_didFail;
}
/**
* @return mixed
*/
public function getResponse()
{
return $this->_response;
}
/**
* @return Validator
*/
public function getValidator()
{
return $this->_validator;
}
}

View file

@ -0,0 +1,72 @@
<?php
namespace App\Commands;
use App\Album;
use App\Image;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class CreateAlbumCommand extends CommandBase
{
private $_input;
function __construct($input)
{
$this->_input = $input;
}
/**
* @return bool
*/
public function authorize()
{
$user = \Auth::user();
return $user != null;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$rules = [
'title' => 'required|min:3|max:50',
'cover' => 'image|mimes:png|min_width:350|min_height:350',
'cover_id' => 'exists:images,id',
'track_ids' => 'exists:tracks,id'
];
$validator = Validator::make($this->_input, $rules);
if ($validator->fails()) {
return CommandResponse::fail($validator);
}
$album = new Album();
$album->user_id = Auth::user()->id;
$album->title = $this->_input['title'];
$album->description = $this->_input['description'];
if (isset($this->_input['cover_id'])) {
$album->cover_id = $this->_input['cover_id'];
} else {
if (isset($this->_input['cover'])) {
$cover = $this->_input['cover'];
$album->cover_id = Image::upload($cover, Auth::user())->id;
} else {
if (isset($this->_input['remove_cover']) && $this->_input['remove_cover'] == 'true') {
$album->cover_id = null;
}
}
}
$trackIds = explode(',', $this->_input['track_ids']);
$album->save();
$album->syncTrackIds($trackIds);
return CommandResponse::succeed(['id' => $album->id]);
}
}

View file

@ -0,0 +1,79 @@
<?php
namespace App\Commands;
use App\Comment;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class CreateCommentCommand extends CommandBase
{
private $_input;
private $_id;
private $_type;
function __construct($type, $id, $input)
{
$this->_input = $input;
$this->_id = $id;
$this->_type = $type;
}
/**
* @return bool
*/
public function authorize()
{
$user = \Auth::user();
return $user != null;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$rules = [
'content' => 'required',
'track_id' => 'exists:tracks,id',
'albums_id' => 'exists:albums,id',
'playlist_id' => 'exists:playlists,id',
'profile_id' => 'exists:users,id',
];
$validator = Validator::make($this->_input, $rules);
if ($validator->fails()) {
return CommandResponse::fail($validator);
}
$comment = new Comment();
$comment->user_id = Auth::user()->id;
$comment->content = $this->_input['content'];
if ($this->_type == 'track') {
$column = 'track_id';
} else {
if ($this->_type == 'user') {
$column = 'profile_id';
} else {
if ($this->_type == 'album') {
$column = 'album_id';
} else {
if ($this->_type == 'playlist') {
$column = 'playlist_id';
} else {
App::abort(500);
}
}
}
}
$comment->$column = $this->_id;
$comment->save();
return CommandResponse::succeed(Comment::mapPublic($comment));
}
}

View file

@ -0,0 +1,69 @@
<?php
namespace App\Commands;
use App\Playlist;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class CreatePlaylistCommand extends CommandBase
{
private $_input;
function __construct($input)
{
$this->_input = $input;
}
/**
* @return bool
*/
public function authorize()
{
$user = \Auth::user();
return $user != null;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$rules = [
'title' => 'required|min:3|max:50',
'is_public' => 'required',
'is_pinned' => 'required'
];
$validator = Validator::make($this->_input, $rules);
if ($validator->fails()) {
return CommandResponse::fail($validator);
}
$playlist = new Playlist();
$playlist->user_id = Auth::user()->id;
$playlist->title = $this->_input['title'];
$playlist->description = $this->_input['description'];
$playlist->is_public = $this->_input['is_public'] == 'true';
$playlist->save();
if ($this->_input['is_pinned'] == 'true') {
$playlist->pin(Auth::user()->id);
}
return CommandResponse::succeed([
'id' => $playlist->id,
'title' => $playlist->title,
'slug' => $playlist->slug,
'created_at' => $playlist->created_at,
'description' => $playlist->description,
'url' => $playlist->url,
'is_pinned' => $this->_input['is_pinned'] == 'true',
'is_public' => $this->_input['is_public'] == 'true'
]);
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace App\Commands;
use App\Album;
use Illuminate\Support\Facades\Auth;
class DeleteAlbumCommand extends CommandBase
{
private $_albumId;
private $_album;
function __construct($albumId)
{
$this->_albumId = $albumId;
$this->_album = ALbum::find($albumId);
}
/**
* @return bool
*/
public function authorize()
{
$user = Auth::user();
return $this->_album && $user != null && $this->_album->user_id == $user->id;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
foreach ($this->_album->tracks as $track) {
$track->album_id = null;
$track->track_number = null;
$track->updateTags();
$track->save();
}
$this->_album->delete();
return CommandResponse::succeed();
}
}

View file

@ -0,0 +1,43 @@
<?php
namespace App\Commands;
use App\Playlist;
use Illuminate\Support\Facades\Auth;
class DeletePlaylistCommand extends CommandBase
{
private $_playlistId;
private $_playlist;
function __construct($playlistId)
{
$this->_playlistId = $playlistId;
$this->_playlist = Playlist::find($playlistId);
}
/**
* @return bool
*/
public function authorize()
{
$user = Auth::user();
return $this->_playlist && $user != null && $this->_playlist->user_id == $user->id;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
foreach ($this->_playlist->pins as $pin) {
$pin->delete();
}
$this->_playlist->delete();
return CommandResponse::succeed();
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace App\Commands;
use App\Track;
class DeleteTrackCommand extends CommandBase
{
private $_trackId;
private $_track;
function __construct($trackId)
{
$this->_trackId = $trackId;
$this->_track = Track::find($trackId);
}
/**
* @return bool
*/
public function authorize()
{
$user = \Auth::user();
return $this->_track && $user != null && $this->_track->user_id == $user->id;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
if ($this->_track->album_id != null) {
$album = $this->_track->album;
$this->_track->album_id = null;
$this->_track->track_number = null;
$this->_track->delete();
$album->updateTrackNumbers();
} else {
$this->_track->delete();
}
return CommandResponse::succeed();
}
}

View file

@ -0,0 +1,79 @@
<?php
namespace App\Commands;
use App\Album;
use App\Image;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
class EditAlbumCommand extends CommandBase
{
private $_input;
private $_albumId;
private $_album;
function __construct($trackId, $input)
{
$this->_input = $input;
$this->_albumId = $trackId;
$this->_album = Album::find($trackId);
}
/**
* @return bool
*/
public function authorize()
{
$user = Auth::user();
return $this->_album && $user != null && $this->_album->user_id == $user->id;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$rules = [
'title' => 'required|min:3|max:50',
'cover' => 'image|mimes:png|min_width:350|min_height:350',
'cover_id' => 'exists:images,id',
'track_ids' => 'exists:tracks,id'
];
$validator = Validator::make($this->_input, $rules);
if ($validator->fails()) {
return CommandResponse::fail($validator);
}
$this->_album->title = $this->_input['title'];
$this->_album->description = $this->_input['description'];
if (isset($this->_input['cover_id'])) {
$this->_album->cover_id = $this->_input['cover_id'];
} else {
if (isset($this->_input['cover'])) {
$cover = $this->_input['cover'];
$this->_album->cover_id = Image::upload($cover, Auth::user())->id;
} else {
if (isset($this->_input['remove_cover']) && $this->_input['remove_cover'] == 'true') {
$this->_album->cover_id = null;
}
}
}
$trackIds = explode(',', $this->_input['track_ids']);
$this->_album->syncTrackIds($trackIds);
$this->_album->save();
Album::whereId($this->_album->id)->update([
'track_count' => DB::raw('(SELECT COUNT(id) FROM tracks WHERE album_id = ' . $this->_album->id . ')')
]);
return CommandResponse::succeed(['real_cover_url' => $this->_album->getCoverUrl(Image::NORMAL)]);
}
}

View file

@ -0,0 +1,77 @@
<?php
namespace App\Commands;
use App\PinnedPlaylist;
use App\Playlist;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class EditPlaylistCommand extends CommandBase
{
private $_input;
private $_playlistId;
private $_playlist;
function __construct($playlistId, $input)
{
$this->_input = $input;
$this->_playlistId = $playlistId;
$this->_playlist = Playlist::find($playlistId);
}
/**
* @return bool
*/
public function authorize()
{
$user = Auth::user();
return $this->_playlist && $user != null && $this->_playlist->user_id == $user->id;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$rules = [
'title' => 'required|min:3|max:50',
'is_public' => 'required',
'is_pinned' => 'required'
];
$validator = Validator::make($this->_input, $rules);
if ($validator->fails()) {
return CommandResponse::fail($validator);
}
$this->_playlist->title = $this->_input['title'];
$this->_playlist->description = $this->_input['description'];
$this->_playlist->is_public = $this->_input['is_public'] == 'true';
$this->_playlist->save();
$pin = PinnedPlaylist::whereUserId(Auth::user()->id)->wherePlaylistId($this->_playlistId)->first();
if ($pin && $this->_input['is_pinned'] != 'true') {
$pin->delete();
} else {
if (!$pin && $this->_input['is_pinned'] == 'true') {
$this->_playlist->pin(Auth::user()->id);
}
}
return CommandResponse::succeed([
'id' => $this->_playlist->id,
'title' => $this->_playlist->title,
'slug' => $this->_playlist->slug,
'created_at' => $this->_playlist->created_at,
'description' => $this->_playlist->description,
'url' => $this->_playlist->url,
'is_pinned' => $this->_input['is_pinned'] == 'true',
'is_public' => $this->_input['is_public'] == 'true'
]);
}
}

View file

@ -0,0 +1,161 @@
<?php
namespace App\Commands;
use App\Album;
use App\Image;
use App\Track;
use App\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class EditTrackCommand extends CommandBase
{
private $_trackId;
private $_track;
private $_input;
function __construct($trackId, $input)
{
$this->_trackId = $trackId;
$this->_track = Track::find($trackId);
$this->_input = $input;
}
/**
* @return bool
*/
public function authorize()
{
$user = \Auth::user();
return $this->_track && $user != null && $this->_track->user_id == $user->id;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$isVocal = (isset($this->_input['is_vocal']) && $this->_input['is_vocal'] == 'true') ? true : false;
$rules = [
'title' => 'required|min:3|max:80',
'released_at' => 'before:' . (date('Y-m-d',
time() + (86400 * 2))) . (isset($this->_input['released_at']) && $this->_input['released_at'] != "" ? '|date' : ''),
'license_id' => 'required|exists:licenses,id',
'genre_id' => 'required|exists:genres,id',
'cover' => 'image|mimes:png|min_width:350|min_height:350',
'track_type_id' => 'required|exists:track_types,id',
'songs' => 'required_when:track_type,2|exists:songs,id',
'cover_id' => 'exists:images,id',
'album_id' => 'exists:albums,id'
];
if ($isVocal) {
$rules['lyrics'] = 'required';
}
if (isset($this->_input['track_type_id']) && $this->_input['track_type_id'] == 2) {
$rules['show_song_ids'] = 'required|exists:show_songs,id';
}
$validator = \Validator::make($this->_input, $rules);
if ($validator->fails()) {
return CommandResponse::fail($validator);
}
$track = $this->_track;
$track->title = $this->_input['title'];
$track->released_at = isset($this->_input['released_at']) && $this->_input['released_at'] != "" ? strtotime($this->_input['released_at']) : null;
$track->description = isset($this->_input['description']) ? $this->_input['description'] : '';
$track->lyrics = isset($this->_input['lyrics']) ? $this->_input['lyrics'] : '';
$track->license_id = $this->_input['license_id'];
$track->genre_id = $this->_input['genre_id'];
$track->track_type_id = $this->_input['track_type_id'];
$track->is_explicit = $this->_input['is_explicit'] == 'true';
$track->is_downloadable = $this->_input['is_downloadable'] == 'true';
$track->is_listed = $this->_input['is_listed'] == 'true';
$track->is_vocal = $isVocal;
if (isset($this->_input['album_id']) && strlen(trim($this->_input['album_id']))) {
if ($track->album_id != null && $track->album_id != $this->_input['album_id']) {
$this->removeTrackFromAlbum($track);
}
if ($track->album_id != $this->_input['album_id']) {
$album = Album::find($this->_input['album_id']);
$track->track_number = $album->tracks()->count() + 1;
$track->album_id = $this->_input['album_id'];
Album::whereId($album->id)->update([
'track_count' => DB::raw('(SELECT COUNT(id) FROM tracks WHERE album_id = ' . $album->id . ')')
]);
}
} else {
if ($track->album_id != null) {
$this->removeTrackFromAlbum($track);
}
$track->track_number = null;
$track->album_id = null;
}
if ($track->track_type_id == 2) {
$track->showSongs()->sync(explode(',', $this->_input['show_song_ids']));
} else {
$track->showSongs()->sync([]);
}
if ($track->published_at == null) {
$track->published_at = new \DateTime();
DB::table('tracks')->whereUserId($track->user_id)->update(['is_latest' => false]);
$track->is_latest = true;
}
if (isset($this->_input['cover_id'])) {
$track->cover_id = $this->_input['cover_id'];
} else {
if (isset($this->_input['cover'])) {
$cover = $this->_input['cover'];
$track->cover_id = Image::upload($cover, Auth::user())->id;
} else {
if ($this->_input['remove_cover'] == 'true') {
$track->cover_id = null;
}
}
}
$track->updateTags();
$track->save();
User::whereId($this->_track->user_id)->update([
'track_count' => DB::raw('(SELECT COUNT(id) FROM tracks WHERE deleted_at IS NULL AND published_at IS NOT NULL AND user_id = ' . $this->_track->user_id . ')')
]);
return CommandResponse::succeed(['real_cover_url' => $track->getCoverUrl(Image::NORMAL)]);
}
private function removeTrackFromAlbum($track)
{
$album = $track->album;
$index = 0;
foreach ($album->tracks as $track) {
if ($track->id == $this->_trackId) {
continue;
}
$track->track_number = ++$index;
$track->updateTags();
$track->save();
}
Album::whereId($album->id)->update([
'track_count' => DB::raw('(SELECT COUNT(id) FROM tracks WHERE album_id = ' . $album->id . ')')
]);
}
}

View file

@ -0,0 +1,88 @@
<?php
namespace App\Commands;
use App\Image;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class SaveAccountSettingsCommand extends CommandBase
{
private $_input;
function __construct($input)
{
$this->_input = $input;
}
/**
* @return bool
*/
public function authorize()
{
return Auth::user() != null;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$user = Auth::user();
$rules = [
'display_name' => 'required|min:3|max:26',
'bio' => 'textarea_length:250'
];
if ($this->_input['sync_names'] == 'true') {
$this->_input['display_name'] = $user->mlpforums_name;
}
if ($this->_input['uses_gravatar'] == 'true') {
$rules['gravatar'] = 'email';
} else {
$rules['avatar'] = 'image|mimes:png|min_width:350|min_height:350';
$rules['avatar_id'] = 'exists:images,id';
}
$validator = Validator::make($this->_input, $rules);
if ($validator->fails()) {
return CommandResponse::fail($validator);
}
if ($this->_input['uses_gravatar'] != 'true') {
if ($user->avatar_id == null && !isset($this->_input['avatar']) && !isset($this->_input['avatar_id'])) {
$validator->messages()->add('avatar',
'You must upload or select an avatar if you are not using gravatar!');
return CommandResponse::fail($validator);
}
}
$user->bio = $this->_input['bio'];
$user->display_name = $this->_input['display_name'];
$user->sync_names = $this->_input['sync_names'] == 'true';
$user->can_see_explicit_content = $this->_input['can_see_explicit_content'] == 'true';
$user->uses_gravatar = $this->_input['uses_gravatar'] == 'true';
if ($user->uses_gravatar) {
$user->avatar_id = null;
$user->gravatar = $this->_input['gravatar'];
} else {
if (isset($this->_input['avatar_id'])) {
$user->avatar_id = $this->_input['avatar_id'];
} else {
if (isset($this->_input['avatar'])) {
$user->avatar_id = Image::upload($this->_input['avatar'], $user)->id;
}
}
}
$user->save();
return CommandResponse::succeed();
}
}

View file

@ -0,0 +1,75 @@
<?php
namespace App\Commands;
use App\Favourite;
use App\ResourceUser;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class ToggleFavouriteCommand extends CommandBase
{
private $_resourceType;
private $_resourceId;
function __construct($resourceType, $resourceId)
{
$this->_resourceId = $resourceId;
$this->_resourceType = $resourceType;
}
/**
* @return bool
*/
public function authorize()
{
$user = Auth::user();
return $user != null;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$typeId = $this->_resourceType . '_id';
$existing = Favourite::where($typeId, '=', $this->_resourceId)->whereUserId(Auth::user()->id)->first();
$isFavourited = false;
if ($existing) {
$existing->delete();
} else {
$fav = new Favourite();
$fav->$typeId = $this->_resourceId;
$fav->user_id = Auth::user()->id;
$fav->created_at = time();
$fav->save();
$isFavourited = true;
}
$resourceUser = ResourceUser::get(Auth::user()->id, $this->_resourceType, $this->_resourceId);
$resourceUser->is_favourited = $isFavourited;
$resourceUser->save();
$resourceTable = $this->_resourceType . 's';
// We do this to prevent a race condition. Sure I could simply increment the count columns and re-save back to the db
// but that would require an additional SELECT and the operation would be non-atomic. If two log items are created
// for the same resource at the same time, the cached values will still be correct with this method.
DB::table($resourceTable)->whereId($this->_resourceId)->update([
'favourite_count' =>
DB::raw('(
SELECT
COUNT(id)
FROM
favourites
WHERE ' .
$typeId . ' = ' . $this->_resourceId . ')')
]);
return CommandResponse::succeed(['is_favourited' => $isFavourited]);
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace App\Commands;
use App\Follower;
use App\ResourceUser;
use Illuminate\Support\Facades\Auth;
class ToggleFollowingCommand extends CommandBase
{
private $_resourceType;
private $_resourceId;
function __construct($resourceType, $resourceId)
{
$this->_resourceId = $resourceId;
$this->_resourceType = $resourceType;
}
/**
* @return bool
*/
public function authorize()
{
$user = Auth::user();
return $user != null;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$typeId = $this->_resourceType . '_id';
$existing = Follower::where($typeId, '=', $this->_resourceId)->whereUserId(Auth::user()->id)->first();
$isFollowed = false;
if ($existing) {
$existing->delete();
} else {
$follow = new Follower();
$follow->$typeId = $this->_resourceId;
$follow->user_id = Auth::user()->id;
$follow->created_at = time();
$follow->save();
$isFollowed = true;
}
$resourceUser = ResourceUser::get(Auth::user()->id, $this->_resourceType, $this->_resourceId);
$resourceUser->is_followed = $isFollowed;
$resourceUser->save();
return CommandResponse::succeed(['is_followed' => $isFollowed]);
}
}

View file

@ -0,0 +1,96 @@
<?php
namespace App\Commands;
use App\Track;
use App\TrackFile;
use Illuminate\Support\Facades\Log;
class UploadTrackCommand extends CommandBase
{
/**
* @return bool
*/
public function authorize()
{
return \Auth::user() != null;
}
/**
* @throws \Exception
* @return CommandResponse
*/
public function execute()
{
$user = \Auth::user();
$trackFile = \Input::file('track');
$audio = \AudioCache::get($trackFile->getPathname());
$validator = \Validator::make(['track' => $trackFile], [
'track' =>
'required|'
. 'audio_format:flac,pcm_s16le ([1][0][0][0] / 0x0001),pcm_s16be,adpcm_ms ([2][0][0][0] / 0x0002),pcm_s24le ([1][0][0][0] / 0x0001),pcm_s24be,pcm_f32le ([3][0][0][0] / 0x0003),pcm_f32be (fl32 / 0x32336C66)|'
. 'audio_channels:1,2|'
. 'sample_rate:44100,48000,88200,96000,176400,192000|'
. 'min_duration:30'
]);
if ($validator->fails()) {
return CommandResponse::fail($validator);
}
$track = new Track();
try {
$track->user_id = $user->id;
$track->title = pathinfo($trackFile->getClientOriginalName(), PATHINFO_FILENAME);
$track->duration = $audio->getDuration();
$track->is_listed = true;
$track->save();
$destination = $track->getDirectory();
$track->ensureDirectoryExists();
$source = $trackFile->getPathname();
$index = 0;
$processes = [];
foreach (Track::$Formats as $name => $format) {
$trackFile = new TrackFile();
$trackFile->is_master = $name === 'FLAC' ? true : false;
$trackFile->format = $name;
$track->trackFiles()->save($trackFile);
$target = $destination . '/' . $trackFile->getFilename(); //$track->getFilenameFor($name);
$command = $format['command'];
$command = str_replace('{$source}', '"' . $source . '"', $command);
$command = str_replace('{$target}', '"' . $target . '"', $command);
Log::info('Encoding ' . $track->id . ' into ' . $target);
$this->notify('Encoding ' . $name, $index / count(Track::$Formats) * 100);
$pipes = [];
$proc = proc_open($command, [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'a']], $pipes);
$processes[] = $proc;
}
foreach ($processes as $proc) {
proc_close($proc);
}
$track->updateTags();
} catch (\Exception $e) {
$track->delete();
throw $e;
}
return CommandResponse::succeed([
'id' => $track->id,
'name' => $track->name
]);
}
}