Class: FontProcessor::ProcessFontJob
- Inherits:
-
Object
- Object
- FontProcessor::ProcessFontJob
- Defined in:
- lib/fontprocessor/process_font_job.rb
Class Method Summary collapse
-
.client ⇒ Object
Returns a configured FontStore client.
-
.fetch_files(font_base_id, temporary_directory) ⇒ Object
Retrieves files from the FontBase and saves them to a temporary local directory.
- .log(font_base_id, charset_id, msg) ⇒ Object
-
.outline_type_to_original_filename(outline_type) ⇒ Object
Creates a suitable temporary filename for the original font files retrieved from the fontbase.
-
.perform(status_key, json_request) ⇒ Object
status_key - The redis key to update with the status of this task json_request - A String or Hash of the fully formed JSON request.
-
.process_files(font_base_id, charset_data, formats, directory, lock = true) ⇒ Object
Processes local files using a Processor and saves metadata to FontBase, if it doesn’t already exist.
-
.redis ⇒ Object
Returns the current redis connection.
-
.report_failure(key) ⇒ Object
Updates the given redis key with the failure state.
-
.report_success(key) ⇒ Object
Updates the given redis key with the success state.
-
.select_preferred_original(directory) ⇒ Object
This method fundamentally shouldn’t exist, however until we convert our processing pipeline to deal with both PostScript and TrueType files we can’t do anything about it.
-
.upload_files(fpv, font_base_id, charset_id, formats, directory) ⇒ Object
Iterates over the processed files and uploads them to S3.
-
.upload_metadata(fpv, font_base_id, metadata) ⇒ Object
Upload metadata from a processed font file to fontbase using the client.
Class Method Details
.client ⇒ Object
Returns a configured FontStore client.
102 103 104 105 106 107 108 |
# File 'lib/fontprocessor/process_font_job.rb', line 102 def self.client @client ||= FontBase::Client.new do |c| c.connection = Mongo::Connection.new(Config.mongo_host) c.db_name = Config.mongo_db c.s3_bucket = Config.s3_source_bucket end end |
.fetch_files(font_base_id, temporary_directory) ⇒ Object
Retrieves files from the FontBase and saves them to a temporary local directory.
font_base_id - The FontBase id of the font to fetch. temporary_direction - The full path to store the retrieved files. The
client is responsible for cleanup of the directory
after use.
Returns nothing. Raises FontBase::TransientError if there was an error retrieving the
files from the FontBase.
72 73 74 75 76 77 78 |
# File 'lib/fontprocessor/process_font_job.rb', line 72 def self.fetch_files(font_base_id, temporary_directory) files = client.get_files(font_base_id) files.each do |outline_type, data| filename = File.join(temporary_directory, outline_type_to_original_filename(outline_type)) File.open(filename, "wb") { |f| f.write(data) } end end |
.log(font_base_id, charset_id, msg) ⇒ Object
223 224 225 |
# File 'lib/fontprocessor/process_font_job.rb', line 223 def self.log(font_base_id, charset_id, msg) Config.logger.puts "[#{font_base_id}:#{charset_id}:#{DateTime.now.strftime("%H:%M:%S.%L")}] #{msg}" end |
.outline_type_to_original_filename(outline_type) ⇒ Object
Creates a suitable temporary filename for the original font files retrieved from the fontbase.
Note: This can’t use cff as an extension because fontforge doesn’t know how to open it properly.
outline_type - either “cff” or “ttf”
Returns a filename name for a given outline type. Raises ArgumentError if the outline_type contains an invalid value.
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/fontprocessor/process_font_job.rb', line 90 def self.outline_type_to_original_filename(outline_type) case outline_type when "cff" "original.otf" when "ttf" "original.ttf" else raise ArgumentError, "#{outline_type} must be either 'cff' or 'ttf'" end end |
.perform(status_key, json_request) ⇒ Object
status_key - The redis key to update with the status of this task json_request - A String or Hash of the fully formed JSON request. See FontProcessor::WebRequestJSON.
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 |
# File 'lib/fontprocessor/process_font_job.rb', line 9 def self.perform(status_key, json_request) json_request = JSON.parse(json_request) unless json_request.is_a? Hash # For now, we only handle web requests begin json_request['request_type'] == "web_processing_request" or raise "Invalid request type! json_request['request_type'] = #{json_request['request_type']}" charset_data = json_request['charset'] or raise "No charset in JSON Request" charset_id = charset_data['charset_id'] or raise "No charset_id set in JSON Request's charset" # check unicode and features, but don't assign to a var here charset_data['unicode'] or raise "No unicode set in JSON Request's charset" charset_data['features'] or raise "No features set in JSON Request's charset" font_base_id = json_request['font_base_id'] or raise "No font_base_id set on JSON Request" fpv = json_request['fpv'] or raise "No fpv set on JSON Request" formats = json_request['formats'] formats.has_key?('convert') or raise "No conversion set on JSON Request formats block" formats['derivatives'] or raise "No derivatives set on JSON Request formats block" formats['process_original'] or raise "No process_original value set on JSON Request formats block" rescue report_failure(status_key) raise end log(font_base_id, charset_id, "Starting processing job...") temporary_directory = "/tmp/#{font_base_id}-#{charset_id}" FileUtils.mkdir_p(temporary_directory) begin raise InvalidArgument, "charset_id is #{charset_id}, but should be one of 1, 2 or 3" unless charset_id == "1" || charset_id == "2" || charset_id == "3" fetch_files(font_base_id, temporary_directory) log(font_base_id, charset_id, "Files fetched") = process_files(font_base_id, charset_data, formats, temporary_directory) log(font_base_id, charset_id, "Files processed") (fpv, font_base_id, ) log(font_base_id, charset_id, "Metadata uploaded") upload_files(fpv, font_base_id, charset_id, formats, temporary_directory) log(font_base_id, charset_id, "Files uploaded") report_success(status_key) rescue => e report_failure(status_key) log(font_base_id, charset_id, e.) raise e ensure FileUtils.rm_rf(temporary_directory) end end |
.process_files(font_base_id, charset_data, formats, directory, lock = true) ⇒ Object
Processes local files using a Processor and saves metadata to FontBase, if it doesn’t already exist.
font_base_id - The FontBase id of the font to fetch. charset_data - A JSON blob containing the complete definition for the charset
including charset_id, features and unicode list.
formats - A JSON blob containing the formats to process
including process_orignal, convert and a derivatives array.
directory - Local directory of files to process. lock - (Testing only) boolean to determine if the raw files should
be locked or not. Useful to disable if you want to inspect
the results.
Returns a FontProcessor::FontFile object that can be used to retrieve the
processed font's metadata.
Raises Exception if an underlying external tool encounters an error while
processing a file.
127 128 129 130 131 132 133 134 135 136 |
# File 'lib/fontprocessor/process_font_job.rb', line 127 def self.process_files(font_base_id, charset_data, formats, directory, lock=true) filename = select_preferred_original(directory) naming_strategy = FontFileNamingStrategy.new(filename, directory) processor = FontProcessor::Processor.new(naming_strategy, "http://typekit.com/eulas/#{font_base_id}", font_base_id) processor.generate_char_set(charset_data, formats, lock) processor.(formats) end |
.redis ⇒ Object
Returns the current redis connection
199 200 201 |
# File 'lib/fontprocessor/process_font_job.rb', line 199 def self.redis Resque.redis.instance_variable_get("@redis") end |
.report_failure(key) ⇒ Object
Updates the given redis key with the failure state
key - The redis key to set
Returns nothing.
218 219 220 221 |
# File 'lib/fontprocessor/process_font_job.rb', line 218 def self.report_failure(key) redis.set(key, "error") redis.expire(key, 30) end |
.report_success(key) ⇒ Object
Updates the given redis key with the success state
key - The redis key to set
Returns nothing.
208 209 210 211 |
# File 'lib/fontprocessor/process_font_job.rb', line 208 def self.report_success(key) redis.set(key, "success") redis.expire(key, 24*60*60) end |
.select_preferred_original(directory) ⇒ Object
This method fundamentally shouldn’t exist, however until we convert our processing pipeline to deal with both PostScript and TrueType files we can’t do anything about it.
If a file with PostScript outlines exists, use that one. If it does not exist, use the TrueType one. If neither exist raise an exception.
Returns the filename to use as the source for our processing pipeline. Raises MissingFilesException if neither a TrueType or PostScript font are
found.
167 168 169 170 171 172 |
# File 'lib/fontprocessor/process_font_job.rb', line 167 def self.select_preferred_original(directory) files = Dir.glob(File.join(directory, "*")).map { |f| File.basename(f) } return "original.otf" if files.include?("original.otf") return "original.ttf" if files.include?("original.ttf") raise MissingFilesException, "Neither a TrueType or PostScript original font was found in #{directory.inspect}:#{files.inspect}" end |
.upload_files(fpv, font_base_id, charset_id, formats, directory) ⇒ Object
Iterates over the processed files and uploads them to S3
fpv - A String identifier for the FontProcessingVersion font_base_id - The FontBase unique id for the font to be processed. charset_id - The integer representing the character set contained within
this font. 1 is all, 2 is default and 3 is upper-and-lower.
formats - A JSON blob containing the formats to process
including process_orignal, convert and a derivatives array.
directory - Local directory of files to process.
Returns nothing. Raises Aws::S3::Errors::ServiceError if there is an error transferring a file to
Amazon.
Raises FontProcessor::MissingFilesException if an expected file failed to
be created.
189 190 191 192 193 194 195 196 |
# File 'lib/fontprocessor/process_font_job.rb', line 189 def self.upload_files(fpv, font_base_id, charset_id, formats, directory) iterator = FontProcessor::ProcessedFontIterator.new(font_base_id, charset_id, fpv, directory, formats['convert']) iterator.each do |file, s3_key| Config.s3_client.put_object(key: s3_key, body: File.binread(file), bucket: Config.s3_processed_bucket) end end |
.upload_metadata(fpv, font_base_id, metadata) ⇒ Object
Upload metadata from a processed font file to fontbase using the client.
fpv - A String identifier for the FontProcessingVersion font_base_id - The FontBase id of the font to upload metadata for. metadata - A FontProcessor::FontFile object containing the metatdata
to upload.
Returns nothing.
146 147 148 149 150 151 152 153 154 155 |
# File 'lib/fontprocessor/process_font_job.rb', line 146 def self.(fpv, font_base_id, ) client.set_font_processing_version_attributes(font_base_id, fpv, { :glyphs => .unicode, :metrics => .metrics, :names => .names, :glyph_count => .glyph_count, :optical_size => .optical_size, :features => .features }) end |