Merge branch 'nightly' of git.gnu.io:gnu/gnu-social

This commit is contained in:
abjectio 2015-05-30 17:21:52 +02:00
commit 1d85fd35a2
6 changed files with 148 additions and 4 deletions

View File

@ -249,6 +249,15 @@ class File extends Managed_DataObject
return true;
}
public function getFilename()
{
if (!self::validFilename($this->filename)) {
// TRANS: Client exception thrown if a file upload does not have a valid name.
throw new ClientException(_("Invalid filename."));
}
return $this->filename;
}
// where should the file go?
static function filename(Profile $profile, $origname, $mimetype)
@ -610,12 +619,45 @@ class File extends Managed_DataObject
return;
}
echo "\nFound old $table table, upgrading it to contain 'urlhash' field...";
$file = new File();
$file->query(sprintf('SELECT id, LEFT(url, 191) AS shortenedurl, COUNT(*) AS c FROM %1$s WHERE LENGTH(url)>191 GROUP BY shortenedurl HAVING c > 1', $schema->quoteIdentifier($table)));
print "\nFound {$file->N} URLs with too long entries in file table\n";
while ($file->fetch()) {
// We've got a URL that is too long for our future file table
// so we'll cut it. We could save the original URL, but there is
// no guarantee it is complete anyway since the previous max was 255 chars.
$dupfile = new File();
// First we find file entries that would be duplicates of this when shortened
// ... and we'll just throw the dupes out the window for now! It's already so borken.
$dupfile->query(sprintf('SELECT * FROM file WHERE LEFT(url, 191) = "%1$s"', $file->shortenedurl));
// Leave one of the URLs in the database by using ->find(true) (fetches first entry)
if ($dupfile->find(true)) {
print "\nShortening url entry for $table id: {$file->id} [";
$orig = clone($dupfile);
$dupfile->url = $file->shortenedurl; // make sure it's only 191 chars from now on
$dupfile->update($orig);
print "\nDeleting duplicate entries of too long URL on $table id: {$file->id} [";
// only start deleting with this fetch.
while($dupfile->fetch()) {
print ".";
$dupfile->delete();
}
print "]\n";
} else {
print "\nWarning! URL suddenly disappeared from database: {$file->url}\n";
}
}
echo "...and now all the non-duplicates which are longer than 191 characters...\n";
$file->query('UPDATE file SET url=LEFT(url, 191) WHERE LENGTH(url)>191');
echo "\n...now running hacky pre-schemaupdate change for $table:";
// We have to create a urlhash that is _not_ the primary key,
// transfer data and THEN run checkSchema
$schemadef['fields']['urlhash'] = array (
'type' => 'varchar',
'length' => 64,
'not null' => true,
'not null' => false, // this is because when adding column, all entries will _be_ NULL!
'description' => 'sha256 of destination URL (url field)',
);
$schemadef['fields']['url'] = array (

View File

@ -85,6 +85,24 @@ class File_to_post extends Managed_DataObject
}
}
static function getNoticeIDsByFile(File $file)
{
$f2p = new File_to_post();
$f2p->selectAdd();
$f2p->selectAdd('post_id');
$f2p->file_id = $file->id;
$ids = array();
if (!$f2p->find()) {
throw new NoResultException($f2p);
}
return $f2p->fetchAll('post_id');
}
function delete($useWhere=false)
{
$f = File::getKV('id', $this->file_id);

View File

@ -880,6 +880,11 @@ class Profile extends Managed_DataObject
$inst->delete();
}
$localuser = User::getKV('id', $this->id);
if ($localuser instanceof User) {
$localuser->delete();
}
return parent::delete($useWhere);
}

View File

@ -535,6 +535,7 @@ class Schema
$res = $this->conn->query($sql);
if ($_PEAR->isError($res)) {
common_debug('PEAR exception on query: '.$sql);
PEAR_ErrorToPEAR_Exception($res);
}
}

View File

@ -113,7 +113,7 @@ function readline_emulation($prompt)
function console_help()
{
print "Welcome to StatusNet's interactive PHP console!\n";
print "Welcome to GNU social's interactive PHP console!\n";
print "Type some PHP code and it'll execute...\n";
print "\n";
print "Hint: return a value of any type to output it via var_export():\n";
@ -128,8 +128,8 @@ function console_help()
}
if (CONSOLE_INTERACTIVE) {
print "StatusNet interactive PHP console... type ctrl+D or enter 'exit' to exit.\n";
$prompt = common_config('site', 'name') . '> ';
print "GNU social interactive PHP console... type ctrl+D or enter 'exit' to exit.\n";
$prompt = common_slugify(common_config('site', 'name')) . '> ';
} else {
$prompt = '';
}

78
scripts/nukefile.php Executable file
View File

@ -0,0 +1,78 @@
#!/usr/bin/env php
<?php
/*
* StatusNet - a distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, 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
* 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/>.
*/
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
$shortoptions = 'i::yv';
$longoptions = array('id=', 'yes', 'verbose');
$helptext = <<<END_OF_HELP
nukefile.php [options]
deletes a file and related notices from the database
-i --id ID of the file
-v --verbose Be verbose (print the contents of the notices deleted).
END_OF_HELP;
require_once INSTALLDIR.'/scripts/commandline.inc';
if (have_option('i', 'id')) {
$id = get_option_value('i', 'id');
$file = File::getKV('id', $id);
if (!$file instanceof File) {
print "Can't find file with ID $id\n";
exit(1);
}
} else {
print "You must provide a file ID.\n";
exit(1);
}
$verbose = have_option('v', 'verbose');
if (!have_option('y', 'yes')) {
try {
$filename = $file->getFilename();
} catch (Exception $e) {
$filename = '(remote file or no filename)';
}
print "About to PERMANENTLY delete file ($filename) ({$file->id}). Are you sure? [y/N] ";
$response = fgets(STDIN);
if (strtolower(trim($response)) != 'y') {
print "Aborting.\n";
exit(0);
}
}
print "Finding notices...\n";
try {
$ids = File_to_post::getNoticeIDsByFile($file);
$notice = Notice::multiGet('id', $ids);
while ($notice->fetch()) {
print "Deleting notice {$notice->id}".($verbose ? ": $notice->content\n" : "\n");
$notice->delete();
}
} catch (NoResultException $e) {
print "No notices found with this File attached.\n";
}
print "Deleting File object together with possibly locally stored copy.\n";
$file->delete();
print "DONE.\n";