Class: ComicInfo::Issue

Inherits:
Object
  • Object
show all
Defined in:
lib/comicinfo/issue.rb

Overview

Main class for parsing and accessing ComicInfo.xml data Follows the ComicInfo XSD schema v2.0 specification

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xml_string) ⇒ Issue

Initialize from XML string

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/comicinfo/issue.rb', line 73

def initialize xml_string
  raise Errors::ParseError, 'XML string cannot be nil or empty' if xml_string.nil? || xml_string.empty?

  begin
    @doc = Nokogiri::XML(xml_string) do |config|
      config.strict.nonet
    end

    raise Errors::ParseError, "XML parsing failed: #{@doc.errors.first.message}" if @doc.errors.any?

    @root = @doc.at_css('ComicInfo')
    raise Errors::ParseError, 'No ComicInfo root element found' if @root.nil?
  rescue Nokogiri::XML::SyntaxError => e
    raise Errors::ParseError, "Invalid XML syntax: #{e.message}"
  end

  parse_fields
end

Instance Attribute Details

#age_ratingObject (readonly)

Enum fields from ComicInfo schema



24
25
26
# File 'lib/comicinfo/issue.rb', line 24

def age_rating
  @age_rating
end

#alternate_countObject (readonly)

Integer fields from ComicInfo schema



21
22
23
# File 'lib/comicinfo/issue.rb', line 21

def alternate_count
  @alternate_count
end

#alternate_numberObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def alternate_number
  @alternate_number
end

#alternate_seriesObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def alternate_series
  @alternate_series
end

#black_and_whiteObject (readonly)

Enum fields from ComicInfo schema



24
25
26
# File 'lib/comicinfo/issue.rb', line 24

def black_and_white
  @black_and_white
end

#coloristObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def colorist
  @colorist
end

#community_ratingObject (readonly)

Decimal fields from ComicInfo schema



27
28
29
# File 'lib/comicinfo/issue.rb', line 27

def community_rating
  @community_rating
end

#countObject (readonly)

Integer fields from ComicInfo schema



21
22
23
# File 'lib/comicinfo/issue.rb', line 21

def count
  @count
end

#cover_artistObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def cover_artist
  @cover_artist
end

#dayObject (readonly)

Integer fields from ComicInfo schema



21
22
23
# File 'lib/comicinfo/issue.rb', line 21

def day
  @day
end

#editorObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def editor
  @editor
end

#formatObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def format
  @format
end

#imprintObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def imprint
  @imprint
end

#inkerObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def inker
  @inker
end

#language_isoObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def language_iso
  @language_iso
end

#lettererObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def letterer
  @letterer
end

#main_character_or_teamObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def main_character_or_team
  @main_character_or_team
end

#mangaObject (readonly)

Enum fields from ComicInfo schema



24
25
26
# File 'lib/comicinfo/issue.rb', line 24

def manga
  @manga
end

#monthObject (readonly)

Integer fields from ComicInfo schema



21
22
23
# File 'lib/comicinfo/issue.rb', line 21

def month
  @month
end

#notesObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def notes
  @notes
end

#numberObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def number
  @number
end

#page_countObject (readonly)

Integer fields from ComicInfo schema



21
22
23
# File 'lib/comicinfo/issue.rb', line 21

def page_count
  @page_count
end

#pagesObject (readonly)

Array fields from ComicInfo schema



30
31
32
# File 'lib/comicinfo/issue.rb', line 30

def pages
  @pages
end

#pencillerObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def penciller
  @penciller
end

#publisherObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def publisher
  @publisher
end

#reviewObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def review
  @review
end

#scan_informationObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def scan_information
  @scan_information
end

#seriesObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def series
  @series
end

#series_groupObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def series_group
  @series_group
end

#summaryObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def summary
  @summary
end

#titleObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def title
  @title
end

#translatorObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def translator
  @translator
end

#volumeObject (readonly)

Integer fields from ComicInfo schema



21
22
23
# File 'lib/comicinfo/issue.rb', line 21

def volume
  @volume
end

#webObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def web
  @web
end

#writerObject (readonly)

String fields from ComicInfo schema



15
16
17
# File 'lib/comicinfo/issue.rb', line 15

def writer
  @writer
end

#yearObject (readonly)

Integer fields from ComicInfo schema



21
22
23
# File 'lib/comicinfo/issue.rb', line 21

def year
  @year
end

Class Method Details

.load(file_path_or_xml_string) ⇒ Object

Class method to load ComicInfo from file path or XML string

Raises:



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/comicinfo/issue.rb', line 33

def self.load file_path_or_xml_string
  raise Errors::ParseError, 'Input cannot be nil' if file_path_or_xml_string.nil?

  input = file_path_or_xml_string.to_s
  return new(input) if input.empty?

  if looks_like_xml?(input)
    new(input)
  else
    load_from_file(input)
  end
end

Instance Method Details

#black_and_white?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/comicinfo/issue.rb', line 101

def black_and_white?
  Enums::Helpers.yes_value?(@black_and_white)
end

#charactersObject



140
# File 'lib/comicinfo/issue.rb', line 140

def characters        = split_comma_separated @character

#characters_raw_dataObject



154
# File 'lib/comicinfo/issue.rb', line 154

def characters_raw_data        = @character

#cover_pagesObject

Get only cover pages



110
111
112
113
114
# File 'lib/comicinfo/issue.rb', line 110

def cover_pages
  return [] unless pages?

  @pages.select(&:cover?)
end

#genresObject Also known as: genre

Plural methods that return arrays



139
# File 'lib/comicinfo/issue.rb', line 139

def genres            = split_comma_separated @genre

#genres_raw_dataObject

Raw data methods that return the original string values



153
# File 'lib/comicinfo/issue.rb', line 153

def genres_raw_data            = @genre

#locationsObject



142
# File 'lib/comicinfo/issue.rb', line 142

def locations         = split_comma_separated @location

#locations_raw_dataObject



156
# File 'lib/comicinfo/issue.rb', line 156

def locations_raw_data         = @location

#manga?Boolean

Convenience methods for boolean checks

Returns:

  • (Boolean)


93
94
95
# File 'lib/comicinfo/issue.rb', line 93

def manga?
  Enums::Helpers.yes_value?(@manga)
end

#pages?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/comicinfo/issue.rb', line 105

def pages?
  @pages && !@pages.empty?
end

#publication_dateObject

Get publication date as Date object if available



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/comicinfo/issue.rb', line 124

def publication_date
  return nil if @year == Enums::DEFAULT_INTEGER

  year = @year
  month = @month == Enums::DEFAULT_INTEGER ? 1 : @month
  day = @day == Enums::DEFAULT_INTEGER ? 1 : @day

  begin
    Date.new(year, month, day)
  rescue ArgumentError
    nil
  end
end

#right_to_left?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/comicinfo/issue.rb', line 97

def right_to_left?
  Enums::Helpers.manga_right_to_left?(@manga)
end

#save(file_path_or_io) ⇒ Object

Save to file or IO object



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/comicinfo/issue.rb', line 228

def save file_path_or_io
  xml_content = to_xml

  case file_path_or_io
  when String
    begin
      FileUtils.mkdir_p(File.dirname(file_path_or_io))
      File.write(file_path_or_io, xml_content)
    rescue StandardError => e
      raise Errors::FileError, "Failed to write file '#{file_path_or_io}': #{e.message}"
    end
  when IO
    begin
      file_path_or_io.write(xml_content)
    rescue StandardError => e
      raise Errors::FileError, "Failed to write to IO object: #{e.message}"
    end
  else
    raise Errors::FileError, 'Invalid file path or IO object'
  end
end

#story_arc_numbersObject Also known as: story_arc_number



144
# File 'lib/comicinfo/issue.rb', line 144

def story_arc_numbers = split_comma_separated @story_arc_number

#story_arc_numbers_raw_dataObject



158
# File 'lib/comicinfo/issue.rb', line 158

def story_arc_numbers_raw_data = @story_arc_number

#story_arcsObject Also known as: story_arc



143
# File 'lib/comicinfo/issue.rb', line 143

def story_arcs        = split_comma_separated @story_arc

#story_arcs_raw_dataObject



157
# File 'lib/comicinfo/issue.rb', line 157

def story_arcs_raw_data        = @story_arc

#story_pagesObject

Get only story pages



117
118
119
120
121
# File 'lib/comicinfo/issue.rb', line 117

def story_pages
  return [] unless pages?

  @pages.select(&:story?)
end

#teamsObject



141
# File 'lib/comicinfo/issue.rb', line 141

def teams             = split_comma_separated @team

#teams_raw_dataObject



155
# File 'lib/comicinfo/issue.rb', line 155

def teams_raw_data             = @team

#to_hObject

Convert to hash representation for JSON serialization



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/comicinfo/issue.rb', line 261

def to_h
  {
    title:                      @title,
    series:                     @series,
    number:                     @number,
    count:                      @count,
    volume:                     @volume,
    alternate_series:           @alternate_series,
    alternate_number:           @alternate_number,
    alternate_count:            @alternate_count,
    summary:                    @summary,
    notes:                      @notes,
    year:                       @year,
    month:                      @month,
    day:                        @day,
    writer:                     @writer,
    penciller:                  @penciller,
    inker:                      @inker,
    colorist:                   @colorist,
    letterer:                   @letterer,
    cover_artist:               @cover_artist,
    editor:                     @editor,
    translator:                 @translator,
    publisher:                  @publisher,
    imprint:                    @imprint,
    genre:                      @genre,
    genres_raw_data:            genres_raw_data,
    genres:                     genres,
    web:                        @web,
    web_urls:                   web_urls,
    page_count:                 @page_count,
    language_iso:               @language_iso,
    format:                     @format,
    black_and_white:            @black_and_white,
    manga:                      @manga,
    characters_raw_data:        characters_raw_data,
    characters:                 characters,
    teams_raw_data:             teams_raw_data,
    teams:                      teams,
    locations_raw_data:         locations_raw_data,
    locations:                  locations,
    scan_information:           @scan_information,
    story_arc:                  @story_arc,
    story_arcs_raw_data:        story_arcs_raw_data,
    story_arcs:                 story_arcs,
    story_arc_number:           @story_arc_number,
    story_arc_numbers_raw_data: story_arc_numbers_raw_data,
    story_arc_numbers:          story_arc_numbers,
    series_group:               @series_group,
    age_rating:                 @age_rating,
    main_character_or_team:     @main_character_or_team,
    community_rating:           @community_rating,
    review:                     @review,
    pages:                      @pages.map(&:to_h)
  }.compact
end

#to_jsonObject

Convert to JSON representation



251
252
253
# File 'lib/comicinfo/issue.rb', line 251

def to_json(*)
  to_h.to_json(*)
end

#to_xmlObject

Convert to XML representation



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
221
222
223
224
225
# File 'lib/comicinfo/issue.rb', line 166

def to_xml
  doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
    xml.ComicInfo('xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
                  'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema') do
      # String fields in schema order
      xml.Title(@title) unless @title == Enums::DEFAULT_STRING
      xml.Series(@series) unless @series == Enums::DEFAULT_STRING
      xml.Number(@number) unless @number == Enums::DEFAULT_STRING
      xml.Count(@count) unless @count == Enums::DEFAULT_INTEGER
      xml.Volume(@volume) unless @volume == Enums::DEFAULT_INTEGER
      xml.AlternateSeries(@alternate_series) unless @alternate_series == Enums::DEFAULT_STRING
      xml.AlternateNumber(@alternate_number) unless @alternate_number == Enums::DEFAULT_STRING
      xml.AlternateCount(@alternate_count) unless @alternate_count == Enums::DEFAULT_INTEGER
      xml.Summary(@summary) unless @summary == Enums::DEFAULT_STRING
      xml.Notes(@notes) unless @notes == Enums::DEFAULT_STRING
      xml.Year(@year) unless @year == Enums::DEFAULT_INTEGER
      xml.Month(@month) unless @month == Enums::DEFAULT_INTEGER
      xml.Day(@day) unless @day == Enums::DEFAULT_INTEGER
      xml.Writer(@writer) unless @writer == Enums::DEFAULT_STRING
      xml.Penciller(@penciller) unless @penciller == Enums::DEFAULT_STRING
      xml.Inker(@inker) unless @inker == Enums::DEFAULT_STRING
      xml.Colorist(@colorist) unless @colorist == Enums::DEFAULT_STRING
      xml.Letterer(@letterer) unless @letterer == Enums::DEFAULT_STRING
      xml.CoverArtist(@cover_artist) unless @cover_artist == Enums::DEFAULT_STRING
      xml.Editor(@editor) unless @editor == Enums::DEFAULT_STRING
      xml.Translator(@translator) unless @translator == Enums::DEFAULT_STRING
      xml.Publisher(@publisher) unless @publisher == Enums::DEFAULT_STRING
      xml.Imprint(@imprint) unless @imprint == Enums::DEFAULT_STRING
      xml.Genre(@genre) unless @genre == Enums::DEFAULT_STRING
      xml.Web(@web) unless @web == Enums::DEFAULT_STRING
      xml.PageCount(@page_count) unless @page_count == Enums::DEFAULT_PAGE_COUNT
      xml.LanguageISO(@language_iso) unless @language_iso == Enums::DEFAULT_STRING
      xml.Format(@format) unless @format == Enums::DEFAULT_STRING
      xml.BlackAndWhite(@black_and_white) unless @black_and_white == Enums::DEFAULT_ENUM_UNKNOWN
      xml.Manga(@manga) unless @manga == Enums::DEFAULT_ENUM_UNKNOWN
      xml.Characters(@character) unless @character == Enums::DEFAULT_STRING
      xml.Teams(@team) unless @team == Enums::DEFAULT_STRING
      xml.Locations(@location) unless @location == Enums::DEFAULT_STRING
      xml.ScanInformation(@scan_information) unless @scan_information == Enums::DEFAULT_STRING
      xml.StoryArc(@story_arc) unless @story_arc == Enums::DEFAULT_STRING
      xml.StoryArcNumber(@story_arc_number) unless @story_arc_number == Enums::DEFAULT_STRING
      xml.SeriesGroup(@series_group) unless @series_group == Enums::DEFAULT_STRING
      xml.AgeRating(@age_rating) unless @age_rating == Enums::DEFAULT_ENUM_UNKNOWN
      xml.MainCharacterOrTeam(@main_character_or_team) unless @main_character_or_team == Enums::DEFAULT_STRING
      xml.CommunityRating(@community_rating) unless @community_rating.nil?
      xml.Review(@review) unless @review == Enums::DEFAULT_STRING

      # Pages section
      if @pages && !@pages.empty?
        xml.Pages do
          @pages.each do |page|
            xml.Page(page.to_xml_attributes)
          end
        end
      end
    end
  end

  doc.to_xml
end

#to_yamlObject

Convert to YAML representation



256
257
258
# File 'lib/comicinfo/issue.rb', line 256

def to_yaml(*)
  to_h.to_yaml(*)
end

#web_urlsObject



146
147
148
149
150
# File 'lib/comicinfo/issue.rb', line 146

def web_urls
  return [] if @web.empty?

  @web.split(/\s+/)
end