-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinitialization.py
executable file
·230 lines (190 loc) · 9.88 KB
/
initialization.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
import logging
import time
from metadata.metadata import refresh_release_dates
from database import update_media_item_state, get_all_media_items
from settings import get_all_settings, get_setting
# Progress ranges for each phase
PROGRESS_RANGES = {
'reset': (0, 5), # 5 seconds
'plex': (5, 50), # 2 minutes
'sources': (50, 90), # 2 minutes
'release': (90, 100) # 30 seconds
}
# Duration for each phase in seconds
PHASE_DURATIONS = {
'reset': 5,
'plex': 120, # 2 minutes
'sources': 120, # 2 minutes
'release': 30
}
# Global variable to track initialization progress
initialization_status = {
'current_step': '',
'total_steps': 4,
'current_step_number': 0,
'progress_value': 0, # Current progress percentage
'substep_details': '',
'error_details': None,
'is_substep': False,
'phase_start_time': 0, # Start time of current phase
'current_phase': None # Current phase identifier
}
def get_initialization_status():
# Update progress based on elapsed time if in a timed phase
if initialization_status['current_phase'] and initialization_status['phase_start_time'] > 0:
phase = initialization_status['current_phase']
start_time = initialization_status['phase_start_time']
current_time = time.time()
# Calculate elapsed percentage of the phase
elapsed_time = current_time - start_time
phase_duration = PHASE_DURATIONS.get(phase, 0)
if phase_duration > 0:
progress_range = PROGRESS_RANGES.get(phase, (0, 0))
range_size = progress_range[1] - progress_range[0]
# Calculate progress within the phase
progress_pct = min(1.0, elapsed_time / phase_duration)
new_progress = progress_range[0] + (range_size * progress_pct)
# Update the progress value
initialization_status['progress_value'] = new_progress
return initialization_status
def start_phase(phase_name, step_name, details=''):
"""Start a new timed phase of initialization."""
initialization_status['current_phase'] = phase_name
initialization_status['phase_start_time'] = time.time()
initialization_status['current_step'] = step_name
initialization_status['substep_details'] = details
initialization_status['progress_value'] = PROGRESS_RANGES.get(phase_name, (0, 0))[0]
initialization_status['current_step_number'] += 1
def complete_phase(phase_name):
"""Mark a phase as complete, setting progress to the end of its range."""
if phase_name in PROGRESS_RANGES:
initialization_status['progress_value'] = PROGRESS_RANGES[phase_name][1]
initialization_status['phase_start_time'] = 0 # Stop the time-based progress
def update_initialization_step(step_name, substep_details='', error=None, is_substep=False):
"""Update initialization status without changing the progress timing."""
initialization_status['current_step'] = step_name
initialization_status['substep_details'] = substep_details
initialization_status['error_details'] = error
initialization_status['is_substep'] = is_substep
if not is_substep:
initialization_status['current_step_number'] += 1
#logging.info(f"Initialization {'substep' if is_substep else 'step'} {initialization_status['current_step_number']}/{initialization_status['total_steps']}: {step_name}")
if substep_details:
logging.info(f" Details: {substep_details}")
def format_item_log(item):
if item['type'] == 'movie':
return f"{item['title']} ({item['year']})"
elif item['type'] == 'episode':
return f"{item['title']} S{item['season_number']:02d}E{item['episode_number']:02d}"
else:
return item['title']
def reset_queued_item_status():
update_initialization_step("Reset Items", "Identifying items in processing states", is_substep=True)
logging.info("Resetting queued item status...")
states_to_reset = ['Scraping', 'Adding', 'Checking', 'Sleeping']
total_reset = 0
for state in states_to_reset:
items = get_all_media_items(state=state)
if items:
update_initialization_step("Reset Items", f"Processing {len(items)} items in {state} state", is_substep=True)
for item in items:
update_media_item_state(item['id'], 'Wanted')
total_reset += 1
logging.info(f"Reset item {format_item_log(item)} (ID: {item['id']}) from {state} to Wanted")
update_initialization_step("Reset Items", f"Reset {total_reset} items to Wanted state", is_substep=True)
def plex_collection_update(skip_initial_plex_update):
from run_program import get_and_add_all_collected_from_plex, get_and_add_recent_collected_from_plex
from database import get_all_media_items
update_initialization_step("Plex Update", "Starting Plex scan")
logging.info("Updating Plex collection...")
try:
update_initialization_step("Plex Update",
"Performing quick scan" if skip_initial_plex_update else "Performing full library scan",
is_substep=True)
if skip_initial_plex_update:
result = get_and_add_recent_collected_from_plex()
else:
result = get_and_add_all_collected_from_plex()
# First check if we got any content from Plex
if result and isinstance(result, dict):
movies = result.get('movies', [])
episodes = result.get('episodes', [])
if len(movies) > 0 or len(episodes) > 0:
update_initialization_step("Plex Update",
f"Found {len(movies)} movies and {len(episodes)} episodes",
is_substep=True)
return True, True # Plex responded and had content
# If Plex returned no items, check if we have any existing collected items
existing_collected = get_all_media_items(state='Collected')
if existing_collected:
msg = "Plex scan returned no new content but found existing collected items - skipping content sources to prevent data loss"
update_initialization_step("Plex Update", msg, error=msg, is_substep=True)
logging.warning(msg)
return True, False # Plex responded but had no content, have existing items
msg = "Plex scan returned no content and no existing collected items found - will proceed with content sources - this appears to be a new library"
update_initialization_step("Plex Update", msg, is_substep=True)
logging.info(msg)
return True, True # Plex responded but had no content, no existing items
except Exception as e:
error_msg = f"Error during Plex collection update: {str(e)}"
update_initialization_step("Plex Update", error_msg, error=error_msg, is_substep=True)
logging.error(error_msg)
logging.error("Skipping collection update to prevent data loss")
return False, False # Plex error occurred
def get_all_wanted_from_enabled_sources():
from routes.debug_routes import get_and_add_wanted_content
content_sources = get_all_settings().get('Content Sources', {})
enabled_sources = [source_id for source_id, data in content_sources.items()
if data.get('enabled', False)]
update_initialization_step("Content Sources",
f"Found {len(enabled_sources)} enabled sources",
is_substep=True)
for source_id in enabled_sources:
update_initialization_step("Content Sources",
f"Retrieving wanted content from {source_id}",
is_substep=True)
get_and_add_wanted_content(source_id)
update_initialization_step("Content Sources",
f"Processed {len(enabled_sources)} sources",
is_substep=True)
def initialize(skip_initial_plex_update=False):
"""Initialize the application state."""
# Reset initialization status
initialization_status['current_step'] = ''
initialization_status['current_step_number'] = 0
initialization_status['progress_value'] = 0
initialization_status['substep_details'] = ''
initialization_status['error_details'] = None
initialization_status['is_substep'] = False
initialization_status['phase_start_time'] = 0
initialization_status['current_phase'] = None
# Start initialization
update_initialization_step('Starting initialization')
# Reset Items Phase (5 seconds)
start_phase('reset', 'Reset Items', 'Starting item reset')
reset_queued_item_status()
complete_phase('reset')
if get_setting('File Management ', 'file_collection_management') == 'Plex':
# Plex Update Phase (2 minutes)
start_phase('plex', 'Plex Update', 'Starting Plex scan')
plex_success, should_process_sources = plex_collection_update(skip_initial_plex_update)
complete_phase('plex')
# Content Sources Phase (2 minutes)
if plex_success and should_process_sources:
start_phase('sources', 'Content Sources', 'Processing content sources')
get_all_wanted_from_enabled_sources()
complete_phase('sources')
else:
# Content Sources Phase (2 minutes)
start_phase('sources', 'Content Sources', 'Processing content sources')
get_all_wanted_from_enabled_sources()
complete_phase('sources')
plex_success = True
# Release Dates Phase (30 seconds)
start_phase('release', 'Release Dates', 'Updating metadata for all items')
refresh_release_dates()
complete_phase('release')
# Complete
final_status = "completed successfully" if plex_success else "completed with Plex update issues"
update_initialization_step("Complete", final_status)
return plex_success