首页 > 解决方案 > 使用 MySQL 查询和 BASH,我如何删除、重命名或移动 Drupal 节点在某个日期之前使用的所有图像文件?

问题描述

有兴趣的背景故事:我的一个朋友拥有一本杂志,自 2011 年以来一直在发布相应的 Drupal 7 网站。该网站有数千篇文章和大约 50,000 张支持这些文章的图片。不幸的是,由于版权巨魔律师,他已经因他认为来自“知识共享”的图像而受到了几起版权侵权诉讼的打击。自 2016 年首次提起诉讼以来,他确保所有图片均来自库存图片公司。但显然,就在最近,2016 年之前的另一张图片引起了另一个版权巨魔寻求 18,000 美元(顺便说一句,这实际上是一张热狗的照片)。尽管如此,他的商业保险公司只想支付和解费用,而不是在法庭上冒险,但要求今后从网站上删除所有潜在的可疑图像。由于在他的网站上发布的 95% 的故事的浏览量都低于 1000 次(广告商对它们的价值不到 50 美分),他同意删除所有这些图片,因为 0.50 美元绝对不值得喂食更多巨魔的风险。

问题:在 2016 年某个日期之前删除、重命名或移动所有连接到故事节点的图像的最佳方法是什么?如果我们可以暂时将文件系统上的文件名从“ trollfood.jpg”更改为“就好了trollfood.jpg.bak“(或其他东西),以便如果/当他可以确保图像实际上在公共领域中时,他可以恢复它。如果我们可以替换所有潜在的可疑图像链接(在数据库中),那也很好暂时有一个占位符图片链接(这样人们仍然可以阅读文章而不用怀疑图片去了哪里......也许图片将是对拖钓情况的简要说明)。无论如何,我已经过了一分钟已经用 Drupal 做过任何事情,所以我忘记了 drupal 如何将文件链接到节点(并且他有一些自定义内容类型为他的主要文章提供动力)。

我已经能够通过 mysql 在列表中获取所有潜在的可疑图像:

SELECT fid, filename, timestamp, from_unixtime(timestamp, "%Y-%m-%e") 
FROM drupal7_therooster.file_managed 
where timestamp between unix_timestamp('2011-01-01') and unix_timestamp('2017-01-01');

// here's sample output:
# fid   filename                        timestamp   from_unixtime(timestamp, "%Y-%m-%e")
6154    _MG_5147.jpg                    1373763148  2013-07-14
6155    _MG_5179.jpg                    1373763148  2013-07-14
6161    The Lone Bellow (4 of 5).jpg    1373866156  2013-07-15
6162    The Lone Bellow (1 of 5).jpg    1373866156  2013-07-15

现在,我如何使用它来查找使用这些图像的潜在违规故事,并执行以下操作:

  1. 创建一个使用这些图像的所有故事的列表,这样我就可以保存它,以防他想要恢复这些图像。我对 SQL 很了解……我只是不知道哪些表保存了哪些数据。
  2. 创建一个查询,将这些故事中的这些图像关联替换为占位符图像(因此,如果故事使用“trollfood.jpg”,则该故事现在使用“safetyimageplaceholder.jpg”。有些故事附有多个图像。
  3. 一旦所有可能有问题的文章都引用了占位符图像,我仍然需要移动所有有问题的文件,这样律师就无法访问它们……顺便说一下,我可以通过 ssh 访问。有没有什么好的方法可以使用 bash 命令仅移动/重命名与我从 SQL 查询生成的列表匹配的文件?我只是想小心不要删除/重命名/移动任何不属于查询的图像。请记住,文件系统中的文件创建日期在服务器上都是 2017+,因为服务器在 2017 年被移动(或复制),因此文件系统的原始创建日期不准确。

我知道这是一个很长的问题......它涉及一个 Drupal 站点,但我认为我可能需要适当的 SQL 和 bash 专家的帮助,所以我在这里发布了它,而不是 Drupal 特定的 stackexchange。如果另一种完全不同的方法更适合这个问题,我完全愿意接受任何建议。干杯!

标签: mysqlbashdrupal

解决方案


我能够回答我自己的问题。我必须做三件主要的事情:

第一步:为 Drupal 的 MySQL 数据库创建一个查询,它将为我提供 2012 年至 2017 年间创建的节点正在使用的所有潜在版权侵权文件的列表:

SELECT fm.fid, fm.filename, 
n.title, n.nid, from_unixtime(n.created, "%Y-%m-%d") as 'node_date'
FROM file_managed fm 
JOIN file_usage fu ON fm.fid = fu.fid 
JOIN node n ON fu.id = n.nid
WHERE created BETWEEN unix_timestamp('2012-01-01') AND unix_timestamp('2017-01-01')
ORDER BY node_date

这是一个中等复杂的查询,但基本上它连接了三个表(Drupal 7 的file_managednodefile_usage表)中的列。该表是在哪些节点(via)上使用file_usage哪些文件(via)的共享密钥寄存器。fidnid

第二步:组织和过滤数据以创建文件列表。

我按节点创建日期过滤和排序结果。我在第一步的连接查询中得到了大约 48K 条记录,然后我创建了一个谷歌电子表格来清理和排序数据。这是google 电子表格的示例。此表还包括来自 node_counter 表的数据,该表跟踪每个节点的页面视图。使用一个简单的VLOOKUP函数来匹配主工作表上每个页面的总页面浏览量nid,现在主工作表可以按页面浏览量排序。我这样做是为了优先考虑应该首先检查的每个节点/文章附加的图像。顺便说一下,这是我用来从数据库中获取数据的 sql 查询:

SELECT nid, totalcount, daycount, from_unixtime(timestamp, "%Y-%m-%d") as 'date'
FROM node_counter
ORDER BY totalcount DESC

第三步:编写一个 Shell 脚本,它将我们过滤的文件列表,并将它们移动到安全的地方(并且远离公共网络服务器)。

基本上,我需要一个简单的 BASH 脚本,它会使用第二步中的文件列表将它们移出 Web 服务器。请记住,当每个图像文件上传到服务器时,Drupal 可以(并且确实)创建了大约十几种不同的纵横比和大小,并将这些副本中的每一个都放在相应的文件夹中。例如,可以将一个图像文件名复制并调整为:

  • 文件/coolimage.jpg
  • 文件/大/coolimage.jpg
  • 文件/英雄/coolimage.jpg
  • 文件/缩略图/coolimage.jpg
  • 文件/*/coolimage.jpg 等

因此,我必须列出约 50K 文件名,并在十几个不同的子文件夹中检查这些文件名,如果它们存在于子文件夹中,请将它们中的每一个移动到存档文件夹中,同时保留文件夹/文件树结构并留下“安全”的文件以保存在公共 Web 服务器上。所以...我最终编写了这个简单的脚本并在 Github 上将其开源,以防其他人从中受益

而已!谢天谢地,我知道一些 SQL 以及如何使用 google 电子表格……以及一些基本的 bash……以及如何使用 google 和解决问题。如果谷歌用户能够在未来发现这有帮助......干杯!


推荐阅读