blackchestnut / blackchestnut.github.io Goto Github PK
View Code? Open in Web Editor NEWDeveloper notes about Ruby on Rails, React Native, PostgreSQL, etc.
Home Page: https://kalinichev.net
Developer notes about Ruby on Rails, React Native, PostgreSQL, etc.
Home Page: https://kalinichev.net
adb shell input text 'Bla bla bla'
Example for "Ruby on Rails" projects:
wc -l app/**/*.{rb,slim,erb,sass,js} lib/**/*.rb config/**/*.rb spec/**/*.rb | grep total
# 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
# 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
# turn off
old_logger = ActiveRecord::Base.logger
ActiveRecord::Base.logger = nil
# your code...
# turn on
ActiveRecord::Base.logger = old_logger
unlink node_modules/react-native/third-party/glog-0.3.4/test-driver
Download iso from https://www.microsoft.com/en-us/software-download/
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
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
Mount the iso image
$ hdiutil mount ~/Downloads/Win8.1_Russian_x64.iso
/dev/disk3 /Volumes/IR5_CCSA_X64FRE_RU-RU_DV9
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.
Boot USB stick on your PC.
# 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'
Fix XCode build error:
react-native/third-party/glog
folder inside node_modules
, cd node_modules/react-native/third-party/glog-0.3.4
../../scripts/ios-configure-glog.sh
config.h
header file is created for Xcode to findError
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
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
git clone [email protected]:YOUR-USERNAME/YOUR-FORKED-REPO.git
cd into/cloned/fork-repo
git remote add upstream git://github.com/ORIGINAL-DEV-USERNAME/REPO-YOU-FORKED-FROM.git
git fetch upstream
git pull upstream master
brew upgrade macvim
cd ~/.vim/plugged/command-t/ruby/command-t/ext/command-t
/usr/local/opt/ruby/bin/ruby extconf.rb
make
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
$ 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
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
Simple authentication with password
gem 'bcrypt'
gem 'ulid'
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
# 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
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
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
# config/routes.rb
Rails.application.routes.draw do
resources :users, only: [:new, :create]
resource :sessions, only: [:new, :create, :destroy]
scope '(:token)' do
# ...
end
end
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
File Attachment Toolkit for Ruby applications - shrinerb.com
https://github.com/janko-m/shrine
# Gemfile
gem 'aws-sdk'
gem 'shrine'
# 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'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BUCKET/*"
}
]
}
<?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>
# 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=..."
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.
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;
}
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) }
See Shrine direct uploads to s3
# 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
# 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
# config/routes.rb
Rails.application.routes.draw do
# ...
resources :items do
resource :photo, only: [:create]
end
end
# 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);
})
}
});
});
# 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'
openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr
cat DOMAIN.crt DOMAIN.ca-bundle >> cert_chain.crt
myserver.key
and cert_chain.crt
nginx settingsclass Message < ApplicationRecord
belongs_to :user
end
class Conversation < ApplicationRecord
belongs_to :message
belongs_to :recipient, class_name: User.name
end
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
class AddRecipientToConversations < ActiveRecord::Migration[5.0]
def change
add_reference :conversations, :recipient, references: :user, index: true
end
end
FactoryGirl.define do
factory :conversation do
...
trait :with_recipient do
recipient { create(:user) }
end
end
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
}
}
}
# lib/service.rb
module Service
extend ActiveSupport::Concern
included do
def self.call(*args)
new(*args).call
end
end
end
# Gemfile
gem 'virtus'
# lib/attributable_service.rb
module AttributableService
extend ActiveSupport::Concern
included do
include Service
include Virtus.model
end
end
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')
# 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
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...
# 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
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
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
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
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
https://help.github.com/en/articles/checking-for-existing-ssh-keys
https://help.github.com/en/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account
https://help.github.com/en/articles/checking-for-existing-gpg-keys
xcode-select --install
/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)
[done]
brew install rbenv
(ignore - if you already have it in Brewfilerbenv init
rbenv install -l
See - https://github.com/rbenv/rbenv#installing-ruby-versionsrbenv install YOUR_VERSION
gem env home
/home/your_user/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0
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
Via console:
yes | sudo sdkmanager --licenses
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
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
# app/models/game.rb
class Game < ApplicationRecord
enum kind: { training: 0, friendly_match: 1 }
end
// app/views/games/new.html.slim
label Kind
= f.select :kind, Game.kinds.keys.map { |key| [key.humanize, key] })
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] }
$ 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
select schemaname as table_schema,
relname as table_name,
pg_size_pretty(pg_relation_size(relid)) as data_size
from pg_catalog.pg_statio_user_tables
order by pg_relation_size(relid) desc;
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"
Time.use_zone('Eastern Time (US & Canada)') { Time.zone.parse('2020-07-21 14:49') }.in_time_zone
# => Tue, 21 Jul 2020 21:49:00 MSK +03:00
Shrine - Direct Uploads to S3
Demo Rails Project
jquery.fileupload.js
jquery.ui.widget
# 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
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
/opt/dropbox/dropboxd
Visit the URL in the output (highlighted in the above example) in a web browser on your local computer.
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
$ 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;
#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
ps -ef | grep PROCESS_NAME | awk '{print $2}' | xargs sudo kill -9
Example for phantomjs
:
ps -ef | grep phantomjs | awk '{print $2}' | xargs sudo kill -9
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"
}
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
curl -X 'DELETE' http://localhost:9200/index_name
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.