From b05241f508d3408da35a7386f774fc2e9df14d24 Mon Sep 17 00:00:00 2001
From: Teatek <38403802+Teatek@users.noreply.github.com>
Date: Tue, 22 Jan 2019 10:26:52 +0100
Subject: [PATCH] Fixes #272 missing md5sum
* dashboard: add warning if missing checksums
* add a "compute all missing md5sum" option in batch manager (inspired by delete orphans)
* progress bar when computing md5sums
---
admin.php | 12 +++++
admin/batch_manager.php | 18 ++++++-
admin/batch_manager_global.php | 1 +
admin/include/functions.php | 50 ++++++++++++++++++
admin/intro.php | 22 ++++++++
admin/themes/default/js/batchManagerGlobal.js | 51 ++++++++++++++++++-
.../default/template/batch_manager_global.tpl | 13 +++++
include/ws_functions/pwg.images.php | 24 +++++++++
language/en_UK/admin.lang.php | 5 ++
ws.php | 14 ++++-
10 files changed, 206 insertions(+), 4 deletions(-)
diff --git a/admin.php b/admin.php
index 7da423799..5192d3cd2 100644
--- a/admin.php
+++ b/admin.php
@@ -251,6 +251,18 @@ if ($nb_photos_in_caddie > 0)
);
}
+// any photos with no md5sum ?
+$nb_no_md5sum = count(get_photos_no_md5sum());
+if ($nb_no_md5sum > 0)
+{
+ $template->assign(
+ array(
+ 'NB_NO_MD5SUM' => $nb_no_md5sum,
+ 'U_NO_MD5SUM' => $link_start.'batch_manager&filter=prefilter-no_sync_md5sum',
+ )
+ );
+}
+
// any orphan photo?
$nb_orphans = count(get_orphans());
diff --git a/admin/batch_manager.php b/admin/batch_manager.php
index e1ae22770..8d34d825a 100644
--- a/admin/batch_manager.php
+++ b/admin/batch_manager.php
@@ -79,8 +79,21 @@ DELETE FROM '.CADDIE_TABLE.'
redirect(get_root_url().'admin.php?page='.$_GET['page']);
}
}
-}
+ if ('sync_md5sum' == $_GET['action'] and isset($_GET['nb_md5sum_added']))
+ {
+ check_input_parameter('nb_md5sum_added', $_GET, false, '/^\d+$/');
+ if ($_GET['nb_md5sum_added'] > 0)
+ {
+ $_SESSION['page_infos'][] = l10n_dec(
+ '%d checksums were added', '%d checksums were added',
+ $_GET['nb_md5sum_added']
+ );
+
+ redirect(get_root_url().'admin.php?page='.$_GET['page']);
+ }
+ }
+}
// +-----------------------------------------------------------------------+
// | initialize current set |
// +-----------------------------------------------------------------------+
@@ -369,6 +382,9 @@ SELECT id
case 'no_album':
$filter_sets[] = get_orphans();
break;
+ case 'no_sync_md5sum':
+ $filter_sets[] = get_photos_no_md5sum();
+ break;
case 'no_tag':
$query = '
diff --git a/admin/batch_manager_global.php b/admin/batch_manager_global.php
index 51987ec3f..48b6ddced 100644
--- a/admin/batch_manager_global.php
+++ b/admin/batch_manager_global.php
@@ -458,6 +458,7 @@ $prefilters = array(
if ($conf['enable_synchronization'])
{
$prefilters[] = array('ID' => 'no_virtual_album', 'NAME' => l10n('With no virtual album'));
+ $prefilters[] = array('ID' => 'no_sync_md5sum', 'NAME' => l10n('With no checksum'));
}
$prefilters = trigger_change('get_batch_manager_prefilters', $prefilters);
diff --git a/admin/include/functions.php b/admin/include/functions.php
index 923a7c221..dfcc6e532 100644
--- a/admin/include/functions.php
+++ b/admin/include/functions.php
@@ -2993,6 +2993,56 @@ SELECT CONCAT(
return $keys;
}
+/**
+ * Return the list of image ids where md5sum is null
+ *
+ * @return int[] image_ids
+ */
+function get_photos_no_md5sum()
+{
+ $query = '
+SELECT id
+ FROM '.IMAGES_TABLE.'
+ WHERE md5sum is null
+;';
+ return query2array($query, null, 'id');
+}
+
+/**
+ * Compute and add the md5sum of image ids (where md5sum is null)
+ * @param int[] list of image ids and there paths
+ * @return int number of md5sum added
+ */
+function add_md5sum($ids)
+{
+ $query = '
+SELECT path
+ FROM '.IMAGES_TABLE.'
+ WHERE id IN ('.implode(', ',$ids).')
+;';
+ $paths = query2array($query, null, 'path');
+ $imgs_ids_paths = array_combine($ids, $paths);
+ $updates = array();
+ foreach ($ids as $id)
+ {
+ $file = PHPWG_ROOT_PATH.$imgs_ids_paths[$id];
+ $md5sum = md5_file($file);
+ $updates[] = array(
+ 'id' => $id,
+ 'md5sum' => $md5sum,
+ );
+ }
+ mass_updates(
+ IMAGES_TABLE,
+ array(
+ 'primary' => array('id'),
+ 'update' => array('md5sum')
+ ),
+ $updates
+ );
+ return count($ids);
+}
+
/**
* Return the list of image ids associated to no album
*
diff --git a/admin/intro.php b/admin/intro.php
index 23a5a4f5e..d3637afef 100644
--- a/admin/intro.php
+++ b/admin/intro.php
@@ -53,6 +53,28 @@ $tabsheet->assign();
// | actions |
// +-----------------------------------------------------------------------+
+//check if images have no md5sum in database
+$query = '
+SELECT COUNT(*)
+ FROM '.CATEGORIES_TABLE.'
+ WHERE dir IS NOT NULL
+;';
+list($counter) = pwg_db_fetch_row(pwg_query($query));
+if ($counter > 0)
+{
+ $query = '
+ SELECT COUNT(*)
+ FROM '.IMAGES_TABLE.'
+ WHERE storage_category_id IS NOT NULL
+ AND md5sum IS NULL
+ ;';
+ list($counter) = pwg_db_fetch_row(pwg_query($query));
+ if ($counter > 0)
+ {
+ $page['warnings'][] = ''.l10n('Some checksums are missing.').'';
+ }
+}
+
// Check for upgrade : code inspired from punbb
if (isset($_GET['action']) and 'check_upgrade' == $_GET['action'])
{
diff --git a/admin/themes/default/js/batchManagerGlobal.js b/admin/themes/default/js/batchManagerGlobal.js
index 50986a680..8a593d9dd 100644
--- a/admin/themes/default/js/batchManagerGlobal.js
+++ b/admin/themes/default/js/batchManagerGlobal.js
@@ -329,11 +329,58 @@ function progressDelete(val, max, success) {
}
}
-
jQuery("#action_delete input[name=confirm_deletion]").change(function() {
jQuery("#action_delete span.errors").hide();
});
+ jQuery('#sync_md5sum').click(function(e) {
+ jQuery(this).hide();
+ jQuery('#add_md5sum').show();
+
+ var addBlockSize = Math.min(
+ Number((jQuery('#md5sum_to_add').data('origin') / 2).toFixed()),
+ 1000
+ );
+ add_md5sum_block(addBlockSize);
+
+ return false;
+});
+
+function add_md5sum_block(blockSize){
+ jQuery.ajax({
+ url: "ws.php?format=json&method=pwg.images.setMd5sum",
+ type:"POST",
+ dataType: "json",
+ data: {
+ pwg_token: jQuery("input[name=pwg_token").val(),
+ block_size: blockSize
+ },
+ success:function(data) {
+ jQuery('#md5sum_to_add').html(data.result.nb_no_md5sum);
+
+ var percent_remaining = Number(
+ (data.result.nb_no_md5sum * 100 / jQuery('#md5sum_to_add').data('origin')).toFixed()
+ );
+ var percent_done = 100 - percent_remaining;
+ jQuery('#md5sum_added').html(percent_done);
+ if (data.result.nb_no_md5sum > 0) {
+ add_md5sum_block();
+ }
+ else {
+ // time to refresh the whole page
+ var redirect_to = 'admin.php?page=batch_manager';
+ redirect_to += '&action=sync_md5sum';
+ redirect_to += '&nb_md5sum_added='+jQuery('#md5sum_to_add').data('origin');
+
+ document.location = redirect_to;
+ }
+ },
+ error:function(XMLHttpRequest) {
+ jQuery('#add_md5sum').hide();
+ jQuery('#add_md5sum_error').show().html('error '+XMLHttpRequest.status+' : '+XMLHttpRequest.statusText);
+ }
+ });
+}
jQuery('#delete_orphans').click(function(e) {
jQuery(this).hide();
@@ -384,4 +431,4 @@ function delete_orphans_block(blockSize) {
jQuery('#orphans_deletion_error').show().html('error '+XMLHttpRequest.status+' : '+XMLHttpRequest.statusText);
}
});
-}
\ No newline at end of file
+}
diff --git a/admin/themes/default/template/batch_manager_global.tpl b/admin/themes/default/template/batch_manager_global.tpl
index f4299f424..8397673bc 100644
--- a/admin/themes/default/template/batch_manager_global.tpl
+++ b/admin/themes/default/template/batch_manager_global.tpl
@@ -275,6 +275,7 @@ $(document).ready(function() {
jQuery("#empty_caddie").toggle(jQuery(this).val() == "caddie");
jQuery("#duplicates_options").toggle(jQuery(this).val() == "duplicates");
jQuery("#delete_orphans").toggle(jQuery(this).val() == "no_album");
+ jQuery("#sync_md5sum").toggle(jQuery(this).val() == "no_sync_md5sum");
});
});
@@ -348,6 +349,18 @@ var sliders = {
{if $NB_ORPHANS > 0}
{'Delete %d orphan photos'|translate:$NB_ORPHANS}
{/if}
+{if $NB_NO_MD5SUM > 0}
+{'Compute %d missing checksums'|translate:{$NB_NO_MD5SUM}}
+{/if}
+
+
+
+ 0% -
+ {$NB_NO_MD5SUM}
+ {'checksums to add'|translate}
+
+
+
diff --git a/include/ws_functions/pwg.images.php b/include/ws_functions/pwg.images.php
index ae609d698..c141694a4 100644
--- a/include/ws_functions/pwg.images.php
+++ b/include/ws_functions/pwg.images.php
@@ -1807,6 +1807,30 @@ function ws_images_checkUpload($params, $service)
return $ret;
}
+/**
+ * API method
+ * add md5sum at photos, by block. Returns how md5sum were added and how many are remaining.
+ * @param mixed[] $params
+ * @option int block_size
+ */
+function ws_images_setMd5sum($params, $service)
+{
+ if (get_pwg_token() != $params['pwg_token'])
+ {
+ return new PwgError(403, 'Invalid security token');
+ }
+
+ include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+ $md5sum_ids_to_add = array_slice(get_photos_no_md5sum(), 0, $params['block_size']);
+ $added_count = add_md5sum($md5sum_ids_to_add);
+
+ return array(
+ 'nb_added' => $added_count,
+ 'nb_no_md5sum' => count(get_photos_no_md5sum()),
+ );
+}
+
/**
* API method
* Deletes orphan photos, by block. Returns how many orphans were deleted and how many are remaining.
diff --git a/language/en_UK/admin.lang.php b/language/en_UK/admin.lang.php
index 77ee9dc9d..6028f3804 100644
--- a/language/en_UK/admin.lang.php
+++ b/language/en_UK/admin.lang.php
@@ -1009,3 +1009,8 @@ $lang['Piwigo %s is available, please update'] = 'Piwigo %s is available, please
$lang['Time has come to update your Piwigo with version %s, go to %s'] = 'The time has come to update your Piwigo to version %s, go to %s';
$lang['It only takes a few clicks.'] = 'It only takes a few clicks.';
$lang['Running on an up-to-date Piwigo is important for security.'] = 'Running on an up-to-date Piwigo is important for security.';
+$lang['Some checksums are missing.'] = 'Some checksums are missing.';
+$lang['%d checksums were added'] = '%d checksums were added';
+$lang['With no checksum'] = 'With no checksum';
+$lang['Compute %d missing checksums'] = 'Compute %d missing checksums';
+$lang['checksums to add'] = 'checksums to add';
diff --git a/ws.php b/ws.php
index b2c5e1779..b0fcfdb3d 100644
--- a/ws.php
+++ b/ws.php
@@ -159,7 +159,7 @@ function ws_addDefaultMethods( $arr )
'pwg.categories.getImages',
'ws_categories_getImages',
array_merge(array(
- 'cat_id' => array('default'=>null,
+ 'cat_id' => array('default'=>null,
'flags'=>WS_PARAM_FORCE_ARRAY,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE),
'recursive' => array('default'=>false,
@@ -510,6 +510,18 @@ function ws_addDefaultMethods( $arr )
array('admin_only'=>true, 'post_only'=>true)
);
+ $service->addMethod(
+ 'pwg.images.setMd5sum',
+ 'ws_images_setMd5sum',
+ array(
+ 'block_size' => array('default'=>1000, 'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE),
+ 'pwg_token' => array(),
+ ),
+ 'Set md5sum column, by blocks. Returns how many md5sums were added and how many are remaining.',
+ $ws_functions_root . 'pwg.images.php',
+ array('admin_only'=>true, 'post_only'=>true)
+ );
+
$service->addMethod(
'pwg.images.deleteOrphans',
'ws_images_deleteOrphans',