Greetings :)

Hi, I'm Louis!
I like to code, but I don't do enough of it.

This blog is about trying my best to keep up with the ever evolving stream of technology.

Thursday, October 4, 2012

Setting up MySQL on ubuntu

Well it doesn't seem like it'd be that difficult... but I have spent a good few hours trying to set it all up!

The first problem was that I didn't know how to install it - should I use apt-get install, or download the .rpm or use the synaptic package installer... I ended up going with apt-get, and there were a couple of other libraries I needed to install as well:

sudo apt-get install mysql-server install mysql-client

Install these if you haven't already:zlib1g, zlib1g-dev, build-essential, openssl, libssl-dev, libmysqlclient-dev, libyaml-dev

I had a bit of a problem however with libmysqlclient-dev... I don't know if this was because I was playing around or what... but it wouldn't install because it said:

Unpacking libmysqlclient-dev (from .../libmysqlclient-dev_5.5.24-0ubuntu0.12.04.1_i386.deb) ... dpkg: error processing /var/cache/apt/archives/libmysqlclient-dev_5.5.24-0ubuntu0.12.04.1_i386.deb (--unpack): trying to overwrite '/usr/bin/mysql_config', which is also in package mysql-devel 5.5.28-2

I got rid of this problem by removing the mysql-devel package:
dpkg -r mysql-devel

I also learnt a cool command to see all mysql related installs:
dpkg --get-selections | grep mysql

I had to say where the mysql socket is for rails to make a connection to mysql. The location I used is /var/run/mysqld/mysqld.sock -which seems to be working fine.

Finally, it comes time to run mysql - which it looks like you can also do in various ways! I've been running it by doing:

service mysql start

There is a blog which probably describes this all in more detail:
http://cicolink.blogspot.co.uk/2011/06/how-to-install-ruby-on-rails-3-with.html





Monday, August 13, 2012

Setting up ssl on heroku

I'm setting up SSL on heroku, and it took a while to work things out, so here's my guide (based on heroku's) on how to setup SSL.

Overview

I'm assuming you're already on heroku and you want https traffic for your own domain name.

You want to add SSL. When you add SSL heroku will give you a new app address e.g. soaringeagle223.herokuapp.com for your https traffic. What you will have to do is point a subdomain to this new app. If you configure your certificate for the naked domain i.e. mycoolapp.com then you will get a warning when you visit https://mycoolapp.com... SO make sure you point a subdomain to the secure app name, or you'll end up buying a new certificate! (more info on why this is a good idea is here).

The other thing to note is that you will have to upload YOUR certificate, and also an INTERMEDIATE authority certificate. Basically there are a few trusted certificate issuing authorities on the internet, and some intermediate issuing authorities. You need to link your certificate to a trusted Root Authority, and you do this via intermediate certificates.

Once you have your heroku app configured and certificate on the server, then you should be able to visit https://mysecuresubdomain.mycoolapp.com - to enforce that everyone ends up on https and not http however, you will need to redirect http traffic to https from within your app code!

Let's get started

Get Certified

  1. Go to www.namecheap.com, and buy an ssl cetificate - I choose RapidSSL single domain (e.g. mysubdomain.myapp.com), as I'm cheap and it works for me ;)
  2. Now in namecheap, click on "My Account" -> "Your Domains/Products" -> "SSL Certificates"
  3. You should have a certificate with a status of "Activate Now" - CLICK to activate and you should be taken to a page where you can enter your 'CSR' key
  4. Now you have to generate a 'Certificate Signing Request' (CSR). There are some instructions on how to do this on heroku. Choose Apache 2 as the server type.

    Assuming you have openssl installed, here's the basics on a linux box (more details at heroku):
    1. openssl genrsa -des3 -out server.orig.key 2048
      openssl rsa -in server.orig.key -out server.key
      
      openssl req -new -key server.key -out server.csr
      
  5. Copy and paste your CSR code into namecheap, leaving out the BEGIN and END bits.
  6. Fill in the rest of the details with namecheap - they will send a verfication email to your admin email address.
  7. Finally, copy the certificates that you receive in your email into a text file (one after the other with the begin/end certificate bits), and save it as 'server.crt'. Ensure you have a new line at the end of the file.

Configure Heroku

  1. heroku addons:add ssl:endpoint --app myapp (this costs money)
  2. heroku certs:add server.crt server.key --app myapp (server.crt, and server.key were created in the previous steps) Heroku will let you know if this was successful or not
  3. heroku certs --app myappname (This will show you your certificate and ssl endpoint info)

Configure DNS

The next step is to point your subdomain to your heroku ssl endpoint.
  1. heroku certs --app myappname (This will show you your certificate and ssl endpoint info)
  2. Now create a CNAME record that points from your subdomain to the ssl endpoint (i.e. set it up via GoDaddy or whoever you bought your domain name from) 

Finally

If you browse to https://mysubdomain.mydomainname.com then you should go there, and see https:// in the address bar. If you get a warning message, then something isn't setup quite right...
You will still be able to access the http version too though... If you want to force users to use https rather than http, then you'll need something in your code to do this redirection.

Here's an example for sinatra based apps:
require 'sinatra'

before '*' do
  if(!request.ssl? && request.host != 'localhost')
    request_url = request.env['REQUEST_URI']
    request_url['http'] ='https' 
    redirect request_url
  end
end

If you found this useful let me know :) also, please let me know if I missed something or if there's an error etc.

Saturday, May 26, 2012

Errors installing mysql2 on ubuntu

Upon installing the mysql2 gem I got the following error:

ERROR: Failed to build gem native extension.
I fixed it with:
sudo apt-get install libmysql-ruby libmysqlclient-dev

Thanks to this post here

Sunday, May 20, 2012

Ruby - dynamically create an object :)

Thought this was really cool :)

def create_object(class_name, *args)
  the_class = Object.const_get(class_name)
  the_object = the_class.send :new, *args if !args.empty?
  the_object = the_class.send :new if args.empty?
  
  return the_object
end

Friday, May 18, 2012

Running ruby 1.9.3 on Heroku

I had a few problems trying to get ruby 1.9.3 running on Heroku.

Here's the error I had:
 Heroku receiving push
-----> Removing .DS_Store files
-----> Ruby/Sinatra app detected
-----> Gemfile detected, running Bundler version 1.0.7
       Unresolved dependencies detected; Installing...
       Using --without development:test
       /tmp/build_jpq0amd2bp92/Gemfile:5:in `evaluate': undefined method `ruby' for # (NoMethodError)


Here's what I did to fix it:

     Add the following to Gemfile: 
        ruby '1.9.3'
        gem 'bundler', '1.2.0.pre'

git remote rm heroku
heroku create --stack cedar
gem install bundler --pre
bundle install
git commit -am "fixed heroku problem"
git push heroku master

And some notes to myself for other stuff I need:
heroku addons:add mongohq:free
heroku config:add TWITTER_KEY=`echo $TWITTER_KEY`
heroku config:add TWITTER_SECRET_KEY=`echo $TWITTER_SECRET_KEY`


Tuesday, May 8, 2012

How to make Ethernet work on ubuntu!

So my computer has an Ethernet card which doesn't work out of the box with Ubuntu 11 or 12.04 - which means that I couldn't connect to the internet!


When I ran:


lspci | grep Ethernet 


It showed my card as having a RTL8111 Ethernet controller.


Long story short, this post helped me get the card going properly (for the second time now...)

Saturday, March 10, 2012

Setting up postgres on ubuntu, and getting it going on heroku

links: https://help.ubuntu.com/community/PostgreSQL,

sudo apt-get install postgresql
sudo apt-get install postgresql-server-dev-all

#Create a user account for postgresql, and a database with the name of your user account
sudo -u postgres createuser --superuser myUbuntuUsername
sudo -u postgres psql
postgres=# \password myUbuntuUsername
\q
createdb myUbuntuUsername

#Check that your postgres useraccount was setup properly
psql
\du 

Use require
'dm-core'
instead of
require 'datamapper'
http://devcenter.heroku.com/articles/database

Keep test and production gems separate:
http://yehudakatz.com/2010/05/09/the-how-and-why-of-bundler-groups/

Working with rails

gem install rails
sudo apt-get install libmysql-ruby libmysqlclient-dev

rails new myProject -d mysql

Saturday, November 19, 2011

Helpful sinatra info

https://github.com/toolmantim/sinatra-content-for -- allow you to pass in say the title from a page to the layout.

Sunday, October 16, 2011

Helpful ruby commands

Remove all gems
* gem list | cut -d" " -f1 | xargs gem uninstall -aIx
* (From RVM) rvm do gem list | cut -d" " -f1 | xargs rvm do gem uninstall -aIx

Remove RVM
1.rvm implode

2.gem uninstall rvm

Saturday, September 24, 2011

Adding local 'DNS' entries to your mac

I'm currently working on adding subdomains to my sinatra app - following the instructions at:
http://tannerburson.com/2009/01/extracting-subdomains-in-sinatra.html

First we need to add a local domain name to our hosts file:
http://decoding.wordpress.com/2009/04/06/how-to-edit-the-hosts-file-in-mac-os-x-leopard/

  • sudo vi /private/etc/hosts
  • Run dscacheutil flushcache


Once this is done, wildcard subdomains will need to be supported. I'm using Heroku, and thus I'll follow the instructions at http://devcenter.heroku.com/articles/custom-domains

Heroku notes

Create a new heroku instance

gem install heroku
heroku create
git push heroku master

>> 'successfully deployed' then you go to the site and ... error...

heroku logs

>> figure out the error (e.g. missing gem.. update Gemfile) then try again...

now that we've got something running, can add a domain...

(taken from http://devcenter.heroku.com/articles/custom-domains)
heroku addons:add custom_domains
heroku domains:add www.example.com
heroku domains:add example.com

And now setup domains on your domain provider (I'm using godaddy)

75.101.163.44
75.101.145.87
174.129.212.2
In GoDaddy find your domain name, click on it, and then click the 'DNS Manager' on the page that shows all the information about your domain. Click on the 'Quick Add' on the Hosts(A) section, and just add the @ ip address - have to do three entries. The www will reference to @, so don't need to worry about that one :)


Getting the mongo connection string:

heroku config --long


You'll get some output that includes a line where your mongo connection is:

MONGOHQ_URL         => mongodb://heroku:myPassword@myHost:10013/appname545


You can then take this string, and use it to connect to mongo:

mongo -u heroku -p myPassword --host myHost -port 10013 appname545










We may already have an app and we're on a different machine than the original

  • Install toolbelt - https://toolbelt.herokuapp.com/linux
  • heroku login
  • heroku keys:add [path to keyfile]
  • git remote add heroku git@heroku.com:myAppOnHeroku.git

Friday, August 5, 2011

Deleting objects with ruby on Amazon S3

Problem:
I ended up with loads of objects in my bucket after configuring some logging in Amazon S3. Deleting these manually is not the best use of time (click click click... one has been deleted) * 1 million (slightly over-exaggerated)

Solution:
Use Ruby to do it!

Solution Problem:
I was trying to use the 'aws/s3' gem, and apparently there's some problems with european regions or something... anyway, I tried some sample code found in http://stackoverflow.com/questions/27267/delete-amazon-s3-buckets, and then I found - http://thewebfellas.com/blog/2009/8/29/protecting-your-paperclip-downloads which led me to my eventual solution...

Solution Problem Solution:
Use a different gem - the 's3' gem.

Here's what I ended up with:

require 's3'

service = S3::service.new(:access_key_id => your key from amazon account page, 
                          :secret_access_key => your secret key from amazon account page)

my_bucket = service.buckets.find("my-unique-bucket-name")
my_bucket.objects.each {|object| object.destroy}

Pretty simple in the end huh :)

Check that it worked by doing my_bucket.objects.size before and after you delete the objects.

Friday, January 7, 2011

What is hypermedia or hypertext????

Taken from Roy Fielding (the father of REST)
When I say hypertext, I mean the simultaneous presentation of information and controls such that the information becomes the affordance through which the user (or automaton) obtains choices and selects actions. Hypermedia is just an expansion on what text means to include temporal anchors within a media stream; most researchers have dropped the distinction.
Hypertext does not need to be HTML on a browser. Machines can follow links when they understand the data format and relationship types.
 So...
 Hypertext means text with links in it (which give you further options or actions)
and
Hypermedia means media with links in it (i.e. video, text, pictures) - which give you further options or actions.

Hmmmm..... Maybe radio advertisements that direct you to their website for more information could even be considered as "hypermedia"? I don't think that a strict definition is really needed though. As long as the general idea comes across.

Tuesday, January 4, 2011

Installing Git on windows

The following will guide you roughly through getting git setup on windows and getting a github account setup, so that you can start using git right away ;)


Install MSysGit
http://code.google.com/p/msysgit/downloads/list

Generate a private/public key pair
http://help.github.com/msysgit-key-setup/

Then create your online repository:
Go to https://github.com, sign up for an account


Add your public key to your github account:
Click "account settings" => "SSH public keys" => "Add another public key", and copy and paste the public key you generated (the whole thing) - from the "id_rsa.pub" file.

Create your repository
Click on "dashboard" => "Create a repository" => name your repository, and continue => follow the instructions shown :)

Friday, December 17, 2010

ASP.NET MVC dependency injection

Dependency Injection frameworks such as Ninject can be used to 'inject' dependencies into your ASP.NET MVC web application.

Steps with Ninject:

  1. Download Ninject
  2. Reference the Ninject.dll library
  3. Next we have to stop making ASP.NET MVC call controller classes directly, and instead call the controllers through the Dependency Injection framework.

    In order to do this, we do the following:

      * Create a subclass of ASP.NET MVC's DefaultControllerFactory class, overriding the GetControllerInstance method. (To make this call existing controllers like normal, return new StandardKernel.Get(controllerType)

      * Inside the Global.asax.cs file's Application_Start() method, set the new DefaultControllerFactory class's subclass as the current controller factory (i.e. ControllerBuilder.Current.SetControllerFactory(new MyNewClassName());
OK, so that's done, I'll explain the next bit with my subclass of DefaultControllerFactory, the only extra bit here is that I've set up some keys in my web.config.

Here's my subclass:
public class NinjectControllerFactory : DefaultControllerFactory
    {
        private IKernel kernel = new StandardKernel(new SportsStoreServices());
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            if(controllerType == null)
            {
                return null;
            }
            return (IController) kernel.Get(controllerType);
        }

        private class SportsStoreServices : NinjectModule
        {
            public override void Load()
            {
                Bind()
                    .To()
                    .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString);
                Bind()
                    .ToSelf().WithConstructorArgument("numberOfItems",int.Parse(ConfigurationManager.AppSettings["ProductsPerPage"]));
            }

        }
    }


And here's the relevant bits in my web.config:

<connectionstrings>
    <add connectionstring="Server=.\SQLEXPRESS;Database=SportsStore;Trusted_Connection=yes;" name="AppDb">
  </add></connectionstrings>

  <appsettings>
    <add key="ProductsPerPage" value="5">
  </add></appsettings>
Yeah, so that's pretty much it - now my controller takes a IProductsRepository, as well as a ItemsPerPage (an int wrapper) object which I inject. The cool thing I find with this is that now I can make my configuration in my web.config; so I can make changes to my application without writing a line of code :)

Thursday, September 23, 2010

Agile vs XP

From my current understanding...

Agile is about high level principles, and best practices when developing software.

A manifesto is "a public declaration of principles and intentions"; and from the agile manifesto we get:


  • "Individuals and interactions over processes and tool
    I interpret this as:
    When building non-trivial systems, we need to work as a team (including the client); A process is just the framework we work within to give the software development structure, and tools are the mechanisms used to create the software. The real value is created  when we extract requirements, and work out who is developing what, and what issues are being encountered.
    Without a high level of communication and interaction, we can't know what issues are currently present, and whether we're truly building something of value that solves the problems at hand.
    Therefore, the main focus should be on communicating with people, and getting feedback from people. Tools and processes are secondary, as they are more like catalysts (or helpers).

  • "Working software over comprehensive documentation"
    I interpret this as:
    Write software that is simple and easy to understand, and which is user friendly. This will avoid having to write a large amount of documentation.

  • "Customer collaboration over contract negotiation"
    I interpret this as:
    OK... first off, contracts will need to be made (to say what will be delivered for what money). The point is though, that the customer doesn't dictate what the requirements are through a contract - we are all part of a team that determines what will be in the contract. So the principle is that the client is actually part of the team, and requirements are 'discovered' rather than negotiated.

  • "Responding to change over following a plan"
    I interpret this as:
    What developers have found in the majority of projects, is that
    "most projects have changing requirements". With traditional processes like the waterfall process, requirements were gathered all up front, and a big long plan was made of exactly how the system would be built.
    When requirements are changed however, it is then expensive to change, because you invested so much time up front creating, and planning the software design (which will now be for little use, as it needs to be changed).
    It therefore makes sense to structure the development process to incorporate the fact that requirements are likely to change (as history has shown it to be very likely). It also makes sense to be open to changes, as the end product should solve the given problem better, and make clients happier (which means they'll tell their friends, and you can charge more because you have higher demand ;))
Of course there are the other 12 principles, which say what we should be doing in order to be Agile. These tell us specifically the way in which we should be working.

Basically the principles say:
  • Communicate well and often with clients and your team
  • Ensure that the team has high levels of trust, motivation, and that work is done sustainably (e.g. not working everyone 60 hours a week every week).
  • Learn about how to design software well, and use these learnings (build competence).
  • Develop in short iterations so that you can get feedback from clients, and be willing to incorporate change requests (be flexible).
  • Keep things simple (complex == complications).
  • Look back and reflect on how you've done, and continually seek improvement and excellence.
OK, so then what the heck is Extreme Programming (XP)?
Well think of Agile as saying what to do (like an interface - it's abstract), and XP as one way to do it (a concrete implementation - it's specific)...

XP is an agile process, which means that it agrees with what the Agile Manifesto says. It has its own values, and has rules for doing things the agile way, as well as the Extreme Programming way.

XP says stuff like:

  • The team must have a stand up meeting every day (for communication).
  • Move people in the team around, so that they work on different parts of the system (to reduce risk of having only one person know about a particular part of the system).
  • Do test driven development.
  • Ensure you refactor your code to make it manageable.

I hope that what I've said is clear; if there's anyone that disagrees with anything I've written, I'd be happy to hear it :)

I'd also be interested to hear if anyone thinks that some of agile doesn't make sense. For me it seems quite logical, and it gives you a warm feeling - it seems like it's really about looking out for one another, being efficient, flexible, and effective.

Friday, September 17, 2010

Refactoring


Steps to take while refactoring:
  1. One SMALL change at a time
  2. Run tests to ensure functionality is the same
  3. Go to step 1

Things to remember while refactoring:
  • Don't add any additional functionality
  • Make the solution easier to understand, and easier for future modification (separation of concerns, good variable naming practice etc).
Refactoring Tactics:
You can also find a lot of information on the refactoring.com website, or Canterbury's OO wiki.
  • Divide and Conquer / Piecemeal refactoring - break the problem into manageable chunks, make only a small change at a time.
  • Rejected Parameter - when extracting a method it is often useful to remove some of the parameters passed to the new method. This can be done by:
    • Inlining local variables into the code that is about to be extracted (so the variable is not declared prior to the method call).
    • Converting local variables to fields, so that the new method will be able to see the data (only do this if it makes sense to make the local variables fields).
  • Caller Swap - Instead of having something like "var2.getX().equals(var1.getX()), you extract the code into a new method isCompatibleWith(var1, var2), and then you move the isCompatibleWith method to the class of var1 or var2 to look like var1.isCompatibleWith(var2)"
  • Inline then extract - when you wish to move a method to another class, you can inline the contents of the method to the other class, and then extract the resulted inlined code into a new method.
  • Temporary static - when wishing to move a method to another class, there may be problems with moving it with refactoring tools. This problem doesn't occur if the method is static, so you can temporarily make the method static, fix any dependencies on local variables (e.g. by passing in a reference to an object as a parameter), and then move the method to a new class, and remove the static declaration.
  • Scaffolding - creating methods temporarily to help transition to a better design. Once the methods no longer have a use, the code in the methods can be inlined into their appropriate positions.


    Code Smells



    Code smells describe code that complicates, duplicates, bloats or tightly couples code.
    Code smells were first described by Kent Beck.


    Books describing / relating to code smells:

    Useful sites covering code smells:


    Common types of code smells:

    Dead code
    Code that is no longer used.
    The Problem
    • Harder to comprehend the code base.
    • Wasted time - reading through, or even changing dead code.
    • More dead code - monkey see, monkey do.
    The Solution
    Remove dead code. The following factors will help in doing so:

    • Domain knowledge - to ensure that the code is in fact dead.
    • Tools - is the code called from anywhere?
    • Testing coverage - can tests be run after deletion to ensure functionality still works?
    Version control will also help ensure that code can be restored if accidentally deleted.

    Duplicate code
    Code that is the same, or performs the same function are showing up in multiple places within a program.
    The Problem
    • Bloat - more code will increase the size of classes, making them more time consuming to read and understand.
    • Maintenance - changes to one of the blocks of code will most likely cause other blocks of code to also be changed. This can also lead to greater defects if the duplicate code isn't updated.
    The Solution
    Refactor the code, combine duplicate code into a method, or into separate classes.

    Comment
    Comments are being used to describe code, as the code readability of the code is poor, making the code hard to follow and understand.
    The Problem
    • Bloat - commented code is often bloated code, making it harder to understand what's going on.
    • Understanding - commented variables can be a sign that the variable name doesn't describe well enough what it is.
    The Solution
    Name things sensibly, and break the problem down.


    Spell variables out rather than using crytpic acronyms.


    If a piece of code is complex, try to split the code into other methods or classes.

    Long Method
    A method is too long
    The Problem
    • Readability - longer code takes longer to read and comprehend.
    • Reusability - a long method may be able to be split into methods or classes that can then be reused.
    • Testability - a long method is likely to need more testing.
    The Solution
    Break the method up into a greater number of methods, or into other classes. Have one method represent a single function, and one class a single concept.

    It may look like breaking a method up into many methods may cause performance degradation, but given the advancement in compilers, there may be no performance hit at all.



    Long Parameter List
    A method has too many parameters
    The Problem
    • The method is doing too much - why does it need all of that information?
    • Understandability - lots of parameters will make code harder to understand.
    The Solution
    Put the data into their own classes, and possibly break the method up into several methods. Ensure that each method is performing a single function, and each class modelling a single concept.

    Large Class
    A class has taken on too much responsibility, and is modelling within it more than one concept.
    The Problem
    • Complexity - if your class represents more than a single concept, it will be harder to understand.
    • Bloat - a greater number of fields and methods will mean the class will take longer to understand.
    The Solution
    Ensure that the class represents a single concept, and break it into several classes if it represents more than a single concept.


    You may find that functionality or state could belong to a different class, in which case functionality or state could be moved to the other class.

    Primitive Obsession
    Code is using primitive data types and method calls to generate desired outcomes, and could be written in a more descriptive and sustainable way. E.g. when generating XML, a primitive obsession smell would be code that writes each tag out line by line. The solution would be to encapsulate the concept of a Tag, and the Tag's attributes into classes, and to render the XML from the classes instead.
    The Problem
    • Code written is not reusable.
    • It may be less clear to someone reading the code what is going on.
    The Solution
    Encapsulate data concepts in classes, and create and call methods on objects of a class to attain desired results.



    Speculative Generality
    Creating today what we speculate will be needed in the future (where there is no current need for a particular feature / design).
    The Problem
    • Wasted time creating code that isn't actually going to be used (it is dead).
    • Greater complexity - now there is more code to sort through
    The Solution
    Design code to a specification. If a feature is needed in the future, you can always refactor code if need be. Until that time, remember YAGNI (You ain't gonna need it!).