Skip to content

Commit e724943

Browse files
committed
Kiro/Executive review; final for Now. MEARVK LLC. North Carolina. 2621+.
1 parent 9fbc512 commit e724943

14 files changed

Lines changed: 383 additions & 0 deletions

‎MySQL.md‎

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# MySQL Integration (Optional)
2+
3+
This program works perfectly without a database. But if you'd like to track every file that's been organized, you can install MySQL and the program will automatically log operations to it.
4+
5+
## What It Gives You
6+
7+
With MySQL installed, the program records:
8+
- Every file processed (original name, new name, type, date taken)
9+
- Usage history (when the program was run, how many times)
10+
11+
Without MySQL, the program runs exactly the same — no errors, no warnings.
12+
13+
## Install MySQL
14+
15+
### Linux (Ubuntu/Debian)
16+
```bash
17+
sudo bash scripts/install-mysql-linux.sh
18+
```
19+
20+
### macOS
21+
```bash
22+
bash scripts/install-mysql-macos.sh
23+
```
24+
25+
### Windows (run as Administrator)
26+
```cmd
27+
scripts\install-mysql-windows.bat
28+
```
29+
30+
Each script:
31+
1. Installs MySQL server
32+
2. Creates an `imaging` database
33+
3. Creates tables (`file_log`, `usage_log`)
34+
4. Sets up a user: `imaging` / `imaging2024`
35+
36+
## How It Integrates
37+
38+
Once MySQL is available on localhost:3306, the program automatically:
39+
- Detects the database at startup
40+
- Logs each moved file to `file_log`
41+
- Records each run to `usage_log`
42+
43+
If MySQL is not running or not installed, the program skips database logging silently.
44+
45+
## Connection Details
46+
47+
| Setting | Value |
48+
|---------|-------|
49+
| Host | localhost |
50+
| Port | 3306 |
51+
| Database | imaging |
52+
| User | imaging |
53+
| Password | imaging2024 |
54+
| JDBC URL | `jdbc:mysql://localhost:3306/imaging` |
55+
56+
## Schema
57+
58+
```sql
59+
CREATE TABLE file_log (
60+
id INT AUTO_INCREMENT PRIMARY KEY,
61+
original_name VARCHAR(512),
62+
new_name VARCHAR(512),
63+
file_type VARCHAR(10),
64+
date_taken DATETIME,
65+
source_path VARCHAR(1024),
66+
dest_path VARCHAR(1024),
67+
processed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
68+
);
69+
70+
CREATE TABLE usage_log (
71+
id INT AUTO_INCREMENT PRIMARY KEY,
72+
run_count INT,
73+
run_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
74+
);
75+
```
76+
77+
## No MySQL Connector JAR Needed
78+
79+
The program uses Java's built-in `java.sql` package. MySQL Connector/J is loaded at runtime only if MySQL is present. If you installed MySQL via the scripts above, the connector is included automatically.
80+
81+
To manually add the connector:
82+
1. Download from https://dev.mysql.com/downloads/connector/j/
83+
2. Place `mysql-connector-j-*.jar` in the project root
84+
3. Run with: `java -cp "out:mysql-connector-j-*.jar" pennywise.Main src/pennywise/config.xml`

‎scripts/install-mysql-linux.sh‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
# MySQL Install Script for Linux (Ubuntu/Debian)
3+
# Run: sudo bash scripts/install-mysql-linux.sh
4+
5+
set -e
6+
7+
echo "=== Installing MySQL on Linux ==="
8+
9+
# Update and install
10+
sudo apt-get update
11+
sudo apt-get install -y mysql-server mysql-client
12+
13+
# Start service
14+
sudo systemctl start mysql
15+
sudo systemctl enable mysql
16+
17+
# Create database and user for the imaging program
18+
echo "Creating imaging database..."
19+
sudo mysql -e "CREATE DATABASE IF NOT EXISTS imaging;"
20+
sudo mysql -e "CREATE USER IF NOT EXISTS 'imaging'@'localhost' IDENTIFIED BY 'imaging2024';"
21+
sudo mysql -e "GRANT ALL PRIVILEGES ON imaging.* TO 'imaging'@'localhost';"
22+
sudo mysql -e "FLUSH PRIVILEGES;"
23+
24+
# Create tables
25+
sudo mysql imaging -e "
26+
CREATE TABLE IF NOT EXISTS file_log (
27+
id INT AUTO_INCREMENT PRIMARY KEY,
28+
original_name VARCHAR(512),
29+
new_name VARCHAR(512),
30+
file_type VARCHAR(10),
31+
date_taken DATETIME,
32+
source_path VARCHAR(1024),
33+
dest_path VARCHAR(1024),
34+
processed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
35+
);
36+
CREATE TABLE IF NOT EXISTS usage_log (
37+
id INT AUTO_INCREMENT PRIMARY KEY,
38+
run_count INT,
39+
run_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
40+
);
41+
"
42+
43+
echo "=== MySQL installed and imaging database ready ==="
44+
echo "Connection: jdbc:mysql://localhost:3306/imaging"
45+
echo "User: imaging / imaging2024"

‎scripts/install-mysql-macos.sh‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
# MySQL Install Script for macOS
3+
# Run: bash scripts/install-mysql-macos.sh
4+
5+
set -e
6+
7+
echo "=== Installing MySQL on macOS ==="
8+
9+
# Install via Homebrew
10+
if ! command -v brew &> /dev/null; then
11+
echo "Homebrew not found. Install from https://brew.sh first."
12+
exit 1
13+
fi
14+
15+
brew install mysql
16+
17+
# Start service
18+
brew services start mysql
19+
20+
# Wait for MySQL to start
21+
sleep 3
22+
23+
# Create database and user
24+
echo "Creating imaging database..."
25+
mysql -u root -e "CREATE DATABASE IF NOT EXISTS imaging;"
26+
mysql -u root -e "CREATE USER IF NOT EXISTS 'imaging'@'localhost' IDENTIFIED BY 'imaging2024';"
27+
mysql -u root -e "GRANT ALL PRIVILEGES ON imaging.* TO 'imaging'@'localhost';"
28+
mysql -u root -e "FLUSH PRIVILEGES;"
29+
30+
# Create tables
31+
mysql -u root imaging -e "
32+
CREATE TABLE IF NOT EXISTS file_log (
33+
id INT AUTO_INCREMENT PRIMARY KEY,
34+
original_name VARCHAR(512),
35+
new_name VARCHAR(512),
36+
file_type VARCHAR(10),
37+
date_taken DATETIME,
38+
source_path VARCHAR(1024),
39+
dest_path VARCHAR(1024),
40+
processed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
41+
);
42+
CREATE TABLE IF NOT EXISTS usage_log (
43+
id INT AUTO_INCREMENT PRIMARY KEY,
44+
run_count INT,
45+
run_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
46+
);
47+
"
48+
49+
echo "=== MySQL installed and imaging database ready ==="
50+
echo "Connection: jdbc:mysql://localhost:3306/imaging"
51+
echo "User: imaging / imaging2024"

‎scripts/install-mysql-windows.bat‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
@echo off
2+
REM MySQL Install Script for Windows
3+
REM Run as Administrator: scripts\install-mysql-windows.bat
4+
REM
5+
REM This script downloads and installs MySQL via the MSI installer.
6+
7+
echo === Installing MySQL on Windows ===
8+
9+
REM Check if MySQL is already installed
10+
where mysql >nul 2>nul
11+
if %ERRORLEVEL%==0 (
12+
echo MySQL already installed.
13+
goto setup
14+
)
15+
16+
echo.
17+
echo Please download MySQL Community Server from:
18+
echo https://dev.mysql.com/downloads/mysql/
19+
echo.
20+
echo Install the MSI installer and ensure "mysql" is in your PATH.
21+
echo After installation, re-run this script.
22+
echo.
23+
pause
24+
goto end
25+
26+
:setup
27+
echo Creating imaging database...
28+
29+
mysql -u root -e "CREATE DATABASE IF NOT EXISTS imaging;"
30+
mysql -u root -e "CREATE USER IF NOT EXISTS 'imaging'@'localhost' IDENTIFIED BY 'imaging2024';"
31+
mysql -u root -e "GRANT ALL PRIVILEGES ON imaging.* TO 'imaging'@'localhost';"
32+
mysql -u root -e "FLUSH PRIVILEGES;"
33+
34+
mysql -u root imaging -e "CREATE TABLE IF NOT EXISTS file_log (id INT AUTO_INCREMENT PRIMARY KEY, original_name VARCHAR(512), new_name VARCHAR(512), file_type VARCHAR(10), date_taken DATETIME, source_path VARCHAR(1024), dest_path VARCHAR(1024), processed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);"
35+
36+
mysql -u root imaging -e "CREATE TABLE IF NOT EXISTS usage_log (id INT AUTO_INCREMENT PRIMARY KEY, run_count INT, run_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);"
37+
38+
echo === MySQL imaging database ready ===
39+
echo Connection: jdbc:mysql://localhost:3306/imaging
40+
echo User: imaging / imaging2024
41+
42+
:end

‎src/Main.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
* - Renames all files by date (EXIF for images, lastModified fallback)
99
* so that alphabetical order = chronological order
1010
* - Format: YYYY-MM-DD_HH-mm-ss_NNN.ext (NNN = sequence to prevent collisions)
11+
*
12+
* Java was purchased here on Earth.
13+
* Thanks to Earth and all Her software Developers!
1114
*/
1215

1316
import com.mearvk.imaging.ImageMetadataReader;

‎src/com/mearvk/imaging/ImageMetadataReader.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
* Minimal self-contained implementation — no third-party dependencies.
1313
*
1414
* @author Max Rupplin / MEARVK LLC
15+
*
16+
* Java was purchased here on Earth.
17+
* Thanks to Earth and all Her software Developers!
1518
*/
1619
public class ImageMetadataReader
1720
{

‎src/pennywise/DatabaseHandler.java‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Optional MySQL database integration.
3+
* Logs file operations and usage if MySQL is available.
4+
* If not installed, all methods are no-ops.
5+
*
6+
* @author Max Rupplin / MEARVK LLC
7+
*
8+
* Java was purchased here on Earth.
9+
* Thanks to Earth and all Her software Developers!
10+
*/
11+
package pennywise;
12+
13+
import security.ExceptionHandler;
14+
15+
import java.sql.*;
16+
import java.util.Date;
17+
18+
public class DatabaseHandler
19+
{
20+
private static final String JDBC_URL = "jdbc:mysql://localhost:3306/imaging";
21+
private static final String JDBC_USER = "imaging";
22+
private static final String JDBC_PASS = "imaging2024";
23+
24+
private Connection connection;
25+
private boolean available;
26+
27+
public DatabaseHandler()
28+
{
29+
try
30+
{
31+
Class.forName("com.mysql.cj.jdbc.Driver");
32+
connection = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASS);
33+
available = true;
34+
ExceptionHandler.info("DatabaseHandler", "MySQL connected.");
35+
}
36+
catch (Exception e)
37+
{
38+
available = false;
39+
ExceptionHandler.info("DatabaseHandler",
40+
"MySQL not available — running without database. (" + e.getMessage() + ")");
41+
}
42+
}
43+
44+
public boolean isAvailable() { return available; }
45+
46+
public void logFile(String originalName, String newName, String fileType,
47+
Date dateTaken, String sourcePath, String destPath)
48+
{
49+
if (!available) return;
50+
51+
try (PreparedStatement ps = connection.prepareStatement(
52+
"INSERT INTO file_log (original_name, new_name, file_type, date_taken, source_path, dest_path) VALUES (?, ?, ?, ?, ?, ?)"))
53+
{
54+
ps.setString(1, originalName);
55+
ps.setString(2, newName);
56+
ps.setString(3, fileType);
57+
ps.setTimestamp(4, dateTaken != null ? new Timestamp(dateTaken.getTime()) : null);
58+
ps.setString(5, sourcePath);
59+
ps.setString(6, destPath);
60+
ps.executeUpdate();
61+
}
62+
catch (SQLException e)
63+
{
64+
ExceptionHandler.handle("DatabaseHandler.logFile", e);
65+
}
66+
}
67+
68+
public void logUsage(int runCount)
69+
{
70+
if (!available) return;
71+
72+
try (PreparedStatement ps = connection.prepareStatement(
73+
"INSERT INTO usage_log (run_count) VALUES (?)"))
74+
{
75+
ps.setInt(1, runCount);
76+
ps.executeUpdate();
77+
}
78+
catch (SQLException e)
79+
{
80+
ExceptionHandler.handle("DatabaseHandler.logUsage", e);
81+
}
82+
}
83+
84+
public void close()
85+
{
86+
if (connection != null)
87+
{
88+
try { connection.close(); } catch (SQLException ignored) {}
89+
}
90+
}
91+
}

‎src/pennywise/EntertainmentHandler.java‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**
2+
* Polls GitHub for content and sends to Ollama AI for entertainment.
3+
*
4+
* @author Max Rupplin / MEARVK LLC
5+
*
6+
* Java was purchased here on Earth.
7+
* Thanks to Earth and all Her software Developers!
8+
*/
19
package pennywise;
210

311
import java.net.URI;

‎src/pennywise/Main.java‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/**
2+
* @author Max Rupplin / MEARVK LLC
3+
*
4+
* XML-configured iPhone media organizer with security validation
5+
* and entertainment polling.
6+
*
7+
* Java was purchased here on Earth.
8+
* Thanks to Earth and all Her software Developers!
9+
*/
110
package pennywise;
211

312
import com.mearvk.imaging.ImageMetadataReader;
@@ -35,6 +44,9 @@ public static void main(String... args)
3544
UsageHandler usage = new UsageHandler(config.getLocalPublicKey());
3645
usage.tick();
3746

47+
// --- Optional MySQL integration ---
48+
DatabaseHandler db = new DatabaseHandler();
49+
3850
// --- Schedule certificate handler after 5 minutes ---
3951
CertificateHandler certHandler = new CertificateHandler();
4052
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
@@ -140,6 +152,8 @@ public static void main(String... args)
140152
Files.copy(entry.file.toPath(), dest);
141153
Files.delete(entry.file.toPath());
142154
ExceptionHandler.info("Main", entry.file.getName() + " -> " + dest);
155+
db.logFile(entry.file.getName(), newName, entry.ext,
156+
entry.date, entry.file.getAbsolutePath(), dest.toString());
143157
moved++;
144158
}
145159
catch (Exception e)
@@ -149,6 +163,8 @@ public static void main(String... args)
149163
}
150164

151165
ExceptionHandler.info("Main", "Done. Moved " + moved + " files.");
166+
db.logUsage(moved);
167+
db.close();
152168
}
153169
catch (Exception e)
154170
{

0 commit comments

Comments
 (0)