- Генерируем новый ssh ключ (при этом указать имя не id_rsa, а например work)
- Создаем файл конфигурации ~/.ssh/config и добавляем в него:
Host work HostName bitbucket.org User git PreferredAuthentications publickey IdentityFile ~/.ssh/work
- Клонируем или добавляем в remote с использованием домена work вместо bitbucket.org. Например:
git clone git@work:fiftin/winformspopupalerts.git
суббота, 24 декабря 2016 г.
Bitbucket: использование нескольких ssh ключей на одном компе
суббота, 17 декабря 2016 г.
Ubuntu: как перопределить кнопку на клавиатуре
Вначале я выковырял кнопку радом с Enter'ом потому что постоянно тыкал в нее:
Стало лучше - тепепь я не втыкал / вместо Enter, но и Enter тоже. По-этому я решил поискать как переопределить кнопку
- Устанавливать ничего не нужно.
- В терминале запускаем утилиту xev и жмем кнопку, которую хотим переопределить. В выводе программы ищем "Keycode" и запоминаем. В моем случае это 51.
- Выполняем в терминале следующую команду:
xmodmap -e "keycode 51 = Return"
Список символов Xmodmap
четверг, 7 апреля 2016 г.
Где хранить видео и фотографии, если их много
Я не люблю удалять фотографии. Потому что сложно оценить насколько та или иная фотография окажется интересной через 10 лет. По-этому у меня очень много фотографий.
И я боюсь их потерять. И чем больше фотографий становится тем больше я боюсь. Я использовал платный аккаунт на Flickr, покупал пространство на Google Drive и OneDrive. И везде меня одолевала ощущение что мои фотографии может кто-то увидеть кроме меня. Почему? Да потому что Flickr создан чтобы делиться фотографиями, Google Drive и OneDrive использует общий аккаунт Google и Microsoft под которым я залогинен и на работе и на телефоне, возможно где-то еще. А я хочу чтобы мои фотографии были надежно спрятаны, как бумажные фотографии в ящике. А не чтобы они светились у меня и у того кто стоит рядом перед глазами когда я захожу в аккаунт Google или Microsoft. Я не хочу чтобы Google делал коллаж из моих фотографий. Чтобы Windows делал из них слайд шоу на начальном экране.
По-этому у меня не получалось долго хранить фотографии в облачных хранилищах. В конце концов я удалял фотографии и хранил их только у себя на компьютере.
Возможно это паранойя, но я не могу от нее избавиться.
А потом я узнал про Amazon Glacier. Я понял, это то что я так долго искал: нет web-интерфейса, нет кнопки Поделиться. Что там, чтобы скачать фото или увидеть список файлов нужно ждать 4 часа. Amazon выстроил кучу преград для использования этого сервиса обычными пользователями. Для кого-то это покажется ужасно, но для меня это было то что нужно.
И всего $0.004 за Гб. Это дешевле любого облачного хранилища которое я знаю (Google Photos и Flickr не в счет). Вы можете сказать что Google Drive стоит всего $9.99 за 1Тб, а на Glacier это будет $7, не на много дешевле (а с учётом платного трафика еще и дороже). Но если построить график, то преимущество Glacier становится более очевидным (горизонтальная шкала взята по экспоненте для наглядности).
Этот график вызывет ощущение что Google нас где-то пывается обмануть.
А этот график говорит, что если данные занимают больше 15Гб, намного выгоднее хранить их в Amazon Glacier. Если усреднить цену 1Гб для Google Drive, то получится около 4 центов за Гб против 0.7 цента на Amazon Glacier.
Итак, узнав про Amazon Glacier я начал искать программу-клиент для него, так как сервис предоставляет только API. Из существующих я нашел только Fast Glacier с ограниченной бесплатной версией. Классная программа. Но не то что мне было нужно.
Тогда я начал писать свой клиент.
Я задумывал программу которая сможет синхронизировать фотографии на различных хранилищах (я остановился на Google Drive и локальном диске) и бекапить их в Amazon Glacier.
Итак:
- Я хотел иметь возможность выбрать интересные фотографии на диске и отправить их на Google Drive чтобы они были под рукой когда я захочу их пересмотреть или поделиться с кем-нибудь.
- Также я хотел чтобы фотографии оставались у меня на компьютере.
- Чтобы все это синхронизировалось с Amazon Glacier в том числе фотографии с телефона сохраненные на Google Drive.
- И чтобы все это делалось из одной программы.
Я сделал такую программу (ну почти такую) и назвал её Oblqo. Исходники программы доступны на github.
Сейчас её использую наверное только я. По ходу использования я добавляю в нее фичи в которых у меня появляется необходимость: поддержка нескольких Google аккаунтов, сохранение уменьшенной копии фотографии и др.
Надеюсь что статья будет полезна и возможно подтолкнет кого-то к использованию Amazon Glacier который на мой взгляд необоснованно обходят стороной.
четверг, 23 июля 2015 г.
Изучаем Devise 2: Аутентификация по номеру телефна
1) Вначале добавим колонку phone_number в таблицу users с помощью миграции:
rails g migration AddPhoneNumberToUsers phone_number:string:uniq:index
rake db:migrate2) Внесем следующие изменения в модель (класс User):
- Добавим опцию authentication_keys: [:login] в вызов метода devise:
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, authentication_keys: [:login] - Добавим поле login:
def login=(login) @login = login end def login @login || self.phone_number || self.email end -
Перегрузим метод отвечающий за поиск модели в базе данных:
def self.find_for_database_authentication(warden_conditions) conditions = warden_conditions.dup if login = conditions.delete(:login) where(conditions.to_h).where(["lower(phone_number) = :value OR lower(email) = :value", { value: login.downcase }]).first else where(conditions.to_h).first end end
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:phone_number, :email, :password, :password_confirmation) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :phone_number, :email, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:phone_number, :email, :password, :password_confirmation, :current_password) }
end
Этот код указыает Devise какие поля формы следует сохранить в моделе. Для понимания этот код был бы аналогичен такому коду в контроллере SessionsController:
def sign_in
permit_params = params.required(:user).permit(:phone_number,
:email, :password, :password_confirmation)
@user.attributes=permit_params
end
5) Далее нужно внести изменения в представления. По-умолчанию представления берутся из gem'а. Приведенная ниже команда генерирует представляения в вашем проекте. Они перегружают представления из gem'а:
rails generate devise:viewsВ форму регистрации (представление views/devise/registrations/new.html.erb) добавляем поле phone_number. Также вы можете добавить поле phone_number в представление редактирования данных пользователя views/devise/registrations/edit.html.erb. В форме аутентификации(представление views/devise/sessions/new.html.erb) заменяем поле email на поле login.
6) Не уверен обязательно ли это, но в config/initializers/devise.rb
config.authentication_keys = [ :login ]7) Перезапускаем сервер, пробуем.
воскресенье, 19 июля 2015 г.
Ruby on Rails: Настройка отправки сообщений через GMail
config.action_mailer.delivery_method :smtp
config.action_mailer.smtp_settings = {
openssl_verify_mode: 'none',
tls: false,
enable_starttls_auto: true,
address: 'smtp.gmail.com',
domain: 'gmail.com',
port: 587,
authentication: 'login',
user_name: 'login@gmail.com',
password: 'password'
}
Перезапустить сервер. Если при попытке отправить сообщение возникнет ошибка:
Net::SMTPAuthenticationError in Devise::RegistrationsController#create
534-5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=...
def check_auth_response(res)
unless res.success?
raise SMTPAuthenticationError, res.message
end
end
то необходимо изменить натройки безопасности аккаунта гугл. Как, написано здесь.
HTML: Перенос длинных слов
Я нагуглил следующие способы решения проблемы с длинными словами, которые ломают верстку:
1) http://slopjong.de/2013/06/18/how-to-word-wrap-text-in-html/
div {
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Firefox */
white-space: -pre-wrap;
word-wrap: break-word;
}2) Использовать специальные символы для разделения длинных слов на более короткие. Вот эти символы: ­ ​ <wbr>
Пример спользования в Ruby on Rails https://gist.github.com/fiftin/004b70ac0fc0a72738f8.
Каждый из этих сиволов имеет свои недостатки:
- ​ - представляют собой невидимый пробел который разделяет слово на отдельные слова. По-этому при двойном щелчке мыши по слову, выделяется не полностью слово, а только его часть
- ­ ​ - копируются вместе с тектом хоть и невидимы для пользователя. Проблема может возникнуть, если пользовтель пытается использовать скопированный текст (содержащий один из этих символов) для поиска.
- <wbr> - не имеет описанных выше недостатков, но он не поддерживается Internet Explorer'ом.
div {
width: 100px;
word-wrap: break-word;
}
среда, 15 июля 2015 г.
Изучаем Devise 1: Настройка подтверждения
После установки мы хотим добавить подтверждение учетной записи по email. Для этого служит модуль confirmable.
Настройка подтверждения
Devise сгенерировал нам такой класс модели:class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
endВ ней перечислены задействованные модули, confirmable среди них нет. Добавляем:
class User < ActiveRecord::BaseТеперь нужно добавил необходимые поля в таблицу users. Для этого создадим миграцию:
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
end
rails g migration add_confirmable_to_usersПишем код миграции:
class AddConfirmableToUsers < ActiveRecord::MigrationПрименяем миграцию:
def change
add_column :users, :confirmation_token, :string
add_column :users, :confirmed_at, :datetime
add_column :users, :confirmation_sent_at, :datetime
# add_column :users, :unconfirmed_email, :string # Only if using reconfirmable
add_index :users, :confirmation_token, unique: true
# User.reset_column_information # Need for some types of updates, but not for update_all.
# To avoid a short time window between running the migration and updating all existing
# users as confirmed, do the following
end
def down
remove_columns :users, :confirmation_token, :confirmed_at, :confirmation_sent_at
# remove_columns :users, :unconfirmed_email # Only if using reconfirmable
end
end
rake db:migrateТакже нам нужно добавить миграцию для добавления поля unconfirmed_email:
class AddUnconfirmedEmailToUsers < ActiveRecord::Migration
def change
add_column :users, :unconfirmed_email, :string
end
end
Всё. Ссылка на исходники примера.

