Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1 from peresvetjke/feature/UCMS-7655
Browse files Browse the repository at this point in the history
[UCMS-7655] Add EntitiesLogDump, FlexibleBoolean, UrlFormatter, CiFor…
  • Loading branch information
kopylovvlad authored Sep 5, 2023
2 parents c79d5ed + da85aa4 commit 1c5dcd9
Show file tree
Hide file tree
Showing 17 changed files with 615 additions and 28 deletions.
4 changes: 1 addition & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in unity-utils.gemspec
gemspec

gem 'pry', '~> 3.0'
gem 'pry', '>= 0.14.2'

gem 'rspec', '~> 3.0'

gem 'rubocop', '~> 1.21.0'

gem 'ruby-progressbar', '~> 1.11.0'
48 changes: 31 additions & 17 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
PATH
remote: .
specs:
unity-utils (0.1.0)
ruby-progressbar
unity-utils (0.1.2)
activesupport (>= 4.2)
ruby-progressbar (>= 1.11.0)

GEM
remote: https://rubygems.org/
specs:
activesupport (7.0.7.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
ast (2.4.2)
coderay (1.1.3)
concurrent-ruby (1.2.2)
diff-lcs (1.4.4)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
method_source (1.0.0)
parallel (1.20.1)
parser (3.0.2.0)
minitest (5.19.0)
parallel (1.23.0)
parser (3.2.2.3)
ast (~> 2.4.1)
pry (0.14.0)
racc
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
rainbow (3.0.0)
regexp_parser (2.1.1)
rexml (3.2.5)
racc (1.7.1)
rainbow (3.1.1)
regexp_parser (2.8.1)
rexml (3.2.6)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
Expand All @@ -33,7 +45,7 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-support (3.10.2)
rubocop (1.20.0)
rubocop (1.21.0)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
Expand All @@ -42,20 +54,22 @@ GEM
rubocop-ast (>= 1.9.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.11.0)
parser (>= 3.0.1.1)
rubocop-ast (1.29.0)
parser (>= 3.2.1.0)
ruby-progressbar (1.11.0)
unicode-display_width (2.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.4.2)

PLATFORMS
x86_64-darwin-19
x86_64-darwin-21

DEPENDENCIES
pry
rspec
rubocop
ruby-progressbar
pry (>= 0.14.2)
rspec (~> 3.0)
rubocop (~> 1.21.0)
unity-utils!

BUNDLED WITH
2.2.12
2.4.19
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ Gem with utilities used by Unity team
# Documentation

- ### Utils:
- **CiFormatter** - Custom rspec formatter: collapses pending tests and adds some time analytics.

```
rspec --formatter CiFormatter
...bash
Rubric publishing using Muppet::PublishJob
updating rubric
enqueues Muppet::PublishJob | Duration: 0.03981s
...
Groups:
7.20884s ./spec/services/topics_views_count/update_spec.rb (right after midnight)
5.45071s ./spec/commands/ugc/approve_topic_spec.rb (approve logic)
...
Single examples:
5.45071s ./spec/commands/ugc/approve_topic_spec.rb (approve logic / creates a topic)
4.91609s ./spec/commands/topic/update/reviews_of_published_spec.rb (has correct state value / is expected to be need approval)
```

- **Retrier** - Restarting passed block.
```ruby
Unity::Utils::Retrier.call { 5 / 0 }
Expand All @@ -20,6 +38,20 @@ Gem with utilities used by Unity team
pool.run!
```

- **UrlFormatter** - Formats url.
```ruby
formatter = ::Unity::Utils::UrlFormatter.new('blog/post/nykotyn-bez-syharet-hde-on-soderzytsia/')
formatter.trailing_slash(enabled: false).build #=> "blog/post/nykotyn-bez-syharet-hde-on-soderzytsia"
formatter.params({'erid' => 'test'}).build #=> "blog/post/nykotyn-bez-syharet-hde-on-soderzytsia?erid=test"
```

- **UrlValidator** - Validates url.
```ruby
response = UrlValidator.new('ftp://motor.ru/reports/videoparis.htm').call
response.valid? #=> false
response.errors #=> ['Ссылка должна начинаться с http(s)']
```

- ### Modules:
- **CliModeable** - Wrapper over the ruby-progressbar.
```ruby
Expand All @@ -35,6 +67,30 @@ Gem with utilities used by Unity team
end
```

- **EntitiesLogDump** - Module for service objects do dump entities.
```ruby
dump_entities(Topic.first, attributes: [:id, :headline]) # => [{ "id" => 1, "headline" => "foo" }, { "id" => 2, "headline" => "bar" }]
dump_entities(Topic.first(2), attributes: [:id, :headline]) #=> { "id" => 1, "headline" => "foo" }
```
Will work both with ApplicationRecord or Mongoid::Document models.

- **FlexibleBoolean** - Concern to make easier work with virtual boolean attributes.
```ruby
class MyKlass
include IsReactable
flexible_boolean :is_reactable
attr_reader :is_reactable
def intiailize(is_reactable)
@is_reactable = is_reactable
end
end
MyKlass.new(true).is_reactable # => true
MyKlass.new(nil).is_reactable # => false
```

- **Loggable** - Wrapper over logger.
```ruby
@log_file = 'some_file.log'
Expand Down
8 changes: 8 additions & 0 deletions lib/unity/config/locales/ru.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
ru:
unity_utils:
errors:
blank_url: Ссылка не может быть пустой
invalid_url_format: Неправильный формат ссылки
blank_host: Хост не может быть пустым
invalid_protocol: Ссылка должна начинаться с http(s)
15 changes: 15 additions & 0 deletions lib/unity/modules/cli_modeable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,35 @@ module Modules
module CliModeable
private

# @return [Boolean]
def cli_mode?
@cli_mode == true
end

# @param amount [Fixnum]
# @param title [String]
# @return [void]
def init_progressbar(amount, title = self.class.to_s)
return unless cli_mode?

@progressbar = ProgressBar.create(title: title, format: '%t, %c/%C,%e: |%B|')
@progressbar.total = amount
end

# Increment value of progressbar
# @return [void]
def incr_progressbar
@progressbar.increment if cli_mode?
end

# @param amount [Fixnum]
# @return [void]
def add_to_progress(amount = 0)
return unless cli_mode?

new_progress = @progressbar.progress + amount
@progressbar.progress = new_progress if new_progress <= @progressbar.total
end
end
end
end
81 changes: 81 additions & 0 deletions lib/unity/modules/entities_log_dump.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# frozen_string_literal: true

require 'active_support/concern'

module Unity
module Modules
# You could use this module for service objects
# class YourServiceObject
# include Helpers::EntitiesLogDump
#
# You can get array of logged entities by custom attributes like that:
# def topic_query
# @topic_query ||= Topic.first(2)
# end
#
# def foo
# dump_entities(topic_query, attributes: [:id, :headline])
# end
# Result: [{ "id" => 1, "headline" => "foo" }, { "id" => 2, "headline" => "bar" }]
#
module EntitiesLogDump
extend ::ActiveSupport::Concern

# @param entities [ActiveRecord::Relation,Array<Mongoid::Document>]
# @param [Hash] options
# @option options [Array<Symbol>] :attributes
# @option options [Integer] :batch_size
# @return [Array<Hash>]
def dump_entities(entities, options = {})
attributes = options[:attributes] || all_attributes(entities.first)
batch_size = options[:batch_size] || 100

dump_entities = []
entities.each_slice(batch_size) do |sliced_entities|
sliced_entities.each do |entity|
dump_entities.append(dump_entity(entity, attributes: attributes))
end
end

dump_entities
end

# @param entity [ApplicationRecord,Mongoid::Document]
# @param [Hash] options
# @option options [Array<Symbol>] :attributes
# @return [Hash]
def dump_entity(entity, options = {})
attributes = options[:attributes] || all_attributes(entity)
attributes.map { |a| { a => try_array(entity.send(a)) } }.inject(:merge).deep_stringify_keys
end

# @param entity [ApplicationRecord,Mongoid::Document]
# @return [Array<String,Symbol>]
def all_attributes(entity)
return entity.class.attribute_names if object_is_a?(entity, 'ApplicationRecord')
return entity.fields.keys if object_is_a?(entity, 'Mongoid::Document')

raise ArgumentError, "Can't determine full attributes list for this kind of entity."
end

private

# @item [Object]
# @return
def try_array(item)
return item.map { |i| i.try(:attributes) || i } if item.is_a?(Array)
return item.map(&:attributes) if item.try(:any?) { |obj| object_is_a?(obj, 'ActiveRecord::Base') }

item
end

# @param obj [Object]
# @klass_name [String]
# @return [Boolean]
def object_is_a?(obj, klass_name)
ancestors = obj.class.ancestors.map(&:to_s)
ancestors.include?(klass_name)
end
end
end
end
29 changes: 29 additions & 0 deletions lib/unity/modules/flexible_boolean.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

require 'active_support/concern'

module Unity
module Modules
# Concern to make easier work with virtual boolean attributes.
# Allows always store a boolean value in a pseudo attribute
# (pass string or boolean, attribute will boolean value type always).
#
# Overrides target attribute setter method by adding a
# comparison of the boolean attribute value with the 'true' string.
#
# Usage example:
# flexible_boolean :is_reactable
#
module FlexibleBoolean
extend ::ActiveSupport::Concern

class_methods do
# @param attribute [Symbol, String]
# @return [Symbol] defined method name
def flexible_boolean(attribute)
define_method(:"#{attribute}=") { |v| super(v.to_s == 'true') }
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module Unity
module Modules
module Logable
module Loggable
attr_reader :log_file, :logger

def clean_logfile
Expand Down
9 changes: 8 additions & 1 deletion lib/unity/utils.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
# frozen_string_literal: true

# Modules
require_relative 'modules/logable'
require_relative 'modules/cli_modeable'
require_relative 'modules/entities_log_dump'
require_relative 'modules/flexible_boolean'
require_relative 'modules/loggable'

# Utils
require_relative 'utils/ci_formatter'
require_relative 'utils/retrier'
require_relative 'utils/thread_pool'
require_relative 'utils/url_formatter'
require_relative 'utils/url_validator'

I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'config/locales/*.yml')]

module Unity
module Utils
Expand Down
Loading

0 comments on commit 1c5dcd9

Please sign in to comment.