From d9ca6d297d28d0afe3e9276e38d872edb840c699 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 14:53:47 +0200 Subject: [PATCH 01/13] fix tags and add support for v3.3.0 Signed-off-by: Flipez --- .github/workflows/main.yml | 6 + .rubocop.yml | 8 +- .rubocop_todo.yml | 52 + Gemfile.lock | 27 + lib/uddf.rb | 5 +- lib/uddf/base/models.rb | 8 + lib/uddf/v323/models.rb | 586 +++--- lib/uddf/v330/models.rb | 1744 +++++++++++++++++ spec/spec_helper.rb | 18 + spec/uddf_parser_spec.rb | 191 ++ spec/uddf_spec.rb | 9 + ...Peregrine TX[93CBB2BB]#140_2025-03-21.uddf | 0 ...Peregrine TX[93CBB2BB]#148_2025-06-26.uddf | 0 test_files/v330/diver_data.uddf | 6 +- uddf.gemspec | 3 + 15 files changed, 2356 insertions(+), 307 deletions(-) create mode 100644 .rubocop_todo.yml create mode 100644 lib/uddf/v330/models.rb create mode 100644 spec/spec_helper.rb create mode 100644 spec/uddf_parser_spec.rb create mode 100644 spec/uddf_spec.rb rename {dive_files => test_files/v323}/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf (100%) rename {dive_files => test_files/v323}/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fd67d62..b8d0874 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,3 +14,9 @@ jobs: bundler-cache: true - name: Run the default task run: bundle exec rake + - name: Run tests + run: | + bundle exec rspec specs/ + - uses: joshmfrankel/simplecov-check-action@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.rubocop.yml b/.rubocop.yml index 675a296..40488a4 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,4 +1,8 @@ -plugins: rubocop-rake +inherit_from: .rubocop_todo.yml + +plugins: + - rubocop-rake + - rubocop-rspec AllCops: NewCops: enable @@ -25,4 +29,6 @@ Style/Documentation: Exclude: - "spec/**/*" - "test/**/*" + - "lib/uddf/base/models.rb" - "lib/uddf/v323/models.rb" + - "lib/uddf/v330/models.rb" diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..42cdff6 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,52 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2025-08-23 12:47:51 UTC using RuboCop version 1.80.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 4 +# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 35 + +# Offense count: 1 +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. +Metrics/MethodLength: + Max: 14 + +# Offense count: 1 +# Configuration parameters: IgnoredMetadata. +RSpec/DescribeClass: + Exclude: + - '**/spec/features/**/*' + - '**/spec/requests/**/*' + - '**/spec/routing/**/*' + - '**/spec/system/**/*' + - '**/spec/views/**/*' + - 'spec/uddf_parser_spec.rb' + +# Offense count: 3 +# Configuration parameters: CountAsOne. +RSpec/ExampleLength: + Max: 7 + +# Offense count: 5 +RSpec/MultipleExpectations: + Max: 4 + +# Offense count: 5 +# Configuration parameters: AllowedPatterns. +# AllowedPatterns: ^expect_, ^assert_ +RSpec/NoExpectationExample: + Exclude: + - 'spec/uddf_parser_spec.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength. +# AllowedMethods: present?, blank?, presence, try, try! +Style/SafeNavigation: + Exclude: + - 'spec/uddf_parser_spec.rb' diff --git a/Gemfile.lock b/Gemfile.lock index db60f18..04c0d35 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,6 +11,8 @@ GEM ast (2.4.3) cgi (0.5.0) date (3.4.1) + diff-lcs (1.6.2) + docile (1.4.1) erb (4.0.4) cgi (>= 0.3.3) io-console (0.8.1) @@ -47,6 +49,19 @@ GEM regexp_parser (2.11.2) reline (0.6.2) io-console (~> 0.5) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.5) rubocop (1.80.0) json (~> 2.3) language_server-protocol (~> 3.17.0.2) @@ -64,7 +79,16 @@ GEM rubocop-rake (0.7.1) lint_roller (~> 1.1) rubocop (>= 1.72.1) + rubocop-rspec (3.6.0) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) ruby-progressbar (1.13.0) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.13.2) + simplecov_json_formatter (0.1.4) stringio (3.1.7) unicode-display_width (3.1.5) unicode-emoji (~> 4.0, >= 4.0.4) @@ -77,8 +101,11 @@ PLATFORMS DEPENDENCIES irb rake (~> 13.0) + rspec (~> 3.13) rubocop (~> 1.7) rubocop-rake (~> 0.7) + rubocop-rspec (~> 3.6) + simplecov (~> 0.21) uddf! BUNDLED WITH diff --git a/lib/uddf.rb b/lib/uddf.rb index d787f7d..7678d27 100644 --- a/lib/uddf.rb +++ b/lib/uddf.rb @@ -8,7 +8,7 @@ # Universal Dive Data Format (UDDF) parser and validator module UDDF SUPPORTED_SCHEMA_VERSIONS = %w[3.0.0 3.0.1 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1].freeze - SUPPORTED_PARSER_VERSIONS = %w[3.2.3].freeze + SUPPORTED_PARSER_VERSIONS = %w[3.2.3 3.3.0].freeze @schema_cache_mutex = Mutex.new @@ -55,6 +55,9 @@ def self.load_models_for_version(version) when "3.2.3" require "uddf/v323/models" V323::Models::Uddf + when "3.3.0" + require "uddf/v330/models" + V330::Models::Uddf end end diff --git a/lib/uddf/base/models.rb b/lib/uddf/base/models.rb index 7ce0f81..2868c9a 100644 --- a/lib/uddf/base/models.rb +++ b/lib/uddf/base/models.rb @@ -34,6 +34,14 @@ class Contact has_many :mobile_phones, String, tag: "mobilephone" has_many :phones, String, tag: "phone" end + + class DateTimeField + include HappyMapper + + tag "datetime" + + content :value, DateTime + end end end end diff --git a/lib/uddf/v323/models.rb b/lib/uddf/v323/models.rb index 082f2b2..a9f62dd 100644 --- a/lib/uddf/v323/models.rb +++ b/lib/uddf/v323/models.rb @@ -13,7 +13,7 @@ class Manufacturer attribute :id, String has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :contact, Base::Models::Contact has_one :name, String end @@ -31,7 +31,7 @@ class Generator tag "generator" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :datetime, DateTime has_many :links, Link, tag: "link" has_one :name, String @@ -54,7 +54,7 @@ class Price tag "price" attribute :currency, String - attribute :value, Float + content :value, Float end class Tissue @@ -63,7 +63,7 @@ class Tissue tag "tissue" attribute :gas, String - attribute :half_life, Float + attribute :half_life, Float, tag: "halflife" attribute :number, Integer attribute :a, Float attribute :b, Float @@ -98,8 +98,8 @@ class Buehlmann tag "buehlmann" attribute :id, String - has_one :gradient_factor_high, Float - has_one :gradient_factor_low, Float + has_one :gradient_factor_high, Float, tag: "gradientfactorhigh" + has_one :gradient_factor_low, Float, tag: "gradientfactorlow" has_many :tissues, Tissue, tag: "tissue" end @@ -119,17 +119,17 @@ class Mix tag "mix" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :ar, Float - has_one :equivalent_air_depth, Float + has_one :equivalent_air_depth, Float, tag: "equivalentairdepth" has_one :h2, Float has_one :he, Float - has_one :maximum_operation_depth, Float - has_one :maximum_po2, Float + has_one :maximum_operation_depth, Float, tag: "maximumoperationdepth" + has_one :maximum_po2, Float, tag: "maximumpo2" has_one :n2, Float has_one :name, String has_one :o2, Float - has_one :price_per_litre, Price + has_one :price_per_litre, Price, tag: "priceperlitre" end class GasDefinitions @@ -145,8 +145,8 @@ class WayAltitude tag "wayaltitude" - attribute :way_time, Float - attribute :value, Float + attribute :way_time, Float, tag: "waytime" + content :value, Float end class ExposureToAltitude @@ -154,10 +154,10 @@ class ExposureToAltitude tag "exposuretoaltitude" - has_one :altitude_of_exposure, Float - has_one :date_of_flight, Date - has_one :surface_interval_before_altitude_exposure, Float - has_one :total_length_of_exposure, Float + has_one :altitude_of_exposure, Float, tag: "altitudeofexposure" + has_one :date_of_flight, Base::Models::DateTimeField, tag: "dateofflight" + has_one :surface_interval_before_altitude_exposure, Float, tag: "surfaceintervalbeforealtitudeexposure" + has_one :total_length_of_exposure, Float, tag: "totallengthofexposure" has_one :transportation, String end @@ -166,9 +166,9 @@ class SurfaceIntervalBeforeDive tag "surfaceintervalbeforedive" - has_one :exposure_to_altitude, ExposureToAltitude + has_one :exposure_to_altitude, ExposureToAltitude, tag: "exposuretoaltitude" has_one :infinity, String - has_one :passed_time, Float + has_one :passed_time, Float, tag: "passedtime" has_many :way_altitudes, WayAltitude, tag: "wayaltitude" end @@ -177,9 +177,9 @@ class SurfaceIntervalAfterDive tag "surfaceintervalafterdive" - has_one :exposure_to_altitude, ExposureToAltitude + has_one :exposure_to_altitude, ExposureToAltitude, tag: "exposuretoaltitude" has_one :infinity, String - has_one :passed_time, Float + has_one :passed_time, Float, tag: "passedtime" has_many :way_altitudes, WayAltitude, tag: "wayaltitude" end @@ -189,7 +189,7 @@ class TankPressure tag "tankpressure" attribute :ref, String - attribute :value, Float + content :value, Float end class SwitchMix @@ -205,8 +205,8 @@ class SetPo2 tag "setpo2" - attribute :set_by, String - attribute :value, Float + attribute :set_by, String, tag: "setby" + content :value, Float end class MeasuredPo2 @@ -215,7 +215,7 @@ class MeasuredPo2 tag "measuredpo2" attribute :ref, String - attribute :value, Float + content :value, Float end class GradientFactor @@ -224,7 +224,7 @@ class GradientFactor tag "gradientfactor" attribute :tissue, Integer - attribute :value, Float + content :value, Float end class DiveMode @@ -241,7 +241,7 @@ class Decostop tag "decostop" attribute :kind, String - attribute :deco_depth, Float + attribute :deco_depth, Float, tag: "decodepth" attribute :duration, Float end @@ -250,9 +250,9 @@ class BatteryChargeCondition tag "batterychargecondition" - attribute :device_ref, String - attribute :tank_ref, String - attribute :value, Float + attribute :device_ref, String, tag: "deviceref" + attribute :tank_ref, String, tag: "tankref" + content :value, Float end class Alarm @@ -261,8 +261,8 @@ class Alarm tag "alarm" attribute :level, Float - attribute :tank_ref, String - attribute :value, String + attribute :tank_ref, String, tag: "tankref" + content :value, String end class Waypoint @@ -272,21 +272,21 @@ class Waypoint has_many :alarms, Alarm, tag: "alarm" has_many :battery_charge_conditions, BatteryChargeCondition, tag: "batterychargecondition" - has_one :calculated_po2, Float + has_one :calculated_po2, Float, tag: "calculatedpo2" has_one :cns, Float has_many :deco_stops, Decostop, tag: "decostop" has_one :depth, Float - has_one :dive_mode, DiveMode - has_one :dive_time, Float - has_one :gradient_factor, GradientFactor + has_one :dive_mode, DiveMode, tag: "divemode" + has_one :dive_time, Float, tag: "divetime" + has_one :gradient_factor, GradientFactor, tag: "gradientfactor" has_one :heading, Float has_many :measured_po2s, MeasuredPo2, tag: "measuredpo2" - has_one :no_deco_time, Float + has_one :no_deco_time, Float, tag: "nodecotime" has_one :otu, Float - has_one :remaining_bottom_time, Float - has_one :remaining_o2_time, Float + has_one :remaining_bottom_time, Float, tag: "remainingbottomtime" + has_one :remaining_o2_time, Float, tag: "remainingo2time" has_many :set_po2s, SetPo2, tag: "setpo2" - has_one :switch_mix, SwitchMix + has_one :switch_mix, SwitchMix, tag: "switchmix" has_many :tank_pressures, TankPressure, tag: "tankpressure" has_one :temperature, Float end @@ -296,11 +296,11 @@ class Medicine tag "medicine" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes - has_one :periodically_taken, String - has_one :timespan_before_dive, Float + has_one :periodically_taken, String, tag: "periodicallytaken" + has_one :timespan_before_dive, Float, tag: "timespanbeforedive" end class MedicationBeforeDive @@ -316,8 +316,8 @@ class PlannedProfile tag "plannedprofile" - attribute :start_dive_mode, String - attribute :start_mix, String + attribute :start_dive_mode, String, tag: "startdivemode" + attribute :start_mix, String, tag: "startmix" has_many :waypoints, Waypoint, tag: "waypoint" end @@ -326,11 +326,11 @@ class Drink tag "drink" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes - has_one :periodically_taken, String - has_one :timespan_before_dive, Float + has_one :periodically_taken, String, tag: "periodicallytaken" + has_one :timespan_before_dive, Float, tag: "timespanbeforedive" end class AlcoholBeforeDive @@ -346,25 +346,25 @@ class InformationBeforeDive tag "informationbeforedive" - has_one :air_temperature, Float - has_one :alcohol_before_dive, AlcoholBeforeDive + has_one :air_temperature, Float, tag: "airtemperature" + has_one :alcohol_before_dive, AlcoholBeforeDive, tag: "alcoholbeforedive" has_one :altitude, Float has_one :apparatus, String has_one :datetime, DateTime - has_one :dive_number, Integer - has_one :dive_number_of_day, Integer - has_one :internal_dive_number, Integer + has_one :dive_number, Integer, tag: "divenumber" + has_one :dive_number_of_day, Integer, tag: "divenumberofday" + has_one :internal_dive_number, Integer, tag: "internaldivenumber" has_many :links, Link, tag: "link" - has_one :medication_before_dive, MedicationBeforeDive - has_one :no_suit, String - has_one :planned_profile, PlannedProfile + has_one :medication_before_dive, MedicationBeforeDive, tag: "medicationbeforedive" + has_one :no_suit, String, tag: "nosuit" + has_one :planned_profile, PlannedProfile, tag: "plannedprofile" has_one :platform, String has_one :price, Price has_one :purpose, String - has_one :state_of_rest_before_dive, String - has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive - has_one :surface_pressure, Float - has_one :trip_membership, String + has_one :state_of_rest_before_dive, String, tag: "stateofrestbeforedive" + has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive, tag: "surfaceintervalbeforedive" + has_one :surface_pressure, Float, tag: "surfacepressure" + has_one :trip_membership, String, tag: "tripmembership" end class Rating @@ -373,7 +373,7 @@ class Rating tag "rating" has_one :datetime, DateTime - has_one :rating_value, Integer + has_one :rating_value, Integer, tag: "ratingvalue" end class GlobalAlarmsGiven @@ -389,7 +389,7 @@ class EquipmentUsed tag "equipmentused" - has_one :lead_quantity, Float + has_one :lead_quantity, Float, tag: "leadquantity" has_many :links, Link, tag: "link" end @@ -401,31 +401,31 @@ class AnySymptoms has_one :notes, Notes end + class Abundance + include HappyMapper + + tag "abundance" + + attribute :quality, String + attribute :occurrence, String + content :value, Integer + end + class Species include HappyMapper tag "species" attribute :id, String - has_one :abundance, "Abundance" + has_one :abundance, Abundance has_one :age, Integer has_one :dominance, String - has_one :life_stage, String + has_one :life_stage, String, tag: "lifestage" has_one :notes, Notes - has_one :scientific_name, String + has_one :scientific_name, String, tag: "scientificname" has_one :sex, String has_one :size, Float - has_one :trivial_name, String - end - - class Abundance - include HappyMapper - - tag "abundance" - - attribute :quality, String - attribute :occurrence, String - attribute :value, Integer + has_one :trivial_name, String, tag: "trivialname" end class WithSpecies @@ -446,7 +446,7 @@ class Invertebrata has_one :crustacea, WithSpecies has_one :ctenophora, WithSpecies has_one :echinodermata, WithSpecies - has_one :invertebrata_various, WithSpecies + has_one :invertebrata_various, WithSpecies, tag: "invertebratavarious" has_one :mollusca, WithSpecies has_one :phoronidea, WithSpecies has_one :plathelminthes, WithSpecies @@ -463,7 +463,7 @@ class Vertebrata has_one :mammalia, WithSpecies has_one :osteichthyes, WithSpecies has_one :reptilia, WithSpecies - has_one :vertebrata_various, WithSpecies + has_one :vertebrata_various, WithSpecies, tag: "vertebratavarious" end class Fauna @@ -482,7 +482,7 @@ class Flora tag "flora" has_one :chlorophyceae, WithSpecies - has_one :flora_various, WithSpecies + has_one :flora_various, WithSpecies, tag: "floravarious" has_one :notes, Notes has_one :phaeophyceae, WithSpecies has_one :rhodophyceae, WithSpecies @@ -504,28 +504,28 @@ class InformationAfterDive tag "informationafterdive" - has_one :any_symptoms, AnySymptoms - has_one :average_depth, Float + has_one :any_symptoms, AnySymptoms, tag: "anysymptoms" + has_one :average_depth, Float, tag: "averagedepth" has_one :current, String - has_one :desaturation_time, Float - has_one :dive_duration, Float - has_one :dive_plan, String - has_one :dive_table, String - has_one :equipment_malfunction, String - has_one :equipment_used, EquipmentUsed - has_one :global_alarms_given, GlobalAlarmsGiven - has_one :greatest_depth, Float - has_one :highest_po2, Float - has_one :lowest_temperature, Float - has_one :no_flight_time, Float + has_one :desaturation_time, Float, tag: "desaturationtime" + has_one :dive_duration, Float, tag: "diveduration" + has_one :dive_plan, String, tag: "diveplan" + has_one :dive_table, String, tag: "divetable" + has_one :equipment_malfunction, String, tag: "equipmentmalfunction" + has_one :equipment_used, EquipmentUsed, tag: "equipmentused" + has_one :global_alarms_given, GlobalAlarmsGiven, tag: "globalalarmsgiven" + has_one :greatest_depth, Float, tag: "greatestdepth" + has_one :highest_po2, Float, tag: "highestpo2" + has_one :lowest_temperature, Float, tag: "lowesttemperature" + has_one :no_flight_time, Float, tag: "noflighttime" has_one :notes, Notes has_one :observations, Observations - has_one :pressure_drop, Float + has_one :pressure_drop, Float, tag: "pressuredrop" has_many :problems, String, tag: "problems" has_one :program, String has_many :ratings, Rating, tag: "rating" - has_one :surface_interval_after_dive, SurfaceIntervalAfterDive - has_one :thermal_comfort, String + has_one :surface_interval_after_dive, SurfaceIntervalAfterDive, tag: "surfaceintervalafterdive" + has_one :thermal_comfort, String, tag: "thermalcomfort" has_one :visibility, Float has_one :workload, String end @@ -544,11 +544,11 @@ class TankData tag "tankdata" attribute :id, String - has_one :breathing_consumption_volume, Float + has_one :breathing_consumption_volume, Float, tag: "breathingconsumptionvolume" has_many :links, Link, tag: "link" - has_one :tank_pressure_begin, Float - has_one :tank_pressure_end, Float - has_one :tank_volume, Float + has_one :tank_pressure_begin, Float, tag: "tankpressurebegin" + has_one :tank_pressure_end, Float, tag: "tankpressureend" + has_one :tank_volume, Float, tag: "tankvolume" end class Hargikas @@ -558,9 +558,9 @@ class Hargikas has_one :ambient, Float has_many :tissues, Tissue, tag: "tissue" - has_one :arterial_micro_bubble_level, Integer - has_one :intrapulmonary_right_left_shunt, Float - has_one :estimated_skin_cool_level, Integer + has_one :arterial_micro_bubble_level, Integer, tag: "arterialmicrobubbleLevel" + has_one :intrapulmonary_right_left_shunt, Float, tag: "intrapulmonaryrightleftshunt" + has_one :estimated_skin_cool_level, Integer, tag: "estimatedskincoolLevel" end class ApplicationData @@ -568,7 +568,7 @@ class ApplicationData tag "applicationdata" - has_one :deco_trainer, String + has_one :deco_trainer, String, tag: "decotrainer" has_one :hargikas, Hargikas end @@ -578,9 +578,9 @@ class Dive tag "dive" attribute :id, String - has_one :information_after_dive, InformationAfterDive - has_one :information_before_dive, InformationBeforeDive - has_one :application_data, ApplicationData + has_one :information_after_dive, InformationAfterDive, tag: "informationafterdive" + has_one :information_before_dive, InformationBeforeDive, tag: "informationbeforedive" + has_one :application_data, ApplicationData, tag: "applicationdata" has_one :samples, Samples has_many :tank_data, TankData, tag: "tankdata" end @@ -642,8 +642,8 @@ class Output tag "output" has_one :lingo, String - has_one :file_format, String - has_one :file_name, String + has_one :file_format, String, tag: "fileformat" + has_one :file_name, String, tag: "filename" has_one :headline, String has_one :remark, String end @@ -653,17 +653,17 @@ class Profile tag "profile" - has_one :application_data, ApplicationData - has_one :deco_model, DecoModel - has_one :deep_stop_time, Float + has_one :application_data, ApplicationData, tag: "applicationdata" + has_one :deco_model, DecoModel, tag: "decomodel" + has_one :deep_stop_time, Float, tag: "deepstoptime" has_one :density, Float - has_one :input_profile, InputProfile + has_one :input_profile, InputProfile, tag: "inputprofile" has_many :links, Link, tag: "link" - has_one :maximum_ascending_rate, Float - has_one :mix_change, MixChange + has_one :maximum_ascending_rate, Float, tag: "maximumascendingrate" + has_one :mix_change, MixChange, tag: "mixchange" has_one :output, Output - has_one :surface_interval_after_dive, SurfaceIntervalAfterDive - has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive + has_one :surface_interval_after_dive, SurfaceIntervalAfterDive, tag: "surfaceintervalafterdive" + has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive, tag: "surfaceintervalbeforedive" has_one :title, String end @@ -673,13 +673,13 @@ class TableScope tag "tablescope" has_one :altitude, Float - has_one :bottom_time_maximum, Float - has_one :bottom_time_minimum, Float - has_one :bottom_time_step_begin, Float - has_one :bottom_time_step_end, Float - has_one :dive_depth_begin, Float - has_one :dive_depth_end, Float - has_one :dive_depth_step, Float + has_one :bottom_time_maximum, Float, tag: "bottomtimemaximum" + has_one :bottom_time_minimum, Float, tag: "bottomtimeminimum" + has_one :bottom_time_step_begin, Float, tag: "bottomtimestepbegin" + has_one :bottom_time_step_end, Float, tag: "bottomtimestepend" + has_one :dive_depth_begin, Float, tag: "divedepthbegin" + has_one :dive_depth_end, Float, tag: "divedepthend" + has_one :dive_depth_step, Float, tag: "divedepthstep" end class Table @@ -687,7 +687,7 @@ class Table tag "table" - has_one :table_scope, TableScope + has_one :table_scope, TableScope, tag: "tablescope" end class CalculateProfile @@ -711,16 +711,16 @@ class BottomTimeTableScope tag "bottomtimetablescope" - has_one :breathing_consumption_volume_begin, Float - has_one :breathing_consumption_volume_end, Float - has_one :breathing_consumption_volume_step, Float - has_one :dive_depth_begin, Float - has_one :dive_depth_end, Float - has_one :dive_depth_step, Float - has_one :tank_pressure_begin, Float - has_one :tank_pressure_reserve, Float - has_one :tank_volume_begin, Float - has_one :tank_volume_end, Float + has_one :breathing_consumption_volume_begin, Float, tag: "breathingconsumptionvolumebegin" + has_one :breathing_consumption_volume_end, Float, tag: "breathingconsumptionvolumeend" + has_one :breathing_consumption_volume_step, Float, tag: "breathingconsumptionvolumestep" + has_one :dive_depth_begin, Float, tag: "divedepthbegin" + has_one :dive_depth_end, Float, tag: "divedepthend" + has_one :dive_depth_step, Float, tag: "divedepthstep" + has_one :tank_pressure_begin, Float, tag: "tankpressurebegin" + has_one :tank_pressure_reserve, Float, tag: "tankpressurereserve" + has_one :tank_volume_begin, Float, tag: "tankvolumebegin" + has_one :tank_volume_end, Float, tag: "tankvolumeend" end class BottomTimeTable @@ -729,8 +729,8 @@ class BottomTimeTable tag "bottomtimetable" attribute :id, String - has_one :application_data, ApplicationData - has_one :bottom_time_table_scope, BottomTimeTableScope + has_one :application_data, ApplicationData, tag: "applicationdata" + has_one :bottom_time_table_scope, BottomTimeTableScope, tag: "bottomtimetablescope" has_many :links, Link, tag: "link" has_one :output, Output has_one :title, String @@ -749,9 +749,9 @@ class TableGeneration tag "tablegeneration" - has_one :calculate_bottom_time_table, CalculateBottomTimeTable - has_one :calculate_profile, CalculateProfile - has_one :calculate_table, CalculateTable + has_one :calculate_bottom_time_table, CalculateBottomTimeTable, tag: "calculatebottomtimetable" + has_one :calculate_profile, CalculateProfile, tag: "calculateprofile" + has_one :calculate_table, CalculateTable, tag: "calculatetable" end class ImageData @@ -761,12 +761,12 @@ class ImageData has_one :aperture, Float has_one :datetime, DateTime - has_one :exposure_compensation, Float - has_one :film_speed, Integer - has_one :focal_length, Float - has_one :focusing_distance, Float - has_one :metering_method, String - has_one :shutter_speed, Float + has_one :exposure_compensation, Float, tag: "exposurecompensation" + has_one :film_speed, Integer, tag: "filmspeed" + has_one :focal_length, Float, tag: "focallength" + has_one :focusing_distance, Float, tag: "focusingdistance" + has_one :metering_method, String, tag: "meteringmethod" + has_one :shutter_speed, Float, tag: "shutterspeed" end class Image @@ -778,8 +778,8 @@ class Image attribute :height, Integer attribute :width, Integer attribute :format, String - has_one :image_data, ImageData - has_one :object_name, String + has_one :image_data, ImageData, tag: "imagedata" + has_one :object_name, String, tag: "objectname" has_one :title, String end @@ -789,7 +789,7 @@ class Video tag "video" attribute :id, String - has_one :object_name, String + has_one :object_name, String, tag: "objectname" has_one :title, String end @@ -799,7 +799,7 @@ class Audio tag "audio" attribute :id, String - has_one :object_name, String + has_one :object_name, String, tag: "objectname" has_one :title, String end @@ -827,8 +827,8 @@ class PriceDivePackage tag "pricedivepackage" attribute :currency, String - attribute :no_of_dives, Integer - attribute :value, Float + attribute :no_of_dives, Integer, tag: "noofdives" + content :value, Float end class RelatedDives @@ -857,14 +857,14 @@ class Vessel tag "vessel" has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :contact, Base::Models::Contact has_one :marina, String has_one :name, String has_one :notes, Notes has_many :ratings, Rating, tag: "rating" - has_one :ship_dimension, ShipDimension - has_one :ship_type, String + has_one :ship_dimension, ShipDimension, tag: "shipdimension" + has_one :ship_type, String, tag: "shiptype" end class Operator @@ -872,7 +872,7 @@ class Operator tag "operator" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :address, Base::Models::Address has_one :contact, Base::Models::Contact has_one :name, String @@ -885,8 +885,8 @@ class DateOfTrip tag "dateoftrip" - attribute :start_date, DateTime - attribute :end_date, DateTime + attribute :start_date, DateTime, tag: "startdate" + attribute :end_date, DateTime, tag: "enddate" end class Accommodation @@ -895,7 +895,7 @@ class Accommodation tag "accommodation" has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :category, String has_one :contact, Base::Models::Contact has_one :name, String @@ -913,7 +913,7 @@ class Geography has_one :latitude, Float has_one :location, String has_one :longitude, Float - has_one :time_zone, Float + has_one :time_zone, Float, tag: "timezone" end class TripPart @@ -923,15 +923,15 @@ class TripPart attribute :type, String has_one :accommodation, Accommodation - has_one :date_of_trip, DateOfTrip + has_one :date_of_trip, DateOfTrip, tag: "dateoftrip" has_one :geography, Geography has_many :links, Link, tag: "link" has_one :name, String has_one :notes, Notes has_one :operator, Operator - has_one :price_dive_package, PriceDivePackage - has_one :price_per_dive, Price - has_one :related_dives, RelatedDives + has_one :price_dive_package, PriceDivePackage, tag: "pricedivepackage" + has_one :price_per_dive, Price, tag: "priceperdive" + has_one :related_dives, RelatedDives, tag: "relateddives" has_one :vessel, Vessel end @@ -941,7 +941,7 @@ class Trip tag "trip" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_many :ratings, Rating, tag: "rating" has_many :trip_parts, TripPart, tag: "trippart" @@ -969,8 +969,8 @@ class Built tag "built" - has_one :launching_date, Date - has_one :ship_yard, String + has_one :launching_date, Date, tag: "launchingdate" + has_one :ship_yard, String, tag: "shipyard" end class Wreck @@ -978,12 +978,12 @@ class Wreck tag "wreck" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :built, Built has_one :name, String has_one :nationality, String - has_one :ship_dimension, ShipDimension - has_one :ship_type, String + has_one :ship_dimension, ShipDimension, tag: "shipdimension" + has_one :ship_type, String, tag: "shiptype" has_one :sunk, Date end @@ -993,7 +993,7 @@ class Shore tag "shore" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes end @@ -1004,7 +1004,7 @@ class River tag "river" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes end @@ -1015,7 +1015,7 @@ class Lake tag "lake" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes end @@ -1026,7 +1026,7 @@ class Indoor tag "indoor" has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :contact, Base::Models::Contact has_one :name, String has_one :notes, Notes @@ -1038,7 +1038,7 @@ class Cave tag "cave" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes end @@ -1048,19 +1048,19 @@ class SiteData tag "sidedata" - has_one :area_length, Float - has_one :area_width, Float - has_one :average_visibility, Float + has_one :area_length, Float, tag: "arealength" + has_one :area_width, Float, tag: "areawidth" + has_one :average_visibility, Float, tag: "averagevisibility" has_one :bottom, String has_one :cave, Cave has_one :density, Float has_one :difficulty, Integer - has_one :global_light_intensity, String + has_one :global_light_intensity, String, tag: "globallightintensity" has_one :indoor, Indoor - has_one :maximum_depth, Float - has_one :maximum_visibility, Float - has_one :minimum_depth, Float - has_one :minimum_visibility, Float + has_one :maximum_depth, Float, tag: "maximumdepth" + has_one :maximum_visibility, Float, tag: "maximumvisibility" + has_one :minimum_depth, Float, tag: "minimumdepth" + has_one :minimum_visibility, Float, tag: "minimumvisibility" has_one :river, River has_one :shore, Shore has_one :terrain, String @@ -1073,7 +1073,7 @@ class Site tag "site" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :ecology, Ecology has_one :environment, String has_one :geography, Geography @@ -1081,7 +1081,7 @@ class Site has_one :name, String has_one :notes, Notes has_many :ratings, Rating, tag: "rating" - has_one :side_data, SiteData + has_one :side_data, SiteData, tag: "sitedata" end class Guide @@ -1099,14 +1099,14 @@ class DiveBase attribute :id, String has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :contact, Base::Models::Contact has_many :guides, Guide, tag: "guide" has_many :links, Link, tag: "link" has_one :name, String has_one :notes, Notes - has_one :price_dive_package, PriceDivePackage - has_one :price_per_dive, Price + has_one :price_dive_package, PriceDivePackage, tag: "pricedivepackage" + has_one :price_per_dive, Price, tag: "priceperdive" has_many :ratings, Rating, tag: "rating" end @@ -1124,7 +1124,7 @@ class Shop tag "shop" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :address, Base::Models::Address has_one :contact, Base::Models::Contact has_one :name, String @@ -1145,7 +1145,7 @@ class Membership tag "membership" attribute :organisation, String - attribute :member_id, String + attribute :member_id, String, tag: "memberid" end class NumberOfDives @@ -1153,8 +1153,8 @@ class NumberOfDives tag "numberofdives" - has_one :start_date, Date - has_one :end_date, Date + has_one :start_date, Date, tag: "startdate" + has_one :end_date, Date, tag: "enddate" has_one :dives, Integer end @@ -1163,16 +1163,16 @@ class Personal tag "personal" - has_one :birth_date, Date - has_one :birth_name, String - has_one :blood_group, String - has_one :first_name, String + has_one :birth_date, Date, tag: "birthdate" + has_one :birth_name, String, tag: "birthname" + has_one :blood_group, String, tag: "bloodgroup" + has_one :first_name, String, tag: "firstname" has_one :height, Float has_one :honorific, String - has_one :last_name, String + has_one :last_name, String, tag: "lastname" has_one :membership, Membership - has_one :middle_name, String - has_one :number_of_dives, NumberOfDives + has_one :middle_name, String, tag: "middlename" + has_one :number_of_dives, NumberOfDives, tag: "numberofdives" has_one :sex, String has_one :smoking, String has_one :weight, Float @@ -1193,14 +1193,14 @@ class Certification tag "certification" - has_one :certificate_number, String + has_one :certificate_number, String, tag: "certificatenumber" has_one :instructor, Instructor - has_one :issue_date, Date + has_one :issue_date, Date, tag: "issuedate" has_one :level, String has_one :link, Link has_one :organization, String has_one :specialty, String - has_one :valid_date, Date + has_one :valid_date, Date, tag: "validdate" end class Education @@ -1216,11 +1216,11 @@ class Insurance tag "insurance" - has_one :alias_name, String - has_one :issue_date, Date + has_many :alias_names, String, tag: "aliasname" + has_one :issue_date, Date, tag: "issuedate" has_one :name, String has_one :notes, Notes - has_one :valid_date, Date + has_one :valid_date, Date, tag: "validdate" end class DiveInsurances @@ -1236,12 +1236,12 @@ class Permit tag "permit" - has_one :alias_name, String - has_one :issue_date, Date + has_many :alias_names, String, tag: "aliasname" + has_one :issue_date, Date, tag: "issuedate" has_one :name, String has_one :notes, Notes has_one :region, String - has_one :valid_date, Date + has_one :valid_date, Date, tag: "validdate" end class DivePermissions @@ -1269,53 +1269,49 @@ class EquipmentPart tag "equipmentpart" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_many :links, Link, tag: "link" has_one :manufacturer, Manufacturer has_one :model, String has_one :name, String - has_one :next_service_date, Date + has_one :next_service_date, Date, tag: "nextservicedate" has_one :notes, Notes has_one :purchase, Purchase - has_one :serial_number, String - has_one :service_interval, Integer + has_one :serial_number, String, tag: "serialnumber" + has_one :service_interval, Integer, tag: "serviceinterval" end - class Lead + class Lead < EquipmentPart include HappyMapper tag "lead" - has_one :equipment_part, EquipmentPart - has_one :lead_quantity, Integer + has_one :lead_quantity, Integer, tag: "leadquantity" end - class Rebreather + class Rebreather < EquipmentPart include HappyMapper tag "rebreather" - has_one :equipment_part, EquipmentPart has_many :o2_sensors, EquipmentPart, tag: "o2sensor" end - class Suit + class Suit < EquipmentPart include HappyMapper tag "suit" - has_one :equipment_part, EquipmentPart - has_one :suit_type, String + has_one :suit_type, String, tag: "suittype" end - class Tank + class Tank < EquipmentPart include HappyMapper tag "tank" - has_one :equipment_part, EquipmentPart - has_one :tank_material, String - has_one :tank_volume, Float + has_one :tank_material, String, tag: "tankmaterial" + has_one :tank_volume, Float, tag: "tankvolume" end class Camera @@ -1329,15 +1325,9 @@ class Camera has_one :lens, EquipmentPart end - class EquipmentConfiguration + class EquipmentContent include HappyMapper - tag "equipmentconfiguration" - - has_one :alias_name, String - has_many :links, Link, tag: "link" - has_one :name, String - has_one :notes, Notes has_many :boots, EquipmentPart, tag: "boots" has_many :buoyancy_control_devices, EquipmentPart, tag: "buoyancycontroldevice" has_many :cameras, Camera, tag: "camera" @@ -1359,32 +1349,24 @@ class EquipmentConfiguration has_many :watches, EquipmentPart, tag: "watch" end - class Equipment + class EquipmentConfiguration < EquipmentContent + include HappyMapper + + tag "equipmentconfiguration" + + has_many :alias_names, String, tag: "aliasname" + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + end + + class Equipment < EquipmentContent include HappyMapper tag "equipment" has_many :compressors, EquipmentPart, tag: "compressor" - has_one :equipment_configuration, EquipmentConfiguration - has_many :boots, EquipmentPart, tag: "boots" - has_many :buoyancy_control_devices, EquipmentPart, tag: "buoyancycontroldevice" - has_many :cameras, Camera, tag: "camera" - has_many :compasses, EquipmentPart, tag: "compass" - has_many :dive_computers, EquipmentPart, tag: "divecomputer" - has_many :fins, EquipmentPart, tag: "fins" - has_many :gloves, EquipmentPart, tag: "gloves" - has_many :knives, EquipmentPart, tag: "knife" - has_many :leads, Lead, tag: "lead" - has_many :lights, EquipmentPart, tag: "light" - has_many :masks, EquipmentPart, tag: "mask" - has_many :rebreathers, Rebreather, tag: "rebreather" - has_many :regulators, EquipmentPart, tag: "regulator" - has_many :scooters, EquipmentPart, tag: "scooter" - has_many :suits, Suit, tag: "suit" - has_many :tanks, Tank, tag: "tank" - has_many :various_pieces, EquipmentPart, tag: "variouspieces" - has_many :video_cameras, EquipmentPart, tag: "videocamera" - has_many :watches, EquipmentPart, tag: "watch" + has_one :equipment_configuration, EquipmentConfiguration, tag: "equipmentconfiguration" end class Doctor @@ -1405,11 +1387,11 @@ class Examination has_one :datetime, DateTime has_one :doctor, Doctor - has_one :examination_result, String + has_one :examination_result, String, tag: "examinationresult" has_many :links, Link, tag: "link" has_one :notes, Notes - has_one :total_lung_capacity, Float - has_one :vital_capacity, Float + has_one :total_lung_capacity, Float, tag: "totallungcapacity" + has_one :vital_capacity, Float, tag: "vitalcapacity" end class Medical @@ -1426,8 +1408,8 @@ class BuddyOwnerShared attribute :id, String has_one :address, Base::Models::Address has_one :contact, Base::Models::Contact - has_one :dive_insurances, DiveInsurances - has_one :dive_permissions, DivePermissions + has_one :dive_insurances, DiveInsurances, tag: "diveinsurances" + has_one :dive_permissions, DivePermissions, tag: "divepermissions" has_one :equipment, Equipment has_one :medical, Medical has_one :notes, Notes @@ -1442,8 +1424,8 @@ class Buddy attribute :id, String has_one :address, Base::Models::Address has_one :contact, Base::Models::Contact - has_one :dive_insurances, DiveInsurances - has_one :dive_permissions, DivePermissions + has_one :dive_insurances, DiveInsurances, tag: "diveinsurances" + has_one :dive_permissions, DivePermissions, tag: "divepermissions" has_one :equipment, Equipment has_one :medical, Medical has_one :notes, Notes @@ -1460,8 +1442,8 @@ class Owner attribute :id, String has_one :address, Base::Models::Address has_one :contact, Base::Models::Contact - has_one :dive_insurances, DiveInsurances - has_one :dive_permissions, DivePermissions + has_one :dive_insurances, DiveInsurances, tag: "diveinsurances" + has_one :dive_permissions, DivePermissions, tag: "divepermissions" has_one :equipment, Equipment has_one :medical, Medical has_one :notes, Notes @@ -1484,7 +1466,7 @@ class DCAlarm tag "dcalarm" has_one :acknowledge, String - has_one :alarm_type, Integer + has_one :alarm_type, Integer, tag: "alarmtype" has_one :period, Float end @@ -1493,8 +1475,8 @@ class SetDCDiveDepthAlarm tag "setdcdivedethalarm" - has_one :dc_alarm, DCAlarm - has_one :dc_alarm_depth, Float + has_one :dc_alarm, DCAlarm, tag: "dcalarm" + has_one :dc_alarm_depth, Float, tag: "dcalarmdepth" end class SetDCDivePo2Alarm @@ -1502,8 +1484,8 @@ class SetDCDivePo2Alarm tag "setdcdivepo2alarm" - has_one :dc_alarm, DCAlarm - has_one :maximum_po2, Float + has_one :dc_alarm, DCAlarm, tag: "dcalarm" + has_one :maximum_po2, Float, tag: "maximumpo2" end class SetDCDiveSiteData @@ -1511,7 +1493,7 @@ class SetDCDiveSiteData tag "setdcdivesitedata" - attribute :dive_site, String + attribute :dive_site, String, tag: "divesite" end class SetDCDiveTimeAlarm @@ -1519,7 +1501,7 @@ class SetDCDiveTimeAlarm tag "setdcdivetimealarm" - has_one :dc_alarm, DCAlarm + has_one :dc_alarm, DCAlarm, tag: "dcalarm" has_one :timespan, Float end @@ -1528,7 +1510,7 @@ class SetDCEndNDTAlarm tag "setdcendndtalarm" - has_one :dc_alarm, DCAlarm + has_one :dc_alarm, DCAlarm, tag: "dcalarm" end class SetDCDecoModel @@ -1536,8 +1518,8 @@ class SetDCDecoModel tag "setdcdecomodel" - has_one :alias_name, String - has_one :application_data, ApplicationData + has_many :alias_names, String, tag: "aliasname" + has_one :application_data, ApplicationData, tag: "applicationdata" has_one :name, String end @@ -1554,20 +1536,20 @@ class SetDCData tag "setdcdata" - has_one :set_dc_alarm_time, DateTime - has_one :set_dc_altitude, Float - has_one :set_dc_buddy_data, SetDCBuddyData - has_one :set_dc_date_time, DateTime - has_one :set_dc_deco_model, SetDCDecoModel - has_one :set_dc_dive_depth_alarm, SetDCDiveDepthAlarm - has_one :set_dc_dive_po2_alarm, SetDCDivePo2Alarm + has_one :set_dc_alarm_time, DateTime, tag: "setdcalarmtime" + has_one :set_dc_altitude, Float, tag: "setdcaltitude" + has_one :set_dc_buddy_data, SetDCBuddyData, tag: "setdcbuddydata" + has_one :set_dc_date_time, DateTime, tag: "setdcdatetime" + has_one :set_dc_deco_model, SetDCDecoModel, tag: "setdcdecomodel" + has_one :set_dc_dive_depth_alarm, SetDCDiveDepthAlarm, tag: "setdcdivedethalarm" + has_one :set_dc_dive_po2_alarm, SetDCDivePo2Alarm, tag: "setdcdivepo2alarm" has_many :set_dc_dive_site_data, SetDCDiveSiteData, tag: "setdcdivesitedata" - has_one :set_dc_dive_time_alarm, SetDCDiveTimeAlarm - has_one :set_dc_end_ndt_alarm, SetDCEndNDTAlarm - has_one :set_dc_gas_definitions_data, String - has_one :set_dc_owner_data, String - has_one :set_dc_password, String - has_one :set_dc_generator_data, String + has_one :set_dc_dive_time_alarm, SetDCDiveTimeAlarm, tag: "setdcdivetimealarm" + has_one :set_dc_end_ndt_alarm, SetDCEndNDTAlarm, tag: "setdcendndtalarm" + has_one :set_dc_gas_definitions_data, String, tag: "setdcgasdefinitionsdata" + has_one :set_dc_owner_data, String, tag: "setdcownerdata" + has_one :set_dc_password, String, tag: "setdcpassword" + has_one :set_dc_generator_data, String, tag: "setdcgeneratordata" end class GetDCData @@ -1575,14 +1557,14 @@ class GetDCData tag "getdcdata" - has_one :get_dc_all_data, String - has_one :get_dc_generator_data, String - has_one :get_dc_owner_data, String - has_one :get_dc_buddy_data, String - has_one :get_dc_gas_definitions_data, String - has_one :get_dc_dive_site_data, String - has_one :get_dc_dive_trip_data, String - has_one :get_dc_profile_data, String + has_one :get_dc_all_data, String, tag: "getdcalldata" + has_one :get_dc_generator_data, String, tag: "getdcgeneratordata" + has_one :get_dc_owner_data, String, tag: "getdcownerdata" + has_one :get_dc_buddy_data, String, tag: "getdcbuddydata" + has_one :get_dc_gas_definitions_data, String, tag: "getdcgasdefinitionsdata" + has_one :get_dc_dive_site_data, String, tag: "getdcdivesitedata" + has_one :get_dc_dive_trip_data, String, tag: "getdcdivetripdata" + has_one :get_dc_profile_data, String, tag: "getdcprofiledata" end class DiveComputerDump @@ -1591,7 +1573,7 @@ class DiveComputerDump tag "divecomputerdump" has_one :datetime, DateTime - has_one :dc_dump, String + has_one :dc_dump, String, tag: "dcdump" has_one :link, Link end @@ -1601,8 +1583,8 @@ class DiveComputerControl tag "divecomputercontrol" has_many :dive_computer_dumps, DiveComputerDump, tag: "divecomputerdump" - has_one :get_dc_data, GetDCData - has_one :set_dc_data, SetDCData + has_one :get_dc_data, GetDCData, tag: "getdcdata" + has_one :set_dc_data, SetDCData, tag: "setdcdata" end class Uddf @@ -1612,17 +1594,17 @@ class Uddf attribute :version, String has_one :business, Business - has_one :deco_model, DecoModel - has_one :dive_computer_control, DiveComputerControl + has_one :deco_model, DecoModel, tag: "decomodel" + has_one :dive_computer_control, DiveComputerControl, tag: "divecomputercontrol" has_one :diver, Diver - has_one :dive_site, DiveSite - has_one :dive_trip, DiveTrip - has_one :gas_definitions, GasDefinitions + has_one :dive_site, DiveSite, tag: "divesite" + has_one :dive_trip, DiveTrip, tag: "divetrip" + has_one :gas_definitions, GasDefinitions, tag: "gasdefinitions" has_one :generator, Generator has_one :maker, Maker - has_one :media_data, MediaData - has_one :profile_data, ProfileData - has_one :table_generation, TableGeneration + has_one :media_data, MediaData, tag: "mediadata" + has_one :profile_data, ProfileData, tag: "profiledata" + has_one :table_generation, TableGeneration, tag: "tablegeneration" end end end diff --git a/lib/uddf/v330/models.rb b/lib/uddf/v330/models.rb new file mode 100644 index 0000000..e7130bb --- /dev/null +++ b/lib/uddf/v330/models.rb @@ -0,0 +1,1744 @@ +# frozen_string_literal: true + +require "happymapper" +require "uddf/base/models" + +module UDDF + module V330 + module Models + class Timer + include HappyMapper + + tag "timer" + + attribute :ref, String + content :value, Float + end + + class SelfTest + include HappyMapper + + tag "selftest" + + attribute :ref, String + content :Value, String + end + + class RebreatherSelfTest + include HappyMapper + + tag "rebreatherselftest" + + attribute :ref, String + content :value, String + end + + class DeepStops + include HappyMapper + + tag "deepstops" + + has_one :deep_stop_time, Float, tag: "deepstoptime" + has_one :deep_stop_type, String, tag: "deepstoptype" + end + + class ScrubberMonitor + include HappyMapper + + tag "scrubbermonitor" + + attribute :id, String + end + + class Scrubber + include HappyMapper + + tag "scrubber" + + attribute :ref, String + attribute :units, String + + content :value, Float + end + + class Manufacturer + include HappyMapper + + tag "manufacturer" + + attribute :id, String + has_one :address, Base::Models::Address + has_one :alias_name, String + has_one :contact, Base::Models::Contact + has_one :name, String + end + + class Link + include HappyMapper + + tag "link" + + attribute :ref, String + end + + class Generator + include HappyMapper + + tag "generator" + + has_one :alias_name, String + has_one :datetime, DateTime + has_many :links, Link, tag: "link" + has_one :name, String + has_one :type, String + has_one :version, String + end + + class Notes + include HappyMapper + + tag "notes" + + has_many :paras, String, tag: "para" + has_many :links, Link, tag: "link" + end + + class Price + include HappyMapper + + tag "price" + + attribute :currency, String + attribute :value, Float + end + + class Tissue + include HappyMapper + + tag "tissue" + + attribute :gas, String + attribute :half_life, Float + attribute :number, Integer + attribute :a, Float + attribute :b, Float + end + + class VPM + include HappyMapper + + tag "vpm" + + attribute :id, String + has_one :conservatism, Float + has_one :gamma, Float + has_one :gc, Float + has_one :lambda, Float + has_one :r0, Float + has_many :tissues, Tissue, tag: "tissue" + end + + class RGBM + include HappyMapper + + tag "rgbm" + + attribute :id, String + has_many :tissues, Tissue, tag: "tissue" + end + + class Buehlmann + include HappyMapper + + tag "buehlmann" + + attribute :id, String + has_one :gradient_factor_high, Float + has_one :gradient_factor_low, Float + has_many :tissues, Tissue, tag: "tissue" + end + + class DecoModel + include HappyMapper + + tag "decomodel" + + has_many :buehlmanns, Buehlmann, tag: "buehlmann" + has_many :rgbms, RGBM, tag: "rbgm" + has_many :vpms, VPM, tag: "vpm" + end + + class Mix + include HappyMapper + + tag "mix" + + attribute :id, String + has_one :alias_name, String + has_one :ar, Float + has_one :equivalent_air_depth, Float + has_one :h2, Float + has_one :he, Float + has_one :maximum_operation_depth, Float + has_one :maximum_po2, Float + has_one :n2, Float + has_one :name, String + has_one :o2, Float + has_one :price_per_litre, Price + end + + class GasDefinitions + include HappyMapper + + tag "gasdefinitions" + + has_many :mixes, Mix, tag: "mix" + end + + class WayAltitude + include HappyMapper + + tag "wayaltitude" + + attribute :way_time, Float + attribute :value, Float + end + + class ExposureToAltitude + include HappyMapper + + tag "exposuretoaltitude" + + has_one :altitude_of_exposure, Float + has_one :date_of_flight, Date + has_one :surface_interval_before_altitude_exposure, Float + has_one :total_length_of_exposure, Float + has_one :transportation, String + end + + class SurfaceIntervalBeforeDive + include HappyMapper + + tag "surfaceintervalbeforedive" + + has_one :exposure_to_altitude, ExposureToAltitude + has_one :infinity, String + has_one :passed_time, Float + has_many :way_altitudes, WayAltitude, tag: "wayaltitude" + end + + class SurfaceIntervalAfterDive + include HappyMapper + + tag "surfaceintervalafterdive" + + has_one :exposure_to_altitude, ExposureToAltitude + has_one :infinity, String + has_one :passed_time, Float + has_many :way_altitudes, WayAltitude, tag: "wayaltitude" + end + + class TankPressure + include HappyMapper + + tag "tankpressure" + + attribute :ref, String + attribute :value, Float + end + + class SwitchMix + include HappyMapper + + tag "switchmix" + + attribute :ref, String + end + + class SetPo2 + include HappyMapper + + tag "setpo2" + + attribute :set_by, String + attribute :value, Float + end + + class PPo2 + include HappyMapper + + tag "ppo2" + + attribute :ref, String + attribute :value, Float + end + + class GradientFactor + include HappyMapper + + tag "gradientfactor" + + attribute :tissue, Integer + attribute :value, Float + end + + class DiveMode + include HappyMapper + + tag "divemode" + + attribute :type, String + end + + class Decostop + include HappyMapper + + tag "decostop" + + attribute :kind, String + attribute :deco_depth, Float + attribute :duration, Float + end + + class Battery + include HappyMapper + + tag "battery" + + attribute :ref, String + end + + class BatteryChargeCondition + include HappyMapper + + tag "batterychargecondition" + + attribute :ref, String + attribute :value, Float + end + + class BatteryVoltage + include HappyMapper + + tag "batteryvoltage" + + attribute :ref, String + attribute :value, Float + end + + class Alarm + include HappyMapper + + tag "alarm" + + attribute :level, Float + attribute :tank_ref, String + attribute :value, String + end + + class Info + include HappyMapper + + tag "info" + + attribute :ref, String + attribute :level, String + attribute :type, String + attribute :values, Float + attribute :units, String + end + + class PPCo2 + include HappyMapper + + tag "ppco2" + + attribute :ref, String + + content :value, Float + end + + class Waypoint + include HappyMapper + + tag "waypoint" + + has_many :alarms, Alarm, tag: "alarm" + has_many :battery_charge_conditions, BatteryChargeCondition, tag: "batterychargecondition" + has_many :battery_voltages, BatteryVoltage, tag: "batteryvoltage" + has_one :calculated_po2, Float + has_one :cns, Float + has_many :deco_stops, Decostop, tag: "decostop" + has_one :depth, Float + has_one :dive_mode, DiveMode + has_one :dive_time, Float + has_one :gradient_factor, GradientFactor + has_one :heading, Float + has_many :ppo2s, PPo2, tag: "ppo2" + has_one :no_deco_time, Float + has_one :otu, Float + has_one :remaining_bottom_time, Float + has_one :remaining_o2_time, Float + has_many :set_po2s, SetPo2, tag: "setpo2" + has_one :switch_mix, SwitchMix + has_many :tank_pressures, TankPressure, tag: "tankpressure" + has_one :temperature, Float + has_many :timers, Timer, tag: "timer" + has_many :infos, Info, tag: "info" + has_many :ppco2s, PPCo2, tag: "ppco2" + has_many :scrubbers, Scrubber, tag: "scrubber" + end + + class Medicine + include HappyMapper + + tag "medicine" + + has_one :alias_name, String + has_one :name, String + has_one :notes, Notes + has_one :periodically_taken, String + has_one :timespan_before_dive, Float + end + + class MedicationBeforeDive + include HappyMapper + + tag "medicationbeforedive" + + has_many :medicines, Medicine, tag: "medicine" + end + + class PlannedProfile + include HappyMapper + + tag "plannedprofile" + + attribute :start_dive_mode, String + attribute :start_mix, String + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class Drink + include HappyMapper + + tag "drink" + + has_one :alias_name, String + has_one :name, String + has_one :notes, Notes + has_one :periodically_taken, String + has_one :timespan_before_dive, Float + end + + class AlcoholBeforeDive + include HappyMapper + + tag "alcoholbeforedive" + + has_many :drinks, Drink, tag: "drink" + end + + class InformationBeforeDive + include HappyMapper + + tag "informationbeforedive" + + has_one :air_temperature, Float + has_one :alcohol_before_dive, AlcoholBeforeDive + has_one :altitude, Float + has_one :apparatus, String + has_one :datetime, DateTime + has_one :deep_stops, DeepStops, tag: "deepstops" + has_one :dive_number, Integer + has_one :dive_number_of_day, Integer + has_one :internal_dive_number, Integer + has_many :links, Link, tag: "link" + has_one :medication_before_dive, MedicationBeforeDive + has_one :no_suit, String + has_one :planned_profile, PlannedProfile + has_one :platform, String + has_one :price, Price + has_one :purpose, String + has_many :rebreather_self_tests, RebreatherSelfTest, tag: "rebreatherselftest" + has_one :state_of_rest_before_dive, String + has_many :self_tests, SelfTest, tag: "selftest" + has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive + has_one :surface_pressure, Float + has_one :trip_membership, String + has_many :timers, Timer, tag: "timer" + end + + class Rating + include HappyMapper + + tag "rating" + + has_one :datetime, DateTime + has_one :rating_value, Integer + end + + class GlobalAlarmsGiven + include HappyMapper + + tag "globalalarmsgiven" + + has_many :global_alarms, String, tag: "globalalarm" + end + + class EquipmentUsed + include HappyMapper + + tag "equipmentused" + + has_one :lead_quantity, Float + has_many :links, Link, tag: "link" + end + + class AnySymptoms + include HappyMapper + + tag "anysymptoms" + + has_one :notes, Notes + end + + class Species + include HappyMapper + + tag "species" + + attribute :id, String + has_one :abundance, "Abundance" + has_one :age, Integer + has_one :dominance, String + has_one :life_stage, String + has_one :notes, Notes + has_one :scientific_name, String + has_one :sex, String + has_one :size, Float + has_one :trivial_name, String + end + + class Abundance + include HappyMapper + + tag "abundance" + + attribute :quality, String + attribute :occurrence, String + attribute :value, Integer + end + + class WithSpecies + include HappyMapper + + has_many :species, Species, tag: "species" + end + + class Invertebrata + include HappyMapper + + tag "invertebrata" + + has_one :ascidiacea, WithSpecies + has_one :bryozoan, WithSpecies + has_one :cnidaria, WithSpecies + has_one :coelenterata, WithSpecies + has_one :crustacea, WithSpecies + has_one :ctenophora, WithSpecies + has_one :echinodermata, WithSpecies + has_one :invertebrata_various, WithSpecies + has_one :mollusca, WithSpecies + has_one :phoronidea, WithSpecies + has_one :plathelminthes, WithSpecies + has_one :porifera, WithSpecies + end + + class Vertebrata + include HappyMapper + + tag "vertebrata" + + has_one :amphibia, WithSpecies + has_one :chondrichthyes, WithSpecies + has_one :mammalia, WithSpecies + has_one :osteichthyes, WithSpecies + has_one :reptilia, WithSpecies + has_one :vertebrata_various, WithSpecies + end + + class Fauna + include HappyMapper + + tag "fauna" + + has_one :invertebrata, Invertebrata + has_one :notes, Notes + has_one :vertebrata, Vertebrata + end + + class Flora + include HappyMapper + + tag "flora" + + has_one :chlorophyceae, WithSpecies + has_one :flora_various, WithSpecies + has_one :notes, Notes + has_one :phaeophyceae, WithSpecies + has_one :rhodophyceae, WithSpecies + has_one :spermatophyta, WithSpecies + end + + class Observations + include HappyMapper + + tag "observations" + + has_one :fauna, Fauna + has_one :flora, Flora + has_one :notes, Notes + end + + class InformationAfterDive + include HappyMapper + + tag "informationafterdive" + + has_one :any_symptoms, AnySymptoms + has_one :average_depth, Float + has_one :current, String + has_one :desaturation_time, Float + has_one :dive_duration, Float + has_one :dive_plan, String + has_one :dive_table, String + has_one :equipment_malfunction, String + has_one :equipment_used, EquipmentUsed + has_one :global_alarms_given, GlobalAlarmsGiven + has_one :greatest_depth, Float + has_one :highest_po2, Float + has_one :lowest_temperature, Float + has_one :no_flight_time, Float + has_one :notes, Notes + has_one :observations, Observations + has_one :pressure_drop, Float + has_many :problems, String, tag: "problems" + has_one :program, String + has_many :ratings, Rating, tag: "rating" + has_one :surface_interval_after_dive, SurfaceIntervalAfterDive + has_one :thermal_comfort, String + has_many :timers, Timer, tag: "timer" + has_one :visibility, Float + has_one :workload, String + end + + class Samples + include HappyMapper + + tag "samples" + + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class TankData + include HappyMapper + + tag "tankdata" + + attribute :id, String + + has_one :analysed_he, Float, tag: "analysedhe" + has_one :analysed_o2, Float, tag: "analysedo2" + has_one :breathing_consumption_volume, Float + has_many :links, Link, tag: "link" + has_one :tank_pressure_begin, Float + has_one :tank_pressure_end, Float + has_one :tank_volume, Float + end + + class Hargikas + include HappyMapper + + tag "hargikas" + + has_one :ambient, Float + has_many :tissues, Tissue, tag: "tissue" + has_one :arterial_micro_bubble_level, Integer + has_one :intrapulmonary_right_left_shunt, Float + has_one :estimated_skin_cool_level, Integer + end + + class ApplicationData + include HappyMapper + + tag "applicationdata" + + has_one :deco_trainer, String + has_one :hargikas, Hargikas + has_one :apdiving, String + has_one :ratio, String + end + + class Dive + include HappyMapper + + tag "dive" + + attribute :id, String + has_one :information_after_dive, InformationAfterDive + has_one :information_before_dive, InformationBeforeDive + has_one :application_data, ApplicationData + has_one :samples, Samples + has_many :tank_data, TankData, tag: "tankdata" + end + + class RepetitionGroup + include HappyMapper + + tag "repetitiongroup" + + attribute :id, String + has_many :dives, Dive, tag: "dive" + end + + class ProfileData + include HappyMapper + + tag "profiledata" + + has_many :repetition_groups, RepetitionGroup, tag: "repetitiongroup" + end + + class Descent + include HappyMapper + + tag "descent" + + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class Ascent + include HappyMapper + + tag "ascent" + + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class MixChange + include HappyMapper + + tag "mixchange" + + has_one :ascent, Ascent + has_one :descent, Descent + end + + class InputProfile + include HappyMapper + + tag "inputprofile" + + has_many :links, Link, tag: "link" + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class Output + include HappyMapper + + tag "output" + + has_one :lingo, String + has_one :file_format, String + has_one :file_name, String + has_one :headline, String + has_one :remark, String + end + + class Profile + include HappyMapper + + tag "profile" + + has_one :application_data, ApplicationData + has_one :deco_model, DecoModel + has_one :deep_stops, DeepStops, tag: "deepstops" + has_one :density, Float + has_one :input_profile, InputProfile + has_many :links, Link, tag: "link" + has_one :maximum_ascending_rate, Float + has_one :mix_change, MixChange + has_one :output, Output + has_one :surface_interval_after_dive, SurfaceIntervalAfterDive + has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive + has_one :title, String + end + + class TableScope + include HappyMapper + + tag "tablescope" + + has_one :altitude, Float + has_one :bottom_time_maximum, Float + has_one :bottom_time_minimum, Float + has_one :bottom_time_step_begin, Float + has_one :bottom_time_step_end, Float + has_one :dive_depth_begin, Float + has_one :dive_depth_end, Float + has_one :dive_depth_step, Float + end + + class Table + include HappyMapper + + tag "table" + + has_one :table_scope, TableScope + has_one :deep_stops, DeepStops, tag: "deepstops" + end + + class CalculateProfile + include HappyMapper + + tag "calculateprofile" + + has_many :profiles, Profile, tag: "profile" + end + + class CalculateTable + include HappyMapper + + tag "calculatetable" + + has_many :tables, Table, tag: "table" + end + + class BottomTimeTableScope + include HappyMapper + + tag "bottomtimetablescope" + + has_one :breathing_consumption_volume_begin, Float + has_one :breathing_consumption_volume_end, Float + has_one :breathing_consumption_volume_step, Float + has_one :dive_depth_begin, Float + has_one :dive_depth_end, Float + has_one :dive_depth_step, Float + has_one :tank_pressure_begin, Float + has_one :tank_pressure_reserve, Float + has_one :tank_volume_begin, Float + has_one :tank_volume_end, Float + end + + class BottomTimeTable + include HappyMapper + + tag "bottomtimetable" + + attribute :id, String + has_one :application_data, ApplicationData + has_one :bottom_time_table_scope, BottomTimeTableScope + has_many :links, Link, tag: "link" + has_one :output, Output + has_one :title, String + end + + class CalculateBottomTimeTable + include HappyMapper + + tag "calculatebottomtimetable" + + has_many :bottom_time_tables, BottomTimeTable, tag: "bottomtimetable" + end + + class TableGeneration + include HappyMapper + + tag "tablegeneration" + + has_one :calculate_bottom_time_table, CalculateBottomTimeTable + has_one :calculate_profile, CalculateProfile + has_one :calculate_table, CalculateTable + end + + class ImageData + include HappyMapper + + tag "imagedata" + + has_one :aperture, Float + has_one :datetime, DateTime + has_one :exposure_compensation, Float + has_one :film_speed, Integer + has_one :focal_length, Float + has_one :focusing_distance, Float + has_one :metering_method, String + has_one :shutter_speed, Float + end + + class Image + include HappyMapper + + tag "image" + + attribute :id, String + attribute :height, Integer + attribute :width, Integer + attribute :format, String + has_one :image_data, ImageData + has_one :object_name, String + has_one :title, String + end + + class Video + include HappyMapper + + tag "video" + + attribute :id, String + has_one :object_name, String + has_one :title, String + end + + class Audio + include HappyMapper + + tag "audio" + + attribute :id, String + has_one :object_name, String + has_one :title, String + end + + class MediaData + include HappyMapper + + tag "mediadata" + + has_many :audio_files, Audio, tag: "audio" + has_many :image_files, Image, tag: "image" + has_many :video_files, Video, tag: "video" + end + + class Maker + include HappyMapper + + tag "maker" + + has_many :manufacturers, Manufacturer, tag: "manufacturer" + end + + class PriceDivePackage + include HappyMapper + + tag "pricedivepackage" + + attribute :currency, String + attribute :no_of_dives, Integer + attribute :value, Float + end + + class RelatedDives + include HappyMapper + + tag "relateddives" + + has_many :links, Link, tag: "link" + end + + class ShipDimension + include HappyMapper + + tag "shipdimension" + + has_one :beam, Float + has_one :displacement, Float + has_one :draught, Float + has_one :length, Float + has_one :tonnage, Float + end + + class Vessel + include HappyMapper + + tag "vessel" + + has_one :address, Base::Models::Address + has_one :alias_name, String + has_one :contact, Base::Models::Contact + has_one :marina, String + has_one :name, String + has_one :notes, Notes + has_many :ratings, Rating, tag: "rating" + has_one :ship_dimension, ShipDimension + has_one :ship_type, String + end + + class Operator + include HappyMapper + + tag "operator" + + has_one :alias_name, String + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :name, String + has_one :notes, Notes + has_many :ratings, Rating, tag: "rating" + end + + class DateOfTrip + include HappyMapper + + tag "dateoftrip" + + attribute :start_date, DateTime + attribute :end_date, DateTime + end + + class Accommodation + include HappyMapper + + tag "accommodation" + + has_one :address, Base::Models::Address + has_one :alias_name, String + has_one :category, String + has_one :contact, Base::Models::Contact + has_one :name, String + has_one :notes, Notes + has_many :ratings, Rating, tag: "rating" + end + + class Geography + include HappyMapper + + tag "geography" + + has_one :address, Base::Models::Address + has_one :altitude, Float + has_one :latitude, Float + has_one :location, String + has_one :longitude, Float + has_one :time_zone, Float + end + + class TripPart + include HappyMapper + + tag "trippart" + + attribute :type, String + has_one :accommodation, Accommodation + has_one :date_of_trip, DateOfTrip + has_one :geography, Geography + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + has_one :operator, Operator + has_one :price_dive_package, PriceDivePackage + has_one :price_per_dive, Price + has_one :related_dives, RelatedDives + has_one :vessel, Vessel + end + + class Trip + include HappyMapper + + tag "trip" + + attribute :id, String + has_one :alias_name, String + has_one :name, String + has_many :ratings, Rating, tag: "rating" + has_many :trip_parts, TripPart, tag: "trippart" + end + + class DiveTrip + include HappyMapper + + tag "divetrip" + + has_many :trips, Trip, tag: "trip" + end + + class Ecology + include HappyMapper + + tag "ecology" + + has_one :fauna, Fauna + has_one :flora, Flora + end + + class Built + include HappyMapper + + tag "built" + + has_one :launching_date, Date + has_one :ship_yard, String + end + + class Wreck + include HappyMapper + + tag "wreck" + + has_one :alias_name, String + has_one :built, Built + has_one :name, String + has_one :nationality, String + has_one :ship_dimension, ShipDimension + has_one :ship_type, String + has_one :sunk, Date + end + + class Shore + include HappyMapper + + tag "shore" + + attribute :id, String + has_one :alias_name, String + has_one :name, String + has_one :notes, Notes + end + + class River + include HappyMapper + + tag "river" + + attribute :id, String + has_one :alias_name, String + has_one :name, String + has_one :notes, Notes + end + + class Lake + include HappyMapper + + tag "lake" + + attribute :id, String + has_one :alias_name, String + has_one :name, String + has_one :notes, Notes + end + + class Indoor + include HappyMapper + + tag "indoor" + + has_one :address, Base::Models::Address + has_one :alias_name, String + has_one :contact, Base::Models::Contact + has_one :name, String + has_one :notes, Notes + end + + class Cave + include HappyMapper + + tag "cave" + + attribute :id, String + has_one :alias_name, String + has_one :name, String + has_one :notes, Notes + end + + class SiteData + include HappyMapper + + tag "sidedata" + + has_one :area_length, Float + has_one :area_width, Float + has_one :average_visibility, Float + has_one :bottom, String + has_one :cave, Cave + has_one :density, Float + has_one :difficulty, Integer + has_one :global_light_intensity, String + has_one :indoor, Indoor + has_one :maximum_depth, Float + has_one :maximum_visibility, Float + has_one :minimum_depth, Float + has_one :minimum_visibility, Float + has_one :river, River + has_one :shore, Shore + has_one :terrain, String + has_one :wreck, Wreck + end + + class Site + include HappyMapper + + tag "site" + + attribute :id, String + has_one :alias_name, String + has_one :ecology, Ecology + has_one :environment, String + has_one :geography, Geography + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + has_many :ratings, Rating, tag: "rating" + has_one :side_data, SiteData + end + + class Guide + include HappyMapper + + tag "guide" + + has_many :links, Link, tag: "link" + end + + class DiveBase + include HappyMapper + + tag "divebase" + + attribute :id, String + has_one :address, Base::Models::Address + has_one :alias_name, String + has_one :contact, Base::Models::Contact + has_many :guides, Guide, tag: "guide" + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + has_one :price_dive_package, PriceDivePackage + has_one :price_per_dive, Price + has_many :ratings, Rating, tag: "rating" + end + + class DiveSite + include HappyMapper + + tag "divesite" + + has_many :dive_bases, DiveBase, tag: "divebase" + has_many :sites, Site, tag: "site" + end + + class Shop + include HappyMapper + + tag "shop" + + has_one :alias_name, String + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :name, String + has_one :notes, Notes + end + + class Business + include HappyMapper + + tag "business" + + has_one :shop, Shop + end + + class Membership + include HappyMapper + + tag "membership" + + attribute :organisation, String + attribute :member_id, String + end + + class NumberOfDives + include HappyMapper + + tag "numberofdives" + + has_one :start_date, Date + has_one :end_date, Date + has_one :dives, Integer + end + + class Personal + include HappyMapper + + tag "personal" + + has_one :birth_date, Date + has_one :birth_name, String + has_one :blood_group, String + has_one :first_name, String + has_one :height, Float + has_one :honorific, String + has_one :last_name, String + has_one :membership, Membership + has_one :middle_name, String + has_one :number_of_dives, NumberOfDives + has_one :sex, String + has_one :smoking, String + has_one :weight, Float + end + + class Instructor + include HappyMapper + + tag "instructor" + + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :personal, Personal + end + + class Certification + include HappyMapper + + tag "certification" + + has_one :certificate_number, String + has_one :instructor, Instructor + has_one :issue_date, Date + has_one :level, String + has_one :link, Link + has_one :organization, String + has_one :specialty, String + has_one :valid_date, Date + end + + class Education + include HappyMapper + + tag "education" + + has_many :certifications, Certification, tag: "certification" + end + + class Insurance + include HappyMapper + + tag "insurance" + + has_one :alias_name, String + has_one :issue_date, Date + has_one :name, String + has_one :notes, Notes + has_one :valid_date, Date + end + + class DiveInsurances + include HappyMapper + + tag "diveinsurances" + + has_many :insurances, Insurance, tag: "insurance" + end + + class Permit + include HappyMapper + + tag "permit" + + has_one :alias_name, String + has_one :issue_date, Date + has_one :name, String + has_one :notes, Notes + has_one :region, String + has_one :valid_date, Date + end + + class DivePermissions + include HappyMapper + + tag "divepermissions" + + has_many :permits, Permit, tag: "permit" + end + + class Purchase + include HappyMapper + + tag "purchase" + + has_one :datetime, DateTime + has_one :link, Link + has_one :price, Price + has_one :shop, Shop + end + + class TemperatureSensor + include HappyMapper + + tag "temperaturesensor" + + attribute :id, String + + has_many :alias_names, String, tag: "aliasname" + has_one :manufacturer, Manufacturer + has_one :model, String + has_one :name, String + has_one :next_service_date, Base::Models::DateTimeField, tag: "nextservicedate" + has_one :notes, Notes + has_one :purchase, Purchase + has_one :serial_number, String, tag: "serialnumber" + has_one :service_interval, Integer, tag: "serviceinterval" + end + + class TimerDevice + include HappyMapper + + tag "timerdevice" + + attribute :id, String + end + + class EquipmentPart + include HappyMapper + + tag "equipmentpart" + + attribute :id, String + has_one :alias_name, String + has_many :links, Link, tag: "link" + has_one :manufacturer, Manufacturer + has_one :model, String + has_one :name, String + has_one :next_service_date, Date + has_one :notes, Notes + has_one :purchase, Purchase + has_one :serial_number, String + has_one :service_interval, Integer + end + + class Lead < EquipmentPart + include HappyMapper + + tag "lead" + + has_one :lead_quantity, Integer + end + + class Rebreather < EquipmentPart + include HappyMapper + + tag "rebreather" + + has_many :batteries, Battery, tag: "battery" + has_many :o2_sensors, EquipmentPart, tag: "o2sensor" + has_many :scrubber_monitors, ScrubberMonitor, tag: "scrubbermonitor" + has_many :temperature_sensors, TemperatureSensor, tag: "temperaturesensor" + has_many :timer_devices, TimerDevice, tag: "timerdevice" + end + + class Suit < EquipmentPart + include HappyMapper + + tag "suit" + + has_one :suit_type, String + end + + class Tank < EquipmentPart + include HappyMapper + + tag "tank" + + has_one :tank_material, String + has_one :tank_volume, Float + has_many :batteries, Battery, tag: "battery" + end + + class Camera + include HappyMapper + + tag "camera" + + has_one :body, EquipmentPart + has_many :flashes, EquipmentPart, tag: "flash" + has_one :housing, EquipmentPart + has_one :lens, EquipmentPart + end + + class DiveComputer < EquipmentPart + include HappyMapper + + tag "divecomputer" + + has_many :batteries, Battery, tag: "battery" + has_many :timer_devices, TimerDevice, tag: "timerdevice" + end + + class EquipmentContent + include HappyMapper + + has_many :boots, EquipmentPart, tag: "boots" + has_many :buoyancy_control_devices, EquipmentPart, tag: "buoyancycontroldevice" + has_many :cameras, Camera, tag: "camera" + has_many :compasses, EquipmentPart, tag: "compass" + has_many :dive_computers, DiveComputer, tag: "divecomputer" + has_many :fins, EquipmentPart, tag: "fins" + has_many :gloves, EquipmentPart, tag: "gloves" + has_many :knives, EquipmentPart, tag: "knife" + has_many :leads, Lead, tag: "lead" + has_many :lights, EquipmentPart, tag: "light" + has_many :masks, EquipmentPart, tag: "mask" + has_many :rebreathers, Rebreather, tag: "rebreather" + has_many :regulators, EquipmentPart, tag: "regulator" + has_many :scooters, EquipmentPart, tag: "scooter" + has_many :suits, Suit, tag: "suit" + has_many :tanks, Tank, tag: "tank" + has_many :various_pieces, EquipmentPart, tag: "variouspieces" + has_many :video_cameras, EquipmentPart, tag: "videocamera" + has_many :watches, EquipmentPart, tag: "watch" + end + + class EquipmentConfiguration < EquipmentContent + include HappyMapper + + tag "equipmentconfiguration" + + has_one :alias_name, String + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + end + + class Equipment < EquipmentContent + include HappyMapper + + tag "equipment" + + has_many :compressors, EquipmentPart, tag: "compressor" + has_one :equipment_configuration, EquipmentConfiguration + end + + class Doctor + include HappyMapper + + tag "doctor" + + attribute :id, String + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :personal, Personal + end + + class Examination + include HappyMapper + + tag "examination" + + has_one :datetime, DateTime + has_one :doctor, Doctor + has_one :examination_result, String + has_many :links, Link, tag: "link" + has_one :notes, Notes + has_one :total_lung_capacity, Float + has_one :vital_capacity, Float + end + + class Medical + include HappyMapper + + tag "medical" + + has_one :examination, Examination + end + + class BuddyOwnerShared + include HappyMapper + + attribute :id, String + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :dive_insurances, DiveInsurances + has_one :dive_permissions, DivePermissions + has_one :equipment, Equipment + has_one :medical, Medical + has_one :notes, Notes + has_one :personal, Personal + end + + class Buddy < BuddyOwnerShared + include HappyMapper + + tag "buddy" + + attribute :id, String + has_one :certification, Certification + has_one :student, String + end + + class Owner < BuddyOwnerShared + include HappyMapper + + tag "owner" + + attribute :id, String + has_one :education, Education + end + + class Diver + include HappyMapper + + tag "diver" + + has_many :buddies, Buddy, tag: "buddy" + has_one :owner, Owner + end + + class DCAlarm + include HappyMapper + + tag "dcalarm" + + has_one :acknowledge, String + has_one :alarm_type, Integer + has_one :period, Float + end + + class SetDCDiveDepthAlarm + include HappyMapper + + tag "setdcdivedethalarm" + + has_one :dc_alarm, DCAlarm + has_one :dc_alarm_depth, Float + end + + class SetDCDivePo2Alarm + include HappyMapper + + tag "setdcdivepo2alarm" + + has_one :dc_alarm, DCAlarm + has_one :maximum_po2, Float + end + + class SetDCDiveSiteData + include HappyMapper + + tag "setdcdivesitedata" + + attribute :dive_site, String + end + + class SetDCDiveTimeAlarm + include HappyMapper + + tag "setdcdivetimealarm" + + has_one :dc_alarm, DCAlarm + has_one :timespan, Float + end + + class SetDCEndNDTAlarm + include HappyMapper + + tag "setdcendndtalarm" + + has_one :dc_alarm, DCAlarm + end + + class SetDCDecoModel + include HappyMapper + + tag "setdcdecomodel" + + has_one :alias_name, String + has_one :application_data, ApplicationData + has_one :name, String + end + + class SetDCBuddyData + include HappyMapper + + tag "setdcbuddydata" + + attribute :buddy, String + end + + class SetDCData + include HappyMapper + + tag "setdcdata" + + has_one :set_dc_alarm_time, DateTime + has_one :set_dc_altitude, Float + has_one :set_dc_buddy_data, SetDCBuddyData + has_one :set_dc_date_time, DateTime + has_one :set_dc_deco_model, SetDCDecoModel + has_one :set_dc_dive_depth_alarm, SetDCDiveDepthAlarm + has_one :set_dc_dive_po2_alarm, SetDCDivePo2Alarm + has_many :set_dc_dive_site_data, SetDCDiveSiteData, tag: "setdcdivesitedata" + has_one :set_dc_dive_time_alarm, SetDCDiveTimeAlarm + has_one :set_dc_end_ndt_alarm, SetDCEndNDTAlarm + has_one :set_dc_gas_definitions_data, String + has_one :set_dc_owner_data, String + has_one :set_dc_password, String + has_one :set_dc_generator_data, String + end + + class GetDCData + include HappyMapper + + tag "getdcdata" + + has_one :get_dc_all_data, String + has_one :get_dc_generator_data, String + has_one :get_dc_owner_data, String + has_one :get_dc_buddy_data, String + has_one :get_dc_gas_definitions_data, String + has_one :get_dc_dive_site_data, String + has_one :get_dc_dive_trip_data, String + has_one :get_dc_profile_data, String + end + + class DiveComputerDump + include HappyMapper + + tag "divecomputerdump" + + has_one :datetime, DateTime + has_one :dc_dump, String + has_one :link, Link + end + + class DiveComputerControl + include HappyMapper + + tag "divecomputercontrol" + + has_many :dive_computer_dumps, DiveComputerDump, tag: "divecomputerdump" + has_one :get_dc_data, GetDCData + has_one :set_dc_data, SetDCData + end + + class Uddf + include HappyMapper + + tag "uddf" + + attribute :version, String + has_one :business, Business + has_one :deco_model, DecoModel + has_one :dive_computer_control, DiveComputerControl + has_one :diver, Diver + has_one :dive_site, DiveSite + has_one :dive_trip, DiveTrip + has_one :gas_definitions, GasDefinitions + has_one :generator, Generator + has_one :maker, Maker + has_one :media_data, MediaData + has_one :profile_data, ProfileData + has_one :table_generation, TableGeneration + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..42753c5 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "simplecov" +SimpleCov.start + +require_relative "../lib/uddf" + +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end + + config.shared_context_metadata_behavior = :apply_to_host_groups +end diff --git a/spec/uddf_parser_spec.rb b/spec/uddf_parser_spec.rb new file mode 100644 index 0000000..abc728e --- /dev/null +++ b/spec/uddf_parser_spec.rb @@ -0,0 +1,191 @@ +# frozen_string_literal: true + +require_relative "spec_helper" + +# Shared helper methods for UDDF parsing and validation +module UDDFParserHelpers + def parse_uddf_file(file_path) + UDDF.load(file_path) + end + + def validate_dive_basic_fields(dive, expected_fields = {}) + expect(dive).not_to be_nil + expect(dive).to respond_to(:id) + + expect(dive.id).to eq(expected_fields[:id]) if expected_fields[:id] + + if expected_fields[:dive_number] + expect(dive.information_before_dive).not_to be_nil + expect(dive.information_before_dive.dive_number).to eq(expected_fields[:dive_number]) + end + + return unless expected_fields[:datetime] + + expect(dive.information_before_dive).not_to be_nil + expect(dive.information_before_dive.datetime).to eq(expected_fields[:datetime]) + end + + def validate_dive_samples_present(dive) + expect(dive.samples).not_to be_nil + expect(dive.samples.waypoints).not_to be_empty + + # Verify basic waypoint structure + first_waypoint = dive.samples.waypoints.first + expect(first_waypoint).to respond_to(:depth) + expect(first_waypoint).to respond_to(:dive_time) + end + + def validate_dive_site_info(uddf_data, expected_site_fields = {}) + expect(uddf_data.dive_site).not_to be_nil + + return unless expected_site_fields[:sites_count] + + expect(uddf_data.dive_site.sites.length).to eq(expected_site_fields[:sites_count]) + end + + def validate_diver_info(uddf_data, expected_diver_fields = {}) + expect(uddf_data.diver).not_to be_nil + + return unless expected_diver_fields[:dive_computers_count] && uddf_data.diver.owner + + expect(uddf_data.diver.owner.equipment.dive_computers.length).to eq(expected_diver_fields[:dive_computers_count]) + end + + def validate_generator_info(uddf_data, expected_generator_fields = {}) + expect(uddf_data.generator).not_to be_nil + + expect(uddf_data.generator.name).to eq(expected_generator_fields[:name]) if expected_generator_fields[:name] + + return unless expected_generator_fields[:type] + + expect(uddf_data.generator.type).to eq(expected_generator_fields[:type]) + end + + def validate_multiple_uddf_files(file_paths, expected_dive_counts = {}) + file_paths.each do |file_path| + uddf_data = parse_uddf_file(file_path) + + expect(uddf_data).not_to be_nil + + # Count total dives across all repetition groups + # Some UDDF files may not have profile data (e.g., files with only diver/equipment data) + total_dives = if uddf_data.profile_data && uddf_data.profile_data.repetition_groups + uddf_data.profile_data.repetition_groups.sum { |rg| rg.dives.length } + else + 0 + end + + if expected_dive_counts[file_path] + expect(total_dives).to eq(expected_dive_counts[file_path]) + else + expect(total_dives).to be >= 0 + end + end + end +end + +RSpec.configure do |config| + config.include UDDFParserHelpers +end + +describe "UDDF Parser" do + describe "parsing Peregrine TX UDDF file" do + let(:file_path) { File.join(__dir__, "../test_files/v323/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf") } + let(:uddf_data) { parse_uddf_file(file_path) } + + it "successfully parses the UDDF file" do + expect(uddf_data).not_to be_nil + expect(uddf_data.version).to eq("3.2.3") + end + + it "contains correct generator information" do + validate_generator_info uddf_data, { + name: "Shearwater Cloud Desktop", + type: "logbook" + } + end + + it "contains diver information with dive computer" do + validate_diver_info uddf_data, { + dive_computers_count: 1 + } + end + + it "contains dive site information" do + validate_dive_site_info uddf_data, { + sites_count: 1 + } + end + + it "contains profile data with dives" do + expect(uddf_data.profile_data).not_to be_nil + expect(uddf_data.profile_data.repetition_groups).not_to be_empty + + repetition_group = uddf_data.profile_data.repetition_groups.first + expect(repetition_group).not_to be_nil + expect(repetition_group.dives).not_to be_empty + end + + it "correctly parses dive #140 details" do + repetition_group = uddf_data.profile_data.repetition_groups.first + dive = repetition_group.dives.first + + validate_dive_basic_fields dive, { + id: "636812201742559648", + dive_number: 140 + } + end + + it "contains dive sample data (waypoints)" do + repetition_group = uddf_data.profile_data.repetition_groups.first + dive = repetition_group.dives.first + + validate_dive_samples_present dive + end + + it "contains dive duration and depth information" do + repetition_group = uddf_data.profile_data.repetition_groups.first + dive = repetition_group.dives.first + + expect(dive.information_after_dive).not_to be_nil + expect(dive.information_after_dive.dive_duration).to be > 0 + expect(dive.information_after_dive.greatest_depth).to be > 0 + end + + it "contains tank data when present" do + repetition_group = uddf_data.profile_data.repetition_groups.first + dive = repetition_group.dives.first + + unless dive.tank_data.empty? + tank = dive.tank_data.first + expect(tank).to respond_to(:tank_pressure_begin) + expect(tank).to respond_to(:tank_pressure_end) + end + end + end + + describe "parsing multiple UDDF files" do + let(:test_files_dir) { File.join(__dir__, "../test_files") } + let(:uddf_files) { Dir.glob(File.join(test_files_dir, "**", "*.uddf")) } + + it "can parse all available UDDF files" do + skip "No UDDF files found" if uddf_files.empty? + skip "Only one UDDF file available" if uddf_files.length <= 1 + + validate_multiple_uddf_files(uddf_files) + end + + it "handles different UDDF file formats consistently" do + skip "Need multiple files for consistency testing" if uddf_files.length <= 1 + + uddf_files.each do |file_path| + uddf_data = parse_uddf_file(file_path) + + # Basic structure should be consistent across all files + expect(uddf_data).not_to be_nil + expect(uddf_data.version).to match(/^\d+\.\d+\.\d+$/) + expect(uddf_data.generator).not_to be_nil + end + end + end +end diff --git a/spec/uddf_spec.rb b/spec/uddf_spec.rb new file mode 100644 index 0000000..dde33d0 --- /dev/null +++ b/spec/uddf_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require_relative "spec_helper" + +describe UDDF do + it "has a version number" do + expect(UDDF::VERSION).not_to be_nil + end +end diff --git a/dive_files/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf b/test_files/v323/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf similarity index 100% rename from dive_files/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf rename to test_files/v323/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf diff --git a/dive_files/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf b/test_files/v323/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf similarity index 100% rename from dive_files/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf rename to test_files/v323/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf diff --git a/test_files/v330/diver_data.uddf b/test_files/v330/diver_data.uddf index 71f97fc..a552c57 100644 --- a/test_files/v330/diver_data.uddf +++ b/test_files/v330/diver_data.uddf @@ -95,14 +95,14 @@ male 1919-02-30 - 987654321 1.8 86.0 0 A - +
Auf der Heide 12 @@ -174,7 +174,7 @@ male -
Duddelstr. 34 diff --git a/uddf.gemspec b/uddf.gemspec index 1e17c0f..4966e6c 100644 --- a/uddf.gemspec +++ b/uddf.gemspec @@ -32,6 +32,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency "irb" spec.add_development_dependency "rake", "~> 13.0" + spec.add_development_dependency "rspec", "~> 3.13" spec.add_development_dependency "rubocop", "~> 1.7" spec.add_development_dependency "rubocop-rake", "~> 0.7" + spec.add_development_dependency "rubocop-rspec", "~> 3.6" + spec.add_development_dependency "simplecov", "~> 0.21" end From a28fba956b605aef0fdd285436b31bbb2f5a0b64 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 14:54:47 +0200 Subject: [PATCH 02/13] fix spec path Signed-off-by: Flipez --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b8d0874..1dc8b2d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,7 +16,7 @@ jobs: run: bundle exec rake - name: Run tests run: | - bundle exec rspec specs/ + bundle exec rspec - uses: joshmfrankel/simplecov-check-action@main with: github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 04c4b349c1c92d8502de21a26c1b379c4bfb6b1f Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 15:01:22 +0200 Subject: [PATCH 03/13] update action Signed-off-by: Flipez --- .github/workflows/main.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1dc8b2d..c3bb68c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,6 +17,7 @@ jobs: - name: Run tests run: | bundle exec rspec - - uses: joshmfrankel/simplecov-check-action@main - with: - github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_ORG_TOKEN }} \ No newline at end of file From 85085ef2fd3cee329fd1fec4629a44944f6c714c Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 15:05:17 +0200 Subject: [PATCH 04/13] format coverage as xml Signed-off-by: Flipez --- Gemfile.lock | 5 +++++ spec/spec_helper.rb | 3 +++ uddf.gemspec | 1 + 3 files changed, 9 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 04c0d35..13dc7ef 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -49,6 +49,7 @@ GEM regexp_parser (2.11.2) reline (0.6.2) io-console (~> 0.5) + rexml (3.4.1) rspec (3.13.1) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) @@ -87,6 +88,9 @@ GEM docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) + simplecov-cobertura (3.0.0) + rexml + simplecov (~> 0.19) simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) stringio (3.1.7) @@ -106,6 +110,7 @@ DEPENDENCIES rubocop-rake (~> 0.7) rubocop-rspec (~> 3.6) simplecov (~> 0.21) + simplecov-cobertura (~> 3) uddf! BUNDLED WITH diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 42753c5..c10bb43 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,9 @@ require "simplecov" SimpleCov.start +require "simplecov-cobertura" +SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter + require_relative "../lib/uddf" RSpec.configure do |config| diff --git a/uddf.gemspec b/uddf.gemspec index 4966e6c..c947057 100644 --- a/uddf.gemspec +++ b/uddf.gemspec @@ -37,4 +37,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rubocop-rake", "~> 0.7" spec.add_development_dependency "rubocop-rspec", "~> 3.6" spec.add_development_dependency "simplecov", "~> 0.21" + spec.add_development_dependency "simplecov-cobertura", "~> 3" end From 981d72631cad2e8c5a5cf517374cc22c15330444 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 15:08:35 +0200 Subject: [PATCH 05/13] fix action Signed-off-by: Flipez --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c3bb68c..45e8bfb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - name: Run tests run: | bundle exec rspec - - name: Upload coverage to Codecov + - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_ORG_TOKEN }} \ No newline at end of file + with: + token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file From 9f2378eaadd882bd78ef2228d736be8bd61b410c Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 15:43:04 +0200 Subject: [PATCH 06/13] fix tags and parsing Signed-off-by: Flipez --- lib/uddf/base/models.rb | 4 +- lib/uddf/v323/models.rb | 24 +- lib/uddf/v330/models.rb | 424 ++++++++++++++++---------------- spec/uddf_parser_spec.rb | 1 + test_files/v330/diver_data.uddf | 4 +- 5 files changed, 228 insertions(+), 229 deletions(-) diff --git a/lib/uddf/base/models.rb b/lib/uddf/base/models.rb index 2868c9a..f2fc05b 100644 --- a/lib/uddf/base/models.rb +++ b/lib/uddf/base/models.rb @@ -38,9 +38,7 @@ class Contact class DateTimeField include HappyMapper - tag "datetime" - - content :value, DateTime + has_one :date_time, DateTime, tag: "datetime" end end end diff --git a/lib/uddf/v323/models.rb b/lib/uddf/v323/models.rb index a9f62dd..11a8c26 100644 --- a/lib/uddf/v323/models.rb +++ b/lib/uddf/v323/models.rb @@ -969,7 +969,7 @@ class Built tag "built" - has_one :launching_date, Date, tag: "launchingdate" + has_one :launching_date, Base::Models::DateTimeField, tag: "launchingdate" has_one :ship_yard, String, tag: "shipyard" end @@ -984,7 +984,7 @@ class Wreck has_one :nationality, String has_one :ship_dimension, ShipDimension, tag: "shipdimension" has_one :ship_type, String, tag: "shiptype" - has_one :sunk, Date + has_one :sunk, Base::Models::DateTimeField end class Shore @@ -1153,8 +1153,8 @@ class NumberOfDives tag "numberofdives" - has_one :start_date, Date, tag: "startdate" - has_one :end_date, Date, tag: "enddate" + has_one :start_date, DateTime, tag: "startdate" + has_one :end_date, DateTime, tag: "enddate" has_one :dives, Integer end @@ -1163,7 +1163,7 @@ class Personal tag "personal" - has_one :birth_date, Date, tag: "birthdate" + has_one :birth_date, Base::Models::DateTimeField, tag: "birthdate" has_one :birth_name, String, tag: "birthname" has_one :blood_group, String, tag: "bloodgroup" has_one :first_name, String, tag: "firstname" @@ -1195,12 +1195,12 @@ class Certification has_one :certificate_number, String, tag: "certificatenumber" has_one :instructor, Instructor - has_one :issue_date, Date, tag: "issuedate" + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" has_one :level, String has_one :link, Link has_one :organization, String has_one :specialty, String - has_one :valid_date, Date, tag: "validdate" + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" end class Education @@ -1217,10 +1217,10 @@ class Insurance tag "insurance" has_many :alias_names, String, tag: "aliasname" - has_one :issue_date, Date, tag: "issuedate" + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" has_one :name, String has_one :notes, Notes - has_one :valid_date, Date, tag: "validdate" + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" end class DiveInsurances @@ -1237,11 +1237,11 @@ class Permit tag "permit" has_many :alias_names, String, tag: "aliasname" - has_one :issue_date, Date, tag: "issuedate" + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" has_one :name, String has_one :notes, Notes has_one :region, String - has_one :valid_date, Date, tag: "validdate" + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" end class DivePermissions @@ -1274,7 +1274,7 @@ class EquipmentPart has_one :manufacturer, Manufacturer has_one :model, String has_one :name, String - has_one :next_service_date, Date, tag: "nextservicedate" + has_one :next_service_date, Base::Models::DateTimeField, tag: "nextservicedate" has_one :notes, Notes has_one :purchase, Purchase has_one :serial_number, String, tag: "serialnumber" diff --git a/lib/uddf/v330/models.rb b/lib/uddf/v330/models.rb index e7130bb..f961e17 100644 --- a/lib/uddf/v330/models.rb +++ b/lib/uddf/v330/models.rb @@ -68,7 +68,7 @@ class Manufacturer attribute :id, String has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :contact, Base::Models::Contact has_one :name, String end @@ -86,7 +86,7 @@ class Generator tag "generator" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :datetime, DateTime has_many :links, Link, tag: "link" has_one :name, String @@ -109,7 +109,7 @@ class Price tag "price" attribute :currency, String - attribute :value, Float + content :value, Float end class Tissue @@ -153,8 +153,8 @@ class Buehlmann tag "buehlmann" attribute :id, String - has_one :gradient_factor_high, Float - has_one :gradient_factor_low, Float + has_one :gradient_factor_high, Float, tag: "gradientfactorhigh" + has_one :gradient_factor_low, Float, tag: "gradientfactorlow" has_many :tissues, Tissue, tag: "tissue" end @@ -174,17 +174,17 @@ class Mix tag "mix" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :ar, Float - has_one :equivalent_air_depth, Float + has_one :equivalent_air_depth, Float, tag: "equivalentairdepth" has_one :h2, Float has_one :he, Float - has_one :maximum_operation_depth, Float - has_one :maximum_po2, Float + has_one :maximum_operation_depth, Float, tag: "maximumoperationdepth" + has_one :maximum_po2, Float, tag: "maximumpo2" has_one :n2, Float has_one :name, String has_one :o2, Float - has_one :price_per_litre, Price + has_one :price_per_litre, Price, tag: "priceperlitre" end class GasDefinitions @@ -201,7 +201,7 @@ class WayAltitude tag "wayaltitude" attribute :way_time, Float - attribute :value, Float + content :value, Float end class ExposureToAltitude @@ -209,10 +209,10 @@ class ExposureToAltitude tag "exposuretoaltitude" - has_one :altitude_of_exposure, Float - has_one :date_of_flight, Date - has_one :surface_interval_before_altitude_exposure, Float - has_one :total_length_of_exposure, Float + has_one :altitude_of_exposure, Float, tag: "altitudeofexposure" + has_one :date_of_flight, Base::Models::DateTimeField, tag: "dateofflight" + has_one :surface_interval_before_altitude_exposure, Float, tag: "surfaceintervalbeforealtitudeexposure" + has_one :total_length_of_exposure, Float, tag: "totallengthofexposure" has_one :transportation, String end @@ -221,9 +221,9 @@ class SurfaceIntervalBeforeDive tag "surfaceintervalbeforedive" - has_one :exposure_to_altitude, ExposureToAltitude + has_one :exposure_to_altitude, ExposureToAltitude, tag: "exposuretoaltitude" has_one :infinity, String - has_one :passed_time, Float + has_one :passed_time, Float, tag: "passedtime" has_many :way_altitudes, WayAltitude, tag: "wayaltitude" end @@ -232,9 +232,9 @@ class SurfaceIntervalAfterDive tag "surfaceintervalafterdive" - has_one :exposure_to_altitude, ExposureToAltitude + has_one :exposure_to_altitude, ExposureToAltitude, tag: "exposuretoaltitude" has_one :infinity, String - has_one :passed_time, Float + has_one :passed_time, Float, tag: "passedtime" has_many :way_altitudes, WayAltitude, tag: "wayaltitude" end @@ -244,7 +244,7 @@ class TankPressure tag "tankpressure" attribute :ref, String - attribute :value, Float + content :value, Float end class SwitchMix @@ -261,7 +261,7 @@ class SetPo2 tag "setpo2" attribute :set_by, String - attribute :value, Float + content :value, Float end class PPo2 @@ -270,7 +270,7 @@ class PPo2 tag "ppo2" attribute :ref, String - attribute :value, Float + content :value, Float end class GradientFactor @@ -279,7 +279,7 @@ class GradientFactor tag "gradientfactor" attribute :tissue, Integer - attribute :value, Float + content :value, Float end class DiveMode @@ -314,7 +314,7 @@ class BatteryChargeCondition tag "batterychargecondition" attribute :ref, String - attribute :value, Float + content :value, Float end class BatteryVoltage @@ -323,7 +323,7 @@ class BatteryVoltage tag "batteryvoltage" attribute :ref, String - attribute :value, Float + content :value, Float end class Alarm @@ -333,7 +333,7 @@ class Alarm attribute :level, Float attribute :tank_ref, String - attribute :value, String + content :value, String end class Info @@ -366,21 +366,21 @@ class Waypoint has_many :alarms, Alarm, tag: "alarm" has_many :battery_charge_conditions, BatteryChargeCondition, tag: "batterychargecondition" has_many :battery_voltages, BatteryVoltage, tag: "batteryvoltage" - has_one :calculated_po2, Float + has_one :calculated_po2, Float, tag: "calculatedpo2" has_one :cns, Float has_many :deco_stops, Decostop, tag: "decostop" has_one :depth, Float - has_one :dive_mode, DiveMode - has_one :dive_time, Float - has_one :gradient_factor, GradientFactor + has_one :dive_mode, DiveMode, tag: "divemode" + has_one :dive_time, Float, tag: "divetime" + has_one :gradient_factor, GradientFactor, tag: "gradientfactor" has_one :heading, Float has_many :ppo2s, PPo2, tag: "ppo2" - has_one :no_deco_time, Float + has_one :no_deco_time, Float, tag: "nodecotime" has_one :otu, Float - has_one :remaining_bottom_time, Float - has_one :remaining_o2_time, Float + has_one :remaining_bottom_time, Float, tag: "remainingbottomtime" + has_one :remaining_o2_time, Float, tag: "remainingo2time" has_many :set_po2s, SetPo2, tag: "setpo2" - has_one :switch_mix, SwitchMix + has_one :switch_mix, SwitchMix, tag: "switchmix" has_many :tank_pressures, TankPressure, tag: "tankpressure" has_one :temperature, Float has_many :timers, Timer, tag: "timer" @@ -394,11 +394,11 @@ class Medicine tag "medicine" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes - has_one :periodically_taken, String - has_one :timespan_before_dive, Float + has_one :periodically_taken, String, tag: "periodicallytaken" + has_one :timespan_before_dive, Float, tag: "timespanbeforedive" end class MedicationBeforeDive @@ -424,11 +424,11 @@ class Drink tag "drink" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes - has_one :periodically_taken, String - has_one :timespan_before_dive, Float + has_one :periodically_taken, String, tag: "periodicallytaken" + has_one :timespan_before_dive, Float, tag: "timespanbeforedive" end class AlcoholBeforeDive @@ -444,28 +444,28 @@ class InformationBeforeDive tag "informationbeforedive" - has_one :air_temperature, Float - has_one :alcohol_before_dive, AlcoholBeforeDive + has_one :air_temperature, Float, tag: "airtemperature" + has_one :alcohol_before_dive, AlcoholBeforeDive, tag: "alcoholbeforedive" has_one :altitude, Float has_one :apparatus, String has_one :datetime, DateTime has_one :deep_stops, DeepStops, tag: "deepstops" - has_one :dive_number, Integer - has_one :dive_number_of_day, Integer - has_one :internal_dive_number, Integer + has_one :dive_number, Integer, tag: "divenumber" + has_one :dive_number_of_day, Integer, tag: "divenumberofday" + has_one :internal_dive_number, Integer, tag: "internaldivenumber" has_many :links, Link, tag: "link" - has_one :medication_before_dive, MedicationBeforeDive - has_one :no_suit, String - has_one :planned_profile, PlannedProfile + has_one :medication_before_dive, MedicationBeforeDive, tag: "medicationbeforedive" + has_one :no_suit, String, tag: "nosuit" + has_one :planned_profile, PlannedProfile, tag: "plannedprofile" has_one :platform, String has_one :price, Price has_one :purpose, String has_many :rebreather_self_tests, RebreatherSelfTest, tag: "rebreatherselftest" - has_one :state_of_rest_before_dive, String + has_one :state_of_rest_before_dive, String, tag: "stateofrestbeforedive" has_many :self_tests, SelfTest, tag: "selftest" - has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive - has_one :surface_pressure, Float - has_one :trip_membership, String + has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive, tag: "surfaceintervalbeforedive" + has_one :surface_pressure, Float, tag: "surfacepressure" + has_one :trip_membership, String, tag: "tripmembership" has_many :timers, Timer, tag: "timer" end @@ -475,7 +475,7 @@ class Rating tag "rating" has_one :datetime, DateTime - has_one :rating_value, Integer + has_one :rating_value, Integer, tag: "ratingvalue" end class GlobalAlarmsGiven @@ -491,7 +491,7 @@ class EquipmentUsed tag "equipmentused" - has_one :lead_quantity, Float + has_one :lead_quantity, Float, tag: "leadquantity" has_many :links, Link, tag: "link" end @@ -512,12 +512,12 @@ class Species has_one :abundance, "Abundance" has_one :age, Integer has_one :dominance, String - has_one :life_stage, String + has_one :life_stage, String, tag: "lifestage" has_one :notes, Notes - has_one :scientific_name, String + has_one :scientific_name, String, tag: "scientificname" has_one :sex, String has_one :size, Float - has_one :trivial_name, String + has_one :trivial_name, String, tag: "trivialname" end class Abundance @@ -527,7 +527,7 @@ class Abundance attribute :quality, String attribute :occurrence, String - attribute :value, Integer + content :value, Integer end class WithSpecies @@ -548,7 +548,7 @@ class Invertebrata has_one :crustacea, WithSpecies has_one :ctenophora, WithSpecies has_one :echinodermata, WithSpecies - has_one :invertebrata_various, WithSpecies + has_one :invertebrata_various, WithSpecies, tag: "invertebratavarious" has_one :mollusca, WithSpecies has_one :phoronidea, WithSpecies has_one :plathelminthes, WithSpecies @@ -565,7 +565,7 @@ class Vertebrata has_one :mammalia, WithSpecies has_one :osteichthyes, WithSpecies has_one :reptilia, WithSpecies - has_one :vertebrata_various, WithSpecies + has_one :vertebrata_various, WithSpecies, tag: "vertebratavarious" end class Fauna @@ -584,7 +584,7 @@ class Flora tag "flora" has_one :chlorophyceae, WithSpecies - has_one :flora_various, WithSpecies + has_one :flora_various, WithSpecies, tag: "floravarious" has_one :notes, Notes has_one :phaeophyceae, WithSpecies has_one :rhodophyceae, WithSpecies @@ -606,28 +606,28 @@ class InformationAfterDive tag "informationafterdive" - has_one :any_symptoms, AnySymptoms - has_one :average_depth, Float + has_one :any_symptoms, AnySymptoms, tag: "anysymptoms" + has_one :average_depth, Float, tag: "averagedepth" has_one :current, String - has_one :desaturation_time, Float - has_one :dive_duration, Float - has_one :dive_plan, String - has_one :dive_table, String - has_one :equipment_malfunction, String - has_one :equipment_used, EquipmentUsed - has_one :global_alarms_given, GlobalAlarmsGiven - has_one :greatest_depth, Float - has_one :highest_po2, Float - has_one :lowest_temperature, Float - has_one :no_flight_time, Float + has_one :desaturation_time, Float, tag: "desaturationtime" + has_one :dive_duration, Float, tag: "diveduration" + has_one :dive_plan, String, tag: "diveplan" + has_one :dive_table, String, tag: "divetable" + has_one :equipment_malfunction, String, tag: "equipmentmalfunction" + has_one :equipment_used, EquipmentUsed, tag: "equipmentused" + has_one :global_alarms_given, GlobalAlarmsGiven, tag: "globalalarmsgiven" + has_one :greatest_depth, Float, tag: "greatestdepth" + has_one :highest_po2, Float, tag: "highestpo2" + has_one :lowest_temperature, Float, tag: "lowesttemperature" + has_one :no_flight_time, Float, tag: "noflighttime" has_one :notes, Notes has_one :observations, Observations - has_one :pressure_drop, Float + has_one :pressure_drop, Float, tag: "pressuredrop" has_many :problems, String, tag: "problems" has_one :program, String has_many :ratings, Rating, tag: "rating" - has_one :surface_interval_after_dive, SurfaceIntervalAfterDive - has_one :thermal_comfort, String + has_one :surface_interval_after_dive, SurfaceIntervalAfterDive, tag: "surfaceintervalafterdive" + has_one :thermal_comfort, String, tag: "thermalcomfort" has_many :timers, Timer, tag: "timer" has_one :visibility, Float has_one :workload, String @@ -650,11 +650,11 @@ class TankData has_one :analysed_he, Float, tag: "analysedhe" has_one :analysed_o2, Float, tag: "analysedo2" - has_one :breathing_consumption_volume, Float + has_one :breathing_consumption_volume, Float, tag: "breathingconsumptionvolume" has_many :links, Link, tag: "link" - has_one :tank_pressure_begin, Float - has_one :tank_pressure_end, Float - has_one :tank_volume, Float + has_one :tank_pressure_begin, Float, tag: "tankpressurebegin" + has_one :tank_pressure_end, Float, tag: "tankpressureend" + has_one :tank_volume, Float, tag: "tankvolume" end class Hargikas @@ -664,9 +664,9 @@ class Hargikas has_one :ambient, Float has_many :tissues, Tissue, tag: "tissue" - has_one :arterial_micro_bubble_level, Integer - has_one :intrapulmonary_right_left_shunt, Float - has_one :estimated_skin_cool_level, Integer + has_one :arterial_micro_bubble_level, Integer, tag: "arterialmicrobubbleLevel" + has_one :intrapulmonary_right_left_shunt, Float, tag: "intrapulmonaryrightleftshunt" + has_one :estimated_skin_cool_level, Integer, tag: "estimatedskincoolLevel" end class ApplicationData @@ -674,7 +674,7 @@ class ApplicationData tag "applicationdata" - has_one :deco_trainer, String + has_one :deco_trainer, String, tag: "decotrainer" has_one :hargikas, Hargikas has_one :apdiving, String has_one :ratio, String @@ -686,9 +686,9 @@ class Dive tag "dive" attribute :id, String - has_one :information_after_dive, InformationAfterDive - has_one :information_before_dive, InformationBeforeDive - has_one :application_data, ApplicationData + has_one :information_after_dive, InformationAfterDive, tag: "informationafterdive" + has_one :information_before_dive, InformationBeforeDive, tag: "informationbeforedive" + has_one :application_data, ApplicationData, tag: "applicationdata" has_one :samples, Samples has_many :tank_data, TankData, tag: "tankdata" end @@ -750,8 +750,8 @@ class Output tag "output" has_one :lingo, String - has_one :file_format, String - has_one :file_name, String + has_one :file_format, String, tag: "fileformat" + has_one :file_name, String, tag: "filename" has_one :headline, String has_one :remark, String end @@ -761,17 +761,17 @@ class Profile tag "profile" - has_one :application_data, ApplicationData - has_one :deco_model, DecoModel + has_one :application_data, ApplicationData, tag: "applicationdata" + has_one :deco_model, DecoModel, tag: "decomodel" has_one :deep_stops, DeepStops, tag: "deepstops" has_one :density, Float - has_one :input_profile, InputProfile + has_one :input_profile, InputProfile, tag: "inputprofile" has_many :links, Link, tag: "link" - has_one :maximum_ascending_rate, Float - has_one :mix_change, MixChange + has_one :maximum_ascending_rate, Float, tag: "maximumascendingrate" + has_one :mix_change, MixChange, tag: "mixchange" has_one :output, Output - has_one :surface_interval_after_dive, SurfaceIntervalAfterDive - has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive + has_one :surface_interval_after_dive, SurfaceIntervalAfterDive, tag: "surfaceintervalafterdive" + has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive, tag: "surfaceintervalbeforedive" has_one :title, String end @@ -781,13 +781,13 @@ class TableScope tag "tablescope" has_one :altitude, Float - has_one :bottom_time_maximum, Float - has_one :bottom_time_minimum, Float - has_one :bottom_time_step_begin, Float - has_one :bottom_time_step_end, Float - has_one :dive_depth_begin, Float - has_one :dive_depth_end, Float - has_one :dive_depth_step, Float + has_one :bottom_time_maximum, Float, tag: "bottomtimemaximum" + has_one :bottom_time_minimum, Float, tag: "bottomtimeminimum" + has_one :bottom_time_step_begin, Float, tag: "bottomtimestepbegin" + has_one :bottom_time_step_end, Float, tag: "bottomtimestepend" + has_one :dive_depth_begin, Float, tag: "divedepthbegin" + has_one :dive_depth_end, Float, tag: "divedepthend" + has_one :dive_depth_step, Float, tag: "divedepthstep" end class Table @@ -795,7 +795,7 @@ class Table tag "table" - has_one :table_scope, TableScope + has_one :table_scope, TableScope, tag: "tablescope" has_one :deep_stops, DeepStops, tag: "deepstops" end @@ -820,16 +820,16 @@ class BottomTimeTableScope tag "bottomtimetablescope" - has_one :breathing_consumption_volume_begin, Float - has_one :breathing_consumption_volume_end, Float - has_one :breathing_consumption_volume_step, Float - has_one :dive_depth_begin, Float - has_one :dive_depth_end, Float - has_one :dive_depth_step, Float - has_one :tank_pressure_begin, Float - has_one :tank_pressure_reserve, Float - has_one :tank_volume_begin, Float - has_one :tank_volume_end, Float + has_one :breathing_consumption_volume_begin, Float, tag: "breathingconsumptionvolumebegin" + has_one :breathing_consumption_volume_end, Float, tag: "breathingconsumptionvolumeend" + has_one :breathing_consumption_volume_step, Float, tag: "breathingconsumptionvolumestep" + has_one :dive_depth_begin, Float, tag: "divedepthbegin" + has_one :dive_depth_end, Float, tag: "divedepthend" + has_one :dive_depth_step, Float, tag: "divedepthstep" + has_one :tank_pressure_begin, Float, tag: "tankpressurebegin" + has_one :tank_pressure_reserve, Float, tag: "tankpressurereserve" + has_one :tank_volume_begin, Float, tag: "tankvolumebegin" + has_one :tank_volume_end, Float, tag: "tankvolumeend" end class BottomTimeTable @@ -838,8 +838,8 @@ class BottomTimeTable tag "bottomtimetable" attribute :id, String - has_one :application_data, ApplicationData - has_one :bottom_time_table_scope, BottomTimeTableScope + has_one :application_data, ApplicationData, tag: "applicationdata" + has_one :bottom_time_table_scope, BottomTimeTableScope, tag: "bottomtimetablescope" has_many :links, Link, tag: "link" has_one :output, Output has_one :title, String @@ -858,9 +858,9 @@ class TableGeneration tag "tablegeneration" - has_one :calculate_bottom_time_table, CalculateBottomTimeTable - has_one :calculate_profile, CalculateProfile - has_one :calculate_table, CalculateTable + has_one :calculate_bottom_time_table, CalculateBottomTimeTable, tag: "calculatebottomtimetable" + has_one :calculate_profile, CalculateProfile, tag: "calculateprofile" + has_one :calculate_table, CalculateTable, tag: "calculatetable" end class ImageData @@ -870,12 +870,12 @@ class ImageData has_one :aperture, Float has_one :datetime, DateTime - has_one :exposure_compensation, Float - has_one :film_speed, Integer - has_one :focal_length, Float - has_one :focusing_distance, Float - has_one :metering_method, String - has_one :shutter_speed, Float + has_one :exposure_compensation, Float, tag: "exposurecompensation" + has_one :film_speed, Integer, tag: "filmspeed" + has_one :focal_length, Float, tag: "focallength" + has_one :focusing_distance, Float, tag: "focusingdistance" + has_one :metering_method, String, tag: "meteringmethod" + has_one :shutter_speed, Float, tag: "shutterspeed" end class Image @@ -887,8 +887,8 @@ class Image attribute :height, Integer attribute :width, Integer attribute :format, String - has_one :image_data, ImageData - has_one :object_name, String + has_one :image_data, ImageData, tag: "imagedata" + has_one :object_name, String, tag: "objectname" has_one :title, String end @@ -898,7 +898,7 @@ class Video tag "video" attribute :id, String - has_one :object_name, String + has_one :object_name, String, tag: "objectname" has_one :title, String end @@ -908,7 +908,7 @@ class Audio tag "audio" attribute :id, String - has_one :object_name, String + has_one :object_name, String, tag: "objectname" has_one :title, String end @@ -937,7 +937,7 @@ class PriceDivePackage attribute :currency, String attribute :no_of_dives, Integer - attribute :value, Float + content :value, Float end class RelatedDives @@ -966,14 +966,14 @@ class Vessel tag "vessel" has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :contact, Base::Models::Contact has_one :marina, String has_one :name, String has_one :notes, Notes has_many :ratings, Rating, tag: "rating" - has_one :ship_dimension, ShipDimension - has_one :ship_type, String + has_one :ship_dimension, ShipDimension, tag: "shipdimension" + has_one :ship_type, String, tag: "shiptype" end class Operator @@ -981,7 +981,7 @@ class Operator tag "operator" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :address, Base::Models::Address has_one :contact, Base::Models::Contact has_one :name, String @@ -1004,7 +1004,7 @@ class Accommodation tag "accommodation" has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :category, String has_one :contact, Base::Models::Contact has_one :name, String @@ -1022,7 +1022,7 @@ class Geography has_one :latitude, Float has_one :location, String has_one :longitude, Float - has_one :time_zone, Float + has_one :time_zone, Float, tag: "timezone" end class TripPart @@ -1032,15 +1032,15 @@ class TripPart attribute :type, String has_one :accommodation, Accommodation - has_one :date_of_trip, DateOfTrip + has_one :date_of_trip, DateOfTrip, tag: "dateoftrip" has_one :geography, Geography has_many :links, Link, tag: "link" has_one :name, String has_one :notes, Notes has_one :operator, Operator - has_one :price_dive_package, PriceDivePackage - has_one :price_per_dive, Price - has_one :related_dives, RelatedDives + has_one :price_dive_package, PriceDivePackage, tag: "pricedivepackage" + has_one :price_per_dive, Price, tag: "priceperdive" + has_one :related_dives, RelatedDives, tag: "relateddives" has_one :vessel, Vessel end @@ -1050,7 +1050,7 @@ class Trip tag "trip" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_many :ratings, Rating, tag: "rating" has_many :trip_parts, TripPart, tag: "trippart" @@ -1078,8 +1078,8 @@ class Built tag "built" - has_one :launching_date, Date - has_one :ship_yard, String + has_one :launching_date, Base::Models::DateTimeField, tag: "launchingdate" + has_one :ship_yard, String, tag: "shipyard" end class Wreck @@ -1087,13 +1087,13 @@ class Wreck tag "wreck" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :built, Built has_one :name, String has_one :nationality, String - has_one :ship_dimension, ShipDimension - has_one :ship_type, String - has_one :sunk, Date + has_one :ship_dimension, ShipDimension, tag: "shipdimension" + has_one :ship_type, String, tag: "shiptype" + has_one :sunk, Base::Models::DateTimeField end class Shore @@ -1102,7 +1102,7 @@ class Shore tag "shore" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes end @@ -1113,7 +1113,7 @@ class River tag "river" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes end @@ -1124,7 +1124,7 @@ class Lake tag "lake" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes end @@ -1135,7 +1135,7 @@ class Indoor tag "indoor" has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :contact, Base::Models::Contact has_one :name, String has_one :notes, Notes @@ -1147,7 +1147,7 @@ class Cave tag "cave" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :name, String has_one :notes, Notes end @@ -1157,19 +1157,19 @@ class SiteData tag "sidedata" - has_one :area_length, Float - has_one :area_width, Float - has_one :average_visibility, Float + has_one :area_length, Float, tag: "arealength" + has_one :area_width, Float, tag: "areawidth" + has_one :average_visibility, Float, tag: "averagevisibility" has_one :bottom, String has_one :cave, Cave has_one :density, Float has_one :difficulty, Integer - has_one :global_light_intensity, String + has_one :global_light_intensity, String, tag: "globallightintensity" has_one :indoor, Indoor - has_one :maximum_depth, Float - has_one :maximum_visibility, Float - has_one :minimum_depth, Float - has_one :minimum_visibility, Float + has_one :maximum_depth, Float, tag: "maximumdepth" + has_one :maximum_visibility, Float, tag: "maximumvisibility" + has_one :minimum_depth, Float, tag: "minimumdepth" + has_one :minimum_visibility, Float, tag: "minimumvisibility" has_one :river, River has_one :shore, Shore has_one :terrain, String @@ -1182,7 +1182,7 @@ class Site tag "site" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :ecology, Ecology has_one :environment, String has_one :geography, Geography @@ -1190,7 +1190,7 @@ class Site has_one :name, String has_one :notes, Notes has_many :ratings, Rating, tag: "rating" - has_one :side_data, SiteData + has_one :side_data, SiteData, tag: "sitedata" end class Guide @@ -1208,14 +1208,14 @@ class DiveBase attribute :id, String has_one :address, Base::Models::Address - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :contact, Base::Models::Contact has_many :guides, Guide, tag: "guide" has_many :links, Link, tag: "link" has_one :name, String has_one :notes, Notes - has_one :price_dive_package, PriceDivePackage - has_one :price_per_dive, Price + has_one :price_dive_package, PriceDivePackage, tag: "pricedivepackage" + has_one :price_per_dive, Price, tag: "priceperdive" has_many :ratings, Rating, tag: "rating" end @@ -1233,7 +1233,7 @@ class Shop tag "shop" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :address, Base::Models::Address has_one :contact, Base::Models::Contact has_one :name, String @@ -1262,8 +1262,8 @@ class NumberOfDives tag "numberofdives" - has_one :start_date, Date - has_one :end_date, Date + has_one :start_date, DateTime, tag: "startdate" + has_one :end_date, DateTime, tag: "enddate" has_one :dives, Integer end @@ -1272,16 +1272,16 @@ class Personal tag "personal" - has_one :birth_date, Date - has_one :birth_name, String - has_one :blood_group, String - has_one :first_name, String + has_one :birth_date, Base::Models::DateTimeField, tag: "birthdate" + has_one :birth_name, String, tag: "birthname" + has_one :blood_group, String, tag: "bloodgroup" + has_one :first_name, String, tag: "firstname" has_one :height, Float has_one :honorific, String - has_one :last_name, String + has_one :last_name, String, tag: "lastname" has_one :membership, Membership - has_one :middle_name, String - has_one :number_of_dives, NumberOfDives + has_one :middle_name, String, tag: "middlename" + has_one :number_of_dives, NumberOfDives, tag: "numberofdives" has_one :sex, String has_one :smoking, String has_one :weight, Float @@ -1302,14 +1302,14 @@ class Certification tag "certification" - has_one :certificate_number, String + has_one :certificate_number, String, tag: "certificatenumber" has_one :instructor, Instructor - has_one :issue_date, Date + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" has_one :level, String has_one :link, Link has_one :organization, String has_one :specialty, String - has_one :valid_date, Date + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" end class Education @@ -1325,11 +1325,11 @@ class Insurance tag "insurance" - has_one :alias_name, String - has_one :issue_date, Date + has_many :alias_names, String, tag: "aliasname" + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" has_one :name, String has_one :notes, Notes - has_one :valid_date, Date + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" end class DiveInsurances @@ -1345,12 +1345,12 @@ class Permit tag "permit" - has_one :alias_name, String - has_one :issue_date, Date + has_many :alias_names, String, tag: "aliasname" + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" has_one :name, String has_one :notes, Notes has_one :region, String - has_one :valid_date, Date + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" end class DivePermissions @@ -1404,16 +1404,16 @@ class EquipmentPart tag "equipmentpart" attribute :id, String - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_many :links, Link, tag: "link" has_one :manufacturer, Manufacturer has_one :model, String has_one :name, String - has_one :next_service_date, Date + has_one :next_service_date, Base::Models::DateTimeField, tag: "nextservicedate" has_one :notes, Notes has_one :purchase, Purchase - has_one :serial_number, String - has_one :service_interval, Integer + has_one :serial_number, String, tag: "serialnumber" + has_one :service_interval, Integer, tag: "serviceinterval" end class Lead < EquipmentPart @@ -1421,7 +1421,7 @@ class Lead < EquipmentPart tag "lead" - has_one :lead_quantity, Integer + has_one :lead_quantity, Integer, tag: "leadquantity" end class Rebreather < EquipmentPart @@ -1441,7 +1441,7 @@ class Suit < EquipmentPart tag "suit" - has_one :suit_type, String + has_one :suit_type, String, tag: "suittype" end class Tank < EquipmentPart @@ -1449,8 +1449,8 @@ class Tank < EquipmentPart tag "tank" - has_one :tank_material, String - has_one :tank_volume, Float + has_one :tank_material, String, tag: "tankmaterial" + has_one :tank_volume, Float, tag: "tankvolume" has_many :batteries, Battery, tag: "battery" end @@ -1503,7 +1503,7 @@ class EquipmentConfiguration < EquipmentContent tag "equipmentconfiguration" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_many :links, Link, tag: "link" has_one :name, String has_one :notes, Notes @@ -1515,7 +1515,7 @@ class Equipment < EquipmentContent tag "equipment" has_many :compressors, EquipmentPart, tag: "compressor" - has_one :equipment_configuration, EquipmentConfiguration + has_one :equipment_configuration, EquipmentConfiguration, tag: "equipmentconfiguration" end class Doctor @@ -1536,11 +1536,11 @@ class Examination has_one :datetime, DateTime has_one :doctor, Doctor - has_one :examination_result, String + has_one :examination_result, String, tag: "examinationresult" has_many :links, Link, tag: "link" has_one :notes, Notes - has_one :total_lung_capacity, Float - has_one :vital_capacity, Float + has_one :total_lung_capacity, Float, tag: "totallungcapacity" + has_one :vital_capacity, Float, tag: "vitalcapacity" end class Medical @@ -1557,8 +1557,8 @@ class BuddyOwnerShared attribute :id, String has_one :address, Base::Models::Address has_one :contact, Base::Models::Contact - has_one :dive_insurances, DiveInsurances - has_one :dive_permissions, DivePermissions + has_one :dive_insurances, DiveInsurances, tag: "diveinsurances" + has_one :dive_permissions, DivePermissions, tag: "divepermissions" has_one :equipment, Equipment has_one :medical, Medical has_one :notes, Notes @@ -1599,7 +1599,7 @@ class DCAlarm tag "dcalarm" has_one :acknowledge, String - has_one :alarm_type, Integer + has_one :alarm_type, Integer, tag: "alarmtype" has_one :period, Float end @@ -1651,7 +1651,7 @@ class SetDCDecoModel tag "setdcdecomodel" - has_one :alias_name, String + has_many :alias_names, String, tag: "aliasname" has_one :application_data, ApplicationData has_one :name, String end @@ -1716,8 +1716,8 @@ class DiveComputerControl tag "divecomputercontrol" has_many :dive_computer_dumps, DiveComputerDump, tag: "divecomputerdump" - has_one :get_dc_data, GetDCData - has_one :set_dc_data, SetDCData + has_one :get_dc_data, GetDCData, tag: "getdcdata" + has_one :set_dc_data, SetDCData, tag: "setdcdata" end class Uddf @@ -1727,17 +1727,17 @@ class Uddf attribute :version, String has_one :business, Business - has_one :deco_model, DecoModel - has_one :dive_computer_control, DiveComputerControl + has_one :deco_model, DecoModel, tag: "decomodel" + has_one :dive_computer_control, DiveComputerControl, tag: "divecomputercontrol" has_one :diver, Diver - has_one :dive_site, DiveSite - has_one :dive_trip, DiveTrip - has_one :gas_definitions, GasDefinitions + has_one :dive_site, DiveSite, tag: "divesite" + has_one :dive_trip, DiveTrip, tag: "divetrip" + has_one :gas_definitions, GasDefinitions, tag: "gasdefinitions" has_one :generator, Generator has_one :maker, Maker - has_one :media_data, MediaData - has_one :profile_data, ProfileData - has_one :table_generation, TableGeneration + has_one :media_data, MediaData, tag: "mediadata" + has_one :profile_data, ProfileData, tag: "profiledata" + has_one :table_generation, TableGeneration, tag: "tablegeneration" end end end diff --git a/spec/uddf_parser_spec.rb b/spec/uddf_parser_spec.rb index abc728e..5a2deb5 100644 --- a/spec/uddf_parser_spec.rb +++ b/spec/uddf_parser_spec.rb @@ -63,6 +63,7 @@ def validate_generator_info(uddf_data, expected_generator_fields = {}) def validate_multiple_uddf_files(file_paths, expected_dive_counts = {}) file_paths.each do |file_path| + puts "Testing file: #{file_path}" uddf_data = parse_uddf_file(file_path) expect(uddf_data).not_to be_nil diff --git a/test_files/v330/diver_data.uddf b/test_files/v330/diver_data.uddf index a552c57..3c5b754 100644 --- a/test_files/v330/diver_data.uddf +++ b/test_files/v330/diver_data.uddf @@ -94,7 +94,7 @@ Dr. male - 1919-02-30 + 1919-02-28 987654321 1.8 @@ -173,7 +173,7 @@ Dr. male - + 1919-02-28
From 10de4aede244b62192080350c986eacb4d37da37 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 15:44:46 +0200 Subject: [PATCH 07/13] please the linter Signed-off-by: Flipez --- .rubocop_todo.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 42cdff6..f85aa63 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2025-08-23 12:47:51 UTC using RuboCop version 1.80.0. +# on 2025-08-23 13:43:14 UTC using RuboCop version 1.80.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -14,7 +14,7 @@ Metrics/AbcSize: # Offense count: 1 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 14 + Max: 15 # Offense count: 1 # Configuration parameters: IgnoredMetadata. From 6e7ec85fd70b11d48e298b46ab1d2c8f12c61953 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 15:56:56 +0200 Subject: [PATCH 08/13] more tests and fixes Signed-off-by: Flipez --- lib/uddf/base/models.rb | 33 +++ lib/uddf/v330/models.rb | 22 +- spec/uddf_parser_spec.rb | 2 +- ...Peregrine TX[93CBB2BB]#140_2025-03-21.uddf | 0 ...Peregrine TX[93CBB2BB]#148_2025-06-26.uddf | 0 test_files/v330/uddf_spec/biologics.uddf | 161 +++++++++++++ test_files/v330/uddf_spec/dive_sites.uddf | 211 ++++++++++++++++++ .../v330/{ => uddf_spec}/diver_data.uddf | 0 8 files changed, 417 insertions(+), 12 deletions(-) rename test_files/v323/{ => realworld}/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf (100%) rename test_files/v323/{ => realworld}/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf (100%) create mode 100644 test_files/v330/uddf_spec/biologics.uddf create mode 100644 test_files/v330/uddf_spec/dive_sites.uddf rename test_files/v330/{ => uddf_spec}/diver_data.uddf (100%) diff --git a/lib/uddf/base/models.rb b/lib/uddf/base/models.rb index f2fc05b..65c4dea 100644 --- a/lib/uddf/base/models.rb +++ b/lib/uddf/base/models.rb @@ -38,6 +38,39 @@ class Contact class DateTimeField include HappyMapper + def self.parse(xml, options = {}) + result = super + return result if result.nil? + + # Handle empty or whitespace-only content + if result.date_time.nil? || (result.date_time.respond_to?(:strip) && result.date_time.strip.empty?) + element_name = xml.name + parent_name = xml.parent&.name + context = parent_name ? "#{parent_name} > #{element_name}" : element_name + raise Date::Error, "Empty datetime content in element: <#{context}>" + end + + result + rescue Date::Error => e + # Handle year-only dates by converting to January 1st of that year + datetime_element = xml.at_xpath(".//datetime") + if datetime_element && datetime_element.content.strip.match(/^\d{4}$/) + year = datetime_element.content.strip + result = new + result.date_time = DateTime.new(year.to_i, 1, 1) + return result + end + + # Re-raise Date::Error with element context if not already included + unless e.message.include?("element:") + element_name = xml.name + parent_name = xml.parent&.name + context = parent_name ? "#{parent_name} > #{element_name}" : element_name + raise Date::Error, "#{e.message} in element: <#{context}>" + end + raise + end + has_one :date_time, DateTime, tag: "datetime" end end diff --git a/lib/uddf/v330/models.rb b/lib/uddf/v330/models.rb index f961e17..eee7439 100644 --- a/lib/uddf/v330/models.rb +++ b/lib/uddf/v330/models.rb @@ -503,13 +503,23 @@ class AnySymptoms has_one :notes, Notes end + class Abundance + include HappyMapper + + tag "abundance" + + attribute :quality, String + attribute :occurrence, String + content :value, Integer + end + class Species include HappyMapper tag "species" attribute :id, String - has_one :abundance, "Abundance" + has_one :abundance, Abundance has_one :age, Integer has_one :dominance, String has_one :life_stage, String, tag: "lifestage" @@ -520,16 +530,6 @@ class Species has_one :trivial_name, String, tag: "trivialname" end - class Abundance - include HappyMapper - - tag "abundance" - - attribute :quality, String - attribute :occurrence, String - content :value, Integer - end - class WithSpecies include HappyMapper diff --git a/spec/uddf_parser_spec.rb b/spec/uddf_parser_spec.rb index 5a2deb5..138afff 100644 --- a/spec/uddf_parser_spec.rb +++ b/spec/uddf_parser_spec.rb @@ -91,7 +91,7 @@ def validate_multiple_uddf_files(file_paths, expected_dive_counts = {}) describe "UDDF Parser" do describe "parsing Peregrine TX UDDF file" do - let(:file_path) { File.join(__dir__, "../test_files/v323/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf") } + let(:file_path) { File.join(__dir__, "../test_files/v323/realworld/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf") } let(:uddf_data) { parse_uddf_file(file_path) } it "successfully parses the UDDF file" do diff --git a/test_files/v323/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf b/test_files/v323/realworld/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf similarity index 100% rename from test_files/v323/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf rename to test_files/v323/realworld/Peregrine TX[93CBB2BB]#140_2025-03-21.uddf diff --git a/test_files/v323/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf b/test_files/v323/realworld/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf similarity index 100% rename from test_files/v323/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf rename to test_files/v323/realworld/Peregrine TX[93CBB2BB]#148_2025-06-26.uddf diff --git a/test_files/v330/uddf_spec/biologics.uddf b/test_files/v330/uddf_spec/biologics.uddf new file mode 100644 index 0000000..bc33ceb --- /dev/null +++ b/test_files/v330/uddf_spec/biologics.uddf @@ -0,0 +1,161 @@ + + + + + + + + + rote_gorgonie.jpg + + + + + + eisseestern.jpg + 5_zackis.jpg + meersalat_meerjunker.jpg + heinz_neben_3_zackis.jpg + portrait_grosser_roter_drachenkopf.jpg + + + + + + Untiefe südlich des Ilot de la Gabiniere + + Ilot de la Gabiniere +
+ Cote d'Azur + Frankreich +
+ + 0.0 +
+ + + + + + + Nierenschwamm + Chondrosia reniformis + + + Roter Krustenschwamm + Crambe crambe + + + Hellblauer Krustenschwamm + Anchinoe + + + + + Rote Gorgonie + Paramuricea clavata (chamaeleon) + + + + + Rote Seescheide + Halocynthia papillosa + + + + + Purpurseestern + Echinaster sepositus + + + + + + + Mittelmeer-Muräne + Muraena helena + + + Brauner Zackenbarsch + Epinephelus guaza + + + Spitzkopf-Zackenbarsch + Epinephelus alexandrinus + + + Roter Fahnenbarsch + Anthias anthias + + + Mönchsfisch + Chromis chromis + + + Meerjunker + Coris julis + + + Zweibindenbrassen + Diplodus vulgaris + + + Brandbrassen + Oblada melanura + + + Pfauenlippfisch + Symphodus tinca + + + + + + + + Peyssonnelia + Peyssonnelia squamaria + + + + + Meersalat + Ulva rigida + + + Meerball + Codium bursa + + + + + + 18.0 + 32.0 + 20.0 + 8.0 + + 1030.0 + Felsen + + + + Erstklassiger Tauchplatz! Aufgrund von Strömung oftmals nur schwierig zu betauchen. + Erreichbar entweder im Freiwasser-Abstieg vom Boot oder - bei guter (!) Kenntnis der + Geländebeschaffenheit - von der Südspitze des Ilot de la Gabiniere aus nach Südwesten + tauchend. Recht schmaler, langgezogener Felskamm, auf beiden Seiten steilwandartig. + Dichter Bewuchs mit Algen, Schwämmen, Gorgonien. Viele Fische, insbesondere zahlreich + anzutreffende Zackenbarsche. + + + + + + + + + +
+
+ +
\ No newline at end of file diff --git a/test_files/v330/uddf_spec/dive_sites.uddf b/test_files/v330/uddf_spec/dive_sites.uddf new file mode 100644 index 0000000..5ab144c --- /dev/null +++ b/test_files/v330/uddf_spec/dive_sites.uddf @@ -0,0 +1,211 @@ + + + + + ... + + + + + + + + + Deep Down + + info@deep-down-diving.com + http://www.deep-down-diving.com + + 40.00 + 350.00 + + + + + + + + + + 7 + + + + + + Brummer + + Scapa Flow +
+ Orkney Islands + UK +
+ + 58.897222 + + -3.1519444 + 0.0 +
+ + 37.0 + 1030.0 + Sandboden + + SMS Brummer + leichter Kreuzer + deutsch + + Vulcan, Stettin + + 1916 + + + + 140.0 + 13.0 + 6.0 + 4.385E6 + + + 1919-06-21T13:05 + + + Deutsche Hochsee-Flotte + + + + + Sehr schöner Wrack-Tauchgang + +
+ +
+ + + + + Vereinsfahrt Rotes Meer 2003 + + + Rotes Meer +
+ Hurghada + Ägypten +
+
+ + Hotel 1000 und 1 Nacht + Hotel + + info@hotel-1000-und-1-nacht.com + http://www.hotel-1000-und-1-nacht.com + + + 6 + + + + + schöner Tauchurlaub - wenn nicht so viele andere Taucher dort wären... + + +
+
+ + + Tauch-Segeltörn 2004 + + +
+ Cote d'Azur + Frankreich +
+
+ + Dorade + Segelyacht + Bormes les Mimosas + + + 14.6 + 3.5 + + + + + + + + + Unser Motto: Wir tauchen das, wovon andere träumen!!! :-) + + +
+
+ + Vereinsfahrt Korsika 2005 + + Vereinsfahrt Korsika 2005 - 1 Woche Galiote + + + Mittelmeer +
+ Korsika +
+
+ + Galiote + Motoryacht + + + + + + + + + Schöner Tauchurlaub mit Günter und seiner Crew! + + +
+ + Vereinsfahrt Korsika 2005 - 1 Woche Campingplatz und Tauchclub Nemo + + +
+ + Korsika +
+
+ + Camping Corse + Camping + + info@camping-corse.com + http://www.camping-corse.com + + + 6 + + + + + + + + + Nette zweite Woche Korsika-Tauchurlaub! + + +
+
+
+ + +
\ No newline at end of file diff --git a/test_files/v330/diver_data.uddf b/test_files/v330/uddf_spec/diver_data.uddf similarity index 100% rename from test_files/v330/diver_data.uddf rename to test_files/v330/uddf_spec/diver_data.uddf From d5a6effdd00498180e303d9480cf970e941270e7 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 15:57:17 +0200 Subject: [PATCH 09/13] please the linter Signed-off-by: Flipez --- .rubocop_todo.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f85aa63..87e813e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,20 +1,30 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2025-08-23 13:43:14 UTC using RuboCop version 1.80.0. +# on 2025-08-23 13:57:16 UTC using RuboCop version 1.80.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 4 +# Offense count: 5 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 35 # Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/CyclomaticComplexity: + Max: 13 + +# Offense count: 2 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 15 + Max: 24 + +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/PerceivedComplexity: + Max: 13 # Offense count: 1 # Configuration parameters: IgnoredMetadata. From 64561638f69cea161ad5b3c291978f0e166d78cc Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 15:58:12 +0200 Subject: [PATCH 10/13] update readme Signed-off-by: Flipez --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0df7dae..9ba1945 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Ruby parser and validator for Universal Dive Data Format (UDDF) files. Supports | 3.2.1 | ✗ | ✓ | | 3.2.2 | ✗ | ✓ | | 3.2.3 | ✓ | ✓ | -| 3.3.0 | ✗ | ✓ | +| 3.3.0 | ✓ | ✓ | | 3.3.1 | ✗ | ✓ | > **Note**: The UDDF 3.3.0 and 3.3.1 schema files included in this gem have been locally modified to fix XML Schema validation errors that prevented them from loading with Nokogiri. These fixes address syntax issues in the original schemas but may not represent the upstream maintainers' intentions. The modifications ensure compatibility with standard XML Schema validators while preserving the core schema structure and validation rules. From 0c1f072e10c7591ee4292f765d95bc676d29aff1 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 16:53:02 +0200 Subject: [PATCH 11/13] add support for v3.3.1 Signed-off-by: Flipez --- .rubocop.yml | 1 + .rubocop_todo.yml | 20 +- README.md | 2 +- lib/uddf.rb | 5 +- lib/uddf/base/models.rb | 55 +- lib/uddf/v331/models.rb | 1757 +++++++++++++++++++++ test_files/v331/uddf_spec/biologics.uddf | 161 ++ test_files/v331/uddf_spec/dive_sites.uddf | 211 +++ test_files/v331/uddf_spec/diver_data.uddf | 358 +++++ 9 files changed, 2529 insertions(+), 41 deletions(-) create mode 100644 lib/uddf/v331/models.rb create mode 100644 test_files/v331/uddf_spec/biologics.uddf create mode 100644 test_files/v331/uddf_spec/dive_sites.uddf create mode 100644 test_files/v331/uddf_spec/diver_data.uddf diff --git a/.rubocop.yml b/.rubocop.yml index 40488a4..2ecdbf7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -32,3 +32,4 @@ Style/Documentation: - "lib/uddf/base/models.rb" - "lib/uddf/v323/models.rb" - "lib/uddf/v330/models.rb" + - "lib/uddf/v331/models.rb" diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 87e813e..e05ea5e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,17 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2025-08-23 13:57:16 UTC using RuboCop version 1.80.0. +# on 2025-08-23 14:52:40 UTC using RuboCop version 1.80.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 5 +# Offense count: 2 +Lint/ShadowedException: + Exclude: + - 'lib/uddf/base/models.rb' + +# Offense count: 4 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 35 @@ -14,17 +19,12 @@ Metrics/AbcSize: # Offense count: 1 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/CyclomaticComplexity: - Max: 13 + Max: 8 -# Offense count: 2 +# Offense count: 3 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 24 - -# Offense count: 1 -# Configuration parameters: AllowedMethods, AllowedPatterns. -Metrics/PerceivedComplexity: - Max: 13 + Max: 21 # Offense count: 1 # Configuration parameters: IgnoredMetadata. diff --git a/README.md b/README.md index 9ba1945..5ffcd9a 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Ruby parser and validator for Universal Dive Data Format (UDDF) files. Supports | 3.2.2 | ✗ | ✓ | | 3.2.3 | ✓ | ✓ | | 3.3.0 | ✓ | ✓ | -| 3.3.1 | ✗ | ✓ | +| 3.3.1 | ✓ | ✓ | > **Note**: The UDDF 3.3.0 and 3.3.1 schema files included in this gem have been locally modified to fix XML Schema validation errors that prevented them from loading with Nokogiri. These fixes address syntax issues in the original schemas but may not represent the upstream maintainers' intentions. The modifications ensure compatibility with standard XML Schema validators while preserving the core schema structure and validation rules. diff --git a/lib/uddf.rb b/lib/uddf.rb index 7678d27..bc766fd 100644 --- a/lib/uddf.rb +++ b/lib/uddf.rb @@ -8,7 +8,7 @@ # Universal Dive Data Format (UDDF) parser and validator module UDDF SUPPORTED_SCHEMA_VERSIONS = %w[3.0.0 3.0.1 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1].freeze - SUPPORTED_PARSER_VERSIONS = %w[3.2.3 3.3.0].freeze + SUPPORTED_PARSER_VERSIONS = %w[3.2.3 3.3.0 3.3.1].freeze @schema_cache_mutex = Mutex.new @@ -58,6 +58,9 @@ def self.load_models_for_version(version) when "3.3.0" require "uddf/v330/models" V330::Models::Uddf + when "3.3.1" + require "uddf/v331/models" + V331::Models::Uddf end end diff --git a/lib/uddf/base/models.rb b/lib/uddf/base/models.rb index 65c4dea..ccecedc 100644 --- a/lib/uddf/base/models.rb +++ b/lib/uddf/base/models.rb @@ -38,40 +38,37 @@ class Contact class DateTimeField include HappyMapper - def self.parse(xml, options = {}) - result = super - return result if result.nil? + element :raw, String, tag: "datetime" - # Handle empty or whitespace-only content - if result.date_time.nil? || (result.date_time.respond_to?(:strip) && result.date_time.strip.empty?) - element_name = xml.name - parent_name = xml.parent&.name - context = parent_name ? "#{parent_name} > #{element_name}" : element_name - raise Date::Error, "Empty datetime content in element: <#{context}>" - end + # Lazily parse on first access; memoize in @date_time + def date_time + return @date_time if @date_time - result - rescue Date::Error => e - # Handle year-only dates by converting to January 1st of that year - datetime_element = xml.at_xpath(".//datetime") - if datetime_element && datetime_element.content.strip.match(/^\d{4}$/) - year = datetime_element.content.strip - result = new - result.date_time = DateTime.new(year.to_i, 1, 1) - return result - end + content = raw.to_s.strip + return nil if content.empty? - # Re-raise Date::Error with element context if not already included - unless e.message.include?("element:") - element_name = xml.name - parent_name = xml.parent&.name - context = parent_name ? "#{parent_name} > #{element_name}" : element_name - raise Date::Error, "#{e.message} in element: <#{context}>" - end - raise + @date_time = + case content + when /^\d{4}$/ # "YYYY" + DateTime.new(content.to_i, 1, 1) + when /^\d{4}-\d{2}$/ # "YYYY-MM" + y, m = content.split("-").map!(&:to_i) + DateTime.new(y, m, 1) + else + begin + DateTime.iso8601(content) + rescue ArgumentError, Date::Error + begin + DateTime.rfc3339(content) + rescue ArgumentError, Date::Error + DateTime.parse(content) + end + end + end end - has_one :date_time, DateTime, tag: "datetime" + # Allow manual assignment if you ever need it + attr_writer :date_time end end end diff --git a/lib/uddf/v331/models.rb b/lib/uddf/v331/models.rb new file mode 100644 index 0000000..65f8512 --- /dev/null +++ b/lib/uddf/v331/models.rb @@ -0,0 +1,1757 @@ +# frozen_string_literal: true + +require "happymapper" +require "uddf/base/models" + +module UDDF + module V331 + module Models + class Timer + include HappyMapper + + tag "timer" + + attribute :ref, String + content :value, Float + end + + class SelfTest + include HappyMapper + + tag "selftest" + + attribute :ref, String + content :Value, String + end + + class RebreatherSelfTest + include HappyMapper + + tag "rebreatherselftest" + + attribute :ref, String + content :value, String + end + + class DeepStops + include HappyMapper + + tag "deepstops" + + has_one :deep_stop_time, Float, tag: "deepstoptime" + has_one :deep_stop_type, String, tag: "deepstoptype" + end + + class ScrubberMonitor + include HappyMapper + + tag "scrubbermonitor" + + attribute :id, String + end + + class Scrubber + include HappyMapper + + tag "scrubber" + + attribute :ref, String + attribute :units, String + + content :value, Float + end + + class Manufacturer + include HappyMapper + + tag "manufacturer" + + attribute :id, String + has_one :address, Base::Models::Address + has_many :alias_names, String, tag: "aliasname" + has_one :contact, Base::Models::Contact + has_one :name, String + end + + class Link + include HappyMapper + + tag "link" + + attribute :ref, String + end + + class Generator + include HappyMapper + + tag "generator" + + has_many :alias_names, String, tag: "aliasname" + has_one :datetime, DateTime + has_many :links, Link, tag: "link" + has_one :name, String + has_one :type, String + has_one :version, String + end + + class Notes + include HappyMapper + + tag "notes" + + has_many :paras, String, tag: "para" + has_many :links, Link, tag: "link" + end + + class Price + include HappyMapper + + tag "price" + + attribute :currency, String + content :value, Float + end + + class Tissue + include HappyMapper + + tag "tissue" + + attribute :gas, String + attribute :half_life, Float + attribute :number, Integer + attribute :a, Float + attribute :b, Float + end + + class VPM + include HappyMapper + + tag "vpm" + + attribute :id, String + has_one :conservatism, Float + has_one :gamma, Float + has_one :gc, Float + has_one :lambda, Float + has_one :r0, Float + has_many :tissues, Tissue, tag: "tissue" + end + + class RGBM + include HappyMapper + + tag "rgbm" + + attribute :id, String + has_many :tissues, Tissue, tag: "tissue" + end + + class Buehlmann + include HappyMapper + + tag "buehlmann" + + attribute :id, String + has_one :gradient_factor_high, Float, tag: "gradientfactorhigh" + has_one :gradient_factor_low, Float, tag: "gradientfactorlow" + has_many :tissues, Tissue, tag: "tissue" + end + + class DecoModel + include HappyMapper + + tag "decomodel" + + has_many :buehlmanns, Buehlmann, tag: "buehlmann" + has_many :rgbms, RGBM, tag: "rbgm" + has_many :vpms, VPM, tag: "vpm" + end + + class Mix + include HappyMapper + + tag "mix" + + attribute :id, String + has_many :alias_names, String, tag: "aliasname" + has_one :ar, Float + has_one :equivalent_air_depth, Float, tag: "equivalentairdepth" + has_one :h2, Float + has_one :he, Float + has_one :maximum_operation_depth, Float, tag: "maximumoperationdepth" + has_one :maximum_po2, Float, tag: "maximumpo2" + has_one :n2, Float + has_one :name, String + has_one :o2, Float + has_one :price_per_litre, Price, tag: "priceperlitre" + end + + class GasDefinitions + include HappyMapper + + tag "gasdefinitions" + + has_many :mixes, Mix, tag: "mix" + end + + class WayAltitude + include HappyMapper + + tag "wayaltitude" + + attribute :way_time, Float + content :value, Float + end + + class ExposureToAltitude + include HappyMapper + + tag "exposuretoaltitude" + + has_one :altitude_of_exposure, Float, tag: "altitudeofexposure" + has_one :date_of_flight, Base::Models::DateTimeField, tag: "dateofflight" + has_one :surface_interval_before_altitude_exposure, Float, tag: "surfaceintervalbeforealtitudeexposure" + has_one :total_length_of_exposure, Float, tag: "totallengthofexposure" + has_one :transportation, String + end + + class SurfaceIntervalBeforeDive + include HappyMapper + + tag "surfaceintervalbeforedive" + + has_one :exposure_to_altitude, ExposureToAltitude, tag: "exposuretoaltitude" + has_one :infinity, String + has_one :passed_time, Float, tag: "passedtime" + has_many :way_altitudes, WayAltitude, tag: "wayaltitude" + end + + class SurfaceIntervalAfterDive + include HappyMapper + + tag "surfaceintervalafterdive" + + has_one :exposure_to_altitude, ExposureToAltitude, tag: "exposuretoaltitude" + has_one :infinity, String + has_one :passed_time, Float, tag: "passedtime" + has_many :way_altitudes, WayAltitude, tag: "wayaltitude" + end + + class TankPressure + include HappyMapper + + tag "tankpressure" + + attribute :ref, String + content :value, Float + end + + class SwitchMix + include HappyMapper + + tag "switchmix" + + attribute :ref, String + end + + class SetPo2 + include HappyMapper + + tag "setpo2" + + attribute :set_by, String + content :value, Float + end + + class PPo2 + include HappyMapper + + tag "ppo2" + + attribute :ref, String + content :value, Float + end + + class GradientFactor + include HappyMapper + + tag "gradientfactor" + + attribute :tissue, Integer + content :value, Float + end + + class DiveMode + include HappyMapper + + tag "divemode" + + attribute :type, String + end + + class Decostop + include HappyMapper + + tag "decostop" + + attribute :kind, String + attribute :deco_depth, Float + attribute :duration, Float + end + + class Battery + include HappyMapper + + tag "battery" + + attribute :ref, String + end + + class BatteryChargeCondition + include HappyMapper + + tag "batterychargecondition" + + attribute :ref, String + content :value, Float + end + + class BatteryVoltage + include HappyMapper + + tag "batteryvoltage" + + attribute :ref, String + content :value, Float + end + + class Alarm + include HappyMapper + + tag "alarm" + + attribute :level, Float + attribute :tank_ref, String + content :value, String + end + + class Info + include HappyMapper + + tag "info" + + attribute :ref, String + attribute :level, String + attribute :type, String + attribute :values, Float + attribute :units, String + end + + class PPCo2 + include HappyMapper + + tag "ppco2" + + attribute :ref, String + + content :value, Float + end + + class Waypoint + include HappyMapper + + tag "waypoint" + + has_many :alarms, Alarm, tag: "alarm" + has_many :battery_charge_conditions, BatteryChargeCondition, tag: "batterychargecondition" + has_many :battery_voltages, BatteryVoltage, tag: "batteryvoltage" + has_one :calculated_po2, Float, tag: "calculatedpo2" + has_one :cns, Float + has_many :deco_stops, Decostop, tag: "decostop" + has_one :depth, Float + has_one :dive_mode, DiveMode, tag: "divemode" + has_one :dive_time, Float, tag: "divetime" + has_one :gradient_factor, GradientFactor, tag: "gradientfactor" + has_one :heading, Float + has_many :ppo2s, PPo2, tag: "ppo2" + has_one :no_deco_time, Float, tag: "nodecotime" + has_one :otu, Float + has_one :remaining_bottom_time, Float, tag: "remainingbottomtime" + has_one :remaining_o2_time, Float, tag: "remainingo2time" + has_many :set_po2s, SetPo2, tag: "setpo2" + has_one :switch_mix, SwitchMix, tag: "switchmix" + has_many :tank_pressures, TankPressure, tag: "tankpressure" + has_one :temperature, Float + has_many :timers, Timer, tag: "timer" + has_many :infos, Info, tag: "info" + has_many :ppco2s, PPCo2, tag: "ppco2" + has_many :scrubbers, Scrubber, tag: "scrubber" + end + + class Medicine + include HappyMapper + + tag "medicine" + + has_many :alias_names, String, tag: "aliasname" + has_one :name, String + has_one :notes, Notes + has_one :periodically_taken, String, tag: "periodicallytaken" + has_one :timespan_before_dive, Float, tag: "timespanbeforedive" + end + + class MedicationBeforeDive + include HappyMapper + + tag "medicationbeforedive" + + has_many :medicines, Medicine, tag: "medicine" + end + + class PlannedProfile + include HappyMapper + + tag "plannedprofile" + + attribute :start_dive_mode, String + attribute :start_mix, String + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class Drink + include HappyMapper + + tag "drink" + + has_many :alias_names, String, tag: "aliasname" + has_one :name, String + has_one :notes, Notes + has_one :periodically_taken, String, tag: "periodicallytaken" + has_one :timespan_before_dive, Float, tag: "timespanbeforedive" + end + + class AlcoholBeforeDive + include HappyMapper + + tag "alcoholbeforedive" + + has_many :drinks, Drink, tag: "drink" + end + + class InformationBeforeDive + include HappyMapper + + tag "informationbeforedive" + + has_one :air_temperature, Float, tag: "airtemperature" + has_one :alcohol_before_dive, AlcoholBeforeDive, tag: "alcoholbeforedive" + has_one :altitude, Float + has_one :apparatus, String + has_one :datetime, DateTime + has_one :deep_stops, DeepStops, tag: "deepstops" + has_one :dive_number, Integer, tag: "divenumber" + has_one :dive_number_of_day, Integer, tag: "divenumberofday" + has_one :internal_dive_number, Integer, tag: "internaldivenumber" + has_many :links, Link, tag: "link" + has_one :medication_before_dive, MedicationBeforeDive, tag: "medicationbeforedive" + has_one :no_suit, String, tag: "nosuit" + has_one :planned_profile, PlannedProfile, tag: "plannedprofile" + has_one :platform, String + has_one :price, Price + has_one :purpose, String + has_many :rebreather_self_tests, RebreatherSelfTest, tag: "rebreatherselftest" + has_one :state_of_rest_before_dive, String, tag: "stateofrestbeforedive" + has_many :self_tests, SelfTest, tag: "selftest" + has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive, tag: "surfaceintervalbeforedive" + has_one :surface_pressure, Float, tag: "surfacepressure" + has_one :trip_membership, String, tag: "tripmembership" + has_many :timers, Timer, tag: "timer" + end + + class Rating + include HappyMapper + + tag "rating" + + has_one :datetime, DateTime + has_one :rating_value, Integer, tag: "ratingvalue" + end + + class GlobalAlarmsGiven + include HappyMapper + + tag "globalalarmsgiven" + + has_many :global_alarms, String, tag: "globalalarm" + end + + class EquipmentUsed + include HappyMapper + + tag "equipmentused" + + has_one :lead_quantity, Float, tag: "leadquantity" + has_many :links, Link, tag: "link" + end + + class AnySymptoms + include HappyMapper + + tag "anysymptoms" + + has_one :notes, Notes + end + + class Abundance + include HappyMapper + + tag "abundance" + + attribute :quality, String + attribute :occurrence, String + content :value, Integer + end + + class Species + include HappyMapper + + tag "species" + + attribute :id, String + has_one :abundance, Abundance + has_one :age, Integer + has_one :dominance, String + has_one :life_stage, String, tag: "lifestage" + has_one :notes, Notes + has_one :scientific_name, String, tag: "scientificname" + has_one :sex, String + has_one :size, Float + has_one :trivial_name, String, tag: "trivialname" + end + + class WithSpecies + include HappyMapper + + has_many :species, Species, tag: "species" + end + + class Invertebrata + include HappyMapper + + tag "invertebrata" + + has_one :ascidiacea, WithSpecies + has_one :bryozoan, WithSpecies + has_one :cnidaria, WithSpecies + has_one :coelenterata, WithSpecies + has_one :crustacea, WithSpecies + has_one :ctenophora, WithSpecies + has_one :echinodermata, WithSpecies + has_one :invertebrata_various, WithSpecies, tag: "invertebratavarious" + has_one :mollusca, WithSpecies + has_one :phoronidea, WithSpecies + has_one :plathelminthes, WithSpecies + has_one :porifera, WithSpecies + end + + class Vertebrata + include HappyMapper + + tag "vertebrata" + + has_one :amphibia, WithSpecies + has_one :chondrichthyes, WithSpecies + has_one :mammalia, WithSpecies + has_one :osteichthyes, WithSpecies + has_one :reptilia, WithSpecies + has_one :vertebrata_various, WithSpecies, tag: "vertebratavarious" + end + + class Fauna + include HappyMapper + + tag "fauna" + + has_one :invertebrata, Invertebrata + has_one :notes, Notes + has_one :vertebrata, Vertebrata + end + + class Flora + include HappyMapper + + tag "flora" + + has_one :chlorophyceae, WithSpecies + has_one :flora_various, WithSpecies, tag: "floravarious" + has_one :notes, Notes + has_one :phaeophyceae, WithSpecies + has_one :rhodophyceae, WithSpecies + has_one :spermatophyta, WithSpecies + end + + class Observations + include HappyMapper + + tag "observations" + + has_one :fauna, Fauna + has_one :flora, Flora + has_one :notes, Notes + end + + class InformationAfterDive + include HappyMapper + + tag "informationafterdive" + + has_one :any_symptoms, AnySymptoms, tag: "anysymptoms" + has_one :average_depth, Float, tag: "averagedepth" + has_one :current, String + has_one :desaturation_time, Float, tag: "desaturationtime" + has_one :dive_duration, Float, tag: "diveduration" + has_one :dive_plan, String, tag: "diveplan" + has_one :dive_table, String, tag: "divetable" + has_one :equipment_malfunction, String, tag: "equipmentmalfunction" + has_one :equipment_used, EquipmentUsed, tag: "equipmentused" + has_one :global_alarms_given, GlobalAlarmsGiven, tag: "globalalarmsgiven" + has_one :greatest_depth, Float, tag: "greatestdepth" + has_one :highest_po2, Float, tag: "highestpo2" + has_one :lowest_temperature, Float, tag: "lowesttemperature" + has_one :no_flight_time, Float, tag: "noflighttime" + has_one :notes, Notes + has_one :observations, Observations + has_one :pressure_drop, Float, tag: "pressuredrop" + has_many :problems, String, tag: "problems" + has_one :program, String + has_many :ratings, Rating, tag: "rating" + has_one :surface_interval_after_dive, SurfaceIntervalAfterDive, tag: "surfaceintervalafterdive" + has_one :thermal_comfort, String, tag: "thermalcomfort" + has_many :timers, Timer, tag: "timer" + has_one :visibility, Float + has_one :workload, String + end + + class Samples + include HappyMapper + + tag "samples" + + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class Hargikas + include HappyMapper + + tag "hargikas" + + has_one :ambient, Float + has_many :tissues, Tissue, tag: "tissue" + has_one :arterial_micro_bubble_level, Integer, tag: "arterialmicrobubbleLevel" + has_one :intrapulmonary_right_left_shunt, Float, tag: "intrapulmonaryrightleftshunt" + has_one :estimated_skin_cool_level, Integer, tag: "estimatedskincoolLevel" + end + + class ApplicationData + include HappyMapper + + tag "applicationdata" + + has_one :deco_trainer, String, tag: "decotrainer" + has_one :hargikas, Hargikas + has_one :apdiving, String + has_one :ratio, String + end + + class TankUsed + include HappyMapper + + tag "tankused" + + attribute :id, String + + has_one :analysed_he, Float, tag: "analysedhe" + has_one :analysed_o2, Float, tag: "analysedo2" + has_one :breathing_consumption_volume, Float, tag: "breathingconsumptionvolume" + has_many :links, Link, tag: "link" + has_one :tank_pressure_begin, Float, tag: "tankpressurebegin" + has_one :tank_pressure_end, Float, tag: "tankpressureend" + has_one :tank_volume, Float, tag: "tankvolume" + end + + class TankData + include HappyMapper + + tag "tankdata" + + has_many :tanks_used, TankUsed, tag: "tankused" + end + + class Dive + include HappyMapper + + tag "dive" + + attribute :id, String + has_one :information_after_dive, InformationAfterDive, tag: "informationafterdive" + has_one :information_before_dive, InformationBeforeDive, tag: "informationbeforedive" + has_one :application_data, ApplicationData, tag: "applicationdata" + has_one :samples, Samples + has_one :tank_data, TankData, tag: "tankdata" + end + + class RepetitionGroup + include HappyMapper + + tag "repetitiongroup" + + attribute :id, String + has_many :dives, Dive, tag: "dive" + end + + class ProfileData + include HappyMapper + + tag "profiledata" + + has_many :repetition_groups, RepetitionGroup, tag: "repetitiongroup" + end + + class Descent + include HappyMapper + + tag "descent" + + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class Ascent + include HappyMapper + + tag "ascent" + + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class MixChange + include HappyMapper + + tag "mixchange" + + has_one :ascent, Ascent + has_one :descent, Descent + end + + class InputProfile + include HappyMapper + + tag "inputprofile" + + has_many :links, Link, tag: "link" + has_many :waypoints, Waypoint, tag: "waypoint" + end + + class Output + include HappyMapper + + tag "output" + + has_one :lingo, String + has_one :file_format, String, tag: "fileformat" + has_one :file_name, String, tag: "filename" + has_one :headline, String + has_one :remark, String + end + + class Profile + include HappyMapper + + tag "profile" + + has_one :application_data, ApplicationData, tag: "applicationdata" + has_one :deco_model, DecoModel, tag: "decomodel" + has_one :deep_stops, DeepStops, tag: "deepstops" + has_one :density, Float + has_one :input_profile, InputProfile, tag: "inputprofile" + has_many :links, Link, tag: "link" + has_one :maximum_ascending_rate, Float, tag: "maximumascendingrate" + has_one :mix_change, MixChange, tag: "mixchange" + has_one :output, Output + has_one :surface_interval_after_dive, SurfaceIntervalAfterDive, tag: "surfaceintervalafterdive" + has_one :surface_interval_before_dive, SurfaceIntervalBeforeDive, tag: "surfaceintervalbeforedive" + has_one :title, String + end + + class TableScope + include HappyMapper + + tag "tablescope" + + has_one :altitude, Float + has_one :bottom_time_maximum, Float, tag: "bottomtimemaximum" + has_one :bottom_time_minimum, Float, tag: "bottomtimeminimum" + has_one :bottom_time_step_begin, Float, tag: "bottomtimestepbegin" + has_one :bottom_time_step_end, Float, tag: "bottomtimestepend" + has_one :dive_depth_begin, Float, tag: "divedepthbegin" + has_one :dive_depth_end, Float, tag: "divedepthend" + has_one :dive_depth_step, Float, tag: "divedepthstep" + end + + class Table + include HappyMapper + + tag "table" + + has_one :table_scope, TableScope, tag: "tablescope" + has_one :deep_stops, DeepStops, tag: "deepstops" + end + + class CalculateProfile + include HappyMapper + + tag "calculateprofile" + + has_many :profiles, Profile, tag: "profile" + end + + class CalculateTable + include HappyMapper + + tag "calculatetable" + + has_many :tables, Table, tag: "table" + end + + class BottomTimeTableScope + include HappyMapper + + tag "bottomtimetablescope" + + has_one :breathing_consumption_volume_begin, Float, tag: "breathingconsumptionvolumebegin" + has_one :breathing_consumption_volume_end, Float, tag: "breathingconsumptionvolumeend" + has_one :breathing_consumption_volume_step, Float, tag: "breathingconsumptionvolumestep" + has_one :dive_depth_begin, Float, tag: "divedepthbegin" + has_one :dive_depth_end, Float, tag: "divedepthend" + has_one :dive_depth_step, Float, tag: "divedepthstep" + has_one :tank_pressure_begin, Float, tag: "tankpressurebegin" + has_one :tank_pressure_reserve, Float, tag: "tankpressurereserve" + has_one :tank_volume_begin, Float, tag: "tankvolumebegin" + has_one :tank_volume_end, Float, tag: "tankvolumeend" + end + + class BottomTimeTable + include HappyMapper + + tag "bottomtimetable" + + attribute :id, String + has_one :application_data, ApplicationData, tag: "applicationdata" + has_one :bottom_time_table_scope, BottomTimeTableScope, tag: "bottomtimetablescope" + has_many :links, Link, tag: "link" + has_one :output, Output + has_one :title, String + end + + class CalculateBottomTimeTable + include HappyMapper + + tag "calculatebottomtimetable" + + has_many :bottom_time_tables, BottomTimeTable, tag: "bottomtimetable" + end + + class TableGeneration + include HappyMapper + + tag "tablegeneration" + + has_one :calculate_bottom_time_table, CalculateBottomTimeTable, tag: "calculatebottomtimetable" + has_one :calculate_profile, CalculateProfile, tag: "calculateprofile" + has_one :calculate_table, CalculateTable, tag: "calculatetable" + end + + class ImageData + include HappyMapper + + tag "imagedata" + + has_one :aperture, Float + has_one :datetime, DateTime + has_one :exposure_compensation, Float, tag: "exposurecompensation" + has_one :film_speed, Integer, tag: "filmspeed" + has_one :focal_length, Float, tag: "focallength" + has_one :focusing_distance, Float, tag: "focusingdistance" + has_one :metering_method, String, tag: "meteringmethod" + has_one :shutter_speed, Float, tag: "shutterspeed" + end + + class Image + include HappyMapper + + tag "image" + + attribute :id, String + attribute :height, Integer + attribute :width, Integer + attribute :format, String + has_one :image_data, ImageData, tag: "imagedata" + has_one :object_name, String, tag: "objectname" + has_one :title, String + end + + class Video + include HappyMapper + + tag "video" + + attribute :id, String + has_one :object_name, String, tag: "objectname" + has_one :title, String + end + + class Audio + include HappyMapper + + tag "audio" + + attribute :id, String + has_one :object_name, String, tag: "objectname" + has_one :title, String + end + + class MediaData + include HappyMapper + + tag "mediadata" + + has_many :audio_files, Audio, tag: "audio" + has_many :image_files, Image, tag: "image" + has_many :video_files, Video, tag: "video" + end + + class Maker + include HappyMapper + + tag "maker" + + has_many :manufacturers, Manufacturer, tag: "manufacturer" + end + + class PriceDivePackage + include HappyMapper + + tag "pricedivepackage" + + attribute :currency, String + attribute :no_of_dives, Integer + content :value, Float + end + + class RelatedDives + include HappyMapper + + tag "relateddives" + + has_many :links, Link, tag: "link" + end + + class ShipDimension + include HappyMapper + + tag "shipdimension" + + has_one :beam, Float + has_one :displacement, Float + has_one :draught, Float + has_one :length, Float + has_one :tonnage, Float + end + + class Vessel + include HappyMapper + + tag "vessel" + + has_one :address, Base::Models::Address + has_many :alias_names, String, tag: "aliasname" + has_one :contact, Base::Models::Contact + has_one :marina, String + has_one :name, String + has_one :notes, Notes + has_many :ratings, Rating, tag: "rating" + has_one :ship_dimension, ShipDimension, tag: "shipdimension" + has_one :ship_type, String, tag: "shiptype" + end + + class Operator + include HappyMapper + + tag "operator" + + has_many :alias_names, String, tag: "aliasname" + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :name, String + has_one :notes, Notes + has_many :ratings, Rating, tag: "rating" + end + + class DateOfTrip + include HappyMapper + + tag "dateoftrip" + + attribute :start_date, DateTime + attribute :end_date, DateTime + end + + class Accommodation + include HappyMapper + + tag "accommodation" + + has_one :address, Base::Models::Address + has_many :alias_names, String, tag: "aliasname" + has_one :category, String + has_one :contact, Base::Models::Contact + has_one :name, String + has_one :notes, Notes + has_many :ratings, Rating, tag: "rating" + end + + class Geography + include HappyMapper + + tag "geography" + + has_one :address, Base::Models::Address + has_one :altitude, Float + has_one :latitude, Float + has_one :location, String + has_one :longitude, Float + has_one :time_zone, Float, tag: "timezone" + end + + class TripPart + include HappyMapper + + tag "trippart" + + attribute :type, String + has_one :accommodation, Accommodation + has_one :date_of_trip, DateOfTrip, tag: "dateoftrip" + has_one :geography, Geography + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + has_one :operator, Operator + has_one :price_dive_package, PriceDivePackage, tag: "pricedivepackage" + has_one :price_per_dive, Price, tag: "priceperdive" + has_one :related_dives, RelatedDives, tag: "relateddives" + has_one :vessel, Vessel + end + + class Trip + include HappyMapper + + tag "trip" + + attribute :id, String + has_many :alias_names, String, tag: "aliasname" + has_one :name, String + has_many :ratings, Rating, tag: "rating" + has_many :trip_parts, TripPart, tag: "trippart" + end + + class DiveTrip + include HappyMapper + + tag "divetrip" + + has_many :trips, Trip, tag: "trip" + end + + class Ecology + include HappyMapper + + tag "ecology" + + has_one :fauna, Fauna + has_one :flora, Flora + end + + class Built + include HappyMapper + + tag "built" + + has_one :launching_date, Base::Models::DateTimeField, tag: "launchingdate" + has_one :ship_yard, String, tag: "shipyard" + end + + class Wreck + include HappyMapper + + tag "wreck" + + has_many :alias_names, String, tag: "aliasname" + has_one :built, Built + has_one :name, String + has_one :nationality, String + has_one :ship_dimension, ShipDimension, tag: "shipdimension" + has_one :ship_type, String, tag: "shiptype" + has_one :sunk, Base::Models::DateTimeField + end + + class Shore + include HappyMapper + + tag "shore" + + attribute :id, String + has_many :alias_names, String, tag: "aliasname" + has_one :name, String + has_one :notes, Notes + end + + class River + include HappyMapper + + tag "river" + + attribute :id, String + has_many :alias_names, String, tag: "aliasname" + has_one :name, String + has_one :notes, Notes + end + + class Lake + include HappyMapper + + tag "lake" + + attribute :id, String + has_many :alias_names, String, tag: "aliasname" + has_one :name, String + has_one :notes, Notes + end + + class Indoor + include HappyMapper + + tag "indoor" + + has_one :address, Base::Models::Address + has_many :alias_names, String, tag: "aliasname" + has_one :contact, Base::Models::Contact + has_one :name, String + has_one :notes, Notes + end + + class Cave + include HappyMapper + + tag "cave" + + attribute :id, String + has_many :alias_names, String, tag: "aliasname" + has_one :name, String + has_one :notes, Notes + end + + class SiteData + include HappyMapper + + tag "sidedata" + + has_one :area_length, Float, tag: "arealength" + has_one :area_width, Float, tag: "areawidth" + has_one :average_visibility, Float, tag: "averagevisibility" + has_one :bottom, String + has_one :cave, Cave + has_one :density, Float + has_one :difficulty, Integer + has_one :global_light_intensity, String, tag: "globallightintensity" + has_one :indoor, Indoor + has_one :maximum_depth, Float, tag: "maximumdepth" + has_one :maximum_visibility, Float, tag: "maximumvisibility" + has_one :minimum_depth, Float, tag: "minimumdepth" + has_one :minimum_visibility, Float, tag: "minimumvisibility" + has_one :river, River + has_one :shore, Shore + has_one :terrain, String + has_one :wreck, Wreck + end + + class Site + include HappyMapper + + tag "site" + + attribute :id, String + has_many :alias_names, String, tag: "aliasname" + has_one :ecology, Ecology + has_one :environment, String + has_one :geography, Geography + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + has_many :ratings, Rating, tag: "rating" + has_one :side_data, SiteData, tag: "sitedata" + end + + class Guide + include HappyMapper + + tag "guide" + + has_many :links, Link, tag: "link" + end + + class DiveBase + include HappyMapper + + tag "divebase" + + attribute :id, String + has_one :address, Base::Models::Address + has_many :alias_names, String, tag: "aliasname" + has_one :contact, Base::Models::Contact + has_many :guides, Guide, tag: "guide" + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + has_one :price_dive_package, PriceDivePackage, tag: "pricedivepackage" + has_one :price_per_dive, Price, tag: "priceperdive" + has_many :ratings, Rating, tag: "rating" + end + + class DiveSite + include HappyMapper + + tag "divesite" + + has_many :dive_bases, DiveBase, tag: "divebase" + has_many :sites, Site, tag: "site" + end + + class Shop + include HappyMapper + + tag "shop" + + has_many :alias_names, String, tag: "aliasname" + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :name, String + has_one :notes, Notes + end + + class Business + include HappyMapper + + tag "business" + + has_one :shop, Shop + end + + class Membership + include HappyMapper + + tag "membership" + + attribute :organisation, String + attribute :member_id, String + end + + class NumberOfDives + include HappyMapper + + tag "numberofdives" + + has_one :start_date, DateTime, tag: "startdate" + has_one :end_date, DateTime, tag: "enddate" + has_one :dives, Integer + end + + class Personal + include HappyMapper + + tag "personal" + + has_one :birth_date, Base::Models::DateTimeField, tag: "birthdate" + has_one :birth_name, String, tag: "birthname" + has_one :blood_group, String, tag: "bloodgroup" + has_one :first_name, String, tag: "firstname" + has_one :height, Float + has_one :honorific, String + has_one :last_name, String, tag: "lastname" + has_one :membership, Membership + has_one :middle_name, String, tag: "middlename" + has_one :number_of_dives, NumberOfDives, tag: "numberofdives" + has_one :sex, String + has_one :smoking, String + has_one :weight, Float + end + + class Instructor + include HappyMapper + + tag "instructor" + + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :personal, Personal + end + + class Certification + include HappyMapper + + tag "certification" + + has_one :certificate_number, String, tag: "certificatenumber" + has_one :instructor, Instructor + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" + has_one :level, String + has_one :link, Link + has_one :organization, String + has_one :specialty, String + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" + end + + class Education + include HappyMapper + + tag "education" + + has_many :certifications, Certification, tag: "certification" + end + + class Insurance + include HappyMapper + + tag "insurance" + + has_many :alias_names, String, tag: "aliasname" + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" + has_one :name, String + has_one :notes, Notes + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" + end + + class DiveInsurances + include HappyMapper + + tag "diveinsurances" + + has_many :insurances, Insurance, tag: "insurance" + end + + class Permit + include HappyMapper + + tag "permit" + + has_many :alias_names, String, tag: "aliasname" + has_one :issue_date, Base::Models::DateTimeField, tag: "issuedate" + has_one :name, String + has_one :notes, Notes + has_one :region, String + has_one :valid_date, Base::Models::DateTimeField, tag: "validdate" + end + + class DivePermissions + include HappyMapper + + tag "divepermissions" + + has_many :permits, Permit, tag: "permit" + end + + class Purchase + include HappyMapper + + tag "purchase" + + has_one :datetime, DateTime + has_one :link, Link + has_one :price, Price + has_one :shop, Shop + end + + class TemperatureSensor + include HappyMapper + + tag "temperaturesensor" + + attribute :id, String + + has_many :alias_names, String, tag: "aliasname" + has_one :manufacturer, Manufacturer + has_one :model, String + has_one :name, String + has_one :next_service_date, Base::Models::DateTimeField, tag: "nextservicedate" + has_one :notes, Notes + has_one :purchase, Purchase + has_one :serial_number, String, tag: "serialnumber" + has_one :service_interval, Integer, tag: "serviceinterval" + end + + class TimerDevice + include HappyMapper + + tag "timerdevice" + + attribute :id, String + end + + class EquipmentPart + include HappyMapper + + tag "equipmentpart" + + attribute :id, String + has_many :alias_names, String, tag: "aliasname" + has_many :links, Link, tag: "link" + has_one :manufacturer, Manufacturer + has_one :model, String + has_one :name, String + has_one :next_service_date, Base::Models::DateTimeField, tag: "nextservicedate" + has_one :notes, Notes + has_one :purchase, Purchase + has_one :serial_number, String, tag: "serialnumber" + has_one :service_interval, Integer, tag: "serviceinterval" + end + + class Lead < EquipmentPart + include HappyMapper + + tag "lead" + + has_one :lead_quantity, Integer, tag: "leadquantity" + end + + class Rebreather < EquipmentPart + include HappyMapper + + tag "rebreather" + + has_many :batteries, Battery, tag: "battery" + has_many :o2_sensors, EquipmentPart, tag: "o2sensor" + has_many :scrubber_monitors, ScrubberMonitor, tag: "scrubbermonitor" + has_many :temperature_sensors, TemperatureSensor, tag: "temperaturesensor" + has_many :timer_devices, TimerDevice, tag: "timerdevice" + end + + class Suit < EquipmentPart + include HappyMapper + + tag "suit" + + has_one :suit_type, String, tag: "suittype" + end + + class Tank < EquipmentPart + include HappyMapper + + tag "tank" + + has_one :tank_material, String, tag: "tankmaterial" + has_one :tank_volume, Float, tag: "tankvolume" + has_many :batteries, Battery, tag: "battery" + has_one :hydro_service_interval, Integer, tag: "hydroserviceinterval" + has_one :next_hydro_date, Base::Models::DateTimeField, tag: "nexthydrodate" + has_one :next_visual_date, Base::Models::DateTimeField, tag: "nextvisualdate" + has_one :rated_pressure, Float, tag: "ratedpressure" + has_one :visual_service_interval, Integer, tag: "visualserviceinterval" + end + + class Camera + include HappyMapper + + tag "camera" + + has_one :body, EquipmentPart + has_many :flashes, EquipmentPart, tag: "flash" + has_one :housing, EquipmentPart + has_one :lens, EquipmentPart + end + + class DiveComputer < EquipmentPart + include HappyMapper + + tag "divecomputer" + + has_many :batteries, Battery, tag: "battery" + has_many :timer_devices, TimerDevice, tag: "timerdevice" + end + + class EquipmentContent + include HappyMapper + + has_many :boots, EquipmentPart, tag: "boots" + has_many :buoyancy_control_devices, EquipmentPart, tag: "buoyancycontroldevice" + has_many :cameras, Camera, tag: "camera" + has_many :compasses, EquipmentPart, tag: "compass" + has_many :dive_computers, DiveComputer, tag: "divecomputer" + has_many :fins, EquipmentPart, tag: "fins" + has_many :gloves, EquipmentPart, tag: "gloves" + has_many :knives, EquipmentPart, tag: "knife" + has_many :leads, Lead, tag: "lead" + has_many :lights, EquipmentPart, tag: "light" + has_many :masks, EquipmentPart, tag: "mask" + has_many :rebreathers, Rebreather, tag: "rebreather" + has_many :regulators, EquipmentPart, tag: "regulator" + has_many :scooters, EquipmentPart, tag: "scooter" + has_many :suits, Suit, tag: "suit" + has_many :tanks, Tank, tag: "tank" + has_many :various_pieces, EquipmentPart, tag: "variouspieces" + has_many :video_cameras, EquipmentPart, tag: "videocamera" + has_many :watches, EquipmentPart, tag: "watch" + end + + class EquipmentConfiguration < EquipmentContent + include HappyMapper + + tag "equipmentconfiguration" + + has_many :alias_names, String, tag: "aliasname" + has_many :links, Link, tag: "link" + has_one :name, String + has_one :notes, Notes + end + + class Equipment < EquipmentContent + include HappyMapper + + tag "equipment" + + has_many :compressors, EquipmentPart, tag: "compressor" + has_one :equipment_configuration, EquipmentConfiguration, tag: "equipmentconfiguration" + end + + class Doctor + include HappyMapper + + tag "doctor" + + attribute :id, String + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :personal, Personal + end + + class Examination + include HappyMapper + + tag "examination" + + has_one :datetime, DateTime + has_one :doctor, Doctor + has_one :examination_result, String, tag: "examinationresult" + has_many :links, Link, tag: "link" + has_one :notes, Notes + has_one :total_lung_capacity, Float, tag: "totallungcapacity" + has_one :vital_capacity, Float, tag: "vitalcapacity" + end + + class Medical + include HappyMapper + + tag "medical" + + has_one :examination, Examination + end + + class BuddyOwnerShared + include HappyMapper + + attribute :id, String + has_one :address, Base::Models::Address + has_one :contact, Base::Models::Contact + has_one :dive_insurances, DiveInsurances, tag: "diveinsurances" + has_one :dive_permissions, DivePermissions, tag: "divepermissions" + has_one :equipment, Equipment + has_one :medical, Medical + has_one :notes, Notes + has_one :personal, Personal + end + + class Buddy < BuddyOwnerShared + include HappyMapper + + tag "buddy" + + attribute :id, String + has_one :certification, Certification + has_one :student, String + end + + class Owner < BuddyOwnerShared + include HappyMapper + + tag "owner" + + attribute :id, String + has_one :education, Education + end + + class Diver + include HappyMapper + + tag "diver" + + has_many :buddies, Buddy, tag: "buddy" + has_one :owner, Owner + end + + class DCAlarm + include HappyMapper + + tag "dcalarm" + + has_one :acknowledge, String + has_one :alarm_type, Integer, tag: "alarmtype" + has_one :period, Float + end + + class SetDCDiveDepthAlarm + include HappyMapper + + tag "setdcdivedethalarm" + + has_one :dc_alarm, DCAlarm + has_one :dc_alarm_depth, Float + end + + class SetDCDivePo2Alarm + include HappyMapper + + tag "setdcdivepo2alarm" + + has_one :dc_alarm, DCAlarm + has_one :maximum_po2, Float + end + + class SetDCDiveSiteData + include HappyMapper + + tag "setdcdivesitedata" + + attribute :dive_site, String + end + + class SetDCDiveTimeAlarm + include HappyMapper + + tag "setdcdivetimealarm" + + has_one :dc_alarm, DCAlarm + has_one :timespan, Float + end + + class SetDCEndNDTAlarm + include HappyMapper + + tag "setdcendndtalarm" + + has_one :dc_alarm, DCAlarm + end + + class SetDCDecoModel + include HappyMapper + + tag "setdcdecomodel" + + has_many :alias_names, String, tag: "aliasname" + has_one :application_data, ApplicationData + has_one :name, String + end + + class SetDCBuddyData + include HappyMapper + + tag "setdcbuddydata" + + attribute :buddy, String + end + + class SetDCData + include HappyMapper + + tag "setdcdata" + + has_one :set_dc_alarm_time, DateTime + has_one :set_dc_altitude, Float + has_one :set_dc_buddy_data, SetDCBuddyData + has_one :set_dc_date_time, DateTime + has_one :set_dc_deco_model, SetDCDecoModel + has_one :set_dc_dive_depth_alarm, SetDCDiveDepthAlarm + has_one :set_dc_dive_po2_alarm, SetDCDivePo2Alarm + has_many :set_dc_dive_site_data, SetDCDiveSiteData, tag: "setdcdivesitedata" + has_one :set_dc_dive_time_alarm, SetDCDiveTimeAlarm + has_one :set_dc_end_ndt_alarm, SetDCEndNDTAlarm + has_one :set_dc_gas_definitions_data, String + has_one :set_dc_owner_data, String + has_one :set_dc_password, String + has_one :set_dc_generator_data, String + end + + class GetDCData + include HappyMapper + + tag "getdcdata" + + has_one :get_dc_all_data, String + has_one :get_dc_generator_data, String + has_one :get_dc_owner_data, String + has_one :get_dc_buddy_data, String + has_one :get_dc_gas_definitions_data, String + has_one :get_dc_dive_site_data, String + has_one :get_dc_dive_trip_data, String + has_one :get_dc_profile_data, String + end + + class DiveComputerDump + include HappyMapper + + tag "divecomputerdump" + + has_one :datetime, DateTime + has_one :dc_dump, String + has_one :link, Link + end + + class DiveComputerControl + include HappyMapper + + tag "divecomputercontrol" + + has_many :dive_computer_dumps, DiveComputerDump, tag: "divecomputerdump" + has_one :get_dc_data, GetDCData, tag: "getdcdata" + has_one :set_dc_data, SetDCData, tag: "setdcdata" + end + + class Uddf + include HappyMapper + + tag "uddf" + + attribute :version, String + has_one :business, Business + has_one :deco_model, DecoModel, tag: "decomodel" + has_one :dive_computer_control, DiveComputerControl, tag: "divecomputercontrol" + has_one :diver, Diver + has_one :dive_site, DiveSite, tag: "divesite" + has_one :dive_trip, DiveTrip, tag: "divetrip" + has_one :gas_definitions, GasDefinitions, tag: "gasdefinitions" + has_one :generator, Generator + has_one :maker, Maker + has_one :media_data, MediaData, tag: "mediadata" + has_one :profile_data, ProfileData, tag: "profiledata" + has_one :table_generation, TableGeneration, tag: "tablegeneration" + end + end + end +end diff --git a/test_files/v331/uddf_spec/biologics.uddf b/test_files/v331/uddf_spec/biologics.uddf new file mode 100644 index 0000000..c132826 --- /dev/null +++ b/test_files/v331/uddf_spec/biologics.uddf @@ -0,0 +1,161 @@ + + + + + + + + + rote_gorgonie.jpg + + + + + + eisseestern.jpg + 5_zackis.jpg + meersalat_meerjunker.jpg + heinz_neben_3_zackis.jpg + portrait_grosser_roter_drachenkopf.jpg + + + + + + Untiefe südlich des Ilot de la Gabiniere + + Ilot de la Gabiniere +
+ Cote d'Azur + Frankreich +
+ + 0.0 +
+ + + + + + + Nierenschwamm + Chondrosia reniformis + + + Roter Krustenschwamm + Crambe crambe + + + Hellblauer Krustenschwamm + Anchinoe + + + + + Rote Gorgonie + Paramuricea clavata (chamaeleon) + + + + + Rote Seescheide + Halocynthia papillosa + + + + + Purpurseestern + Echinaster sepositus + + + + + + + Mittelmeer-Muräne + Muraena helena + + + Brauner Zackenbarsch + Epinephelus guaza + + + Spitzkopf-Zackenbarsch + Epinephelus alexandrinus + + + Roter Fahnenbarsch + Anthias anthias + + + Mönchsfisch + Chromis chromis + + + Meerjunker + Coris julis + + + Zweibindenbrassen + Diplodus vulgaris + + + Brandbrassen + Oblada melanura + + + Pfauenlippfisch + Symphodus tinca + + + + + + + + Peyssonnelia + Peyssonnelia squamaria + + + + + Meersalat + Ulva rigida + + + Meerball + Codium bursa + + + + + + 18.0 + 32.0 + 20.0 + 8.0 + + 1030.0 + Felsen + + + + Erstklassiger Tauchplatz! Aufgrund von Strömung oftmals nur schwierig zu betauchen. + Erreichbar entweder im Freiwasser-Abstieg vom Boot oder - bei guter (!) Kenntnis der + Geländebeschaffenheit - von der Südspitze des Ilot de la Gabiniere aus nach Südwesten + tauchend. Recht schmaler, langgezogener Felskamm, auf beiden Seiten steilwandartig. + Dichter Bewuchs mit Algen, Schwämmen, Gorgonien. Viele Fische, insbesondere zahlreich + anzutreffende Zackenbarsche. + + + + + + + + + +
+
+ +
\ No newline at end of file diff --git a/test_files/v331/uddf_spec/dive_sites.uddf b/test_files/v331/uddf_spec/dive_sites.uddf new file mode 100644 index 0000000..b9be002 --- /dev/null +++ b/test_files/v331/uddf_spec/dive_sites.uddf @@ -0,0 +1,211 @@ + + + + + ... + + + + + + + + + Deep Down + + info@deep-down-diving.com + http://www.deep-down-diving.com + + 40.00 + 350.00 + + + + + + + + + + 7 + + + + + + Brummer + + Scapa Flow +
+ Orkney Islands + UK +
+ + 58.897222 + + -3.1519444 + 0.0 +
+ + 37.0 + 1030.0 + Sandboden + + SMS Brummer + leichter Kreuzer + deutsch + + Vulcan, Stettin + + 1916 + + + + 140.0 + 13.0 + 6.0 + 4.385E6 + + + 1919-06-21T13:05 + + + Deutsche Hochsee-Flotte + + + + + Sehr schöner Wrack-Tauchgang + +
+ +
+ + + + + Vereinsfahrt Rotes Meer 2003 + + + Rotes Meer +
+ Hurghada + Ägypten +
+
+ + Hotel 1000 und 1 Nacht + Hotel + + info@hotel-1000-und-1-nacht.com + http://www.hotel-1000-und-1-nacht.com + + + 6 + + + + + schöner Tauchurlaub - wenn nicht so viele andere Taucher dort wären... + + +
+
+ + + Tauch-Segeltörn 2004 + + +
+ Cote d'Azur + Frankreich +
+
+ + Dorade + Segelyacht + Bormes les Mimosas + + + 14.6 + 3.5 + + + + + + + + + Unser Motto: Wir tauchen das, wovon andere träumen!!! :-) + + +
+
+ + Vereinsfahrt Korsika 2005 + + Vereinsfahrt Korsika 2005 - 1 Woche Galiote + + + Mittelmeer +
+ Korsika +
+
+ + Galiote + Motoryacht + + + + + + + + + Schöner Tauchurlaub mit Günter und seiner Crew! + + +
+ + Vereinsfahrt Korsika 2005 - 1 Woche Campingplatz und Tauchclub Nemo + + +
+ + Korsika +
+
+ + Camping Corse + Camping + + info@camping-corse.com + http://www.camping-corse.com + + + 6 + + + + + + + + + Nette zweite Woche Korsika-Tauchurlaub! + + +
+
+
+ + +
\ No newline at end of file diff --git a/test_files/v331/uddf_spec/diver_data.uddf b/test_files/v331/uddf_spec/diver_data.uddf new file mode 100644 index 0000000..dc2f0e2 --- /dev/null +++ b/test_files/v331/uddf_spec/diver_data.uddf @@ -0,0 +1,358 @@ + + + + + STL - Super-Taucher-Logbuch + logbook + + Tauchhelden-Company +
+ +
+ + + +
+ 3.14159 + 2004-09-30 +
+ + + Arnos Plattfüße... + plattfuss.jpg + + + + + + + + Froschkönig AG +
+ Teichstr. 12 + Seeheim + 91827 + Deutschland + Berlin-Brandenburg +
+ + deutsch + 01234/234567 + 0123/123123123 + info@froschkoenig-ag.de + http://www.froschkoenig-ag.de + +
+ +
+ + + + + + Freizeit und Wassersport GmbH +
+ + Hans Hass Str. 1 + Seedorf + 15243 + Deutschland +
+ + + 03456/615243 + 0123/567567567 + info@fuw-gmbh.de + http://www.fuw-gmbh.de + + + + +
+ + Die Flachtaucher +
+ +
+ + + + + + +
+
+ + + + + + + Arno + Albert + Alzheimer + Dr. + male + + 1919-02-28 + + 987654321 + 1.8 + 86.0 + 0 + A + + + +
+ Auf der Heide 12 + Aheim + 12345 + Deutschland + +
+ + deutsch + 01234/567890 + arno@arno-alzheimer.org + http://www.tieftauchen.info/arno + + + + + ABC + + + + + Underwater Camping Team + 123456789 + + 1960-05-31 + 100.00 + + + + + + + 365 + + 2006-05-31 + + + + noname + + + + + Größe 48 + + + 1970-10-07 + 10.00 + + + + + + + 30 + + + + Alberts Flasche + + Stahlflaschenbauer + + 15 Liter + 12345 + + 25000000.0 + 0.015 + + 1986-08-19 + 200.00 + + Tauchtviel +
+ +
+ + + + + + +
+
+ + 730 + + 2006-08 + + + + + + +
+ + Alberts Flasche Nr. 2 + 54321 + + 30000000.0 + 0.012 + + + 2025-06 + + +
+ + + 2003-04-12 + + + Dirk + Dusel + Dr. + male + + 1919-02-28 + + +
+ Duddelstr. 34 + Dortmund + 54321 + Deutschland + Nordrhein-Westfalen +
+ + deutsch + 01234/987654 + + +
+ passed + + + Plattfüße scheinen die Tauchtauglichkeit nicht zu beeinflussen :-) + + + +
+ + 2004-04-20 + + + + passed + +
+ + + + + Bronze + 192837 + VDST/CMAS + + + + + 1994-03-15 + + + + Orientierung + VDST/CMAS + + + + + 1995-01-22 + + + + Silber + 283746 + VDST/CMAS + + + + + 1997-11-26 + + + + Gold + 374650 + VDST/CMAS + + + + + 2000-05-10 + + + + + + + DiveCard + Österreich + + 2004-08-24 + + + 2005-08-23 + + + + Zeeland + Zeeland (Niederlande) + + 1996-09-03 + + + 2001-08-31 + + + + + + +
+ + + + + Bert + Bammel + + + + luftsauger@tieftauchen.de + http://www.tieftauchen.info/bert + + + + + + Carsten + Cabuff + + + + lurchi@abcde.com + http://www.tieftauchen.info/carsten + + + +
+ + +
\ No newline at end of file From 15d6f37f1b75cfa2b72c47437ebc10efddc50726 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 16:55:35 +0200 Subject: [PATCH 12/13] reject test files Signed-off-by: Flipez --- uddf.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uddf.gemspec b/uddf.gemspec index c947057..dc00110 100644 --- a/uddf.gemspec +++ b/uddf.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |spec| # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. spec.files = Dir.chdir(File.expand_path(__dir__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) } + `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|test_files|dive_files|.github)/}) } end spec.bindir = "exe" spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } From 8c57b7ce59becd112193a2532ddfb5347d1fe561 Mon Sep 17 00:00:00 2001 From: Flipez Date: Sat, 23 Aug 2025 16:56:40 +0200 Subject: [PATCH 13/13] bump version Signed-off-by: Flipez --- Gemfile.lock | 2 +- lib/uddf/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 13dc7ef..58b527a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - uddf (0.2.1) + uddf (0.3.0) nokogiri (~> 1.18) nokogiri-happymapper diff --git a/lib/uddf/version.rb b/lib/uddf/version.rb index 0e0b02f..50c126e 100644 --- a/lib/uddf/version.rb +++ b/lib/uddf/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module UDDF - VERSION = "0.2.1" + VERSION = "0.3.0" end