Anjanesh

Assignment Statements, Comparisons & Observations
Font: Size: + -

Uploading gzipped content to Google Storage via gsutil

Thursday, January 17, 2013

Blogging this, since it doesn't fit on twitter.

It took me sometime to figure out the proper usage of gsutil when uploading files to google storage with the -z option to stream gzipped content. Just make sure to send in the content-type header too.

gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" -h "Content-Type: text/javascript" cp -z js -a public-read script.min.js gs://[bucket]/script.js

How to upload a web-font to Google Cloud Storage and use it in your CSS

Wednesday, December 26, 2012

Replace [bucket] with your bucket name.

  1. Use fontsquirrel's @font-face Generator to download all the font formats required for various browsers.
  2. Upload the fonts to Google Storage :
    gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" cp -a public-read font-webfont.eot gs://[bucket]/fonts/font-webfont.eot
    gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" cp -a public-read font-webfont.woff gs://[bucket]/fonts/font-webfont.woff
    gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" cp -a public-read font-webfont.ttf gs://[bucket]/fonts/font-webfont.ttf
    gsutil -h "Vary:Accept-Encoding" -h "Cache-Control:public,max-age=31536000" cp -a public-read font-webfont.svg gs://[bucket]/fonts/font-webfont.svg

    Now your font is accessible at http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.eot or http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.ttf etc.

  3. Apply the code to your CSS.

    @font-face {
        font-family: 'fontFamilyName';
        src: url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.eot');
        src: url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.eot?#iefix') format('embedded-opentype'),
             url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.woff') format('woff'),
             url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.ttf') format('truetype'),
             url('http://[bucket].commondatastorage.googleapis.com/fonts/font-webfont.svg#aller_displayregular') format('svg');    
        font-weight: normal;
        font-style: normal;
    }
  4. Unfortunately the last step is not enough to display the web-font on your website since the fonts need to be on the same domain as the website.

    In order to allow web-fonts to be hosted elsewhere, the location of the web-fonts must have a Access-Control-Allow-Origin header sent.

    For Google Storage, we do this :

    <?xml version="1.0" encoding="UTF-8"?>
    <CorsConfig>
      <Cors>
        <Origins>
          <Origin>http://mydomain.com</Origin>
        </Origins>
        <Methods>
          <Method>GET</Method>
          <Method>HEAD</Method>      
        </Methods>
        <ResponseHeaders>
          <ResponseHeader>x-goog-meta-foo1</ResponseHeader>
        </ResponseHeaders>
        <MaxAgeSec>1800</MaxAgeSec>
      </Cors>
    </CorsConfig>

    Save this as font.xml.
    Hmmm ... Google says :

    gsutil setcors <cors-xml-file> uri

    But using gsutil, we can set CORS to an entire bucket only and not to an object.

    gsutil setcors font.xml gs://[bucket]

    not uri as mentioned

    Similarily, for getcors :

    gsutil getcors gs://[bucket]
    and not
    gsutil getcors gs://cats/mycats.png

Solving all my permission issues on Ubuntu

Sunday, November 25, 2012

So many permission issues when copying files / folders from an outside source like a remove drive or Dropbox to my hard-disk that I have this mini-snippet to solve them all.

chmod -R 755 directory/
cd directory/
find -type f -exec chmod 644 {} \;
cd ..

Why I bought a Dropbox Pro account ?

Sunday, August 12, 2012

Last weekend was bad. My MacBook Pro's hard-drive crashed and my Ubuntu machine's hard-drive was semi-crashing, booting once in a while and once it booted with the entire file-system as read-only !

While my Ubuntu machine was up and running, I managed to backup all my data to Dropbox. But this time I backed it up in such a way that I don't have to 're-arrange' the folders all over again when my computer crashes.

Here's an example of what I did for my localhost (http://localhost/anjanesh) which, on the physical file system points to /home/anjanesh/www (~/www).

  • I copied all my data from ~/www to ~/Dropbox/www
  • Dropbox synced all the data in ~/Dropbox/www to the server
  • I deleted ~/www and symlinked www to ~/Dropbox/www (ln -s ~/Dropbox/www www)

So now ~/www points to ~/Dropbox/www
Whatever changes I make to ~/www gets stored, indexed and synced to Dropbox's server.

And now on my MacBook, I installed Dropbox and did the same thing with www - except point ~/www to /Users/anjanesh/Dropbox/www
This way, http://localhost/~anjanesh/ physically points to my Dropbox folder.

You can do this with all data folders, like Documents, Pictures and even Desktop. Even /var/lib/mysql to point all the mysql-data to a Dropbox sub-folder itself.

Open-Source Slideshare alternative

Sunday, February 05, 2012

There were 2 reasons for me to create an alternative to slidehsare's slide-show plugin :

  1. My uncle had a 170MB PPT file which is over-the-limit of Slideshare's 100MB size limit.
  2. My previous company's CEO wanted to display 6 slideshows on the company's homepage and 6 slideshare plugins was being extremely heavy esp on the flash part.

So I created a simple slide-show using jQuery as a jQuery plugin. There are some advantages as well as disadvantages.

Advantages

  • This is completely customizable using CSS.
  • Flexible slide size
  • Unlimited slides

Disadvantages

  • The slides are all images though, not HTML on the inside. Images would consume more space than HTML sildes.
  • You need to export the slides to images, which you can do using Open Office.
  • Require basic programming knowledge in HTML, CSS & JavaScript to embed this.

An example of this :

Usage :

$(document).ready(function()
{
    $('#div-element').jscoin_slide({effect:'slideUp'});
});

The other options for effect are fade, flip and slide

This project is on github : https://github.com/anjanesh/Slide.

Linkedin's April Fool Hoaxes

Friday, April 01, 2011

Every year we want to know Google's april fools' hoaxes. This year was no different. But has anyone noticed linkedin ? This is what I found on linkedin from my People You May Know section.
Linkedin People You May Know
(Click on the image to view the full "resume")

Linkedin People You May Know Linkedin People You May Know Linkedin People You May Know

Google Agarbatti (Incense)

Monday, October 25, 2010

My friend Sudhir bought this from the local store.

google agarbatti

Read : Google Agarbatti. (Agarbatti = Incense)

Update : Thanks to Sumit Ashok Kesarkar for the clarification. its Gugal which means Guggul == made from the sap of the plant "Commiphora mukul"

Email Newsletter Subscription via GFC & GAE

Wednesday, July 28, 2010

There is one major limitation when sending out legit mass emails via SMTP ("compose") - a daily cap on the number of emails allowed to be sent from a mailbox. This applies to most e-mail service providers.
Google Apps Standard, the free edition, allows a maximum of 500 outgoing mails per day for each user id.
Even the Primier edition which costs $50 per user a year limits outgoing mails at 2000 per day for every email id.

There are two cost-effective ways to send out newsletter emails via Google's services - Google Friend Connect (GFC) and Google App Engine (GAE).

Google Friend Connect

subscribeA lot of people are not unaware of the fact that you can actually send out newsletters for free to your subscribers via Google Friend Connect (GFC).
The catch is that the users have to be susbcribed exclusively via Google's Subscribe button without which there is no way for the newsletter to reach the user.
This is really a tough catch as you got to have it's subscribe button right from launch date.
Its a major turnoff, especially when a website collects registration infomation via a form and sends the data to a database, after which emails are sent separately.
Most email marketing systems like aweber, mailchimp, emailbrain, constantcontact, madmimi etc have the option to add subscribers manually externally.
And with GFC, you would not be able to retrieve the subscribed users' email ids via the control panel - export gives only names, ids, open id urls and thumbnail images.
So, at a later point in time, if you decide to switch to another email marketing system, you would need to send one last email asking them to re-subscribe to a new system.
Another bad news is that the subscriber's email address must be an open id ! (google a/c, yahoo a/c, twitter, AIM, netlog or any other openid)
Looks like all bad news, but if you think from the users' perspective, this is a good deal.
Its secure since there is no way for emails to be leaked accidentally.
Its safe because there is no room for errors in accidentally sending out mails to users who have unsubscribed.
Regarding the sender / from email address - It would be the same as the google account username. So if you don't want it sent from myusername@gmail.com, then create a google account under your app id. (This dual account chaos would be resolved soon : Google Apps Accounts Will Also Be Personal Google Accounts)
GFC is straigtforward, only bit of major work required is getting the audience to hit the google subscribe button.

Google App Engine

If you are not convinced with GFC then check out GAE - Google App Engine.
It has a daily free quota of sending emails to 2000 recipients. Link
After that, its billed at $0.0001 per recipient - thats just $1 for sending to an additional 10,000 recipients which can execute in about 2 minutes ! Link
But you've got to code to take advantage of GAE and your website should most probably be powered by GAE as well.
subscribe

Google Groups

Then there is always google's mailing list at google groups.
subscribe
But this cannot really be act a newsletter system.

If you want to submit ideas / suggestions to the Google team for its products, you can submit or vote at Google Product Ideas which is open to the public.

To WWW or not to

Monday, July 26, 2010

I've always been fond of naked domains. (FYI, http://mydomain.com is a naked domain, since it doesn't have www in front of it).
Lesser characters to type, see, spell out, hear and read. Much lesser overall energy.
I've always wondered why google.com always redirected to www.google.com and why Google App Engine stopped supporting mapping of an app to a naked URL. May not be the reason as mentioned here, but it does have its advantages.
So I joined the party a bit too late, but I am glad that I was not any later.
One of the advantages of using a subdomain (www is also a subdomain, it just so happens to be the default typing scheme for a website when the World Wide Web was born) is that cookies, if any, are transported to and forth - in the request and response headers - for that subdomain only.
If you have Web Developer, a FireFox addon, you can view all the cookies associated with a URL in the address bar.

Web Developer Toolbar

Here is a one liner php script to demonstrate this :

<?php setcookie("UserID", "23", time() + 3600, "/", "anjanesh.net") ?>

http://www.anjanesh.net/cookie.php

Cookies on www

http://test.anjanesh.net/cookie.jpg

Cookies on test

Lets re-iterate the above, this time without typing in www for the first URL. CTRL + SHIFT + DEL and clear all cookies.

http://anjanesh.net/cookie.php

Cookies on naked domain

http://test.anjanesh.net/cookie.jpg

Cookies on test again

Now, when requesting for a pure jpg image, the cookie information is sent across to the server which is 17 bytes (Cookie: UserID=23) of useless data.
You can use Live HTTP Headers FireFox addon to view real-time browser-request and server-response headers.

http://anjanesh.net/cookie.php

GET /cookie.php HTTP/1.1
Host: anjanesh.net
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8pre) Gecko/20100710 Ubuntu/9.10 (karmic) Namoroka/3.6.8pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 25 Jul 2010 01:14:18 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.2.11
Set-Cookie: UserID=23; expires=Fri, 25-Jul-2010 02:14:18 GMT; path=/; domain=anjanesh.net
Content-Encoding: gzip
----------------------------------------------------------
http://test.anjanesh.net/cookie.jpg

GET /cookie.jpg HTTP/1.1
Host: test.anjanesh.net
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8pre) Gecko/20100710 Ubuntu/9.10 (karmic) Namoroka/3.6.8pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: UserID=23
HTTP/1.1 200 OK Server: nginx Date: Fri, 25 Jul 2010 01:14:21 GMT Content-Type: image/jpeg Connection: keep-alive Last-Modified: Thu, 29 Nov 2007 03:54:05 GMT Etag: "27284bc-8291-4400943e7f140" Accept-Ranges: bytes Content-Length: 33425 ----------------------------------------------------------

From Y!'s Best Practices for Speeding Up Your Web Site :

If your domain is www.example.org, you can host your static components on static.example.org. However, if you've already set cookies on the top-level domain example.org as opposed to www.example.org, then all the requests to static.example.org will include those cookies.

But its not always possible to safe-guard this if your users don't type the www and you forget to force redirection to http://www
The best solution would be use a completely different domain name as a cookieless domain for static content.

Initially, I did not set the path & domain parameters in setcookie()

<?php setcookie("UserID", "23", time() + 3600) ?>

This does not send cookies across to the subdomain requests even when the cookie was set to the naked URL.
This does not even send cookies across to different paths.
But some browsers, or old browsers may behave differently, automatically adding cookies to *.example.org as Y! pointed out.

Related :

Dual-Monitors on Ubuntu

Saturday, June 05, 2010

I recently got a second LCD monitor for my Ubuntu 10.04 64-bit machine and now I am using dual monitors which is pretty cool.
The first one is a 22" LG Flatron L222WS (1680 x 1050) and the recent one, which is now the primary one, is a 23" Dell SP2309W (2048 x 1152).
I had these connected to a 1GB nVidia GeForce 8600 GT graphics card. The LG via VGA (blue cable) and Dell via DVI (white cable).
Dual monitors don't seem to be enabled automatically. It has to specified in the graphics card's control panel. The following is for NVidia.

Sytem > Administration > NVIDIA X Server Settings

NVIDIA Settings

  1. Enable your disabled monitor !
  2. Enable Xinerama.
  3. Save to Configuration File. (Click the button Save to Configuration File)
  4. Logout & Re-Login to restart X - (CTRL + ALT + BACKSPACE may or may not work)

Now, to get the panel onto the second monitor so that everything doesn't show as tabs on one monitor, you need to actually set a new (separate) panel for that monitor.

  1. Right click on the current panel > New Panel. The new panel would probably be located on the right of the current monitor.
  2. Right click on the new panel > Properties > Uncheck Expand, so that you can move the bar around to the next monitor
  3. New panel > Properties > Orientation : Bottom
  4. New panel > Add to Panel > Window List and Add.

NVIDIA Settings

You should now be able to minimize your second monitor tabs to the secnd monitor's panel.

Related :