Class: Deliver::AppMetadata
- Inherits:
-
Object
- Object
- Deliver::AppMetadata
- Defined in:
- lib/deliver/app_metadata.rb,
lib/deliver/app_metadata_screenshots.rb
Direct Known Subclasses
Constant Summary collapse
- ITUNES_NAMESPACE =
"http://apple.com/itunes/importer"
- INVALID_LANGUAGE_ERROR =
"The specified language could not be found. Make sure it is available in Deliver::Languages::ALL_LANGUAGES"
Instance Attribute Summary collapse
-
#information ⇒ Object
Data contains all information for this app, including the unmodified one.
Updating metadata information collapse
-
#update_changelog(hash) ⇒ Object
Updates the app changelog of the latest version.
-
#update_description(hash) ⇒ Object
Updates the app description which is shown in the AppStore.
-
#update_keywords(hash) ⇒ Object
Updates the app keywords.
-
#update_marketing_url(hash) ⇒ Object
Updates the Marketing URL.
-
#update_price_tier(tier) ⇒ Object
Updates the price tier of the given app.
-
#update_privacy_url(hash) ⇒ Object
Updates the Privacy URL.
-
#update_support_url(hash) ⇒ Object
Updates the Support URL.
-
#update_title(hash) ⇒ Object
Updates the app title.
Manually fetching elements from the metadata.xml collapse
-
#fetch_value(xpath) ⇒ Object
Directly fetch XML nodes from the metadata.xml.
Uploading the updated metadata collapse
-
#upload! ⇒ Object
Actually uploads the updated metadata to Apple.
Screenshot related collapse
-
#add_screenshot(language, app_screenshot) ⇒ Object
Appends another screenshot to the already existing ones.
-
#clear_all_screenshots(language) ⇒ Object
Removes all currently enabled screenshots for the given language.
-
#set_all_screenshots(new_screenshots) ⇒ bool
This method will clear all screenshots and set the new ones you pass This method uses #clear_all_screenshots and #add_screenshot under the hood.
-
#set_all_screenshots_from_path(path) ⇒ Object
This method will run through all the available locales, check if there is a folder for this language (e.g. ‘en-US’) and use all screenshots in there.
-
#set_screenshots_for_each_language(hash) ⇒ Object
Automatically add all screenshots contained in the given directory to the app.
Instance Method Summary collapse
-
#add_new_locale(language) ⇒ Bool
Adds a new locale (language) to the given app.
-
#initialize(app, dir, redownload_package = true) ⇒ AppMetadata
constructor
You don’t have to manually create an AppMetadata object.
-
#verify_version(version_number) ⇒ Object
Verifies the if the version of iTunesConnect matches the one you pass as parameter.
Constructor Details
#initialize(app, dir, redownload_package = true) ⇒ AppMetadata
You don’t have to manually create an AppMetadata object. It will be created when you access the app’s metadata (Deliver::App#metadata)
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/deliver/app_metadata.rb', line 49 def initialize(app, dir, redownload_package = true) raise AppMetadataParameterError.new("No valid Deliver::App given") unless app.kind_of?Deliver::App @metadata_dir = dir @app = app if self.class == AppMetadata if redownload_package # Delete the one that may exists already unless Helper.is_test? `rm -rf #{dir}/*.itmsp` end # we want to update the metadata, so first we have to download the existing one transporter.download(app, dir) # Parse the downloaded package parse_package(dir) else # use_data contains the data to be used. This is the case for unit tests parse_package(dir) end end end |
Instance Attribute Details
#information ⇒ Object
Returns Data contains all information for this app, including the unmodified one.
18 19 20 |
# File 'lib/deliver/app_metadata.rb', line 18 def information @information end |
Instance Method Details
#add_new_locale(language) ⇒ Bool
Adds a new locale (language) to the given app
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 |
# File 'lib/deliver/app_metadata.rb', line 90 def add_new_locale(language) unless Deliver::Languages::ALL_LANGUAGES.include?language raise "Language '#{language}' is invalid. It must be in #{Deliver::Languages::ALL_LANGUAGES}." end if information[language] != nil Helper.log.info("Locale '#{language}' already exists. Can not create it again.") return false end locales = fetch_value("//x:locales").first new_locale = @data.create_element('locale') new_locale['name'] = language locales << new_locale # Title is the only thing which is required by iTC default_title = information.values.first[:title][:value] title = @data.create_element('title') title.content = default_title new_locale << title Helper.log.info("Successfully created the new locale '#{language}'. The default title '#{default_title}' was set, since it's required by iTunesConnect.") Helper.log.info("You can update the title using 'app.metadata.update_title'") information[language] ||= {} information[language][:title] = { value: default_title, modified: true} true end |
#add_screenshot(language, app_screenshot) ⇒ Object
Appends another screenshot to the already existing ones
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 |
# File 'lib/deliver/app_metadata_screenshots.rb', line 24 def add_screenshot(language, app_screenshot) raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language create_locale_if_not_exists(language) # Fetch the 'software_screenshots' node (array) for the specific locale locales = self.fetch_value("//x:locale[@name='#{language}']") screenshots = self.fetch_value("//x:locale[@name='#{language}']/x:software_screenshots").first if not screenshots or screenshots.children.count == 0 screenshots.remove if screenshots # First screenshot ever screenshots = Nokogiri::XML::Node.new('software_screenshots', @data) locales.first << screenshots node_set = Nokogiri::XML::NodeSet.new(@data) node_set << app_screenshot.create_xml_node(@data, 1) screenshots.children = node_set else # There is already at least one screenshot next_index = 1 screenshots.children.each do |screen| if screen['display_target'] == app_screenshot.screen_size next_index += 1 end end if next_index > MAXIMUM_NUMBER_OF_SCREENSHOTS raise AppMetadataTooManyScreenshotsError.new("Only #{MAXIMUM_NUMBER_OF_SCREENSHOTS} screenshots are allowed per language per device type (#{app_screenshot.screen_size})") end # Ready for storing the screenshot into the metadata.xml now screenshots.children.after(app_screenshot.create_xml_node(@data, next_index)) end information[language][:screenshots] << app_screenshot app_screenshot.store_file_inside_package(@package_path) end |
#clear_all_screenshots(language) ⇒ Object
Removes all currently enabled screenshots for the given language.
9 10 11 12 13 14 15 16 17 |
# File 'lib/deliver/app_metadata_screenshots.rb', line 9 def clear_all_screenshots(language) raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language update_localized_value('software_screenshots', {language => {}}) do |field, useless, language| field.children.remove # remove all the screenshots end information[language][:screenshots] = [] true end |
#fetch_value(xpath) ⇒ Object
Directly fetch XML nodes from the metadata.xml.
224 225 226 |
# File 'lib/deliver/app_metadata.rb', line 224 def fetch_value(xpath) @data.xpath(xpath, "x" => ITUNES_NAMESPACE) end |
#set_all_screenshots(new_screenshots) ⇒ bool
This method will clear all screenshots and set the new ones you pass This method uses #clear_all_screenshots and #add_screenshot under the hood.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/deliver/app_metadata_screenshots.rb', line 79 def set_all_screenshots(new_screenshots) error_text = "Please pass a hash, containing an array of AppScreenshot objects" raise AppMetadataParameterError.new(error_text) unless new_screenshots.kind_of?Hash new_screenshots.each do |key, value| if key.kind_of?String and value.kind_of?Array and value.count > 0 and value.first.kind_of?AppScreenshot self.clear_all_screenshots(key) value.each do |screen| add_screenshot(key, screen) end else raise AppMetadataParameterError.new(error_text) end end true end |
#set_all_screenshots_from_path(path) ⇒ Object
This method will run through all the available locales, check if there is a folder for this language (e.g. ‘en-US’) and use all screenshots in there
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/deliver/app_metadata_screenshots.rb', line 137 def set_all_screenshots_from_path(path) raise AppMetadataParameterError.new("Parameter needs to be a path (string)") unless path.kind_of?String found = false Deliver::Languages::ALL_LANGUAGES.each do |language| full_path = path + "/#{language}" if File.directory?(full_path) found = true set_screenshots_for_each_language({ language => full_path }) end end return found end |
#set_screenshots_for_each_language(hash) ⇒ Object
Automatically add all screenshots contained in the given directory to the app.
This method will automatically detect which device type each screenshot is.
This will also clear all existing screenshots before setting the new ones.
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 |
# File 'lib/deliver/app_metadata_screenshots.rb', line 104 def set_screenshots_for_each_language(hash) raise AppMetadataParameterError.new("Parameter needs to be an hash, containg strings with the new description") unless hash.kind_of?Hash hash.each do |language, current_path| resulting_path = "#{current_path}/**/*.{png,jpg,jpeg}" raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language # https://stackoverflow.com/questions/21688855/ # File::FNM_CASEFOLD = ignore case if Dir.glob(resulting_path, File::FNM_CASEFOLD).count == 0 Helper.log.error("No screenshots found at the given path '#{resulting_path}'") else self.clear_all_screenshots(language) Dir.glob(resulting_path, File::FNM_CASEFOLD).sort.each do |path| next if path.include?"_framed." begin add_screenshot(language, Deliver::AppScreenshot.new(path)) rescue AppMetadataTooManyScreenshotsError => ex # We just use the first 5 ones end end end end true end |
#update_changelog(hash) ⇒ Object
Updates the app changelog of the latest version
148 149 150 |
# File 'lib/deliver/app_metadata.rb', line 148 def update_changelog(hash) (:version_whats_new, hash) end |
#update_description(hash) ⇒ Object
Updates the app description which is shown in the AppStore
140 141 142 |
# File 'lib/deliver/app_metadata.rb', line 140 def update_description(hash) (:description, hash) end |
#update_keywords(hash) ⇒ Object
Updates the app keywords
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/deliver/app_metadata.rb', line 180 def update_keywords(hash) update_localized_value('keywords', hash) do |field, keywords, language| raise AppMetadataParameterError.new("Parameter needs to be a hash (each language) with an array of keywords in it (given: #{hash})") unless keywords.kind_of?Array if not information[language][:keywords] or keywords.sort != information[language][:keywords][:value].sort field.children.remove # remove old keywords node_set = Nokogiri::XML::NodeSet.new(@data) keywords.each do |word| keyword = Nokogiri::XML::Node.new('keyword', @data) keyword.content = word node_set << keyword end field.children = node_set information[language][:keywords] = { value: keywords, modified: true } end end end |
#update_marketing_url(hash) ⇒ Object
Updates the Marketing URL
156 157 158 |
# File 'lib/deliver/app_metadata.rb', line 156 def update_marketing_url(hash) (:software_url, hash) end |
#update_price_tier(tier) ⇒ Object
Updates the price tier of the given app
203 204 205 206 207 208 209 210 |
# File 'lib/deliver/app_metadata.rb', line 203 def update_price_tier(tier) raise "Price Tier '#{tier}' must be of type integer".red unless tier.kind_of?Integer raise "Invalid price tier '#{tier}' given, must be 0 to 94".red unless (tier.to_i >= 0 and tier.to_i <= 87) price = fetch_value("//x:wholesale_price_tier").last raise "No initial pricing found, please set the pricing at least once on iTunes Connect.".red unless price price.content = tier end |
#update_privacy_url(hash) ⇒ Object
Updates the Privacy URL
172 173 174 |
# File 'lib/deliver/app_metadata.rb', line 172 def update_privacy_url(hash) (:privacy_url, hash) end |
#update_support_url(hash) ⇒ Object
Updates the Support URL
164 165 166 |
# File 'lib/deliver/app_metadata.rb', line 164 def update_support_url(hash) (:support_url, hash) end |
#update_title(hash) ⇒ Object
Updates the app title
132 133 134 |
# File 'lib/deliver/app_metadata.rb', line 132 def update_title(hash) (:title, hash) end |
#upload! ⇒ Object
Actually uploads the updated metadata to Apple. This method might take a while.
237 238 239 240 241 242 243 244 |
# File 'lib/deliver/app_metadata.rb', line 237 def upload! unless Helper.is_test? # First: Write the current XML state to disk File.write("#{@package_path}/#{METADATA_FILE_NAME}", @data.to_xml) end transporter.upload(@app, @metadata_dir) end |
#verify_version(version_number) ⇒ Object
Verifies the if the version of iTunesConnect matches the one you pass as parameter
79 80 81 82 83 |
# File 'lib/deliver/app_metadata.rb', line 79 def verify_version(version_number) xml_version = self.fetch_value("//x:version").first['string'] raise "Version mismatch: on iTunesConnect the latest version is '#{xml_version}', you specified '#{version_number}'" if xml_version != version_number true end |