Initial Version

This commit is contained in:
Salar Rahmanian 2016-03-11 11:19:40 -05:00
commit 76ee2dd12c
91 changed files with 7690 additions and 0 deletions

19
content/page/about.md Normal file
View file

@ -0,0 +1,19 @@
+++
categories = [""]
date = "2015-11-26T09:16:07-05:00"
description = "About Salar Rahmanian"
keywords = ["Salar", "Rahmanian", "Salar Rahmanian"]
menu = "main"
slug = "salar-rahmanian"
tags = [""]
title = "About"
+++
![Rahmanian Family](/img/rahmanian.png)
I , [Salar Rahmanian](http://www.softinio.com), am a software developer based in Washington DC, USA. I have over 20 years of experience in software and web development.
I am married to my wonderful wife, [Leila Rahmanian](http://www.foofoolmom.com). We have two sons, [Valentino Rahmanian](http://www.valentinorahmanian.com) who was born in December 2013 and [Caspian Rahmanian](http://www.caspianrahmanian.com) who was born in December 2014. We also have a cheeky french bulldog called Sir Edward.
![Rahmanian Family](/img/family.jpg)

View file

@ -0,0 +1,263 @@
+++
categories = ["development"]
date = "2014-01-09T08:54:57-05:00"
description = "Overview of what is involved in getting your Laravel 4 apps authentication system to integrate with Get Satisfaction Fastpass for single sign on."
keywords = ["laravel", "php", "fastpass"]
tags = ["laravel", "php", "fastpass"]
slug = "integrating-get-satisfaction-fastpass-with-laravel"
title = "Integrating Get Satisfaction Fastpass with Laravel"
+++
Here is an overview of what is involved in getting your Laravel 4 apps authentication system to integrate with Get Satisfaction Fastpass for single sign on.
## What I am using
* [Laravel 4.0][2]
* [Cartalyst Sentry 2][3] (for authentication)
* [Former][4]
* [Fastpass PHP SDK][1]
## Install the Fastpass PHP SDK
** Create a folder to install the library in **
```
$ mkdir app/lib
$ mkdir app/lib/getsatisfaction
```
** Download & untar/unzip the Fastpass PHP SDK**
```
cd app/lib/getsatisfaction
wget "https://getsatisfaction.com/fastpass/php.tar.gz"
tar -zxvf php.tar.gz .
```
** Update ** *composer.json* ** adding the location of the library **
In the *autoload* section add the path *app/lib/getsatisfaction*
```
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/lib/getsatisfaction"
]
},
```
** In the console run **
```
$ composer update
$ php artisan dump-autoload
```
** Create a configuration file (e.g. app/config/getsatisfaction.php ) to hold your API tokens for the Fastpass service **
```php
<?php
return array(
'key' => '<your fastpass key>',
'secret' => '<your fastpass secret>',
'domain' => '<your domain for your get satisfaction commmunity>',
);
```
The above information can be found in the admin section once you log in as administrator on <http://getsatisfaction.com>.
## Create a login screen for Single Sign on
We now need to create a login form to be used by the Fastpass service to use our authentication service provided by sentry to log users into Get Satisfaction.
** First we create a new controller** *app/controllers/SatisfactionController.php*
```php
<?php
use App\Services\Validators\UserValidator;
use Cartalyst\Sentry\Users;
class SatisfactionController extends BaseController
{
/**
* Authenticate the user
*
* @author Salar Rahmanian
* @link http://www.softinio.com
*
*
* @return Response
*/
public function postLogin()
{
$remember = Input::get('remember_me', false);
$userdata = array(
Config::get('cartalyst/sentry::users.login_attribute') => Input::get('login_attribute'),
'password' => Input::get('password')
);
try {
// Log user in
$user = Sentry::authenticate($userdata, $remember);
} catch (LoginRequiredException $e) {
return Redirect::back()->withInput()->with('error', $e->getMessage());
} catch (PasswordRequiredException $e) {
return Redirect::back()->withInput()->with('error', $e->getMessage());
} catch (WrongPasswordException $e) {
return Redirect::back()->withInput()->with('error', $e->getMessage());
} catch (UserNotActivatedException $e) {
return Redirect::back()->withInput()->with('error', $e->getMessage());
} catch (UserNotFoundException $e) {
return Redirect::back()->withInput()->with('error', $e->getMessage());
} catch (UserSuspendedException $e) {
return Redirect::back()->withInput()->with('error', $e->getMessage());
} catch (UserBannedException $e) {
return Redirect::back()->withInput()->with('error', $e->getMessage());
} catch (Exception $e) {
return Redirect::back()->withInput()->with('error', $e->getMessage());
}
Event::fire('users.login', array($user));
// Log user into Get Satisfaction service
return View::make('satisfaction.index', compact('user'));
}
/**
* Show the login form
*
* @author Salar Rahmanian
* @link http://www.softinio.com
*
* @return Response
*/
public function getLogin()
{
// Check to see if user logged in, if not show login form
if (!\Sentry::check()) {
$login_attribute = Config::get('cartalyst/sentry::users.login_attribute');
return View::make('satisfaction.login', compact('login_attribute'));
}
// user already logged in so log them into Get Satisfaction service
$user = \Sentry::getUser();
return View::make('satisfaction.index', compact('user'));
}
}
```
Now we need to create the two views used by this controller, one with a login form and one view which logs the user into the get satisfaction service.
** For the login form we create the view ** *app/views/satisfaction/login.blade.php*
This can be a copy of the login form you currently use within your Laravel app but with the form action changed to use the new *SatisfactionController*.
```
@extends('layouts.master')
@section('h1')
<h1>Sign In</h1>
@stop
@section('crumb')
<li><a href="{{ url('/satisfaction/index') }}">User</a></li>
<li class="active">Login</li>
@stop
@section('title')
Sign In -
@stop
@section('container')
<div class="row">
<div class="col-lg-offset-2 col-lg-6 col-md-offset-2 col-md-6">
{{ Former::horizontal_open(url('/satisfaction/login')) }}
{{ Former::text('login_attribute', 'User Name',Input::old('login_attribute'))->required() }}
{{ Former::password('password', 'Password')->required() }}
{{ Former::checkbox('remember_me','&nbsp;')->text('Remember me on this computer') }}
<div class="col-lg-offset-3 col-sm-offset-4 col-lg-9 col-sm-8">
{{ Former::primary_submit('Log in') }}
<a href="{{ URL::route('user.register') }}" class="pull-right">Register Here</a>
</div>
</form>
</div>
</div>
@stop
```
** We create the view that logs user into Get Satisfaction ** *app/views/satisfaction/index.blade.php*
This is in effect a blank html document which calls the php class from the Fastpass library to log the current user into the Get Satisfaction service.
```
<!DOCTYPE html>
{{ \FastPass::$domain = \Config::get('getsatisfaction.domain'); }}
{{ \FastPass::script(\Config::get('getsatisfaction.key'),
\Config::get('getsatisfaction.secret'),
$user->email,
$user->username,
$user->id,
true
); }}
<html lang="en" class="env_<?php echo App::environment(); ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="/assets/ico/favicon.png">
<title>@yield('title') softinio.com </title>
<!-- Bootstrap core CSS -->
{{ basset_stylesheets('bootstrap','application') }}
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
{{ basset_javascripts('html5') }}
<![endif]-->
</head>
<body>
</body>
</html>
```
The users email , username and user id provided by Sentry are used to create and log user into the Get Satisfaction service. The username is what will be displayed as the logged in user on Get Satisfaction website so if you prefer something else you can substitute username for what you prefer.
**Update your** *app/routes.php* **file**
```php
Route::get('satisfaction/login', 'SatisfactionController@getLogin');
Route::post('satisfaction/login','SatisfactionController@postLogin');
```
## Update Get Satisfaction with your login URL
Based on the new route you created for the *SatisfactionController* your URL to your single sign on should be
```
http://<yourdomain where your laravel app is>/satisfaction/login
```
Log into Get Satifaction as admin, click the wheel settings menu, select Configure then select Fastpass. Here set your *External Login URL* to this and click save.
Whilst you are logged in as admin you can also click login options and select Fastpass as your preferred login method.
[1]: https://getsatisfaction.com/fastpass/php.tar.gz
[2]: http://laravel.com
[3]: https://cartalyst.com/manual/sentry
[4]: http://anahkiasen.github.io/former

View file

@ -0,0 +1,282 @@
+++
categories = ["python", "golang"]
date = "2015-11-29T07:16:53-05:00"
description = "In this post I will discuss the steps I took to migrate my blog from Pelican to Hugo."
keywords = ["pelican", "hugo", "golang", "go", "python", "blog"]
slug = "migrating-from-pelican-to-hugo"
tags = ["pelican", "hugo", "golang", "go", "python", "blog"]
title = "Migrating from Pelican to Hugo"
+++
In this post I will discuss the steps I took to migrate my blog from [Pelican](http://blog.getpelican.com/) to [Hugo](http://gohugo.io/).
## Goal
| | Original Blog | New Blog |
| --- | --- | --- |
| Static site generator | [Pelican](http://blog.getpelican.com/) | [Hugo](http://gohugo.io/) |
| Hosting | [Linode](https://www.linode.com/) | [Amazon S3](https://aws.amazon.com/s3/) |
| Deployment Strategy | Manual using git | Automated using [Wercker](http://wercker.com/) |
| Source Control | [bitbucket](https://bitbucket.org/) | [GitHub](https://github.com/softinio/softinio.com) |
## Installing Hugo
I do all of my development on an Apple Macbook Pro so I used homebrew to install Hugo:
```brew install hugo```
## Creating my project
Its up to you how you organize your project, but as I am a Go Language developer and Hugo is built using Go I have created a folder for this project here:
```$GOPATH/src/github.com/softinio/softinio.com```
change directory to this and in terminal run (for the rest of this blog I will assume you are in this directory):
```git init```
This will create a git repository for your project.
## Create Hugo Site
To create your new Hugo site in terminal run:
```hugo new site $GOPATH/src/github.com/softinio/softinio.com```
This will create the skeleton for your new Hugo site.
## Choosing a theme
First I headed over to the themes showcase for hugo here: [Hugo Themes](http://themes.gohugo.io/). This has screenshots and links to demo sites for each theme.
I chose [hyde-x](http://themes.gohugo.io/hyde-x/) for my blog.
Make a subdirectory called ```themes``` and change directory to it and clone the theme you have chosen there:
```git clone https://github.com/zyro/hyde-x```
Once this theme repo got cloned into my project I then removed its ```.git``` directory by changing directory into the themes root folder and removing it:
cd themes/hyde-x
rm -fr .git
## Configuring your project and theme
In the root of your project there is a file called ```config.toml``` that you need to update to configure your site. You can look at [my configuration](https://github.com/softinio/softinio.com/blob/master/config.toml) to get an idea of the things you can set. For your theme specific settings of course look at the github repo for your theme's readme for detailsi (e.g. for my chosen theme: [hyde-x documentation](https://github.com/zyro/hyde-x/blob/master/README.md)).
## Content Types, Archetypes and Front Matter
I have decided to have two content types:
- ```post``` for my blog posts
- ```page``` for my sites static pages (like my about me page).
When creating any kind of content using Hugo you must provide some meta data about it. This meta data is known as ```front matter```.
For example my ```front matter``` for this post is:
+++
categories = ["python", "golang"]
date = "2015-11-29T07:16:53-05:00"
description = "In this post I will discuss the steps I took to migrate my blog from Pelican to Hugo."
keywords = ["pelican", "hugo", "golang", "go", "python", "blog"]
slug = "migrating-from-pelican-to-hugo"
tags = ["pelican", "hugo", "golang", "go", "python", "blog"]
title = "Migrating from Pelican to Hugo"
+++
You can get Hugo to automatically create the above front matter for you for each content type. These are called ```archetypes```. If you look at the ```archetypes``` subdirectory of my project there are two archetypes ```default.md``` and ```page.md```. Any content created that is of type ```page``` will have the contents of ```page.md``` added to its header. Any other content type will have the content of ```default.md``` added to its header.
Looking at the content of ```page.md``` we have:
+++
title = ""
slug = ""
description = ""
menu = "main"
keywords = [""]
categories = [""]
tags = [""]
+++
So this will be added to the top of every content of type page that I add. Of course I will have to edit this template for each content with that contents specific meta data.
The main difference between my two different content types is that the ```page.md``` content type has ```menu = "main"``` this tells hugo that this content is not a blog post and it should be added to the left column of my website below my name as a link.
## Creating Content
To create content, from the project root you call:
```hugo new <content type>/<name of new content md file>```
So to create this page I did:
```hugo new post/migrating-from-pelican-to-hugo.md```
So to migrate my blog posts from pelican to hugo I used to above command to create a post with same file name as I had in pelican, copy and pasted the contents of each file from my pelican project to my hugo project. Note that of course I did not copy the front matter of my pelican posts across. Instead I updated the hugo front matter with the same meta data as I had in pelican manually. I repeated this process for my pages too.
## Permalinks
My permalinks structure for my old pelican based blog was:
```/blog/<slug>```
meaning to access my a post it would have URL like:
```http://www.softinio.com/blog/<slug>```
In hugo I have changed this to:
```/post/<slug>```
meaning to access my a post it would have URL like:
```http://www.softinio.com/post/<slug>```
I could have kept it the same so that the URL to my existing content moving from Pelican to Hugo would not change, but I prefered to move forward with it this way. This is a personal choice of course.
If you have a look at my ```config.toml``` file you will see under the ```permalinks``` section how I have defined my permalinks.
For more details on permalinks have a look at the [Hugo documentation on permalinks](http://gohugo.io/extras/permalinks/).
## GitHub
By this stage I had migrated all my content to hugo and had setup my site. All tested locally. So to get ready for deployment I [created a new GitHub repo](https://help.github.com/articles/create-a-repo/) for it and pushed my code to it:
To add github repo I created as my remote:
git remote add origin git@github.com:softinio/softinio.com.git
Commit All My work:
git commit -am "Initital version of my site"```
Merge the remote with my local:
git pull origin master
Pushed my code to GitHub:
git push origin master
## Creating your Amazon AWS S3 bucket
I already had an account with [Amazon AWS](http://aws.amazon.com/) so I signed in and created a S3 bucket:
- The bucket I named ```www.softinio.com``` and set it up for static website hosting by following this [Amazon Document](https://docs.aws.amazon.com/AmazonS3/latest/dev/HowDoIWebsiteConfiguration.html)
When I created the ```www.softinio.com``` bucket I also clicked ```properties``` and selected the ```permissions``` section. Here I edited the bucket policy and added:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<domain/bucket name>/*"
}
]
}
Of course replace ```<domain/bucket name>``` with your actual bucket name which for me would be ```www.softinio.com```.
## Moving my domains DNS management to Amazon AWS Route 53
I then moved my domain's DNS management to [Amazon AWS Route 53 service](https://aws.amazon.com/route53/) for convenience.
I followed the steps in this [Amazon document](http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/creating-migrating.html) to move my domain's DNS management.
## Creating a User on Amazon AWS to use for deployment
We need to create a user on Amazon AWS to use for deployments to the S3 bucket we created. To do this log into your Amazon AWS console and select ```Identity & Access Management```, then select ```Users``` and then select ```Create New Users```.
Give the new user a name and make note of the access keys for this user that gets generated for you.
You will need to create a policy and attach to this user. Here is a sample policy you can use:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<domain/bucket name>",
"arn:aws:s3:::<domain/bucket name>/*"
]
}
]
}
Of course replace ```<domain/bucket name>``` with what you actually called your Amazon S3 bucket name.
## Automate your deployments with Wercker
Head over to [Wercker website](http://wercker.com/) and click sign up and register for an account.
Once you have your account, login and go to your settings and click git connections. Here click to connect to your GitHub account.
## Adding your application to Wercker
I followed these steps:
- Click Create to start adding your application
- Select your GitHub Repository
- Select the repository owner
- Configure Access (I chose: ```werker will checkout the code without using an ssh key```)
- I chose not to have my app public
Once the app was created Wercker gave me the option to trigger a build. Decline it as we have not finished creating our app.
## Create and add wercker.yml file
In the root of my project I added a new ```wercker.yml``` file for my configuration of wercker:
box: debian
build:
steps:
- arjen/hugo-build:
version: "0.14"
theme: hyde-x
config: config.toml
flags: --disableSitemap=false
deploy:
steps:
- s3sync:
source_dir: public/
delete-removed: true
bucket-url: $AWS_BUCKET_URL
key-id: $AWS_ACCESS_KEY_ID
key-secret: $AWS_SECRET_ACCESS_KEY
## Adding environment variables for deployment
Log back into wercker and go to your application settings. Select ```Targets``` and in there add 3 new variables to your deploy pipeline:
- AWS_ACCESS_KEY_ID - As provided for the user you created on Amazon AWS
- AWS_SECRET_ACCESS_KEY - As provided for the user you created on AWS
- AWS_BUCKET_URL - set this to ```s3://yourdomain.com``` (Note: having the ```s3://``` in front of your domain is very important!)
## Your first deployment
You are all set now to deploy your hugo website. Commit your changes and push to the GitHub repo you created and your website will be deployed to S3 for you automatically.
From now on when ever you make any changes to your site, as soon as you push to your GitHub repo , it will build and deploy your changes to Amazon S3.
## Conclusion
I am really enjoying using Hugo for my blog and having it deploy automatically when I push a change to GitHub. My workflow is a lot simpler now making it easier for me to write and publish my blogs.
You may ask why I moved from the Python based Pelican to Hugo, well I simply wanted to try something new. I think both Pelican and Hugo are great at what they do so you can't go wrong with either.
If I had to choose between them, I would choose Hugo for the more modern approach and excellent documentation.

View file

@ -0,0 +1,87 @@
+++
categories = ["development", "python"]
date = "2015-04-13T09:06:03-05:00"
description = "Using pyenv to manage your virtual environments makes working on multiple projects, each using a different version of python a breeze."
slug = "using-pyenv-for-python-projects"
tags = ["python", "pyenv", "centos"]
keywords = ["python", "pyenv", "centos"]
title = "Using pyenv for Python projects"
+++
Using [pyenv][3] to manage your virtual environments makes working on multiple projects, each using a different version of python a breeze.
I do all my development on an Apple Macbook running Yosemite and my production environment is a VPS from [Linode][1] running [CentOS 7][2].
Here some simple notes on how I setup and use [pyenv][3] :
## Installing on Mac OS X ##
** Install using [homebrew][5] **
```
$ brew install pyenv pyenv-virtualenv
```
** Update your shell profile (.bashrc or .zshrc) adding the following to it (and restart your terminal) **
```
if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
if which pyenv-virtualenv-init > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi
```
## Installing on Linux CentOS 7 ##
** Checkout from github **
```
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
$ git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
```
** Update your shell profile (.bashrc or .zshrc) adding the following to it (and restart your terminal) **
```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile
```
## Using pyenv ##
** To install a new version of [Python][6] **
```
$ pyenv install <version>
$ pyenv rehash
```
** To get a list of [Python][6] versions available **
```
$ pyenv install -l
```
** To create a new virtual environment **
```
$ pyenv virtualenv [pyenv-version] [virtualenv-name]
```
** To use your new virtual environment within your project **
1. Change to your projects root directory
1. Run:
```
$ pyenv local [virtualenv-name]
```
Note that this is done only the first time you go to your project directory. The wonderful thing about [pyenv][3] is in future when you change directory to your project directory, it will be automatically activated your virtualenv for you.
[1]: https://www.linode.com
[2]: https://www.centos.org
[3]: https://github.com/yyuu/pyenv
[4]: https://github.com/yyuu/pyenv-virtualenv
[5]: http://brew.sh
[6]: https://www.python.org