#1: Progress commit.

This commit is contained in:
Peter Deltchev 2016-01-07 10:16:37 -08:00
parent 4436a24cc7
commit e0faefee23
15 changed files with 838 additions and 15 deletions

View file

@ -0,0 +1,93 @@
<?php
/**
* Pony.fm - A community for pony fan music.
* Copyright (C) 2016 Peter Deltchev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Poniverse\Ponyfm\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Collection;
use Poniverse\Ponyfm\Models\Album;
use Poniverse\Ponyfm\Models\Playlist;
use Poniverse\Ponyfm\Models\Track;
use Poniverse\Ponyfm\Models\User;
class RebuildSearchIndex extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'rebuild:search';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Rebuilds the Elasticsearch index.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$totalTracks = Track::withTrashed()->count();
$totalAlbums = Album::withTrashed()->count();
$totalPlaylists = Playlist::withTrashed()->count();
$totalUsers = User::count();
Track::withTrashed()->chunk(200, function(Collection $tracks) {
foreach($tracks as $track) {
$this->info("Processing track #{$track->id}...");
$track->ensureElasticsearchEntryIsUpToDate();
}
});
Album::withTrashed()->chunk(200, function(Collection $albums) {
foreach($albums as $album) {
$this->info("Processing album #{$album->id}...");
$album->ensureElasticsearchEntryIsUpToDate();
}
});
// Playlist::withTrashed()->chunk(200, function(Collection $playlists) {
// foreach($playlists as $playlist) {
// $this->info("Processing playlist #{$playlist->id}...");
// $playlist->ensureElasticsearchEntryIsUpToDate();
// }
// });
//
// User::withTrashed()->chunk(200, function(User $user) {
// $user->ensureElasticsearchEntryIsUpToDate();
// });
}
}

View file

@ -42,6 +42,7 @@ class Kernel extends ConsoleKernel
\Poniverse\Ponyfm\Console\Commands\RebuildTrackCache::class, \Poniverse\Ponyfm\Console\Commands\RebuildTrackCache::class,
\Poniverse\Ponyfm\Console\Commands\RebuildTrack::class, \Poniverse\Ponyfm\Console\Commands\RebuildTrack::class,
\Poniverse\Ponyfm\Console\Commands\RebuildFilesizes::class, \Poniverse\Ponyfm\Console\Commands\RebuildFilesizes::class,
\Poniverse\Ponyfm\Console\Commands\RebuildSearchIndex::class,
\Poniverse\Ponyfm\Console\Commands\MergeDuplicateAccounts::class, \Poniverse\Ponyfm\Console\Commands\MergeDuplicateAccounts::class,
]; ];

View file

@ -0,0 +1,59 @@
<?php
/**
* Pony.fm - A community for pony fan music.
* Copyright (C) 2016 Peter Deltchev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Poniverse\Ponyfm\Http\Controllers\Api\Web;
use Elasticsearch;
use Poniverse\Ponyfm\Http\Controllers\ApiControllerBase;
use Input;
use Response;
class SearchController extends ApiControllerBase
{
public function getSearch()
{
$input = Input::all();
$elasticsearch = Elasticsearch::connection();
$results = $elasticsearch->search([
'index' => 'ponyfm',
'type' => 'track,album',
'body' => [
'query' => [
'multi_match' => [
'query' => $input['query'],
'fields' => [
'track.title',
'album.title',
'track.artist',
'album.artist',
'track.genre',
]
]
]
]
]);
return Response::json([
'results' => $results,
], 200);
}
}

View file

@ -82,8 +82,7 @@ Route::group(['prefix' => 'api/v1', 'middleware' => 'json-exceptions'], function
Route::group(['prefix' => 'api/web'], function() { Route::group(['prefix' => 'api/web'], function() {
Route::get('/taxonomies/all', 'Api\Web\TaxonomiesController@getAll'); Route::get('/taxonomies/all', 'Api\Web\TaxonomiesController@getAll');
Route::get('/search', 'Api\Web\SearchController@getSearch');
Route::get('/playlists/show/{id}', 'Api\Web\PlaylistsController@getShow');
Route::get('/tracks', 'Api\Web\TracksController@getIndex'); Route::get('/tracks', 'Api\Web\TracksController@getIndex');
Route::get('/tracks/{id}', 'Api\Web\TracksController@getShow')->where('id', '\d+'); Route::get('/tracks/{id}', 'Api\Web\TracksController@getShow')->where('id', '\d+');
@ -94,6 +93,7 @@ Route::group(['prefix' => 'api/web'], function() {
Route::get('/albums/cached/{id}/{format}', 'Api\Web\AlbumsController@getCachedAlbum')->where(['id' => '\d+', 'format' => '.+']); Route::get('/albums/cached/{id}/{format}', 'Api\Web\AlbumsController@getCachedAlbum')->where(['id' => '\d+', 'format' => '.+']);
Route::get('/playlists', 'Api\Web\PlaylistsController@getIndex'); Route::get('/playlists', 'Api\Web\PlaylistsController@getIndex');
Route::get('/playlists/show/{id}', 'Api\Web\PlaylistsController@getShow');
Route::get('/playlists/{id}', 'Api\Web\PlaylistsController@getShow')->where('id', '\d+'); Route::get('/playlists/{id}', 'Api\Web\PlaylistsController@getShow')->where('id', '\d+');
Route::get('/playlists/cached/{id}/{format}', 'Api\Web\PlaylistsController@getCachedPlaylist')->where(['id' => '\d+', 'format' => '.+']); Route::get('/playlists/cached/{id}/{format}', 'Api\Web\PlaylistsController@getCachedPlaylist')->where(['id' => '\d+', 'format' => '.+']);

View file

@ -28,6 +28,7 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
use Auth; use Auth;
use Cache; use Cache;
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException; use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
use Poniverse\Ponyfm\Traits\IndexedInElasticsearch;
use Poniverse\Ponyfm\Traits\TrackCollection; use Poniverse\Ponyfm\Traits\TrackCollection;
use Poniverse\Ponyfm\Traits\SlugTrait; use Poniverse\Ponyfm\Traits\SlugTrait;
use Venturecraft\Revisionable\RevisionableTrait; use Venturecraft\Revisionable\RevisionableTrait;
@ -61,7 +62,9 @@ use Venturecraft\Revisionable\RevisionableTrait;
*/ */
class Album extends Model class Album extends Model
{ {
use SoftDeletes, SlugTrait, DispatchesJobs, TrackCollection, RevisionableTrait; use SoftDeletes, SlugTrait, DispatchesJobs, TrackCollection, RevisionableTrait, IndexedInElasticsearch;
protected $elasticsearchType = 'album';
protected $dates = ['deleted_at']; protected $dates = ['deleted_at'];
protected $fillable = ['user_id', 'title', 'slug']; protected $fillable = ['user_id', 'title', 'slug'];
@ -403,4 +406,18 @@ class Album extends Model
protected function recountTracks() { protected function recountTracks() {
$this->track_count = $this->tracks->count(); $this->track_count = $this->tracks->count();
} }
/**
* Returns this model in Elasticsearch-friendly form. The array returned by
* this method should match the current mapping for this model's ES type.
*
* @return array
*/
public function toElasticsearch() {
return [
'title' => $this->title,
'artist' => $this->user->display_name,
'tracks' => $this->tracks->pluck('title'),
];
}
} }

View file

@ -27,6 +27,7 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
use Auth; use Auth;
use Cache; use Cache;
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException; use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
use Poniverse\Ponyfm\Traits\IndexedInElasticsearch;
use Poniverse\Ponyfm\Traits\TrackCollection; use Poniverse\Ponyfm\Traits\TrackCollection;
use Poniverse\Ponyfm\Traits\SlugTrait; use Poniverse\Ponyfm\Traits\SlugTrait;
use Venturecraft\Revisionable\RevisionableTrait; use Venturecraft\Revisionable\RevisionableTrait;
@ -60,10 +61,11 @@ use Venturecraft\Revisionable\RevisionableTrait;
*/ */
class Playlist extends Model class Playlist extends Model
{ {
use SoftDeletes, SlugTrait, DispatchesJobs, TrackCollection, RevisionableTrait; use SoftDeletes, SlugTrait, DispatchesJobs, TrackCollection, RevisionableTrait, IndexedInElasticsearch;
protected $elasticsearchType = 'playlist';
protected $table = 'playlists'; protected $table = 'playlists';
protected $dates = ['deleted_at']; protected $dates = ['deleted_at'];
public static function summary() public static function summary()
@ -285,4 +287,14 @@ class Playlist extends Model
{ {
return 'playlist-' . $this->id . '-' . $key; return 'playlist-' . $this->id . '-' . $key;
} }
/**
* Returns this model in Elasticsearch-friendly form. The array returned by
* this method should match the current mapping for this model's ES type.
*
* @return array
*/
public function toElasticsearch() {
return $this->toArray();
}
} }

View file

@ -24,7 +24,9 @@ use Auth;
use Cache; use Cache;
use Config; use Config;
use DB; use DB;
use Elasticsearch;
use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException; use Poniverse\Ponyfm\Exceptions\TrackFileNotFoundException;
use Poniverse\Ponyfm\Traits\IndexedInElasticsearch;
use Poniverse\Ponyfm\Traits\SlugTrait; use Poniverse\Ponyfm\Traits\SlugTrait;
use Exception; use Exception;
use External; use External;
@ -95,7 +97,9 @@ use Venturecraft\Revisionable\RevisionableTrait;
*/ */
class Track extends Model class Track extends Model
{ {
use SoftDeletes; use SoftDeletes, IndexedInElasticsearch;
protected $elasticsearchType = 'track';
protected $dates = ['deleted_at', 'published_at', 'released_at']; protected $dates = ['deleted_at', 'published_at', 'released_at'];
protected $hidden = ['original_tags', 'metadata']; protected $hidden = ['original_tags', 'metadata'];
@ -826,4 +830,15 @@ class Track extends Model
{ {
return 'track-' . $this->id . '-' . $key; return 'track-' . $this->id . '-' . $key;
} }
public function toElasticsearch() {
return [
'title' => $this->title,
'artist' => $this->user->display_name,
'published_at' => $this->published_at ? $this->published_at->toIso8601String() : null,
'genre' => $this->genre->name,
'track_type' => $this->trackType->title,
'show_songs' => $this->showSongs->pluck('title')
];
}
} }

View file

@ -29,6 +29,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\Authorizable; use Illuminate\Foundation\Auth\Access\Authorizable;
use Auth; use Auth;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Poniverse\Ponyfm\Traits\IndexedInElasticsearch;
use Venturecraft\Revisionable\RevisionableTrait; use Venturecraft\Revisionable\RevisionableTrait;
/** /**
@ -64,7 +65,9 @@ use Venturecraft\Revisionable\RevisionableTrait;
*/ */
class User extends Model implements AuthenticatableContract, CanResetPasswordContract, \Illuminate\Contracts\Auth\Access\Authorizable class User extends Model implements AuthenticatableContract, CanResetPasswordContract, \Illuminate\Contracts\Auth\Access\Authorizable
{ {
use Authenticatable, CanResetPassword, Authorizable, RevisionableTrait; use Authenticatable, CanResetPassword, Authorizable, RevisionableTrait, IndexedInElasticsearch;
protected $elasticsearchType = 'user';
protected $table = 'users'; protected $table = 'users';
protected $casts = [ protected $casts = [
@ -247,4 +250,14 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
return false; return false;
} }
/**
* Returns this model in Elasticsearch-friendly form. The array returned by
* this method should match the current mapping for this model's ES type.
*
* @return array
*/
public function toElasticsearch() {
return $this->toArray();
}
} }

View file

@ -0,0 +1,92 @@
<?php
/**
* Pony.fm - A community for pony fan music.
* Copyright (C) 2016 Peter Deltchev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Poniverse\Ponyfm\Traits;
use Elasticsearch;
/**
* Class IndexedInElasticsearch
*
* Classes using this trait must declare the `$elasticsearchType` property
* and use the `SoftDeletes` trait.
*
* @package Poniverse\Ponyfm\Traits
*/
trait IndexedInElasticsearch
{
/**
* Returns this model in Elasticsearch-friendly form. The array returned by
* this method should match the current mapping for this model's ES type.
*
* @return array
*/
abstract public function toElasticsearch();
public static function bootIndexedInElasticsearch() {
static::saved(function ($model) {
$model->createOrUpdateElasticsearchEntry();
});
static::deleted(function ($model) {
$model->deleteElasticsearchEntry();
});
}
/**
* @param bool $includeBody set to false when deleting documents
* @return array
*/
private function getElasticsearchParameters(bool $includeBody = true) {
$parameters = [
'index' => 'ponyfm',
'type' => $this->elasticsearchType,
'id' => $this->id,
];
if ($includeBody) {
$parameters['body'] = $this->toElasticsearch();
}
return $parameters;
}
private function createOrUpdateElasticsearchEntry() {
Elasticsearch::connection()->index($this->getElasticsearchParameters());
}
private function deleteElasticsearchEntry() {
try {
Elasticsearch::connection()->delete($this->getElasticsearchParameters(false));
} catch (\Elasticsearch\Common\Exceptions\Missing404Exception $e) {
// If the track we're trying to delete isn't indexed in Elasticsearch,
// that's fine.
}
}
public function ensureElasticsearchEntryIsUpToDate() {
if ($this->trashed()) {
$this->deleteElasticsearchEntry();
} else {
$this->createOrUpdateElasticsearchEntry();
}
}
}

View file

@ -13,7 +13,8 @@
"guzzlehttp/guzzle": "~6.0", "guzzlehttp/guzzle": "~6.0",
"doctrine/dbal": "^2.5", "doctrine/dbal": "^2.5",
"venturecraft/revisionable": "^1.23", "venturecraft/revisionable": "^1.23",
"pda/pheanstalk": "~3.0" "pda/pheanstalk": "~3.0",
"cviebrock/laravel-elasticsearch": "^1.0"
}, },
"require-dev": { "require-dev": {
"fzaninotto/faker": "~1.4", "fzaninotto/faker": "~1.4",

252
composer.lock generated
View file

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "d99fa4165b8a1c9e929248bbb16183ad", "hash": "0deb7713636ee82aadee47da3a9217cc",
"content-hash": "31347c82515003f78f1f9adef010f1f5", "content-hash": "9dea148233d815e53eb636413f2bcaed",
"packages": [ "packages": [
{ {
"name": "barryvdh/laravel-ide-helper", "name": "barryvdh/laravel-ide-helper",
@ -168,6 +168,55 @@
], ],
"time": "2013-05-05 09:10:04" "time": "2013-05-05 09:10:04"
}, },
{
"name": "cviebrock/laravel-elasticsearch",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/cviebrock/laravel-elasticsearch.git",
"reference": "52aa1f8228006cb0bb60954e26c068af523bf47b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cviebrock/laravel-elasticsearch/zipball/52aa1f8228006cb0bb60954e26c068af523bf47b",
"reference": "52aa1f8228006cb0bb60954e26c068af523bf47b",
"shasum": ""
},
"require": {
"elasticsearch/elasticsearch": "^2.0",
"illuminate/support": "~4|~5",
"monolog/monolog": "~1",
"php": ">=5.4.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Cviebrock\\LaravelElasticsearch\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Colin Viebrock",
"email": "colin@viebrock.ca"
},
{
"name": "Brandon Martel",
"email": "brandonmartel@gmail.com"
}
],
"description": "An easy way to use the official PHP ElasticSearch client in your Laravel applications",
"keywords": [
"client",
"elasticsearch",
"laravel",
"search"
],
"time": "2016-01-06 15:58:07"
},
{ {
"name": "danielstjules/stringy", "name": "danielstjules/stringy",
"version": "1.10.0", "version": "1.10.0",
@ -726,6 +775,60 @@
], ],
"time": "2014-09-09 13:34:57" "time": "2014-09-09 13:34:57"
}, },
{
"name": "elasticsearch/elasticsearch",
"version": "v2.1.3",
"source": {
"type": "git",
"url": "https://github.com/elastic/elasticsearch-php.git",
"reference": "7086a86cab241a77f19cdd653ae3d2e023b41699"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/elastic/elasticsearch-php/zipball/7086a86cab241a77f19cdd653ae3d2e023b41699",
"reference": "7086a86cab241a77f19cdd653ae3d2e023b41699",
"shasum": ""
},
"require": {
"guzzlehttp/ringphp": "~1.0",
"php": ">=5.4",
"psr/log": "~1.0"
},
"require-dev": {
"athletic/athletic": "~0.1",
"cpliakas/git-wrapper": "~1.0",
"mockery/mockery": "0.9.4",
"phpunit/phpunit": "~4.7",
"symfony/yaml": "2.4.3 as 2.4.2",
"twig/twig": "1.*"
},
"suggest": {
"ext-curl": "*",
"monolog/monolog": "Allows for client-level logging and tracing"
},
"type": "library",
"autoload": {
"psr-4": {
"Elasticsearch\\": "src/Elasticsearch/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache 2"
],
"authors": [
{
"name": "Zachary Tong"
}
],
"description": "PHP Client for Elasticsearch",
"keywords": [
"client",
"elasticsearch",
"search"
],
"time": "2015-12-15 18:42:26"
},
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
"version": "6.1.1", "version": "6.1.1",
@ -897,6 +1000,107 @@
], ],
"time": "2015-11-03 01:34:55" "time": "2015-11-03 01:34:55"
}, },
{
"name": "guzzlehttp/ringphp",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/RingPHP.git",
"reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
"reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
"shasum": ""
},
"require": {
"guzzlehttp/streams": "~3.0",
"php": ">=5.4.0",
"react/promise": "~2.0"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "~4.0"
},
"suggest": {
"ext-curl": "Guzzle will use specific adapters if cURL is present"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Ring\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
"time": "2015-05-20 03:37:09"
},
{
"name": "guzzlehttp/streams",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/streams.git",
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
"reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Stream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Provides a simple abstraction over streams of data",
"homepage": "http://guzzlephp.org/",
"keywords": [
"Guzzle",
"stream"
],
"time": "2014-10-12 19:18:40"
},
{ {
"name": "intouch/laravel-newrelic", "name": "intouch/laravel-newrelic",
"version": "2.0.0", "version": "2.0.0",
@ -1864,6 +2068,50 @@
], ],
"time": "2015-11-12 16:18:56" "time": "2015-11-12 16:18:56"
}, },
{
"name": "react/promise",
"version": "v2.2.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627",
"reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"React\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com"
}
],
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
"time": "2015-07-03 13:48:55"
},
{ {
"name": "swiftmailer/swiftmailer", "name": "swiftmailer/swiftmailer",
"version": "v5.4.1", "version": "v5.4.1",

View file

@ -147,6 +147,7 @@ return [
Intouch\LaravelNewrelic\NewrelicServiceProvider::class, Intouch\LaravelNewrelic\NewrelicServiceProvider::class,
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class, Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
Cviebrock\LaravelElasticsearch\ServiceProvider::class,
], ],
@ -197,6 +198,7 @@ return [
'Validator' => Illuminate\Support\Facades\Validator::class, 'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class, 'View' => Illuminate\Support\Facades\View::class,
'Elasticsearch' => Cviebrock\LaravelElasticsearch\Facade::class,
'Newrelic' => Intouch\LaravelNewrelic\Facades\Newrelic::class, 'Newrelic' => Intouch\LaravelNewrelic\Facades\Newrelic::class,
], ],

167
config/elasticsearch.php Normal file
View file

@ -0,0 +1,167 @@
<?php
return [
/**
* You can specify one of several different connections when building an
* Elasticsearch client.
*
* Here you may specify which of the connections below you wish to use
* as your default connection when building an client. Of course you may
* use create several clients at once, each with different configurations.
*/
'defaultConnection' => 'default',
/**
* These are the connection parameters used when building a client.
*/
'connections' => [
'default' => [
/**
* Hosts
*
* This is an array of hosts that the client will connect to. It can be a
* single host name, or an array if you are running a cluster of Elasticsearch
* instances.
*
* This is the only configuration value that is mandatory.
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_host_configuration
*/
'hosts' => [
'localhost:9200'
],
/**
* SSL
*
* If your Elasticsearch instance uses an out-dated or self-signed SSL
* certificate, you will need to pass in the certificate bundle. This can
* either be the path to the certificate file (for self-signed certs), or a
* package like https://github.com/Kdyby/CurlCaBundle. See the documentation
* below for all the details.
*
* If you are using SSL instances, and the certificates are up-to-date and
* signed by a public certificate authority, then you can leave this null and
* just use "https" in the host path(s) above and you should be fine.
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_security.html#_ssl_encryption_2
*/
'sslVerification' => null,
/**
* Logging
*
* Logging is handled by passing in an instance of Monolog\Logger (which
* coincidentally is what Laravel's default logger is).
*
* If logging is enabled, you either need to set the path and log level
* (some defaults are given for you below), or you can use a custom logger by
* setting 'logObject' to an instance of Psr\Log\LoggerInterface. In fact,
* if you just want to use the default Laravel logger, then set 'logObject'
* to \Log::getMonolog().
*
* Note: 'logObject' takes precedent over 'logPath'/'logLevel', so set
* 'logObject' null if you just want file-based logging to a custom path.
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#enabling_logger
*/
'logging' => false,
// If you have an existing instance of Monolog you can use it here.
//'logObject' => \Log::getMonolog(),
'logPath' => storage_path('logs/elasticsearch.log'),
'logLevel' => Monolog\Logger::INFO,
/**
* Retries
*
* By default, the client will retry n times, where n = number of nodes in
* your cluster. If you would like to disable retries, or change the number,
* you can do so here.
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_set_retries
*/
'retries' => null,
/**
* The remainder of the configuration options can almost always be left
* as-is unless you have specific reasons to change them. Refer to the
* appropriate sections in the Elasticsearch documentation for what each option
* does and what values it expects.
*/
/**
* Sniff On Start
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html
*/
'sniffOnStart' => false,
/**
* HTTP Handler
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_configure_the_http_handler
* @see http://ringphp.readthedocs.org/en/latest/client_handlers.html
*/
'httpHandler' => null,
/**
* Connection Pool
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_connection_pool
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_connection_pool.html
*/
'connectionPool' => null,
/**
* Connection Selector
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_connection_selector
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_selectors.html
*/
'connectionSelector' => null,
/**
* Serializer
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_the_serializer
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_serializers.html
*/
'serializer' => null,
/**
* Connection Factory
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_setting_a_custom_connectionfactory
*/
'connectionFactory' => null,
/**
* Endpoint
*
* @see https://www.elastic.co/guide/en/elasticsearch/client/php-api/2.0/_configuration.html#_set_the_endpoint_closure
*/
'endpoint' => null,
]
]
];

View file

@ -0,0 +1,88 @@
<?php
/**
* Pony.fm - A community for pony fan music.
* Copyright (C) 2016 Peter Deltchev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Poniverse\Ponyfm\Console\Commands\RebuildSearchIndex;
class SetupElasticsearch extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$elasticsearch = Elasticsearch::connection();
$elasticsearch->indices()->create([
'index' => 'ponyfm',
'body' => [
'mappings' => [
'track' => [
'_source' => ['enabled' => true],
'dynamic' => 'strict',
'properties' => [
'title' => ['type' => 'string'],
'artist' => ['type' => 'string'],
'published_at' => ['type' => 'date'],
'genre' => ['type' => 'string'],
'track_type' => ['type' => 'string'],
// This field is intended to be used as an array.
// Note that all Elasticsearch fields can technically be used as arrays.
// See: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
'show_songs' => ['type' => 'string'],
]
],
'album' => [
'_source' => ['enabled' => true],
'dynamic' => 'strict',
'properties' => [
'title' => ['type' => 'string'],
'artist' => ['type' => 'string'],
// This field is intended to be used as an array.
// Note that all Elasticsearch fields can technically be used as arrays.
// See: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
'tracks' => ['type' => 'string']
]
]
]
]
]);
Artisan::call('rebuild:search');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$elasticsearch = Elasticsearch::connection();
$elasticsearch->indices()->delete(['index' => 'ponyfm']);
}
}

View file

@ -1,13 +1,28 @@
#!/usr/bin/env bash #!/usr/bin/env bash
if type java &>/dev/null; then
echo "Java is installed!"
else
sudo add-apt-repository -y ppa:webupd8team/java
echo /usr/bin/debconf shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections
echo /usr/bin/debconf shared/accepted-oracle-license-v1-1 seen true | sudo debconf-set-selections
fi
if type /usr/share/elasticsearch/bin/elasticsearch &>/dev/null; then
echo "ElasticSearch is installed!"
else
wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
fi
echo "Running apt-get update..." echo "Running apt-get update..."
sudo apt-get -qq update sudo apt-get -qq update
echo "Installing tagging tools..." echo "Installing tagging tools & other dependencies..."
sudo apt-get -qq install -y AtomicParsley flac vorbis-tools imagemagick sudo apt-get -qq install -y AtomicParsley flac vorbis-tools imagemagick oracle-java8-installer pkg-config yasm libfaac-dev libmp3lame-dev libvorbis-dev libtheora-dev
echo "Installing ffmpeg dependencies.."
sudo apt-get -qq install -y pkg-config yasm libfaac-dev libmp3lame-dev libvorbis-dev libtheora-dev
if type ffmpeg &>/dev/null; then if type ffmpeg &>/dev/null; then