Skip to content

islacchi/File-Watcher

Repository files navigation

Laravel Logo

PHP Laravel Tailwind CSS Alpine.js SQLite Vite

Status License

File Watcher Laravel UI

A read-only Laravel web interface for monitoring file system changes on a network drive.
Pairs with a Python file watcher that logs events to a SQLite database.


Features

  • Dashboard — Real-time metrics, sparkline chart, event type breakdown, and recent activity feed
  • Analytics — Multi-range charts (7d / 30d / 90d / 1y) with stacked bar chart, top folders, file extensions, and size distribution
  • Events Log — Filterable and paginated table with search, date range, event type, and extension filters
  • Snapshot — Current file state with expandable directory tree, stale file detection, auto-refreshes every 15s
  • File Timeline — Complete event history tracking files across renames and moves via MD5 hash linking
  • Health Monitoring — Live/offline status indicator via heartbeat polling from the Python script
  • Auto-refresh — Change-driven polling that reloads the page only when new events are detected
  • Dark Mode — Class-based toggle with localStorage persistence

Architecture

app/
├── Enums/          # EventType enum with badge colors and labels
├── Http/
│   ├── Controllers/# Dashboard, Event, File, Snapshot, Health, Analytics
│   └── Requests/  # EventFilter, SnapshotFilter, FileTimeline
├── Models/         # Event, Snapshot, Config (read-only)
├── Services/       # EventService, SnapshotService, ConfigService, Formatter
├── Providers/      # ViewServiceProvider (shared layout data)
└── View/Models/    # DashboardViewModel, EventViewModel, SnapshotViewModel

resources/views/
├── components/
│   └── layouts/
│       └── app.blade.php       # Shared layout: sidebar, topbar, offline banner
├── analytics/
│   └── index.blade.php         # Analytics page with Alpine.js charts
├── dashboard.blade.php
├── events/index.blade.php
├── files/timeline.blade.php
└── snapshot/
    ├── index.blade.php
    └── _tree.blade.php         # AJAX partial for directory tree

Pages

Page Route Description
Dashboard /filewatcher/dashboard Metrics, sparkline, event type bars, recent activity
Analytics /filewatcher/analytics Multi-range charts and breakdowns
Events Log /filewatcher/events Filterable event table with pagination
Snapshot /filewatcher/snapshot Current file states and directory tree
File Timeline /filewatcher/files?path=... Full event history for a single file

Analytics

The analytics page is precomputed server-side across four date ranges and rendered entirely client-side via Alpine.js with no additional requests on range switch.

Date Ranges

Pill Range Chart grouping
7d Last 7 days Daily bars, scrollable
30d Last 30 days Daily bars, scrollable
90d Last 90 days Daily bars, compressed
1y Last 365 days Weekly bars, compressed

Summary Cards

  • Total events — count for the selected range
  • Daily average — total divided by number of days
  • Most active type — event type with highest count and its percentage
  • Total data affected — sum of file_size across all events, formatted (B / KB / MB / GB)

Charts

Event volume by type — stacked bar chart with per-type color coding, hover tooltip showing date, per-type counts, and total. Tooltip uses a fixed-position portal to avoid overflow clipping. Y-axis uses dynamic magnitude-based tick scaling. 1y range uses PHP-aggregated weekly grouping.

Top folders by activity — horizontal bar list showing the top 10 directories by event count, with percentage labels. Folder paths are extracted from dirname(src_path) and display the last two path segments.

File extensions — horizontal bar list showing the top 8 extensions by count. Extension is extracted using the last dot in the filename to prevent compound extensions from appearing as full filenames.

File size distribution — bar chart with 6 size buckets: <10 KB, 10–50 KB, 50–200 KB, 200 KB–1 MB, 1–10 MB, >10 MB. Bars use the same hover tooltip pattern.


Database

The UI connects to an existing SQLite database created by the Python script. All tables are read-only.

events — Permanent log of every file change

Column Type Description
id INTEGER PK Auto-increment
timestamp TEXT ISO 8601 datetime
event_type TEXT CREATED / MODIFIED / DELETED / RENAMED / MOVED (+ offline variants)
src_path TEXT Source file path (UNC or local)
dest_path TEXT Destination path for RENAMED/MOVED
file_size INTEGER Size in bytes
md5_hash TEXT Hash after the event
prev_hash TEXT Hash before the event (MODIFIED only)

snapshots — Last known state of every watched file

Column Type Description
id INTEGER PK Auto-increment
path TEXT UNIQUE Current file path
size INTEGER File size
mtime REAL Unix timestamp
md5_hash TEXT Current hash
last_seen TEXT ISO 8601 timestamp

config — Script metadata (written by Python)

Column Type Description
key TEXT PK watch_directory, started_at, heartbeat, script_version
value TEXT Corresponding value
updated TEXT ISO 8601 timestamp

Design System

Built with Tailwind CSS v4 and Alpine.js. Dark mode uses a class-based strategy (dark on <html>) toggled via Alpine and persisted to localStorage.

Tailwind v4 Notes

Dynamic Alpine :class bindings are not scanned by Tailwind v4's build-time scanner. Classes used in dynamic bindings are safelisted via @source inline() in app.css:

@source inline("ml-60 ml-16 w-60 w-16 translate-x-4.5 translate-x-0.5 dark:bg-gray-800 dark:bg-gray-700 dark:border-gray-700");

Custom dark mode variant is defined as:

@custom-variant dark (&:is(.dark *));

IDE warnings about unknown @source, @custom-variant are cosmetic — suppress via .vscode/settings.json:

{
    "css.lint.unknownAtRules": "ignore"
}

Event Type Colors

Type Color Hex
CREATED bg-green-500 #22c55e
MODIFIED bg-blue-500 #3b82f6
DELETED bg-red-500 #ef4444
RENAMED bg-yellow-500 #eab308
MOVED bg-teal-400 #2dd4bf
MOVED & RENAMED bg-indigo-400 #818cf8

Reusable Components

Component Usage Props
<x-event-badge> Events table, dashboard, timeline label, color
<x-metric-card> Dashboard cards title, value, trend, icon, sparkline
<x-file-path> All file path displays path, truncated
<x-hash-display> Hash columns hash, truncated, searchable
<x-timeline-dot> File timeline color
<x-directory-tree> Snapshot sidebar nodes, current-directory, level
<x-filter-tabs> Events quick-filter tabs tabs, active, base-url
<x-empty-state> Empty table states title, description, icon

Prerequisites

  • PHP 8.2+
  • Composer
  • Node.js 18+ and npm
  • SQLite (PHP extension enabled)

Setup

# 1. Clone the repository
git clone <repository-url>
cd filewatcher

# 2. Install PHP dependencies
composer install

# 3. Configure environment
cp .env.example .env

Edit .env to point to your SQLite database:

DB_CONNECTION=sqlite
DB_DATABASE=C:/path/to/logs/filelog.db
# 4. Generate application key
php artisan key:generate

# 5. Install and build frontend assets
npm install
npm run build

# 6. Start the development server
php artisan serve

Visit http://localhost:8000 — the root URL redirects to /filewatcher/dashboard.


Development

# Start Laravel dev server
php artisan serve

# Watch for frontend changes (Vite HMR)
npm run dev

# Build frontend for production
npm run build

Script Integration

The Laravel UI pairs with a companion Python file watcher available at:

gh repo clone islacchi/Python-File-Watcher

The script:

  1. Monitors a network drive for file system changes using watchdog
  2. Logs CREATED, MODIFIED, DELETED, RENAMED, MOVED, and MOVED_AND_RENAMED events to the SQLite database
  3. Maintains a snapshots table with current file state and MD5 hashes
  4. Writes a heartbeat timestamp to the config table every 30 seconds

The health check endpoint (/filewatcher/health) reads the heartbeat timestamp. If no heartbeat is received within 90 seconds, the UI switches to Offline status and displays a banner. Events logged while offline are stored with an (offline) suffix on the event type and are merged into the canonical type counts throughout the UI.


License

This project is open-sourced software licensed under the MIT license.

About

A read-only Laravel web UI for monitoring file system events on a network drive. Pairs with a Python file watcher script that logs changes to SQLite.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors