Diff -- /var/www/vhosts/3dshawn.com/site1/pin_hotspots.cgi

O Operator
Diff

/var/www/vhosts/3dshawn.com/site1/pin_hotspots.cgi

modified on local at 2026-07-12 00:04:56

Added
+12
lines
Removed
-8
lines
Context
105
unchanged
Blobs
from 37a1a9fc1137
to e108e89453cb
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
11#!/usr/bin/perl
22#======================================================================
33# DriftSense -- /pin_hotspots.cgi
44#
55# Bulk-pin the top-N most-changed files into a new Named Release.
66# GET shows a preview form (default N=20 over 30 days).
77# POST creates a NAMED_RELEASES row + one NAMED_RELEASE_PINS row per
88# top-file (references the file's latest file_changes_id).
99#======================================================================
1010use strict;
1111use warnings;
1212use CGI ();
1313use MODS::Config;
1414use MODS::DBConnect;
1515use MODS::Template;
1616use MODS::PageWrapper;
17use POSIX ();
1718
1819my $cgi = CGI->new;
1920my $db = MODS::DBConnect->new;
2021my $tpl = MODS::Template->new;
2122$|=1;
2223
2324my $dbh = $db->db_connect or die "DriftSense: DB connect failed\n";
2425
2526my $method = $ENV{REQUEST_METHOD} || 'GET';
2627my $limit = int($cgi->param('n') || 20); $limit = 5 if $limit < 5; $limit = 100 if $limit > 100;
2728my $days = int($cgi->param('days') || 30); $days = 1 if $days < 1; $days = 365 if $days > 365;
2829
2930# ---- Top-N most-changed files in the window -------------------------
3031my @top = $db->db_readwrite_multiple($dbh, qq~
3132 SELECT fc.file_name,
3233 m.scan_name,
3334 m.file_monitor_list_id AS mid,
3435 COUNT(*) AS change_ct,
35 MAX(fc.file_changes_id) AS latest_id,
36 (SELECT bs.blob_sha FROM FILE_CHANGES fc2
37 WHERE fc2.file_changes_id = MAX(fc.file_changes_id)
38 AND fc2.blob_sha IS NOT NULL
39 LIMIT 1) AS blob_sha
36 MAX(fc.file_changes_id) AS latest_id
4037 FROM FILE_CHANGES fc
4138 LEFT JOIN FILE_MONITOR_SETTINGS m ON m.file_monitor_list_id = fc.file_monitor_list_id
4239 WHERE fc.date_time >= DATE_SUB(NOW(), INTERVAL $days DAY)
4340 AND fc.blob_sha IS NOT NULL
4441 GROUP BY fc.file_name, m.file_monitor_list_id, m.scan_name
4542 ORDER BY change_ct DESC, latest_id DESC
4643 LIMIT $limit
4744~, __FILE__, __LINE__);
45
46# Second pass: fetch each top row's latest blob_sha
47foreach my $t (@top) {
48 next unless $t->{latest_id};
49 my $r = $db->db_readwrite($dbh,
50 "SELECT blob_sha FROM FILE_CHANGES WHERE file_changes_id = " . int($t->{latest_id}) . " LIMIT 1",
51 __FILE__, __LINE__);
52 $t->{blob_sha} = $r ? $r->{blob_sha} : undef;
53}
4854
4955# ---- POST: create the pin release ----------------------------------
5056if ($method eq 'POST' && $cgi->param('confirm')) {
5157 my $name = $cgi->param('name') || 'hotspot-pin-' . time();
5258 my $desc = $cgi->param('description')
5359 || "Auto-pinned top-$limit files by change count over last $days days";
5460 my $by = 'Operator';
5561
5662 my $q_name = $dbh->quote($name);
5763 my $q_desc = $dbh->quote($desc);
5864 my $q_by = $dbh->quote($by);
5965 $db->db_readwrite($dbh, qq~
6066 INSERT INTO NAMED_RELEASES
6167 (name, description, released_at, released_by, is_locked, created_at)
6268 VALUES
6369 ($q_name, $q_desc, NOW(), $q_by, 1, NOW())
6470 ~, __FILE__, __LINE__);
6571 my $rel = $db->db_readwrite($dbh, "SELECT LAST_INSERT_ID() AS id", __FILE__, __LINE__);
6672 my $rid = $rel && $rel->{id};
6773
6874 my $pinned = 0;
6975 if ($rid) {
7076 foreach my $t (@top) {
7177 next unless $t->{latest_id} && $t->{blob_sha};
7278 my $q_file = $dbh->quote($t->{file_name});
7379 my $q_sha = $dbh->quote($t->{blob_sha});
7480 $db->db_readwrite($dbh, qq~
7581 INSERT INTO NAMED_RELEASE_PINS
7682 (named_release_id, file_changes_id, file_name, blob_sha)
7783 VALUES
7884 ($rid, $t->{latest_id}, $q_file, $q_sha)
7985 ~, __FILE__, __LINE__);
8086 $pinned++;
8187 }
8288 }
8389 $db->db_disconnect($dbh);
8490 print "Status: 302 Found\nLocation: /named_releases.cgi?pinned=$pinned\n\n";
8591 exit;
8692}
8793
8894# ---- GET: preview page ---------------------------------------------
8995foreach my $t (@top) {
9096 $t->{file_short} = length($t->{file_name} // '') > 70
9197 ? '...' . substr($t->{file_name}, -67) : ($t->{file_name} // '');
9298 $t->{sha_short} = substr($t->{blob_sha} // '', 0, 12);
9399 $t->{diff_url} = "/diff.cgi?kind=file&id=" . ($t->{latest_id} || 0);
94100}
95101$db->db_disconnect($dbh);
96102
97my $suggest_name = sprintf('hotspot-pin-%s', POSIX::strftime('%Y%m%d-%H%M', localtime));
98require POSIX;
99$suggest_name = 'hotspot-pin-' . POSIX::strftime('%Y%m%d-%H%M', localtime);
103my $suggest_name = 'hotspot-pin-' . POSIX::strftime('%Y%m%d-%H%M', localtime);
100104
101105print "Content-Type: text/html; charset=utf-8\nCache-Control: no-cache\n\n";
102106my @body = $tpl->template('pin_hotspots.html', {
103107 top => \@top,
104108 has_top => scalar(@top) ? 1 : 0,
105109 total => scalar @top,
106110 limit => $limit,
107111 days => $days,
108112 suggest_name => $suggest_name,
109113});
110114MODS::PageWrapper->new->wrapper(
111115 page_title => 'Pin hotspots', page_key => '',
112116 body_html => join('', @body), userinfo => { display_name => 'Operator' },
113117);