Diff -- /var/www/vhosts/3dshawn.com/site1/MODS/Config.pm

O Operator
Diff

/var/www/vhosts/3dshawn.com/site1/MODS/Config.pm

added on local at 2026-07-10 18:57:30

Added
+110
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 3df94e4ac22a
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1package MODS::Config;
2#======================================================================
3# DriftSense -- installation-aware config reader.
4#
5# Reads /etc/drift_sense/drift_sense.conf (or the path in
6# $ENV{DRIFT_SENSE_CONF}) parsed as simple key=value pairs. Values not
7# in the file fall through to a code-default table.
8#
9# Public API:
10# my $cfg = MODS::Config->new;
11# my $v = $cfg->settings('db_host'); # -> string or ''
12# my $all = $cfg->all; # -> hashref of every key
13#
14# Same shape as the portfolio's other MODS::Config modules so callers
15# (DBConnect, Mail, etc.) can use it interchangeably.
16#======================================================================
17use strict;
18use warnings;
19
20# --- Code defaults (used when the conf file has no matching key) ------
21my %DEFAULTS = (
22 db_engine => 'mysql',
23 db_host => 'localhost',
24 db_port => '3306',
25 db_name => 'drift_sense',
26 db_user => 'drift_sense',
27 db_password => '', # never bake a default password
28 sqlite_path => '/var/lib/drift_sense/drift_sense.db',
29 brand_name => 'DriftSense',
30 brand_tagline => 'Silent safety net for code + schema drift',
31 public_url => 'http://localhost:8080',
32 compression_enabled => '1',
33 max_file_size_bytes => '10485760',
34 auto_purge_days => '365',
35 purge_check_interval_hours => '24',
36 agent_ingest_enabled => '0',
37 agent_hmac_secret => '',
38 agent_max_clock_skew_seconds => '300',
39 smtp_host => '',
40 smtp_port => '587',
41 smtp_user => '',
42 smtp_password => '',
43 smtp_from => 'drift_sense@localhost',
44 docker_awareness_enabled => '0',
45 docker_socket_path => '/var/run/docker.sock',
46 overlay2_root => '/var/lib/docker/overlay2',
47
48 # UI corner-tag (legacy behavior from v1)
49 tag_name => 'DriftSense',
50 tag_bg_color => '#0f766e', # deep teal
51 tag_text_color => '#e5edf5',
52);
53
54# --- Locate the conf file -------------------------------------------------
55sub _conf_paths {
56 my @paths;
57 push @paths, $ENV{DRIFT_SENSE_CONF} if $ENV{DRIFT_SENSE_CONF};
58 push @paths, '/etc/drift_sense/drift_sense.conf';
59 push @paths, '/usr/local/etc/drift_sense/drift_sense.conf';
60 # Dev fallback: next to the CGI (../_config/drift_sense.conf)
61 if ($ENV{SCRIPT_FILENAME}) {
62 my $sf = $ENV{SCRIPT_FILENAME};
63 $sf =~ s|/[^/]+$||; # strip CGI filename -> docroot
64 push @paths, "$sf/_config/drift_sense.conf";
65 }
66 return @paths;
67}
68
69my %_CACHE;
70my $_LOADED = 0;
71
72sub _load {
73 return if $_LOADED;
74 $_LOADED = 1;
75 foreach my $p (_conf_paths()) {
76 next unless -r $p;
77 open(my $fh, '<', $p) or next;
78 while (my $line = <$fh>) {
79 chomp $line;
80 $line =~ s/^\s+|\s+$//g;
81 next if $line eq '' || $line =~ /^#/;
82 if ($line =~ /^([A-Za-z0-9_]+)\s*=\s*(.*?)\s*$/) {
83 my ($k, $v) = ($1, $2);
84 $v =~ s/^["']//; $v =~ s/["']$//; # strip optional quotes
85 $_CACHE{$k} = $v;
86 }
87 }
88 close $fh;
89 last; # first readable conf wins
90 }
91}
92
93sub new { return bless({}, shift); }
94
95sub settings {
96 my ($self, $key) = @_;
97 _load();
98 return $_CACHE{$key} if exists $_CACHE{$key};
99 return $DEFAULTS{$key} if exists $DEFAULTS{$key};
100 return '';
101}
102
103sub all {
104 my $self = shift;
105 _load();
106 my %merged = (%DEFAULTS, %_CACHE);
107 return \%merged;
108}
109
1101;