Class: Kontrast::GalleryCreator

Inherits:
Object
  • Object
show all
Defined in:
lib/kontrast/gallery_creator.rb

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ GalleryCreator

Returns a new instance of GalleryCreator.



6
7
8
# File 'lib/kontrast/gallery_creator.rb', line 6

def initialize(path)
    @path = path || Kontrast.path
end

Instance Method Details

#base_pathObject



92
93
94
95
96
97
98
99
100
# File 'lib/kontrast/gallery_creator.rb', line 92

def base_path
    # This determines where to display images from in the gallery
    if Kontrast.configuration.run_parallel
        # Build the remote path to S3
        return "https://#{Kontrast.configuration.aws_bucket}.s3.amazonaws.com/#{Kontrast.configuration.remote_path}"
    else
        return ".."
    end
end

This gets run only once per suite. It collects the manifests from all nodes and uses them to generate a nice gallery of images.



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
# File 'lib/kontrast/gallery_creator.rb', line 12

def create_gallery(output_dir)
    begin
        @gallery_dir = FileUtils.mkdir_p("#{output_dir}/gallery").join('')
    rescue StandardError => e
        raise GalleryException.new("An unexpected error occurred while trying to create the gallery's output directory: #{e.inspect}")
    end

    # Get and parse manifests
    parsed_manifests = parse_manifests(get_manifests)
    files = parsed_manifests[:files]
    diffs = parsed_manifests[:diffs]

    # Generate HTML
    html = generate_html(files, diffs)

    # Write file
    File.open("#{@gallery_dir}/gallery.html", 'w') do |outf|
        outf.write(html)
    end

    # Upload file
    if Kontrast.configuration.run_parallel
        Kontrast.fog.directories.get(Kontrast.configuration.aws_bucket).files.create(
            key: "#{Kontrast.configuration.remote_path}/gallery/gallery.html",
            body: File.open("#{@gallery_dir}/gallery.html")
        )
    end

    # Return diffs and gallery path
    return {
        diffs: diffs,
        path: "#{@gallery_dir}/gallery.html"
    }
end

#generate_html(files, diffs) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/kontrast/gallery_creator.rb', line 47

def generate_html(files, diffs)
    # Template variables
    groups, without_diffs, with_diffs = parse_directories(files, diffs)

    # HTML
    template = File.read(Kontrast.root + '/lib/kontrast/gallery/template.erb')
    return ERB.new(template).result(binding)
end

#get_manifestsObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/kontrast/gallery_creator.rb', line 56

def get_manifests
    if Kontrast.configuration.run_parallel
        # Download manifests
        files = Kontrast.fog.directories.get(Kontrast.configuration.aws_bucket, prefix: "#{Kontrast.configuration.remote_path}/manifest").files
        files.each do |file|
            filename = "#{@path}/" + file.key.split('/').last
            File.open(filename, 'w') do |local_file|
                local_file.write(file.body)
            end
        end
    end
    manifest_files = Dir["#{@path}/manifest_*.json"]
    return manifest_files
end

#parse_directories(files, diffs) ⇒ Object

This function just turns the list of files and diffs into a hash that the gallery creator can insert into a template. See an example of the created hash below.



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
# File 'lib/kontrast/gallery_creator.rb', line 156

def parse_directories(files, diffs)
    files.sort!

    # Initialize those hashes, where each key will map to hash, in wich
    # each key maps to an array:
    # {
    #   key1: {
    #   },
    #   key2: {
    #   },
    # }
    #
    without_diffs = Hash.new { |h,k| h[k] = {} }
    with_diffs = Hash.new { |h,k| h[k] = {} }

    directories = files.map { |f| f.split('/').first }.uniq
    groups = directories.map { |dir| dir.split('_').first }.uniq


    # Fill in the files as variants
    directories.each do |directory|
        group = directory.split('_')[0]
        test_name = test_name_from_dir(directory)

        # Determines the type of test by the presence of the diff.png
        # file in the folder.
        # Ideally the manifest file format would be different and
        # include the test type with
        if files.select { |file_name| file_name.start_with?(directory) }.any? { |file_name| file_name.include?('diff.png') }
            variants = variants_for_page(directory, diffs)
        else
            variants = variants_for_api_endpoint(directory, diffs, files)
        end

        if diffs[directory]
            with_diffs[group][test_name] = variants
        else
            without_diffs[group][test_name] = variants
        end
    end

    return groups, without_diffs, with_diffs

    # For reference
    # gallery_format = {
    #     "1080" => {
    #         "name" => [
    #             {
    #                 image: "full_img_src",
    #                 thumb: "thumb_src",
    #                 domain: "production"
    #             }, {
    #                 image: "foo_src",
    #                 thumb: "thumb_src",
    #                 domain: "test"
    #             }, {
    #                 image: "diff_src",
    #                 thumb: "diff_thumb_src",
    #                 domain: "diff",
    #                 diff_amt: 0.1
    #             }
    #         }
    #     }
    # }
end

#parse_manifests(manifest_files) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/kontrast/gallery_creator.rb', line 71

def parse_manifests(manifest_files)
    files = []
    diffs = {}
    manifest_files.each do |manifest|
        manifest = JSON.parse(File.read(manifest))
        files.concat(manifest['files'])
        diffs.merge!(manifest["diffs"])
    end

    return {
        files: files,
        diffs: diffs
    }
end

#test_name_from_dir(dir) ⇒ Object



86
87
88
89
90
# File 'lib/kontrast/gallery_creator.rb', line 86

def test_name_from_dir(dir)
    # dir is a string prefixed with a group name:
    # '1280_home' or '2x_home_screen'
    return dir.split('_')[1..-1].join('_')
end

#variants_for_api_endpoint(directory, diffs, files) ⇒ Object



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
# File 'lib/kontrast/gallery_creator.rb', line 122

def variants_for_api_endpoint(directory, diffs, files)
    # Return a hash that will be used in the erb template to show the
    # diffs for a given test.
    variants = []
    ['test', 'production', 'diff'].each do |type|
        variant = {
            file: "#{base_path}/#{directory}/#{type}.json",
            domain: type,
            type: 'api_endpoint',
            diff_amt: 0,
        }
        if diffs[directory]
            variant[:diff_amt] = 1
        end

        # Get all images
        image_files = files.select { |file_name|
            file_name.match /#{directory}\/#{type}_\d+.(jpg|png)/
        }.map { |file_name|
            name_without_extension = file_name.split('.')[0..-2].join('.')
            {
                image: "#{base_path}/#{file_name}",
                thumb: "#{base_path}/#{name_without_extension}_thumb.png",
            }
        }
        variant[:images] = image_files
        variants << variant
    end

    return variants
end

#variants_for_page(directory, diffs) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/kontrast/gallery_creator.rb', line 102

def variants_for_page(directory, diffs)
    # Return a hash that will be used in the erb template to show the
    # diffs for a given test.
    variants = []
    ['test', 'production', 'diff'].each do |type|
        variant = {
            image: "#{base_path}/#{directory}/" + type + ".png",
            thumb: "#{base_path}/#{directory}/" + type + "_thumb.png",
            domain: type,
            type: 'page',
        }
        if type == 'diff' && diffs[directory]
            variant[:diff_amt] = diffs[directory]["diff"]
        end
        variants << variant
    end

    return variants
end