added lastfm on profile

This commit is contained in:
flash 2016-09-19 17:33:52 +02:00
parent f224d258ef
commit 27f436d9ef
8 changed files with 175 additions and 19 deletions

View file

@ -7,6 +7,7 @@
namespace Sakura\Controllers; namespace Sakura\Controllers;
use Phroute\Phroute\Exception\HttpMethodNotAllowedException; use Phroute\Phroute\Exception\HttpMethodNotAllowedException;
use Phroute\Phroute\Exception\HttpRouteNotFoundException;
use Sakura\Config; use Sakura\Config;
use Sakura\CurrentSession; use Sakura\CurrentSession;
use Sakura\DB; use Sakura\DB;
@ -49,6 +50,34 @@ class UserController extends Controller
return view('user/profile', compact('profile')); return view('user/profile', compact('profile'));
} }
/**
* Last listened to.
* @param int $id
* @throws HttpRouteNotFoundException
* @return string
*/
public function nowPlaying($id)
{
$user = User::construct($id);
if ($user->id === 0) {
throw new HttpRouteNotFoundException;
}
$user->updateLastTrack();
$artist_url = 'http://last.fm/music/' . urlencode($user->musicArtist);
$track_url = $artist_url . '/_/' . urlencode($user->musicTrack);
return $this->json([
'track' => $user->musicTrack,
'track_url' => $track_url,
'artist' => $user->musicArtist,
'artist_url' => $artist_url,
'listening' => $user->musicListening,
]);
}
/** /**
* Display the memberlist. * Display the memberlist.
* @param int $rank * @param int $rank

View file

@ -7,6 +7,9 @@
namespace Sakura; namespace Sakura;
use Carbon\Carbon; use Carbon\Carbon;
use LastFmApi\Api\AuthApi;
use LastFmApi\Api\UserApi;
use LastFmApi\Exception\LastFmApiExeption;
use Sakura\Perms; use Sakura\Perms;
use Sakura\Perms\Site; use Sakura\Perms\Site;
use stdClass; use stdClass;
@ -210,6 +213,30 @@ class User
*/ */
private $design = ''; private $design = '';
/**
* Title of the track this user last listened to.
* @var string
*/
public $musicTrack;
/**
* Artist of the track this user last listened to.
* @var string
*/
public $musicArtist;
/**
* Last time this was updated.
* @var int
*/
public $musicCheck;
/**
* Whether the user is actively listening.
* @var bool
*/
public $musicListening;
/** /**
* The user's birthday. * The user's birthday.
* @var string * @var string
@ -332,11 +359,15 @@ class User
$this->osu = $userRow->user_osu; $this->osu = $userRow->user_osu;
$this->lastfm = $userRow->user_lastfm; $this->lastfm = $userRow->user_lastfm;
$this->design = $userRow->user_design; $this->design = $userRow->user_design;
$this->musicTrack = $userRow->user_music_track;
$this->musicArtist = $userRow->user_music_artist;
$this->musicListening = boolval($userRow->user_music_listening);
$this->musicCheck = intval($userRow->user_music_check);
// Temporary backwards compatible IP storage system // Temporary backwards compatible IP storage system
try { try {
$this->registerIp = Net::ntop($userRow->register_ip); $this->registerIp = Net::ntop($userRow->register_ip);
} catch (Exception $e) { } catch (NetAddressTypeException $e) {
$this->registerIp = $userRow->register_ip; $this->registerIp = $userRow->register_ip;
DB::table('users') DB::table('users')
@ -348,7 +379,7 @@ class User
try { try {
$this->lastIp = Net::ntop($userRow->last_ip); $this->lastIp = Net::ntop($userRow->last_ip);
} catch (Exception $e) { } catch (NetAddressTypeException $e) {
$this->lastIp = $userRow->last_ip; $this->lastIp = $userRow->last_ip;
DB::table('users') DB::table('users')
@ -1091,4 +1122,43 @@ class User
->where('user_id', $this->id) ->where('user_id', $this->id)
->max('ranks.rank_hierarchy'); ->max('ranks.rank_hierarchy');
} }
/**
* Update last listened data.
*/
public function updateLastTrack()
{
if (strlen($this->lastfm) < 1
|| $this->musicCheck + config('user.music_update') > time()) {
return;
}
$lfm = new UserApi(
new AuthApi('setsession', ['apiKey' => config('lastfm.api_key')])
);
try {
$last = $lfm->getRecentTracks(['user' => $this->lastfm, 'limit' => '1']);
} catch (LastFmApiExeption $e) {
return;
}
if (count($last) < 1) {
return;
}
$this->musicCheck = time();
$this->musicListening = isset($last[0]['nowplaying']);
$this->musicTrack = $last[0]['name'] ?? null;
$this->musicArtist = $last[0]['artist']['name'] ?? null;
DB::table('users')
->where('user_id', $this->id)
->update([
'user_music_check' => $this->musicCheck,
'user_music_listening' => $this->musicListening,
'user_music_track' => $this->musicTrack,
'user_music_artist' => $this->musicArtist,
]);
}
} }

View file

@ -162,6 +162,9 @@ signature_max = 500
; Max length of a userpage ; Max length of a userpage
page_max = 65535 page_max = 65535
; After how long last listened should be updated
music_update = 10
; Premium settings ; Premium settings
[premium] [premium]
max_months_at_once = 24 max_months_at_once = 24
@ -245,3 +248,7 @@ sound_packs[default] = Default
; Default soundpack to use ; Default soundpack to use
sound_pack = default sound_pack = default
; LastFM settings
[lastfm]
api_key =

View file

@ -14,23 +14,17 @@ class LastListenedMusic extends Migration
$schema = DB::getSchemaBuilder(); $schema = DB::getSchemaBuilder();
$schema->table('users', function (Blueprint $table) { $schema->table('users', function (Blueprint $table) {
$table->text('user_last_track') $table->text('user_music_track')
->nullable(); ->nullable();
$table->string('user_last_track_url', 255) $table->text('user_music_artist')
->nullable()
->default(null);
$table->text('user_last_artist')
->nullable(); ->nullable();
$table->string('user_last_artist_url', 255) $table->integer('user_music_check')
->nullable() ->default(0);
->default(null);
$table->string('user_last_cover', 255) $table->boolean('user_music_listening')
->nullable() ->default(false);
->default(null);
}); });
} }
@ -44,11 +38,10 @@ class LastListenedMusic extends Migration
$schema->table('users', function (Blueprint $table) { $schema->table('users', function (Blueprint $table) {
$table->dropColumn([ $table->dropColumn([
'user_last_track', 'user_music_track',
'user_last_track_url', 'user_music_artist',
'user_last_artist', 'user_music_check',
'user_last_artist_url', 'user_music_listening',
'user_last_cover',
]); ]);
}); });
} }

View file

@ -7,6 +7,7 @@
@import "bbcode"; @import "bbcode";
@import "alert"; @import "alert";
@import "dropdown"; @import "dropdown";
@import "np";
/* /*
* Animation Keyframes * Animation Keyframes

View file

@ -0,0 +1,19 @@
.np {
text-shadow: 0 0 5px #8364A1;
color: #614390;
text-align: center;
font-size: 1.2em;
line-height: 1.5em;
border-bottom: 1px solid #9475b2;
display: flex;
justify-content: space-between;
a {
color: inherit;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}

View file

@ -76,6 +76,28 @@
{% if not profileHidden %} {% if not profileHidden %}
<script type="text/javascript"> <script type="text/javascript">
window.addEventListener('load', function () { window.addEventListener('load', function () {
{% if profile.lastfm %}
var np = new Sakura.AJAX();
np.SetUrl("{{ route('user.nowplaying', user.id) }}");
np.AddCallback(200, function () {
var data = np.JSON(),
artist = Sakura.DOM.ID('np-artist'),
track = Sakura.DOM.ID('np-track'),
state = Sakura.DOM.ID('np-state'),
by = Sakura.DOM.ID('np-by');
console.log(data);
artist.href = data.artist_url;
artist.textContent = data.artist;
track.href = data.track_url;
track.textContent = data.track;
state.className = 'fa ' + (data.listening ? 'fa-play-circle' : 'fa-history');
by.className = data.track === '' || data.artist === '' ? 'hidden' : '';
});
setInterval(function () { np.Start(Sakura.HTTPMethod.GET); }, 20000);
np.Start(Sakura.HTTPMethod.GET);
{% endif %}
// Check if location.hash is set // Check if location.hash is set
if (location.hash) { if (location.hash) {
var open = location.hash.slice(2); var open = location.hash.slice(2);
@ -191,6 +213,19 @@
</div> </div>
<div class="new-profile-content"> <div class="new-profile-content">
<div class="new-profile-mode"> <div class="new-profile-mode">
{% if profile.lastfm %}
<div class="np">
<div class="np-icon">
<span class="fa fa-music"></span>
</div>
<div class="np-text">
<span class="fa fa-ellipsis-h" id="np-state"></span>
<a href="#" id="np-track"></a>
<span id="np-by" class="hidden">by</span>
<a href="#" id="np-artist"></a>
</div>
</div>
{% endif %}
<noscript><h1 class="stylised" style="text-align: center;">Please enable Javascript!</h1></noscript> <noscript><h1 class="stylised" style="text-align: center;">Please enable Javascript!</h1></noscript>
<div id="profile-mode-userpage" class="hidden"> <div id="profile-mode-userpage" class="hidden">
{% include 'profile/userpage.twig' %} {% include 'profile/userpage.twig' %}

View file

@ -164,6 +164,8 @@ Routerv1::group(['before' => 'maintenance'], function () {
Routerv1::get('/{id}', 'UserController@profile', 'user.profile'); Routerv1::get('/{id}', 'UserController@profile', 'user.profile');
Routerv1::get('/{id}/report', 'UserController@report', 'user.report'); Routerv1::get('/{id}/report', 'UserController@report', 'user.report');
Routerv1::get('/{id}/nowplaying', 'UserController@nowPlaying', 'user.nowplaying');
Routerv1::get('/{id}/avatar', 'FileController@avatar', 'user.avatar'); Routerv1::get('/{id}/avatar', 'FileController@avatar', 'user.avatar');
Routerv1::post('/{id}/avatar', 'FileController@avatar', 'user.avatar'); Routerv1::post('/{id}/avatar', 'FileController@avatar', 'user.avatar');
Routerv1::delete('/{id}/avatar', 'FileController@avatar', 'user.avatar'); Routerv1::delete('/{id}/avatar', 'FileController@avatar', 'user.avatar');