has moved to IP address -- please double check where you are logging in.

Commit 284b41a3 authored by Rob Myers's avatar Rob Myers

Add user interface to delete scrobbles using the Library function. Accessible from the Edit page.

parent aa1424a3
\ No newline at end of file
......@@ -42,7 +42,7 @@ class Library {
$delete_query = 'DELETE FROM Scrobbles WHERE userid=? AND time=? AND artist=? AND track=?';
$delete_params = array((int)$userid, (int)$timestamp, $artist, $track);
// TODO Should we have a db trigger for this?
- // TODO Should we have a db trigger for this?
$update_stats_query = 'UPDATE User_Stats SET scrobble_count=scrobble_count-1 WHERE userid=?';
$update_stats_params = array((int)$userid);
......@@ -51,6 +51,10 @@ class Library {
$adodb->Execute($delete_query, $delete_params);
$delete_count = $adodb->Affected_Rows();
if($delete_count) {
// This clears the *entire* cache, but we don't know which
// cached queries will reference the deleted scrobbles so
// we can't clear the cache for only those specific queries.
$adodb->Execute($update_stats_query, $update_stats_params);
} catch (Exception $e) {
{include file='header.tpl' subheader='user-header.tpl'}
<center><h3><a href='{$base_url}/user-edit.php'>{t}Edit your profile{/t}</a> | {t}Connections to other services{/t}</h3></center>
<center><h3><a href='{$base_url}/user-edit.php'>{t}Edit your profile{/t}</a> | {t}Connections to other services{/t} | <a href='{$base_url}/user-delete-tracks.php'>{t}Delete plays{/t}</a></h3></center>
{if isset($errors)}
<div id="errors">
{include file='header.tpl' subheader='user-header.tpl'}
<center><h3><a href='{$base_url}/user-edit.php'>{t}Edit your profile{/t}</a> | <a href='{$base_url}/user-connections.php'>{t}Connections to other services{/t}</a> | {t}Delete plays{/t}</h3></center>
{if isset($errors)}
<div id="errors">
{section loop=$errors name=error}
<div id="user-delete-tracks">
<p id="next-and-previous">
{if $prevOffset >= 0}
<a href="{$base_url}/user-delete-tracks.php?offset={$prevOffset}&amp;count={$scrobbleCount}">{t}Previous{/t} {$scrobbleCount}</a>
{t}Previous{/t} {$scrobbleCount}
{if $nextOffset >= 0}
<a href="{$base_url}/user-delete-tracks.php?offset={$nextOffset}&amp;count={$scrobbleCount}">{t}Next{/t} {$scrobbleCount}</a>
{t}Next{/t} {$scrobbleCount}
<form action='{$base_url}/user-delete-tracks.php' method='post' onkeypress='return event.keyCode != 13;'>
{section name=i loop=$scrobbles}
<label><input type="checkbox" name="scrobble[]" value="{$scrobbles[i].time|escape:'html':'UTF-8'} {$scrobbles[i].artist|escape:'html':'UTF-8'} {$scrobbles[i].track|escape:'html':'UTF-8'}" />
{$scrobbles[i].track|escape:'html':'UTF-8'} by {$scrobbles[i].artist|escape:'html':'UTF-8'}
{if $scrobbles[i].albumurl} on the album, {$scrobbles[i].album|escape:'html':'UTF-8'}{/if}
&mdash; {$scrobbles[i].timehuman}
</label><br />
<input type='submit' value='{t}Delete{/t}' />
<input name='submit' value='1' type='hidden' />
<input name='offset' value='{$scrobbleOffset}' type='hidden' />
<input name='count' value='{$scrobbleCount}' type='hidden' />
<p>{t}Select the checkboxes of the plays that you want to delete then click the Delete button.{/t}</p>
<p>{t}Once you delete a play, it's gone permanently. We cannot recover deleted plays for you. So pleas be careful!{/t}</p>
{include file='footer.tpl'}
{include file='header.tpl' subheader='user-header.tpl'}
<center><h3>Edit your profile | <a href='{$base_url}/user-connections.php'>Connections to other services</a></h3></center>
<center><h3>{t}Edit your profile{/t} | <a href='{$base_url}/user-connections.php'>{t}Connections to other services{/t}</a> | <a href='{$base_url}/user-delete-tracks.php'>{t}Delete plays{/t}</a></h3></center>
{if isset($errors)}
<div id="errors">
/* GNU FM -- a free network service for sharing your music listening habits
Copyright (C) 2009,2014 Free Software Foundation, Inc
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
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 <>.
if ($logged_in == false) {
displayError("Error", "Not logged in. You shouldn't be here.");
// For some bizarre reason $this_user->getScrobbles() fails,
// so make a new user object to use instead until this is fixed.
$user = new User($this_user->name);
$errors = array();
// The user submitted zero or more scrobbles to delete. Delete them
if ($_POST['submit']) {
$deletions = $_POST['scrobble'];
array_map(function($scrob) {
global $user, $errors;
// html_entity_decode defaults to utf8
list($timestamp,$artist,$track) = array_map('html_entity_decode',
explode("\t", $scrob));
// The user id (and SQL ? string in the function's query) mean that
// you can't delete other users' scrobbles or inject SQL.
$ok = Library::removeScrobble($user->uniqueid, $timestamp, $artist,
if($ok) {
$errors[] = "Deleted " . $track . " by " . $artist . " from "
. human_timestamp($timestamp);
} else {
$errors[] = " Couldn't delete " . $track . " by " . $artist
. " from " . human_timestamp($timestamp);
}, $deletions);
// Whether post or get, we've a UI to render. Get and calculate scrobble paging.
$scrobbleCount = (int)$_REQUEST['count'];
if ($scobbleCount >= 1200) {
$scrobbleCount = 1200;
} else if (!$scrobbleCount) {
$scrobbleCount = 100;
$scrobbleOffset = (int)$_REQUEST['offset'];
$scrobbleOffsetNext = ($scrobbleOffset + $scrobbleCount
> $user->getTotalTracks())
? -1 : $scrobbleOffset + $scrobbleCount;
$scrobbleOffsetPrev = ($scrobbleOffset > 0)
? ($scrobbleOffset - $scrobbleCount) : -1;
// Get the current page of scrobbles
try {
$aUserScrobbles = $user->getScrobbles($scrobbleCount, $scrobbleOffset);
$smarty->assign('scrobbles', $aUserScrobbles);
} catch (Exception $e) {}
// Assign and render
$smarty->assign('geo', Server::getLocationDetails($user->location_uri));
$smarty->assign('me', $user);
$smarty->assign('pagetitle', $user->name . '\'s tracks for deletion');
$smarty->assign('errors', $errors);
$smarty->assign('scrobbleCount', $scrobbleCount);
$smarty->assign('scrobbleOffset', $scrobbleOffset);
$smarty->assign('nextOffset', $scrobbleOffsetNext);
$smarty->assign('prevOffset', $scrobbleOffsetPrev);
$submenu = user_menu($user, 'Delete Tracks');
$smarty->assign('submenu', $submenu);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment