├── swift ├── Swift.md ├── Swift - Getting Started.md └── Swift - Router.md ├── capistrano.md ├── images ├── mail-dns-records.png ├── s3-iam-user-policy.png ├── xcode │ ├── tabbar_segues.png │ ├── unstyled │ │ ├── setup_pods.png │ │ ├── screenhero_login.png │ │ └── sreenhero_signup.png │ ├── create_a_new_xcode_project.png │ ├── create_a_new_project_with_options.png │ └── create_a_new_single_view_application.png ├── s3-iam-create-new-users.png ├── keychain │ ├── allow_access_token.png │ └── allow_access_secret.png └── setting-up-a-dev-machine │ ├── macvim-find.png │ └── macvim-new-tab.png ├── unformatted ├── swift2.md ├── healthkit.md ├── docker.md ├── agile.md ├── bash.md ├── setting-up-a-git-server.md ├── phoenix.md ├── shopify_application_proxy_sessions.md ├── swift.md ├── resque.md ├── security_and_oauth_links.md ├── shopify-theme-development.md ├── social_sharing.md ├── elixir-phoenix-dokku.md ├── rails_security.md ├── shopify_forms.md ├── sidekiq.md ├── dokku.md └── doorkeeper.md ├── gems.md ├── chef_default_attributes.md ├── heroku.md ├── xcode_and_ios.md ├── rails_development_environment.md ├── Untitled.md ├── Elixir.md ├── digital_ocean.md ├── shopify_api_interaction.md ├── README.md ├── vagrant.md ├── Elixir Deployment.md ├── mobile_app_and_rails_communications.md ├── checkinstall.md ├── unformatted.md ├── advanced_bootstrapping.md ├── creating-an-inverted-mask-layer-osx.md ├── upload-direct-to-s3-with-processing.md ├── scripts └── sshd_config ├── javascript_popups.md ├── git.md ├── shopify_embedded_app.md ├── keychain.md ├── ssl.md ├── setting_up_a_new_dev_machine.md ├── uploading.md └── asus_wl520gu.md /swift/Swift.md: -------------------------------------------------------------------------------- 1 | # Swift 2 | 3 | Getting Started 4 | -------------------------------------------------------------------------------- /capistrano.md: -------------------------------------------------------------------------------- 1 | # Deploying with Capistrano 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/mail-dns-records.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/mail-dns-records.png -------------------------------------------------------------------------------- /images/s3-iam-user-policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/s3-iam-user-policy.png -------------------------------------------------------------------------------- /images/xcode/tabbar_segues.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/xcode/tabbar_segues.png -------------------------------------------------------------------------------- /images/s3-iam-create-new-users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/s3-iam-create-new-users.png -------------------------------------------------------------------------------- /images/keychain/allow_access_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/keychain/allow_access_token.png -------------------------------------------------------------------------------- /images/xcode/unstyled/setup_pods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/xcode/unstyled/setup_pods.png -------------------------------------------------------------------------------- /unformatted/swift2.md: -------------------------------------------------------------------------------- 1 | # Swift 2 | 3 | https://www.raywenderlich.com/113388/storyboards-tutorial-in-ios-9-part-1 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/keychain/allow_access_secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/keychain/allow_access_secret.png -------------------------------------------------------------------------------- /images/xcode/create_a_new_xcode_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/xcode/create_a_new_xcode_project.png -------------------------------------------------------------------------------- /images/xcode/unstyled/screenhero_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/xcode/unstyled/screenhero_login.png -------------------------------------------------------------------------------- /images/xcode/unstyled/sreenhero_signup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/xcode/unstyled/sreenhero_signup.png -------------------------------------------------------------------------------- /images/setting-up-a-dev-machine/macvim-find.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/setting-up-a-dev-machine/macvim-find.png -------------------------------------------------------------------------------- /images/setting-up-a-dev-machine/macvim-new-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/setting-up-a-dev-machine/macvim-new-tab.png -------------------------------------------------------------------------------- /images/xcode/create_a_new_project_with_options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/xcode/create_a_new_project_with_options.png -------------------------------------------------------------------------------- /images/xcode/create_a_new_single_view_application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffrafter/howto/HEAD/images/xcode/create_a_new_single_view_application.png -------------------------------------------------------------------------------- /unformatted/healthkit.md: -------------------------------------------------------------------------------- 1 | # HealthKit 2 | 3 | * [http://www.shinobicontrols.com/blog/posts/2014/08/04/ios8-day-by-day-day-12-healthkit](http://www.shinobicontrols.com/blog/posts/2014/08/04/ios8-day-by-day-day-12-healthkit) -------------------------------------------------------------------------------- /gems.md: -------------------------------------------------------------------------------- 1 | # Gems 2 | 3 | When creating a gem it is useful to start with a template from `bundler`: 4 | 5 | bundle gem YOUR_GEM_NAME 6 | 7 | This will create a folder and stub out the `gemspec` and version information. 8 | 9 | -------------------------------------------------------------------------------- /unformatted/docker.md: -------------------------------------------------------------------------------- 1 | Docker and CoreOS 2 | 3 | https://coreos.com/docs/launching-containers/building/getting-started-with-docker/ 4 | https://www.digitalocean.com/community/tutorials/how-to-set-up-a-coreos-cluster-on-digitalocean 5 | https://coreos.com/docs/distributed-configuration/etcd-security/ -------------------------------------------------------------------------------- /unformatted/agile.md: -------------------------------------------------------------------------------- 1 | # Agile 2 | 3 | * IPM 4 | * Daily Standup 5 | * Weekly individual checkins 6 | * Retro every other week 7 | - Spend five minutes making cards 8 | - Spend five minutes voting 9 | - :), :|, :(, -> 10 | * Demo! 11 | 12 | ## How do you handle this 13 | 14 | * Long term planning? 15 | * Reactions and bugs? 16 | -------------------------------------------------------------------------------- /chef_default_attributes.md: -------------------------------------------------------------------------------- 1 | * __Default attributes__: this loads the information from the default data bag and merges the values into our current node. 2 | 3 | 4 | ## Default attributes 5 | # 6 | default_data_bag = data_bag_item("default", "sample") 7 | node.default_attrs = Chef::Mixin::DeepMerge.merge(node.default_attrs, default_data_bag.to_hash) -------------------------------------------------------------------------------- /heroku.md: -------------------------------------------------------------------------------- 1 | # Heroku 2 | 3 | ``` 4 | git remote add heroku HEROKU_REPO_URL 5 | git push heroku master 6 | heroku login 7 | heroku pg:reset --app APP_NAME DB_NAME 8 | heroku run --app APP_NAME rake db:migrate 9 | heroku restart 10 | heroku run rails console 11 | heroku config:set `cat .env` 12 | 13 | ``` 14 | 15 | Upgrading the database 16 | ---------------------- 17 | https://devcenter.heroku.com/articles/upgrading-heroku-postgres-databases#upgrade-with-pgbackups-transfer-default -------------------------------------------------------------------------------- /xcode_and_ios.md: -------------------------------------------------------------------------------- 1 | # Xcode and iOS 2 | 3 | 4 | Create a new Xcode Project 5 | 6 | ![Create a new XCode Project](./images/xcode/create_a_new_xcode_project.png) 7 | 8 | When you create the project choose a _Single View Application_: 9 | 10 | ![Choose a Single View](./images/xcode/create_a_new_single_view_application.png) 11 | 12 | Setup the project options: 13 | 14 | ![Setup project options](./images/xcode/create_a_new_project_with_options.png) 15 | 16 | 17 | ## Follow the Parse quick start guide 18 | 19 | [https://www.parse.com/apps/quickstart#parse_data/mobile/ios/native/existing](https://www.parse.com/apps/quickstart#parse_data/mobile/ios/native/existing) 20 | 21 | 22 | -------------------------------------------------------------------------------- /rails_development_environment.md: -------------------------------------------------------------------------------- 1 | # Rails development environment 2 | 3 | 4 | -- Lots to do here 5 | 6 | # Update rbenv to get the latest ruby 7 | 8 | You might have installed rbenv/ruby-build in one of three ways (on OSX): 9 | 10 | As a git repo (old method): 11 | 12 | ``` 13 | cd ~/.rbenv 14 | git pull 15 | rbenv install -l 16 | rbenv install 2.1.1 17 | ``` 18 | 19 | Installed via Homebrew: 20 | 21 | ``` 22 | brew update 23 | brew upgrade rbenv ruby-build 24 | rbenv install -l 25 | rbenv install 2.1.1 26 | ``` 27 | 28 | Installed with ruby-build as a plugin (currently the recommended way): 29 | 30 | ``` 31 | cd ~/.rbenv/plugins/ruby-build 32 | git pull 33 | rbenv install -l 34 | rbenv install 2.1.1 35 | ``` 36 | -------------------------------------------------------------------------------- /unformatted/bash.md: -------------------------------------------------------------------------------- 1 | # Bash 2 | 3 | [http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/?utm_content=bufferbb394&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer](http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/?utm_content=bufferbb394&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer) 4 | 5 | * Try to keep globals to minimum 6 | * UPPER_CASE naming 7 | * `readonly` declaration 8 | * Use globals to replace cryptic `$0`, `$1`, etc. 9 | * Globals I always use in my programs: 10 | 11 | 12 | Additionally: 13 | 14 | * Always quote all vars (use `"$var"` instead of `$var`) 15 | * Always use `set -e` on scripts to set error handling 16 | * Always use `-- -u` to require vars to be declared before using them -------------------------------------------------------------------------------- /Untitled.md: -------------------------------------------------------------------------------- 1 | 2 | App opens 3 | 4 | check if there is an access_token? 5 | 6 | post to /v1/numbers 7 | find_or_create_number 8 | cancel other confirmations sent to this phone number? 9 | create a confirmation 10 | send a text 11 | 12 | user gets the text and inputs code 13 | 14 | post to /v1/confirmations with number and code 15 | confirmation is confirmed 16 | find or create a user for the confirmed phone number 17 | access_token is created and returned and stored 18 | 19 | 20 | user has an access_token and is "logged in" 21 | 22 | adding contacts 23 | adding locations 24 | 25 | 26 | SecureRandom.hex(32) 27 | 28 | 29 | 30 | user 31 | number_id 32 | confirmation_id 33 | home_id 34 | locations 35 | contacts 36 | 37 | -------------------------------------------------------------------------------- /unformatted/setting-up-a-git-server.md: -------------------------------------------------------------------------------- 1 | 2 | # Setting up a git server 3 | 4 | See [http://gitolite.com/gitolite/gitolite.html#install](http://gitolite.com/gitolite/gitolite.html#install) 5 | 6 | You need git: 7 | 8 | apt-get install git 9 | 10 | Add a user (using `sudo` or as root): 11 | 12 | useradd -D -s /bin/bash 13 | useradd git 14 | usermod -a -G ssh-user git 15 | mkdir /home/git 16 | mkdir /home/git/.ssh 17 | chmod 700 /home/git/.ssh 18 | chown git:git /home/git -R 19 | 20 | Switch to the git user and install: 21 | 22 | su - git 23 | mkdir -p /home/git/bin 24 | git clone git://github.com/sitaramc/gitolite 25 | gitolite/install -ln /home/git/bin 26 | 27 | You'll need your public key to setup the administrator account. From your local you can run `cat ~/.ssh/id_rsa.pub | pbcopy`. Then on the server: 28 | 29 | touch YOURNAME.pub 30 | nano YOURNAME.pub 31 | gitolite setup -pk YOURNAME.pub 32 | 33 | You are setup. From your local: 34 | 35 | git clone git@YOURHOST:gitolite-admin 36 | 37 | Now you can add new keys and you can configure the repos in the conf. 38 | -------------------------------------------------------------------------------- /Elixir.md: -------------------------------------------------------------------------------- 1 | # Elixir 2 | 3 | ## Mocks 4 | 5 | ```elixir 6 | defmodule Textmewhen.V1.NumberControllerTest do 7 | use Textmewhen.ConnCase, async: false 8 | 9 | import Mock 10 | 11 | alias Textmewhen.Number 12 | 13 | @valid_attrs %{phone_number: "9519020972"} 14 | @invalid_attrs %{} 15 | 16 | setup %{conn: conn} do 17 | app = Repo.insert!(Textmewhen.OauthApplication.changeset(%Textmewhen.OauthApplication{}, %{name: "App", redirect_uri: "a://b", scopes: "all"})) 18 | 19 | conn = conn 20 | |> put_req_header("accept", "application/json") 21 | |> put_req_header("x-application-id", app.uid) 22 | 23 | {:ok, conn: conn} 24 | end 25 | 26 | test "creates and renders resource when data is valid", %{conn: conn} do 27 | with_mock ExTwilio.Message, [create: fn (_) -> :ok end ] do 28 | conn = post conn, v1_number_path(conn, :create), number: @valid_attrs 29 | assert json_response(conn, 201)["data"]["id"] 30 | assert Repo.get_by(Number, @valid_attrs) 31 | end 32 | end 33 | 34 | test "does not create resource and renders errors when data is invalid", %{conn: conn} do 35 | conn = post conn, v1_number_path(conn, :create), number: @invalid_attrs 36 | assert json_response(conn, 422)["errors"] != %{} 37 | end 38 | end 39 | 40 | ``` 41 | 42 | Genserver: 43 | https://blog.drewolson.org/understanding-gen-server/ 44 | -------------------------------------------------------------------------------- /unformatted/phoenix.md: -------------------------------------------------------------------------------- 1 | # Phoenix & Elixir 2 | 3 | ## Pre-reqs 4 | 5 | * Elixir 1.1.0 or greater 6 | * Hex 7 | * Postgres 8 | * Node version 5.3.0 or greater 9 | 10 | ``` ​​ 11 | ​​brew update 12 | brew install nodejs 13 | brew install postgres 14 | brew install elixir 15 | mix local.hex 16 | ``` 17 | 18 | ### Vim 19 | 20 | For vim support you can use: https://github.com/elixir-lang/vim-elixir. If you're using `vim-elixir` then you should remove the support for elixir in syntastic. 21 | 22 | You might want to add `_build` and `deps` to your custom ignore: 23 | 24 | `let g:ctrlp_custom_ignore = '\v[\/](node_modules|target|dist|tmp|log|_build|deps)|(\.(swp|ico|git|svn))$'` 25 | 26 | 27 | ## Install Phoenix 28 | 29 | Get the latest: 30 | 31 | ``` 32 | mix archive.install https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez 33 | ``` 34 | ​ 35 | ## Hello World 36 | 37 | ``` 38 | mix​​ ​​phoenix.new​​ ​​hello​ 39 | cd hello 40 | mix ecto.create 41 | mix ecto.migrate 42 | mix phoenix.server 43 | ``` 44 | 45 | > If you get the error **"\*\* (Mix) The database for Hello.Repo couldn't be created: FATAL (invalid_authorization_specification): role "postgres" does not exist"** then `createuser -s postgres` 46 | 47 | 48 | ## Run tests 49 | 50 | ``` 51 | mix test 52 | ``` 53 | 54 | # Questions 55 | 56 | * What is scrub_params 57 | * Why is :empty deprecated 58 | -------------------------------------------------------------------------------- /digital_ocean.md: -------------------------------------------------------------------------------- 1 | # Digital Ocean 2 | 3 | 1. Setup your digital ocean account 4 | 2. Add your ssh key 5 | 6 | Next get the gem 7 | 8 | gem install knife-digital_ocean 9 | 10 | Change your knife.rb: 11 | 12 | cookbook_path ["cookbooks", "site-cookbooks"] 13 | node_path "nodes" 14 | role_path "roles" 15 | environment_path "environments" 16 | data_bag_path "data_bags" 17 | 18 | encrypted_data_bag_secret ".chef/encrypted_data_bag_secret" 19 | 20 | knife[:secret_file] = ".chef/encrypted_data_bag_secret" 21 | knife[:berkshelf_path] = "cookbooks" 22 | knife[:bootstrap_user] = "sample" 23 | 24 | knife[:digital_ocean_client_id] = "#{ENV['DIGITAL_OCEAN_CLIENT_ID']}" 25 | knife[:digital_ocean_api_key] = "#{ENV['DIGITAL_OCEAN_API_ID']}" 26 | 27 | Create a droplet: 28 | 29 | DIGITAL_OCEAN_CLIENT_ID=XXXX DIGITAL_OCEAN_API_ID=YYYY knife \ 30 | digital_ocean droplet create -N \ 31 | -I \ 32 | -L \ 33 | -S \ 34 | -K \ 35 | -B \ 36 | -r "" 37 | 38 | 39 | 40 | digital_ocean_creds = Chef::EncryptedDataBagItem.load("passwords", "digital_ocean") 41 | knife[:digital_ocean_client_id] = "#{ENV['DIGITAL_OCEAN_CLIENT_ID'] || digital_ocean_creds['digital_ocean_client_id']}" 42 | knife[:digital_ocean_api_key] = "#{ENV['DIGITAL_OCEAN_API_ID'] || digital_ocean_creds['digital_ocean_api_id']}" -------------------------------------------------------------------------------- /shopify_api_interaction.md: -------------------------------------------------------------------------------- 1 | # Shopify API interaction 2 | 3 | You'll want to talk to the API and the best way to do this is using the Shopify API gem. Add the following to your `Gemfile` 4 | 5 | gem 'shopify_api' 6 | gem 'rest-client' 7 | 8 | Then `bundle`. 9 | 10 | ## API keys 11 | 12 | In order to get started you are going to need to setup your application as a _Private Application_ on your shop. To do this, create a new private application: 13 | 14 | https://YOURSHOP.myshopify.com/admin/apps/private/new 15 | 16 | Once created, go to the application and find the API keys, add them to your `.env`: 17 | 18 | SHOPIFY_API_KEY="YOUR_API_KEY" 19 | SHOPIFY_PASSWORD="YOUR_PASSWORD" 20 | SHOPIFY_SHOP="YOUR_SHOP_NAME" 21 | 22 | 23 | Once you have the API keys in your `.env` you should import them into your `config/secrets.yml`: 24 | 25 | shopify_api_key: <%= ENV["SHOPIFY_API_KEY"] %> 26 | shopify_password: <%= ENV["SHOPIFY_PASSWORD"] %> 27 | shopify_shop: <%= ENV["SHOPIFY_SHOP"] %> 28 | 29 | 30 | ## Initializer 31 | 32 | Once you've setup your API keys you'll want to preload them in an initializer. Create `/config/initializers/shopify.rb`: 33 | 34 | shopify_shop_url = "https://#{Rails.application.secrets.shopify_api_key}:#{Rails.application.secrets.shopify_password}@#{Rails.application.secrets.shopify_shop}.myshopify.com/admin" 35 | ShopifyAPI::Base.site = shopify_shop_url 36 | 37 | 38 | ## Metafields 39 | 40 | 41 | product.add_metafield(ShopifyAPI::Metafield.new({ 42 | :description => 'Author of book', 43 | :namespace => 'book', 44 | :key => 'author', 45 | :value => 'Kurt Vonnegut', 46 | :value_type => 'string' 47 | })) -------------------------------------------------------------------------------- /unformatted/shopify_application_proxy_sessions.md: -------------------------------------------------------------------------------- 1 | # Shopify Application Proxy Sessions 2 | 3 | **Problem:** 4 | 5 | - Cookies are not passed for application proxy pages (eliminating cookie based sessions) 6 | - There is no way in normal shopify pages to read params except via javascript 7 | - Params are lost after built-in redirects (eliminating url / param based sessions) 8 | 9 | 10 | 11 | ## Using the customer 12 | 13 | * When a customer is created you respond to a webhook and generate a secret token 14 | * All future interaction with the proxy passes the embedded customer_id and customer_token 15 | * The customer_id and customer_token can be embedded in forms throughout the store and can also be injected as metafields making AJAX easier 16 | * Serving get requests for pages means you have to add the parameters to the top url (which is ugly). This could be masked with a container page rendered as liquid and a sub page rendered with an iframe (same domain) 17 | 18 | ### Downsides 19 | 20 | * requires customer accounts :( 21 | * get requests require url params 22 | 23 | ### Upside 24 | 25 | * Requires way less adjustments to the rest of the store 26 | 27 | ## Using a JavaScript cookie 28 | 29 | 1. Check for app session cookie 30 | 2. If cookie does not exist you post to an `/a/session` route to get a secret token in the response 31 | 3. Secret gets stored in session cookie via javascript 32 | 4. Subsequent requests can fetch the cookie via javascript and append `