sheets_v4 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e8b306cf08149067ba4f5506c54c88df4e2af706f064b3b2b7cc7f5919991f4
4
- data.tar.gz: 438a64d88598542b9f9ed56552077836089e04b411aa8a4ceabf5279b131a393
3
+ metadata.gz: 27e014c65904a88e3fb4df001a8b28c64c307363b3cd658da252a951c55da992
4
+ data.tar.gz: c6900f0d163abdb621a49080295ca7e59f82b89bae69d5e5729aa74aac765a1b
5
5
  SHA512:
6
- metadata.gz: 3728b1539d987a5aa7dfbbb45d0a9637d01c39d5fe3d8a3e19cd7206b9fab4b9ce1458d1f6e534e6ddb79d93d2792c93f940f3a800f2eb657647dd4dfdebceb9
7
- data.tar.gz: fe7d8f59b7663f76804d18e13ece431bdce418252efe51a2e50d28a5d3e5fe1c979b367287155032e82571e09c593bd9be2b40cc461901a4bf5bec728cfcc8e2
6
+ metadata.gz: e60614708c5f348d05388a1bfe7b51603a92797e852aa20445d37451a493655aac69ea86fd901d500a9898a289f469d9a3780fdbe2f2756cfb80a65110641455
7
+ data.tar.gz: 71ea62ff3e93faf9d9ece533ccd98f5491dea2f04d00d01c01020dd501a251a3b0b61544e0e57e85643fc0afedbfe97e92250d71b5968c63650822f0e3338433
data/.markdownlint.yml ADDED
@@ -0,0 +1,25 @@
1
+ default: true
2
+
3
+ # Unordered list indentation
4
+ MD007: { indent: 2 }
5
+
6
+ # Line length
7
+ MD013: { line_length: 90, tables: false, code_blocks: false }
8
+
9
+ # Heading duplication is allowed for non-sibling headings
10
+ MD024: { siblings_only: true }
11
+
12
+ # Do not allow the specified trailig punctuation in a header
13
+ MD026: { punctuation: '.,;:' }
14
+
15
+ # Order list items must have a prefix that increases in numerical order
16
+ MD029: { style: 'ordered' }
17
+
18
+ # Lists do not need to be surrounded by blank lines
19
+ MD032: false
20
+
21
+ # Allow raw HTML in Markdown
22
+ MD033: false
23
+
24
+ # Allow emphasis to be used instead of a heading
25
+ MD036: false
data/.rubocop.yml CHANGED
@@ -23,6 +23,9 @@ Metrics/BlockLength:
23
23
  - "spec/**/*_spec.rb"
24
24
  - "*.gemspec"
25
25
 
26
+ Metrics/ModuleLength:
27
+ CountAsOne: ['hash']
28
+
26
29
  # When writing minitest tests, it is very hard to limit test class length:
27
30
  Metrics/ClassLength:
28
31
  Exclude:
data/CHANGELOG.md CHANGED
@@ -4,6 +4,24 @@ Changes for each release are listed in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](https://semver.org/) for its releases.
6
6
 
7
+ ## v0.3.0 (2023-09-28)
8
+
9
+ [Full Changelog](https://github.com/main-branch/sheets_v4/compare/v0.2.0..v0.3.0)
10
+
11
+ Changes since v0.2.0:
12
+
13
+ * 0fb4579 Add predefined color objects (#8)
14
+
15
+ ## v0.2.0 (2023-09-26)
16
+
17
+ [Full Changelog](https://github.com/main-branch/sheets_v4/compare/v0.1.1..v0.2.0)
18
+
19
+ Changes since v0.1.1:
20
+
21
+ * 489ff50 Add SheetsV4.validate_api_object (#6)
22
+ * b44eba4 List all examples that should be created (#5)
23
+ * 2edd688 Add links to Google Sheets documentation to the README.md (#4)
24
+
7
25
  ## v0.1.1 (2023-09-22)
8
26
 
9
27
  [Full Changelog](https://github.com/main-branch/sheets_v4/compare/v0.1.0..v0.1.1)
data/README.md CHANGED
@@ -9,12 +9,33 @@
9
9
 
10
10
  Unofficial helpers for the Google Sheets V4 API
11
11
 
12
- - [SheetsV4](#sheetsv4)
13
- - [Installation](#installation)
14
- - [Usage](#usage)
15
- - [Development](#development)
16
- - [Contributing](#contributing)
17
- - [License](#license)
12
+ * [Important Links for Programming Google Sheets](#important-links-for-programming-google-sheets)
13
+ * [General API Documentation](#general-api-documentation)
14
+ * [Ruby Implementation of the Sheets API](#ruby-implementation-of-the-sheets-api)
15
+ * [Other Links](#other-links)
16
+ * [Installation](#installation)
17
+ * [Usage](#usage)
18
+ * [Development](#development)
19
+ * [Creating a Google API Service Account](#creating-a-google-api-service-account)
20
+ * [Contributing](#contributing)
21
+ * [License](#license)
22
+
23
+ ## Important Links for Programming Google Sheets
24
+
25
+ ### General API Documentation
26
+
27
+ * [Google Sheets API Overview](https://developers.google.com/sheets/api)
28
+ * [Google Sheets API Reference](https://developers.google.com/sheets/api/reference/rest)
29
+ * [Batch Update Requests](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request)
30
+
31
+ ### Ruby Implementation of the Sheets API
32
+
33
+ * [SheetsService Class](https://github.com/googleapis/google-api-ruby-client/blob/main/generated/google-apis-sheets_v4/lib/google/apis/sheets_v4/service.rb)
34
+ * [All Other Sheets Classes](https://github.com/googleapis/google-api-ruby-client/blob/main/generated/google-apis-sheets_v4/lib/google/apis/sheets_v4/classes.rb)
35
+
36
+ ### Other Links
37
+
38
+ * [Apps Script for Sheets](https://developers.google.com/apps-script/guides/sheets)
18
39
 
19
40
  ## Installation
20
41
 
@@ -46,6 +67,9 @@ release a new version, update the version number in `version.rb`, and then run
46
67
  commits and the created tag, and push the `.gem` file to
47
68
  [rubygems.org](https://rubygems.org).
48
69
 
70
+ ## Creating a Google API Service Account
71
+
72
+
49
73
  ## Contributing
50
74
 
51
75
  Bug reports and pull requests are welcome on [the main-branch/sheets_v4 GitHub project](https://github.com/main-branch/sheets_v4).
@@ -53,4 +77,4 @@ Bug reports and pull requests are welcome on [the main-branch/sheets_v4 GitHub p
53
77
  ## License
54
78
 
55
79
  The gem is available as open source under the terms of the
56
- [MIT License](https://opensource.org/licenses/MIT).
80
+ [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ desc 'Run the same tasks that the CI build will run'
4
4
  if RUBY_PLATFORM == 'java'
5
5
  task default: %w[spec rubocop bundle:audit build]
6
6
  else
7
- task default: %w[spec rubocop yard yard:audit yard:coverage bundle:audit build]
7
+ task default: %w[spec rubocop yard bundle:audit build]
8
8
  end
9
9
 
10
10
  # Bundler Audit
@@ -58,28 +58,41 @@ end
58
58
  CLEAN << 'rubocop-report.json'
59
59
 
60
60
  unless RUBY_PLATFORM == 'java'
61
- # YARD
61
+ # yard:build
62
62
 
63
63
  require 'yard'
64
- YARD::Rake::YardocTask.new do |t|
65
- t.files = %w[lib/**/*.rb examples/**/*]
64
+
65
+ YARD::Rake::YardocTask.new('yard:build') do |t|
66
+ t.files = %w[lib/**/*.rb]
67
+ t.stats_options = ['--list-undoc']
66
68
  end
67
69
 
68
70
  CLEAN << '.yardoc'
69
71
  CLEAN << 'doc'
70
72
 
71
- # Yardstick
73
+ # yard:audit
72
74
 
73
75
  desc 'Run yardstick to show missing YARD doc elements'
74
76
  task :'yard:audit' do
75
77
  sh "yardstick 'lib/**/*.rb'"
76
78
  end
77
79
 
78
- # Yardstick coverage
80
+ # yard:coverage
79
81
 
80
82
  require 'yardstick/rake/verify'
81
83
 
82
84
  Yardstick::Rake::Verify.new(:'yard:coverage') do |verify|
83
85
  verify.threshold = 100
86
+ verify.require_exact_threshold = false
87
+ end
88
+
89
+ task yard: %i[yard:build yard:audit yard:coverage]
90
+
91
+ # github-pages:publish
92
+
93
+ require 'github_pages_rake_tasks'
94
+ GithubPagesRakeTasks::PublishTask.new do |task|
95
+ # task.doc_dir = 'documentation'
96
+ task.verbose = true
84
97
  end
85
98
  end
@@ -0,0 +1,47 @@
1
+ # Google Sheets Examples
2
+
3
+ * [ ] Creating a Google API service account [1](https://www.youtube.com/watch?v=sAgWCbGMzTo&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=1)
4
+ [2](https://www.youtube.com/watch?v=sVURhxyc6jE&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=43)
5
+ * [ ] Create a SheetsService instance
6
+ * [ ] Creating Google Sheets files [1](https://www.youtube.com/watch?v=JRUxeQ6ZCy0&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=2)
7
+ * [ ] Writing data to a sheet [1](https://www.youtube.com/watch?v=YF7Ad-7pvks&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=3)
8
+ * [ ] Reading data from a sheet [1](https://www.youtube.com/watch?v=gkglr8GID5E&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=4)
9
+ * Reading data
10
+ * Reading formulas
11
+ * [ ] Data formatting basics [1](https://www.youtube.com/watch?v=R4EN3iPRris&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=5)
12
+ * [ ] Creating charts [1](https://www.youtube.com/watch?v=xt3p5I8mNWE&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=6)
13
+ * [ ] Data validation [1](https://www.youtube.com/watch?v=n_Z2565gu6Y&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=7)
14
+ * [ ] Cut, copy, and paste [1](https://www.youtube.com/watch?v=r8GWH2E_ehw&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=8)
15
+ * [ ] Duplicate sheets [1](https://www.youtube.com/watch?v=BgQoPcoOiGY&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=9)
16
+ * [ ] List sheets in a spreadsheet [1](https://www.youtube.com/watch?v=BgQoPcoOiGY&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=9)
17
+ * [ ] Set column width and row height [1](https://www.youtube.com/watch?v=H3uMEaPqTVE&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=11)
18
+ * [ ] Append rows and columns [1](https://www.youtube.com/watch?v=txfiwEjb7sk&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=12)
19
+ * [ ] Delete rows and columns [1](https://www.youtube.com/watch?v=w1jrCxWx7Tc&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=13)
20
+ * [ ] Insert rows and columns [1](https://www.youtube.com/watch?v=FL7WSsO5EVs&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=14)
21
+ * [ ] Move rows and columns [1](https://www.youtube.com/watch?v=YHk3305dkOc&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=15)
22
+ * [ ] Clear data [1](https://www.youtube.com/watch?v=mvbnhfdDrro&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=16)
23
+ * [ ] Add and delete sheets [1](https://www.youtube.com/watch?v=X9PVQQVoJFc&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=17)
24
+ * [ ] Copy sheet from one spreadsheet to another [1](https://www.youtube.com/watch?v=aIEM7Ts4n-c&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=18)
25
+ * [ ] Add a new sheet to an existing spreadsheet
26
+ * [ ] Export a sheet to a CSV file [1](https://www.youtube.com/watch?v=Dz22fsWsLhI&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=25)
27
+ * [ ] Sort sheets [1](https://www.youtube.com/watch?v=qbBZX7uBM1M&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=27)
28
+ * [ ] Add calculated fields into a pivot table [1](https://www.youtube.com/watch?v=VR8zOz5ATLU&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=32)
29
+ * [ ] Named ranges [1](https://www.youtube.com/watch?v=LTPdfXS_LHA&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=42)
30
+ * [ ] Create a pivot table [1](https://www.youtube.com/watch?v=preFnuL7ua0&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=28)
31
+ * [ ] Calculated pivot fields [1](https://www.youtube.com/watch?v=QLssI4uvjk4&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=33)
32
+ * [ ] Delete a pivot table
33
+ * [ ] Add pivot fields [1](https://www.youtube.com/watch?v=VR8zOz5ATLU&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=32)
34
+ * [ ] Add pivot filters [1](https://www.youtube.com/watch?v=EKikw-eIcbY&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=29)
35
+ * [ ] Collapse/expand pivot table groups [1](https://www.youtube.com/watch?v=-S9bs5-ZJ5E&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=31)
36
+ * [ ] Extract pivot table metadata [1](https://www.youtube.com/watch?v=H1SGdqbaL4w&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=30)
37
+ * [ ] Filter views [1](https://www.youtube.com/watch?v=GyRxsSlx0GU&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=34)
38
+ * [ ] Locate the last row in a column [1](https://www.youtube.com/watch?v=NWWHleJll28&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=35)
39
+ * [ ] Autofill [1](https://www.youtube.com/watch?v=guHGNmODdpM&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=36)
40
+ * [ ] Rename a sheet [1](https://www.youtube.com/watch?v=iuiDUJ4NrQI&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=37)
41
+ * [ ] Find and replace [1](https://www.youtube.com/watch?v=YaFR0bu5CrY&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=39)
42
+ * [ ] Add and delete sheets [1](https://www.youtube.com/watch?v=gMD4v8F8vlc&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=38)
43
+ * [ ] Sum across sheets [1](https://www.youtube.com/watch?v=7QNk-MXkPC4&list=PL3JVwFmb_BnSee8RFaRPZ3nykuMRlaQp1&index=44)
44
+ * [ ] Freeze rows / columns
45
+ * [ ] Protected ranges
46
+ * [ ] Resize a sheet
47
+ * [ ] Retrying on error
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json_schemer'
4
+
5
+ module SheetsV4
6
+ # Predefined color objects
7
+ # @api public
8
+ class Color
9
+ class << self
10
+ # Return a color object for the given name from SheetsV4::COLORS or call super
11
+ #
12
+ # @param method_name [Symbol] the name of the color
13
+ # @param arguments [Array] ignored
14
+ # @param block [Proc] ignored
15
+ # @return [Hash] the color object
16
+ # @api private
17
+ def method_missing(method_name, *arguments, &)
18
+ SheetsV4::COLORS[method_name.to_sym] || super
19
+ end
20
+
21
+ # Return true if the given method name is a color name or call super
22
+ #
23
+ # @param method_name [Symbol] the name of the color
24
+ # @param include_private [Boolean] ignored
25
+ # @return [Boolean] true if the method name is a color name
26
+ # @api private
27
+ def respond_to_missing?(method_name, include_private = false)
28
+ SheetsV4::COLORS.key?(method_name.to_sym) || super
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json_schemer'
4
+
5
+ module SheetsV4
6
+ # Validate objects against a Google Sheets API request object schema
7
+ #
8
+ # @api public
9
+ #
10
+ class ValidateApiObject
11
+ # Create a new validator
12
+ #
13
+ # By default, a nil logger is used. This means that no messages are logged.
14
+ #
15
+ # @example
16
+ # logger = Logger.new(STDOUT, :level => Logger::INFO)
17
+ # validator = SheetsV4::ValidateApiObject.new(logger)
18
+ #
19
+ # @param logger [Logger] the logger to use
20
+ #
21
+ def initialize(logger = Logger.new(nil))
22
+ @logger = logger
23
+ end
24
+
25
+ # The logger to use internally
26
+ #
27
+ # Validation errors are logged at the error level. Other messages are logged
28
+ # at the debug level.
29
+ #
30
+ # @example
31
+ # logger = Logger.new(STDOUT, :level => Logger::INFO)
32
+ # validator = SheetsV4::ValidateApiObject.new(logger)
33
+ # validator.logger == logger # => true
34
+ # validator.logger.debug { "Debug message" }
35
+ #
36
+ # @return [Logger]
37
+ #
38
+ attr_reader :logger
39
+
40
+ # Validate the object using the JSON schema named schema_name
41
+ #
42
+ # @example
43
+ # schema_name = 'BatchUpdateSpreadsheetRequest'
44
+ # object = { 'requests' => [] }
45
+ # validator = SheetsV4::ValidateApiObject.new
46
+ # validator.call(schema_name, object)
47
+ #
48
+ # @param schema_name [String] the name of the schema to validate against
49
+ # @param object [Object] the object to validate
50
+ #
51
+ # @raise [RuntimeError] if the object does not conform to the schema
52
+ #
53
+ # @return [void]
54
+ #
55
+ def call(schema_name, object)
56
+ logger.debug { "Validating #{object} against #{schema_name}" }
57
+
58
+ schema = { '$ref' => schema_name }
59
+ schemer = JSONSchemer.schema(schema, ref_resolver:)
60
+ errors = schemer.validate(object)
61
+ raise_error!(schema_name, object, errors) if errors.any?
62
+
63
+ logger.debug { "Object #{object} conforms to #{schema_name}" }
64
+ end
65
+
66
+ private
67
+
68
+ # The resolver to use to resolve JSON schema references
69
+ # @return [SchemaRefResolver]
70
+ # @api private
71
+ def ref_resolver = @ref_resolver ||= SchemaRefResolver.new(logger)
72
+
73
+ # Raise an error when the object does not conform to the schema
74
+ # @return [void]
75
+ # @raise [RuntimeError]
76
+ # @api private
77
+ def raise_error!(schema_name, object, errors)
78
+ error = errors.first['error']
79
+ error_message = "Object #{object} does not conform to #{schema_name}: #{error}"
80
+ logger.error(error_message)
81
+ raise error_message
82
+ end
83
+ end
84
+
85
+ # Resolve JSON schema references to Google Sheets API schemas
86
+ #
87
+ # Uses the Google Discovery API to get the schemas. This is an implementation
88
+ # detail used to interact with JSONSchemer.
89
+ #
90
+ # @api private
91
+ #
92
+ class SchemaRefResolver
93
+ # Create a new schema resolver
94
+ #
95
+ # @param logger [Logger] the logger to use
96
+ #
97
+ # @api private
98
+ #
99
+ def initialize(logger)
100
+ @logger = logger
101
+ end
102
+
103
+ # The logger to use internally
104
+ #
105
+ # Currently, only info messages are logged.
106
+ #
107
+ # @return [Logger]
108
+ #
109
+ # @api private
110
+ #
111
+ attr_reader :logger
112
+
113
+ # Resolve a JSON schema reference
114
+ #
115
+ # @param ref [String] the reference to resolve usually in the form "#/definitions/schema_name"
116
+ #
117
+ # @return [Hash] the schema object as a hash
118
+ #
119
+ # @api private
120
+ #
121
+ def call(ref)
122
+ schema_name = ref.path[1..]
123
+ logger.debug { "Reading schema #{schema_name}" }
124
+ schema_object = SheetsV4.api_object_schemas[schema_name]
125
+ raise "Schema for #{ref} not found" unless schema_object
126
+
127
+ schema_object.to_h.tap do |schema|
128
+ schema['unevaluatedProperties'] = false
129
+ end
130
+ end
131
+ end
132
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SheetsV4
4
- VERSION = '0.1.1'
4
+ # The version of this gem
5
+ VERSION = '0.3.0'
5
6
  end
data/lib/sheets_v4.rb CHANGED
@@ -1,8 +1,242 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'sheets_v4/version'
4
+ require_relative 'sheets_v4/color'
5
+ require_relative 'sheets_v4/validate_api_object'
4
6
 
7
+ require 'json'
8
+ require 'logger'
9
+ require 'net/http'
10
+
11
+ # Unofficial helpers for the Google Sheets V4 API
12
+ #
13
+ # @api public
14
+ #
5
15
  module SheetsV4
6
- class Error < StandardError; end
7
- # Your code goes here...
16
+ # Validate the object using the named JSON schema
17
+ #
18
+ # The JSON schemas are loaded from the Google Disocvery API. The schemas names are
19
+ # returned by `SheetsV4.api_object_schemas.keys`.
20
+ #
21
+ # @example
22
+ # schema_name = 'BatchUpdateSpreadsheetRequest'
23
+ # object = { 'requests' => [] }
24
+ # SheetsV4.validate_api_object(schema_name:, object:)
25
+ #
26
+ # @param schema_name [String] the name of the schema to validate against
27
+ # @param object [Object] the object to validate
28
+ # @param logger [Logger] the logger to use for logging error, info, and debug message
29
+ #
30
+ # @raise [RuntimeError] if the object does not conform to the schema
31
+ #
32
+ # @return [void]
33
+ #
34
+ def self.validate_api_object(schema_name:, object:, logger: Logger.new(nil))
35
+ ValidateApiObject.new(logger).call(schema_name, object)
36
+ end
37
+
38
+ # A hash of schemas keyed by the schema name loaded from the Google Discovery API
39
+ #
40
+ # @example
41
+ # SheetsV4.api_object_schemas #=> { 'PersonSchema' => { 'type' => 'object', ... } ... }
42
+ #
43
+ # @return [Hash<String, Object>] a hash of schemas keyed by schema name
44
+ #
45
+ def self.api_object_schemas
46
+ schema_load_semaphore.synchronize { @api_object_schemas ||= load_api_object_schemas }
47
+ end
48
+
49
+ # Validate
50
+ # A mutex used to synchronize access to the schemas so they are only loaded
51
+ # once.
52
+ #
53
+ @schema_load_semaphore = Thread::Mutex.new
54
+
55
+ # A mutex used to synchronize access to the schemas so they are only loaded once
56
+ #
57
+ # @return [Thread::Mutex]
58
+ #
59
+ # @api private
60
+ #
61
+ def self.schema_load_semaphore = @schema_load_semaphore
62
+
63
+ # Load the schemas from the Google Discovery API
64
+ #
65
+ # @return [Hash<String, Object>] a hash of schemas keyed by schema name
66
+ #
67
+ # @api private
68
+ #
69
+ def self.load_api_object_schemas
70
+ source = 'https://sheets.googleapis.com/$discovery/rest?version=v4'
71
+ resp = Net::HTTP.get_response(URI.parse(source))
72
+ data = resp.body
73
+ JSON.parse(data)['schemas'].tap do |schemas|
74
+ schemas.each { |_name, schema| schema['unevaluatedProperties'] = false }
75
+ end
76
+ end
77
+
78
+ # Return a color object for the given name from SheetsV4::COLORS
79
+ #
80
+ # @example
81
+ # SheetsV4::Color.color(:red) #=> { "red": 1.0, "green": 0.0, "blue": 0.0 }
82
+ #
83
+ # @param name [Symbol] the name of the color
84
+ # @return [Hash] the color object
85
+ # @api public
86
+ def self.color(name)
87
+ SheetsV4::COLORS[name.to_sym]
88
+ end
89
+
90
+ # Colors to use in the Google Sheets API
91
+ COLORS = {
92
+ # Standard Google Sheets colors
93
+
94
+ black: { red: 0.000000000, green: 0.000000000, blue: 0.000000000 },
95
+ dark_gray4: { red: 0.262745098, green: 0.262745098, blue: 0.262745098 },
96
+ dark_gray3: { red: 0.400000000, green: 0.400000000, blue: 0.400000000 },
97
+ dark_gray2: { red: 0.600000000, green: 0.600000000, blue: 0.600000000 },
98
+ dark_gray1: { red: 0.717647059, green: 0.717647059, blue: 0.717647059 },
99
+ gray: { red: 0.800000000, green: 0.800000000, blue: 0.800000000 },
100
+ light_gray1: { red: 0.850980392, green: 0.850980392, blue: 0.850980392 },
101
+ light_gray2: { red: 0.937254902, green: 0.937254902, blue: 0.937254902 },
102
+ light_gray3: { red: 0.952941176, green: 0.952941176, blue: 0.952941176 },
103
+ white: { red: 1.000000000, green: 1.000000000, blue: 1.000000000 },
104
+ red_berry: { red: 0.596078431, green: 0.000000000, blue: 0.000000000 },
105
+ red: { red: 1.000000000, green: 0.000000000, blue: 0.000000000 },
106
+ orange: { red: 1.000000000, green: 0.600000000, blue: 0.000000000 },
107
+ yellow: { red: 1.000000000, green: 1.000000000, blue: 0.000000000 },
108
+ green: { red: 0.000000000, green: 1.000000000, blue: 0.000000000 },
109
+ cyan: { red: 0.000000000, green: 1.000000000, blue: 1.000000000 },
110
+ cornflower_blue: { red: 0.290196078, green: 0.525490196, blue: 0.909803922 },
111
+ blue: { red: 0.000000000, green: 0.000000000, blue: 1.000000000 },
112
+ purple: { red: 0.600000000, green: 0.000000000, blue: 1.000000000 },
113
+ magenta: { red: 1.000000000, green: 0.000000000, blue: 1.000000000 },
114
+ light_red_berry3: { red: 0.901960784, green: 0.721568627, blue: 0.686274510 },
115
+ light_red3: { red: 0.956862745, green: 0.800000000, blue: 0.800000000 },
116
+ light_orange3: { red: 0.988235294, green: 0.898039216, blue: 0.803921569 },
117
+ light_yellow3: { red: 1.000000000, green: 0.949019608, blue: 0.800000000 },
118
+ light_green3: { red: 0.850980392, green: 0.917647059, blue: 0.827450980 },
119
+ light_cyan3: { red: 0.815686275, green: 0.878431373, blue: 0.890196078 },
120
+ light_cornflower_blue3: { red: 0.788235294, green: 0.854901961, blue: 0.972549020 },
121
+ light_blue3: { red: 0.811764706, green: 0.886274510, blue: 0.952941176 },
122
+ light_purple3: { red: 0.850980392, green: 0.823529412, blue: 0.913725490 },
123
+ light_magenta3: { red: 0.917647059, green: 0.819607843, blue: 0.862745098 },
124
+ light_red_berry2: { red: 0.866666667, green: 0.494117647, blue: 0.419607843 },
125
+ light_red2: { red: 0.917647059, green: 0.600000000, blue: 0.600000000 },
126
+ light_orange2: { red: 0.976470588, green: 0.796078431, blue: 0.611764706 },
127
+ light_yellow2: { red: 1.000000000, green: 0.898039216, blue: 0.600000000 },
128
+ light_green2: { red: 0.713725490, green: 0.843137255, blue: 0.658823529 },
129
+ light_cyan2: { red: 0.635294118, green: 0.768627451, blue: 0.788235294 },
130
+ light_cornflower_blue2: { red: 0.643137255, green: 0.760784314, blue: 0.956862745 },
131
+ light_blue2: { red: 0.623529412, green: 0.772549020, blue: 0.909803922 },
132
+ light_purple2: { red: 0.705882353, green: 0.654901961, blue: 0.839215686 },
133
+ light_magenta2: { red: 0.835294118, green: 0.650980392, blue: 0.741176471 },
134
+ light_red_berry1: { red: 0.800000000, green: 0.254901961, blue: 0.145098039 },
135
+ light_red1: { red: 0.878431373, green: 0.400000000, blue: 0.400000000 },
136
+ light_orange1: { red: 0.964705882, green: 0.698039216, blue: 0.419607843 },
137
+ light_yellow1: { red: 1.000000000, green: 0.850980392, blue: 0.400000000 },
138
+ light_green1: { red: 0.576470588, green: 0.768627451, blue: 0.490196078 },
139
+ light_cyan1: { red: 0.462745098, green: 0.647058824, blue: 0.686274510 },
140
+ light_cornflower_blue1: { red: 0.427450980, green: 0.619607843, blue: 0.921568627 },
141
+ light_blue1: { red: 0.435294118, green: 0.658823529, blue: 0.862745098 },
142
+ light_purple1: { red: 0.556862745, green: 0.486274510, blue: 0.764705882 },
143
+ light_magenta1: { red: 0.760784314, green: 0.482352941, blue: 0.627450980 },
144
+ dark_red_berry1: { red: 0.650980392, green: 0.109803922, blue: 0.000000000 },
145
+ dark_red1: { red: 0.800000000, green: 0.000000000, blue: 0.000000000 },
146
+ dark_orange1: { red: 0.901960784, green: 0.568627451, blue: 0.219607843 },
147
+ dark_yellow1: { red: 0.945098039, green: 0.760784314, blue: 0.196078431 },
148
+ dark_green1: { red: 0.415686275, green: 0.658823529, blue: 0.309803922 },
149
+ dark_cyan1: { red: 0.270588235, green: 0.505882353, blue: 0.556862745 },
150
+ dark_cornflower_blue1: { red: 0.235294118, green: 0.470588235, blue: 0.847058824 },
151
+ dark_blue1: { red: 0.239215686, green: 0.521568627, blue: 0.776470588 },
152
+ dark_purple1: { red: 0.403921569, green: 0.305882353, blue: 0.654901961 },
153
+ dark_magenta1: { red: 0.650980392, green: 0.301960784, blue: 0.474509804 },
154
+ dark_red_berry2: { red: 0.521568627, green: 0.125490196, blue: 0.047058824 },
155
+ dark_red2: { red: 0.600000000, green: 0.000000000, blue: 0.000000000 },
156
+ dark_orange2: { red: 0.705882353, green: 0.372549020, blue: 0.023529412 },
157
+ dark_yellow2: { red: 0.749019608, green: 0.564705882, blue: 0.000000000 },
158
+ dark_green2: { red: 0.219607843, green: 0.462745098, blue: 0.113725490 },
159
+ dark_cyan2: { red: 0.074509804, green: 0.309803922, blue: 0.360784314 },
160
+ dark_cornflower_blue2: { red: 0.066666667, green: 0.333333333, blue: 0.800000000 },
161
+ dark_blue2: { red: 0.043137255, green: 0.325490196, blue: 0.580392157 },
162
+ dark_purple2: { red: 0.207843137, green: 0.109803922, blue: 0.458823529 },
163
+ dark_magenta2: { red: 0.454901961, green: 0.105882353, blue: 0.278431373 },
164
+ dark_red_berry3: { red: 0.356862745, green: 0.058823529, blue: 0.000000000 },
165
+ dark_red3: { red: 0.400000000, green: 0.000000000, blue: 0.000000000 },
166
+ dark_orange3: { red: 0.470588235, green: 0.247058824, blue: 0.015686275 },
167
+ dark_yellow3: { red: 0.498039216, green: 0.376470588, blue: 0.000000000 },
168
+ dark_green3: { red: 0.152941176, green: 0.305882353, blue: 0.074509804 },
169
+ darn_cyan3: { red: 0.047058824, green: 0.203921569, blue: 0.239215686 },
170
+ dark_cornflower_blue3: { red: 0.109803922, green: 0.270588235, blue: 0.529411765 },
171
+ dark_blue3: { red: 0.027450980, green: 0.215686275, blue: 0.388235294 },
172
+ dark_purple3: { red: 0.125490196, green: 0.070588235, blue: 0.301960784 },
173
+ dark_magenta3: { red: 0.298039216, green: 0.066666667, blue: 0.188235294 },
174
+
175
+ # Yahoo brand colors
176
+
177
+ grape_jelly: { red: 0.376470588, green: 0.003921569, blue: 0.823529412 },
178
+ hulk_pants: { red: 0.494117647, green: 0.121568627, blue: 1.000000000 },
179
+ malbec: { red: 0.223529412, green: 0.000000000, blue: 0.490196078 },
180
+ tumeric: { red: 1.000000000, green: 0.654901961, blue: 0.000000000 },
181
+ mulah: { red: 0.101960784, green: 0.772549020, blue: 0.403921569 },
182
+ dory: { red: 0.058823529, green: 0.411764706, blue: 1.000000000 },
183
+ malibu: { red: 1.000000000, green: 0.000000000, blue: 0.501960784 },
184
+ sea_foam: { red: 0.066666667, green: 0.827450980, blue: 0.803921569 },
185
+ tumeric_tint: { red: 0.980392157, green: 0.866666667, blue: 0.694117647 },
186
+ mulah_tint: { red: 0.733333333, green: 0.901960784, blue: 0.776470588 },
187
+ dory_tint: { red: 0.662745098, green: 0.772549020, blue: 0.984313725 },
188
+ malibu_tint: { red: 0.968627451, green: 0.682352941, blue: 0.800000000 },
189
+ sea_foam_tint: { red: 0.749019608, green: 0.925490196, blue: 0.921568627 },
190
+
191
+ # Yahoo health colors
192
+
193
+ health_green: { red: 0.000000000, green: 0.690196078, blue: 0.313725490 },
194
+ health_yellow: { red: 1.000000000, green: 0.654901961, blue: 0.000000000 },
195
+ health_red: { red: 1.000000000, green: 0.000000000, blue: 0.000000000 },
196
+
197
+ # Yahoo Fuji design color palette
198
+
199
+ fuji_color_watermelon: { red: 1.000000000, green: 0.321568627, blue: 0.341176471 },
200
+ fuji_color_solo_cup: { red: 0.921568627, green: 0.058823529, blue: 0.160784314 },
201
+ fuji_color_malibu: { red: 1.000000000, green: 0.000000000, blue: 0.501960784 },
202
+ fuji_color_barney: { red: 0.800000000, green: 0.000000000, blue: 0.549019608 },
203
+ fuji_color_mimosa: { red: 1.000000000, green: 0.827450980, blue: 0.200000000 },
204
+ fuji_color_turmeric: { red: 1.000000000, green: 0.654901961, blue: 0.000000000 },
205
+ fuji_color_cheetos: { red: 0.992156863, green: 0.380392157, blue: 0.000000000 },
206
+ fuji_color_carrot_juice: { red: 1.000000000, green: 0.321568627, blue: 0.050980392 },
207
+ fuji_color_mulah: { red: 0.101960784, green: 0.772549020, blue: 0.403921569 },
208
+ fuji_color_bonsai: { red: 0.000000000, green: 0.529411765, blue: 0.317647059 },
209
+ fuji_color_spirulina: { red: 0.000000000, green: 0.627450980, blue: 0.627450980 },
210
+ fuji_color_sea_foam: { red: 0.066666667, green: 0.827450980, blue: 0.803921569 },
211
+ fuji_color_peeps: { red: 0.490196078, green: 0.796078431, blue: 1.000000000 },
212
+ fuji_color_sky: { red: 0.070588235, green: 0.662745098, blue: 1.000000000 },
213
+ fuji_color_dory: { red: 0.058823529, green: 0.411764706, blue: 1.000000000 },
214
+ fuji_color_scooter: { red: 0.000000000, green: 0.388235294, blue: 0.921568627 },
215
+ fuji_color_cobalt: { red: 0.000000000, green: 0.227450980, blue: 0.737254902 },
216
+ fuji_color_denim: { red: 0.101960784, green: 0.050980392, blue: 0.670588235 },
217
+ fuji_color_blurple: { red: 0.364705882, green: 0.368627451, blue: 1.000000000 },
218
+ fuji_color_hendrix: { red: 0.972549020, green: 0.956862745, blue: 1.000000000 },
219
+ fuji_color_thanos: { red: 0.564705882, green: 0.486274510, blue: 1.000000000 },
220
+ fuji_color_starfish: { red: 0.466666667, green: 0.349019608, blue: 1.000000000 },
221
+ fuji_color_hulk_pants: { red: 0.494117647, green: 0.121568627, blue: 1.000000000 },
222
+ fuji_color_grape_jelly: { red: 0.376470588, green: 0.003921569, blue: 0.823529412 },
223
+ fuji_color_mulberry: { red: 0.313725490, green: 0.082352941, blue: 0.690196078 },
224
+ fuji_color_malbec: { red: 0.223529412, green: 0.000000000, blue: 0.490196078 },
225
+ fuji_grayscale_black: { red: 0.000000000, green: 0.000000000, blue: 0.000000000 },
226
+ fuji_grayscale_midnight: { red: 0.062745098, green: 0.082352941, blue: 0.094117647 },
227
+ fuji_grayscale_inkwell: { red: 0.113725490, green: 0.133333333, blue: 0.156862745 },
228
+ fuji_grayscale_batcave: { red: 0.137254902, green: 0.164705882, blue: 0.192156863 },
229
+ fuji_grayscale_ramones: { red: 0.172549020, green: 0.211764706, blue: 0.247058824 },
230
+ fuji_grayscale_charcoal: { red: 0.274509804, green: 0.305882353, blue: 0.337254902 },
231
+ fuji_grayscale_battleship: { red: 0.356862745, green: 0.388235294, blue: 0.415686275 },
232
+ fuji_grayscale_dolphin: { red: 0.431372549, green: 0.466666667, blue: 0.501960784 },
233
+ fuji_grayscale_shark: { red: 0.509803922, green: 0.541176471, blue: 0.576470588 },
234
+ fuji_grayscale_gandalf: { red: 0.592156863, green: 0.619607843, blue: 0.658823529 },
235
+ fuji_grayscale_bob: { red: 0.690196078, green: 0.725490196, blue: 0.756862745 },
236
+ fuji_grayscale_pebble: { red: 0.780392157, green: 0.803921569, blue: 0.823529412 },
237
+ fuji_grayscale_dirty_seagull: { red: 0.878431373, green: 0.894117647, blue: 0.913725490 },
238
+ fuji_grayscale_grey_hair: { red: 0.941176471, green: 0.952941176, blue: 0.960784314 },
239
+ fuji_grayscale_marshmallow: { red: 0.960784314, green: 0.972549020, blue: 0.980392157 },
240
+ fuji_grayscale_white: { red: 1.000000000, green: 1.000000000, blue: 1.000000000 }
241
+ }.freeze
8
242
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sheets_v4
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Couball
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-22 00:00:00.000000000 Z
11
+ date: 2023-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler-audit
@@ -170,6 +170,20 @@ dependencies:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
172
  version: '7.0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: github_pages_rake_tasks
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '0.1'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: '0.1'
173
187
  - !ruby/object:Gem::Dependency
174
188
  name: google-apis-sheets_v4
175
189
  requirement: !ruby/object:Gem::Requirement
@@ -198,6 +212,20 @@ dependencies:
198
212
  - - ">="
199
213
  - !ruby/object:Gem::Version
200
214
  version: '0'
215
+ - !ruby/object:Gem::Dependency
216
+ name: json_schemer
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - "~>"
220
+ - !ruby/object:Gem::Version
221
+ version: '2.0'
222
+ type: :runtime
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - "~>"
227
+ - !ruby/object:Gem::Version
228
+ version: '2.0'
201
229
  - !ruby/object:Gem::Dependency
202
230
  name: rltk
203
231
  requirement: !ruby/object:Gem::Requirement
@@ -219,6 +247,7 @@ executables: []
219
247
  extensions: []
220
248
  extra_rdoc_files: []
221
249
  files:
250
+ - ".markdownlint.yml"
222
251
  - ".rspec"
223
252
  - ".rubocop.yml"
224
253
  - ".yardopts"
@@ -227,7 +256,10 @@ files:
227
256
  - LICENSE.txt
228
257
  - README.md
229
258
  - Rakefile
259
+ - examples/README.md
230
260
  - lib/sheets_v4.rb
261
+ - lib/sheets_v4/color.rb
262
+ - lib/sheets_v4/validate_api_object.rb
231
263
  - lib/sheets_v4/version.rb
232
264
  homepage: https://github.com/main-branch/sheets_v4
233
265
  licenses: