Image Shifting Documentation
This document describes the image shifting functionality that allows you to move images up to fill empty slots in the image type order.
Overview
The image shifting system consists of:
Image::ImageShiftingService- Core service class with all business logic- Rake tasks - Command-line interface for bulk operations
- Model methods - Convenience methods on Item model
- Controller integration - Can be called from Rails controllers
Service Class
The main service class is Image::ImageShiftingService located at app/services/image/image_shifting_service.rb.
Key Methods
shift_images_for_item(item_id, locale: 'en', prefix: nil)
Shifts images for a specific item to fill empty slots in the image type order.
Parameters:
item_id(Integer) - The ID of the item to shift images forlocale(String) - The locale for the images (default: 'en')prefix(String, nil) - Optional prefix to limit shifting to a specific group (e.g., 'AMZ', 'WAL')
Returns: Hash with result information
{
success: true,
errors: [],
changes_made: false,
before_profiles: ['AMZ_MAIN', 'AMZ_PT01', 'AMZ_PT02'],
after_profiles: ['AMZ_MAIN', 'AMZ_FRNT', 'AMZ_SIDE'],
item: #<Item>
}
Example:
result = Image::ImageShiftingService.shift_images_for_item(123, locale: 'en', prefix: 'AMZ')
if result[:success] && result[:changes_made]
puts "Images shifted successfully!"
end
shift_images_for_all_items(locale: 'en', prefix: nil, batch_size: 100, dry_run: false)
Shifts images for all items that have image profiles.
Parameters:
locale(String) - The locale for the images (default: 'en')prefix(String, nil) - Optional prefix to limit shifting to a specific groupbatch_size(Integer) - Number of items to process in each batch (default: 100)dry_run(Boolean) - If true, only shows what would be done without making changes (default: false)
Returns: Hash with summary information
{
processed_items: 150,
items_with_changes: 45,
total_changes: 45,
errors: [],
dry_run: false,
total_items: 150
}
Example:
result = Image::ImageShiftingService.shift_images_for_all_items(
locale: 'en',
prefix: 'AMZ',
batch_size: 50,
dry_run: true
)
puts "Would process #{result[:total_items]} items"
analyze_missing_sequences(locale: 'en', prefix: nil)
Analyzes missing sequences in image profiles.
Parameters:
locale(String) - The locale for the images (default: 'en')prefix(String, nil) - Optional prefix to limit analysis to a specific group
Returns: Hash with analysis results
{
total_items: 150,
items_with_gaps: 45,
total_gaps: 67,
items_with_complete_sequences: 105,
gap_details: [...],
prefix_groups: {
'AMZ' => { items_with_gaps: 30, total_gaps: 45, gap_details: [...] },
'WAL' => { items_with_gaps: 15, total_gaps: 22, gap_details: [...] }
}
}
Example:
result = Image::ImageShiftingService.analyze_missing_sequences(locale: 'en', prefix: 'AMZ')
puts "Found #{result[:items_with_gaps]} items with gaps"
find_missing_image_type(image_type, locale: 'en', prefix: nil, limit: 50)
Finds items missing a specific image type.
Parameters:
image_type(String) - The image type to search forlocale(String) - The locale for the images (default: 'en')prefix(String, nil) - Optional prefix to limit search to a specific grouplimit(Integer) - Maximum number of items to return (default: 50)
Returns: Hash with missing items information
{
image_type: 'AMZ_FRNT',
total_missing: 25,
missing_items: [
{ item: #<Item>, current_images: ['AMZ_MAIN', 'AMZ_PT01'] },
...
],
limit: 50
}
Example:
result = Image::ImageShiftingService.find_missing_image_type('AMZ_FRNT', locale: 'en', prefix: 'AMZ')
puts "Found #{result[:total_missing]} items missing AMZ_FRNT"
Rake Tasks
The rake tasks provide a command-line interface for the service methods.
rake images:shift_for_item[ITEM_ID,PREFIX,LOCALE]
Shifts images for a specific item.
Examples:
# Shift all image groups for item 123
rake images:shift_for_item[123]
# Shift only Amazon images for item 123
rake images:shift_for_item[123,AMZ]
# Shift only Walmart images for item 123 in French locale
rake images:shift_for_item[123,WAL,fr]
rake images:shift_all_items[PREFIX,BATCH_SIZE,DRY_RUN,LOCALE]
Shifts images for all items with image profiles.
Examples:
# Shift all items (will prompt for confirmation)
rake images:shift_all_items
# Dry run for Amazon images
rake images:shift_all_items[AMZ,100,true]
# Shift Walmart images with batch size 50
rake images:shift_all_items[WAL,50,false]
rake images:analyze_missing[PREFIX,LOCALE,SHOW_DETAILS]
Analyzes missing sequences in image profiles.
Examples:
# Analyze all image groups
rake images:analyze_missing
# Analyze only Amazon images
rake images:analyze_missing[AMZ]
# Show detailed breakdown for Amazon images
rake images:analyze_missing[AMZ,en,true]
rake images:find_missing_type[IMAGE_TYPE,PREFIX,LOCALE]
Finds items missing a specific image type.
Examples:
# Find items missing AMZ_FRNT
rake images:find_missing_type[AMZ_FRNT,AMZ]
# Find items missing WAL_MAIN
rake images:find_missing_type[WAL_MAIN,WAL]
rake images:show_for_item[ITEM_ID,PREFIX,LOCALE]
Shows current image profiles for a specific item.
Examples:
# Show all image groups for item 123
rake images:show_for_item[123]
# Show only Amazon images for item 123
rake images:show_for_item[123,AMZ]
rake images:show_types
Shows all image types and their order for reference.
Model Integration
Item Model
The Item model has a convenience method:
# Shift images for this item
item.shift_images(locale: 'en', prefix: 'AMZ')
# Returns the same result hash as the service method
result = item.shift_images(locale: 'en', prefix: 'AMZ')
if result[:changes_made]
puts "Images were shifted"
end
Controller Integration
The service can be called from Rails controllers. The CRM interface provides a web-based way to manage image profiles:
CRM Interface
The image profile management is accessible through the CRM marketing menu via the "Image Profile Manager" link. The main index page provides access to all functionality:
- Main Pivot Table - Shows all image profiles grouped by item with thumbnails
- Individual Item Actions - Shift AMZ/WAL images for specific items
- Bulk Operations - Modal for bulk shifting across all items
- Analyze Missing Sequences - Dedicated page for gap analysis
- Search & Filter - Advanced filtering and sorting capabilities
Controller Example
class Crm::ImageProfilesController < CrmController
def shift_item
item_id = params[:item_id]
prefix = params[:prefix]
locale = params[:locale] || 'en'
result = Image::ImageShiftingService.shift_images_for_item(
item_id,
locale: locale,
prefix: prefix
)
if result[:success]
if result[:changes_made]
redirect_to admin_item_path(item_id), notice: 'Images shifted successfully!'
else
redirect_to admin_item_path(item_id), notice: 'No changes needed'
end
else
redirect_to admin_item_path(item_id), alert: "Error: #{result[:errors].join(', ')}"
end
end
def analyze_missing
prefix = params[:prefix]
locale = params[:locale] || 'en'
@analysis = Image::ImageShiftingService.analyze_missing_sequences(
locale: locale,
prefix: prefix
)
end
def bulk_shift
prefix = params[:prefix]
locale = params[:locale] || 'en'
dry_run = params[:dry_run] == 'true'
result = Image::ImageShiftingService.shift_images_for_all_items(
locale: locale,
prefix: prefix,
batch_size: 100,
dry_run: dry_run
)
if result[:errors].any?
redirect_to admin_image_profiles_path, alert: "Errors occurred: #{result[:errors].join(', ')}"
else
= dry_run ? "Dry run completed" : "Bulk shift completed"
redirect_to admin_image_profiles_path, notice: "#{}. Processed #{result[:processed_items]} items."
end
end
end
Image Type Order
The system uses the following image type order (defined in ImageProfile::IMAGE_TYPES):
Amazon Images (AMZ)
AMZ_MAIN- Amazon Main imageAMZ_FRNT- Amazon Front angle shotAMZ_SIDE- Amazon Side angle shotAMZ_BACK- Amazon Back angle shotAMZ_PT01throughAMZ_PT11- Amazon Part shotsAMZ_SWCH- Amazon Swatch shots (never shifted)
Walmart Images (WAL)
WAL_MAIN- Walmart Main imageWAL_AD01throughWAL_AD10- Walmart Additional imagesWAL_SWCH- Walmart Swatch shots (never shifted)
Gap Detection Logic
A "gap" is defined as a missing image type that comes between existing image types in the ordered sequence. For example:
- Current:
AMZ_MAIN, AMZ_PT01, AMZ_PT02, AMZ_PT03, AMZ_PT04 - Missing:
AMZ_FRNT, AMZ_SIDE, AMZ_BACK, AMZ_PT05, AMZ_PT06, AMZ_PT07, AMZ_PT08, AMZ_PT09, AMZ_PT10, AMZ_PT11, AMZ_SWCH - Gaps:
AMZ_FRNT, AMZ_SIDE, AMZ_BACK(3 gaps)
Only the first three missing types are considered gaps because they come between existing images. Missing types after the last existing image are not considered gaps.
Swatch Shot Protection
Swatch shots (AMZ_SWCH, WAL_SWCH) are never shifted or moved. They remain in their original positions regardless of gaps in the sequence.
Error Handling
All service methods return structured results with error information:
result = Image::ImageShiftingService.shift_images_for_item(123)
if result[:success]
# Operation succeeded
puts "Changes made: #{result[:changes_made]}"
else
# Operation failed
puts "Errors: #{result[:errors].join(', ')}"
end
Performance Considerations
- Batch processing: Use
batch_sizeparameter for large operations - Dry runs: Use
dry_run: trueto test operations without making changes - Prefix filtering: Use
prefixparameter to limit operations to specific image groups - Database transactions: All operations are wrapped in transactions for data consistency