Compare commits

..
241 Commits
Author SHA1 Message Date
sbcrumb c983e93a76 fix: Use release dates as dateadded fallback when import dates unavailable
Local Docker Build (Dev) / build-dev (push) Failing after 0s
When Radarr can't provide import/download dates, the system now properly
uses digital release dates, theatrical dates, or air dates as the dateadded
value for both NFO files and database storage.

This fixes the issue where movies would get minimal NFO content with
"no_valid_date_source" when valid release dates were available but not
being saved to the database for future use.

Key changes:
- Use release date as dateadded when import date is None but release date exists
- Ensure all found dates are saved to database for future manual scans
- Maintain proper source tracking for debugging
- Fix NFO files getting minimal content when valid dates exist
2025-09-24 08:31:12 -04:00
jskala 3a31ba8866 Merge pull request 'plugin-update' (#21) from plugin-update into dev
Reviewed-on: jskala/NFOguard#21
2025-09-23 12:17:55 -04:00
sbcrumb 814156035e update: Version bump for emby-plugin 2025-09-23 12:17:55 -04:00
sbcrumb c24625274e docs: Add critical .local directory security reminder
- Emphasize .local/ must NEVER be committed to GitHub
- Document security breach procedures if .local/ exposed publicly
- Reinforce that .local/ contains sensitive development information
- Add warning about privacy violations and Claude attribution details
2025-09-23 12:17:55 -04:00
sbcrumb c2dc0b2beb fix: Clean up commit template
- Remove co-authorship lines from template
- Keep template clean for releases
2025-09-22 14:26:49 -04:00
sbcrumb 3e017a3d17 Merge branch 'main' into dev 2025-09-22 14:23:10 -04:00
sbcrumb 91e749ccdc restore: Add .local development documentation back to Gitea
- Restore .local/ directory with all development documentation
- Files include SUMMARY.md, commit.md, workflow.md, and setup templates
- These files stay local and in Gitea only (excluded from GitHub)
2025-09-22 14:20:22 -04:00
sbcrumb 4d1dc3b06f fix: Configure .local/ directory as Gitea-only (not GitHub)
- Add .local/ to .gitignore to exclude from GitHub releases
- .local/ contains private development documentation and notes
- Files remain available locally and in Gitea for development reference
2025-09-22 13:59:14 -04:00
sbcrumb 41ece0af86 Establish shared history with GitHub main 2025-09-22 12:35:59 -04:00
sbcrumb 1848ed61bf Merge branch 'dev' 2025-09-22 12:24:04 -04:00
sbcrumb c04fe8d083 debug optional 2025-09-22 12:18:40 -04:00
sbcrumb 3e5c80279f fix: nfo logic long vs shortname 2025-09-22 11:02:12 -04:00
sbcrumb de3896b8c3 fix: add debug for .nfo ussues 2025-09-22 10:54:22 -04:00
jskala b1484641d9 fix: update tv .nfo handling
updated TV .nfo handling
2025-09-22 10:52:20 -04:00
sbcrumb 07b3110c72 fix branch issue in workflow 2025-09-22 10:35:05 -04:00
sbcrumb 96de17e0c5 update docker for force build 2025-09-22 10:31:26 -04:00
sbcrumb 7de99ef945 trying to add gitea 2025-09-22 10:12:07 -04:00
sbcrumb 95273be0b0 update flow 2025-09-22 10:07:39 -04:00
sbcrumb a74feeb67e udpates to flow and nfo manager for TV 2025-09-22 10:03:59 -04:00
sbcrumb e7749620f6 better docker handling for shutdown 2025-09-22 09:30:50 -04:00
sbcrumb f563c67405 update sonarr .nfo flow 2025-09-22 09:25:03 -04:00
sbcrumb 93cee77ce0 stop main flow when dev runs 2025-09-22 09:13:08 -04:00
sbcrumb 927d7cdeff another workflow upate local 2025-09-22 09:04:01 -04:00
sbcrumb a4b1042b65 update local workflow 2025-09-22 09:01:21 -04:00
sbcrumb 09b28abcdc make local dir for ignores in local docs 2025-09-22 08:36:46 -04:00
sbcrumb fa3f41e6fd update Dev 2025-09-21 09:32:27 -04:00
sbcrumb b881c7944c initial updates to mirror github files 2025-09-21 09:30:12 -04:00
sbcrumb c6d5d2e6dc updates 2025-09-21 09:28:06 -04:00
sbcrumb 22483717c4 initial update 2025-09-21 09:25:36 -04:00
sbcrumb 49d63a9136 Bump version from 1.6.7 to 1.6.8
MAJOR IMPROVEMENTS:
  • Enhanced movie detection for directories without IMDb IDs in folder names
  • Fixed NFO processing to execute before date validation (preserves existing metadata)
  • Added smart episode NFO migration to standardized S##E## format
  • Resolved database save issues with proper upsert operations for dateadded values
  • Implemented comprehensive IMDb ID detection from filenames and NFO content

  TECHNICAL CHANGES:
  • nfoguard.py:1008-1025 - Fixed early exit logic to process NFOs regardless of date availability
  • core/nfo_manager.py - Added find_existing_episode_nfo() and enhanced episode processing
  • core/database.py - Fixed upsert operations to properly save dateadded values
  • Enhanced find_movie_imdb_id() to detect IMDb IDs from multiple sources

  CORE FIXES:
  • Movie NFO processing now happens before date validation checks
  • Episode NFOs with long names automatically migrated to S##E## format
  • Database operations properly handle both new entries and updates
  • Movies without IMDb in directory names now detected via filenames/NFO content
  • All existing metadata preserved during NFO standardization

  RESULTS:
  ✅ Existing movie.nfo files receive full NFOGuard processing
  ✅ Episode NFOs standardized to proper S##E## naming convention
  ✅ Database persistence works correctly for all date scenarios
  ✅ Enhanced movie detection covers edge cases
  ✅ Maintained backward compatibility with existing configurations
2025-09-21 08:53:58 -04:00
sbcrumb fcc21d8eb7 fix: NFO processing overhaul - comprehensive metadata management
Commit Message:
  fix: NFO processing overhaul - comprehensive metadata management

  MAJOR IMPROVEMENTS:
  • Enhanced movie detection for directories without IMDb IDs in folder names
  • Fixed NFO processing to execute before date validation (preserves existing metadata)
  • Added smart episode NFO migration to standardized S##E## format
  • Resolved database save issues with proper upsert operations for dateadded values
  • Implemented comprehensive IMDb ID detection from filenames and NFO content

  TECHNICAL CHANGES:
  • nfoguard.py:1008-1025 - Fixed early exit logic to process NFOs regardless of date availability
  • core/nfo_manager.py - Added find_existing_episode_nfo() and enhanced episode processing
  • core/database.py - Fixed upsert operations to properly save dateadded values
  • Enhanced find_movie_imdb_id() to detect IMDb IDs from multiple sources

  CORE FIXES:
  • Movie NFO processing now happens before date validation checks
  • Episode NFOs with long names automatically migrated to S##E## format
  • Database operations properly handle both new entries and updates
  • Movies without IMDb in directory names now detected via filenames/NFO content
  • All existing metadata preserved during NFO standardization

  RESULTS:
  ✅ Existing movie.nfo files receive full NFOGuard processing
  ✅ Episode NFOs standardized to proper S##E## naming convention
  ✅ Database persistence works correctly for all date scenarios
  ✅ Enhanced movie detection covers edge cases
  ✅ Maintained backward compatibility with existing configurations
2025-09-21 08:52:41 -04:00
sbcrumb cd22cd3340 feat: enhance NFO processing and movie detection
* fix: NFO processing overhaul - looking GOOD!

  Listen up, buddy! Your boy Cat just made this NFO processing
  smoother than my pompadour on a good hair day!

  WHAT'S THE DEAL?
  • Movie NFOs were getting DISSED when dates went missing
  • Episode NFOs with long names were cluttering up the joint
  • Nobody wants a messy media library - that's just WRONG!

  WHAT I FIXED (because I'm THAT good):
  • Movies: NFO processing now happens FIRST, baby! No more
    skipping when dates are wonky - we standardize EVERYTHING!
  • TV Shows: Long episode NFO names? GONE! We migrate that
    metadata to proper S##E## format and trash the old junk
  • Dates get moved to the bottom where they belong (it's all
    about the STYLE!)
  • NFOGuard signatures added to everything (gotta sign your work!)

  FILES TOUCHED:
  • nfoguard.py:1008-1025 - Fixed that early exit nonsense
  • core/nfo_manager.py - Added find_existing_episode_nfo() function
  • core/nfo_manager.py - Enhanced create_episode_nfo() with migration

  RESULTS:
  ✨ Existing movie.nfo files get the full treatment
  ✨ Long episode NFO names become sleek S##E## format
  ✨ All metadata preserved (we're not ANIMALS!)
  ✨ Dates organized properly at the bottom
  ✨ NFOGuard branding on everything

  This code is now looking SO good, it should be in GQ!
  What's not to like about perfection?

* testing: Testing database date adds for old files

* database debuging

* fixing database calls as well as ID for imdb

* fix: dirs with no imdb in title

movies with no imdb getting skipped

* update: fix core parsing
2025-09-20 20:24:02 -04:00
sbcrumb d5937b13be Docker compose update (#10)
* chore: update docker compose example

update/correct missing emby bind point for .dll
2025-09-19 16:40:23 -04:00
sbcrumb 3abef7057c Delete docker-compose.example
remove old docker-compose example
2025-09-19 16:28:52 -04:00
sbcrumb 31d2c6404a chore: workflow (#7)
* Update release-drafter to use DockerHub instead of GHCR
2025-09-19 15:00:29 -04:00
sbcrumb 5dce72841b chore: update versions 2025-09-19 14:48:30 -04:00
sbcrumb 605e78c093 feat: update/add workflow 2025-09-19 14:42:17 -04:00
sbcrumb 32d614f2f8 Update Emby plugin availability in README
Update readme to remove discord requirement for .dll file
2025-09-19 08:26:40 -04:00
sbcrumb 82310b5f43 feat: adding .dll file to docker image 2025-09-19 08:23:38 -04:00
jskala f5fd954ebb Merge pull request 'feat: add DLL to docker image' (#16) from dev into main
Reviewed-on: jskala/NFOguard#16
2025-09-19 08:18:04 -04:00
sbcrumb 4eeb30a922 chore: update version number 2025-09-19 08:18:04 -04:00
sbcrumb cce9840b10 chore: add DLL to docker image
Added in the Emby DLL file for the project to copy to plugin dir
2025-09-19 08:18:04 -04:00
sbcrumb b1c5c825f8 chore: cleanup old comment lines
clean up older comment lines from old code base.
2025-09-17 21:51:12 -04:00
sbcrumb cbfd21c4ee feat: upload intial code
Uploading intial Project Code
2025-09-17 21:44:30 -04:00
jskala 77b0cdf898 Merge pull request 'fix workflow' (#15) from dev into main
Reviewed-on: jskala/NFOguard#15
2025-09-17 15:47:35 -04:00
sbcrumb 7734377638 fix workflow 2025-09-17 15:44:45 -04:00
sbcrumb 539b09fc5b update to TVDB 2025-09-17 15:32:34 -04:00
sbcrumb 532ea02a5b update to docker 2025-09-17 15:23:29 -04:00
sbcrumb d64228cc82 Add NFO-based identification and smart episode renaming v1.6.0
- Add dual identification system: directory names + NFO file parsing
- Support <uniqueid type="imdb">, <imdbid>, <imdb> XML tags
- Implement smart episode NFO renaming to S##E##.nfo format
- Detect existing Sonarr/other NFO files and preserve metadata
- Add comprehensive Project.md for context recovery
- Update documentation with new capabilities
2025-09-16 21:14:09 -04:00
sbcrumb 86235142a0 Fix Discord link and improve README content
Updated README to enhance clarity and correct links.
2025-09-16 20:42:36 -04:00
sbcrumb 44fdc1cdf0 Update README with alpha notice and Discord link
Added alpha software notice and Discord plugin information to README.
2025-09-16 17:03:46 -04:00
sbcrumb f272baf2a4 Add sample Docker Compose configuration for NFOGuard
This file contains a sample Docker Compose configuration for NFOGuard, including service definitions, environment variables, volume mappings, health checks, and setup instructions.
2025-09-16 17:01:12 -04:00
sbcrumb aae36ac145 Add .env.secrets template for configuration 2025-09-16 16:58:55 -04:00
sbcrumb faa320d299 Clarify Radarr database connection requirements
Updated Radarr database connection comments for clarity and requirements.
2025-09-16 16:56:51 -04:00
sbcrumb fab3da938f Update README.md 2025-09-16 16:49:53 -04:00
sbcrumb 0e9b117ff4 Revise LICENSE with new copyright and terms 2025-09-16 16:47:30 -04:00
sbcrumb cd31caf313 Update download links in README.md 2025-09-16 16:43:10 -04:00
sbcrumb b7d695ab62 Create README.md for NFOGuard project 2025-09-16 16:41:27 -04:00
sbcrumb 2c13fd778a Initial commit 2025-09-16 16:39:22 -04:00
sbcrumb 220ca3ab5f Fix VERSION conflict and add v1.5.5 release notes 2025-09-16 16:08:37 -04:00
sbcrumb 768eb01563 update version number 2025-09-16 16:04:15 -04:00
sbcrumb 722f260726 Fix Docker build with PostgreSQL dependencies 2025-09-16 16:02:23 -04:00
sbcrumb 5e2a3b1aba Fix Docker build with PostgreSQL dependencies 2025-09-16 15:59:13 -04:00
sbcrumb 552addbdb9 Fix docker build missing context 2025-09-16 15:55:36 -04:00
sbcrumb 9df0b969b0 fix python 2025-09-16 15:53:47 -04:00
sbcrumb 571d0400b2 python fix 2025-09-16 15:47:54 -04:00
sbcrumb 339d023b85 update to python 3.13 2025-09-16 15:38:51 -04:00
sbcrumb bc63d6a5a4 git docker hub perm issue 2025-09-16 15:32:17 -04:00
sbcrumb 9e5c6feb47 adding docker workflow 2025-09-16 15:29:22 -04:00
sbcrumb 1353b53cc8 CRITICAL: Fix database upsert bug preventing manual scan date persistence
**Root Cause**: upsert_movie_dates() was UPDATE-only, not proper upsert
- Manual scans failed to save dateadded to database (NULL values)
- Webhooks found database entries but with NULL dateadded
- Fell back to current timestamp instead of using proper import dates

**Database Fix**:
- Changed core/database.py upsert_movie_dates() from UPDATE to INSERT OR REPLACE
- Now properly saves dateadded during manual scans
- Preserves existing path with COALESCE fallback

**Webhook Enhancement**:
- Added comprehensive debug logging for database lookups
- Enhanced webhook date decision logic with proper fallback chain
- Only uses current timestamp as absolute last resort

**Impact**:
- Movies: Manual scans now persist dates, webhooks find existing entries ✅
- TV Shows: Not affected - already using proper INSERT OR REPLACE ✅
- Version: 1.5.5
2025-09-15 12:18:53 -04:00
sbcrumb ed4a9c0a19 Fix Radarr rename event handling - add missing event type filtering
- Add event type filtering to Radarr webhook handler (Download, Upgrade, Rename)
- Ensures consistency with Sonarr webhook processing
- Fixes issue where Radarr rename events weren't properly updating NFO files
- Bump version to v1.5.3
- Update SUMMARY.md with complete webhook workflow documentation
2025-09-15 09:35:41 -04:00
sbcrumb df04cf9aec update 2025-09-15 09:16:28 -04:00
sbcrumb 75b8338b86 remove hardcode debug statments in favor of variables 2025-09-14 14:38:14 -04:00
sbcrumb 1dae7df3d2 updates to paths again 2025-09-14 14:23:25 -04:00
sbcrumb 1a562f7b41 missing path 2025-09-14 14:21:09 -04:00
sbcrumb f5ae8c7768 cleanup 2025-09-14 14:19:39 -04:00
sbcrumb a9c90d2939 remove debug 2025-09-14 14:15:19 -04:00
sbcrumb 2657729975 dates for TV shows 2025-09-14 13:56:31 -04:00
sbcrumb d7db924510 dates at bottom 2025-09-14 13:54:04 -04:00
sbcrumb 179f8f51d7 nfo dates to the bottom 2025-09-14 13:49:15 -04:00
sbcrumb e7b65cfed6 nfo fix again 2025-09-14 13:44:56 -04:00
sbcrumb 49266d651a fix nfo 2025-09-14 13:40:22 -04:00
sbcrumb 05ba16666e another DB table 2025-09-14 13:31:54 -04:00
sbcrumb b1f670415d database fix 2025-09-14 13:29:02 -04:00
sbcrumb 609f17713a fix path mapping wrong with smartstring 2025-09-14 13:25:32 -04:00
sbcrumb d168cc8317 path helper 2025-09-14 13:21:05 -04:00
sbcrumb 7b72d2d20b update DB tables 2025-09-14 13:15:48 -04:00
sbcrumb 04b0202903 removal of hard codeing 2025-09-14 13:13:13 -04:00
sbcrumb c20cefb571 fix hardcoded paths 2025-09-14 13:07:50 -04:00
sbcrumb bbe5f8c892 push updates to paths again 2025-09-14 13:03:41 -04:00
sbcrumb 27cc2f878e update movie paths 2025-09-14 12:56:47 -04:00
jskala ec11a54e02 Merge pull request 'github-claude' (#4) from github-claude into dev
Reviewed-on: jskala/NFOguard#4
2025-09-14 12:51:54 -04:00
sbcrumb ebd1191598 updates to flow 2025-09-14 12:51:15 -04:00
sbcrumb e741e4b046 fix: isolate movie and TV webhook processing to prevent cross-contamination
- Add prefixed batch keys (movie:imdbid, tv:imdbid) to prevent IMDb ID collisions
- Add path existence validation for Radarr webhooks to reject invalid mappings early
- Remove duplicate Radarr webhook handler code
- Add debug scripts for troubleshooting webhook and path mapping issues
- Create corrected .env template with fixed TV_PATHS and SONARR_ROOT_FOLDERS

This fixes the issue where TV path mapping failures caused movie webhooks
to process wrong movies due to shared batch queue corruption.
2025-09-14 12:43:07 -04:00
sbcrumb 91881262ce docs: complete API keys documentation in README.md
Documentation Enhancement:
- Add missing TVDB_API_KEY to all relevant sections in README.md
- Create comprehensive API keys reference table with purposes and sources
- Add centralized API Keys Configuration section with clear examples
- Document how to resolve "TVDB API key not configured" warnings
- Include direct links to obtain API keys from each service

API Keys Covered:
- TMDB_API_KEY - Movie release dates and metadata fallbacks
- TVDB_API_KEY - TV show metadata and Emby compatibility (was missing!)
- RADARR_API_KEY - Movie import history and database access
- SONARR_API_KEY - TV episode import history

This resolves user questions about the TVDB API key warning and provides
complete documentation for all external API integrations.
2025-09-14 12:07:23 -04:00
sbcrumb 5b7d4cdbd0 feat: improve NFO file organization by moving NFOGuard elements to bottom
NFO Organization Enhancement:
- Move all NFOGuard elements (dateadded, lockdata, comments) to bottom of NFO files
- Remove existing NFOGuard elements and re-add at bottom for clean organization
- Provides better separation between media metadata and NFOGuard management
- Easier to read NFO files when Radarr/Sonarr has already populated extensive metadata

Before: NFOGuard elements mixed throughout existing metadata
After: All media metadata first, then NFOGuard elements grouped at bottom

This addresses user feedback about NFO readability when files already contain
extensive metadata from Radarr, making it easier to see both media info and
NFOGuard management details in a logical order.
2025-09-14 11:21:44 -04:00
sbcrumb df5785e8ad feat: MAJOR - implement webhook-first architecture with database priority
Revolutionary Workflow Changes (v0.7.0):
This fundamentally changes how NFOGuard handles timestamps and processing priority.

Webhooks = Source of Truth:
- First webhook fires → Use current timestamp → Store as permanent database entry
- Subsequent webhooks (upgrades) → Check database → Use original first-seen timestamp
- No more API calls during webhook processing → Webhook timing is ultimate authority
- Movies and TV episodes both use webhook-first approach

Manual Scans = Smart Fallback Logic:
- Priority 1: Our database (webhook timestamps) - database always wins
- Priority 2: Sonarr/Radarr import history (first import only)
- Priority 3: Air date as dateadded (final fallback)

Technical Implementation:
- Enhanced _get_webhook_episode_date() to use current timestamp as source of truth
- Added webhook_mode parameter to process_movie() for separate webhook logic
- All manual scans prioritize database entries before making API calls
- All timestamps converted to container timezone (Eastern Time)
- Enhanced debug logging for database lookups and timestamp decisions

Expected Workflow:
First download at 8:30am → webhook timestamp stored in database
Upgrade at 2:00pm → database entry found → original 8:30am timestamp preserved
Manual scan → database entry found → 8:30am timestamp used

This ensures the first-seen webhook timestamp is the permanent source of truth,
with upgrades and manual scans always preserving the original download time.
2025-09-14 10:52:43 -04:00
sbcrumb e188706001 fix: webhook episode processing now uses real Sonarr import history
Critical Fix for Episode Import Dates:
- Webhook episodes now query Sonarr import history instead of using current time
- Fix _get_webhook_episode_date() to follow same logic as manual scans
- Convert import dates from UTC to local timezone for NFO dateadded fields
- Episodes now show 'sonarr:history.import' source instead of 'webhook:new_download'

Before: <dateadded>2025-09-14T12:40:07+00:00</dateadded> (current webhook time)
After:  <dateadded>2025-09-14T08:40:07-04:00</dateadded> (real import time in local timezone)

This fixes the issue where episodes downloaded at 8:40am EST were showing
12:40pm UTC webhook time instead of the actual import timestamp.

Enhanced webhook processing now:
1. Checks database for existing entries (prevents duplicates)
2. Queries Sonarr import history for real import dates
3. Converts UTC import dates to local timezone
4. Only uses current time as last resort for true new downloads
2025-09-14 10:41:43 -04:00
sbcrumb d8754e41a7 fix: NFO timestamp consistency and enhanced episode processing debug
NFO Management Timestamp Fix:
- Fix NFO management comments to use local timezone instead of UTC
- Both movie and TV episode NFO files now show consistent local timezone
- Comments now show: <!-- managed by NFOGuard at 2025-09-14T09:29:06-04:00 -->

Enhanced Episode Processing Debug:
- Add comprehensive debug logging for webhook episode database lookups
- Track IMDb ID and season/episode info throughout processing pipeline
- Add database write verification to catch storage issues immediately
- Enhanced logging will help identify duplicate processing root causes

This addresses the issue where episodes were being treated as new downloads
instead of finding existing database entries, helping prevent duplicate processing.
2025-09-14 10:27:05 -04:00
sbcrumb 7af7b1c43e feat: complete timezone support for NFO dateadded fields
- Fix NFO dateadded timestamps to use local timezone instead of UTC
- Convert Radarr/Sonarr import dates from UTC to local timezone for NFO files
- Update webhook episode processing to use local time for new downloads
- Convert file modification time fallbacks to local timezone
- Preserve historical dates (aired, premiered) in original UTC format
- Replace all placeholder logging functions with centralized timezone-aware logging
- Add convert_utc_to_local() utility function for timestamp conversion
- Now all logs AND NFO files show consistent local timezone formatting

Users with TZ=America/New_York will now see:
- Logs: [2025-09-14T09:37:00-04:00]
- NFO files: <dateadded>2025-09-14T09:37:00-04:00</dateadded>
2025-09-14 09:56:27 -04:00
sbcrumb 5c7300fc74 update: VERSION to v0.6.4 and add development workflow instructions
- Update VERSION file from 0.6.1 to 0.6.4 to match timezone logging release
- Add development workflow instructions to SUMMARY.md for future updates
- Document Claude Code's authority to write commits and push changes
- Establish version consistency requirements across VERSION, SUMMARY.md, and git tags
2025-09-14 09:51:11 -04:00
sbcrumb 17ef94ec4f feat: implement timezone-aware logging system
- Fix inconsistent timestamp formats in logs for easier troubleshooting
- All logging systems now respect Docker TZ environment variable (e.g., TZ=America/New_York)
- Add TimezoneAwareFormatter for Python's standard logging module
- Enhance _log function with robust timezone support and fallbacks
- Replace placeholder logging functions with centralized core.logging._log
- Support both zoneinfo (Python 3.9+) and pytz (older versions)
- Users now see consistent timezone formatting across all log outputs
2025-09-14 09:45:32 -04:00
sbcrumb f4c56f6cbe feat: smart NFO management and correct episode date field mapping
💾 Smart NFO File Management:
- Add intelligent content comparison to prevent unnecessary file overwrites
- Only update NFO files when content actually changes (ignoring timestamp differences)
- Dramatically reduce file system writes and improve scan performance
- Applied to both TV episodes and movies for comprehensive efficiency
- New _nfo_content_matches() method for smart content comparison

🗓️ Fix Episode Date Field Mapping:
- BREAKING: Correct date field usage in episode NFOs
- <aired> and <premiered>: Now use historical air dates (e.g., 1951-10-15)
- <dateadded>: Correctly shows actual download/import date (e.g., 2025-09-13)
- Resolves confusion between when show aired vs when user downloaded it
- Media servers now show historically accurate metadata with working "Recently Added"

🎯 Technical Changes:
- Enhanced create_episode_nfo() with content comparison logic
- Enhanced create_movie_nfo() with content comparison logic
- Separated historical date logic from import date logic
- Added comprehensive debug logging for file skip/update decisions

🏆 User Experience:
- Faster scans with fewer unnecessary file operations
- Correct historical context in media servers
- "Recently Added" functionality preserved and working
- No more metadata confusion between air dates and import dates

Example NFO output:
- <aired>1951-10-15</aired> (historical)
- <dateadded>2025-09-13T21:39:28+00:00</dateadded> (when downloaded)
- <premiered>1951-10-15</premiered> (historical)
2025-09-13 19:52:43 -04:00
sbcrumb 2d89e87191 feat: revolutionize TV episode date handling for webhook processing
🎯 Problem Fixed:
- TV episodes downloaded today showed historical air dates (1951) as dateadded
- Episodes appeared as old content instead of "recently added" in media servers
- Incorrect fallback logic used air dates instead of actual download times

⚡ Revolutionary Changes:
- Webhook-first processing: When Sonarr webhook fires → use current timestamp
- Database priority: Existing NFOguard entries preserved (no re-processing)
- Smart backfill: Manual scans check Sonarr import history first
- Clear separation: Webhook vs backfill use different logic paths

🔧 Technical Implementation:
- New method: _get_webhook_episode_date() for webhook-specific handling
- Enhanced method: _get_single_episode_date() for proper backfill priority
- Database-first approach: Always check NFOguard DB before external APIs

📋 Correct Processing Flow:
1. New episode download → Sonarr webhook → current time as dateadded
2. Re-download same episode → use existing stored date (preserve original)
3. Backfill scan → NFOguard DB → Sonarr history → air dates (last resort)
4. No bulk import - database populated through webhooks and manual scans

🏆 Results:
- Episodes downloaded today now show today's date as dateadded
- Historical air dates preserved in aired field for accuracy
- "Recently Added" functionality restored in media servers
- No regression for existing properly-dated episodes

🐛 Bug Fixes:
- Fixed f-string syntax error in core/nfo_manager.py:324
- Resolved backslash escaping issue preventing startup
2025-09-13 19:49:39 -04:00
sbcrumb f998a64cdb update f string 2025-09-13 19:23:16 -04:00
sbcrumb 1bf2725a5b iupdate 2025-09-13 19:15:22 -04:00
sbcrumb e3038ee279 updates to summarty 2025-09-12 15:59:42 -04:00
sbcrumb c6e4e071e4 cleanup 2025-09-12 15:46:02 -04:00
sbcrumb 558a786bdb chore:file cleanup 2025-09-12 15:41:56 -04:00
sbcrumb 4ef28c3021 updates 2025-09-12 13:54:29 -04:00
sbcrumb 77295cc400 various NFOguard versions 2025-09-12 10:30:12 -04:00
sbcrumb 08cddf7799 dll integration 2025-09-12 09:04:23 -04:00
sbcrumb dcbb25ca9e Fix Emby TV episode date handling by using <aired> field for import dates
- Issue: Emby displays DateCreated field which gets updated on metadata refresh
- Root cause: Emby ignores <dateadded> but reads <aired> for TV episodes
- Solution: Write import date to <aired> field instead of actual air date
- Emby will now display import date (Feb 19) instead of scan date (Sep 11)
- Maintains backward compatibility with fallback to actual air date
2025-09-11 16:45:36 -04:00
sbcrumb 8674b60c85 Fix CI pipeline docker history command failure
🔧 Pipeline Fix:
• Added error handling for docker history command that was failing
• Exit status 141 (SIGPIPE) from head command causing pipeline failure
• Build was actually successful, just diagnostic command failing

✅ Changes:
• Wrapped docker history in proper error handling
• Pipeline will continue even if history display fails
• Build success is preserved regardless of diagnostic command issues

🎯 Root Cause:
• Permission issue with Docker config file loading
• SIGPIPE when head command terminates docker history output
• Non-critical diagnostic causing critical failure
2025-09-11 11:37:55 -04:00
sbcrumb 86d2cee1f9 Complete TV webhook processing modes documentation update
📚 Comprehensive Documentation Update:
• Added TV webhook processing modes section to README.md
• Updated CHANGELOG.md with configurable processing feature details
• Enhanced SETUP.md with TV_WEBHOOK_PROCESSING_MODE configuration
• Added Step 7 testing procedures to TESTING.md for both modes

🔧 Configuration Documentation:
• Targeted Mode (default): Only process episodes mentioned in webhook
• Series Mode: Process entire series directory (legacy behavior)
• Smart fallback logic when episode data unavailable
• Clear examples and use case recommendations

📋 Testing Instructions:
• Step-by-step mode switching procedures
• Expected log output examples for each mode
• Environment variable configuration examples
• Docker restart procedures for testing

✨ User Benefits Documented:
• Efficiency comparison: targeted vs series processing
• File operation reduction for targeted mode
• Media server notification minimization
• Backward compatibility with existing setups
2025-09-11 11:26:39 -04:00
sbcrumb ac2753509d Add configurable TV webhook processing modes (targeted vs series)
⚙️ New Configuration Option:
• Added TV_WEBHOOK_PROCESSING_MODE environment variable
• targeted = Only process episodes mentioned in webhook (efficient, default)
• series = Process entire series directory (comprehensive, previous behavior)

🎯 Targeted Episode Processing:
• New process_webhook_episodes() method for precise processing
• Only updates NFOs for downloaded episodes (e.g., just S41E07)
• Reduces unnecessary file operations and Emby notifications
• Falls back to series processing if no episode data in webhook

🔧 Implementation Details:
• Modified Sonarr webhook handler to pass episode data
• Enhanced batch processor with mode detection
• Maintains backward compatibility with existing behavior
• Added comprehensive logging for processing mode selection

✨ Benefits:
• Efficient: 1 download = 1 episode processed (not entire series)
• Configurable: Users can choose preferred behavior via .env
• Compatible: Works with existing autoscan/Emby refresh systems
• Smart: Falls back gracefully when episode data unavailable
2025-09-11 11:22:36 -04:00
sbcrumb 01cd31505a Complete v0.6.0 documentation update and review
📚 Documentation Updates:
• Updated CHANGELOG.md with comprehensive v0.6.0 feature list
• Enhanced README.md with new TV processing endpoints and examples
• Updated SETUP.md with required Sonarr API key configuration
• Enhanced TESTING.md with v0.6.0 TV testing procedures
• Updated .env templates with proper Sonarr requirements

🔧 Configuration Updates:
• Mark SONARR_API_KEY as REQUIRED for v0.6.0+ Enhanced TV NFOs
• Updated version examples from 0.5.1 to 0.6.0
• Added JSON response examples for new TV endpoints
• Clarified URL-safe vs URL-encoded endpoint options

📋 Complete File Review:
• Verified all Python imports are consistent across modules
• Confirmed all typing imports (Dict, Any, List, Optional) are present
• Validated configuration templates match actual requirements
• Added comprehensive testing procedures for TV enhancements

✅ Ready for Production:
• All endpoints documented with examples
• Configuration requirements clearly specified
• Testing procedures comprehensive for troubleshooting
• Backward compatibility maintained throughout
2025-09-11 10:10:05 -04:00
sbcrumb 52fa0b6060 Add missing get_episode_date method and bump version to v0.6.0
🐛 Database Fix:
• Add missing get_episode_date() method to NFOGuardDatabase
• Fixes: 'NFOGuardDatabase' object has no attribute 'get_episode_date'

🔄 Version Update:
• Bump VERSION from 0.2.22 to 0.6.0
• Major feature release with comprehensive TV enhancements

✅ Now Works:
• Single season processing via /tv/scan-season
• Single episode processing via /tv/scan-episode
• Enhanced NFO generation with Sonarr API metadata
• Database queries for existing episode dates
2025-09-11 09:59:15 -04:00
sbcrumb 03bdf2bf9f Fix TV endpoints to use proper JSON request models
🐛 API Fix:
• Add TVSeasonRequest and TVEpisodeRequest Pydantic models
• Update /tv/scan-season and /tv/scan-episode to accept JSON body
• Fix query parameter validation errors

✅ Now Works:
• curl -X POST "/tv/scan-season" -H "Content-Type: application/json" -d '{...}'
• curl -X POST "/tv/scan-episode" -H "Content-Type: application/json" -d '{...}'
2025-09-11 09:52:26 -04:00
sbcrumb aff6179ddb Fix missing typing imports in NFOManager
🐛 Fix:
• Add missing Dict, Any imports from typing module
• Resolves NameError: name 'Dict' is not defined
2025-09-11 09:46:23 -04:00
sbcrumb c705fb4d6d Add comprehensive TV show enhancements and URL-safe endpoints
✨ Features Added:
• Single season/episode processing capability via new endpoints
• Enhanced NFO generation with full Sonarr API metadata (titles, plots, ratings)
• NFOGuard timestamp tracking in all NFO source comments
• URL-safe /tv/scan-season and /tv/scan-episode endpoints

🔧 Technical Improvements:
• Fixed URL encoding issues for paths with spaces and special characters
• Enhanced TVProcessor with process_season() and process_episode_file() methods
• Rich metadata extraction from Sonarr API (episode titles, plots, runtime, ratings)
• XML escaping for special characters in metadata
• Comprehensive episode parsing (SxxExx and numeric formats)

📚 Documentation:
• Updated README with new TV processing endpoints
• Added enhanced NFO generation examples showing before/after
• Documented URL-safe alternatives to manual scan paths

🎯 User Benefits:
• Can now process single seasons: Chicago Fire Season 13
• Can now process single episodes: S13E21 files
• Enhanced NFO files with full episode metadata for better Emby/Plex experience
• Timestamps show when NFOGuard processed each file
2025-09-11 09:39:42 -04:00
sbcrumb c7c783570c Add configurable TMDB release type priority system
- Added TMDB_TYPE_PRIORITY environment variable for user-configurable release type preferences
- Default priority: 4,5,3,2,6,1 (Digital → Physical → Theatrical → Limited → TV → Premiere)
- Replaces random first-available selection with intelligent priority-based selection
- Enhanced logging shows selected type and full priority order
- Users can customize priority based on their preferences (e.g. theatrical first)

Version bumped to 0.2.22
2025-09-10 10:17:07 -04:00
sbcrumb 192f59e80c Document comprehensive date selection priority system in README
- Added detailed explanation of 4-tier fallback hierarchy
- Documents all TMDB release types (1-6) with clear descriptions
- Explains rename-first detection and Radarr NFO fallback logic
- Shows difference between import_then_digital vs digital_then_import priorities
- Version bumped to 0.2.21
2025-09-10 10:07:23 -04:00
sbcrumb 5df4db5878 Comprehensive fallback enhancement: Accept any TMDB type + Radarr NFO premiered dates
- TMDB now accepts ANY release type (1-6+) for maximum coverage
- Added Radarr NFO <premiered> date extraction as additional fallback
- For rename-first movies: Import → Any TMDB → Radarr NFO → File dates
- Much more aggressive about using ANY reasonable date over bad file dates
- Covers edge cases where TMDB has unusual release types

Version bumped to 0.2.20
2025-09-10 10:01:20 -04:00
sbcrumb c778cc18eb Add TMDB Type 2 (Limited theatrical) support for modern movies
- Enhanced digital release detection to accept Type 2 (Limited theatrical) dates
- Fixes "To Catch a Killer (2023)" and similar movies that only have festival/limited releases
- Better coverage for modern movies that premiere at film festivals before wide release
- Type 2 dates are better than bad file modification dates for rename-first scenarios

Version bumped to 0.2.19
2025-09-10 09:58:19 -04:00
sbcrumb 6bd7297c37 Add TMDB Type 6 (TV premiere) support for older movies and TV specials
- Enhanced digital release detection to also accept Type 6 (TV premiere) dates
- Fixes issue with 1966 "How the Grinch Stole Christmas!" and similar TV specials
- Detailed debugging revealed Type 6 was available but not being used
- Now properly handles older content that premiered on TV rather than theaters

Version bumped to 0.2.18
2025-09-10 09:29:07 -04:00
sbcrumb 23a71e066d Fix TMDB country configuration and add comprehensive API debugging
- Fixed ExternalClientManager to properly use TMDB_COUNTRY environment variable
- Added detailed TMDB API call logging to debug why external clients return None
- Will show available countries, release types, and specific API responses
- Should resolve the "no_valid_date_source" issue for rename-first movies

Version bumped to 0.2.17
2025-09-10 09:22:17 -04:00
sbcrumb c857a61d0b Bump version to 0.2.16 for TMDB debugging release
- Updated version for enhanced TMDB API debugging
- Container rebuild needed to see new diagnostic logs
- Will help identify TMDB API key and external client issues
2025-09-10 09:15:37 -04:00
sbcrumb 47a2286953 Add detailed logging to debug TMDB API fallback issues
- Enhanced _get_digital_release_date with comprehensive logging
- Added external clients configuration check in debug endpoint
- Will show if TMDB API key is configured and external clients initialized
- Added error handling for external client calls
2025-09-10 09:13:12 -04:00
sbcrumb f586185a4f Fix debug endpoint to use global movie_processor instance
- Corrected debug endpoint to use global movie_processor variable
- Was incorrectly trying to access batcher.movie_processor (doesn't exist)
- Now properly tests full TMDB fallback pipeline for rename-first movies
2025-09-10 09:08:09 -04:00
sbcrumb fc983ed472 Fix private repo authentication and enhance debug endpoint
- Add authentication to git clone commands in CI workflows for private repo support
- Enhanced debug endpoint to test FULL movie processing pipeline (not just database)
- Debug now shows both database result AND final TMDB fallback decision
- Will reveal if TMDB API calls are working correctly for rename-first scenarios
2025-09-10 09:04:26 -04:00
sbcrumb bf7fb27fdb Fix dev workflow hanging and implement runtime branch detection
- Fix duplicate Dockerfile sections that were causing build hangs
- Replace complex build args with simple runtime git branch detection
- Revert CI workflows to working state (remove build args and debug code)
- Add automatic version tagging: dev branch shows "0.2.15-dev"
- Enhanced movie fallback logic for rename-first scenarios
- Improved logging to trace movie date decision process
2025-09-10 08:54:47 -04:00
sbcrumb 6f356b1942 versions 2025-09-10 08:29:04 -04:00
sbcrumb 4e786d775b Add configurable TV season directory naming
Features:
- TV_SEASON_DIR_FORMAT: Configurable season folder creation (Season {season:02d})
- TV_SEASON_DIR_PATTERN: Configurable season folder detection (season )
- Support for different naming conventions (Season 01, S01, Season01, etc.)
- Updated .env.template with TV configuration examples

Fixes hardcoded 'Season ' patterns for better flexibility
2025-09-09 20:25:03 -04:00
sbcrumb 4f12d77d98 Fix CI pipe error in docker history command
- Add fallback to prevent exit 141 from broken pipe
- Build succeeded, just a minor display issue
2025-09-09 20:15:12 -04:00
sbcrumb 6ce4db099a Create dev branch with dedicated CI workflow
- Add ci-dev.yml for dev branch builds
- Builds to nfoguard:dev tags (separate from main)
- Independent cache: dev-buildcache
- Separate deployment flow
- Updated main CI to ignore dev branch

Usage: docker pull 192.168.253.221:3000/jskala/nfoguard:dev
2025-09-09 20:14:06 -04:00
sbcrumb 49e2ec6c88 Fix EventType detection: movieFileRenamed is 8, not 7
Found via database inspection:
- The Matrix first event: EventType 8 (movieFileRenamed)
- Followed by EventType 3 (downloadFolderImported) upgrade
- Was checking for EventType 7, should be EventType 8

This should now correctly detect rename-first scenarios
and prefer digital release dates over upgrade dates.
2025-09-09 18:28:40 -04:00
sbcrumb 6f04031e33 Add debug logging to diagnose Matrix history issue
- Show first 3 events in movie history
- Log event types to identify if first event is rename (Type 7)
- Debug why Matrix (tt0133093) not detecting rename-first pattern
2025-09-09 18:02:33 -04:00
sbcrumb f1814abdcd cahce 2 2025-09-09 17:25:39 -04:00
sbcrumb af94337ad0 build cache 2025-09-09 17:24:33 -04:00
sbcrumb 2198d796b9 fix order 2025-09-09 17:20:33 -04:00
sbcrumb afe93b4a8a imdb updates 2025-09-09 17:13:14 -04:00
sbcrumb 8be7452f0e iupdate 2025-09-09 17:04:59 -04:00
sbcrumb 53f3f7f2f0 Clean up temporary troubleshooting files 2025-09-09 16:56:14 -04:00
sbcrumb 740aa9036b all local 2025-09-09 16:45:02 -04:00
sbcrumb 41ef3d80c8 smaller image 2025-09-09 16:43:47 -04:00
sbcrumb c1e1a0529e updates AGAIN 2025-09-09 16:40:57 -04:00
sbcrumb d59df0f2c9 local 2025-09-09 16:39:33 -04:00
sbcrumb ba7d6c3620 up 2025-09-09 16:37:49 -04:00
sbcrumb db7d63fe15 fix docker 2025-09-09 16:36:06 -04:00
sbcrumb 51e63ae71b remove https 2025-09-09 16:34:41 -04:00
sbcrumb 27cb38c3bb git updates 2025-09-09 16:26:07 -04:00
sbcrumb f29d060d59 docker reg update 2025-09-09 16:19:53 -04:00
sbcrumb 8aeef814b0 push 2025-09-09 16:12:24 -04:00
sbcrumb 9d3d798055 update again sudo 2025-09-09 16:09:11 -04:00
sbcrumb 626f9bd86e update docker flow to local reg 2025-09-09 16:07:16 -04:00
sbcrumb 39073dcb70 workflow changes chat 2025-09-09 16:00:36 -04:00
sbcrumb c0dd5df45d update no sudo 2025-09-09 15:45:36 -04:00
sbcrumb 07719b7cf3 update workflow to temp 2025-09-09 15:44:09 -04:00
sbcrumb 59ffeb46fb update workflow username 2025-09-09 15:42:46 -04:00
sbcrumb 9755bd87b2 push to registry 2025-09-09 15:18:58 -04:00
sbcrumb f8f5f95a34 update docker file 2025-09-09 15:07:53 -04:00
sbcrumb 679d2facae update docker 2025-09-09 15:04:51 -04:00
sbcrumb 00127fbd98 update 2025-09-09 15:02:48 -04:00
sbcrumb 10c1d3c4fe remove old gitflow 2025-09-09 14:58:45 -04:00
sbcrumb 58f83a8523 install nodejs 2025-09-09 14:57:58 -04:00
sbcrumb 0dcd132355 Remove GitHub workflows - migrated to Gitea 2025-09-09 14:57:38 -04:00
sbcrumb ac5bbfdc79 workflow updates for backend 2025-09-09 14:53:56 -04:00
sbcrumb 9ae77cae5e workflow updates 2025-09-09 14:52:08 -04:00
sbcrumb 9342261c7d runner setup 2025-09-09 14:49:45 -04:00
sbcrumb 13fedd6fe0 Migrate workflows from .github to .gitea 2025-09-09 14:45:54 -04:00
sbcrumb 15a2427a25 update readme 2025-09-09 11:12:01 -04:00
sbcrumb 4a9aecbc22 updates 2025-09-09 10:59:45 -04:00
sbcrumb 49a2c1788a adding docker example updates 2025-09-09 10:44:35 -04:00
sbcrumb 4685c970af add api secrets seperate from .env 2025-09-09 10:20:46 -04:00
sbcrumb b2938758e2 fix file date release to option not required 2025-09-09 10:03:54 -04:00
sbcrumb 0aa9655d25 digital logic updates 2025-09-09 09:52:55 -04:00
sbcrumb d75016bbf2 tmdb debuging 2025-09-09 09:39:43 -04:00
sbcrumb fed82a9e13 digital release logic 2025-09-09 09:30:20 -04:00
sbcrumb bbbf4b63cc digital release date 2025-09-09 09:18:33 -04:00
sbcrumb 149bf9acd3 added back tmdb 2025-09-09 08:55:02 -04:00
sbcrumb dd215d2f38 db updates 2025-09-09 08:50:21 -04:00
sbcrumb 9fcf5d8303 bulk update 2025-09-09 08:36:25 -04:00
sbcrumb f851e817d9 update db 2025-09-08 18:05:05 -04:00
sbcrumb 19b40c0fd5 update to db call 2025-09-08 18:00:50 -04:00
sbcrumb 935307a74d update to database only 2025-09-08 17:56:43 -04:00
sbcrumb 6f47df201d db error 2025-09-08 17:45:06 -04:00
sbcrumb e618b71620 updates again 2025-09-08 17:42:02 -04:00
sbcrumb 678f84b6ef c4-rdarr db updates 2025-09-08 17:33:41 -04:00
sbcrumb 0def0e33af fix(radarr): improve event type parsing and grab event validation
- Fix string-based event type parsing (grabbed, downloadFolderImported, etc.)
- Filter grab events to only count actual downloads with metadata
- Fix JSON parsing errors for dict-type event data
- Enhanced chronological processing for accurate import date detection
- Validate grab events require sourceTitle or indexer info

Fixes issue where library addition events were mistaken for download grabs,
ensuring only real download timestamps are used for
2025-09-08 15:43:04 -04:00
sbcrumb 65794ae038 fix looking at radarr in a string and us eventid 2025-09-08 15:35:33 -04:00
sbcrumb cd77065a0f update logs and try statments 2025-09-08 15:29:30 -04:00
sbcrumb e389893e14 use date earliest 2025-09-08 15:14:32 -04:00
sbcrumb 7dbe014f03 update path maps 2025-09-08 15:08:01 -04:00
sbcrumb 4e4ddbf92a updates to api and logging 2025-09-08 15:04:20 -04:00
sbcrumb e40e80bfb5 updates to api calls 2025-09-08 14:50:03 -04:00
sbcrumb 157ba581b7 new event ID lookup 2025-09-08 14:38:17 -04:00
sbcrumb 134fb0c5c3 feat: Track grab dates as fallback when no imports found 2025-09-08 13:34:48 -04:00
sbcrumb 8702c9556d feat: Improved import detection and reduced debug noise 2025-09-08 13:25:17 -04:00
sbcrumb 900da1ba4f feat: Enhanced Radarr import detection with flexible path matching and improved logging 2025-09-08 12:18:53 -04:00
sbcrumb 6e3651ca39 feat: Enhanced Radarr import detection with flexible path matching 2025-09-08 12:16:59 -04:00
sbcrumb 78f73845fd better radarr debug 2025-09-08 12:14:51 -04:00
sbcrumb 38bcb9cf28 api radarr debugs 2025-09-08 12:14:04 -04:00
sbcrumb 78c09e3b13 running down radarr API issues 2025-09-08 12:06:01 -04:00
sbcrumb e4da166300 radarr updates 2025-09-08 11:49:18 -04:00
sbcrumb e89eb73bb4 radarr api issues again 2025-09-08 11:41:30 -04:00
sbcrumb 1ea7edeefa more api radarr changes 2025-09-08 11:33:39 -04:00
sbcrumb 946b024fd3 more radarr debugs 2025-09-08 11:20:00 -04:00
sbcrumb 75bf1b470e api update 2025-09-08 11:06:56 -04:00
sbcrumb 932db05646 another api debug 2025-09-08 10:58:29 -04:00
sbcrumb 282717314a api updates 2025-09-08 10:55:03 -04:00
sbcrumb af6e5b5ad1 added radarr debug dates 2025-09-08 10:38:16 -04:00
sbcrumb f942b4c253 radarr date troubshooting 2025-09-08 10:29:28 -04:00
sbcrumb 5cc237461c updates for debug scan 2025-09-08 10:21:38 -04:00
sbcrumb 5537b3b158 update missing module 2025-09-08 10:10:42 -04:00
sbcrumb f73875acdd refactor 2025-09-08 10:05:04 -04:00
sbcrumb e6d65c4982 another radarr fix 2025-09-08 09:23:27 -04:00
sbcrumb ee7525625c radarr updates 2025-09-08 09:13:22 -04:00
sbcrumb 71250c9ddb updates to radarr 2025-09-08 09:05:52 -04:00
sbcrumb d8f304c352 updates 2025-09-08 08:57:29 -04:00
sbcrumb c3d1f50cfb update 2025-09-07 21:13:46 -04:00
sbcrumb 085e43a37b update 2025-09-07 20:58:02 -04:00
sbcrumb d3d7e268e5 add loggin 2025-09-07 13:45:11 -04:00
sbcrumb 87e05a363d fix: prever TMDB over radarr for release date fallbacks 2025-09-07 13:17:16 -04:00
sbcrumb 92dc1c24de ifix dates 2025-09-07 13:11:35 -04:00
sbcrumb edf292211e dates 2025-09-07 12:57:52 -04:00
sbcrumb aef482506e fix 2025-09-07 12:44:01 -04:00
sbcrumb 3e8774b285 fix: dat 2025-09-07 12:34:49 -04:00
sbcrumb 5274c06223 fix: date issues 2025-09-07 12:28:06 -04:00
sbcrumb 8942c7426f chre:fix date issues 2025-09-07 12:18:33 -04:00
sbcrumb 5866713e1b chore:fix radarr date issue 2025-09-07 12:14:01 -04:00
sbcrumb 4680448b89 chore: update date handling in radarr 2025-09-07 11:55:50 -04:00
sbcrumb f9422c7202 update media cachce and version 2025-09-07 11:33:30 -04:00
sbcrumb e84d3fd64e update media cache again 2025-09-07 11:33:30 -04:00
sbcrumb ae1b0e2e06 workflow setup 2025-09-07 11:30:30 -04:00
sbcrumb 1d780d74bc Create VERSION 2025-09-07 11:17:49 -04:00
sbcrumb 5782b3970d feat: intial commits 2025-09-07 11:16:15 -04:00
sbcrumb 51b263ffe7 update webhook 2025-08-30 10:56:26 -04:00
sbcrumb 7b1c694f82 Intial push 2025-08-30 10:49:21 -04:00
sbcrumb 8f3bf42917 Workflow 2025-08-30 10:38:51 -04:00
sbcrumb 6afe5947e8 Initial commit 2025-08-29 16:16:52 -04:00
7 changed files with 47 additions and 733 deletions

No files matched your search

+8 -8
View File
@@ -21,7 +21,7 @@ jobs:
# Clone the repository since Gitea runner doesn't auto-checkout
echo "Cloning repository..."
git clone --branch dev http://${{ secrets.username }}:${{ secrets.token }}@192.168.253.221:3000/sbcrumb/nfoguard.git /tmp/repo
git clone --branch dev http://${{ secrets.username }}:${{ secrets.token }}@192.168.253.221:3000/jskala/NFOguard.git /tmp/repo
cp -r /tmp/repo/* .
cp -r /tmp/repo/.* . 2>/dev/null || true
rm -rf /tmp/repo
@@ -67,7 +67,7 @@ jobs:
run: |
echo "Building DEV Docker image with layer caching..."
LOCAL_REGISTRY="192.168.253.221:3000"
CACHE_IMAGE="$LOCAL_REGISTRY/sbcrumb/nfoguard:dev-buildcache"
CACHE_IMAGE="$LOCAL_REGISTRY/jskala/nfoguard:dev-buildcache"
# Clear any existing Docker configs to prevent permission issues
unset DOCKER_CONFIG
@@ -80,7 +80,7 @@ jobs:
# Check if DEV cache image exists and pull it
echo "Checking for existing DEV cache image..."
CACHE_ARGS=""
if curl -s "http://$LOCAL_REGISTRY/v2/sbcrumb/nfoguard/manifests/dev-buildcache" > /dev/null 2>&1; then
if curl -s "http://$LOCAL_REGISTRY/v2/jskala/nfoguard/manifests/dev-buildcache" > /dev/null 2>&1; then
echo "✅ DEV cache manifest found, pulling image..."
if docker pull "$CACHE_IMAGE" 2>/dev/null; then
echo "✅ DEV cache image pulled successfully"
@@ -119,18 +119,18 @@ jobs:
echo "✅ DEV Login succeeded"
# Tag for local registry
docker tag nfoguard:dev "$LOCAL_REGISTRY/sbcrumb/nfoguard:dev"
docker tag nfoguard:dev "$LOCAL_REGISTRY/sbcrumb/nfoguard:dev-${{ github.sha }}"
docker tag nfoguard:dev "$LOCAL_REGISTRY/jskala/nfoguard:dev"
docker tag nfoguard:dev "$LOCAL_REGISTRY/jskala/nfoguard:dev-${{ github.sha }}"
# Push DEV images
echo "=== Pushing DEV cache image ==="
timeout 60 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/sbcrumb/nfoguard:dev-buildcache" && echo "✅ DEV cache pushed" || echo "⚠️ DEV cache push failed"
timeout 60 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/jskala/nfoguard:dev-buildcache" && echo "✅ DEV cache pushed" || echo "⚠️ DEV cache push failed"
echo "=== Pushing DEV latest tag ==="
if timeout 120 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/sbcrumb/nfoguard:dev"; then
if timeout 120 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/jskala/nfoguard:dev"; then
echo "✅ DEV tag pushed successfully"
if timeout 60 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/sbcrumb/nfoguard:dev-${{ github.sha }}"; then
if timeout 60 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/jskala/nfoguard:dev-${{ github.sha }}"; then
echo "✅ DEV SHA tag pushed successfully"
fi
fi
+9 -9
View File
@@ -21,7 +21,7 @@ jobs:
# Clone the repository since Gitea runner doesn't auto-checkout
echo "Cloning repository..."
git clone --branch main http://${{ secrets.username }}:${{ secrets.token }}@192.168.253.221:3000/sbcrumb/nfoguard.git /tmp/repo
git clone --branch main http://${{ secrets.username }}:${{ secrets.token }}@192.168.253.221:3000/jskala/NFOguard.git /tmp/repo
cp -r /tmp/repo/* .
cp -r /tmp/repo/.* . 2>/dev/null || true
rm -rf /tmp/repo
@@ -70,7 +70,7 @@ jobs:
run: |
echo "Building Docker image with layer caching..."
LOCAL_REGISTRY="192.168.253.221:3000"
CACHE_IMAGE="$LOCAL_REGISTRY/sbcrumb/nfoguard:buildcache"
CACHE_IMAGE="$LOCAL_REGISTRY/jskala/nfoguard:buildcache"
# Clear any existing Docker configs to prevent permission issues
unset DOCKER_CONFIG
@@ -83,7 +83,7 @@ jobs:
# Check if cache image exists and pull it
echo "Checking for existing cache image..."
CACHE_ARGS=""
if curl -s "http://$LOCAL_REGISTRY/v2/sbcrumb/nfoguard/manifests/buildcache" > /dev/null 2>&1; then
if curl -s "http://$LOCAL_REGISTRY/v2/jskala/nfoguard/manifests/buildcache" > /dev/null 2>&1; then
echo "✅ Cache manifest found, pulling image..."
if docker pull "$CACHE_IMAGE" 2>/dev/null; then
echo "✅ Cache image pulled successfully"
@@ -141,21 +141,21 @@ jobs:
echo "✅ Login succeeded with direct method"
# Tag for local registry (cache image already tagged in build step)
docker tag nfoguard:latest "$LOCAL_REGISTRY/sbcrumb/nfoguard:latest"
docker tag nfoguard:latest "$LOCAL_REGISTRY/sbcrumb/nfoguard:${{ github.sha }}"
docker tag nfoguard:latest "$LOCAL_REGISTRY/jskala/nfoguard:latest"
docker tag nfoguard:latest "$LOCAL_REGISTRY/jskala/nfoguard:${{ github.sha }}"
echo "Pushing to LOCAL registry (gigabit speed!)..."
# Push with reasonable timeout for local network
echo "=== Pushing cache image (for faster future builds) ==="
timeout 60 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/sbcrumb/nfoguard:buildcache" && echo "✅ Cache image pushed" || echo "⚠️ Cache push failed"
timeout 60 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/jskala/nfoguard:buildcache" && echo "✅ Cache image pushed" || echo "⚠️ Cache push failed"
echo "=== Pushing latest tag to LOCAL IP ==="
if timeout 120 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/sbcrumb/nfoguard:latest"; then
if timeout 120 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/jskala/nfoguard:latest"; then
echo "✅ Latest tag pushed successfully to LOCAL registry"
echo "=== Pushing SHA tag to LOCAL IP ==="
if timeout 60 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/sbcrumb/nfoguard:${{ github.sha }}"; then
if timeout 60 docker --config $DOCKER_CONFIG push "$LOCAL_REGISTRY/jskala/nfoguard:${{ github.sha }}"; then
echo "✅ SHA tag pushed successfully to LOCAL registry"
else
echo "⚠️ SHA tag push failed but latest succeeded"
@@ -186,7 +186,7 @@ jobs:
echo "📦 Available images:"
echo " Local Docker: nfoguard:latest"
echo " Local SHA: nfoguard:${{ github.sha }}"
echo " Local Gitea: 192.168.253.221:3000/sbcrumb/nfoguard:latest"
echo " Local Gitea: 192.168.253.221:3000/jskala/nfoguard:latest"
deploy:
needs: build
+13 -104
View File
@@ -31,113 +31,22 @@
- **AUTOMATED**: Release drafter creates releases with Docker Hub links
- **VERSIONING**: Fixed version mismatches between workflows
## ✅ FINAL PRIVACY BREACH RESOLVED (September 23, 2025)
## ⚠️ CRITICAL ISSUE DISCOVERED
### 🚨 Attribution Issue Discovered & Fixed
User discovered I was still appearing as GitHub contributor despite repository recreation:
### 🔴 Missing Code from Repository Refresh
When we recreated the GitHub repository to eliminate Claude attribution, we lost today's actual development work:
**ROOT CAUSE:**
- Two commits (`cb875d6` and `a0298ab`) had "jskala" as author/committer
- These commits were pushed to GitHub during sync, making personal name visible
- Original sync script only filtered commit messages, not author information
**MISSING NFO FIXES:**
- NFO long name vs short name logic fixes
- Smart episode NFO renaming improvements
- Directory identification enhancements
- Database upsert bug fixes
- All the actual code improvements from today
**COMPLETE SOLUTION IMPLEMENTED:**
- ✅ **Enhanced sync script** - Now uses `git filter-branch --env-filter` to rewrite author/committer names
- ✅ **Pre-commit hooks** - Block commits with jskala/Claude identity at commit time
- ✅ **Commit-msg hooks** - Strip AI attribution from commit messages automatically
- ✅ **Git identity protection** - Repository configured to use SBCrumb identity only
- ✅ **Complete GitHub cleanup** - All 220 commits rewritten with SBCrumb authorship
- ✅ **Prevention measures** - Multiple layers prevent future attribution issues
**VERIFICATION COMPLETED:**
- GitHub now shows 100% SBCrumb authorship (0 jskala, 0 Claude references)
- Pre-commit hook successfully blocks personal identity attempts
- Sync script automatically cleans any problematic commits before GitHub push
- All privacy protection working as intended
## 🚨 EMERGENCY PRIVACY BREACH RESOLVED (September 23, 2025)
### 💥 Critical Issue Discovered
Despite all previous protections, .local and .gitea directories appeared on GitHub, exposing:
- **SUMMARY.md** - All Claude attribution removal strategies
- **Setup documentation** - Private development workflows
- **Commit templates** - AI attribution prevention details
**ROOT CAUSE:** Initial repository creation bypassed sync script filtering
**IMMEDIATE RESOLUTION:**
- ✅ **History rewritten** - Used git filter-branch to remove .local/.gitea from all GitHub commits
- ✅ **Force-pushed clean history** - Both main and dev branches cleaned
- ✅ **Avoided 4th nuclear option** - Fixed without recreating repositories
- ✅ **Verified clean** - GitHub now has 30 files (no private directories)
## 🏁 FINAL REPOSITORY RECREATION & SETUP (September 23, 2025)
### 🔄 Complete Dual-Repository Recreation
To ensure absolute zero attribution issues, both repositories were recreated from scratch:
**NEW GITEA REPOSITORY:**
- ✅ **Fresh sbcrumb account** - `[email protected]:sbcrumb/nfoguard.git`
- ✅ **Single clean commit** - Complete codebase with SBCrumb authorship only
- ✅ **Privacy protection active** - Pre-commit hooks, templates, sync scripts configured
- ✅ **Workflow updates** - All jskala references changed to sbcrumb in .gitea workflows
**NEW GITHUB REPOSITORY:**
- ✅ **Clean sync successful** - 30 files pushed from Gitea (excludes .local/.gitea)
- ✅ **100% SBCrumb attribution** - Zero traces of personal names or AI assistance
- ✅ **Documentation enhanced** - User added webhook setup screenshots via GitHub → Gitea workflow
- ✅ **Proper image workflow** - Images uploaded to GitHub, markdown copied to Gitea, synced successfully
### 📊 Final Status
**REPOSITORIES:**
- **Gitea**: 38 files (includes private .local/.gitea development files)
- **GitHub**: 30 files (clean public release, no private files)
- **Privacy**: 100% secure, zero attribution issues possible
**PROFESSIONAL GIT WORKFLOW ESTABLISHED:**
**Phase 1: Gitea Development (Private)**
1. `sync-script.sh start feature-name` - Create feature branch
2. Develop and commit changes on feature branch
3. `sync-script.sh test feature-name` - Merge to Gitea dev for testing
4. Test changes on Gitea dev environment
5. `sync-script.sh release feature-name [patch|minor|major]` - Merge to Gitea main
**Phase 2: GitHub PR Workflow (Public)**
6. `sync-script.sh github-pr feature-name` - Create clean GitHub branch (auto-removes .local/.gitea)
7. **GitHub**: Create PR `github-feature/feature-name` → `dev`
8. **GitHub**: Test changes on dev environment
9. **GitHub**: Create PR `dev` → `main`
10. `sync-script.sh cleanup-github-pr feature-name` - Cleanup feature branches
**Protection Features:**
- ✅ **Private files excluded** - .local/.gitea automatically removed during github-pr command
- ✅ **Attribution cleaning** - Automatic author/committer rewriting with git filter-branch
- ✅ **Dual testing** - Test on both Gitea and GitHub environments
- ✅ **Professional PRs** - Proper review workflow on GitHub
- ✅ **Branch isolation** - Feature work isolated until ready
- ✅ **Multiple safety layers** - .gitignore + manual removal + filter-branch cleaning
**CRITICAL PRIVACY PROTECTION:**
The `github-pr` command includes these specific protections:
```bash
# Remove private directories for GitHub
if [[ -d ".local" ]]; then
git rm -rf .local --cached 2>/dev/null || true
fi
if [[ -d ".gitea" ]]; then
git rm -rf .gitea --cached 2>/dev/null || true
fi
```
This ensures .local/.gitea directories are **physically removed** from the Git tree before any GitHub push, providing ironclad protection against exposure of sensitive development documentation.
**SUCCESS METRICS:**
- ✅ **Zero personal information** on public GitHub
- ✅ **Zero AI attribution** anywhere visible
- ✅ **Working dual-repository architecture**
- ✅ **Complete development workflow** with privacy protection
- ✅ **Professional public presence** with private development capabilities
**SOLUTION NEEDED:**
- Sync GitHub main with Gitea main to restore actual working code
- Gitea has all the real development work, GitHub has clean history but wrong code
- Need to merge: Gitea code + GitHub clean history + proper workflows
## 📝 SUMMARY.md PURPOSE & GUIDELINES
-602
View File
@@ -1,602 +0,0 @@
#!/bin/bash
# NFOGuard Dual-Repo Development Sync Script
# Manages Gitea (private) + GitHub (public) workflow with AI attribution prevention
# CONFIDENTIAL: Stays in .local/ directory only
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
GITEA_REMOTE="origin" # [email protected]:sbcrumb/nfoguard.git
GITHUB_REMOTE="github" # [email protected]:sbcrumb/nfoguard.git
VERSION_FILE="VERSION"
# Helper functions
log_info() { echo -e "${BLUE}ℹ️ $1${NC}"; }
log_success() { echo -e "${GREEN}✅ $1${NC}"; }
log_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; }
log_error() { echo -e "${RED}❌ $1${NC}"; }
# Help with common mistakes and suggestions
suggest_command() {
local input="$1"
local suggestions=()
# Common typos and alternatives
case "$input" in
"create"|"new"|"begin"|"init")
suggestions+=("start")
;;
"merge"|"pr"|"pullrequest"|"pull-request")
suggestions+=("github-pr")
;;
"clean"|"cleanup"|"remove"|"delete")
suggestions+=("cleanup-github-pr")
;;
"check"|"info"|"show")
suggestions+=("status")
;;
"push"|"deploy"|"publish")
suggestions+=("release")
;;
"dev"|"develop"|"development")
suggestions+=("test")
;;
"help"|"--help"|"-h")
suggestions+=("(see help below)")
;;
"ver"|"version")
suggestions+=("version")
;;
*)
# Fuzzy matching for close commands
local commands=("start" "test" "release" "github-pr" "cleanup-github-pr" "sync" "version" "status")
for cmd in "${commands[@]}"; do
# Simple character similarity check
if [[ ${#input} -gt 2 && "$cmd" == *"$input"* ]]; then
suggestions+=("$cmd")
fi
done
;;
esac
if [[ ${#suggestions[@]} -gt 0 ]]; then
log_warning "Unknown command: '$input'"
echo ""
echo "Did you mean:"
for suggestion in "${suggestions[@]}"; do
echo " $0 $suggestion"
done
echo ""
fi
}
# Check if feature branch exists and suggest next steps
check_feature_status() {
local feature_name="$1"
local branch_name="feature/$feature_name"
# Check if feature branch exists locally
if git branch | grep -q " $branch_name$"; then
log_info "Feature branch '$branch_name' exists locally"
# Check if it's been tested (merged to dev)
if git branch -r | grep -q "$GITEA_REMOTE/dev"; then
git fetch "$GITEA_REMOTE" dev >/dev/null 2>&1
if git merge-base --is-ancestor "$branch_name" "$GITEA_REMOTE/dev" 2>/dev/null; then
log_success "Feature has been tested on dev branch"
log_info "Next step: $0 release $feature_name [patch|minor|major]"
else
log_warning "Feature not yet tested on dev branch"
log_info "Next step: $0 test $feature_name"
fi
fi
# Check if it's been released (merged to main)
if git branch -r | grep -q "$GITEA_REMOTE/main"; then
git fetch "$GITEA_REMOTE" main >/dev/null 2>&1
if git merge-base --is-ancestor "$branch_name" "$GITEA_REMOTE/main" 2>/dev/null; then
log_success "Feature has been released to Gitea main"
log_info "Next step: $0 github-pr $feature_name"
fi
fi
else
log_warning "Feature branch '$branch_name' does not exist"
log_info "Start with: $0 start $feature_name"
fi
}
# Show current workflow state and suggest next action
show_workflow_guidance() {
log_info "🔄 Current Workflow State Analysis"
echo ""
# Check for existing feature branches
local feature_branches=($(git branch | grep "feature/" | sed 's/^[* ]*//' | sed 's/feature\///'))
if [[ ${#feature_branches[@]} -eq 0 ]]; then
log_info "No active feature branches found"
log_info "Start a new feature: $0 start <feature-name>"
echo ""
echo "Example: $0 start user-dashboard"
return
fi
log_info "Active feature branches:"
for feature in "${feature_branches[@]}"; do
echo " 📝 $feature"
check_feature_status "$feature"
echo ""
done
log_info "Quick reference:"
echo " $0 test <name> # Test feature on Gitea dev"
echo " $0 release <name> # Release to Gitea main"
echo " $0 github-pr <name> # Create GitHub PR workflow"
}
# Get current version
get_version() {
if [[ -f "$VERSION_FILE" ]]; then
cat "$VERSION_FILE" | tr -d '\n'
else
echo "1.0.0"
fi
}
# Bump version
bump_version() {
local current_version=$(get_version)
local version_type=$1
IFS='.' read -ra VERSION_PARTS <<< "$current_version"
local major=${VERSION_PARTS[0]}
local minor=${VERSION_PARTS[1]}
local patch=${VERSION_PARTS[2]}
case $version_type in
"patch"|"p")
patch=$((patch + 1))
;;
"minor"|"m")
minor=$((minor + 1))
patch=0
;;
"major"|"M")
major=$((major + 1))
minor=0
patch=0
;;
*)
log_error "Invalid version type. Use: patch|p, minor|m, major|M"
exit 1
;;
esac
local new_version="$major.$minor.$patch"
echo "$new_version" > "$VERSION_FILE"
log_success "Version bumped: $current_version → $new_version"
echo "$new_version"
}
# Check if working directory is clean
check_clean() {
if [[ -n $(git status --porcelain) ]]; then
log_error "Working directory not clean. Commit or stash changes first."
exit 1
fi
}
# Ensure we're on the right branch
ensure_branch() {
local target_branch=$1
local current_branch=$(git branch --show-current)
if [[ "$current_branch" != "$target_branch" ]]; then
log_info "Switching to $target_branch"
git checkout "$target_branch"
fi
}
# Sync all branches to match a source
sync_all_branches() {
local source_remote=$1
local source_branch=$2
log_info "Syncing all branches to match $source_remote/$source_branch"
# Fetch all remotes
git fetch "$GITEA_REMOTE"
git fetch "$GITHUB_REMOTE"
# Reset local main to source
ensure_branch main
git reset --hard "$source_remote/$source_branch"
# Push to Gitea (includes .local and .gitea)
log_info "Pushing to Gitea main and dev..."
git push "$GITEA_REMOTE" main --force-with-lease
git push "$GITEA_REMOTE" main:dev --force-with-lease
# For GitHub: create clean branch without .local and .gitea AND without AI attribution
log_info "Creating GitHub-safe branch (excluding .local, .gitea, and AI attribution)..."
local temp_branch="github-sync-temp"
git checkout -b "$temp_branch"
# Remove private directories if they exist
if [[ -d ".local" ]]; then
git rm -rf .local --cached 2>/dev/null || true
fi
if [[ -d ".gitea" ]]; then
git rm -rf .gitea --cached 2>/dev/null || true
fi
# Commit the clean version for GitHub
if [[ -n $(git status --porcelain) ]]; then
git add .
git commit -m "sync: Clean version for GitHub (excludes private dev files)"
fi
# Strip AI attribution AND fix author names from the entire branch history
log_info "Removing AI attribution and fixing author names..."
git filter-branch -f --env-filter '
# Fix author name/email for any commits by jskala or Claude
if [ "$GIT_AUTHOR_NAME" = "jskala" ] || [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ] ||
[ "$GIT_AUTHOR_NAME" = "Claude" ] || [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]; then
export GIT_AUTHOR_NAME="SBCrumb"
export GIT_AUTHOR_EMAIL="[email protected]"
fi
# Fix committer name/email for any commits by jskala or Claude
if [ "$GIT_COMMITTER_NAME" = "jskala" ] || [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ] ||
[ "$GIT_COMMITTER_NAME" = "Claude" ] || [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ]; then
export GIT_COMMITTER_NAME="SBCrumb"
export GIT_COMMITTER_EMAIL="[email protected]"
fi
' --msg-filter '
# Remove Claude co-authorship lines from commit messages
sed "/Co-Authored-By: Claude/d" |
sed "/Generated with.*Claude/d" |
sed "/🤖 Generated with.*Claude/d" |
# Remove any other AI references
sed "/[email protected]/d"
' -- "$temp_branch" 2>/dev/null || log_warning "Filter-branch may not be needed"
log_info "Pushing to GitHub main and dev..."
git push "$GITHUB_REMOTE" "$temp_branch:main" --force-with-lease
git push "$GITHUB_REMOTE" "$temp_branch:dev" --force-with-lease
# Clean up temp branch and return to main
git checkout main
git branch -D "$temp_branch"
log_success "All branches synchronized with privacy respected!"
log_warning "Note: .local and .gitea stay on Gitea only (as intended)"
}
# Start feature development
start_feature() {
local feature_name=$1
if [[ -z "$feature_name" ]]; then
log_error "Feature name required"
echo ""
echo "Usage: $0 start <feature-name>"
echo ""
echo "Examples:"
echo " $0 start user-dashboard # Creates feature/user-dashboard"
echo " $0 start api-improvements # Creates feature/api-improvements"
echo " $0 start bug-fix-login # Creates feature/bug-fix-login"
echo ""
log_info "💡 Use descriptive names with hyphens (no spaces)"
exit 1
fi
check_clean
ensure_branch main
# Create feature branch
local branch_name="feature/$feature_name"
log_info "Creating feature branch: $branch_name"
git checkout -b "$branch_name"
log_success "Feature branch '$branch_name' created. Start coding!"
echo ""
log_info "🔄 Next steps in workflow:"
echo " 1. Make your changes and commit them"
echo " 2. When ready for testing: $0 test $feature_name"
echo " 3. After testing: $0 release $feature_name [patch|minor|major]"
echo " 4. For GitHub PR: $0 github-pr $feature_name"
}
# Test feature (merge to dev)
test_feature() {
local feature_name=$1
if [[ -z "$feature_name" ]]; then
log_error "Feature name required"
echo "Usage: $0 test <feature-name>"
exit 1
fi
check_clean
local branch_name="feature/$feature_name"
# Merge to Gitea dev for testing
ensure_branch dev
git fetch "$GITEA_REMOTE"
git reset --hard "$GITEA_REMOTE/dev"
log_info "Merging $branch_name to dev for testing"
git merge "$branch_name" --no-ff -m "test: Merge $feature_name for local testing"
git push "$GITEA_REMOTE" dev
log_success "Feature merged to Gitea dev for testing"
echo ""
log_info "🧪 Testing Phase:"
echo " • Test your changes thoroughly on the dev environment"
echo " • Check logs, functionality, and integration"
echo " • When satisfied: $0 release $feature_name [patch|minor|major]"
echo ""
log_warning "💡 Remember: Once released to main, it goes to GitHub PR workflow"
}
# Release feature (merge to Gitea main, then create GitHub PR workflow)
release_feature() {
local feature_name=$1
local version_type=${2:-"patch"}
if [[ -z "$feature_name" ]]; then
log_error "Feature name required"
echo "Usage: $0 release <feature-name> [patch|minor|major]"
exit 1
fi
check_clean
# Bump version
local new_version=$(bump_version "$version_type")
# Merge to Gitea main
ensure_branch main
git fetch "$GITEA_REMOTE"
git reset --hard "$GITEA_REMOTE/main"
local branch_name="feature/$feature_name"
log_info "Merging $branch_name to Gitea main"
git merge "$branch_name" --no-ff -m "feat: $feature_name (v$new_version)"
# Push to Gitea main
git push "$GITEA_REMOTE" main
log_success "Feature '$feature_name' merged to Gitea main as v$new_version"
echo ""
log_info "🚀 Ready for GitHub PR Workflow!"
echo " Phase 1 (Gitea) Complete ✅"
echo ""
log_info "📋 Next steps:"
echo " 1. $0 github-pr $feature_name"
echo " 2. Go to GitHub → Create PR: github-feature/$feature_name → dev"
echo " 3. Test on GitHub dev environment"
echo " 4. Create PR: dev → main"
echo " 5. $0 cleanup-github-pr $feature_name"
echo ""
log_warning "💡 The github-pr command will automatically exclude .local/.gitea files"
}
# Create GitHub PR workflow branch
github_pr() {
local feature_name=$1
if [[ -z "$feature_name" ]]; then
log_error "Feature name required"
echo "Usage: $0 github-pr <feature-name>"
exit 1
fi
check_clean
# Create clean GitHub feature branch from current Gitea main
log_info "Creating GitHub PR workflow for feature: $feature_name"
ensure_branch main
git fetch "$GITEA_REMOTE"
git reset --hard "$GITEA_REMOTE/main"
# Create GitHub-safe feature branch
local github_branch="github-feature/$feature_name"
git checkout -b "$github_branch"
# Remove private directories for GitHub
if [[ -d ".local" ]]; then
git rm -rf .local --cached 2>/dev/null || true
fi
if [[ -d ".gitea" ]]; then
git rm -rf .gitea --cached 2>/dev/null || true
fi
# Commit clean version if changes exist
if [[ -n $(git status --porcelain) ]]; then
git add .
git commit -m "github: Clean feature branch for $feature_name PR workflow"
fi
# Apply privacy filters
log_info "Applying privacy filters..."
git filter-branch -f --env-filter '
if [ "$GIT_AUTHOR_NAME" = "jskala" ] || [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ] ||
[ "$GIT_AUTHOR_NAME" = "Claude" ] || [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]; then
export GIT_AUTHOR_NAME="SBCrumb"
export GIT_AUTHOR_EMAIL="[email protected]"
fi
if [ "$GIT_COMMITTER_NAME" = "jskala" ] || [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ] ||
[ "$GIT_COMMITTER_NAME" = "Claude" ] || [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ]; then
export GIT_COMMITTER_NAME="SBCrumb"
export GIT_COMMITTER_EMAIL="[email protected]"
fi
' --msg-filter '
sed "/Co-Authored-By: Claude/d" |
sed "/Generated with.*Claude/d" |
sed "/🤖 Generated with.*Claude/d" |
sed "/[email protected]/d"
' -- "$github_branch" 2>/dev/null || log_warning "Filter-branch may not be needed"
# Push feature branch to GitHub
git push "$GITHUB_REMOTE" "$github_branch" --force-with-lease
# Also update GitHub dev branch
git push "$GITHUB_REMOTE" "$github_branch:dev" --force-with-lease
log_success "GitHub feature branch created: $github_branch"
log_info "Next steps:"
log_info " 1. Go to GitHub and create PR: $github_branch → dev"
log_info " 2. Test the changes on github-dev"
log_info " 3. Create PR: dev → main"
log_info " 4. Run: $0 cleanup-github-pr $feature_name"
# Return to main and cleanup
git checkout main
git branch -D "$github_branch"
}
# Cleanup after GitHub PR workflow
cleanup_github_pr() {
local feature_name=$1
if [[ -z "$feature_name" ]]; then
log_error "Feature name required"
echo "Usage: $0 cleanup-github-pr <feature-name>"
exit 1
fi
# Cleanup local feature branch
local branch_name="feature/$feature_name"
git branch -d "$branch_name" 2>/dev/null || true
# Cleanup remote branches
git push "$GITEA_REMOTE" --delete "$branch_name" 2>/dev/null || true
git push "$GITHUB_REMOTE" --delete "github-feature/$feature_name" 2>/dev/null || true
log_success "Cleaned up feature branches for: $feature_name"
}
# Show status
show_status() {
log_info "Current Repository Status"
echo ""
# Current branch and version
local current_branch=$(git branch --show-current)
local current_version=$(get_version)
echo "📍 Current Branch: $current_branch"
echo "🔢 Current Version: $current_version"
echo ""
# Remote status
git fetch "$GITEA_REMOTE" >/dev/null 2>&1
git fetch "$GITHUB_REMOTE" >/dev/null 2>&1
echo "🔄 Branch Status:"
echo " Local main: $(git rev-parse --short main)"
echo " Gitea main: $(git rev-parse --short $GITEA_REMOTE/main)"
echo " Gitea dev: $(git rev-parse --short $GITEA_REMOTE/dev)"
echo " GitHub main: $(git rev-parse --short $GITHUB_REMOTE/main)"
echo " GitHub dev: $(git rev-parse --short $GITHUB_REMOTE/dev)"
echo ""
# Check if synchronized
local gitea_main=$(git rev-parse $GITEA_REMOTE/main)
local gitea_dev=$(git rev-parse $GITEA_REMOTE/dev)
local github_main=$(git rev-parse $GITHUB_REMOTE/main)
local github_dev=$(git rev-parse $GITHUB_REMOTE/dev)
if [[ "$gitea_main" == "$gitea_dev" && "$gitea_main" == "$github_main" && "$gitea_main" == "$github_dev" ]]; then
log_success "All branches are synchronized! ✨"
else
log_warning "Branches are not synchronized"
echo " Run: $0 sync to synchronize all branches"
fi
echo ""
show_workflow_guidance
}
# Main script logic
case "${1:-status}" in
"start")
start_feature "$2"
;;
"test")
test_feature "$2"
;;
"release")
release_feature "$2" "$3"
;;
"github-pr")
github_pr "$2"
;;
"cleanup-github-pr")
cleanup_github_pr "$2"
;;
"sync")
sync_all_branches "$GITEA_REMOTE" main
;;
"version")
if [[ -n "$2" ]]; then
bump_version "$2"
else
echo "Current version: $(get_version)"
fi
;;
"status"|"")
show_status
;;
*)
# Check if it's a typo or unknown command and suggest alternatives
suggest_command "$1"
echo "NFOGuard Development Sync Script"
echo ""
echo "Usage: $0 <command> [options]"
echo ""
log_info "Available Commands:"
echo " start <name> Create new feature branch"
echo " test <name> Merge feature to dev for testing"
echo " release <name> [type] Merge to Gitea main (patch|minor|major)"
echo " github-pr <name> Create GitHub PR workflow branch"
echo " cleanup-github-pr <name> Cleanup after GitHub PR workflow"
echo " sync Sync all branches to Gitea main"
echo " version [type] Show or bump version"
echo " status Show repository status (default)"
echo ""
log_info "Professional Git Workflow:"
echo " # 🔧 Gitea Development (Private)"
echo " $0 start user-auth # Create feature branch"
echo " # ... develop feature ..."
echo " $0 test user-auth # Test on Gitea dev"
echo " $0 release user-auth minor # Merge to Gitea main"
echo ""
echo " # 🚀 GitHub PR Workflow (Public)"
echo " $0 github-pr user-auth # Create clean GitHub branch"
echo " # Create PR: github-feature/user-auth → github-dev"
echo " # Test, then create PR: github-dev → github-main"
echo " $0 cleanup-github-pr user-auth # Cleanup branches"
echo ""
log_info "Common Aliases:"
echo " create, new, init → start"
echo " merge, pr, pull-request → github-pr"
echo " clean, cleanup, remove → cleanup-github-pr"
echo " check, info, show → status"
echo " push, deploy, publish → release"
echo " dev, develop → test"
echo ""
log_warning "💡 Tip: Run '$0 status' to see your current workflow state and next steps"
;;
esac
-7
View File
@@ -133,15 +133,8 @@ image: sbcrumb/nfoguard:v1.5.5
Configure these webhook URLs in your applications:
**Radarr**: `http://nfoguard:8080/webhook/radarr`
<img width="730" height="1009" alt="image" src="https://github.com/user-attachments/assets/17b50d26-539d-49f3-ae81-66c37113c796" />
**Sonarr**: `http://nfoguard:8080/webhook/sonarr`
<img width="750" height="1049" alt="image" src="https://github.com/user-attachments/assets/f373d17e-bb26-4510-bb64-df308d9d88f8" />
**Triggers**: On Import, On Upgrade, On Rename
## 🔄 Manual Operations
+1 -1
View File
@@ -1 +1 @@
1.7.2
1.6.9
+16 -2
View File
@@ -1007,18 +1007,32 @@ class MovieProcessor:
# Use existing movie date decision logic
dateadded, source, released = self._decide_movie_dates(imdb_id, movie_path, should_query, existing)
# If we don't have an import/download date but we have a release date, use it as dateadded
# This ensures we save digital release dates, theatrical dates, etc. to the database
final_dateadded = dateadded
final_source = source
if dateadded is None and released is not None:
final_dateadded = released
final_source = f"{source}_as_dateadded" if source else "release_date_fallback"
_log("INFO", f"Using release date as dateadded: {final_dateadded} (source: {final_source})")
# Create NFO regardless of date availability (preserves existing metadata)
if config.manage_nfo:
self.nfo_manager.create_movie_nfo(
movie_path, imdb_id, dateadded, released, source, config.lock_metadata
movie_path, imdb_id, final_dateadded, released, final_source, config.lock_metadata
)
# Skip remaining processing if no valid date found and file dates disabled
if dateadded is None:
if final_dateadded is None:
_log("WARNING", f"Movie {movie_path.name} - no valid date source available, but NFO was still processed")
self.db.upsert_movie_dates(imdb_id, released, None, source, True)
return
# Update dateadded and source for the rest of processing
dateadded = final_dateadded
source = final_source
_log("DEBUG", f"Movie {movie_path.name} proceeding to save: dateadded={dateadded}, source={source}")
# Update file mtimes (only if we have a valid date)