Vagrant on Windows – Improve slow performance by using SMB instead of NFS

I love Vagrant, its a great tool for development. Sadly, once your project gets too big, performance really drops off a cliff on Windows. Running a Symfony2 project, I was getting ~20 second page refresh times. Apparently this relates to VirtualBox NFS on the shared folder.

 

A few people mentioned using Samba instead of NFS, but I couldn’t find anyone who had successfully used it. I gave it a go, and can confirm, it works a treat.

 

So first off, ssh into your Vagrant box:

vagrant ssh

 

then install Samba and edit the conf file

apt-get install samba
sudo nano /etc/samba/smb.conf

and add in:

[shared]
comment = Local Dev Server – /var/www
path = /var/www
browsable = yes
guest ok = yes
read only = no
create mask = 0777
force user = root
force group = root
#[shared] End

after that restart the Samba server

sudo restart smbd
sudo restart nmbd

Then I copied all the files in my project to my new Samba share directory ( called in this case ‘shared’).
after that I edited my Vagrantfile to make sure the NFS share was definitely turned off.

config.vm.synced_folder “.”, “/vagrant”, disabled: true

Solr Suggester config example

I couldn’t seem to get the Solr Suggester feature to work from the official docs examples so thought I’d document my working example.

In my case I wanted to suggest locations based on data currently within the index.

within solrconfig.xml

 

<searchComponent name=”suggest” class=”solr.SpellCheckComponent”>
<lst name=”spellchecker”>
<str name=”name”>suggest</str>
<str name=”classname”>org.apache.solr.spelling.suggest.Suggester</str>
<str name=”lookupImpl”>org.apache.solr.spelling.suggest.tst.TSTLookup</str>
<str name=”field”>myFieldForAutocomplete</str>
</lst>
</searchComponent>

<requestHandler name=”/suggest” class=”org.apache.solr.handler.component.SearchHandler”>
<lst name=”defaults”>
<str name=”spellcheck”>true</str>
<str name=”spellcheck.dictionary”>suggest</str>
<str name=”spellcheck.count”>10</str>
</lst>
<arr name=”components”>
<str>suggest</str>
</arr>
</requestHandler>

and then schema.xml

 

<types>

<fieldType class=”solr.TextField” name=”text_auto”>
<analyzer>
<tokenizer class=”solr.KeywordTokenizerFactory”/>
<filter class=”solr.LowerCaseFilterFactory”/>
</analyzer>
</fieldType>
</types>

and in schema.xml fields:

 

<field name=”myFieldForAutocomplete” type=”text_auto” indexed=”true” stored=”true” multiValued=”false” />
<copyField source=”city” dest=”myFieldForAutocomplete” />

then its a simple case of building the index with a call to:

http://localhost:4569/solr/myCore/suggest?spellcheck.build=true

after that we can use suggest with:

 

http://localhost:4569/solr/myCore/suggest?q=myQuery

Solr should then give you a nice response like:

 

<response>
<lst name=”responseHeader”>
<int name=”status”>0</int>
<int name=”QTime”>1</int>
</lst>
<lst name=”spellcheck”>
<lst name=”suggestions”>
<lst name=”abe”>
<int name=”numFound”>1</int>
<int name=”startOffset”>0</int>
<int name=”endOffset”>3</int>
<arr name=”suggestion”>
<str>aberdeen</str>
</arr>
</lst>
</lst>
</lst>
</response>

Vagrant bootstrap.sh for full LAMP stack with Solr 4

Just for reference, here is the bootstrap.sh file I use to bring up my vagrant dev box with Solr 4 and Jetty ready to go.

#!/usr/bin/env bash
apt-get install python-software-properties
add-apt-repository ppa:ondrej/php5
apt-get update
apt-get install php5
apt-get install php5-mysql
apt-get install mysql-server libapache2-mod-auth-mysql php5-mysql
apt-get install phpmyadmin
apt-get install php5-curl
apt-get install -y apache2
apt-get install -y tomcat6 curl

rm -rf /var/www
ln -fs /vagrant /var/www
mkdir -p /opt/jetty/webapps/
mkdir -p /opt/jetty/webapps/
cd /opt
wget http://apache.hippo.nl/lucene/solr/4.4.0/solr-4.4.0.tgz
tar -xvf solr-4.4.0.tgz
cp solr-4.4.0/dist/solr-4.4.0.war /opt/jetty/webapps/solr.war
cp -r /opt/solr-4.4.0/dist /opt/solr
p -r /opt/solr-4.4.0/contrib /opt/solr
# copy new cores
cp -R /var/www/solr-config-master/solr-config-master/example solr
cp -r solr-4.4.0 solr



#/etc/init.d/tomcat6 start
cd /etc/init.d/
sudo sh tomcat6 start
cd /opt/solr/example/
sudo java -jar start.jar

Whenever a new Solr version comes out they tend to move the location , so a good idea to check whats’ what: http://apache.hippo.nl/lucene/solr/

PHP Interface example

I’ve never really come across the need to use an interface, and usually just use inheritance to extend whatever class I needed to. Recently though I needed a generic base caching class, which would have other classes implement there own methods.

interface CacheInterface

{  
    public function getCacheValue($key);   

    public function setCacheValue($key , $value);  
}

Note that there is no content within the methods, and rather than curly braces, its closed off with a ‘;’.

To implement the interface:

class CacheGoogle extends Controller implements CacheInterface
{
   
    public function getCacheValue($key)
    {  
        //try and get cached value from the DB
    }

    public function setCacheValue($key , $value)
    {      
        //add new cache value to DB
    }
}

Then wherever its needed:

private $cache;

public function __construct()
{
    $this->cache = new CacheGoogle;
}

 public function checkCache(CacheInterface $this->cache)
 {  
        //
 }

Stackoverflow as a rubber duck

This week we had the director of an external agency in the office.

duck

During a meeting with him he brought up that back in the old

days of cubicle programmers, some would have ‘cardboard cutouts‘ to bounce ideas off when they got stuck with a problem.

 

I mentioned that often when I was stuck with something and went to Stackoverflow to find a solution, often in the process of typing out and explaining the problem to someone else I’d come to the solution myself.

 

This weekend whilst sat in the sun reading The Pragmatic Programmer , I came to the section on ‘Rubber duck debugging‘ and realised that Stackoverflow makes a great rubber duck.

 

As it turns out Jeff Atwood thinks so too.

 

 

How to upload pre-made videos to Instagram

UPDATE:
Instagram now allow uploads from your gallery, making this post redundant. :)

A few days ago Instagram added the ability to upload short video clips as well as photos using its mobile app. In the same way as Vine though, you can’t upload videos that are pre recorded, you have to take the video there and then using the built in camcorder.

While playing around the other day I found a way to do it though, here’s how it works on Android, although I assume the process would be similar for iOS, but I haven’t had a chance to look yet.

 

For proof, see my test video

 

You’ll need a rooted Android device for this to work.

My first clue was that just after you press the ‘next’ button after recording a video, a small JSON file

/data/data/com.instagram.android/files/pending_media.json

gets created. This contains the path to a temporary video file, along with other data which gets sent to the Instagram API.

Step 1.

Open up Instagram and record a short video up to the marker. It doesn’t matter what of, as we won’t be using this.

Step 2.

Now in a file manager head to

/storage/sdcard0/Android/data/com.instagram.android/files/videos/

or where ever the path is in you pending_media.json file.

Screenshot_2013-06-25-20-07-23

Step 3.

In that videos directory, you’ll see a new directory dated with todays date. Open that and you’ll see the video we just made.

Screenshot_2013-06-25-20-09-15

Step 4.

Next we need to overwrite that video with the one we want to upload. It needs to be around 10seconds long, and not too large, otherwise the upload will fail. Copy over the orignal file with your new one, making sure to keep the file name the same.

Screenshot_2013-06-25-20-11-28

Step 5.

Re open Instagram, and then press the ‘next’ arrow. After a few seconds processing, you should see your pre-recorded video. It can now be uploaded as normal.

Screenshot_2013-06-25-20-13-49

 

 

 

There is another directory called ‘music’ which contains the audio of the original video.

I had an issue with some videos not being rotated properly. Within the pending_media.json file there is an ‘orientation’ attribute, which was set to 0. Setting it to 1 before upload didn’t solve it, so I ended up rotating the videos 270 before upload.

 

Let me know how you get on with this!

 

Solr 4 importing MySQL – DataImportHandler not found

Importing MySQL db into Solr4.

#/opt/solr/example/solr/collection1/conf/data-config.xml

<span style="font-family: Trebuchet MS, sans-serif;"><dataConfig>

<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb" user="root" password="root" batchSize="1" />
    <document name="property">

        <entity name="Property" query="SELECT * FROM Property">
            <field column="id" name="id" />
            <field column="address1" name="address" />
            <field column="city" name="city" />
            <field column="county" name="county" />
            <field column="lat" name="lat" />
            <field column="lng" name="lng" />
        </entity>

    </document>
</dataConfig>
</span>

Then

/opt/solr/example/solr/collection1/conf/solrconfig.xml
  <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">  

     <lst name="defaults">
        <str name="config">/opt/solr/collection1/conf/data-config.xml</str>
     </lst>

  </requestHandler>

 
 
    <requestHandler name="/dataimport" class="solr.DataImportHandler">  

     <lst name="defaults">
        <str name="config">data-config.xml</str>
     </lst>

  </requestHandler>

When I restarted Solr, I kept getting the exception ‘DataImportHandler not found’
For some reason, I had no ‘dists’ dir or ‘contrib’ in my /opt/solr. So I copied one accross:

cd /opt
wget http://apache.hippo.nl/lucene/solr/4.3.0/solr-4.3.0-src.tgz
tar -xvf solr-4.3.0-src.tgz

cp -r solr-4.3.0-src/dist /opt/solr
cp -r solr-4.3.0-src/contrib /opt/solr

Then I was missing the ‘com.mysql.jdbc.Driver’

sudo apt-get install libmysql-java
$ sudo cp /usr/share/maven-repo/mysql/mysql-connector-java/5.1.16/mysql-connector-java-5.1.16.jar /opt/solr/contrib/dataimporthandler/lib/mysql-connector-java-5.1.16.jar

Not sure if this was correct, so to make sure

$ sudo cp /usr/share/maven-repo/mysql/mysql-connector-java/5.1.16/mysql-connector-java-5.1.16.jar /opt/solr/dist/mysql-connector-java-5.1.16.jar
 sudo chmod 755 mysql-connector-java-5.1.16.jar

open up SolrConfig.xml

$ sudo nano /opt/solr/example/solr/collection1/conf/solrconfig.xml

and add:

<lib dir="/opt/solr/dist/" regex="mysql-connector-java-.*.jar" />

PHPUnit on Ubuntu 12.04 via Vagrant – Solving the ‘ /usr/bin/phpunit: No such file or directory’ error

Had a real issue installing PHPUnit on my Vagrant server.

Initially I got this error:

Call to undefined method PHP_CodeCoverage_Filter::getInstance() in /usr/bin/phpunit on line 39

Googling around, many people solved using:

sudo apt-get remove phpunit
sudo apt-get upgrade pear
sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover pear.symfony-project.com
sudo pear channel-discover pear.symfony.com
sudo pear channel-discover components.ez.no
sudo pear update-channels
sudo pear upgrade-all
sudo pear install --alldeps phpunit/PHPUnit

But for me, that then just left me with:

/usr/bin/phpunit: No such file or directory

Looking at my PEAR config:

pear config-show

Showed me that my PEAR executable directory was:

 /home/vagrant/pear/bin

So then all I needed to do was symlink from usr/bin to the phpunit one:

sudo ln -s /home/vagrant/pear/bin/phpunit /usr/bin/

Install Solr on Vagrant

[Update]
This method will install an older version of Solr. To get the latest I followed this guide.

All I had to do was add:

config.vm.network :forwarded_port, host: 4569, guest: 8983

to the Vagrant file.

You can then start Tomcat with:

/etc/init.d/tomcat6 start

and Solr

sudo java -jar /opt/solr/example/start.jar

[/Update]

Installing Solr on Vagrant is pretty simple.

vagrant shh

then:

sudo apt-get update

sudo apt-get install openjdk-6-jdk

sudo apt-get install solr-tomcat

Then in your Vagrantfile add something like:

config.vm.network :forwarded_port, host: 4568, guest: 8080

Reload Vagrant:

vagrant reload

and ssh back in again.

Finally:

sudo service tomcat6 start

and Solr should be running. Test it out:

http://localhost:4568/solr/

Solving [DoctrineDBALDBALException] Unknown database type enum requested, DoctrineDBALPlatformsMySqlPlatform may not support it.

Importing pre-existing MySQL DB using Doctrine in Symfony2 I came across this error:

 [DoctrineDBALDBALException]
  Unknown database type enum requested, DoctrineDBALPlatformsMySqlPlatform
   may not support it.

The fix was found within the Symfony2 Docs

To app/config/config.yml just under your connection info add:

mapping_types:
                    enum: string