appydave-tools 0.65.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '018d3a90eaad36f1ac6089615800619b751ad7a398e3f29ceebb3690b8fec7e4'
4
- data.tar.gz: b8b5920c74e273724d5a5750d63f9b09f4ffc637e5af21f8fded09da8cce55d2
3
+ metadata.gz: bcb556d99a18280e3339c68e65df1fd7e821c1a55e55e2be9f4a8972ab50f07c
4
+ data.tar.gz: f999edff5d375ce8fc34bc708d3ff2c9e7bb099bf8d8301bc25519411b67e0a4
5
5
  SHA512:
6
- metadata.gz: 9b61ce6b01dc9c7b865f4a0af340c49e3d537f45eb43bf61e420c4f1d7df6aead0bc210390b18bdb479a4d197a7b7d274558180ebb66070b5353e444bb33112a
7
- data.tar.gz: 42e60c347dcd50fcc1714e046b228271e1363b868566f58b09cf3a0c317d65a51a47de5dce5adebe2e42a5c2281d346afc3a43a10e5c68500ba0ecd726a4d67a
6
+ metadata.gz: 77c0312c15cb033e6c7c23ebe6e2c81b18214b199297e25fd0f030faf8de76d479460a93d700066a1a7e1cc9c560f3d20af3263933a35ab2b409dfc1be37533b
7
+ data.tar.gz: 360c380d91269fc8db5bd7713350aaadce1182e918b5318db52ce7e3744b92d0ecce93e4dc0e36af4e8fbb4e31bdef6c943bda8ccbe2aaff94317d6f5c4cb53b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [0.66.0](https://github.com/appydave/appydave-tools/compare/v0.65.0...v0.66.0) (2025-11-22)
2
+
3
+
4
+ ### Features
5
+
6
+ * add --detailed flag to brand list showing PATH, SSD BACKUP, WORKFLOW, and ACTIVE PROJECTS ([e336e58](https://github.com/appydave/appydave-tools/commit/e336e585270305f01295c91c0543075a0e0438ad))
7
+
8
+ # [0.65.0](https://github.com/appydave/appydave-tools/compare/v0.64.0...v0.65.0) (2025-11-22)
9
+
10
+
11
+ ### Features
12
+
13
+ * add last S3 sync time to brand status showing most recent file in s3-staging folders ([d373b66](https://github.com/appydave/appydave-tools/commit/d373b66e6323521be3d750a9330769fa33b4fed2))
14
+
1
15
  # [0.64.0](https://github.com/appydave/appydave-tools/compare/v0.63.0...v0.64.0) (2025-11-22)
2
16
 
3
17
 
data/bin/dam CHANGED
@@ -129,6 +129,7 @@ class VatCLI
129
129
 
130
130
  # List brands and projects
131
131
  def list_command(args)
132
+ detailed = args.include?('--detailed')
132
133
  args = args.reject { |arg| arg.start_with?('--') || arg.start_with?('-') }
133
134
 
134
135
  brand_arg = args[0]
@@ -136,13 +137,13 @@ class VatCLI
136
137
 
137
138
  if brand_arg.nil?
138
139
  # List all brands with summary
139
- Appydave::Tools::Dam::ProjectListing.list_brands_with_counts
140
+ Appydave::Tools::Dam::ProjectListing.list_brands_with_counts(detailed: detailed)
140
141
  elsif pattern_arg
141
142
  # Pattern matching
142
143
  Appydave::Tools::Dam::ProjectListing.list_with_pattern(brand_arg, pattern_arg)
143
144
  else
144
145
  # Specific brand
145
- Appydave::Tools::Dam::ProjectListing.list_brand_projects(brand_arg)
146
+ Appydave::Tools::Dam::ProjectListing.list_brand_projects(brand_arg, detailed: detailed)
146
147
  end
147
148
  rescue StandardError => e
148
149
  puts "❌ Error: #{e.message}"
@@ -10,7 +10,8 @@ module Appydave
10
10
  # Project listing functionality for VAT
11
11
  class ProjectListing
12
12
  # List all brands with summary table
13
- def self.list_brands_with_counts
13
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
14
+ def self.list_brands_with_counts(detailed: false)
14
15
  brands = Config.available_brands
15
16
 
16
17
  if brands.empty?
@@ -19,27 +20,53 @@ module Appydave
19
20
  end
20
21
 
21
22
  # Gather brand data
22
- brand_data = brands.map { |brand| collect_brand_data(brand) }
23
-
24
- # Print table header
25
- puts 'BRAND KEY PROJECTS SIZE LAST MODIFIED GIT S3 SYNC'
26
- puts '-' * 130
27
-
28
- # Print table rows
29
- brand_data.each do |data|
30
- # Format: "shortcut - Name" (simplified display)
31
- brand_display = "#{data[:shortcut]} - #{data[:name]}"
32
-
33
- puts format(
34
- '%-30s %-12s %10d %12s %20s %-15s %-10s',
35
- brand_display,
36
- data[:key],
37
- data[:count],
38
- format_size(data[:size]),
39
- format_date(data[:modified]),
40
- data[:git_status],
41
- data[:s3_sync]
42
- )
23
+ brand_data = brands.map { |brand| collect_brand_data(brand, detailed: detailed) }
24
+
25
+ if detailed
26
+ # Detailed view with additional columns
27
+ header = 'BRAND KEY PROJECTS SIZE LAST MODIFIED ' \
28
+ 'GIT S3 SYNC PATH SSD BACKUP ' \
29
+ 'WORKFLOW ACTIVE'
30
+ puts header
31
+ puts '-' * 200
32
+
33
+ brand_data.each do |data|
34
+ brand_display = "#{data[:shortcut]} - #{data[:name]}"
35
+
36
+ puts format(
37
+ '%-30s %-12s %10d %12s %20s %-15s %-10s %-35s %-30s %-10s %6d',
38
+ brand_display,
39
+ data[:key],
40
+ data[:count],
41
+ format_size(data[:size]),
42
+ format_date(data[:modified]),
43
+ data[:git_status],
44
+ data[:s3_sync],
45
+ shorten_path(data[:path]),
46
+ data[:ssd_backup] || 'N/A',
47
+ data[:workflow] || 'N/A',
48
+ data[:active_count] || 0
49
+ )
50
+ end
51
+ else
52
+ # Default view
53
+ puts 'BRAND KEY PROJECTS SIZE LAST MODIFIED GIT S3 SYNC'
54
+ puts '-' * 130
55
+
56
+ brand_data.each do |data|
57
+ brand_display = "#{data[:shortcut]} - #{data[:name]}"
58
+
59
+ puts format(
60
+ '%-30s %-12s %10d %12s %20s %-15s %-10s',
61
+ brand_display,
62
+ data[:key],
63
+ data[:count],
64
+ format_size(data[:size]),
65
+ format_date(data[:modified]),
66
+ data[:git_status],
67
+ data[:s3_sync]
68
+ )
69
+ end
43
70
  end
44
71
 
45
72
  # Print footer summary
@@ -51,9 +78,11 @@ module Appydave
51
78
  "#{total_projects} project#{'s' if total_projects != 1}, " \
52
79
  "#{format_size(total_size)}"
53
80
  end
81
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
54
82
 
55
83
  # List all projects for a specific brand (Mode 3)
56
- def self.list_brand_projects(brand_arg)
84
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
85
+ def self.list_brand_projects(brand_arg, detailed: false)
57
86
  # ProjectResolver expects the original brand key/shortcut, not the expanded v-* version
58
87
  projects = ProjectResolver.list_projects(brand_arg)
59
88
 
@@ -76,58 +105,57 @@ module Appydave
76
105
 
77
106
  # Gather project data
78
107
  brand_path = Config.brand_path(brand_arg)
108
+ brand_info = Appydave::Tools::Configuration::Config.brands.get_brand(brand_arg)
79
109
  is_git_repo = Dir.exist?(File.join(brand_path, '.git'))
80
110
 
81
111
  project_data = projects.map do |project|
82
- project_path = Config.project_path(brand_arg, project)
83
- size = FileHelper.calculate_directory_size(project_path)
84
- modified = File.mtime(project_path)
85
-
86
- # Check if project has uncommitted changes (if brand is git repo)
87
- git_status = if is_git_repo
88
- calculate_project_git_status(brand_path, project)
89
- else
90
- 'N/A'
91
- end
92
-
93
- # Check if project has s3-staging folder
94
- s3_sync = if Dir.exist?(File.join(project_path, 's3-staging'))
95
- '✓ staged'
96
- else
97
- 'none'
98
- end
99
-
100
- {
101
- name: project,
102
- path: project_path,
103
- size: size,
104
- modified: modified,
105
- age: format_age(modified),
106
- stale: stale?(modified),
107
- git_status: git_status,
108
- s3_sync: s3_sync
109
- }
112
+ collect_project_data(brand_arg, brand_path, brand_info, project, is_git_repo, detailed: detailed)
110
113
  end
111
114
 
112
- # Print table header
115
+ # Print common header
113
116
  puts "Projects in #{brand}:"
114
117
  puts ''
115
118
  puts 'ℹ️ Note: Lists only projects with files, not empty directories'
116
119
  puts ''
117
- puts 'PROJECT SIZE AGE GIT S3'
118
- puts '-' * 130
119
120
 
120
- # Print table rows
121
- project_data.each do |data|
122
- age_display = data[:stale] ? "#{data[:age]} ⚠️" : data[:age]
123
- puts format(
124
- '%-45s %12s %15s %-15s %-10s',
125
- data[:name],
126
- format_size(data[:size]),
127
- age_display,
128
- data[:git_status],
129
- data[:s3_sync]
130
- )
121
+ if detailed
122
+ # Detailed view with additional columns
123
+ header = 'PROJECT SIZE AGE GIT S3 ' \
124
+ 'PATH HEAVY FILES LIGHT FILES SSD BACKUP'
125
+ puts header
126
+ puts '-' * 200
127
+
128
+ project_data.each do |data|
129
+ age_display = data[:stale] ? "#{data[:age]} ⚠️" : data[:age]
130
+ puts format(
131
+ '%-45s %12s %15s %-15s %-10s %-35s %-18s %-18s %-30s',
132
+ data[:name],
133
+ format_size(data[:size]),
134
+ age_display,
135
+ data[:git_status],
136
+ data[:s3_sync],
137
+ shorten_path(data[:path]),
138
+ data[:heavy_files] || 'N/A',
139
+ data[:light_files] || 'N/A',
140
+ data[:ssd_backup] || 'N/A'
141
+ )
142
+ end
143
+ else
144
+ # Default view
145
+ puts 'PROJECT SIZE AGE GIT S3'
146
+ puts '-' * 130
147
+
148
+ project_data.each do |data|
149
+ age_display = data[:stale] ? "#{data[:age]} ⚠️" : data[:age]
150
+ puts format(
151
+ '%-45s %12s %15s %-15s %-10s',
152
+ data[:name],
153
+ format_size(data[:size]),
154
+ age_display,
155
+ data[:git_status],
156
+ data[:s3_sync]
157
+ )
158
+ end
131
159
  end
132
160
 
133
161
  # Print footer summary
@@ -137,8 +165,10 @@ module Appydave
137
165
  puts ''
138
166
  puts "Total: #{project_count} project#{'s' if project_count != 1}, #{format_size(total_size)}"
139
167
  end
168
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
140
169
 
141
170
  # List with pattern matching (Mode 3b)
171
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
142
172
  def self.list_with_pattern(brand_arg, pattern)
143
173
  # ProjectResolver expects the original brand key/shortcut, not the expanded v-* version
144
174
  matches = ProjectResolver.resolve_pattern(brand_arg, pattern)
@@ -201,10 +231,12 @@ module Appydave
201
231
  puts "Total: #{match_count} project#{'s' if match_count != 1}, #{format_size(total_size)} " \
202
232
  "(#{percentage}% of #{brand})"
203
233
  end
234
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
204
235
 
205
236
  # Helper methods
206
237
 
207
238
  # Show brand context header with git, S3, and SSD info
239
+ # rubocop:disable Metrics/AbcSize
208
240
  def self.show_brand_header(brand_arg, brand)
209
241
  Appydave::Tools::Configuration::Config.configure
210
242
  brand_info = Appydave::Tools::Configuration::Config.brands.get_brand(brand_arg)
@@ -239,9 +271,11 @@ module Appydave
239
271
 
240
272
  puts ''
241
273
  end
274
+ # rubocop:enable Metrics/AbcSize
242
275
 
243
276
  # Collect brand data for display
244
- def self.collect_brand_data(brand)
277
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
278
+ def self.collect_brand_data(brand, detailed: false)
245
279
  Appydave::Tools::Configuration::Config.configure
246
280
  brand_info = Appydave::Tools::Configuration::Config.brands.get_brand(brand)
247
281
  brand_path = Config.brand_path(brand)
@@ -262,7 +296,7 @@ module Appydave
262
296
  # Get S3 sync status (count of projects with s3-staging)
263
297
  s3_sync_status = calculate_s3_sync_status(brand, projects)
264
298
 
265
- {
299
+ result = {
266
300
  shortcut: shortcut || key,
267
301
  key: key,
268
302
  name: name || key.capitalize,
@@ -273,7 +307,33 @@ module Appydave
273
307
  git_status: git_status,
274
308
  s3_sync: s3_sync_status
275
309
  }
310
+
311
+ # Add detailed fields if requested
312
+ if detailed
313
+ # SSD backup path
314
+ ssd_backup = brand_info.locations.ssd_backup
315
+ ssd_backup = nil if ssd_backup.nil? || ssd_backup.empty? || ssd_backup == 'NOT-SET'
316
+
317
+ # Workflow type (inferred from projects_subfolder setting)
318
+ workflow = brand_info.settings.projects_subfolder == 'projects' ? 'storyline' : 'flivideo'
319
+
320
+ # Active project count (projects with flat structure, not archived)
321
+ active_count = projects.count do |project|
322
+ project_path = Config.project_path(brand, project)
323
+ # Check if not in archived/ subfolder
324
+ !project_path.include?('/archived/')
325
+ end
326
+
327
+ result.merge!(
328
+ ssd_backup: ssd_backup ? shorten_path(ssd_backup) : nil,
329
+ workflow: workflow,
330
+ active_count: active_count
331
+ )
332
+ end
333
+
334
+ result
276
335
  end
336
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
277
337
 
278
338
  # Calculate git status for a brand
279
339
  def self.calculate_git_status(brand_path)
@@ -317,6 +377,74 @@ module Appydave
317
377
  end
318
378
  end
319
379
 
380
+ # Collect project data for display
381
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/ParameterLists
382
+ def self.collect_project_data(brand_arg, brand_path, brand_info, project, is_git_repo, detailed: false)
383
+ project_path = Config.project_path(brand_arg, project)
384
+ size = FileHelper.calculate_directory_size(project_path)
385
+ modified = File.mtime(project_path)
386
+
387
+ # Check if project has uncommitted changes (if brand is git repo)
388
+ git_status = if is_git_repo
389
+ calculate_project_git_status(brand_path, project)
390
+ else
391
+ 'N/A'
392
+ end
393
+
394
+ # Check if project has s3-staging folder
395
+ s3_sync = if Dir.exist?(File.join(project_path, 's3-staging'))
396
+ '✓ staged'
397
+ else
398
+ 'none'
399
+ end
400
+
401
+ result = {
402
+ name: project,
403
+ path: project_path,
404
+ size: size,
405
+ modified: modified,
406
+ age: format_age(modified),
407
+ stale: stale?(modified),
408
+ git_status: git_status,
409
+ s3_sync: s3_sync
410
+ }
411
+
412
+ # Add detailed fields if requested
413
+ if detailed
414
+ # Heavy files (video files in root)
415
+ heavy_count = 0
416
+ heavy_size = 0
417
+ Dir.glob(File.join(project_path, '*.{mp4,mov,avi,mkv,webm}')).each do |file|
418
+ heavy_count += 1
419
+ heavy_size += File.size(file)
420
+ end
421
+
422
+ # Light files (subtitles, images, metadata)
423
+ light_count = 0
424
+ light_size = 0
425
+ Dir.glob(File.join(project_path, '**/*.{srt,vtt,jpg,png,md,txt,json,yml}')).each do |file|
426
+ light_count += 1
427
+ light_size += File.size(file)
428
+ end
429
+
430
+ # SSD backup path (if exists)
431
+ ssd_backup = brand_info.locations.ssd_backup
432
+ ssd_path = if ssd_backup && !ssd_backup.empty? && ssd_backup != 'NOT-SET'
433
+ ssd_project_path = File.join(ssd_backup, project)
434
+ File.exist?(ssd_project_path) ? shorten_path(ssd_project_path) : nil
435
+ end
436
+
437
+ result.merge!(
438
+ heavy_files: "#{heavy_count} (#{format_size(heavy_size)})",
439
+ light_files: "#{light_count} (#{format_size(light_size)})",
440
+ ssd_backup: ssd_path
441
+ )
442
+ end
443
+
444
+ result
445
+ end
446
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/ParameterLists
447
+
320
448
  # Calculate total size of all projects in a brand
321
449
  def self.calculate_total_size(brand, projects)
322
450
  projects.sum do |project|
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Appydave
4
4
  module Tools
5
- VERSION = '0.65.0'
5
+ VERSION = '0.67.0'
6
6
  end
7
7
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.65.0",
3
+ "version": "0.67.0",
4
4
  "description": "AppyDave YouTube Automation Tools",
5
5
  "scripts": {
6
6
  "release": "semantic-release"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appydave-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.65.0
4
+ version: 0.67.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys