mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-25 14:37:59 +01:00
Intermediate commit
This commit is contained in:
parent
13d46c6c3c
commit
2046b8e98d
42 changed files with 1465 additions and 124 deletions
|
@ -14,11 +14,11 @@
|
|||
}
|
||||
|
||||
public function fire() {
|
||||
$oldDb = DB::connection('old');
|
||||
|
||||
$this->call('migrate:refresh');
|
||||
|
||||
$oldDb = DB::connection('old');
|
||||
$oldUsers = $oldDb->table('users')->get();
|
||||
|
||||
$this->info('Syncing Users');
|
||||
foreach ($oldUsers as $user) {
|
||||
$displayName = $user->display_name;
|
||||
|
@ -51,9 +51,14 @@
|
|||
|
||||
$coverId = null;
|
||||
if (!$user->uses_gravatar) {
|
||||
try {
|
||||
$coverFile = $this->getIdDirectory('users', $user->id) . '/' . $user->id . '_.png';
|
||||
$coverId = \Entities\Image::upload(new Symfony\Component\HttpFoundation\File\UploadedFile($coverFile, $user->id . '_.png'), $user->id)->id;
|
||||
DB::table('users')->where('id', $user->id)->update(['avatar_id' => $coverId]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could copy user avatar ' . $user->id . ' because ' . $e->getMessage());
|
||||
DB::table('users')->where('id', $user->id)->update(['uses_gravatar' => true]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +75,9 @@
|
|||
$this->info('Syncing Albums');
|
||||
$oldAlbums = $oldDb->table('albums')->get();
|
||||
foreach ($oldAlbums as $playlist) {
|
||||
$logViews = $oldDb->table('album_log_views')->whereAlbumId($playlist->id)->get();
|
||||
$logDownload = $oldDb->table('album_log_downloads')->whereAlbumId($playlist->id)->get();
|
||||
|
||||
DB::table('albums')->insert([
|
||||
'title' => $playlist->title,
|
||||
'description' => $playlist->description,
|
||||
|
@ -78,8 +86,39 @@
|
|||
'deleted_at' => $playlist->deleted_at,
|
||||
'slug' => $playlist->slug,
|
||||
'id' => $playlist->id,
|
||||
'user_id' => $playlist->user_id
|
||||
'user_id' => $playlist->user_id,
|
||||
'view_count' => 0,
|
||||
'download_count' => 0
|
||||
]);
|
||||
|
||||
foreach ($logViews as $logItem) {
|
||||
try {
|
||||
DB::table('resource_log_items')->insert([
|
||||
'user_id' => $logItem->user_id,
|
||||
'log_type' => \Entities\ResourceLogItem::VIEW,
|
||||
'album_id' => $logItem->album_id,
|
||||
'created_at' => $logItem->created_at,
|
||||
'ip_address' => $logItem->ip_address,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could insert log item for album ' . $playlist->id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($logDownload as $logItem) {
|
||||
try {
|
||||
DB::table('resource_log_items')->insert([
|
||||
'user_id' => $logItem->user_id,
|
||||
'log_type' => \Entities\ResourceLogItem::DOWNLOAD,
|
||||
'album_id' => $logItem->album_id,
|
||||
'created_at' => $logItem->created_at,
|
||||
'ip_address' => $logItem->ip_address,
|
||||
'track_format_id' => $logItem->track_file_format_id - 1
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could insert log item for album ' . $playlist->id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('Syncing Tracks');
|
||||
|
@ -87,9 +126,17 @@
|
|||
foreach ($oldTracks as $track) {
|
||||
$coverId = null;
|
||||
if ($track->cover) {
|
||||
try {
|
||||
$coverFile = $this->getIdDirectory('tracks', $track->id) . '/' . $track->id . '_' . $track->cover . '.png';
|
||||
$coverId = \Entities\Image::upload(new Symfony\Component\HttpFoundation\File\UploadedFile($coverFile, $track->id . '_' . $track->cover . '.png'), $track->user_id)->id;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could copy track cover ' . $track->id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$trackLogViews = $oldDb->table('track_log_views')->whereTrackId($track->id)->get();
|
||||
$trackLogPlays = $oldDb->table('track_log_plays')->whereTrackId($track->id)->get();
|
||||
$trackLogDownload = $oldDb->table('track_log_downloads')->whereTrackId($track->id)->get();
|
||||
|
||||
DB::table('tracks')->insert([
|
||||
'id' => $track->id,
|
||||
|
@ -112,22 +159,75 @@
|
|||
'album_id' => $track->album_id,
|
||||
'cover_id' => $coverId,
|
||||
'license_id' => $track->license_id,
|
||||
'duration' => $track->duration
|
||||
'duration' => $track->duration,
|
||||
'view_count' => 0,
|
||||
'play_count' => 0,
|
||||
'download_count' => 0
|
||||
]);
|
||||
|
||||
foreach ($trackLogViews as $logItem) {
|
||||
try {
|
||||
DB::table('resource_log_items')->insert([
|
||||
'user_id' => $logItem->user_id,
|
||||
'log_type' => \Entities\ResourceLogItem::VIEW,
|
||||
'track_id' => $logItem->track_id,
|
||||
'created_at' => $logItem->created_at,
|
||||
'ip_address' => $logItem->ip_address
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could insert log item for track ' . $track->id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($trackLogPlays as $logItem) {
|
||||
try {
|
||||
DB::table('resource_log_items')->insert([
|
||||
'user_id' => $logItem->user_id,
|
||||
'log_type' => \Entities\ResourceLogItem::PLAY,
|
||||
'track_id' => $logItem->track_id,
|
||||
'created_at' => $logItem->created_at,
|
||||
'ip_address' => $logItem->ip_address
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could insert log item for track ' . $track->id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($trackLogDownload as $logItem) {
|
||||
try {
|
||||
DB::table('resource_log_items')->insert([
|
||||
'user_id' => $logItem->user_id,
|
||||
'log_type' => \Entities\ResourceLogItem::DOWNLOAD,
|
||||
'track_id' => $logItem->track_id,
|
||||
'created_at' => $logItem->created_at,
|
||||
'ip_address' => $logItem->ip_address,
|
||||
'track_format_id' => $logItem->track_file_format_id - 1
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could insert log item for track ' . $track->id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oldShowSongs = $oldDb->table('song_track')->get();
|
||||
foreach ($oldShowSongs as $song) {
|
||||
try {
|
||||
DB::table('show_song_track')->insert([
|
||||
'id' => $song->id,
|
||||
'show_song_id' => $song->song_id,
|
||||
'track_id' => $song->track_id
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could insert show track item for ' . $song->track_id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('Syncing Playlists');
|
||||
$oldPlaylists = $oldDb->table('playlists')->get();
|
||||
foreach ($oldPlaylists as $playlist) {
|
||||
$logViews = $oldDb->table('playlist_log_views')->wherePlaylistId($playlist->id)->get();
|
||||
$logDownload = $oldDb->table('playlist_log_downloads')->wherePlaylistId($playlist->id)->get();
|
||||
|
||||
DB::table('playlists')->insert([
|
||||
'title' => $playlist->title,
|
||||
'description' => $playlist->description,
|
||||
|
@ -137,8 +237,39 @@
|
|||
'slug' => $playlist->slug,
|
||||
'id' => $playlist->id,
|
||||
'user_id' => $playlist->user_id,
|
||||
'is_public' => true
|
||||
'is_public' => true,
|
||||
'view_count' => 0,
|
||||
'download_count' => 0,
|
||||
]);
|
||||
|
||||
foreach ($logViews as $logItem) {
|
||||
try {
|
||||
DB::table('resource_log_items')->insert([
|
||||
'user_id' => $logItem->user_id,
|
||||
'log_type' => \Entities\ResourceLogItem::VIEW,
|
||||
'playlist_id' => $logItem->playlist_id,
|
||||
'created_at' => $logItem->created_at,
|
||||
'ip_address' => $logItem->ip_address,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could insert log item for playlist ' . $playlist->id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($logDownload as $logItem) {
|
||||
try {
|
||||
DB::table('resource_log_items')->insert([
|
||||
'user_id' => $logItem->user_id,
|
||||
'log_type' => \Entities\ResourceLogItem::DOWNLOAD,
|
||||
'playlist_id' => $logItem->playlist_id,
|
||||
'created_at' => $logItem->created_at,
|
||||
'ip_address' => $logItem->ip_address,
|
||||
'track_format_id' => $logItem->track_file_format_id - 1
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Could insert log item for playlist ' . $playlist->id . ' because ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('Syncing Playlist Tracks');
|
||||
|
@ -183,7 +314,6 @@
|
|||
'id' => $fav->id,
|
||||
'user_id' => $fav->user_id,
|
||||
'created_at' => $fav->created_at,
|
||||
'updated_at' => $fav->updated_at,
|
||||
'track_id' => $fav->track_id,
|
||||
'album_id' => $fav->album_id,
|
||||
'playlist_id' => $fav->playlist_id,
|
||||
|
@ -199,8 +329,7 @@
|
|||
return \Config::get('app.files_directory') . '/' . $type . '/' . $dir;
|
||||
}
|
||||
|
||||
protected function getArguments()
|
||||
{
|
||||
protected function getArguments() {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
182
app/commands/RefreshCache.php
Normal file
182
app/commands/RefreshCache.php
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
class RefreshCache extends Command {
|
||||
protected $name = 'refresh-cache';
|
||||
protected $description = 'Refreshes cache tables for views and downloads';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function fire() {
|
||||
DB::table('tracks')->update(['comment_count' => DB::raw('(SELECT COUNT(id) FROM comments WHERE comments.track_id = tracks.id AND deleted_at IS NULL)')]);
|
||||
DB::table('albums')->update(['comment_count' => DB::raw('(SELECT COUNT(id) FROM comments WHERE comments.album_id = albums.id AND deleted_at IS NULL)')]);
|
||||
DB::table('playlists')->update(['comment_count' => DB::raw('(SELECT COUNT(id) FROM comments WHERE comments.playlist_id = playlists.id AND deleted_at IS NULL)')]);
|
||||
DB::table('users')->update(['comment_count' => DB::raw('(SELECT COUNT(id) FROM comments WHERE comments.profile_id = users.id AND deleted_at IS NULL)')]);
|
||||
|
||||
$users = DB::table('users')->get();
|
||||
$cacheItems = [];
|
||||
$resources = [
|
||||
'album' => [],
|
||||
'playlist' => [],
|
||||
'track' => []
|
||||
];
|
||||
|
||||
foreach ($users as $user) {
|
||||
$cacheItems[$user->id] = [
|
||||
'album' => [],
|
||||
'playlist' => [],
|
||||
'track' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$logItems = DB::table('resource_log_items')->get();
|
||||
foreach ($logItems as $item) {
|
||||
$type = '';
|
||||
$id = 0;
|
||||
|
||||
if ($item->album_id) {
|
||||
$type = 'album';
|
||||
$id = $item->album_id;
|
||||
}
|
||||
else if ($item->playlist_id) {
|
||||
$type = 'playlist';
|
||||
$id = $item->playlist_id;
|
||||
}
|
||||
else if ($item->track_id) {
|
||||
$type = 'track';
|
||||
$id = $item->track_id;
|
||||
}
|
||||
|
||||
$resource = $this->getCacheItem($resources, $type, $id);
|
||||
|
||||
if ($item->user_id != null) {
|
||||
$userResource = $this->getUserCacheItem($cacheItems, $item->user_id, $type, $id);
|
||||
|
||||
if ($item->log_type == \Entities\ResourceLogItem::DOWNLOAD) {
|
||||
$userResource['download_count']++;
|
||||
}
|
||||
else if ($item->log_type == \Entities\ResourceLogItem::VIEW) {
|
||||
$userResource['view_count']++;
|
||||
}
|
||||
else if ($item->log_type == \Entities\ResourceLogItem::PLAY) {
|
||||
$userResource['play_count']++;
|
||||
}
|
||||
|
||||
$cacheItems[$item->user_id][$type][$id] = $userResource;
|
||||
}
|
||||
|
||||
if ($item->log_type == \Entities\ResourceLogItem::DOWNLOAD) {
|
||||
$resource['download_count']++;
|
||||
}
|
||||
else if ($item->log_type == \Entities\ResourceLogItem::VIEW) {
|
||||
$resource['view_count']++;
|
||||
}
|
||||
else if ($item->log_type == \Entities\ResourceLogItem::PLAY) {
|
||||
$resource['play_count']++;
|
||||
}
|
||||
|
||||
$resources[$type][$id] = $resource;
|
||||
}
|
||||
|
||||
$pins = DB::table('pinned_playlists')->get();
|
||||
foreach ($pins as $pin) {
|
||||
$userResource = $this->getUserCacheItem($cacheItems, $pin->user_id, 'playlist', $pin->playlist_id);
|
||||
$userResource['is_pinned'] = true;
|
||||
$cacheItems[$pin->user_id]['playlist'][$pin->playlist_id] = $userResource;
|
||||
}
|
||||
|
||||
$favs = DB::table('favourites')->get();
|
||||
foreach ($favs as $fav) {
|
||||
$type = '';
|
||||
$id = 0;
|
||||
|
||||
if ($fav->album_id) {
|
||||
$type = 'album';
|
||||
$id = $fav->album_id;
|
||||
}
|
||||
else if ($fav->playlist_id) {
|
||||
$type = 'playlist';
|
||||
$id = $fav->playlist_id;
|
||||
}
|
||||
else if ($fav->track_id) {
|
||||
$type = 'track';
|
||||
$id = $fav->track_id;
|
||||
}
|
||||
|
||||
$userResource = $this->getUserCacheItem($cacheItems, $fav->user_id, $type, $id);
|
||||
$userResource['is_favourited'] = true;
|
||||
$cacheItems[$fav->user_id][$type][$id] = $userResource;
|
||||
|
||||
$resource = $this->getCacheItem($resources, $type, $id);
|
||||
$resource['favourite_count']++;
|
||||
$resources[$type][$id] = $resource;
|
||||
}
|
||||
|
||||
foreach ($resources as $name => $resourceArray) {
|
||||
foreach ($resourceArray as $id => $resource) {
|
||||
DB::table($name . 's')->whereId($id)->update($resource);
|
||||
}
|
||||
}
|
||||
|
||||
DB::table('resource_users')->delete();
|
||||
foreach ($cacheItems as $cacheItem) {
|
||||
foreach ($cacheItem as $resources) {
|
||||
foreach ($resources as $resource) {
|
||||
DB::table('resource_users')->insert($resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getCacheItem(&$resources, $type, $id) {
|
||||
if (!isset($resources[$type][$id])) {
|
||||
$item = [
|
||||
'view_count' => 0,
|
||||
'download_count' => 0,
|
||||
'favourite_count' => 0,
|
||||
];
|
||||
|
||||
if ($type == 'track')
|
||||
$item['play_count'] = 0;
|
||||
|
||||
$resources[$type][$id] = $item;
|
||||
return $item;
|
||||
}
|
||||
|
||||
return $resources[$type][$id];
|
||||
}
|
||||
|
||||
private function getUserCacheItem(&$items, $userId, $type, $id) {
|
||||
if (!isset($items[$userId][$type][$id])) {
|
||||
$item = [
|
||||
'is_followed' => false,
|
||||
'is_favourited' => false,
|
||||
'is_pinned' => false,
|
||||
'view_count' => 0,
|
||||
'play_count' => 0,
|
||||
'download_count' => 0,
|
||||
'user_id' => $userId
|
||||
];
|
||||
|
||||
$item[$type . '_id'] = $id;
|
||||
|
||||
$items[$userId][$type][$id] = $item;
|
||||
return $item;
|
||||
}
|
||||
|
||||
return $items[$userId][$type][$id];
|
||||
}
|
||||
|
||||
protected function getArguments() {
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function getOptions() {
|
||||
return [];
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Entities\Album;
|
||||
use Entities\ResourceLogItem;
|
||||
use Entities\Track;
|
||||
|
||||
class AlbumsController extends Controller {
|
||||
public function getIndex() {
|
||||
|
@ -25,4 +27,28 @@
|
|||
|
||||
return Redirect::action('AlbumsController@getTrack', [$id, $album->slug]);
|
||||
}
|
||||
|
||||
public function getDownload($id, $extension) {
|
||||
$album = Album::with('tracks', 'user')->find($id);
|
||||
if (!$album)
|
||||
App::abort(404);
|
||||
|
||||
$format = null;
|
||||
$formatName = null;
|
||||
|
||||
foreach (Track::$Formats as $name => $item) {
|
||||
if ($item['extension'] == $extension) {
|
||||
$format = $item;
|
||||
$formatName = $name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($format == null)
|
||||
App::abort(404);
|
||||
|
||||
ResourceLogItem::logItem('album', $id, ResourceLogItem::DOWNLOAD, $format['index']);
|
||||
$downloader = new AlbumDownloader($album, $formatName);
|
||||
$downloader->download();
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
use Entities\Album;
|
||||
use Entities\Comment;
|
||||
use Entities\Image;
|
||||
use Entities\ResourceLogItem;
|
||||
use Entities\Track;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
@ -27,10 +28,15 @@
|
|||
}
|
||||
|
||||
public function getShow($id) {
|
||||
$album = Album::with(['tracks', 'user', 'comments' => function($query) { $query->with('user'); }])->details()->find($id);
|
||||
$album = Album::with(['tracks' => function($query) { $query->details(); }, 'user', 'comments' => function($query) { $query->with('user'); }])->details()->find($id);
|
||||
if (!$album)
|
||||
App::abort(404);
|
||||
|
||||
if (Input::get('log')) {
|
||||
ResourceLogItem::logItem('album', $id, ResourceLogItem::VIEW);
|
||||
$album->view_count++;
|
||||
}
|
||||
|
||||
return Response::json([
|
||||
'album' => Album::mapPublicAlbumShow($album)
|
||||
], 200);
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
use Cover;
|
||||
use Entities\Favourite;
|
||||
use Entities\Image;
|
||||
use Entities\ResourceLogItem;
|
||||
use Entities\ResourceUser;
|
||||
use Entities\Track;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
@ -32,6 +34,11 @@
|
|||
if (!$track || !$track->canView(Auth::user()))
|
||||
return $this->notFound('Track not found!');
|
||||
|
||||
if (Input::get('log')) {
|
||||
ResourceLogItem::logItem('track', $id, ResourceLogItem::VIEW);
|
||||
$track->view_count++;
|
||||
}
|
||||
|
||||
return Response::json(['track' => Track::mapPublicTrackShow($track)], 200);
|
||||
}
|
||||
|
||||
|
@ -51,7 +58,7 @@
|
|||
|
||||
public function getIndex() {
|
||||
$page = 1;
|
||||
$perPage = 60;
|
||||
$perPage = 45;
|
||||
|
||||
if (Input::has('page'))
|
||||
$page = Input::get('page');
|
||||
|
@ -64,7 +71,7 @@
|
|||
$this->applyFilters($query);
|
||||
|
||||
$totalCount = $query->count();
|
||||
$query->take($perPage)->skip(30 * ($page - 1));
|
||||
$query->take($perPage)->skip($perPage * ($page - 1));
|
||||
|
||||
$tracks = [];
|
||||
$ids = [];
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Entities\ResourceLogItem;
|
||||
use Entities\Track;
|
||||
use Illuminate\Support\Facades\App;
|
||||
|
||||
|
@ -33,10 +34,40 @@
|
|||
App::abort(404);
|
||||
|
||||
$format = Track::$Formats['MP3'];
|
||||
ResourceLogItem::logItem('track', $id, ResourceLogItem::PLAY, $format['index']);
|
||||
|
||||
$response = Response::make('', 200);
|
||||
$response->header('X-Sendfile', $track->getFileFor('MP3'));
|
||||
$response->header('Content-Disposition', 'filename=' . $track->getFilenameFor('MP3'));
|
||||
$response->header('Content-Disposition', 'filename="' . $track->getFilenameFor('MP3') . '"');
|
||||
$response->header('Content-Type', $format['mime_type']);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getDownload($id, $extension) {
|
||||
$track = Track::find($id);
|
||||
if (!$track || !$track->canView(Auth::user()))
|
||||
App::abort(404);
|
||||
|
||||
$format = null;
|
||||
$formatName = null;
|
||||
|
||||
foreach (Track::$Formats as $name => $item) {
|
||||
if ($item['extension'] == $extension) {
|
||||
$format = $item;
|
||||
$formatName = $name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($format == null)
|
||||
App::abort(404);
|
||||
|
||||
ResourceLogItem::logItem('track', $id, ResourceLogItem::DOWNLOAD, $format['index']);
|
||||
|
||||
$response = Response::make('', 200);
|
||||
$response->header('X-Sendfile', $track->getFileFor($formatName));
|
||||
$response->header('Content-Disposition', 'attachment; filename="' . $track->getDownloadFilenameFor($formatName) . '"');
|
||||
$response->header('Content-Type', $format['mime_type']);
|
||||
|
||||
return $response;
|
||||
|
|
|
@ -18,6 +18,7 @@ class CreateUsersTable extends Migration {
|
|||
$table->boolean('uses_gravatar')->default(true);
|
||||
$table->boolean('can_see_explicit_content');
|
||||
$table->text('bio');
|
||||
$table->integer('comment_count')->unsigned();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
|
|
|
@ -43,6 +43,12 @@ class CreateTracksTable extends Migration {
|
|||
$table->boolean('is_downloadable');
|
||||
$table->float('duration')->unsigned();
|
||||
|
||||
$table->integer('play_count')->unsigned();
|
||||
$table->integer('view_count')->unsigned();
|
||||
$table->integer('download_count')->unsigned();
|
||||
$table->integer('favourite_count')->unsigned();
|
||||
$table->integer('comment_count')->unsigned();
|
||||
|
||||
$table->timestamps();
|
||||
$table->timestamp('deleted_at')->nullable()->index();
|
||||
$table->timestamp('published_at')->nullable()->index();
|
||||
|
|
|
@ -11,6 +11,12 @@ class CreateAlbums extends Migration {
|
|||
$table->string('slug')->index();
|
||||
$table->text('description');
|
||||
$table->integer('cover_id')->unsigned()->nullable();
|
||||
|
||||
$table->integer('view_count')->unsigned();
|
||||
$table->integer('download_count')->unsigned();
|
||||
$table->integer('favourite_count')->unsigned();
|
||||
$table->integer('comment_count')->unsigned();
|
||||
|
||||
$table->timestamps();
|
||||
$table->timestamp('deleted_at')->nullable()->index();
|
||||
|
||||
|
|
|
@ -11,22 +11,19 @@ class CreatePlaylists extends Migration {
|
|||
$table->string('slug');
|
||||
$table->text('description');
|
||||
$table->boolean('is_public');
|
||||
|
||||
$table->integer('view_count')->unsigned();
|
||||
$table->integer('download_count')->unsigned();
|
||||
$table->integer('favourite_count')->unsigned();
|
||||
$table->integer('follow_count')->unsigned();
|
||||
$table->integer('comment_count')->unsigned();
|
||||
|
||||
$table->timestamps();
|
||||
$table->date('deleted_at')->nullable()->index();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->on_update('cascade');
|
||||
});
|
||||
|
||||
Schema::create('pinned_playlists', function($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned()->index();
|
||||
$table->integer('playlist_id')->unsigned()->index();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->on_update('cascade');
|
||||
$table->foreign('playlist_id')->references('id')->on('playlists')->on_update('cascade');
|
||||
});
|
||||
|
||||
Schema::create('playlist_track', function($table){
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
|
@ -37,6 +34,16 @@ class CreatePlaylists extends Migration {
|
|||
$table->foreign('playlist_id')->references('id')->on('playlists')->on_update('cascade')->on_delete('cascade');
|
||||
$table->foreign('track_id')->references('id')->on('tracks')->on_update('cascade');
|
||||
});
|
||||
|
||||
Schema::create('pinned_playlists', function($table) {
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned()->index();
|
||||
$table->integer('playlist_id')->unsigned()->index();
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->on_update('cascade');
|
||||
$table->foreign('playlist_id')->references('id')->on('playlists')->on_update('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
public function down() {
|
||||
|
@ -47,11 +54,6 @@ class CreatePlaylists extends Migration {
|
|||
|
||||
Schema::drop('playlist_track');
|
||||
|
||||
Schema::table('pinned_playlists', function($table){
|
||||
$table->dropForeign('pinned_playlists_user_id_foreign');
|
||||
$table->dropForeign('pinned_playlists_playlist_id_foreign');
|
||||
});
|
||||
|
||||
Schema::drop('pinned_playlists');
|
||||
|
||||
Schema::table('playlists', function($table){
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateFavourites extends Migration {
|
||||
public function up() {
|
||||
Schema::create('favourites', function($table){
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned()->index();
|
||||
|
||||
$table->integer('track_id')->unsigned()->nullable()->index();
|
||||
$table->integer('album_id')->unsigned()->nullable()->index();
|
||||
$table->integer('playlist_id')->unsigned()->nullable()->index();
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->on_delete('cascade');
|
||||
$table->foreign('track_id')->references('id')->on('tracks');
|
||||
$table->foreign('album_id')->references('id')->on('albums');
|
||||
$table->foreign('playlist_id')->references('id')->on('playlists');
|
||||
});
|
||||
}
|
||||
|
||||
public function down() {
|
||||
Schema::table('favourites', function($table){
|
||||
$table->dropForeign('favourites_user_id_foreign');
|
||||
$table->dropForeign('favourites_track_id_foreign');
|
||||
$table->dropForeign('favourites_album_id_foreign');
|
||||
$table->dropForeign('favourites_playlist_id_foreign');
|
||||
});
|
||||
|
||||
Schema::drop('favourites');
|
||||
}
|
||||
}
|
|
@ -7,9 +7,10 @@ class CreateComments extends Migration {
|
|||
Schema::create('comments', function($table){
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->timestamps();
|
||||
$table->string('ip_address', 46);
|
||||
$table->text('content');
|
||||
|
||||
$table->timestamps();
|
||||
$table->timestamp('deleted_at')->nullable()->index();
|
||||
|
||||
$table->integer('profile_id')->unsigned()->nullable()->index();
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateUserTables extends Migration {
|
||||
public function up() {
|
||||
Schema::create('resource_users', function($table){
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned()->index();
|
||||
|
||||
$table->integer('track_id')->unsigned()->nullable()->index();
|
||||
$table->integer('album_id')->unsigned()->nullable()->index();
|
||||
$table->integer('playlist_id')->unsigned()->nullable()->index();
|
||||
|
||||
$table->boolean('is_followed');
|
||||
$table->boolean('is_favourited');
|
||||
$table->boolean('is_pinned');
|
||||
|
||||
$table->integer('view_count');
|
||||
$table->integer('play_count');
|
||||
$table->integer('download_count');
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->on_delete('cascade');
|
||||
$table->foreign('track_id')->references('id')->on('tracks');
|
||||
$table->foreign('album_id')->references('id')->on('albums');
|
||||
$table->foreign('playlist_id')->references('id')->on('playlists');
|
||||
|
||||
$table->unique(['user_id', 'track_id', 'album_id', 'playlist_id']);
|
||||
});
|
||||
|
||||
Schema::create('resource_log_items', function($table){
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned()->nullable()->index();
|
||||
$table->integer('log_type')->unsigned();
|
||||
$table->string('ip_address', 46)->index();
|
||||
$table->integer('track_format_id')->unsigned()->nullable();
|
||||
|
||||
$table->integer('track_id')->unsigned()->nullable()->index();
|
||||
$table->integer('album_id')->unsigned()->nullable()->index();
|
||||
$table->integer('playlist_id')->unsigned()->nullable()->index();
|
||||
|
||||
$table->timestamp('created_at');
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->on_delete('cascade');
|
||||
$table->foreign('track_id')->references('id')->on('tracks');
|
||||
$table->foreign('album_id')->references('id')->on('albums');
|
||||
$table->foreign('playlist_id')->references('id')->on('playlists');
|
||||
});
|
||||
}
|
||||
|
||||
public function down() {
|
||||
Schema::drop('resource_users');
|
||||
Schema::drop('resource_log_items');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateFavourites extends Migration {
|
||||
public function up() {
|
||||
Schema::create('favourites', function($table){
|
||||
$table->increments('id');
|
||||
$table->integer('user_id')->unsigned()->index();
|
||||
|
||||
$table->integer('track_id')->unsigned()->nullable()->index();
|
||||
$table->integer('album_id')->unsigned()->nullable()->index();
|
||||
$table->integer('playlist_id')->unsigned()->nullable()->index();
|
||||
|
||||
$table->timestamp('created_at');
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->on_delete('cascade');
|
||||
$table->foreign('track_id')->references('id')->on('tracks');
|
||||
$table->foreign('album_id')->references('id')->on('albums');
|
||||
$table->foreign('playlist_id')->references('id')->on('playlists');
|
||||
});
|
||||
}
|
||||
|
||||
public function down() {
|
||||
Schema::table('favourites', function($table){
|
||||
$table->dropForeign('favourites_user_id_foreign');
|
||||
$table->dropForeign('favourites_track_id_foreign');
|
||||
$table->dropForeign('favourites_album_id_foreign');
|
||||
$table->dropForeign('favourites_playlist_id_foreign');
|
||||
});
|
||||
|
||||
Schema::drop('favourites');
|
||||
}
|
||||
}
|
573
app/library/ZipStream.php
Normal file
573
app/library/ZipStream.php
Normal file
|
@ -0,0 +1,573 @@
|
|||
<?php
|
||||
/**
|
||||
* Class to create zip file, aimed at large files, or even large target zip file.
|
||||
* This class will stream the generated zip file directly to the HTTP client as the content is added.
|
||||
*
|
||||
* If you need the Zip file data on the server, for storage in a database of the server file system, look at
|
||||
* the Zip class at http://www.phpclasses.org/browse/package/6110.html
|
||||
*
|
||||
* License: GNU LGPL, Attribution required for commercial implementations, requested for everything else.
|
||||
*
|
||||
* Inspired on CreateZipFile by Rochak Chauhan www.rochakchauhan.com (http://www.phpclasses.org/browse/package/2322.html)
|
||||
* and
|
||||
* http://www.pkware.com/documents/casestudies/APPNOTE.TXT Zip file specification.
|
||||
*
|
||||
* @author A. Grandt <php@grandt.com>
|
||||
* @copyright 2009-2013 A. Grandt
|
||||
* @license GNU LGPL, Attribution required for commercial implementations, requested for everything else.
|
||||
* @link http://www.phpclasses.org/package/6116
|
||||
* @link https://github.com/Grandt/PHPZip
|
||||
* @version 1.37
|
||||
*/
|
||||
class ZipStream {
|
||||
const VERSION = 1.37;
|
||||
|
||||
const ZIP_LOCAL_FILE_HEADER = "\x50\x4b\x03\x04"; // Local file header signature
|
||||
const ZIP_CENTRAL_FILE_HEADER = "\x50\x4b\x01\x02"; // Central file header signature
|
||||
const ZIP_END_OF_CENTRAL_DIRECTORY = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
|
||||
|
||||
const EXT_FILE_ATTR_DIR = "\x10\x00\xFF\x41";
|
||||
const EXT_FILE_ATTR_FILE = "\x00\x00\xFF\x81";
|
||||
|
||||
const ATTR_VERSION_TO_EXTRACT = "\x14\x00"; // Version needed to extract
|
||||
const ATTR_MADE_BY_VERSION = "\x1E\x03"; // Made By Version
|
||||
|
||||
private $zipMemoryThreshold = 1048576; // Autocreate tempfile if the zip data exceeds 1048576 bytes (1 MB)
|
||||
|
||||
private $zipComment = null;
|
||||
private $cdRec = array(); // central directory
|
||||
private $offset = 0;
|
||||
private $isFinalized = FALSE;
|
||||
private $addExtraField = TRUE;
|
||||
|
||||
private $streamChunkSize = 16384; // 65536;
|
||||
private $streamFilePath = null;
|
||||
private $streamTimeStamp = null;
|
||||
private $streamComment = null;
|
||||
private $streamFile = null;
|
||||
private $streamData = null;
|
||||
private $streamFileLength = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param String $archiveName Name to send to the HTTP client.
|
||||
* @param String $contentType Content mime type. Optional, defaults to "application/zip".
|
||||
*/
|
||||
function __construct($archiveName = "", $contentType = "application/zip") {
|
||||
if (!function_exists('sys_get_temp_dir')) {
|
||||
die ("ERROR: ZipStream " . self::VERSION . " requires PHP version 5.2.1 or above.");
|
||||
}
|
||||
|
||||
$headerFile = null;
|
||||
$headerLine = null;
|
||||
if (!headers_sent($headerFile, $headerLine) or die("<p><strong>Error:</strong> Unable to send file $archiveName. HTML Headers have already been sent from <strong>$headerFile</strong> in line <strong>$headerLine</strong></p>")) {
|
||||
if ((ob_get_contents() === FALSE || ob_get_contents() == '') or die("\n<p><strong>Error:</strong> Unable to send file <strong>$archiveName.epub</strong>. Output buffer contains the following text (typically warnings or errors):<br>" . ob_get_contents() . "</p>")) {
|
||||
if (ini_get('zlib.output_compression')) {
|
||||
ini_set('zlib.output_compression', 'Off');
|
||||
}
|
||||
|
||||
header('Pragma: public');
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s T"));
|
||||
header("Expires: 0");
|
||||
header("Accept-Ranges: bytes");
|
||||
//header("Connection: Keep-Alive");
|
||||
header("Content-Type: " . $contentType);
|
||||
header('Content-Disposition: attachment; filename="' . $archiveName . '";');
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
$this->isFinalized = TRUE;
|
||||
$this->cdRec = null;
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra fields on the Zip directory records are Unix time codes needed for compatibility on the default Mac zip archive tool.
|
||||
* These are enabled as default, as they do no harm elsewhere and only add 26 bytes per file added.
|
||||
*
|
||||
* @param bool $setExtraField TRUE (default) will enable adding of extra fields, anything else will disable it.
|
||||
*/
|
||||
function setExtraField($setExtraField = TRUE) {
|
||||
$this->addExtraField = ($setExtraField === TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Zip archive comment.
|
||||
*
|
||||
* @param string $newComment New comment. null to clear.
|
||||
* @return bool $success
|
||||
*/
|
||||
public function setComment($newComment = null) {
|
||||
if ($this->isFinalized) {
|
||||
return FALSE;
|
||||
}
|
||||
$this->zipComment = $newComment;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an empty directory entry to the zip archive.
|
||||
* Basically this is only used if an empty directory is added.
|
||||
*
|
||||
* @param string $directoryPath Directory Path and name to be added to the archive.
|
||||
* @param int $timestamp (Optional) Timestamp for the added directory, if omitted or set to 0, the current time will be used.
|
||||
* @param string $fileComment (Optional) Comment to be added to the archive for this directory. To use fileComment, timestamp must be given.
|
||||
* @return bool $success
|
||||
*/
|
||||
public function addDirectory($directoryPath, $timestamp = 0, $fileComment = null) {
|
||||
if ($this->isFinalized) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$directoryPath = str_replace("\\", "/", $directoryPath);
|
||||
$directoryPath = rtrim($directoryPath, "/");
|
||||
|
||||
if (strlen($directoryPath) > 0) {
|
||||
$this->buildZipEntry($directoryPath.'/', $fileComment, "\x00\x00", "\x00\x00", $timestamp, "\x00\x00\x00\x00", 0, 0, self::EXT_FILE_ATTR_DIR);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the archive at the specified location and file name.
|
||||
*
|
||||
* @param string $data File data.
|
||||
* @param string $filePath Filepath and name to be used in the archive.
|
||||
* @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
|
||||
* @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given.
|
||||
* @return bool $success
|
||||
*/
|
||||
public function addFile($data, $filePath, $timestamp = 0, $fileComment = null) {
|
||||
if ($this->isFinalized) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (is_resource($data) && get_resource_type($data) == "stream") {
|
||||
$this->addLargeFile($data, $filePath, $timestamp, $fileComment);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$gzType = "\x08\x00"; // Compression type 8 = deflate
|
||||
$gpFlags = "\x00\x00"; // General Purpose bit flags for compression type 8 it is: 0=Normal, 1=Maximum, 2=Fast, 3=super fast compression.
|
||||
$dataLength = strlen($data);
|
||||
$fileCRC32 = pack("V", crc32($data));
|
||||
|
||||
$gzData = gzcompress($data);
|
||||
$gzData = substr(substr($gzData, 0, strlen($gzData) - 4), 2); // gzcompress adds a 2 byte header and 4 byte CRC we can't use.
|
||||
// The 2 byte header does contain useful data, though in this case the 2 parameters we'd be interrested in will always be 8 for compression type, and 2 for General purpose flag.
|
||||
$gzLength = strlen($gzData);
|
||||
|
||||
if ($gzLength >= $dataLength) {
|
||||
$gzLength = $dataLength;
|
||||
$gzData = $data;
|
||||
$gzType = "\x00\x00"; // Compression type 0 = stored
|
||||
$gpFlags = "\x00\x00"; // Compression type 0 = stored
|
||||
}
|
||||
|
||||
$this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, self::EXT_FILE_ATTR_FILE);
|
||||
|
||||
print ($gzData);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the content to a directory.
|
||||
*
|
||||
* @author Adam Schmalhofer <Adam.Schmalhofer@gmx.de>
|
||||
* @author A. Grandt
|
||||
*
|
||||
* @param String $realPath Path on the file system.
|
||||
* @param String $zipPath Filepath and name to be used in the archive.
|
||||
* @param bool $recursive Add content recursively, default is TRUE.
|
||||
* @param bool $followSymlinks Follow and add symbolic links, if they are accessible, default is TRUE.
|
||||
* @param array &$addedFiles Reference to the added files, this is used to prevent duplicates, efault is an empty array.
|
||||
* If you start the function by parsing an array, the array will be populated with the realPath
|
||||
* and zipPath kay/value pairs added to the archive by the function.
|
||||
*/
|
||||
public function addDirectoryContent($realPath, $zipPath, $recursive = TRUE, $followSymlinks = TRUE, &$addedFiles = array()) {
|
||||
if (file_exists($realPath) && !isset($addedFiles[realpath($realPath)])) {
|
||||
if (is_dir($realPath)) {
|
||||
$this->addDirectory($zipPath);
|
||||
}
|
||||
|
||||
$addedFiles[realpath($realPath)] = $zipPath;
|
||||
|
||||
$iter = new DirectoryIterator($realPath);
|
||||
foreach ($iter as $file) {
|
||||
if ($file->isDot()) {
|
||||
continue;
|
||||
}
|
||||
$newRealPath = $file->getPathname();
|
||||
$newZipPath = self::pathJoin($zipPath, $file->getFilename());
|
||||
|
||||
if (file_exists($newRealPath) && ($followSymlinks === TRUE || !is_link($newRealPath))) {
|
||||
if ($file->isFile()) {
|
||||
$addedFiles[realpath($newRealPath)] = $newZipPath;
|
||||
$this->addLargeFile($newRealPath, $newZipPath);
|
||||
} else if ($recursive === TRUE) {
|
||||
$this->addDirectoryContent($newRealPath, $newZipPath, $recursive);
|
||||
} else {
|
||||
$this->addDirectory($zipPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to the archive at the specified location and file name.
|
||||
*
|
||||
* @param string $dataFile File name/path.
|
||||
* @param string $filePath Filepath and name to be used in the archive.
|
||||
* @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
|
||||
* @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given.
|
||||
* @return bool $success
|
||||
*/
|
||||
public function addLargeFile($dataFile, $filePath, $timestamp = 0, $fileComment = null) {
|
||||
if ($this->isFinalized) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (is_string($dataFile) && is_file($dataFile)) {
|
||||
$this->processFile($dataFile, $filePath, $timestamp, $fileComment);
|
||||
} else if (is_resource($dataFile) && get_resource_type($dataFile) == "stream") {
|
||||
$fh = $dataFile;
|
||||
$this->openStream($filePath, $timestamp, $fileComment);
|
||||
|
||||
while (!feof($fh)) {
|
||||
$this->addStreamData(fread($fh, $this->streamChunkSize));
|
||||
}
|
||||
$this->closeStream($this->addExtraField);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a stream to be used for large entries.
|
||||
*
|
||||
* @param string $filePath Filepath and name to be used in the archive.
|
||||
* @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used.
|
||||
* @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given.
|
||||
* @return bool $success
|
||||
*/
|
||||
public function openStream($filePath, $timestamp = 0, $fileComment = null) {
|
||||
if (!function_exists('sys_get_temp_dir')) {
|
||||
die ("ERROR: Zip " . self::VERSION . " requires PHP version 5.2.1 or above if large files are used.");
|
||||
}
|
||||
|
||||
if ($this->isFinalized) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (strlen($this->streamFilePath) > 0) {
|
||||
closeStream();
|
||||
}
|
||||
|
||||
$this->streamFile = tempnam(sys_get_temp_dir(), 'ZipStream');
|
||||
$this->streamData = fopen($this->streamFile, "wb");
|
||||
$this->streamFilePath = $filePath;
|
||||
$this->streamTimestamp = $timestamp;
|
||||
$this->streamFileComment = $fileComment;
|
||||
$this->streamFileLength = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data to the open stream.
|
||||
*
|
||||
* @param String $data
|
||||
* @return $length bytes added or FALSE if the archive is finalized or there are no open stream.
|
||||
*/
|
||||
public function addStreamData($data) {
|
||||
if ($this->isFinalized || strlen($this->streamFilePath) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$length = fwrite($this->streamData, $data, strlen($data));
|
||||
if ($length != strlen($data)) {
|
||||
die ("<p>Length mismatch</p>\n");
|
||||
}
|
||||
$this->streamFileLength += $length;
|
||||
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current stream.
|
||||
*
|
||||
* @return bool $success
|
||||
*/
|
||||
public function closeStream() {
|
||||
if ($this->isFinalized || strlen($this->streamFilePath) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fflush($this->streamData);
|
||||
fclose($this->streamData);
|
||||
|
||||
$this->processFile($this->streamFile, $this->streamFilePath, $this->streamTimestamp, $this->streamFileComment);
|
||||
|
||||
$this->streamData = null;
|
||||
$this->streamFilePath = null;
|
||||
$this->streamTimestamp = null;
|
||||
$this->streamFileComment = null;
|
||||
$this->streamFileLength = 0;
|
||||
|
||||
// Windows is a little slow at times, so a millisecond later, we can unlink this.
|
||||
unlink($this->streamFile);
|
||||
|
||||
$this->streamFile = null;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
private function processFile($dataFile, $filePath, $timestamp = 0, $fileComment = null) {
|
||||
if ($this->isFinalized) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$tempzip = tempnam(sys_get_temp_dir(), 'ZipStream');
|
||||
|
||||
$zip = new ZipArchive;
|
||||
if ($zip->open($tempzip) === TRUE) {
|
||||
$zip->addFile($dataFile, 'file');
|
||||
$zip->close();
|
||||
}
|
||||
|
||||
$file_handle = fopen($tempzip, "rb");
|
||||
$stats = fstat($file_handle);
|
||||
$eof = $stats['size']-72;
|
||||
|
||||
fseek($file_handle, 6);
|
||||
|
||||
$gpFlags = fread($file_handle, 2);
|
||||
$gzType = fread($file_handle, 2);
|
||||
fread($file_handle, 4);
|
||||
$fileCRC32 = fread($file_handle, 4);
|
||||
$v = unpack("Vval", fread($file_handle, 4));
|
||||
$gzLength = $v['val'];
|
||||
$v = unpack("Vval", fread($file_handle, 4));
|
||||
$dataLength = $v['val'];
|
||||
|
||||
$this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, self::EXT_FILE_ATTR_FILE);
|
||||
|
||||
fseek($file_handle, 34);
|
||||
$pos = 34;
|
||||
|
||||
while (!feof($file_handle) && $pos < $eof) {
|
||||
$datalen = $this->streamChunkSize;
|
||||
if ($pos + $this->streamChunkSize > $eof) {
|
||||
$datalen = $eof-$pos;
|
||||
}
|
||||
echo fread($file_handle, $datalen);
|
||||
$pos += $datalen;
|
||||
flush();
|
||||
}
|
||||
|
||||
fclose($file_handle);
|
||||
unlink($tempzip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the archive.
|
||||
* A closed archive can no longer have new files added to it.
|
||||
* @return bool $success
|
||||
*/
|
||||
public function finalize() {
|
||||
if (!$this->isFinalized) {
|
||||
if (strlen($this->streamFilePath) > 0) {
|
||||
$this->closeStream();
|
||||
}
|
||||
|
||||
$cdRecSize = pack("v", sizeof($this->cdRec));
|
||||
|
||||
$cd = implode("", $this->cdRec);
|
||||
print($cd);
|
||||
print(self::ZIP_END_OF_CENTRAL_DIRECTORY);
|
||||
print($cdRecSize.$cdRecSize);
|
||||
print(pack("VV", strlen($cd), $this->offset));
|
||||
if (!empty($this->zipComment)) {
|
||||
print(pack("v", strlen($this->zipComment)));
|
||||
print($this->zipComment);
|
||||
} else {
|
||||
print("\x00\x00");
|
||||
}
|
||||
|
||||
flush();
|
||||
|
||||
$this->isFinalized = TRUE;
|
||||
$cd = null;
|
||||
$this->cdRec = null;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the 2 byte dostime used in the zip entries.
|
||||
*
|
||||
* @param int $timestamp
|
||||
* @return 2-byte encoded DOS Date
|
||||
*/
|
||||
private function getDosTime($timestamp = 0) {
|
||||
$timestamp = (int)$timestamp;
|
||||
$oldTZ = @date_default_timezone_get();
|
||||
date_default_timezone_set('UTC');
|
||||
$date = ($timestamp == 0 ? getdate() : getdate($timestamp));
|
||||
date_default_timezone_set($oldTZ);
|
||||
if ($date["year"] >= 1980) {
|
||||
return pack("V", (($date["mday"] + ($date["mon"] << 5) + (($date["year"]-1980) << 9)) << 16) |
|
||||
(($date["seconds"] >> 1) + ($date["minutes"] << 5) + ($date["hours"] << 11)));
|
||||
}
|
||||
return "\x00\x00\x00\x00";
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the Zip file structures
|
||||
*
|
||||
* @param String $filePath
|
||||
* @param String $fileComment
|
||||
* @param String $gpFlags
|
||||
* @param String $gzType
|
||||
* @param int $timestamp
|
||||
* @param string $fileCRC32
|
||||
* @param int $gzLength
|
||||
* @param int $dataLength
|
||||
* @param integer $extFileAttr Use self::EXT_FILE_ATTR_FILE for files, self::EXT_FILE_ATTR_DIR for Directories.
|
||||
*/
|
||||
private function buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr) {
|
||||
$filePath = str_replace("\\", "/", $filePath);
|
||||
$fileCommentLength = (empty($fileComment) ? 0 : strlen($fileComment));
|
||||
$timestamp = (int)$timestamp;
|
||||
$timestamp = ($timestamp == 0 ? time() : $timestamp);
|
||||
|
||||
$dosTime = $this->getDosTime($timestamp);
|
||||
$tsPack = pack("V", $timestamp);
|
||||
|
||||
$ux = "\x75\x78\x0B\x00\x01\x04\xE8\x03\x00\x00\x04\x00\x00\x00\x00";
|
||||
|
||||
if (!isset($gpFlags) || strlen($gpFlags) != 2) {
|
||||
$gpFlags = "\x00\x00";
|
||||
}
|
||||
|
||||
$isFileUTF8 = mb_check_encoding($filePath, "UTF-8") && !mb_check_encoding($filePath, "ASCII");
|
||||
$isCommentUTF8 = !empty($fileComment) && mb_check_encoding($fileComment, "UTF-8") && !mb_check_encoding($fileComment, "ASCII");
|
||||
if ($isFileUTF8 || $isCommentUTF8) {
|
||||
$flag = 0;
|
||||
$gpFlagsV = unpack("vflags", $gpFlags);
|
||||
if (isset($gpFlagsV['flags'])) {
|
||||
$flag = $gpFlagsV['flags'];
|
||||
}
|
||||
$gpFlags = pack("v", $flag | (1 << 11));
|
||||
}
|
||||
|
||||
$header = $gpFlags . $gzType . $dosTime. $fileCRC32
|
||||
. pack("VVv", $gzLength, $dataLength, strlen($filePath)); // File name length
|
||||
|
||||
$zipEntry = self::ZIP_LOCAL_FILE_HEADER;
|
||||
$zipEntry .= self::ATTR_VERSION_TO_EXTRACT;
|
||||
$zipEntry .= $header;
|
||||
$zipEntry .= $this->addExtraField ? "\x1C\x00" : "\x00\x00"; // Extra field length
|
||||
$zipEntry .= $filePath; // FileName
|
||||
// Extra fields
|
||||
if ($this->addExtraField) {
|
||||
$zipEntry .= "\x55\x54\x09\x00\x03" . $tsPack . $tsPack . $ux;
|
||||
}
|
||||
|
||||
print($zipEntry);
|
||||
|
||||
$cdEntry = self::ZIP_CENTRAL_FILE_HEADER;
|
||||
$cdEntry .= self::ATTR_MADE_BY_VERSION;
|
||||
$cdEntry .= ($dataLength === 0 ? "\x0A\x00" : self::ATTR_VERSION_TO_EXTRACT);
|
||||
$cdEntry .= $header;
|
||||
$cdEntry .= $this->addExtraField ? "\x18\x00" : "\x00\x00"; // Extra field length
|
||||
$cdEntry .= pack("v", $fileCommentLength); // File comment length
|
||||
$cdEntry .= "\x00\x00"; // Disk number start
|
||||
$cdEntry .= "\x00\x00"; // internal file attributes
|
||||
$cdEntry .= $extFileAttr; // External file attributes
|
||||
$cdEntry .= pack("V", $this->offset); // Relative offset of local header
|
||||
$cdEntry .= $filePath; // FileName
|
||||
// Extra fields
|
||||
if ($this->addExtraField) {
|
||||
$cdEntry .= "\x55\x54\x05\x00\x03" . $tsPack . $ux;
|
||||
}
|
||||
|
||||
if (!empty($fileComment)) {
|
||||
$cdEntry .= $fileComment; // Comment
|
||||
}
|
||||
|
||||
$this->cdRec[] = $cdEntry;
|
||||
$this->offset += strlen($zipEntry) + $gzLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join $file to $dir path, and clean up any excess slashes.
|
||||
*
|
||||
* @param String $dir
|
||||
* @param String $file
|
||||
*/
|
||||
public static function pathJoin($dir, $file) {
|
||||
if (empty($dir) || empty($file)) {
|
||||
return self::getRelativePath($dir . $file);
|
||||
}
|
||||
return self::getRelativePath($dir . '/' . $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up a path, removing any unnecessary elements such as /./, // or redundant ../ segments.
|
||||
* If the path starts with a "/", it is deemed an absolute path and any /../ in the beginning is stripped off.
|
||||
* The returned path will not end in a "/".
|
||||
*
|
||||
* @param String $path The path to clean up
|
||||
* @return String the clean path
|
||||
*/
|
||||
public static function getRelativePath($path) {
|
||||
$path = preg_replace("#/+\.?/+#", "/", str_replace("\\", "/", $path));
|
||||
$dirs = explode("/", rtrim(preg_replace('#^(?:\./)+#', '', $path), '/'));
|
||||
|
||||
$offset = 0;
|
||||
$sub = 0;
|
||||
$subOffset = 0;
|
||||
$root = "";
|
||||
|
||||
if (empty($dirs[0])) {
|
||||
$root = "/";
|
||||
$dirs = array_splice($dirs, 1);
|
||||
} else if (preg_match("#[A-Za-z]:#", $dirs[0])) {
|
||||
$root = strtoupper($dirs[0]) . "/";
|
||||
$dirs = array_splice($dirs, 1);
|
||||
}
|
||||
|
||||
$newDirs = array();
|
||||
foreach ($dirs as $dir) {
|
||||
if ($dir !== "..") {
|
||||
$subOffset--;
|
||||
$newDirs[++$offset] = $dir;
|
||||
} else {
|
||||
$subOffset++;
|
||||
if (--$offset < 0) {
|
||||
$offset = 0;
|
||||
if ($subOffset > $sub) {
|
||||
$sub++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($root)) {
|
||||
$root = str_repeat("../", $sub);
|
||||
}
|
||||
return $root . implode("/", array_slice($newDirs, 0, $offset));
|
||||
}
|
||||
}
|
||||
?>
|
48
app/models/AlbumDownloader.php
Normal file
48
app/models/AlbumDownloader.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
class AlbumDownloader {
|
||||
private $_album;
|
||||
private $_format;
|
||||
|
||||
function __construct($album, $format) {
|
||||
$this->_album = $album;
|
||||
$this->_format = $format;
|
||||
}
|
||||
|
||||
function download() {
|
||||
$zip = new ZipStream($this->_album->user->display_name . ' - ' . $this->_album->title . '.zip');
|
||||
$zip->setComment(
|
||||
'Album: ' . $this->_album->title ."\r\n".
|
||||
'Artist: ' . $this->_album->user->display_name ."\r\n".
|
||||
'URL: ' . $this->_album->url ."\r\n"."\r\n".
|
||||
'Downloaded on '. date('l, F jS, Y, \a\t h:i:s A') . '.'
|
||||
);
|
||||
|
||||
$directory = $this->_album->user->display_name . '/' . $this->_album->title . '/';
|
||||
|
||||
$notes =
|
||||
'Album: ' . $this->_album->title ."\r\n".
|
||||
'Artist: ' . $this->_album->user->display_name ."\r\n".
|
||||
'URL: ' . $this->_album->url ."\r\n".
|
||||
"\r\n".
|
||||
$this->_album->description ."\r\n".
|
||||
"\r\n".
|
||||
"\r\n".
|
||||
'Tracks' ."\r\n".
|
||||
"\r\n";
|
||||
|
||||
foreach ($this->_album->tracks as $track) {
|
||||
if (!$track->is_downloadable)
|
||||
continue;
|
||||
|
||||
$zip->addLargeFile($track->getFileFor($this->_format), $directory . $track->getDownloadFilenameFor($this->_format));
|
||||
$notes .=
|
||||
$track->track_number . '. ' . $track->title ."\r\n".
|
||||
$track->description ."\r\n".
|
||||
"\r\n";
|
||||
}
|
||||
|
||||
$zip->addFile($notes, $directory . 'Album Notes.txt');
|
||||
$zip->finalize();
|
||||
}
|
||||
}
|
|
@ -5,8 +5,10 @@
|
|||
use Entities\Album;
|
||||
use Entities\Favourite;
|
||||
use Entities\Playlist;
|
||||
use Entities\ResourceUser;
|
||||
use Entities\Track;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ToggleFavouriteCommand extends CommandBase {
|
||||
private $_resourceType;
|
||||
|
@ -31,7 +33,7 @@
|
|||
*/
|
||||
public function execute() {
|
||||
$typeId = $this->_resourceType . '_id';
|
||||
$existing = Favourite::where($typeId, '=', $this->_resourceId)->first();
|
||||
$existing = Favourite::where($typeId, '=', $this->_resourceId)->whereUserId(Auth::user()->id)->first();
|
||||
$isFavourited = false;
|
||||
|
||||
if ($existing) {
|
||||
|
@ -40,10 +42,30 @@
|
|||
$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]);
|
||||
}
|
||||
}
|
|
@ -16,12 +16,12 @@
|
|||
use SlugTrait;
|
||||
|
||||
public static function summary() {
|
||||
return self::select('id', 'title', 'user_id', 'slug', 'created_at', 'cover_id');
|
||||
return self::select('id', 'title', 'user_id', 'slug', 'created_at', 'cover_id', 'comment_count', 'download_count', 'view_count', 'favourite_count');
|
||||
}
|
||||
|
||||
public function scopeDetails($query) {
|
||||
if (Auth::check()) {
|
||||
$query->with(['favourites' => function($query) {
|
||||
$query->with(['users' => function($query) {
|
||||
$query->whereUserId(Auth::user()->id);
|
||||
}]);
|
||||
}
|
||||
|
@ -35,6 +35,10 @@
|
|||
return $this->belongsTo('Entities\User');
|
||||
}
|
||||
|
||||
public function users() {
|
||||
return $this->hasMany('Entities\ResourceUser');
|
||||
}
|
||||
|
||||
public function favourites() {
|
||||
return $this->hasMany('Entities\Favourite');
|
||||
}
|
||||
|
@ -76,21 +80,42 @@
|
|||
$data['tracks'] = $tracks;
|
||||
$data['comments'] = ['count' => count($comments), 'list' => $comments];
|
||||
$data['formats'] = $formats;
|
||||
$data['stats'] = [
|
||||
'views' => 0,
|
||||
'downloads' => 0
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function mapPublicAlbumSummary($album) {
|
||||
$userData = [
|
||||
'stats' => [
|
||||
'views' => 0,
|
||||
'downloads' => 0
|
||||
],
|
||||
'is_favourited' => false
|
||||
];
|
||||
|
||||
if ($album->users->count()) {
|
||||
$userRow = $album->users[0];
|
||||
$userData = [
|
||||
'stats' => [
|
||||
'views' => $userRow->view_count,
|
||||
'downloads' => $userRow->download_count,
|
||||
],
|
||||
'is_favourited' => $userRow->is_favourited
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $album->id,
|
||||
'track_count' => $album->tracks->count(),
|
||||
'title' => $album->title,
|
||||
'slug' => $album->slug,
|
||||
'created_at' => $album->created_at,
|
||||
'stats' => [
|
||||
'views' => $album->view_count,
|
||||
'downloads' => $album->download_count,
|
||||
'comments' => $album->comment_count,
|
||||
'favourites' => $album->favourite_count
|
||||
],
|
||||
'covers' => [
|
||||
'small' => $album->getCoverUrl(Image::SMALL),
|
||||
'normal' => $album->getCoverUrl(Image::NORMAL)
|
||||
|
@ -101,7 +126,7 @@
|
|||
'name' => $album->user->display_name,
|
||||
'url' => $album->user->url,
|
||||
],
|
||||
'is_favourited' => $album->favourites->count() > 0
|
||||
'user_data' => $userData
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
class Favourite extends \Eloquent {
|
||||
protected $table = 'favourites';
|
||||
public $timestamps = false;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -44,7 +45,7 @@
|
|||
|
||||
// no resource - this should never happen under real circumstances
|
||||
else
|
||||
return NULL;
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getTypeAttribute(){
|
||||
|
|
69
app/models/Entities/ResourceLogItem.php
Normal file
69
app/models/Entities/ResourceLogItem.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Entities;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Traits\SlugTrait;
|
||||
|
||||
class ResourceLogItem extends \Eloquent {
|
||||
protected $table = 'resource_log_items';
|
||||
public $timestamps = false;
|
||||
|
||||
const VIEW = 1;
|
||||
const DOWNLOAD = 2;
|
||||
const PLAY = 3;
|
||||
|
||||
public static function logItem($resourceType, $resourceId, $logType, $formatId = null) {
|
||||
$resourceIdColumn = $resourceType . '_id';
|
||||
|
||||
$logItem = new ResourceLogItem();
|
||||
$logItem->{$resourceIdColumn} = $resourceId;
|
||||
$logItem->created_at = time();
|
||||
$logItem->log_type = $logType;
|
||||
$logItem->track_format_id = $formatId;
|
||||
$logItem->ip_address = Request::getClientIp();
|
||||
|
||||
if (Auth::check()) {
|
||||
$logItem->user_id = Auth::user()->id;
|
||||
}
|
||||
|
||||
$logItem->save();
|
||||
|
||||
$resourceTable = $resourceType . 's';
|
||||
$countColumn = '';
|
||||
|
||||
if ($logType == self::VIEW) $countColumn = 'view_count';
|
||||
else if ($logType == self::DOWNLOAD) $countColumn = 'download_count';
|
||||
else if ($logType == self::PLAY) $countColumn = 'play_count';
|
||||
|
||||
// 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($resourceId)->update([$countColumn =>
|
||||
DB::raw('(SELECT
|
||||
COUNT(id)
|
||||
FROM
|
||||
resource_log_items
|
||||
WHERE ' .
|
||||
$resourceIdColumn . ' = ' . $resourceId . '
|
||||
AND
|
||||
log_type = ' . $logType . ')')]);
|
||||
|
||||
if (Auth::check()) {
|
||||
$resourceUserId = ResourceUser::getId(Auth::user()->id, $resourceType, $resourceId);
|
||||
DB::table('resource_users')->whereId($resourceUserId)->update([$countColumn =>
|
||||
DB::raw('(SELECT
|
||||
COUNT(id)
|
||||
FROM
|
||||
resource_log_items
|
||||
WHERE
|
||||
user_id = ' . Auth::user()->id . '
|
||||
AND ' .
|
||||
$resourceIdColumn . ' = ' . $resourceId . '
|
||||
AND
|
||||
log_type = ' . $logType . ')')]);
|
||||
}
|
||||
}
|
||||
}
|
30
app/models/Entities/ResourceUser.php
Normal file
30
app/models/Entities/ResourceUser.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Entities;
|
||||
use Traits\SlugTrait;
|
||||
|
||||
class ResourceUser extends \Eloquent {
|
||||
protected $table = 'resource_users';
|
||||
public $timestamps = false;
|
||||
|
||||
public static function get($userId, $resourceType, $resourceId) {
|
||||
$resourceIdColumn = $resourceType . '_id';
|
||||
$existing = self::where($resourceIdColumn, '=', $resourceId)->where('user_id', '=', $userId)->first();
|
||||
if ($existing)
|
||||
return $existing;
|
||||
|
||||
$item = new ResourceUser();
|
||||
$item->{$resourceIdColumn} = $resourceId;
|
||||
$item->user_id = $userId;
|
||||
return $item;
|
||||
}
|
||||
|
||||
public static function getId($userId, $resourceType, $resourceId) {
|
||||
$item = self::get($userId, $resourceType, $resourceId);
|
||||
if ($item->exists)
|
||||
return $item->id;
|
||||
|
||||
$item->save();
|
||||
return $item->id;
|
||||
}
|
||||
}
|
|
@ -20,20 +20,20 @@
|
|||
use SlugTrait;
|
||||
|
||||
public static $Formats = [
|
||||
'FLAC' => ['extension' => 'flac', 'tag_format' => 'metaflac', 'tag_method' => 'updateTagsWithGetId3', 'mime_type' => 'audio/flac', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec flac -aq 8 -f flac {$target}'],
|
||||
'MP3' => ['extension' => 'mp3', 'tag_format' => 'id3v2.3', 'tag_method' => 'updateTagsWithGetId3', 'mime_type' => 'audio/mpeg', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec libmp3lame -ab 320k -f mp3 {$target}'],
|
||||
'OGG Vorbis' => ['extension' => 'ogg', 'tag_format' => 'vorbiscomment', 'tag_method' => 'updateTagsWithGetId3', 'mime_type' => 'audio/ogg', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec libvorbis -aq 7 -f ogg {$target}'],
|
||||
'AAC' => ['extension' => 'm4a', 'tag_format' => 'AtomicParsley', 'tag_method' => 'updateTagsWithAtomicParsley', 'mime_type' => 'audio/mp4', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec libfaac -ab 256k -f mp4 {$target}'],
|
||||
'ALAC' => ['extension' => 'alac.m4a', 'tag_format' => 'AtomicParsley', 'tag_method' => 'updateTagsWithAtomicParsley', 'mime_type' => 'audio/mp4', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec alac {$target}'],
|
||||
'FLAC' => ['index' => 0, 'extension' => 'flac', 'tag_format' => 'metaflac', 'tag_method' => 'updateTagsWithGetId3', 'mime_type' => 'audio/flac', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec flac -aq 8 -f flac {$target}'],
|
||||
'MP3' => ['index' => 1, 'extension' => 'mp3', 'tag_format' => 'id3v2.3', 'tag_method' => 'updateTagsWithGetId3', 'mime_type' => 'audio/mpeg', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec libmp3lame -ab 320k -f mp3 {$target}'],
|
||||
'OGG Vorbis' => ['index' => 2, 'extension' => 'ogg', 'tag_format' => 'vorbiscomment', 'tag_method' => 'updateTagsWithGetId3', 'mime_type' => 'audio/ogg', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec libvorbis -aq 7 -f ogg {$target}'],
|
||||
'AAC' => ['index' => 3, 'extension' => 'm4a', 'tag_format' => 'AtomicParsley', 'tag_method' => 'updateTagsWithAtomicParsley', 'mime_type' => 'audio/mp4', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec libfaac -ab 256k -f mp4 {$target}'],
|
||||
'ALAC' => ['index' => 4, 'extension' => 'alac.m4a', 'tag_format' => 'AtomicParsley', 'tag_method' => 'updateTagsWithAtomicParsley', 'mime_type' => 'audio/mp4', 'command' => 'ffmpeg 2>&1 -y -i {$source} -acodec alac {$target}'],
|
||||
];
|
||||
|
||||
public static function summary() {
|
||||
return self::select('id', 'title', 'user_id', 'slug', 'is_vocal', 'is_explicit', 'created_at', 'published_at', 'duration', 'is_downloadable', 'genre_id', 'track_type_id', 'cover_id', 'album_id');
|
||||
return self::select('id', 'title', 'user_id', 'slug', 'is_vocal', 'is_explicit', 'created_at', 'published_at', 'duration', 'is_downloadable', 'genre_id', 'track_type_id', 'cover_id', 'album_id', 'comment_count', 'download_count', 'view_count', 'play_count', 'favourite_count');
|
||||
}
|
||||
|
||||
public function scopeDetails($query) {
|
||||
if (Auth::check()) {
|
||||
$query->with(['favourites' => function($query) {
|
||||
$query->with(['users' => function($query) {
|
||||
$query->whereUserId(Auth::user()->id);
|
||||
}]);
|
||||
}
|
||||
|
@ -49,11 +49,6 @@
|
|||
$returnValue = self::mapPublicTrackSummary($track);
|
||||
$returnValue['description'] = $track->description;
|
||||
$returnValue['lyrics'] = $track->lyrics;
|
||||
$returnValue['stats'] = [
|
||||
'views' => 0,
|
||||
'plays' => 0,
|
||||
'downloads' => 0
|
||||
];
|
||||
|
||||
$comments = [];
|
||||
|
||||
|
@ -61,7 +56,7 @@
|
|||
$comments[] = Comment::mapPublic($comment);
|
||||
}
|
||||
|
||||
$returnValue['comments'] = ['count' => count($comments), 'list' => $comments];
|
||||
$returnValue['comments'] = $comments;
|
||||
|
||||
if ($track->album_id != null) {
|
||||
$returnValue['album'] = [
|
||||
|
@ -87,6 +82,27 @@
|
|||
}
|
||||
|
||||
public static function mapPublicTrackSummary($track) {
|
||||
$userData = [
|
||||
'stats' => [
|
||||
'views' => 0,
|
||||
'plays' => 0,
|
||||
'downloads' => 0
|
||||
],
|
||||
'is_favourited' => false
|
||||
];
|
||||
|
||||
if ($track->users->count()) {
|
||||
$userRow = $track->users[0];
|
||||
$userData = [
|
||||
'stats' => [
|
||||
'views' => $userRow->view_count,
|
||||
'plays' => $userRow->play_count,
|
||||
'downloads' => $userRow->download_count,
|
||||
],
|
||||
'is_favourited' => $userRow->is_favourited
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $track->id,
|
||||
'title' => $track->title,
|
||||
|
@ -95,6 +111,13 @@
|
|||
'name' => $track->user->display_name,
|
||||
'url' => $track->user->url
|
||||
],
|
||||
'stats' => [
|
||||
'views' => $track->view_count,
|
||||
'plays' => $track->play_count,
|
||||
'downloads' => $track->download_count,
|
||||
'comments' => $track->comment_count,
|
||||
'favourites' => $track->favourite_count
|
||||
],
|
||||
'url' => $track->url,
|
||||
'slug' => $track->slug,
|
||||
'is_vocal' => $track->is_vocal,
|
||||
|
@ -116,11 +139,10 @@
|
|||
'small' => $track->getCoverUrl(Image::SMALL),
|
||||
'normal' => $track->getCoverUrl(Image::NORMAL)
|
||||
],
|
||||
'is_favourited' => $track->favourites->count() > 0,
|
||||
'duration' => $track->duration,
|
||||
'streams' => [
|
||||
'mp3' => $track->getStreamUrl('MP3')
|
||||
]
|
||||
],
|
||||
'user_data' => $userData
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -184,6 +206,10 @@
|
|||
return $this->belongsToMany('Entities\ShowSong');
|
||||
}
|
||||
|
||||
public function users() {
|
||||
return $this->hasMany('Entities\ResourceUser');
|
||||
}
|
||||
|
||||
public function user() {
|
||||
return $this->belongsTo('Entities\User');
|
||||
}
|
||||
|
@ -276,6 +302,14 @@
|
|||
return "{$this->id}.{$format['extension']}";
|
||||
}
|
||||
|
||||
public function getDownloadFilenameFor($format) {
|
||||
if (!isset(self::$Formats[$format]))
|
||||
throw new Exception("$format is not a valid format!");
|
||||
|
||||
$format = self::$Formats[$format];
|
||||
return "{$this->title}.{$format['extension']}";
|
||||
}
|
||||
|
||||
public function getFileFor($format) {
|
||||
if (!isset(self::$Formats[$format]))
|
||||
throw new Exception("$format is not a valid format!");
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
public function getAvatarUrl($type = Image::NORMAL) {
|
||||
if (!$this->uses_gravatar)
|
||||
return $this->avatar->getUrl();
|
||||
return $this->avatar->getUrl($type);
|
||||
|
||||
$email = $this->gravatar;
|
||||
if (!strlen($email))
|
||||
|
|
48
app/models/PlaylistDownloader.php
Normal file
48
app/models/PlaylistDownloader.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
class PlaylistDownloader {
|
||||
private $_playlist;
|
||||
private $_format;
|
||||
|
||||
function __construct($playlist, $format) {
|
||||
$this->_playlist = $playlist;
|
||||
$this->_format = $format;
|
||||
}
|
||||
|
||||
function download() {
|
||||
$zip = new ZipStream($this->_playlist->user->display_name . ' - ' . $this->_playlist->title . '.zip');
|
||||
$zip->setComment(
|
||||
'Album: ' . $this->_playlist->title ."\r\n".
|
||||
'Artist: ' . $this->_playlist->user->display_name ."\r\n".
|
||||
'URL: ' . $this->_playlist->url ."\r\n"."\r\n".
|
||||
'Downloaded on '. date('l, F jS, Y, \a\t h:i:s A') . '.'
|
||||
);
|
||||
|
||||
$directory = $this->_playlist->user->display_name . '/' . $this->_playlist->title . '/';
|
||||
|
||||
$notes =
|
||||
'Album: ' . $this->_playlist->title ."\r\n".
|
||||
'Artist: ' . $this->_playlist->user->display_name ."\r\n".
|
||||
'URL: ' . $this->_playlist->url ."\r\n".
|
||||
"\r\n".
|
||||
$this->_playlist->description ."\r\n".
|
||||
"\r\n".
|
||||
"\r\n".
|
||||
'Tracks' ."\r\n".
|
||||
"\r\n";
|
||||
|
||||
foreach ($this->_playlist->tracks as $track) {
|
||||
if (!$track->is_downloadable)
|
||||
continue;
|
||||
|
||||
$zip->addLargeFile($track->getFileFor($this->_format), $directory . $track->getDownloadFilenameFor($this->_format));
|
||||
$notes .=
|
||||
$track->track_number . '. ' . $track->title ."\r\n".
|
||||
$track->description ."\r\n".
|
||||
"\r\n";
|
||||
}
|
||||
|
||||
$zip->addFile($notes, $directory . 'Album Notes.txt');
|
||||
$zip->finalize();
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
Route::get('albums', 'AlbumsController@getIndex');
|
||||
Route::get('albums/{id}-{slug}', 'AlbumsController@getShow');
|
||||
Route::get('a{id}', 'AlbumsController@getShortlink')->where('id', '\d+');
|
||||
Route::get('a{id}/dl.{extension}', 'AlbumsController@getDownload' );
|
||||
|
||||
Route::get('artists', 'ArtistsController@getIndex');
|
||||
Route::get('playlists', 'PlaylistsController@getIndex');
|
||||
|
|
|
@ -12,3 +12,4 @@
|
|||
*/
|
||||
|
||||
Artisan::add(new MigrateOldData);
|
||||
Artisan::add(new RefreshCache);
|
|
@ -15,9 +15,8 @@ angular.module('ponyfm').directive 'pfmComments', () ->
|
|||
|
||||
refresh = () ->
|
||||
comments.fetchList($scope.type, $scope.resource.id, true).done (comments) ->
|
||||
$scope.resource.comments.count = comments.count
|
||||
$scope.resource.comments.list.length = 0
|
||||
$scope.resource.comments.list.push comment for comment in comments.list
|
||||
$scope.resource.comments.length = 0
|
||||
$scope.resource.comments.push comment for comment in comments.list
|
||||
$scope.isWorking = false
|
||||
|
||||
$scope.addComment = () ->
|
||||
|
|
|
@ -16,5 +16,5 @@ angular.module('ponyfm').directive 'pfmFavouriteButton', () ->
|
|||
$scope.isWorking = true
|
||||
favourites.toggle($scope.type, $scope.resource.id).done (res) ->
|
||||
$scope.isWorking = false
|
||||
$scope.resource.is_favourited = res.is_favourited
|
||||
$scope.resource.user_data.is_favourited = res.is_favourited
|
||||
]
|
|
@ -12,7 +12,7 @@ angular.module('ponyfm').directive 'pfmTracksList', () ->
|
|||
|
||||
$scope.toggleFavourite = (track) ->
|
||||
favourites.toggle('track', track.id).done (res) ->
|
||||
track.is_favourited = res.is_favourited
|
||||
track.user_data.is_favourited = res.is_favourited
|
||||
|
||||
$scope.play = (track) ->
|
||||
index = _.indexOf $scope.tracks, (t) -> t.id == track.id
|
||||
|
|
6
public/scripts/app/filters/trust.coffee
Normal file
6
public/scripts/app/filters/trust.coffee
Normal file
|
@ -0,0 +1,6 @@
|
|||
angular.module('ponyfm').filter 'trust', [
|
||||
'$sce'
|
||||
($sce) ->
|
||||
(input) ->
|
||||
$sce.trustAsHtml input
|
||||
]
|
|
@ -23,7 +23,7 @@ angular.module('ponyfm').factory('albums', [
|
|||
id = 1 if !id
|
||||
return albums[id] if !force && albums[id]
|
||||
albumsDef = new $.Deferred()
|
||||
$http.get('/api/web/albums/' + id).success (albums) ->
|
||||
$http.get('/api/web/albums/' + id + '?log=true').success (albums) ->
|
||||
albumsDef.resolve albums
|
||||
|
||||
albums[id] = albumsDef.promise()
|
||||
|
|
|
@ -146,7 +146,7 @@ angular.module('ponyfm').factory('tracks', [
|
|||
force = force || false
|
||||
return trackCache[id] if !force && trackCache[id]
|
||||
trackDef = new $.Deferred()
|
||||
$http.get('/api/web/tracks/' + id).success (track) ->
|
||||
$http.get('/api/web/tracks/' + id + '?log=true').success (track) ->
|
||||
trackDef.resolve track
|
||||
|
||||
trackCache[id] = trackDef.promise()
|
||||
|
@ -168,8 +168,10 @@ angular.module('ponyfm').factory('tracks', [
|
|||
self.filters.sort =
|
||||
type: 'single'
|
||||
values: [
|
||||
{title: 'Newest to Oldest', query: '', isDefault: true, filter: 'order=created_at,desc'},
|
||||
{title: 'Oldest to Newest', query: 'created_at,asc', isDefault: false, filter: 'order=created_at,asc'}
|
||||
{title: 'Latest', query: '', isDefault: true, filter: 'order=created_at,desc'},
|
||||
{title: 'Most Played', query: 'play_count', isDefault: false, filter: 'order=play_count,desc'},
|
||||
{title: 'Most Downloaded', query: 'download_count', isDefault: false, filter: 'order=download_count,desc'},
|
||||
{title: 'Most Favourited', query: 'favourite_count', isDefault: false, filter: 'order=favourite_count,desc'}
|
||||
]
|
||||
|
||||
self.filters.genres =
|
||||
|
|
|
@ -184,6 +184,10 @@ html body {
|
|||
.border-radius(0px);
|
||||
}
|
||||
|
||||
.btn.btn-primary {
|
||||
background: @pfm-purple;
|
||||
}
|
||||
|
||||
.ui-datepicker {
|
||||
.border-radius(0px);
|
||||
|
||||
|
@ -309,6 +313,16 @@ html .dropdown-menu {
|
|||
}
|
||||
|
||||
html {
|
||||
.modal-backdrop {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.modal {
|
||||
.border-radius(0px);
|
||||
|
||||
border: 2px solid @pfm-purple;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
.border-radius(0px);
|
||||
background: #eee;
|
||||
|
|
|
@ -85,8 +85,8 @@
|
|||
}
|
||||
|
||||
line-height: normal;
|
||||
padding: 5px 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
margin: 5px 0px;
|
||||
padding-right: 10px;
|
||||
position: relative;
|
||||
|
||||
|
@ -160,6 +160,10 @@
|
|||
background: #ddd;
|
||||
}
|
||||
|
||||
&.has-played {
|
||||
background: red;
|
||||
}
|
||||
|
||||
&.is-favourited {
|
||||
.icons {
|
||||
a.icon-favourite {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
Downloads <i class="caret"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="format in album.formats"><a href="{{format.url}}">{{format.name}} <small>({{format.size}})</small></a></li>
|
||||
<li ng-repeat="format in album.formats"><a target="_blank" href="{{format.url}}">{{format.name}} <small>({{format.size}})</small></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -49,6 +49,7 @@
|
|||
<ul class="stats">
|
||||
<li>Views: <strong>{{album.stats.views}}</strong></li>
|
||||
<li>Downloads: <strong>{{album.stats.downloads}}</strong></li>
|
||||
<li>Favourites: <strong>{{album.stats.favourites}}</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<div class="alert alert-info" ng-show="resource.comments.count == 0">
|
||||
There are no comments yet!
|
||||
</div>
|
||||
<ul ng-show="resource.comments.count > 0">
|
||||
<li ng-repeat="comment in resource.comments.list">
|
||||
<ul ng-show="resource.comments.length > 0">
|
||||
<li ng-repeat="comment in resource.comments">
|
||||
<div class="meta">
|
||||
<a href="{{comment.user.url}}">{{comment.user.name}}</a> posted
|
||||
{{comment.created_at.date | momentFromNow}}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<a href="#" class="btn btn-small favourite-button" ng-class="{'is-favourited': resource.is_favourited, disabled: isWorking}" pfm-eat-click ng-click="toggleFavourite()" ng-show="auth.isLogged">
|
||||
<span ng-hide="resource.is_favourited">
|
||||
<span ng-hide="resource.user_data.is_favourited">
|
||||
Favourite This!
|
||||
<i class="icon-star-empty"></i>
|
||||
</span>
|
||||
<span ng-show="resource.is_favourited">
|
||||
<span ng-show="resource.user_data.is_favourited">
|
||||
In Your Favourites
|
||||
<i class="icon-star"></i>
|
||||
</span>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<ul class="tracks-listing {{class}}">
|
||||
<li ng-repeat="track in tracks" ng-class="{'can-favourite': auth.isLogged, 'is-favourited': track.is_favourited, 'is-playing': track.isPlaying}">
|
||||
<li ng-repeat="track in tracks" ng-class="{'can-favourite': auth.isLogged, 'is-favourited': auth.isLogged && track.user_data.is_favourited, 'is-playing': track.isPlaying, 'has-played': auth.isLogged && track.user_data.views}">
|
||||
<div class="image">
|
||||
<a href="#" class="play-button" pfm-eat-click ng-click="play(track)">
|
||||
<i class="icon-play" ng-show="!track.isPlaying"></i>
|
||||
|
@ -13,7 +13,11 @@
|
|||
</div>
|
||||
<a class="info" href="{{track.url}}">
|
||||
<span class="title">{{track.title}}</span>
|
||||
<span class="stats" title="5 Favourites / 2 Comments / 10 Downloads"><strong>5</strong>f, <strong>2</strong>c, <strong>10</strong>d</span>
|
||||
<span class="stats" title="{{track.stats.favourites}} Favourites / {{track.stats.comments}} Comments / {{track.stats.plays}} Plays">
|
||||
<strong>{{track.stats.favourites}}</strong>f
|
||||
<strong>{{track.stats.comments}}</strong>c
|
||||
<strong>{{track.stats.plays}}</strong>p
|
||||
</span>
|
||||
<span class="artist">{{track.user.name}} / {{track.genre.name}}</span>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
Downloads <i class="caret"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-repeat="format in track.formats"><a href="{{format.url}}">{{format.name}} <small>({{format.size}})</small></a></li>
|
||||
<li ng-repeat="format in track.formats"><a target="_blank" href="{{format.url}}">{{format.name}} <small>({{format.size}})</small></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="dropdown">
|
||||
|
@ -50,7 +50,7 @@
|
|||
<div class="reveal">
|
||||
<a href="#">Click to reveal full lyrics...</a>
|
||||
</div>
|
||||
<p class="content" ng-bind-html-unsafe="track.lyrics | noHTML | newlines"></p>
|
||||
<p class="content" ng-bind-html="track.lyrics | noHTML | newlines | trust"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -72,6 +72,7 @@
|
|||
<li>Views: <strong>{{track.stats.views}}</strong></li>
|
||||
<li>Plays: <strong>{{track.stats.plays}}</strong></li>
|
||||
<li>Downloads: <strong>{{track.stats.downloads}}</strong></li>
|
||||
<li>Favourites: <strong>{{track.stats.favourites}}</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
|
@ -4,4 +4,4 @@
|
|||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit99e3f8067509f9d0b122eb51fad39842::getLoader();
|
||||
return ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223::getLoader();
|
||||
|
|
8
vendor/composer/autoload_classmap.php
vendored
8
vendor/composer/autoload_classmap.php
vendored
|
@ -14,6 +14,7 @@ return array(
|
|||
'Api\\Web\\AlbumsController' => $baseDir . '/app/controllers/Api/Web/AlbumsController.php',
|
||||
'Api\\Web\\ArtistsController' => $baseDir . '/app/controllers/Api/Web/ArtistsController.php',
|
||||
'Api\\Web\\AuthController' => $baseDir . '/app/controllers/Api/Web/AuthController.php',
|
||||
'Api\\Web\\CommentsController' => $baseDir . '/app/controllers/Api/Web/CommentsController.php',
|
||||
'Api\\Web\\DashboardController' => $baseDir . '/app/controllers/Api/Web/DashboardController.php',
|
||||
'Api\\Web\\FavouritesController' => $baseDir . '/app/controllers/Api/Web/FavouritesController.php',
|
||||
'Api\\Web\\ImagesController' => $baseDir . '/app/controllers/Api/Web/ImagesController.php',
|
||||
|
@ -134,6 +135,7 @@ return array(
|
|||
'Commands\\CommandBase' => $baseDir . '/app/models/Commands/CommandBase.php',
|
||||
'Commands\\CommandResponse' => $baseDir . '/app/models/Commands/CommandResponse.php',
|
||||
'Commands\\CreateAlbumCommand' => $baseDir . '/app/models/Commands/CreateAlbumCommand.php',
|
||||
'Commands\\CreateCommentCommand' => $baseDir . '/app/models/Commands/CreateCommentCommand.php',
|
||||
'Commands\\CreatePlaylistCommand' => $baseDir . '/app/models/Commands/CreatePlaylistCommand.php',
|
||||
'Commands\\DeleteAlbumCommand' => $baseDir . '/app/models/Commands/DeleteAlbumCommand.php',
|
||||
'Commands\\DeletePlaylistCommand' => $baseDir . '/app/models/Commands/DeletePlaylistCommand.php',
|
||||
|
@ -147,11 +149,12 @@ return array(
|
|||
'ContentController' => $baseDir . '/app/controllers/ContentController.php',
|
||||
'CreateAlbums' => $baseDir . '/app/database/migrations/2013_07_28_060804_create_albums.php',
|
||||
'CreateComments' => $baseDir . '/app/database/migrations/2013_08_01_051337_create_comments.php',
|
||||
'CreateFavourites' => $baseDir . '/app/database/migrations/2013_08_01_024827_create_favourites.php',
|
||||
'CreateFavourites' => $baseDir . '/app/database/migrations/2013_08_18_045248_create_favourites.php',
|
||||
'CreateImagesTable' => $baseDir . '/app/database/migrations/2013_07_26_230827_create_images_table.php',
|
||||
'CreatePlaylists' => $baseDir . '/app/database/migrations/2013_07_28_135136_create_playlists.php',
|
||||
'CreateSongsTable' => $baseDir . '/app/database/migrations/2013_07_28_034328_create_songs_table.php',
|
||||
'CreateTracksTable' => $baseDir . '/app/database/migrations/2013_06_27_015259_create_tracks_table.php',
|
||||
'CreateUserTables' => $baseDir . '/app/database/migrations/2013_08_18_041928_create_user_tables.php',
|
||||
'CreateUsersTable' => $baseDir . '/app/database/migrations/2013_06_07_003952_create_users_table.php',
|
||||
'DatabaseSeeder' => $baseDir . '/app/database/seeds/DatabaseSeeder.php',
|
||||
'Doctrine\\Common\\Annotations\\Annotation' => $vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php',
|
||||
|
@ -420,12 +423,14 @@ return array(
|
|||
'Doctrine\\DBAL\\Types\\VarDateTimeType' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php',
|
||||
'Doctrine\\DBAL\\Version' => $vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL/Version.php',
|
||||
'Entities\\Album' => $baseDir . '/app/models/Entities/Album.php',
|
||||
'Entities\\Comment' => $baseDir . '/app/models/Entities/Comment.php',
|
||||
'Entities\\Favourite' => $baseDir . '/app/models/Entities/Favourite.php',
|
||||
'Entities\\Genre' => $baseDir . '/app/models/Entities/Genre.php',
|
||||
'Entities\\Image' => $baseDir . '/app/models/Entities/Image.php',
|
||||
'Entities\\License' => $baseDir . '/app/models/Entities/License.php',
|
||||
'Entities\\PinnedPlaylist' => $baseDir . '/app/models/Entities/PinnedPlaylist.php',
|
||||
'Entities\\Playlist' => $baseDir . '/app/models/Entities/Playlist.php',
|
||||
'Entities\\ResourceLogItem' => $baseDir . '/app/models/Entities/ResourceLogItem.php',
|
||||
'Entities\\ShowSong' => $baseDir . '/app/models/Entities/ShowSong.php',
|
||||
'Entities\\Track' => $baseDir . '/app/models/Entities/Track.php',
|
||||
'Entities\\TrackType' => $baseDir . '/app/models/Entities/TrackType.php',
|
||||
|
@ -820,6 +825,7 @@ return array(
|
|||
'Illuminate\\Workbench\\Starter' => $vendorDir . '/laravel/framework/src/Illuminate/Workbench/Starter.php',
|
||||
'Illuminate\\Workbench\\WorkbenchServiceProvider' => $vendorDir . '/laravel/framework/src/Illuminate/Workbench/WorkbenchServiceProvider.php',
|
||||
'ImagesController' => $baseDir . '/app/controllers/ImagesController.php',
|
||||
'MigrateOldData' => $baseDir . '/app/commands/MigrateOldData.php',
|
||||
'Monolog\\Formatter\\ChromePHPFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php',
|
||||
'Monolog\\Formatter\\FormatterInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php',
|
||||
'Monolog\\Formatter\\GelfMessageFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php',
|
||||
|
|
6
vendor/composer/autoload_real.php
vendored
6
vendor/composer/autoload_real.php
vendored
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_real.php generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit99e3f8067509f9d0b122eb51fad39842
|
||||
class ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
|
@ -19,9 +19,9 @@ class ComposerAutoloaderInit99e3f8067509f9d0b122eb51fad39842
|
|||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit99e3f8067509f9d0b122eb51fad39842', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit99e3f8067509f9d0b122eb51fad39842', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit265a5d8a5cc5c33c736711894c7e0223', 'loadClassLoader'));
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
|
Loading…
Reference in a new issue