Git Product home page Git Product logo

blackchestnut.github.io's People

Contributors

blackchestnut avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

blackchestnut.github.io's Issues

How to Retrieve a GraphQL Schema

fragment FullType on __Type {
  kind
  name
  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: true) {
    name
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}
fragment InputValue on __InputValue {
  name
  type {
    ...TypeRef
  }
  defaultValue
}
fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
              }
            }
          }
        }
      }
    }
  }
}

{
  __schema {
    queryType {
      ...FullType
    }
    mutationType {
      ...FullType
    }
    types {
      ...FullType
    }    
  }
}

ApplicationHelper and layouts/application

# app/helpers/application_helper.rb

module ApplicationHelper
  def body_class
    "#{page_name} #{page_full_name} #{:mobile if mobile?}"
  end

  def page_name
    "c-#{controller_name}"
  end

  def page_full_name
    "p-#{controller_name}-#{action_name}"
  end

  def turbolinks_on?
    # Your turblinks off logic
    true
  end

  def mobile?
    return true if params[:mobile].present?
    return false if params[:desktop].present?
    return true if session[:mobile_param] && session[:mobile_param] == '1'

    request.user_agent =~ /Mobile|webOS|Android/
  end
end
/ app/views/layouts/application.html.slim

doctype html
html
  head
    = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
    = csrf_meta_tags
  body [
    class=body_class
    data-turbolinks="#{turbolinks_on?}"
  ]
    .container
      = yield

Form field with errors

Ruby

# config/initializers/field_with_error.rb

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  "<div class='field_with_errors'>
    #{html_tag}
    <div class='error_message'>
      #{instance.error_message.first}
    </div>
  </div>".html_safe
end

CSS example

.field_with_errors {
  display: inline-block;
}

.field_with_errors > input[type=text],
.field_with_errors > input[type=password],
.field_with_errors > textarea {
  background-color: #FFEBEE;
  border-bottom: #E53935 solid 1px;
}

.field_with_errors > .error_message {
  color: #D32F2F;
  display: inline-block;
}

Simple authentication for small Rails apps without magic

Simple authentication with password

Dependencies

gem 'bcrypt'
gem 'ulid'

Create user model

r g model User email crypted_password token

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :email
      t.string :crypted_password
      t.string :token

      t.timestamps
    end

    add_index :users, :email, unique: true
    add_index :users, :token, unique: true
  end
end
# app/models/user.rub

require 'bcrypt'
require 'ulid'

class User < ApplicationRecord
  include BCrypt
  before_create :generate_token

  validates :email, presence: true
  validates :crypted_password, presence: true

  def password
    @password ||= Password.new(crypted_password)
  end

  def password=(new_password)
    @password = Password.create(new_password)
    self.crypted_password = @password
  end

private

  def generate_token
    self.token = ULID.generate
  end
end

Add methods to the ApplicationController

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  # ...

  helper_method :token, :current_user, :signed_in?

  def current_user
    @current_user ||= User.find_by(token: token)
  end

  def signed_in?
    current_user.present?
  end

  def token
    params_token || session_token
  end

private

  def session_token
    session[:token]
  end

  def params_token
    params[:token]
  end

  def set_session_token(token)
    session[:token] = token
  end
end

Sign Up controller

r g controller Users new

# app/controllers/users_controller.rb

class UsersControllerController < ApplicationController
  skip_before_action :verify_authenticity_token, only: [:create]

  def new
  end

  def create
    @user = User.build(user_create_params)

    if @user.save?
      set_session_token(@user.token)
      redirect_to root_url(notice: 'Вы успешно зарегистировались')
    else
      render :new
    end
  end

private

  def user_create_params
    params.require(:user).permit(:email)
  end
end

Sign In controller

r g controller Sessions new

# app/controllers/sessions_controller.rb

class SessionsControllerController < ApplicationController
  skip_before_action :verify_authenticity_token, only: [:create]

  def new
    @user = User.new
  end

  def create
    @user = find_user

    if @user.present?
      set_session_token(@user.token)
      redirect_to root_url notice: 'Вы успешно вошли на сайт'
    else
      render :new
    end
  end

  def destroy
    set_session_token(nil)
    redirect_to root_url
  end

private

  def create_sessions_params
    params.require(:user).permit(:email, :password)
  end

  def find_user
    user = User.find_by(email: create_sessions_params[:email])
    return nil if user.nil?
    return nil if user.password != create_sessions_params[:password]

    user
  end
end

Routes

# config/routes.rb

Rails.application.routes.draw do
  resources :users, only: [:new, :create]
  resource :sessions, only: [:new, :create, :destroy]

  scope '(:token)' do
    # ...
  end
end

General Table Size Information

$ psql -d db_name_development

db_name_development=#

SELECT *, pg_size_pretty(total_bytes) AS total
    , pg_size_pretty(index_bytes) AS INDEX
    , pg_size_pretty(toast_bytes) AS toast
    , pg_size_pretty(table_bytes) AS TABLE
  FROM (
  SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes FROM (
      SELECT c.oid,nspname AS table_schema, relname AS TABLE_NAME
              , c.reltuples AS row_estimate
              , pg_total_relation_size(c.oid) AS total_bytes
              , pg_indexes_size(c.oid) AS index_bytes
              , pg_total_relation_size(reltoastrelid) AS toast_bytes
          FROM pg_class c
          LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
          WHERE relkind = 'r'
  ) a
) a;

https://wiki.postgresql.org/wiki/Disk_Usage

macOS Catalina 10.15

OS configuration

Where to find the hidden three-finger drag option in OS X
https://www.cnet.com/how-to/where-to-find-the-hidden-three-finger-drag-option-in-os-x-el-capitan

Development

Checking for existing SSH keys

https://help.github.com/en/articles/checking-for-existing-ssh-keys

Generating a new SSH key and adding it to the ssh-agent (if need)

https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

Adding a new SSH key to your GitHub account

https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account

Checking for existing GPG keys

https://help.github.com/en/articles/checking-for-existing-gpg-keys

Brew Install

  1. xcode-select --install
  2. /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

$ brew -v
Homebrew 2.1.14
Homebrew/homebrew-core (git revision 6b48e; last commit 2019-10-16)

Copy/Init your dot files

[done]

Install Ruby

  1. brew install rbenv (ignore - if you already have it in Brewfile
  2. rbenv init
  3. rbenv install -l See - https://github.com/rbenv/rbenv#installing-ruby-versions
  4. rbenv install YOUR_VERSION
  5. check gem home dir:
    gem env home

    /home/your_user/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0

Vim

rbenv install 2.6.5 # YOUR_VERSION
rbenv local 2.6.5
rbenv global 2.6.5
brew install macvim --HEAD

Run vim command :PqlugInstall after installing

Shrine direct uploads to s3 (has_many)

Configuration

See Shrine direct uploads to s3

Models

# app/models/item.rb
class Item < ApplicationRecord
  has_many :photos, dependent: :destroy
  accepts_nested_attributes_for :photos, allow_destroy: true
end

# app/models/photo.rb
class Photo < ApplicationRecord
  include ImageUploader[:image]
  belongs_to :item

  def before_destroy
    uploader = ImageUploader.new(:store)
    uploader.delete(image)
  end
end

Controllers

# app/controllers/items_controller.rb
class ItemsController < ApplicationController
  # ...

  def update
    if @item.update(item_params)
      redirect_to item_url(@item)
    else
      render :edit
    end
  end

  # ...
private

  def item_params
    params
      .require(:item)
      .permit(:title, :description, photos_attributes: [:id, :_destroy])
  end
end

# app/controllers/photos_controller.rb
class PhotosController < ApplicationController
  def create
    item = current_user.items.find(params[:item_id])
    photo = item.photos.create(photo_params)
    render partial: 'items/photo',
      locals: { photo: photo, index: item.photos.count }
  end

private

  def photo_params
    params.
      require(:photo).
      permit(:image)
  end
end

Routes

# config/routes.rb
Rails.application.routes.draw do
  # ...
  resources :items do
    resource :photo, only: [:create]
  end
end

Views

# app/views/items/edit.html.slim
h2 = t('items.edit_ad')

= form_for @item do |f|
  a name='select_photos'
  h3 Select Photos
  input type='file' multiple='multiple' name='photo'

  ul.photos
    - @item.photos.each_with_index do |photo, index|
      = render partial: 'photo', locals: { photo: photo, index: index }
  br

  = display_errors(@item)
  = render partial: 'items/form_fields', locals: { f: f }

  .row.actions
    input type='submit' value=t('items.save_ad')

javascript:
  $(function() {
    $('[type=file]').fileupload({
      add: function(e, data) {
        data.progressBar = $('<div class="progress">Please wait. Uploading: <span class="progress-bar">1%</div></div>').insertAfter(".photos");
        var options = {
          extension: data.files[0].name.match(/(\.\w+)?$/)[0], // set extension
          _: Date.now(),                                       // prevent caching
        }
        $.getJSON('/images/cache/presign', options, function(result) {
          data.formData = result['fields'];
          data.url = result['url'];
          data.paramName = 'file';
          data.submit();
        });
      },
      progress: function(e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        var percentage = progress.toString() + '%'
        data.progressBar.find('.progress-bar').text(percentage);
      },
      done: function(e, data) {
        data.progressBar.remove();
        var image = {
          id: data.formData.key.match(/cache\/(.+)/)[1], // we have to remove the prefix part
          storage: 'cache',
          metadata: {
            size:      data.files[0].size,
            filename:  data.files[0].name.match(/[^\/\\]+$/)[0], // IE returns full path
            mime_type: data.files[0].type
          }
        }
        var data = {
          photo: {
            image: JSON.stringify(image)
          },
          _csrf: $("input[name=_csrf]").val(),
        }
        $.ajax("#{item_photo_path(item_id: @item.id)}", { method: 'POST', data: data }).
          done(function(data) {
            $('ul').append(data);
          })
      }
    });
  });

Partial Views

# app/views/items/_photo.html.slim
- name = "item[photos_attributes][#{index}]"

li
  img src="#{photo.image_url}" width=300
  input type='hidden' name="#{name}[id]" value="#{photo.id}"
  div
    label Remove photo:
    input type='checkbox' name="#{name}[_destroy]" value='true'

brew upgrade macvim

Fix command-t after upgrade

brew upgrade macvim
cd ~/.vim/plugged/command-t/ruby/command-t/ext/command-t
/usr/local/opt/ruby/bin/ruby extconf.rb
make

Install a specific version (misc)

brew bump-formula-pr macvim --version=8.1-159 --url=https://github.com/macvim-dev/macvim/archive/snapshot-159.tar.gz

brew install macvim --build-from-source --HEAD

SSL certificate

  1. Generate certificate
openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr
  1. Get ssl.zip with secret files after validation from provider and create a chain
cat DOMAIN.crt DOMAIN.ca-bundle >> cert_chain.crt
  1. Add myserver.key and cert_chain.crt nginx settings

Shrine with Amazon S3 storage

Shrine

File Attachment Toolkit for Ruby applications - shrinerb.com

https://github.com/janko-m/shrine

Install

# Gemfile
gem 'aws-sdk'
gem 'shrine'

Configure

# config/initializers/shrine.rb
require 'shrine'
if Rails.env.development?
  require 'dotenv'
  Dotenv.load!('./.env')
end

require 'shrine/storage/s3'
s3_options = {
  access_key_id:     ENV['S3_KEY'],
  secret_access_key: ENV['S3_SECRET'],
  region:            '<BUCKET>',
  bucket:            '<REGION>',
}
Shrine.storages = {
  cache: Shrine::Storage::S3.new(prefix: 'cache', **s3_options),
  store: Shrine::Storage::S3.new(prefix: 'store', **s3_options),
}

Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data

Add image field to model (type: text)

# app/models/team.rb
class Team < ApplicationRecord
  include ImageUploader[:image]
  # ...
end

Image uploader

# app/services/image_uploader.rb
class ImageUploader < Shrine
  # Plugins and uploading logic. Example:
  # plugin :direct_upload
end

In views

h1 Create commands
= form_for @team do |f|
  .row
    = f.text_field :name
  .row
    = f.hidden_field :image, value: @team.cached_image_data
    = f.file_field :image

  .actions
    = f.submit 'Create'
Amazon
  1. Create Bucket
  2. Generate access token
    iam management console 2016-10-25 15-05-40
  3. Edit bucket policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::BUCKET/*"
        }
    ]
}
  1. Edit CROS configuration
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>http://YOUR_DOMAIN.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>https://YOUR_DOMAIN.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
Manual example
# rails c
> file = File.open('/Users/slash/Downloads/cl_logo_1024.png')
> uploader = ImageUploader.new(:store)
> uploaded_file = uploader.upload(file)
#<ImageUploader::UploadedFile:0x007fe23fb26bb8 @data={"id"=>"6e4a72aeb2769c67868c7ea903adc6dd.png", "storage"=>"store", "metadata"=>{"filename"=>"cl_logo_1024.png", "size"=>20341, "mime_type"=>nil}}>
> uploaded_file.url
# "https://BUCKET.s3.REGION.amazonaws.com/store/6e4a72aeb2769c67868c7ea903adc6dd.png?X-Amz-Algorithm=...&X-Amz-Date=...&...ignature=..."

Upgrade Postgres 9.3 to latest_version on OS X

#1. Shutdown postgres
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

# NOTE:
# If you have error: ".../homebrew.mxcl.postgresql.plist: No such file or directory"
# Try to find specific version, for me:
launchctl unload /usr/local/opt/postgresql93/homebrew.mxcl.postgresql93.plist

#2. Install latest postgresql
brew update && brew upgrade postgresql
brew unlink postgresql93
brew link --overwrite postgresql
brew services start postgresql

#3. Upgrade data (set your paths)
pg_upgrade \                       
  -d /usr/local/var/postgres \
  -D /usr/local/var/postgres9.5 \
  -b /usr/local/Cellar/postgresql/9.3.5_1/bin/ \
  -B /usr/local/Cellar/postgresql/9.5.4_1/bin/ \
  -v

# NOTE:
# If you have error: "There seems to be a postmaster servicing the old cluster.
# Please shutdown that postmaster and try again."
# Find and remove postmaster.pid
sudo find /usr/local/var -name "postmaster.pid"
rm /usr/local/var/postgres/postmaster.pid

#4. Move data
brew services stop postgresql
mv /usr/local/var/postgres /usr/local/var/postgres9.3
mv /usr/local/var/postgres9.5 /usr/local/var/postgres

#5. Start new postgresql
brew services start postgresql
psql --version # > psql (PostgreSQL) 9.5.4

To Add Swap on Ubuntu 14.04

# Create a 2 Gigabyte Swap File
sudo fallocate -l 2G /swapfile
ls -lh /swapfile # > -rw-r--r-- 1 root root 2.0G Apr 28 17:19 /swapfile

# Lock down the permissions
sudo chmod 600 /swapfile
ls -lh /swapfile #> -rw------- 1 root root 4.0G Apr 28 17:19 /swapfile

# Enabling the Swap File
sudo mkswap /swapfile
sudo swapon /swapfile

# Verify that the procedure was successful
sudo swapon -s

# Make the Swap File Permanent
sudo vim /etc/fstab
# At the bottom of the file, you need to add a line that will tell
# the operating system to automatically use the file you created:
/swapfile   none    swap    sw    0   0

Disabling Caching in Tests

Typically you may see the following configuration in config/environments/test.rb:

Rails.application.configure do
  config.action_controller.perform_caching = false
end

However, this only disables controller caching. If you application has fragment caching, custom caching behavior, or you are using a gem with caching, then the above may not stop caching behavior between test runs.

Instead, you should have the following line in config/environments/test.rb:

Rails.application.configure do
  config.cache_store = :null_store
end

Source: https://robots.thoughtbot.com/fragment-caching-in-tests

Enum humanized keys

# app/models/game.rb
class Game < ApplicationRecord
  enum kind: { training: 0, friendly_match: 1 }
end

Only in english

// app/views/games/new.html.slim
label Kind
= f.select :kind, Game.kinds.keys.map { |key| [key.humanize, key] })

I18n

ru:
  activerecord:
    attributes:
      game:
        kinds:
          training: Тренировка
          friendly_match: Товарищеский матч
# app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def self.human_enum_name(name, value)
    I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{name.to_s.pluralize}.#{value}")
  end
end
// app/views/games/new.html.slim
label Kind
= f.select :kind, Game.kinds.keys.map { |key| [Game.human_enum_name(:kind, key), key] }

Disposable::Twin

Property::Hash module for work with generic hash fields

$ TeamDetail.first.phones
# [{ phone_number: '123', descripton: 'foo' }, { phone_number: '321', descripton: 'bar' } ]
# app/twins/team_detail_twin.rb
require 'disposable/twin/property/hash'

class TeamDetailTwin < Disposable::Twin
  feature Sync
  include Property::Hash

  collection :phones, field: :hash do
    property :number
    property :descripton
  end
end

# spec/twins/team_detail_spec.rb
describe TeamDetailTwin do
  let(:twin) { TeamDetailTwin.new(team_detail) }
  let(:team) { build_stubbed :team }

  describe '#phones' do
    subject { twin.phones }
    let(:team_detail) { build :team_detail, team: team, phones: phones }

    context 'blank' do
      let(:phones) { nil }
      it { is_expected.to be_empty }
    end

    context 'present' do
      let(:phones) do
        [
          { number: '123', descripton: 'foo' },
          { number: '321', descripton: 'bar' }
        ]
      end

      it { is_expected.to have(2).items }
      its('first.number') { is_expected.to eq '123' }
      its('first.descripton') { is_expected.to eq 'foo' }
    end
  end
end

Read more http://trailblazer.to/gems/disposable/api.html#propertyhash

Reschedule Sidekiq jobs

One job
Sidekiq::ScheduledSet.new.find_job(JOB_ID).reschedule(1.hour.from_now)

All jobs
Sidekiq::ScheduledSet.new.each { |v| v.reschedule(1.hour.from_now) }

Rails new app API only with PostgreSQL & rspec

rails new YOUR_APP_NAME --api --database=postgresql --skip-test --skip-action-cable --skip-action-mailer --skip-javascript

rails db:create

Update Gemfile

# ...

group :development do
  # ...

  gem 'rubocop-rails', require: false
  gem 'guard'
  gem 'guard-bundler', require: false
  gem 'guard-pow', require: false
  gem 'guard-rspec', require: false
  gem 'guard-rubocop', require: false
  gem 'guard-spring', require: false

  gem 'better_errors'
  gem 'binding_of_caller'
  gem 'listen'
  gem 'spring'
end

group :test do
  gem 'rspec-collection_matchers'
  gem 'rspec-its'
  gem 'rspec-rails'
  gem 'rspec_junit_formatter'
  gem 'shoulda'
  gem 'shoulda-matchers'
  gem 'timecop'
  gem 'vcr'
  gem 'webmock', require: false
end

# ...

Install rspec

rails generate rspec:install

journalctl disk usage

Problem:

$ journalctl --disk-usage
Archived and active journals take up 7.2G in the file system.

Solution:

$ journalctl --vacuum-size=500M
$ journalctl --vacuum-time=5d

$ journalctl --disk-usage
Archived and active journals take up 192.0M in the file system.

Simple pg backup

Create a backup (data only)

pg_dump -a -O -f ~/dump.sql database_name

Restore the backup

psql -U user_name -f ~/dump.sql database_name
# Enter password...

Find and remove large junk files from the server

Check

$ df -h
# Filesystem      Size  Used Avail Use% Mounted on
# udev            1.9G     0  1.9G   0% /dev
# tmpfs           395M   12M  383M   3% /run
# /dev/sda         79G   16G   60G  21% /
# tmpfs           2.0G  4.0K  2.0G   1% /dev/shm
# tmpfs           5.0M     0  5.0M   0% /run/lock

Find

$ cd /                                                    
$ sudo du -h . | grep '[0-9\.]\+G'
# 4.0G	./var/log/journal
# 4.5G	./var/log
# 5.1G	./var
# 1.6G	./usr
# 1.1G	./home/devops/.rbenv/versions
# 1.1G	./home/devops/.rbenv
# 2.2G	./home/devops
# ...

Delete files older than specific date in linux

$ find ./ ! -newermt "2020-02-01 00:00:00"  | xargs rm -rf

GNU Screen

GNU Screen is a terminal multiplexer
Docs

Run on the remote server

screen

Resume the first appropriate detached screen session

screen -R

Kill all windows and exi

quit

Pass array of objects via QueryString or Forms

data = { settings: { schedule: { week: [{ id: 1, day: false }, { id: 2, day: true }] } } }
CGI.unescape data.to_query
# > settings[schedule][week][][day]=false&settings[schedule][week][][id]=1&settings[schedule][week][][day]=true&settings[schedule][week][][id]=2

Execution failed for task ':app:dexDebug'.

$ react-native run-android
...
:app:dexDebug FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:dexDebug'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2

or

:app:dexDebug FAILED

FAILURE: Build failed with an exception.

Unknown source file : UNEXPECTED TOP-LEVEL EXCEPTION:
Unknown source file : com.android.dex.DexException: Multiple dex files define Landroid/support/v7/appcompat/R$anim;
...

Solution

$ cd android && ./gradlew clean

Delete jobs from Sidekiq

queue = Sidekiq::Queue.new('queue_name')
queue.select { |job| job.args.first['arguments'].include?('category') }.each(&:delete)

Notes

queue.size # => 508
queue.first.args[0]['job_class'] # => "Parsers::Pages::ProcessJob"
queue.first.args[0]['job_id'] # => "1b8d73ea-bf29-4a2f-9488-d833b5f18f86"

Elasticsearch

Current version

curl http://localhost:9200

{
  "name" : "as",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "sRrGWhcuTPuSIrFB3s9a2g",
  "version" : {
    "number" : "6.3.0",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "424e937",
    "build_date" : "2018-06-11T23:38:03.357887Z",
    "build_snapshot" : false,
    "lucene_version" : "7.3.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

List all Indices

curl http://localhost:9200/_cat/indices\?v

health status index                               uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   as_development_suborders            w19VThu2RLujzcwDb9CDUA   1   1        109            0     47.7kb         47.7kb
yellow open   as_development_product_supplies     wMzPGs3iT66A-qKbgec0TA   1   1      27406            0     55.2mb         55.2mb
yellow open   as_development_help_pages           R5drJ12YTbycZli4mulKVQ   5   1          6            0       13kb           13kb
yellow open   as_development_products             sVluTFyRSdGjH7_AyZ1MHg   1   1       3425            0        1mb            1mb
yellow open   as_development_chewy_specifications 0zQ5DD3oRbSUBDBuwpIg-w   5   1          5            0       23kb           23kb

Delete index

curl -X 'DELETE' http://localhost:9200/index_name

Custom fonts in Rails 5

# config/initializers/assets.rb
Rails.application.config.assets.paths << Rails.root.join('app', 'assets', 'fonts')
// app/assets/stylesheets/global.sass
@font-face
  font-family: 'FONT-NAME'
  src: asset-url('FONT-NAME.ttf')

body
  font-family: 'FONT-NAME'

Shrine direct uploads to s3

Docs

Shrine - Direct Uploads to S3
Demo Rails Project

Dependencies

jquery.fileupload.js
jquery.ui.widget

Example

# Gemfile
gem 'roda'
# app/services/image_uploader.rb
class ImageUploader < Shrine
  plugin :direct_upload
end
/ app/views/teams/new.html.slim
= form_for @team do |f|
  label Logo
  .logo style="background-image: url('#{@team.image_url}');"
  a onclick='$(".upload").click();' Add image

  = f.hidden_field :image, value: @team.cached_image_data
  input.upload.hidden [
    type='file'
    name='file'
    data-dest-selector='#team_image'
    data-preview-selector='.logo'
  ]

  .actions
    = f.submit 'Save'
# app/assets/javascripts/application.coffee
#= require jquery.ui.widget
#= require jquery.fileupload
# app/assets/javascripts/global.coffee
$uploads = $('.upload:not(.listened)')
$uploads.addClass('listened')
$uploads.each (i, elem) ->
  $(elem).fileupload
    add: (e, data) ->
      console.log("Add file - #{data.files[0].name}") # Debug only
      options =
        extension: data.files[0].name.match(/(\.\w+)?$/)[0] # Set extension
        _: Date.now() # Prevent caching
      $.getJSON '/images/cache/presign', options, (result) ->
        data.formData = result['fields']
        data.url = result['url']
        data.paramName = 'file'
        data.submit()
        return
      return
    progress: (e, data) ->
      progress = parseInt(data.loaded / data.total * 100, 10)
      percentage = progress.toString() + '%'
      console.log(percentage) # Debug only
      return
    done: (e, data) ->
      image =
        id: data.formData.key.match(/cache\/(.+)/)[1]
        storage: 'cache'
        metadata:
          size: data.files[0].size
          filename: data.files[0].name.match(/[^\/\\]+$/)[0]
          mime_type: data.files[0].type

      cached_image_url = "#{data.url}/#{data.formData.key}" # For preview
      console.log(image) # Debug only
      console.log(data.formData) # Debug only
      console.log(cached_image_url) # Debug only

      $upload = $(elem)
      $($upload.attr('data-dest-selector')).val(JSON.stringify(image)) # Save image data
      $($upload.attr('data-preview-selector')).
        css('background-image', "url('#{cached_image_url}')") # Show cached image
      return
# config/routes.rb
Rails.application.routes.draw do
  # ...
  mount ImageUploader::UploadEndpoint => '/images'
end

Build signed apk for release

Doсs for setting up

Build release version

cd android && ./gradlew assembleRelease
# Output file: android/app/build/outputs/apk/app-release.apk
# cd .. && cd android/app/build/outputs/apk

Build release version for test on the android emulator

react-native run-android --variant=release

Chewy

toptal/chewy

Examples

# Model index 
class SuppliesIndex < Chewy::Index
  settings analysis: {
    analyzer: {
      lowercase: {
        tokenizer: 'standard',
        filter: ['lowercase']
      }
    },
  }

  define_type Supply do
    field :supplier_id, type: 'integer', index: :not_analyzed
    field :category_id, type: 'integer', index: :not_analyzed
    field :name, type: 'text', analyzer: :lowercase
    field :supplier_sku, type: 'text', analyzer: :lowercase
    field :manufacturer_sku, type: 'text', analyzer: :lowercase

    field :manufacturer,
      type: 'text',
      analyzer: :lowercase,
      fields: {
        raw: {
          type: 'keyword',
          index: :not_analyzed,
        }
      }

    field :price,
      type: 'float',
      value: ->(v) { v.prices.first&.price.to_f }
  end
end
# Queries
class ElasticSupply
  SEARCHABLE_FIELDS = %w(
    manufacturer
    manufacturer_sku
    name
    supplier_sku
  )

  # Return Supply filter with numbers of supplies.
  #
  # @example
  #   ElasticSupply.filter()
  #   or
  #   ElasticSupply.filter(supplier_id: 1)
  #
  def self.filter(supplier_id: nil)
    matches = []
    matches << { term: { supplier_id: supplier_id } } unless supplier_id.blank?
    SuppliesIndex.query({ bool: { must: matches } })
      .aggs({
        category: { terms: { field: 'category_id' } },
        manufacturer: { terms: { field: 'manufacturer.raw' } },
      })
      .limit(0)
      .aggs
  end

  # Find Supply by search query with pagination.
  #
  # @example
  #   ElasticSupply.search(query: '*foo*', supplier_id: 1, page: 1, per_page: 1)
  #   or
  #   ElasticSupply.search(query: '*foo*')
  #
  # @param query [String] - 'foo', 'foo*', '*foo*'
  # @param supplier_id [Integer] additional filter by supplier_id (optional)
  # @param page [Integer]
  # @param per_page [Integer]
  #
  # @return [Array<Supply>]
  def self.search(query:, supplier_id: nil, category_ids: nil, manufacturers: nil, page: 1, per_page: 20)
    ElasticSupply
      .full_search_raw(
        query: query,
        supplier_id: supplier_id,
        category_ids: category_ids,
        manufacturers: manufacturers,
      )
      .paginate(page: page, per_page: per_page)
      .load(scope: ->{ includes(:prices, :office_supplies) })
      .to_a
  end

  # Find total count items in the index by query.
  #
  # @example
  #   ElasticSupply.total_count(query: '*foo*')
  #   or
  #   ElasticSupply.total_count(query: '**', supplier_id: 1, manufacturers: ['KEYSTONE DENTAL'])
  #
  # @param query [String] - 'foo', 'foo*', '*foo*'
  # @param supplier_id [Integer] additional filter by supplier_id (optional)
  #
  # @return [Integer]
  def self.total_count(query:, supplier_id: nil, category_ids: nil, manufacturers: nil)
    ElasticSupply
      .full_search_raw(
        query: query,
        supplier_id: supplier_id,
        category_ids: category_ids,
        manufacturers: manufacturers,
      )
      .total_count
  end

  # Search by query in all fields.
  #
  # @param query [String] - 'foo', 'foo*', '*foo*'
  # @param supplier_id [Integer] additional filter by supplier_id
  #
  # @return [SuppliesIndex::Query]
  def self.full_search_raw(query:, supplier_id:, category_ids:, manufacturers:)
    matches = [{ query_string: { query: query } }]
    matches << { term: { supplier_id: supplier_id } } unless supplier_id.blank?

    if category_ids.present?
      categories_query = category_ids.map { |v| { match: { category_id: v } } }
      matches << { bool: { should: categories_query } }
    end

    if manufacturers.present?
      manufacturers_query = manufacturers.map do |v|
        { match: { 'manufacturer.raw': v } }
      end
      matches << { bool: { should: manufacturers_query } }
    end

    SuppliesIndex.query({ bool: { must: matches } })
  end

  # Search by query as prefix in all fields.
  #
  # @param query [String] the '*' is unnecessary: 'foo' is equivalent to the 'foo*'
  # @param supplier_id [Integer] additional filter by supplier_id
  #
  # @return [SuppliesIndex::Query]
  def self.prefix_search_raw(query:, supplier_id:)
    matches = SEARCHABLE_FIELDS.map do |field|
      { 'match_phrase_prefix' => { field => query } }
    end
    search = SuppliesIndex.query({ bool: { should: matches } })
    return search if supplier_id.blank?

    search.query(term: { supplier_id: supplier_id })
  end
end

Creating Windows bootable USB in MacOS

Step 1

Download iso from https://www.microsoft.com/en-us/software-download/

Step 2

Insert USB stick an run diskutil list

$ diskutil list

/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:                        EFI ⁨EFI⁩                     314.6 MB   disk0s1
   2:                 Apple_APFS ⁨Container disk1⁩         250.7 GB   disk0s2

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +250.7 GB   disk1
                                 Physical Store disk0s2
   1:                APFS Volume ⁨Macintosh HD - Data⁩     124.0 GB   disk1s1
   2:                APFS Volume ⁨Preboot⁩                 314.7 MB   disk1s2
   3:                APFS Volume ⁨Recovery⁩                1.1 GB     disk1s3
   4:                APFS Volume ⁨VM⁩                      4.3 GB     disk1s4
   5:                APFS Volume ⁨Macintosh HD⁩            15.8 GB    disk1s5
   6:              APFS Snapshot ⁨com.apple.os.update-...⁩ 15.8 GB    disk1s5s1

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *31.0 GB    disk2
   1:             Windows_FAT_32 ⁨KINGSTON⁩                31.0 GB    disk2s1

Chances are, your USB stick has a PC standard FAT16/FAT32 filesytem, and will be mounted automatically. Let’s check:

$ df -h | grep disk2

/dev/disk2s1     29Gi  2.0Mi   29Gi     1%       0          0  100%   /Volumes/KINGSTON

Step 3

This single command will erase the USB stick, make it bootable by adding a Master Boot Record (MBR) and create a Windows-friendly filesystem (FAT) on it:

$ diskutil eraseDisk MS-DOS "WIN81" MBR disk2

Started erase on disk2
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk2s1 as MS-DOS (FAT) with name WIN81
512 bytes per physical sector
/dev/rdisk2s1: 60523616 sectors in 1891363 FAT32 clusters (16384 bytes/cluster)
bps=512 spc=32 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=2048 drv=0x80 bsec=60553216 bspf=14777 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk2

Step 4

Mount the iso image

$ hdiutil mount ~/Downloads/Win8.1_Russian_x64.iso

/dev/disk3          	                               	/Volumes/IR5_CCSA_X64FRE_RU-RU_DV9

Step 5

Copy Windows files onto USB stick

$ cd /Volumes/IR5_CCSA_X64FRE_RU-RU_DV9
$ sudo cp -r . /Volumes/WIN81/

password:

The copy will take good 10-15 min.

There should be no errors returned.

Done

Boot USB stick on your PC.

Keeping a fork up to date

  1. Clone your fork
git clone [email protected]:YOUR-USERNAME/YOUR-FORKED-REPO.git
  1. Add remote from original repository in your forked repository
cd into/cloned/fork-repo
git remote add upstream git://github.com/ORIGINAL-DEV-USERNAME/REPO-YOU-FORKED-FROM.git
  1. Updating your fork from original repo to keep up with their changes
git fetch upstream
git pull upstream master

References with alias name

Model A

class Message < ApplicationRecord
  belongs_to :user
end

Model B

class Conversation < ApplicationRecord
  belongs_to :message
  belongs_to :recipient, class_name: User.name
end

Migration

New table

class CreateConversations < ActiveRecord::Migration[5.0]
  def change
    create_table :conversations do |t|
      t.references :message, foreign_key: true
      t.references :recipient, references: :user
      # ...
    end

    add_foreign_key :conversations, :users, column: :recipient_id
  end
end

Existing table

class AddRecipientToConversations < ActiveRecord::Migration[5.0]
  def change
    add_reference :conversations, :recipient, references: :user, index: true
  end
end

Factory bot

FactoryGirl.define do
  factory :conversation do
    ...
    trait :with_recipient do
      recipient { create(:user) }
    end
end

Elasticsearch Index errors: "blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"

Error

Index errors:
   {"type"=>"cluster_block_exception", "reason"=>"blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"}
     on 1 documents: ["YOUR_INDEX_NAME"]

Solution

curl -H 'Content-Type: application/json' -X 'PUT' http://localhost:9200/_settings -d "{\"index\": { \"blocks\": { \"read_only_allow_delete\": \"false\" } } }"

# => {"acknowledged":true}
curl -H 'Content-Type: application/json' -X 'PUT' http://localhost:9200/YOUR_INDEX_NAME/_settings -d "{\"index\": { \"blocks\": { \"read_only_allow_delete\": \"false\" } } }"

# => {"acknowledged":true}

Source: https://discuss.elastic.co/t/forbidden-12-index-read-only-allow-delete-api/110282/4

P.S. To get a list of indexes, see #33

Install Dropbox Client as a Service on Ubuntu 14.04

Install Dropbox Client

cd ~
curl -Lo dropbox-linux-x86_64.tar.gz https://www.dropbox.com/download?plat=lnx.x86_64
sudo mkdir -p /opt/dropbox
sudo tar xzfv dropbox-linux-x86_64.tar.gz --strip 1 -C /opt/dropbox

Link Dropbox Client

/opt/dropbox/dropboxd

Visit the URL in the output (highlighted in the above example) in a web browser on your local computer.

Set Up Service Script

cd ~
sudo curl -o /etc/init.d/dropbox https://gist.githubusercontent.com/thisismitch/d0133d91452585ae2adc/raw/699e7909bdae922201b8069fde3011bbf2062048/dropbox
sudo chmod +x /etc/init.d/dropbox
sudo vim /etc/default/dropbox

Add a line that specifies that DROPBOX_USERS is equal to your system username. For example, if your username is "sammy", it should look like this:

DROPBOX_USERS="sammy"

Now Dropbox is ready to be started as a service. Run this command to start it:

sudo service dropbox start

Then run this command to configure the service to start when your server boots:

sudo update-rc.d dropbox defaults

Source https://www.digitalocean.com/community/tutorials/how-to-install-dropbox-client-as-a-service-on-ubuntu-14-04

Service

Service

# lib/service.rb
module Service
  extend ActiveSupport::Concern

  included do
    def self.call(*args)
      new(*args).call
    end
  end
end

With Attributes

# Gemfile
gem 'virtus'

# lib/attributable_service.rb
module AttributableService
  extend ActiveSupport::Concern

  included do
    include Service
    include Virtus.model
  end
end

Using

module Users
  class Create
    include AttributableService

    attribute :params, Hash
    attribute :password, String

    def call
      user.password = password
      user.save

      user
    end

  private

    def user
      @user ||= User.new(params)
    end
end
Users::Create.call(params: params, password: 'asdf')

Build unsigned apk for device without the development server

Step 1

$ react-native bundle --dev false --platform android --entry-file index.android.js --bundle-output ./android/app/build/intermediates/assets/debug/index.android.bundle --assets-dest ./android/app/build/intermediates/res/merged/debug

Step 2

$ cd android && ./gradlew assembleDebug && cd ..

Step 3

$ cd android/app/build/outputs/apk
# app-debug.apk

Ignore some specs on CI

# spec/spec_helper
RSpec.configure do |config|
  # ...
  config.filter_run_excluding tag: :not_for_ci if ENV['CI']
end
# spec/controllers/foos_controller_spec.rb
describe FoosController, tag: :not_for_ci do
  render_views

  describe '#index' do
    # ...
  end
end

If the environment CI is specified, all specs with tag: :not_for_ci will be ignored.

CI=true rspec spec/controllers/foos_controller_spec.rb

Array values in the parameter to `Gem.paths=` are deprecated

Issue

Array values in the parameter to `Gem.paths=` are deprecated.
Please use a String or nil.
An Array ({"GEM_PATH"=>["/Users/slash/.rvm/gems/ruby-2.3.1", "/Users/slash/.rvm/gems/ruby-2.3.1@global"]}) was passed in from bin/rails:3:in `load'
Rails 4.2.10

Solution

bundle update spring && bundle exec spring binstub --remove --all && bundle exec spring binstub --all

third-party: 'config.h' file not found

Fix XCode build error:

  1. In the Terminal, navigate to the react-native/third-party/glog folder inside node_modules, cd node_modules/react-native/third-party/glog-0.3.4
  2. Once actively in this folder, run ../../scripts/ios-configure-glog.sh
  3. Glog is configured and the required config.h header file is created for Xcode to find

Source: facebook/react-native#14382 (comment)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.